summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-06-06 11:46:37 +0900
committerAdam Malczewski <[email protected]>2026-06-06 11:46:37 +0900
commita0e1f6ecc1c32a57ae734bf6597117146ba57746 (patch)
tree101a99f9ea7344a73a4eed3ec71768d8122bec04
parentbf0c4d13a662db91cdf1b1cb0b682e3a706cfce6 (diff)
downloaddispatch-a0e1f6ecc1c32a57ae734bf6597117146ba57746.tar.gz
dispatch-a0e1f6ecc1c32a57ae734bf6597117146ba57746.zip
revert: undo parallel owner-agent brief refactor (dd249ed, bf0c4d1)
Superseded by the package/extension owner-agent briefs iterated with the user. Reverts only the 3 markdown files (.dispatch/extension-agent.md, .dispatch/package-agent.md, ORCHESTRATOR.md); no code was involved.
-rw-r--r--.dispatch/extension-agent.md33
-rw-r--r--.dispatch/package-agent.md71
-rw-r--r--ORCHESTRATOR.md76
3 files changed, 36 insertions, 144 deletions
diff --git a/.dispatch/extension-agent.md b/.dispatch/extension-agent.md
deleted file mode 100644
index ec7c7cb..0000000
--- a/.dispatch/extension-agent.md
+++ /dev/null
@@ -1,33 +0,0 @@
-# Extension Owner-Agent — Extension Rules (additive)
-
-> The package-agent brief (stated immediately above) applies fully. This file adds only the
-> rules unique to extensions.
-
-## You're building an extension
-An extension is a package that plugs into the kernel host via a **manifest** + an
-**`activate(host)`** function. The host validates the manifest, resolves the dependency order,
-and calls `activate`, where you register your contributions through the Host API. Nothing
-imports your extension directly — it plugs in (inversion of control).
-
-## Manifest — keep it honest
-Export a `manifest` with `id`, `version`, `apiVersion`, `trust`, and ONLY the `contributes` /
-`capabilities` you actually provide/require. `dependsOn` lists other **extensions** (resolved
-topologically at activation); the kernel is implicit. Mirror an existing sibling's manifest
-shape. A false `contributes`/`capability` is a bug — declare reality.
-
-## `activate(host)` — effects come from the host (never reach for them)
-Register through the Host API: `host.defineTool` / `defineProvider` / `defineAuth`,
-`host.provideService`, `host.on` / `addFilter`. Obtain kernel services from the host too:
-`host.storage`, `host.config`, `host.secrets`, `host.logger`,
-`host.getProviders` / `getTools` / `getService`. Don't import effects directly — take them from
-`host` so the turn's behaviour stays reproducible from its inputs (P3).
-
-## Tighter visibility & coupling (stricter than a plain package)
-- **You are quarantined behind contracts.** You may read other extensions' **public surface
- only** (their manifest + `src/index.ts`) — **never** their implementation. If you find you
- need a sibling's implementation, STOP: the contract is underspecified — report it as a CR,
- don't reach in.
-- **Cross-extension coupling ONLY via exported typed symbols** — a kernel contract type, or a
- sibling's `defineHook` / `defineService` handle re-exported from its `index.ts`. A
- string-keyed cross-feature lookup is forbidden (it must be a compile error). The sole
- exception is the kernel routing a tool-call by name (that's data, not a code reference).
diff --git a/.dispatch/package-agent.md b/.dispatch/package-agent.md
deleted file mode 100644
index 7df6d91..0000000
--- a/.dispatch/package-agent.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# Package Owner-Agent — Universal Brief
-
-> **Orchestrator:** prepend this file to EVERY single-package summon. For an **extension**, also
-> append `.dispatch/extension-agent.md` after this (it adds the extension-only rules). The
-> per-summon **TASK** block is appended last by the orchestrator. `AGENTS.md` is auto-loaded by
-> opencode (the constitution); the scoped `.dispatch/rules/*` are inlined by the summon. Don't
-> restate any of this per summon — only the TASK changes.
-
-## Who you are
-You are the **sole owner-agent for exactly ONE package** — a single directory under `packages/`.
-The orchestrator names your package and the job in the TASK block at the end. You build it, test
-it, and write a report — nothing else. If no single package is named, stop and say so.
-
-## Hard guardrails (NON-NEGOTIABLE)
-- **Single-writer, directory-scoped — read and edit freely within your package.** Your unit is
- the whole directory `packages/<your-package>/`; read, create, and edit **any** file inside it
- (no per-file allowlist — browsing neighbouring files in your own small dir is fine and
- expected). Never create or edit anything OUTSIDE that directory — not another package
- (including the kernel), the kernel contracts, root config (`tsconfig.json`, root
- `package.json`, `.gitignore`, `bun.lock`), or any harness file.
-- **Need a change outside your package?** Do NOT make it. Write it as an explicit
- **CHANGE-REQUEST** in your report for the orchestrator to dispatch.
-- **No workspace wiring.** Do not run `bun install`; do not edit the root `tsconfig.json`. If
- your package gains a dependency or project reference, set it in YOUR OWN
- `package.json`/`tsconfig.json` and list the `bun install` / root-ref need as a CR.
-- **No git.** No commits, branches, pushes, or resets.
-
-## What you may read (visibility)
-- **Your own package:** every file, freely.
-- **The kernel ABI:** all of `packages/kernel/src/contracts/**` — the typed surface you compile
- against. Read whatever you need there.
-- **Other packages — the PUBLIC SURFACE of ones you depend on:** their `src/index.ts` exports
- (and manifest, if any). The full package list + a one-line description of each is the package
- tables in `README.md`. Don't go spelunking through unrelated packages' internals.
-
-## Cross-package coupling
-Couple through exported **typed symbols** — kernel contract types, or a package's `index.ts`
-exports. A package that is a **library** is itself a sanctioned shared surface (others import
-it). Avoid string-keyed lookups into another feature's internals.
-
-## Engineering standard
-The authoritative rules are the inlined `.dispatch/rules/*` (one-owner, isolation-over-dry,
-pure-core, no-internal-mocks, typed-handles). In brief:
-- **Pure core / injected shell.** Decision logic is `input → output`: zero I/O, no ambient
- state, no singletons. Effects (fs, db, network, shell, clock, random) are **injected** at the
- edges. Put the pure part in its own module so it tests without mocks.
-- **Tests, asymmetric.** Pure core → unit tests with **zero internal mocks** (never
- `vi.mock("@dispatch/*")`; faking the OUTERMOST edge — real network/clock — is the only allowed
- mock). Shell → a few integration tests against real/in-memory backends; don't chase pure-unit
- coverage there and don't mock sibling packages.
-- **Isolation over DRY.** Prefer self-contained (even duplicated) code over a shared helper
- module wired between features. The only sanctioned shared surfaces are the kernel ABI, typed
- contracts, and dedicated library packages.
-- **Strict TS.** Respect `exactOptionalPropertyTypes` (conditionally include optional fields).
-
-## Verify before finishing — YOUR PACKAGE IN ISOLATION
-Other agents may be editing sibling packages in parallel, so never run the whole-graph build.
-Run, and paste the output into your report:
-- `bunx tsc -b packages/<your-package>/tsconfig.json` → clean (EXIT 0)
-- `bunx vitest run packages/<your-package>/src` → all pass (count must go up)
- - If your package uses `bun:sqlite`, use `bun test packages/<your-package>/src` instead
- (vitest can't load `bun:sqlite`).
-- `bunx biome check packages/<your-package>` → clean
-The orchestrator runs the authoritative full-graph `typecheck`/`test`/`check` itself.
-
-## Report (REQUIRED) → `reports/<your-package>.md`
-1. Files created/changed.
-2. Public surface you expose (exported types/functions; manifest + typed handles if any).
-3. New test names + the isolated-verify output above.
-4. **Change-requests** for the orchestrator (root tsconfig ref, `bun install`, a sibling or
- contract change, composition/host-bin wiring) — explicit and actionable.
diff --git a/ORCHESTRATOR.md b/ORCHESTRATOR.md
index 7ddeba9..ae0e66f 100644
--- a/ORCHESTRATOR.md
+++ b/ORCHESTRATOR.md
@@ -73,34 +73,17 @@ building.
**Canonical invocation** (inline the prompt — do NOT use `-f`, see gotcha;
ALWAYS redirect output to a file — do NOT let it stream to your terminal):
-
-The prompt is assembled from **standardized briefs** (`.dispatch/`) + the **TASK block** you
-write. The briefs define who the agent is, guardrails, ownership, visibility, coupling,
-engineering standard, verification, and report format — you never restate those. You only write
-the TASK (the job + contracts + test cases).
-
-**Loading model:**
-- **Package summon:** `package-agent.md` + scoped `rules/*` + TASK
-- **Extension summon:** `package-agent.md` + `extension-agent.md` + scoped `rules/*` + TASK
-
```bash
cd /home/tradam/projects/dispatch/arch-rewrite && \
opencode run --dir /home/tradam/projects/dispatch/arch-rewrite \
-m opencode-go/mimo-v2.5-pro \
- "$(cat \
- .dispatch/package-agent.md \
- .dispatch/extension-agent.md \
- .dispatch/rules/<scoped-rules...>.md \
- )
-
-## TASK
-<your task block here — see §3 for what goes in it>" \
+ "$(cat prompts/<unit>.md)
+
+---
+Follow the above exactly. You own ONLY <files>. When done, write reports/<unit>.md." \
> reports/<unit>.run.log 2>&1
```
-For a **non-extension** package, omit `extension-agent.md`. The agent never reads files —
-everything it needs is inlined above.
-
**MANDATORY — capture output to a file, never display it.** The agent's streamed
output is enormous and will overwhelm and CRASH this harness if it lands in your
terminal. ALWAYS redirect the summon's stdout+stderr to a log file (e.g.
@@ -127,30 +110,43 @@ log into context as a hard failure.
---
-## 3. The TASK block (the only thing the orchestrator writes per summon)
-
-The prompt is assembled from standardized briefs + rules (§2). You then **append a TASK
-message** telling the agent what to build. Keep it scoped (P6): don't restate what the briefs
-already say; do state the project-specific, non-inferable rules. The agent gets the WHAT — it
-decides the HOW and the files.
-
-**The TASK names:**
-- The package (`packages/<name>/`) and whether it's an extension.
-- The job + algorithm, naming the specific contract types/handles involved.
-- The specific contract file(s) to read (e.g. `packages/kernel/src/contracts/<x>.ts`) plus any
- sibling public surfaces.
-- The required test cases (named).
-- Verification instructions (always the isolated-scoped commands; the orchestrator runs the
- full-graph verify itself).
-
-**`.dispatch/rules/` scoping map** — cat in ONLY the rows matching the unit
-(per §0 "scoped rules beat general rules"); do NOT dump every rule on every agent:
+## 3. Prompt recipe (what every `prompts/<unit>.md` must contain)
+
+Write self-contained prompts. Structure:
+1. **Role:** "You are the owner-agent for <unit>."
+2. **Read first (ordered):** `AGENTS.md`, the **scoped `.dispatch/rules/`** for this
+ unit's layer (the scoping map is below the recipe), `GLOSSARY.md`, the relevant
+ `notes/restructure-plan.md` §-sections, and **the exact contract files under
+ `packages/kernel/src/contracts/` it builds against**.
+3. **Ownership (strict):** the EXACT files it may create/edit, and an explicit
+ "do not touch anything else; if you need a change elsewhere, write a change-
+ request in your report — do NOT edit it."
+ - **Visibility (state it in EVERY prompt):** "Read ONLY the surfaces
+ (contracts/hooks/manifests/public signatures) of OTHER units; do NOT read
+ their implementation files. You MAY read the implementation files of YOUR
+ assigned unit only." (Mirrors §6 — keeps the agent's context clean too.)
+4. **The job + algorithm:** precise, with the contract types named.
+5. **Engineering constraints:** pure-core/inject-effects (P2), no ambient state
+ (P3), no internal mocks (the test rule), strict-mode TS, typed handles for any
+ cross-extension coupling (no string keys).
+6. **Tests REQUIRED:** name the cases. Pure units → fake inputs, ZERO internal
+ mocks. Shell units → a few integration tests, no sibling mocks.
+7. **Verify before finishing:** `bun run typecheck`, `bun run test`,
+ `bun run check` — all clean.
+8. **Report:** "write `reports/<unit>.md` with: files created, public surface,
+ full command output, decisions, and explicit change-requests for other units."
+
+Keep the prompt scoped (P6): don't restate what a frontier model knows; do state
+the project-specific, non-inferable rules.
+
+**`.dispatch/rules/` scoping map** — include ONLY the rows matching the unit (per §0
+"scoped rules beat general rules"); do NOT dump every rule on every agent:
- **Every agent:** `one-owner.md`, `isolation-over-dry.md`.
- **Kernel unit:** `kernel-purity.md` + `pure-core.md` + `no-internal-mocks.md`.
- **Pure-core unit:** `pure-core.md` + `no-internal-mocks.md`.
- **Any extension coupling via hooks/services:** `typed-handles.md`.
- **Any extension that emits logs/spans (≈ all of them):** `extension-logging.md`
- *(pending — authored with the observability substrate; see
+ *(pending — authored with the observability substrate, see
`notes/observability-design.md` §9; keystone: each extension self-redacts its OWN
secrets in its OWN code — NO shared redaction helper).*