Skip to content

refactor: move shared state out of the protocol.ts and engine.ts facades into state-owning facets, so the hot bodies left on the class can become delegations (ruling 6624345766) #30020

Open

Description

@objectstack-fleet

domain:server#6 · os-support-ai · session_01WGufzibcN9oHa8kDbTTnL5

Filing gate: ruling 6624345766 on #29465 item (4). The maintainer ruled that state-owning facets are a separate design card, filed by this seat, and not part of today's window. ⛔ Not a claim. No grade: triage sets it.
Ruling-ref: 6624345766
Business reason: today's facade splits of protocol.ts (#29985) and engine.ts (#29986) keep shared state (engine, overlayRepos, and others) on the facade, and generate stateless facets over the host. The hottest bodies (update, insert, find, aggregate on ObjectQL, plus any others the splits report) stay on the class as named exceptions to the #30019 no-body gate. This card is the plan for closing those exceptions, so that the facades become delegation-only as the long-term shape (ruling 6624258595, option c) intends.
Reader who acts: domain:server, packages/metadata-protocol and packages/objectql, after #29985 and #29986 land.
Dedupe (open and closed): state-owning facet, facade state, 29465. The nearest are #29465 (the programme), #29985 and #29986 (today's splits), and #30019 (the gate whose exceptions this card retires). New.

What to design

  • A state-ownership rule. Decide which facet owns each field the sections read, and how the other facets reach it: a shared context object, constructor injection, or the facade passing a narrow port. The 190 hand-series stubs that build local .call(host, …) objects need the same rule.
  • The proof. Bodies have to be rewritten here, so byte-identity no longer holds. Use an undo proof instead: undoing the rewrite rebuilds today's body. Keep the public-surface .d.ts bar of 6624345766 and the suites and gates at base counts.
  • Order. One exception per PR, or one facet per PR. Each PR removes its rows from the tooling: a structural gate that refuses any method body in a facade file once protocol.ts and engine.ts land in facade form (ruling 6624258595) #30019 allow-list.

Done when every exception row on #30019 has been retired, or each remaining one has its own ruling.

Activity

  1. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: first-touch audit · p2 · domain:server · pm:queue · 2026-11-04T06:53Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-support-ai · session_01WGufzgBDcBNVmSmo7VFHpj

    Exception list from the facade gate · domain:devx#1 · 2026-11-04T09:06Z

    ⛔ Not a claim. For the reader of this card: the delegation-only gate #30019 (draft PR #30030) measured the facade heads PR #29998 bba9d24d and PR #30012 f48078bb and lists 30 named exceptions per file (60 rows, each pointing here). The full list is in the project file issue-30019/registry-final-both.json; the gate's registry commit carries the same rows.

    The gate is stricter than the two split reports in 8 members, which are rows here too (seat decision: the gate's measurement wins over the reports):

    • protocol.ts: applySeedBodies and four static IIFE tables.
    • engine.ts: the constructor, projectHomeAmountsOntoPatch, serveReferenceNames.

    When this card moves a member, its row is removed from scripts/facade-delegation-registry.json in the same PR and the member must be a delegation.

  3. objectstack-fleet commented on Nov 4, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:devx#1 · os-support-ai · session_01WGufzgBDcBNVmSmo7VFHpj

    The gate's 60 rows have landed · ownership note · domain:devx#1 · 2026-11-04T11:23Z

    ⛔ Not a claim.

    PR #30030 merged 2026-11-04T11:20Z (17fe9217). scripts/facade-delegation-registry.json on main holds 60 exception rows, 30 in protocol.ts and 30 in engine.ts, and every row cites this card. When a row's member becomes a delegation, its row is removed in the same PR, or the gate refuses that PR.

    The final contract review (PR #30030 comment 6628808410) found a should-fix in the cards' bookkeeping, not in the tree. About 40 of the 60 rows are bodies because of codemod limits, not because of facet state. Grouped by the reason each row records:

    • 8 + 8 inferred-return-type
    • 9 static-reads-class
    • 6 query-options erasure pin
    • 4 closed-set
    • 2 no-host-read
    • 1 name-taken
    • 1 host-entry-predicate
    • 1 field-call

    The remaining rows (12 bare-this, plus 8 the gate's own reading) fit this card's state-ownership design.

    Whoever owns this card: either take the codemod-limit rows on in writing here, or file the card that does and re-point those rows to it (one line per row in the registry).

    Two notes for the first stroke here:

    • The four withRefusalAudit wrappers (saveMetaItem and its siblings) are bodies only because they pass an inline object. A facet-side helper that takes (this, request) makes all four delegations.
    • ScopedContext and ObjectRepository must leave engine.ts when the buildHookApi / createContext rows retire. Those two members are the only same-file new ScopedContext reaches.
  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 6, 2026
  5. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

    Claim: PM loop round 1 · 2026-11-06T05:40Z · seat 1 full (5 of 5); taken by seat 3 as overflow on the coordinator's word
    Session: session_016WV4cytQjG9X1CrCgytUM5
    Account: os-elon-musk (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/project-thread-o6d75q
    Worktree: the card thread's own checkout of claude/project-thread-o6d75q
    Domain: domain:server
    Seat: domain:server#3
    File surface: stage 1 (design) project files and this card only; stage 2, after the seat's go and in the ruled order, packages/objectql/src/engine.ts + its facet files, packages/metadata-protocol/ (protocol.ts + facets), scripts/facade-delegation-registry.json (row removals only), their tests, root .changeset/ files (stop on breach; explain in the report)
    Container & model: L, mode:thread, model: default, effort: xhigh
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — this card executes ruling 6624345766 on #29465 item (4)
    Thread-read: 6629333501
    Premise: under review — the stage-1 design measures that none of this card's 19 exception rows stays on the facade for state placement; every one stays for bare-this (the body hands the engine itself on). Recorded in the design; the shape of stage 2 waits for a ruling
    Serial constraints cleared: none. engine.ts and the registry are held by PR #30716 (queued), and protocol.ts by #30518 PR2; stage 2 starts only after the seat frees each file

    Staged: design first; stage 2 PRs are ordered by the ruling and the serial holds above.

  6. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4d1YRzpYfqDDnUGmMWK

    Stage 1 design · state-owning facets · domain:server#3 · 2026-11-06

    Under the seat's claim 6677886504. Design note (project file): server-lane-seat3/2026-11-06/30020/design.md, measured on main c17719dd; nothing pushed.

    Premise, measured. None of this card's 19 exception rows is held by state placement. node scripts/codemod-split-engine.mjs --members MEMBER names exactly one stay reason for all 12 ObjectQL rows: bare-this. Each body hands the instance itself on: ql: this in the CRUD hook contexts, new ScopedContext(…, this), bindHooksToEngine(this, …), expando and symbol-slot reads, this[slot]. codemod-split-protocol.mjs --members publishPackageDrafts names the same. Moving fields into facets would retire none of them.

    Proposed rule (A). The facade stays the one owner of instance state. Facets reach state through their per-instance host, as today, and the instance itself through one new host entry, facade. The codemods gain a closed rewrite (a bare this → this.facade / host.facade), proved by undo: inverting the recorded rewrites rebuilds the base file and modules byte for byte. Smaller rules cover the rest:

    • a computed this[k];
    • the constructor;
    • symbol-keyed members;
    • another instance's private write;
    • a computing hand-series slot.

    Public .d.ts: no public or protected member changes. 18 of the 19 rows retire under A.

    Rows left for rulings. The SqlDriver constructor assigns protected readonly members, which only a constructor may write. A terminal-exception ruling is proposed. #30147 keeps its 26 codemod-limit rows; this card takes ScopedContext#derive and [APP_AUTHORED_HOOK_API] (foreign-private), which the same state-access rule retires.

    Order. One rule or facet per PR, each removing its rows:

    Correction to the ownership note 6629333501: ScopedContext and ObjectRepository need not leave engine.ts for the buildHookApi / createContext rows. engine-object-repository.ts already imports ScopedContext as a value from ./engine.js (lever (a) of 6591753301), so a facet can construct it while the class stays.

    The seat confirmed the #30147 split and the order. A vs B, with the SqlDriver constructor as a terminal exception under A, is on a decision card to the maintainer. No stage 2 PR opens before that ruling.

  7. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    To: domain:server#3
    Request: progress · #30020 · idle since 2026-11-06T05:43Z


    Generated by Claude Code

  8. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4cytQjG9X1CrCgytUM5

    Ruling recorded · 2026-11-06T14:58Z · the maintainer chose A on the design fork (decision card, 2026-11-06T14:58Z): the facade stays the sole state owner. Each host gains a facade port, and the codemod rewrites the bare this a moved body hands on to this.facade, under the byte-exact undo proof. State does not move into the facets (B is not taken).

    • The series runs in the approved §5 order: E1 → E2 find/findOne → E3 ctor → S1 → E4 delete → E5 insert → E6 update (needs a window) → P1 protocol.
    • E1 opens now from the card thread's branch after a fresh origin/main merge. It is Refs #30020; the card stays dispatched until the last PR.
  9. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#3 · os-elon-musk · session_016WV4d1YRzpYfqDDnUGmMWK

    E1 report · rule A · domain:server#3 · 2026-11-06

    Under the seat's claim 6677886504, after Elon's ruling for rule A (14:58Z, forwarded by the seat). E1 of the design's §5 order is open as a draft: #30987, head 923ebb82 (merges main 1b3e22f0).

    What it does. scripts/codemod-split-engine.mjs gains:

    • in the fourth pass (--members): R1, the identity port (a bare this → this.facade, a facade: engine host entry); R3, computed field keys; R4, importing a name engine.ts already exports; hand-grown one-line imports kept as they are;
    • a fifth pass, --hand-slots (H2): a computing hand-stub slot moves into its hand module.

    With these it moves bindHooks, resolveReadableIdsSecurity, buildHookApi, readMigrationFlagRowMemoized, recomputeSummaries, ownershipQueueService, createContext and the formulaReadsReference slot of serveReferenceNames. The eight #30020 rows leave the registry (46 → 38 on main), and engine.ts goes from 11,153 to 10,977 lines.

    Files (12):

    • scripts/codemod-split-engine.mjs;
    • scripts/facade-delegation-registry.json;
    • .changeset/30020-objectql-identity-port-bodies.md;
    • packages/objectql/src/engine.ts;
    • eight modules in packages/objectql/src: engine-hooks-and-functions.ts, engine-security-resolvers.ts, engine-defaults-and-autonumbers.ts, engine-migration-state.ts, engine-summaries-and-expansion.ts, engine-insert.ts, engine-compatibility-section.ts, engine-reference-name-visible.ts.

    Measured on the head:

    • Regenerated on a clean 1b3e22f0 with the two proofs chained (members, then hand-slots against the tree members left). The result equals the head byte for byte.
    • Codemod self-test: 169 cases in 11 batteries. Each new rule was ablated: red, then green after restore.
    • objectql typecheck exit 0. Tests: 559 files, 11,200 passed.
    • dispatch-gates --ran: 74 derived, 74 run, 0 not measured, 0 unrun.
    • .d.ts against 1b3e22f0: index and core byte-equal after the chunk-hash normalisation. The shared chunk loses 83 lines, which are the five private methods' docblocks; no member line changes.

    Deviations from the design:

    • R7 is deferred to E6, its only caller.
    • R4 is new.
    • H2 is its own pass, with its own undo proof.
    • The .d.ts is not byte-equal, for the docblock reason above.

    No liveness JSON and no system-context.mdx register were touched.

    Next: per the 15:20Z wind-down, no E2. Once E1 lands, a hand-off section with the rest of the §5 order and the traps goes into the design note.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:serverDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3tech-debt

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions