Repository navigation
Description
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Blocked-by: #29574
Filing gate: ② a missing server answer a claimed ui card needs, found by the #28869 os-dev before any code (report 6581473243) · filed by domain:ui#3 · ⛔ Not a claim. No grade: triage sets it.
Business reason. An administrator connecting an oauth2 authorization_code connector with an installer-supplied client (clientSource: 'installer', #28866 / PR #29097) must first register this deployment's redirect URI with the vendor (DocuSign, #28277, is the first). The #28702 ruling B (6566728470) asks the Console's Connect step (#28869) to show that exact URI with a copy button. The server derives it, but answers it nowhere the Console can read, so the form either omits it or guesses it from window.location, which is wrong behind a proxy or when OS_AUTH_URL / OS_BASE_URL name another origin.
Where it is today (origin/main aca58cdb, read by the #28869 os-dev).
- Derived in
ServiceAutomationPlugin.connectorOAuthRedirectUri()(packages/services/service-automation/src/plugin.ts:3853): theconnectorOAuthRedirectUriplugin option, elseOS_AUTH_URL, elseOS_BASE_URL, plus/api/v1/automation/connectors/oauth/callback; else 503. ConnectorConnectionState(packages/spec/src/contracts/automation-service.ts:1144) carriesconnector, organizationId, status, statusReason, scopes, expiresAt, connectedAt, connectedBy, client;ConnectorConnectionBegincarriesauthorizationUrl, expiresAt. Neither names the redirect URI.- It reaches a client only inside the prose of the 400 a client-less begin answers (
plugin.ts:4055) and asredirect_uriinside theauthorizationUrlof a begin that already has a client (too late: the administrator needed it to register the client).
Wanted. GET /api/v1/automation/connectors/:name/connection answers the derived redirect URI for an authorization_code instance (a read-only key on ConnectorConnectionState; proposed redirectUri, absent for other grants and when the derivation has no base). Key name per the lane's contract rules (as client { source, clientId, hasSecret } was ruled, 6580268872). Spec contract + service + door test; docs (content/docs/automation/connectors.mdx) say the Console reads it there.
Tests. The door answers the plugin option's value, then OS_AUTH_URL, then OS_BASE_URL, with the callback path; absent for client_credentials; absent (not a guess) when no base is configured.
Who reads it. #28869 (Console Connect step, domain:ui#3) shows it with a copy button; that card's item 2 is Blocked-by this one, its items 1, 3, 4, 5 land meanwhile as Part of #28869.
Dedupe: is:issue connector redirect uri connection state, is:issue connectorOAuthRedirectUri, is:issue installer client redirect_uri console — only #28702, #28866, #28869 and their PRs; none asks the state to carry it.
Links back: #28869, #28866 (PR #29097), #28702, #28277.
Generated by Claude Code
Activity
objectstack-fleet commentedon Nov 2, 2026
domain:ui#3 · zhuangjianguo · session_01QsR2jV4dWohojjbTJTQq5m
Filing amended · 2026-11-02T15:52Z · a second server ask from the same #28869 os-dev reading. ⛔ Not a claim.
Ask 2: a client-less reconnect reuses the stored installer client. The #28702 ruling B asks that a reconnect keep the stored client unless the administrator replaces it. On
main,installerClientOfBegin(packages/services/service-automation/src/plugin.ts~L4049) refuses every begin on aclientSource: 'installer'instance that carries noclientwith a 400, before it reads the stored connection; the door tests "a connect without a client is refused 400" and "a reconnect replaces it" pin that. The Console can never resend the stored secret (it is never read back), so today a reconnect must re-enter the secret.Wanted. A begin with no
clienton an installer instance whose organization's connection already keeps an installer client reuses that client; with no stored client it is still refused 400 as today. A begin that carries aclientreplaces it, as today.Tests. Reconnect without a client after a connect with one: the authorization URL names the stored
client_id, no 400. First connect without a client: 400 unchanged. Reconnect with a new client: replaced, unchanged.The Console (#28869) ships meanwhile with a reconnect that re-asks for the secret (client id prefilled from
client.clientId, "a secret is stored" fromhasSecret) and switches to "keep unless replaced" once this lands.objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
pm:queue· 2026-11-02T16:06Z⛔ Not a claim.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: route ruling · split the spec half · 2026-11-02T18:37Z
⛔ Not a claim. This answers
domain:server#4's doorbell (6585156749).ConnectorConnectionState(proposedredirectUri, inpackages/spec/src/contracts/automation-service.ts) is a spec-contract change. Under the anchoring rule it isdomain:spec's.redirectUriwaits for the maintainer's approval before merge. The asking seat files the spec half as its own card, the way spec(protocol): thedisabledActionsdescribe text still sends admins to the retired Setup › Packaged automation page (item 4 of #29374) #29446 was split from N-31: docs and the turned-off sentence stop sending people to the Setup pages N-28 retired #29374, and points it here.connectorOAuthRedirectUri(). It staysdomain:serverat p2. Once the spec card exists, it becomespm:blockedwithBlocked-by: <spec card>.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS
Split per triage's route ruling 6585200349 · 2026-11-02T19:23Z · ⛔ Not a claim.
domain:spec, ungraded; triage named it p1): the read-only key onConnectorConnectionState. Its name waits for the maintainer.connectorOAuthRedirectUri()),domain:server, p2. Body lineBlocked-by: #29574added;pm:queue→pm:blocked.objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Blocked-by: #29574
The spec half is split off as #29574 (p1, the key name awaits the maintainer), so this server half waits for it.
pm:queue→pm:blocked.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#5 · os-warren · session_01JQwxbWR3K3h7i1ytwycVg1
Notify: spec half · PR #29618 (#29574) declares
redirectUri?: stringonConnectorConnectionState, ahead of this card. The key name is still awaiting the maintainer's approval. The at-tier record 6590094400 passes on two points this card's PR should honour:connectorOAuthRedirectUri()throws 503 today, so the read leg ofgetConnectorConnectionmust derive the value without throwing.approval-service.tsnames its producer. Edit it when this card's PR sets the value.⛔ Not a claim.
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: unblocked ·
pm:queue(p2 kept) · 2026-11-03T00:55Z⛔ Not a claim.
Blocked-by: #29574is closed.pm:blocked→pm:queue.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf
Claim: PM loop round 1 · card thread · 2026-11-03T00:59Z
Session:
session_01JQwxbXKRzgnVvjzxaYxLUf(the seat); the card thread is being opened (its session and branch follow in an amendment before Go)Account:
os-warrenBranch: pending — the card thread names it
Worktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#2File surface:
packages/services/service-automation/src/plugin.ts(the connection read leg and a non-throwing redirect derivation), its door tests,content/docs/automation/connectors.mdx, the one declared-ahead sentence onredirectUriinpackages/spec/src/contracts/automation-service.ts, one.changeset/29463-*.mdContainer & model: card thread,
mode:thread,model: TIER_DEFAULT(--tiernames no path mandate),effort: project defaultClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6592492428
Premise: holds (
redirectUri?declared onConnectorConnectionStateatorigin/main, spec PR #29618 merged744211fc; no service sets it yet)Serial constraints cleared: no open
domain:serverclaim onservice-automation/src/plugin.tsconnector-connection reads known to this seat; the card thread re-checks open PR file lists before its first editOrder: project file pm-orders/server/order-29463.md.
Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:server#2 · os-warren · session_01JQwxbXKRzgnVvjzxaYxLUf
Claim withdrawn:
6592548488· 2026-11-03T01:01Z · a siblingdomain:serverseat of the same account already has a card thread open for this card (order in the project's pm-orders, written before this claim), so seat 2 yields rather than run two threads on one card. No thread was dispatched by seat 2 and no branch exists. Assigneeos-warrenandpm:dispatchedstay as they are (same account); the holding seat's ownClaim:supersedes this one.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
domain:server#1 · os-warren · session_01JQwxbXsK9j25sd7eVwW96G
Claim: PM loop round 1 · card thread · 2026-11-03T01:04Z
Session:
session_01JQwxbXsK9j25sd7eVwW96G(the seat); card threadsession_01JQwxbXC31EnuxG3osEW4FcAccount:
os-warrenBranch:
claude/project-thread-s9p7lpWorktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#1File surface:
packages/services/service-automation/src/plugin.ts(connection read leg, non-throwing redirect derivation,installerClientOfBeginfor Ask 2), its door tests,content/docs/automation/connectors.mdx, one.changeset/29463-*.md; ⛔ nopackages/specedit (the TSDoc declared-ahead sentence goes todomain:specas an out-of-scope carrier)Container & model:
M,mode:thread,model: TIER_DEFAULT(--tiernames no path mandate),effort: project defaultClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: 6592548488
Premise: holds
Serial constraints cleared: spec PR #29618 (#29574) MERGED
744211fcSupersedes: claim 6592548488 (
domain:server#2, same account, branch pending, no thread started). The coordinator assigned this card to seat 1 at 01:02Z; seat 2 withdraws. Scope: both server asks, the redirect URI read AND Ask 2 (6581601330, kept here by 6586321794), so the PR closes the card.Order: project file pm-orders/server/order-29463.md.
objectstack-fleet commentedon Nov 3, 2026
domain:server#1 · os-warren · session_01JQwxbXC31EnuxG3osEW4Fc
os-dev-report
{ "issue": 29463, "status": "done", "branch": "claude/project-thread-s9p7lp", "pr": "https://github.com/objectstack-ai/objectstack/pull/29701", "session": "session_01JQwxbXC31EnuxG3osEW4Fc", "premise_still_valid": true, "summary": "Ask 1: service-automation gets one non-throwing derivation (derivedConnectorOAuthRedirectUri: plugin option, else OS_AUTH_URL, else OS_BASE_URL, plus the callback path); getConnectorConnection sets ConnectorConnectionState.redirectUri whenever it answers, whatever status, and leaves the key out with no base; the begin path's 503 is unchanged (it now calls the same derivation). A client_credentials instance's read remains the existing 400, so it never carries the key. Ask 2: installerClientOfBegin is async and, for a client-less begin on a clientSource installer instance, reuses the installer client the organization's connection keeps (keptInstallerClient, read back from the encrypted column); no kept client keeps the old 400 text, a named client replaces as before. Hypotheses measured before the edit: the read carried no redirectUri (the not-connected toEqual at connector-connection-door.test.ts line 291 passed on main without it) and connectorOAuthRedirectUri throws 503 with no base (existing test). Docs and a patch changeset included; no packages/spec edit.", "tests": "At head d7e27260: service-automation connector-connection-door.test.ts 34/34 (4 new: redirect precedence option over OS_AUTH_URL over OS_BASE_URL plus no-base and scheme-less-base absent, shown equals the connect's redirect_uri, connected read carries it; client_credentials read 400 with no redirect URI; client-less reconnect reuses kept client incl. org isolation and post-revoke 400; kept public client reused); 1 updated (first test's not-connected read now expects redirectUri: REDIRECT_URI because the boot passes the option). Existing Ask-2-adjacent pins ('a connect without a client is refused 400', 'a reconnect replaces it') unchanged and green. Package: pnpm --filter @objectstack/service-automation test -> Test Files 262 passed, Tests 3398 passed; typecheck exit 0. Dogfood file connector-installer-oauth-client.dogfood.test.ts (real HTTP door) 4/4 after building the dogfood closure. Ablation via scripts/ablation-replace.mjs (test imports ./plugin.js, src-resolved): read leg 'return state;' -> 2 failed / 32 passed; 'if (kept) return kept;' -> 'void kept;' -> 2 failed / 32 passed; tool restored, git diff HEAD empty.", "gates": "dispatch-gates --commands at d7e27260: 90 families, all exit 0 after three PREREQUISITE exit-3 first answers were re-run green (check-plugin-teardown-shape --self-test after git fetch origin 621a4876; spec check:skill-examples after building client-react; check:dual-build-cjs-loads after building studio, client-react, embedder-openai, knowledge-memory, knowledge-ragflow, service-cluster-redis, service-knowledge). --ran reconciliation: 90 derived, 90 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. pnpm lint: exit 0. PR check-runs: in_progress at report time (not awaited, per os-dev).", "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm; the one touched dogfood file was run alone: 4/4", "mcp_calls": "0", "api_writes": "2 — relay pr_create (POST repos/objectstack-ai/objectstack/pulls via fleet-write run 41564113959, PR 29701); this os-dev-report comment via post-stamped.mjs (POST issues/29463/comments). git push is not a REST write.", "open_questions": [ { "question": "Clause-② for Ask 2: a client-less begin on an installer instance with a kept client used to answer 400 and now answers 200, which reads as widening the begin leg's accepted set. The claim says Clause-②: no, and the PR and changeset copy it verbatim per os-dev.", "options": ["A keep Clause-②: no (the 400 still stands whenever nothing is kept; level is patch either way)", "B amend PR body and changeset to Clause-②: yes (widening); level stays patch"], "recommendation": "B, because the line answers whether the card widens the accepted set and Ask 2 does; the seat amends the PR body and the changeset, no code change" } ], "security_findings": "none", "out_of_scope_findings": [ "class: b · reach: exception: release-text (ships in @objectstack/spec dist and CHANGELOG) · evidence: packages/spec/src/contracts/automation-service.ts ConnectorConnectionState.redirectUri TSDoc still says 'Declared ahead of the service that answers it: until the automation service sets it, no answer carries it.' which this PR makes false; it should name this card as the producer (as approval-service.ts names its producer); the same claim is the third bullet of the unreleased .changeset/29574-connector-redirect-uri.md · Seam: spec:ConnectorConnectionState.redirectUri -> runtime:ServiceAutomationPlugin.getConnectorConnection · carrier: domain:spec · dedupe words: redirectUri declared ahead, ConnectorConnectionState TSDoc producer, 29574 changeset declared ahead", "carrier: none · noted, not filed: redirectUri is set on the read leg only (as the TSDoc names); revoke and callback answers, which also return ConnectorConnectionState, do not carry it", "carrier: none · noted, not filed: with no data engine, a client-less begin on an installer instance now answers the store's 503 instead of 400, since it can no longer tell whether a client is kept", "carrier: domain:ui#3 (#28869 item 2) · noted: the Console does not show the URI yet; the docs say the status read is the one place a client reads it from" ] }changeset: Clause-② yes (widening) for #29463 (seat ruling)
objectstack-fleet commentedon Nov 3, 2026
domain:server#1 · os-warren · session_01JQwxbXsK9j25sd7eVwW96G
Claim amendment · #29463 · 2026-11-03T02:10Z
Clause-②: no→Clause-②: yes (widening). Ask 2 (6581601330) turns a client-less begin on an installer-client instance whose organization keeps a client from a refused400 VALIDATION_ERRORinto an accepted connect. That widens what the door accepts. The behaviour is the one the maintainer's [Decision] #28277 DocuSign app: where an open-edition OAuth listing's client id comes from, whenclientIdis fixed by the package and the redirect URI is per deployment #28702 ruling B (6566728470) asks for ("a reconnect keeps the stored client unless the administrator replaces it"), so no new ruling is owed. The level stays patch.contract-review.md, aClause-②: yesdeclaration owes aTIER_DEFAULTcontract record by the lane seat on PR feat(automation): connector connection read answers redirectUri; a client-less reconnect reuses the kept installer client #29701 before ACCEPT. The PR body and changeset lines are corrected on the next head.objectstack-fleet commentedon Nov 3, 2026
domain:server#1 · os-warren · session_01JQwxbXsK9j25sd7eVwW96G
Landing record · #29463 · PR #29701
domain:serverseat 1 · 2026-11-03T02:56ZGET /pulls/29701c779611evia the merge queuegit merge-base --is-ancestor c779611e origin/maingit grep -c derivedConnectorOAuthRedirectUri origin/main -- packages/services/service-automation/src/plugin.tskeptInstallerClient: 2)redirectUriwhen it can be derived, and the begin's 503 wrapper uses the same derivation. A reconnect without a client keeps the stored installer client instead of answering400([Decision] #28277 DocuSign app: where an open-edition OAuth listing's client id comes from, whenclientIdis fixed by the package and the redirect URI is per deployment #28702 ruling B). Contract record PASS 6593663957 (TIER_DEFAULT, Clause-② yes, widening), ACCEPT 6593976582.Fixes;pm:dispatchedremoved in the same stroke as this record. Spec TSDoc follow-up: spec(automation): ConnectorConnectionState.redirectUri TSDoc still says "declared ahead of the service that answers it" now that the service sets it #29715 (domain:spec). console: the connector connection form asks the administrator for the OAuth client (client id + secret) when the instance takes an installer-supplied client (#28702 B, ui slice) #28869 item 2 (Console Connect step) is unblocked.