Repository navigation
Conversation
The pre-script sets authorization.mutation_authorized from the runner-only FULLSEND_TRIAGE_MUTATION_AUTHORIZED variable: exact 'true' authorizes, unset or 'false' stays report-only, any other value fails closed (exit 1, no bundle). The variable is never exposed to the sandbox. Enabling it in CI is gated on TC-6191. Implements TC-6934 Assisted-by: Claude Code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reviewer's GuideIntroduces a trusted runner-side opt-in for triage mutation authorization, propagates it into validated bundles while failing closed on malformed configuration, adds coverage for default/authorized/rejected modes, and documents the operational and CI safeguards. Sequence diagram for runner-side triage mutation authorizationsequenceDiagram
participant Runner
participant PreScript as pre_triage_security.py
participant Collector as collect_bundle
participant Bundle as Authorization bundle
participant Executor
Runner->>PreScript: collect
PreScript->>PreScript: os.environ.get(FULLSEND_TRIAGE_MUTATION_AUTHORIZED)
PreScript->>PreScript: parse_mutation_authorization(value)
alt exact true
PreScript->>Collector: collect_bundle(..., mutation_authorized=True)
Collector->>Bundle: mutation_authorized=True
Bundle-->>Executor: authorized bundle
Executor->>Executor: accept mutation-authorized result
else unset or exact false
PreScript->>Collector: collect_bundle(..., mutation_authorized=False)
Collector->>Bundle: mutation_authorized=False
Bundle-->>Executor: report-only bundle
else malformed value
PreScript-->>Runner: ERROR on stderr, exit 1
PreScript-->>Runner: no bundle written
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="plugins/sdlc-workflow/scripts/pre_triage_security.py" line_range="743" />
<code_context>
-def collect_bundle(issue_key, project_root, release_decisions=None):
- """Collect all credentialed evidence for one poller-dispatched security issue."""
+def collect_bundle(issue_key, project_root, release_decisions=None, mutation_authorized=False):
+ """Collect all credentialed evidence for one poller-dispatched security issue.
+
</code_context>
<issue_to_address>
**String input grants mutation authorization**
When a Python caller passes a string or another truthy non-boolean value to `collect_bundle`, `collect_bundle` forwards the value to `build_bundle`, which applies `bool(mutation_authorized)`. A caller passing the non-empty string `"false"` therefore produces an authorized bundle, and the executor accepts mutation plans from it.
Require `mutation_authorized` to be an actual `bool` at the collector or bundle-building boundary instead of coercing arbitrary values.
</issue_to_address>Sourcery assessment
Needs a human reviewer. 1 finding to address first, and if the runner opts in when it should not, the bundle is marked authorized and the executor can perform Jira mutations; those changes may remain after this code is reverted. The default stays report-only, so the risk depends on the trusted runner setting the opt-in.
Blocking findings: plugins/sdlc-workflow/scripts/pre_triage_security.py:743
|
|
||
| def collect_bundle(issue_key, project_root, release_decisions=None): | ||
| """Collect all credentialed evidence for one poller-dispatched security issue.""" | ||
| def collect_bundle(issue_key, project_root, release_decisions=None, mutation_authorized=False): |
There was a problem hiding this comment.
🟡 Medium · String input grants mutation authorization
When a Python caller passes a string or another truthy non-boolean value to collect_bundle, collect_bundle forwards the value to build_bundle, which applies bool(mutation_authorized). A caller passing the non-empty string "false" therefore produces an authorized bundle, and the executor accepts mutation plans from it.
Require mutation_authorized to be an actual bool at the collector or bundle-building boundary instead of coercing arbitrary values.
Prompt for AI agents
In `plugins/sdlc-workflow/scripts/pre_triage_security.py` at line 743:
**String input grants mutation authorization**
When a Python caller passes a string or another truthy non-boolean value to `collect_bundle`, `collect_bundle` forwards the value to `build_bundle`, which applies `bool(mutation_authorized)`. A caller passing the non-empty string `"false"` therefore produces an authorized bundle, and the executor accepts mutation plans from it.
Require `mutation_authorized` to be an actual `bool` at the collector or bundle-building boundary instead of coercing arbitrary values.Re-pin the triage-security child base to the commit carrying the mutation-authorization opt-in and re-lock triage-security only; the verify-pr harness and lock entry are unchanged. Implements TC-6934 Assisted-by: Claude Code Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Superseded by #356 (same commits plus the triage-security re-pin, opened from an upstream branch so fullsend lock can fetch the pinned commit). |
Summary
pre_triage_security.py collectnow reads the runner-only opt-inFULLSEND_TRIAGE_MUTATION_AUTHORIZEDand passes it tocollect_bundle→build_bundle→authorization.mutation_authorized, replacing the hardcodedFalse.true→true; unset orfalse→false(unchanged report-only default); any other value →ERROR:on stderr, exit 1, no bundle written (fail closed).FULLSEND_RELEASE_DECISIONS); it is not added to the harnessenv.sandboxand never reaches the sandbox.execute_planalready acceptsmutation-authorizedresults only when the bundle is authorized (covered by the existingtest_authorized_actions_execute_in_order_with_footnoted_comments/test_unauthorized_mutating_plan_fails_without_jira_calls).fullsend.md"Triage-security release orchestration" documents the opt-in and that enabling it in CI is gated on TC-6191.Tests
test_mutation_authorization_opt_in_reaches_collector(unset/false/true),test_invalid_mutation_authorization_fails_closed(7 malformed values),test_authorized_bundle_satisfies_input_contract.python3 -m pytest plugins/sdlc-workflow/scripts/ -q→ 740 passed, 3 skipped;uvx skillsaw0 errors;claude plugin validate plugins/sdlc-workflowpassed.Implements TC-6934
🤖 Generated with Claude Code
Summary by Sourcery
Enable explicit, fail-closed runner authorization for triage-security mutations while preserving report-only behavior by default.
New Features:
Bug Fixes:
Enhancements:
Chores: