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
Commit 1979df0
Browse filesBrowse the repository at this point in the historyBrowse files
docs(qa): re-point the eight accept-set checklist anchors at their enclosing declarations (#20999)
Fixes#18101
Clause-②: no
Ruling-ref: 5748968793
## What this does
The shared symbol-anchor resolver refuses eight platform-checklist
anchors that name real sites: six are object-literal keys written INLINE
in config, seed, datasource and action literals, and two are data
identifiers (`sys_user`, `sys_invitation`) that appear only as the HEAD
of dotted action names. Under the ruling on the card (letter C), the
shared core in `scripts/symbol-anchors.mjs` is **not** widened, and no
citation is dropped to a bare one. Each anchor now points at the nearest
enclosing declaration the resolver does read, so every pointer stays
checkable. The eight `accept-set` rows leave `SHARED_RESOLVER_RESIDUAL`
by repair.
`scripts/symbol-anchors.mjs` is untouched; `git diff 05be352 --
scripts/symbol-anchors.mjs` is empty.
## The eight rows
How I picked each one: the first segment is always the top-level
declaration that encloses the literal. I add a member segment only when
the cited sentence names that member itself (the `admin` /
`organization` feature entries, the `parent` field). The config file is
the one exception. Its default export is an anonymous `defineStack(...)`
call, so its nearest enclosing declaration that resolves is the
`plugins` key. Each re-pointed value also gets a `re-pointed #18101:
...` note saying why, following the trace the `bad-citation` drain cuts
used.
| area file | old anchor | new anchor | why this declaration encloses
the cited site |
|---|---|---|---|
| `dashboards.json` |
`examples/app-showcase/src/data/seed/index.ts#signed_on` |
`...#accounts` | `signed_on` is set inline in each account seed row.
`const accounts = defineSeed(Account, ...)` declares those rows. |
| `dashboards.json` |
`examples/app-showcase/src/data/seed/index.ts#sales_region` |
`...#accounts` | Same rows: `sales_region` and `signed_on` are both
inline keys of the records in the `accounts` seed constant. |
| `identity-auth.json` |
`packages/spec/src/kernel/public-auth-features.ts#sys_invitation` |
`...#PUBLIC_AUTH_FEATURES.organization` | The three
`sys_invitation.actions.*` tokens all sit in
`PUBLIC_AUTH_FEATURES.organization.gatedInputs`. The sentence is about
the organization feature. |
| `identity-auth.json` |
`packages/spec/src/kernel/public-auth-features.ts#sys_user` |
`...#PUBLIC_AUTH_FEATURES.admin` | The `sys_user` lifecycle action
tokens (create / ban / unban / unlock / set password / impersonate) sit
in `PUBLIC_AUTH_FEATURES.admin.gatedInputs`. The sentence is about the
admin flag. |
| `integration-system.json` |
`examples/app-showcase/objectstack.config.ts#declarativeStdio` |
`...#plugins` | `declarativeStdio` is inline in `new
ConnectorMcpPlugin({ ... })`, an element of the `plugins:` array. The
config is an anonymous `export default defineStack(...)`, and
`defineStack` / `ConnectorMcpPlugin` are imports, which do not resolve.
`plugins` is the nearest enclosing key the resolver reads. |
| `integration-system.json` |
`examples/app-showcase/src/system/datasources/showcase-external.datasource.ts#onMismatch`
| `...#ShowcaseExternalDatasource` | `onMismatch` is inline in
`external.validation`. `export const ShowcaseExternalDatasource =
defineDatasource(...)` is the datasource constant that holds it, and the
file's only declaration. |
| `records-forms.json` |
`examples/app-showcase/src/ui/actions/index.ts#maxSize` |
`...#ActionParamGalleryAction` | Both `maxSize` sites (the `p_cover` and
`p_attachments` params) are inline in the `params` of `export const
ActionParamGalleryAction`. No other action in the file sets `maxSize`. |
| `records-forms.json` |
`examples/app-showcase/src/data/objects/business-unit.object.ts#allowCreate`
| `...#BusinessUnit.parent` | `allowCreate: true` is inline in the
options of the `parent: Field.lookup(...)` field of `export const
BusinessUnit`. The sentence is "parent allowCreate:true". |
I probed every new anchor through `symbolSegmentResolution` before
editing (every segment `declaration`, none `literal`), then confirmed it
with the gate run below.
## The ceiling: 18 → 10
At `origin/main` `05be35259` the ceiling is already 18, not the 55 the
ruling quotes; the `bad-citation` drain lowered it after the ruling was
written. The ledger's own drain contract says: "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". So removing 8 rows takes
`SHARED_RESOLVER_RESIDUAL_CEILING` from 18 to 10, and rows == ceiling
again. That matches the ruling's intent (the ledger is shrink-only).
Only the number 55 has moved since then.
I also updated the ledger prose that this change made false:
- the second- and third-slice notes said these files "still carry" their
`accept-set` rows;
- the `accept-set` verdict description said the rows were "a different
card, against the shared core".
The `accept-set` verdict stays in the closed two-verdict vocabulary with
**0 rows**. The shape it names still exists; the ruling only decided how
such a row is repaired. I added a short drain paragraph that records the
ruling.
## Verification (at `9919256b81`)
`pnpm check:platform-checklist` is red on `main` because of ONE
unrelated row: `areas/identity-auth.json` →
`packages/plugins/plugin-auth/src/auth-plugin.ts#twoFactor`, already
filed as #20464. That row is not touched here and stays red. The proof
for this PR is that this one problem stays, no new one appears, and the
eight residual rows are gone.
| reading | before (`05be35259`) | after (`9919256b81`) |
|---|---|---|
| `pnpm check:platform-checklist` | exit 1, `1 problem(s)`: the #20464
`twoFactor` row | exit 1, `1 problem(s)`: the same #20464 `twoFactor`
row, nothing else |
| `--anchor-census` resolved | 628/647 | 636/647 |
| on the named residual | 18 | 10 |
| per-file floor population (resolved + residual) | dashboards 22 ·
identity-auth 82 · integration-system 57 · records-forms 84 | identical
(census JSON byte-equal), so no floor moves and none was touched |
| `node scripts/check-platform-checklist.mjs --self-test` | 221
assertions, exit 0 | 221 assertions, exit 0 |
Intermediate reading: I ran the gate with the anchors already re-pointed
and the ledger not yet edited. It printed exactly 8 `STALE RESIDUAL ROW`
reds, one per row, plus the #20464 row, and no `ABSENT SYMBOL` for any
new anchor. That shows the gate really reads the eight re-pointed
citations, and that each one resolves.
One-shot mutation (run from the committed state, through
`scripts/ablation-replace.mjs`, restore verified): I changed the
re-pointed `#accounts` in `areas/dashboards.json` to `#accountz`. The
gate printed `ABSENT SYMBOL —
examples/app-showcase/src/data/seed/index.ts#accountz` and `SYMBOL
ANCHORS LOST — 21 anchor(s) resolve here but the floor is 22`, alongside
the #20464 row. After the run the file blob equals HEAD (`85e8f6f4a702`)
and `git diff HEAD` is empty. So a re-pointed anchor is still checked
both ways: by the resolver, and by the per-file floor. No test file was
added for this.
Every gate `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands` derives for this diff (32
commands, change set from merge base `05be35259`), run at `9919256b81`.
`--ran` reconciles them as `32 derived, 32 run, 0 NOT-MEASURED, 0 UNRUN`
(every line exit-coded):
- **exit 0 (30 commands):** `check-ci-filter-parity`,
`check-closing-keyword-parity` (+ `--self-test`),
`check-comment-mask-corpus`, `check-declaration-mirrors` (+
`--self-test`), `check-scripts-symbol-anchors` (+ `--self-test`; this
corpus reads the new comment prose in the gate script),
`check-self-test-wired` (+ `--self-test`),
`check-self-test-workflow-commands` (+ `--self-test`),
`check-whole-set-label-write` (+ `--self-test`), `pm/bare-root-worklist
--self-test`, and `pnpm check:` `agent-test-spelling` · `bash32-floor` ·
`cli-command-ids` · `cross-package-test-inputs` · `doc-authoring` ·
`driver-memory-census` · `entry-guard` · `gitlink-declared` ·
`nul-bytes` · `parse-guard` · `pnpm-filter-targets` ·
`ratchet-remedy-authority` · `refd-timer-probe` · `watch-hint-literal`.
- **exit 0, re-run (2 commands):**
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions`
first exited 3 with PREREQUISITE NOT MET: `@objectstack/formula` and
`@objectstack/lint` had no `dist/`, so nothing was measured. I built
both under the verify lock and re-ran it: exit 0.
- `pnpm check:pm-dispatch-gates`: my batch runner's time cap killed the
first attempt. I ran it alone to completion: exit 0, `dispatch-gates
self-test: 1976 cases pass`, battery 912.6 s on this shared box.
- **exit 1 (1 command):** `pnpm check:platform-checklist`, on the one
#20464 row only, as shown above.
## Changeset
None needed. `docs/qa/**` and the root `scripts/` directory sit outside
every package directory, and the root package is `private`. Across 81
tracked `package.json` files, no non-private package's `files[]` names
either path. ⇒ `skip-changeset`.
## Acceptance notes
- The `shape` legend in the ledger header still gives the per-shape
counts from when the binding was made ("string-substring … 12 rows",
"import-only … 6 rows", …). The 10 live rows are 5 / 3 / 2. These are
old dated readings and not a defect. I did not touch them here because
they are outside this card's 8 rows. Nobody is carrying this.
- Self-test `D4` still reads "the `accept-set` rows are the minority and
are named as a DIFFERENT card". It holds numerically (zero `accept-set`
rows against ten `bad-citation` rows), but the label is out of date
after the ruling. I kept the change to the surface the ruling names, so
the label is not edited here.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JAhu8u8QfBvRjVZDox7CP9)_
Co-authored-by: Claude <noreply@anthropic.com>
"examples/app-showcase/src/ui/dashboards/ops-dashboard.dashboard.ts#dateRange (dateRange + global filter levers)",
639
-
"examples/app-showcase/src/data/seed/index.ts#signed_on (prospects carry no signed_on — the deliberate NULL population)"
639
+
"examples/app-showcase/src/data/seed/index.ts#accounts (prospects carry no signed_on — the deliberate NULL population; re-pointed #18101: signed_on is a key written INLINE in each seed row, which the shared resolver does not read as a declaration, and accounts is the seed constant that declares those rows)"
"examples/app-showcase/src/data/seed/index.ts#sales_region (sales_region + signed_on seeding, prospects unset by design)",
752
+
"examples/app-showcase/src/data/seed/index.ts#accounts (sales_region + signed_on seeding, prospects unset by design — re-pointed #18101: both keys are written INLINE in each seed row, which the shared resolver does not read as a declaration, and accounts is the seed constant that declares those rows)",
"objectui packages/plugin-dashboard/src/DashboardFilterBar.tsx (isDirty→Reset affordance RotateCcw, data-testid dashboard-filter-bar; SelectFilter {value,label} options + server GROUP BY via queryDataset, #2578 item 5)",
"packages/rest/src/rest-route-ledger.ts#REST_ROUTE_LEDGER (GET /api/v1/security/my-delegable-scope — security.describeDelegableScope, ADR-0090 D12 / ADR-0105 D8, self-scoped read half of the delegated-admin gate — re-pointed #18104: describeDelegableScope is a CLIENT METHOD name, carried in this file only inside a string value)",
360
360
"packages/spec/src/contracts/security-service.ts#DelegableScope (DelegableScope: isTenantAdmin, scopes, placeableBusinessUnitIds, assignablePositions — no invitation-role field, which is why the scope read cannot be the invite picker's allowlist)",
"packages/spec/src/kernel/public-auth-features.ts#PUBLIC_AUTH_FEATURES.organization (organization feature gates sys_invitation invite/cancel/resend actions — re-pointed #18101: sys_invitation is carried in this file only as the HEAD of dotted action names, never as a complete quoted token, and the organization entry of PUBLIC_AUTH_FEATURES is the declaration that holds them)"
362
362
],
363
363
"history": [
364
364
{ "revision": 1, "date": "2026-08-07", "change": "new item: invitation scope gates and lifecycle, pinned to the delegated-admin-invite dogfood test", "ref": "claude/platform-test-checklist-ocwugl" },
"packages/plugins/plugin-security/src/security-plugin.ts#SecurityPlugin (§A5 #3023 EXEMPTION: __referentialFieldClear owner_id-null cascade rides a server-derived context, the owner-anchor guard must not veto it — re-pointed #18104: __referentialFieldClear is a CONTEXT KEY this file only reads off opCtx.context, a member access; the guard that honours it is in the SecurityPlugin class this file declares) + security-plugin.test.ts '[#3023] … engine referential FK clear … is exempt'",
482
-
"packages/spec/src/kernel/public-auth-features.ts#sys_user (admin flag gates the sys_user lifecycle actions; SCIM forces it on — ADR-0134)",
482
+
"packages/spec/src/kernel/public-auth-features.ts#PUBLIC_AUTH_FEATURES.admin (admin flag gates the sys_user lifecycle actions; SCIM forces it on — ADR-0134; re-pointed #18101: sys_user is carried in this file only as the HEAD of dotted action names, never as a complete quoted token, and the admin entry of PUBLIC_AUTH_FEATURES is the declaration that holds the lifecycle ones)",
"packages/plugins/plugin-auth/src/anonymous-session-refusal.ts#ANONYMOUS_SESSION_REFUSAL_STATUS (since #17881 an anonymous or revoked /get-session answers 401 with the ADR-0112 refusal envelope, code UNAUTHENTICATED derived from that status; a live session still answers 200 with { user, session }. Both legs are driven end to end in packages/plugins/plugin-auth/src/anonymous-session-refusal.test.ts, and the body-not-status discipline for a revoke is kept in packages/plugins/plugin-auth/src/session-of-record.test.ts)"
"packages/connectors/connector-mcp/src/mcp-provider.ts (#3055 policy: default deny, strict-equality allowlist, both messages)",
259
-
"examples/app-showcase/objectstack.config.ts#declarativeStdio (declarativeStdio: ['node'] opt-in) + src/system/connectors/index.ts (the 'remove that option and boot fails loudly — try it' fixture note)"
259
+
"examples/app-showcase/objectstack.config.ts#plugins (declarativeStdio: ['node'] opt-in on the ConnectorMcpPlugin entry — re-pointed #18101: declarativeStdio is a key written INLINE in that constructor call, which the shared resolver does not read as a declaration, and the config itself is an anonymous default export, so plugins is the nearest enclosing key it does read) + src/system/connectors/index.ts (the 'remove that option and boot fails loudly — try it' fixture note)"
"packages/spec/src/data/datasource.zod.ts#checkOnBoot (validation policy schema; checkOnBoot default true, the checkonboot/validateonboot alias rows are REJECTION-path did-you-means, not folds — enforced since #13149, so declared = enforced here now)",
1409
-
"examples/app-showcase/src/system/datasources/showcase-external.datasource.ts#onMismatch (stock policy onMismatch:'warn' — deliberate, per its own comment)",
1409
+
"examples/app-showcase/src/system/datasources/showcase-external.datasource.ts#ShowcaseExternalDatasource (stock policy onMismatch:'warn' — deliberate, per its own comment; re-pointed #18101: onMismatch is a key written INLINE in the external validation literal, which the shared resolver does not read as a declaration, and ShowcaseExternalDatasource is the datasource constant that declares it)",
"examples/app-showcase/src/ui/actions/index.ts#ActionParamGalleryAction (maxSize declarations on its image and file params — re-pointed #18101: maxSize is a key written INLINE in each param literal, which the shared resolver does not read as a declaration, and ActionParamGalleryAction is the action constant that declares those params)"
"examples/app-showcase/src/data/objects/business-unit.object.ts#BusinessUnit.parent + category.object.ts (parent allowCreate:true — re-pointed #18101: allowCreate is a key written INLINE in the lookup options, which the shared resolver does not read as a declaration, and the parent field of the BusinessUnit object is the declaration that carries it)",
0 commit comments