feat: artifact update & audit — advisory revise + staleness/audit layer - #44
Merged
Conversation
Add an additive, advisory layer for changing a pre-Build artifact after the fact and auditing the trail. Connects "when each artifact changed" (SHA-256) with "what depends on what" (declared traceability) so staleness falls out. - artifact_model.py: change-ledger entry shape + staleness disposition state machine (OPEN -> REFRESHED|ACKNOWLEDGED|NOT_AFFECTED) with honest counting; REFRESHED is derived-only, never a recordable word. - artifact_lineage.py: upstream->downstream edge harvest (declared + labeled coarse phase-order fallback), cycle-safe; id-ownership restricted to .sdlc/artifacts/ so a stem-collision can't reverse an edge. - audit_artifacts.py: record / impact / report engine, exit 0 always; own JSONL ledger (never gate_results), tz-safe --since, corrupt-ledger and unreadable-file safe. - /sdlc-revise + /sdlc-audit-artifacts commands; references/artifact-lifecycle.md. - Wiring: /sdlc-status stale rollup, /sdlc-next advisory record --scan. - Counts 21 -> 23 in CLAUDE.md / README.md / docs/commands.md. Protected core byte-for-byte unchanged; /sdlc-audit output identical with or without the ledger. 512 tests pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The advisory surface promises exit 0 always, and broke that promise on the happy path. `_format_freshness` printed two glyphs a default Windows console (cp1252) cannot encode: the arrow on every stale line and the check on every signed-off phase. Printing either raises UnicodeEncodeError and kills the process with exit 1 — so `/sdlc-audit-artifacts` worked right up until it had something to report, then crashed instead of reporting it. Both glyphs now degrade to ASCII when, and only when, the console can't encode them; a UTF-8 terminal is byte-for-byte unchanged. Resolved per call rather than at import because stdout gets replaced after load. The suite could not have caught this: capsys buffers as UTF-8 and CI is Linux, so both instruments are blind to it by construction. The three new tests bind stdout to a real cp1252 stream — the first in the suite that reproduces what a Windows user actually sees — and one pins the UTF-8 rendering so the fallback can't silently become the default. Verified against the reproduction: both crashing commands now exit 0 and render. 514 passed, 1 skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
MCKRUZ
added a commit
that referenced
this pull request
Aug 6, 2026
#44 added /sdlc-revise and /sdlc-audit-artifacts to the Additional Commands table but left the sentence above it reading "Ten commands" — the count the consistency check calls authoritative, and the one a reader trusts. Invisible to the PR: its branch predates the check that asserts this, so the branch was green and only the merge result is red. CI tests the merge, which is exactly the gap the Actions outage left open. 658 passed, 7 skipped. Co-Authored-By: Claude Opus 5 (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.
What
An additive, advisory layer for changing a pre-Build artifact after the fact and auditing the trail. It connects two facts the tool already has — when each artifact changed (SHA-256) and what depends on what (declared traceability) — so staleness falls out for free.
Pieces
scripts/artifact_model.pyOPEN → REFRESHED | ACKNOWLEDGED | NOT_AFFECTED) with honest counting.REFRESHEDis derived-only, never a typed word.scripts/artifact_lineage.pyupstream → downstreamedges (declared + labeled coarse phase-order fallback), cycle-safe.scripts/audit_artifacts.pyrecord/impact/reportengine — exit 0 always; its own JSONL ledger, never insidegate_results.commands/sdlc-revise.mdDL-NN) → re-gate → show downstream staleness.commands/sdlc-audit-artifacts.md/sdlc-audit: freshness dashboard,--impact,--history.references/artifact-lifecycle.mdWiring (additive touches):
/sdlc-statusstale rollup,/sdlc-nextadvisoryrecord --scan, command counts 21 → 23 inCLAUDE.md/README.md/docs/commands.md.Guarantees
check_spec.py,check_gates.py,phase_model.py,advance_phase.py,section-evaluator,harness/**,phase-registry.yaml,/sdlc-coach,/sdlc-spec)./sdlc-auditoutput is byte-identical with or without it.Verification
--repoand--statemodes.REFRESHEDclearing debt; now rejected).🤖 Generated with Claude Code