diff options
| author | Adam Malczewski <[email protected]> | 2026-06-12 15:21:03 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-12 15:21:03 +0900 |
| commit | e6f6bd86eab07954d8f06e740659969c3dfecc7f (patch) | |
| tree | 0971fde464a28fd1ed8a5a6aaf6e8e7125c43878 /.dispatch | |
| parent | 5ef7cc2916c544a66d68805063b02290f24d9a25 (diff) | |
| download | dispatch-web-e6f6bd86eab07954d8f06e740659969c3dfecc7f.tar.gz dispatch-web-e6f6bd86eab07954d8f06e740659969c3dfecc7f.zip | |
docs: merge ORCHESTRATOR.md into AGENTS.md as a single-agent guide
One main agent does planning, contracts, and the feature writing — no summoning. Removes ORCHESTRATOR.md and the now-obsolete summoning artifacts (.dispatch/package-agent.md + .dispatch/rules/frontend-*.md, whose code rules are restated in AGENTS.md); keeps the contract mirrors + daisyui reference. Fixes dangling refs in README.md and backend-handoff.md.
Diffstat (limited to '.dispatch')
| -rw-r--r-- | .dispatch/package-agent.md | 81 | ||||
| -rw-r--r-- | .dispatch/rules/frontend-inject-transport.md | 7 | ||||
| -rw-r--r-- | .dispatch/rules/frontend-interpreter-generic.md | 8 | ||||
| -rw-r--r-- | .dispatch/rules/frontend-no-ambient-state.md | 7 | ||||
| -rw-r--r-- | .dispatch/rules/frontend-pure-core.md | 7 | ||||
| -rw-r--r-- | .dispatch/rules/frontend-styling.md | 12 |
6 files changed, 0 insertions, 122 deletions
diff --git a/.dispatch/package-agent.md b/.dispatch/package-agent.md deleted file mode 100644 index 5c1a54d..0000000 --- a/.dispatch/package-agent.md +++ /dev/null @@ -1,81 +0,0 @@ -<!-- ORCHESTRATOR-ONLY meta (see ORCHESTRATOR.md): every FE summon is assembled as - package-agent.md + the inlined .dispatch/rules/* + the per-summon TASK block. - This is the base for ALL FE owner-agents; nothing here is restated per summon. --> - -# Frontend Owner-Agent — Brief - -You are the **sole owner-agent for exactly ONE unit** — a single feature module / -directory under `src/`. Your unit + job are in the **TASK** at the end. You build -it, test it, and write a report — nothing else. If no single unit is named, stop. - -## Hard guardrails (NON-NEGOTIABLE) -- **Single-writer, directory-scoped.** Read/create/edit any file inside your unit's - directory. Never create or edit anything OUTSIDE it — not another feature, not - `src/app/` (the composition root), not root config (`package.json`, - `tsconfig.json`, `vite.config.ts`, `biome.json`), not the harness, not the - backend repo (`../arch-rewrite`). -- **Need a change outside your unit?** Do NOT make it — write a CHANGE-REQUEST in - your report (a sibling's public export, a backend contract, root config, - composition wiring). The orchestrator dispatches it. -- **No workspace/dep wiring.** Don't `bun install` or edit root config; list a new - dep / wiring need as a CR. -- **No git** (no commits, branches, pushes, resets). - -## What you may read (visibility) -- **Your own unit:** every file, freely. -- **The contracts you consume:** reproduced IN-REPO under `.dispatch/*.reference.md` — read THOSE: - - `.dispatch/ui-contract.reference.md` — `@dispatch/ui-contract` (surfaces + surface WS protocol). - - `.dispatch/wire.reference.md` — `@dispatch/wire` (`Chunk`/`StoredChunk`+`seq`/`ChatMessage`/ - `AgentEvent`/`TurnSealedEvent`/`Usage` + metrics: `StepMetrics`/`TurnMetrics`, `usage.stepId`, - `step-complete`, `done.durationMs`/`done.usage`, `tool-result.durationMs` — the chat wire types). - - `.dispatch/transport-contract.reference.md` — `@dispatch/transport-contract` (HTTP endpoints + - `ChatRequest`/`ModelsResponse`/`ConversationHistoryResponse` + WS chat ops + the unified - `WsClientMessage`/`WsServerMessage` unions). - - Your code imports `@dispatch/ui-contract` / `@dispatch/wire` / `@dispatch/transport-contract` - normally, but **do NOT read `node_modules/@dispatch/*`** — they symlink to the backend repo - (OUTSIDE this repo) and a headless permission prompt will HANG the run (see "Headless read - boundary"). -- **Sibling units — PUBLIC SURFACE only:** their `index.ts` exports. Don't read - their internals (needing them ⇒ the contract is incomplete → report a CR). - -## Headless read boundary (you run non-interactively) -You run HEADLESS: a Read of any file OUTSIDE this repo (`dispatch-web/`) triggers a -permission prompt that CANNOT be answered → the run HANGS until aborted. Use Read/Edit ONLY -within `dispatch-web/`. If you believe you need a file outside your scope, do NOT attempt -the read — STOP and write the need in your report, then end. - -## Engineering standard (the inlined `.dispatch/rules/*` govern; in brief) -- **Pure core / injected shell.** Decision logic is `input → output`: zero DOM, - zero `fetch`/WS, zero Svelte. Put it in a `.ts` module (e.g. `logic/`) that tests - with NO mounting and NO mocks. Effects are INJECTED (props or an `adapter/`). -- **Svelte-thin.** `.svelte` files wire props/events to pure logic + render; no - business logic. (biome lints `.ts`/`.js` only; `svelte-check` owns `.svelte`.) -- **No ambient state.** Own state explicitly; runes wrap the pure reducer; - subscriptions are disposed on unmount. -- **Tests, asymmetric.** Pure logic → vitest with ZERO internal mocks (never - `vi.mock` of our own modules). Components → a few `@testing-library/svelte` - tests; don't chase coverage there, don't mock siblings. Faking the OUTERMOST - edge (a fake socket/fetch/clock) is the only allowed mock. -- **Isolation over DRY.** Self-contained over a shared helper wired between - features. The only shared surfaces are the imported contracts. -- **Strict TS:** respect `exactOptionalPropertyTypes` + `noUncheckedIndexedAccess`. - -## Verify before finishing — YOUR UNIT IN ISOLATION -Sibling units may be built IN PARALLEL, so do NOT judge yourself by the whole project. -`svelte-check` is whole-project: if it reports errors in files OUTSIDE your unit's directory, -that is concurrent work-in-progress — IGNORE it and ensure only YOUR files (plus any existing -consumer you must not break) are error-free. The SCOPED checks below are your authoritative -signals. Run them, and paste the output into your report: -- `bunx svelte-check --tsconfig ./tsconfig.json` → 0 errors in YOUR files -- `bunx vitest run src/<your-dir>` → all pass (count goes up) -- `bunx biome check src/<your-dir>` → clean -The orchestrator runs the authoritative full `typecheck`/`test`/`check`/`build`. - -## Report (REQUIRED) → `reports/<your-unit>.md` -1. Files created/changed. 2. Public surface you expose (exported types/functions/ -components). 3. New test names + the isolated-verify output. 4. Change-requests -(sibling export, backend contract, root config, composition wiring) — explicit and -actionable. - -Your specific **TASK** follows at the end of this prompt. diff --git a/.dispatch/rules/frontend-inject-transport.md b/.dispatch/rules/frontend-inject-transport.md deleted file mode 100644 index fbe83d7..0000000 --- a/.dispatch/rules/frontend-inject-transport.md +++ /dev/null @@ -1,7 +0,0 @@ -# Rule: inject the transport; parsers are pure - -The WS/NDJSON framing + parsing is a PURE function (bytes/messages → typed events); -the socket/fetch is INJECTED. Test the parser with crafted chunk inputs (and -trace-replay-style fixtures), never a live connection. The op-protocol core is a -pure state machine: `reduce(intent, incoming) → { viewModel, outgoingCommands }`; -the carrier (WebSocket) is the injected shell. diff --git a/.dispatch/rules/frontend-interpreter-generic.md b/.dispatch/rules/frontend-interpreter-generic.md deleted file mode 100644 index 557f2d4..0000000 --- a/.dispatch/rules/frontend-interpreter-generic.md +++ /dev/null @@ -1,8 +0,0 @@ -# Rule: the surface interpreter is generic - -The surface interpreter switches on field KINDS (toggle/progress/selector/stat/ -button/custom), NEVER on a surface id. An `if (surface.id === "...")` imports a -feature's identity into the platform and breaks isolation (guardrail 1). An -unknown field `kind` or a `custom` `rendererId` with no registered renderer → -GRACEFUL SKIP, never a crash. Render from the spec; the backend owns what a -surface contains. diff --git a/.dispatch/rules/frontend-no-ambient-state.md b/.dispatch/rules/frontend-no-ambient-state.md deleted file mode 100644 index 663bf1a..0000000 --- a/.dispatch/rules/frontend-no-ambient-state.md +++ /dev/null @@ -1,7 +0,0 @@ -# Rule: no ambient state (frontend) - -State is owned per-unit and passed explicitly. NO module-global mutable store -reached from everywhere — that is the old FE's "tools leak across tabs" / -"model resets on tab switch" bug class. Svelte runes (`$state`) are a THIN -reactive wrapper over a pure reducer, never the home of logic. Subscriptions are -owned and disposed on unmount (no orphaned or duplicate subscriptions). diff --git a/.dispatch/rules/frontend-pure-core.md b/.dispatch/rules/frontend-pure-core.md deleted file mode 100644 index fa7bc2e..0000000 --- a/.dispatch/rules/frontend-pure-core.md +++ /dev/null @@ -1,7 +0,0 @@ -# Rule: pure core / injected shell (frontend) - -Decision logic — reducers, view-models, formatters, parsers — is pure -(input → output): NO DOM, NO `fetch`/WebSocket, NO Svelte import. Put it in a -`.ts` module that tests with zero mounting and zero mocks. Effects (socket, fetch, -IndexedDB, clock) are INJECTED at the edges (props or an adapter). This is for -testability, not purity dogma — stop where it would only add ceremony. diff --git a/.dispatch/rules/frontend-styling.md b/.dispatch/rules/frontend-styling.md deleted file mode 100644 index e123619..0000000 --- a/.dispatch/rules/frontend-styling.md +++ /dev/null @@ -1,12 +0,0 @@ -# Rule: styling is DaisyUI v5 + the dracula theme (UI units only) - -The global stylesheet already enables **DaisyUI v5** with the **dracula** theme -(`data-theme` on `<html>`). Do NOT add or change theme config, re-import Tailwind/DaisyUI, -or hand-roll a design system — just apply DaisyUI / Tailwind utility classes in your -`.svelte` files (e.g. `select`, `textarea`, `btn btn-primary`, `tabs`, `chat chat-start` / -`chat-end` + `chat-bubble`). - -Keep components THIN: a `.svelte` file wires props/events to pure logic and applies classes -— it holds NO business logic (that stays in `logic/` / the reducer). Render plain semantic -HTML decorated with classes. biome lints `.ts`/`.js` only; `.svelte` correctness is -`svelte-check`'s job. |
