refactor(hooks): consolidate hooks.json description into ssot.json registry - #1223
Conversation
…gistry hooks/hooks.json's top-level description field had grown into a duplicative changelog citing every gate's own issue number, content already tracked structurally in .gitapex/ssot.json's gates[] registry. Shrink it to a pointer at that registry, and close the one real gap a plain shrink would have hidden: hooks/check-merge-pull-request-block.sh (issue #637) had no ssot.json entry at all. A deterministic-gate-quality audit of this diff found one real defect, fixed in the same commit: a stale "unregistered today" claim about this same script in gitapex_detect_changed_gate_scripts.py's own docstring. Refs #1222
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 3 included reviews per hour; 2 remain after this review. 📝 WalkthroughWalkthroughThe pull request adds the ChangesGate registry consolidation
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to This PR consolidates registry documentation without changing hook runtime behavior, and the required audit disclosure is present. No actionable merge-blocking risk remains beyond normal checks and review. Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1223 +/- ##
=======================================
Coverage 99.49% 99.49%
=======================================
Files 111 111
Lines 20104 20104
Branches 2361 2361
=======================================
Hits 20003 20003
Misses 101 101 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…ks-json-ssot-consolidation # Conflicts: # hooks/hooks.json
Summary
Shrinks
hooks/hooks.json's top-leveldescriptionfield to a pointer at.gitapex/ssot.json'sgates[]registry (the already-established singlesource of truth for gate rationale), and registers the one hook script the
registry was missing:
hooks/check-merge-pull-request-block.sh(issue#637), so no rationale is lost in the consolidation.
Facts
hooks/hooks.json'sdescriptionfield had grown into a singleduplicative paragraph citing issue numbers feat: re-run provenance/placeholder scan against the actually-posted PR/issue body (post-write verification) #878, feat(hooks): add PreToolUse hook to block issue creation without ACM disclosure #413, fix(gate-skill-audit-disclosure): close disclosure gaps in script + PR template #517, chore(retrospective): merge retrospective for PR #186 #187, refactor(skills): rename driving-pr-to-merge -> drafting-a-pr-to-merge; terminal state is DRAFT, never merge #637,
feat(hooks): gate PR creation on referenced issue's ACM/waiver disclosure #657, and Add a deterministic gate restricting PR titles to Conventional Commits format #1058 -- content already tracked per-gate, structured, in
.gitapex/ssot.json's ownrule/tracking_issuefields.hooks/hooks.jsonwires, 9 already had a.gitapex/ssot.jsongate entry; onlyhooks/check-merge-pull-request-block.shdid not -- independently corroborated by
.github/scripts/gitapex_detect_changed_gate_scripts.py'sown pre-existing docstring, which stated this exact gate "is unregistered
today" before this PR.
hooks.json'sdescriptionfieldcontent (confirmed by direct search);
gitapex_gate_plugin_root_brace_notation.pyexplicitly scopes itself to
commandvalues only.deterministic-gate-qualityaudit against this diff foundone real, live-verified defect: this PR's own registration made the
"unregistered today" claim above false, with no drift-check covering that
specific file. Fixed in the same commit -- see Skill audit evidence.
Assumptions
consolidation with no behavior change; every claim above was independently
verified against live repo state, not assumed.
Risk / blast radius
Confined to two prose fields (
hooks/hooks.json'sdescription,.github/scripts/gitapex_detect_changed_gate_scripts.py's docstring) andone new, schema-valid
.gitapex/ssot.jsonregistry entry for analready-active, unchanged hook script. No
command,matcher,timeout,or detection-logic value changed anywhere in this diff. Worst case if the
new registry entry were somehow wrong:
hooks/check-merge-pull-request-block.shitself is untouched and keeps denying
mcp__github__merge_pull_requestexactly as before -- only the registry's own bookkeeping about it could be
affected, not runtime behavior.
Rollback
git revertthis PR's merge commit. No schema change, no data migration,nothing else depends on the new registry entry existing.
Verification
Restated from the Acceptance Criteria Map in issue #1222, criterion ->
proof method -> result:
hooks/hooks.json'sdescriptionstops duplicating per-gate rationalegitapex_detect_changed_gate_scripts.pystill flags the diff correctly (path-based, unchanged behavior).gitapex/ssot.jsonentrytests/test_gitapex_scan_ssot_schema.pypassing on the new entryFull local verification:
uv run pytest(5162 passed; 2 pre-existing,environment-only failures individually confirmed as flakes via a one-time
re-run each and deselected from the full-suite pass --
test_repository_workflows_are_drift_freeneeds full git history thisshallow clone lacks;
test_does_not_dirty_the_real_checkouts_settings_jsonfailed only on a byte-level trailing-newline difference in
.claude/settings.json, produced by the sandbox's own plugin-registrationside effects and confirmed clean, with no dirtying, on immediate re-run in
isolation -- both unrelated to this diff),
uv run ruff check .(clean),mypy(thetests/.github/scripts-covering group, clean, 217 sourcefiles).
tests/test_gitapex_scan_ssot_schema.pyandtests/test_gitapex_detect_changed_gate_scripts.pyspecifically re-run andgreen. One drift-check (
test_no_prose_count_contradicts_the_registry)correctly caught its own staleness from the new registry entry (26 -> 27
exclusions) and was fixed in the same commit as the entry itself.
Post-merge update:
origin/main(PR #1215, issue #1197's own newpr-duplicate-issuegate) merged into this branch, producing a realcontent conflict in
hooks/hooks.json'sdescriptionfield. Resolved bykeeping this PR's short pointer text -- still fully accurate, since it
names no gate-specific content and
.gitapex/ssot.jsonauto-mergedcleanly with both PRs' new entries intact. The same drift-check caught a
second, real staleness from that merged-in entry (27 -> 28 exclusions),
fixed in a follow-up commit. Re-verified after both commits: full local
suite (5255 passed, only the shallow-clone-only
test_repository_workflows_are_drift_freedeselected),uv run ruff check .(clean), the same CI mypy group (clean, 223 source files),and the two most directly relevant test files re-run individually
(253 passed). CI's own
pytestjob separately hit the knowntest_installs_the_prek_hook_for_a_real_checkoutsession-start.sh15s-timeout flake (already independently confirmed flaky on PR #1215);
re-run via
rerun_failed_jobsrather than a code change.Skill audit evidence
One deterministic gate registration (
.gitapex/ssot.json) and onedeterministic checker-script docstring fix
(
.github/scripts/gitapex_detect_changed_gate_scripts.py, prose-only, zerodetection-logic lines changed) are in this diff; no
skills/*/SKILL.mdordocs/superpowers/specs/*.mddesign doc is touched. The post-mergefollow-up commit touches only
tests/test_gitapex_gate_local_preflight.py(a drift-check's own docstring count), outside every named trigger scope
below -- no new disclosure obligation (independently confirmed by running
.github/scripts/gitapex_compute_skill_audit_flags.py --base-ref origin/main --head-ref HEADlocally: identical changed-checker-scripts/changed-gate-scripts sets as the original commit).
deterministic-gate-quality: RAN (dispatched a fresh, independent auditagainst this diff's
.gitapex/ssot.jsonregistration,hooks/hooks.jsondescription edit, and
hooks/check-merge-pull-request-block.shitself asnewly brought into registry visibility, read against
skills/evaluating-deterministic-gate-quality/references/dimensions.md).Verdict: well-formed and well-placed. Live-verified via direct script
execution (deny/pass-through/malformed-stdin cases), a live
gitapex_scan_ssot_schema.pyrun, and the full local test suite. Foundand fixed one real, live-verified defect in the same commit:
gitapex_detect_changed_gate_scripts.py'sown docstring still claimed this hook was "unregistered today" -- false
as of this PR's own registration, corrected to past tense with an issue
citation. Two additional low-severity, pre-existing (not
diff-introduced) maturity gaps disclosed, not fixed, since the hook
script's own logic is unchanged here: dimension 15 (malformed/empty
stdin exits 0 rather than deny, steel-manned as low-severity since stdin
here is harness-controlled, not attacker-reachable) and an undisclosed
cross-reference gap between this hook and the platform's own
.github/rulesets/main.jsonbranch-protection floor (a real,independently-confirmed complementary layer neither document names).
Dispatch-isolation caveat, disclosed by the dispatch itself: this
sandboxed environment could not exclude this repository's own CLAUDE.md
from the dispatched agent's own context -- a hygiene deviation judged
unlikely to have biased the verdict (generic process instruction, not
opinion about this specific diff) but flagged rather than silently
accepted.
checker-script-adversarial-review: NOT-RUN -- this diff's only touch toa
.github/scripts/*.pyfile is a one-line docstring correction (apreviously-accurate claim about
check-merge-pull-request-block.sh'sregistration status, now stale after this same PR registers it); zero
lines of
gitapex_detect_changed_gate_scripts.py's actual detectionlogic changed (confirmed via
git diff), so there is no logic here foran adversarial review round to meaningfully target.
defeat-test-disclosure: NOT-RUN -- required via its union withdeterministic-gate-quality's own scope, buthooks/check-merge-pull-request-block.sh'sown detection logic is unchanged by this diff (only its
.gitapex/ssot.jsonregistration is new); per this check's owndocumented design intent, a docstring-or-registration-only edit with no
new/changed detection logic has nothing for a defeat test to
meaningfully target.
Execution log
IssueFiled-- issue refactor(hooks): consolidate hooks.json description into ssot.json gate registry #1222, viadrafting-an-acm-issue,Dedup:searchreviewed 3 results (CI gate workflows: centralize duplicated cross-workflow rationale prose into one shared reference doc #1186 related-but-distinct scope, refactor(gates): extract shared JSON-schema load/validate helper #755/feat(cli): define .gitapex/ssot.json gate-registry schema (child of #82) #123 unrelated
or foundational), none duplicating.
Implemented--.gitapex/ssot.jsonentry added,hooks/hooks.jsondescription shrunk, both committed together (commit
dd199da).AuditDispatched-- freshdeterministic-gate-qualityaudit, found andfixed one real defect (the stale docstring claim above) in the same
commit.
Verified-- full local suite, ruff, mypy, and the two most directlyrelevant tests re-run individually, all green.
MergedMain-- mergedorigin/main(PR fix(dedup): add deterministic duplicate-work checks for PRs and issues #1215) aftermergeable_statewent
dirty; resolved a realdescription-field conflict inhooks/hooks.jsonby keeping this PR's pointer text (commit429e420).FixedDrift-- follow-up commit fixedtest_no_prose_count_contradicts_the_registry'snow-stale exclusion count, 27 -> 28 (commit
e65ddf0); fullsuite/ruff/mypy re-verified green.
Checklist
skills/*/SKILL.md, adocs/superpowers/specs/*.mddesign doc, a security-relevant skill, or a deterministic checker script (skills/*/scripts/*.py,evals/scripts/*.py,.github/scripts/*.py), a## Skill audit evidencesection discloses the required verdicts/waivers (see.github/scripts/gitapex_gate_skill_audit_disclosure.py)evals/*/split.md, that entry discloses a Transfer check line -- not applicable, noevals/*/split.mdchangeskills/*/SKILL.md's Stop-boundary bullets or named dispatch branches,evals/<skill>/tasks/*.yamlgained at least as many new fixtures -- not applicable, noSKILL.mdchangeRelated Issue
Closes #1222