Development record
a-resolved-issue-points-at-what-fixed-it-abcd-capture-resolv
Summary
Delivers the --intent / --spec / --commit provenance flags on
abcd capture resolve, writing the structured resolved_by object the schema
already parses. Closes the resolved_by half of iss-245. Provenance is
optional: a flagless resolve stays byte-identical to today.
Scope
internal/core/capture/workflow.go—ResolveRequestgainsByIntent, BySpec, ByCommit string;Resolve(workflow.go, currently writing onlyresolution+impact) validates and threads the object into the existingtransitionwrite.internal/core/capture/serialize.go— a deterministic nested-map writer (setMapField) besidesetScalarField:resolved_byis an object, and the currentkvextras write scalars only. Fixed member orderintent, spec, commit; omitted members are omitted, never empty strings.internal/core/capture/promote.go/ a small shared helper — the record-id existence probe (see Approach); place it wherever spc-24's implementation put its link-mode check so both verbs share one probe.internal/surface/cli/cli.go— three flags on theresolvesub-command innewCaptureCommand; JSON result carries the writtenresolved_by.- Docs sweep:
commands/capture.md(resolve section +argument-hint),.abcd/work/issues/README.md(theresolved_byfield is now written by the verb),CHANGELOG.md(additive entry).
Out of scope: backfilling already-resolved issues (ruled out at the grill —
resolve still transitions open issues only); any change to wontfix; any
change to promoted_to (historical) (itd-119/spc-24).
Approach
Validation, before any write.
--intent: must match^itd-[0-9]+$and exist in the intent store — a filename probe over.abcd/development/intents/{drafts,planned,shipped, disciplines,superseded}/for<id>.mdor<id>-*.md, the same match rulefindIssueuses (exact id or id-prefixed slug, extension.md).--spec:^spc-[0-9]+$and the same probe over.abcd/development/specs/{open,closed}/.--commit: shape only,^[0-9a-f]{7,64}$— no git invocation; a sha's home may be the remote and shallow/rebased states must not refuse a legitimate resolution.
Any failure refuses the whole transition with a diagnostic naming the failing
flag; nothing is written and the issue stays in open/.
Write. Extend transition's extras so Resolve passes the validated
object; setMapField renders
resolved_by:
intent: "itd-119"
spec: "spc-24"
with only the supplied members, quoted like the ledger's other scalars, in the
one atomic checksum-guarded write transition already performs under
withLedgerLock. No flags → no resolved_by key (assert byte-identical
output to the pre-change writer in a regression test). The read side
(validate.go's resolved_by object check and the ResolvedBy parse) is
already correct and unchanged — round-trip tests prove write→read fidelity.
CLI. capture resolve <iss-N> "<note>" --impact <…> [--intent itd-N] [--spec spc-N] [--commit sha] --json. The human rendering names what was
stamped; JSON adds a resolved_by object mirroring the frontmatter. Fault
conventions mirror the existing resolve errors (non-zero exit, diagnostic,
nothing written).
Acceptance-criteria mapping
- Provenance written in the same atomic transition — the
transitionextension; test: resolve with all three flags, assert frontmatter object, member order, and single-write atomicity (file appears inresolved/with the object; no intermediate state). - Existence for ids, shape for sha; refusal writes nothing — the validation
block; tests: unknown
itd-N/spc-N, malformed sha, each asserting the issue remains inopen/byte-identical. - Flagless resolve unchanged — regression test asserting byte-identical output against the current writer.
--jsoncontract — surface test asserting theresolved_bymembers in the result.wontfixuntouched — no code path change; existing tests stand guard.- Docs sweep — file list in Scope;
docs-lint/record-lintstay clean.
Every new behaviour lands with a test watched fail before the change.
Frontmatter
| id | spc-25 |
|---|---|
| type | spec |
| lifecycle | closed |
.abcd/development/specs/closed/spc-25-a-resolved-issue-points-at-what-fixed-it.md
open on GitHub ↗ · commit history ↗
References1
- itd-120A Resolved Issue Points At What Fixed Itimplements
mentions4
- iss-245The capture store's schema models resolution provenance it has no verb to write. ResolvedBy{Intent,Spec,Commit} (capture.go:72) is parsed on read (validate.go:275) but Resolve (workflow.go:162) writes only resolution and impact and exposes no flag to supply it, so a resolved issue can assert it was fixed in prose but cannot point at the intent, spec or commit that fixed it. PromotedTo (capture.go:92) is validated against ^itd-[0-9]+$ (validate.go:121) and documented in the issues README as 'the itd-N this issue graduated into', yet no verb writes it and no issue in the ledger carries it — so the capture-to-intent promotion the schema anticipates is unreachable, which is why the 'Which ledger?' note in commands/intent.md forces the intent-vs-issue call at the moment of lowest information with no way to revise it. Contrast the intent side, where the fidelity review binds its verdict to a sha256 receipt over the acceptance criteria: one record store, two very different evidence standards.
- iss-356round-2 fixed nitpick batch: guard check help omits the disclosed backtick limit; urlguard misses CGNAT 100.64/10 and other RFC 6890 ranges; readHookInput misreports an over-cap payload as malformed (iss-201's class at the shared helper); repolint privacy-hygiene silently skips textual files over the 4 MiB cap; capture reCommitSha refuses 64-hex commits; launch Short hides that --dry-run is required; release.yml verify-tag comment overstates what gh verifies; release.yml header says dispatch runs only the rehearsal job; dependabot covers no pip ecosystem for docs; brief pointer lines enumerate five of nine internals chapters; phase-6 and 06-lint carry change-narration blocks; 05-internals cites a ledger entry that does not exist; 03-evidence names the retired activity record nitpick documentation
- itd-119An Issue Graduates Into An Intent Without Retyping
- spc-24an-issue-graduates-into-an-intent-without-retyping-abcd-capt