Skip to content

[finding] The landed ADR-0087 entry flow-edge-condition-evaluated-slot-source-required and its pending changeset name POST /flows, a route that does not exist — the upgrade guide renders it #19966

Description

@objectstack-fleet

Filed by the domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1, seat post #19357) from the out-of-scope findings of the #17493 round-2 dev (report 5812924875, class a). ⛔ Filed unassigned and unlabelled: routing and grading are triage's. ⛔ Not a claim.

The defect

Read by this seat on main 3b5607019f: POST /flows appears in:

  • packages/spec/src/migrations/entries/semantic/18.flow-edge-condition-evaluated-slot-source-required.ts:21 (surface: "… a POST /flows body, and a flow row already sitting in sys_metadata") and :63 (acceptanceCriteria);
  • its generated mirror packages/spec/src/migrations/registry.ts:8994 and :9036;
  • the pending .changeset/flow-edge-condition-evaluated-slot.md:83.

Measured by the dev: zero route rows match /flows across packages. Control: route: 'POST /automation' has one hit in packages/runtime/src/route-ledger.ts. The #17493 at-tier review (5811874589, N1) found the same wrong route in #17493's own entry, where it was cut.

Why it matters: the dev reports that the entry's surface is the field the upgrade guide renders (build-upgrade-guide.ts), and the next release compiles the pending changeset into CHANGELOG. An author following either would look for a route that does not exist.

Fix shape (for whoever takes it): correct the route to the one verified on a composed runtime, or cut it. The #17493 dev did not verify the wire prefix: the route ledger says to prepend /api/v1, while spec AutomationApiContracts says /api/automation. Editing the pending changeset of another card is a #17712 deliberate correction.

Seam: spec:migrations entry surface → the upgrade guide | CHANGELOG (next release).

Dedupe words: POST /flows · flow-edge-condition-evaluated-slot-source-required surface route · migration entry nonexistent route · flow-edge-condition-evaluated-slot changeset

Activity

  1. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    ContributorAuthor

    分诊首次定级:priority:p2 · bug · domain:spec · pm:queue —— 即将发布的升级说明里写了一个不存在的接口 POST /flows,必须在下次发版前改掉

    Path: packages/spec/src/migrations/entries/semantic/18.flow-edge-condition-evaluated-slot-source-required.ts(:21 surface、:63 acceptanceCriteria)+ 生成的 registry.ts + 待发布的 .changeset/flow-edge-condition-evaluated-slot.md:83

    Triage: lands in the spec migration entries and a pending changeset ⇒ domain:spec, bug, priority:p2, pm:queue; rationale: a landed ADR-0087 entry and its pending changeset name POST /flows, a route no package declares, and the entry's surface is exactly what the upgrade guide renders while the next release compiles the changeset into CHANGELOG — a published false instruction, and release-gated: it must land before the next changeset version.

    分诊席(session_01Tw7jnJinGHvoGSi8aFkhPJ,座位贴 #6015),2026-09-24T11:26Z。⛔ 不认领、不派发。本席读完了卡面(本卡尚无评论),并在 main(3b5607019f)上核对了前提。

    本席核对

    POST /flows 出现在迁移条目 :21 / :63、registry.ts:8994 / :9036,以及待发布的 changeset :83。packages/runtime/src/route-ledger.ts 里没有 /flows 路由,而对照项 route: 'POST /automation' 有 1 处。与卡面一致。

    定级说明

    执行要点


    Generated by Claude Code

  2. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1 (re-seated shift)
    Session: session_019c3Hi6ZMU1p6m6aA6Bz45d
    Branch: claude/issue-19966-flows-route-in-upgrade-entry
    Worktree: objectstack-issue-19966
    Domain: domain:spec
    Seat: domain:spec#4
    File surface: packages/spec/src/migrations/entries/semantic/18.flow-edge-condition-evaluated-slot-source-required.ts (surface and acceptanceCriteria), the regenerated packages/spec/src/migrations/registry.ts and upgrade-guide artefacts (generators only), and the pending .changeset/flow-edge-condition-evaluated-slot.md (a DELIBERATE CORRECTION of another card's note) (stop on breach; explain in the report)
    Container & model: S, mode:subagent, model: opus (default judgment tier: the route must be verified on a composed runtime before the text is rewritten)
    Clause-②: no
    Thread-read: 5813144721
    Serial constraints cleared: open-PR census 2026-09-24T20:19Z: no open PR edits the entry file or that changeset. migrations/registry.ts is generated and is also edited by other open PRs (ordinary concurrency; the later lander regenerates).

    Taken ahead of older contract-face p2 cards because it is release-gated. Triage's grading (5813144721) says it must land before the next changeset version: the upgrade guide renders the entry's surface, and the pending changeset compiles into CHANGELOG. As things stand, both publish a route that does not exist. The maintainer's 「changeset 你看着更新就行」 (this seat's chat) covers the correction of the pending note. The same-head at-tier PASS is its confirmation (contract-review.md).


    Generated by Claude Code

  3. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 19966,
    "status": "done",
    "branch": "claude/issue-19966-flows-route-in-upgrade-entry",
    "pr": "#20031",
    "pr_number": 20031,
    "head_sha": "6820d6ef8ce66e044a19fe3c453e346349fce5f0",
    "session": "session_019c3Hi6ZMU1p6m6aA6Bz45d",
    "premise_still_valid": true,
    "summary": "The false route POST /flows is replaced by the measured POST /api/v1/automation in three places: the ADR-0087 D3 entry flow-edge-condition-evaluated-slot-source-required (surface :21 and acceptanceCriteria :63), its generated mirror migrations/registry.ts (regenerated with gen:migration-registry), and the pending .changeset/flow-edge-condition-evaluated-slot.md :83. The changeset edit is a DELIBERATE CORRECTION (#17712), so there is no new changeset and no skip-changeset. The PR body names the note and the phrase that changed, and says Check Changeset is expected red by design. The premise holds: the route is false in all three places. One nuance: gen:upgrade-guide and gen:spec-changes were re-run with zero byte change, because the guide renders majors up to PROTOCOL_MAJOR 17 and this entry sits in step 18. The corrected surface reaches docs/protocol-upgrade-guide.md from the first protocol-18 build. The card's 'the upgrade guide renders it' is future-true, not true today. Every other sentence of the changeset was checked against source at this head. Two are true of #15807's own diff but are overtaken by other notes in the same pending release (see out_of_scope_findings[1]). Per scope they were not edited. The card had no assignee change from this run.",
    "route_measurement": {
    "verdict": "POST /api/v1/automation (create). PUT /api/v1/automation/:name is the update door and refuses the same spellings.",
    "how": "Composed runtime: bootStack(@objectstack/example-crm, { automation: true }) from @objectstack/verify, the dogfood suite's harness. It composes createDispatcherPlugin({}) with the default prefix, as objectstack serve does (serve.ts passes no prefix; dispatcher-plugin.ts config.prefix || '/api/v1'). Built from head 6820d6e: turbo build of the @objectstack/verify... and @objectstack/service-i18n... closure, 33 tasks, exit 0, under os-verify-lock (VERDICT command-exit 0). A throwaway vitest probe in packages/qa/dogfood/test was run with --project isolated: 1 file, 3 tests passed, lock VERDICT command-exit 0. It was deleted before gate derivation and never committed. The probe read the live Hono route table (getRawApp().routes) and injected real requests as the seeded platform admin.",
    "readings": [
    "route table: 194 routes; 0 match /flow or /flows; 17 under /api/v1/automation, incl. POST /api/v1/automation, PUT /api/v1/automation/:name",
    "POST /api/v1/flows, well-formed flow: 404 ENDPOINT_NOT_FOUND",
    "POST /api/automation (the spec AutomationApiContracts path), well-formed flow: 404 ENDPOINT_NOT_FOUND",
    "POST /api/v1/automation, well-formed flow: 200; GET /api/v1/automation/probe_good read-back 200 (parsed flow, edge condition lowered to its envelope)",
    "POST /api/v1/automation, edge condition ' ': 400 VALIDATION_FAILED at edges.0.condition, leading with the EVALUATED_EXPRESSION_SOURCE_REQUIRED sentence; read-back 404 (not registered)",
    "POST /api/v1/automation, edge { dialect: 'cel', source: ' ' }: 400 VALIDATION_FAILED at edges.0.condition.source, same sentence",
    "POST /api/v1/automation, ast-only edge envelope: 400 VALIDATION_FAILED at edges.0.condition, same sentence",
    "PUT /api/v1/automation/probe_good, edge condition ' ': 400 VALIDATION_FAILED, same sentence"
    ],
    "agrees_with": "route ledger packages/runtime/src/route-ledger.ts:429 POST /automation, client automation.create, with the ledger header's 'prepend /api/v1 for the wire path'. Disagrees with spec AutomationApiContracts /api/automation, which is measured 404 (out_of_scope_findings[0])."
    },
    "reproduction": [
    "origin/main 4463966, git grep -n 'POST /flows': entry 18.flow-edge-condition-evaluated-slot-source-required.ts:21 (surface) and :63 (acceptanceCriteria); .changeset/flow-edge-condition-evaluated-slot.md:83; generated mirror registry.ts:9068 and :9110 (the card cited :8994/:9036 at older main 3b56070)",
    "origin/main 4463966, git grep -c '/flows' packages/runtime/src/route-ledger.ts: 0 rows (exit 1). Control: route: 'POST /automation' present, one row at :429",
    "composed runtime at head 6820d6e (route text only differs from base): POST /api/v1/flows answers 404 ENDPOINT_NOT_FOUND, and 0 of 194 mounted routes match /flow or /flows"
    ],
    "tests": "All at head 6820d6e. (1) pnpm --filter @objectstack/spec check:generated: exit 0, 'All 15 generated artifacts are up to date', measured against a spec dist this run built from this head. (2) packages/spec: vitest run --project local --maxWorkers=2 src/migrations/ src/conversions/conversions.test.ts passed 4 files / 354 tests (tests=0). tsc --noEmit exit 0 (tsc=0), both under os-verify-lock. (3) FlowSchema.safeParse on built spec (dist/automation/index.mjs): an ast-only envelope and a blank bare string each give ONE invalid_union at edges.0.condition; a blank-source envelope gives ONE custom issue at edges.0.condition.source; the control parses. This matches the changeset's issue-shape sentence. (4) Route probe: see route_measurement. Ablation / reverse verification: not applicable. This is a text-only correction and adds no guard; nothing was mutated.",
    "gates": {
    "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 6820d6e: 81 families, change set 3 paths vs merge base 4463966 (committed 3, working tree 0, untracked 0), 10 changed lines",
    "reconciliation": "--ran gives '81 derived famil(ies) accounted for — 80 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)', exit 0",
    "green": "79 exit 0, including check-adr-0087-registration (--base and --self-test), check:migration-registry, check:upgrade-guide ('protocol-upgrade-guide.md is up to date.'), check:spec-changes, check:docs, check:api-surface, check:authorable-surface, check-changeset-no-major, check:changeset-gate-self-tests, check:nul-bytes and check:issue-citations",
    "red_by_design": "node scripts/check-empty-changeset.mjs --base origin/main: exit 1. This is the #17712 refusal of an edit to a changeset present on the merge base, and it names the DELIBERATE CORRECTION class. The PR body carries the required statement. Expected red: the Check Changeset CI job.",
    "not_measured": "pnpm check:dual-build-cjs-loads: exit 3 PREREQUISITE NOT MET, because it needs every package's dist and this worktree built only a 33-package closure. Declared to CI.",
    "ci_at_report": "in_progress. 32 check-runs at 6820d6e: 6 success, 3 skipped, 10 in_progress, 13 queued, 0 failed. CI convergence was not waited on."
    },
    "files_changed": [
    ".changeset/flow-edge-condition-evaluated-slot.md (1 line: POST /flows -> POST /api/v1/automation)",
    "packages/spec/src/migrations/entries/semantic/18.flow-edge-condition-evaluated-slot-source-required.ts (2 lines: surface, acceptanceCriteria)",
    "packages/spec/src/migrations/registry.ts (2 lines, generated by pnpm --filter @objectstack/spec gen:migration-registry)"
    ],
    "deviations": [
    "Commit trailers use the model-free pair from AGENTS.md (Claude-Session: plus Co-authored-by: Claude) instead of the harness reminder's model-named Co-Authored-By. The dispatch forbids model identifiers, and pre-push check:commit-card-trailers passed.",
    "The first lock request timed out with VERDICT queue-timeout exit 99 (NOT MEASURED; slot issue-19966 kept). The second request exceeded the tool's 600 s timeout while its build held the lock, so the harness moved it to the background. I then waited in the foreground on the recorded holder pid 8805 (tail --pid) and read the lock VERDICT command-exit 0 from its log. No poll loop, no retry.",
    "The upgrade-guide and spec-changes generators ran and changed nothing: the entry is in step 18, above PROTOCOL_MAJOR 17. Only registry.ts changed."
    ],
    "mcp_calls": "0 — no MCP GitHub tool called",
    "api_writes": "2 — (1) pr_create draft POST /repos/objectstack-ai/objectstack/pulls, via the fleet-write relay (repository_dispatch request fw-20260924T211753Z-3246be, run 36060560437, success), as objectstack-fleet[bot]; (2) this os-dev-report comment, POST /repos/objectstack-ai/objectstack/issues/19966/comments, via scripts/pm/post-stamped.mjs. git push (x2) is not a REST write. No label, assignee, ready, merge or PATCH writes. The PR body was read back byte-identical, 7938 of 7938 bytes.",
    "open_questions": [],
    "out_of_scope_findings": [
    "class: b · The spec AutomationApiContracts (packages/spec/src/api/automation-api.zod.ts:14, 'Base path: /api/automation'; createFlow.path '/api/automation', pinned in automation-api.zod.test.ts:803-811) declares nine paths under /api/automation. The composed runtime answers 404 ENDPOINT_NOT_FOUND at POST /api/automation and mounts 0 of 194 routes there; it serves /api/v1/automation. Every other spec API contract uses /api/v1 (23 path rows vs these 9). The export is published (api-surface/api.json:106). Seam: spec:AutomationApiContracts.*.path → runtime:dispatcher-plugin.ts server.post of base + '/automation', base = config.prefix or '/api/v1' | consumer: none (in-repo). Dedupe words: AutomationApiContracts /api/automation · automation-api.zod base path · ApiContracts path prefix api/v1 · spec automation contract path 404",
    "carrier: the PM seat domain:spec#4, owner of this card's #17712 correction of the note · noted, not filed. Two sentences in .changeset/flow-edge-condition-evaluated-slot.md are true of #15807's own diff but are overtaken by notes in the SAME pending release. (i) 'The whitespace-only STRING ruling on config.condition (#15662: consistent false on both sides) is untouched.': .changeset/blank-node-condition-refused-at-registration.md (#17322) refuses a whitespace-only config.condition at registerFlow, and .changeset/validate-refuses-blank-structural-condition.md (#17495) at objectstack validate. The spec docblock (flow-node-expression-paths.ts, structuralConditionRefusal) records that #15807 removed the ground of that ruling. (ii) 'its producer-side gate is the structural refusal above': since #17322, the evaluated-slot rule at registerFlow also gates it. Not edited, because the dispatch scope is the route only."
    ]
    }


    Generated by Claude Code

  4. objectstack-fleet commented on Sep 24, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 19966,
    "round": "PM patch round 1 on PR #20031",
    "status": "done",
    "branch": "claude/issue-19966-flows-route-in-upgrade-entry",
    "pr": "#20031",
    "pr_number": 20031,
    "head_sha": "66417af31f21671b927f69d9feb1d5af488e24ec",
    "previous_head_sha": "6820d6ef8ce66e044a19fe3c453e346349fce5f0",
    "session": "session_019c3Hi6ZMU1p6m6aA6Bz45d",
    "premise_still_valid": true,
    "summary": "The patch round is folded in. Commit 66417af edits ONLY .changeset/flow-edge-condition-evaluated-slot.md (+10/-3) and changes two sentences so the note reads true in the release it ships in. The migration entry, registry.ts and every other changeset are untouched. I verified the pushed diff against the patch round's two asks: (i) the whitespace-only config.condition sentence keeps 'untouched by this change' and points at the two sibling notes by card and package, without restating their rule; (ii) the start-node gate sentence keeps 'has no Zod schema to narrow' and names the structural pass with its EvaluatedExpressionInputSchema blank-source check. All 81 derived gates were re-run at the new head. The PR body was NOT updated by me: see open_questions[0] for the conflict with my role file. The updated body is ready, validated and one command away for the seat.",
    "sentence_edits": [
    {
    "where": ".changeset/flow-edge-condition-evaluated-slot.md:63-67",
    "before": "The whitespace-only STRING ruling on config.condition (#15662: consistent false on both sides) is untouched.",
    "after": "The whitespace-only STRING ruling on config.condition (#15662: consistent false on both sides) is untouched by this change, but it does not survive the release that carries it: two sibling notes in that release refuse the value, at registerFlow (#17322, @objectstack/service-automation) and at objectstack validate (#17495, @objectstack/lint).",
    "measured_at_66417af31f": [
    "registerFlow refuses it: packages/services/service-automation/src/engine.ts:4107 registerFlow → :4134 validateFlowExpressions → :9480 checkStructuralCondition(node config.condition) → :9460 second gate evaluatedSourceRefusal (:9437-:9451) → :9448 EvaluatedExpressionInputSchema.safeParse(source)",
    "objectstack validate refuses it: packages/lint/src/validate-expressions.ts:1368 checkStructuralCondition(nodeCondWhere, cfg.condition) → :1349 evaluatedSourceRefusal → :966-:972 (safeParse at :969), severity 'error'",
    "same release: .changeset/blank-node-condition-refused-at-registration.md ('@objectstack/service-automation': minor) and .changeset/validate-refuses-blank-structural-condition.md ('@objectstack/lint': minor) are both present at head. None of #15807 / #17322 / #17495 appears in packages/spec, service-automation or lint CHANGELOG.md (grep -c = 0 each), so all three notes are pending for the same changeset version",
    "cited cards exist: #17322 (closed) 'A whitespace-only config.condition string is a silent false at the node door…'; #17495 (closed) 'lint: objectstack validate reports nothing for exactly the blank config.condition that registerFlow now refuses…'",
    "'untouched by this change' still true: #15807's diff did not refuse the blank string; the admission in structuralConditionRefusal is unchanged (spec/src/automation/flow-node-expression-paths.ts:578-582, every string admitted)"
    ],
    "judgment": "The patch round's parenthetical named the .changeset/*.md files. The note points at them by card and package instead, because changeset version deletes those files and the sentence ships into the CHANGELOG, where a path would dangle. The PR body names both files by path."
    },
    {
    "where": ".changeset/flow-edge-condition-evaluated-slot.md:109-115",
    "before": "Not touched here: start.config.condition has no Zod schema to narrow (the start node's config is an open record); its producer-side gate is the structural refusal above, which this change tightens but does not type.",
    "after": "Not touched here: start.config.condition has no Zod schema to narrow (the start node's config is an open record). Its producer-side gate is the structural pass at registerFlow and objectstack validate: the shape refusal above, which this change tightens but does not type, and after it a blank-source check that runs this change's EvaluatedExpressionInputSchema on the condition's source (added by #17322 at registerFlow and by #17495 at objectstack validate).",
    "measured_at_66417af31f": [
    "'no Zod schema to narrow' still true: FlowNodeSchema config: z.record(z.string(), z.unknown()).optional() at packages/spec/src/automation/flow.zod.ts:488; the only per-type config parse on the node contract is end (parseEndNodeConfig :439-:449); no StartConfigSchema / StartNodeConfigSchema anywhere under packages/spec/src (grep: 0 files)",
    "the structural pass = shape refusal then blank-source check: engine.ts:9453-:9466 (checkStructuralCondition: structuralConditionRefusal, then evaluatedSourceRefusal) and lint validate-expressions.ts:1342-:1354 (same order)",
    "applied to the source, not the whole value: engine.ts:9439-:9448 ('Applied to the SOURCE rather than to the whole value on purpose'); lint :967-:969"
    ]
    }
    ],
    "diff_verification": "git diff 6820d6ef8c 66417af31f --stat: 1 file, .changeset/flow-edge-condition-evaluated-slot.md, 10 insertions / 3 deletions. Worktree clean at 66417af. Remote tip = 66417af (git ls-remote). The route edit at :86 is unchanged from round 1.",
    "tests": "Changeset-only round: no package source changed after 6820d6e, so the round-1 package readings carry over. At 6820d6e: spec check:generated exit 0; spec vitest (src/migrations/, conversions) 4 files / 354 tests passed; spec tsc --noEmit exit 0. This round: 33-package closure rebuilt at 66417af under os-verify-lock (VERDICT command-exit 0, turbo 33/33 cached), then every derived gate re-run (below). No ablation (text only).",
    "gates": {
    "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 66417af: 81 families, change set 3 paths vs merge base 4463966, 23 changed lines (+15/-8). Identical command list to round 1 (diff empty). Tool note: tree is ≥3 commits behind origin/main 9d81af7, with none of the visible ones touching the derivation inputs.",
    "reconciliation": "--ran gives '81 derived famil(ies) accounted for — 80 run, 1 NOT-MEASURED (1 DERIVED from a recorded exit 3)', exit 0",
    "green": "79 exit 0 at 66417af, including check-adr-0087-registration (--base: 'this PR adds no declared-breaking changeset'), check-changeset-no-major, check:changeset-gate-self-tests, check:migration-registry, check:upgrade-guide, check:spec-changes, check:docs, check:api-surface, check:authorable-surface, check:doc-authoring, check:issue-citations (self-test only is what the pnpm script runs) and check:nul-bytes ('no raw ASCII control bytes')",
    "red_by_design": "node scripts/check-empty-changeset.mjs --base origin/main: exit 1, the #17712 DELIBERATE CORRECTION refusal of an edit to a merge-base changeset, as in round 1",
    "not_measured": "pnpm check:dual-build-cjs-loads: exit 3 PREREQUISITE NOT MET (needs every package's dist; only the 33-package closure is built). Declared to CI.",
    "ci_at_report": "35 check-runs at 66417af: 31 success, 3 skipped, 1 failure = Check Changeset (expected red by design). Read once; not waited on."
    },
    "files_changed": [
    "this round: .changeset/flow-edge-condition-evaluated-slot.md (two sentences, +10/-3)",
    "PR total: .changeset/flow-edge-condition-evaluated-slot.md (route at :86 plus the two sentences); packages/spec/src/migrations/entries/semantic/18.flow-edge-condition-evaluated-slot-source-required.ts (2 lines); packages/spec/src/migrations/registry.ts (2 lines, generated)"
    ],
    "pr_body_update": {
    "done_by_me": false,
    "ready_file": "/tmp/claude-0/-home-user/ddb68d60-e0ff-50cc-827e-e854fc95dead/scratchpad/issue-19966/pr-body-v2.md (10764 bytes, md5 87df1c624f42ae0156acd1a5617ce817)",
    "ready_actions_file": "/tmp/claude-0/-home-user/ddb68d60-e0ff-50cc-827e-e854fc95dead/scratchpad/issue-19966/actions-pr-body-v2.json ([{op: issue_patch, issue: 20031, body}]; fleet-write/dispatch.mjs --dry-run exit 0)",
    "send": "bash scripts/pm/with-fleet.sh --via dispatch --repo objectstack-ai/objectstack --actions /tmp/claude-0/-home-user/ddb68d60-e0ff-50cc-827e-e854fc95dead/scratchpad/issue-19966/actions-pr-body-v2.json",
    "what_it_changes": "Based on the stored body, which I read back and found still byte-identical to what was sent at create. (1) The file table: the route row now points at :86, and two rows are added for :63-:67 and :109-:115. (2) The DELIBERATE CORRECTION section lists all three sentence corrections, each with its file:line measurements. (3) The Verification section moves to head 66417af. (4) The acceptance note that said the two sentences were 'not edited here' is replaced. The first two lines, Fixes #19966 / Clause-②: no, and the session-URL footer are unchanged. The body has 0 angle-bracket characters, no model identifier, and one closing keyword (line 1)."
    },
    "deviations": [
    "PR body not PATCHed, although the patch round asked for it. The os-dev role file says a dev writes the PR body once, at pr_create, and never PATCHes it; later changes are named in the report for the seat to write. It also says the role file wins on conflict and the conflict must be named. See open_questions[0].",
    "Commit trailers: model-free pair, as in round 1; pre-push check:commit-card-trailers passed."
    ],
    "mcp_calls": "0",
    "api_writes": "1 this round — the os-dev-report comment on #19966, POST /repos/objectstack-ai/objectstack/issues/19966/comments, via scripts/pm/post-stamped.mjs (relay). git push x1 (6820d6e..66417af) is not a REST write. No PR body, label, assignee, ready or merge write. Round 1 writes were pr_create (#20031) and comment 5822432366.",
    "open_questions": [
    {
    "question": "Role-file conflict: the patch round asks the dev to update the PR body. The os-dev role file forbids a dev PATCH of the PR body after pr_create, and routes that write to the seat. Who sends the prepared body?",
    "options": [
    "A: the seat sends it with the one command in pr_body_update.send (issue_patch through the relay), then reads it back against pr-body-v2.md md5 87df1c624f42ae0156acd1a5617ce817",
    "B: the PM re-dispatches with an explicit exception naming this clause, and the dev sends it"
    ],
    "recommendation": "A. It keeps the role file's single-writer rule for PR bodies intact, the body is already built from the stored copy and validated, and the send is one command. If the clause is wrong, the role file is where to fix it, not a per-round override."
    }
    ],
    "out_of_scope_findings": [
    "class: b · (carried from round 1, unchanged) spec AutomationApiContracts declares nine paths under /api/automation (packages/spec/src/api/automation-api.zod.ts:14; pinned automation-api.zod.test.ts:803-811). The composed runtime answers 404 ENDPOINT_NOT_FOUND there and serves /api/v1/automation; every other spec API contract uses /api/v1. Seam: spec:AutomationApiContracts.*.path → runtime:dispatcher-plugin.ts server.post of base + '/automation' | consumer: none (in-repo). Dedupe words: AutomationApiContracts /api/automation · automation-api.zod base path · ApiContracts path prefix api/v1 · spec automation contract path 404"
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Sep 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — PR #20031 → 1872e52a27, 2026-09-25T02:13Z

    domain:spec seat 4 (session_019c3Hi6ZMU1p6m6aA6Bz45d). Landed through the merge queue only, via the allow-listed ccr pair; ⛔ no hand approval, no hand merge.

    • Merged by the queue at 2026-09-25T02:13Z. The card closed completed through Fixes #19966, the PR body's only closing keyword.
    • The squash 1872e52a27 has one parent and is an ancestor of origin/main. Content probe: git patch-id --stable of the squash's own diff equals that of the PR's diff from its merge base to head 66417af31f, the head the at-tier PASS 5823948144 names. The DELIBERATE CORRECTION of .changeset/flow-edge-condition-evaluated-slot.md landed on the maintainer's confirmation 5823714381.
    • pm:dispatched and the assignee are removed in one label write. Nothing on this card remains in flight.

    Generated by Claude Code

  6. added 2 commits that reference this issue on Sep 28, 2026
    1872e52
    1df29df
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

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions