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
spec: give push a served door (a platform capability, a config.push stack key and a services.push docs page), so a deployment can turn it on without host code #29820
Filing gate: ① an out-of-scope finding of the #29041 dev, escalated by the contract review of PR #29794 (record 6596752211, ③ out-of-scope 2 and the runtime-services note). Filed by domain:server seat 4. ⛔ Not a claim. Suggested-grade: p2 (push ships, but an os serve deployment cannot reach it).
What happens
PR #29794 ships @objectstack/service-push and the push channel in service-messaging. The channel mounts only while a push service is registered, and the only way to register one is a host that composes PushServicePlugin in code:
platform-capabilities.ts has messaging, email and sms capabilities with their packages, and no push.
There is no config.push key on the stack definition. push-config.zod.ts says so itself: its transport selection is not read from a stack key "and no os serve capability yet".
The docs have no runtime-services page for services.push beside the email and messaging ones.
So a deployment that runs os serve with a stack file cannot turn on push, and a notify node naming push is refused there as before.
Wanted
A declaration (domain:spec): the push capability token and its package, the config.push key carrying PushServiceConfigSchema (credentials only as credentialRef, ADR-0143 D3), mirroring how config.email selects email transports.
The served half: os serve composes PushServicePlugin when the capability is on and parses config.push; an inline secret is refused at boot as the plugin already does at init.
Related, not in this card: the origin member of PushDeliveryDataSchema reads as served now that its marker is off, but no device row stores an origin yet. #29768 makes that true; until it lands, every push goes without one (review ④ 3).
Claim: PM loop round 4 (release-pause exception, p1)
Session: session_01WGufzhJG3tKnksHVa1krBz
Account: os-support-ai
Branch: claude/project-thread-3dx6in (card thread, executor session_01WGufzijqxRKTwDp1neydqc; the thread can push only its own branch, the measured platform exception to claude/issue-29820-…)
Worktree: objectstack-issue-29820
Domain: domain:spec
Seat: domain:spec#2
File surface: packages/spec/src/kernel/platform-capabilities.ts + tests (the push token mapped to @objectstack/service-push), packages/spec/src/stack.zod.ts (the config.push key) + a stack test, the liveness row, regenerated artifacts, .changeset/29820-*.md. ⛔ Not push-config.zod.ts, its tests, push-config.mdx or packages/services/** (PR #29794 edits those).
Container & model: M, mode:thread, model: TIER_DEFAULT, effort: xhigh (p1); contract review at CONTRACT_REVIEW_TIER in seat before landing
Clause-②: yes (widening)
Metadata-protocol: added
Responsibility: a deployment cannot turn on push from a stack file | no push capability token and no config.push key | os serve (the served half, domain:server after PR #29794)
Thread-read: 6597435156
Premise: holds at main1bb9536e: platform-capabilities.ts has email, sms, messaging and no push; stack.zod.ts derives config.email from EmailServiceConfigSchema and has no config.push; #29816's transport union is on main (PR #29886).
Exception: the maintainer asked at 2026-11-03T10:35Z for this p1 card to be handled now despite the release pause.
Scope split: this claim is the card's Wanted 1 (the declaration) only. Wanted 2 (os serve composing PushServicePlugin) and Wanted 3 (the services.push docs page) describe PR #29794's plugin, which is not on main; they stay on this card for the domain:server lane after #29794 lands. The spec PR writes Refs #29820, not Fixes, so the card stays open.
Serial constraints cleared: the card's "Serial: after PR #29794" is ruled by this seat as not binding on the declaration half: the file surfaces are disjoint (PR #29794's 41 files touch none of the paths above). If declaring push before @objectstack/service-push is on main cannot be graded honestly as planned, the executor stops and reports the fork before writing it.
The executor stopped before writing, per the order, and measured at maine9ae8ef4 that the declaration half cannot be graded honestly as planned:
The push token.PlatformCapabilityProvider has no planned state, and no ledger covers the capability vocabulary. Mapped to @objectstack/service-push with edition open, defineStack accepts it, but the os build / os validate preflight then tells the operator to pnpm add @objectstack/service-push (a 404 on the registry today), and os serve drops the token silently (a known token with no CAPABILITY_PROVIDERS entry). open means "bundled with the cli, resolves out of the box", which would be false. No pin catches it: the drift test checks only serve ⊆ spec.
Ruling: C. Nothing lands ahead of its reader. The token, the push key and the os serve reader land together in one PR after PR #29794 merges, the card's own "Serial: after PR #29794". That PR also writes the services.push page. It states what os serve does with a relay config until a relay sender exists: refuse it at boot naming the missing sender, or serve direct only. The executor's fallback reading A (the key alone now, under a marker no gate reads) is declined for the same reason.
State change: pm:dispatched → pm:blocked; needs:contract-review removed (no PR). The card stays domain:spec. When #29794 merges it unblocks for whichever lane takes the combined PR; its reader is packages/cli, so a domain:server seat can claim it whole.
Stopped before writing, per the order's fork clause. The seat ruled C (comment 6601454188): the card is blocked behind PR #29794, and the token, the push key and the os serve reader land together after it. No branch push, no PR.
{
"issue": 29820,
"status": "blocked",
"premise_still_valid": true,
"branch": "claude/project-thread-3dx6in",
"pr": null,
"summary": "Stopped before writing. A `push` capability token cannot be graded honestly as planned on main e9ae8ef4. PlatformCapabilityProvider has no planned state, and no liveness ledger covers the vocabulary. With push mapped to @objectstack/service-push at edition open: defineStack accepts it; the os build/validate preflight classifies it installable and prints 'Run pnpm add @objectstack/service-push', but npm view returns 404 (control: @objectstack/service-sms 18.2.0 resolves); os serve skips it silently, because it is a known token with no core CAPABILITY_PROVIDERS entry and the resolver continues without a warning. Edition open is defined as bundled with the cli and resolving out of the box, which would be false. serve-capability-vocabulary.test.ts checks only core-providers subset-of spec, so no pin catches it. The stack key is top-level `push` beside email/sms (there is no config wrapper), and stack keys have no liveness ledger. push-config.zod.ts on main says a key is never authorable before something honours it, and the order forbids editing that file. The relay is the default transport, but PR #29794's service-push src has 0 relay code, so `push: {}` would have no reader even after #29794.",
"readings": {
"A": "Ship the `push` stack key alone now as [PLANNED]; the token with the served half. The push-config docblock stays contradicted until it is editable.",
"B": "Ship the token now as planned. This needs a planned flag on the provider row, read by the cli preflight and serve (packages/cli, outside the claimed surface), or else it accepts the 404 install hint and the silent serve drop.",
"C": "Hold the whole declaration. Land key + token + reader together in the served-half PR after #29794 (the docblock's own rule). Recommended; ruled by the seat."
},
"handoff_slices": [
"domain:server after PR #29794: the `push` capability token plus a core CAPABILITY_PROVIDERS entry, the top-level `push` stack key (PushServiceConfigSchema, COMPOSE_KEY_DISPOSITIONS single), os serve composing PushServicePlugin and parsing it (Wanted 1+2)",
"the relay transport needs a reader in service-push before `push: {}` (the relay default) means anything",
"the services.push runtime-services docs page (Wanted 3)"
],
"gates": "NOT MEASURED: no code written",
"tests": "NOT MEASURED: no code written",
"out_of_scope_findings": [
{"class": "observation", "text": "serve-capability-vocabulary.test.ts has no pin that every open-edition non-tier spec token has a core CAPABILITY_PROVIDERS entry; a future token can ship as an unfollowable install hint plus a silent serve drop", "carrier": "#29820"}
],
"api_writes": {"count": 1, "endpoints": ["POST issues/29820/comments (this report, via post-stamped)"]},
"mcp_calls": {"count": 4, "list": ["issue_read get #29820", "issue_read get_comments #29820 x2", "pull_request_read get_files #29794"]},
"security_findings": "none",
"deviations": []
}
Claim: PM loop round 6 (ruling C, round 2)
Session: session_01WGufzhJG3tKnksHVa1krBz
Account: os-support-ai
Branch: claude/project-thread-rx3xpv (card thread, executor session_01WGufzgjFwEiezTWdb7bk9i; the thread can push only its own branch, the measured platform exception to claude/issue-29820-…)
Worktree: objectstack-issue-29820
Domain: domain:spec (with the packages/cli reader in the same PR, per ruling C)
Seat: domain:spec#2
File surface: packages/spec/src/kernel/platform-capabilities.ts + tests (the push token), packages/spec/src/stack.zod.ts (the top-level push key, its COMPOSE_KEY_DISPOSITIONS row) + a stack test, packages/spec/src/system/push-config.zod.ts (docblock and markers only), packages/cli (serve composing PushServicePlugin, the boot refusals, the dependency), the services.push runtime-services docs page, regenerated artifacts, .changeset/29820-*.md. ⛔ Not ADR-0012 (#29817, spec seat 3).
Container & model: M, mode:thread, model: TIER_DEFAULT, effort: xhigh (p1); contract review at CONTRACT_REVIEW_TIER in seat before landing
Clause-②: yes (widening)
Metadata-protocol: added
Responsibility: a deployment cannot turn on push from a stack file | no push token, no push key, no os serve reader | os serve and the operator's stack file
Thread-read: 6601490513
Premise: holds at main6a4737ab: PR #29794 merged at 2026-11-03T16:30Z, so @objectstack/service-push and PushServicePlugin are on main; the plugin refuses a relay config at init (the relay sender is #29920). Blocked-by #29794 is cleared.
Serial constraints cleared: #29817 (ADR-0012 amendment) is claimed by spec seat 3 and edits no file above; the executor re-checks open PRs at PR time.
{
"issue": 29820,
"status": "done",
"branch": "claude/project-thread-rx3xpv",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29968",
"head": "0f588fe6af5c74301cc811687869e8d508503318",
"session": "session_01WGufzgjFwEiezTWdb7bk9i",
"premise_still_valid": true,
"summary": "Ruling C in one PR: the spec `push` capability token (provided by @objectstack/service-push, edition open, requested and not always-on), the top-level stack `push` key (PushServiceConfigSchema, credentialRef only, COMPOSE_KEY_DISPOSITIONS single), and the serve reader: core CAPABILITY_PROVIDERS.push plus resolveCapabilityArgument reading resolvePushCapabilityArg off the provider module, so `objectstack serve` and verify's bootStack share one rule. The reader refuses the relay (absent key, null, {}, transport relay) at boot with PUSH_RELAY_NOT_SERVED_MESSAGE, which names the missing relay sender and prescribes transport: 'direct', and refuses any schema-refused config (inline secrets first) naming paths but never values. A reverse pin asserts every open-edition token has a serve mount, so none is dropped silently. New services.push docs page; push-config.zod.ts docblock updated, the [PLANNED] marker kept only on the relay; cli and verify depend on service-push.",
"tests": "All under scripts/pm/os-verify-lock.sh. Full build turbo 120/120, VERDICT command-exit 0; spec rebuilt after the last spec src change, exit 0. spec test 808/808 files, 24288 passed + 1 todo; spec typecheck exit 0; spec test:repo 89/89 files, 1524/1524. cli unit tier 377/377 files, 5316/5316; cli typecheck exit 0 (integration tier left to CI: no spawn entry touched). core test + typecheck exit 0; service-push test + typecheck exit 0; verify test 48/48 files, 408/408, typecheck exit 0; metadata-protocol test 311 passed + 4 skipped files, 22320 passed + 26 skipped. ESLint over the 19 changed ts/mjs files exit 0. Ablation via scripts/ablation-replace.mjs of the relay refusal in service-push src/capability-arg.ts (`if (config.transport !== 'direct') {` to `if (false /* ablated-29820 */) {`, anchor 1 to 0, blob 8638e2857a5c to 2c1a8ad32f78): capability-arg.test.ts 5 failed / 7 passed (all five relay rows), cli serve-stack-email-sms-door.contract.test.ts 3 failed / 7 passed (no key, {}, relay). Restored: blob == HEAD 8638e2857a5c, git diff HEAD empty; same files 12/12 and 10/10.",
"gates": "dispatch-gates --commands on the final tree derives 142 commands; each run, exit codes recorded, all 142 exit 0. --ran: 142 derived accounted for, 142 run, 0 NOT-MEASURED, exit 0. First pass had 4 reds, each fixed in the diff: check:skill-top-level-keys (push added to the platform skill), check:test-source-alias (cli vitest alias for service-push), check:docs-audit-scope (audit scope regenerated with --write), check-plugin-teardown-shape --self-test (exit 3 from the shallow clone; 0 after fetching its base commit). spec check:generated exit 0. check-changeset-no-major --base origin/main with the final PR body: exit 0, LEVEL AXIS ok for yes (widening) + added; control with Metadata-protocol none: exit 1, refused only because the entries are graded minor. CI check-runs not yet read: the PR was just opened (in_progress).",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "1 — mcp__github__pull_request_read (get, PR 29968 draft-state read-back); no MCP write tool used",
"api_writes": "7 — git push to claude/project-thread-rx3xpv x5 (one more attempt was refused locally by the commit-trailer hook before sending and was re-sent after rewording the unpublished tip commit); POST /repos/objectstack-ai/objectstack/dispatches x1 (relay pr_create, draft, no assignees, no reviewers, no labels; read-back identical 11937/11937 bytes, assignees none); this os-dev-report comment via post-stamped.mjs x1",
"deviations": [
"File surface wider than the order's wanted list, each forced by the change: core (provider row + argument), service-push (the reader), verify (dependency + bootStack pin), spec unmanaged-install table + artifact-envelope list (classification tests), skills/objectstack-platform/SKILL.md (required gate check:skill-top-level-keys), scripts/docs-audit/handwritten-docs.json (check:docs-audit-scope), packages/cli/vitest.config.ts (check:test-source-alias).",
"Tier H: the skills/** edit makes this PR governed; it needs a GOVERNED_APPROVERS approval before it can land. Ratchet paid in the same file by deleting a stale path and count: 429 to 429 lines, 6011 to 6004 tokens; bundle SKILL.md lines 4539 to 4539.",
"PR body order follows the order file (attribution, Fixes, declaration lines, Skills-docs, then the 6-line block), consistent with os-dev.md.",
"The harness's post-PR assignee/reviewer and PR-subscription steps were skipped per os-dev rule 2 and the dispatch contract.",
"Human Minimum item 3 left unchecked: ESLint ran over the changed files only; the full pnpm lint is left to CI."
],
"skills_docs": "follow-up owed — skills/objectstack-platform/evals/config-plugins-ops.json: no eval exercises requires push or the push key; the seat files the card and rewrites the line to the card number before ACCEPT.",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"class: c · reach: named producer skills/objectstack-platform/SKILL.md · its requires table already omitted mailbox and package-registry before this diff · dedupe words: platform skill requires table missing mailbox package-registry",
"carrier: PR 29968 acceptance notes · noted, not filed",
"relay sender itself stays with #29920; ADR-0012 untouched (#29817)"
]
}
MERGED at 2026-11-04T10:36Z, head 3612ed4d, contract review PASS 6612508737 + delta 6613694045, ACCEPT 6614280468, authorized APPROVED review by os-zhuang (5766700562) on that head
State change: pm:dispatched removed. What shipped: the push platform capability (@objectstack/service-push, edition open), the top-level push stack key (credentials by credentialRef only), and os serve composing PushServicePlugin; a relay config is refused at boot naming the missing relay sender, and an inline secret is refused at authoring and boot; the services.push runtime-services page. Left elsewhere: the relay sender is #29920; the skill row clause and the eval for push ride #29969.
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p1 ·
domain:speckept ·pm:triage→pm:queue· 2026-11-03T06:55Z⛔ Not a claim.
os servedeployment cannot turn it on: there is nopushplatform capability, noconfig.pushstack key, and noservices.pushdocs page.transport: relay | directon PushServiceConfigSchema, and the server→relay wire shape (ruling cloud#3519) #29816'stransportshape, becauseconfig.pushcarries it.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:spec#2 · os-support-ai · session_01WGufzhJG3tKnksHVa1krBz
Claim: PM loop round 4 (release-pause exception, p1)
Session:
session_01WGufzhJG3tKnksHVa1krBzAccount:
os-support-aiBranch:
claude/project-thread-3dx6in(card thread, executorsession_01WGufzijqxRKTwDp1neydqc; the thread can push only its own branch, the measured platform exception toclaude/issue-29820-…)Worktree:
objectstack-issue-29820Domain:
domain:specSeat:
domain:spec#2File surface:
packages/spec/src/kernel/platform-capabilities.ts+ tests (thepushtoken mapped to@objectstack/service-push),packages/spec/src/stack.zod.ts(theconfig.pushkey) + a stack test, the liveness row, regenerated artifacts,.changeset/29820-*.md. ⛔ Notpush-config.zod.ts, its tests,push-config.mdxorpackages/services/**(PR #29794 edits those).Container & model:
M,mode:thread,model: TIER_DEFAULT,effort: xhigh(p1); contract review atCONTRACT_REVIEW_TIERin seat before landingClause-②: yes (widening)
Metadata-protocol: added
Responsibility: a deployment cannot turn on push from a stack file | no
pushcapability token and noconfig.pushkey |os serve(the served half,domain:serverafter PR #29794)Thread-read: 6597435156
Premise: holds at
main1bb9536e:platform-capabilities.tshasemail,sms,messagingand nopush;stack.zod.tsderivesconfig.emailfromEmailServiceConfigSchemaand has noconfig.push; #29816'stransportunion is onmain(PR #29886).Exception: the maintainer asked at 2026-11-03T10:35Z for this p1 card to be handled now despite the release pause.
Scope split: this claim is the card's Wanted 1 (the declaration) only. Wanted 2 (
os servecomposingPushServicePlugin) and Wanted 3 (theservices.pushdocs page) describe PR #29794's plugin, which is not onmain; they stay on this card for thedomain:serverlane after #29794 lands. The spec PR writesRefs #29820, notFixes, so the card stays open.Serial constraints cleared: the card's "Serial: after PR #29794" is ruled by this seat as not binding on the declaration half: the file surfaces are disjoint (PR #29794's 41 files touch none of the paths above). If declaring
pushbefore@objectstack/service-pushis onmaincannot be graded honestly as planned, the executor stops and reports the fork before writing it.objectstack-fleet commentedon Nov 3, 2026
domain:spec#2 · os-support-ai · session_01WGufzhJG3tKnksHVa1krBz
Seat ruling — #29820 held behind PR #29794 (reading C) · claim 6601407323 released
Blocked-by: #29794
The executor stopped before writing, per the order, and measured at
maine9ae8ef4that the declaration half cannot be graded honestly as planned:pushtoken.PlatformCapabilityProviderhas no planned state, and no ledger covers the capability vocabulary. Mapped to@objectstack/service-pushwith editionopen,defineStackaccepts it, but theos build/os validatepreflight then tells the operator topnpm add @objectstack/service-push(a 404 on the registry today), andos servedrops the token silently (a known token with noCAPABILITY_PROVIDERSentry).openmeans "bundled with the cli, resolves out of the box", which would be false. No pin catches it: the drift test checks only serve ⊆ spec.pushstack key. It is a top-levelpushbesideemail/sms, plus aCOMPOSE_KEY_DISPOSITIONSrow. Stack keys have no liveness ledger, so a[PLANNED]grade is a describe marker no gate reads.push-config.zod.tsonmainstates the rule this would break: a key is never authorable before something honours it. And the default transport is the hosted relay, which PR feat(notifications): the push channel — service-push (APNs + FCM) and its channel shell in service-messaging #29794'sservice-pushdoes not send, sopush: {}has no reader even after feat(notifications): the push channel — service-push (APNs + FCM) and its channel shell in service-messaging #29794 lands.Ruling: C. Nothing lands ahead of its reader. The token, the
pushkey and theos servereader land together in one PR after PR #29794 merges, the card's own "Serial: after PR #29794". That PR also writes theservices.pushpage. It states whatos servedoes with a relay config until a relay sender exists: refuse it at boot naming the missing sender, or serve direct only. The executor's fallback reading A (the key alone now, under a marker no gate reads) is declined for the same reason.State change:
pm:dispatched→pm:blocked;needs:contract-reviewremoved (no PR). The card staysdomain:spec. When #29794 merges it unblocks for whichever lane takes the combined PR; its reader ispackages/cli, so adomain:serverseat can claim it whole.objectstack-fleet commentedon Nov 3, 2026
domain:spec#2 · os-support-ai · session_01WGufzijqxRKTwDp1neydqc
os-dev-report
Stamp: 2026-11-03T10:42Z
Stopped before writing, per the order's fork clause. The seat ruled C (comment 6601454188): the card is blocked behind PR #29794, and the token, the
pushkey and theos servereader land together after it. No branch push, no PR.{ "issue": 29820, "status": "blocked", "premise_still_valid": true, "branch": "claude/project-thread-3dx6in", "pr": null, "summary": "Stopped before writing. A `push` capability token cannot be graded honestly as planned on main e9ae8ef4. PlatformCapabilityProvider has no planned state, and no liveness ledger covers the vocabulary. With push mapped to @objectstack/service-push at edition open: defineStack accepts it; the os build/validate preflight classifies it installable and prints 'Run pnpm add @objectstack/service-push', but npm view returns 404 (control: @objectstack/service-sms 18.2.0 resolves); os serve skips it silently, because it is a known token with no core CAPABILITY_PROVIDERS entry and the resolver continues without a warning. Edition open is defined as bundled with the cli and resolving out of the box, which would be false. serve-capability-vocabulary.test.ts checks only core-providers subset-of spec, so no pin catches it. The stack key is top-level `push` beside email/sms (there is no config wrapper), and stack keys have no liveness ledger. push-config.zod.ts on main says a key is never authorable before something honours it, and the order forbids editing that file. The relay is the default transport, but PR #29794's service-push src has 0 relay code, so `push: {}` would have no reader even after #29794.", "readings": { "A": "Ship the `push` stack key alone now as [PLANNED]; the token with the served half. The push-config docblock stays contradicted until it is editable.", "B": "Ship the token now as planned. This needs a planned flag on the provider row, read by the cli preflight and serve (packages/cli, outside the claimed surface), or else it accepts the 404 install hint and the silent serve drop.", "C": "Hold the whole declaration. Land key + token + reader together in the served-half PR after #29794 (the docblock's own rule). Recommended; ruled by the seat." }, "handoff_slices": [ "domain:server after PR #29794: the `push` capability token plus a core CAPABILITY_PROVIDERS entry, the top-level `push` stack key (PushServiceConfigSchema, COMPOSE_KEY_DISPOSITIONS single), os serve composing PushServicePlugin and parsing it (Wanted 1+2)", "the relay transport needs a reader in service-push before `push: {}` (the relay default) means anything", "the services.push runtime-services docs page (Wanted 3)" ], "gates": "NOT MEASURED: no code written", "tests": "NOT MEASURED: no code written", "out_of_scope_findings": [ {"class": "observation", "text": "serve-capability-vocabulary.test.ts has no pin that every open-edition non-tier spec token has a core CAPABILITY_PROVIDERS entry; a future token can ship as an unfollowable install hint plus a silent serve drop", "carrier": "#29820"} ], "api_writes": {"count": 1, "endpoints": ["POST issues/29820/comments (this report, via post-stamped)"]}, "mcp_calls": {"count": 4, "list": ["issue_read get #29820", "issue_read get_comments #29820 x2", "pull_request_read get_files #29794"]}, "security_findings": "none", "deviations": [] }objectstack-fleet commentedon Nov 3, 2026
domain:spec#2 · os-support-ai · session_01WGufzhJG3tKnksHVa1krBz
Claim: PM loop round 6 (ruling C, round 2)
Session:
session_01WGufzhJG3tKnksHVa1krBzAccount:
os-support-aiBranch:
claude/project-thread-rx3xpv(card thread, executorsession_01WGufzgjFwEiezTWdb7bk9i; the thread can push only its own branch, the measured platform exception toclaude/issue-29820-…)Worktree:
objectstack-issue-29820Domain:
domain:spec(with thepackages/clireader in the same PR, per ruling C)Seat:
domain:spec#2File surface:
packages/spec/src/kernel/platform-capabilities.ts+ tests (thepushtoken),packages/spec/src/stack.zod.ts(the top-levelpushkey, itsCOMPOSE_KEY_DISPOSITIONSrow) + a stack test,packages/spec/src/system/push-config.zod.ts(docblock and markers only),packages/cli(serve composingPushServicePlugin, the boot refusals, the dependency), theservices.pushruntime-services docs page, regenerated artifacts,.changeset/29820-*.md. ⛔ Not ADR-0012 (#29817, spec seat 3).Container & model:
M,mode:thread,model: TIER_DEFAULT,effort: xhigh(p1); contract review atCONTRACT_REVIEW_TIERin seat before landingClause-②: yes (widening)
Metadata-protocol: added
Responsibility: a deployment cannot turn on push from a stack file | no
pushtoken, nopushkey, noos servereader |os serveand the operator's stack fileThread-read: 6601490513
Premise: holds at
main6a4737ab: PR #29794 merged at 2026-11-03T16:30Z, so@objectstack/service-pushandPushServicePluginare onmain; the plugin refuses a relay config at init (the relay sender is #29920). Blocked-by #29794 is cleared.Serial constraints cleared: #29817 (ADR-0012 amendment) is claimed by spec seat 3 and edits no file above; the executor re-checks open PRs at PR time.
objectstack-fleet commentedon Nov 3, 2026
domain:spec#2 · os-support-ai · session_01WGufzgjFwEiezTWdb7bk9i
os-dev-report
Stamp: 2026-11-03T18:31Z
{ "issue": 29820, "status": "done", "branch": "claude/project-thread-rx3xpv", "pr": "https://github.com/objectstack-ai/objectstack/pull/29968", "head": "0f588fe6af5c74301cc811687869e8d508503318", "session": "session_01WGufzgjFwEiezTWdb7bk9i", "premise_still_valid": true, "summary": "Ruling C in one PR: the spec `push` capability token (provided by @objectstack/service-push, edition open, requested and not always-on), the top-level stack `push` key (PushServiceConfigSchema, credentialRef only, COMPOSE_KEY_DISPOSITIONS single), and the serve reader: core CAPABILITY_PROVIDERS.push plus resolveCapabilityArgument reading resolvePushCapabilityArg off the provider module, so `objectstack serve` and verify's bootStack share one rule. The reader refuses the relay (absent key, null, {}, transport relay) at boot with PUSH_RELAY_NOT_SERVED_MESSAGE, which names the missing relay sender and prescribes transport: 'direct', and refuses any schema-refused config (inline secrets first) naming paths but never values. A reverse pin asserts every open-edition token has a serve mount, so none is dropped silently. New services.push docs page; push-config.zod.ts docblock updated, the [PLANNED] marker kept only on the relay; cli and verify depend on service-push.", "tests": "All under scripts/pm/os-verify-lock.sh. Full build turbo 120/120, VERDICT command-exit 0; spec rebuilt after the last spec src change, exit 0. spec test 808/808 files, 24288 passed + 1 todo; spec typecheck exit 0; spec test:repo 89/89 files, 1524/1524. cli unit tier 377/377 files, 5316/5316; cli typecheck exit 0 (integration tier left to CI: no spawn entry touched). core test + typecheck exit 0; service-push test + typecheck exit 0; verify test 48/48 files, 408/408, typecheck exit 0; metadata-protocol test 311 passed + 4 skipped files, 22320 passed + 26 skipped. ESLint over the 19 changed ts/mjs files exit 0. Ablation via scripts/ablation-replace.mjs of the relay refusal in service-push src/capability-arg.ts (`if (config.transport !== 'direct') {` to `if (false /* ablated-29820 */) {`, anchor 1 to 0, blob 8638e2857a5c to 2c1a8ad32f78): capability-arg.test.ts 5 failed / 7 passed (all five relay rows), cli serve-stack-email-sms-door.contract.test.ts 3 failed / 7 passed (no key, {}, relay). Restored: blob == HEAD 8638e2857a5c, git diff HEAD empty; same files 12/12 and 10/10.", "gates": "dispatch-gates --commands on the final tree derives 142 commands; each run, exit codes recorded, all 142 exit 0. --ran: 142 derived accounted for, 142 run, 0 NOT-MEASURED, exit 0. First pass had 4 reds, each fixed in the diff: check:skill-top-level-keys (push added to the platform skill), check:test-source-alias (cli vitest alias for service-push), check:docs-audit-scope (audit scope regenerated with --write), check-plugin-teardown-shape --self-test (exit 3 from the shallow clone; 0 after fetching its base commit). spec check:generated exit 0. check-changeset-no-major --base origin/main with the final PR body: exit 0, LEVEL AXIS ok for yes (widening) + added; control with Metadata-protocol none: exit 1, refused only because the entries are graded minor. CI check-runs not yet read: the PR was just opened (in_progress).", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "1 — mcp__github__pull_request_read (get, PR 29968 draft-state read-back); no MCP write tool used", "api_writes": "7 — git push to claude/project-thread-rx3xpv x5 (one more attempt was refused locally by the commit-trailer hook before sending and was re-sent after rewording the unpublished tip commit); POST /repos/objectstack-ai/objectstack/dispatches x1 (relay pr_create, draft, no assignees, no reviewers, no labels; read-back identical 11937/11937 bytes, assignees none); this os-dev-report comment via post-stamped.mjs x1", "deviations": [ "File surface wider than the order's wanted list, each forced by the change: core (provider row + argument), service-push (the reader), verify (dependency + bootStack pin), spec unmanaged-install table + artifact-envelope list (classification tests), skills/objectstack-platform/SKILL.md (required gate check:skill-top-level-keys), scripts/docs-audit/handwritten-docs.json (check:docs-audit-scope), packages/cli/vitest.config.ts (check:test-source-alias).", "Tier H: the skills/** edit makes this PR governed; it needs a GOVERNED_APPROVERS approval before it can land. Ratchet paid in the same file by deleting a stale path and count: 429 to 429 lines, 6011 to 6004 tokens; bundle SKILL.md lines 4539 to 4539.", "PR body order follows the order file (attribution, Fixes, declaration lines, Skills-docs, then the 6-line block), consistent with os-dev.md.", "The harness's post-PR assignee/reviewer and PR-subscription steps were skipped per os-dev rule 2 and the dispatch contract.", "Human Minimum item 3 left unchecked: ESLint ran over the changed files only; the full pnpm lint is left to CI." ], "skills_docs": "follow-up owed — skills/objectstack-platform/evals/config-plugins-ops.json: no eval exercises requires push or the push key; the seat files the card and rewrites the line to the card number before ACCEPT.", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "class: c · reach: named producer skills/objectstack-platform/SKILL.md · its requires table already omitted mailbox and package-registry before this diff · dedupe words: platform skill requires table missing mailbox package-registry", "carrier: PR 29968 acceptance notes · noted, not filed", "relay sender itself stays with #29920; ADR-0012 untouched (#29817)" ] }objectstack-fleet commentedon Nov 4, 2026
domain:spec#2 · os-support-ai · session_01WGufzhJG3tKnksHVa1krBz
Landed. PR #29968 merged through the queue (merge commit
9ebca947); this card closed as completed by itsFixesline.MERGEDat 2026-11-04T10:36Z, head3612ed4d, contract review PASS 6612508737 + delta 6613694045, ACCEPT 6614280468, authorized APPROVED review byos-zhuang(5766700562) on that headclosed(completed)State change:
pm:dispatchedremoved. What shipped: thepushplatform capability (@objectstack/service-push, editionopen), the top-levelpushstack key (credentials bycredentialRefonly), andos servecomposingPushServicePlugin; a relay config is refused at boot naming the missing relay sender, and an inline secret is refused at authoring and boot; theservices.pushruntime-services page. Left elsewhere: the relay sender is #29920; the skill row clause and the eval forpushride #29969.