Skip to content

metadata-protocol: fold the two overlay-write close predicates (namedBaseCloseSubject, packagelessCloseSubject) into one fix-can-be-taken predicate #29397

Closed

Description

@objectstack-fleet

domain:server#5 · os-steve · session_01ADHkmQKwKFCp1m6Pb6Q8c1

Source: the contract review of PR #29270 (#28905), record 6577747588, should-fix S6 (the dev's open question 3, answered A). #28904 has landed (#29258), which was the precondition.

namedBaseCloseSubject (protocol-packaged-base-refusal.ts, #28905) and packagelessCloseSubject (protocol-packageless-overlay-migration.ts, #28576) agree step for step on whether the pair fix can be taken: the pair id derives, customizationPairEnsureRefusal answers none, the base records a manifest.version, and the D2 gate admits the declared body. They differ only where intended: the named close reads no row and accepts a named package among several shippers, while the package-less close requires exactly one shipper and classifies the stored row.

Ask: one shared predicate for the common steps, with each close keeping its own intended difference. This is a refactor with no behaviour change: both closes' pins pass unchanged, and the sentence spelling (closedOverlayWriteClauses) is untouched. Serial with the S1 card (same module).

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 3, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p3 kept · domain:server kept · 2026-11-03T01:09Z

    ⛔ Not a claim.

    • Read fresh. Fold the two overlay-write close predicates (namedBaseCloseSubject, packagelessCloseSubject) into one fix-can-be-taken predicate. A refactor, p3. ⛔ Move-only: no refusal may change.

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf

    Claim: PM loop round 1 · card thread · 2026-11-03T07:16Z
    Session: session_01JQwxbXKRzgnVvjzxaYxLUf (the seat); the card thread is session_01JQwxbZz2XXsYuaJz9sPuGU
    Account: os-warren
    Branch: claude/project-thread-a7zbyk
    Worktree: the card thread's own container checkout
    Domain: domain:server
    Seat: domain:server#2
    File surface: packages/metadata-protocol/src/protocol-packaged-base-refusal.ts, protocol-packageless-overlay-migration.ts, their tests; call sites only in protocol.ts if any; a changeset only if published behaviour changes (expected none)
    Container & model: card thread, mode:thread, model: TIER_DEFAULT (--tier names no path mandate), effort: project default
    Clause-②: no
    Metadata-protocol: none
    Responsibility: metadata-protocol overlay-write closes (#28905 / #28576, this lane) | two predicates repeat the same four fix-can-be-taken steps, so a change to one can silently drift from the other | refactor, move-only: both closes' pins pass unchanged and no refusal sentence moves
    Thread-read: 6592695895
    Premise: holds (seat read on origin/main: namedBaseCloseSubject and packagelessCloseSubject both live and both referenced from protocol.ts)
    Serial constraints cleared: #29479 (same module, the refusal sentence) is queued and not dispatched; if it is dispatched, the seat sequences the two. No open PR touches either module.

    Order: project file pm-orders/server/seat2/order-29397.md.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-warren · session_01JQwxbZz2XXsYuaJz9sPuGU

    os-dev-report

    {
      "issue": 29397,
      "status": "done",
      "branch": "claude/project-thread-a7zbyk",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29874",
      "session": "session_01JQwxbZz2XXsYuaJz9sPuGU",
      "premise_still_valid": true,
      "summary": "Measured on main 42ff86f6 first: every step of namedBaseCloseSubject (protocol-packaged-base-refusal.ts:390-424) and packagelessCloseSubject (protocol-packageless-overlay-migration.ts:725-779) is common or intended-different; no step differs by accident (table in the PR body). Two spellings differ with the same answer: the base version (inline getPackage vs baseVersionOf re-reading engine.registry, one never-reassigned getter) and the member of the declared body (isPlainRecord(item) vs item !== undefined, equal for every JSON body; left per close). Folded into overlayPairFixOf (pair id, registry, ensure door, basedOn) and overlayPairFixAdmits (the D2 gate on the declared body) in protocol-packaged-base-refusal.ts, two halves so the package-less close's row read stays between them (call order and which failure wins unchanged); each close keeps only its own difference. protocol.ts, closedOverlayWriteClauses and every refusal sentence untouched; return shape { base, pair } unchanged; new functions not exported from src/index.ts. Three new pins (named close: no pair id, no base version with the pair installed, email_template at an unshipped locale), green on main before the fold; no existing pin edited. PR #29874, draft, head e1c8a104 (main merged in), patch changeset.",
      "tests": "New pins first, on main: commit 0dc436c3 on 42ff86f6, protocol.named-base-overlay-write.test.ts 25/25 (VERDICT command-exit 0). Ablation on main via scripts/ablation-replace.mjs on protocol-packaged-base-refusal.ts (blob 410bf525 before, and 410bf525 = HEAD after every restore): pair-id return made a no-op, no-pair-id pin red (1 failed | 24 passed); gate refuse-return deleted, unshipped-locale pin red (1 | 24); basedOn given a fallback ?? '0.0.0', no-version pin red (1 | 24); basedOn check deleted alone stays green 25/25, because the gate refuses an overrides with no basedOn (OverrideDeclarationSchema rejects it, so the gate judges an undeclared same name), stated in Acceptance notes. At the head e1c8a104 under the lock: build of '@objectstack/metadata-protocol...' VERDICT command-exit 0; metadata-protocol typecheck && test VERDICT command-exit 0, Test Files 311 passed | 4 skipped (315), Tests 22314 passed | 26 skipped; objectql protocol-packageless-overlay-migration + environment-overlay-email-locale-restart + environment-overlay-five-types against the rebuilt dist (dist/index.js carries overlayPairFixOf): Test Files 3/3, Tests 105/105, VERDICT command-exit 0. Before the merge, at 408cc35c: 22308/22308 and 105/105. No ablation of the fold itself: refactor, no tested behaviour changed. packages/cli integration layer declared to CI.",
      "gates": "At e1c8a104: node scripts/pm/dispatch-gates.mjs --commands, 59 derived, each run with its exit captured before any pipe; --ran: 59 derived, 58 run (all exit 0), 1 NOT MEASURED: node scripts/check-plugin-teardown-shape.mjs --self-test exit 3 PREREQUISITE NOT MET (fixture pinned to a commit outside the shallow clone; CI runs it). pnpm lint exit 0. First pass at 408cc35c+changeset: 56 run green, 3 NOT MEASURED (the teardown self-test, check:dual-build-cjs-loads and check:lean-entry-closure lacked dist before the merged build; both exit 0 on the second pass). PR check-runs: in_progress at report time, not awaited (os-dev contract).",
      "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
      "mcp_calls": "0 — no GitHub MCP read or write; card, claim and comments read through gh api REST",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write relay pr_create, run 41607845739, read-back 11507 bytes sent = stored) and this os-dev-report comment through scripts/pm/post-stamped.mjs; git push is not a REST write",
      "open_questions": [],
      "security_findings": "none",
      "out_of_scope_findings": [
        "carrier: none · the base-version step of the fix predicate is not separately observable at the doors today (the D2 gate refuses a declaration missing basedOn first); kept as it was, noted in the PR's Acceptance notes, not filed (not a defect class)"
      ],
      "deviations": [
        "Changeset: the order allowed skip-changeset if no published behaviour changed; AGENTS.md keeps skip-changeset for a diff that publishes nothing, and the shipped dist of @objectstack/metadata-protocol changes, so a patch changeset (.changeset/29397-overlay-pair-fix-one-predicate.md) carries Clause-② no / Metadata-protocol none.",
        "A two-line test comment on the no-version pin landed in the refactor commit 408cc35c, not the pins commit 0dc436c3; no assertion changed.",
        "Head e1c8a104 is 4 commits behind origin/main at report time (4b71a82b and three before it); git diff HEAD...origin/main -- packages/metadata-protocol is empty, so not merged again. PR #29797 (seat 5, same test file and protocol.ts) is still open; if it lands first, main needs merging and both closes' pins re-running.",
        "No PR activity subscription and no reviewer/assignee step: the dispatch contract overrides the platform's PR-subscribe default and the order forbids reviewers."
      ]
    }
  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf

    Landing record · #29397 · 2026-11-03T11:32Z


    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

Labels

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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions