/90-phase-audit
**Goal:** Verify the change from multiple independent angles.
$ npx -y skills add heurema/signum --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/90-phase-audit
Context preview
What this command does when you run it.
**Goal:** Verify the change from multiple independent angles.
Command definition
90-phase-audit.mdPhase 3: AUDIT
**Goal:** Verify the change from multiple independent angles.
Risk-Proportional Ceremony
Read the contract's `riskLevel` and apply the matching ceremony profile. Steps marked "skip" MUST be skipped entirely (no agent launches, no CLI calls).
| Step | Low | Medium | High | |------|-----|--------|------| | 3.0.5 Repo-contract invariants | run | run | run | | 3.1 Mechanic | run | run | run | | 3.1.4 Reuse and duplication audit | conditional | conditional | conditional | | 3.1.5 Holdout validation | skip (0 required) | run (≥2 required) | run (≥5 required) | | 3.2 Prepare review prompts | skip | run | run | | 3.2.5 Launch reviews | Claude only | Claude + available externals | Claude + Codex + Gemini (all 3) | | 3.3–3.3.5 Collect + parse | Claude only | all launched | all launched | | 3.5 Synthesizer | run | run | run |
**Budget targets:** Low <2 min, <$0.20 | Medium 3-5 min | High 5-10 min, full panel.
**Single-model graceful degradation:** If external CLIs are not installed (not failed — genuinely absent), the synthesizer allows AUTO_OK with single Claude review for low and medium risk. High risk always requires multi-model or HUMAN_REVIEW.
Use the Bash tool to read the risk level and save it for conditional checks:
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
CONTRACT_PATH="${ARTIFACT_ROOT}contract.json"
RISK_LEVEL=$(jq -r '.riskLevel' "$CONTRACT_PATH")
echo "RISK_LEVEL=$RISK_LEVEL"Save `RISK_LEVEL` for use in all subsequent steps.
Step 3.0.5: Repo-contract invariant check
If `repo-contract.json` and `repo_contract_baseline.json` under the canonical artifact root both exist, re-run invariants and detect regressions:
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
REPO_CONTRACT_BASELINE_PATH="${ARTIFACT_ROOT}repo_contract_baseline.json"
REPO_CONTRACT_VIOLATIONS_PATH="${ARTIFACT_ROOT}repo_contract_violations.json"
if [ -f "repo-contract.json" ] && [ -f "$REPO_CONTRACT_BASELINE_PATH" ]; then
python3 - "$REPO_CONTRACT_BASELINE_PATH" "$REPO_CONTRACT_VIOLATIONS_PATH" <<'PY'
import json
import subprocess
import sys
baseline_path = sys.argv[1]
violations_path = sys.argv[2]
with open('repo-contract.json') as f:
rc = json.load(f)
with open(baseline_path) as f:
baseline = json.load(f)
regressions = []
results = {}
for inv in rc.get('invariants', []):
iid = inv['id']
r = subprocess.run(inv['verify'], shell=True, capture_output=True, text=True)
now_passed = r.returncode == 0
was_passing = baseline.get(iid, {}).get('passed', True)
regressed = was_passing and not now_passed
results[iid] = {
'description': inv['description'],
'severity': inv['severity'],
'verify': inv['verify'],
'exit_code': r.returncode,
'passed': now_passed,
'was_passing': was_passing,
'regressed': regressed,
}
if regressed:
regressions.append(f'{iid} ({inv["severity"]}): {inv["description"]}')
with open(violations_path, 'w') as f:
json.dump({'invariants': results, 'regressions': regressions}, f, indent=2)
if regressions:
print('INVARIANT REGRESSIONS:')
for reg in regressions:
print(f' - {reg}')
print('AUTO_BLOCK')
else:
total = len(results)
passed = sum(1 for v in results.values() if v['passed'])
print(f'Repo-contract: PASS ({passed}/{total} invariants holding)')
PY
fiIf output contains `AUTO_BLOCK`, **STOP**. Invariant regressions are critical failures regardless of task-level AC results. Do not proceed to Step 3.1.
Step 3.1: Mechanic (bash, zero LLM)
Run full project checks and compare with baseline. Use the Bash tool:
# Resolve mechanic-parser.sh from known trusted Signum install roots only.
# SIGNUM_PLUGIN_DIR env var is intentionally excluded to prevent environment
# hijacking — only fixed install paths are trusted.
# Home directory is resolved from the account database, not $HOME, to prevent
# environment-variable override attacks.
_REAL_HOME=$(getent passwd "$(id -un)" 2>/dev/null | cut -d: -f6 || python3 -c "import pwd,os; print(pwd.getpwuid(os.getuid()).pw_dir)" 2>/dev/null || echo "$HOME")
_SIGNUM_MECHANIC=""
for _d in \
"${_REAL_HOME}/.claude/plugins/signum/platforms/claude-code" \
"${_REAL_HOME}/.local/share/emporium/signum/platforms/claude-code" \
"${_REAL_HOME}/.nex/plugins/signum/platforms/claude-code"; do
[ -f "${_d}/lib/mechanic-parser.sh" ] || continue
_SIGNUM_MECHANIC="${_d}/lib/mechanic-parser.sh"
break
done
if [ -z "$_SIGNUM_MECHANIC" ]; then
echo "ERROR: mechanic-parser.sh not found in Signum plugin directories" >&2
exit 1
fi
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
BASELINE_PATH="${ARTIFACT_ROOT}baseline.json"
bash "$_SIGNUM_MECHANIC" "$BASELINE_PATH"If any check has a NEW regression, continue to reviews — mechanic regression influences the final decision but does not block the audit.
Step 3.1.3: Policy scanner (bash, zero LLM cost)
Run the deterministic policy scanner on `combined.patch` under the canonical artifact root. This step scans addition lines only for security, unsafe, and dependency patterns. Use the Bash tool:
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
COMBINED_PATCH_PATH="${ARTIFACT_ROOT}combined.patch"
# Resolve policy-scanner.sh from known trusted Signum install roots only.
# SIGNUM_PLUGIN_DIR env var is intentionally excluded to prevent environment
# hijacking — only fixed install paths derived from $HOME are trusted.
_SIGNUM_SCANNER=""
for _d in \
"${HOME}/.claude/plugins/signum/platforms/claude-code" \
"${HOME}/.local/share/emporium/signum/platforms/claude-code" \
"${HOME}/.nex/plugins/signum/platforms/claude-code"; do
[ -f "${_d}/lib/policy-scannRead more
Phase 3: AUDIT
**Goal:** Verify the change from multiple independent angles.
Risk-Proportional Ceremony
Read the contract's `riskLevel` and apply the matching ceremony profile. Steps marked "skip" MUST be skipped entirely (no agent launches, no CLI calls).
| Step | Low | Medium | High | |------|-----|--------|------| | 3.0.5 Repo-contract invariants | run | run | run | | 3.1 Mechanic | run | run | run | | 3.1.4 Reuse and duplication audit | conditional | conditional | conditional | | 3.1.5 Holdout validation | skip (0 required) | run (≥2 required) | run (≥5 required) | | 3.2 Prepare review prompts | skip | run | run | | 3.2.5 Launch reviews | Claude only | Claude + available externals | Claude + Codex + Gemini (all 3) | | 3.3–3.3.5 Collect + parse | Claude only | all launched | all launched | | 3.5 Synthesizer | run | run | run |
**Budget targets:** Low <2 min, <$0.20 | Medium 3-5 min | High 5-10 min, full panel.
**Single-model graceful degradation:** If external CLIs are not installed (not failed — genuinely absent), the synthesizer allows AUTO_OK with single Claude review for low and medium risk. High risk always requires multi-model or HUMAN_REVIEW.
Use the Bash tool to read the risk level and save it for conditional checks:
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
CONTRACT_PATH="${ARTIFACT_ROOT}contract.json"
RISK_LEVEL=$(jq -r '.riskLevel' "$CONTRACT_PATH")
echo "RISK_LEVEL=$RISK_LEVEL"Save `RISK_LEVEL` for use in all subsequent steps.
Step 3.0.5: Repo-contract invariant check
If `repo-contract.json` and `repo_contract_baseline.json` under the canonical artifact root both exist, re-run invariants and detect regressions:
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
REPO_CONTRACT_BASELINE_PATH="${ARTIFACT_ROOT}repo_contract_baseline.json"
REPO_CONTRACT_VIOLATIONS_PATH="${ARTIFACT_ROOT}repo_contract_violations.json"
if [ -f "repo-contract.json" ] && [ -f "$REPO_CONTRACT_BASELINE_PATH" ]; then
python3 - "$REPO_CONTRACT_BASELINE_PATH" "$REPO_CONTRACT_VIOLATIONS_PATH" <<'PY'
import json
import subprocess
import sys
baseline_path = sys.argv[1]
violations_path = sys.argv[2]
with open('repo-contract.json') as f:
rc = json.load(f)
with open(baseline_path) as f:
baseline = json.load(f)
regressions = []
results = {}
for inv in rc.get('invariants', []):
iid = inv['id']
r = subprocess.run(inv['verify'], shell=True, capture_output=True, text=True)
now_passed = r.returncode == 0
was_passing = baseline.get(iid, {}).get('passed', True)
regressed = was_passing and not now_passed
results[iid] = {
'description': inv['description'],
'severity': inv['severity'],
'verify': inv['verify'],
'exit_code': r.returncode,
'passed': now_passed,
'was_passing': was_passing,
'regressed': regressed,
}
if regressed:
regressions.append(f'{iid} ({inv["severity"]}): {inv["description"]}')
with open(violations_path, 'w') as f:
json.dump({'invariants': results, 'regressions': regressions}, f, indent=2)
if regressions:
print('INVARIANT REGRESSIONS:')
for reg in regressions:
print(f' - {reg}')
print('AUTO_BLOCK')
else:
total = len(results)
passed = sum(1 for v in results.values() if v['passed'])
print(f'Repo-contract: PASS ({passed}/{total} invariants holding)')
PY
fiIf output contains `AUTO_BLOCK`, **STOP**. Invariant regressions are critical failures regardless of task-level AC results. Do not proceed to Step 3.1.
Step 3.1: Mechanic (bash, zero LLM)
Run full project checks and compare with baseline. Use the Bash tool:
# Resolve mechanic-parser.sh from known trusted Signum install roots only.
# SIGNUM_PLUGIN_DIR env var is intentionally excluded to prevent environment
# hijacking — only fixed install paths are trusted.
# Home directory is resolved from the account database, not $HOME, to prevent
# environment-variable override attacks.
_REAL_HOME=$(getent passwd "$(id -un)" 2>/dev/null | cut -d: -f6 || python3 -c "import pwd,os; print(pwd.getpwuid(os.getuid()).pw_dir)" 2>/dev/null || echo "$HOME")
_SIGNUM_MECHANIC=""
for _d in \
"${_REAL_HOME}/.claude/plugins/signum/platforms/claude-code" \
"${_REAL_HOME}/.local/share/emporium/signum/platforms/claude-code" \
"${_REAL_HOME}/.nex/plugins/signum/platforms/claude-code"; do
[ -f "${_d}/lib/mechanic-parser.sh" ] || continue
_SIGNUM_MECHANIC="${_d}/lib/mechanic-parser.sh"
break
done
if [ -z "$_SIGNUM_MECHANIC" ]; then
echo "ERROR: mechanic-parser.sh not found in Signum plugin directories" >&2
exit 1
fi
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
BASELINE_PATH="${ARTIFACT_ROOT}baseline.json"
bash "$_SIGNUM_MECHANIC" "$BASELINE_PATH"If any check has a NEW regression, continue to reviews — mechanic regression influences the final decision but does not block the audit.
Step 3.1.3: Policy scanner (bash, zero LLM cost)
Run the deterministic policy scanner on `combined.patch` under the canonical artifact root. This step scans addition lines only for security, unsafe, and dependency patterns. Use the Bash tool:
source lib/contract-dir.sh 2>/dev/null || true
ARTIFACT_ROOT="$(active_artifact_root 2>/dev/null || echo .signum/)"
COMBINED_PATCH_PATH="${ARTIFACT_ROOT}combined.patch"
# Resolve policy-scanner.sh from known trusted Signum install roots only.
# SIGNUM_PLUGIN_DIR env var is intentionally excluded to prevent environment
# hijacking — only fixed install paths derived from $HOME are trusted.
_SIGNUM_SCANNER=""
for _d in \
"${HOME}/.claude/plugins/signum/platforms/claude-code" \
"${HOME}/.local/share/emporium/signum/platforms/claude-code" \
"${HOME}/.nex/plugins/signum/platforms/claude-code"; do
[ -f "${_d}/lib/policy-scannSignum is a contract-first proof gate for agentic software changes: it turns a task into a reviewed contract, executes against that contract, audits the result, and packages evidence that humans and CI can inspect.
Other commands on signum.
- /apply
Implement tasks from an OpenSpec change (Experimental)
Open command - /archive
Archive a completed change in the experimental workflow
Open command - /explore
Enter explore mode - think through ideas, investigate problems, clarify requirements
Open command - /propose
Propose a new change - create it and generate all artifacts in one step
Open command - /sync
Sync delta specs from a change to main specs
Open command - /update
Update a change - revise existing planning artifacts and keep them coherent (Experimental)
Open command

