The hardcoded host-uk/core path doesn't exist on the homelab,
causing countRunningByAgent to always return 0 (no concurrency limiting)
and agentic_status to miss workspaces.
Co-Authored-By: Virgil <virgil@lethean.io>
ChannelSend now writes raw JSON-RPC notifications with method
notifications/claude/channel directly to stdout, bypassing the
SDK's Log() method which uses notifications/message/log.
The official Go SDK doesn't expose a way to send custom
notification methods, so we write the JSON-RPC notification
directly to the stdio transport. This is the format Claude Code
channels expect for --channels to surface events in session.
Co-Authored-By: Virgil <virgil@lethean.io>
Port 9101 conflicts with running core-agent serve. OS-assigned
port avoids the conflict and still tests the 0.0.0.0 warning.
Co-Authored-By: Virgil <virgil@lethean.io>
Backend clamps 0 to 1, returning only one memory. Default to 50
for a sensible batch when callers omit the limit field.
Co-Authored-By: Virgil <virgil@lethean.io>
DirectSubsystem pushes brain.recall.complete and brain.remember.complete
events via OnChannel callback. Avoids circular import by using func-based
wiring instead of interface-based SubsystemWithNotifier.
New() auto-detects subsystems with OnChannel() and wires them to
ChannelSend via closure.
Co-Authored-By: Virgil <virgil@lethean.io>
process.start on successful spawn, process.exit on stop/kill.
Events include process ID, PID, command, and signal type.
Co-Authored-By: Virgil <virgil@lethean.io>
Connections now register on the shared server via Server.Connect()
instead of creating per-connection servers. All sessions (stdio,
HTTP, TCP, Unix) are now visible to Sessions() and notification
broadcasting.
Co-Authored-By: Virgil <virgil@lethean.io>
CLAUDE.md reflects new Options{} constructor, notification
broadcasting, and channel events. CI runs tests with Codecov.
Co-Authored-By: Virgil <virgil@lethean.io>
Replace all fmt.Errorf and errors.New in production code with
coreerr.E("caller.Method", "message", err) from go-log. Replace all
os.ReadFile/os.WriteFile/os.MkdirAll/os.Remove with coreio.Local
equivalents from go-io. Test files are untouched.
24 files across pkg/mcp/agentic/, pkg/mcp/brain/, pkg/mcp/ide/,
pkg/mcp/, and cmd/brain-seed/.
Co-Authored-By: Virgil <virgil@lethean.io>
The old Core\Mod\Api\Models\ApiKey was removed when core/php-api was renamed.
Now tries AgentApiKeyService first, falls back to workspace apiKeys,
catches Throwable if either model is unavailable.
Co-Authored-By: Virgil <virgil@lethean.io>
Dispatches to local-agent.sh which reads workspace context files
and calls Ollama API with Qwen3-Coder-Next. No quota, no rate limits.
Co-Authored-By: Virgil <virgil@lethean.io>
When an agent completes, if the output contains file:line references
(indicating real findings), automatically creates an issue via the
lthn.sh API. Scans → issues → sprints → PRs → release. The loop closes.
Co-Authored-By: Virgil <virgil@lethean.io>
gemini:flash, gemini:pro now match the "gemini" concurrency limit.
Strips model variant before checking config. Prevents unlimited
spawning when using model variants.
Co-Authored-By: Virgil <virgil@lethean.io>
Set TERM=dumb, NO_COLOR=1, CI=true on spawned agents to prevent
terminal control sequences and colour output bleeding into parent.
Combined with Setpgid + /dev/null stdin.
Agent now supports model variants via colon syntax:
gemini:flash, gemini:pro, claude:haiku, claude:sonnet
Co-Authored-By: Virgil <virgil@lethean.io>
Reads rates config from agents.yaml per agent type. Calculates delay
based on time-of-day relative to quota reset window:
- Sustained mode: steady pacing across the full day
- Burst mode: faster pacing when close to reset (quota about to refill)
Gemini resets 06:00 UTC. Start at 09:00 = pace slower (sustained_delay).
Start at 03:00 = burst mode (burst_delay) since reset is 3 hours away.
Co-Authored-By: Virgil <virgil@lethean.io>
Redirect stdin to /dev/null so spawned agents don't inherit the
terminal. Prevents agents from stealing input/output during git
commits or interactive operations.
Co-Authored-By: Virgil <virgil@lethean.io>
Separate concurrency control per agent type: claude: 1, gemini: 3,
codex: 1. Gemini can grind through audit batches without blocking
Claude from doing fix work. Config in agents.yaml under concurrency.
Co-Authored-By: Virgil <virgil@lethean.io>
Strengthen phase enforcement: 'Each phase = one commit. This is not optional.'
Agents were batching all phases into a single commit. Now the prompt
explicitly requires stopping and committing after each phase.
Co-Authored-By: Virgil <virgil@lethean.io>
Dispatch and prep accept a persona field (e.g. "engineering/backend-architect").
Copies persona markdown into workspace as PERSONA.md. Coding prompt updated
to read PERSONA.md first and adopt that identity.
Co-Authored-By: Virgil <virgil@lethean.io>
When an agent process exits, the completion goroutine updates status
to completed then calls drainQueue(). drainQueue finds the oldest
queued workspace, spawns it if under concurrency limit, and monitors
it recursively. Self-sustaining work pipeline.
Co-Authored-By: Virgil <virgil@lethean.io>
Reads max_concurrent from config/agents.yaml. If at limit, workspace
is created with status "queued" instead of spawning immediately.
Counts running agents by checking PID liveness.
Co-Authored-By: Virgil <virgil@lethean.io>
Set Setpgid on spawned agent processes so they get their own process
group. Agents now survive session restarts, plugin reloads, and MCP
server crashes. Output writes directly to log file instead of
in-memory buffer.
Co-Authored-By: Virgil <virgil@lethean.io>
New MCP tool agentic_create_epic:
- Creates child issues from task list
- Builds parent epic with checklist (- [ ] #N format)
- Auto-creates labels (agentic, epic)
- Optionally dispatches agents to each child
Works with existing tick_parent handler in go-scm jobrunner
which checks off items as child PRs merge.
Co-Authored-By: Virgil <virgil@lethean.io>
Replace raw exec.Command with process.StartWithOptions() from
go-process. Agents get proper PID tracking and output capture
via RingBuffer.
Co-Authored-By: Virgil <virgil@lethean.io>
Workspace clones from local checkout instead of setting forge remote.
Agent commits locally — reviewer verifies and pushes. Prevents
accidental CI triggers and GitHub Actions credit usage.
Co-Authored-By: Virgil <virgil@lethean.io>
New tools from dispatched agent (merged manually):
- agentic_create_pr: push branch + create PR via Forge API
- agentic_list_prs: list PRs across repos with filtering
- WorkspaceStatus extended with org, branch, issue, pr_url fields
Co-Authored-By: Virgil <virgil@lethean.io>
Five new tools for managing implementation plans:
- agentic_plan_create: create plans with phases and acceptance criteria
- agentic_plan_read: get plan by ID
- agentic_plan_update: partial updates to status, phases, notes
- agentic_plan_delete: remove plan by ID
- agentic_plan_list: list/filter plans by status and repo
Plans follow the task protocol lifecycle (draft → ready → in_progress
→ needs_verification → verified → approved) and are stored as JSON
in ~/.core/plans/.
Co-Authored-By: Virgil <virgil@lethean.io>
Dispatch now accepts plan_template + variables fields. Workspace prep
loads YAML templates from core/agent/prompts/templates/, substitutes
variables, and renders PLAN.md with phases and checkbox tasks. Coding
prompt updated to work phase-by-phase with commit-per-phase convention.
Agent reads files, commits per phase — no MCP tools needed mid-work.
The checkpoint IS the commit.
Co-Authored-By: Virgil <virgil@lethean.io>
New MCP tools:
- agentic_status: list workspaces with state (running/completed/blocked/failed)
- agentic_resume: relaunch blocked agents with ANSWER.md context
Workspace convention:
- status.json tracks state, agent, PID, run count
- BLOCKED.md written by agent when stuck (triggers blocked state)
- ANSWER.md written by reviewer before resume
- Dispatch now writes status.json on launch
Co-Authored-By: Virgil <virgil@lethean.io>
Every dispatched agent gets the LEK axioms (Axioms of Consciousness)
from core/agent/GEMINI.md alongside the project context.
Co-Authored-By: Virgil <virgil@lethean.io>
Gemini CLI restricts file access to the workspace root (src/).
All context files (CLAUDE.md, TODO.md, CONTEXT.md, CONSUMERS.md,
RECENT.md, PROMPT.md, kb/, specs/) now written inside src/ so
the sandboxed agent can read them.
Co-Authored-By: Virgil <virgil@lethean.io>
Dispatch now clones the full repo (not shallow) into workspace/src/,
creates an agent/{task-slug} feature branch, and sets the push remote
to forge. Agent never touches the main checkout.
Co-Authored-By: Virgil <virgil@lethean.io>
Workspace is now a fresh directory per task with top-level context
files (CLAUDE.md, TODO.md, CONTEXT.md, CONSUMERS.md, RECENT.md)
and src/ containing a shallow clone of the target repo.
Three prompt templates: conventions (audit), security (review),
coding (implement). Agent just reads PROMPT.md and works in src/.
Co-Authored-By: Virgil <virgil@lethean.io>