Skip to content

views: 数组的三个门形状判断不一致:栈级 schema 只收容器、授权 lint 按记录门映射、运行时注册循环全收 —— declared ≠ enforced 的「运行时更宽」向 #5320

Closed

Description

@os-zhuang

#4959 前提实测(PR #5319 rider,2026-08-04)的两条残余观察,原单前提已证伪关闭,残余按 finding 纪律归档。实测证据全文见 #5074 验收链与 PR #5319 正文「Rider」节。

观察一:授权 lint 与栈级 schema 对同一数组的映射不一致

metadata-authoring-lint 把 views 集合映射到 view 元数据类型 schema(接受 ViewItem 的 union),而 ObjectStackSchema.views(stack.zod.ts:250)只收容器。方向良性(parse 更严且拒绝带处方:「viewKind belongs to a single VIEW, not to the container. Wrap it: defineView({...})」),但 lint 的预解析告警够不到这类拒绝 —— 作者要到 parse 才知道。

观察二:运行时比 schema 宽

objectql/engine.ts(~:1999)的注册循环把 views: 数组里每一项都注册为 view 类型,仅当 isAggregatedViewContainer 为真时额外展开 —— 一个 ViewItem 放进 manifest 的 views: 数组在运行时注册成功,而 defineStack 会拒。今天无用户可撞(授权门先拒且带处方),但属「声明 ≠ 生效」的运行时更宽向,与 #3950 同型。

持有理由

两条今天都无用户可见伤害;观察二在 manifest 绕过 defineStack 的路径上才成立(该路径本身受 #5086/#5311 一族门治理演进影响)。发现分诊轮按过时前提检查后定级。

关联:#4959(已关,前提证伪)、PR #5319(实测)、#5311(直写第三通路)、#3950。

Activity

  1. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 4, 2026
  2. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    分诊轮判级(spec 车道 PM,session_018fxLGQdatPbBUvCgiVxg6D,2026-08-05):持有(finding 留)。理由:三门形状不一致的收敛方向(栈级收紧 vs 运行时对齐)未定,且「运行时更宽」向意味着收紧会拒存量 —— 需与 #4001 战役 view 面的批次同做以带全套 guidance/conversion 纪律,不宜单点动。重启条件:#4001 view 面批次开列时并入。


    Generated by Claude Code

  3. claude commented on Aug 6, 2026

    @claude
    Contributor

    发现分诊轮(#4949 纪律):持有(留 finding + domain:spec),08-05 判级维持。本轮产出是一条重启条件可达性预警 —— 现在还不构成重新锚定,但再拖一步就会变成 #5299 那种「谁也退不出的状态」。

    过时前提检查(origin/main @ 9e3709a)

    两条观察的机制面未见变化,持有理由(「运行时更宽」向、收紧会拒存量、无用户今日可撞)不变。

    ⚠️ 重启条件的可达性预警

    08-05 写的重启条件是「#4001 view 面批次开列时并入」。核 #4001 现状:

    ⇒ 若 #4001 就此收口而始终不开 view 面批次,本单的重启条件将永远不触发。

    处置(本轮不改判,设一个明确的复查触点)

    关联:#4001(伞单)、#5311、#3950。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. claude commented on Aug 7, 2026

    @claude
    Contributor

    Findings triage round (#4949 discipline): HOLD (finding + domain:spec kept). Two concrete updates: the cited line number has drifted, and last round's reachability warning on the restart condition got worse, not better.

    Stale-premise check (origin/main)

    Observation two's mechanism is intact but has moved: the registration loop that registers every item in a manifest views: array as type view, expanding only when isAggregatedViewContainer is true, is now at packages/objectql/src/engine.ts:2334 — the issue body cites ~:1999. Worth correcting on the record, because engine.ts took 5 commits since 2026-08-06T20:00Z (148d451b, 13630842, ee3bde1b, eda599ea, 2680cd37) and a stale line number invites a future reader to conclude the premise died. It did not: all five are transactions / migration / seed work (#5351, #5696, #6063, #4795, #5979), none touch the views loop. The "runtime is wider than the schema" asymmetry is unchanged.

    ⚠️ Restart-condition reachability — the warning is now stronger

    Last round (08-06 22:56Z) flagged that the 08-05 restart condition — "fold in when #4001 opens its view-face batch" — may never trigger, and set the recheck touchpoint at #4001's closure. State of #4001 today:

    • still open, still pm:queue + pm:dispatched, still assigned;
    • last updated 2026-08-04T12:22:25Z — no timeline movement in ~3 days, against a repo averaging ~18 merges a day.

    So the anchor issue is not merely "hasn't opened a view-face batch yet"; it has gone quiet entirely. That does not license re-anchoring this round (the touchpoint is #4001 closing, and a stalled issue has not closed), and stale-claim handling on #4001 is the executing seat's business, not this seat's — this seat does not touch claims. But it sharpens the standing instruction for whichever round sees #4001 close: re-anchor that round, do not roll it forward again. Candidate anchors recorded last round remain the two on file (fold into the #5311 "third direct-write path" gate batch, or promote standalone as a "three gate shapes align" convergence issue).

    ⇒ HOLD this round; no exit condition invented, none rolled over silently.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  5. os-project-manager commented on Aug 8, 2026

    @os-project-manager
    Collaborator

    Findings sweep (maintainer-authorized one-off, 2026-08-07 — registered on #6015): hold confirmed. Runtime-wider-than-schema, but the authoring gate rejects first with a prescription, so no author reaches the wide path today. Restart: when the #5086/#5311 manifest-write governance opens that bypass face, align the runtime registration loop in the same change.


    Generated by Claude Code

  6. os-zhuang commented on Aug 9, 2026

    @os-zhuang
    ContributorAuthor

    Findings triage round: HOLD maintained (finding + domain:spec kept). Stale-premise check @ origin/main b88f5e8 — the mechanism is intact; both anchors drifted, recorded so a future reader doesn't mistake line noise for a dead premise.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  7. claude commented on Aug 10, 2026

    @claude
    Contributor

    Findings round (periodic re-verification): HOLD maintained (finding + domain:spec unchanged). Re-checked @ origin/main 603cab8: packages/spec/src/stack.zod.ts:251 still views: z.array(ViewSchema) and the strict container prose survives with line drift only (view.zod.ts:1920 → :2221, same 'this view container' surface). The three-gate asymmetry the card records is intact; restart conditions unfired.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  8. claude commented on Aug 10, 2026

    @claude
    Contributor

    Findings round (quota re-verification): HOLD maintained (finding + domain:spec unchanged). Re-checked @ origin/main a76a3af: packages/spec/src/stack.zod.ts:251 still views: z.array(ViewSchema); the strict container prose drifted view.zod.ts:2221 → :2230 ('this view container', same surface); the runtime registration loop (isAggregatedViewContainer expansion) drifted engine.ts:3050 → :3722. The three-gate asymmetry the card records is intact; restart condition (the #5086/#5311 manifest-write governance opening the bypass face) unfired; #4001 touchpoint unchanged (still open).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  9. claude commented on Aug 11, 2026

    @claude
    Contributor

    Findings round (quota re-verification): HOLD maintained (finding + domain:spec unchanged). Re-checked @ origin/main c546c89: packages/spec/src/stack.zod.ts:251 still views: z.array(ViewSchema); the strict-container prose drifted again view.zod.ts:2230 → :2328 ('this view container', same surface); the runtime registration loop is at engine.ts:3722 (isAggregatedViewContainer). Three-gate asymmetry intact; no evidence on the card that the #5086/#5311 restart condition fired. Held.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  10. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    ContributorAuthor

    Findings triage (cadence re-check): HOLD — stays finding.

    Premise re-verified on origin/main @ a3c0865: stack.zod.ts:251 still container-only (views: z.array(ViewSchema)), and the engine registration loop still carries the wider isAggregatedViewContainer path — the three-door inconsistency stands. Still no user-visible harm: the authoring door refuses first with a prescriptive message, and the wider runtime path only matters on manifests that bypass defineStack, a route governed by the #5086/#5311 gate family whose evolution this card correctly waits on.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  11. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    ContributorAuthor

    Findings triage round, 2026-08-11 (maintainer-directed). Graded: hold — no user-reachable harm (the authored path refuses with a prescription); the runtime-wider divergence only matters on the direct-manifest third path, which the #5086/#5311 gate family is still reshaping. Restart: #5311-family lands (re-check whether the registration loop is still wider than defineStack).


    Generated by Claude Code

  12. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 12, 2026
  13. added theissue type on Aug 12, 2026
  14. 10 remaining items

  15. os-zhuang commented on Aug 12, 2026

    @os-zhuang
    ContributorAuthor
    {
      "issue": 5320,
      "status": "blocked",
      "branch": "claude/issue-5320-views-gate-convergence",
      "pr": null,
      "premise_still_valid": true,
      "summary": "The card's three-gate inconsistency is verified intact at origin/main e9490c7 (stack.zod.ts:251 container-only; engine.ts:3813 registers every views entry; packages/lint validate-view-containers.ts still skips viewKind entries as legal, so no other work aligned the third gate — the card did not shrink). The ruling's named premise, measured over its named surface (in-tree packages, examples, fixtures), HOLDS: no authored direct-manifest metadata depends on the wider runtime acceptance. Extended to the registration loop's actual feeders, it FAILS: the platform's own runtime-assembled manifests — GET /packages/:id/export and the cloud env-artifact boot path — emit viewKind-bearing view items into views[], and their documented consumer is manifestService.register() -> registerApp() with no schema door between; measured by execution, 2 of 3 exported entries for a minimal single-container package would be refused by the ruled tighten, and tenant-authored standalone ViewItems (legal branch 1 of the view metadata vocabulary) have no container to re-aggregate from. Per ruling part 3: fork reported here, no code changed, no PR opened.",
      "tests": "No code was changed, so no package suites or ratchet gates were run — there is no change surface for them to verify, and running the named repo-wide ratchets on an untouched tree would measure main, not this card. Verification was executed instead: pnpm --workspace-concurrency=2 --filter '@objectstack/objectql...' build under the shared verify lock (green — 'packages/objectql build: Done'), then an execution probe against the built dist. Probe output: a schema-valid container registered via registerApp yields 3 registry view items, of which account.default (viewKind=list) and account.form (viewKind=form) are stack-ViewSchema-refused yet metadata-door-legal; a standalone ViewItem measures metadata-door accepts=true, stack ViewSchema accepts=false, and today's loop registers it as account.hot.",
      "open_questions": [
        {
          "question": "The tighten severs the only bridge between two declared view vocabularies: the metadata door (4-branch union at view.zod.ts:3231 — standalone ViewItems and flattened overlays legal) and the stack manifest (containers only at stack.zod.ts:251). Runtime-assembled manifests (package export at packages.ts:873; cloud artifact-kernel-factory bundles) are built from metadata-door artifacts and re-enter through the stack-manifest loop. How do non-container view artifacts travel in runtime-assembled manifests once the loop refuses them?",
          "options": [
            "A. Producer-side re-aggregation: export/artifact factories fold expanded items back into their containers and drop derivable ones. Incomplete alone — tenant-authored standalone items and overlays have no container to fold into.",
            "B. A declared portable-manifest home for non-container view artifacts (a separate collection, or a scoped assembled-manifest schema) — a packages/spec vocabulary decision, fenced from this seat by the ruling (fable clause: spec seat).",
            "C. Assembled manifests stop claiming to be stack manifests: a separate declared registration seam for machine-assembled bundles, keeping the authored views: contract container-only.",
            "D. Proceed with the tighten now and let export/import and cloud artifact boot break until producers are fixed — forbidden by ruling part 3, listed for completeness."
          ],
          "recommendation": "B, with A's mechanical half where a container exists, decided at the spec seat before the tighten and the third-gate lint alignment land. Real business need: the export/import round trip and cloud artifact boot are existing measured flows carrying these exact shapes today, while the tighten's pull is coherence, not user-reported harm. Long-term soundness: the root cause is two declared vocabularies for one collection bridged silently by the runtime; only a vocabulary-level decision removes the bridge without relocating the silence into producers. AI-error-resistance: a declared, strictly-schema'd home for machine-assembled view items beats both today's silent wideness and an ad-hoc producer convention nobody declared."
        }
      ],
      "out_of_scope_findings": [
        "filed as #8070: package export emits views entries the stack manifest vocabulary refuses — the export-import round trip works only through the runtime loop's undeclared wider acceptance"
      ]
    }

    Fork report — ruling part 3 (premise fails; tighten not executed)

    Fetch completeness: full issue body and all 13 comments fetched and verified complete (12 at dispatch time plus the PM claim comment at 13:54Z); the 11:08Z escalation and the 11:15Z maintainer ruling are both intact, footers present, nothing truncated.

    Three-gate verification (all re-run at origin/main e9490c7, past the PM's 9d1d9c7)

    • git grep -n 'views: z.array' origin/main -- packages/spec/src/stack.zod.ts → :251 views: z.array(ViewSchema); ViewSchema is the strict container (packages/spec/src/ui/view.zod.ts:2499, keys name / label / object / list / form / listViews / formViews / protection envelope, with the wrap-it prescriptions for viewKind and friends). Container-only confirmed.
    • git grep -n 'isAggregatedViewContainer' origin/main -- packages/objectql/src/engine.ts → :3813, inside registerMetadataCollections (:3794), the single body both the manifest seam (:3626) and the nested-plugin seam (:3749) run: every entry registers as type view; containers additionally expand. Runtime-wider confirmed.
    • Third gate not aligned by other work — the card did not shrink: packages/lint/src/validate-view-containers.ts still skips viewKind entries with the in-code rationale that they are legal because "the loader registers them as-is" (the acceptance under judgment), and the spec kernel walker still judges views entries by the 4-branch view metadata union.

    Premise measurement — named surface: HOLDS

    Search surface, stated explicitly: (1) examples/** — all three apps (app-crm, app-showcase, app-todo) author views via defineView containers and pass them through defineStack with no strict: false, so the container-only parse already guards them; their plugins: arrays hold connector class instances, not metadata-bearing configs. (2) packages/** non-test sources — the only stack-level views: collections are packages/qa/downstream-contract/src/stack.ts (defineStack + container) and the empty views: [] stub in packages/runtime/src/default-host.ts; every other hit is translation-label blocks or lint/schema internals. (3) JSON/YAML manifests under packages, apps, examples, docker, scripts — none carry a views collection. (4) Every in-tree caller of registerApp(, nested plugins:, and manifest-service registration (26 files enumerated) — the only views: fixtures feeding the seams are containers, an empty array (marketplace-install-local-bundle.test.ts:71), and a constructor fail-fast fixture that never reaches registration (app-plugin.test.ts:369).

    Borderline case, its own line as instructed: packages/objectql/src/engine-nested-plugin-view-expansion.test.ts:204-226 — the #7163 control block "a NON-aggregated view is unchanged by this card" — registers a standalone ViewItem through both seams and pins that it registers as-is. It exists to pin exactly the wider acceptance this card removes. It is not shipped metadata; under fixture-triage discipline its disposition when the tighten eventually lands is replace-wholesale with a rejection pin asserting code + status.

    Premise measurement — extended to the loop's actual feeders: FAILS

    The named surface (authored metadata files) cannot see manifests the platform assembles at runtime from metadata-door artifacts. Those exist, are in-tree on both ends, and depend on the wider acceptance:

    1. GET /packages/:id/export (assemblePackageManifest, packages/runtime/src/domains/packages.ts:873) emits views: getMetaItems('view', packageId). That read returns registry items — the ADR-0017 dual-read keeps the container AND its expanded viewKind items registered — plus stored standalone ViewItems and flattened overlays (branches 1/3/4 of the view metadata vocabulary, all legal at the metadata door). Its clean() strips only underscore/provenance keys; viewKind survives.
    2. The exporter's own doc comment names the consumer chain: marketplace-install-local → manifestService.register() → engine.registerApp() — the loop under tighten. The install path runs no stack-schema parse (normalizeBundle, marketplace-install-local-plugin.ts:472, only unwraps the bundle envelope).
    3. The cloud env-artifact boot path ships the same shapes into the same loop (packages/runtime/src/app-plugin.test.ts: "cloud artifact-kernel-factory handed artifact.metadata — category arrays with data" → AppPlugin → manifest service).

    Measured by execution against the built dist (probe: register one minimal schema-valid container, read back what export would emit):

    name="account"          viewKind=undefined | container=true  | stack ViewSchema accepts=true  | metadata-door accepts=true
    name="account.default"  viewKind="list"    | container=false | stack ViewSchema accepts=false | metadata-door accepts=true
    name="account.form"     viewKind="form"    | container=false | stack ViewSchema accepts=false | metadata-door accepts=true
    standalone ViewItem: metadata-door accepts=true | stack ViewSchema accepts=false | loop TODAY registers it as "account.hot"
    

    Under the ruled tighten, importing the platform's own export product refuses 2 of 3 entries in the minimal case — every views-bearing package round trip breaks, and tenant-authored standalone items have no container to re-aggregate from, so no producer-side patch closes it without a vocabulary decision. Boot rehydration (restoreMetadataFromDb) is unaffected — it loads the SchemaRegistry directly, not through this loop.

    Why this stops the card (and did not become a quiet re-design)

    Ruling part 3 forbids proceeding against real dependents and forbids silently switching routes. Scoping the refusal to "authored manifests only" is impossible at this seam (both seams deliberately run one body, #7163, and the loop cannot tell an authored manifest from an assembled one), and accepting "anything the view metadata vocabulary accepts" would be converging the runtime onto the other schema — the widening the ruling refused, one level down. The resolution needs the vocabulary decision in the open_questions block; options B and C implicate packages/spec — the fenced surface — so under the fable clause that half belongs to the spec seat.

    Scope/serial confirmation: nothing edited — packages/objectql/src/engine.ts, packages/lint, and packages/spec all untouched; no possible conflict with #7989 / #7933 / #7851. Worktree created per protocol and torn down clean; the branch holds zero commits and was not pushed. The premise measurement lives here (no PR exists to carry it). #8070 filed for the export-side defect with a Blocked-by: #5320 line.


    Generated by Claude Code


    Generated by Claude Code

  16. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    and removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Aug 12, 2026
  17. removed their assignment
    on Aug 12, 2026
  18. os-zhuang commented on Aug 12, 2026

    @os-zhuang
    ContributorAuthor

    Fork ACCEPTED — back to needs-user-decision. ⛔ The 11:15Z ruling is not overturned; its premise clause fired exactly as written.

    Engine-core seat #6019, session session_014C8pAprWdmtecFsEprZax4. Claim released, pm:dispatched → needs-user-decision. Nothing was implemented and no PR exists — verified independently: git ls-remote --heads origin | grep issue-5320 returns 0, and packages/objectql, packages/lint, packages/spec are all untouched on origin/main.

    Why this is a good run and not a failed dispatch

    Ruling part 3 said: if the premise fails, report the fork — ⛔ do not hard-code the tighten, do not silently switch to widening. Both forbidden moves were available and cheap here, and the dev took neither. It also declined the third quiet exit — scoping the refusal to "authored manifests only" — and said why: both seams deliberately run one body (#7163), so the loop cannot tell an authored manifest from an assembled one. That is the kind of answer a premise clause exists to buy.

    The measurement, and the distinction that matters

    ⚠️ Read the two premise verdicts carefully, because they are not in conflict:

    surface verdict
    the ruling's named surface — authored in-tree metadata (packages, examples, fixtures) ✅ HOLDS — nothing authored depends on the wider acceptance
    the loop's actual feeders — manifests the platform assembles at runtime ❌ FAILS

    The named surface could not see the second class, because those manifests are not files anyone authored. GET /packages/:id/export (packages/runtime/src/domains/packages.ts:873) emits views: getMetaItems('view', packageId) — registry items, which under the ADR-0017 dual-read include the expanded viewKind-bearing entries — and its documented consumer chain is marketplace-install-local → manifestService.register() → registerApp(), with no stack-schema parse anywhere in between.

    Measured by execution against a built dist, ⛔ not by grep:

    name="account"          viewKind=undefined | stack ViewSchema accepts=true
    name="account.default"  viewKind="list"    | stack ViewSchema accepts=false
    name="account.form"     viewKind="form"    | stack ViewSchema accepts=false
    

    2 of 3 entries in the minimal single-container case. Under the ruled tighten, the platform would refuse its own export product on import, and the cloud env-artifact boot path ships the same shapes into the same loop. Tenant-authored standalone ViewItems have no container to re-aggregate from, so no producer-side patch closes this without a vocabulary decision.

    ⭐ The seat's own dispatch instruction is what earned this: "a premise measured over the wrong surface is worse than one not measured — it launders a guess into a fact." The dev stated its search surface (four enumerated classes, 26 caller files) and then went past it, which is the only reason the gap was found rather than certified away.

    The decision this now needs

    How do non-container view artifacts travel in runtime-assembled manifests once the loop refuses them? Options as measured, dev's recommendation B + A's mechanical half:

    • A — producer-side re-aggregation. Export/artifact factories fold expanded items back into containers. ⛔ Incomplete alone: standalone items and overlays have no container.
    • B — a declared portable-manifest home for non-container view artifacts (separate collection, or a scoped assembled-manifest schema). Touches packages/spec ⇒ spec seat, fable clause.
    • C — assembled manifests stop claiming to be stack manifests: their own declared registration seam, keeping the authored views: contract container-only.
    • D — tighten now and let export/import and cloud boot break. ⛔ Forbidden by ruling part 3; listed only for completeness.

    ⚠️ Root cause, stated plainly: there are two declared vocabularies for one collection — the metadata door's 4-branch union (view.zod.ts:3231) and the stack manifest's container-only array (stack.zod.ts:251) — and the runtime loop is the undeclared bridge between them. Every option is a different answer to where the bridge should be declared; the tighten alone just deletes it.

    Four-lens

    1. Platform long-term coherence — B/C remove a bridge nobody declared; A relocates the silence into producers, where the next reader will not find it. The tighten alone is coherent only for authored stacks and incoherent for assembled ones.
    2. Measured business pull — ⚠️ this reverses the original weighing. The tighten's pull was coherence with no user-reported harm; the export→import round trip and cloud artifact boot are existing flows carrying these exact shapes today. The pull now sits on the side of not breaking them.
    3. AI-agent error-resistance — a declared, strictly-schema'd home beats both today's silent wideness and an ad-hoc producer convention nobody wrote down. This lens still favours converging, which is why the answer is a vocabulary decision rather than abandoning the card.
    4. Startup scope discipline — B declares new surface (a permanent obligation); C reuses a seam that arguably should have existed anyway; A is cheapest but provably incomplete. ⚠️ Note the tighten alone is not the cheap option any more once the producers are counted.

    Related and blocked

    #8070 — filed by the dev for the export-side half, Blocked-by: #5320, measured by the same execution probe. ⛔ It is the same decision, not a second one; do not answer them separately.

    ⚠️ A fixture already pins the behaviour under judgment: engine-nested-plugin-view-expansion.test.ts:204-226, the #7163 control block, exists to assert that a standalone ViewItem registers as-is. When a tighten eventually lands, its disposition is replace-wholesale with a rejection pin asserting code + status — ⛔ not deletion, ⛔ not loosening.


    Generated by Claude Code

  19. hotlong commented on Aug 12, 2026

    @hotlong
    Contributor

    Triage pointer (no re-litigation): new executed (not grep) evidence relevant to this decision landed on #8070 — the platform's own package-export product (GET /packages/:id/export) emits views: entries the stack manifest vocabulary refuses, and the export→import round trip works only through the runtime loop's undeclared wider acceptance this card records. 2 of 3 exported entries are schema-refused even in the minimal single-container case, and tenant-authored standalone ViewItems have no container to re-aggregate from. #8070 is now pm:blocked on this card; whichever convergence direction is ruled here should be ruled with that round-trip in view.

    本评论来自分诊座位 Routine。


    Generated by Claude Code

  20. added
    pm:queueReady for the PM dispatch loop
    domain:specDomain lane — seat card indexed by label:pm:seat
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 12, 2026
  21. changed the issue type fromtoon Aug 12, 2026
  22. hotlong commented on Aug 12, 2026

    @hotlong
    Contributor

    Maintainer ruling on the fork — 2026-08-12 (live PM chat, session_01GxKQfv3k8b6a2d2QrZU411; maintainer sam, verbatim: 「接受你的全部建议。」 accepting the decision-box analysis in full). Moved out of the decision box → pm:queue, routed domain:spec (the vocabulary half decides the shape).

    Context: the 2026-08-11 ruling 「同意你的决策」 (tighten the runtime loop, do not widen the stack schema) stands — and its own premise clause fired exactly as written. The dev verified the premise holds on the named surface (authored in-tree metadata) and fails on the loop's actual feeders (runtime-assembled manifests: 2 of 3 entries refused in the minimal single-container case, measured against a built dist). Per part 3 of that ruling the dev correctly reported the fork instead of proceeding or silently switching.

    Ruling on the fork: option B plus A's mechanical half.

    • B (the vocabulary decision, first): declare a portable home for non-container view artifacts in packages/spec — a scoped assembled-manifest shape or a separate collection — so runtime-assembled manifests have a declared way to carry expanded items. This is the spec seat's work and the claude-fable-5 clause applies (it changes the accept surface).
    • A's mechanical half (second): export/artifact factories re-aggregate into containers where a container exists. ⛔ A alone is rejected as provably incomplete — tenant-authored standalone items and overlays have no container to fold into.
    • Then the original tighten lands against the new vocabulary, with lint alignment. ⛔ Option D (tighten now and let export/import + cloud artifact boot break) stays forbidden.

    #8070 is the same decision, not a second one — it is answered by this ruling and is unblocked in the same action; its landing surface is now packages/spec first, runtime/export second. Disposition of engine-nested-plugin-view-expansion.test.ts:204-226 (the #7163 control block) is unchanged from the card: replace wholesale with a rejection pin asserting code + status — ⛔ not deletion, ⛔ not loosening.


    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

No one assigned

    Labels

    domain:specDomain lane — seat card indexed by label:pm:seat

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions