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
datasources: migrateCredential's drop-inline refusal blames a missing secret row when the stored credential is empty #29069
Filing gate: ① out-of-scope finding of the #28928 dev (PR #29064, os-dev-report 6570874270 on #28928), also the should-fix of that PR's contract review. Filed by domain:server seat 1. ⛔ Not a claim. Graded by this seat p3 under 「定级你可以自己决定」 (Leehom, 2026-11-01): refusal text that names the wrong cause; the outcome is right.
Reach: an admin running the datasource credential migration (drop-inline) over a credential whose sys_secret row decrypts to an empty value (rows sealed before PR #29064).
migrateCredential in packages/services/service-datasource/src/datasource-admin-service.ts (about L1179) refuses on resolved == null || resolved === '' with one sentence that blames a missing row or a changed encryption key. PR #29064 already split the connect path's status reason (an empty credential is named as empty); this refusal still conflates the two.
Wanted
The empty-value branch names the credential as empty, in PR #29064's wording; the missing-row / changed-key branch keeps its sentence. Same status and code; a test pins both texts.
Claim: PM loop round 1 · card thread · 2026-11-02T08:31Z
Session: session_01ADHkmQJdgarUjPLNgFBY67 (the seat); the card thread is session_01ADHkmP66rDL21VeBrVWovN
Account: os-steve (the seat's linked user; the card's assignee)
Branch: claude/project-thread-3dvabi
Worktree: the card thread's own container checkout
Domain: domain:server
Seat: domain:server#3
Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
File surface: packages/services/service-datasource/src/datasource-admin-service.ts (migrateCredential empty-value branch), service-datasource tests, a changeset
Container & model: card thread cmsg_01FdL1XeUyvVNxLreh3F4Qi9VrDSYbFeBRpZi2Rbi1iw6B, mode:thread, model: opus (--tier names no path mandate: PM's call, default), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: packages/services/service-datasource refusal text names the wrong cause; no platform path covers it; an admin migrating a credential sealed empty before PR #29064
Thread-read: none
Premise: holds (site re-read on origin/maina4015ab4 by the seat before dispatch)
Serial constraints cleared: none (PR #29064 merged; no open PR touches packages/services/service-datasource/src/)
Resume-from: none — fresh from origin/main
State: pm:queue → pm:dispatched, assigned to os-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/29069-delta.md.
{
"issue": 29069,
"status": "done",
"branch": "claude/project-thread-3dvabi",
"pr": "https://github.com/objectstack-ai/objectstack/pull/29192",
"session": "session_01ADHkmP66rDL21VeBrVWovN",
"premise_still_valid": true,
"summary": "migrateCredential's drop-inline step now splits its refusal: a ref that resolves to '' is refused with the connect path's PR #29064 clause (credential 'REF' is empty (its sys_secret row holds an empty value)) and a remedy to set the secret again; an unresolvable ref keeps its sentence and remedy. Same refused status, no write, inline copy kept; no new code, status or member. Changeset patch on @objectstack/service-datasource.",
"tests": "datasource-admin-service.test.ts: red on base (source fea2dbb7, tests at head) Tests 1 failed | 38 passed (39), the new case received the missing-row sentence; green at b213c369 Tests 39 passed (39). Forced test edit: the existing unresolvable-ref case moved from toContain to an exact pin of the unchanged sentence plus remedy. Ablation via scripts/ablation-replace.mjs (whole empty branch replaced by the old conflated condition, anchor 1->0, blob 144b0a89->bcdb23c3): Tests 1 failed | 38 passed (39), received the conflated sentence; restore blob == HEAD 144b0a89, git diff HEAD empty. Source-relative import, no dist leg. Package: pnpm --filter @objectstack/service-datasource test Test Files 69 passed (69), Tests 1153 passed (1153), exit 0; typecheck exit 0.",
"gates": "At b213c369: dispatch-gates --commands derived 61 families; 61 run, all exit 0 (check-plugin-teardown-shape --self-test exit 3 on a shallow clone, exit 0 after git fetch --unshallow; check:dual-build-cjs-loads exit 3 before a full build, exit 0 after pnpm turbo run build under the lock). --ran reconciliation: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. eslint --no-inline-config on the two changed .ts files exit 0; repo-wide pnpm lint and all CI-only families: the PR's check-runs (in_progress at report time).",
"line_budget": "59 changed lines (+57 / -2) across 3 files, under the 3000 human-merge threshold",
"files_changed": [
".changeset/29069-migrate-credential-empty-refusal.md",
"packages/services/service-datasource/src/datasource-admin-service.ts",
"packages/services/service-datasource/src/__tests__/datasource-admin-service.test.ts"
],
"deviations": "The local lint run is eslint on the changed files, not repo-wide pnpm lint (CI's). The empty-credential clause is now spelled twice (connect path and this refusal) rather than through a shared helper, because the claim's file surface is the admin service only; each spelling has its own exact pin.",
"dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm",
"mcp_calls": "3: mcp__github__issue_read x3 (get_comments x2, get), reads only",
"api_writes": "2: fleet-write relay pr_create (PR #29192, 4931 bytes sent = stored, no assignees, no labels) and this os-dev-report comment via post-stamped.mjs",
"open_questions": [
{
"question": "Should the empty-credential clause become one shared helper used by the connect path and migrateCredential?",
"options": ["A: leave two pinned spellings (this PR)", "B: a follow-up extracts a module-private helper in service-datasource used by both"],
"recommendation": "A, because both texts are pinned exactly and B would widen this claim's file surface to datasource-connection-service.ts"
}
],
"out_of_scope_findings": []
}
Landed: merged as e66e3095 (2026-11-02T10:35Z). The drop-inline credential migration now names an empty stored credential as empty, in the connect path's wording; the missing-row / changed-key sentence is unchanged.
Seat ACCEPT 6573446105 (Clause-②: no, no contract review owed). Fixes #29069 closed this card on merge.
State: pm:dispatched and the assignee removed in the same round.
Activity
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Claim: PM loop round 1 · card thread · 2026-11-02T08:31Z
Session:
session_01ADHkmQJdgarUjPLNgFBY67(the seat); the card thread issession_01ADHkmP66rDL21VeBrVWovNAccount:
os-steve(the seat's linked user; the card's assignee)Branch:
claude/project-thread-3dvabiWorktree: the card thread's own container checkout
Domain:
domain:serverSeat:
domain:server#3Ruling-ref: the maintainer, verbatim, in the project thread: 「开 server 2、3、5 号席位, 前任已经下班,接手所有开发,包括跟进之前未完成的开发落地。」
File surface:
packages/services/service-datasource/src/datasource-admin-service.ts(migrateCredentialempty-value branch), service-datasource tests, a changesetContainer & model: card thread
cmsg_01FdL1XeUyvVNxLreh3F4Qi9VrDSYbFeBRpZi2Rbi1iw6B,mode:thread,model: opus(--tiernames no path mandate: PM's call, default),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
packages/services/service-datasourcerefusal text names the wrong cause; no platform path covers it; an admin migrating a credential sealed empty before PR #29064Thread-read: none
Premise: holds (site re-read on
origin/maina4015ab4by the seat before dispatch)Serial constraints cleared: none (PR #29064 merged; no open PR touches
packages/services/service-datasource/src/)Resume-from: none — fresh from
origin/mainState:
pm:queue→pm:dispatched, assigned toos-steve, recorded by this claim. Order: project file server-seat3/standard-order.md + server-seat3/29069-delta.md.objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmP66rDL21VeBrVWovN
os-dev-report
{ "issue": 29069, "status": "done", "branch": "claude/project-thread-3dvabi", "pr": "https://github.com/objectstack-ai/objectstack/pull/29192", "session": "session_01ADHkmP66rDL21VeBrVWovN", "premise_still_valid": true, "summary": "migrateCredential's drop-inline step now splits its refusal: a ref that resolves to '' is refused with the connect path's PR #29064 clause (credential 'REF' is empty (its sys_secret row holds an empty value)) and a remedy to set the secret again; an unresolvable ref keeps its sentence and remedy. Same refused status, no write, inline copy kept; no new code, status or member. Changeset patch on @objectstack/service-datasource.", "tests": "datasource-admin-service.test.ts: red on base (source fea2dbb7, tests at head) Tests 1 failed | 38 passed (39), the new case received the missing-row sentence; green at b213c369 Tests 39 passed (39). Forced test edit: the existing unresolvable-ref case moved from toContain to an exact pin of the unchanged sentence plus remedy. Ablation via scripts/ablation-replace.mjs (whole empty branch replaced by the old conflated condition, anchor 1->0, blob 144b0a89->bcdb23c3): Tests 1 failed | 38 passed (39), received the conflated sentence; restore blob == HEAD 144b0a89, git diff HEAD empty. Source-relative import, no dist leg. Package: pnpm --filter @objectstack/service-datasource test Test Files 69 passed (69), Tests 1153 passed (1153), exit 0; typecheck exit 0.", "gates": "At b213c369: dispatch-gates --commands derived 61 families; 61 run, all exit 0 (check-plugin-teardown-shape --self-test exit 3 on a shallow clone, exit 0 after git fetch --unshallow; check:dual-build-cjs-loads exit 3 before a full build, exit 0 after pnpm turbo run build under the lock). --ran reconciliation: 61 derived, 61 run, 0 NOT-MEASURED, 0 UNRUN, exit 0. eslint --no-inline-config on the two changed .ts files exit 0; repo-wide pnpm lint and all CI-only families: the PR's check-runs (in_progress at report time).", "line_budget": "59 changed lines (+57 / -2) across 3 files, under the 3000 human-merge threshold", "files_changed": [ ".changeset/29069-migrate-credential-empty-refusal.md", "packages/services/service-datasource/src/datasource-admin-service.ts", "packages/services/service-datasource/src/__tests__/datasource-admin-service.test.ts" ], "deviations": "The local lint run is eslint on the changed files, not repo-wide pnpm lint (CI's). The empty-credential clause is now spelled twice (connect path and this refusal) rather than through a shared helper, because the claim's file surface is the admin service only; each spelling has its own exact pin.", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "3: mcp__github__issue_read x3 (get_comments x2, get), reads only", "api_writes": "2: fleet-write relay pr_create (PR #29192, 4931 bytes sent = stored, no assignees, no labels) and this os-dev-report comment via post-stamped.mjs", "open_questions": [ { "question": "Should the empty-credential clause become one shared helper used by the connect path and migrateCredential?", "options": ["A: leave two pinned spellings (this PR)", "B: a follow-up extracts a module-private helper in service-datasource used by both"], "recommendation": "A, because both texts are pinned exactly and B would widen this claim's file surface to datasource-connection-service.ts" } ], "out_of_scope_findings": [] }Stamped 2026-11-02T09:15Z.
Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
ACCEPT → PR #29192 comment 6573446105 (head
b213c369). Landing once CI is green.objectstack-fleet commentedon Nov 2, 2026
domain:server#3 · os-steve · session_01ADHkmQJdgarUjPLNgFBY67
Landing record · #29069 · PR #29192
domain:serverseat 3 ·session_01ADHkmQJdgarUjPLNgFBY67· 2026-11-02T10:35Zgit ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29192-*'git merge-base --is-ancestor e66e3095a6 origin/maingit grep -n "resolved === ''" origin/main -- packages/services/service-datasource/src/datasource-admin-service.tse66e3095(2026-11-02T10:35Z). The drop-inline credential migration now names an empty stored credential as empty, in the connect path's wording; the missing-row / changed-key sentence is unchanged.6573446105(Clause-②: no, no contract review owed).Fixes #29069closed this card on merge.pm:dispatchedand the assignee removed in the same round.