Repository navigation
Commit 3e51491
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuMYdF2uchcinMphEKW4sYxd)_
Part of #25223
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6353073966
Cut 3 of the `security-plugin.ts` split. The claim is 6354388643. The
bodies of five async methods move unedited to the new module
`packages/plugins/plugin-security/src/security-plugin-cbp-write-gate.ts`:
- `checkControlledByParentWrite`
- `assertControlledByParentWrite`
- `assertControlledByParentChainEditable`
- `controlledByParentPredicateWriteMasters`
- `assertMasterRowEditable`
Together they are the ADR-0055 §3 controlled-by-parent write gate the
write path runs at step 2.8, and the check the `security` service
serves. The three module-level declarations only those bodies read move
with them: `MASTER_EDIT_DENIAL_LEG`, `controlledByParentWriteOutcomeOf`
and `writesMasterReference`. So do the four error classes only those
bodies construct or test.
It is move-only, and the card stays open for the later cuts. Branch:
`claude/project-thread-3fzya4`, the harness-pinned branch for this
session, restarted from `origin/main` at `21a25dd9f1` (cut 2's merge).
It names no issue, so the claim comment is the identity record.
**Five exports, said up front.** `security-plugin.ts` adds the `export`
keyword to five module-level declarations, and the new module imports
them by value. Each line is otherwise byte-identical to base, and
`index.ts` re-exports only `SecurityPlugin`, so none reaches the
package's surface (the export tables below are unchanged). They stay in
`security-plugin.ts` for these reasons:
- `CBP_MAX_CHAIN_DEPTH`: ADR-0055:135 anchors it by symbol in that file
(ruling 6353073966 item 5), and `controlledByParentChainRefusal` there
walks it too.
- `requiredCapsForOperation`: `packages/spec/liveness/object.json`
anchors it by symbol in that file, and that file belongs to the spec
lane. The CRUD gate reads it too.
- `PREDICATE_WRITE_READABLE_ID_CAP`, `predicateWriteReadableCapError`
and `copyOfCallerPredicate`: `readableRowsScopeForPredicateWrite`, which
stays, reads all three. Moving them would leave a value import running
the other way.
Each value is read only inside a function body, at call time, never
while either module evaluates. So the two-way import is safe under ESM,
and the published bundle holds one module. The plugin's 4403 tests run
on the source modules, cycle included, and pass.
These stay in `security-plugin.ts` byte for byte, by ruling item 4,
until docs PR #25316 (card #25314) lands:
`computeControlledByParentFilter`, `controlledByParentChainRefusal` and
`composeWriteTenantWall`.
## The published `.d.ts` does not change
Under the series bar (ruling 6348891160 item 1), measured on base
`21a25dd9f1` and on the head (the tree of this PR's commit):
- Raw sha256 of `dist/index.d.ts` and `dist/index.d.mts`, base and head,
all four the same:
`803f5bfb7da0b00f8cd8d8f25172463d8dfb07d93fbdd8a9c6f4d4b7435e429a`. The
raw diff is 0 lines, so no union order moved either.
- Normalised sha256, all four the same:
`b6b5c1b7fa6fa188f6e2f7e4cca3816a246b570f20d708643d116012aa86fa77`.
- The normaliser, run from `packages/plugins/plugin-security` (it sorts
the members of each string-literal union and changes nothing else):
```sh
node -e 'const s=require("fs").readFileSync(process.argv[1],"utf8");process.stdout.write(s.replace(/"[^"\n]*"(?:\s*\|\s*"[^"\n]*")+/g,r=>r.split(/\s*\|\s*/).sort().join(" | ")))' dist/index.d.ts | sha256sum
```
- Positive controls on a copy of the head `dist/index.d.ts`, line 2308
(`private assertControlledByParentWrite;`):
- Made public (`assertControlledByParentWrite;`): raw
`ea8bebdf8cd6c0e974393bf00a9434fce8ec2ba1c3cb816549fd203c39cb90c7`,
normalised
`1a405f50b386e1209593962447896d000b736456d5dcaa64ab8f9921522053bb`.
- Renamed (`private assertControlledByParentWriteRenamed;`): raw
`7a055168bef89d872b54102a60b735a6f12e7bf1af7f367ea67531e10b56654e`,
normalised
`5f730b82bac2ce457a64717cd57973fa75fcf06d0aee180f1b5cb86c8e4d83ab`.
- Both differ from the real hashes, so the comparison does see a
visibility change and a rename.
- Export tables: the ESM and CJS bundles each export the same 63 names
at base and head. The lists were loaded at runtime, not parsed. The
sorted name list hashes
`f607fd765d6b277e08b3b46ccb16d1e2d133ec55658ffe40155aef25e1bf54f0` on
all four, the same as at cut 2.
- The bundle JS bytes differ (`index.js` `6d2a398f` to `aece9708`,
`index.mjs` `953c5d9a` to `38b8f218`), because code moved within them.
No changeset: `skip-changeset`, per ruling 6348891160 item 4.
## What moved
Base line numbers are each member's signature at `21a25dd9f1`. The last
column lists the members the body reads, which is exactly what its host
carries.
| method | base lines | host members |
|---|---|---|
| `checkControlledByParentWrite` | `:9363`-`:9390` |
`assertControlledByParentWrite`, `declaresControlledByParent`,
`resolveOperationPrincipals` |
| `assertControlledByParentWrite` | `:9525`-`:9780` |
`assertControlledByParentChainEditable`,
`controlledByParentPredicateWriteMasters`, `declaresControlledByParent`,
`extractSingleId`, `readRowById`, `resolveCbpRelation` |
| `assertControlledByParentChainEditable` | `:9804`-`:9899` |
`assertMasterRowEditable`, `declaresControlledByParent`, `readRowById`,
`resolveCbpRelation` |
| `controlledByParentPredicateWriteMasters` | `:9937`-`:9986` | `ql` |
| `assertMasterRowEditable` | `:10003`-`:10230` |
`checkAuthoredRowWrite`, `collectRLSPolicies`, `computeRlsFilter`,
`declaresControlledByParent`, `delegatorOwnWriteFloorOptions`,
`getObjectSecurityMeta`, `permissionEvaluator`, `ql`,
`resolveSharingCanEdit`, `resolveSharingWriteVerdict` |
All five methods are async, and every moved function is async too.
Module-level declarations that move, each with its docblock and
verbatim: `MASTER_EDIT_DENIAL_LEG` (base `:659`, 11 lines with its
docblock), `controlledByParentWriteOutcomeOf` (`:673`, 24 lines) and
`writesMasterReference` (`:740`, 15 lines). No code left in
`security-plugin.ts` reads them.
Imports: `MasterDetailRelationMissingError`,
`DetailRecordNotFoundError`, `MasterReferenceMissingError` and
`MasterReferenceNotWritableError` leave the `errors.js` import of
`security-plugin.ts`. No code there reads them any more. The module
imports them, plus the names its bodies share with code that stays
(`withoutOperationPrivateKeys`, the metadata-core engine dispatch
resolvers, `PermissionSet`, the two contract types and
`isPlatformOwnershipFloorPolicy`). Those stay imported in
`security-plugin.ts` too.
## The shape (#23050 shape B, as cuts 1 and 2 applied it)
- The class keeps each private method with its name, signature, docblock
and position, because tsup emits private members with their JSDoc into
the `.d.ts`. Each body is now one host literal plus `fn.call(host, …)`,
marked `[#25223 cut 3]`.
- `CbpWriteGateHost` types every member as the class member itself
(`SecurityPlugin['m']`). Each moved function types its `this` as the
`Pick` of the host over exactly the members its body reads, and each
stub annotates its literal with the same `Pick`. There is no cast, and
no member becomes public or protected.
- The module imports `SecurityPlugin` type-only. `CbpRelation` keeps its
one declaration in `security-plugin.ts`, and the module names it through
the class's own signature, as cut 2's module does (an alias over the
non-null return type of `SecurityPlugin['resolveCbpRelation']`).
- Methods go in as late-bound closures that call `this.m(...a)` on the
plugin at call time. A spy or test double set on the plugin is still the
one the gate reaches. The bodies that call one another (the check and
the gate, the gate and its chain walk, each leg and the master-row
verdict) still do so through the plugin. No moved body calls a
function-valued field, so no receiver changes.
- Fields: `ql` and `permissionEvaluator` go as getters, because neither
is declared `readonly`. `start()` assigns `ql` after construction, and
`security-plugin.test.ts` replaces `permissionEvaluator` on a
constructed plugin. The host declares both `readonly`, so a moved body
cannot assign a member through it; the typecheck passes, so none does.
- Async: every stub drops `async` and returns the moved function's own
promise. Building the host reads no field and runs no getter, and
calling an async function never throws synchronously, so a caller awaits
a promise that settles exactly as the old method's did.
- Nothing re-exports the module, so the package entry does not move.
- The class docblocks keep their `{@link}` tags to the four error
classes, byte for byte. Those names are no longer imported in
`security-plugin.ts`, so an editor shows the links unresolved there. No
gate resolves docblock links, and the `.d.ts` is unchanged.
## Proof of move-only
- **Bodies, by AST token**: for all 5 methods, the moved function's body
has the same TypeScript token sequence as the base method body, and each
of its 617 lines is the base line with two leading spaces removed.
Parameters, return types and `async` match. A negative control, `if
(context?.isSystem)` changed to `if (!context?.isSystem)`, fails the
check.
- **Class side**: each method keeps its docblock and signature, with
`async` dropped. The three moved declarations are verbatim in the module
and absent from `security-plugin.ts`. Each of the five exported values
is its base text with `export ` added and nothing else. `CbpRelation`,
`computeControlledByParentFilter`, `controlledByParentChainRefusal` and
`composeWriteTenantWall` are byte-identical to base.
- **git's own view** (`git diff --color-moved=plain
--color-moved-ws=allow-indentation-change 21a25dd HEAD` over the two
source files): 673 of 683 deleted lines and 709 of 923 added lines are
detected as moved.
- Deleted, not moved (10): the five declaration lines that gain
`export`, and the five `private async` signature lines that lose
`async`.
- Added, not moved: the replacements of those ten lines, the stub
bodies, and the import of the new module with its comment. In the
module: the license header, the module docblock, the imports, the
`CbpRelation` alias, `CbpWriteGateHost`, one pointer docblock per
function and the rewritten signature heads. The rest are lines git does
not pair with a moved block, such as blanks and closing braces.
- **Size**: 1613 changed lines (+930 / -683, 3 files), under the
3000-line human-merge threshold. `security-plugin.ts` goes from 10,823
to 10,208 lines.
## ADR anchors (ruling 6353073966 item 2)
- `node scripts/check-adr-symbol-anchors.mjs`: exit 0 at base
`21a25dd9f1` and exit 0 at head, both with `2383 anchors across 142
records resolve — 467 symbol (440 declaration, 27 literal), 1888
file-level, 28 cross-repo, 6 exempt, 18 continuation`. CI runs this gate
(`lint.yml`), but `dispatch-gates --commands` does not derive it for
this change set (#21697), so it is run by hand here.
- `pnpm check:adr-anchors`: exit 0, 77 anchored files (76 at base, plus
the new entry). The new entry is
`scripts/adr-anchors/packages__plugins__plugin-security__src__security-plugin-cbp-write-gate.ts.json`.
It carries ADR-0055 and the §1 invariant paragraph of the
`security-plugin.ts` entry, verbatim, as cut 2's entry does. Its "writes
throw MasterDetailRelationMissingError" half is the gate's relation leg,
which now lives here. The moved comments also cite ADR-0066 and
ADR-0090. Like the `security-plugin.ts` entry, which lists four of the
many ADRs that file cites, the new entry does not list them, and the
gate passes. The `security-plugin.ts` entry is unchanged, because the
methods, their docblocks and the read half remain in that file.
`docs/adr/**` is not touched.
- The anchor map covers every ADR symbol anchor naming
`security-plugin.ts`: 28 anchors, 20 symbols, 10 ADRs. It was measured
with `extractAnchors` and `symbolSegmentResolution` from
`scripts/symbol-anchors.mjs`, which is measurement, not a new gate. It
was read on `21a25dd9f1` BEFORE the cut, with the five ranges blanked:
no anchor changed class. Every anchor resolves at head in
`security-plugin.ts` with its base class.
The table gives each anchor's class at base and head, the code lines it
resolves on, and the member each line sits in. The member is shown after
the line number. Every anchor stays in `security-plugin.ts`.
| anchor | cited at | base class · lines (member) | head class · lines
(member) |
|---|---|---|---|
| `#CBP_MAX_CHAIN_DEPTH` | ADR-0055:135 | declaration · `:635`
(top-level) | declaration · `:643` (top-level, now exported) |
| `#SecurityPlugin` | ADR-0049:49, ADR-0138:248, ADR-0138:265 |
declaration · `:1377` (class) | declaration · `:1332` (class) |
| `#SecurityPlugin.getMetadataReadableFields` | ADR-0138:153 |
declaration · `:2526` (`start`), `:6119` (method) | declaration ·
`:2481`, `:6074` |
| `#SecurityPlugin.resolvePermissionSetsForContextUnmemoized` |
ADR-0138:427 | declaration · `:7030` (method) | declaration · `:6985`
(method) |
| `#assertControlledByParentWrite` | ADR-0055:125 | declaration ·
`:9525` (method) | declaration · `:9465` (method shell) |
| `#assertMasterRowEditable` | ADR-0055:125 | declaration · `:10003`
(method) | declaration · `:9591` (method shell) |
| `#collectRLSPolicies` | ADR-0105:93 | declaration · `:10260` (method)
| declaration · `:9645` (method) |
| `#computeControlledByParentFilter` | ADR-0055:5, ADR-0055:123,
ADR-0139:246 | declaration · `:9071` (method) | declaration · `:9026`
(method) |
| `#computeDelegatedReadFilter` | ADR-0139:223 | declaration · `:5997`
(method) | declaration · `:5952` (method) |
| `#computeRlsFilter` | ADR-0055:24 | declaration · `:5249`
(`explainAccessForCaller`), `:7652` (method) | declaration · `:5204`,
`:7607` |
| `#controlled_by_parent` | ADR-0055:58 | literal · `:9080`
(`computeControlledByParentFilter`), `:9146`
(`controlledByParentChainRefusal`) | literal · `:9035`, `:9101` |
| `#getReadFilter` | ADR-0096:181, :182, :183, :199, ADR-0139:222 |
declaration · `:2289` (`start`), `:5875` (method) | declaration ·
`:2244`, `:5830` |
| `#hasPlatformAdminPosture` | ADR-0099:317 | declaration · `:7679`
(method) | declaration · `:7634` (method) |
| `#isPrincipalLessContext` | ADR-0138:152 | declaration · `:489`
(top-level) | declaration · `:497` (top-level) |
| `#manage_metadata` | ADR-0099:68 | literal · `:238`
(`PLATFORM_ADMIN_ONLY_CAPABILITIES`) | literal · `:246` |
| `#nav_permission_sets` | ADR-0126:363 | literal · `:1782` (`init`) |
literal · `:1737` |
| `#refuseNoActiveOrganization` | ADR-0123:4 | declaration · `:8492`
(local in `composeWriteTenantWall`) | declaration · `:8447` |
| `#rlsFilter` | ADR-0055:24 | declaration · `:4352` (local in `start`)
| declaration · `:4307` |
| `#sharingModel` | ADR-0055:26 | declaration · `:9079` (local in
`computeControlledByParentFilter`) | declaration · `:9034` |
| `#writeCheckPolicies` | ADR-0066:112 | declaration · `:1272`
(top-level) | declaration · `:1227` (top-level) |
No resolving site moves. The two anchors that name a moved method
resolve on its declaration, which stays as a shell.
`#collectRLSPolicies` and `#computeRlsFilter` are read by
`assertMasterRowEditable`, but they resolve on their own declarations,
which do not move.
At head, four of these names appear on extra lines inside the stubs:
`assertControlledByParentWrite`, `assertMasterRowEditable`,
`collectRLSPolicies` and `computeRlsFilter`. Each is a key of a host
literal (a line-start member key, so declaration-class) and a quoted
member of the stub's `Pick` list (a literal). The class each anchor
resolves with is the same at head as at base.
The three anchors ruling item 4 holds for #25316 (ADR-0055:26
`#sharingModel`, ADR-0055:58 `#controlled_by_parent` and ADR-0123:4
`#refuseNoActiveOrganization`) still resolve only inside
`computeControlledByParentFilter`, `controlledByParentChainRefusal` and
`composeWriteTenantWall`. This cut does not touch those bodies.
## Readers
One docs anchor reads a moved line by path: row 9b of
`content/docs/permissions/system-context.mdx`, re-pointed below. No
test, script, gate or baseline does. (Corrected by the seat; the report
`6355294898` carries the same correction.)
- **The census page, re-pointed in this PR.**
`check-system-context-census` exits 1 on the cut without it. The served
check's elevation read, `if (context?.isSystem) return { outcome:
'allow' };`, is the first line of `checkControlledByParentWrite`'s body,
so it moved with the body. The census then finds that read in the new
module with no row pointing at it (`file-without-a-row`). The page's row
9b still names `security-plugin.ts#checkControlledByParentWrite`, where
the census no longer sees a read (`anchor-is-not-a-read-site`).
- The fix is the second commit, `d87954919b`. Row 9b of
`content/docs/permissions/system-context.mdx` now anchors
`packages/plugins/plugin-security/src/security-plugin-cbp-write-gate.ts#checkControlledByParentWrite`.
That is a one-line change, and the row's prose and every other row are
unchanged. The page is hand-written and not a governed surface. The
claim's surface covers it: a docs anchor that reads a moved line by path
moves in the same PR.
- Base `21a25dd9f1` and head, compared with `node
scripts/isystem-census.mjs --json`: the same 148 elevation read sites,
the same symbols, receivers and text, once the one moved site's file is
mapped back to `security-plugin.ts`. `nonElevationReads`, `roleCounts`
and `staleLedgerRows` are identical. The gate then exits 0 at head with
the same summary as base, except that the sites now span 70 files
instead of 69. Its `--self-test` exits 0 too.
- The other symbol-anchor gates all exit 0:
`check-scripts-symbol-anchors`, `check-spec-docblock-symbol-anchors`,
`pnpm --filter @objectstack/spec check:liveness`, and
`check-platform-checklist --changed-from origin/main`. The last of these
judged 6 anchors and lost 0. `packages/spec/liveness/object.json`
anchors `security-plugin.ts#requiredCapsForOperation`, which stays.
- Line citations: no `security-plugin.ts:N` citation in the repo points
into a moved range. The moved ranges at `21a25dd9f1` are `:649`-`:684`,
`:732`-`:746` and the five method bodies between `:9363` and `:10230`.
- Head line numbers shift by +12 for base `:120`-`:167` (the new
import), by +8 for base `:172`-`:648` (four error names left the
`errors.js` import), by -29 for base `:686`-`:731` and by -45 for base
`:747`-`:9362`.
- The citations `:132`, `:303`, `:309`, `:1614`, `:1690`, `:1736`,
`:3215`, `:3281`, `:3519` and `:4344` all land in those shifted ranges.
They are the same list cut 2 read, in `CHANGELOG.md`,
`docs/launch-readiness.md`,
`docs/design/predicate-compilation-convergence.md`,
`packages/objectql/src/engine.ts` and
`packages/spec/liveness/object.json`. Cut 2's report found every one of
them already pointing at an unrelated line, so this cut does not make
any of them wrong.
- Docs Drift Check, re-derived with `node
scripts/docs-audit/affected-docs.mjs --json 21a25dd` (advisory): 4
pages. `system-context.mdx` is the page re-pointed above.
`authorization.mdx`, `explain.mdx` and `rls.mdx` are reached only
through the string literal `'not_applicable'` inside
`checkControlledByParentWrite`. The literal moved unchanged and its
behaviour is the same, so there is nothing to edit on those pages.
- Census gates, run on base `21a25dd9f1` and head and compared:
- Identical output: `check-platform-object-tenancy-census`,
`check-position-name-fold-loaders`, `check-registry-log-declared`,
`check-rest-log-spy-declared`, `check-tenant-audit-census` (237 write
call sites at both), `check:cross-package-test-inputs`,
`check:driver-memory-census` and `check:query-options-erasure`. The last
of these reports the same counts at both, and `security-plugin.ts` is
not a baseline key. The moved bodies carry no erasure site the baseline
counts.
- Only the scanned counts move, by the one new file:
- `check-undeclared-dep-imports`: 3288 to 3289 files, and 2827 to 2831
specifiers. The 4 are the new module's package imports
(`@objectstack/core`, `@objectstack/spec/security`,
`@objectstack/metadata-core` and `@objectstack/spec/contracts`), all
declared dependencies.
- `check:doc-authoring`: 1411 to 1412 sources.
- `check:org-identifier`: 3630 to 3631 files.
- `check:logger-receiver-detach`: 3604 to 3606 files. The second extra
file is `apps/docs/.next/types/validator.ts`, a gitignored local build
output of the docs app, as at cut 2. It is not in the tree CI checks
out.
- `check-system-context-census`: compared above.
- `check-issue-citations` judges a change set, so it has nothing to read
at base. At head it judged 40 citations across 2 files, and all resolve.
## Acceptance notes
- Nothing outside this cut is touched: no other section of the class, no
behaviour, no other lane's file, and no `docs/adr/**`.
- Serial check, also in the claim: of the open PRs, only #25311 touches
`security-plugin.ts`, with one import after the
`catalog-reference-report.js` import and one block inside `start()`.
This cut has no hunk in either place. #25316 touches only
`docs/adr/0055` and `docs/adr/0123`.
- The next cut must not move `composeWriteTenantWall`,
`computeControlledByParentFilter` or `controlledByParentChainRefusal`
until #25316 lands (ruling item 4).
## Gates
All gates ran at the head, the tree of `d87954919b`, on base
`21a25dd9f1`. `origin/main` has not moved since that base.
- `pnpm --filter @objectstack/plugin-security test` (`vitest run
--maxWorkers=3`, under the verify lock): Test Files 210 passed (210),
Tests 4403 passed, 45 skipped (4448). Base `21a25dd9f1` gives the same
counts. VERDICT command-exit 0 on both. This ran on the cut commit
`c3e6ac12cd`; the second commit changes only the docs page.
- `pnpm --filter @objectstack/plugin-security typecheck`: exit 0. It
runs `tsc --noEmit`, the scripts tsconfig, and `check:test-typecheck`.
- `eslint --no-inline-config` over the two touched source files: exit 0.
- `pnpm --filter @objectstack/plugin-security build`: exit 0. It
produced the `.d.ts` and bundles measured above.
- `node scripts/check-adr-symbol-anchors.mjs` exit 0, `pnpm
check:query-options-erasure` exit 0, plus the three symbol-anchor gates
under Readers. None of these is derived for this change set; each was
run by hand.
- `dispatch-gates --commands`: 92 commands on the 4 changed paths (62
for the cut alone; the docs page adds 30 docs-family gates). The `--ran`
reconciliation shows 92 derived, 92 run, 0 NOT-MEASURED, 0 UNRUN. The
zero is derived: all 92 recorded an exit code and none is 3.
- Two docs-family gates first refused on a prerequisite, not a finding:
`pnpm --filter @objectstack/spec run check:docs` exited 1 because the
local `packages/spec/json-schema` tree was older than
`packages/spec/src`, and `pnpm --filter @objectstack/spec run
check:skill-examples` exited 3 because the local spec `dist` was stale.
After `pnpm --filter @objectstack/spec build` (which left the tree
clean), both exit 0. The list below records those re-runs.
Per command (exit code):
- `node scripts/check-ci-filter-parity.mjs` exit 0
- `node scripts/check-closing-keyword-parity.mjs` exit 0
- `node scripts/check-closing-keyword-parity.mjs --self-test` exit 0
- `node scripts/check-comment-mask-adoption.mjs` exit 0
- `node scripts/check-comment-mask-adoption.mjs --self-test` exit 0
- `node scripts/check-comment-mask-corpus.mjs` exit 0
- `node scripts/check-doc-frontmatter.mjs` exit 0
- `node scripts/check-doc-frontmatter.mjs --self-test` exit 0
- `node scripts/check-doc-route-spelling.mjs --advisory` exit 0
- `node scripts/check-doc-route-spelling.mjs --self-test` exit 0
- `node scripts/check-docs-section-name.mjs` exit 0
- `node scripts/check-docs-section-name.mjs --self-test` exit 0
- `node scripts/check-dts-emitted.mjs --self-test` exit 0
- `node scripts/check-issue-citations.mjs` exit 0
- `node scripts/check-keyed-text-bounds.mjs` exit 0
- `node scripts/check-keyed-text-bounds.mjs --self-test` exit 0
- `node scripts/check-platform-object-tenancy-census.mjs` exit 0
- `node scripts/check-platform-object-tenancy-census.mjs --self-test`
exit 0
- `node scripts/check-plugin-teardown-shape.mjs` exit 0
- `node scripts/check-plugin-teardown-shape.mjs --self-test` exit 0
- `node scripts/check-position-name-fold-loaders.mjs` exit 0
- `node scripts/check-position-name-fold-loaders.mjs --self-test` exit 0
- `node scripts/check-registry-log-declared.mjs` exit 0
- `node scripts/check-registry-log-declared.mjs --self-test` exit 0
- `node scripts/check-rest-log-spy-declared.mjs` exit 0
- `node scripts/check-rest-log-spy-declared.mjs --self-test` exit 0
- `node scripts/check-scripts-symbol-anchors.mjs` exit 0
- `node scripts/check-scripts-symbol-anchors.mjs --self-test` exit 0
- `node scripts/check-section-landing-index.mjs` exit 0
- `node scripts/check-section-landing-index.mjs --self-test` exit 0
- `node scripts/check-system-context-census.mjs` exit 0
- `node scripts/check-system-context-census.mjs --self-test` exit 0
- `node scripts/check-tenant-audit-census.mjs` exit 0
- `node scripts/check-tenant-audit-census.mjs --self-test` exit 0
- `node scripts/check-undeclared-dep-imports.mjs` exit 0
- `node scripts/check-undeclared-dep-imports.mjs --self-test` exit 0
- `node scripts/docs-audit/check-affected-docs.mjs` exit 0
- `node scripts/docs-audit/check-drift-comment.mjs` exit 0
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions`
exit 0
- `pnpm --filter @objectstack/lint run check:doc-security-posture` exit
0
- `pnpm --filter @objectstack/spec run check:docs` exit 0
- `pnpm --filter @objectstack/spec run check:duration-unit-keys` exit 0
- `pnpm --filter @objectstack/spec run check:empty-state` exit 0
- `pnpm --filter @objectstack/spec run check:liveness` exit 0
- `pnpm --filter @objectstack/spec run check:skill-examples` exit 0
- `pnpm --filter @objectstack/spec run check:strictness-ledger` exit 0
- `pnpm --filter @objectstack/spec run check:variant-docs` exit 0
- `pnpm --filter @objectstack/spec run check:yaml-examples` exit 0
- `pnpm check:adr-anchors` exit 0
- `pnpm check:agent-test-spelling` exit 0
- `pnpm check:bash32-floor` exit 0
- `pnpm check:cli-command-ids` exit 0
- `pnpm check:closed-ceremony-text` exit 0
- `pnpm check:corpus-claim-drift` exit 0
- `pnpm check:cross-package-test-inputs` exit 0
- `pnpm check:doc-anchors` exit 0
- `pnpm check:doc-authoring` exit 0
- `pnpm check:docs-audit-scope` exit 0
- `pnpm check:docs-redirects` exit 0
- `pnpm check:docs-single-h1` exit 0
- `pnpm check:docs-spec-enumerations` exit 0
- `pnpm check:docs-transcript-drift` exit 0
- `pnpm check:driver-memory-census` exit 0
- `pnpm check:dts-closure` exit 0
- `pnpm check:dual-build-cjs-loads` exit 0
- `pnpm check:entry-guard` exit 0
- `pnpm check:error-status-conformance` exit 0
- `pnpm check:gitlink-declared` exit 0
- `pnpm check:i18n` exit 0
- `pnpm check:i18n-stale-fill` exit 0
- `pnpm check:issue-citations` exit 0
- `pnpm check:lean-entry-closure` exit 0
- `pnpm check:logger-receiver-detach` exit 0
- `pnpm check:merge-driver` exit 0
- `pnpm check:nul-bytes` exit 0
- `pnpm check:org-identifier` exit 0
- `pnpm check:page-declaration-shape` exit 0
- `pnpm check:parse-guard` exit 0
- `pnpm check:pnpm-filter-targets` exit 0
- `pnpm check:pnpm-flag-spellings` exit 0
- `pnpm check:published-files` exit 0
- `pnpm check:published-readme-links` exit 0
- `pnpm check:react-page-adapter-contract` exit 0
- `pnpm check:refd-timer-probe` exit 0
- `pnpm check:role-word` exit 0
- `pnpm check:skill-identifier-liveness` exit 0
- `pnpm check:slot-lookup` exit 0
- `pnpm check:sourcemap-no-sources-content` exit 0
- `pnpm check:test-source-alias` exit 0
- `pnpm check:tier-file-adoption` exit 0
- `pnpm check:vendor-version-stamps` exit 0
- `pnpm check:watch-hint-literal` exit 0
- `pnpm check:query-options-erasure` exit 0
- `node scripts/check-adr-symbol-anchors.mjs` exit 0
- `node scripts/check-spec-docblock-symbol-anchors.mjs` exit 0
- `pnpm --filter @objectstack/spec check:liveness` exit 0
- `node scripts/check-platform-checklist.mjs --changed-from origin/main`
exit 0
---
_Generated by [Claude
Code](https://claude.ai/code/session_017BoLT8Gaa8t9a7AWVH8qZa)_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_017BoLT8Gaa8t9a7AWVH8qZa
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 54df640 commit 3e51491
4 files changed
Lines changed: 931 additions & 684 deletions
File tree
- content/docs/permissions
- packages/plugins/plugin-security/src
- scripts/adr-anchors
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
108 | 108 | | |
109 | 109 | | |
110 | 110 | | |
111 | | - | |
| 111 | + | |
112 | 112 | | |
113 | 113 | | |
114 | 114 | | |
| |||
0 commit comments