Commit graph

74 commits

Author SHA1 Message Date
Virgil
bd12c0a31a fix(ax): align code comments with AX principles
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 22:54:19 +00:00
Virgil
b8e948f2d6 fix(ax): continue AX naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 22:40:28 +00:00
Virgil
40a26ca28c fix(ax): continue AX comment cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 22:30:05 +00:00
Virgil
32c2a33284 fix(ax): align service comments with AX examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:47:44 +00:00
Virgil
5e5e19d6de fix(ax): continue AX naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:41:45 +00:00
Virgil
da25b6f79f fix(ax): continue AX naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:37:15 +00:00
Virgil
e825550a90 fix(ax): continue AX naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:30:49 +00:00
Virgil
1cc8fb50e1 fix(ax): continue workspace naming cleanup
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 21:22:54 +00:00
Virgil
f9eca5e395 fix(ax): align runtime names with AX principles
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 20:53:36 +00:00
Virgil
7d6fd8af5e fix(ax): make agentic status reads Result-native
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 20:40:31 +01:00
Virgil
b8466fb56d fix(ax): make workspace extraction Result-native
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 20:14:57 +01:00
Virgil
faf6b8b6fb fix(ax): unify home-path resolution
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 19:54:17 +01:00
Virgil
3c2575f45b fix(ax): remove proc.go wrapper layer
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 15:48:21 +00:00
Virgil
7672e0922f fix(ax): align plan IDs and validation helpers
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 14:32:01 +00:00
Virgil
3d2fa035a9 refactor(agentic): migrate workflow helpers to core.Result
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 07:30:42 +00:00
Virgil
6c246a7165 docs(ax): add remaining usage examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 00:20:03 +00:00
Virgil
54581dcbd7 fix(ax): register named agentic commands
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 23:37:28 +00:00
Virgil
cef4d5d1f6 docs(ax): add remaining usage examples
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 23:14:26 +00:00
Virgil
2f7ca89d80 fix(ax): name handlers and align process coverage
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-29 21:56:45 +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
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
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
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
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
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
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
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
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
8521a55907 refactor: eliminate os/exec from all source files → go-process
Replace ALL exec.Command calls with proc.go helpers backed by go-process:
- runCmd/runCmdEnv/runCmdOK — general command execution
- gitCmd/gitCmdOK/gitOutput — git-specific helpers
- ensureProcess() — lazy default service init

Refactored files (0 source files import os/exec now):
- verify.go: runGoTests, runPHPTests, runNodeTests, rebaseBranch
- dispatch.go: runQA (3 exec.Command chains → runCmdOK)
- prep.go: getGitLog, prepWorkspace clone/branch
- pr.go: createPR branch detection + push
- auto_pr.go: commit counting + push
- mirror.go: all git ops + gh CLI calls
- review_queue.go: pushAndMerge, buildReviewCommand (returns string+args now)
- paths.go: DefaultBranch

Coverage: 77.2% → 78.4% (+1.2pp from testable process paths)
802 tests

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 09:51:57 +00:00
Snider
04f91ed6a0 feat: all commands in services — cmd/ has only main.go (97 lines) + update.go (24 lines)
- forge.go moved to pkg/agentic/commands_forge.go
- Uses s.forge directly (no newForgeClient())
- registerForgeCommands called in OnStartup
- main.go: 97 lines, zero command registration
- cmd/ total: 121 lines (was 650+)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 00:06:46 +00:00
Snider
72387dde91 feat: move workspace + process commands into services — main.go 98 lines
- ProcessRegister: proper factory in pkg/agentic
- Workspace commands (list/clean/dispatch): moved to agentic.registerWorkspaceCommands
- workspace.go deleted from cmd/
- main.go: 98 lines, just core.New + app commands + c.Run()

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 00:03:22 +00:00
Snider
67658ec90c fix: imports forge.lthn.ai/core/mcp → dappco.re/go/mcp
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:40:04 +00:00
Snider
909bb3bb6c feat: services own their commands — main.go is 132 lines
Commands moved to their owning services:
- agentic: run/task, run/orchestrator, prep, status, prompt, extract
- mcp: mcp, serve (in core/mcp OnStartup)
- main.go: version, check, env (app-level only)

ServiceStartup before Cli().Run() — services register commands in OnStartup.
ServiceShutdown on exit.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:24:29 +00:00
Snider
4803f396d3 feat: use mcp.Register — MCP is a Core service
- core.New() includes mcp.Register — auto-discovers subsystems
- mcp/serve commands use c.Service("mcp") for typed retrieval
- ServiceStartup called once before Cli().Run()
- run/task and run/orchestrator registered by agentic.OnStartup
- Removed ServiceFor generics — c.Service() returns instances directly

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:16:20 +00:00
Snider
adafee0f18 feat: use RegisterService + ServiceFor — proper instance lifecycle
- agentic.PrepSubsystem implements Startable/Stoppable
- monitor.Subsystem implements Startable/Stoppable (OnStartup/OnShutdown)
- Register factories use c.RegisterService() — auto-discovers interfaces
- Register factories return instances via Result.Value
- main.go uses ServiceFor[T]() instead of ConfigGet — typed retrieval
- No more c.Config().Set("x.instance") workaround

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 17:42:16 +00:00
Snider
cdb29a2f75 feat(ipc): replace CompletionNotifier callbacks with Core IPC messages
Phase 3 of Core DI migration:
- Remove CompletionNotifier interface from pkg/agentic
- dispatch.go emits messages.AgentStarted/AgentCompleted via c.ACTION()
- monitor registers IPC handlers in SetCore() — handleAgentStarted/handleAgentCompleted
- Remove circular callback wiring (SetCompletionNotifier) from main.go
- Export ReadStatus for cross-package use
- Update run/orchestrator to use SetCore() instead of SetCompletionNotifier()

Services now communicate through typed messages, not direct references.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 14:46:59 +00:00
Snider
bb88604045 feat(core): wire Core framework into agentic + monitor subsystems
Phase 2 of Core DI migration:
- Add *core.Core field + SetCore() to PrepSubsystem and monitor.Subsystem
- Register agentic/monitor/brain as Core services with lifecycle hooks
- Mark SetCompletionNotifier and SetNotifier as deprecated (removed in Phase 3)
- Fix monitor test to match actual event names
- initServices() now wires Core refs before legacy callbacks

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 14:44:53 +00:00
Snider
9bdd47d9d5 feat(agent): v0.3.0 — dispatch control, run task CLI, quiet notifications, spark pool
- Add agentic_dispatch_start / shutdown / shutdown_now MCP tools
- Queue frozen by default, CORE_AGENT_DISPATCH=1 to auto-start
- Add run task CLI command — single task e2e (prep → spawn → wait)
- Add DispatchSync for blocking dispatch without MCP
- Quiet notifications — only agent.failed and queue.drained events
- Remove duplicate notification paths (direct callback + polling loop)
- codex-spark gets separate concurrency pool (baseAgent routing)
- Rate-limit backoff detection (3 fast failures → 30min pause)
- Review agent uses exec with sandbox bypass (not codex review)
- Bump: core-agent 0.3.0, core plugin 0.15.0, devops plugin 0.2.0

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-23 16:08:08 +00:00
Snider
6d4b92737e feat(agent): background runner, slim status, Docker dispatch, stopwatch, CLI fixes
- Add background queue runner (runner.go) — 30s tick + poke on completion
- drainQueue now loops to fill all slots per tick
- Add run orchestrator command — standalone queue runner without MCP
- Slim agentic_status — stats only, blocked workspaces listed
- Docker containerised dispatch — all agents run in core-dev container
- Forge stopwatch start/stop on issue when agent starts/completes
- issue create supports --milestone, --assignee, --ref
- Auto-PR targets dev branch (not main)
- PR body includes Closes #N for issue-linked work
- CLI usage strings use spaces not slashes
- Review agent uses exec with sandbox bypass (not codex review subcommand)
- Local model support via codex --oss with socat Ollama proxy

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-23 12:53:33 +00:00
Snider
9b225af2f9 refactor(monitor): direct event push, no filesystem polling
CompletionNotifier interface now has AgentStarted() and
AgentCompleted() instead of Poke(). Dispatch pushes notifications
directly to monitor with agent/repo/status data. Monitor pushes
MCP channel events immediately — no scanning, no dedup maps,
no filesystem polling latency.

Events.jsonl kept as audit log only, not notification mechanism.
Timer-based scan kept for startup seeding and stale detection.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 16:19:13 +00:00
Snider
24fdaa3bad fix: extract default workspace template for go.work
QA gate failed because cloned repos weren't in a Go workspace.
Extract default template (including go.work with use ./repo)
into workspace dir before cloning. Fixes go test isolation.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:32 +00:00
Snider
7f84ac8348 refactor(agentic): use go-forge library instead of raw HTTP
Replace raw http.Client calls with go-forge typed API:
- prep.go: getIssueBody via forge.Issues.Get, pullWikiContent
  via forge.Wiki.ListPages/GetPage
- pr.go: forgeCreatePR via forge.Pulls.Create, commentOnIssue
  via forge.Issues.CreateComment, listRepoPRs via forge.Pulls.ListAll
- scan.go: listOrgRepos via forge.Repos.ListOrgRepos

Eliminates manual JSON marshalling, auth headers, pagination loops,
and anonymous struct declarations. One Forge client, one auth,
type-safe responses.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:16 +00:00
Snider
6e03287178 refactor(agentic): workspace = clone, prompt replaces files
Major simplification of the dispatch model:
- Workspace dir: .core/workspace/{org}/{repo}/{pr|task|branch|tag}/
- Clone into repo/ (not src/), metadata in .meta/
- One of issue, pr, branch, or tag required for dispatch
- All context (brain, consumers, git log, wiki, plan) assembled
  into prompt string — no TODO.md, PROMPT.md, CONTEXT.md files
- Resume detection: skip clone if repo/.git exists
- Default agent changed to codex
- spawnAgent drops srcDir param, runs from repo/
- No --skip-git-repo-check (repo/ IS a git repo)
- All downstream files: srcDir → repoDir

Track PRs, not workspace iterations.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:16 +00:00
Snider
6e37bd22f0 feat: devops plugin, CLI commands, Codex dispatch fixes, AX sweep
DevOps plugin (5 skills):
- install-core-agent, repair-core-agent, merge-workspace,
  update-deps, clean-workspaces

CLI commands: version, check, extract for diagnostics.

Codex dispatch: --skip-git-repo-check, removed broken
--model-reasoning-effort, --sandbox workspace-write via
--full-auto. Workspace template extracts to wsDir not srcDir.

AX sweep (Codex-generated): sanitise.go extracted from prep/plan,
mirror.go JSON parsing via encoding/json, setup/config.go URL
parsing via net/url, strings/fmt imports eliminated from setup.

CODEX.md template updated with Env/Path patterns.
Review workspace template with audit-only PROMPT.md.
Marketplace updated with devops plugin.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 15:45:16 +00:00
Snider
6393bfe4da refactor(agentic): adopt core.Env() + core.Path() across package
Replace all os.UserHomeDir/os.Getenv/os.Hostname with core.Env().
Replace all filepath.Base/Dir/Glob/IsAbs with core.PathBase/PathDir/
PathGlob/PathIsAbs.

10 files migrated: paths, prep, review_queue, remote, dispatch,
ingest, mirror, plan, verify, watch.

Imports eliminated: 5x os, 7x filepath. All file I/O and path
construction now routes through Core primitives.

Bumps dappco.re/go/core to v0.6.0.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 10:15:15 +00:00
Snider
3022f05fb8 refactor(agentic): route file I/O through core.Fs
Replace raw os.* file operations with Core Fs equivalents:
- os.Stat → fs.Exists/fs.IsFile/fs.IsDir (resume, pr, plan, mirror, prep)
- os.ReadDir → fs.List (queue, status, plan, mirror, review_queue)
- os.Remove → fs.Delete (dispatch)
- os.OpenFile(append) → fs.Append (events, review_queue)
- strings.Replace → core.Replace (scan)

Eliminates os import from resume.go, pr.go. Eliminates strings
import from scan.go. Trades os for io in events.go.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 09:08:45 +00:00
Snider
4f66eb4cca fix: resolve final AX audit findings
- cmd/main.go: keyed core.Result literals (go vet clean)
- pkg/brain/direct.go: compile-time mcp.Subsystem assertion
- pkg/monitor/monitor.go: compile-time Subsystem + CompletionNotifier assertions
- pkg/agentic/prep.go: alias stdlib io as goio
- pkg/agentic/remote_client.go: UK English (initialise/initialised)
- pkg/monitor/monitor_test.go: updated inbox tests for current contract

AX audit now returns 0 convention findings.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 06:42:42 +00:00
Snider
a0dc9c32e7 refactor: migrate core/agent to Core primitives — reference implementation
Phase 1: go-io/go-log → core.Fs{}, core.E(), core.Error/Info/Warn
Phase 2: strings/fmt → core.Contains, core.Sprintf, core.Split etc
Phase 3: embed.FS → core.Mount/core.Embed, core.Extract
Phase 4: cmd/main.go → core.Command(), c.Cli().Run(), no cli package

All packages migrated:
- pkg/lib (Codex): core.Mount, core.Extract, Result returns, AX comments
- pkg/setup (Codex): core.Fs, core.E, fixed missing lib helpers
- pkg/brain (Codex): Core primitives, AX comments
- pkg/monitor (Codex): Core string/logging primitives
- pkg/agentic (Codex): 20 files, Core primitives throughout
- cmd/main.go: pure Core CLI, no fmt/log/filepath/strings/cli

Remaining stdlib: path/filepath (Core doesn't wrap OS paths),
fmt.Sscanf/strings.Map (no Core equivalent).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 06:13:41 +00:00
Snider
b266db5069 fix(pkg): address code review findings
- Fix import ordering in verify.go and remote_client.go (stdlib before third-party)
- Convert os.MkdirAll to fs.EnsureDir in prep.go
- Preserve underlying error in !r.OK branches (writeStatus, writePlan, planDelete, planList, resume)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 03:45:50 +00:00