Rationale label migration retrospective
Status: complete
Capture surprises when discovered. This is the second directional-label run and must test whether the evidence migration's procedure generalizes.
Decision gate
- Live source→destination inventory: implementation-time rebaseline found 134 active
rationaleedges and 314 activegroundsedges.rationalepairs remained reference→notes 95, reference→reference 16, agentic-systems→notes 9, agent-memory-systems→notes 5, instructions→notes 5, notes→reference 2, sources→notes 1, and types→notes 1.groundshad 276 note→note edges and the same 38 off-pattern edges; four canonical rows landed after the 310-edge semantic review. - Neighboring-label findings: the rationale corpus splits into 114 rationale dependencies, 2 evidence edges, and 18 navigation/architecture edges. The grounds cohort has 38 off-pattern edges and only two files author both labels.
- Adopted identifier and assertion template: ADR 060 adopts
source rests-on targetfor the 114 rationale-dependency edges and 8 off-pattern grounds edges. The other 50 boundary rows becameevidenced-by(35),is-evidence-for(12),implements(2), orcompares-with(1), with no removals. The 276 note→notegroundsrows remain a distinct deferred cohort.
Baseline and exclusions
- Positive mutable surface: active registered footer edges in non-generated Markdown under notes, reference (excluding proposal archive), instructions, agent-memory-systems, agentic-systems, sources analyses/ingests, and types; both ordinary and bold footer forms were parsed.
- Exclusion buckets and counts at implementation rebaseline: 1,674 generated-report rows, 181 inactive-workshop-history rows, and 10 archived-proposal rows across the two old labels. No active row came from an immutable snapshot; ordinary prose and historical quotations were not registered edges. After migration, the 57 surviving
rationalerows are generated reports 45, archived proposals 9, and workshop history 3; all survivinggroundsrows are the 276 active canonical cohort or an unchanged exclusion. - Authorization gaps: the migration replaces
rationalewithrests-onin each affected source collection, addsis-evidence-forfor agentic-systems→notes and sources→agent-memory, and giveskb/types/its ownCOLLECTION.md. No contract is widened to authorize off-patterngrounds. - Guidance-only occurrences: ADRs 019/020/058, the catalogue, collection contracts, proposal guidance, current theory vocabulary, and the write/connect consumption path were reconciled. Historical ADR discussion retains the retired identifier explicitly as history.
Surprises
- Expected: one coherent renameable rationale relation. Observed: 114 R edges, 2 E edges, and 18 N edges. Why it mattered: a lexical rename would convert evidence and architecture/history into false design dependencies. Local resolution: classify before naming; defer migration of E/N rows. Reusable lesson: tuple inventory and semantic disposition must precede any directional-label edit. Deferred owner: maintainer in the migration run.
- Expected: the current label boundary would be visible in authorization. Observed: 38 active
groundsedges are outside note→note, including 15 external citations, 9 source→note evidence mappings, and 6 reference→note cross-register cases. Why it mattered: authorized labels are hypotheses, not semantic evidence, and off-contract rows carry the highest information about drift. Local resolution: record authorization gaps separately and do not widen contracts during evaluation. Reusable lesson: compare every disposition against both resolved destination and source collection. Deferred owner: vocabulary/contract migration maintainer. - Expected: same-file use of both labels would reveal a stable distinction. Observed: only
kb/reference/tag-readme-trace-as-self-improving-loop.mdandkb/types/type-spec.mduse both, and their local contexts mostly restate “why/basis.” Why it mattered: the cases expose uncontrolled synonymy at the cross-register boundary without invalidating the larger note→note grounds cohort. Local resolution: treat the two files as reclassification cases. Reusable lesson: same-file co-occurrence is a high-information drift test, not a reason to merge by count. Deferred owner: migration maintainer. - Expected: the N and off-pattern buckets would require removals or new vocabulary. Observed: all 58 boundary edges retain an articulated reader need and fit five existing or already-selected relations; the real residue is three authorization-surface decisions. Why it mattered: semantic cleanup can remain conservative without preserving overloaded labels or inventing synonyms. Local resolution: record exact successor dispositions and authorization deltas in the boundary adjudication. Reusable lesson: after coarse classification, run a second pass that must choose an existing assertion or removal for every tuple before contracts change. Deferred owner: migration maintainer.
- Expected: the reviewed 310-edge grounds baseline would still be current. Observed: four new canonical note→note
groundsedges landed before implementation, raising the active cohort to 314 without changing the 38-edge off-pattern boundary. Why it mattered: blindly conserving 272 deferred tuples would have omitted live edges even though the adjudicated edits were still correct. Local resolution: rebuild the baseline, classify the four rows as canonical, and defer 276 tuples. Reusable lesson: rebaseline after concurrent sessions and immediately before mutation; review-time counts are evidence, not an execution lock. Deferred owner: none. - Expected: the global type surface could receive three migrated links without changing collection topology. Observed:
kb/types/authored real links but had noCOLLECTION.md, so any label remained outside collection-owned authorization. Why it mattered: borrowing the reference contract or self-authorizing through the root type would preserve a structural exception. Local resolution: ADR 060 makeskb/types/a collection with a minimal text/link contract while keeping type semantics type-owned. Reusable lesson: when a positive mutable surface lies outside the authorization topology, resolve the ownership gap rather than treating it as a label exception. Deferred owner: none. - Expected: the batch edit's final count check would confirm its own writes. Observed: all 172 edits applied, then a typo in the script's expected-count expression produced a failure after mutation. Why it mattered: retrying the mutator would have been unsafe and its failure could not attest rollback. Local resolution: stop, report the partial state, and run a separate read-only reconciliation that found the exact expected distribution. Reusable lesson: mutation and verification must be separate phases; a post-write failure always triggers independent state inspection before any rerun. Deferred owner: the promoted procedure records this rule.
Edge reconciliation
- Migrated old
rationale: 114 →rests-on; 15 →evidenced-by; 2 →is-evidence-for; 2 →implements; 1 →compares-with; 0 removed. Total 134. - Reclassified off-pattern
grounds: 8 →rests-on; 20 →evidenced-by; 10 →is-evidence-for; 0 removed. Total 38. - Deferred active
grounds: 276 note→note tuples, unchanged. - Final active old labels:
rationale0;grounds276, all notes→notes. - Final active
rests-on: 123 — 122 conserved migrated tuples plus one new edge authored by ADR 060 and accounted separately. - Excluded old labels remain untouched in generated reports, archived proposals, and workshop history. Reciprocal edges were not part of the mutation set.
Verification friction
- Checks that caught a real issue: the bold-footer-aware temporary TSV exposed six active source-analysis edges omitted by the first parser; resolved-target classification exposed all 38 off-pattern grounds rows and the 19 rationale authorization gaps.
- Checks that produced noise: generated reports and workshop histories dominated raw lexical counts, confirming that repository-wide replacement sets are not a usable baseline.
- Unsafe manual step or missing check: the temporary parser still needs fixtures for nested Markdown targets and link-like prose before it could become a reusable command. The batch mutator combined writing with a final assertion, so its assertion typo surfaced only after files changed.
- Automation worth retaining: a temporary disposition-bearing TSV, mutually exclusive exclusion buckets, and an independent read-only post-migration reconciliation. The label-specific semantic classifier and one-off corpus parser remain review-owned rather than promoted as code.
Procedure promotion decision
Accept promotion. Both evidence and rationale runs repeated the same stable core: fresh positive-surface inventory, exclusive exclusions, resolved source/destination authorization comparison, complete semantic disposition before edits, coordinated decision/catalogue/contract/guidance changes, exact tuple mutation, independent old-label and tuple reconciliation, validation, and surprise capture. The promoted directional-label migration instruction records that core.
The successor assertion, neighboring-label comparisons, corpus classification, and authorization decisions remained label-specific and are deliberately excluded. Parser code also remains unpromoted until real fixtures establish one stable registered-edge grammar.
Completion
- Validation and tests: affected library collections and each changed workshop artifact validated with no failures. The sources collection retained its unrelated pre-existing missing-distillation-link warnings.
pytest: 486 passed, 1 unrelated pre-existing redirect-map target failure (a-decomposition-earns-explanatory-reach-by-derivation-or-inheritance.md). Independent tuple, exclusion, deferred-cohort, authorization-pair, andgit diff --checkchecks passed. - Migration commits: pending maintainer request.
- Deferred follow-ups: evaluate and migrate the 276 canonical note→note
groundsedges; add parser fixtures before promoting a reusable corpus command; repair the unrelated redirect target under its owning work.