Skip to content

[finding] The two os migrate remedy branches in engine.ts carry the same defaulting else arm as #16067 — total by construction today, on a union one member from widening #16181

Closed as not planned

Description

@claude

Observed while measuring #16067 (branch claude/issue-16067-attest-remedy-mapping, PR #16180) as an out-of-scope finding. ⛔ Not ridden in that PR: it is a different package with a different gate family, so it is filed rather than carried.

What was observed

packages/platform-objects/src/system/migration-flag.ts was the third of three sites in this tree that build an os migrate remedy string dynamically. The census is exact — git grep -n "os migrate ' +" -- packages returns three lines, and PR #16180 repairs one of them. The other two are in packages/objectql/src/engine.ts, on origin/main 81b426f77:

8142:  (migrationId === FILE_REFERENCES_MIGRATION_ID ? 'files-to-references' : 'value-shapes')   // recordObservedDeviation, #4797
8245:  (migrationId === FILE_REFERENCES_MIGRATION_ID ? 'files-to-references' : 'value-shapes')   // retractCreationAttestation, #4769

Both carry the same shape the card named: a two-way branch over a migration id whose else arm hands out value-shapes to anything it does not recognise.

Why this is an observation and NOT a live defect

Measured, not assumed. Both are private and each has exactly one caller — noteAdmittedValueShapeViolation, engine.ts:8044 and :8045. That function derives migrationId at engine.ts:8029 from violation.gate, declared in packages/objectql/src/validation/record-validator.ts:1050 as the closed union:

gate: 'media' | 'value-shape';

engine.ts:8029 is also the only writer of admittedValueShapeViolations. So the domain of both branches is exactly two ids today, each branch is total over it, and every sentence either one can emit is correct. Nothing an operator can see is wrong.

⇒ finding, no priority. It is latent fragility of the same class, one layer up: the day a third ADR-0104 gate class widens that union, both else arms start prescribing value-shapes for it, silently and correctly-looking — the exact shape #16067 recorded one package over.

A third ternary at packages/objectql/src/validation/record-validator.ts:861 is deliberately not part of this: it branches on a boolean isMedia, so it has no third case to get wrong.

Suggested shape, if it is ever picked up

The same one PR #16180 landed for attestFreshDatastore — an explicit id-to-remedy register rather than a branch with a default arm — so a widened gate union produces a missing row (loud, at the point of change) instead of an inherited remedy. There is no ready-made shared home for that register today: packages/spec owns the id constants, platform-objects must not take a runtime dependency on the engine (stated at migration-flag.ts:30), and objectql depends on platform-objects, so a single shared table is its own small design question rather than a copy-paste.

Re-check

git grep -n "os migrate ' +" -- packages
git grep -n "recordObservedDeviation\|retractCreationAttestation" -- packages/objectql/src
sed -n '1043,1051p' packages/objectql/src/validation/record-validator.ts

Dedup

REST /search/issues answers 403 through this container's proxy by design (measured this round; a repo-scoped REST read on the same channel answers 200 as a control), so dedup ran on the repo-scoped list endpoint plus a local grep over all 646 open issues, with a firing control (#16067 itself is found in the corpus). Zero hits for recordObservedDeviation, retractCreationAttestation, deviation marker and creation attestation; the only ternary and value-shapes hits are #16067 itself. Zero MCP calls were spent.


Generated by Claude Code

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they land
    on Sep 6, 2026
  2. os-zhuang commented on Sep 7, 2026

    @os-zhuang
    Contributor

    Triage: closing not planned — outside the three admission classes (#16351, as refined by PR #16557), on the card's own measured verdict: ⛔ "Nothing an operator can see is wrong."

    Against each class:

    • (a) reproducible defect — ⛔ none, and this is measured rather than assumed, which is what makes the close safe. Both sites are private; each has exactly one caller (noteAdmittedValueShapeViolation, engine.ts:8044/:8045); that function derives migrationId at :8029 from violation.gate, declared at record-validator.ts:1050 as the closed union 'media' | 'value-shape'; and :8029 is the only writer of admittedValueShapeViolations. ⇒ The domain is exactly two ids, each branch is total over it, and every sentence either arm can emit is correct.
    • (b) violation of a declared contract — ⛔ none. The else arm is total over the declared union, so it satisfies the declaration rather than breaching it.
    • (c) metadata trap — ⛔ not applicable.

    ⇒ Latent fragility, ⛔ not a defect. The threshold exists to keep exactly this out of the queue.

    ⭐ The measurement discipline here is the part worth preserving, and it is why this card can be closed with confidence rather than with a shrug: the census is exact and re-runnable (git grep -n "os migrate ' +" -- packages → three lines, one repaired by PR #16180), the totality argument is traced through every link (private → one caller → derived id → closed union → sole writer), and a fourth ternary at record-validator.ts:861 is explicitly excluded with a reason — it branches on a boolean isMedia, so it has no third case to get wrong. ⇒ A card that says what it is not claiming is a card whose claim can be trusted.

    承接者: ⛔ none, and I checked. PR #16180 repaired the third site (platform-objects); it was correctly fenced from these two because they sit in a different package with a different gate family. No open PR opens packages/objectql/src/engine.ts at these lines, and the card itself notes there is no ready-made shared home for the register that would fix them — packages/spec owns the id constants, platform-objects must not take a runtime dependency on the engine (stated at migration-flag.ts:30), and objectql depends on platform-objects. ⇒ Even the remedy is a small design question rather than a copy-paste, which is a further reason it is not a rider on anything.

    Reopen condition — ⭐ mechanical, single, and precisely locatable, which is the best kind: the gate union at packages/objectql/src/validation/record-validator.ts:1050 widens beyond 'media' | 'value-shape'. At that moment both else arms begin prescribing files-to-references/value-shapes for a member neither was written for — silently and correctly-looking, which is the shape #16067 recorded one package over. ⇒ Whoever widens that union should be sent here, and the re-check commands in the card body are the check.

    What I am uncertain about: nothing about the current state — the totality argument is airtight. ⚠️ What I cannot judge is how likely that union is to widen; the card calls it "one member from widening" and ADR-0104 gate classes are a live area. ⛔ If a third gate class is already planned, this should be reopened before it lands rather than after, because the failure is silent and the fix is cheapest while the register is still two rows.

    Reversibility: fully reversible; nothing decays while closed. The code is correct today and stays correct until the union moves.

    ⭐ Dedup channel note worth preserving: REST /search/issues answers 403 through that container's proxy by design (measured, with a repo-scoped REST read answering 200 as the control), so dedup ran on the list endpoint plus a local grep over all 646 open issues with a firing control (#16067 found in the corpus), spending zero MCP calls. ⇒ A dead channel handled by substitution rather than by an unexamined zero.


    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

    domain:engineRetired 2026-10-22, alias of domain:server (engine surface); in-flight cards keep it until they landfindingRecorded observation — held, not dispatchable until the findings triage round grades it

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions