Repository navigation
Commit f9bcd08
fix(datasource, approvals): runtime strings state each decision in words instead of a tracker number (stage 3) (#21346)
Part of #20751
Clause-②: no
**Stage 3 of the `domain:services` lane under the maintainer's A / A
ruling (5902360492): the `service-datasource` and `plugin-approvals`
strings.** The card stays open for the later stages, so this PR carries
no closing keyword. Text only: no status, error `code`, field, route,
export or control flow moves (AST skeleton reads SAME for 12 of 12
changed sources, below).
## What this does
The two packages' refusals, warnings, log lines, datasource route-ledger
notes, the generated object-draft comment, and the `sys_approval_action`
/ `sys_approval_delegation` field help and description (with their
`es-ES`, `ja-JP` and `zh-CN` variants) sent the reader to a tracker
number for the reason behind them. In form D, as stages 1 and 2 applied
it, the number goes. Where the sentence already said what was decided,
only the citation goes. Where it leaned on the number, it now says the
decision in words.
All 34 ledgered occurrences in the two packages (claim `5945630892`),
re-derived from the ledger on `origin/main` at `1371dc98` and again on
the merged tree at `222ecc27`: `service-datasource` 9 (9 pairs, 3
files), `plugin-approvals` 25 (23 pairs, 7 files). They sit in 32 string
sites. None of them is in the three excluded files
(`datasource-secret-binder.test.ts`, `sys-approval-token.object.ts`,
`approval-token-internal-hash.integration.test.ts`); none of those files
is touched.
### Rewritten in words
Author- and administrator-visible text first, log lines last.
| Where (head line) | Cited | The text now says | Decision read from |
|---|---|---|---|
| `plugin-approvals` `sys-approval-action.object.ts:165`, `via_override`
help, and its three locale leaves | 3424 | "admitted to this action only
by the privileged override, which lets a platform or organization admin
act on any pending request so that one nobody in its slate can decide
never stays stuck" | the card's fix comment (an admin escape hatch
rather than refusing empty approvers at creation) and the
`isOverrideActor` contract it landed: a platform or tenant admin may
always act on a PENDING request |
| `service-datasource` `datasource-credential-migration.ts:269-272`, the
migration refusal `reason` | 8078, 8081 | "an alias spelling from before
inline credentials were refused at publish, which no connection builder
reads, or ... turso's `encryptionKey`, which has no secret slot of its
own: the one slot carries the `authToken`" | 8078 (the spec half:
`password` / `authToken` declared unwritable, the old alias spellings
carry the refusal, `encryptionKey` left writable because neither ruled
mechanism can carry it) and 8081 item 4 (the binder injects exactly one
secret slot; a second slot is undecided) |
| `service-datasource` `external-datasource-service.ts:925`, the
generated draft's remote-primary-key comment | 10997 | "For a COMPOSITE
key a driver's introspection can report only the first column, so treat
the list as a lower bound" | 10997 repaired the SQLite arm (every column
whose `pk` ordinal is above zero, ordered by key position, PR 11104), so
the old "some drivers report only the first column" named a defect that
is gone in-tree; the caveat stays because the generator renders whatever
key it was given and the driver population is open (the
`external-datasource-service.ts` docblock records both) |
| `plugin-approvals` `approval-service.ts:1765`, the `queue` approver
warning | 3508 | "because the platform has no ownership queue to expand
it from (the type is deprecated and no longer offered for authoring).
Route this step to a team, department or position instead." | the card's
resolution: deep deprecation rather than an implementation, since there
is no queue entity or member table; the routing advice is the same one
the `approval-approver-type-unsupported` lint hint gives |
| `plugin-approvals` `approval-service.ts:2629`, `:2636`, the
live-record warnings | 3447 | "resolving approvers against the trigger
snapshot instead of the live record they are normally resolved from" |
the card's P1 (approvers are resolved against the live record re-read at
node entry; the trigger snapshot is the fallback the code keeps when
that read finds nothing or fails) |
| `plugin-approvals` `approval-service.ts:3669`, the recall refusal's
developer log line | 3424 | "holds no admin override for a ... request
(the override reaches pending requests only)" | same as the
`via_override` row |
| `service-datasource` `datasource-route-ledger.ts:139`, list note |
3827 | "the retained connect verdict per datasource, so a datasource
that failed to connect reports `error` here instead of looking untested"
| the card's half A (`status` reports the retained connect result
instead of a constant `unvalidated`) |
| `service-datasource` `datasource-route-ledger.ts:149`,
migrate-credential note | 8155 | "drops the inline key only once the
secret is stored" | the maintainer-approved shape (b): the reference is
durably written before the inline key is removed |
| `service-datasource` `datasource-route-ledger.ts:161`, remote-tables
note | 7744, 4249, 7955 | "both stay mounted, because renaming a live
route to match a ledger would be an API break ... one failure contract
(a refusal answers 400 `EXTERNAL_DATASOURCE_ERROR`, the code registered
for the service that refused) and one request shape (both forward
`?schema=` with the same coercion)" | 7744's dispatch and outcome (the
ledger describes what is mounted; no rename), 4249's option 1 as landed
(the separately registered `EXTERNAL_DATASOURCE_ERROR`), 7955's route A
(forward `?schema=` with the twin's coercion) |
### Citation only (the sentence already stated the decision)
- `plugin-approvals`: `sys-approval-action.object.ts:194` `attachments`
help, and its three locale leaves (3266, "Files supporting this action —
e.g. a signed contract or evidence");
`sys-approval-delegation.object.ts:43` description, and its three locale
leaves (1322, "route this user's approver slots to a delegate within a
time window"); `approval-service.ts:1782` (3807, "the slot routes to no
one and the request cannot advance until someone is added or the
approver is re-pointed"); `:2044` (10230), `:2113` and `:2139` (10547),
`:2474` (10153), each already saying the team, member or manager is
dropped because routing to them "would put approval authority over the
record outside its tenant", and the truncated-read line already saying
routing is left unchanged rather than risk dropping a member; `:4245`
(3823, "that pause continues only through this service ... any other
node type there is resumable by anyone with the run id (amended
ADR-0044)").
- `service-datasource`: `external-datasource-service.ts:921` (11000,
"Preserved as a COMMENT because 'ServiceObject' has no authorable key
for a federated object's remote primary key: 'fields.FIELD.primaryKey'
is not part of the field schema").
Every cited card (19: 8078, 8081, 3827, 4249, 7744, 7955, 8155, 10997,
11000, 10153, 10230, 10547, 3424, 3447, 3508, 3807, 3823, 3266, 1322)
was read through REST, body and every comment, before its string was
rewritten. 8078 is a pull request; its body carries the decision.
### Translations
- `via_override` help: the `es-ES`, `ja-JP` and `zh-CN` leaves were real
translations; each now carries the same decision ("un administrador de
la plataforma o de la organización", "プラットフォーム管理者または組織管理者",
"平台管理员或组织管理员") and no number.
- `attachments` help (all three) and the `zh-CN`
`sys_approval_delegation` description were real translations; each
dropped its citation only.
- The `es-ES` and `ja-JP` `sys_approval_delegation` descriptions were
byte copies of the English source. They are now copies of the revised
English, and `node scripts/check-i18n-bundles.mjs --write
--filter=plugin-approvals` rewrote `en` from the object source and
recorded the two new digests in the `es-ES` / `ja-JP`
`*.source-hashes.generated.ts` companions. No digest and no `en` leaf
was hand-edited; the merge kept every hand-written translated value.
- Tracker numbers left in the package's locale bundles: 0.
## Ledger (`scripts/doc-authoring-prose-id.baseline.json`)
Stage 2 (PR #21311) held this file. This branch was built while it sat
in the queue, then `origin/main` (`222ecc27`, which contains `6091136e`,
the stage-2 merge) was merged in, and only then was the ledger
recomputed with `node scripts/check-doc-authoring.mjs --census-ledger`
(exit 0, no growth refusal) into a scratch file and copied into place.
The diff deletes 52 lines and adds none: exactly the 10 file blocks of
the two packages. Every other row is unchanged (a scripted comparison of
the 62 other keys: 0 moved).
| | before (`222ecc27`) | after |
|---|---|---|
| `service-datasource` | 9 occurrences, 9 pairs, 3 files | 0 |
| `plugin-approvals` | 25 occurrences, 23 pairs, 7 files | 0 |
| whole ledger | 261 occurrences, 189 pairs, 72 files | 227 occurrences,
157 pairs, 62 files |
`pnpm check:doc-authoring` at the head: "sibling-package prose ids hold
the baseline — 204 pinned site(s) across 62 file(s), 85660 string(s)
read in 1247 parsed source(s), no growth, no burn-down unrecorded". No
gate is added or loosened; `scripts/check-doc-authoring.mjs` is
untouched.
## Changeset
`.changeset/20751-services-strings-stage3-state-the-decision.md`:
`patch` for `@objectstack/service-datasource` and
`@objectstack/plugin-approvals`. Measured after building at the head:
the new author-visible sentences are in each package's built output
(`plugin-approvals` `dist/index.js` and `dist/index.mjs`;
`service-datasource` `dist/index.js` and `dist/index.cjs`). A TypeScript
scan of every string literal and template text in the built output finds
0 tracker ids in `service-datasource`; in `plugin-approvals` its six
matches are all CSS hex colours (`#2563eb`, `#64748b`) in the
action-link page template, not tracker ids. Control: the same scan reads
82 in `plugin-security`'s built output and 66 in `service-automation`'s.
The datasource route ledger does not ship: `DATASOURCE_ROUTE_LEDGER` and
its new note text are in 0 files under
`packages/services/service-datasource/dist`, so the changeset does not
describe it.
## Text-only proof
A TypeScript-AST skeleton of each changed non-test `.ts` file, where
every string literal and template text is a placeholder, a run of
adjacent string operands of a `+` chain is one string (only its embedded
expressions are kept), identifiers and numbers keep their text, and
comments are never read. `222ecc27` against the head: 12 of 12 SAME.
Controls on scratch copies of `approval-service.ts`, each mutation's
marker counted once on disk first: a one-identifier rename reads DIFF; a
text-only change reads SAME; a re-split of one template into two
concatenated pieces reads SAME. (A first draft of the tool wrapped every
`+` chain in its own token and read `approval-service.ts` DIFF by two
tokens: the `queue` warning went from one template to a three-piece
chain. The corrected tool treats a chain of strings as one string, which
is what the re-split control pins.)
## Pins
Assertions that found a warning or comment by its tracker number now
find it by what it says. No `code` or `status` assertion was touched;
none of these strings is a coded refusal.
- `approval-service.test.ts:3165`: the `queue` warning by `'queue'` and
"no ownership queue to expand it from" instead of the id.
- `approval-service.test.ts:3218`: the expanded-to-nobody warning by
"cannot advance until someone is added or the approver is re-pointed"
instead of the id.
- `team-approver-org-screen.test.ts:223` and
`team-member-org-screen.test.ts:250`: the warning found by "team
'team_b' was dropped from the approver slate" and "member(s) of team
'team_a' were dropped from the approver slate"; both test titles drop
"and the card".
- `external-object-draft-primary-key.test.ts:218` and `:229`: "a
driver's introspection can report only the first column" and "not part
of the field schema" instead of the ids; the first test's title said
10997 "is unfixed and in another lane", which stopped being true when PR
11104 landed, and now says "a driver can under-report a composite key".
The `lower bound` and `no authorable key` assertions beside them are
unchanged.
- `external-object-draft-authorised-shape.test.ts:151` pins the comment
line "Preserved as a COMMENT because 'ServiceObject' has no authorable
key for a", which this PR leaves byte-identical.
Every re-pinned case was run with the verbose reporter and is listed as
passed.
## Tests
All through `scripts/pm/os-verify-lock.sh`, every verdict `VERDICT
command-exit 0`:
- Build: `turbo run build` over the closure of the two packages and
`@objectstack/cli` (59/59), then, after merging `origin/main`, `turbo
run build --filter=./packages/* --filter=./packages/*/*` (71/71).
- At the merged head `7740c0f0`: `@objectstack/service-datasource` 35
files, 707 tests passed; `@objectstack/plugin-approvals` 53 files, 824
tests passed.
- `typecheck` for both, including `check:test-typecheck: OK` for
`plugin-approvals`.
## Gates
- `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack
--commands` (no paths) at `7740c0f0` (18 paths vs merge base
`222ecc27`): 72 commands, run one at a time from the worktree, each exit
code recorded before any pipe. `--ran`: "72 derived famil(ies) accounted
for — 72 run, 0 NOT-MEASURED (a DERIVED zero — all 72 recorded an exit
code and none of them is 3)".
- `check:i18n`: "all bundles in sync, no undeclared authoring keys";
`check:i18n-stale-fill`: "no new stale fills, 0 baselined";
`check:issue-citations`: "no issue citations added against 222ecc2 (12
file(s) read)"; `check:nul-bytes`: OK, 9637 files;
`check:type-check-debt`: "none above its recorded number";
`check:dual-build-cjs-loads`: 105 require entry points across 66
packages load; `check:dts-closure`: 71 built packages, 167/167;
`check:sourcemap-no-sources-content`: 68 packages, 522 maps.
- Outside the derived set, all exit 0: the eleven declared
wide-population families (`check:init-service-contract`,
`check:live-db-isolation`, `check:meta-type-normalized`,
`check:optional-error-sink`, `check:resume-authority-declared`,
`check:route-envelope`, `check:runner-env-posture`,
`check:settings-bind-window`, `check:startup-registry-verdict`,
`check:verify-stand-in`, `check:wildcard-fallthrough`) and the
artifact-roster families whose roster sits under one of this PR's
directories (`check-changeset-fixed`, `check-published-list-mirrors` and
its self-test, `check:authz-resolver`, `check:console-injection`,
`check:error-code-casing`, `check:filter-alias-parity`,
`check:published-readme-exports`, `check-dts-references --self-test`;
`check:engine-double-contract` and `check:i18n-stale-fill` are already
in the derived set). The path-scheduled CI jobs and the type-check lanes
are CI's.
- `pnpm lint` (`eslint . --no-inline-config`, repo-wide, not narrowed)
at `7740c0f0`: exit 0, 146 s under the lock.
## Acceptance notes
Noted, not filed:
- `docs/qa/platform-checklist/areas/approvals.json:1249` quotes the
`queue` warning with its old tracker suffix. The part it quotes before
the suffix survives verbatim in the new text, so a runner still finds
the warning; the file is outside this stage's surface. Carrier: none.
- `external-object-draft-primary-key.test.ts` keeps a docblock (lines 63
to 67) saying 10997 is a separate, unfixed defect in the engine lane. It
is a comment above the fixture, outside the ledger; this PR changes only
the title and assertion of the test that pins the caveat. Carrier: none.
- `packages/lint/src/validate-approval-approvers.ts:463` carries the
same `queue` citation in its lint message, and its test pins the id.
`packages/lint` is outside this lane's ledger share.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01DiCSbmJrkzNhuEAier4VoJ)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 1878ef9 commit f9bcd08
18 files changed
Lines changed: 66 additions & 96 deletions
File tree
- .changeset
- packages
- plugins/plugin-approvals/src
- translations
- services/service-datasource/src
- __tests__
- scripts
Lines changed: 15 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3162 | 3162 | | |
3163 | 3163 | | |
3164 | 3164 | | |
3165 | | - | |
| 3165 | + | |
3166 | 3166 | | |
3167 | 3167 | | |
3168 | 3168 | | |
| |||
3215 | 3215 | | |
3216 | 3216 | | |
3217 | 3217 | | |
3218 | | - | |
| 3218 | + | |
3219 | 3219 | | |
3220 | 3220 | | |
3221 | 3221 | | |
| |||
Lines changed: 14 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1762 | 1762 | | |
1763 | 1763 | | |
1764 | 1764 | | |
1765 | | - | |
| 1765 | + | |
| 1766 | + | |
| 1767 | + | |
1766 | 1768 | | |
1767 | 1769 | | |
1768 | 1770 | | |
| |||
1777 | 1779 | | |
1778 | 1780 | | |
1779 | 1781 | | |
1780 | | - | |
| 1782 | + | |
1781 | 1783 | | |
1782 | 1784 | | |
1783 | 1785 | | |
| |||
2039 | 2041 | | |
2040 | 2042 | | |
2041 | 2043 | | |
2042 | | - | |
| 2044 | + | |
2043 | 2045 | | |
2044 | 2046 | | |
2045 | 2047 | | |
| |||
2108 | 2110 | | |
2109 | 2111 | | |
2110 | 2112 | | |
2111 | | - | |
| 2113 | + | |
2112 | 2114 | | |
2113 | 2115 | | |
2114 | 2116 | | |
| |||
2134 | 2136 | | |
2135 | 2137 | | |
2136 | 2138 | | |
2137 | | - | |
| 2139 | + | |
2138 | 2140 | | |
2139 | 2141 | | |
2140 | 2142 | | |
| |||
2469 | 2471 | | |
2470 | 2472 | | |
2471 | 2473 | | |
2472 | | - | |
| 2474 | + | |
2473 | 2475 | | |
2474 | 2476 | | |
2475 | 2477 | | |
| |||
2624 | 2626 | | |
2625 | 2627 | | |
2626 | 2628 | | |
2627 | | - | |
| 2629 | + | |
| 2630 | + | |
2628 | 2631 | | |
2629 | 2632 | | |
2630 | 2633 | | |
2631 | 2634 | | |
2632 | 2635 | | |
2633 | | - | |
| 2636 | + | |
| 2637 | + | |
2634 | 2638 | | |
2635 | 2639 | | |
2636 | 2640 | | |
| |||
3662 | 3666 | | |
3663 | 3667 | | |
3664 | 3668 | | |
3665 | | - | |
| 3669 | + | |
3666 | 3670 | | |
3667 | 3671 | | |
3668 | 3672 | | |
| |||
4238 | 4242 | | |
4239 | 4243 | | |
4240 | 4244 | | |
4241 | | - | |
| 4245 | + | |
4242 | 4246 | | |
4243 | 4247 | | |
4244 | 4248 | | |
| |||
Lines changed: 4 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
162 | 162 | | |
163 | 163 | | |
164 | 164 | | |
165 | | - | |
166 | | - | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
167 | 168 | | |
168 | 169 | | |
169 | 170 | | |
| |||
190 | 191 | | |
191 | 192 | | |
192 | 193 | | |
193 | | - | |
| 194 | + | |
194 | 195 | | |
195 | 196 | | |
196 | 197 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
43 | | - | |
| 43 | + | |
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
218 | 218 | | |
219 | 219 | | |
220 | 220 | | |
221 | | - | |
| 221 | + | |
222 | 222 | | |
223 | | - | |
| 223 | + | |
224 | 224 | | |
225 | 225 | | |
226 | 226 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
245 | 245 | | |
246 | 246 | | |
247 | 247 | | |
248 | | - | |
| 248 | + | |
249 | 249 | | |
250 | | - | |
| 250 | + | |
251 | 251 | | |
252 | 252 | | |
253 | 253 | | |
| |||
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
260 | 260 | | |
261 | 261 | | |
262 | 262 | | |
263 | | - | |
| 263 | + | |
264 | 264 | | |
265 | 265 | | |
266 | 266 | | |
| |||
272 | 272 | | |
273 | 273 | | |
274 | 274 | | |
275 | | - | |
| 275 | + | |
276 | 276 | | |
277 | 277 | | |
278 | 278 | | |
| |||
297 | 297 | | |
298 | 298 | | |
299 | 299 | | |
300 | | - | |
| 300 | + | |
301 | 301 | | |
302 | 302 | | |
303 | 303 | | |
| |||
Lines changed: 3 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
260 | 260 | | |
261 | 261 | | |
262 | 262 | | |
263 | | - | |
| 263 | + | |
264 | 264 | | |
265 | 265 | | |
266 | 266 | | |
| |||
272 | 272 | | |
273 | 273 | | |
274 | 274 | | |
275 | | - | |
| 275 | + | |
276 | 276 | | |
277 | 277 | | |
278 | 278 | | |
| |||
297 | 297 | | |
298 | 298 | | |
299 | 299 | | |
300 | | - | |
| 300 | + | |
301 | 301 | | |
302 | 302 | | |
303 | 303 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
25 | | - | |
| 25 | + | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| |||
0 commit comments