From 05a2e923258e96fe788f18c31f1aba8735513ff2 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 19 Sep 2026 08:21:59 +0000 Subject: [PATCH] fix(qa-checklist): drain nine bad-citation residual rows by re-pointing route-ledger anchors First slice of the SHARED_RESOLVER_RESIDUAL drain. Nine `bad-citation` rows across three area files are repaired at the citation, not at the resolver: each anchor named a client-method name, a route path parameter or an imported class, none of which is a declaration site in the cited file. Every one is re-pointed at the declaration the item actually means -- the route table the file exports, or the host plugin list -- following the convention this corpus already uses for `auth-route-ledger.ts#AUTH_ROUTE_LEDGER`. No `#symbol` is dropped, so the floor population is byte-identical: the anchor census prints the same per-file counts before and after, with ten occurrences moving from `residual` to `resolved` (577/633 -> 587/633). The ledger's ceiling comes down with the rows, 55 -> 46, and the shape and verdict tallies in its header are re-counted in the same edit. Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk Co-authored-by: Claude --- .../areas/access-security.json | 4 +-- .../platform-checklist/areas/api-backend.json | 8 ++--- .../platform-checklist/areas/automation.json | 8 ++--- scripts/check-platform-checklist.mjs | 34 ++++++++++++------- 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/docs/qa/platform-checklist/areas/access-security.json b/docs/qa/platform-checklist/areas/access-security.json index 6b4219c7448..717400791d0 100644 --- a/docs/qa/platform-checklist/areas/access-security.json +++ b/docs/qa/platform-checklist/areas/access-security.json @@ -1110,7 +1110,7 @@ "wrong-persona" ], "source": [ - "packages/rest/src/rest-route-ledger.ts#shareId (record-shares family: GET/POST /data/:object/:id/shares, DELETE .../:shareId; sharing-rules family evaluate)", + "packages/rest/src/rest-route-ledger.ts#REST_ROUTE_LEDGER (record-shares family: GET/POST /data/:object/:id/shares, DELETE .../:shareId; sharing-rules family evaluate — re-pointed #18104: shareId is a route PATH PARAMETER, carried in this file only inside a route string)", "packages/rest/src/rest-server.ts#registerSharingRuleEndpoints (the evaluate leg; the record-shares family GET/POST /data/:object/:id/shares + DELETE .../:shareId is registered inline, under no registrar of its own — #13788 measured that the registerRecordShareEndpoints this citation used to name is not in the file)", "packages/plugins/plugin-sharing/src/objects/sys-record-share.object.ts#recipient_type (recipient_type/recipient_id/access_level/source fields)", "packages/plugins/plugin-sharing/src/sharing-rule-service.ts#evaluateRule (evaluateRule → SharingRuleEvaluationResult)", @@ -1860,7 +1860,7 @@ "source": [ "objectui packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx (type=permission editor; client.save → PUT /api/v1/meta/permission/; object CRUD+VAMA+lifecycle + field R/W)", "packages/spec/src/security/permission.zod.ts#PermissionSetSchema (PermissionSetSchema)", - "packages/rest/src/rest-route-ledger.ts#saveItem (PUT /api/v1/meta/:type/:name saveItem; POST .../publish publishItem)", + "packages/rest/src/rest-route-ledger.ts#REST_ROUTE_LEDGER (PUT /api/v1/meta/:type/:name saveItem; POST .../publish publishItem — re-pointed #18104: saveItem is a CLIENT METHOD name, carried in this file only inside a string value)", "examples/app-showcase/src/security/permission-sets.ts", "cross-ref access-security.crud-permission-matrix + access-security.readonly-package-locks-studio, ADR-0090 D1/D5, ADR-0033" ], diff --git a/docs/qa/platform-checklist/areas/api-backend.json b/docs/qa/platform-checklist/areas/api-backend.json index 637461ecccb..64486cd5022 100644 --- a/docs/qa/platform-checklist/areas/api-backend.json +++ b/docs/qa/platform-checklist/areas/api-backend.json @@ -797,16 +797,16 @@ "absence-inference" ], "source": [ - "packages/rest/src/rest-route-ledger.ts#REST (variant source — the 19 REST families)", + "packages/rest/src/rest-route-ledger.ts#REST_ROUTE_LEDGER (variant source — the 19 REST families — re-pointed #18104: the bare word REST is carried in this file only as a substring of longer tokens)", "packages/rest/src/rest-route-ledger.conformance.test.ts", - "packages/runtime/src/route-ledger.ts#getLegalNextStates (dispatcher ledger — share-links/keys/notifications/suggested-bindings/i18n/analytics families + the meta.getLegalNextStates state route)", + "packages/runtime/src/route-ledger.ts#ROUTE_LEDGER (dispatcher ledger — share-links/keys/notifications/suggested-bindings/i18n/analytics families + the meta.getLegalNextStates state route — re-pointed #18104: getLegalNextStates is a CLIENT METHOD name, carried here only inside a dotted string value)", "packages/plugins/plugin-auth/src/auth-route-ledger.ts#AUTH_ROUTE_LEDGER (AUTH_ROUTE_LEDGER — the enumerated better-auth table, #3656; raw-app mount)", "packages/services/service-storage/src/storage-route-ledger.ts + packages/services/service-i18n/src/i18n-route-ledger.ts (tranche-3 per-service ledgers, #3636)", "packages/services/service-settings/src/settings-route-ledger.ts (#7526 — the /api/settings family, ledgered; guarded by the parity dogfood gate, no per-package test by design)", "packages/services/service-datasource/src/datasource-route-ledger.ts + datasource-route-ledger.conformance.test.ts (#7744 — the admin family, ledgered)", "packages/services/service-datasource/src/admin-routes.ts#manage_platform_settings (the #9391/#9593 manage_platform_settings floor on all eleven routes, drivers catalog included)", "packages/metadata/src/metadata-route-ledger.ts (metadata HMR — raw-app mount, dev-only posture #12140/#5673)", - "packages/triggers/trigger-api/src/trigger-api-route-ledger.ts#flowName (#11863 — POST /api/v1/automation/hooks/:flowName/:hookId, raw-app mount)", + "packages/triggers/trigger-api/src/trigger-api-route-ledger.ts#TRIGGER_API_ROUTE_LEDGER (#11863 — POST /api/v1/automation/hooks/:flowName/:hookId, raw-app mount — re-pointed #18104: flowName is a route PATH PARAMETER, carried here only inside the route string)", "packages/cloud-connection/src/cloud-connection-route-ledger.ts (#11882 — 16 rows / four registrar families, raw-app mounts unfindable by the parity gate by construction)", "packages/cli/src/utils/console-route-ledger.ts (#11882 — the four static-asset rows)", "packages/qa/dogfood/test/route-ledger-live-mount-parity.dogfood.test.ts#getMountedRoutes (#7526 — the parity gate whose getMountedRoutes() blind spot the raw-app clause covers)", @@ -1080,7 +1080,7 @@ "source": [ "objectui apps/console/src/pages/developer/ApiConsolePage.tsx (the API console: raw fetch to `${client.baseUrl}${url}`, status/duration/JSON pane, request history)", "objectui apps/console/src/pages/developer/hooks/useApiDiscovery.ts (tree built from GET /api/v1/discovery services/routes + client.meta types/objects; isServiceUsable gate per ADR-0076 D12)", - "packages/rest/src/rest-route-ledger.ts#REST (the REST families the tree is spot-checked against)", + "packages/rest/src/rest-route-ledger.ts#REST_ROUTE_LEDGER (the REST families the tree is spot-checked against — re-pointed #18104: the bare word REST is carried in this file only as a substring of longer tokens)", "packages/spec/src/api/discovery.zod.ts (the discovery payload)" ], "history": [ diff --git a/docs/qa/platform-checklist/areas/automation.json b/docs/qa/platform-checklist/areas/automation.json index 23a4deadb01..27f5fd02032 100644 --- a/docs/qa/platform-checklist/areas/automation.json +++ b/docs/qa/platform-checklist/areas/automation.json @@ -809,7 +809,7 @@ "objectui packages/app-shell/src/views/FlowRunner.tsx (onClose = dismiss without POSTing resume; the durable suspension is untouched, so the paused run stays resumable)", "examples/app-showcase/src/automation/flows/index.ts#ReassignWizardFlow (ReassignWizardFlow)", "packages/services/service-automation/src/builtin/screen-resume-validation.test.ts + src/screen-input-contract.ts (400 on missing required inputs)", - "packages/runtime/src/route-ledger.ts#getScreen (resume + getScreen routes)" + "packages/runtime/src/route-ledger.ts#ROUTE_LEDGER (resume + getScreen routes — re-pointed #18104: getScreen is a CLIENT METHOD name, carried here only inside a dotted string value)" ], "history": [ { @@ -991,7 +991,7 @@ ], "source": [ "examples/app-showcase/src/automation/flows/index.ts#TaskCompletedRestPingFlow (TaskCompletedRestPingFlow, ShowcaseDeclarativeConnectorPingFlow, ShowcaseMcpConnectorEchoFlow)", - "examples/app-showcase/objectstack.config.ts#ConnectorRestPlugin (ConnectorRestPlugin/ConnectorSlackPlugin/ConnectorMcpPlugin + declarative connectors)", + "examples/app-showcase/objectstack.config.ts#plugins (ConnectorRestPlugin/ConnectorSlackPlugin/ConnectorMcpPlugin + declarative connectors — re-pointed #18104: the three plugin classes are IMPORTED here and declared in their own packages; the host declaration this item is about is the plugins list itself)", "packages/runtime/src/route-ledger.ts (GET /automation/connectors)", "ADR-0097 (provider-bound declarative connector instances)" ], @@ -1085,7 +1085,7 @@ "objectui apps/console/src/pages/developer/FlowRunsPage.tsx (FlowTestRunner + inline FlowRunsPanel; framework#3528 — hands a paused screen run to FlowRunner so it no longer orphans a paused row)", "objectui packages/app-shell/src/views/FlowRunner.tsx (the shared screen runner reused here)", "objectui apps/console/src/AppContent.tsx (Route path 'developer/flow-runs') + registerDeveloperComponents.tsx (ref 'developer:flow-runs')", - "packages/runtime/src/route-ledger.ts#runId (POST /automation/:name/trigger, GET /automation/:name/runs, POST /automation/:name/runs/:runId/resume)", + "packages/runtime/src/route-ledger.ts#ROUTE_LEDGER (POST /automation/:name/trigger, GET /automation/:name/runs, POST /automation/:name/runs/:runId/resume — re-pointed #18104: runId is a route PATH PARAMETER, carried here only inside the route string)", "examples/app-showcase/src/automation/flows/index.ts#BatchRemindersFlow (BatchRemindersFlow tasks input, ReassignWizardFlow screen)" ], "history": [ @@ -1161,7 +1161,7 @@ "dispatcher-vs-hono-route" ], "source": [ - "packages/runtime/src/route-ledger.ts#getRuntimeStatus (POST /automation/:name/toggle → automation.toggle; GET /automation/_status → automation.getRuntimeStatus)", + "packages/runtime/src/route-ledger.ts#ROUTE_LEDGER (POST /automation/:name/toggle → automation.toggle; GET /automation/_status → automation.getRuntimeStatus — re-pointed #18104: getRuntimeStatus is a CLIENT METHOD name, carried here only inside a dotted string value)", "packages/services/service-automation/src/engine.ts#toggleFlow (toggleFlow — writes the sys_metadata_activation row FIRST, then updates the flowLedgerDisabled projection and activateFlowTrigger/deactivateFlowTrigger; the process-local flowEnabled map this item originally cited is RETIRED by ADR-0126 §7.2) + (flowLedgerDisabled is a projection of the ledger, not the old map under a new name) + getFlowRuntimeStates enabled/bound", "docs/adr/0126-packaged-metadata-customization-model.md §7.2 (the durable ledger row replaces the process-local flowEnabled map as the sanctioned off-switch)", "examples/app-showcase/src/automation/flows/index.ts#UrgentTaskAlertFlow (UrgentTaskAlertFlow — the record_change flow, #3427)", diff --git a/scripts/check-platform-checklist.mjs b/scripts/check-platform-checklist.mjs index e1f4d4af103..b52b00f365d 100644 --- a/scripts/check-platform-checklist.mjs +++ b/scripts/check-platform-checklist.mjs @@ -1867,9 +1867,9 @@ const CORPUS = defineCorpus({ // string-substring the symbol survives only INSIDE a longer string token: // `saveItem` in `client: 'meta.saveItem'`, `:shareId` in a // route pattern, a name inside an `it(...)` title or a -// `.describe(...)` sentence. 29 rows, the largest class. +// `.describe(...)` sentence. 21 rows, the largest class. // import-only the cited file IMPORTS the symbol; the declaration is in -// another file. 9 rows. +// another file. 8 rows. // member-access the symbol survives only as `x.symbol` on some other // object — `manifest.objectExtensions`. 3 rows. // json-value-not-key the `.json` target carries the symbol as a VALUE; the @@ -1884,10 +1884,27 @@ const CORPUS = defineCorpus({ // 1 row — the sharpest single illustration of what a // looser second resolver buys. // +// ⭐ THE DRAIN (#18104). The `bad-citation` half is a population with an owner, +// and it leaves this ledger ONE WAY: the citation is re-pointed at what the +// cited file actually declares, the row goes, and the ceiling below comes down +// by the same number in the same edit. ⛔ Never by raising the ceiling, ⛔ never +// by widening `scripts/symbol-anchors.mjs`, ⛔ never by lowering a file floor — +// a repair moves an anchor from `residual` to `resolved` and leaves the floor +// population untouched, which is why draining costs no floor headroom at all. +// +// ⚠️ The binding measurement above (56 of 633, at #16898) is a DATED READING of +// the tree it was taken against and is left standing as one. It is not this +// ledger's current size: the drain lands per area file, so read the live count +// off `SHARED_RESOLVER_RESIDUAL.length` and the console line, never off that +// paragraph. First slice landed (#18104): `areas/access-security.json`, +// `areas/api-backend.json` and `areas/automation.json` — 9 rows, all of them +// citations naming a route table's client-method names or route path +// parameters where the declaration the item means is the ledger export itself. +// // `verdict` is the classification #16898's acceptance asks for, and there are // exactly two: // -// bad-citation (47 rows) the anchor names a symbol the cited file does not +// bad-citation (38 rows) the anchor names a symbol the cited file does not // declare. The repair is in the LEDGER: re-point the anchor at // what the file carries, or drop to a bare citation. ⚠️ Dropping // costs the file an anchor and most floors have no headroom, so @@ -1902,19 +1919,10 @@ const CORPUS = defineCorpus({ // the core to reach them: it is shared with four other corpora // and widening it would export this defect to all of them. const SHARED_RESOLVER_RESIDUAL = Object.freeze([ - { doc: 'areas/access-security.json', anchor: 'packages/rest/src/rest-route-ledger.ts#saveItem', shape: 'string-substring', verdict: 'bad-citation' }, - { doc: 'areas/access-security.json', anchor: 'packages/rest/src/rest-route-ledger.ts#shareId', shape: 'string-substring', verdict: 'bad-citation' }, { doc: 'areas/ai.json', anchor: 'packages/mcp/src/plugin.ts#OS_MCP_SERVER_ENABLED', shape: 'string-substring', verdict: 'bad-citation' }, { doc: 'areas/ai.json', anchor: 'packages/runtime/src/domains/ai.ts#capabilityUnavailable', shape: 'import-only', verdict: 'bad-citation' }, - { doc: 'areas/api-backend.json', anchor: 'packages/rest/src/rest-route-ledger.ts#REST', shape: 'string-substring', verdict: 'bad-citation' }, - { doc: 'areas/api-backend.json', anchor: 'packages/runtime/src/route-ledger.ts#getLegalNextStates', shape: 'string-substring', verdict: 'bad-citation' }, - { doc: 'areas/api-backend.json', anchor: 'packages/triggers/trigger-api/src/trigger-api-route-ledger.ts#flowName', shape: 'string-substring', verdict: 'bad-citation' }, { doc: 'areas/approvals.json', anchor: 'examples/app-showcase/src/security/seed-approval-demo.ts#AUDITOR_DEMO_USER', shape: 'import-only', verdict: 'bad-citation' }, { doc: 'areas/attachments-storage.json', anchor: 'packages/spec/liveness/field.json#live', shape: 'json-value-not-key', verdict: 'bad-citation' }, - { doc: 'areas/automation.json', anchor: 'examples/app-showcase/objectstack.config.ts#ConnectorRestPlugin', shape: 'import-only', verdict: 'bad-citation' }, - { doc: 'areas/automation.json', anchor: 'packages/runtime/src/route-ledger.ts#getRuntimeStatus', shape: 'string-substring', verdict: 'bad-citation' }, - { doc: 'areas/automation.json', anchor: 'packages/runtime/src/route-ledger.ts#getScreen', shape: 'string-substring', verdict: 'bad-citation' }, - { doc: 'areas/automation.json', anchor: 'packages/runtime/src/route-ledger.ts#runId', shape: 'string-substring', verdict: 'bad-citation' }, { doc: 'areas/cli.json', anchor: 'packages/cli/src/commands/compile.ts#emitJson', shape: 'import-only', verdict: 'bad-citation' }, { doc: 'areas/cli.json', anchor: 'packages/cli/src/commands/doctor-deprecation-hint-commands.test.ts#Doctor', shape: 'import-only', verdict: 'bad-citation' }, { doc: 'areas/cli.json', anchor: 'packages/cli/src/utils/format.exit-code.test.ts#emitJson', shape: 'import-only', verdict: 'bad-citation' }, @@ -1963,7 +1971,7 @@ const SHARED_RESOLVER_RESIDUAL = Object.freeze([ // fail), so this is the belt on the braces: a silent append — the one edit that // would turn a closed ledger back into a permissive rule, one row at a time — // refuses here rather than validating. -const SHARED_RESOLVER_RESIDUAL_CEILING = 55; +const SHARED_RESOLVER_RESIDUAL_CEILING = 46; const residualKey = (doc, anchor) => `${doc}::${anchor}`; const SHARED_RESOLVER_RESIDUAL_INDEX = new Map(