Skip to content

fix(sdlc): activate inert INV-1..5 trace-checker + unify auto-mint onto the live escape-grant contract#3839

Merged
ryanklee merged 1 commit into
mainfrom
epsilon/reform-inv-trace-checker-activate-20260601
Jun 1, 2026
Merged

fix(sdlc): activate inert INV-1..5 trace-checker + unify auto-mint onto the live escape-grant contract#3839
ryanklee merged 1 commit into
mainfrom
epsilon/reform-inv-trace-checker-activate-20260601

Conversation

@ryanklee
Copy link
Copy Markdown
Collaborator

@ryanklee ryanklee commented Jun 1, 2026

What

Activate the inert SDLC never-stuck INV-1..5 trace-checker and unify its INV-3/4/5 auto-mint onto the live escape-grant.sh contract. Two independent defects, both fixed.

Defect 1 — hapax-sdlc-invariants.service crash-looped 203/EXEC (the keystone ran ZERO times)

ExecStart hardcoded %h/projects/hapax-council — the primary worktree a lane had parked on a feature branch (alpha/screwm-xvfb-safe-smoke) where scripts/hapax-sdlc-invariants + shared/sdlc_invariants.py don't exist. The wrapper then self-redirected back via REPO=${HAPAX_COUNCIL_REPO:-$HOME/projects/hapax-council}.

  • Repoint ExecStart / ExecStartPre / Documentation / ConditionPathExists at the stable deploy worktree %h/.cache/hapax/rebuild/worktree (kept fresh on origin/main by reform-deploy-chain-repair) — the pattern the hapax-audio-health-* units already use. Set HAPAX_COUNCIL_REPO + PATH.
  • Wrapper resolves REPO from its own location (never self-redirects), resolves uv under a minimal systemd PATH, and grows a --verify mode used as ExecStartPre + OnFailure=notify-failure@%n so a misdeploy fails loudly (ntfy) instead of a silent 203/EXEC; ConditionPathExists turns an absent/not-yet-deployed target into a clean skip.

Defect 2 — INV-3/4/5 auto-minted escapes were inert (wrong dir + extension + key)

The auto-mint wrote <slug>-<id>.json to ~/.cache/hapax/escape-grants signed with ~/.config/hapax/coord-capability.key — none of which the live shim reads (it globs <coord>/grants/*.grant verified with <coord>/grant-key). The chaos test masked this by mint+verifying in-process with a shared tmp_path key.

  • shared/sdlc_invariants.py now imports default_grant_dir() / default_grant_key() from shared.coord_event_log (the SSOT coord-grant-mint and the shim use), resolved at call time, and writes <grant_id>.grant. No module-level path snapshot — the snapshot was the bug.

Tests

  • New tests/test_sdlc_invariants_escape_grant_integration.py: drives BOTH the Python minter and the real escape-grant.sh through the canonical resolvers (HAPAX_COORD_DIR-redirected) and asserts the shim's glob + HMAC-verify accepts the auto-minted grant — fails if dir/extension/key diverge. Includes a control (empty dir → shim denies, proving it can fail).
  • Chaos test <slug>-<id>.json assertions updated to the <grant_id>.grant contract.
  • 46 tests pass; ruff + pyright clean.

Audit (AC#5)

hapax-sdlc-invariants.service is now clean. Still hardcoding the primary worktree (other clusters, out of this task's mutation scope — flagged for them): hapax-opus-route-authority-receipt, hapax-reform-complete, policy-decide-promote, policy-decide-shadow-replay.

Activation note

Systemd Active rc=0 across ≥2 cycles + scheduled findings.jsonl land when this merges and deploys via reform-deploy-chain-repair (the deploy chain is currently severed — that sibling task is the keystone). Verified in-session: --verify ok against the deploy worktree, FAIL against the stale primary worktree; full evaluator run exits 0.

Task: reform-inv-trace-checker-activate-20260601 · AuthorityCase: CASE-SDLC-REFORM-001

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced deployment verification mode that checks configuration integrity and reports specific failures.
  • Improvements

    • Strengthened path resolution mechanisms to support flexible deployment locations and override configurations.
    • Standardized escape-grant filename convention to use .grant extension.
    • Enhanced error reporting with explicit messages for misconfigured deployments.

…to the live escape-grant contract

hapax-sdlc-invariants.service (#3820, the reform never-stuck keystone) crash-looped
203/EXEC every ~5min: ExecStart hardcoded %h/projects/hapax-council — the primary
worktree a lane had parked on a feature branch where the script + shared/sdlc_invariants.py
don't exist — and the wrapper then self-redirected back there via
REPO=${HAPAX_COUNCIL_REPO:-$HOME/projects/hapax-council}. And even if it ran, the INV-3/4/5
auto-mint wrote <slug>-<id>.json into ~/.cache/hapax/escape-grants signed with
~/.config/hapax/coord-capability.key — none of which the live escape-grant.sh shim reads
(it globs <coord>/grants/*.grant verified with <coord>/grant-key), so every auto-minted
escape was inert. The chaos test passed only because it mint+verifies in-process with a
shared tmp_path key, masking the production disconnect.

Unit + wrapper (defect 1 — 203/EXEC):
- Repoint ExecStart/ExecStartPre/Documentation/ConditionPathExists at the stable deploy
  worktree %h/.cache/hapax/rebuild/worktree (kept fresh on origin/main by
  reform-deploy-chain-repair) — the pattern the hapax-audio-health-* units already use — and
  set HAPAX_COUNCIL_REPO + PATH so the wrapper never self-redirects into the primary worktree.
- Wrapper resolves REPO from its own location (the deploy worktree), resolves uv under a
  minimal systemd PATH, and grows a --verify mode used as ExecStartPre so a misdeploy fails
  loudly (OnFailure=notify-failure@%n -> ntfy) instead of a silent 203/EXEC; ConditionPathExists
  turns an absent/not-yet-deployed target into a clean skip.

Auto-mint (defect 2 — inert escape):
- shared/sdlc_invariants.py imports default_grant_dir()/default_grant_key() from
  shared.coord_event_log (the SSOT coord-grant-mint and the shim use), resolved at CALL TIME,
  and writes <grant_id>.grant — so an auto-minted escape lands where the shim globs, signed
  with the key the shim verifies. No module-level path snapshot (the snapshot WAS the bug).

Tests:
- New tests/test_sdlc_invariants_escape_grant_integration.py drives BOTH the Python minter and
  the REAL escape-grant.sh shim through the canonical resolvers (HAPAX_COORD_DIR-redirected)
  and asserts the shim's glob + HMAC-verify ACCEPTS the auto-minted grant — failing if dir,
  extension, or key diverge. Includes a control (empty dir -> shim denies, proving it can fail).
- Update the chaos test's <slug>-<id>.json assertions to the <grant_id>.grant contract.

Audit (AC#5): hapax-sdlc-invariants.service is now clean; hapax-opus-route-authority-receipt,
hapax-reform-complete, policy-decide-promote, policy-decide-shadow-replay still hardcode the
primary worktree — flagged for their clusters (out of this task's mutation scope).

Activation (systemd Active rc=0 across >=2 cycles + scheduled findings.jsonl) lands when this
fix deploys via reform-deploy-chain-repair. Verified in-session: --verify ok against the deploy
worktree, FAIL against the stale primary worktree; full evaluator run exits 0; 46 tests pass.

Task: reform-inv-trace-checker-activate-20260601
AuthorityCase: CASE-SDLC-REFORM-001

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 992a63a2-1a29-4968-8a54-089fc4f117ab

📥 Commits

Reviewing files that changed from the base of the PR and between dc984c3 and 80b7d56.

📒 Files selected for processing (5)
  • scripts/hapax-sdlc-invariants
  • shared/sdlc_invariants.py
  • systemd/units/hapax-sdlc-invariants.service
  • tests/test_sdlc_invariants_chaos.py
  • tests/test_sdlc_invariants_escape_grant_integration.py

📝 Walkthrough

Walkthrough

Escape-grant and SDLC invariant verification paths now resolve signing keys and grant directories at runtime instead of import time, aligning Python auto-mint logic and bash shim tooling. The deployment script adds dynamic repo discovery and a pre-flight --verify mode; the systemd service integrates both with skip guards and failure notifications. Integration tests confirm round-trip compatibility.

Changes

Escape Grant Runtime Resolution and Deployment Integration

Layer / File(s) Summary
Dynamic grant/key resolution at call time
shared/sdlc_invariants.py
Replaces module-level path constants with runtime resolution via default_grant_dir() and default_grant_key() helpers from shared.coord_event_log. Function signatures for load_or_create_grant_key, mint_escape_for_violation, and run_evaluator now accept optional parameters (defaulting to None) to trigger canonical path resolution at invocation time rather than module load time. CLI argument defaults similarly shift from explicit paths to None with updated help text.
Script path resolution and --verify mode
scripts/hapax-sdlc-invariants
Script now dynamically computes target repo from HAPAX_COUNCIL_REPO or the script's parent directory, reliably resolves the uv executable under minimal PATH, and adds a --verify control flow that checks for the presence of shared/sdlc_invariants.py and uv executability, exiting with status 1 on verification failure. Final execution passes resolved paths to Python module invocation.
Systemd service deployment configuration
systemd/units/hapax-sdlc-invariants.service
Updates unit to run from rebuild worktree script location, adds ConditionPathExists guard to skip cleanly when script is absent, introduces ExecStartPre=... --verify to fail loudly on misdeployment, configures HAPAX_COUNCIL_REPO and PATH environment overrides, and adds OnFailure notification handler.
Chaos test updates for .grant filename convention
tests/test_sdlc_invariants_chaos.py
Updates assertions to read back minted grants from <grant_id>.grant instead of globbed *-<id>.json patterns. Handwritten grant test paths change from .json to .grant extension.
Integration tests: auto-mint + real shim round-trip
tests/test_sdlc_invariants_escape_grant_integration.py
New test module with coord_env fixture that hermetically isolates coordinate directory, _shim_allows helper that invokes the real hooks/scripts/escape-grant.sh shim, and two round-trip tests verifying auto-minted grants are written in canonical <grant_id>.grant format and accepted by the real shim's signature verification path.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • hapax-systems/hapax-council#3805: Introduces the daemon-independent escape_grant_allows verifier that scans and validates .grant files that this PR now mints and writes.
  • hapax-systems/hapax-council#3820: Updates the same SDLC runtime machinery (scripts/hapax-sdlc-invariants, shared/sdlc_invariants.py grant/key resolution, and corresponding invariants tests) with the new .grant filename persistence convention.
  • hapax-systems/hapax-council#3822: Tightly coupled through shared default_grant_dir() and default_grant_key() resolution in shared/coord_event_log.py that this PR now calls at runtime for consistent path handling.

Poem

🐰 A rabbit hops through grant-time paths,
No hardcoded walls to block,
Runtime resolve, dynamic dance,
Where shim and Python lock in sync,
All in .grant files now—hooray!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.15% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description provides comprehensive context (What/Defect 1/Defect 2/Tests/Audit/Activation) but does not follow the required template structure with Summary, AuthorityCase, and Test plan sections. Restructure the description to match the template: add explicit Summary, AuthorityCase (CASE-SDLC-REFORM-001 / SLICE-XXX), and Test plan sections; clarify CLAUDE.md hygiene checklist status.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: activating the INV-1..5 trace-checker and unifying auto-mint onto the live escape-grant contract, which matches the primary objectives of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch epsilon/reform-inv-trace-checker-activate-20260601

Comment @coderabbitai help to get the list of available commands and usage tips.

@ryanklee ryanklee added this pull request to the merge queue Jun 1, 2026
Merged via the queue into main with commit d46c933 Jun 1, 2026
31 of 32 checks passed
@ryanklee ryanklee deleted the epsilon/reform-inv-trace-checker-activate-20260601 branch June 1, 2026 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant