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(auth): declare the mobile sign-in hand-off surface (one-time-token generate/verify paths, the registered app-scheme list, any advertised feature flag) before #29714 enables it #29736
立卡门类别: ④ 协调节点 — the spec slice of #29714 (carries the contract-first half of #29714; #29714 keeps the server half). Triage first-touch on #29714 (6594269680): 「the new public surface is declared in packages/spec by a domain:spec card or PR before the server PR goes ready. The server seat files it at claim」. Routed to domain:server#2 to dispatch by the coordinator (2026-11-03 03:02Z).
业务理由: ④ — inherits #29714's: a mobile user whose identity provider refuses embedded WebViews (Google among them) cannot sign in to the app today. #29714 (maintainer-ruled option B, mobile#148 comment 6593861138) enables better-auth's one-time-token plugin; the routes and config it adds are public, so the spec declares them first.
动手的读者: a domain:spec card thread dispatched by domain:server#2; one spec PR under packages/spec/src/api/ (and kernel/public-auth-features.ts / system/auth-config.zod.ts if they are touched). Suggested-grade: p2 · inherits #29714.
查重 (includes closed): is:issue one-time-token spec 9 (only #29714 relevant), is:issue AuthEndpointPaths one-time 0, is:issue app scheme auth spec 45 (only #29714 relevant; #26768 / #28277 are outbound connector auth), is:issue mobile sign-in handoff 4 (none about this). 0 duplicates.
What main declares today
packages/spec/src/api/auth-endpoints.zod.tsAuthEndpointPaths lists better-auth paths (sign-in, session, two-factor, passkey, magic-link, device) and no /one-time-token/* path.
packages/spec/src/system/auth-config.zod.ts has trustedOrigins and no list of registered native app schemes.
packages/spec/src/kernel/public-auth-features.ts is the registry every served features flag must be classified in (plugin-auth's drift guard reds an unclassified one).
Declare where a deployment registers the app schemes the server may redirect a token to (key name by repo precedent, e.g. beside trustedOrigins; a new key name settled by precedent is the seat's call under the veto window), with its refusal for an unregistered scheme stated in the docblock.
Claim: PM loop round 1 · card thread · 2026-11-03T03:13Z
Session: session_01JQwxbXKRzgnVvjzxaYxLUf (the seat); the card thread is session_01JQwxbXghRkYmSR5dVh8PFG
Account: os-warren
Branch: claude/project-thread-s5w2nj
Worktree: the card thread's own container checkout
Domain: domain:spec (the spec slice of #29714, routed to domain:server#2 by the coordinator)
Seat: domain:server#2
File surface: packages/spec/src/api/auth-endpoints.zod.ts (two paths + request/response schemas), packages/spec/src/system/auth-config.zod.ts (the registered app-scheme list), packages/spec/src/kernel/public-auth-features.ts if a flag is advertised, their pins and generated docs, one .changeset/29736-*.md
Container & model: card thread, mode:thread, model: TIER_DEFAULT (--tier names no path mandate), effort: project default
Clause-②: yes
Metadata-protocol: added
Responsibility: packages/spec auth surface (spec lane) | the mobile hand-off routes and scheme list are undeclared | mobile users signing in with a provider that refuses WebViews, via #29714; reachable today
Thread-read: none
Premise: holds (seat read origin/main: no /one-time-token/* in AuthEndpointPaths, no app-scheme list beside trustedOrigins)
Serial constraints cleared: none owed; #29714 (claim 6594410165) waits on this card, shapes agreed between the two threads
{
"issue": 29736,
"status": "done",
"branch": "claude/project-thread-s5w2nj",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29804",
"session": "session_01JQwxbXghRkYmSR5dVh8PFG",
"premise_still_valid": true,
"summary": "Declared the mobile sign-in hand-off contract in packages/spec. AuthEndpointPaths gains oneTimeTokenHandoff (/one-time-token/handoff, ObjectStack's GET route) and oneTimeTokenVerify (/one-time-token/verify, better-auth 1.7.12's route, measured from its dist), with OneTimeTokenHandoffQuerySchema (strict: redirect_uri, an S256 code_challenge, an optional S256-only method), OneTimeTokenVerifyRequestSchema (token = vendor token, a dot, the RFC 7636 verifier) and OneTimeTokenVerifyResponseSchema (vendor unwrapped session + user). AuthConfig gains trustedAppSchemes, an array of TrustedAppSchemeSchema: lowercase bare reverse-domain schemes with at least one dot (RFC 8252 7.1), so every web scheme is refused by construction, and a bad entry is refused, never dropped. No features flag: no consumer exists (PUBLIC_AUTH_FEATURES passkeys precedent), so public-auth-features.ts is untouched. All five shapes were agreed with the #29714 card thread before writing; vendor generate is deliberately undeclared (it refuses client requests). Key-name precedent: trustedAppSchemes beside trustedOrigins, same trusted-plus-plural form, separate because trustedOrigins is trusted for every better-auth redirect.",
"tests": "Head b73cfb24d. pnpm --filter @objectstack/spec test: 803 files passed, 23811 tests passed, 1 todo (lock VERDICT command-exit 0). New cases: auth-endpoints.test.ts block 'mobile sign-in hand-off (one-time token)' (7 cases: paths, query accept, unrecognized_keys refusal, plain/short/padded/missing challenge refused at path, verify binding accept incl. dotted verifier, bare token and short verifier refused, vendor body parses); auth-config.test.ts accept + 8-row refusal table at path trustedAppSchemes.1 (https, javascript, myapp, com.example.app://, com.example.app:, Com.Example.App, com..app, com.example.); type-alias-convention.pin.test.ts 3 Iso pins, count 819 to 822. No ablation: additive schemas, no tested behaviour changed.",
"gates": "Local, head b73cfb24d: dispatch-gates --commands derived 102 families; all 102 exit 0; dispatch-gates --ran: 102 run, 0 NOT-MEASURED (exit 0). Outside derivation, also exit 0: spec test, spec typecheck, pnpm lint (the order asked for pnpm lint; os-dev.md calls it CI-owned, run anyway, no conflict in outcome). First pass on 4b54dade: check:spec-parsed-alias exit 1 (three new aliases unpinned) and check:generated exit 1 (declaration-map) fixed in-PR; check-plugin-teardown-shape --self-test, check:skill-examples, check:dual-build-cjs-loads, check:lean-entry-closure exit 3 (prerequisites: unbuilt packages, shallow-clone fixture commit) then green on the final head after building formula, lint, objectql, client, client-react and fetching the fixture commit. CI check-runs on PR 29804: in_progress at report time, not awaited per os-dev.md.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — relay pr_create (objectstack-ai/objectstack#29804, 8988 bytes sent = stored, no assignees, no labels) and this os-dev-report comment via post-stamped.mjs on #29736",
"open_questions": [],
"security_findings": "withheld",
"out_of_scope_findings": [],
"deviations": "The first WIP commit 8d930315 carries no Claude-Session / Co-authored-by trailer pair (the pre-push hook accepted it; history not rewritten, branch is not claude/issue-* so no force-push). The session-context MCP assignee/reviewer step was skipped as the order forbids MCP and reviewer requests. Branch was a few commits behind origin/main at the final union; dispatch-gates found no derivation input touched.",
"body_amendments": "none"
}
Review chain: contract review of record at CONTRACT_REVIEW_TIER (schema face) PASS 6596452314 on b73cfb24 → S1 (prose vs regex) and S2 (redirect_uri min(1)) fixed in ffba6e29 → delta PASS 6596937905 on 9f3ce177 → seat ACCEPT 6596950367 → pr_ready + automerge_enable by the seat.
Declared:Clause-②: yes (widening), Metadata-protocol: added (trustedAppSchemes and the hand-off endpoint shapes in @objectstack/spec).
Activity
objectstack-fleet commentedon Nov 3, 2026
domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf
Claim: PM loop round 1 · card thread · 2026-11-03T03:13Z
Session:
session_01JQwxbXKRzgnVvjzxaYxLUf(the seat); the card thread issession_01JQwxbXghRkYmSR5dVh8PFGAccount:
os-warrenBranch:
claude/project-thread-s5w2njWorktree: the card thread's own container checkout
Domain:
domain:spec(the spec slice of #29714, routed todomain:server#2by the coordinator)Seat:
domain:server#2File surface:
packages/spec/src/api/auth-endpoints.zod.ts(two paths + request/response schemas),packages/spec/src/system/auth-config.zod.ts(the registered app-scheme list),packages/spec/src/kernel/public-auth-features.tsif a flag is advertised, their pins and generated docs, one.changeset/29736-*.mdContainer & model: card thread,
mode:thread,model: TIER_DEFAULT(--tiernames no path mandate),effort: project defaultClause-②: yes
Metadata-protocol: added
Responsibility:
packages/spec auth surface (spec lane)|the mobile hand-off routes and scheme list are undeclared|mobile users signing in with a provider that refuses WebViews, via #29714; reachable todayThread-read: none
Premise: holds (seat read
origin/main: no/one-time-token/*inAuthEndpointPaths, no app-scheme list besidetrustedOrigins)Serial constraints cleared: none owed; #29714 (claim 6594410165) waits on this card, shapes agreed between the two threads
Order: project file pm-orders/server/seat2/order-29736.md.
Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p1 ·
domain:speckept ·pm:dispatchedkept · 2026-11-03T03:57Z⛔ Not a claim.
Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:server#2 · os-warren · session_01JQwxbXghRkYmSR5dVh8PFG
os-dev-report
{ "issue": 29736, "status": "done", "branch": "claude/project-thread-s5w2nj", "pr": "https://github.com/objectstack-ai/objectstack/pull/29804", "session": "session_01JQwxbXghRkYmSR5dVh8PFG", "premise_still_valid": true, "summary": "Declared the mobile sign-in hand-off contract in packages/spec. AuthEndpointPaths gains oneTimeTokenHandoff (/one-time-token/handoff, ObjectStack's GET route) and oneTimeTokenVerify (/one-time-token/verify, better-auth 1.7.12's route, measured from its dist), with OneTimeTokenHandoffQuerySchema (strict: redirect_uri, an S256 code_challenge, an optional S256-only method), OneTimeTokenVerifyRequestSchema (token = vendor token, a dot, the RFC 7636 verifier) and OneTimeTokenVerifyResponseSchema (vendor unwrapped session + user). AuthConfig gains trustedAppSchemes, an array of TrustedAppSchemeSchema: lowercase bare reverse-domain schemes with at least one dot (RFC 8252 7.1), so every web scheme is refused by construction, and a bad entry is refused, never dropped. No features flag: no consumer exists (PUBLIC_AUTH_FEATURES passkeys precedent), so public-auth-features.ts is untouched. All five shapes were agreed with the #29714 card thread before writing; vendor generate is deliberately undeclared (it refuses client requests). Key-name precedent: trustedAppSchemes beside trustedOrigins, same trusted-plus-plural form, separate because trustedOrigins is trusted for every better-auth redirect.", "tests": "Head b73cfb24d. pnpm --filter @objectstack/spec test: 803 files passed, 23811 tests passed, 1 todo (lock VERDICT command-exit 0). New cases: auth-endpoints.test.ts block 'mobile sign-in hand-off (one-time token)' (7 cases: paths, query accept, unrecognized_keys refusal, plain/short/padded/missing challenge refused at path, verify binding accept incl. dotted verifier, bare token and short verifier refused, vendor body parses); auth-config.test.ts accept + 8-row refusal table at path trustedAppSchemes.1 (https, javascript, myapp, com.example.app://, com.example.app:, Com.Example.App, com..app, com.example.); type-alias-convention.pin.test.ts 3 Iso pins, count 819 to 822. No ablation: additive schemas, no tested behaviour changed.", "gates": "Local, head b73cfb24d: dispatch-gates --commands derived 102 families; all 102 exit 0; dispatch-gates --ran: 102 run, 0 NOT-MEASURED (exit 0). Outside derivation, also exit 0: spec test, spec typecheck, pnpm lint (the order asked for pnpm lint; os-dev.md calls it CI-owned, run anyway, no conflict in outcome). First pass on 4b54dade: check:spec-parsed-alias exit 1 (three new aliases unpinned) and check:generated exit 1 (declaration-map) fixed in-PR; check-plugin-teardown-shape --self-test, check:skill-examples, check:dual-build-cjs-loads, check:lean-entry-closure exit 3 (prerequisites: unbuilt packages, shallow-clone fixture commit) then green on the final head after building formula, lint, objectql, client, client-react and fetching the fixture commit. CI check-runs on PR 29804: in_progress at report time, not awaited per os-dev.md.", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — relay pr_create (objectstack-ai/objectstack#29804, 8988 bytes sent = stored, no assignees, no labels) and this os-dev-report comment via post-stamped.mjs on #29736", "open_questions": [], "security_findings": "withheld", "out_of_scope_findings": [], "deviations": "The first WIP commit 8d930315 carries no Claude-Session / Co-authored-by trailer pair (the pre-push hook accepted it; history not rewritten, branch is not claude/issue-* so no force-push). The session-context MCP assignee/reviewer step was skipped as the order forbids MCP and reviewer requests. Branch was a few commits behind origin/main at the final union; dispatch-gates found no derivation input touched.", "body_amendments": "none" }objectstack-fleet commentedon Nov 3, 2026
domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf
Landing record · #29736 · 2026-11-03T06:46Z
55a48987282b17ef93c4a8f76cb0559c03376f9a; head9f3ce177; this card closed byFixes.CONTRACT_REVIEW_TIER(schema face) PASS 6596452314 onb73cfb24→ S1 (prose vs regex) and S2 (redirect_urimin(1)) fixed inffba6e29→ delta PASS 6596937905 on9f3ce177→ seat ACCEPT 6596950367 →pr_ready+automerge_enableby the seat.Clause-②: yes (widening),Metadata-protocol: added(trustedAppSchemesand the hand-off endpoint shapes in@objectstack/spec).TrustedAppSchemeSchemafrom the spec; ruling A (6597001931) is built there.pm:dispatchedremoved in the same stroke as this record.Generated by Claude Code
refactor(plugin-auth): the hand-off reads trustedAppSchemes and its r…