Promote trigger to a subcommand + add trust-root-touched verify check (M1)#139
Merged
Merged
Conversation
… (M1) Productizes the existing trigger evaluator and ships the cheap half of the reward-hacking guard. - Promote triggers.py to a first-class `agents-shipgate trigger` subcommand with --changed-files/--diff file inputs and --base/--head git mode (the only path that shells out to git). evaluate() now emits should_run, force_run, skip_reason, changed_files, and diff_tokens alongside the preserved back-compat fields; action precedence is unchanged. - Add SHIP-VERIFY-TRUST-ROOT-TOUCHED, a changed-files-only path classifier in a new `verify` check category. It fires only when a VerificationContext is present (scan --changed-files) and emits an ordinary medium-severity Finding routed through release_decision — never a second verdict. - Add a reverse triggers.json <-> AGENTS.md parity test; closing the gap it found required a new TRIGGER-N8N-WORKFLOW-CHANGED rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses two PR review findings. - High: a PR could edit shipgate.yaml to add `checks.ignore` (or a below-default severity_override) for SHIP-VERIFY-TRUST-ROOT-TOUCHED and silence the very check that flags the edit. apply_suppressions now skips UNSUPPRESSIBLE_FINDING_CATEGORIES (the `verify` trust-spine category), mirroring how baseline-integrity findings stay immune; and the check declares floor_severity: medium so a severity_override below the review tier is a hard ConfigError (exit 2) rather than a silent downgrade. - Medium: `scan --changed-files` is documented single-config-only but was fanned across every manifest in a multi-config workspace. It now rejects with a ConfigError (exit 2) when more than one manifest resolves; the dead verification_context threading through _run_multi_scan is removed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Addresses a PR review finding (P2). The public `agents-shipgate trigger` command read its --changed-files / --diff input files without catching errors, so a missing or undecodable path crashed with a Typer traceback (exit 1). It now catches OSError / UnicodeDecodeError, prints a concise message to stderr, and exits 2 — matching the --base/--head git-failure path and `scan --changed-files` behavior. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
agents-shipgate triggersubcommand. It takes--changed-files/--difffile inputs and--base/--headgit mode (the only path that shells out to git), keeps--list-rules --json, and preservespython -m agents_shipgate.triggersfor developers.evaluate()now emits the M1 output shape (should_run,force_run,skip_reason,changed_files,diff_tokens) alongside the preserved back-compat fields (run_shipgate,stop_conditions_fired,rationale); action precedence is unchanged.SHIP-VERIFY-TRUST-ROOT-TOUCHED— the cheap half of the reward-hacking guard. A changed-files-only path classifier in a newverifycheck category that fires only when aVerificationContextis present (scan --changed-files) and emits an ordinarymedium-severityFindingrouted throughrelease_decisiontoreview_required— never a second verdict. Plainscanbehavior is unchanged.docs/triggers.json↔ AGENTS.md parity test. Closing the gap it surfaced required a newTRIGGER-N8N-WORKFLOW-CHANGEDrule (keyed on the adapter's ownn8n-nodes-*markers), so the prose table and catalog are now in true parity.Why
This is milestone M1 of the AI coding workflow verifier direction (roadmap P0): productize the trigger evaluator and land trust-root protection. Reward hacking is the coding-agent threat model — an optimizer told to "make CI green" may edit the gate instead of fixing the readiness issue — so touching a release trust root (manifest, policies, prompts, the Shipgate CI gate, agent instructions, tool-surface declarations) now requires human review. The
verifycommand's base/head orchestration is the separate P1 milestone;scan --changed-filesis the M1 injection point that makes the check reachable through the existing gate.Type
Verification
CI is authoritative for
python -m ruff check .,python -m compileall -q src tests, andpython -m pytest.Additional local checks run:
python -m ruff check .— clean.python -m pytest— 2104 passed, 5 skipped. The 7tests/test_bootstrap.pyfailures are pre-existing and environmental (confirmed identical onmain): this sandbox's editable install points at a sibling worktree without__main__.py, so bootstrap'spython -m agents_shipgatesubprocess can't resolve. They are unrelated to this change.python scripts/generate_schemas.py --check—docs/checks.json(and manifest/report/packet schemas) in sync.triggermodes (file inputs and--base/--headgit) andscan --changed-filesend-to-end (trust-root finding flows toreview_required).Release-readiness notes
trigger --base/--head; the trust-boundary allowlist intests/test_adapter_static_only.pyandSTABILITY.md§ Meta-CLI surfaces are updated to pin the new call sites)docs/checks.md(SHIP-VERIFY-TRUST-ROOT-TOUCHED)STABILITY.md(newverifycategory indocs/checks.json; newtriggercommand +scan --changed-filesflag added to the stable command surface)🤖 Generated with Claude Code