Commit graph

133 commits

Author SHA1 Message Date
Snider
841fc7f2ca feat: rename package to lthn/php-agentic for Packagist
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
2026-03-09 18:00:01 +00:00
Snider
da152fdd37 fix: rename core/php-framework dependency to core/php
Some checks failed
CI / PHP 8.3 (push) Failing after 1s
CI / PHP 8.4 (push) Failing after 1s
2026-03-09 17:38:57 +00:00
Snider
9a6aebd128 fix(api): correct route prefix comments — no prefix applied
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 18:40:34 +00:00
Snider
c47c23406f fix(api): use event-scoped route registration
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Routes must go through $event->routes() so they only load for API
requests, not globally. LifecycleEventProvider adds /api prefix,
so Go client sets BaseURL to .../api.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 18:39:56 +00:00
Snider
29625c462b fix: restore Routes/api.php after case-sensitive rebase conflict
Some checks failed
CI / PHP 8.3 (push) Failing after 1s
CI / PHP 8.4 (push) Failing after 1s
macOS case-insensitive filesystem caused routes/api.php removal
to also delete Routes/api.php during rebase.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 18:35:44 +00:00
Snider
f15093843b feat(api): add REST endpoints for go-agentic Client
16 endpoints matching the go-agentic Client contract:
- Plans: list, get, create, update status, archive
- Phases: get, update status, checkpoint, task update, task toggle
- Sessions: list, get, start, end, continue
- Health: /v1/health ping

Routes at /v1/* with AgentApiAuth Bearer token middleware.
Permission-scoped: plans.read, plans.write, phases.write, sessions.write.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 18:34:59 +00:00
Snider
2ce8a02ce6 feat: add agentic:prep-workspace command
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Automates agent workspace preparation — pulls repo wiki pages from
Forge, copies protocol specs, generates TODO.md from issues, and
queries the vector DB for relevant context.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 16:16:29 +00:00
Snider
b0ed221cfa feat(brain): add wiki source type — ingest Forge repo wikis via API
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
Fetches wiki pages from all core/* repos on Forge, parses into
sections, and stores as type:service with repo/lang tags. Gives
the PHP orchestrator contextual knowledge about the Go services
it coordinates.

71+ pages across 22+ repos, ~770 vectorised sections.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 15:58:01 +00:00
Snider
01826bc5e9 feat(brain): add docs source type for framework documentation ingestion
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Discovers markdown files from core-php/docs/build/php/ and packages/
for vectorisation into OpenBrain. Tagged as source:docs with 0.85
confidence, typed as documentation.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 15:40:14 +00:00
Snider
b32d339a53 feat: add agentic:scan, agentic:dispatch, agentic:pr-manage commands
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 14:43:22 +00:00
Snider
6ac515d80e feat: add AssignAgent, ManagePullRequest, ReportToIssue actions
AssignAgent activates a plan and starts an agent session.
ManagePullRequest evaluates PR state/CI checks and merges when ready.
ReportToIssue posts progress comments on Forgejo issues.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 14:40:44 +00:00
Snider
08d397fbf6 feat: add CreatePlanFromIssue action
Converts Forgejo work items (from ScanForWork) into AgentPlans.
Extracts checklist tasks from issue body, creates a single-phase plan,
and deduplicates by matching issue metadata on existing plans.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 14:40:10 +00:00
Snider
b3cf2a4b7d feat: add ScanForWork action for Forgejo epic scanning
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 14:37:12 +00:00
Snider
e82d35c13d feat: add ForgejoService API client for agent orchestration
Co-Authored-By: Virgil <virgil@lethean.io>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 14:34:20 +00:00
Snider
440ea340df fix: rename agent_sessions columns to match model expectations
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Renames uuid → session_id and last_activity_at → last_active_at,
and changes session_id column type from uuid to varchar to support
prefixed IDs (sess_...).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 14:06:06 +00:00
Snider
6f0618692a feat: add plan/session/phase/task Actions + slim MCP tools
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Extract business logic from MCP tool handlers into 15 Action classes
(Plan 5, Session 5, Phase 3, Task 2) following the Brain pattern.
MCP tools become thin wrappers calling Action::run(). Add framework-level
REST controllers and routes as sensible defaults for consumers.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 13:58:45 +00:00
Snider
8b8a9c26e5 feat: extract Brain operations into CorePHP Actions + API routes
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
- Create 4 Actions in Actions/Brain/ (RememberKnowledge, RecallKnowledge,
  ForgetKnowledge, ListKnowledge) using the Action trait pattern
- Slim MCP tool handlers to thin wrappers calling Actions
- Add BrainController with REST endpoints (remember, recall, forget, list)
- Add API route file with api.auth + api.scope.enforce middleware
- Wire ApiRoutesRegistering in Boot.php
- Rename routes/ → Routes/ to match CorePHP convention
- Remove empty database/migrations/ (legacy Laravel boilerplate)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-04 12:15:13 +00:00
Snider
8bc6e62f13 fix: bind AgentToolRegistry as singleton for in-process tool execution
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Without singleton binding, each app()->make() call creates a fresh
instance and tools registered via McpToolsRegistering are lost.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 07:38:23 +00:00
Snider
bad718da8d revert: remove domains array, keep single domain config
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Multi-domain handled at app level via config override.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 17:08:52 +00:00
Snider
b75fa0ba57 feat: add mcp.domains config for multi-domain portal support
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
New 'domains' key accepts comma-separated MCP_DOMAINS env var,
falling back to single MCP_DOMAIN value for backward compatibility.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 16:59:28 +00:00
Snider
8efd939ce4 fix: derive MCP portal domain from APP_DOMAIN
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Instead of hardcoding mcp.host.uk.com as the default, derive it from
APP_DOMAIN env var so it works automatically per environment without
needing a separate MCP_DOMAIN override.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 16:51:16 +00:00
Snider
1ef8157822 fix: truncate oversized sections and clear DB on fresh ingest
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
- Truncate content to 3800 chars before embedding (embeddinggemma has
  a 2048-token context, ~4K char limit). Eliminates all 73 Ollama 500
  errors from oversized plan sections.
- Clear brain_memories DB table when --fresh is used, keeping DB rows
  in sync with Qdrant vectors.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 16:02:11 +00:00
Snider
331796c1da feat: add dedicated brain database connection for remote MariaDB
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Brain memories can now be stored in a separate database, co-located
with Qdrant vectors on the homelab. Defaults to the app's main DB
when no BRAIN_DB_* env vars are set (zero-config for existing installs).

- Add brain.database config with BRAIN_DB_* env var support
- Register 'brain' database connection in Boot.php
- Set BrainMemory model to use 'brain' connection
- Update BrainService transactions to use brain connection
- Update migration to use brain connection, drop workspace FK
  (cross-database FKs not supported)
- Add migration to drop FK on existing installs
- Update default URLs from *.lthn.lan to *.lthn.sh

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 15:14:01 +00:00
Snider
ad0ee04b83 chore: make TLS skip detect any non-public TLD, not just .lan
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Prepares for lthn.lan → lthn.sh migration. Once real certs are
deployed, verifySsl will always be true and this logic becomes
a no-op safety net for .lan/.lab/.local/.test domains.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 13:56:06 +00:00
Snider
02cc11d2cf chore: update default brain URLs to *.lthn.lan convention
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Ollama and Qdrant defaults now use ollama.lthn.lan and
qdrant.lthn.lan to match the homelab service mesh naming.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 13:19:59 +00:00
Snider
9623e1e0b5 feat: add brain:ingest command for comprehensive knowledge archival
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Discovers markdown across 4 source types:
- memory: ~/.claude/projects memory files
- plans: docs/plans across repos + ~/.claude/plans
- claude-md: CLAUDE.md repo instructions
- tasks: core/tasks research and ideas

Supports --fresh to clear collection, --dry-run for preview,
and --source to target specific types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:10:37 +00:00
Snider
9d49fc601b refactor: build HTTP client in single call, not conditional mutation
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:54:57 +00:00
Snider
b6823538d5 feat: skip TLS verification for .lan domains in BrainService
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Adds a private http() helper that wraps Http::timeout() with
conditional withoutVerifying() for self-signed .lan certs behind
Traefik. Boot singleton auto-detects .lan URLs at construction.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:53:00 +00:00
Snider
20a0b584ae fix: remove glob path from docblock that broke PHP tokenizer
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
The `*/` in `projects/*/memory/` was closing the docblock comment
early, causing PHP to see `for` as a keyword on the same line.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 10:49:30 +00:00
Snider
31e2aae980 chore: rename package from host-uk/core-agentic to core/php-agentic
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Aligns composer package name with forge repo path
(forge.lthn.ai/core/php-agentic).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 10:37:04 +00:00
Snider
c697a6657f chore(brain): use HTTPS for Qdrant via Traefik
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
Qdrant is also behind Traefik at qdrant.lan alongside ollama.lan.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 10:13:06 +00:00
Snider
f17e1a0b6c chore(brain): use HTTPS for Ollama via Traefik
Some checks are pending
CI / PHP 8.3 (push) Waiting to run
CI / PHP 8.4 (push) Waiting to run
Ollama is behind Traefik reverse proxy on ollama.lan, so no port
needed and TLS should be enforced by default.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 10:12:34 +00:00
Snider
43b470257b feat(brain): configurable embedding model, default to EmbeddingGemma
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 3s
Make embedding model swappable via BRAIN_EMBEDDING_MODEL env var.
Switch default from nomic-embed-text to embeddinggemma (Gemma 3
based, 2x better cluster separation in benchmarks).

Default Ollama URL now points to ollama.lan (Linux homelab GPU).

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 10:10:02 +00:00
Snider
dfd3dde7b1 feat(brain): add brain:seed-memory artisan command
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
Scans ~/.claude/projects/*/memory/ for MEMORY.md and topic markdown
files, parses sections, infers memory types, and imports into
OpenBrain via BrainService::remember().

Supports --dry-run, --workspace, --agent, and --path options.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:53:28 +00:00
Snider
d82ad2b9b1 fix(brain): address code quality review findings
- Move BrainMemory::create() inside BrainService::remember() for
  full atomicity (DB + Qdrant in single transaction)
- Add forWorkspace() scope to recall() MariaDB query (tenant isolation)
- Wrap forget() in DB::transaction (MariaDB first, then Qdrant)
- Check qdrantDelete() response and log warnings on failure
- Validate embed() response is a non-empty array

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:47:42 +00:00
Snider
2c6a095a0e fix(brain): address spec review findings
- Move BrainForget DB lookup inside circuit breaker for consistency
- Check ensureCollection() PUT response for Qdrant errors
- Wrap remember() in DB::transaction for atomicity
- Align migration confidence default to 0.8 (matches PHP default)

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:45:05 +00:00
Snider
eeb6927d8f feat(brain): add BrainService, MCP tools, and registration
- BrainService: Ollama embeddings + Qdrant vector upsert/search/delete
- brain_remember: store knowledge with type, tags, confidence, supersession
- brain_recall: semantic search with filter by project/type/agent/confidence
- brain_forget: workspace-scoped deletion from both stores
- brain_list: MariaDB query with model scopes, no vector search
- Config: brain.ollama_url, brain.qdrant_url, brain.collection
- Boot: BrainService singleton + tool registration via AgentToolRegistry

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 09:39:19 +00:00
Snider
627813cc4d feat(brain): add BrainMemory model and migration
UUID-keyed brain_memories table with workspace scoping, self-referential
supersession chain, TTL expiry, and confidence scoring. Eloquent model
includes all scopes and helpers needed by the MCP tool layer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 09:33:46 +00:00
Snider
daa11bab39 docs: OpenBrain implementation plan — 8 tasks, TDD
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
8-task plan: migration, BrainService (Ollama+Qdrant), 4 MCP tools
(remember/recall/forget/list), Go bridge subsystem, MEMORY.md seed
command. 18 files across php-agentic and go-ai.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:28:31 +00:00
Snider
a6e4f865e4 docs: OpenBrain design — shared agent knowledge graph
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
Shared vector-indexed knowledge store accessible by all agents via MCP.
MariaDB for relational metadata, Qdrant for semantic search, Ollama for
embeddings. Four MCP tools: brain_remember, brain_recall, brain_forget,
brain_list. Replaces scattered MEMORY.md files with singular state.

Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-03 09:22:56 +00:00
Snider
1ead364afe fix(ci): install zip in release workflow
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 4s
Forgejo Composer API requires zip format.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:43:52 +00:00
Snider
647635fc6d fix(ci): simplify release workflow, use FORGEJO_REF_NAME
Some checks failed
CI / PHP 8.3 (push) Failing after 4s
CI / PHP 8.4 (push) Failing after 3s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:36:18 +00:00
Snider
522433c019 fix(ci): use Forgejo-native variables in release workflow
Some checks failed
CI / PHP 8.3 (push) Failing after 5s
CI / PHP 8.4 (push) Failing after 3s
Replace github.server_url/GITHUB_REF_NAME with explicit forge URL
and GITEA_REF_NAME/GITEA_OUTPUT.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:13:12 +00:00
Snider
29656e3b92 feat: add Forgejo release workflow for Composer registry
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
On tag push (v*), zips the package and publishes to the
forge.lthn.ai Composer package registry.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:00:19 +00:00
1bbc1336b7 Merge pull request 'refactor: consolidate duplicate state models (#18)' (#48) from refactor/consolidate-workspace-state-models into main
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:26:37 +00:00
darbs-claude
7fadbcb96c
refactor: consolidate duplicate state models into WorkspaceState (#18)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 1s
CI / PHP 8.4 (pull_request) Failing after 1s
- Delete Models/AgentWorkspaceState.php (legacy port, no backing table)
- Rewrite Models/WorkspaceState.php as the single canonical state model
  backed by agent_workspace_states table with array value cast,
  type helpers, scopeForPlan/scopeOfType, static getValue/setValue,
  and toMcpContext() for MCP tool output
- Update AgentPlan::states() relation and setState() return type
- Update StateSet MCP tool import
- Update SecurityTest to use WorkspaceState
- Add WorkspaceStateTest covering table, casts, type helpers, scopes,
  static helpers, toMcpContext, and AgentPlan integration
- Mark CQ-001 done in TODO.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:26:23 +00:00
80c778cb08 Merge pull request 'feat: add template version management' (#63) from feat/template-version-management into main
Some checks failed
CI / PHP 8.3 (push) Failing after 2s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:25:33 +00:00
0e7b617551
feat: add template version management (#35)
Some checks failed
CI / PHP 8.3 (pull_request) Failing after 2s
CI / PHP 8.4 (pull_request) Failing after 1s
Snapshots YAML template content in a new `plan_template_versions` table
whenever a plan is created from a template. Plans reference their version
via `template_version_id` so existing plans are unaffected by future
template file edits.

Key changes:
- Migration 0006: create `plan_template_versions` table (slug, version,
  name, content JSON, content_hash SHA-256); add nullable FK
  `template_version_id` to `agent_plans`
- Model `PlanTemplateVersion`: `findOrCreateFromTemplate()` deduplicates
  identical content by hash; `historyFor()` returns versions newest-first
- `AgentPlan`: add `template_version_id` fillable and `templateVersion()`
  relationship
- `PlanTemplateService::createPlan()`: snapshot raw template before
  variable substitution; store version id and version number in metadata;
  add `getVersionHistory()` and `getVersion()` public methods
- Tests: `TemplateVersionManagementTest` covering model behaviour, plan
  creation snapshotting, deduplication, history ordering, and service
  methods

Closes #35

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:25:17 +00:00
ffc441f22a Merge pull request 'fix: improve template variable error messages' (#58) from fix/template-variable-error-messages into main
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:21:14 +00:00
a9a6e258e1 Merge pull request 'feat: add plan archival with retention policy' (#62) from feat/plan-retention-policy into main
Some checks failed
CI / PHP 8.3 (push) Failing after 3s
CI / PHP 8.4 (push) Failing after 2s
2026-02-24 13:20:38 +00:00