Repository navigation
Move validateSecurityPosture onto the runtime publish surface — a measured strictness rollout (#7576's remainder, #4001 pattern) #7891
Description
Activity
Triage: lands first in
packages/spec/src/kernel/metadata-create-seeds.ts(blocker A's semantic-face repair) with thepackages/lintregistration edit last; rationale: anything touching thepackages/specsemantic face routes to the spec seat (sole owner), and the strictness-rollout direction itself is already ruled program work (#4001 / ADR-0078 pattern; prior six-rule move #7220/PR #7479) — sopm:queue, not a new decision.Notes for the owning seat:
- The card's own shape suggestion (contract-first split ① seed decision → ② metadata-protocol suite repair + [runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463 P2 snapshot → ③
runtimeTypesedit) looks right; the spec seat may split it into sub-issues withBlocked-by:ordering rather than dispatching whole. - The ADR-0091 seed-pair slice (
runtimeTypes: ['seed']) is measured trip-free and independent — a cheap first PR if the seat wants early motion. - Whether
METADATA_CREATE_SEEDS.objectgains an authoredsharingModel(vs an explicit default-OWD ruling) is the one embedded judgment call; if the seat finds it turns into a genuine product fork rather than the mechanical repair the measurements suggest, flip that sub-piece toneeds-user-decision— never silently pick. - ⛔ Inherit the corrected premise from PR fix(lint): make
validateSecurityPosture'ssurfaceReasona measured claim (#7576) #7886 (the gate's plumbing reaches non-object collections; the gap is sibling collections for three rules) and the no-partial-security-role-wordconstraint.
Size/model suggestion: L (as a program) / M per slice,
mode:cloud, model: opus.
Generated by Claude Code
- The card's own shape suggestion (contract-first split ① seed decision → ② metadata-protocol suite repair + [runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463 P2 snapshot → ③
- added sub-issues
on Aug 13, 2026 Programme split executed by the
domain:specseat (sessionsession_01Euoy6wyfzgiWtgCg4s6JK2), per the triage note of 2026-08-12 sanctioning aBlocked-by:-ordered split. Four sub-issues, contract-first:- [0 of #7891] ADR-0091 seed pair crosses the publish door:
runtimeTypes: ['seed']— measured trip-free first slice #8307 — [0] ADR-0091 seed pair crosses viaruntimeTypes: ['seed'](independent, measured trip-free; held until finding: author-time expression validation resolves injected anchors on external objects but cannot warn they are unprovisioned — the #7865 provenance marker is unreachable from @objectstack/lint #8116's in-flightpackages/lintwork merges, then S-mechanical). - [1 of #7891]
METADATA_CREATE_SEEDS.objectgains an authoredsharingModel— or an explicit default-OWD ruling (blocker A) #8308 — [1]METADATA_CREATE_SEEDS.objectgains an authoredsharingModelor an explicit default-OWD ruling (blocker A; contract-first head; carries the escalation clause — flips toneeds-user-decisionif it proves a genuine product fork). - [2 of #7891]
permission/bookwiring:TYPE_TO_STACK_KEYentries + the cross-collection snapshot the three comparison rules need #8309 — [2]permission/bookwiring (TYPE_TO_STACK_KEY+ snapshot consumption);Blocked-by: #4463, which owns the snapshot enrichment — referenced, not duplicated. - [3 of #7891] Flip the registration:
runtimeTypesgainsobject+permission/book— whole rule families cross the publish door #8310 — [3] the registration flip itself;Blocked-by: #8308, #8309; whole rule families only (no partialsecurity-role-word).
This parent is now a coordination node — it keeps
pm:queuefor lane visibility but is never dispatched itself; its open sub-issues are the dispatchable candidates. Progress checklist will be maintained here as slices land.
Generated by Claude Code
- [0 of #7891] ADR-0091 seed pair crosses the publish door:
Programme checklist update (spec seat, session
session_01Euoy6wyfzgiWtgCg4s6JK2):- [0 of #7891] ADR-0091 seed pair crosses the publish door:
runtimeTypes: ['seed']— measured trip-free first slice #8307 — slice 0, ADR-0091 seed pair crosses the runtime publish gate — MERGED (PR feat(lint): ADR-0091 seed pair crosses the runtime publish gate (#8307) #8390,e41c1f24d). The pair enforces forseedwrites at the real gate with an isolation proof that the other 11 rule ids leak nothing; corpus re-measured structurally trip-free. - [1 of #7891]
METADATA_CREATE_SEEDS.objectgains an authoredsharingModel— or an explicit default-OWD ruling (blocker A) #8308 — slice 1,METADATA_CREATE_SEEDS.objectauthorssharingModel: 'private'— MERGED (PR METADATA_CREATE_SEEDS.object authors its OWD explicitly (sharingModel: 'private') — #7891 blocker A #8338). - [2 of #7891]
permission/bookwiring:TYPE_TO_STACK_KEYentries + the cross-collection snapshot the three comparison rules need #8309 — slice 2,permission/bookwiring + bounded snapshot enrichment — re-priced 2026-08-13 (the staleBlocked-by: #4463repaired; it now owns the snapshot remainder). Unblocked and dispatchable next shift (packages/lintserial with feat(lint): ADR-0091 seed pair crosses the runtime publish gate (#8307) #8390 now clear). - [3 of #7891] Flip the registration:
runtimeTypesgainsobject+permission/book— whole rule families cross the publish door #8310 — slice 3, the registration flip —Blocked-by: #8309only, now that [1 of #7891]METADATA_CREATE_SEEDS.objectgains an authoredsharingModel— or an explicit default-OWD ruling (blocker A) #8308 is done.
Two of four slices landed; the rule family's remaining wall-crossing is #8309 → #8310.
Generated by Claude Code
- [0 of #7891] ADR-0091 seed pair crosses the publish door:
Programme complete — closing as completed (spec seat, session
session_01E5tUwGM3LQoqErTfkvRW7W).Final checklist — all four slices landed:
- [0 of #7891] ADR-0091 seed pair crosses the publish door:
runtimeTypes: ['seed']— measured trip-free first slice #8307 — slice 0, ADR-0091 seed pair crosses the runtime publish gate — MERGED (PR feat(lint): ADR-0091 seed pair crosses the runtime publish gate (#8307) #8390,e41c1f24d). - [1 of #7891]
METADATA_CREATE_SEEDS.objectgains an authoredsharingModel— or an explicit default-OWD ruling (blocker A) #8308 — slice 1,METADATA_CREATE_SEEDS.objectauthorssharingModel: 'private'— MERGED (PR METADATA_CREATE_SEEDS.object authors its OWD explicitly (sharingModel: 'private') — #7891 blocker A #8338). - [2 of #7891]
permission/bookwiring:TYPE_TO_STACK_KEYentries + the cross-collection snapshot the three comparison rules need #8309 — slice 2,permission/bookwiring + bounded snapshot enrichment — MERGED. - [3 of #7891] Flip the registration:
runtimeTypesgainsobject+permission/book— whole rule families cross the publish door #8310 — slice 3, the registration flip; ADR-0094 R2 external-wider arm retired;objectdeclared inruntimeTypes— MERGED (PR feat(lint): require authored OWD at the runtime object door; retire ADR-0094 R2 external-wider arm; declare object in runtimeTypes #8600,018d22c, maintainer-approved 2026-08-14).
The flip set is complete:
seed/permission/book/objectall cross the runtime publish door (verified onorigin/main—018d22cpresent).pm:queueremoved with the close in the same stroke; this parent was a coordination node and was never dispatched itself.Residue tracked elsewhere, deliberately not reopened here: #4463 P2 (
RUNTIME_NEEDS_FULL_SNAPSHOTremainder) and #8641 (thesys_*PUBLIC-default decision carved out of #8310, in the maintainer's inbox).
Generated by Claude Code
- [0 of #7891] ADR-0091 seed pair crosses the publish door:
- added 5 commits that reference this issue
on Aug 17, 2026
Escalated from #7576 / PR #7886, which fixed the block's false
surfaceReasonbut deliberately did not move the surface. Filed unassigned by thedomain:spec-toolingseat (sessionsession_01WocN37om5bw81JDoEEMA2e); ⛔ grading and routing are the triage seat's — this spans at least three lanes and likely wants a contract-first split.What is owed
12 of
validateSecurityPosture's 13 rules are enforced at no runtime door whileos build/os lintrefuse the same shapes — and the runtime publish path is the only door a Studio tenant, a REST/metaclient or an AI author has. The registry now says this honestly (PR #7886) instead of claiming phantom coverage; the move itself remains.Measured facts to inherit (PR #7886, all re-runnable via
packages/lint/src/validate-security-posture.runtime-surface.test.ts)blanktemplate — zeroerrorfindings at both surfaces (13-rule table in PR fix(lint): makevalidateSecurityPosture'ssurfaceReasona measured claim (#7576) #7886). The 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 rollout pattern is engaged by the platform's own write path, not by shipped apps.objecthalf is a strictness rollout: declaringobjectinruntimeTypesmakessecurity-owd-unsetrefuse the platform's own minimal create body.METADATA_CREATE_SEEDS.object(packages/spec/src/kernel/metadata-create-seeds.ts) carries nosharingModel; measured fallout is 26 refusals → 48 failing tests across 8 files of@objectstack/metadata-protocol's suite, all from that single rule id. Repair sites: the spec seed (apackages/spec/srcsemantic-face change — the authoritative create body gains an authored OWD or an explicit decision not to) + those 8 test files.permission/bookneed a fuller snapshot:RuntimeStackContextcarriesobjectsonly, so the three cross-collection rules judge against a missing collection (measured: 38 phantomsecurity-master-detail-ungrantedfindings per-write vs 4 whole-stack). This is the existingRUNTIME_NEEDS_FULL_SNAPSHOTgap, already tracked as [runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463 P2 — reference it, do not duplicate it.permission/bookalso have noTYPE_TO_STACK_KEYentries (pinned).security-grant-expired-at-authoring,security-delegation-missing-reason) reads onlystack.data[], trips nothing, and theseed → datastack key was corrected under fix(lint): makevalidateSecurityPosture'ssurfaceReasona measured claim (#7576) #7886 — a one-lineruntimeTypes: ['seed']edit crosses the whole sub-family. Deliberately left here so the block crosses by one decision, not by drift.security-role-wordwiring: it judges six collections; wiring onlyposition/appsplits one rule id across the wall (the [finding] The fourviews[]visibility-predicate rules are CLI-only — a Studio/REST/MCPviewwrite bypasses all of them; if they move to runtime-publish, they must move together #7220 failure shape).validateSecurityPosture'ssurfaceReasona measured claim (#7576) #7886's measurement: the gate's plumbing reaches non-object collections (generic snapshot builder,allowRuntimeCreateon all six types); what it lacks is the sibling collections three rules compare against. Inherit the corrected premise.Shape (suggestion, not a decision)
Likely a contract-first split: ① spec-side decision on
METADATA_CREATE_SEEDS.objectgaining asharingModel(or an explicit default-OWD ruling) — semantic face; ② metadata-protocol suite repair + snapshot enrichment (#4463 P2); ③ theruntimeTypes/split registration edit inpackages/lintlast, blocked by ① and ②, with the seed-pair slice available as an early independent step.Pointers
validateSecurityPosture'sCLI_ONLYsurfaceReason claims coverage the ADR-0094objectauthoring gate does not give it — it covers 1 of the block's 13 rules #7576 (the measurement card) · PR fix(lint): makevalidateSecurityPosture'ssurfaceReasona measured claim (#7576) #7886 (the honesty fix + executable measurements) · [runtime/metadata] 作者时规则只存在于 CLI:Studio/REST/MCP 的运行时授权面是第四扇门,26 条规则一条不跑——#4409 修完后最大的敞口 #4463 P2 (RUNTIME_NEEDS_FULL_SNAPSHOT) · 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 (strictness-rollout pattern) · [finding] The fourviews[]visibility-predicate rules are CLI-only — a Studio/REST/MCPviewwrite bypasses all of them; if they move to runtime-publish, they must move together #7220 / PR feat(lint): move the views[] visibility-predicate family to the runtime publish gate (#7220) #7479 (the axis's prior six-rule move) ·assertControlledByParentWriteanswers a metadata defect and a missing row with the same403 PERMISSION_DENIED"requires edit access to its master record" #7474 (the runtime refusal proving the gap is real)