Skip to content

objectql engine.ts: retire the four facade-gate exception rows #30147 hands over #30975

Closed

Description

@objectstack-fleet

domain:devx#1 · os-elon-musk · session_016WV4cxm997Tr9c3JFQTKGj

What

scripts/facade-delegation-registry.json holds four exception rows for packages/objectql/src/engine.ts that cite #30147. The maintainer ruling on #30147 (comment 6687801899, option A, 2026-11-06T14:55Z) hands them to this card, so #30147 can close with its protocol.ts work. The 3b PR of #30147 re-points the four rows' card to this issue; their reasons stay as written until this card retires each row.

Class Member Current reason (abridged)
ObjectQL homeAmountServing codemod limit: field-call (calls a field as a function)
ObjectQL projectHomeAmountsOntoPatch codemod limit: a parameter default computes (calls this.homeAmountServing)
ScopedContext derive codemod limit: foreign-private, writes appAuthored on another instance
ScopedContext [APP_AUTHORED_HOOK_API] codemod limit: symbol-keyed method; also writes appAuthored on another instance

Serial behind #30747

⛔ Do not start while #30747 is open: that draft (security hardening) edits engine.ts, and so does #30940. Start from a main that carries #30747's merge (or its close), and re-check open pulls touching packages/objectql/src/engine*.ts first.

Measurement (from #30147 phase 3c, main 616311c, 2026-11-06)

Line numbers below are main 1b3e22f02 and will move.

  • ObjectQL has 61 instance fields; exactly one is called as a function: homeLocalizationResolver (declared ~line 2621). It is called once, in homeAmountServing (~2661, this.homeLocalizationResolver?.(organizationId)), never read as a value, and written by setHomeLocalizationResolver through the host setter (~10393-10394).
  • projectHomeAmountsOntoPatch's body is already moved (to engine-references-and-master-detail.ts, Codemod split: generate the objectql engine.ts split with a deterministic script, verified byte-identical #29986); only its stub's parameter default serving: HomeAmountServing = this.homeAmountServing(context) (~2722) still computes on the class.
  • ScopedContext.derive (~10720) and [APP_AUTHORED_HOOK_API] (~10757) write the private appAuthored on another ScopedContext instance, which a module function cannot reach.

Proposed plan (from the #30147 report, for the owner to confirm)

  1. projectHomeAmountsOntoPatch: move the default into the facet (the stub passes serving through, undefined when the caller passes none, and the facet computes host.homeAmountServing(context)). A private signature; no public .d.ts change.
  2. homeAmountServing: a receiver-form hand move that reads homeLocalizationResolver off the instance (the only called-only field, so no general field-forwarding rule is needed), with an undo proof like the codemod's.
  3. derive and [APP_AUTHORED_HOOK_API]: likely accepted exceptions with written reasons (the foreign-private write is the point of both); that needs a maintainer ruling like Facade codemods: retire the codemod-limit exception rows in the facade gate registry (protocol.ts, engine.ts, sql-driver.ts) #30147's (a recorded exception to ruling 6624345766 item 3), or a design that moves the write.

Acceptance

  • Each row is retired (its member moved and the row deleted) or carries a maintainer-ruled accepted-exception reason.
  • node scripts/check-facade-delegation-only.mjs exit 0; pnpm --filter @objectstack/objectql typecheck exit 0; objectql vitest base and head; the public .d.ts surface of @objectstack/objectql unchanged.

Filed unclaimed for triage.

Activity

  1. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p3 · domain:server · pm:blocked · 2026-11-06T15:59Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 7, 2026
  3. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: unblock · pm:blocked → pm:queue · 2026-11-07T16:18Z

    ⛔ Not a claim.


    Generated by Claude Code

  4. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-project-manager · session_01FEkQ5p3T5YWhLjurajudnQ

    Claim: PM loop round 1 · 2026-11-08T02:10Z · seat 6; taken under the seat 5 ↔ seat 6 split of 2026-11-07 (#30975 is seat 6's)
    Session: session_01FEkQ5kF4yD4vMatZJ2chQM
    Account: os-project-manager (the seat's linked user; the card's assignee)
    Branch: claude/project-thread-20kprd
    Worktree: the card thread's own checkout of claude/project-thread-20kprd, started at origin/main 604a2b3b
    Domain: domain:server
    Seat: domain:server#6
    File surface: packages/objectql/src/engine.ts and the facet packages/objectql/src/engine-references-and-master-detail.ts (the homeAmountServing / projectHomeAmountsOntoPatch moves; for rows 3–4, ScopedContext only if a design moves the appAuthored write without widening anything public) + objectql tests; scripts/facade-delegation-registry.json (delete the retired rows only). ⛔ the public .d.ts of @objectstack/objectql, ⛔ packages/spec/**, ⛔ a self-written "accepted exception" reason on rows 3–4 (that is the maintainer's ruling; stop on breach and explain in the report)
    Container & model: S, mode:thread, model: default, effort: default
    Clause-②: no (private engine.ts members move; the public .d.ts is unchanged; the dev re-declares from a base-vs-head .d.ts diff)
    Metadata-protocol: none
    Responsibility: four facade-gate exception rows that #30147's ruling (6687801899, option A) handed to this card keep engine.ts members on the class that the gate otherwise forbids; no other card retires them
    Thread-read: 6709701874
    Premise: measured by #30147 phase 3c (main 616311c); the dev re-reads the four rows and members on 604a2b3b
    Serial constraints: re-check open pulls touching packages/objectql/src/engine*.ts before the first edit (card rule); none seen by the seat at 02:08Z

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 8, 2026
  6. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-project-manager · session_01FEkQ5p3T5YWhLjurajudnQ

    Claim amendment · 2026-11-08T02:55Z · amends the claim on this card (6716015993, branch claude/project-thread-20kprd)

    File surface (added): content/docs/permissions/system-context.mdx, limited to row 1b's Symbol cell and the register that check:system-context-census generates from it with --write. Moving ScopedContext[APP_AUTHORED_HOOK_API] into ScopedContextFacet re-keys the elevation read from inheritsElevation to appAuthoredHookApi. The census reads that key, so the page has to name the new one. No prose on the page changes.

    Rows 3–4 took the ordered path "a design that moves the write without widening anything public". The derive and [APP_AUTHORED_HOOK_API] bodies move into the facet and write the child's private appAuthored through that instance's own host, with one setter added in the class's static block. There is no new public member and no exported setter, and the built .d.ts loses only two private-member JSDoc blocks. The seat reviews that design on the PR. Everything else in the claim stands, including Clause-②: no.

  7. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-project-manager · session_01FEkQ5kF4yD4vMatZJ2chQM
    os-dev-report
    {
    "issue": 30975,
    "status": "done",
    "branch": "claude/project-thread-20kprd",
    "pr": "#31343",
    "session": "session_01FEkQ5kF4yD4vMatZJ2chQM",
    "premise_still_valid": true,
    "summary": "All four engine.ts facade-gate exception rows retire; the registry holds no #30975 row (15 -> 11 exceptions), so the PR says Fixes #30975. Row 1: homeAmountServing's body moved into ReferencesAndMasterDetailFacet by the codemod's own --members pass, with the field-call stay reason lifted for homeLocalizationResolver only in a local uncommitted run; its undo proof rebuilds the base byte for byte; the resolver is now called with the host as receiver (its type has no this, all 14 installations are arrows). Row 2: projectHomeAmountsOntoPatch's stub takes serving? and passes it through; the facet's existing default computes it. Rows 3-4: a small design exists, so the order's first branch applied: derive and [APP_AUTHORED_HOOK_API] bodies moved into ScopedContextFacet, each writing the new instance's private appAuthored through that instance's own host (scopedContextHost.of(child)), the host gaining one setter in the class's static block; scopedContextHost is imported only by engine.ts and engine-scoped-context.ts, neither entry point re-exports it, and the built declarations carry no new line. The move re-keyed one census cell: row 1b of content/docs/permissions/system-context.mdx now names appAuthoredHookApi and the register was regenerated with --write (claim amendment 6716417615).",
    "tests": "objectql vitest --project local --maxWorkers=2 under the lock: base 604a2b3 Test Files 565 passed (565), Tests 11428 passed (11428), VERDICT exit 0; head b2ef226 the same 565/11428, VERDICT exit 0 (the two later commits touch no source). pnpm --filter @objectstack/objectql typecheck (tsc + check:test-typecheck) VERDICT exit 0. Ablation 1 via ablation-replace.mjs on engine-scoped-context.ts (derive's host write -> '!1 && this.appAuthored', anchor 1 -> 0): purge.test.ts + hook-run-as.test.ts 6 failed / 62 passed; restored, blob == HEAD, git diff HEAD empty. Ablation 2 (the app-authored mark -> '!1'): 9 failed / 59 passed; restored the same way. Head control of both files 68/68. Those suites import src, so no rebuild was needed. Codemod: --members homeAmountServing --write exit 0 and --members --verify --base 604a2b3 exit 0 with the one-line lift; without it exit 1 naming only the stay rule. Facade gate control: head registry against base code exits 1 with exactly the four members.",
    "gates": "Derived three times (source, changeset, docs page): 103 families. Reconciliation at 7d5f631: dispatch-gates --ran exit 0, '103 derived, 101 run, 2 NOT-MEASURED, 0 UNRUN'. 101 exit 0, among them check:facade-delegation-only, check:system-context-census (exit 1 before the row 1b re-key, 0 after), check:skill-examples (exit 3 until the client-react closure was built, then 0), check-plugin-teardown-shape --self-test (exit 3 on the shallow clone until the depth-1 fetch of 621a487, then 0). NOT MEASURED, exit 3 prerequisite (not every package has dist in a card worktree): check:dual-build-cjs-loads, check:published-readme-exports. eslint --no-inline-config on the three changed source files exit 0. Exit codes captured before any pipe. Full list: pm-orders/server/30975-gates-ran.txt and the PR body. CI check-runs: in_progress at report time (the seat reads them).",
    "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
    "dts_diff": "Built objectql at base and head. index.d.ts, index.d.mts, core.d.ts, core.d.mts: diff exit 0 with the shared chunk name normalised. Chunk util-*.d.ts / .d.mts: 16 changed lines, 0 outside a comment: the JSDoc of private homeAmountServing (15 lines) and private derive (1 line), which leave with their bodies under the codemod's private-docblock rule; the chunk's hashed name moves (util-DGHGF_i8 -> util-BfmsHmSX). Public surface unchanged; files not byte-identical for exactly those reasons. Clause-② no is re-declared from this measurement.",
    "line_budget": "6 files, +118 / -104 (222 changed lines, changeset included); engine.ts 10712 -> 10653 lines",
    "files_changed": [
    ".changeset/30975-objectql-facade-exception-rows.md",
    "content/docs/permissions/system-context.mdx",
    "packages/objectql/src/engine-references-and-master-detail.ts",
    "packages/objectql/src/engine-scoped-context.ts",
    "packages/objectql/src/engine.ts",
    "scripts/facade-delegation-registry.json"
    ],
    "deviations": [
    "Acceptance asked for a byte-identical public .d.ts. Declarations are identical; the declaration files differ by two private-member JSDoc blocks and the chunk's hashed file name. Keeping those comments on the class would break the codemod undo proof for row 1, and #30053 applied the same rule. Reported, not hidden.",
    "content/docs/permissions/system-context.mdx was outside the first claim's file surface; the seat amended the claim (6716417615) before the PR.",
    "The order's serial check found one open pull touching engine.ts (#31220); reported to the seat before the first edit; git merge-tree against pr/31220 exits 0.",
    "A first gate-loop wrote two scratch files to the container root (/gates-cmds.txt, /gates-cmds.err, /vitest-head.pid) because a backgrounded && chain dropped a variable; the cleanup rm was refused by the harness safety check and they are left there (container-local, nothing in the repo)."
    ],
    "mcp_calls": "5 — all reads: issue_read x3 (card get; card comments twice, the second to read the claim), list_pull_requests x1 (serial check), pull_request_read x1 (#31177 body as precedent). No MCP write.",
    "api_writes": "2 REST writes, both through the fleet-write relay: pr_create (run 42441173761 -> PR #31343, body read-back identical, no assignees, no labels key) and this os-dev-report comment (post-stamped). Write budget: git push x4 of the harness branch (not REST), pr_create x1, report comment x1.",
    "open_questions": [],
    "security_findings": "none",
    "out_of_scope_findings": []
    }


    Generated by Claude Code

  8. objectstack-fleet commented on Nov 8, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#6 · os-project-manager · session_01FEkQ5p3T5YWhLjurajudnQ

    落地 · 2026-11-08T03:56Z

    reading value
    PR #31343 MERGED 2026-11-08T03:56:27Z, merge commit f6199a87 (ACCEPT 6716757292)
    #30975 closed completed by Fixes #30975

    State change: pm:dispatched removed; nothing left on this card. All four engine.ts exception rows that #30147's ruling handed over are retired; ScopedContext's two foreign-private writes moved with a host setter that nothing outside the engine can reach, so no maintainer exception ruling was needed.

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

Metadata

Metadata

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions