Repository navigation
fix(auth, webhooks, messaging): runtime strings state each decision in words instead of a tracker number (stage 1) - #21218
Conversation
…n words instead of a tracker number (stage 1) The plugin-auth, plugin-webhooks and service-messaging refusals, warnings, log lines, route-ledger notes and sys_http_delivery field help (with its es-ES / ja-JP / zh-CN variants) drop the tracker numbers they cited; where a sentence leaned on the number it now says what was decided. Three test pins move to the new substance. The doc-authoring prose-id ledger is recomputed with --census-ledger: the three packages' 84 occurrences leave it, no other row moves. Claude-Session: https://claude.ai/code/session_01DiCSbmJrkzNhuEAier4VoJ Co-authored-by: Claude <noreply@anthropic.com>
…h companions `node scripts/check-i18n-bundles.mjs --write --filter=service-messaging`: the es-ES / ja-JP / zh-CN `headers_json.help` and `error.help` leaves are byte copies of the revised English source, so the extractor records their new digests. No digest was hand-edited. Claude-Session: https://claude.ai/code/session_01DiCSbmJrkzNhuEAier4VoJ Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 3 package(s): 13 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 4 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 16 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ee55203ce2625c8513d6c080ae8920c0c8c73304 && git checkout ee55203ce2625c8513d6c080ae8920c0c8c73304
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 097ef802700e109aa98a89c2991041516476b6f9 0bb7a64f69eee0ef1d670ff9620c39a669d5ec74 && git checkout -B drift-repro 097ef802700e109aa98a89c2991041516476b6f9 && git merge --no-ff 0bb7a64f69eee0ef1d670ff9620c39a669d5ec74
node scripts/docs-audit/affected-docs.mjs --json 097ef802700e109aa98a89c2991041516476b6f9
|
Part of #20751
Clause-②: no
Stage 1 of the
domain:serviceslane under the maintainer's A / A ruling (5902360492): theplugin-auth,plugin-webhooksandservice-messagingstrings. The card stays open for the later stages, so this PR carries no closing keyword. Text only: no status, errorcode, field, route, export or control flow moves. One module-private interface loses the two members that held the citations as data (see Text-only proof).What this does
The three packages' refusals, thrown errors, boot and log lines, auth route-ledger notes and the
sys_http_deliveryfield help (with itses-ES,ja-JPandzh-CNvariants) sent the reader to a tracker number for the reason behind them. In form D, as the earlier stages of the other lanes 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 84 ledgered occurrences in the three packages (claim
5936032644), re-derived from the ledger onorigin/mainat5e5ce48c:plugin-auth28 (21 pairs, 13 files),plugin-webhooks33 (19 pairs, 8 files),service-messaging23 (15 pairs, 8 files). They sit in 70 string sites.Rewritten in words
Author- and administrator-visible text first, log lines last.
service-messaginghttp-delivery.object.ts:237,attemptshelp, and its three locale leavesattempts === 0because a parked row has no signature) under the maintainer's minimal-cut rulingservice-messaginghttp-outbox.ts:514,DELIVERY_NEVER_SENTmessageservice-messaginghttp-outbox.ts:547,DELIVERY_NOT_ELIGIBLEmessageservice-messagingoutbox.ts:187,ack()refusalplugin-webhooksauto-enqueuer.ts:536, the parked row'serror(shown in Setup)plugin-webhooksredeliver-guard.ts:90and:123, redeliver refusalsplugin-authaudience-posture.ts:245, boot refusalplugin-authinternal-field-readback.ts:336, thrown composition errorinternalcolumn is withheld from every ordinary read and recovered only through it)"plugin-authwalled-owner-verification-path.ts:367, boot warningplugin-authobjectql-adapter.ts:400, warning$ieqis deliberately deferred until there is demonstrated pull for it"plugin-authauth-route-ledger.ts:146, change-email noteplugin-authauth-route-ledger.ts:157, delete-user noteplugin-authauth-route-ledger.ts:234, import-users noteplugin-authauth-route-ledger.ts:236,:237, SSO register notesplugin-authauth-route-ledger.ts:254, add-member noteauth.api.addMember)plugin-authlast-admin-guard.ts:795, standing-key exclusion reasonplugin-authlast-admin-guard.ts:840, standing-key exclusion reasonplugin-webhooksauto-enqueuer.ts:517, errorplugin-webhooksauto-enqueuer.ts:833, warningplugin-webhookswebhook-outbox-plugin.ts:343, errorplugin-webhooksbootstrap-declared-webhooks.ts:266, warningplugin-webhooksmigrate-webhook-secrets.ts:134,:135, warningsdefinition_jsoninto encrypted columns)plugin-authtwo-factor-reenrollment-verified-reset.ts:130,:149,:170, error linesverifiedso the new secret is inert until confirmed)plugin-authmember-role-canonical.ts:259(debug) and:473(warning)Citation only (the sentence already stated the decision)
plugin-auth:adopt-membership.ts:246(7725, "adopted the existing sys_member row instead of inserting a second one ... unique by declaration");auth-manager.ts:2837(3585, "will now 500 every /get-session instead of degrading to a missing set-auth-jwt header");auth-plugin.ts:507,:511(2780, 4790, the budget's name and its per-node impact);last-admin-guard.ts:1215(6084, "the state a DELETED 'admin_full_access' permission-set row leaves behind: it un-makes every platform admin at once");member-role-canonical.ts:463,:484(8317);objectql-adapter.ts:492(5813, "refusing the query rather than dropping the predicate");otp-send-guard.ts:174(4808, "bounded rather than silently truncated");sso-client-secret.ts:339(8009, now naming the move out of cleartextoidc_config).plugin-webhooks:auto-enqueuer.ts:543,:764(8022, "re-arms on registration and at the next periodic refresh"),:742(the say-once repeat line),:756,:759(7799 or 7986, 8069);webhook-headers-gate.ts:155(7986, 8558, 8566, "checked at the write door because one step later there is nothing left to check");webhook-headers.ts:253,:324,:335(7986, 8558);webhook-secret.ts:291,:301(7799, 8542, "this is NOT an unsigned webhook, and delivering it unsigned would strip the receiver of its only proof of origin").service-messaging:http-delivery.object.ts:176(8118, "never returned on the generic data path ... recovers it through the engine's privileged accessor") and:260(8069);http-outbox.ts:573(8069);sql-http-outbox.ts:327(8118);outbox.ts:210(11453, 11859).Every cited card was read (REST, open or closed) before its string was rewritten. Two answer 404 on the issue itself, 11453 and 11859, and were read through their comment threads, which carry the scope ruling and the decision analysis.
Translations
attemptshelp: thees-ES,ja-JPandzh-CNleaves were real translations; each now carries the same decision ("porque no lleva firma", "署名を持たないため", "因不带签名") and no number.headers_jsonanderrorhelp: in all three locales these leaves were byte copies of the English source. They are now copies of the revised English, andnode scripts/check-i18n-bundles.mjs --write --filter=service-messagingrecorded their new digests in the three*.source-hashes.generated.tscompanions. No digest was hand-edited; theenbundle was already byte-identical to what the extractor writes.Ledger (
scripts/doc-authoring-prose-id.baseline.json)Recomputed with
node scripts/check-doc-authoring.mjs --census-ledger(exit 0, no growth refusal) into a scratch file, then copied into place. The diff deletes 113 lines and adds none: exactly the 29 file blocks of the three packages. Every other row is byte-identical (a scripted comparison of every other key: 0 moved).5e5ce48c)plugin-authplugin-webhooksservice-messagingpnpm check:doc-authoringat the head: "393 pinned site(s) across 118 file(s), 85833 string(s) read in 1245 parsed source(s), no growth, no burn-down unrecorded" (before: 463 sites across 147 files). No gate is added or loosened;scripts/check-doc-authoring.mjsis untouched.Changeset
.changeset/20751-services-strings-state-the-decision.md:patchfor@objectstack/plugin-auth,@objectstack/plugin-webhooksand@objectstack/service-messaging. Measured after building the three packages at the head: each new author-visible sentence named above is in its package'sdist/index.jsanddist/index.cjs(2 files each). A TypeScript scan of every string literal and template in the three packages' built.js/.cjsfinds 0 tracker ids (the ids left indistare in comments). Control: the same scan reads 86 inplugin-security's built output and 66 inservice-automation's. The auth route ledger does not ship:AUTH_ROUTE_LEDGERis in 0 files underpackages/plugins/plugin-auth/dist.Text-only proof
A TypeScript-AST skeleton of each changed non-test
.tsfile, 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), and comments and JSDoc are never read.5e5ce48cagainst the head0bb7a64f: 31 of 32 SAME, token counts identical per file. The one DIFF isauto-enqueuer.ts, and it is exactly the citations-as-data: the module-privateDropReasoninterface loses itsissueandissuesmembers, the two credential constants lose those two properties, and three interpolations (credential.issuetwice,credential.issuesonce) leave three templates. Nothing else in the file's skeleton moves. Control: the first draft of the tool compared only each file's first statement and reportedauto-enqueuer.tsSAME; that miss is what exposed it, and the corrected tool reports the DIFF above.Pins
Three assertions named the old strings and now name the new substance:
auth-plugin.test.ts:1706:per-number OTP send budget bound to the kernel cache service.last-admin-guard.test.ts:1905,:1908:toThrow(/state a DELETED 'admin_full_access' permission-set row leaves behind/)instead of the bare citation. The sibling test still assertscode: 'PERMISSION_DENIED',status: 403on the same refusal.scim-case-insensitive-identifier.test.ts:357:`$ieq` is deliberately deferred until there is demonstrated pullinstead of the citation.Every other old fragment was searched repo-wide. The remaining hits are comments, test titles and assertion labels, and two test files (
rate-limit-storage.test.ts,otp-send-guard.test.ts) that pass their OWN subject string into the counter store and assert it back; none reads production text. Nocodeorstatusassertion was touched.Tests
All at head
0bb7a64f, throughscripts/pm/os-verify-lock.sh, every verdictVERDICT command-exit 0:turbo run buildover the closure of the three packages and@objectstack/cli(59/59 tasks), then the three packages rebuilt at the head, thenturbo run build --filter=./packages/* --filter=./packages/*/*(71/71).@objectstack/plugin-auth: 116 files, 2484 tests passed.@objectstack/plugin-webhooks: 13 files, 160 tests passed.@objectstack/service-messaging: 46 files, 507 tests passed.typecheckfor all three, includingcheck:test-typecheck: OKforplugin-authandplugin-webhooks.Gates
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands(no paths) at0bb7a64f: 75 commands, run one at a time from the worktree, each exit code recorded before any pipe.--ran: "75 derived famil(ies) accounted for — 75 run, 0 NOT-MEASURED (a DERIVED zero — all 75 recorded an exit code and none of them is 3)".check:dual-build-cjs-loadsfirst answeredPREREQUISITE NOT MET(exit 3: only the closure was built). After the full package build it and the other dist-reading gates were re-run, all exit 0: 105 require entry points across 66 packages load;check:dts-closure71 built packages, 167/167 declaration files;check:sourcemap-no-sources-content68 packages, 522 maps;check:lean-entry-closureandcheck:published-filesgreen.check:i18n: "all bundles in sync";check:i18n-stale-fill: "0 stale-fill leaf/leaves";check:issue-citations: "no issue citations added against 5e5ce48 (32 file(s) read)";check:nul-bytes: OK, 9850 files;check:type-check-debt: "none above its recorded number".check:init-service-contract,check:live-db-isolation,check:meta-type-normalized,check:optional-error-sink,check:resume-authority-declared,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-mirrorsand 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). The path-scheduled CI jobs and the type-check lanes are CI's.pnpm lint(eslint . --no-inline-config, repo-wide, not narrowed) at0bb7a64f: exit 0, 101 s under the lock.Acceptance notes
origin/mainmoved to862f12c0(four commits) after the branch point. None touches any of this PR's 37 paths, and none adds or removes an id-bearing line in a non-test source underpackages/, so the recomputed ledger stands on the merged tree. The branch was not merged withmain; the queue rebuilds it there.docs/qa/platform-checklist/areas/integration-system.json:572cites 7799 and 8069 in its own clause prose; it quotes none of the text changed here.Generated by Claude Code