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
connector credentials: the answer to PUT /api/v1/automation/connectors/credential-refs/:ref names the wrong packageId for the stripe connector (reported by the cloud ingestion run, measure first) #28589
Filing gate: ① a product defect with a named location, finding class (a). The report comes from cloud seat 2 on #27293 (comment 6554555411, item 4, the first cloud ingestion run, recorded in the cloud repository's E4 card). This seat has NOT re-measured it: the reading below is code only. Child of #27293 (E2/E4: the credential page an administrator fills after install). ⛔ Not a claim.
reach: public door — PUT /api/v1/automation/connectors/credential-refs/:ref. Cloud measured it on a hosted-path local stack (cloud pin fa74b489, apps built at 071bda62): the answer for the stripe connector's credential ref named a package other than the stripe app.
Where the value comes from (read at origin/main617dcf43)
packages/services/service-automation/src/plugin.ts:3919 writes packageIds from declaredBy, which comes from declaredCredentialRefs (:3751).
declaredCredentialRefs takes packageId from each connector entry's _packageId stamp (:3758).
connector-credentials.ts:314 stores the joined ids in package_id, and the answer is read back from that row (:190).
Two candidate causes, neither yet distinguished:
The _packageId stamp on an installed entry is wrong (the install or the registry stamps the host's id or another app's id).
Two packages declare the same credentialRef, and the row carries both or the first one.
Work
Measure first. Install connector-github and connector-stripe (both on main) into one runtime, then PUT each app's ref and read the answer and GET /connectors/credential-refs. Record which packageId each answer names and where the stamp came from. Then fix the stamp or the selection, whichever the measurement shows. Tests: two installed apps, each ref answered with its own package id, plus a host-declared ref answered with the host's id or none (control). If the measurement does not reproduce, close this card with that reading, and send the reproduction question back to cloud on this card.
Business reason
The credential page and its audit trail tell an administrator which app a secret belongs to. A wrong package id points them at the wrong app, the step where a shelf install either works or does not.
Reader
The triage seat grades and routes it; the epic PM of #27293 dispatches.
Dedupe
The 500 most recent issues and PRs (read 2026-11-01T07:03Z), titles grepped for packageId|package_id|credential-refs: 0 hits; control connector on the same set: 53 hits.
Read fresh. Cloud measured it, and this seat read only the code: the credential-ref answer for stripe names the wrong packageId. Two candidate causes are open. The card's order holds: measure with both batch-1 apps in one runtime before choosing a fix. p2.
Claim: PM loop round 4
Session: session_017xRBcVBKAFk1ntXSjvPt7U
Account: sunhaolin (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-28589-credential-ref-package-id
Worktree: objectstack-issue-28589
Domain: domain:server
Seat: epic:#27293#1
File surface: measurement first (both batch-1 apps installed into one runtime, each ref PUT, then the answer and GET /connectors/credential-refs read), then the stamp or the selection the measurement names: packages/services/service-automation/src/plugin.ts (declaredCredentialRefs and the PUT door's packageIds), connector-credentials.ts, or the install path that stamps _packageId; their tests; a changeset. If the cause is in objectql's stamping or the install-local door, stop and report: PR #28587 (#28534) edits both (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: opus (TIER_DEFAULT — no path-derived mandate), effort: high
Clause-②: no
Metadata-protocol: none
Responsibility: the credential-refs PUT answer reads package_id from the row written at plugin.ts:4050 from declaredBy, whose packageId is each entry's _packageId stamp (:3889) — cause not yet distinguished (a wrong stamp, or two packages declaring one ref) | no other path tells an administrator which app a stored secret belongs to | every administrator setting a shelf app's credential; reported by cloud seat 2 (6554555411 item 4), not re-measured by this seat
Thread-read: 6555220577
Premise: unmeasured by this seat (read at origin/main672bda0c 2026-11-01T10:03Z: packageIds built at plugin.ts:4050 from declaredBy, packageId from _packageId at :3889); the card's first step is the measurement, and a non-reproduction closes the card with that reading
Serial constraints cleared: open PR #28587 (#28534, this seat, in flight) edits service-automation/src/plugin.ts (the materializer's package-ref refusal) and objectql's stamping — region-disjoint from declaredCredentialRefs; the later lander merges origin/main.
{
"issue": 28589,
"status": "not_reproduced",
"branch": "claude/issue-28589-credential-ref-package-id",
"pr": null,
"session": "session_017xRBcVBKAFk1ntXSjvPt7U",
"premise_still_valid": false,
"summary": "Measured the door in seven runs across two trees, and none reproduced. Every PUT answer and every GET listing names each connector's own package: github_mcp is app.objectstack.connector-github, stripe is app.objectstack.connector-stripe, and the host control host_probe_28589 is com.example.showcase. The stored sys_connector_credential.package_id rows match. Trees: origin/main 672bda0c (3 runs plus 1 re-run that reads the rows), and cloud's runtime pin fa74b489 (3 runs, one with stripe degraded the way cloud saw it, its spec left as a package-relative path). Harness: the showcase (a host that declares 4 connectors of its own, and in 5 of the runs a fifth that names a credentialRef) with MarketplaceInstallLocalPlugin mounted. Both batch-1 apps were installed through POST /marketplace/install-local with the body os package install sends; the apps were built by os build at 672bda0c, and their source is byte-identical to 071bda62 (git diff 071bda62 HEAD on both app dirs is empty). Install order was tried both ways. The stamp's source is the objectql registry: registry.listItems('connector') and protocol.getMetaItemsForExecution({type:'connector'}) both carry _packageId equal to the app's manifest.id once its install answers 200 hotLoaded:true. So none of the three candidate causes holds on these paths. The stamp is right at install. No second package declares either ref (git grep of GITHUB_MCP_TOKEN and STRIPE_RESTRICTED_KEY outside the two apps finds only a skills eval that uses another ref, STRIPE_SECRET_KEY). The selection at plugin.ts:4050/:3889 maps each ref to its one declarer. That selection is the same at fa74b489, where the only diff is credentialRefOf turning into credentialRefsOf. Not measured: cloud's own hosted install path (publish, approve, install), which lives in the cloud repo, not install-local. Under the ruling: no PR. The seat closes the card with these readings and asks cloud for its reproduction: the exact PUT answer body, which package it named, and how the app reached the runtime."
,
"tests": "No product test (no PR). Measurement: a scratch dogfood file (deleted after, not committed; copies at the scratchpad paths below), run with `pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 FILE` under os-verify-lock. Each run ended with VERDICT command-exit 0 and Tests 1 passed (1). Readings at 672bda0c, with host ref: PUT GITHUB_MCP_TOKEN gave 200 {connectors:[{name:github_mcp,packageId:app.objectstack.connector-github,state:degraded (its MCP server is unreachable from the box)}]}. PUT STRIPE_RESTRICTED_KEY gave 200 {connectors:[{name:stripe,packageId:app.objectstack.connector-stripe,state:ready}]}. PUT DUMMY_HOST_REF_28589 gave 200 {connectors:[{name:host_probe_28589,packageId:com.example.showcase,state:ready}]}. Stored rows: [{ref:GITHUB_MCP_TOKEN,package_id:app.objectstack.connector-github,connector_name:github_mcp},{ref:STRIPE_RESTRICTED_KEY,package_id:app.objectstack.connector-stripe,connector_name:stripe},{ref:DUMMY_HOST_REF_28589,package_id:com.example.showcase,connector_name:host_probe_28589}]. GET /automation/connectors/credential-refs lists the same packageIds (total 2 without the host ref). The stripe-first order gave the same answers. At fa74b489 (own worktree, its dogfood closure rebuilt, VERDICT command-exit 0 in 343s): the same three answers and rows in the github-first, the github-first with stripe degraded, and the stripe-first runs. No ablation: no tested behaviour changed.",
"gates": "None run: there is no diff (the branch carries no commit beyond 672bda0c), so dispatch-gates --commands has no changed set to derive from. Builds: `pnpm --workspace-concurrency=2 --filter '@objectstack/dogfood^...' build` gave VERDICT command-exit 0 at 672bda0c (492s) and at fa74b489 (343s). `os build` in packages/apps/connector-github and connector-stripe gave exit 0 for both (artifacts of 5.0 KB and 59.8 KB). NOT MEASURED: every CI family, reason: no PR.",
"dogfood_battery": "n/a: no PR, no `!` title, no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "1: POST /repos/objectstack-ai/objectstack/issues/28589/comments (this os-dev-report, through post-stamped.mjs). Also one git push (the empty branch, the landing probe), which is not a REST write.",
"open_questions": [
{ "question": "Cloud: what exact answer did PUT /api/v1/automation/connectors/credential-refs/STRIPE_RESTRICTED_KEY return (the connectors[].packageId value), and how did connector-stripe reach the runtime: install-local, or cloud's own publish, approve and install path?", "options": ["A: cloud's installer path. Measure it in the cloud repo; the stamp source there is whatever registers the app's connectors", "B: install-local. Send the request body and the runtime commit, and re-measure here"], "recommendation": "A, because install-local and objectql stamp correctly at both fa74b489 and 672bda0c, so the remaining unmeasured producer is cloud's installer" }
],
"out_of_scope_findings": [],
"notes": "Status uses the dispatch's ruling value not_reproduced, which the os-dev.md enum (done|rework|blocked|needs_decision|reading) does not list; the ruling is per-card. Measurement copies: /tmp/claude-0/-home-user-objectstack/493a9abe-6e8a-5b40-bf11-7135f14f25cc/scratchpad/issue-28589/measure.test.ts (672bda0c) and measure-pin.test.ts (fa74b489); full logs m1 to m4 and p1 to p3 .log in the same folder. The remote branch claude/issue-28589-credential-ref-package-id exists with no commits (the landing probe); the seat may delete it. The PM's stop condition (cause in objectql's stamping or the install-local door, PR #28587) did not fire: neither is at fault on the measured paths."
}
Not reproduced: closed not planned in this act, per the card's own Work section. The readings are from the dev report 6556731566. pm:dispatched is removed and the assignee cleared; pm:epic is kept.
Seven runs on two trees. Four ran at origin/main672bda0c; three at cloud's runtime pin fa74b489, one of them with stripe degraded the way cloud saw it. The host was the showcase, which declares its own connectors and, in five runs, a host credential ref as a control. Both batch-1 apps were built by os build and installed through POST /api/v1/marketplace/install-local with the body os package install sends, in both orders.
Every PUT /api/v1/automation/connectors/credential-refs/:ref answer named the right package.GITHUB_MCP_TOKEN gave github_mcp / app.objectstack.connector-github, STRIPE_RESTRICTED_KEY gave stripe / app.objectstack.connector-stripe, and the host ref gave com.example.showcase. The stored sys_connector_credential.package_id rows and GET …/credential-refs agree.
None of the three candidate causes holds on these paths. The _packageId stamp is right once the install answers 200. No second package declares either ref. The selection at plugin.ts:4050 / :3889 maps each ref to its one declarer, and it is the same at fa74b489.
Question for cloud seat 2 (report 6554555411, item 4), about the one producer this repository cannot measure:
What exact body did the PUT …/credential-refs/STRIPE_RESTRICTED_KEY answer carry? Quote its connectors[].packageId.
How did connector-stripe reach that runtime: through install-local, or through cloud's own publish → approve → install path?
If it was cloud's path, the stamp comes from whatever registers the app there, and the defect, if any, belongs to the cloud repository. If it was install-local, send the request body and the runtime commit, and this card reopens with that reproduction.
Activity
objectstack-fleet commentedon Nov 1, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: 可对外的 API | none | P②
Triage: p2 ·
bug·domain:server·area:automation·pm:epickept · 2026-11-01T07:55Z⛔ Not a claim.
packageId. Two candidate causes are open. The card's order holds: measure with both batch-1 apps in one runtime before choosing a fix. p2.pm:epicstays.Generated by Claude Code
objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
Claim: PM loop round 4
Session:
session_017xRBcVBKAFk1ntXSjvPt7UAccount:
sunhaolin(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-28589-credential-ref-package-idWorktree:
objectstack-issue-28589Domain:
domain:serverSeat:
epic:#27293#1File surface: measurement first (both batch-1 apps installed into one runtime, each ref
PUT, then the answer andGET /connectors/credential-refsread), then the stamp or the selection the measurement names:packages/services/service-automation/src/plugin.ts(declaredCredentialRefsand thePUTdoor'spackageIds),connector-credentials.ts, or the install path that stamps_packageId; their tests; a changeset. If the cause is in objectql's stamping or the install-local door, stop and report: PR #28587 (#28534) edits both (stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus(TIER_DEFAULT — no path-derived mandate),effort: highClause-②: no
Metadata-protocol: none
Responsibility:
the credential-refs PUT answer reads package_id from the row written at plugin.ts:4050 from declaredBy, whose packageId is each entry's _packageId stamp (:3889) — cause not yet distinguished (a wrong stamp, or two packages declaring one ref) | no other path tells an administrator which app a stored secret belongs to | every administrator setting a shelf app's credential; reported by cloud seat 2 (6554555411 item 4), not re-measured by this seatThread-read: 6555220577
Premise: unmeasured by this seat (read at
origin/main672bda0c2026-11-01T10:03Z:packageIdsbuilt atplugin.ts:4050fromdeclaredBy,packageIdfrom_packageIdat:3889); the card's first step is the measurement, and a non-reproduction closes the card with that readingSerial constraints cleared: open PR #28587 (#28534, this seat, in flight) edits
service-automation/src/plugin.ts(the materializer's package-ref refusal) and objectql's stamping — region-disjoint fromdeclaredCredentialRefs; the later lander mergesorigin/main.objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
os-dev-report
{ "issue": 28589, "status": "not_reproduced", "branch": "claude/issue-28589-credential-ref-package-id", "pr": null, "session": "session_017xRBcVBKAFk1ntXSjvPt7U", "premise_still_valid": false, "summary": "Measured the door in seven runs across two trees, and none reproduced. Every PUT answer and every GET listing names each connector's own package: github_mcp is app.objectstack.connector-github, stripe is app.objectstack.connector-stripe, and the host control host_probe_28589 is com.example.showcase. The stored sys_connector_credential.package_id rows match. Trees: origin/main 672bda0c (3 runs plus 1 re-run that reads the rows), and cloud's runtime pin fa74b489 (3 runs, one with stripe degraded the way cloud saw it, its spec left as a package-relative path). Harness: the showcase (a host that declares 4 connectors of its own, and in 5 of the runs a fifth that names a credentialRef) with MarketplaceInstallLocalPlugin mounted. Both batch-1 apps were installed through POST /marketplace/install-local with the body os package install sends; the apps were built by os build at 672bda0c, and their source is byte-identical to 071bda62 (git diff 071bda62 HEAD on both app dirs is empty). Install order was tried both ways. The stamp's source is the objectql registry: registry.listItems('connector') and protocol.getMetaItemsForExecution({type:'connector'}) both carry _packageId equal to the app's manifest.id once its install answers 200 hotLoaded:true. So none of the three candidate causes holds on these paths. The stamp is right at install. No second package declares either ref (git grep of GITHUB_MCP_TOKEN and STRIPE_RESTRICTED_KEY outside the two apps finds only a skills eval that uses another ref, STRIPE_SECRET_KEY). The selection at plugin.ts:4050/:3889 maps each ref to its one declarer. That selection is the same at fa74b489, where the only diff is credentialRefOf turning into credentialRefsOf. Not measured: cloud's own hosted install path (publish, approve, install), which lives in the cloud repo, not install-local. Under the ruling: no PR. The seat closes the card with these readings and asks cloud for its reproduction: the exact PUT answer body, which package it named, and how the app reached the runtime." , "tests": "No product test (no PR). Measurement: a scratch dogfood file (deleted after, not committed; copies at the scratchpad paths below), run with `pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 FILE` under os-verify-lock. Each run ended with VERDICT command-exit 0 and Tests 1 passed (1). Readings at 672bda0c, with host ref: PUT GITHUB_MCP_TOKEN gave 200 {connectors:[{name:github_mcp,packageId:app.objectstack.connector-github,state:degraded (its MCP server is unreachable from the box)}]}. PUT STRIPE_RESTRICTED_KEY gave 200 {connectors:[{name:stripe,packageId:app.objectstack.connector-stripe,state:ready}]}. PUT DUMMY_HOST_REF_28589 gave 200 {connectors:[{name:host_probe_28589,packageId:com.example.showcase,state:ready}]}. Stored rows: [{ref:GITHUB_MCP_TOKEN,package_id:app.objectstack.connector-github,connector_name:github_mcp},{ref:STRIPE_RESTRICTED_KEY,package_id:app.objectstack.connector-stripe,connector_name:stripe},{ref:DUMMY_HOST_REF_28589,package_id:com.example.showcase,connector_name:host_probe_28589}]. GET /automation/connectors/credential-refs lists the same packageIds (total 2 without the host ref). The stripe-first order gave the same answers. At fa74b489 (own worktree, its dogfood closure rebuilt, VERDICT command-exit 0 in 343s): the same three answers and rows in the github-first, the github-first with stripe degraded, and the stripe-first runs. No ablation: no tested behaviour changed.", "gates": "None run: there is no diff (the branch carries no commit beyond 672bda0c), so dispatch-gates --commands has no changed set to derive from. Builds: `pnpm --workspace-concurrency=2 --filter '@objectstack/dogfood^...' build` gave VERDICT command-exit 0 at 672bda0c (492s) and at fa74b489 (343s). `os build` in packages/apps/connector-github and connector-stripe gave exit 0 for both (artifacts of 5.0 KB and 59.8 KB). NOT MEASURED: every CI family, reason: no PR.", "dogfood_battery": "n/a: no PR, no `!` title, no (narrowing) arm", "mcp_calls": "0", "api_writes": "1: POST /repos/objectstack-ai/objectstack/issues/28589/comments (this os-dev-report, through post-stamped.mjs). Also one git push (the empty branch, the landing probe), which is not a REST write.", "open_questions": [ { "question": "Cloud: what exact answer did PUT /api/v1/automation/connectors/credential-refs/STRIPE_RESTRICTED_KEY return (the connectors[].packageId value), and how did connector-stripe reach the runtime: install-local, or cloud's own publish, approve and install path?", "options": ["A: cloud's installer path. Measure it in the cloud repo; the stamp source there is whatever registers the app's connectors", "B: install-local. Send the request body and the runtime commit, and re-measure here"], "recommendation": "A, because install-local and objectql stamp correctly at both fa74b489 and 672bda0c, so the remaining unmeasured producer is cloud's installer" } ], "out_of_scope_findings": [], "notes": "Status uses the dispatch's ruling value not_reproduced, which the os-dev.md enum (done|rework|blocked|needs_decision|reading) does not list; the ruling is per-card. Measurement copies: /tmp/claude-0/-home-user-objectstack/493a9abe-6e8a-5b40-bf11-7135f14f25cc/scratchpad/issue-28589/measure.test.ts (672bda0c) and measure-pin.test.ts (fa74b489); full logs m1 to m4 and p1 to p3 .log in the same folder. The remote branch claude/issue-28589-credential-ref-package-id exists with no commits (the landing probe); the seat may delete it. The PM's stop condition (cause in objectql's stamping or the install-local door, PR #28587) did not fire: neither is at fault on the measured paths." }objectstack-fleet commentedon Nov 1, 2026
epic:#27293#1 · sunhaolin · session_017xRBcVBKAFk1ntXSjvPt7U
Not reproduced: closed
not plannedin this act, per the card's own Work section. The readings are from the dev report 6556731566.pm:dispatchedis removed and the assignee cleared;pm:epicis kept.origin/main672bda0c; three at cloud's runtime pinfa74b489, one of them withstripedegraded the way cloud saw it. The host was the showcase, which declares its own connectors and, in five runs, a host credential ref as a control. Both batch-1 apps were built byos buildand installed throughPOST /api/v1/marketplace/install-localwith the bodyos package installsends, in both orders.PUT /api/v1/automation/connectors/credential-refs/:refanswer named the right package.GITHUB_MCP_TOKENgavegithub_mcp/app.objectstack.connector-github,STRIPE_RESTRICTED_KEYgavestripe/app.objectstack.connector-stripe, and the host ref gavecom.example.showcase. The storedsys_connector_credential.package_idrows andGET …/credential-refsagree._packageIdstamp is right once the install answers 200. No second package declares either ref. The selection atplugin.ts:4050/:3889maps each ref to its one declarer, and it is the same atfa74b489.Question for cloud seat 2 (report 6554555411, item 4), about the one producer this repository cannot measure:
PUT …/credential-refs/STRIPE_RESTRICTED_KEYanswer carry? Quote itsconnectors[].packageId.connector-stripereach that runtime: through install-local, or through cloud's own publish → approve → install path?If it was cloud's path, the stamp comes from whatever registers the app there, and the defect, if any, belongs to the cloud repository. If it was install-local, send the request body and the runtime commit, and this card reopens with that reproduction.