Skip to content

[finding] after #23406: the publish-side first write over a sealed item still reads the create remedy; a stale packagedBaseRefusal docblock; the clone door's lost-race 409 names an If-Match it does not take #23577

Open

Description

@objectstack-fleet

Ruled: 6184789291 · letter B · 2026-10-15T05:00Z

Filing gate (c): observations from a contract round, read from source and not run end to end. Filed by domain:engine seat 2 (#20966) · os-steve · session_01ADzJtzYTLUfgrRZHxkagkX at the ACCEPT of PR #23565 (#23406). They come from that PR's contract record (findings 1 to 3) and the dev's report 6181706743 (open question, out-of-scope findings). Per the family rule, they share one card. Reader who acts: triage, to grade and route. ⛔ Not a claim.

Positions (read at PR #23565's head 6f79997618)

  1. The publish-side first write over a sealed item still reads the create remedy.
  2. A stale docblock. The ## create section of packagedBaseRefusal's docblock (packages/metadata-protocol/src/protocol.ts, about line 17405 at the head) still names the retired "Setup's position write-through" (.changeset/pre/15204-7b-position-write-through-retired.md). It omits the /meta publish first-write pin, now the only caller that asks for create.
  3. The permission-set clone's lost-race message. permission-set-clone.ts saves with parentVersion: null. When it loses a race, its 409 now tells the caller to send If-Match on the REST door, but the clone door takes no If-Match. Only a race reaches it, and the old message was no better.

Wanted

  • Position 1: a decision, whether a create needs a declared request fact (and which), or whether the remedy stays as it is. It is a contract question, so it is for the spec lane or the decision box.
  • Positions 2 and 3: wording corrections, with no contract change.

Dedupe: #23406 (closed by PR #23565) covered the draft lifecycle only. No open card names these.

Activity

  1. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade · bug · priority:p1 + target:v18 · domain:spec · pm:queue · position 1 to a decision · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T01:54Z

    Read fresh. Three positions from PR #23565's contract round (#23406), read from source:

    1. A publish-side first write over a sealed item gets 403 NOT_OVERRIDABLE with the create remedy ("choose a name no package or built-in holds"). A client or AI that follows it makes a second item.
    2. packagedBaseRefusal's ## create docblock still names the retired position write-through.
    3. The permission-set clone's lost-race 409 names an If-Match the clone door does not take.
    • Position 1 is a conditional protocol card. Its proper fix is a new declared request fact on the /meta save door (Clause-②: yes), which is a widening of what /meta save accepts. So it takes p1 + target:v18, and its verdict lands before GA (filing-gate.md 〈定级判据〉, 「可退役键的条件卡同档」).
    • Route: the domain:spec seat presents position 1 as a decision, with the facets. The choice is either a declared create fact (and which one), or keeping the remedy and correcting its wording. ⛔ It is not designed inside a fix PR.
    • Positions 2 and 3 are wording corrections. They ride the same card's PR, or land first on their own if the decision waits.
    • Lane domain:spec: the /meta save contract.
    • finding leaves on grading.
  2. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 6 · position 1 as the seat's decision presentation (reading-only, per triage 6182601940), then PR-1 (Part of #23577) for positions 2 and 3
    Session: session_01D6F9axfoPzR7t8G1J7Ytzz
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee from this act)
    Branch: claude/issue-23577-sealed-first-write-texts (PR-1 only; the presentation writes no code)
    Worktree: objectstack-issue-23577
    Domain: domain:spec
    Seat: domain:spec#3 (seat post #18883)
    File surface for PR-1 (at origin/main after PR #23565 lands; stop on a breach and explain it in the report): packages/metadata-protocol/src/protocol.ts (the ## create section of packagedBaseRefusal's docblock, above ~17457 on main c980d114d), packages/runtime/src/domains/permission-set-clone.ts (its lost-race 409 message), their tests, .changeset/23577-*.md. ⛔ No protocol change in PR-1: position 1 waits on the maintainer.
    Container & model: S for PR-1, mode:subagent, model: default (no path-derived mandate); the position 1 measurement is a read-only analysis
    Clause-②: no (PR-1)
    Responsibility: n/a — positions read at PR #23565's contract round; position 3's message is that PR's
    Thread-read: 6182601940
    Serial constraints cleared: PR #23565 (domain:engine seat 2, #23406) is open and changes protocol.ts (hunks from ~17805) and the clone door's 409 text that position 3 names; PR-1 is dispatched after it lands, on its merged text. Open PRs #23504 and #23469 touch protocol.ts far from packagedBaseRefusal (hunks from ~25889 and elsewhere).

    Read on origin/main c980d114d at 2026-10-15T02:12Z: packagedBaseRefusal at protocol.ts:17457 takes operation: 'save' | 'create' | 'delete'.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    待裁:#23577 position 1 · 封存条目上的 /meta 首写,门如何区分「新建」与「编辑」 · domain:spec seat 3 · 2026-10-15T02:23Z

    Session session_01D6F9axfoPzR7t8G1J7Ytzz · baozhoutao. Presentation per triage 6182601940 (position 1 to a decision; ⛔ not designed inside a fix PR). Facts are read from source at main c980d114d3, PR #23565 head 6f79997618 and objectui pin b9814b334d; nothing was run end to end.

    维护者速读

    Facts (cited)

    1. What fix(metadata-protocol): a first draft of a sealed package-shipped item names the edit remedy; a refused first-write pin's 409 states its assertion #23565 changes. sealedWrite becomes parentVersion === null && mode !== 'draft' ? 'create' : 'save' (protocol.ts:21900-21901 @6f79997618; main :21911 reads parentVersion === null ? 'create' : 'save'). A draft * over a held name now reads the edit remedy; a publish * keeps the create remedy. Its contract record 6182096728 and seat adoption rule A: "a publish-mode first write keeps the create remedy … B needs a declared create fact." No packages/spec file moves.
    2. The two remedies (packaged-base-regime.ts): create — "…its name is taken. To author your own ${singular}, choose a name no package or built-in holds (GET /api/v1/meta/${singular} lists the names in use)" (:371-372); edit — "…sealed against in-place edits: … Edit the source artifact and redeploy" (:400-410). Neither names the holding package.
    3. The read that leads a client to the pin. Uncached reads (cache off, ?package=, ?state=draft, member address, app/dashboard/book/doc) serve version: null for an artifact item with no stored row (protocol.ts:11281); the same read serves editable: false for a sealed item (:17547-17548). GetMetaItemResponseSchema.version's describe says null ⇒ "the next save creates one: pin it with If-None-Match: *" (packages/spec/src/api/protocol.zod.ts:562-578), repeated at MetadataConflictErrorSchema.currentVersion (:987-992).
    4. The door. A sealed item (isArtifactBacked && !registryAllowsOverlay, protocol.ts:17194-17197) is refused 403 NOT_OVERRIDABLE (:17990-18064) whatever the save; only the remedy sentence depends on sealedWrite. On overlay types (view, dashboard, report, translation, email_template) the same * is a legitimate first overlay row, i.e. an edit, so the pin already carries two meanings.
    5. Producers. objectui sends ifNoneMatch: '*' only with mode: 'draft' (ResourceEditPage.tsx:1644-1654, StudioDesignSurface.tsx, ObjectHooksPanel.tsx:365, DraftConflictDialog.tsx:112-137), for creates and for first drafts of existing items alike. @objectstack/client cannot send If-None-Match on a save (packages/client/src/index.ts:722-820). No CLI, MCP, service or plugin publish * save; the permission-set clone (parentVersion: null) refuses a taken name with its own 409 first and reaches the sealed door only through a race. The console edit path treats a sealed artifact item as read-only (ResourceEditPage.tsx:1460-1466).
    6. The live path. The console's Setup positions page is the generic metadata-admin page (apps/console/src/AppContent.tsx:167-170); its create sends draft * with no name pre-check. metadata-protocol: a refused save of a package-held position name tells the author to "Edit the source artifact and redeploy", which is wrong for a create, where the remedy is a name no package or built-in holds #22591's original producer (Setup position write-through) is retired (.changeset/pre/15204-7b-position-write-through-retired.md), so this console create is the path metadata-protocol: a refused save of a package-held position name tells the author to "Edit the source artifact and redeploy", which is wrong for a create, where the remedy is a name no package or built-in holds #22591's create remedy serves today. fix(metadata-protocol): a first draft of a sealed package-shipped item names the edit remedy; a refused first-write pin's 409 states its assertion #23565's unit block pins this request for position (protocol.sealed-remedy-kind.test.ts:210-216).
    7. The create operation's producers. Outside protocol.ts, packagedBaseRefusal is called only by runtime/src/domains/automation.ts:1551 with 'save' | 'delete'; the create arm is produced only by sealedWrite's inference.
    8. Spelling precedents for a declared create. The ?mode= query enum on the same door (protocol.zod.ts:826); the clone route's own name-taken refusal; no POST /meta/:type create route exists.

    Options

    Four-axis analysis

    • Real business need. A measured first-party pull exists for one path only: the console create under a held name (fact 6). A1 and A2 serve it precisely; B serves it with a true fact and the listing route; B0 misdirects it. The publish-side editor is theoretical (no producer found).
    • Long-term soundness. A1 is the contract-first statement of intent. A2 overloads a precondition header with intent, varying by type regime: a standing ambiguity worked around in prose. B is minimal and sound: it states only facts the door holds and retires an arm no caller produces truthfully; a future create door can bring back a create-specific sentence when it ships. B0 keeps two inferred readings, each wrong for some caller.
    • Making AI mistakes harder. B is strong: no sentence prescribes an act the caller did not declare, editable: false is the loud signal, and the docblock stops prescribing a pin for an item that takes no save. A1 is strongest only if enforced, and weak as advice. A2 is weakest: an AI following version: null → If-None-Match: * is told to make a second item.
    • No requirement creep at the startup stage. B narrows (retires a zero-consumer arm immediately, adds no gate or key). A1 widens (a new key and a two-repo client change) for a pull that B already satisfies. A2 adds nothing but reverts a fix about to land. B0 is cheapest now and leaves the defect.

    Recommendation: B. It is correct for every caller that measurably reaches the door, with Clause-②: no and no new key. Axis conflict: on business need, the console creator is served more precisely by an explicit "choose another name" (A1); if that precision is wanted, take A1 with an enforced declaration and the objectui change scheduled.

    Open unknowns: nothing observed end to end; whether other objectui create surfaces pre-check names; external third-party clients are not visible; the cost of naming the holding package in a B sentence; the runtime dispatcher's /meta PUT door was not re-traced separately.

    After the ruling: the card returns to pm:queue and one PR (Fixes #23577) carries the ruled position 1 change together with positions 2 and 3. Under B or A1 it supersedes #23565's draft/publish split; under B0 it lands after #23565. This act moves the card to needs-user-decision and clears its assignee.


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    待裁补充:PR #23565 已落 · domain:spec seat 3 · 2026-10-15T02:31Z

    PR #23565 merged as 3b289052a at 2026-10-15T02:31Z. 由此 main 上的现状即选项 B0 的前半:控制台通用新建页(Setup 岗位)以 mode: 'draft' + If-None-Match: * 在已被包占用的名字上新建,现在读到的是「Edit the source artifact and redeploy」(管理员做不到);发布侧仍读「choose a name no package or built-in holds」。上方 A1 / A2 / B 的取舍不变,只是「取代/回滚 #23565」现在指对 main 的改动。请回 A1 / A2 / B / B0 之一。


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Decision-box entry: passes once completed · the four facets added · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-15T03:00Z

    Entry check on 6182970120 and its addendum 6183067442 (domain:spec seat 3). These are present:

    • the speed read with the one-word ask (A1 / A2 / B / B0);
    • the facts with citations;
    • the options, the recommendation (B) and the timing.

    The four-facets block was missing, so this seat completes it below from the presentation's own facts. The card is p1 + target:v18.

    Since PR #23565 landed (3b289052a, 02:31Z), the measured caller now reads the wrong remedy on main. That caller is the console's generic create page (Setup positions), with mode: 'draft' and If-None-Match: *. It is told to "edit the source artifact and redeploy", which an administrator cannot do. So the answer is time-sensitive.

    os-decision-facets

  6. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    席位意见(增量)· director seat (summon #37 continuation 2, session_01LqNgdPZB2Jnr5HpGbaqLeB), read as batch #348 item 1, 2026-10-15T04:48Z

    Premises re-run on origin/main 8d05456cb: PR #23565 is merged (3b289052a, +314/−19, 6 files), so main carries the mode-aware split: sealedWrite at packages/metadata-protocol/src/protocol.ts:21942 and refusePackagedBaseOverride(request, sealedWrite) at :22115; outside protocol.ts the only packagedBaseRefusal( caller is runtime/src/domains/automation.ts:1553 with 'save' | 'delete', so the create arm is produced by the inference alone; the two remedy sentences stand in packaged-base-regime.ts; permission-set-clone.ts carries no If-Match (position 3's sentence is the protocol's conflict text, not the clone's). Prior rulings (check-prior-rulings --card 23577): 195 candidates; ADR-0070 D1 and ADR-0131 D3 are term matches, none decides the remedy. The presentation carries no workload column; it is added below.

    Facets: ① agree (the door states what it knows; a create door, when it ships, brings its own sentence; A1 widens the accept set for a pull B already serves; A2 puts intent back onto the OCC header, which on overlay types already means "first overlay row", an edit) · ② agree, and time-sensitive: since 3b289052a the console's generic create (Setup positions, mode: 'draft' + If-None-Match: *) reads "edit the source artifact and redeploy", which an administrator cannot do · ③ agree · ④ agree.

    Recommend B, fallback A1, with 口径 for the executor:

    1. One sentence for every write over a sealed held name, stating the fact and the listing route: "'position/manager' is provided by a managed package and is sealed: it cannot be written here. GET /api/v1/meta/position lists the names in use." It names the holding package only when the door already has the artifact's package at hand (the dev measures; no extra lookup is added for it).
    2. sealedWrite, the create arm of SealedItemOperation and packagedBaseRefusal's 'create' member retire in the same PR (zero producers after the change); the version and currentVersion docblocks (packages/spec/src/api/protocol.zod.ts) say a null beside editable: false takes no save and prescribe no pin for it.
    3. Positions 2 and 3 ride the same PR; Clause-②: no; the spec docblock hunk is published schema prose, so the PR's contract review is at CONTRACT_REVIEW_TIER by face.
    4. Pins: the console create over a held name (draft + *) and a publish-mode * over a sealed item both read the one sentence; the overlay-type first write (view) still succeeds.

    Workload (added): B = domain:spec · 1 PR (protocol.ts refusal and retirements, packaged-base-regime.ts, two spec docblocks, pins) · precedent PR #23565 (+314/−19, 6 files). A1 = 1 spec PR (new key, describe, REST/dispatcher parity, docs, changeset) + 1 objectui PR + @objectstack/client · no precedent. A2 = 1 PR reverting #23565's split plus the docs. B0 = 1 small PR (positions 2 and 3 only).

    自检:只看①选 B;②③④ 是否翻转:否。

  7. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #348 item 1 · letter B · maintainer 「同意」 2026-10-15T05:00Z

    Director seat, summon #37 (continuation 2), session_01LqNgdPZB2Jnr5HpGbaqLeB, on the seat's presentation 6182970120 and its addendum 6183067442 (recommendation B, fallback A1), triage's entry 6183409695 (the four facets) and the seat's delta 6184655968; the maintainer's 「同意」 takes the recommendation.

    What the ruling binds (letter B):

    1. Every write over a sealed, package-held name is refused with one sentence that states what the door knows and where the names are listed: "'/' is provided by a managed package and is sealed: it cannot be written here. GET /api/v1/meta/ lists the names in use." It names the holding package only when the door already has the artifact's package at hand; no lookup is added for it. No create advice and no source-artifact advice.
    2. sealedWrite, the create arm of SealedItemOperation and packagedBaseRefusal's 'create' member retire in the same PR (no producer remains); the version and currentVersion docblocks in packages/spec/src/api/protocol.zod.ts say that a null beside editable: false takes no save and prescribe no pin for it.
    3. Positions 2 and 3 (the stale ## create docblock; the clone's lost-race 409 naming an If-Match the clone door does not take) ride the same PR. Clause-②: no; the spec docblock hunk is published schema prose, so the PR's contract review is at CONTRACT_REVIEW_TIER by face.
    4. Pins: the console's generic create over a held name (mode: 'draft' + If-None-Match: *) and a publish-mode * over a sealed item both read the one sentence; an overlay type's first overlay write (view) still succeeds. fix(metadata-protocol): a first draft of a sealed package-shipped item names the edit remedy; a refused first-write pin's 409 states its assertion #23565's draft/publish unit block re-points to the one sentence.

    Workload of the letter: domain:spec · 1 PR (protocol.ts refusal and retirements, packaged-base-regime.ts, two spec docblocks, the pins) · precedent PR #23565 (+314/−19, 6 files).

    Execution: this card is the execution card: needs-user-decision removed and pm:queue added in this act for domain:spec (priority:p1 + target:v18 stand; time-sensitive: the console create reads the wrong remedy on main since 3b289052a); the body's first line carries Ruled:. One PR, Fixes #23577.

  8. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 2 (second shift) · 2026-10-15T05:17Z · ruling 6184789291 (batch #348 item 1, letter B): the one-sentence sealed refusal, the inferred create arm retired, the two spec docblocks, positions 2 and 3, the pins. One PR, Fixes #23577.
    Session: session_01LFqdRsuM5nkqoJdHd5ztVk (the seat; the dev is a cloud session whose draft PR carries its own session link)
    Account: os-bill (the seat's linked user as GET /user answers it; always the card's assignee)
    Branch: claude/issue-23577-sealed-write-one-sentence
    Worktree: objectstack-issue-23577
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface (at origin/main dd4ef3850 or later; stop on a breach and explain it in the report):

  9. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23577,
      "status": "done",
      "branch": "claude/issue-23577-sealed-write-one-sentence",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23626",
      "session": "session_01M83DE8c8ySe7XfBTNTxzFd",
      "premise_still_valid": true,
      "summary": "Ruling 6184789291 letter B executed. For a type with no regime row, every write over a sealed package-held name now reads one sentence: 'TYPE/NAME' is provided by a managed package and is sealed: it cannot be written here. GET /api/v1/meta/TYPE lists the names in use. This holds for the console create (draft + If-None-Match *), a publish *, and unpinned and pinned saves, at both the protocol package door and the repository type door. Code NOT_OVERRIDABLE and status 403 are unchanged. Retired: sealedWrite, the 'create' member of packagedBaseRefusal, SealedItemOperation's create arm, heldNameSentence, and the operation params of refusePackagedBaseOverride and tenantAuthoredWriteRefusal. Position 2: the ## create docblock is replaced. The spec version and currentVersion describes now say a null beside editable:false takes no save and prescribe no pin for it. Position 3: the clone door rethrows a METADATA_CONFLICT from its create-only save as its own name-taken 409 (RESOURCE_CONFLICT, no If-Match); the /meta conflict sentence is unchanged. Hypothesis readings. H1: no packages/spec schema declares an operation detail. The removed operation spread was an argument to tenantAuthoredWriteRefusal, never an error detail. Searched NOT_OVERRIDABLE in packages/spec/src: 3 ledger rows plus prose, no details shape. H2: SealedItemOperation is not exported (packages/metadata-protocol/src/index.ts exports only ObjectStackProtocolImplementation and siblings from protocol.js). packagedBaseRefusal and tenantAuthoredWriteRefusal are public methods of the exported class, so their param narrowing is named in the changeset. automation.ts is untouched. H3: the package is not at hand. refusePackagedBaseOverride asks isSealedManagedItem, a boolean. isArtifactBacked discards the lookupArtifactItem result. assertAllowed gets the intent only. So the sentence names no package and no lookup is added. H4: the 409 text is built in protocol.ts metadataConflictRefusal (firstWritePin branch) and reaches the clone via saveMetaItem parentVersion null and errorFromThrown. The fix is at the clone door. H5: confirmed by a real write-path pin: a view first write pinned * lands an overlay row. H6: .describe() texts. Regenerated content/docs/references/api/protocol.mdx only, via check:generated --fix.",
      "tests": "Run at heads 9ec5053e and 3f354c73 (the latter adds only the rest test file). Closure build runtime^... + runtime: VERDICT command-exit 0. typecheck spec, metadata-protocol, runtime: exit 0. metadata-protocol test: 236 files passed, 3 skipped; 28418 tests passed. runtime test: 383 files, 5773 tests passed. spec test: 678 files, 20728 tests passed. rest test at 9ec5053e: 1 failed file (rest-meta-sealed-first-draft-remedy.test.ts, #23565's REST pin, missed by my first grep), 284 passed. CI Test Core 5/6 caught the same file. Re-pointed in 3f354c73, now 6/6 with rest-meta-packaged-flow-refusal. objectql protocol-commit-history.test.ts: 30/30. Ablations, committed first, via scripts/ablation-replace.mjs, each restored with blob == HEAD and an empty git diff HEAD. Clone guard renamed: predicted 1 red, measured 1 failed / 22 passed. Sentence-builder save branch disabled: predicted the row-less pins red, measured 7 failed / 6 passed; flow, reach, removal and the view control stayed green.",
      "gates": "Local union on 9ec5053e: 122 derived, plus 5 roster families under my paths, run sequentially with exit codes captured before any pipe. dispatch-gates --ran with exit-code records: 122 derived accounted, 121 run, 1 NOT-MEASURED (check-plugin-teardown-shape --self-test, exit 3, shallow clone). check-engine-split-ratio exited 2 on a shallow-clone refusal: NOT MEASURED, reason shallow checkout. All others exit 0, including the 5 rosters. First run at 51f2e48b: check:durability-log-level and check:engine-double-contract were real reds. Fixed in 9ec5053e (rethrow to the door's one errorFromThrown; ledger --write rows) and green after. On 3f354c73 the derivation was unchanged; re-ran cross-package-test-inputs, test-source-alias, engine-double-contract, durability-log-level, tier-file-adoption and nul-bytes: all exit 0. CI on 9ec5053e at report time: success for TypeScript Type Check, Lint and Repo Gates, Build Core, Build Docs, Governed Surface Queue Guard, Check Changeset, every Lint and Type Check lane, and Test Core 1/6 and 6/6. Test Core 5/6 failed on @objectstack/rest (the file fixed in 3f354c73). Test Core 2/6, 3/6 and 4/6 were in_progress. CI on 3f354c73 is in_progress.",
      "mcp_calls": "5 — issue_read x2 (get, get_comments), pull_request_read x1 (get_check_runs), get_job_logs x1, plus ToolSearch schema loads (not GitHub calls). No write tool.",
      "api_writes": "2 — fleet-write relay strokes: pr_create (POST /repos/objectstack-ai/objectstack/pulls draft, then POST issues/23626/assignees os-bill), and this comment (POST /repos/objectstack-ai/objectstack/issues/23577/comments). git push is not counted.",
      "line_budget": "PR diff about 13 files (14 at 3f354c73), under the 3000-line human-merge threshold (582 changed lines measured at 51f2e48b).",
      "deviations": [
        "The PR body was written once at 9ec5053e and was not PATCHed. Its Verification section predates 3f354c73: it lists the rest pins as 4/4 only, and does not name rest-meta-sealed-first-draft-remedy.test.ts as re-pointed. Seat amendment if wanted: add that file to Pins, and record the CI Test Core 5/6 red at 9ec5053e and its fix in 3f354c73.",
        "Harness attribution asked for a model-named Co-Authored-By trailer. AGENTS.md wins: the commits carry the model-free pair."
      ],
      "files_changed": [
        ".changeset/23577-sealed-write-one-sentence.md",
        "content/docs/references/api/protocol.mdx",
        "packages/metadata-protocol/src/packaged-base-regime.ts",
        "packages/metadata-protocol/src/protocol.ts",
        "packages/metadata-protocol/src/protocol.sealed-remedy-kind.test.ts",
        "packages/metadata-protocol/src/protocol.packaged-base-refusal.test.ts",
        "packages/metadata-protocol/src/sys-metadata-repository.package-writability.test.ts",
        "packages/objectql/src/protocol-commit-history.test.ts",
        "packages/rest/src/rest-meta-packaged-flow-refusal.test.ts",
        "packages/rest/src/rest-meta-sealed-first-draft-remedy.test.ts",
        "packages/runtime/src/domains/permission-set-clone.ts",
        "packages/runtime/src/domains/permission-set-clone.test.ts",
        "packages/spec/src/api/protocol.zod.ts",
        "scripts/engine-double-contract.pinned.json"
      ],
      "open_questions": [
        {
          "question": "Ruling item 1 says every write over a sealed package-held name reads one sentence. Should types with a regime row (flow, action, permission: Regime C; datasource: origin-gated) also read it?",
          "options": [
            "A: keep the regime sentences, as implemented. ADR-0126 §2 requires a Regime C refusal to name its sanctioned path, and those sentences carry neither create nor source advice. datasource items are code-defined, not package-held.",
            "B: replace them with the one sentence too. That needs an ADR-0126 §2 amendment (AGENTS #13).",
            "C: the one sentence plus the regime's sanctioned path."
          ],
          "recommendation": "A. Long-term: an accepted ADR binds. AI-error axis: the sanctioned path is the loud, correct remedy. Business need: the measured caller (Setup positions) is row-less and reads the ruled sentence. Startup focus: no ADR churn."
        },
        {
          "question": "The ITEM_LOCKED named-base limb (readOnlyBaseOverrideError, a write that names a read-only base package) still prescribes 'Edit the source artifact and redeploy'. It has a different code, and here the door does have the package at hand. Bring it into line?",
          "options": [
            "A: leave it; out of the ruling's NOT_OVERRIDABLE scope",
            "B: a follow-up card to apply the one-sentence principle there"
          ],
          "recommendation": "B, filed by the seat if wanted. Same family as this card; no producer of a named read-only-base write was measured."
        },
        {
          "question": "The unreleased .changeset/23406-sealed-first-draft-remedy.md describes the split this PR supersedes. Amend it?",
          "options": [
            "A: leave it; this PR's changeset says it supersedes that entry",
            "B: edit 23406's changeset in this PR"
          ],
          "recommendation": "A. The ruling's file surface does not name it. Both entries ship in one release."
        }
      ],
      "out_of_scope_findings": [
        "carrier: none · noted, not filed — ITEM_LOCKED named-base sentence keeps the source-artifact remedy (sys-metadata-repository.ts readOnlyBaseOverrideError); see open_questions 2"
      ]
    }

    Generated by Claude Code

  10. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23577,
      "status": "done",
      "round": "changeset patch (seat Q3 = B, AGENTS.md:711)",
      "branch": "claude/issue-23577-sealed-write-one-sentence",
      "head": "f0761ed3",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23626",
      "session": "session_01M83DE8c8ySe7XfBTNTxzFd",
      "files_changed": [
        ".changeset/23406-sealed-first-draft-remedy.md",
        ".changeset/23577-sealed-write-one-sentence.md"
      ],
      "before_after": [
        "23406 title: 'a first draft of a sealed, package-shipped item is told to edit the source artifact, not to choose another name; a refused first-write pin is told what it asserted' -> 'a refused first-write pin is told what it asserted'",
        "23406 What was wrong: the remedy-split paragraph (draft pinned If-None-Match * read the create remedy; unpinned read edit source artifact) -> one paragraph on the 409 METADATA_CONFLICT pin text that used to read 'TYPE/NAME has been modified since you loaded it. Expected parent null but current is VERSION.' though the caller loaded nothing",
        "23406 What changed: first bullet (first draft names the item's own remedy; publish * still names a free name) deleted; second bullet (the first-write-pin 409 sentence) kept, reworded to stand alone",
        "23406 Unchanged line: kept verbatim",
        "23577: deleted the sentence 'This supersedes the draft/publish split described in this release's earlier entry for the first-draft remedy.'"
      ],
      "gates": [
        "node scripts/check-empty-changeset.mjs --base origin/main :: exit 0",
        "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0",
        "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0",
        "pnpm changeset status --since=origin/main :: exit 0",
        "node scripts/check-closing-keyword-parity.mjs :: exit 0",
        "node scripts/check-changeset-fixed.mjs :: exit 0"
      ],
      "code_change": "none",
      "api_writes": "1 this round: fleet-write comment POST /repos/objectstack-ai/objectstack/issues/23577/comments (this comment); total for the card: 3",
      "mcp_calls": "0 this round; total for the card: 4"
    }

    Generated by Claude Code

  11. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT → PR #23626 comment 6186492810 · domain:spec seat 2 · session session_01LFqdRsuM5nkqoJdHd5ztVk · 2026-10-15T07:04Z · on f0761ed3, after a CI-red REST pin fix and a changeset round (the unconsumed 23406 entry amended in place, no erratum); open questions Q1 A · Q2 noted, not filed · Q3 B; contract review at CONTRACT_REVIEW_TIER before ready.

  12. objectstack-fleet commented on Oct 15, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 23577,
      "status": "done",
      "round": "changeset patch 2 (contract review 6186902880, FAIL on semver level)",
      "branch": "claude/issue-23577-sealed-write-one-sentence",
      "head": "26a5eb92",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/23626",
      "session": "session_01M83DE8c8ySe7XfBTNTxzFd",
      "files_changed": [
        ".changeset/23577-sealed-write-one-sentence.md"
      ],
      "before_after": [
        "frontmatter: '@objectstack/metadata-protocol': patch -> minor (runtime and spec stay patch)",
        "added after the Clause-② line: one ADR-0087 marker, not-required (runtime-interface-only packages/metadata-protocol/src/protocol.ts#ObjectStackProtocolImplementation), whose why says no metadata, spec key, stored row or authorable spelling moves and that the compiler is the channel",
        "added: a **BREAKING** paragraph (public method-signature narrowing, shipped as minor under the launch-window convention). It names the retired 'create' member of packagedBaseRefusal's operation and the retired optional operation parameter of tenantAuthoredWriteRefusal; a caller passes 'save' (or omits operation); verdict, code and status unchanged",
        "metadata-protocol retired bullet: the migration sentence moved under BREAKING; the bullet now points there and keeps the internal SealedItemOperation create arm",
        "runtime bullet: 'code RESOURCE_CONFLICT' -> 'code RESOURCE_CONFLICT, where it used to answer code METADATA_CONFLICT'",
        "Clause-②: no unchanged; .changeset/23406-sealed-first-draft-remedy.md untouched"
      ],
      "gates": [
        "node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0 (1 declared-breaking changeset; not-required (runtime-interface-only) verified: protocol.ts#ObjectStackProtocolImplementation (class))",
        "node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0",
        "node scripts/check-empty-changeset.mjs --base origin/main :: exit 1, one error only, the expected one: .changeset/23406-sealed-first-draft-remedy.md exists on the merge base and was not added by this PR (DELIBERATE CORRECTION class, confirmed by the seat)",
        "pnpm changeset status --since=origin/main :: exit 0"
      ],
      "note": "The first gate pass ran before the commit and read the committed HEAD, so the ADR gate saw no breaking changeset; the numbers above are from after the commit.",
      "code_change": "none",
      "api_writes": "1 this round: fleet-write comment POST /repos/objectstack-ai/objectstack/issues/23577/comments (this comment); card total 4",
      "mcp_calls": "0 this round; card total 4"
    }

    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

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions