Commit graph

343 commits

Author SHA1 Message Date
Virgil
e8a46c2f95 fix(ax): align runner helper layer and examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 21:27:32 +00:00
Virgil
4cc763176f fix(ax): share workspace path helpers across services
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 21:19:37 +00:00
Virgil
65970527e8 fix(ax): centralise workspace path helpers
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 21:11:46 +00:00
Virgil
547f23a6f0 fix(ax): align core-agent CLI bootstrap
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 21:02:14 +00:00
Virgil
c77a9b93bc fix(ax): finish brain provider cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 20:52:55 +00:00
Virgil
de7844dcb9 fix(ax): restore live agent reference paths
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 20:24:58 +00:00
Virgil
6ac195c2e6 fix(agentic): align workspace flow with AX design
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 20:15:58 +00:00
Snider
6bb4fb8d57 fix(dispatch): concurrency, queue runner, and path improvements
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 20:40:20 +01:00
Virgil
bf27743c44 docs(review): add 2026-03-29 general audit
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 20:00:18 +01:00
Snider
1762620a43 fix(prep): pull latest on workspace resume instead of stale clone
When a workspace already exists (resumed=true), checkout main and
pull origin before creating the feature branch. Prevents agents
from working on stale code after previous runs merged.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 09:22:58 +01:00
Snider
fe1892c9bb missing files from claude's work. 2026-03-27 17:55:06 +00:00
Snider
dd4f6e248f doc save 2026-03-27 17:54:08 +00:00
Snider
95c104f7b3 feat(workspace): add PHP CODEX.md template + language-aware prep
Workspace prep now detects repo language and copies the right CODEX.md:
- Go repos get CODEX.md.tmpl (existing — Core primitives, banned imports)
- PHP repos get CODEX-PHP.md.tmpl (CorePHP patterns, lifecycle events,
  Actions, BelongsToWorkspace, Flux Pro, FA Pro, UK English)

Added lib.WorkspaceFile() helper for reading individual template files.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-27 06:50:54 +00:00
Snider
f7397324b1 feat(prep): clone core/docs into workspace for agent reference
Agents now get the full ecosystem docs (core.help) at
.core/reference/docs/ in their workspace. 349 markdown files
covering architecture, guides, specs — not just the RFC.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-27 04:39:06 +00:00
Snider
9156237923 fix(prompt): tell agents to read CODEX.md + RFC.md first
All dispatch prompts now instruct agents to read CODEX.md (mandatory
patterns) and .core/reference/docs/RFC.md (full API contract) before
starting work. These files were already in the workspace template but
agents were never told to read them.

Also fixes stale references: src/ → repo/, coreerr.E() → core.E().

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-27 03:53:31 +00:00
Snider
23f31953d4 fix(runner): direct spawn via ServiceFor, only mark running after success
drainOne now spawns agents directly via ServiceFor[spawner] instead of
IPC SpawnQueued (which was never received by agentic). Workspace status
is only set to "running" AFTER successful spawn — no more PID=0 ghosts.

Also fixes workspace name resolution: uses relative path from workspace
root (core/go-ai/dev) instead of PathBase (dev).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 14:24:05 +00:00
Snider
ac510fde19 fix(agentic): handle SpawnQueued IPC — actually spawn agents from queue drain
Runner's drainOne sends SpawnQueued but agentic never handled it,
creating ghost "running" entries with PID=0. Now agentic catches
SpawnQueued, calls spawnAgent, and updates status with real PID.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 14:02:56 +00:00
Snider
a174227a62 feat(flow): add v0.8.0 upgrade flow YAMLs + fix runner queue drain
- flow/upgrade/v080-plan.yaml: structured audit for banned imports, tests, comments
- flow/upgrade/v080-implement.yaml: step-by-step implementation with per-step commits
- fix(runner): update workspace Registry on AgentCompleted so concurrency count drops and queue drains

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 13:21:59 +00:00
Snider
6924ff3f49 fix(monitor): push full message content via ChannelPush, not counts
Monitor checkInbox now sends each new message as a ChannelPush with
from/subject/content — lands directly in the Claude Code session.
Removes the useless InboxMessage{New, Total} count relay through runner.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 12:55:52 +00:00
Snider
3b038032af feat(runner): push channel notifications for AgentStarted + AgentCompleted
Runner HandleIPCEvents now catches AgentStarted in addition to
AgentCompleted, sending ChannelPush to MCP for both lifecycle events.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:55:44 +00:00
Snider
63db9e8733 fix(runner): use c.Config().Get() instead of ConfigGet generic
ConfigGet type assertion fails across package boundaries —
agentic stores map[string]agentic.ConcurrencyLimit but runner
tries to retrieve map[string]runner.ConcurrencyLimit.

Use Core's c.Config().Get() → Result → type assert instead.
This is why concurrency limits were never enforced.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:30:38 +00:00
Snider
53db749738 fix(runner): reserve slot on approval to prevent TOCTOU race
Runner now creates a reservation entry (PID=-1) in the workspace Registry
immediately when approving a dispatch. This prevents parallel requests
from all seeing count < limit before any spawn completes.

Reservations are counted by countRunningByAgent/ByModel (PID < 0 = always
count). Agentic overwrites with real PID via TrackWorkspace after spawn.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:23:04 +00:00
Snider
8911dc5f42 fix(agentic): delegate runner/shutdown/poke to runner service
StartRunner and Poke are now no-ops — runner.Service owns the queue.
Shutdown MCP tools delegate to runner.start/stop/kill Actions via IPC.
Updated 18 tests to verify delegation instead of direct state mutation.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:19:45 +00:00
Snider
0fc6eeb4cc feat(runner): extract dispatch runner into independent Core service
Moves concurrency, queue drain, workspace lifecycle, and frozen state
from agentic/prep into pkg/runner/ — a standalone Core service that
communicates via IPC Actions only.

- runner.Register wires Actions: dispatch, status, start, stop, kill, poke
- runner.HandleIPCEvents catches AgentCompleted → ChannelPush + queue poke
- Agentic dispatch asks runner for permission via c.Action("runner.dispatch")
- Dispatch mutex moved to struct-level sync.Mutex (fixes core.Lock init race)
- Registry-based concurrency counting replaces disk scanning
- TrackWorkspace called on both queued and running status writes
- SpawnQueued message added for runner→agentic spawn requests
- ChannelPush message in core/mcp enables any service to push channel events
- 51 new tests covering runner service, queue, and config parsing

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 11:00:47 +00:00
Snider
cf4130a4fa deps: bump dappco.re/go/core to v0.8.0-alpha.1
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 09:37:01 +00:00
Snider
e5b7b4f7d7 fix: only clone direct deps, skip indirect
parseCoreDeps now skips // indirect lines from go.mod.
Reduces cloned repos from 17 to 10 — only what the repo directly imports.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 07:43:02 +00:00
Snider
ba281a2a2d feat: clone workspace dependencies + Docker cleanup
- cloneWorkspaceDeps: reads go.mod, clones Core ecosystem modules from Forge
  into workspace alongside ./repo, rebuilds go.work with all use directives
- Deduplicates deps (dappco.re + forge.lthn.ai map to same repos)
- Container chmod: workspace files made writable before exit so host can clean up
- GONOSUMCHECK for local workspace modules (bypass checksum for dev branches)
- Removed stale OLLAMA_HOST env from container

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 07:37:43 +00:00
Snider
0ffaacca87 fix: CLAUDE.md stale module path — forge.lthn.ai → dappco.re/go/agent
Found by Codex review dispatched from core-agent CLI.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 07:18:33 +00:00
Snider
19d849aa75 fix: use Core PerformAsync for agent monitoring — app stays alive
The monitoring goroutine that waits for agent completion was a raw `go func()`
that Core didn't know about. ServiceShutdown killed it immediately on CLI exit.

Now uses PerformAsync which registers with Core's WaitGroup:
- ServiceShutdown waits for all async tasks to drain
- `core-agent workspace dispatch` blocks until agent completes
- Agent lifecycle properly tracked by the framework

Also whitelist agentic.monitor.* and agentic.complete in entitlement checker.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 07:16:48 +00:00
Snider
b57be6eb91 fix: spawnAgent uses ServiceFor instead of global process.Default()
The global process.StartWithOptions() requires process.SetDefault() which
was never called. Use core.ServiceFor[*process.Service] to get the registered
service instance directly — same code path, proper Core wiring.

Fixes: dispatch failing with "failed to spawn codex" on CLI dispatch.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 06:47:44 +00:00
Snider
537226bd4d feat: AX v0.8.0 upgrade — Core features + quality gates
AX Quality Gates (RFC-025):
- Eliminate os/exec from all test + production code (12+ files)
- Eliminate encoding/json from all test files (15 files, 66 occurrences)
- Eliminate os from all test files except TestMain (Go runtime contract)
- Eliminate path/filepath, net/url from all files
- String concat: 39 violations replaced with core.Concat()
- Test naming AX-7: 264 test functions renamed across all 6 packages
- Example test 1:1 coverage complete

Core Features Adopted:
- Task Composition: agent.completion pipeline (QA → PR → Verify → Ingest → Poke)
- PerformAsync: completion pipeline runs with WaitGroup + progress tracking
- Config: agents.yaml loaded once, feature flags (auto-qa/pr/merge/ingest)
- Named Locks: c.Lock("drain") for queue serialisation
- Registry: workspace state with cross-package QUERY access
- QUERY: c.QUERY(WorkspaceQuery{Status: "running"}) for cross-service queries
- Action descriptions: 25+ Actions self-documenting
- Data mounts: prompts/tasks/flows/personas/workspaces via c.Data()
- Content Actions: agentic.prompt/task/flow/persona callable via IPC
- Drive endpoints: forge + brain registered with tokens
- Drive REST helpers: DriveGet/DrivePost/DriveDo for Drive-aware HTTP
- HandleIPCEvents: auto-discovered by WithService (no manual wiring)
- Entitlement: frozen-queue gate on write Actions
- CLI dispatch: workspace dispatch wired to real dispatch method
- CLI: --quiet/-q and --debug/-d global flags
- CLI: banner, version, check (with service/action/command counts), env
- main.go: minimal — 5 services + c.Run(), no os import
- cmd tests: 84.2% coverage (was 0%)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 06:38:02 +00:00
Snider
e46c1f66fa fix: dogfood review_queue_extra_test — eliminate os + encoding/json
os.MkdirAll→fs.EnsureDir, os.WriteFile→fs.Write, os.ReadFile→fs.Read,
os.Remove→fs.Delete, json.Marshal→core.JSONMarshalString.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 02:16:44 +00:00
Snider
316dbf6018 fix: dogfood queue_extra_test — eliminate encoding/json, reduce os
45 os/json calls replaced with Core primitives. os remains only for
os.Getpid() (no Core equivalent for PID as int).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 02:12:03 +00:00
Snider
12588e8b4e fix: dogfood auto_pr_test + status_logic_test — eliminate os + encoding/json
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 02:07:31 +00:00
Snider
76b167a874 fix: dogfood watch_test + resume_test — eliminate os + encoding/json
os.MkdirAll→fs.EnsureDir, os.WriteFile→fs.Write, os.ReadFile→fs.Read,
json.Marshal→core.JSONMarshalString. Both files now clean.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 02:03:08 +00:00
Snider
68b55572f1 fix: dogfood status_test.go — eliminate encoding/json
json.MarshalIndent→core.JSONMarshalString, json.Unmarshal→core.JSONUnmarshalString.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:58:36 +00:00
Snider
7be229d40d fix: dogfood handlers_test + commands_workspace_test
os.MkdirAll→fs.EnsureDir, os.WriteFile→fs.Write,
json.Marshal→core.JSONMarshalString, os.Stat→fs.Exists/fs.IsDir.
Both files now free of os + encoding/json.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:55:57 +00:00
Snider
56981772c7 fix: dogfood dispatch_test.go — eliminate os + json.Marshal
os.WriteFile→fs.Write, os.MkdirAll→fs.EnsureDir, os.ReadFile→fs.Read,
os.Stat+os.IsNotExist→fs.Exists, json.Marshal→core.JSONMarshalString.
Only json.NewEncoder remains (httptest handler — legitimate).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:51:03 +00:00
Snider
b3ed21b6a3 wip: test dogfooding — dispatch_test.go json.Marshal→core.JSONMarshalString
Partial migration of dispatch_test.go: 5 of 9 json.Marshal+os.WriteFile
pairs replaced with fs.Write+core.JSONMarshalString. Pattern established
for remaining 74 calls across 30 test files.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:46:25 +00:00
Snider
23bb62a116 fix: eliminate path/filepath from all test files
29 test files migrated: filepath.Join→core.JoinPath,
filepath.Dir→core.PathDir, filepath.Base→core.PathBase,
filepath.IsAbs→core.PathIsAbs. Test dogfooding complete for filepath.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:39:41 +00:00
Snider
aafa63818f fix: remove dead client field from PrepSubsystem + test literals
client *http.Client removed — all HTTP routes through transport.go.
75 test struct literals cleaned, 3 test assertions updated.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:32:17 +00:00
Snider
f83c753277 feat(v0.8.0): full AX migration — ServiceRuntime, Actions, quality gates, transport
go-process:
- Register factory, Result lifecycle, 5 named Action handlers
- Start/Run/StartWithOptions/RunWithOptions all return core.Result
- core.ID() replaces fmt.Sprintf, core.As replaces errors.As

core/agent:
- PrepSubsystem + monitor.Subsystem + setup.Service embed ServiceRuntime[T]
- 22 named Actions + agent.completion Task pipeline in OnStartup
- ChannelNotifier removed — all IPC via c.ACTION(messages.X{})
- proc.go: all methods via s.Core().Process(), returns core.Result
- status.go: WriteAtomic + JSONMarshalString
- paths.go: Fs.NewUnrestricted() replaces unsafe.Pointer
- transport.go: ONE net/http file — HTTPGet/HTTPPost/HTTPDo/MCP transport
- All disallowed imports eliminated from source files (13 quality gates)
- String concat eliminated — core.Concat() throughout
- 1:1 _test.go + _example_test.go for every source file
- Reference docs synced from core/go v0.8.0
- RFC-025 updated with net/http, net/url, io/fs quality gates
- lib.go: io/fs eliminated via Data.ListNames, Array[T].Deduplicate

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-26 01:27:46 +00:00
Snider
96ac2d99cd feat: add RFC.plan.md — session boot instructions for future agents
Step-by-step: load 3 RFCs, verify understanding, work migration,
follow session cadence. Lists what NOT to do (10 disallowed imports,
no string concat, no anonymous closures, no nested ACTION).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 20:05:25 +00:00
Snider
4216dddea9 feat(rfc): add Current State + File Layout — save future session research
- Current State: lists every file that needs migration with specific action
- File Layout: annotated tree showing DELETE/REWRITE/MIGRATE per file
- MCP closure capture bug fixed (re-resolve action at call time)
- Message types location documented (pkg/messages/)

Future session reads this and knows exactly what to touch.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 20:00:50 +00:00
Snider
6ac69ac07c fix(rfc): final check — go-process v0.8.0, readStatus dogfood, grep paths
- Depends on: go-process v0.7.0 → v0.8.0
- Section 6: readStatus uses JSONUnmarshalString + Fs.Read (dogfood)
- Section 22: quality gate grep uses generic paths not pkg/**
- Fixed double blank line in Section 19

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 19:56:04 +00:00
Snider
9f215e9d9b feat(rfc): add Sections 14-18 — errors, config, registry, streams, data/drive
Complete coverage of every core/go primitive:
- Section 14: Error handling (core.E, Wrap, Root) + Logging (Info, Warn, Security)
- Section 15: Configuration (Config.Set/Get/String/Int, feature flags)
- Section 16: Registry[T] (workspace tracking, cross-cutting queries)
- Section 17: Stream helpers (ReadAll, WriteAll, CloseStream)
- Section 18: Data (embedded assets) + Drive (transport config)

22 sections total. Every core/go primitive mapped to core/agent usage.
Next session loads this + core/go RFC → complete domain context.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 19:52:32 +00:00
Snider
76b87574a5 feat(rfc): add Sections 14-17 — string ops, comments, examples, full quality gate
- Section 14: String operations — Println, Sprintf, Concat, Path, Contains, Split, Trim
- Section 15: AX Principle 2 — every exported function needs usage-example comment
- Section 16: Example tests — one {source}_example_test.go per source file
- Section 17: Quality gates — all 10 disallowed imports + string concat check

The next session agent loads this RFC and knows exactly what v0.8.0 looks like.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 19:48:41 +00:00
Snider
2d2a4116ed refactor(rfc): rewrite as v0.8.0 contract, not migration plan
Was: "current state → target state" migration narrative
Now: "this is what core/agent v0.8.0 IS" API contract

14 sections covering: registration, actions, pipeline, process,
status, filesystem, validation, entitlements, MCP aggregator,
remote dispatch, JSON, testing, quality gates.

Written with full core/go domain context — every example uses
the implemented v0.8.0 primitives.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 18:12:01 +00:00
Snider
c4a1178ae6 feat: universal AGENTS.md, remove CODEX.md + GEMINI.md
AGENTS.md is the universal agent instructions — any model reads this.
CLAUDE.md stays as Claude-specific (hooks, permissions, memory).
CODEX.md and GEMINI.md removed — one source of truth.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:58:00 +00:00
Snider
1bd014222d feat: add llm.txt — agent entry point for core/agent
Standard llm.txt with package layout, test coverage stats, conventions.
Points to CLAUDE.md and RFC-025 for full specs.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:53:04 +00:00