Context
Operator-observed (2026-06-18): frequent new browser tabs spawning during local dev. Root cause located: the webpack dev-server is started via npm run server-start (= webpack serve … --open) and/or the gitignored VS Code .claude/launch.json neo-dev-server config — and the --open flag opens a browser tab on every (re)start. The local orchestrator (ai/daemons/orchestrator/) already supervises chroma / wake / embed daemons, but it does not supervise the dev-server, so it's hand-started and re-opens a tab each time.
Release classification: post-release (local-dev orchestrator stability/self-healing; boardless — not a v13 release gate).
Live latest-open sweep: checked latest 25 open issues on 2026-06-18; no equivalent orchestrator dev-server / tab-spawn ticket. A2A in-flight sweep: latest 20 messages; no competing [lane-claim].
The Problem
No orchestrator supervision of the local dev-server means (a) manual start/restart toil, and (b) a browser tab spawned per (re)start via --open — which accumulates during long local dev / agent sessions (the observed "tabs keep appearing"). This is a local-dev-loop stability/self-healing gap, not a cloud concern.
The Architectural Reality
ai/daemons/orchestrator/taskDefinitions.mjs buildTaskDefinitions() already defines supervised daemons (chroma, bridgeDaemon (= the wake daemon), embedDaemon, …), each shaped {label, command, args, pidFileName, expectedCommand, [singletonPort], [livenessProbe]}. Orchestrator.poll() + continuousTasks own liveness + restart.
package.json server-start = webpack serve -c ./buildScripts/webpack/webpack.server.config.mjs --open (port 8080). The --open is the tab-spawner.
.claude/launch.json (gitignored, operator-local) runs the same webpack serve on 8080 — restarts there also re-open.
The Fix
Add a devServer continuous task to buildTaskDefinitions():
- runs
webpack serve -c ./buildScripts/webpack/webpack.server.config.mjs without --open (port 8080),
livenessProbe against :8080 + singletonPort: 8080 so it never double-spawns over a manually-started dev-server,
- gated LOCAL-only via a new
aiConfig.orchestrator.devServer.{enabled,port,livenessProbeTimeoutMs} leaf (default active only in local/dev deploymentMode; the cloud orchestrator never launches a dev-server).
- Leave
server-start's manual --open intact for explicit manual use (or add a server-start-headless alias for the no-open invocation).
Contract Ledger
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback / Edge Case |
Docs |
Evidence |
devServer orchestrator task |
taskDefinitions.mjs + Orchestrator continuousTasks |
Supervise webpack serve :8080, no --open, restart-on-death |
singletonPort: 8080 defers if a dev-server already listens (manual start) |
Inline task JSDoc |
Unit test: task-def shape + args contain no --open |
aiConfig.orchestrator.devServer.{enabled,port,livenessProbeTimeoutMs} |
ai/config.template.mjs (ADR 0019 leaf) |
LOCAL-only gate (off under cloud deploymentMode); livenessProbeTimeoutMs (default 1000) bounds the TCP singleton probe |
Absent leaf → conservative local default / fail-loud per ADR 0019 |
config.template JSDoc + Tier-1 config.template.spec snapshot |
ai:lint-config-template-ssot + spec assert |
Ledger reconciled to shipped reality (PR #13490): the leaf ships {enabled, port, livenessProbeTimeoutMs} — the livenessProbeTimeoutMs field is additive beyond the original {enabled, port} scoping.
Decision Record impact
none — aligned-with the orchestrator's existing daemon-supervision design + ADR 0019 (the config leaf).
Acceptance Criteria
Out of Scope
- Cloud / deploy-plane web serving.
- Changing
server-start's manual --open behavior (explicit manual open stays available).
- The gitignored
.claude/launch.json (operator-local).
Avoided Traps
- Running the dev-server in the cloud orchestrator (LOCAL-only gate).
- Double-spawning over a manually-started dev-server (
singletonPort).
- Stripping
--open from server-start itself (manual users may want it).
Related
Refs #13012 (Agent Harness — the local orchestrator powers the harness dev loop).
- Sibling stability ticket filed alongside: orchestrator-supervised Neural Link Bridge.
Origin Session ID: d1903453-9b2d-4f5d-bb5a-cf51ac2f7538
Handoff Retrieval Hints: query_raw_memories("orchestrator dev-server webpack serve --open browser tab spawn local taskDefinitions devServer"). Anchors: ai/daemons/orchestrator/taskDefinitions.mjs, package.json server-start, .claude/launch.json.
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega), at @tobiu's request.
Context
Operator-observed (2026-06-18): frequent new browser tabs spawning during local dev. Root cause located: the webpack dev-server is started via
npm run server-start(=webpack serve … --open) and/or the gitignored VS Code.claude/launch.jsonneo-dev-serverconfig — and the--openflag opens a browser tab on every (re)start. The local orchestrator (ai/daemons/orchestrator/) already supervises chroma / wake / embed daemons, but it does not supervise the dev-server, so it's hand-started and re-opens a tab each time.Release classification: post-release(local-dev orchestrator stability/self-healing; boardless — not a v13 release gate).Live latest-open sweep: checked latest 25 open issues on 2026-06-18; no equivalent orchestrator dev-server / tab-spawn ticket. A2A in-flight sweep: latest 20 messages; no competing
[lane-claim].The Problem
No orchestrator supervision of the local dev-server means (a) manual start/restart toil, and (b) a browser tab spawned per (re)start via
--open— which accumulates during long local dev / agent sessions (the observed "tabs keep appearing"). This is a local-dev-loop stability/self-healing gap, not a cloud concern.The Architectural Reality
ai/daemons/orchestrator/taskDefinitions.mjsbuildTaskDefinitions()already defines supervised daemons (chroma,bridgeDaemon(= the wake daemon),embedDaemon, …), each shaped{label, command, args, pidFileName, expectedCommand, [singletonPort], [livenessProbe]}.Orchestrator.poll()+ continuousTasks own liveness + restart.package.jsonserver-start=webpack serve -c ./buildScripts/webpack/webpack.server.config.mjs --open(port 8080). The--openis the tab-spawner..claude/launch.json(gitignored, operator-local) runs the samewebpack serveon 8080 — restarts there also re-open.The Fix
Add a
devServercontinuous task tobuildTaskDefinitions():webpack serve -c ./buildScripts/webpack/webpack.server.config.mjswithout--open(port 8080),livenessProbeagainst:8080+singletonPort: 8080so it never double-spawns over a manually-started dev-server,aiConfig.orchestrator.devServer.{enabled,port,livenessProbeTimeoutMs}leaf (default active only in local/devdeploymentMode; the cloud orchestrator never launches a dev-server).server-start's manual--openintact for explicit manual use (or add aserver-start-headlessalias for the no-open invocation).Contract Ledger
devServerorchestrator tasktaskDefinitions.mjs+OrchestratorcontinuousTaskswebpack serve:8080, no--open, restart-on-deathsingletonPort: 8080defers if a dev-server already listens (manual start)--openaiConfig.orchestrator.devServer.{enabled,port,livenessProbeTimeoutMs}ai/config.template.mjs(ADR 0019 leaf)deploymentMode);livenessProbeTimeoutMs(default 1000) bounds the TCP singleton probeconfig.template.specsnapshotai:lint-config-template-ssot+ spec assertLedger reconciled to shipped reality (PR #13490): the leaf ships
{enabled, port, livenessProbeTimeoutMs}— thelivenessProbeTimeoutMsfield is additive beyond the original{enabled, port}scoping.Decision Record impact
none— aligned-with the orchestrator's existing daemon-supervision design + ADR 0019 (the config leaf).Acceptance Criteria
:8080), auto-restarting it on death.--open→ no browser tab spawned on (re)start.deploymentMode(cloud orchestrator never launches a dev-server) via anaiConfig.orchestrator.devServerleaf.:8080.--open; LOCAL-only gating).Out of Scope
server-start's manual--openbehavior (explicit manual open stays available)..claude/launch.json(operator-local).Avoided Traps
singletonPort).--openfromserver-startitself (manual users may want it).Related
Refs #13012(Agent Harness — the local orchestrator powers the harness dev loop).Origin Session ID: d1903453-9b2d-4f5d-bb5a-cf51ac2f7538
Handoff Retrieval Hints:
query_raw_memories("orchestrator dev-server webpack serve --open browser tab spawn local taskDefinitions devServer"). Anchors:ai/daemons/orchestrator/taskDefinitions.mjs,package.jsonserver-start,.claude/launch.json.Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega), at @tobiu's request.