feat(debug): make --debug emit the probe-level diagnostics SPEC promises - #49
Open
sroberts wants to merge 1 commit into
Open
feat(debug): make --debug emit the probe-level diagnostics SPEC promises#49sroberts wants to merge 1 commit into
sroberts wants to merge 1 commit into
Conversation
SPEC.md §8.2.7 calls --debug "the load-bearing affordance for trust": a user who can see which paths were probed and which patterns ran can file a precise issue against a signal instead of reshaping their repo to guess at a matcher. The DiagEntry type existed, Result.Diag existed and was serialized — and zero signals populated either. --debug printed one summary line per signal and nothing else. That gap has a cost with a name. The report that started #42 was a Go repo scoring 0.67 on both L3 gates while implementing both, with no way to see which probe failed; the fix hint told them to add a lint step to a workflow that had three. One --debug run would have answered it. Adds acmm.Diagnostics: detectors call NewDiagnostics(ctx) and wrap conditions in d.Probe(path, action, hit, detail...), which returns hit unchanged so it reads inline. Recording is a no-op unless --debug marked the context, so the normal scan path allocates nothing — the perf budgets in internal/signals are unmoved. Instruments l3.build-lint-gate and l3.coverage-gate, the two signals that thread was about. Other signals emit only their summary line, and SPEC now says which are instrumented rather than implying all are. Two contract details found while wiring it: - The repo's own integration test caught Diag leaking into assess's stdout JSON, which violates the flag's documented promise that --debug "does not change stdout — gate output stays stable". Probes now go to stderr only for assess. - `inspect --debug` was `_ = debug`, a flag that parsed and did nothing while advertising "Include detection diagnostics in output". It now does, on stdout, where there is no gate output to keep stable. A test asserts verdicts are byte-identical with and without diagnostics across five fixtures. Probe wraps the conditions detectors branch on, so a mistake there would change behaviour under --debug only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XtNwLDzRYmPrXcYeQypTf9
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.
The gap
SPEC §8.2.7 calls
--debug"the load-bearing affordance for trust": a user who can see which paths were probed and which patterns ran can file a precise issue against a signal instead of reshaping their repo to guess at a matcher.DiagEntryexisted.Result.Diagexisted and was serialized. Zero signals populated either.--debugprinted one summary line per signal and nothing else.That gap has a cost with a name. The report behind #42 was a Go repo scoring 0.67 on both L3 gates while implementing both, with no way to see which probe failed — and a fix hint telling them to add a lint step to a workflow that had three. One
--debugrun would have answered it. Now it does:Design
acmm.Diagnostics. Detectors callNewDiagnostics(ctx)and wrap conditions ind.Probe(path, action, hit, detail...), which returnshitunchanged so it reads inline:Recording is a no-op unless
--debugmarked the context, so the normal scan path allocates nothing. The perf budgets ininternal/signalsare unmoved.Scope, stated rather than implied
Instrumented:
l3.build-lint-gate,l3.coverage-gate— the two signals this thread was about. Everything else emits only its summary line. SPEC now says exactly that, rather than describing a universal trace that doesn't exist. An uninstrumented signal is visibly uninstrumented rather than silently so, and adding probes is a local change that can't alter a verdict.Two contract bugs found while wiring it
The repo's own integration test caught the first one.
Diagleaked intoassess's stdout JSON, violating the flag's documented promise that--debug"does not change stdout — gate output stays stable." A CI gate adding--debugto a failing run would have seen its JSON move. Probes now go to stderr only forassess.Second:
inspect --debugwas_ = debug— a flag that parsed, did nothing, and advertised "Include detection diagnostics in output." It works now, printing on stdout, where there's no gate output to keep stable:Tests
pkg/acmm: disabled-by-default, records-when-enabled, nil-safe.internal/signals/l3: verdicts byte-identical with and without diagnostics across five fixtures, and probes recorded only under--debug.Probewraps the conditions detectors branch on, so a mistake there would change behaviour under--debugonly — the worst kind to find later.Full suite,
go vet,gofmt, perf budgets clean.🤖 Generated with Claude Code
https://claude.ai/code/session_01XtNwLDzRYmPrXcYeQypTf9