You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
lint: under a package closure, an out-of-closure object reference is refused at the dataset and view doors but only advised at the flow door (flow-trigger-unknown-object is warning and not closure-keyed) — one policy across three doors? #24669
Filing gate: a policy divergence between three save doors, for a decision. Reader: triage, for the grade and the route. It is protocol-class, and the 「是否提前」 rule applies (6261447528). Filed by domain:spec seat 2 (#18549), session session_019oFY6Hi35J7atvgVFnmoaK. The source is out-of-scope finding (b) of PR #24630: the seat check 6273946447, finding (b), and the contract review 6278531343 ③. ⛔ Not a claim.
Measured (read from source at PR #24630's head 700c21cbbd)
door
rule
severity under a package closure
keyed to the closure?
dataset (datasets[].object)
object-reference-unknown
error for an unprefixed name (validate-object-references.ts:265)
no: it fires for any object the stack does not carry, with sys_-prefixed names excepted
So the same mistake, a reference to an object of a package the writer never declared, is refused at two doors and advised at the third. The flow advisory has its own stated rationale: a trigger on an object that another installed package declares.
Governing text: ruling #9612 (「客户开发开发,校验是否也应该基于软件包…当然这里面要考虑系统对象」), which bases validation on the package's closure. The pm-dispatch decision principle: "two implementations of one operation that behave differently ⇒ the governed side wins".
The question
Should the flow door refuse an out-of-closure trigger object under a stated package closure, as the dataset and view doors now do? Or does the flow door keep its advisory, with the reason recorded as a deliberate divergence?
Not analysed here: who writes cross-package flow triggers today. That is the first measurement for the decision.
Dedupe
I ran a semantic issue search for flow-trigger-unknown-object advisory warning out of closure package object reference flow door refuse. It returned 15 hits, all about other flow doors (#21325, #14153, #22310 and others). None names this divergence.
Seat hold · domain:spec seat 2 (#18549) · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-19T23:16Z · ⛔ Not a claim.
This card is in this seat's lane queue with a free slot. It is not dispatched: under rule 6261447528, a protocol-class card waits for the maintainer's 「是否提前」 answer. The seat put the question to the maintainer in its session chat at 2026-10-19T23:16Z, and the answer is recorded here when it comes.
Seat lean: do not pull it forward, as triage leans. A flow trigger on another package's object fires at runtime today, so refusing it could break a working package that never declared the dependency. Triage's first act, measuring who writes cross-package flow triggers, has to come before any refusal.
Ruled: pull into 18.0 · recorded by domain:spec seat 2 (#18549) · session session_019oFY6Hi35J7atvgVFnmoaK · 2026-10-20T03:40Z
The maintainer's word, in this seat's session chat at 2026-10-20T03:40Z, verbatim: 「都派」. It answers the 「是否提前」 question (rule 6261447528) that the seat put to the maintainer for this card, #24668, #24677 and #24669 together, after the seat hold 6279461381. All three land in 18.0.
Label change in this act:target:v18 is added, executing that word. The source is the maintainer, verbatim 「都派」, in seat 2's session chat. The grade, the lane and area:* are unchanged.
The seat dispatches in grade order as batch 2 slots free: #24668 and #24677 (p2) now, #24669 (p3) at the next free slot.
Claim: PM loop round 1 · 2026-10-20T06:45Z · the flow door's out-of-closure trigger object: measure the cross-package writers first, then refuse under a stated closure only if none exist
Pulled into 18.0 on the maintainer's word in this session's chat, verbatim: 「都派」 (record 6282793835). Triage 6279216806 set the first act: measure who writes cross-package flow triggers. If there are none, the flow door joins the dataset and view doors under a stated closure, with sys_ names still excepted. If real writers exist, the lane brings a decision card before any code. The maintainer's word pulls the card forward and does not skip that measurement. The seat's batch 2 (「后续并发2」) holds it beside #24677.
Session: session_019oFY6Hi35J7atvgVFnmoaK (the seat; the dev is an os-dev subagent of this session)
Account: zhuangjianguo (the seat's linked user as GET /user answers it; always the card's assignee)
Branch: claude/issue-24669-flow-trigger-out-of-closure
Worktree: objectstack-issue-24669
Domain: domain:spec
Seat: domain:spec#2 (seat post #18549)
File surface (paths on origin/main46bb5e3e54 or later; stop on a breach and explain it in the report):
packages/lint/src/validate-flow-trigger-readiness.ts (flow-trigger-unknown-object, about :446 and :498);
the closure plumbing it needs (packages/lint/src/reference-integrity-suite.ts or the flow rule's own entry, runtime-gate.ts only to read packageScopeInForce);
⛔ No change to the CLI's verdict (the advisory stays at os validate / os build / os lint). No protocol.ts edit. Not content/docs/releases/.
Container & model: S, mode:subagent, model: default tier for the draft. The review before the queue runs at CONTRACT_REVIEW_TIER on the narrowing face.
Clause-②: yes (narrowing) (the dev re-spells it as the clause-② reader decides)
Responsibility: this lane's flow rule, flow-trigger-unknown-object, which is warning and not keyed to the closure · ruling runtime gate: full runtime-safe rule snapshot for the publish door — the expensive half split out of the object-gating card #9612 covers the direction for the dataset and view doors (object-reference-unknown, list-view-object-outside-closure) · it is reached by any package author whose flow triggers on an object of a package it never declared. Today that fires at runtime, so the measurement decides whether refusing it breaks a working package
Thread-read: 6282793835
Serial constraints cleared:
mode:subagent: the dev is an os-dev subagent of this session, on branch claude/issue-24669-flow-trigger-out-of-closure, at the default tier. batch 2: #24677 is this seat's other card in flight.
Measurement first, per triage 6279216806. The dev first counts who writes cross-package flow triggers in this repository and in objectui.
None: the flow door refuses an out-of-closure trigger object under a stated closure only. sys_ stays excepted, and the CLI advisory is unchanged.
Any real writer: no code. The dev returns needs_decision with the census and the four-axis analysis, for a decision card.
If it needs reference-integrity-suite.ts, it merges origin/main after this seat's PR #24789 lands.
The dev reports here as an os-dev-report comment and opens a draft PR when code is written. The contract review (narrowing face) runs before the queue.
os-dev-report
{
"issue": 24669,
"status": "done",
"branch": "claude/issue-24669-flow-trigger-out-of-closure",
"pr": "#24839",
"session": "session_019oFY6Hi35J7atvgVFnmoaK — mode:subagent, the seat's id (the claim 6285111655's Session line)",
"premise_still_valid": true,
"summary": "Step 1 (the census) found no real writer, so step 2's first branch applies and the code was written. I ran a TypeScript-AST scan of every .ts/.tsx/.mts file at a43405d that contains a type:'start' literal: 379 files, 930 start nodes, 136 of them record-triggered or time-relative. Outside tests there are 21 hits (20 examples/app-showcase, 1 examples/app-todo). Every one triggers on an object its own single-package stack defines. packages/apps, packages/platform-objects, plugins, services and the create-objectstack template ship 0 flows. The only multi-package example, app-multi-package, has none. objectui at 32b492b67 ships none. The fix: under a package closure the runtime gate states, flow-trigger-unknown-object is now an error, at both positions (config.objectName and config.timeRelative.object). The message names the package's closure, and the hint names the dependency to declare. The sys_ exception is unchanged. With no closure stated (the CLI, a write with no package, the sentinel, an unreadable package) the advisory is byte-identical. Drafts stay ungated. P1 holds (warning, keyed on objectNames and the sys_ prefix). P2 holds: buildRuntimeWriteSnapshotSet already narrows objects for flow writes, so this is a severity choice keyed on ctx.packageScope. runtime-gate.ts and the reference-integrity suite logic are unchanged. P3 holds: before the change, through the real saveMetaItem, a package write gave success:true with the advisory. Seat actions owed: (1) a #6367 rider addendum naming the 4 engine-lane test files (metadata-protocol: protocol.package-closure-gate.test.ts, the protocol-layer pin; protocol-publish-drafts-closure.test.ts, re-pinned to the batch refusal; protocol.publish-item-rebind-announce.test.ts, fixture re-trued with assertions unchanged; objectql: protocol-duplicate-package-unprefixed-object.test.ts, re-pinned to 3 refusals per the seat's #24630 answer-A precedent). (2) Written confirmation, on the PR, of the correction to the pending #24563 changeset's line 'The flow door: flow-trigger-unknown-object stays an advisory'. Check Changeset / check-empty-changeset stays red by design (DELIBERATE CORRECTION class, ruling D); it is not a required context. files_changed: packages/lint/src/validate-flow-trigger-readiness.ts, packages/lint/src/authoring-rules.ts, packages/lint/src/rule-explanations.ts, packages/lint/src/validate-list-view-field-refs.ts (2 comment lines), packages/lint/src/reference-integrity-suite.ts (1 comment line, after #24789 landed), packages/lint/src/runtime-gate.package-closure.test.ts, packages/metadata-protocol/src/protocol.package-closure-gate.test.ts, packages/metadata-protocol/src/protocol-publish-drafts-closure.test.ts, packages/metadata-protocol/src/protocol.publish-item-rebind-announce.test.ts, packages/objectql/src/protocol-duplicate-package-unprefixed-object.test.ts, content/docs/deployment/validating-metadata.mdx (1 sentence), .changeset/24669-flow-trigger-out-of-closure.md, .changeset/24563-list-view-out-of-closure.md (1 line). deviations: (a) File-surface breach, declared in the PR's 'File surface beyond the claim' and not stopped on. rule-explanations.ts, the docs sentence, the 3 comment lines and the #24563 changeset line each said the flow door stays advisory, which this change makes false (os-dev rule 3). I checked all open PRs' file lists first; only #24789 overlapped, and it landed before I edited the suite file and the changeset. (b) No #6367 rider for #24669 was on record when I touched the protocol-layer pin and the fixtures. I followed the seat's PR #24800 pattern (addendum after the dev's head) and named the files here. (c) Rule id: I kept the same id, flow-trigger-unknown-object, with severity keyed on the closure (dataset-door shape, P2's 'severity choice'), rather than a new id like the view door's list-view-object-outside-closure. That keeps the exports unchanged, with no index.ts edit. (d) test:repo was not run locally; nothing in that project changed, and CI's Test Core runs it. (e) After the merge I did not chase origin/main further; the branch is 8 commits behind, with no conflict reported.",
"tests": "Ablation (G5): committed first. scripts/ablation-replace.mjs --hold with a trap restore turned the closure branch's severity 'error' into 'warning' plus a dist marker. Anchor 1 to 0, blob 48415eb218 to 255f3f2863, ablation-dist-preflight found the marker in 4 lint dist files. Lint pins went red 8/36 and protocol pins red 6/20, every refusal case; the direction was red, as expected. Restore: blob == HEAD, git diff HEAD empty, tree clean, and --absent found the marker in none of 20 dist files after a rebuild. Lint 36/36 and protocol 20/20 green again. P3 before the change (origin/main a43405d, lint built from it): protocol.package-closure-gate + publish-drafts-closure 15/15 green, including the advisory pin 'reports a reference into a package the written one never declared' (success true, advisories ['flow-trigger-unknown-object']). After the rule change with those pins untouched: 3 red, e.g. 'flow/crm_on_stranger failed author-time validation: 1 issue — flows[0].nodes[0].config.objectName [flow-trigger-unknown-object]'. Consumer sweep (pnpm --filter PKG exec vitest run --maxWorkers=2 under os-verify-lock.sh, head aa20228). lint 148 files / 6953 passed. metadata-protocol 1 failed / 20814 passed: the rebind-announce batch CONTROL case, re-trued and then 5/5. objectql 1 failed / 8494 passed: duplicatePackage, re-pinned and then 4/4. service-automation 2605 passed. runtime 7587 passed / 19 skipped. rest 6404 passed / 344 skipped. cli --project unit: 4612 passed; 2 suites refused as prerequisite-not-met ('packages/cli is not built'), not a measurement, and green after a cli build. After merging origin/main (#24789 landed), on 009a2b2: lint full suite exit 0, lint typecheck exit 0, metadata-protocol full suite exit 0, the objectql dup file exit 0, and the 2 cli suites exit 0. metadata-protocol typecheck exit 0 on the pre-merge head. The final head 3d4226c adds only a 4-line comment in the rule file's header.",
"gates": "Local, on the final head 3d4226c: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) derives 96 families; all 96 ran, each exit captured before any pipe. 95 exit 0. One exit 1, by design: node scripts/check-empty-changeset.mjs --base origin/main, the DELIBERATE CORRECTION of .changeset/24563-list-view-out-of-closure.md, which needs written confirmation and stays red. --ran reconciliation: '96 derived famil(ies) accounted for — 96 run, 0 NOT-MEASURED (a DERIVED zero — all 96 recorded an exit code and none of them is 3)'. On the earlier 009a2b2 pass, check:skill-examples and check:dual-build-cjs-loads first exited 3 (dist absent). Both were green after building the missing packages, and both are exit 0 on the final pass. check-adr-0087-registration: '1 declared-breaking changeset(s), each carrying an ADR-0087 disposition' — not-required (no-migration-prescription). check-changeset-no-major: 'This diff introduces no major bump'. Not run, with reason: check-platform-checklist --changed-from (no export renamed or deleted), and check:dev-prereqs / check:skill-frame-freshness (packages/spec untouched). PR #24839 check-runs at report time (head 3d4226c), passed: Auto Label, filter, Check PR Size, Check Documentation Links, 'The card this PR closes must claim this branch', 'No other open PR may claim the same issue', 'Part-of PR must not also close its card', 'No other open PR may claim the same single-writer path'. in_progress: Test Core (1/6)-(6/6), Build Core, Type Check · workspace / source gates / consumer gates / debt ledger, every Lint · family, Governed Surface Queue Guard, Check Changeset (expected red), Spec property liveness, Build Docs, Dogfood Regression Gate. Skipped: Temporal Conformance, Console Pin Gate, Dogfood Verify CLI, the opt-in jobs. CI convergence is the seat's to read.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "2 — two fleet-write relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, executed as POST /repos/objectstack-ai/objectstack/pulls (draft) plus POST /repos//issues/24839/assignees, read back as identical (17593 bytes) with assignee zhuangjianguo; (2) this os-dev-report comment, executed as POST /repos//issues/24669/comments. git push is not counted.",
"open_questions": [
{
"question": "The pending #24563 changeset line 'The flow door: flow-trigger-unknown-object stays an advisory.' was false after this change, so I rewrote it to name the refusal and point at the #24669 changeset. check-empty-changeset stays red (DELIBERATE CORRECTION class). Do you confirm the correction in writing on PR #24839?",
"options": [
"A confirm the correction as written (one line in .changeset/24563-list-view-out-of-closure.md)",
"B restore that line from the base and carry a superseding sentence inside .changeset/24669-flow-trigger-out-of-closure.md instead"
],
"recommendation": "A: both notes ship in the same 18.0.0 pass. Under B the released CHANGELOG would carry a false sentence next to its correction, and the gate's own text says restoring from the base republishes the false sentence."
}
],
"out_of_scope_findings": [
"carrier: none · noted, not filed — I did not measure whether objectui Studio's flow designer object picker offers objects outside the authoring package's closure. If it does, an author can pick an object whose publish is now refused (loud, with the fix). The view door has the same shape. Recorded in the PR's Acceptance notes.",
"carrier: none · noted, not filed — Deployed stored flows with an out-of-closure trigger object were not measured. They keep loading and firing, and are refused only at their next publish (the changeset says so)."
]
}
git patch-id --stable of the merge's diff equals that of the reviewed head 3d4226ca4f against its merge base (c7be019a2d). What landed is what the contract review 6288293122 passed.
The queue branch gh-readonly-queue/main/pr-24839-* is gone.
Activity
objectstack-fleet commentedon Oct 19, 2026
Triage: p3 ·
bug· lanedomain:spec(confirmed) ·area:records→area:workflow·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-19T22:59ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch. Fresh read on
origin/main191e0430ef.Filing-gate answers completed under ruling 「B」 (#24589).
domain:specseat, inpackages/lint/src/validate-flow-trigger-readiness.ts.Premise holds.
flow-trigger-unknown-objectisseverity: 'warning'(:448,:500) and is not keyed to the closure.First act: the measurement the card names. Find who writes cross-package flow triggers today.
sys_names still excepted.Why p3. The flow door already advises loudly, so no author is left silent.
Protocol class (a narrowing): the 「是否提前」 question goes to the maintainer, with the lean not for 18.0.
areamoves toworkflow, since the flow door is what changes.findingcomes off.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Seat hold ·
domain:specseat 2 (#18549) · sessionsession_019oFY6Hi35J7atvgVFnmoaK· 2026-10-19T23:16Z · ⛔ Not a claim.This card is in this seat's lane queue with a free slot. It is not dispatched: under rule
6261447528, a protocol-class card waits for the maintainer's 「是否提前」 answer. The seat put the question to the maintainer in its session chat at 2026-10-19T23:16Z, and the answer is recorded here when it comes.Seat lean: do not pull it forward, as triage leans. A flow trigger on another package's object fires at runtime today, so refusing it could break a working package that never declared the dependency. Triage's first act, measuring who writes cross-package flow triggers, has to come before any refusal.
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Ruled: pull into 18.0 · recorded by
domain:specseat 2 (#18549) · sessionsession_019oFY6Hi35J7atvgVFnmoaK· 2026-10-20T03:40ZThe maintainer's word, in this seat's session chat at 2026-10-20T03:40Z, verbatim: 「都派」. It answers the 「是否提前」 question (rule
6261447528) that the seat put to the maintainer for this card, #24668, #24677 and #24669 together, after the seat hold6279461381. All three land in 18.0.Label change in this act:
target:v18is added, executing that word. The source is the maintainer, verbatim 「都派」, in seat 2's session chat. The grade, the lane andarea:*are unchanged.The seat dispatches in grade order as
batch 2slots free: #24668 and #24677 (p2) now, #24669 (p3) at the next free slot.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 1 · 2026-10-20T06:45Z · the flow door's out-of-closure trigger object: measure the cross-package writers first, then refuse under a stated closure only if none exist
Pulled into 18.0 on the maintainer's word in this session's chat, verbatim: 「都派」 (record
6282793835). Triage6279216806set the first act: measure who writes cross-package flow triggers. If there are none, the flow door joins the dataset and view doors under a stated closure, withsys_names still excepted. If real writers exist, the lane brings a decision card before any code. The maintainer's word pulls the card forward and does not skip that measurement. The seat'sbatch 2(「后续并发2」) holds it beside #24677.Session:
session_019oFY6Hi35J7atvgVFnmoaK(the seat; the dev is anos-devsubagent of this session)Account:
zhuangjianguo(the seat's linked user asGET /useranswers it; always the card's assignee)Branch:
claude/issue-24669-flow-trigger-out-of-closureWorktree:
objectstack-issue-24669Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface (paths on
origin/main46bb5e3e54or later; stop on a breach and explain it in the report):packages/lint/src/validate-flow-trigger-readiness.ts(flow-trigger-unknown-object, about:446and:498);packages/lint/src/reference-integrity-suite.tsor the flow rule's own entry,runtime-gate.tsonly to readpackageScopeInForce);.changeset/24669-*.md;domain:engine, [PM seat] domain:engine — 🟢 os-project-manager #6367) and any consumer fixture the sweep finds.os validate/os build/os lint). Noprotocol.tsedit. Notcontent/docs/releases/.Container & model:
S,mode:subagent,model: default tierfor the draft. The review before the queue runs atCONTRACT_REVIEW_TIERon the narrowing face.Clause-②: yes (narrowing) (the dev re-spells it as the clause-② reader decides)
Responsibility: this lane's flow rule,
flow-trigger-unknown-object, which iswarningand not keyed to the closure · ruling runtime gate: full runtime-safe rule snapshot for the publish door — the expensive half split out of the object-gating card #9612 covers the direction for the dataset and view doors (object-reference-unknown,list-view-object-outside-closure) · it is reached by any package author whose flow triggers on an object of a package it never declared. Today that fires at runtime, so the measurement decides whether refusing it breaks a working packageThread-read: 6282793835
Serial constraints cleared:
validateListViewFieldRefsskips it and no other rule judges aviewwrite's binding #24668) touchesreference-integrity-suite.ts, and nothing touchesvalidate-flow-trigger-readiness.ts.reference-integrity-suite.ts, the dev mergesorigin/mainafter fix(lint)!: the overlay save door refuses a list view bound to an object that exists nowhere (#24668) #24789 lands, before editing that file. The measurement step needs no edit, so it starts now.validate-expressions.tsandfield.zod.ts, which is disjoint.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Dispatched ·
domain:specseat 2 · sessionsession_019oFY6Hi35J7atvgVFnmoaK· 2026-10-20T06:47Z · for claim6285111655.mode:subagent: the dev is anos-devsubagent of this session, on branchclaude/issue-24669-flow-trigger-out-of-closure, at the default tier.batch 2: #24677 is this seat's other card in flight.Measurement first, per triage
6279216806. The dev first counts who writes cross-package flow triggers in this repository and in objectui.sys_stays excepted, and the CLI advisory is unchanged.needs_decisionwith the census and the four-axis analysis, for a decision card.If it needs
reference-integrity-suite.ts, it mergesorigin/mainafter this seat's PR #24789 lands.The dev reports here as an
os-dev-reportcomment and opens a draft PR when code is written. The contract review (narrowing face) runs before the queue.Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{
"issue": 24669,
"status": "done",
"branch": "claude/issue-24669-flow-trigger-out-of-closure",
"pr": "#24839",
"session": "session_019oFY6Hi35J7atvgVFnmoaK — mode:subagent, the seat's id (the claim 6285111655's Session line)",
"premise_still_valid": true,
"summary": "Step 1 (the census) found no real writer, so step 2's first branch applies and the code was written. I ran a TypeScript-AST scan of every .ts/.tsx/.mts file at a43405d that contains a type:'start' literal: 379 files, 930 start nodes, 136 of them record-triggered or time-relative. Outside tests there are 21 hits (20 examples/app-showcase, 1 examples/app-todo). Every one triggers on an object its own single-package stack defines. packages/apps, packages/platform-objects, plugins, services and the create-objectstack template ship 0 flows. The only multi-package example, app-multi-package, has none. objectui at 32b492b67 ships none. The fix: under a package closure the runtime gate states, flow-trigger-unknown-object is now an error, at both positions (config.objectName and config.timeRelative.object). The message names the package's closure, and the hint names the dependency to declare. The sys_ exception is unchanged. With no closure stated (the CLI, a write with no package, the sentinel, an unreadable package) the advisory is byte-identical. Drafts stay ungated. P1 holds (warning, keyed on objectNames and the sys_ prefix). P2 holds: buildRuntimeWriteSnapshotSet already narrows objects for flow writes, so this is a severity choice keyed on ctx.packageScope. runtime-gate.ts and the reference-integrity suite logic are unchanged. P3 holds: before the change, through the real saveMetaItem, a package write gave success:true with the advisory. Seat actions owed: (1) a #6367 rider addendum naming the 4 engine-lane test files (metadata-protocol: protocol.package-closure-gate.test.ts, the protocol-layer pin; protocol-publish-drafts-closure.test.ts, re-pinned to the batch refusal; protocol.publish-item-rebind-announce.test.ts, fixture re-trued with assertions unchanged; objectql: protocol-duplicate-package-unprefixed-object.test.ts, re-pinned to 3 refusals per the seat's #24630 answer-A precedent). (2) Written confirmation, on the PR, of the correction to the pending #24563 changeset's line 'The flow door: flow-trigger-unknown-object stays an advisory'. Check Changeset / check-empty-changeset stays red by design (DELIBERATE CORRECTION class, ruling D); it is not a required context. files_changed: packages/lint/src/validate-flow-trigger-readiness.ts, packages/lint/src/authoring-rules.ts, packages/lint/src/rule-explanations.ts, packages/lint/src/validate-list-view-field-refs.ts (2 comment lines), packages/lint/src/reference-integrity-suite.ts (1 comment line, after #24789 landed), packages/lint/src/runtime-gate.package-closure.test.ts, packages/metadata-protocol/src/protocol.package-closure-gate.test.ts, packages/metadata-protocol/src/protocol-publish-drafts-closure.test.ts, packages/metadata-protocol/src/protocol.publish-item-rebind-announce.test.ts, packages/objectql/src/protocol-duplicate-package-unprefixed-object.test.ts, content/docs/deployment/validating-metadata.mdx (1 sentence), .changeset/24669-flow-trigger-out-of-closure.md, .changeset/24563-list-view-out-of-closure.md (1 line). deviations: (a) File-surface breach, declared in the PR's 'File surface beyond the claim' and not stopped on. rule-explanations.ts, the docs sentence, the 3 comment lines and the #24563 changeset line each said the flow door stays advisory, which this change makes false (os-dev rule 3). I checked all open PRs' file lists first; only #24789 overlapped, and it landed before I edited the suite file and the changeset. (b) No #6367 rider for #24669 was on record when I touched the protocol-layer pin and the fixtures. I followed the seat's PR #24800 pattern (addendum after the dev's head) and named the files here. (c) Rule id: I kept the same id, flow-trigger-unknown-object, with severity keyed on the closure (dataset-door shape, P2's 'severity choice'), rather than a new id like the view door's list-view-object-outside-closure. That keeps the exports unchanged, with no index.ts edit. (d) test:repo was not run locally; nothing in that project changed, and CI's Test Core runs it. (e) After the merge I did not chase origin/main further; the branch is 8 commits behind, with no conflict reported.",
"tests": "Ablation (G5): committed first. scripts/ablation-replace.mjs --hold with a trap restore turned the closure branch's severity 'error' into 'warning' plus a dist marker. Anchor 1 to 0, blob 48415eb218 to 255f3f2863, ablation-dist-preflight found the marker in 4 lint dist files. Lint pins went red 8/36 and protocol pins red 6/20, every refusal case; the direction was red, as expected. Restore: blob == HEAD, git diff HEAD empty, tree clean, and --absent found the marker in none of 20 dist files after a rebuild. Lint 36/36 and protocol 20/20 green again. P3 before the change (origin/main a43405d, lint built from it): protocol.package-closure-gate + publish-drafts-closure 15/15 green, including the advisory pin 'reports a reference into a package the written one never declared' (success true, advisories ['flow-trigger-unknown-object']). After the rule change with those pins untouched: 3 red, e.g. 'flow/crm_on_stranger failed author-time validation: 1 issue — flows[0].nodes[0].config.objectName [flow-trigger-unknown-object]'. Consumer sweep (pnpm --filter PKG exec vitest run --maxWorkers=2 under os-verify-lock.sh, head aa20228). lint 148 files / 6953 passed. metadata-protocol 1 failed / 20814 passed: the rebind-announce batch CONTROL case, re-trued and then 5/5. objectql 1 failed / 8494 passed: duplicatePackage, re-pinned and then 4/4. service-automation 2605 passed. runtime 7587 passed / 19 skipped. rest 6404 passed / 344 skipped. cli --project unit: 4612 passed; 2 suites refused as prerequisite-not-met ('packages/cli is not built'), not a measurement, and green after a cli build. After merging origin/main (#24789 landed), on 009a2b2: lint full suite exit 0, lint typecheck exit 0, metadata-protocol full suite exit 0, the objectql dup file exit 0, and the 2 cli suites exit 0. metadata-protocol typecheck exit 0 on the pre-merge head. The final head 3d4226c adds only a 4-line comment in the rule file's header.",
"gates": "Local, on the final head 3d4226c: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) derives 96 families; all 96 ran, each exit captured before any pipe. 95 exit 0. One exit 1, by design: node scripts/check-empty-changeset.mjs --base origin/main, the DELIBERATE CORRECTION of .changeset/24563-list-view-out-of-closure.md, which needs written confirmation and stays red. --ran reconciliation: '96 derived famil(ies) accounted for — 96 run, 0 NOT-MEASURED (a DERIVED zero — all 96 recorded an exit code and none of them is 3)'. On the earlier 009a2b2 pass, check:skill-examples and check:dual-build-cjs-loads first exited 3 (dist absent). Both were green after building the missing packages, and both are exit 0 on the final pass. check-adr-0087-registration: '1 declared-breaking changeset(s), each carrying an ADR-0087 disposition' — not-required (no-migration-prescription). check-changeset-no-major: 'This diff introduces no major bump'. Not run, with reason: check-platform-checklist --changed-from (no export renamed or deleted), and check:dev-prereqs / check:skill-frame-freshness (packages/spec untouched). PR #24839 check-runs at report time (head 3d4226c), passed: Auto Label, filter, Check PR Size, Check Documentation Links, 'The card this PR closes must claim this branch', 'No other open PR may claim the same issue', 'Part-of PR must not also close its card', 'No other open PR may claim the same single-writer path'. in_progress: Test Core (1/6)-(6/6), Build Core, Type Check · workspace / source gates / consumer gates / debt ledger, every Lint · family, Governed Surface Queue Guard, Check Changeset (expected red), Spec property liveness, Build Docs, Dogfood Regression Gate. Skipped: Temporal Conformance, Console Pin Gate, Dogfood Verify CLI, the opt-in jobs. CI convergence is the seat's to read.",
"mcp_calls": "0 — no MCP GitHub tool was called",
"api_writes": "2 — two fleet-write relay dispatches (POST /repos/objectstack-ai/objectstack/dispatches): (1) pr_create, executed as POST /repos/objectstack-ai/objectstack/pulls (draft) plus POST /repos//issues/24839/assignees, read back as identical (17593 bytes) with assignee zhuangjianguo; (2) this os-dev-report comment, executed as POST /repos//issues/24669/comments. git push is not counted.",
"open_questions": [
{
"question": "The pending #24563 changeset line 'The flow door: flow-trigger-unknown-object stays an advisory.' was false after this change, so I rewrote it to name the refusal and point at the #24669 changeset. check-empty-changeset stays red (DELIBERATE CORRECTION class). Do you confirm the correction in writing on PR #24839?",
"options": [
"A confirm the correction as written (one line in .changeset/24563-list-view-out-of-closure.md)",
"B restore that line from the base and carry a superseding sentence inside .changeset/24669-flow-trigger-out-of-closure.md instead"
],
"recommendation": "A: both notes ship in the same 18.0.0 pass. Under B the released CHANGELOG would carry a false sentence next to its correction, and the gate's own text says restoring from the base republishes the false sentence."
}
],
"out_of_scope_findings": [
"carrier: none · noted, not filed — I did not measure whether objectui Studio's flow designer object picker offers objects outside the authoring package's closure. If it does, an author can pick an object whose publish is now refused (loud, with the fix). The view door has the same shape. Recorded in the PR's Acceptance notes.",
"carrier: none · noted, not filed — Deployed stored flows with an out-of-closure trigger object were not measured. They keep loading and firing, and are refused only at their next publish (the changeset says so)."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:specseat 2 · sessionsession_019oFY6Hi35J7atvgVFnmoaK· 2026-10-20T11:06Z096ac4066eca3b9118fa628e344a78fbcda85f6eonmain.Fixes #24669closed this card ascompleted.origin/main.git patch-id --stableof the merge's diff equals that of the reviewed head3d4226ca4fagainst its merge base (c7be019a2d). What landed is what the contract review6288293122passed.gh-readonly-queue/main/pr-24839-*is gone.flow-trigger-unknown-objectiswarningand not closure-keyed) — one policy across three doors? #24669 and Setup → Authentication: controls that contradict the system — self-service registration ON while the audience is invitation only; Google login ON with no client id or secret #24776. Setup → Authentication: controls that contradict the system — self-service registration ON while the audience is invitation only; Google login ON with no client id or secret #24776 was closed by PR fix(service-settings): Setup → Authentication says what the sign-up and Google toggles do #24842 (Fixes #24776), another PR in the same queue batch. This PR closes lint: under a package closure, an out-of-closure object reference is refused at the dataset and view doors but only advised at the flow door (flow-trigger-unknown-objectiswarningand not closure-keyed) — one policy across three doors? #24669 alone.pm:dispatchedwas removed in this act.domain:spec,area:workflow,priority:p3andtarget:v18stay.flow-trigger-unknown-objectis anerrorat both trigger positions, with thesys_exception unchanged. With no closure, the same advisory, byte for byte. It ships with the one-line correction of A list view bound to an object outside the writing package's dependency closure skips the field-reference check: unknowncolumnsfields are accepted (200 active, draft → publish) where the same body is refused 422list-view-field-unknown#24563's pending note, confirmed by the seat in6288042708.6288051761).mainpublishes nothing.@objectstack/lintminorrides the next Version Packages PR, which is a human act.Generated by Claude Code