Add a weak, directional Answered by field to the ADR process #123
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/adr-answered-by-field"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Task 131. ADR-0107 supersedes ADR-0001 wholesale (the first full, non-partial supersession in the project) rather than editing it — a record defining which edits are permitted can't exempt itself from its own rule. Restates every rule ADR-0001 stated, unchanged, and adds
Answered by: written only on a record that explicitly deferred a named question, pointing at whatever later record answered it; never changes the deferring record's ownStatus; needs no reciprocal field on the answering record.Applied retroactively in the same change: ADR-0003 and ADR-0011 both gain
Answered by: ADR-0019(metadata-only edits, no prose touched) — this is what actually retires the cost ADR-0019's own Consequences named and left open.template.mdgains the field.AdrIndex/AdrIndexTestsgain a matching check — everyAnswered byfield must name an ADR that actually exists (mutation-tested: a bogus number reddens the check, naming the file and the number). No bidirectional check, deliberately — the field is one-directional by design.docs/adr/README.md's generated index table and its hand-written "Open questions" section are both updated; the Status column is unaffected byAnswered by, the same way it's never shownSupersedes— the field is orthogonal to whether a record is still in force.Noted in ADR-0107's own Consequences, not fixed here: a second, independently-discovered instance of the identical gap exists between ADR-0002 and ADR-0032 (ADR-0032 says so itself). Out of this ticket's scope, which names ADR-0003/ADR-0011 specifically; left for a follow-up.
Fixed since first review (
changes needed): the wholesale restatement had silently dropped two of ADR-0001's own clauses — the sentence stating the rule binds from the moment a record merges ontomain, and the one valuing a wrong decision's record over its absence. Found by diffing the two documents clause for clause, not by any mechanical check; both restored verbatim. Also recorded, in the Alternatives considered section: on reflection, a partial supersession touching only the permitted-edits clause would have carried the same answer to "don't let a record exempt itself from its own rule" with far less transcription risk than restating the whole record — that alternative was never separately weighed the first time, and future single-clause amendments should default to it, reserving full restatement for records where most of the content has genuinely changed. Mergedmain(#120, #122 and others); the generated index was regenerated, not hand-merged.Architecture-test suite (119 tests),
dotnet format --verify-no-changesclean on the pinned SDK.Verdict: changes needed
ADR-0107's restatement of ADR-0001's Decision section drops two clauses. Diffed the pre-PR ADR-0001 against ADR-0107's "Every rule ADR-0001 stated stands, restated here in full" section line by line. Missing, not reworded anywhere else in the document:
main. ADRs 0001 to 0011 were edited and one was renamed while this structure was still under review, which is exactly what the rule forbids afterwards." — this is substantive, not decoration: it's the only place the original states when immutability starts. Without it, ADR-0107's "An accepted ADR's body is immutable. Once a record is accepted, the only permitted edits are..." reads as binding from the momentStatus: Acceptedis typed, even in an open, unmerged PR — which was never the rule.This is exactly the risk you named going in — a wholesale restatement is where a clause quietly goes missing, and nothing mechanical catches it. Add both before merge.
Everything else checks out:
Answered byfield in the header block; no other line touched.AdrIndexTestsgenuinely passes — ran it myself rather than trusting the PR description, 12/12 green. Mutation-testedAnsweredByGapsbeyond the placeholder-only case already in the suite: pointed ADR-0003's own field at a well-formed but nonexistentADR-9999and confirmed it reddens, naming the file and the bogus number; restored.Superseded by 0107for ADR-0001 verbatim, and the hand-written prose correctly describes both records now carrying the field.Minor:
mergeableis currentlyfalseagainstmain's current tip (main has moved since this PR's base) — mechanical, needs a rebase before merge, not a content problem.Verdict: mergeable
CI green (#548, success, 9m55s — mostly queueing behind other PRs on one runner) on
55f4867, head unchanged from the SHA given.Independently diffed the two Decision sections, programmatically rather than by eye — extracted both, joined wrapped lines into paragraphs, and checked each of ADR-0001's 10 original paragraphs for a verbatim match in ADR-0107's restatement. Result: 8 of 10 match exactly, including both previously-missing clauses ("binds from the moment a record is merged onto
main" and "a record of a wrong decision is more useful than its absence") — now present word-for-word. The two non-verbatim matches are both expected and correct: the numbering sentence gained "once merged" (consistent with, not contradicting, the restored standalone sentence), and the permitted-edits field list was extended to includeAnswered by(the entire point of the record). Nothing else is missing. I did not accept the PR body's own claim of completeness — this is my own diff.Placement is coherent, not just present: both restored clauses sit in the same relative position as the original (immutable-body clause → binds-from-merge → wrong-decision-value → supersession-may-be-partial), with the new
Answered bysection appended after, in a sensible spot rather than interleaved or buried in Alternatives/Consequences.The new Alternatives entry, judged on its own merits, not just accepted: I agree with it. Partial supersession is a materially different, lower-risk mechanism here, not just a smaller version of the same risk — it would have required retyping nothing (point at ADR-0001's own frozen text for everything but the one changed clause), where wholesale restatement required retyping nine paragraphs to change one. The entry is honest about the process failure (states plainly the alternative wasn't weighed the first time, and that the omission was found by manual diff, not any mechanical check) without overclaiming — it doesn't argue ADR-0107 must be restructured now, and gives a defensible reason not to (redoing a reviewed record's own shape is itself a risk). The forward-looking default it sets — partial supersession for a single-clause change, full restatement only where most content has genuinely changed — is sound, generalisable guidance, not a caveat added to look responsible.
Retroactive ADR-0003/ADR-0011 application, the field's definition, and the metadata-only diffs are unchanged from
cb72866(confirmed by diffing both files against the pre-PR base — still exactly the oneAnswered byline each, nothing else touched) — not re-litigated per your steer.AdrIndexTestsrun genuinely against this worktree: 119/119 pass.dotnet format --verify-no-changesclean. Pinned SDK confirmed (10.0.100).Nothing else to flag.