core/php/agent RFC — Agentic Module (PHP Implementation)
The PHP implementation of the agent system, specced from existing code.
Implements code/core/agent/RFC.md contract in PHP.
An agent should be able to build agent features from this document alone.
Module: dappco.re/php/agent
Namespace: Core\Mod\Agentic\*
Sub-specs: Actions | Architecture | Commands | Endpoints | MCP Tools | Models | OpenBrain Design | OpenBrain Impl | Porting Plan | Security | UI
1. Domain Model
| Model |
Table |
Purpose |
AgentPlan |
agent_plans |
Structured work plans with phases, soft-deleted, activity-logged |
AgentPhase |
agent_phases |
Individual phase within a plan (tasks, deps, status) |
AgentSession |
agent_sessions |
Agent work sessions (context, work_log, artefacts, handoff) |
AgentMessage |
agent_messages |
Direct agent-to-agent messaging (chronological, not semantic) |
AgentApiKey |
agent_api_keys |
External agent access keys (hashed, scoped, rate-limited) |
BrainMemory |
brain_memories |
Semantic knowledge store (tags, confidence, vector-indexed) |
Issue |
issues |
Bug/feature/task tracking (labels, priority, sprint) |
IssueComment |
issue_comments |
Comments on issues |
Sprint |
sprints |
Time-boxed iterations grouping issues |
Task |
tasks |
Simple tasks (title, status, file/line ref) |
Prompt |
prompts |
Reusable AI prompt templates (system + user template) |
PromptVersion |
prompt_versions |
Immutable prompt snapshots |
PlanTemplateVersion |
plan_template_versions |
Immutable YAML template snapshots |
WorkspaceState |
workspace_states |
Key-value state per plan (typed, shared across sessions) |
2. Actions
Single-responsibility action classes in Actions/:
Brain
| Action |
Method |
Purpose |
ForgetKnowledge |
execute(id) |
Delete a memory |
ListKnowledge |
execute(filters) |
List memories with filtering |
RecallKnowledge |
execute(query) |
Semantic search via Qdrant |
RememberKnowledge |
execute(content, tags) |
Store + embed memory |
Forge
| Action |
Method |
Purpose |
AssignAgent |
execute(issue, agent) |
Assign agent to Forge issue |
CreatePlanFromIssue |
execute(issue) |
Generate plan from issue description |
ManagePullRequest |
execute(pr) |
Review/merge/close PRs |
ReportToIssue |
execute(issue, report) |
Post agent findings to issue |
ScanForWork |
execute() |
Scan Forge repos for actionable issues |
Issue
| Action |
Method |
Purpose |
CreateIssue |
execute(data) |
Create issue |
GetIssue |
execute(id) |
Get issue by ID |
ListIssues |
execute(filters) |
List with filtering |
UpdateIssue |
execute(id, data) |
Update fields |
AddIssueComment |
execute(id, body) |
Add comment |
ArchiveIssue |
execute(id) |
Soft delete |
Plan
| Action |
Method |
Purpose |
CreatePlan |
execute(data) |
Create plan with phases |
GetPlan |
execute(id) |
Get plan by ID/slug |
ListPlans |
execute(filters) |
List plans |
UpdatePlanStatus |
execute(id, status) |
Update plan status |
ArchivePlan |
execute(id) |
Soft delete plan |
Phase
| Action |
Method |
Purpose |
GetPhase |
execute(id) |
Get phase details |
UpdatePhaseStatus |
execute(id, status) |
Update phase status |
AddCheckpoint |
execute(id, checkpoint) |
Record checkpoint |
Session
| Action |
Method |
Purpose |
StartSession |
execute(data) |
Start agent session |
ContinueSession |
execute(id, data) |
Resume session |
EndSession |
execute(id, summary) |
End session with summary |
GetSession |
execute(id) |
Get session details |
ListSessions |
execute(filters) |
List sessions |
Sprint
| Action |
Method |
Purpose |
CreateSprint |
execute(data) |
Create sprint |
GetSprint |
execute(id) |
Get sprint |
ListSprints |
execute(filters) |
List sprints |
UpdateSprint |
execute(id, data) |
Update sprint |
ArchiveSprint |
execute(id) |
Soft delete |
Task
| Action |
Method |
Purpose |
ToggleTask |
execute(id) |
Toggle task completion |
UpdateTask |
execute(id, data) |
Update task fields |
3. API Endpoints
Routes in Routes/api.php, auth via AgentApiAuth middleware:
Brain (/v1/brain/*)
| Method |
Endpoint |
Action |
| POST |
/v1/brain/remember |
RememberKnowledge |
| POST |
/v1/brain/recall |
RecallKnowledge |
| DELETE |
/v1/brain/forget/{id} |
ForgetKnowledge |
| GET |
/v1/brain/list |
ListKnowledge |
Plans (/v1/plans/*)
| Method |
Endpoint |
Action |
| POST |
/v1/plans |
CreatePlan |
| GET |
/v1/plans |
ListPlans |
| GET |
/v1/plans/{id} |
GetPlan |
| PATCH |
/v1/plans/{id}/status |
UpdatePlanStatus |
| DELETE |
/v1/plans/{id} |
ArchivePlan |
Sessions (/v1/sessions/*)
| Method |
Endpoint |
Action |
| POST |
/v1/sessions |
StartSession |
| GET |
/v1/sessions |
ListSessions |
| GET |
/v1/sessions/{id} |
GetSession |
| POST |
/v1/sessions/{id}/continue |
ContinueSession |
| POST |
/v1/sessions/{id}/end |
EndSession |
Messages (/v1/messages/*)
| Method |
Endpoint |
Action |
| POST |
/v1/messages/send |
AgentSend |
| GET |
/v1/messages/inbox |
AgentInbox |
| GET |
/v1/messages/conversation/{agent} |
AgentConversation |
Issues, Sprints, Tasks, Phases — similar CRUD patterns.
Auth (/v1/agent/auth/*)
| Method |
Path |
Action |
Auth |
| POST |
/v1/agent/auth/provision |
ProvisionAgentKey |
OAuth (Authentik) |
| DELETE |
/v1/agent/auth/revoke/{key_id} |
RevokeAgentKey |
AgentApiKey |
Fleet (/v1/fleet/*)
| Method |
Path |
Action |
Auth |
| POST |
/v1/fleet/register |
RegisterNode |
AgentApiKey |
| POST |
/v1/fleet/heartbeat |
NodeHeartbeat |
AgentApiKey |
| POST |
/v1/fleet/deregister |
DeregisterNode |
AgentApiKey |
| GET |
/v1/fleet/nodes |
ListNodes |
AgentApiKey |
| POST |
/v1/fleet/task/assign |
AssignTask |
AgentApiKey |
| POST |
/v1/fleet/task/complete |
CompleteTask |
AgentApiKey |
| GET |
/v1/fleet/task/next |
GetNextTask |
AgentApiKey |
Fleet Events (SSE)
| Method |
Path |
Purpose |
Auth |
| GET |
/v1/fleet/events |
SSE stream — pushes task assignments to connected nodes |
AgentApiKey |
The SSE connection stays open. When the scheduler assigns a task to a node, it pushes a task.assigned event. Nodes that can't hold SSE connections fall back to polling GET /v1/fleet/task/next.
Fleet Stats (/v1/fleet/stats)
| Method |
Path |
Action |
Auth |
| GET |
/v1/fleet/stats |
GetFleetStats |
AgentApiKey |
Returns: nodes_online, tasks_today, tasks_week, repos_touched, findings_total, compute_hours.
Sync (/v1/agent/sync/*)
| Method |
Path |
Action |
Auth |
| POST |
/v1/agent/sync |
PushDispatchHistory |
AgentApiKey |
| GET |
/v1/agent/context |
PullFleetContext |
AgentApiKey |
| GET |
/v1/agent/status |
GetAgentSyncStatus |
AgentApiKey |
Credits (/v1/credits/*)
| Method |
Path |
Action |
Auth |
| POST |
/v1/credits/award |
AwardCredits |
Internal |
| GET |
/v1/credits/balance/{agent_id} |
GetBalance |
AgentApiKey |
| GET |
/v1/credits/history/{agent_id} |
GetCreditHistory |
AgentApiKey |
Subscription (/v1/subscription/*)
| Method |
Path |
Action |
Auth |
| POST |
/v1/subscription/detect |
DetectCapabilities |
AgentApiKey |
| GET |
/v1/subscription/budget/{agent_id} |
GetNodeBudget |
AgentApiKey |
| PUT |
/v1/subscription/budget/{agent_id} |
UpdateBudget |
AgentApiKey |
4. MCP Tools
Registered via AgentToolRegistry in onMcpTools():
Brain Tools
| Tool |
MCP Name |
Maps To |
BrainRemember |
brain_remember |
RememberKnowledge action |
BrainRecall |
brain_recall |
RecallKnowledge action |
BrainForget |
brain_forget |
ForgetKnowledge action |
BrainList |
brain_list |
ListKnowledge action |
Messaging Tools
| Tool |
MCP Name |
Maps To |
AgentSend |
agent_send |
POST /v1/messages/send |
AgentInbox |
agent_inbox |
GET /v1/messages/inbox |
AgentConversation |
agent_conversation |
GET /v1/messages/conversation |
Plan/Session/Phase/Task/Template tools — same pattern.
5. OpenBrain
OpenBrain architecture (storage layers, schema, flow, lifecycle) is defined in code/core/agent/RFC.md section "OpenBrain Architecture". PHP provides the MariaDB persistence layer, Qdrant integration, and Ollama embedding via BrainService.
6. Provider Abstraction
interface AgenticProviderInterface
{
public function generate(string $prompt, array $options = []): string;
public function stream(string $prompt, array $options = [], callable $onToken): void;
public function name(): string;
public function defaultModel(): string;
public function isAvailable(): bool;
}
AgenticManager registers providers (Claude, Gemini, OpenAI) with retry + exponential backoff.
7. Session Lifecycle
StartSession(plan_id, agent) -> active session with context
-> Agent works, appends to work_log
-> ContinueSession(id, work) -> resume from last state
-> EndSession(id, summary, handoff_notes) -> closed
-> session_handoff tool: {summary, next_steps, blockers, context_for_next}
-> session_replay tool: recover context from completed session
Workspace State
Key-value store shared between sessions within a plan:
// Agent A discovers something
WorkspaceState::set($planId, 'discovered_pattern', 'observer');
// Agent B reads it later
$pattern = WorkspaceState::get($planId, 'discovered_pattern');
8. API Key Security
- Hashing: Argon2id (upgraded from SHA-256 Jan 2026)
- Scoping: Permission strings (
plans:read, plans:write, sessions:write, brain:recall)
- IP restriction: IPv4/IPv6/CIDR whitelist via
IpRestrictionService
- Rate limiting: Per-key configurable limits
- Display: Key shown once on creation, stored hashed, prefix
ak_ for identification
9. Services
| Service |
Purpose |
AgenticManager |
Provider registry (claude, gemini, openai) |
AgentSessionService |
Session lifecycle management |
AgentApiKeyService |
API key CRUD + hashing |
AgentToolRegistry |
MCP tool registration |
BrainService |
Qdrant + Ollama integration (embed, search, store) |
ClaudeService |
Anthropic API client |
GeminiService |
Google Gemini API client |
OpenAIService |
OpenAI API client |
ForgejoService |
Forgejo API client (issues, PRs, repos) |
ContentService |
AI content generation pipeline |
PlanTemplateService |
YAML template loading + versioning |
IpRestrictionService |
IP whitelist enforcement |
AgentDetection |
Detect agent type from request headers |
10. Console Commands
| Command |
Artisan |
Purpose |
TaskCommand |
agentic:task |
Manage tasks |
PlanCommand |
agentic:plan |
Manage plans |
GenerateCommand |
agentic:generate |
AI content generation |
PlanRetentionCommand |
agentic:plan-cleanup |
Clean old plans (scheduled daily) |
BrainSeedMemoryCommand |
brain:seed-memory |
Seed brain from files |
BrainIngestCommand |
brain:ingest |
Bulk ingest into brain |
ScanCommand |
agentic:scan |
Scan Forge for work (every 5 min) |
DispatchCommand |
agentic:dispatch |
Dispatch agents (every 2 min) |
PrManageCommand |
agentic:pr-manage |
Manage PRs (every 5 min) |
PrepWorkspaceCommand |
agentic:prep-workspace |
Prepare agent workspace |
11. Admin UI (Livewire)
| Component |
Route |
Purpose |
Dashboard |
/admin/agentic |
Overview stats |
Plans |
/admin/agentic/plans |
Plan listing |
PlanDetail |
/admin/agentic/plans/{id} |
Single plan view |
Sessions |
/admin/agentic/sessions |
Session listing |
SessionDetail |
/admin/agentic/sessions/{id} |
Single session view |
ApiKeys |
/admin/agentic/api-keys |
Key management |
ApiKeyManager |
— |
Key CRUD modal |
Templates |
/admin/agentic/templates |
Template management |
ToolAnalytics |
/admin/agentic/tools |
Tool usage stats |
ToolCalls |
/admin/agentic/tool-calls |
Tool call log |
Playground |
/admin/agentic/playground |
AI playground |
RequestLog |
/admin/agentic/requests |
API request log |
12. Content Generation Pipeline
The agentic module was originally built for AI-driven content generation. This is the PHP side's primary product — the Go agent inherited dispatch/workspace/brain but content generation stays PHP.
Pipeline
Product Briefs (per service)
-> Prompt Templates (system + user, versioned)
-> AI Generation (Claude/Gemini via AgenticManager)
-> Drafts (blog posts, help articles, social media)
-> Quality Refinement (scoring, rewriting)
-> Publication (CMS, social scheduler, help desk)
Product Briefs
Each service has a brief (Resources/briefs/) that gives AI the product context.
| Brief |
Product |
host-link.md |
LinkHost |
host-social.md |
SocialHost |
host-analytics.md |
AnalyticsHost |
host-trust.md |
TrustHost |
host-notify.md |
NotifyHost |
Prompt Templates
Versioned prompt templates in Resources/prompts/:
| Category |
Templates |
| Content |
blog-post, help-article, landing-page, social-media, quality-refinement |
| Development |
architecture-review, code-review, debug-session, test-generation |
| Visual |
infographic, logo-generation, social-graphics |
| System |
dappcore-writer (brand voice) |
Natural Progression SEO
Content changes create future revisions (scheduled posts with no date). When Googlebot visits a page with pending revisions, the system schedules publication 8-62 minutes later — making updates appear as natural content evolution rather than bulk changes.
MCP Content Tools
content_generate — Generate content from brief + prompt template
content_batch — Batch generation across services
content_brief_create — Create new product brief
SEO Schema Generation
Structured data templates for generated content:
- Article (BlogPosting, TechArticle)
- FAQ (FAQPage)
- HowTo (step-by-step guides)
13. Reference Material
| Resource |
Location |
| Agent contract (cross-cutting) |
code/core/agent/RFC.md |
| Go implementation |
code/core/go/agent/RFC.md |
| lthn.sh platform |
project/lthn/ai/RFC.md |
Changelog
- 2026-03-29: Restructured as PHP implementation spec. OpenBrain architecture and polyglot mapping moved to
code/core/agent/RFC.md. Added contract reference. Kept all PHP-specific detail (Eloquent, Livewire, actions, services, commands, admin UI, content pipeline).
- 2026-03-27: Initial RFC specced from existing PHP codebase. 14 models, 30+ actions, 20+ API endpoints, 12 MCP tools, 10 console commands, 12 admin UI components.