Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 77 additions & 0 deletions devlog/_plan/260905_now_split_train/000_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# 260905 — RESOLVABLE_NOW split train (stacked PRs)

Date: 2026-09-05. Worktree a2c0, docs branch `codex/260905-modular-debt-ledger-docs`
at 4cc219549 (source basis 980a9fbed; origin/dev tip at unit open 583d6a91b,
6 commits ahead, only one of which touches a NOW file — see 001). Session
01a06e97-b9d8-7250-8204-bb788338c288, goalplan
`.codexclaw/goalplans/reduce-the-68-resolvable-now-modularization-debt/`.
Input ledger: `devlog/_plan/260905_modular_debt_ledger/021_ledger.md` (68 rows
with `RESOLVABLE_NOW`); lane evidence in that unit's 011–016.

## Objective

Bring each of the 68 files under the cxc-dev §1 400-line limit by pure-move
splits (leaf modules + barrel re-exports), published as stacked PRs against
`dev`, each layer independently reviewable and mergeable. Zero behavior
change; every existing export stays importable from its original path.
Per-file success is `RESOLVED` or `RESIDUAL-FN` (003 RESIDUAL-ACCOUNTING-01);
the closeout tallies both and only the first counts as resolved.

## Constraints (binding on every layer)

- Pure move only. No renames of exported identifiers, no signature changes,
no deletion of exports, no "while I'm here" fixes. A behavior defect found
during a move is recorded in the decade doc and left alone.
- New leaf files ≤400 lines; the residual original file ≤400 lines or the
layer states why a second layer (`#b`) follows (003 INTERMEDIATE-RESIDUAL-01,
RESIDUAL-FN-01).
- The ≤500-line PR cap is measured on the non-move diff for pure-move layers
(003 PURE-MOVE-SIZE-01); non-move diff ≤150 lines.
- Re-export binds nothing locally (260818 WP1 lesson): internal call sites in
the residual file import from the leaf explicitly.
- Text-oracle tests that read a split file as source (001 column
`textoracle`) are retargeted to the leaf **without weakening**; the
decade doc names each and the C phase drives the retargeted guard red once
when it is a guard.
- `tests/lab/core-lab-boundary.test.ts` PROTECTED roots are never edited;
a new leaf imported from a protected root must not reach `src/lab`.
- Verification from WP400 onward: typecheck, focused tests, privacy scan and
full suite run in an isolated checkout on `ssh lidge`; no local suites.
- Git: layer branches `codex/split-<slug>`; bottom layer base `dev`, each
upper layer base = the branch below; push + PR creation pre-authorized by
the user for this loop; **merge never** (DEV-STACK-04 ESCALATE). Cascade
with `git rebase --update-refs` + `--force-with-lease` when a lower layer
changes (DEV-STACK-02).
- Open-stack depth cap: 5 dependent PRs. S04 contains six total layers,
including prerequisite layer 105, but STACK-INDEPENDENCE-01 replaced the initial
six-deep linear proposal: its longest current base chain is 3. Across the
77-layer map, the longest planned chain is 4. The former S04 depth-six
exception is historical, not permission to create a six-deep stack now.
- From WP400 onward, code and receipts use the existing a2c0 worktree in
place (003 WORKTREE-EVIDENCE-01). Preserve each previous branch before
selecting the next layer branch. Never relocate or recreate a2c0.

## Work-phase map (dependency-ordered)

| WP | Deliverable | Depends on | Verifier |
|---|---|---|---|
| wp1 | 000–003, including binding parent decisions, + every layer's decade doc (010…750) at diff level | — | docs checks (numbered only, every layer has a doc, every NOW file appears in exactly one stack, 003 amendments agree with 000/002 and the layer plans); privacy scan |
| wp2… | one layer per work-phase, dependency-ordered by the base edges in 002; independent groups may be interleaved | its declared base layer, if any | the current decade document's Verification and Accept criteria sections |

Total: 77 implementation layers across 21 stacks (002_layer_map.md; 105 and
625 appended per 003).

## Out of scope

The 151 `RESOLVABLE_AFTER` and 19 `ACCEPTED` rows; core.ts / config.ts /
service.ts / auth-api.ts; merges; releases.

## Terminal outcome expected

DONE when every layer in 002 has an open PR with a green exact-head CI rollup
recorded in its decade doc.

## Completion spine

- WP400 closed through C→D with head `bbf8d3cd25ccf70eb595bc7982f63528d060c1bd`, ready PR #3611 against dev, clean remote receipt, all current logical CI checks passed/configured-skipped, and zero unresolved review threads. The CLI returned to IDLE and immediately entered P for WP450. The 1298-line facade still has its declared WP410 successor; this is layer completion, not completion of all68files.
- Earlier layer records remain in their decade documents. Global criterion c-5 still requires final reconciliation, including the known older verification debts; no whole-goal completion is claimed.
205 changes: 205 additions & 0 deletions devlog/_plan/260905_now_split_train/003_parent_decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
# 003 — Parent decisions on drafter escalations (binding amendments to 000/002)

Twenty-one drafters (one per stack) returned 75 decade docs. Fourteen of them
escalated the same conflict and six raised stack-specific questions. Each
decision below is an amendment to 000_plan.md constraints and is what the
A-phase audits and every executor obey.

## PURE-MOVE-SIZE-01 — the ≤500-line changeset cap for pure-move layers

Conflict: cxc-dev §1 says "PR changeset >500 lines → split" (DEFAULT class:
exceed only with a stated reason). A pure move of a file that must lose
≥1,000 original lines produces ≥2,000 raw diff lines however it is layered;
adding layers only multiplies fully-gated PRs and leaves intermediate residuals
over 400 with no review benefit (S02, S03, S05, S07, S08, S10, S11, S13, S15,
S16, S19, S20, S21 all showed this arithmetic).

Decision (stated reason for exceeding): for a layer whose decade doc classes
it as pure-move, the 500-line cap is measured on the **non-move diff** — the
lines that are not a verbatim relocation: re-export blocks, import edits in
the residual and in consumers, test retargets, route-registry metadata. That
non-move diff must stay ≤150 lines per layer. Moved lines are reviewed as
moves: the PR body links `git diff --color-moved=dimmed-zebra` guidance and the
executor's C phase records `git diff -M --stat` plus a symbol-inventory check
(every symbol in the doc's inventory appears exactly once in the tree after
the move).

Permitted transformations of a moved line (still pure-move):

1. Adding or removing the `export` modifier on a moved declaration (a leaf must
export what the residual re-exports; a symbol that was module-private and
is now consumed only inside its leaf may stay private).
2. Changing the import specifier path of a moved symbol's own imports.
3. Object-literal method → factory-produced function when an adapter's
returned object literal is split across leaves (S03 Anthropic #b,
`createAnthropicAdapter` returns `{ ...methods }` capturing lexical
`provider`/`toolNames`): the method body is moved verbatim into a
leaf function `makeX(captured…)` whose parameters are exactly the
lexical bindings the body captures, called once inside the original
factory so the returned property becomes `x: makeX(provider, toolNames)`.
Capture identity and invocation lifetime are preserved because the
factory is invoked in the same closure scope the literal was built in.
Evidence: the C phase pastes `git diff --color-moved=dimmed-zebra
--color-moved-ws=allow-indentation-change` for each converted method and
shows the body as a move block; the layer's focused tests cover every
converted method (listed in the doc's Tests section). The same rule
covers a class method split by `this`-fields, should one occur.
4. JSX block → sibling component with verbatim props (GUI-SEAM-01).

Anything else (reordering statements inside a moved body, renaming, changing
a literal, altering control flow) is not pure-move; the layer falls back to
the literal 500-line cap or is re-sliced.

The layer count in 002 stands as drafted; no stack is re-sliced for size.

## RESIDUAL-FN-01 — residual >400 caused by a single function

S07 L1: `parseRequest` is 464 lines by itself, so `src/responses/parser.ts`
cannot reach ≤400 by moving other symbols. Splitting the function is a
behavior-preserving extraction, not a move, and is out of this train's scope.
Decision: the layer moves everything movable, the residual stays over 400,
and the doc records the function as `RESOLVABLE_AFTER(design:L1-parse-request-extraction)`
for the 021 ledger's next revision. Same rule applies to any other layer that
finds a single >350-line function (none other reported).

## INTERMEDIATE-RESIDUAL-01 — over-400 residuals inside a multi-part file

S13 (config-export #a), S18 (IntegrationsOverview), S21 (release-notes #a),
S02 (registry #a/#b): an intermediate residual over 400 is acceptable when a
**bounded successor chain inside the same stack** brings it under 400 and
each doc states the number it hands to the next layer (registry:
3250 → 2429 → 1267 → 219 across #a/#b/#c). S18 had no next layer: **layer
625 (IntegrationsOverview #b)** is appended to 002 and drafted by the same
agent.

## RESIDUAL-ACCOUNTING-01 — what "done" means for a file

000's objective is amended: the train's success measure is per file, one of
`RESOLVED` (residual ≤400 and all leaves ≤400), or `RESIDUAL-FN` (residual
>400 solely because of one unsplittable function, recorded per
RESIDUAL-FN-01 with the `design:` id for the ledger). The closeout doc
tallies both; a file in the second bucket is *not* counted as resolved. At
draft time exactly one file is expected there: `src/responses/parser.ts`
(561, `parseRequest`).

## TYPE-CYCLE-01 — pre-existing type-only cycles

S04 L1 reports `src/types.ts → src/types/provider.ts → native-exec-desktop.ts
→ native-exec-tools.ts → tool-definitions.ts → src/types.ts`; S02 reports an
Antigravity type cycle. Both pre-exist on `dev` and are erased at runtime.
Decision: a layer must not add a **runtime** cycle and must not add a new
type-only cycle; it may leave existing ones untouched. The audit checks the
delta, not the whole graph.

S04 is the exception: its new leaves would each join the existing type cycle
(`tool-naming → ../../types → provider → native-exec-desktop →
native-exec-tools → tool-definitions → tool-naming`), which is a *new* cycle
through new files. Decision: the prerequisite the S04 drafter named is
approved and becomes **layer 105 (`codex/split-cursor-desktop-executor-contract`,
base `dev`, new bottom of S04)**: move `DesktopExecutorConfig`
(`src/adapters/cursor/native-exec-desktop.ts:28–37`) to a new dependency-free
`src/adapters/cursor/desktop-executor-contract.ts`, keep it exported from
`native-exec-desktop.ts` via `export type { DesktopExecutorConfig } from
"./desktop-executor-contract"` plus a local `import type`, and retarget the
inline `import("../adapters/cursor/native-exec-desktop").DesktopExecutorConfig`
at `src/types/provider.ts:701` to the contract file. Type-only, zero runtime
effect; breaks the provider → desktop-implementation edge for good. 110's
base becomes `codex/split-cursor-desktop-executor-contract`. S04 has six
members including 105. The original linear proposal called that depth 6 and
made an exception; STACK-INDEPENDENCE-01 below superseded that topology.
Current planned parents are 105→dev, 110/120/130→105, 140→130, 150→110.
Thus S04's maximum dependent depth is 3, and the five-layer cap still applies.

## COMPANION-EDIT-01 — allowed edits outside the split file

- S09 L2/L3: `src/server/management/route-registry.ts` module-path metadata
for routes whose handler moves to a leaf — allowed (it is the route table's
pointer to the owning file; the registry test enumerates siblings).
- S02 L3: one `import type` path change for FastWire types — allowed
(type-only, no runtime effect).
- Consumer import edits are only allowed when the doc lists them; default is
that consumers keep importing from the original path via re-export.

## GUI-SEAM-01 — React component extraction as the seam

S17 (Storage policy panel) and other gui layers: extracting a JSX block into a
sibling component file with its props passed through verbatim counts as a
pure move for this train when the rendered tree is unchanged. Verification for
such layers adds the GUI checks: `bun run lint:gui`, `bun run build:gui`, and
a before/after screenshot of the affected page attached to the PR (the
`enforce-target` gate requires a screenshot for gui PRs anyway).

## STACK-INDEPENDENCE-01 — stacks whose layers do not depend on each other

DEV-STACK-01 says independent parts go as parallel PRs off trunk. The
original 002 chained every stack by directory. Decision, applied **per
layer** to every stack: a layer's base is the nearest lower layer in its
stack that it imports from (001's 47 edges) or that is a `#`-part of the
same file; S04 layers additionally base on the 105 type-contract layer;
otherwise the base is `dev`. 002 is regenerated with this rule (29 chained
layers, 48 `dev`-based). The stack id still groups execution order and PR
stack-map navigation; a `dev`-based layer's PR body still shows its stack's
map but states "base: dev — no dependency on the layers below". Each decade
doc's PR section is the authority for its own base and must match 002.

## S06-ORACLE-01 — correcting 002

002's S06 thesis said "47 text oracles retargeted". The drafter showed the
count came from a broad `index.ts` basename match; no test reads
`src/vision/index.ts` as text. 002 is corrected to "no text oracle; three
recursive source-walk guards must include the new leaves".

## S10-SIZE-01 — resolved by PURE-MOVE-SIZE-01

prompt-layers stays two layers (518 + 913 moved lines) under the pure-move
measure.

## WORKTREE-EVIDENCE-01 — real implementation and receipt identity

Each active decade document owns its branch and pinned base. The verifier
derives the tested layer head from the clean current branch and matches the
fetched remote branch; a base commit is never substituted for that head.
Scoped CI reruns and repair work are authorized; no local suite or merge is requested.

Closed WP400 example: branch `codex/split-clients-config-export-a`, PR #3611,
base dev at `be81013fab6d83ff630ca5f38e7881678a303871`, final verified head
`bbf8d3cd25ccf70eb595bc7982f63528d060c1bd`. #3610 had already landed as
`5ab8aa9a2d9d2a3926469f9d8c82387b43c6d0e9`; it is not an open prerequisite.

Historical only: WP400 temporarily used #3610 at
`afdd38ff43c64696153372fc2e27a38aff208c73` to separate a verification fix
from the split. That older basis and its open-parent workflow are retired.
The historical evidence remains in400; do not execute it as the current plan.

The original dedicated-worktree execution choice conflicts with the FSM's
checkout-local source identity. Operational audit by Wegener found no
separate supported execution-root binding: `--cwd` selects both state and
source. The main agent amends its own topology choice, not the user's scope.

From WP400, preserve the docs branch and every completed layer branch, then
create the current layer branch in the same a2c0 directory from its pinned
base. Carry 000, 003 and the current decade doc as tracked layer documentation;
the complete roadmap remains on `codex/260905-modular-debt-ledger-docs` and
can be read by immutable commit/ref. The ignored `.codexclaw` state stays
in a2c0; do not copy, hand-edit or relocate session state. Actual source edits
must occur there during B. Commit the layer before C and preserve that HEAD
through its receipt and C→D. Source changes from another checkout cannot be
represented by a documentation-only delta.

All tests from WP400 run remotely. Each run uses its own mktemp checkout,
fetches the layer branch, and requires the fetched SHA to equal a2c0 HEAD.
Never switch or reset the shared remote seed checkout. Install root and GUI
dependencies with frozen lockfiles, then typecheck, focused checks, privacy
scan and full suite. Preserve full output and propagate each actual exit
code, including SSH transport failures. Failed or incomplete gates keep the
layer unverified; do not synthesize a passing receipt. Retain temporary
checkouts/evidence until scoped cleanup is authorized.

Use the active decade document's complete isolated Bash recipe from C.
WP400 supplies the verified pattern; substitute the active layer's own branch,
test list and evidence names instead of reusing WP400's targets.
It checks the clean local layer HEAD, fetched remote HEAD and final remote
state, while preserving output and failures inside the receipt command.
No local Bun test command is allowed. Older shared-checkout recipes must not
be reused; each current plan must supply its isolated verifier. Availability
and success require real execution evidence.
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# 445 — Runtime verification prerequisite

## Scope and workflow

C3 independent runtime-maintenance prerequisite for the modularization train.
PR #3640 uses branch `codex/fix-port-probe-peer-disposal`, base `dev`.
Its production and test diff is the review surface. Investigation, negative
controls, failure analysis and reproduction records remain in ignored scratch,
not public devlog. Publication of the final retrospective waits for release.

Bound session: `01a06e97-b9d8-7250-8204-bb788338c288`; same a2c0 checkout
owns implementation, persisted PABCD and receipts. Main owns Git/PR/CI.
Delegation uses gpt-6-astra high with disjoint source/test ownership.
No merge, release, live-service change or repository-wide setting change.

## Planned files and acceptance

- `src/server/ports.ts`: bounded existing-owner maintenance; preserve public
exports, caller interfaces, error handling and selection policies.
- `tests/server/ports.test.ts`: scoped regression coverage; preserve the
original test cases and isolate test doubles from the parent process.
- `structure/01_runtime.md`: ownership row only.
- This public scope record and the carried000/003 workflow documents.

Keep source/tests below400lines and added functions below50lines. Do not
weaken assertions, alter verification thresholds or mark a failed check passed.

All runtime verification is remote. Use the reviewed source-bound receipt
recipe stored in ignored evidence: check clean expected HEAD before/after
SSH, create a fresh isolated clone, match fetched branch SHA, frozen dependency
setup, explicit package Bun1.4.0, build, typecheck, focused subsystem/boundary
tests, privacy, full suite, and final clean HEAD. Preserve full output and
actual exits. No local suites or typecheck; no shared-checkout reset.

Independent review, exact-head remote gates and hosted CI must pass. A prior
head's results do not establish a later head. Detailed verification records
are kept with private receipt evidence; no completion is inferred from a plan.

## Continuation and coordination

This work does not close a modularization ledger row. D resumes suspended
WP450 for its own P/A, restack and fresh verification; do not count it done.
PR #3633 remains independent until that controlled restack is performed.

The user requires conversational one-at-a-time non-Windows CI coordination.
Windows-owner work remains excluded. Changes that start CI, including pushes,
retargeting and landing, require the scheduled slot. Code/static review may
continue while waiting. Scope authority is already granted; a queue wait is
not a request for more user permission.

## Review disposition

A reviewer identified that the previous version mixed investigation records
with this public scope document. Those details were moved to ignored scratch
and removed from the current public document. Earlier published commits may
still be accessible; this change is not a history-purge claim. The actual
source/test review and all verification requirements remain unchanged.
Loading
Loading