Skip to content

ARCHIVED — Previous Forge specification-stage overview

Historical input preserved verbatim below. This file is not current architecture. Use docs/product/, docs/architecture/, docs/design/, and docs/context.md for current truth. This archive exists so earlier ideas and research are never lost.


Forge — Complete Project Overview

A single-file briefing on the forge repository, written to hand to another agent or reviewer. Generated 2026-09-10 from the repo at commit 19c81d8. Everything below is a summary of files in the repo; where the repo contradicts itself, the precedence order in §0 applies.


0. How to read this repo (precedence order)

The repo is a specification-stage project. There is ~12,000 lines of documentation and ~160 lines of Go. The docs were written in layers, and later layers supersede earlier ones:

LayerFilesAuthority
1. Product specdocs/PRD.md (1077 ln)Oldest. Vision-level. Superseded in several places.
2. Technical specdocs/TDS.md (1743 ln)Oldest. Contains inline "Superseded by ADR-XXXX" banners.
3. Researchdocs/research/*.md (4155 ln)Primary-source findings that caused the ADRs.
4. ADRsdocs/adr/00010012Operative. Win where they conflict with PRD/TDS.
5. GlossaryCONTEXT.mdThe canonical vocabulary. Use its terms exactly.
6. Plandocs/plans/2026-09-01-core-spine.md (3842 ln)The current build plan, 15 tasks.
7. Codecore/Task 1 of 15, partially done.

If you are here because "a few ideas have changed": the changes are the ADRs. PRD and TDS still contain their original (now wrong) text with a banner on top pointing at the ADR that replaced it. Read the ADRs first, then treat PRD/TDS as background.

Issue tracking is Linear, team key MAR (per docs/agents/issue-tracker.md; note AGENTS.md still says team FORGE — that is a stale inconsistency). Ticket refs like MAR-16 appear throughout.


1. What Forge is

A local-first engineering workspace where a developer coordinates their own work and work delegated to AI coding agents, without losing awareness, judgement, or final approval.

The framing: the hard problem is no longer getting AI to write code, it is using increasingly autonomous agents without losing awareness, engineering skill, control, or software quality.

Forge is not an IDE, a chat app, an agent terminal manager, a swarm framework, a PM SaaS, or a coding agent. It is a control plane organized around engineering work, not around sessions.

The four core problems (PRD §4)

  1. Being out of the loop — a raw transcript is technically transparent and practically useless.
  2. Skill atrophy — the developer must be able to dial their own involvement.
  3. AI tool fatigue — consolidate the machinery.
  4. High-quality output — verification + mandatory human review.

Principles (PRD §5)

  • Work is primary — the task is the unit; agent runs are subordinate records.
  • Human judgment is first-class — answer "where do I need to think?", not "what's running?".
  • Local first — no account, no hosted backend; offline-capable.
  • Existing agents stay native(qualified heavily by ADR-0007, see §4).
  • Git is the code source of truth — no competing AI representation of the repo.
  • Provide primitives, not ceremony.
  • Human review is mandatory by default — AI never auto-transitions to Done.

North star

"I am still engineering. The AI is doing work for me, and the workspace handles the machinery."

Platform

Linux-first, Omarchy as a first-class target. Electron + React + TypeScript over an independent Go core (workspace-core), SQLite, typed local RPC.


2. Domain vocabulary (CONTEXT.md — use these terms exactly)

Work

  • Task — the unit of engineering work; everything attaches to it. Avoid: ticket, issue, story.
  • Agent Run — one supervised execution of an agent against a task. A run is not a process; its identity is opaque and may be assigned by the agent. Avoid: session, job, process.

Policy

  • Execution Modewho authors the implementation (human or agent).
  • Involvement Modehow readily an agent stops to consult the human. A preset over an escalation policy. Avoid: autonomy level, working style.
  • Escalation Policy — two halves: a host-enforced half (tool-call gating) and an agent-instructed half.
  • Escalation Reason — eight named classes (see §4). An involvement mode is a subscription to a subset of them.
  • Escalation Tool — the tool Forge injects into a run, replacing the agent's native question tools, through which the agent raises a Decision.
  • Assumptions Ledger — choices an agent made without escalating, recorded per turn, surfaced in review. Guards against the missing escalation.
  • Learning Checkpoint — an escalation raised so the developer thinks, not because the agent is blocked. The distinguishing feature of Teach Me.
  • Policy Snapshot — the escalation policy in force when a run started, recorded immutably.

Adapters

  • Agent Adapter — a binding to one (agent, strategy) pair, not one per agent.
  • Execution Strategy — the particular way an agent is driven (subprocess+protocol, long-lived service, …). Capabilities belong to a strategy.
  • Capability — something an adapter may support, declared honestly; a precondition on the domain model, not a UI hint.
  • Stopped Reasoncompleted | user_stopped | crashed | supervisor_shutdown | agent_error | deferred. Distinct from delivery error (Forge failed to capture output the agent produced).

Gating

  • Tool Capability Class — every adapter classifies each tool as read, write, or exec.
  • Gating Tier — how aggressively the host stops tool calls, by class. Independent of involvement mode.

Activity

  • Meaningful Activity — two tiers: agent-authored phases over deterministic steps. Narrated by the agent as it works, never summarized from its transcript.
  • Intent Marker — an agent-authored statement of intent/conclusion (the coarse tier).
  • Fact — something Forge observed (a file edited, an exit status).
  • Claim — something the agent said. Never merged with facts.

Human attention

  • Decision — a recorded moment where human judgement was required, carrying its escalation reason, options, and resolution. Avoid: question, prompt, approval.
  • Needs You — the task state entered when waiting on human judgement.

3. Information & lifecycle model

Workspace
└── Project (= one local git repo; multi-repo is post-MVP)
    ├── Feature
    │   └── Task
    ├── Standalone Task
    ├── Artifacts
    ├── Decisions
    └── Project Knowledge

Task lifecycle:

BACKLOG → READY → WORKING ⇄ NEEDS_YOU

                  REVIEW ⇄ WORKING (changes requested)

                   DONE

REVIEW → DONE requires human approval + valid required verification + acknowledged acceptance criteria. Note (TDS §18 banner): whether a red check blocks or merely annotates was explicitly deferred (MAR-14) — this transition asserts a gate nobody has decided.

Surfaces: Kanban / List / Tree over the same objects, Decision Inbox (global, flagship), Review (diff + criteria + verification + inline comments + optional AI review + mandatory human approval), meaningful activity feed, automatic worktrees (one active task → one worktree).


4. The twelve ADRs — this is where the ideas changed

ADR-0001 — Involvement and execution are separate axes

PRD modelled Delegate / Collaborate / Teach Me / I'll Implement as one four-value choice. They are not peers. Split into execution mode (who authors) × involvement mode (escalation preset), so "I'm writing this, but teach me as we go" is expressible. Switching execution mode mid-run is a stop, not a policy change.

ADR-0002 — Escalation-dependent involvement modes require a capability

Some CLIs cannot ask the supervisor anything (codex exec --json has no back-channel; OpenCode's ACP bridge has no question handler). Such adapters offer Delegate only. Silent degradation is refused: an agent that never asks is indistinguishable from an agent doing fine.

ADR-0003 — Host gating is by tool capability class, not tool name

Tool names differ per agent (Bash / shell / run_command), so name-based rules don't port, and delegating to each agent's permission system makes policy only as strong as the weakest agent. Classes are exactly read | write | exec. Gating tier is independent of involvement mode — Delegate means "don't interrupt me for engineering choices", not "don't stop before rm -rf".

ADR-0004 — Bounded event replay with snapshot fallback

TDS §8's "reconnect using last sequence number" is unbounded. t3code shipped exactly that and its own source records the outcome: "reconnects with cursors hundreds of thousands of events behind have OOM-killed servers". Five rules replace it: bound the gap (snapshot beyond it); subscribe before snapshotting; buffer and drain before declaring sync; bound to the head captured at catch-up start; treat a cursor ahead of the server as invalid. Not implemented in the current plan — it's a core↔UI concern and there is no UI yet.

ADR-0005 — Agent transcripts live outside SQLite

vibe-kanban went through four schema regimes in ~8 months before migrating transcripts out to flat JSONL behind a blocking startup migration + VACUUM. Forge stores raw transcripts as append-only files on disk from the start; SQLite holds only what is queried. TDS §9's "append-oriented activity tables" applies to normalized activity only.

ADR-0006 — Agent-run completion is a state, not an edge

"Done" is not reliably done. OMP hit this three times in production; opencode avoids it by re-deriving the continuation condition each step. Claude Code's exit code cannot classify a run (policy denial and tool_deferred both exit 0; SIGINT exits 0 with an error result; SIGTERM exits 143 with no result event). So AgentRunCompleted carries a terminality flag and is supersedable, and classification comes from the run's own result event. Nothing user-visible fires on the first completed event — not task transitions, not notifications.

ADR-0007 — Escalation is an injected tool, not inference ⭐ (the load-bearing one)

An output stream never contains what the agent was considering. A supervisor watching from outside can only infer mechanical reasons; ARCHITECTURAL_DECISION and ASSUMPTION_CONFLICT are not inferable at all. So Forge suppresses each agent's native question tools and registers its own escalation tool, instructing the model to prefer it. (Sculptor already ships this.) All four target CLIs support it per-invocation.

The native boundary — an explicit, deliberate departure from PRD §5.4:

Forge configures a run, never a repository or a user. Per-invocation flags, env, an MCP server on the command line, a registered host tool — permitted. Writing to the user's or the repo's agent config files — not permitted, at all.

All ten surveyed orchestrators cross the "stay native" line at the permission boundary; PRD §5.4 describes nobody's practice.

Blocking discipline: adapters declare whether they hold the process or exit-and-resume; the core implements both. Prefer exit-and-resume ("unattended overnight" otherwise means a held process for ten hours).

Consequences: every Decision carries a recommended option; deadlines are supported but off by default and never permitted for DESTRUCTIVE_ACTION; a default-fired resolution is recorded as such so it is never mistaken for human review.

Amended by the live prototype (MAR-16), two findings:

  1. The escalation tool must be explicitly allowlisted and the adapter must verify it. A permission mode that accepts edits does not cover MCP tools. When the tool was called but denied, the agent fell back to guessing and continued — a silently-denied escalation tool is indistinguishable from a working one until you read the transcript.
  2. Forge must isolate a run from ambient user config, not merely refrain from adding to it. An un-isolated run inherited the machine's user-level MCP servers and permission hooks.

Also demonstrated end-to-end: an instructed model does use the tool, including obeying an answer that contradicted its own recommendation; an identical run without the tool made the same choice silently. Untested: the escalation rate across varied real tasks.

The eight escalation reasons (pruned from TDS §20's ten — AGENT_UNCERTAINTY cut because it describes every escalation; SECURITY_DECISION folded into DESTRUCTIVE_ACTION + ADR-0003 gating):

  • Host-inferable: DESTRUCTIVE_ACTION, VERIFICATION_FAILURE
  • Agent-declared: ARCHITECTURAL_DECISION, MULTIPLE_VALID_APPROACHES, REQUIREMENT_AMBIGUITY, ASSUMPTION_CONFLICT, LEARNING_CHECKPOINT, USER_REQUESTED

ADR-0008 — Agents record the assumptions they did not escalate

The dangerous failure is the missing escalation. No surveyed tool addresses it. The agent is instructed to emit an assumptions ledger at end of turn, surfaced in review beside the diff. Rides ADR-0007's mechanism, so it costs no extra model call. It is agent-authored and therefore narrows where a reviewer looks; it does not replace review. Not in the current plan — needs ADR-0011's narration channel; named as the first follow-up.

ADR-0009 — Adapters register per strategy, and a run is not a process

TDS §21 assumed one adapter per agent and one process per run. Both fail.

  • Capabilities belong to a strategy. "Codex (app-server)" and "Codex (exec)" register as separate, selectable adapters. Choosing an agent is really choosing a capability set.
  • A run is not a process. OpenCode is one long-lived server hosting many sessions; run identity is a persisted session id, events arrive demultiplexed on a shared bus, killing the process kills every session. So process supervision, PTY handling and run recovery (TDS §24–26) move inside adapters. The core owns run lifecycle, not processes.
  • pi and OMP are two adapters over one shared decoder package (OMP is a hard fork of pi; the ~20% that differs is exactly capabilities, escalation, session identity and config discovery).
  • Session identity may be agent-assigned (Codex has no --session-id), so AgentRun carries a nullable external session id populated from the first event.

ADR-0010 — The core persists the raw line before anything parses it

Every raw line hits durable storage before the adapter interprets it; adapters emit canonical events on a channel the core drives and never push into shared state. Normalization becomes a projection over retained data, so a parser bug is recoverable and history can be re-normalized. Unknown-event policy: loud at the message level, quiet at the delta level (an unrecognised message is surfaced with its payload; an unrecognised streaming delta is dropped since its content arrives in the completed message). Dispatch is the opposite — an unrecognised type being acted on fails closed, loudly.

ADR-0011 — Meaningful activity is authored by the agent, not summarized from it

PRD §22's "Found reusable worker retry infrastructure" is a conclusion, not a summary of tool calls; no parser recovers it. The best prior art (Vibe Kanban's ActionType) yields "Edited scheduler.rs". Not one of ten surveyed tools runs a model over agent activity; OMP actively disables an extra model call for this.

So Forge asks the agent to narrate — the third use of ADR-0007's injected-tool mechanism. Two tiers: phases (agent-authored, coarse, a handful per task) over steps (deterministic, from tool events, nested, collapsed by default). Markers come from two sources:

  • Native plan/todo events where the adapter declares NativePlan — free, unprompted, says what the agent intends.
  • An injected narration marker for findings — nothing emits conclusions unless asked.

Prefer the free source; instruct only for what it cannot provide. Activity streams during the run rather than being produced afterwards. Missing narration degrades to deterministic steps and disqualifies nothing — escalation remains the only capability whose absence gates a mode.

ADR-0012 — Facts and claims are never merged

"Edited scheduler.rs" is observed; "Found reusable worker retry infrastructure" is said. In one undifferentiated feed they read as equally verified. Deterministic tool-derived events are facts; intent markers and the assumptions ledger are claims. The distinction lives in the data model, not in rendering, so it survives every change to display/export/AI-review. When narration is absent, Forge falls back to facts and shows the gap honestly. It never fills one in.


5. Research findings that drove the decisions

Seven research documents, all dated 2026-09-01, all primary-source (repos cloned and read at pinned SHAs; binaries probed live; claims labelled [code] / [test] / [schema] / [inference] / observed — not guaranteed).

Agent CLI execution surfaces

Against TDS §23's ladder (native structured events > JSON/JSONL > hooks > PTY parsing > raw PTY):

AgentVersion probedLadder rungCan it block on a question?
Claude Code2.1.252Rung 1 — bidirectional NDJSON agent protocol over stdin/stdout, control_requests in, interrupt as a first-class verb, ~30 hook events, per-tool-call permission delegation that blocks the agentYes, three ways
Codex0.151.0Rung 1 via codex app-server (JSON-RPC 2.0, full duplex, server→client requests that block the agent). codex exec --json is rung 2 with no back-channel at allYes (app-server only)
pi / OMPpi 0.84.3, omp 18.0.10Rung 1 both. OMP is a hard fork of pi with near-identical protocol vocabulary → two adapters over one shared transport coreYes, both — the strongest finding
OpenCode1.18.25Rung 1 via HTTP/SSE only — OpenAPI 3.1 served by the binary, 89 discriminated SSE event variants. opencode run --format json republishes only 6 flattened kinds (~93% loss) and forfeits blocking questionsYes natively via HTTP — but opencode run turns it off

OpenCode's verdict is emphatic: it is service-shaped, and Start(ctx, req) (RunningAgent, error) as written in TDS §21 does not fit it. That finding is what produced ADR-0009.

Orchestrator survey (10 tools) — where the field has converged

  • C1. Nobody parses a terminal when a machine protocol exists. TDS §23's ladder is a description of settled practice, not a hypothesis.
  • C2. Everyone normalizes to one internal event vocabulary and they look alike (user msg / assistant msg / reasoning / tool-use-with-lifecycle / plan / todo / error / compaction / usage).
  • C3. Progress is derived deterministically. Not one tool runs an LLM over agent activity.
  • C4. The unit of isolation is the git worktree; the unit of integration is the branch/PR.
  • C5. Every tool crosses the "stay native" line at the permission boundary, without exception. Anyone claiming a fully native line has not implemented approvals.
  • C6. Nobody reimplements authentication or native config.

Where the field is genuinely split

  • S1. How much of the agent you rewrite — four positions, from Claude Squad's untouched process (attention = English substring matching) through t3code's machine-protocol-no-prompt-changes to Sculptor's substituted tools + injected system prompt. "Everyone drifts toward position 4 for any feature they actually care about; the line is drawn per-feature, not per-product."
  • S2. Worktree isolation automatic vs opt-in (a worktree-per-task default is a per-task tax).
  • S3. Surface, replace, or suppress the agent's questions. "Forge's Decision Inbox is only viable if the answer path is as reliable as the question path."
  • S4. Local worktree vs remote container — notably, OMP prefers filesystem-level clones (APFS/Btrfs/ZFS/reflink/overlayfs) and treats worktree as a back-compat alias, i.e. the people closest to the isolation problem think git worktrees are the weakest backend.

What nobody has solved

  • U1. Turning tool calls into engineering narrative. Nobody is even attempting it. This is the biggest gap in the field and the biggest risk in Forge's design — and it is what ADR-0011 answers by asking the agent to narrate rather than trying to infer.

Harness/orchestrator internals read

vibe-kanban (Rust, 34 crates, Axum+SQLite+Tauri), t3code (TS, Effect-TS, SQLite event store), Chorus (TS/Next.js+Prisma), pi, OMP, opencode. Key transferable disagreement: is the event log the source of truth? t3code says yes (and paid for it with the OOM bug behind ADR-0004); opencode went the other way. Forge takes the middle road (TDS §9 + ADR-0005).


6. Data model (TDS §10–17, as reconciled 2026-09-01)

Tables/entities: Workspace, Project, Feature, Task, AcceptanceCriterion, TaskDependency, AgentDefinition, AgentRun, AgentRunMessage, AgentEvent, Decision, DecisionOption, DecisionResolution, Worktree, VerificationDefinition, VerificationRun, Review, ReviewComment, Artifact, ProjectKnowledge.

Reconciliation changes (the ones that matter):

  • Taskinvolvement_mode becomes two fields, execution_mode + involvement_mode (ADR-0001). preferred_agent names a strategy, not an agent (ADR-0009).
  • AgentRunexit_code dropped, replaced by stopped_reason ∈ {completed, user_stopped, crashed, supervisor_shutdown, agent_error, deferred} plus nullable delivery_error. status carries a terminality flag and is supersedable. agent_type becomes a strategy id. Adds policy_snapshot (immutable). session_identifier stays nullable (Codex assigns it).
  • AgentEventraw_reference is not optional (ADR-0010) and a fact/claim discriminator is added (ADR-0012).
  • Decisioncategory is the eight-value reason set. recommendation is required. Adds an optional deadline, off by default, never for DESTRUCTIVE_ACTION.
  • DecisionResolution — must distinguish human-judged from default-fired.

Worktree statuses: ACTIVE | MERGING | MERGED | ABANDONED | REMOVED. Review statuses: PENDING | IN_PROGRESS | CHANGES_REQUESTED | APPROVED | STALE. Verification status is valid only for the revision it ran against; current_revision != verified_revision ⇒ STALE.


7. Architecture & technical spec highlights

Electron (window lifecycle, notifications, OS integration, core daemon lifecycle)

React renderer (Kanban/List/Tree, task workspace, Decision Inbox, Review/Diff, Settings)
    │  typed local RPC (loopback only, random session token)
Go core `workspace-core` (domain, agent supervision, decisions, git/worktrees,
    verification, review, SQLite, realtime events)

Claude Code · Codex · pi/OMP · OpenCode  →  Git worktrees
  • Core stack: Go, stdlib-first, SQLite, log/slog, context.Context, native subprocess, PTY where needed, the user's git binary (never a git library — vibe-kanban got this wrong with libgit2 twice).
  • Desktop: Electron + TypeScript + React + Vite; TanStack Router/Query; Zustand for ephemeral UI state only; Tailwind; Radix; Lucide; xterm.js; a diff library.
  • Protocol: Protobuf + ConnectRPC + Buf recommended; a typed HTTP API + server streaming is acceptable. The requirement is a generated shared contract between Go and TS.
  • API shape: domain commands (CreateTask, StartTask, ResolveDecision, ApproveTask, RunVerification, RequestAIReview), not CRUD. Queries may be resource-oriented.
  • Electron security: nodeIntegration: false, contextIsolation: true, sandboxed renderer, narrow preload, no arbitrary renderer command execution. External editor goes through a controlled argv path, never shell-string concatenation.
  • XDG paths: $XDG_DATA_HOME/<app>/workspace.db, config/state/cache under their XDG homes.
  • Migrations are versioned and embedded in the Go binary; applied before serving.
  • Concurrency: goroutines + context, a lightweight in-process supervisor. No distributed job queue. Configurable max_concurrent_agent_runs / max_concurrent_verification_runs; conservative defaults — permit parallelism without encouraging excessive parallelism.
  • Testing: Go unit + integration (real temp git repos, no git mocks), an adapter contract suite every adapter must pass, frontend component/route tests, and E2E driven by a fake deterministic agent so no model API is needed in CI.
  • Packaging: AppImage first, then AUR/.deb. Go core bundled with Electron.

Core technical principle:

React knows presentation. Electron knows desktop integration. Go knows engineering work and execution. Agents know how to code. Git knows the repository.


8. MVP scope

In: Projects, Features, Tasks, Kanban/List/Tree, the task-creation workflow, involvement modes, adapters for Claude Code + Codex + pi/OMP + OpenCode, automatic worktrees, activity normalization, Decision Inbox, diff review, inline review comments, verification commands, mandatory human approval, external editor integration, raw agent-session access.

Explicitly out: proprietary models or agents, swarms, execution DAGs, model routing, team collaboration, mobile, hosted execution, learning analytics, a full AI memory system, prompt/skill marketplaces, a Jira replacement, a full IDE, a mandatory account, a custom methodology.

Technical milestones: 1 Shell → 2 Work model → 3 Git → 4 First agent (Claude Code) → 5 Human attention (decisions / Needs You / Inbox) → 6 Quality loop (verification, review, approval) → 7 More agents → 8 Hardening.

Acceptance test: the full loop — create feature → task → goal + criteria → involvement mode → launch agent → automatic worktree → meaningful progress → ambiguity → Needs You → resolve → continue → verify → review → inline feedback → agent revision → human approval → merge → Done — must feel natural.

Metrics are behavioral, not vanity: how often raw logs are needed (lower better), whether Needs You events are genuinely meaningful, review rate (target ~100% by design), verification rate, tool consolidation, and return clarity after reopening a project later.


9. Current implementation state

Plan: docs/plans/2026-09-01-core-spine.md — 15 tasks, fully written out (real code and real tests in every step, no TBDs), executed via the superpowers subagent-driven-development skill.

Goal of this milestone: the Go core that takes a task, runs Claude Code inside an isolated git worktree, streams legible activity, and blocks to ask the human when the work is ambiguous.No UI — exercised through a CLI harness and tests.

Global constraints (non-negotiable, from the plan):

  • Go 1.26, module github.com/MarzouqAdebayo/forge/core, all code under core/.
  • No cgo — SQLite is modernc.org/sqlite (the core must cross-compile for packaging).
  • Use the user's git binary, never a library.
  • Never delete a worktree containing uncommitted changes (vibe-kanban's 72-hour timer is the failure to avoid).
  • Raw before parse — every Event carries a non-empty RawRef.
  • Facts and claims never merge — no code path produces an event without setting Kind.
  • Exit codes never classify a run.
  • Forge configures a run, never a repository or a user — never write ~/.claude, .claude/settings.json, or .mcp.json.
  • Always pass --strict-mcp-config to isolate a run from ambient config.
  • Every test touching git creates a real temporary repository. No git mocks.

Planned package layout:

core/
├── cmd/workspace-core/main.go     CLI: serve, task, run, escalation-server
└── internal/
    ├── storage/     SQLite open + embedded migrations          ← Task 1 (partial)
    ├── domain/      Task, modes, state machine                 ← Task 2
    ├── gitsvc/      git binary wrapper + worktree lifecycle    ← Tasks 3–4
    ├── rawlog/      append-only JSONL, returns RawRef          ← Task 5
    ├── events/      Event, Kind (fact/claim), StoppedReason    ← Task 6
    ├── agent/       AgentAdapter, per-strategy registry,
    │                contract suite, fake/, claudecode/         ← Tasks 7–9
    ├── decision/    Decision model + escalation MCP server     ← Tasks 10–11
    ├── activity/    steps from facts, phases from claims       ← Task 13
    └── orchestr/    preflight + task→run→Needs You→resume      ← Tasks 12, 14

Responsibility boundaries: rawlog knows nothing about agents; events knows nothing about SQLite; agent never touches the database; orchestr is the only package that coordinates across the others.

The 15 tasks: 1 bootstrap SQLite+migrations · 2 task domain & state machine · 3 git service · 4 worktree lifecycle that refuses to destroy work · 5 raw log · 6 event model with fact/claim split · 7 adapter contract + per-strategy registry · 8 fake adapter + the contract suite · 9 Claude Code adapter (stream-json wire decoding) · 10 decision model + mode subscriptions · 11 the escalation tool as an MCP server (blocking; MAR-16 measured an 8-second block with clean resume) · 12 escalation preflight (verify the tool is actually invocable — the one capability the core preflights, because its failure is silent) · 13 activity projection · 14 orchestration · 15 CLI + live acceptance run.

Deliberate gaps in the plan, named rather than hidden:

  • ADR-0004 not implemented — bounded replay is a core↔UI concern; there is no UI this milestone.
  • ADR-0008 not implemented — the assumptions ledger needs Task 13's claim channel. Named as the first follow-up after this plan lands, and cheap once that channel exists.

What actually exists in code (~160 lines, untracked — core/ is still ?? in git)

  • core/go.mod — Go 1.26.2, modernc.org/sqlite v1.57.0.
  • core/internal/storage/migrate.gocomplete. Embedded migrations/*.sql via embed.FS, applied once each in filename order, each inside its own transaction alongside its schema_migrations row, so a half-applied migration is impossible.
  • core/internal/storage/migrations/001_init.sqlworkspaces, projects, tasks. The tasks table already reflects ADR-0001 (execution_mode + involvement_mode) and ADR-0009 (preferred_strategy).
  • core/internal/storage/db.gohas an open TODO(human). pragmas() returns nil; it needs to decide foreign_keys (off by default in SQLite, so every REFERENCES in 001_init.sql is currently unenforced), journal_mode (WAL vs default), and busy_timeout. The doc comment records a verified finding: pragmas must go in the DSN, not db.Exec, because *sql.DB is a pool and an Exec'd pragma lands on one connection only — two pooled connections were observed disagreeing about foreign_keys.
  • core/internal/storage/migrate_test.go — tests migration idempotence and that foreign keys are on (the latter currently fails until the TODO(human) is filled).

Immediate next steps: fill pragmas(), then Task 2 onward.


10. Open questions / known tensions

  1. Verification policy is undecided (MAR-14) — does a red required check block REVIEW → DONE or merely annotate? TDS §18 asserts a gate nobody decided.
  2. Escalation rate is untestedMAR-16 proved the mechanism works on one task; whether agents escalate at a useful frequency across varied real work is unknown, and it is the product's central bet.
  3. Durable global sequence for the agent-run subtree — explicitly left open by ADR-0005.
  4. Worktree-per-task tax (survey S2) — setup cost per task (deps, dev server, index) is real; the PRD does not argue its side.
  5. AGENTS.md says Linear team FORGE; docs/agents/issue-tracker.md says MAR. The MAR-* refs throughout the ADRs suggest MAR is correct and AGENTS.md is stale.
  6. PRD §5.4 vs ADR-0007 — the README and PRD still advertise "existing agents stay native", which ADR-0007 explicitly and deliberately departs from. Worth reconciling the public framing.
  7. U1 remains unproven — ADR-0011's bet (ask the agent to narrate) is a plausible answer to a problem no shipped tool has solved. If agents narrate poorly, the feed degrades to the field standard ("Edited scheduler.rs") — survivable, but the flagship promise of PRD §22 goes with it.

Forge is local-first. The docs are part of the product engineering system.