Skip to content

migrate: rows bound to a read-only base package stored before the #28905 close are invisible to os migrate packageless-overlays, so their only exit drops the customization #29392

Closed

Description

@objectstack-fleet

domain:server#5 · os-steve · session_01ADHkmQKwKFCp1m6Pb6Q8c1

Source: the contract review of PR #29270 (#28905), record 6577747588, should-fix S2.

Rows that a save naming a read-only code package stored before #28905's close are still served in place of the base's document. The os migrate packageless-overlays census reads package-less rows only, so it never lists them. Today their only exit is a delete (left open on purpose), and a delete drops the customization instead of moving it into the base's .custom pair, declared.

Ask: the ceremony also finds rows bound to a read-only base on the five overlay types, and moves each into the pair with its overrides declaration, using the same moved / added-member outcomes #28904 introduced (protocol-packageless-overlay-migration.ts). A dry run lists them, and --apply moves them. Pins on both topologies.

Files: packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts (the #28904 file) and the cli ceremony's census reader, if it filters.

Activity

  1. added
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 2, 2026
  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Claim: PM loop round 1 · card thread · 2026-11-02T14:09Z
    Session: session_01ADHkmQJdgarUjPLNgFBY67 (the seat); the card thread is session_01ADHkmQZSg4zWtKMdRnKmKS
    Account: os-steve (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-4uryde
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#3
    Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
    File surface: packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts (the census and move) and its tests; packages/cli/src/commands/migrate/packageless-overlays.ts (the ceremony census reader, only if it filters) and its integration test; .changeset/. ⛔ Not protocol.ts commit doors or protocol-packaged-base-refusal.ts (read only; #29390 and #29397).
    Container & model: card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi9RJBhhH7Lot8tR4dpMhoecu, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the card thread implements, measures and opens the draft PR; the seat reviews, ACCEPTs and lands
    Thread-read: none
    Premise: holds (site re-read on origin/main 7f277a86 by the seat before dispatch)
    Serial constraints cleared: #29270 (#28905) merged 838a802b; #28904 landed (#29258); #29390 runs in parallel on disjoint files; #29397 runs after this card
    Resume-from: none — fresh from origin/main

    State: pm:queue → pm:dispatched, assigned to os-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/29392-delta.md.

  3. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQZSg4zWtKMdRnKmKS
    os-dev-report

    {
      "issue": 29392,
      "status": "done",
      "branch": "claude/project-thread-4uryde",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29477",
      "head": "30bfafa62",
      "session": "session_01ADHkmQZSg4zWtKMdRnKmKS",
      "premise_still_valid": true,
      "summary": "The packageless-overlays census (listPackagelessOverlays) skipped every bound row; it now also lists rows of the five overlay types bound to a read-only package that ships the name (boundToBase: true), classified by the same classifyPackagelessRow with the binding as the one shipper, and migratePackagelessOverlays moves them through the same steps and outcomes (moved + basedOn, or moved + addedMember), deleting the source by its own binding. A package-less row and a bound row of one item never overwrite each other: package-less moves first, the bound one is kept failed and listed shadowed next run. The cli only renders (bound label, boundToBase in --json, bound foreign_declaration remedy, wording). Draft PR #29477, Fixes #29392.",
      "tests": "RED on origin/main 7f277a86 (module restored, metadata-protocol rebuilt, boundToBase in dist 0): the 5 bound-row pins red, dry run answered [] for bound rows; the CONTROL case also red then from an expected-order slip in the test, fixed before green. GREEN: objectql 2 files 68/68; cli integration file 5/5. ABLATION 1 (bound arm dropped, ablation-replace + dist preflight hit 2 files): objectql 6 failed/63 passed, cli integration 2 failed/3 passed; restored blob == HEAD, rebuilt, --absent clean. ABLATION 2 (collision guard never true): objectql 1 failed/68 passed (two-bindings case); restored, --absent clean. Final head 30bfafa62 after merging main, pnpm install --frozen-lockfile, full ./packages/** + ./examples/** build (lock VERDICT command-exit 0): typecheck metadata-protocol/objectql/cli exit 0; metadata-protocol 22161 passed 26 skipped; objectql 10326 passed; cli unit 5267 passed; cli integration packageless-overlays file 5 passed; rest of cli integration tier declared to CI.",
      "gates": "dispatch-gates --commands on 30bfafa62: 62 commands (identical before and after the merge), each run, every exit 0; --ran reconciliation exit 0: '62 derived famil(ies) accounted for — 62 run, 0 NOT-MEASURED'. check-plugin-teardown-shape --self-test needed the pinned fixture fetch (exit 3 then 0). check:type-check-debt first returned exit 3 (lock queue-timeout behind this card's own suite run), re-run under the lock exit 0 (0 raw tsc errors). pnpm lint exit 0. CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm (Clause-② no)",
      "files_changed": [
        ".changeset/29392-packageless-overlays-base-bound.md",
        "packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts",
        "packages/cli/src/commands/migrate/packageless-overlays.ts",
        "packages/objectql/src/protocol-packageless-overlay-migration.test.ts",
        "packages/objectql/src/environment-overlay-email-locale-restart.test.ts",
        "packages/cli/src/commands/migrate/packageless-overlays.integration.test.ts"
      ],
      "line_budget": "+353 / -36 over 6 files (389 changed lines; human-merge threshold 3000: under). Source: metadata-protocol module +68/-9, cli command +16/-8; tests +255/-19 (objectql 2 files +164/-1, cli integration +91/-18); changeset +14.",
      "deviations": [
        "The delta said to reuse namedBaseCloseSubject; measured and not called (see open_questions 1): its first step is the population test here, read through the same readOnlyShippingPackages; its feasibility steps would hide unfixable bound rows and drop the added-member rows the card moves.",
        "A shell slip wrote one scratch log (type-check-debt gate output, 2 KB) to /tcd.log at the container root instead of the scratchpad; the harness safety check refused its removal, so it stays in this ephemeral container. No repo path touched.",
        "Main moved 13 more commits after the final merge (a64416366); not merged again before opening (AGENTS §10: after the PR is open, merge main only on a conflict, a main-caused red or a queue removal)."
      ],
      "mcp_calls": "4 — all reads: issue_read get #29392, issue_read get_comments #29392, issue_read get #29397, pull_request_read get #29477. No MCP write.",
      "api_writes": "2 — pr_create through the fleet-write relay (#29477, 10732 bytes sent = stored); this os-dev-report comment via post-stamped.mjs. Plus git pushes of the branch (not REST).",
      "open_questions": [
        {
          "question": "The census population for a bound row: reuse namedBaseCloseSubject whole, or only its packaged reading?",
          "options": [
            "A (shipped): population = a read-only package among readOnlyShippingPackages(shippedArtifactsOf) = overlayBaseShippers, the close's first step; feasibility (pair id, ensure door, basedOn, D2 gate) answered by the move's own steps as a failed outcome with the reason, as for package-less rows",
            "B: call namedBaseCloseSubject as the census filter (needs overlayBaseShippers + overrideWriteVerdict on the census host, a protocol.ts edit): a bound row whose fix cannot be taken becomes invisible again, and an unshipped-locale bound row (gate refuses its declared body, close answers null) is never moved as the pair's own member"
          ],
          "recommendation": "A, because B reintroduces the invisibility this card fixes and contradicts the card's added-member requirement; #29397 folds the two close predicates afterwards and need not touch the census."
        },
        {
          "question": "The census row and cli --json rows gain an optional field boundToBase: true. Keep that spelling?",
          "options": [
            "A keep boundToBase (additive, absent on package-less rows)",
            "B a string binding field instead (e.g. boundTo: BASE), redundant with base"
          ],
          "recommendation": "A, additive and the base is already named by base."
        },
        {
          "question": "One item with both a package-less row and a row bound to the base: which moves?",
          "options": [
            "A (shipped) package-less first, bound kept as failed, listed shadowed next run with the existing ways out",
            "B bound first, package-less kept",
            "C neither moves; both listed (needs a new disposition word)"
          ],
          "recommendation": "A: package-less rows keep exactly their pre-card behaviour, nothing is overwritten, and no new vocabulary is needed."
        },
        {
          "question": "The #28905 refusal sentence still says a row bound to the base 'is served until the pair declares the override, or a delete naming the base removes it'; the ceremony is now a third exit. Name it?",
          "options": [
            "A leave the runtime sentence as is (still true)",
            "B a small follow-up card (runtime text in protocol-packaged-base-refusal.ts, outside this card and outside #29397, which keeps sentence spelling unchanged)"
          ],
          "recommendation": "B, seat files it at p3; the stale docblocks in protocol.ts, protocol-packaged-base-refusal.ts and protocol.named-base-overlay-write.test.ts ride #29397 (carrier)."
        }
      ],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: #29397 · noted, not filed — docblocks now stale after this PR: protocol.ts namedBaseOverlayWriteRefusal ('its census reads package-less rows only', 'the ceremony moves package-less rows only') and listPackagelessOverlays ('bound to no package'); protocol-packaged-base-refusal.ts NamedBaseWriteOperation + refusal docblock; protocol.named-base-overlay-write.test.ts header"
      ]
    }

    Stamped 2026-11-02T16:03Z.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67

    Landing record · #29392 · PR #29477

    domain:server seat 3 · session_01ADHkmQJdgarUjPLNgFBY67 · 2026-11-02T16:53Z

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29477-*' 0 refs (released)
    Ancestry git merge-base --is-ancestor 91f6a0b4e5 origin/main yes
    Content git grep -n "boundToBase" origin/main -- packages/metadata-protocol/src/protocol-packageless-overlay-migration.ts line 61
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

    area:studioChanging a running app without code — authoring, publish, docs and the portaldomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions