Commit graph

522 commits

Author SHA1 Message Date
Snider
2fc0de321d feat(agent): RFC §15.5 orphan QA buffer recovery on startup
Adds `recoverStateOrphans` per RFC §15.5 — startup scans `.core/state/`
for leftover QA workspace buffers from dispatches that crashed before
commit, and discards them so partial cycles do not poison the diff
history described in RFC §7.

- `statestore.go` — new `recoverStateOrphans` wrapper around go-store's
  `RecoverOrphans("")` so the agent inherits the store's configured
  state directory
- `prep.go` — wires the recovery into OnStartup immediately after
  `hydrateWorkspaces` so the registry, queue, and buffers all come back
  into a consistent state on restart
- `statestore_test.go` — Good/Bad/Ugly coverage, includes the cwd
  redirect guard so the go-store default relative path cannot leak test
  artefacts into the package working tree

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 13:51:54 +01:00
Snider
03e5934607 feat(agent): RFC §15.5 parent workspace stats store
Adds `.core/workspace/db.duckdb` — the permanent record of dispatch
cycles described in RFC §15.5. Stats rows persist BEFORE workspace
directories are deleted so "what happened in the last 50 dispatches"
queries survive cleanup and sync drain.

- `workspace_stats.go` — lazy go-store handle for the parent stats DB,
  build/record/filter/list helpers, report payload projection
- `commit.go` — writes a stats row as part of the completion pipeline so
  every committed dispatch carries forward into the permanent record
- `commands_workspace.go` — `workspace/clean` captures stats before
  deleting, new `workspace/stats` command + `agentic.workspace.stats`
  action answer the spec's "query on the parent" use case

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 13:41:07 +01:00
Snider
364655662a feat(agent): RFC §7 Post-Run Analysis — diff + cluster dispatch findings
Extends DispatchReport with the three RFC §7 diff lists (New, Resolved,
Persistent) and a Clusters list that groups findings by tool/severity/
category/rule_id. runQAWithReport now queries the SQLite journal for up
to persistentThreshold previous cycles of the same workspace, computes
the diff against the current cycle, and populates .meta/report.json
before ws.Commit(). The full findings payload is also pushed to the
journal via CommitToJournal so later cycles have findings-level data
to compare against (workspace.Commit only stores aggregated counts).

Matches RFC §7 Post-Run Analysis without pulling in Poindexter as a
direct dependency — uses straightforward deterministic clustering so
agent stays inside the core/go-* dependency tier.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 13:19:34 +01:00
Snider
eaf17823d9 feat(agent): RFC §7 QA capture pipeline
The runQA handler now captures every lint finding, tool run, build, vet
and test result into a go-store workspace buffer and commits the cycle
to the journal. Intelligence survives in the report and the journal per
RFC §7 Completion Pipeline.

- qa.go: QAFinding / QAToolRun / QASummary / QAReport DTOs mirroring
  lint.Report shape; DispatchReport struct written to .meta/report.json;
  runQAWithReport opens NewWorkspace("qa-<workspace>"), invokes
  core-lint run --output json via c.Process().RunIn(), records every
  finding + tool + stage result, then commits
- runQALegacy preserved for graceful degradation when go-store is
  unavailable (RFC §15.6)
- dispatch.go: runQA now delegates to runQAWithReport, bool contract
  unchanged for existing call sites
- qa_test.go: Good/Bad/Ugly triads per repo convention

Poindexter clustering from RFC §7 Post-Run Analysis remains open —
needs its own RFC pass for the package boundary.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 13:02:14 +01:00
Snider
eed2274746 feat(agent): pairing-code login per RFC §9 Fleet Mode
Implements `core login CODE` — exchanges a 6-digit pairing code generated
at app.lthn.ai/device for an AgentApiKey, persisted to ~/.claude/brain.key.
Pairing code is the proof, so the POST is unauthenticated.

- auth.go: AuthLoginInput/Output DTOs + handleAuthLogin handler
- commands_platform.go: login / auth/login / agentic:login CLI commands
  with cmdAuthLogin persisting the returned key
- prep.go: registered agentic.auth.login / agent.auth.login actions
- auth_test.go / commands_platform_test.go / prep_test.go: Good/Bad/Ugly
  triads per repo convention, including key persistence verification

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 12:51:17 +01:00
Snider
716546d0d5 feat(agent): workspace state mirror + ghost reap + sync queue via go-store
- prep.go TrackWorkspace mirrors into queue + concurrency store groups
  (previously only registry); hydrateWorkspaces reaps filesystem ghosts
  (dead PID → failed, persisted back to status.json) so cmdStatus and
  out-of-process consumers see coherent state (RFC §15.3)
- sync.go queue read/write goes through go-store first per RFC §16.5
  ("Queue persists across restarts in db.duckdb"), file remains fallback
  for graceful degradation
- statestore.go stateStoreGet helper for go-store-first reads
- tests/cli/restart — new CLI test for RFC §15.7 "dispatch → kill →
  restart → no ghost agents" dead-PID reap flow
- 4 new statestore tests: queue group mirror, concurrency refresh,
  sync queue persistence, fs ghost reap with disk write-back

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 12:36:44 +01:00
Snider
4684ae725a feat(agent): go-store backing for dispatch state per RFC §15
Introduce an optional go-store persistence layer for the three state
groups described in RFC §15.3 — queue, concurrency, registry — plus
runtime_state and dispatch_history used by the sync pipeline.

- statestore.go lazily opens `.core/db.duckdb` via go-store when
  available; nil-safe helpers return cleanly so in-memory/file-based
  fallbacks survive when the store cannot open (graceful degradation,
  RFC §15.6)
- prep.go tracks the store reference on the subsystem and closes it on
  shutdown; hydrateWorkspaces now consults the registry group before
  the filesystem scan so ghost agents are marked failed across
  restarts, and TrackWorkspace mirrors updates back into the cache
- runtime_state.go persists backoff + fail-count snapshots into the
  go-store runtime group so dispatch backoff survives restarts even
  when the JSON file rotates
- commit.go writes the completed dispatch record into dispatch_history
  for RFC §16.3 sync push to drain without rescanning workspaces
- statestore_test.go covers lazy-once init, restore/delete round trip,
  ghost-agent failure marking, and runtime-state replay across
  subsystem instances

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 12:17:08 +01:00
Snider
83364a6080 feat(agent): sync backoff + ledger + auto-flush loop
- sync.go: syncBackoffSchedule (1s/5s/15s/60s/5min) with per-push Attempts
  and NextAttempt honoured on retry (RFC §16.5)
- runSyncFlushLoop: ticks every minute from OnStartup when API key present,
  drains the queue without re-scanning workspaces
- SyncPushInput.QueueOnly: lets flush loop drain without triggering a full
  workspace scan (prevents duplicate pushes)
- Sync ledger at .core/sync/ledger.json: fingerprints keyed by workspace
  name + (updated_at, runs); skips already-synced workspaces until fresh
  activity
- docs/RFC-AGENT.md: synced from plans/code/core/agent/RFC.md with latest
  AgentPlan status enum, complete capability, pr.close/branch.delete,
  indexed_at/org brain fields

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 12:06:04 +01:00
Snider
edfcb1bdfe feat(agent): unblock factory dispatch, runtime-aware containers, RFC gaps
- paths.go: resolve relative workspace_root against $HOME/Code so workspaces
  land in the conventional location regardless of launch cwd (MCP stdio vs CLI)
- dispatch.go: container mounts use /home/agent (matches DEV_USER), plus
  runtime-aware dispatch (apple/docker/podman) with GPU toggle per RFC §15.5
- queue.go / runner/queue.go: DispatchConfig adds Runtime/Image/GPU fields;
  AgentIdentity parsing for the agents: block (RFC §10/§11)
- pr.go / commands_forge.go / actions.go: agentic_delete_branch tool +
  branch/delete CLI (RFC §7)
- brain/tools.go / provider.go: Org + IndexedAt fields on Memory (RFC §4)
- config/agents.yaml: document new dispatch fields, fix identity table
- tests: dispatch_runtime_test.go (21), expanded pr_test.go + queue_test.go,
  new CLI fixtures for branch/delete and pr/list

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-14 11:45:09 +01:00
Snider
db6d06ae2b merge: integrate forge dispatch + mcp changes with AX compliance sweep
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:39:41 +01:00
Snider
39914fbf14 refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.

Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:00 +01:00
Snider
7a531d1112 perf(mcp): reduce tool count from 189 to 82
Gate non-essential MCP tools behind CORE_MCP_FULL=1 env var.
Core factory tools (dispatch, status, plan, issue, PR, scan, mirror,
watch, brain, files) always registered. Extended tools (session, sprint,
state, phase, task, template, message, content, platform, epic, remote,
review-queue, setup, metrics, RAG, webview) only when full mode enabled.

189 → 82 tools in default mode. Fixes slow MCP startup and tool
registration timeout in Claude Code.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-08 19:17:21 +01:00
Snider
e8862e26be feat(dispatch): LEM profiles + native Claude agents
- Add isLEMProfile(): codex:lemmy/lemer/lemma/lemrd use --profile not --model
- Add isNativeAgent(): Claude agents run natively (not in Docker)
- Update localAgentCommandScript for LEM profile support
- 12 new tests (Good/Bad/Ugly for profiles, native agent, codex variants)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-08 17:17:33 +01:00
Snider
9c6f10902e fix(agent): mcp.Register startup panic + test isolation + CLI test standard
- Replace broken registerMCPService with mcp.Register (fixes nil ServiceRuntime panic)
- Remove dead mcp_service.go, update tests to use mcp.Register directly
- Add setTestWorkspace() helper to clear workspaceRootOverride between tests
- Fix 40+ test files with workspace state poisoning from loadAgentConfig
- Fix forge.lthn.ai → dappco.re in findConsumersList test
- Fix BranchWorkspaceCount test to use isolated temp dir
- Add CLI test standard: 32 tests across 19 subsystems (tests/cli/)
- All 9 packages pass, 0 failures

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-08 16:15:14 +01:00
Snider
5f0878d93d fix(mcp): update Subsystem interface to match mcp v0.5.1 Service API
All RegisterTools and internal register*Tool methods updated from
*mcp.Server to *coremcp.Service. Tool registration calls updated to
use svc.Server() for SDK AddTool calls. Monitor subsystem updated
to store *coremcp.Service and access Server() for Sessions/ResourceUpdated.
Tests updated to create coremcp.Service via New() instead of raw SDK server.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-07 14:11:19 +01:00
Snider
a4b72c6129 fix: migrate module paths from forge.lthn.ai to dappco.re
Replace all forge.lthn.ai import paths in Go source files with dappco.re
equivalents. Update go.mod deps to dappco.re versions as specified.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-07 13:09:47 +01:00
Virgil
2a95ba6ff5 fix(agentic): normalise remote host inputs
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 09:12:49 +00:00
Virgil
6bc24d5213 docs(ax): replace alias descriptions with usage examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 09:07:12 +00:00
Virgil
ea53bdbf8c fix(agentic): normalise issue context keys
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 09:01:55 +00:00
Virgil
4c6296c1c1 refactor(agentic): replace core path helpers
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:58:17 +00:00
Virgil
165db215a2 docs(ax): improve remote client usage example
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:53:28 +00:00
Virgil
103fcb473b ax(brain): normalise remember response keys
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:49:22 +00:00
Virgil
8b159abd17 refactor(agentic): wire service runtime directly
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:44:48 +00:00
Virgil
ce6f016d63 ax(brain): rename direct options for clarity
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:40:24 +00:00
Virgil
c27f019a02 feat(agentic): add provider retry backoff
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:36:01 +00:00
Virgil
5f59911e52 ax(agentic): align provider manager comments with ax
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:29:59 +00:00
Virgil
5dc0983b77 feat(agentic): align model contracts with RFC
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:26:02 +00:00
Virgil
4e82ec8da6 feat(agentic): add auth IP restrictions
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:18:43 +00:00
Virgil
0779a7dbe5 refactor(setup-monitor): align service option names with RFC
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:13:16 +00:00
Virgil
44321aab25 fix(agentic): use typed EOF handling
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:08:20 +00:00
Virgil
791fc1a3a1 docs(agentic): improve handler usage example
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 08:04:51 +00:00
Virgil
9f9e42768d fix(agentic): add task aliases and session model normalization
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:59:58 +00:00
Virgil
92703d5af5 fix(agentic): route root plan command
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:47:59 +00:00
Virgil
428cd25ebc feat(agentic): add RFC model aliases
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:43:15 +00:00
Virgil
dfa466707d refactor(agentic): name platform tool inputs
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:37:44 +00:00
Virgil
a18723d564 refactor(agentic): clarify local agent command quoting
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:32:23 +00:00
Virgil
7389b2f801 fix(agentic): add missing plan MCP aliases
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:27:48 +00:00
Virgil
ceaa1601de refactor(agentic): improve prompt builder naming
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:23:08 +00:00
Virgil
b693695e41 feat(agentic): add content provider registry
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:18:38 +00:00
Virgil
75fc9d4bf4 fix(agentic): add namespaced MCP aliases for core tools
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:11:13 +00:00
Virgil
1b1aaa3d66 refactor(monitor): use typed inbox notifications
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:06:12 +00:00
Virgil
f5fdbb8cac fix(agentic): close transport response bodies
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 07:01:51 +00:00
Virgil
e5472f6aa5 ax(agentic): add platform command aliases
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:58:12 +00:00
Virgil
1dd6170dd4 refactor(agentic): validate forge command inputs
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:54:05 +00:00
Virgil
9f1315d1a8 refactor(agentic): add namespaced command aliases
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:47:34 +00:00
Virgil
7a034ccbe8 feat(agentic): expose setup action surface
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:39:02 +00:00
Virgil
613e1fc58e refactor(agentic): add namespaced action aliases
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:29:46 +00:00
Virgil
2d3ec1e8c3 refactor(agentic): centralise remote MCP client
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:23:07 +00:00
Virgil
8c2884cc6f fix(agentic): keep process actions registered
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:14:48 +00:00
Virgil
9a8aa2bfac refactor(agentic): improve AX naming and context propagation
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-02 06:10:33 +00:00