diff options
| author | Adam Malczewski <[email protected]> | 2026-06-24 17:15:59 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-24 17:15:59 +0900 |
| commit | 709f00869f7601c3e5729cbb5a2877197d3b66b8 (patch) | |
| tree | f0fac62d9e68fcce3ab7362dec9091492e827c1a | |
| parent | 8f6114be790016bd954fcfccbe80a88bd0cb758e (diff) | |
| download | dispatch-709f00869f7601c3e5729cbb5a2877197d3b66b8.tar.gz dispatch-709f00869f7601c3e5729cbb5a2877197d3b66b8.zip | |
docs: update tasks.md (per-edit diagnostics milestone, 1468 tests) + retire stale HANDOFF.md
- tasks.md: record per-edit LSP diagnostics auto-append milestone (commit
8f6114b), fix test count 1453→1468
- HANDOFF.md: retire stale post-MVP handoff (referenced arch-rewrite path,
178 tests, next-steps all done) → current accurate pointer file
| -rw-r--r-- | HANDOFF.md | 123 | ||||
| -rw-r--r-- | tasks.md | 18 |
2 files changed, 45 insertions, 96 deletions
@@ -1,112 +1,45 @@ # HANDOFF — next steps for the incoming orchestrator > Read `ORCHESTRATOR.md` first (your operating manual), then `tasks.md` (live -> status), then this file (what to do next). The MVP is DONE and verified live; -> this is the post-MVP backlog, ordered. +> status), then this file (what to do next). The project is mature; this file +> points at the live source of truth and the current open work. ## Where things stand (one paragraph) -Kernel (contracts, bus, runtime/`runTurn`, host) + 6 core extensions -(storage-sqlite, conversation-store, auth-apikey, provider-openai-compat, -session-orchestrator, transport-http) + host-bin are built, full-fidelity -(every core feature is a real manifest-loaded extension). **178 tests pass; -typecheck + biome clean.** Multi-turn `curl` against OpenCode Go flash works -(use the `conversationId` field). Keys are rotated to **opencode-1** (active); -ports are **24203 backend / 24204 frontend** (in `.env`). + +Kernel + core extensions + host-bin are built, full-fidelity (every core feature +is a real manifest-loaded extension). The turn loop runs real tools end-to-end +against live models. LSP integration, observability (journal/collector/trace-store), +cache warming, turn continuity (detached turns + multi-client), skills, message +queue + steering, metrics (live + persisted), per-conversation model/cwd/reasoning +persistence, and broken-chat self-repair are all DONE and live-verified. +**`tsc -b` EXIT 0 · biome clean · 1468 vitest green.** The web frontend is a +separate repo (`../dispatch-web`); contract changes are couriered via the user. ## How to boot & smoke-test ```bash -cd /home/tradam/projects/dispatch/arch-rewrite -set -a; source .env; set +a # loads DISPATCH_API_KEY + BACKEND_PORT -bun packages/host-bin/src/main.ts # boots on BACKEND_PORT (24203) -# another shell: +cd /home/tradam/projects/dispatch/dispatch-backend +# .env auto-loads DISPATCH_API_KEY + BACKEND_PORT (24203). +# Dev stack (live-reload): bin/up (ports 24203/24205/24204) +# Stable second stack: ../bin/up2 (ports 25203/25205/25204, isolated data) +bun packages/host-bin/src/main.ts # boots app + collector curl -s -X POST localhost:24203/chat -H 'content-type: application/json' \ -d '{"conversationId":"c1","message":"Say hello in 3 words."}' -# multi-turn: send a 2nd POST with the SAME conversationId; it sees turn 1. ``` -A 429 `GoUsageLimitError` = upstream monthly cap, not a bug. opencode-1 is active; -opencode-2 (in `.env` as `DISPATCH_API_KEY_OPENCODE2`) is rate-limited until reset. - ---- - -## Next steps (ordered; each is one summon unless noted) - -### 1. Wire auth → provider properly ⟵ DO FIRST (correctness, small) -**Problem:** `auth-apikey` is currently **vestigial**. `provider-openai-compat` -reads its credentials straight from `host.config` (`provider.openai-compat.*`) -and never calls `AuthContract.resolve()`. So the auth extension exists but does -nothing — the architecture isn't actually exercising the auth seam. -**Goal:** the provider obtains credentials via the `AuthContract` (resolved by -the orchestrator/host-bin and handed to the provider), not by reading config -directly. -**Likely a 2-unit change (contract-touching → coordinate):** -- `provider-openai-compat`: accept resolved `Credentials` (apiKey/baseURL) at - registration/stream instead of reading `host.config`. -- `host-bin` (composition root): resolve `auth-apikey`'s `AuthContract` → - feed the provider. (Orchestrator may do this small wiring edit directly.) -- Watch the **`ProviderContract.stream` credentials gap** noted since the - contracts were written — decide whether creds flow via `ProviderStreamOptions`, - a provider factory arg, or a resolve-at-activate step. If `provider.ts` - contract must change, run `lsp references` and fan out (§5.3). -**Verify:** boot + curl still returns a real response; auth-apikey now on the -path. Add/adjust tests so the seam is covered without internal mocks. +Process cleanup uses the `[x]` bracket trick (ORCHESTRATOR §8) — leaked +server/collector procs poison the next run's counts. -### 2. First TOOL extension — exercise the dispatch loop ⟵ proves §3.3 -**Problem:** every turn so far runs with `tools: []`. The kernel's tool-dispatch -loop (eager / semaphore / dedup / concurrencySafe / abort) has unit tests but has -NEVER run end-to-end with a real tool + a real model. -**Goal:** add a `read_file` tool extension (standard tier), register it via the -host, and have a live turn where flash actually calls it. -- New unit `packages/tool-read-file/` (or `tools-fs/`): a `ToolContract` - (`name`, `description`, JSON-schema `parameters`, `execute` using `node:fs`, - workdir-contained — see the OLD repo's `read-file.ts` for the containment - guard, `/home/tradam/projects/dispatch/dispatch-source/packages/core/src/tools/read-file.ts`, - as a REFERENCE only — do not copy blindly). -- Manifest with `capabilities: { fs: true }`. -- host-bin registers it; session-orchestrator passes the tool set to `runTurn`. -- **Live test:** ask the model to read a file → confirm a `tool-call` + - `tool-result` round-trip + final answer using the content. -**This is the highest-value next step** — it's the first real validation that the -turn loop's tool path works against a live model. +## What's open now -### 3. Small CRs / hygiene (batch; mostly orchestrator wiring) -- **host CR-1:** `createHost` should expose `getHostAPI()` so host-bin drops its - duplicate `HostAPI` adapter (`buildPostActivationHostAPI`). Kernel-host unit. -- **storage-sqlite CR-2:** manifest declares `contributes.services:["storage"]` - but `activate` is a no-op (backend is a kernel dep passed via host-bin). Either - remove the misleading `contributes`, or make it provide the factory as a - service. Reconcile manifest vs reality. -- **Stale detached server** may linger on an old port from earlier runs — harmless; - kill if it blocks a port. - -### 4. Vocabulary drift fix: `tabId` → `conversationId` ⟵ contract change -**Problem (tracked in GLOSSARY.md "Known vocabulary drift"):** the canonical term -is **`conversationId`**, but `AgentEvent`s and `RunTurnInput` still use **`tabId`** -(the orchestrator bridges `conversationId → tabId`). This is pure P8 debt. -**Goal:** rename `tabId` → `conversationId` across `events.ts` + `runtime.ts` -contracts and every consumer. -**Process (textbook §5.3 fan-out):** kernel-contracts owner renames the symbols, -runs `lsp references` to get the TRUE consumer list, orchestrator dispatches the -affected owners (runtime, session-orchestrator, transport-http, host-bin) to -update. Do this as ONE coordinated change; expect ~4–5 files. Update GLOSSARY -(remove the drift note) when done. - ---- +See `tasks.md` for the live checklist. As of this writing: +- **Per-edit LSP diagnostics** (commit `8f6114b`) — committed + green, NOT yet + live-verified against a real running server. +- **MCP (Model Context Protocol) integration** — the next major feature. Research + + plan in progress; see `notes/mcp-design.md` (when written) + `PLAN-mcp.md`. +- `notes/pending-issues.md` item 1 (workspace tab) — awaiting a user handoff. ## Standing reminders (from ORCHESTRATOR.md — don't relearn the hard way) -- Summon via the **Task tool** (`subagent_type: "Opus 4.8"`, ORCHESTRATOR §2). The Task - `prompt` is a SHORT pointer that tells the agent to READ the briefs + scoped rules + - `prompts/<unit>.md` ITSELF — **never `Read`/`cat` those files into your own context to - inline them** (that burns your tokens; the whole point of the file harness is to keep the - guardrails in the *subagent's* context, not yours). Parallel wave = multiple Task calls in - ONE message (disjoint file sets only). -- **`deepseek-v4-flash` is the app's runtime testbench, NOT for building agents.** -- Parallelize ONLY disjoint file sets (single-writer). Log parallel runs in tasks.md. -- Verify independently (typecheck/test/check) + confirm single-lane edits. Trust - nothing until green yourself. +- Summon via `opencode run` (ORCHESTRATOR §2). Parallel wave = multiple concurrent + summons on disjoint file sets only. +- Verify independently (typecheck/test/check) + confirm single-lane edits. - Keep `tasks.md` current; write decisions down before pivoting. - Be careful with destructive git; back up `notes/` before any reset/clean. - -## Open design decisions still parked (post-rewrite, from plan §8) -- Persistent *waking* agents + wake-time contract-delta sync (we use fresh - summons for now). -- These are NOT blocking the next steps above. @@ -5,7 +5,23 @@ > Keep this lean and current; do not let it re-accrete a step-by-step changelog. ## Status (current) -`tsc -b` EXIT 0 · biome clean · **1453 vitest** green. +`tsc -b` EXIT 0 · biome clean · **1468 vitest** green. + +## Per-edit LSP diagnostics auto-append (DONE) +After a successful `edit_file`, the extension now calls LSP `getDiagnostics` on the +post-edit buffer and appends any errors/warnings (severity ≤ 2) to the tool result — +so the model sees lint/diagnostics feedback inline without a separate round-trip. +Multi-server aggregation queries ALL connected servers matching the file's extension +(not just the first), merging diagnostics tagged by source (`[steep]`, `[ruby-lsp]`, etc.). +Incremental sync (`textDocument/didChange`) captures each server's `change` kind during +`initialize` and computes prefix/suffix diff ranges for `change:2` servers, full content +for `change:1`. New pure `diff.ts` (`computeChangeRange` + `offsetToPosition`, O(n)). +60s timeout; slow warning if >10s; graceful degradation when no LSP available. Generic +— works for any LSP. `languageId` mapping extended (`.rb`/`.rbs`/`.c`/`.cpp`/etc.). +- [x] Wave 1 — `packages/lsp/` (single unit): diff.ts, client, tool, diagnostics, language, types, extension. 15 new diff tests + multi-server tool test. +- [x] Wave 2 — `packages/tool-edit-file/`: optional dep on `@dispatch/lsp` via `host.getService()` (not manifest `dependsOn`); appends diagnostics after successful edit. +- [x] Verified: `tsc -b` EXIT 0, biome clean, **1468 vitest** pass (was 1453, +15). +- [ ] **LIVE-VERIFIED** — not yet exercised against a real running server. ## Broken-chat self-repair (read-time reconcile) (DONE) Conversation `77574596` broke unrecoverably: `reconcile()` only repaired orphaned |
