Repository navigation
Commit e57a4c3
<!-- claude-projects-attribution: {"github_login":"os-sales"} -->
_Requested by **Sales** · [project
thread](https://claude.ai/code/project/chan_01D5bWFY3rFzgJcytD5gD4Uu?thread=cmsg_01D5bWFY3rFzgJcytD5gD4UuCEzLkAB12FfRHL9ipwfKPd)_
Part of #25222
Clause-②: no
Metadata-protocol: none
Ruling-ref: 6348891160
This is slice 7 of the `engine.ts` split. Its claim is comment
6378948491, narrowed by one body in comment 6379054858. It follows the
seat's shape call A: one PR, five seam modules. The bodies of 42
`AutomationEngine` methods move, unedited, into five new modules under
`packages/services/service-automation/src/`:
| Module | Host | Bodies | What they do |
| --- | --- | --- | --- |
| `dispatch-claims.ts` | `DispatchClaimsHost` | 7 | `claim`,
`claimInProcess`, `settleDispatch`, `readDispatch`, `nextRunId`,
`warnAdvanceClaimDegraded`, `releaseSuspension`: claiming, settling and
reading a dispatch, minting a run id, announcing a degraded advance
claim, releasing a suspension |
| `flow-definitions.ts` | `FlowDefinitionsHost` | 12 |
`resolveFunction`, `registerConnectorProvider`,
`canonicalizeStoredFlow`, `canonicalizeFlow`, `unregisterFlow`,
`recordFlowRefusal`, `getFlowRuntimeStates`, `describeUnboundReason`,
`getTriggerBindingAudit`, `flowCredentialHoldings`,
`hookSecretResolver`, `rollbackFlow`: canonicalising, unregistering,
refusing and rolling back a flow; its runtime states and trigger
bindings; its function, connector-provider and credential surfaces |
| `subflow-guards.ts` | `SubflowGuardsHost` | 11 |
`describeDisabledFlow`, `subflowTargets`, `packagedSubflowCallers`,
`parkedRunsOf`, `refuseUnderReachingCallers`,
`disabledPackagedSubflows`, `ledgerDisabledChainReaches`,
`refuseEnableOntoDisabledSubflow`, `describeDisabledSubflows`,
`rejudgeSubflowCallers`, `refuseCustomerAuthoredToggle`: finding and
describing disabled or packaged subflows and their callers, and refusing
what would reach a disabled subflow |
| `consumed-suspension-restore.ts` | `ConsumedSuspensionRestoreHost` | 6
| `rowSupersedesJournal`, `resolveConsumedSuspensionWitnesses`,
`restoreConsumedSuspension`, `resolveRestoreChain`,
`peekConsumedSuspension`, `inspectConsumedSuspension`: resolving a
consumed suspension's witnesses, and restoring, peeking at or inspecting
one |
| `node-text-rendering.ts` | `NodeTextRenderingHost` | 6 |
`unknownNodeTypes`, `warnIfNodeTypeVocabularyNeverSealed`,
`setNodeError`, `renderRefusalMessage`, `renderFlowTextSlot`,
`translatedFlowTemplate`: the node-type vocabulary checks a run makes, a
failed node's error variable, and rendering refusal messages and flow
text slots |
The change is move-only, and the card stays open for the later slices.
The branch is `claude/project-thread-nirtwt`, which the harness pins for
this session. It was restarted from `main` at `ea6fe000` after slice 6
(#25567) merged. The branch name has no issue number, so the claim
comment is the identity record.
## Scope
- **The 33-site question.** The ruling on the 33
`this.FIELD.delete/insert/update(` sites in 21 methods is still pending
with Sales. This slice moves **0** of those sites, because none of the
42 bodies holds one. `check-tenant-audit-census` and
`check-system-context-census` give byte-identical output at base and
head (see Readers).
- **Return types.** Each of the 42 methods declares its return type; the
generator refuses one that does not. So no public body with an inferred
return type moves.
- **Four bodies stay**, because each reads a name that `engine.ts`
documents as private, and moving it would mean exporting that name:
- `claimAdvance` returns `AdvanceClaim`, whose docblock says
"Module-private: it is a control-flow verdict, not a contract."
- `validateNodeInputSchemas` throws `InputSchemaViolationError`, whose
docblock says "Not exported on purpose — callers read the ADR-0112
`code` off the result, never the throw."
- `refuseInvalidScreenInput` and `buildSubflowResumeSignal` (slice 6's
two) read `ENGINE_BUILT_SIGNAL` / `engineBuilt`.
`docs/adr/0019-approval-as-flow-node.md` calls it "a module-private
symbol", and its docblock says "Module-private and symbol-keyed".
- **`pullConnectorSource` stays too** (the claim amendment, comment
6379054858). `connector-pull.ts` already has a top-level
`pullConnectorSource`, which `index.ts` re-exports. With the method's
body moved as well, the bundle held two top-level functions of that
name, and the bundler renamed the public one: both bundles exported
`pullConnectorSource2 as pullConnectorSource`, so its `.name` changed.
That would be an observable change to a public export, so the body
stays. On this head, every exported function's `.name` matches base in
both bundles (see Bundles below).
- **None of the other stays moves.** The remaining-bodies table (comment
6376268510) marks these as stays:
- for liveness, `retryExecution` and `getConnectorDescriptors`;
- for private statics, `resolveCanonicalDescriptor`,
`resolveResumeAuthority` and `resolveEffectiveSuspension`. A moved
function reading a private static would not compile, and `tsc` passes;
- for the startup-registry gate, `knownNodeTypes`,
`getUnknownNodeTypeAudit`, `sealNodeTypeVocabulary` and
`warnUnknownNodeTypes`.
- **Size.** 2,406 changed lines, under the 3,000-line bar: `engine.ts`
+365 / -771, the five modules +1,268, and the test 1 / 1.
`check-governed-merges --branch` on this commit says NOT governed, 0 of
7 paths on the register.
## What stays in `engine.ts`
- Every moved method keeps its name, docblock, signature and position in
the class, because tsup emits each member, private ones included, into
the published `.d.ts`.
## The shape (slices 1 to 6)
- **The host interfaces.** Each module's host holds exactly the members
its bodies read, each typed as the class member itself
(`AutomationEngine['m']`), so a renamed member is a compile error. There
is no cast, and no member becomes public or protected.
- Each moved function types `this` as the `Pick` of its host over
exactly the members its own body reads, read off each body's AST in
first-read order.
- Six bodies read no member and are called directly, without a host:
`nextRunId`, `subflowTargets`, `describeDisabledSubflows`,
`rowSupersedesJournal`, `unknownNodeTypes` and `setNodeError`.
- **Methods** are passed as late-bound closures, `(...a) =>
this.m(...a)`, so a spy or test double set on the instance is still the
one called.
- **Six fields go through a getter**, in the `store` form (#25223 cut 1,
PR #25290), because a method reassigns each. The write sites are
`engine.ts` at the base `ea6fe000`:
- `flowDispatchStore`: `setFlowDispatchStore` (`:2778`);
- `functionResolver`: `setFunctionResolver` (`:3962`);
- `flowCredentialSource`: `setFlowCredentialSource` (`:4746`);
- `store`: `setSuspendedRunStore` (`:2769`), and the constructor
(`:2745`);
- `nodeTypeVocabularySealed`: `sealNodeTypeVocabulary` (`:9424`);
- `i18nServiceSource`: `setI18nServiceSource` (`:4769`).
For each one, the stub builds `const readX = () => this.X;` and the host
member `get X() { return readX(); }`. Each read in the body reads the
engine's current value, as it did inside the class.
- **Four warned-once flags go through a get/set pair** (#25224 cut 10,
PR #25508), because a moved body sets each. The stub adds `const writeX
= (v: AutomationEngine['X']) => { this.X = v; };` and the host member
`set X(v) { writeX(v); }` beside the getter, and the host interface
member is not `readonly`. So each write lands on the engine, as it did
through `this`.
- `git grep -nE
"(dispatchClaimDegradationWarned|dispatchOutcomeDegradationWarned|advanceClaimDegradationWarned|nodeTypeSealOmissionWarned)"`
over the whole repo at the base finds 13 lines, all in `engine.ts`:
- the four declarations, each `= false`: `nodeTypeSealOmissionWarned`
(`:2540`), `dispatchClaimDegradationWarned` (`:2725`),
`advanceClaimDegradationWarned` (`:2734`),
`dispatchOutcomeDegradationWarned` (`:2741`);
- one `{@link}` in a docblock (`:2544`);
- the four writes, each in the one moved body that sets it: `claim`
(`:2815`), `readDispatch` (`:2911`), `warnAdvanceClaimDegraded`
(`:3310`), `warnIfNodeTypeVocabularyNeverSealed` (`:9481`);
- the four reads just above those writes, in the same bodies.
- The constructor writes none of them, and no other file names any of
them.
- **Fifteen fields go by value**: `logger`, `inProcessDispatchClaims`,
`nodeExecutors`, `connectorProviders`, `flows`, `flowRefusals`,
`flowShadowing`, `boundFlowTriggers`, `policyDisabledFlows`,
`subflowDeclinedFlows`, `triggers`, `flowVersionHistory`,
`flowLedgerDisabled`, `flowStatusDisabled` and `consumedSuspensions`.
The seat asked for proof that none is reassigned after construction:
- `git grep -nE "this\.(FIELDS)\s*(=[^=>]|\?\?=|\|\|=|&&=)" --
packages/services/service-automation/src`, with the fifteen names, finds
1 line, in the constructor: `this.logger = logger;` (`:2744`).
- Across the repo, the same pattern on any receiver (`\.(FIELDS)`) for
the fourteen names other than `logger` finds nothing. The bracket form,
`['name']` followed by `=` or `??=`, finds nothing for any of the
fifteen. And `\.(flows|triggers|logger)\s*(=[^=>]|\?\?=)` on any
receiver in the package finds only that constructor line.
- The bodies change the collections' contents in place, on the engine's
own `Map`s and `Set`s, and never rebind the fields.
- **Async.** The stubs of the nine async methods drop `async` and return
the moved function's promise, as in slices 3 to 6.
- The caller gets the very promise the body makes.
- Dropping `async` is the only edit to those signature lines, and the
`.d.ts` does not print `async`.
- **Parameter defaults.** `canonicalizeStoredFlow` and
`canonicalizeFlow` take `options: { includeRetired?: boolean } = {}`.
- The class stub keeps that default exactly as written, so a caller that
omits `options` still gets `{}`.
- The moved text keeps it too, token-identical, because the moved lines
are unedited. That default is now dead: the stub always passes
`options`, already defaulted. It is disclosed here, not edited.
- The moved bodies keep saying `this.`, so the moved lines are unedited.
## Module-level declarations and imports
- **Seven helpers gain `export`, in place.** The moved bodies read them,
so each module imports them from `./engine.js`. Nothing else about them
changes: the same line, the same docblock, the same position. `index.ts`
adds no re-export, and the package's export map is `.` only, so none of
them is reachable from outside the package. The signatures at head:
- `export const CONVERSIONS_NOT_REPLAYED_AT_REHYDRATION: readonly
string[] = [` (read by `canonicalizeFlow`)
- `export const MAX_RESTORE_CHAIN_HOPS = 32;` (read by
`resolveRestoreChain`)
- `export function chainEntryOf(runId: string, result:
SuspensionRestoreResult): ChainRestoreEntry {` (read by
`restoreConsumedSuspension`)
- `export function flowRegistrationTodo(flowName: string, site:
RegistrationCheckSite): ConversionTodoNotice {` (read by
`canonicalizeStoredFlow`)
- `export function graftConditionEnvelopes(converted: unknown, parsed:
unknown): unknown {` (read by `canonicalizeFlow`)
- `export function negotiatedServiceLocale(service: RefusalI18nService,
requested: string): string {` (read by `translatedFlowTemplate`)
- `export function nestedChildRunId(correlation: string | undefined):
string | undefined {` (read by `resolveRestoreChain`)
- None of their docblocks says the name is private. Two other files
place `CONVERSIONS_NOT_REPLAYED_AT_REHYDRATION` "in
`service-automation/src/engine.ts`" (`metadata-core`'s
`artifact-forward-conversion.ts` and `metadata-protocol`'s
`protocol.ts`), and it stays there.
- **The cut-6 trap.** `flowRegistrationTodo`'s signature names types
from other files (`RegistrationCheckSite`, `ConversionTodoNotice`). On
this PR the rolled-up `.d.ts` gains no declaration and moves none; its
only raw change is 87 reordered string-literal unions, each shown below
as a swap.
- The ESM and CJS export lists are identical at base and head (39 names
each, ESM equal to CJS on each side). They are listed in the `.d.ts`
section.
- **The modules' imports** use the same specifiers as `engine.ts`'s own
imports. A comment above each value import from `./engine.js` says the
value is read only inside function bodies, at call time, so the import
cycle is safe under ESM live bindings, as in slices 3, 5 and 6. The tsup
bundle is one file and has no cycle.
- **Import edits in `engine.ts`.**
- `import { FLOW_HOOK_SECRET_KEY, flowCredentialClassLabel,
flowCredentialPositions } from './flow-credential-projection.js';`
moves, verbatim, to `flow-definitions.ts`: only moved bodies read those
names.
- The 6-line `[#15788]` comment and `import { renderTextSlot,
FlowTextTemplateError } from './builtin/template.js';` move, verbatim,
to `node-text-rendering.ts`. The comment's claim ("`template.ts` imports
only `../guard-refusal.js` and package-external contracts, so nothing it
pulls in reaches back here") is as true there as it was in `engine.ts`.
- Three imports are narrowed to the names `engine.ts` still reads:
- `@objectstack/spec/automation` keeps `FLOW_RESERVED_NODE_TYPES` and
`FLOW_STRUCTURAL_NODE_TYPES`; `FlowSchema`, `validateControlFlow` and
`collectFlowGraphs` go to the modules;
- `@objectstack/spec` keeps `CONVERSION_TODO_CODE` and the types
`ConversionNotice` and `ConversionTodoNotice`; `applyConversionsToFlow`
goes to `flow-definitions.ts`;
- `@objectstack/spec/system` keeps `resolveBundleLocale`;
`flowRefusalMessageKey` goes to `node-text-rendering.ts`.
- No `engine.ts` docblock `{@link}`s any of the names that left, so no
link stops resolving. `tsc` with `noUnusedLocals` passes, so every name
left in an `engine.ts` import is still read or linked.
- `engine.ts` gains the five module imports, after the `./run-resume.js`
one, each with a comment naming its bodies.
- **Authored text.** Each module's docblock and its host interface's
docblock are new. Each host docblock names the method that reassigns
each getter field and the body that sets each get/set flag.
## Proof of move-only
- **Moved block.** This is `git diff --color-moved=plain
--color-moved-ws=allow-indentation-change ea6fe00 HEAD` over
`engine.ts` and the five modules. It detects 752 of the 771 deleted
lines and 892 of the 1,633 added lines as moved.
- **Deleted, not moved (19):**
- the signature heads of the nine async methods, each of which drops
`async`;
- the seven helper declaration lines, each of which gains `export`;
- the three import lines that are narrowed.
- **Added, not moved (741):** the modules' docblocks, imports and host
interfaces; the 42 pointer docblocks and rewritten function heads; the
five module imports in `engine.ts` and their comments; the narrowed
imports; the nine heads without `async`; the seven `export` lines; the
42 stub bodies; and lines git does not pair with a moved block.
- **An independent check.** A script compared base and head `engine.ts`
against the five modules.
- **Module lines.** 898 of the modules' 1,268 lines are in 43 verbatim
runs of base `engine.ts`: the 42 method texts, de-indented one level,
and the `[#15788]` comment with its `./builtin/template.js` import. The
script names each of the other 370:
- 278 head lines: per module, the copyright line, the docblock, the
imports and their comments, the host docblock and the host interface
(10, 22, 15, 9 and 6 members);
- the 42 pointer docblocks;
- 50 signature lines: 42 `export function` heads, and 8 `this` parameter
lines, each a `Pick` of the host.
- **Deleted lines.** Every line deleted from `engine.ts` (771 in all, 9
of them blank) is among the modules' lines, apart from the 19 above. The
deleted `./flow-credential-projection.js` import, the `[#15788]` comment
and the `./builtin/template.js` import are among them, verbatim.
- **Added lines.** Of the 365 lines added to `engine.ts`, 284 are found
nowhere in base:
- the five module import blocks (47 lines) and their comments (17);
- the three narrowed imports and the seven `export` lines;
- the nine heads without `async`;
- the stub lines: 42 pointer comments, 36 host literals with their 36
calls, 35 method closures, 16 by-value members, 15 read/write closures,
15 getter and setter members, and 6 direct calls.
The other 81, such as `logger: this.logger,` and `};`, are lines base
already contains elsewhere.
- **Literals.** No string or template literal in the 42 method bodies
spans a line, checked on the TypeScript AST of base `engine.ts`. So
de-indenting changed no string value.
- **Tests.** `@objectstack/service-automation`'s suite passes the same
at base and head, 199 of 199 files and 2628 of 2628 tests.
## `.d.ts` reading (ruling 6348891160, item 2)
The merge base is `ea6fe000`, the head of `main`, so the merge-base
reading and the base reading are one reading.
- **Base** is `dist/`, built at `ea6fe000` in this container, in a
worktree of that commit.
- **Head** is `dist/`, built at this PR's commit.
- The package's dependencies were built by `turbo run build
--filter=@objectstack/service-automation` (31 of 31 tasks), and both
sides resolve the same built dependencies.
The readings:
- **Raw sha256**, `index.d.ts` and `index.d.cts`, which are identical to
each other on both sides: base
`1a5162a4dd929399460a3936e22747a74cf0a8db24d398ffbab5d7ead7bf212e`, head
`deb08bdfb32c2a247b98780ad67162bd2938da46669e81af313526f69af6ecc4`.
- **Normalised sha256**, all four files: base
`0df32585069f743135440763aabff8c23473231181297c8d164f5f7ee4f10232`, head
`0df32585069f743135440763aabff8c23473231181297c8d164f5f7ee4f10232`.
- **Raw diff**, `index.d.ts` base vs head: **174 lines**, 87 per side,
with 19,626 lines on each side. They are 87 one-line `c` hunks: each
base line and its head line are the same line with one string-literal
union's members in another order. Outside the union, each pair is
byte-identical, and each union holds the same members on both sides.
- **The 87 pairs**, which are five distinct swaps. All of them sit
inside three declarations, `SysAutomationRun`, `SysFlowDispatch` and
`SysFlowCredential`, which inline the spec's field and flow types:
| Member | Union | The swap | Lines (base = head) |
| --- | --- | --- | --- |
| `type:` | 49 field types | `"secret"` moves from 3rd to 6th, after
`"code"` | 5851, 6366, 13468, 13983, 15679, 16194 |
| `dialect:` | `"cron" \| "cel" \| "template"` | `"template"` moves from
3rd to 1st | 72 lines: 5889, 5933, 5942, 5976, 6002, 6011, 6020, 6033,
6043, 6088, 6097, 6109, 6118, 6130, 6139, 6151, 6160, 6202, 6396, 6428,
6756, 6775, 6829, 6840, 13506, 13550, 13559, 13593, 13619, 13628, 13637,
13650, 13660, 13705, 13714, 13726, 13735, 13747, 13756, 13768, 13777,
13819, 14013, 14045, 14373, 14392, 14446, 14457, 15717, 15761, 15770,
15804, 15830, 15839, 15848, 15861, 15871, 15916, 15925, 15937, 15946,
15958, 15967, 15979, 15988, 16030, 16224, 16256, 16584, 16603, 16657,
16668 |
| `type?:` | 6 action types | `"form"` and `"api"` swap (2nd and 3rd) |
6720, 14337, 16548 |
| `type?:` | 49 field types | `"secret"` moves from 3rd to 6th, after
`"code"` | 6747, 14364, 16575 |
| `category?:` | 7 categories | `"flow"` and `"data"` swap (1st and 2nd)
| 6858, 14475, 16686 |
For example, line 5889 is `dialect: "cron" | "cel" | "template";` at
base and `dialect: "template" | "cron" | "cel";` at head. A script
checked each of the 87 pairs: it replaced each union with a placeholder
and compared the rest of the line, and it compared each union's sorted
members. All 87 are swaps, 0 are not.
- **The normaliser**, the ruling's one-liner, verbatim:
`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**, each one line changed in the head `index.d.ts`,
then the same normaliser:
- Line 1865, `private claimInProcess;`, a private member whose body
moved, made public (`claimInProcess;`):
`196ae606dce0584f296ce860802b020ab52eb604cde3f4f09cb835f5deba1b0c`.
- The same member renamed (`private claimInProcessRenamed;`):
`a972fa4d01a6a8cd8654a4ce08619a48df26fe4745758cc0bcfca4c9edf4bf4d`.
- Line 5889 with one union member changed (`"cel"` to `"cel2"`):
`a21f02dba31881caec16bae8623f780cc6aae2cc9cd56f110d7eb0cb4a66b188`.
- All three differ from `0df32585…`. So the normaliser does not hide a
visibility change, a rename or a changed union member; it hides only
member order.
- **Item 1 holds:**
- (a) the declaration set and visibility are the same: no line is added,
removed or moved, and the 87 changed lines change only member order;
- (b) the files are byte-identical after the normalisation;
- (c) the ESM and CJS export lists are identical;
- (d) every raw-diff line is a union-member swap.
## Bundles
- **Export lists.** 39 names each, identical at base and at head, and
ESM equal to CJS on each side: `AutomationEngine`,
`AutomationServicePlugin`, `CONNECTOR_PULL_PROVIDERS`,
`ConnectorPullError`, `DEFAULT_MAX_EXECUTION_LOG_SIZE`,
`DEFAULT_MAX_TERMINAL_RUNS_PER_FLOW`, `FLOW_CREDENTIAL_MIGRATION_ID`,
`FLOW_CREDENTIAL_OBJECT`, `FLOW_CREDENTIAL_VALUE_FIELD`,
`FlowCredentialChannel`, `FlowCredentialChannelRefusal`,
`FlowCredentialUnresolvableError`, `InMemoryFlowActivationStore`,
`InMemoryFlowDispatchStore`, `InMemorySuspendedRunStore`,
`MAX_PERSISTED_HISTORY_STEPS`, `ObjectStoreFlowActivationStore`,
`ObjectStoreFlowDispatchStore`, `ObjectStoreSuspendedRunStore`,
`SysAutomationRun`, `SysFlowCredential`, `SysFlowDispatch`,
`UnscopedRunDataAccessError`, `createPackageFileLoader`,
`describeFlowContender`, `formatRunSummaryLine`, `installBuiltinNodes`,
`migrateFlowCredentialsIntoChannel`, `pullConnectorSource`,
`registerConnectorNodes`, `registerCrudNodes`, `registerHttpNodes`,
`registerLogicNodes`, `registerScreenNodes`, `renderFlowContender`,
`resolveFlowPrecedence`, `resolveRunDataContext`,
`stampSystemInsertOwner`, `summarizeRun`.
- **Each export's code.** A script fingerprinted each export's
`Function#toString` in both bundles, at base and at head. Only
`AutomationEngine` differs, because its stubs changed. In the CJS
bundle, six other functions (`migrateFlowCredentialsIntoChannel` and the
five `register*Nodes`) print differently too, but only in esbuild's
import-namespace variable names (`import_automation3` becomes another
number, because the new modules add import statements). With those names
folded, they are identical.
- **Each export's name.** Every exported function's `.name` matches base
in both bundles. (`AutomationEngine` prints as `_AutomationEngine` at
both ends.) This is the check that caught `pullConnectorSource`; see
Scope.
- The bundle JS bytes otherwise differ only because code moved within
the bundle.
## Readers
**One reader re-pointed.** `src/flow-activation-ledger.test.ts`'s
`ENGINE_SOURCES` holds the #10243 grep pins, which are absence checks.
It gains the five modules, so a moved body is not a place the retired
mechanism could come back unseen. That 1-line edit is the PR's seventh
file.
**Readers examined.** The base for each is `ea6fe000`, in a worktree of
that commit.
- **`check-tenant-audit-census`** (derived): output byte-identical to
base.
- It certifies 238 write call sites (162 decidable; 2 provably without
tenant context, 29 more unreadable).
- It holds 23 prose figures and matches every `UNTYPED_RECEIVERS` row.
- Its `--self-test` output is identical too.
- **`check-system-context-census`** (derived): output byte-identical. It
finds 149 elevation read sites in 22 packages across 77 files, in 129
symbols.
- **`check:liveness`** (spec lane, not derived; run by hand as
`packages/spec`'s `tsx scripts/liveness/check-liveness.mts`): output
byte-identical at base and head.
- 753 (entry, cited file) pairs: 752 anchored, 1 exempt.
- 982 of 982 symbol anchors resolve.
- **`check:platform-checklist`** (not derived; run by hand): output
identical at base and head. 987 of 997 symbol anchors resolve; the other
10 are the same ones, the named #16898 residual.
- **`check-adr-symbol-anchors`** (not derived; run by hand): output
identical at base and head. 2384 anchors across 142 records resolve.
- **`check:adr-anchors`** (decision letters; run by hand at the merge
base and the head): output identical apart from the count of files
holding a citation, 6699 at base and 6702 at head.
- The 52309 citations are the same in number: the citations in the moved
bodies of `flow-definitions.ts`, `subflow-guards.ts` and
`node-text-rendering.ts` are now counted in those three files.
- It reads 84 anchored files and 1939 decision-letter citations, the
same at both ends.
- Neither `engine.ts` nor any of the five modules is on the anchored
surface.
- **`check:startup-registry-verdict`** (not derived; run by hand at both
ends, on the hand-gate list): 46 seams, 40 of them read-only, none
recording a verdict, at base and at head.
- Its `--list` is the same at both ends apart from line numbers and the
scanned-file count, 3463 at base and 3468 at head; the five extra files
are the new modules.
- None of its four engine bodies moves.
`warnIfNodeTypeVocabularyNeverSealed` and `unknownNodeTypes` move, and
the `registerFlow` and `sealNodeTypeVocabulary` seams still name the
same `warn` sites, at their new line numbers.
- **Symbol anchors into moved methods.** Four anchors name a method
whose body moved:
- `docs/adr/0087-metadata-protocol-upgrade-contract.md`,
`engine.ts#canonicalizeStoredFlow`;
- `docs/qa/platform-checklist/areas/automation.json`,
`engine.ts#packagedSubflowCallers`;
- `packages/spec/liveness/translation.json`,
`engine.ts#renderRefusalMessage` and `engine.ts#translatedFlowTemplate`.
Each still resolves: the method stays in `engine.ts` with its docblock
and calls its body. This is the same as slice 5's `engine.ts#recordLog`
anchor in `approvals.json`. The readers above give identical output, and
the `translation.json` key-mention pairs (`refusals`, `message`) stay
anchored through `engine.ts`'s own docblocks.
- **`path:line` citations.** None points into this package's `engine.ts`
at a line this slice moves. The one fixture citation,
`service-automation/src/engine.ts:44` in
`packages/spec/scripts/liveness/evidence.test.ts`, is a
realm-attribution string that `scanEvidence` parses without reading the
file.
## Gates
- **Derived.** `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` on this commit derives 60 families from the
7 changed paths: 2,406 changed lines, under the 3,000-line human-merge
threshold. These are the same 60 as slice 6.
- All 60 ran in this container on this commit, with each exit code
captured before any pipe, and all 60 exit 0. `dispatch-gates.mjs --ran`
reconciles: 60 derived, 60 run, 0 NOT-MEASURED, 0 UNRUN.
- An earlier run on the first commit, the one that still moved
`pullConnectorSource`, was stopped after 23 families when I narrowed the
slice. It is not counted.
- **By hand, at base and head, not derived:** `check:liveness`,
`check:platform-checklist`, `check-adr-symbol-anchors`,
`check:adr-anchors` and `check:startup-registry-verdict`, with the
readings in the Readers section above.
- **`check-governed-merges --branch`** on this commit: 0 of 7 paths on
the register, NOT governed, 2,406 lines.
- **Package checks.**
- `@objectstack/service-automation`'s `vitest run` gives 199 of 199
files and 2628 of 2628 tests, the same at base and head.
- The package's `typecheck` (`tsc --noEmit` and `check:test-typecheck`)
passes.
- ESLint on the seven files passes.
- **Open PRs**, re-listed just before this PR was opened: 11.
- I diffed each one's head against its merge base with `origin/main`.
None of them touches `service-automation/src`, the readers above, their
ledgers, `docs/adr/0019-approval-as-flow-node.md`, or the three files
that hold anchors into moved methods.
- The Version Packages PR #24876 touches only the package's
`CHANGELOG.md` and `package.json`.
- `main` has moved to `e0734559`. Of what landed since `ea6fe000`, only
#25545 touches a reader above,
`scripts/check-system-context-census.mjs`, and only in its
`plugin-security` rows.
```text
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-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-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/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.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/spec run check:duration-unit-keys :: exit 0
pnpm check:closed-ceremony-text :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:dispatcher-error-vocabulary :: exit 0
pnpm check:doc-authoring :: 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:durability-log-level :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:error-status-conformance :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:issue-citations :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:logger-receiver-detach :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:objectql-double-limit :: exit 0
pnpm check:org-identifier :: exit 0
pnpm check:page-declaration-shape :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: 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:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
```
## Acceptance notes
- This is the slice the seat agreed (shape call A), less
`pullConnectorSource`, which stays so that the public
`pullConnectorSource` export keeps its name. The claim amendment says
so.
- Six host getters in the slice-5 `store` form, and four get/set pairs
in the #25508 form, one for each warned-once flag a moved body sets.
- Seven helpers gain `export` in place. No new public export: the export
lists and every export's code, apart from `AutomationEngine`, are the
same.
- The `.d.ts` changes only in the order of members in 87 string-literal
unions, each shown above.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01Mnj4nkWuhJ18xEdZvb2cjE
Co-authored-by: Claude <noreply@anthropic.com>
1 parent dad27ef commit e57a4c3
7 files changed
Lines changed: 1634 additions & 772 deletions
File tree
- packages/services/service-automation/src
| 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 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
0 commit comments