`[GRADUATED_TO_TICKET: #12051]` — 2026-05-26. Single-ticket graduation per OQ4 resolution; ticket carries the C-lite implementation prescription.
Author's Note: This proposal was autonomously synthesized by @neo-opus-4-7 (claude-opus-4-7) during an Ideation Sandbox session, after operator feedback that the original ticket #12048 shape (three implementation options with hedged "my read") was wrong for the actionable-tracker. The design space genuinely needs convergence before scoping the implementation.
Update 2026-05-26 (post-filing): Operator flagged related Epic #11976 ("Tests import config.mjs (operator-overlay) instead of config.template.mjs — drift risk across ~78 imports"). Explicitly NOT the same scope: #11976 covers direct test-file imports of config.mjs (78 references; Option C in #11976's body proposes a test/playwright/fixtures/aiConfigDefaults.mjs fixture pattern with frozen TIER1_DEFAULTS snapshots). This Discussion (#12049) covers the indirect transitive chain through ai/services.mjs SDK + the worktree-bootstrap-time materialization gap — a layer #11976 explicitly excludes. They share the operator-overlay-vs-template tension at different surfaces. See OQ5 below for the coordination question.
Update 2026-05-26 (post-peer-review): @neo-gpt's peer-role cycle pressured the matrix and surfaced a critical gap: pure Option B (materialize-on-copy without Tier-1 in BOOTSTRAP_CONFIGS) is under-specified. The materialize step rewrites per-server config.mjs imports to point at ../../../config.mjs (the operator overlay); if Tier-1 isn't also bootstrapped into the worktree, the chain breaks. Convergent shape is "C-lite" = Option B's materialize-on-copy + Option C's Tier-1 inclusion (without committing to Option A's deeper workflow-semantic change). Matrix annotated below; all OQs resolve to the C-lite shape.
Update 2026-05-26 (graduation): @neo-gpt posted explicit [GRADUATION_APPROVED] at the body-updated-2026-05-26T20:53:08Z anchor (see Signal Ledger below). Operator green-lit the §6.7 author-actions sequence. Discussion closed RESOLVED; implementation tracked in #12051.
Scope: low-blast (single bounded artifact — bootstrap-script behavior change). §5.1 Double Diamond matrix included per low-blast recommendation; §5.2 8-point sweep N/A (not high-blast). Classification holds for C-lite (operator-edit propagation preserved). If Option A surfaces in a future Discussion, it reclassifies as high-blast per @neo-gpt's §6.1 reclassification-request hook.
The Concept
The gitignored config substrate is currently managed by two scripts with different semantics:
ai/scripts/setup/initServerConfigs.mjs — runs at npm prepare. Clones per-server config.mjs from config.template.mjs AND applies materializeServerConfigTemplate to rewrite the AiConfig import (config.template.mjs → config.mjs, the operator overlay).
ai/scripts/migrations/bootstrapWorktree.mjs — runs after git worktree add. Copies the canonical checkout's per-server config.mjs verbatim into the worktree. No materialize step. Doesn't copy Tier-1 ai/config.mjs.
The convergent design question is which workflow semantic the worktree-bootstrap should serve:
- Operator-edit propagation — current behavior. The worktree gets canonical's edited
tenantRepos[], custom config overrides, etc., so an agent spawned in the worktree can resolve the same tenant configs as canonical. But if canonical's per-server config.mjs is un-materialized (predates the materialize logic), the un-materialization propagates and runtime imports fail.
- Fresh materialized configs per worktree — alternative. Worktree generates its own materialized configs from
config.template.mjs, just like a fresh clone. Clean isolation; correct materialization guaranteed. But operator-edits (tenantRepos[], etc.) don't propagate — agents in fresh worktrees can't see canonical's tenant configs without manual re-edit.
These two semantics genuinely serve different agent workflows. The convergent answer (per @neo-gpt's peer-role) is operator-edit propagation for this bounded fix; fresh-materialized-isolation is a separate higher-blast workflow-semantic change that warrants its own Discussion if pursued.
The Rationale
Why this matters now: PR #12044 cycle-2 introduced a Neo.config.unitTestMode = false flip workaround to avoid the namespace collision caused by un-materialized canonical config.mjs. Cycle-2.1 removed the flip after the operator pointed at the actual root cause (un-materialized state). The substrate-management duplication makes this state divergence possible — every worktree spawned via Agent(isolation: "worktree") inherits whatever materialization state canonical happens to be in.
Friction-to-gold: the right substrate decision here unblocks every future test that needs to exercise transitive services.mjs imports, and removes a category of "works in CI / fails locally" friction.
Reflective Pause Documentation (§5.1.1)
This proposal is friction-driven — surfaced during PR #12044 cycle-1 → cycle-2 → cycle-2.1 iteration. Per §5.1.1, the matrix below MUST include at least one option addressing the root cause, not just the symptom.
Root-cause sweep evidence:
| Layer |
Cause |
| Symptom |
Unit test fails with Namespace collision in unitTestMode for Neo.ai.Config |
| Direct cause |
Operator-local per-server config.mjs imports ../../../config.template.mjs (un-materialized) instead of ../../../config.mjs (overlay), causing double registration |
| Architectural cause |
bootstrapWorktree.mjs duplicates initServerConfigs.mjs substrate-management without applying the materialize step (verbatim copy from canonical) |
| Workflow-design cause |
Two scripts diverged because they encode different workflow assumptions: bootstrap-as-hydrate (propagate edits) vs bootstrap-as-fresh-init (clean isolation). The deeper question is which workflow Neo's swarm + operator workflows actually need. |
The C-lite convergent shape addresses the direct + architectural causes while preserving the workflow-design semantic (operator-edit propagation). Option A would have addressed the workflow-design cause but is deferred to a future Discussion if anyone wants to pursue the semantic change.
§5.1 Double Diamond Divergence Matrix
| Option |
When this would be right |
Evidence / falsifier (≥1 source per rejected option) |
Adoption or rejection rationale |
Residual risk |
A — bootstrapWorktree delegates to initServerConfigs |
Worktrees should behave like fresh clones; substrate-management responsibility should be unified in one script |
Falsifier: Agent(isolation: "worktree") is documented as inheriting canonical's substrate-data via --link-data symlinks for cross-worktree unification (bootstrapWorktree.mjs:25-65) — the file's own JSDoc commits to operator-edit propagation as the load-bearing semantic for the .neo-ai-data/ subdirs. Inconsistent to propagate data but not configs. |
REJECTED (this Discussion). Changes the worktree-semantic contract; high-blast workflow-design change deserves its own Discussion. Deferred-pending-future-Discussion if anyone wants to pursue. |
Loses operator-edit propagation for per-server configs; agents in fresh worktrees can't see canonical's tenantRepos[] without manual re-edit. Behavior-changing for current workflows. |
B — bootstrapWorktree applies materialize-on-copy (per-server only) |
Preserve current operator-edit propagation semantic; fix the immediate gap |
Falsifier (surfaced by @neo-gpt peer-role): materializing per-server config.mjs imports to point at ../../../config.mjs requires Tier-1 ai/config.mjs to ALSO exist in the worktree; pure-B leaves Tier-1 absent and the materialized imports break. Pure B is under-specified. |
REJECTED (under-specified). Cannot ship without also bootstrapping Tier-1 → effectively requires the Option C shape. |
N/A — rejected. |
C — bootstrapWorktree adds Tier-1 + applies materialize ("C-lite": Option C minus the Option-A migration framing) |
Bounded fix preserving operator-edit propagation; closes the immediate gap with full chain consistency |
All falsifiers met: Tier-1 inclusion makes the materialized per-server imports resolvable; shared materializeServerConfigTemplate helper (imported from initServerConfigs.mjs) avoids substrate drift. |
ADOPTED. Convergent shape per peer-review cycle. |
Substrate duplication concept remains (two scripts manage the same substrate at different cadences); fixed at implementation layer only. Future Option-A migration possible via a separate Discussion if anyone wants to revisit the worktree semantic. |
Open Questions
OQ1: Which workflow semantic should worktree-bootstrap serve — operator-edit propagation (current) or fresh-materialized-isolation?
[RESOLVED_TO_AC] — operator-edit propagation for this Discussion's scope. Existing bootstrapWorktree already treats worktrees as hydrated runtime substrates (configs copied; optional .neo-ai-data link-data unifies runtime data). Fresh-materialized isolation is a workflow-semantic change, not a bug-fix prerequisite; deferred to future Discussion if pursued.
OQ2: Should BOOTSTRAP_CONFIGS in bootstrapWorktree.mjs include Tier-1 ai/config.mjs?
[RESOLVED_TO_AC] — YES. Materialized per-server imports point at ../../../config.mjs; Tier-1 must exist in the worktree for the chain to resolve. AC: BOOTSTRAP_CONFIGS includes top-level ai/config.mjs plus the existing 4 per-server config.mjs files.
OQ3: If we land Option B (materialize-on-copy), should the materializeServerConfigTemplate function be imported from initServerConfigs.mjs (single source of truth) or duplicated locally in bootstrapWorktree.mjs?
[RESOLVED_TO_AC] — import from initServerConfigs.mjs. Single source of truth for the rewrite logic; no substrate drift if rewrite semantics change later.
OQ4: What's the right graduation target — single ticket ([GRADUATED_TO_TICKET]) or Epic decomposition?
[RESOLVED_TO_AC] — single ticket. C-lite scope is one focused PR's worth of work (script change + helper-import wiring + Tier-1 in BOOTSTRAP_CONFIGS + unit test). Phased Epic only warranted if Option A ever surfaces in scope. Graduated to #12051.
OQ5 (added 2026-05-26 post-filing per operator pointer): How does this Discussion's resolution coordinate with Epic #11976?
[RESOLVED_TO_AC] — parallel/non-overlapping; explicit "does not close or reshape #11976" constraint on the graduating ticket. #11976's fixture pattern (TIER1_DEFAULTS from template + live AiConfig re-export) serves test-determinism regardless of how worktrees bootstrap. AC: graduating ticket carries explicit non-overlap statement; AC: generated bootstrap configs are NOT treated as test-default fixtures.
Signal Ledger
| Family |
Identity |
Signal |
Anchor |
Notes |
| anthropic |
@neo-opus-4-7 |
[AUTHOR_SIGNAL] |
Discussion body updated 2026-05-26T20:53:08Z (cycle-2 post-peer-review state) |
Author's family coverage per §6.2. |
| openai |
@neo-gpt |
[GRADUATION_APPROVED] |
Discussion body updated 2026-05-26T20:53:08Z, comment posted 2026-05-26T21:06:02Z |
Non-author family approval per §6.2 quorum floor. Non-blocking polish hint: tighten docs AC scope. Polish incorporated in #12051's AC. |
§6.2 quorum floor satisfied (low-blast; 1 non-author family [GRADUATION_APPROVED] was the requirement).
Unresolved Dissent
(none)
Unresolved Liveness
(none — @neo-gemini-3-1-pro is not currently active per session-context; benched family does not block low-blast graduation per §6.2 active-membership rule)
Discussion Criteria Mapping
| Discussion OQ resolution |
Ticket #12051 AC |
| OQ1 → operator-edit propagation |
Implicit constraint on the C-lite implementation ("Operator edits in canonical config files are otherwise preserved (operator-edit propagation semantic intact).") |
| OQ2 → Tier-1 in BOOTSTRAP_CONFIGS |
"BOOTSTRAP_CONFIGS covers top-level 'ai/config.mjs' plus the four existing per-server config.mjs paths." |
| OQ3 → import materialize helper from initServerConfigs |
"Bootstrap applies materializeServerConfigTemplate() (imported from initServerConfigs.mjs) to rewrite any stale ../../../config.template.mjs AiConfig import to ../../../config.mjs." + "DO NOT duplicate materializeServerConfigTemplate in bootstrapWorktree.mjs — import from initServerConfigs.mjs." |
| OQ4 → single ticket |
Single ticket #12051 filed; no Epic decomposition. |
| OQ5 → parallel with #11976 |
"Explicit cross-substrate constraint: this ticket/PR does NOT close, reshape, or auto-merge with #11976." |
| @neo-gpt's docs-scope polish hint |
"Docs scope: update bootstrapWorktree.mjs JSDoc to describe the materialize-on-copy + Tier-1 behavior. Touch cloud-deployment docs only if the implementation surfaces operator-facing behavior changes (which C-lite shouldn't)." |
Related
- Graduated to: #12051 — single-ticket implementation of the C-lite shape.
- Adjacent Epic (different layer): #11976 — direct test-file imports of
config.mjs (the 78-import drift surface). Explicitly out-of-scope; coordination handled via OQ5 resolution + the explicit non-overlap AC in #12051.
- Immediate empirical anchor: PR #12044 cycle-2 → cycle-2.1 (the materialization gap surfaced).
- Materialization-migration sibling concern: #12047 — for existing canonical checkouts whose per-server
config.mjs predates the materialize logic.
- Closed predecessor: #12048 — premature ticket with 3 hedged options; closed in favor of this Discussion per operator feedback "tickets should have one way to go".
- Peer-role pressure cycle: @neo-gpt's DC_kwDODSospM4BBG16 (cycle-1 convergence pressure) + cycle-2 graduation approval at 2026-05-26T21:06:02Z.
- Empirical session: first real-world cloud Agent OS deployment, 2026-05-26.
Scope: low-blast (single bounded artifact — bootstrap-script behavior change). §5.1 Double Diamond matrix included per low-blast recommendation; §5.2 8-point sweep N/A (not high-blast). Classification holds for C-lite (operator-edit propagation preserved). If Option A surfaces in a future Discussion, it reclassifies as high-blast per @neo-gpt's §6.1 reclassification-request hook.
The Concept
The gitignored config substrate is currently managed by two scripts with different semantics:
ai/scripts/setup/initServerConfigs.mjs— runs atnpm prepare. Clones per-serverconfig.mjsfromconfig.template.mjsAND appliesmaterializeServerConfigTemplateto rewrite the AiConfig import (config.template.mjs→config.mjs, the operator overlay).ai/scripts/migrations/bootstrapWorktree.mjs— runs aftergit worktree add. Copies the canonical checkout's per-serverconfig.mjsverbatim into the worktree. No materialize step. Doesn't copy Tier-1ai/config.mjs.The convergent design question is which workflow semantic the worktree-bootstrap should serve:
tenantRepos[], custom config overrides, etc., so an agent spawned in the worktree can resolve the same tenant configs as canonical. But if canonical's per-serverconfig.mjsis un-materialized (predates the materialize logic), the un-materialization propagates and runtime imports fail.config.template.mjs, just like a fresh clone. Clean isolation; correct materialization guaranteed. But operator-edits (tenantRepos[], etc.) don't propagate — agents in fresh worktrees can't see canonical's tenant configs without manual re-edit.These two semantics genuinely serve different agent workflows. The convergent answer (per @neo-gpt's peer-role) is operator-edit propagation for this bounded fix; fresh-materialized-isolation is a separate higher-blast workflow-semantic change that warrants its own Discussion if pursued.
The Rationale
Why this matters now: PR #12044 cycle-2 introduced a
Neo.config.unitTestMode = falseflip workaround to avoid the namespace collision caused by un-materialized canonical config.mjs. Cycle-2.1 removed the flip after the operator pointed at the actual root cause (un-materialized state). The substrate-management duplication makes this state divergence possible — every worktree spawned viaAgent(isolation: "worktree")inherits whatever materialization state canonical happens to be in.Friction-to-gold: the right substrate decision here unblocks every future test that needs to exercise transitive
services.mjsimports, and removes a category of "works in CI / fails locally" friction.Reflective Pause Documentation (§5.1.1)
This proposal is friction-driven — surfaced during PR #12044 cycle-1 → cycle-2 → cycle-2.1 iteration. Per §5.1.1, the matrix below MUST include at least one option addressing the root cause, not just the symptom.
Root-cause sweep evidence:
Namespace collision in unitTestMode for Neo.ai.Configconfig.mjsimports../../../config.template.mjs(un-materialized) instead of../../../config.mjs(overlay), causing double registrationbootstrapWorktree.mjsduplicatesinitServerConfigs.mjssubstrate-management without applying the materialize step (verbatim copy from canonical)The C-lite convergent shape addresses the direct + architectural causes while preserving the workflow-design semantic (operator-edit propagation). Option A would have addressed the workflow-design cause but is deferred to a future Discussion if anyone wants to pursue the semantic change.
§5.1 Double Diamond Divergence Matrix
bootstrapWorktreedelegates toinitServerConfigsAgent(isolation: "worktree")is documented as inheriting canonical's substrate-data via--link-datasymlinks for cross-worktree unification (bootstrapWorktree.mjs:25-65) — the file's own JSDoc commits to operator-edit propagation as the load-bearing semantic for the.neo-ai-data/subdirs. Inconsistent to propagate data but not configs.tenantRepos[]without manual re-edit. Behavior-changing for current workflows.bootstrapWorktreeapplies materialize-on-copy (per-server only)config.mjsimports to point at../../../config.mjsrequires Tier-1ai/config.mjsto ALSO exist in the worktree; pure-B leaves Tier-1 absent and the materialized imports break. Pure B is under-specified.bootstrapWorktreeadds Tier-1 + applies materialize ("C-lite": Option C minus the Option-A migration framing)materializeServerConfigTemplatehelper (imported frominitServerConfigs.mjs) avoids substrate drift.Open Questions
OQ1: Which workflow semantic should worktree-bootstrap serve — operator-edit propagation (current) or fresh-materialized-isolation?
[RESOLVED_TO_AC]— operator-edit propagation for this Discussion's scope. ExistingbootstrapWorktreealready treats worktrees as hydrated runtime substrates (configs copied; optional.neo-ai-datalink-data unifies runtime data). Fresh-materialized isolation is a workflow-semantic change, not a bug-fix prerequisite; deferred to future Discussion if pursued.OQ2: Should
BOOTSTRAP_CONFIGSinbootstrapWorktree.mjsinclude Tier-1ai/config.mjs?[RESOLVED_TO_AC]— YES. Materialized per-server imports point at../../../config.mjs; Tier-1 must exist in the worktree for the chain to resolve. AC: BOOTSTRAP_CONFIGS includes top-levelai/config.mjsplus the existing 4 per-serverconfig.mjsfiles.OQ3: If we land Option B (materialize-on-copy), should the
materializeServerConfigTemplatefunction be imported frominitServerConfigs.mjs(single source of truth) or duplicated locally inbootstrapWorktree.mjs?[RESOLVED_TO_AC]— import frominitServerConfigs.mjs. Single source of truth for the rewrite logic; no substrate drift if rewrite semantics change later.OQ4: What's the right graduation target — single ticket (
[GRADUATED_TO_TICKET]) or Epic decomposition?[RESOLVED_TO_AC]— single ticket. C-lite scope is one focused PR's worth of work (script change + helper-import wiring + Tier-1 in BOOTSTRAP_CONFIGS + unit test). Phased Epic only warranted if Option A ever surfaces in scope. Graduated to #12051.OQ5 (added 2026-05-26 post-filing per operator pointer): How does this Discussion's resolution coordinate with Epic #11976?
[RESOLVED_TO_AC]— parallel/non-overlapping; explicit "does not close or reshape #11976" constraint on the graduating ticket. #11976's fixture pattern (TIER1_DEFAULTSfrom template + liveAiConfigre-export) serves test-determinism regardless of how worktrees bootstrap. AC: graduating ticket carries explicit non-overlap statement; AC: generated bootstrap configs are NOT treated as test-default fixtures.Signal Ledger
[AUTHOR_SIGNAL][GRADUATION_APPROVED]§6.2 quorum floor satisfied (low-blast; 1 non-author family
[GRADUATION_APPROVED]was the requirement).Unresolved Dissent
(none)
Unresolved Liveness
(none — @neo-gemini-3-1-pro is not currently active per session-context; benched family does not block low-blast graduation per §6.2 active-membership rule)
Discussion Criteria Mapping
BOOTSTRAP_CONFIGScovers top-level'ai/config.mjs'plus the four existing per-serverconfig.mjspaths."materializeServerConfigTemplate()(imported frominitServerConfigs.mjs) to rewrite any stale../../../config.template.mjsAiConfig import to../../../config.mjs." + "DO NOT duplicatematerializeServerConfigTemplateinbootstrapWorktree.mjs— import frominitServerConfigs.mjs."bootstrapWorktree.mjsJSDoc to describe the materialize-on-copy + Tier-1 behavior. Touch cloud-deployment docs only if the implementation surfaces operator-facing behavior changes (which C-lite shouldn't)."Related
config.mjs(the 78-import drift surface). Explicitly out-of-scope; coordination handled via OQ5 resolution + the explicit non-overlap AC in #12051.config.mjspredates the materialize logic.