Skip to content

ADR-0087 still states that a retired entry is skipped by the loader, 35 lines above its own addendum saying the opposite — and the artifact-ingestion door policy from #12772 is recorded in no addendum at all #17894

Description

@os-bill

Filed by the domain:spec execution seat (session session_01MkQhmuuJAVDjmeWNixwDDH) while landing #16864's first share. ⛔ Filed unassigned and unlabelled: routing, grading and type are the triage seat's.

This is share 2 of 3 of #16864's correction. Share 1 landed as PR #17888 (the packages/spec carriers). Share 3 is the skills-lane carrier. They were split by which surface the carrier lives on, not by topic.

Two defects in one file, both measured on origin/main

docs/adr/0087-metadata-protocol-upgrade-contract.md

1. A pre-addendum claim still stands 35 lines above its own correction

Line 355 reads, in the present tense:

MetadataConversion.retiredFromLoadPath implements "retired from the load path in N+1 — but never deleted": a retired entry is skipped by the loader (applyConversions) and replayed only by the chain (migrate meta) and the fixture CI

Line 390 of the same file is ## Addendum (2026-07-31) — stored metadata replays the chain (#3903), which supersedes it. Both are present, in document order, and a reader who stops at 355 gets the false one.

The addendum's own words (ratified from PR #4317, which closed #3903):

Every stored-row rehydration seam replays the FULL chain, retired entries included — applyConversionsToStoredItem in spec/conversions/stored.ts is the one primitive … Rationale: retirement is an authoring-surface event. The window exists so a live author is taught the canonical spelling; a row at rest has no author to teach.

2. The artifact-ingestion door's policy is recorded nowhere in the ADR

#12772 ruled that the artifact-ingestion door opens a version-keyed window and replays retired entries, and its ruling text is explicit about the shape:

So the conversion must be a versioned forward conversion keyed off the artifact's authored specVersion, ⛔ not an unconditional strip

That policy lives only in the issue and its review comments. Measured: docs/adr/0087-metadata-protocol-upgrade-contract.md carries eight ## Addendum headings and none of them is the artifact door; artifact-ingestion and applyArtifactForwardConversions return zero hits in that file. ⇒ a reader of the ADR meets the 2026-07-31 stored-row policy and nothing at all about the boot seam.

Why it is filed rather than done

docs/adr/** is a governed surface. A PR touching it is draft-only with a human merge, so it is a separate step from #16864's ordinary-queue share, not a rider on it.

Measurement provenance

The seat verified both readings itself on origin/main (git show origin/main:PATH, with a dark control returning 0). The seam inventory behind them was re-taken by the #16864 determination round: three includeRetired: true literals, four runtime callers (because applyArtifactForwardConversions has two), and stored.ts pins the flag rather than offering it (StoredConversionOptions is Omit over the option, so no caller can turn it off).

Refs

#16864 (the parent correction) · PR #17888 (share 1, landed) · #3903 / PR #4317 (the stored-row ruling) · #12772 (the artifact-door ruling) · #17885 (the default-flip instance the same round measured, a separate question) · #16693 (removed field-required-notnull-explicit)


Generated by Claude Code

Activity

  1. claude commented on Sep 13, 2026

    @claude
    Contributor

    Deferred by same-file serial — not dispatched this fire (skills seat, session session_01DAcomhvR9kKizeYgg89Vo8, GitHub os-project-manager, 2026-09-13T07:15Z). This card stays pm:queue, next in this lane's total order once its file is free.

    docs/adr/0087-metadata-protocol-upgrade-contract.md is touched by open PR #17776 (os-bill, draft, fix(check-adr-0087): walk a dotted member path through a class body), hunk at :758–:770 — inside the ADR body, below the addenda this card counts. Same file ⇒ hard serial; the dispatch waits for PR #17776 to land (or close). Known pit for that dispatch, recorded now: acceptance 3 pins the ## Addendum heading count 8 → 9; re-measure the count on the merged ref before writing, because a sibling PR on this file can move it. Everything else in triage 5651629548 stands as written.


    Generated by Claude Code

  2. claude commented on Sep 13, 2026

    @claude
    Contributor

    Claim: PM loop round 1
    Session: session_01DAcomhvR9kKizeYgg89Vo8 (GitHub os-project-manager, skills seat), claimed at 2026-09-13T10:09Z
    Branch: claude/issue-17894-adr-0087-retired-entry-and-artifact-door
    Worktree: objectstack-issue-17894
    Domain: domain:skills (governed docs/adr/**; graded p2 Bug by triage 5651629548 — ruled as 「pull back to what is already declared」, no new decision: the file's own addendum convention, used eight times, is the form)
    File surface: docs/adr/0087-metadata-protocol-upgrade-contract.md ONLY — (1) at the pre-addendum sentence (「a retired entry is skipped by the loader …」, :355 at filing; re-anchor by content), an in-place note that the 2026-07-31 addendum on stored metadata (#3903) supersedes it, ⛔ the original sentence not rewritten; (2) one new ## Addendum recording the artifact-ingestion door's policy as ruled on #12772, in the file's own addendum form, citing the ruling comment. Acceptance 3 of the card pins the heading count — re-measure ^## Addendum on the merged ref before writing (PR #17776 landed 2026-09-13T08:41Z, its hunk at :758–:770 is below the addenda; the file is 827 lines now).
    Container & model: S, mode:subagent, model: opus (no path mandate for docs/adr/**); seat review at the contract-review tier; governed ⇒ draft PR + four-piece, then lands under ruling C (#17971) once an authorized approval exists
    Clause-②: no
    Thread-read: 5651882940 (this seat's deferral, 2026-09-13T07:15Z — the newest comment at this claim)
    Serial constraints cleared: PR #17776 landed; no open PR touches this ADR (read at 2026-09-13T10:04Z across 23 open PRs by the #17748 dev's re-check, and by name here); H17 index ∩ this face = ∅; the sibling code half is #16864 (queue), not this card.


    Generated by Claude Code

  3. claude commented on Sep 13, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 17894,
      "status": "done",
      "branch": "claude/issue-17894-adr-0087-retired-entry-and-artifact-door",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/17997",
      "premise_still_valid": true,
      "summary": "Both defects were repaired in place in docs/adr/0087-metadata-protocol-upgrade-contract.md, additively: 101 insertions, 0 deletions, no code and no test. Defect 1: the pre-addendum sentence ('a retired entry is skipped by the loader (applyConversions) and replayed only by the chain (migrate meta) and the fixture CI') gained an in-place blockquote pointer naming the 2026-07-31 (#3903) and the new 2026-09-13 (#12772) addenda that supersede it for metadata at rest; the sentence itself is byte-unchanged, in the blockquote form ADR-0044 and ADR-0058 already use. Defect 2: a ninth '## Addendum' records the artifact-ingestion door's policy ruled on #12772 - the ruling quoted verbatim from comment 5443380108 (whitespace-normalised diff against the API body: exact match), the as-built versioned window and its four branches, the two in-tree doors that consume the one policy (packages/metadata/src/plugin.ts, packages/runtime/src/app-plugin.ts), the default-flip exclusion, the schema-layer residue boundary (comments 5448522858 / 5448958115) and the flag's seam inventory. Draft PR only; governed surface, not readied, not enqueued, no auto-merge. skip-changeset label applied and read back.",
      "tests": "No test suite is in scope (docs-only). GATES: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 22 families at f7d8e9da; all 22 run, every one exit 0; reconciled with --ran carrying exit codes -> '22 derived, 22 run, 0 NOT-MEASURED, 0 UNRUN' (derived zero). pnpm --filter @objectstack/lint run check:doc-formula-expressions first exited 3 (PREREQUISITE NOT MET: unbuilt @objectstack/formula and @objectstack/lint - nothing measured); closure built under the shared lock (OS_VERIFY_LOCK_SLOT=issue-17894-adr, VERDICT command-exit 0, waited 0s) and it re-ran exit 0. ABLATION (non-vacuity of check:adr-symbol-anchors on THIS diff): the new anchor packages/metadata-core/src/artifact-forward-conversion.ts#applyArtifactForwardConversions was mutated on disk to a ZZZ-suffixed name; on-disk proof grep real 1->0 and fake 0->1; node scripts/check-adr-symbol-anchors.mjs then exited 1 with [unresolved-symbol] naming that anchor at :867; restored with git checkout HEAD -- (path) under a trap, git diff HEAD empty and blob 4c83b339... equal to the HEAD blob. No build/dist is involved (the gate reads the working tree, proved by the mutation firing). ACCEPTANCE GREPS origin/main 65767d23 -> HEAD f7d8e9da: '^## Addendum' 8->9; 'Superseded for metadata at rest' 0->1; 'skipped by the loader' 1->1 (original sentence untouched); '#12772' 0->6; 'artifact-ingestion' 0->1; 'applyArtifactForwardConversions' 0->1; controls '## Addendum (2026-07-31)' 1->1 and 'retiredFromLoadPath' 2->2. The whole 2026-07-31 addendum section is byte-identical across the refs (md5 0b3788f178526522dd8dcac7aedb519d, 2657 bytes both sides) and git diff --stat is +101/-0. REPO-WIDE pnpm lint: declared narrowing with its three readings - (1) population from eslint.config.mjs's own files: blocks, all of them ts/tsx/mts/cts/js/jsx/mjs/cjs, no markdown block; (2) pnpm exec eslint --no-inline-config --format json over the one changed file returns 1 result, errorCount 0, message 'File ignored because no matching configuration was supplied.'; (3) invariance - the diff is one .md file plus no config, and no type-aware linting is configured, so no untouched file's verdict can move. CI owns the full sweep.",
      "gates": "22/22 derived families run, all exit 0, reconciled with --ran; the only non-zero was check:doc-formula-expressions' first exit 3 (prerequisite, not a finding), green after the closure build. Outside the derived total and NOT measured locally, as the tool itself declares: 52 artifact-roster families, 11 wide-population families, 10 changeset-dependent families (no changeset exists - skip-changeset), 2 workflow-valued commands and 1 path-scheduled CI job (Test Core shards).",
      "files_changed": [
        "docs/adr/0087-metadata-protocol-upgrade-contract.md (+101/-0, insertions only)"
      ],
      "premise_checks": {
        "P1_origin_main_readings": "HELD at 65767d23: 827 lines, '^## Addendum' 8, 'skipped by the loader' 1, the 2026-07-31 heading present, 'artifact-ingestion' 0, 'applyArtifactForwardConversions' 0, 'retiredFromLoadPath' 2 (positive control). Everything re-anchored by content, not by line number.",
        "P2_ruling_location": "HELD, and sharpened: the operative policy sentence is in #12772 triage comment 5443380108 (huangyiirene, 2026-08-27) and is quoted verbatim. The policy is spread: the M2 reason (#1883) sits in that same comment; the accept/refuse boundary at the door was moved later by #12845 and is recorded in this card's own thread, comments 5448522858 (dev report) and 5448958115 (contract review) - both cited by id in the addendum.",
        "P3_serial": "HELD, re-checked after 10:08Z: 25 open PRs listed at report time; the three created after 10:00Z (#17996, #17994, #17993) were file-listed and none touches this ADR.",
        "P4_gates": "HELD with a correction to the expectation: the derived family list is the 22 above; check:adr-0087-registration reads this file to pin its `not-required` disposition VOCABULARY (both directions, CATEGORIES vs the marker examples the ADR documents) and asserts NOTHING about addendum headings or their count. The new text adds no disposition marker, so that pin is untouched; the gate is green. check:refd-timer-probe, check:nul-bytes and check:doc-authoring were in the derived set and are green."
      },
      "deviations": [
        "The ninth addendum records more than the bare #12772 sentence, by the card's own acceptance 4 and to avoid writing a NEW false statement: (a) the default-flip exclusion (DEFAULT_FLIPS_NOT_REPLAYED_HERE), decided later on #16693 / #17885 and attributed to them - without it the ADR would claim the door replays the whole chain, which the shipped code contradicts; (b) the schema-layer residue boundary from #12845, cited to the two #12772 comments that record it. #17885 itself was not touched, as triage required.",
        "The card and the 2026-07-31 addendum name AutomationEngine.registerFlow as the flow seam; the includeRetired literal actually lives in canonicalizeStoredFlow, which registerFlow calls. The new addendum anchors the symbol that exists (engine.ts#canonicalizeStoredFlow) and says registerFlow calls it, rather than writing an anchor the resolver would reject.",
        "The ruling says 'keyed off the artifact's authored specVersion'; the shipped key is the floor of the declared engines.protocol range. Recorded IN the addendum as an as-built reading with a warning marker, not smoothed over and not re-ruled."
      ],
      "mcp_calls": "0 - every GitHub read and write went through REST curl (card + comments, #12772, #17885, open-PR file lists, PR create, label write, both read-backs)",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: the ruling's 'authored specVersion' vs the shipped 'declared engines.protocol floor' is a real gap and is load-bearing (it is why the default-flip exclusion exists), but it is already carded twice and both are shut (#16693, #17885), so it is recorded in the new addendum instead of filed a third time. Carrier for the reading: this PR (#17997)."
      ]
    }

    Generated by Claude Code

  4. claude commented on Sep 13, 2026

    @claude
    Contributor

    ACCEPT — skills seat (session session_01DAcomhvR9kKizeYgg89Vo8), 2026-09-13T10:32Z. PR #17997 head f7d8e9da (docs/adr/0087-metadata-protocol-upgrade-contract.md, +101 −0): contract review of record 5652729413 (PASS at the contract-review tier, Served-tier: carried), 速读终稿 5652729538. Seat re-verified on origin/main: the #12772 ruling sentence is quoted verbatim (normalised containment against comment 5443380108), all nine symbol/file anchors resolve, ^## Addendum 8 → 9, the original 「skipped by the loader」 sentence unchanged. Governed (docs/adr/**): needs-user-decision on the PR and reviewers os-zhuang + hotlong requested and read back; the seat lands under ruling C (#17971) once an authorized approval exists and the three still-running checks read green. Card stays pm:dispatched + assignee until the landing record.


    Generated by Claude Code

  5. claude commented on Sep 13, 2026

    @claude
    Contributor

    LANDED — skills seat (session session_01DAcomhvR9kKizeYgg89Vo8), 2026-09-13T11:51Z. PR #17997 merged through the merge queue at 2026-09-13T11:50Z as 24a86923 (merged_by os-zhuang; ruling C: os-zhuang's approval 5190544235 on head f7d8e9da at 11:26Z was the authorization, the maintainer flipped ready and enqueued, the seat did the four readings and cleared the label — 5652983376). Two readings at 2026-09-13T11:51Z: the queue ref gh-readonly-queue/main/pr-17997-* is gone, and origin/main carries the content — git log origin/main --oneline -80 has (#17997) 1 with control (#17998) 1. Card closed by the PR's Fixes line; pm:dispatched residue and the assignee stripped in this pass and read back. Contract review of record 5652729413 (head f7d8e9da, unchanged to landing); 速读 5652729538; ACCEPT 5652729841. ADR-0087 now carries its ninth addendum and the in-place pointer at the pre-addendum sentence.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions