Commit graph

21 commits

Author SHA1 Message Date
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
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
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
d67336c761 test: batch 5 — proc.go GBU + getGitLog + runGoTests + prepWorkspace — 836 tests
New: proc_test.go with 28 tests for all proc.go helpers (runCmd, gitCmd,
gitOutput, processIsRunning, processKill, ensureProcess).

Plus: getGitLog GBU, runGoTests GBU, prepWorkspace Good,
listLocalRepos Ugly, loadRateLimitState Bad, runLoop skips.

AX-7: 501/543 filled (92%), 167/181 functions complete
Coverage: 78.5%, 836 tests

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 10:20:50 +00:00
Snider
c0bc7675a1 test: batch 4 — fill 36 testable gaps, 802 tests, AX-7 89%
- commands.go: factory wrapper Good/Bad/Ugly
- dispatch.go: containerCommand Bad
- queue.go: UnmarshalYAML/loadAgentsConfig Good/Bad/Ugly
- remote.go: resolveHost/remoteToken Bad/Ugly
- remote_client.go: setHeaders Bad
- prep.go: TestPrepWorkspace/TestBuildPrompt public API GBU
- prep.go: sanitise Good tests (collapseRepeatedRune, sanitisePlanSlug, trimRuneEdges)
- ingest.go: ingestFindings/createIssueViaAPI Ugly
- scan.go: scan Good
- runner.go: Poke Ugly, StartRunner Bad/Ugly
- process_register.go: ProcessRegister Good/Bad/Ugly

AX-7: 462/516 filled (89%), 152/172 functions complete
Coverage: 77.2%, 802 tests

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 09:31:38 +00:00
Snider
eeaed52256 test: batch 3 — add 73 Good/Bad/Ugly tests across 9 files
Fill missing categories for:
- prep.go: 25 lifecycle/detect/env tests
- prep_extra.go: pullWikiContent/renderPlan/brainRecall/findConsumers Ugly
- pr.go: buildPRBody/commentOnIssue/createPR/listPRs/listRepoPRs GBU
- epic.go: createEpic/createIssue/resolveLabelIDs/createLabel Ugly
- scan.go: scan/listOrgRepos/listRepoIssues GBU
- events (logic_test.go): emitStartEvent/emitCompletionEvent GBU
- review_queue_extra.go: buildReviewCommand/countFindings/parseRetryAfter/store/save/load
- watch.go: findActiveWorkspaces/resolveWorkspaceDir Bad/Ugly
- paths.go: newFs/parseInt Good
- plan_crud.go: generatePlanID/planList/writePlan Bad/Ugly

AX-7 scorecard: 425/516 categories filled (82%)
Gap: 166 → 91 missing categories
Tests: 690 → 765 (+75)
Coverage: 76.0% → 76.8%

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 09:19:05 +00:00
Snider
a5afad870c test: batch 1 — add 80 Bad/Ugly tests for paths, plan, status, shutdown, forge cmds
Fill missing Good/Bad/Ugly categories for:
- paths.go: LocalFs, WorkspaceRoot, CoreRoot, PlansRoot, AgentName, GitHubOrg, parseInt, DefaultBranch
- plan.go: planCreate/Read/Update/Delete/List Ugly, planPath Ugly, validPlanStatus Ugly
- status.go: writeStatus Bad, status Good/Bad
- shutdown.go: dispatchStart/shutdownGraceful Bad/Ugly, shutdownNow Ugly
- commands_forge.go: all 9 cmd* functions Ugly (with httptest mocks)
- sanitise.go: Bad/Ugly for all 5 functions
- prep.go: various lifecycle Bad/Ugly

Gap: 260 → 208 missing categories
Tests: 566 → 646 (+80)
Coverage: 74.4%

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 08:43:35 +00:00
Snider
97d06c1e90 refactor(test): bulk rename 478 tests to TestFile_Function_{Good,Bad,Ugly}
Mechanical rename of all test functions to follow the convention:
  TestFilename_FunctionName_{Good,Bad,Ugly}

Examples:
  TestForgeMergePR_Good_Success → TestVerify_ForgeMergePR_Good_Success
  TestAgentCommand_Good_Gemini → TestDispatch_AgentCommand_Good_Gemini
  TestReadStatus_Bad_NoFile → TestStatus_ReadStatus_Bad_NoFile

Gap analysis now works: 137 functions still need 260 missing categories.
566 tests, agentic 74.3% — naming is now the tooling.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-25 08:32:08 +00:00
Snider
60b0b0b63b fix: test uses core.New() directly — no .Value unwrap
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 21:53:45 +00:00
Snider
919dcf963f feat: factories return instances — WithService handles registration
Register factories no longer call c.RegisterService() explicitly.
WithService auto-discovers name from package path and registers.
Eliminates double-registration error.

Uses WithOption("name", "core-agent") for Options struct.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 20:36:17 +00:00
Snider
9f8a63ae21 feat: Register() factories + consume new core.New() API
Each package exposes Register(c *Core) Result for core.WithService():
- agentic.Register: creates PrepSubsystem, wires IPC handlers, lifecycle
- monitor.Register: creates Subsystem, wires IPC handler, lifecycle
- brain.Register: creates Direct, registers service

main.go updated for core.New() returning Result.
Ready for core.New(WithService(agentic.Register)) pattern.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-24 16:23:44 +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
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
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
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
deaa06a54d refactor(pkg): migrate go-io/go-log to Core primitives
Replace separate go-io (coreio) and go-log (coreerr) packages with
Core's built-in Fs and error/logging functions. This is the reference
implementation for how all Core ecosystem packages should migrate.

Changes:
- coreio.Local.Read/Write/EnsureDir/Delete/IsFile → core.Fs methods
- coreerr.E() → core.E(), coreerr.Info/Warn/Error → core.Info/Warn/Error
- (value, error) return pattern → core.Result pattern (r.OK, r.Value)
- go-io and go-log moved from direct to indirect deps in go.mod
- Added AX usage-example comments on key public types
- Added newFs("/") helper for unrestricted filesystem access

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 03:41:07 +00:00
Snider
c6490c175a refactor: migrate imports to dappco.re paths + bump mcp to v0.4.0
Update all go-* imports from forge.lthn.ai to dappco.re/go/core/*.
Bump mcp to v0.4.0 (Options{} struct API).
Versions: core v0.5.0, io v0.2.0, log v0.1.0, process v0.3.0,
ws v0.3.0, ai v0.2.0, webview v0.2.0, i18n v0.2.0.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-22 01:27:48 +00:00
Snider
726a384873 test(agentic): add unit tests for paths, status, queue, plans
Some checks failed
CI / test (push) Failing after 3s
Coverage: 4.2% → 9.2%. Tests for extractPRNumber, workspace
status scanning, queue management, and plan file operations.
Remaining coverage requires integration tests (git/forge/process).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-21 15:06:19 +00:00