From f9d646331bb3e1b429845ed4cc8e93d706db5ee1 Mon Sep 17 00:00:00 2001 From: Jarek Potiuk Date: Sat, 17 Oct 2026 02:40:42 +0200 Subject: [PATCH 1/4] fix(security-tracker): harden the local and Jira backends after review The security-tracker backends merged in #1647 without the fixes from its last review rounds. This carries them forward and closes the findings of the final review that were still open. Local-files tracker (git run outside the sandbox through vetted-ops): - publish pushes `HEAD:` to exactly the remote and ref it checked, with --no-follow-tags, so push.default=matching, a remote's push refspecs or push.followTags cannot send other branches or tags; - git reads attributes from the empty tree (GIT_ATTR_SOURCE), so no .gitattributes can switch on a filter, diff or merge driver even if one is configured after the per-command config check; - network-only pushes, no gc/maintenance hooks, and a tree comparison against the destination (from the earlier rounds); - descriptor names may contain spaces (`in progress`), still one path component; a bare number naming two reports is ambiguous, and underscore slugs resolve by their bare ID; - inline lists split on real item boundaries (apostrophes, escapes); - comment-marker authors are percent-encoded, so names with spaces read back. Jira tracker and setup: - a fence closes only on a matching fence of the same character and at least the same length, so a longer block cannot expose PoC headings; - the CLI takes an explicit --deployment, which vetted-ops always passes, so an inherited JIRA_DEPLOYMENT cannot switch a Server tracker to Cloud endpoints; - fresh setup scaffolds `tracker.platform: TODO`, so the backend question is asked; the Jira steps map labels to whitespace-free names and require `doctor` to pass. The plugin's copy of the vetted-ops sources and README is brought back in line with tools/vetted-ops. Generated-by: Claude Opus 5 --- ...26-10-15-security-tracker-backends-plan.md | 2 +- .../2026-10-15-security-tracker-backends.md | 9 +- .../skills/cve-allocate/SKILL.md | 17 +- .../skills/issue-deduplicate/SKILL.md | 17 +- .../magpie-security/skills/issue-fix/SKILL.md | 17 +- .../skills/issue-import-from-md/SKILL.md | 17 +- .../skills/issue-import-from-pr/SKILL.md | 17 +- .../skills/issue-import-from-scan/SKILL.md | 17 +- .../issue-import-via-forwarder/SKILL.md | 17 +- .../skills/issue-import/SKILL.md | 17 +- .../skills/issue-invalidate/SKILL.md | 17 +- .../skills/issue-sync/SKILL.md | 17 +- .../skills/issue-triage/SKILL.md | 17 +- .../skills/tracker-stats-dashboard/SKILL.md | 20 +- plugins/magpie-setup/skills/setup/config.md | 23 +- plugins/magpie-setup/templates/project.md | 5 +- plugins/magpie-vetted-ops/tools/jira | 1 + plugins/magpie-vetted-ops/tools/local-tracker | 1 + .../tools/vetted-ops/README.md | 31 +- .../tools/vetted-ops/src/vetted_ops/cli.py | 29 +- .../tools/vetted-ops/src/vetted_ops/config.py | 25 +- .../tools/vetted-ops/src/vetted_ops/ops.py | 54 ++ .../src/vetted_ops/tracker_backends.py | 44 +- tools/dev/blocks/tracker-backend.md | 15 +- tools/jira/README.md | 8 +- tools/jira/pyproject.toml | 13 +- tools/jira/src/jira_bridge/markup.py | 60 +- .../jira/src/jira_bridge/security_tracker.py | 103 ++- tools/jira/tests/test_markup.py | 48 ++ tools/jira/tests/test_security_tracker.py | 98 ++- tools/local-tracker/README.md | 18 +- tools/local-tracker/pyproject.toml | 10 +- .../src/magpie_local_tracker/cli.py | 39 +- .../src/magpie_local_tracker/descriptor.py | 38 +- .../src/magpie_local_tracker/detect.py | 6 +- .../src/magpie_local_tracker/metadata.py | 135 +++- .../src/magpie_local_tracker/sections.py | 171 ++++- .../src/magpie_local_tracker/store.py | 313 ++++++-- .../src/magpie_local_tracker/vcs.py | 257 ++++++- .../local-tracker/tests/test_local_tracker.py | 724 ++++++++++++++++++ tools/security-tracker/contract.md | 26 +- tools/vetted-ops/README.md | 31 +- tools/vetted-ops/src/vetted_ops/cli.py | 29 +- tools/vetted-ops/src/vetted_ops/config.py | 25 +- tools/vetted-ops/src/vetted_ops/ops.py | 54 ++ .../src/vetted_ops/tracker_backends.py | 44 +- .../vetted-ops/tests/test_tracker_backends.py | 161 +++- tools/vetted-ops/tests/test_vetted_ops.py | 5 + uv.lock | 20 - 49 files changed, 2592 insertions(+), 290 deletions(-) create mode 120000 plugins/magpie-vetted-ops/tools/jira create mode 120000 plugins/magpie-vetted-ops/tools/local-tracker diff --git a/docs/designs/2026-10-15-security-tracker-backends-plan.md b/docs/designs/2026-10-15-security-tracker-backends-plan.md index 8bbea9cc7..86d2acbdb 100644 --- a/docs/designs/2026-10-15-security-tracker-backends-plan.md +++ b/docs/designs/2026-10-15-security-tracker-backends-plan.md @@ -31,7 +31,7 @@ Per the [designs convention](README.md), this plan is folded into the design and | 10 | Setup: Step 3a — choose backend, detect format, confirm access, write descriptor | `plugins/magpie-setup/skills/setup/config.md` | Done | | 11 | Taxonomy: `contract:security-tracker` in the validator, capability docs, labeler | `tools/skill-and-tool-validator`, `docs/labels-and-capabilities.md`, `.github/labeler.yml` | Done | | 12 | Token restamp for the edited skills; `prek run --all-files` | `measured_tokens:` frontmatter | Done | -| 12a | vetted-ops: `[tracker]` policy, translation of every tracker operation, six new operations, refusal of the rest, tests incl. an end-to-end run against the local tracker | `tools/vetted-ops/` | Done | +| 12a | vetted-ops: `[tracker]` policy, translation of every tracker operation, nine new operations, refusal of the rest, tests incl. an end-to-end run against the local tracker | `tools/vetted-ops/` | Done | | 12b | Contract: skill-command → vetted-operation → backend table; shared block points skills at vetted operations | `tools/security-tracker/contract.md`, `tools/dev/blocks/tracker-backend.md` | Done | | 13 | Security-skill eval suites (self-eval) — 308/313; the 5 failures come from prompt files this change does not touch | `tools/skill-evals/evals/security-*` | Done (cross-model pass to do) | | 14 | Create the `contract:security-tracker` label on `apache/magpie` | GitHub labels | To do (maintainer) | diff --git a/docs/designs/2026-10-15-security-tracker-backends.md b/docs/designs/2026-10-15-security-tracker-backends.md index 2a7b5d9e7..0d595d4f1 100644 --- a/docs/designs/2026-10-15-security-tracker-backends.md +++ b/docs/designs/2026-10-15-security-tracker-backends.md @@ -56,12 +56,13 @@ named body fields, the single status rollup, attachments for the CVE record, and Skills never call a backend CLI. Every tracker `gh` command in a skill maps to a [vetted operation](../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations), and vetted-ops translates that operation for the backend its policy names (`[tracker] platform`). - The translation is reviewed code: the policy supplies the backend's tool directory and pinned target, never a command, + The translation is reviewed code: the policy supplies only the pinned target, and the backend's code runs from the tool installed beside vetted-ops, never from a path a policy names, so the closed-shape guarantees — fixed program, unaddressable target, parameters as argv elements, bodies on stdin, reads unreachable from the write entry point — hold on all three backends. - Six operations were added so every tracker shape the skills use has a vetted form: + Nine operations were added so every tracker shape the skills use has a vetted form: `issue-create`, `issue-reopen`, `issue-list-label`, `issue-search` (plain words, no `:` qualifiers), - `tracker-pending` and `tracker-publish`. + `issue-body` and `issue-attach` (so CVE JSON generation works without GitHub), + `tracker-doctor` (the pre-flight on another backend), `tracker-pending` and `tracker-publish`. Tracker operations with no counterpart (boards, milestone administration, the roster, `rollup-fold`) refuse by name, and a test derives the tracker operations from the catalogue so a new one cannot go unmapped. 5. **Skills switch through one shared block**, `tools/dev/blocks/tracker-backend.md`, @@ -131,7 +132,7 @@ the Groovy bridge stays the general `contract:tracker` write path for the `issue one question in the existing batch picks the backend. For local files it finds the folder, runs `detect`, shows the decisions and notes, asks who can read the repository, and writes the descriptor only after that answer. The descriptor is the one file this step writes outside the personal layer. It is left uncommitted, and the first publish proposal includes it. -For both non-GitHub backends the step also shows the vetted-ops `[tracker]` table and the six new caller grants, and writes them only on confirmation. +For both non-GitHub backends the step also shows the vetted-ops `[tracker]` table and the nine new caller grants, and writes them only on confirmation. ## Alternatives considered diff --git a/plugins/magpie-security/skills/cve-allocate/SKILL.md b/plugins/magpie-security/skills/cve-allocate/SKILL.md index 02cc2acf9..75f13022d 100644 --- a/plugins/magpie-security/skills/cve-allocate/SKILL.md +++ b/plugins/magpie-security/skills/cve-allocate/SKILL.md @@ -21,7 +21,7 @@ argument-hint: "[issue-number] [CVE-YYYY-NNNNN]" capability: capability:resolve surface_hash: sha256:25c2286c4e159c66 license: Apache-2.0 -measured_tokens: 7366 +measured_tokens: 7638 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-deduplicate/SKILL.md b/plugins/magpie-security/skills/issue-deduplicate/SKILL.md index 723084571..691610717 100644 --- a/plugins/magpie-security/skills/issue-deduplicate/SKILL.md +++ b/plugins/magpie-security/skills/issue-deduplicate/SKILL.md @@ -25,7 +25,7 @@ argument-hint: "[kept-issue] [duplicate-issue]" capability: capability:resolve surface_hash: sha256:3c9f502b802d2037 license: Apache-2.0 -measured_tokens: 5989 +measured_tokens: 6261 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-fix/SKILL.md b/plugins/magpie-security/skills/issue-fix/SKILL.md index ab1b82263..fedf56bbd 100644 --- a/plugins/magpie-security/skills/issue-fix/SKILL.md +++ b/plugins/magpie-security/skills/issue-fix/SKILL.md @@ -23,7 +23,7 @@ capability: - capability:resolve surface_hash: sha256:550eabe3b9bb3689 license: Apache-2.0 -measured_tokens: 7163 +measured_tokens: 7435 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-import-from-md/SKILL.md b/plugins/magpie-security/skills/issue-import-from-md/SKILL.md index b8a5476a4..8129c9fea 100644 --- a/plugins/magpie-security/skills/issue-import-from-md/SKILL.md +++ b/plugins/magpie-security/skills/issue-import-from-md/SKILL.md @@ -27,7 +27,7 @@ argument-hint: "[path-to-markdown-file]" capability: capability:intake surface_hash: sha256:e2437e84cdf98aa5 license: Apache-2.0 -measured_tokens: 7095 +measured_tokens: 7367 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-import-from-pr/SKILL.md b/plugins/magpie-security/skills/issue-import-from-pr/SKILL.md index 579a0450b..150d5dceb 100644 --- a/plugins/magpie-security/skills/issue-import-from-pr/SKILL.md +++ b/plugins/magpie-security/skills/issue-import-from-pr/SKILL.md @@ -20,7 +20,7 @@ argument-hint: "[pr-number] [repo:owner/name]" capability: capability:intake surface_hash: sha256:c746e4aecc3cf315 license: Apache-2.0 -measured_tokens: 8447 +measured_tokens: 8719 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-import-from-scan/SKILL.md b/plugins/magpie-security/skills/issue-import-from-scan/SKILL.md index 337a6942e..9ea423307 100644 --- a/plugins/magpie-security/skills/issue-import-from-scan/SKILL.md +++ b/plugins/magpie-security/skills/issue-import-from-scan/SKILL.md @@ -19,7 +19,7 @@ argument-hint: "[scan-source ...] (one or more GitHub issues and/or report fold capability: capability:intake surface_hash: sha256:7adfbe73f79606b1 license: Apache-2.0 -measured_tokens: 5964 +measured_tokens: 6236 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-import-via-forwarder/SKILL.md b/plugins/magpie-security/skills/issue-import-via-forwarder/SKILL.md index cd152b64b..895bf6a0b 100644 --- a/plugins/magpie-security/skills/issue-import-via-forwarder/SKILL.md +++ b/plugins/magpie-security/skills/issue-import-via-forwarder/SKILL.md @@ -20,7 +20,7 @@ when_to_use: | capability: capability:intake surface_hash: sha256:43894008501eb56d license: Apache-2.0 -measured_tokens: 6213 +measured_tokens: 6485 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-import/SKILL.md b/plugins/magpie-security/skills/issue-import/SKILL.md index 4fb44b2d8..24407d825 100644 --- a/plugins/magpie-security/skills/issue-import/SKILL.md +++ b/plugins/magpie-security/skills/issue-import/SKILL.md @@ -20,7 +20,7 @@ argument-hint: "[import] [last Nd|all] [skip threadId]" capability: capability:intake surface_hash: sha256:e9c563d494821baf license: Apache-2.0 -measured_tokens: 9864 +measured_tokens: 10136 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-invalidate/SKILL.md b/plugins/magpie-security/skills/issue-invalidate/SKILL.md index 0d6b8e2f5..ec7f88243 100644 --- a/plugins/magpie-security/skills/issue-invalidate/SKILL.md +++ b/plugins/magpie-security/skills/issue-invalidate/SKILL.md @@ -20,7 +20,7 @@ argument-hint: "[issue-number]" capability: capability:resolve surface_hash: sha256:43a163bcbdb06f11 license: Apache-2.0 -measured_tokens: 7582 +measured_tokens: 7854 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-sync/SKILL.md b/plugins/magpie-security/skills/issue-sync/SKILL.md index 52f07ebff..77190a99d 100644 --- a/plugins/magpie-security/skills/issue-sync/SKILL.md +++ b/plugins/magpie-security/skills/issue-sync/SKILL.md @@ -25,7 +25,7 @@ argument-hint: "[issue-number]" capability: capability:intake surface_hash: sha256:5c4aad61d458d98f license: Apache-2.0 -measured_tokens: 6734 +measured_tokens: 7006 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/issue-triage/SKILL.md b/plugins/magpie-security/skills/issue-triage/SKILL.md index cc5499958..2a1d038af 100644 --- a/plugins/magpie-security/skills/issue-triage/SKILL.md +++ b/plugins/magpie-security/skills/issue-triage/SKILL.md @@ -23,7 +23,7 @@ when_to_use: | capability: capability:triage surface_hash: sha256:4fb1fcfc79d7f275 license: Apache-2.0 -measured_tokens: 7130 +measured_tokens: 7402 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). diff --git a/plugins/magpie-security/skills/tracker-stats-dashboard/SKILL.md b/plugins/magpie-security/skills/tracker-stats-dashboard/SKILL.md index 6a11079c7..1fef821d2 100644 --- a/plugins/magpie-security/skills/tracker-stats-dashboard/SKILL.md +++ b/plugins/magpie-security/skills/tracker-stats-dashboard/SKILL.md @@ -18,7 +18,7 @@ when_to_use: | capability: capability:stats surface_hash: sha256:779340f8eb985eeb license: Apache-2.0 -measured_tokens: 4232 +measured_tokens: 4591 --- -Read `tracker.platform` from `/project.md` (default `github`) before the first tracker operation. +Read `tracker.platform` from `/project.md` before the first tracker operation; unset or `TODO` means `github`. With `github`, every recipe below runs as written. With `local-files` or `jira`, never run a `gh` command against ``: look the command up in the [skill-command → vetted-operation table](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations) and run that vetted operation instead — `vetted-op-read` for reads, `vetted-op-tracker` for the rollup, body-field and publish operations, `vetted-op` for the other writes. -Vetted-ops translates it for the configured backend; `` issue numbers become the backend's IDs, and the returned `url` is the link. +Vetted-ops translates it for the configured backend; issue numbers become the backend's IDs (`SEC-0012`, `FOOSEC-12`), and the returned `url` is the link. Operations on `` (PRs, code search) do not change. A refusal — the backend's confidentiality guard, or an operation the backend does not have — stops the step: report it, never route around it. +**Pre-flight on another backend.** The GitHub checks in Step 0 — `gh api repos/` access, the collaborator roster, project-board ids — do not apply. +Run the `tracker-doctor` vetted operation instead and stop on any failing check; take the security-team roster from `/release-trains.md`, and treat the project board as disabled. + +**CVE JSON on another backend.** `generate-cve-json --attach` reads and attaches through GitHub, so do not run it. +Instead: save the body with the `issue-body` vetted operation (`vetted-op-read … --save cve-body issue-body `), +run `generate-cve-json --stdin --title "" --output /.json` on that saved file — +adding `--review` when the issue's labels (from `issue-view`) include the release-vote label or a forward-state label the generator's config names, since `--stdin` cannot see labels and would otherwise produce DRAFT — +and attach the result with the `issue-attach` vetted operation (` /.json .json`). + **Publish local tracker changes before ending.** With `local-files`, nothing reaches the team until it is committed. -If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files, +If this run wrote to the tracker, run the `tracker-pending` vetted operation as the last step, show the changed files and any unpushed commits, draft a commit message naming the trackers and the action, ending with the project's commit-attribution trailer, and ask. Only on the user's confirmation run `tracker-publish` with that message file (Git: commit the tracker folder and push; SVN: commit, which publishes). +**This skill is GitHub-only today.** Its fetch pipeline (`run.sh` and the scripts it runs) reads `` with `gh` directly, so the vetted-operation translation above does not reach it. +With `tracker.platform` set to `local-files` or `jira`, stop before fetching anything and tell the user the dashboard does not support that backend yet; never point the pipeline at a GitHub repository instead. + *Renderer* configuration (bucket granularity, milestones, categories, scope labels, triage keywords, …) lives in a separate YAML file at `.apache-magpie-overrides/security-tracker-stats.yaml` (path set by `tracker_stats_config:` in [`/security-tracker-stats.md`](../../../magpie-setup/templates/security-tracker-stats.md)). diff --git a/plugins/magpie-setup/skills/setup/config.md b/plugins/magpie-setup/skills/setup/config.md index 8c89e982e..c8b3a0cb0 100644 --- a/plugins/magpie-setup/skills/setup/config.md +++ b/plugins/magpie-setup/skills/setup/config.md @@ -215,12 +215,27 @@ Step 3c's harness command files are the two named exceptions). Never stage anyth ## Step 3a — Security tracker backend Run this when a `security-*` skill is in scope and `tracker.platform` in `project.md` is still unset or `TODO`. +A freshly scaffolded `project.md` carries `platform: TODO`, so the question is part of every first setup; +a `TODO` the user skips reads as `github`. Put one question in Step 3's batch, offering the three backends of the [security-tracker contract](../../../../tools/security-tracker/contract.md): -- **`github`** (default) — a private GitHub repository, `tracker_repo`. +- **`github`** (default) — a private GitHub repository, `tracker_repo`; write `tracker.platform: github`. - **`local-files`** — Markdown files in a folder of this repository (Git or SVN), committed and pushed at the end of each session. -- **`jira`** — a Jira project whose issues carry an issue-security level; ask for `url`, `project` and `security_level`, and run the backend's `doctor`. +- **`jira`** — a Jira project whose issues carry an issue-security level; follow the Jira steps below. + +For **`jira`**: + +1. **Ask for the target**: `tracker.jira.url`, `tracker.jira.project`, `tracker.jira.security_level` and `tracker.jira.deployment` (`server` or `cloud`). + Write them, with `tracker.platform: jira`, to the personal layer's `project.md`. +2. **Make every label Jira-safe.** Jira labels cannot contain whitespace and the backend refuses any label that does, so the template's names (`needs triage`, `cve allocated`, …) fail on the first write. + Map each configured label to a whitespace-free name (`needs triage` → `needs-triage`) everywhere it is configured: + the `tracker.labels.*` values and the `scope_detection.labels` keys in `project.md`, + the `any_label` lists in `security-tracker-stats.md`, + and the vetted-ops policy's `[values] labels` list. + Show the mapping and apply it on the user's confirmation; the policy change goes in the same diff as the `[tracker]` table below. +3. **Run `doctor`**: `uv run --project /tools/jira magpie-jira-tracker --url --project --security-level --deployment doctor`, and show its checks. + Do not declare the backend ready until every label is mapped and `doctor` passes. For **`local-files`**: @@ -246,10 +261,10 @@ For **`local-files`**: For both `local-files` and `jira`, the skills reach the tracker only through vetted operations ([mapping](../../../../tools/security-tracker/contract.md#from-skill-commands-to-vetted-operations)). When a vetted-ops policy exists, show the `[tracker]` table it needs — -`platform`, the backend's absolute `project` directory, and `root` or the `jira_*` target +`platform`, and `root` or the `jira_*` target (the backend's code comes from the tool installed beside vetted-ops, never from the policy) ([vetted-ops → Tracker backends](../../../../tools/vetted-ops/README.md#tracker-backends)) — and write it only on the user's confirmation; the policy is a security control, not configuration this step may change unasked. -Grant the security callers `issue-create`, `issue-search`, `issue-list-label`, `issue-reopen`, `tracker-pending` and `tracker-publish` in the same diff. +Grant the security callers `issue-create`, `issue-search`, `issue-list-label`, `issue-reopen`, `issue-body`, `issue-attach`, `tracker-doctor`, `tracker-pending` and `tracker-publish` in the same diff. ## Step 3b — Record what this run reconciled diff --git a/plugins/magpie-setup/templates/project.md b/plugins/magpie-setup/templates/project.md index c123d9f62..0bdba0408 100644 --- a/plugins/magpie-setup/templates/project.md +++ b/plugins/magpie-setup/templates/project.md @@ -457,8 +457,9 @@ tracker: # Git or SVN working copy (tools/local-tracker/). `jira`: a Jira project # whose issues carry an issue-security level (tools/jira/). # `/magpie-setup config` asks and, for local-files, learns the format of - # the reports already in the folder. - platform: github + # the reports already in the folder. `TODO` (not yet asked) reads as + # `github`; the question writes the confirmed choice here. + platform: TODO # local-files only. local: diff --git a/plugins/magpie-vetted-ops/tools/jira b/plugins/magpie-vetted-ops/tools/jira new file mode 120000 index 000000000..2186c6252 --- /dev/null +++ b/plugins/magpie-vetted-ops/tools/jira @@ -0,0 +1 @@ +../../../tools/jira \ No newline at end of file diff --git a/plugins/magpie-vetted-ops/tools/local-tracker b/plugins/magpie-vetted-ops/tools/local-tracker new file mode 120000 index 000000000..9c47fb609 --- /dev/null +++ b/plugins/magpie-vetted-ops/tools/local-tracker @@ -0,0 +1 @@ +../../../tools/local-tracker \ No newline at end of file diff --git a/plugins/magpie-vetted-ops/tools/vetted-ops/README.md b/plugins/magpie-vetted-ops/tools/vetted-ops/README.md index d72ac582a..a90504a01 100644 --- a/plugins/magpie-vetted-ops/tools/vetted-ops/README.md +++ b/plugins/magpie-vetted-ops/tools/vetted-ops/README.md @@ -506,24 +506,29 @@ of its `gh` builder, and the skills keep calling the same operations: ```toml [tracker] platform = "local-files" # github (default) | local-files | jira -project = "/abs/path/to/.apache-magpie/tools/local-tracker" root = "/abs/path/to/the/repo/security/reports" # the tracker folder # platform = "jira" -# project = "/abs/path/to/.apache-magpie/tools/jira" # jira_url = "https://issues.example.org/jira" # jira_project = "FOOSEC" # jira_security_level = "Security Team" +# jira_issue_type = "Bug" # default Bug # jira_deployment = "server" # server | cloud ``` The guarantees above carry over, because the translation lives in reviewed code ([`tracker_backends.py`](src/vetted_ops/tracker_backends.py)), not in the policy: -- **The program is fixed.** The policy supplies data — the backend's tool - directory, which must be the `tools/local-tracker` or - `tools/jira` directory the platform names, and its pinned - target — never a command. The argv is `uv run --project