ADR-0018 — Durable Work Orchestration, Semantic Activity Feed and Runtime WebUI¶
Repository: agent-adk-wpdoctor
Version: 1.0
Status: Proposed for immediate adoption
Type: Amendment to ADR-0017
Date: 2026-09-09
Supersedes: No ADR in full
Amends: ADR-0017 (ADR-0001-wpdoctor-v1.md en el repositorio de producto)
1. Purpose¶
This ADR extends ADR-0017 with four foundational capabilities that MUST become part of WPDoctor architecture before complex multi-agent operations are implemented:
- Durable Work Orchestration
- Per-tenant SQLite operational persistence
- Human-readable Semantic Activity Feed
- Built-in operator WebUI
The objective is to ensure WPDoctor does not become a collection of ephemeral ADK agents whose internal work disappears into prompts, stdout or framework session state.
WPDoctor MUST provide durable, observable, resumable and human-comprehensible autonomous work.
The resulting architecture is:
Customer / Operator
│
▼
WPDoctor Manager
│
▼
Work Planner
│
▼
Persistent TaskBoard
│
▼
Task Scheduler
│
┌──────┼────────┬─────────┐
▼ ▼ ▼ ▼
Linux PHP DB WordPress
Agent Agent Agent Agent
│ │ │ │
└───────┴────────┴─────────┘
│
▼
Operations
│
▼
Policy Engine
│
▼
Tools / Adapters
│
▼
SSH
│
▼
Customer Infrastructure
Parallel planes:
SQLite
├── WorkPlans
├── Tasks
├── Incidents
├── Inventory
├── Evidence metadata
├── Activity Events
├── Audit
└── Approvals
Hindsight
└── Long-term semantic tenant memory
OpenTelemetry
└── Technical observability
WebUI
└── Human operational observability
2. Architectural Decision¶
WPDoctor v1 SHALL use the following persistence and coordination model:
1 tenant
=
1 active WPDoctor runtime
=
1 Docker container / Kubernetes Pod
=
1 persistent local SQLite database
The canonical database path SHALL initially be:
The runtime persistent area SHALL be:
The initial Kubernetes model SHALL assume:
Two active WPDoctor runtimes MUST NOT concurrently open the same SQLite database.
3. Rationale for SQLite¶
SQLite is selected for WPDoctor v1 because the initial deployment model already provides natural single-runtime tenant isolation.
It offers:
- zero external database dependency;
- simple tenant deployment;
- local durability;
- easy backup;
- easy debugging;
- easy migration between hosts;
- sufficient concurrency for one runtime;
- excellent fit for early dogfooding and pilots.
This decision is intentionally temporary but not disposable.
All persistence MUST be abstracted behind repository interfaces so PostgreSQL can replace SQLite without modifying agents, operations, policies or domain semantics.
4. SQLite Configuration¶
Every runtime MUST configure SQLite with at minimum:
PRAGMA journal_mode=WAL;
PRAGMA foreign_keys=ON;
PRAGMA busy_timeout=5000;
PRAGMA synchronous=NORMAL;
The exact synchronous policy MAY become configurable later.
Database connections MUST use short transactions.
The following pattern is forbidden:
Transactions MUST contain only short database work.
Correct pattern:
5. Persistence Boundary¶
No specialist agent may access SQLite directly.
Forbidden:
inside:
Database access SHALL happen through application-level repositories/services.
Required abstractions:
TenantRepository
HostRepository
SiteRepository
InventoryRepository
IncidentRepository
EvidenceRepository
WorkPlanRepository
TaskRepository
TaskAttemptRepository
ApprovalRepository
ActivityRepository
AuditRepository
ArtifactRepository
Conceptual example:
class TaskRepository(Protocol):
async def create(...)
async def get(...)
async def list(...)
async def claim(...)
async def heartbeat(...)
async def complete(...)
async def fail(...)
async def block(...)
async def cancel(...)
async def release_expired_leases(...)
A future implementation may provide:
without affecting calling code.
6. Revised Orchestration Model¶
ADR-0017 described:
This ADR extends that model.
Complex work SHALL use:
Simple operations MAY still execute synchronously.
7. Direct Execution vs WorkPlan¶
The runtime SHALL support two execution classes.
7.1 Direct Operation¶
Appropriate for:
- simple inspection;
- single target;
- short deterministic action;
- no dependencies;
- no parallelization;
- no approval delay;
- no need for resumability.
Example:
7.2 Durable WorkPlan¶
SHALL be used when one or more of the following applies:
- multiple servers;
- multiple sites;
- multiple specialists;
- dependencies;
- fan-out/fan-in;
- human approval;
- retries;
- potentially long execution;
- autonomous multi-step remediation;
- background/resumable work;
- operation expected to survive runtime restart.
Examples:
Audit 150 WordPress sites.
Investigate intermittent 502 errors.
Update all safe WordPress plugins across the estate.
Perform a complete performance analysis.
Migrate sites from PHP 8.2 to PHP 8.3.
The exact threshold MUST NOT be based solely on elapsed time.
It is a semantic orchestration decision.
8. Domain Model: WorkPlan¶
A WorkPlan represents durable decomposition of an objective.
Required fields:
id:
tenant_id:
incident_id: optional
title:
objective:
status:
created_by:
created_at:
updated_at:
budget:
max_tasks:
max_parallel_tasks:
max_attempts_per_task:
max_model_calls:
max_tool_calls:
max_runtime_seconds:
max_cost: optional
current_summary:
started_at:
completed_at:
cancelled_at:
Recommended status values:
9. Domain Model: Task¶
A Task represents one schedulable unit of work.
Required model:
id:
tenant_id:
workplan_id:
incident_id: optional
type:
title:
description:
status:
priority:
required_role:
required_capabilities: []
target:
host_id: optional
site_id: optional
service_id: optional
risk_level:
claimed_by: optional
lease_until: optional
attempt_count:
max_attempts:
current_summary:
next_action:
created_by:
created_at:
updated_at:
started_at:
finished_at:
Optional metadata MAY be stored in JSON.
Fields involved in scheduling MUST remain first-class indexed columns.
10. Task States¶
Canonical Task state model:
Exceptional states:
Transitions MUST be validated by domain logic.
Arbitrary state mutation is forbidden.
Example valid transitions:
BACKLOG → READY
READY → CLAIMED
CLAIMED → RUNNING
RUNNING → REVIEW
REVIEW → DONE
RUNNING → BLOCKED
RUNNING → WAITING_APPROVAL
RUNNING → FAILED
CLAIMED → READY
when lease expires
FAILED → READY
when retry policy permits
11. Dependencies¶
Task dependencies SHALL be first-class persistent records.
Table:
Fields:
Initial dependency semantics:
A Task SHALL remain blocked from scheduling until dependencies are satisfied.
12. Fan-Out / Fan-In¶
The planner MUST support workload expansion.
Example:
Audit estate
│
▼
Discover inventory
│
▼
fan-out
┌────┼────┬────┐
▼ ▼ ▼ ▼
srv1 srv2 srv3 srv4
│ │ │ │
└────┴────┴────┘
│
▼
fan-in
│
▼
Aggregate
│
▼
Review
Example:
may materialize into dozens of independent tasks.
The Manager SHALL NOT need all task contents inside its active LLM context simultaneously.
13. Scheduler¶
WPDoctor SHALL implement an internal TaskScheduler.
Responsibilities:
- find runnable tasks;
- match task requirements to specialist role;
- enforce dependencies;
- enforce WorkPlan budgets;
- enforce max concurrency;
- claim tasks atomically;
- maintain leases;
- recover expired tasks;
- invoke task workers;
- schedule retries;
- respect cancellation/pause;
- avoid duplicate execution.
The scheduler SHALL NOT rely on LLM reasoning for atomic ownership.
14. Task Claims and Leases¶
Tasks MUST use claim/lease semantics.
Example:
Workers SHALL periodically heartbeat long-running tasks.
If a lease expires:
depending on retry policy.
Task ownership SHALL be assigned to a worker instance, not permanently to an agent identity.
15. Role-Based Scheduling¶
Tasks SHALL request roles/capabilities rather than concrete agents.
Correct:
Incorrect:
This ensures future horizontal scaling.
Possible roles:
manager
operator
linux-specialist
web-specialist
php-specialist
database-specialist
wordpress-specialist
woocommerce-specialist
performance-specialist
security-specialist
lifecycle-specialist
backup-specialist
reviewer
16. Task Creation by Agents¶
Specialists MUST NOT have unrestricted authority to recursively generate arbitrary work.
A specialist may request a follow-up task via:
This request MUST pass through the Work Planner / Scheduler policy.
The runtime SHALL enforce limits such as:
Defaults MUST be configurable.
The planner SHALL detect obvious duplicates before task creation.
17. Work Budgets¶
Every WorkPlan MUST support resource budgets.
Minimum budget fields:
max_tasks:
max_parallel_tasks:
max_attempts_per_task:
max_model_calls:
max_tool_calls:
max_runtime_seconds:
Future:
Budget exhaustion MUST produce an explicit state/event.
The runtime MUST NOT silently continue unlimited autonomous execution.
18. Task Attempts¶
Each execution attempt SHALL create a separate record.
Table:
Fields:
id
tenant_id
task_id
worker_id
attempt_number
status
started_at
finished_at
error_code
error_summary
model_calls
tool_calls
trace_id
Task history MUST remain available after retries.
19. Durable Runtime Recovery¶
At startup, WPDoctor SHALL perform recovery.
Recovery steps:
open SQLite
↓
run migrations
↓
validate DB
↓
find expired task leases
↓
recover eligible tasks
↓
restore pending WorkPlans
↓
restore WAITING_APPROVAL items
↓
start scheduler
A container restart MUST NOT lose the operational state of existing work.
20. Operational Persistence Schema¶
Initial SQLite SHOULD contain at minimum:
schema_migrations
tenants
hosts
sites
capabilities
incidents
evidence
workplans
tasks
task_dependencies
task_attempts
approvals
activity_events
audit_events
artifacts
memory_references
Additional tables MAY be added through migrations.
21. Database Migration System¶
Schema migrations SHALL exist from the first implementation.
Do not use ad-hoc:
as the permanent migration strategy.
Choose a versioned migration mechanism.
Every release changing schema MUST provide forward migration.
22. Semantic Activity Feed¶
WPDoctor SHALL implement a human-readable semantic activity stream.
This is a distinct architectural plane.
It MUST NOT be treated as ordinary stdout logging.
The purpose is to answer:
What is the agent doing?
What has it learned?
What changed?
What will it do next?
Why is it waiting?
The activity feed SHALL summarize operational state without exposing hidden chain-of-thought.
23. No Chain-of-Thought Requirement¶
WPDoctor MUST NOT attempt to persist or display private model chain-of-thought.
Do NOT instruct models:
Instead, agents SHALL emit explicit concise operational summaries.
Allowed:
Not required:
Activity is a product-facing operational narrative.
24. ActivityEvent Domain Model¶
Every semantic event SHALL have a structured model.
Required fields:
id:
tenant_id:
incident_id: optional
workplan_id: optional
task_id: optional
actor:
type:
role:
worker_id: optional
event_type:
severity:
title:
message:
target:
host_id: optional
site_id: optional
service: optional
evidence_refs: []
artifact_refs: []
created_at:
25. Canonical Activity Event Types¶
Initial event vocabulary:
WORKPLAN_CREATED
WORKPLAN_STARTED
WORKPLAN_COMPLETED
WORKPLAN_FAILED
TASK_CREATED
TASK_READY
TASK_CLAIMED
TASK_STARTED
TASK_BLOCKED
TASK_RETRYING
TASK_COMPLETED
TASK_FAILED
TASK_CANCELLED
INVESTIGATION_STARTED
FINDING
HYPOTHESIS_CREATED
HYPOTHESIS_UPDATED
DIAGNOSIS
PLAN_CREATED
PLAN_UPDATED
ACTION_PROPOSED
ACTION_STARTED
ACTION_COMPLETED
ACTION_FAILED
VALIDATION_STARTED
VALIDATION_PASSED
VALIDATION_FAILED
APPROVAL_REQUIRED
APPROVAL_GRANTED
APPROVAL_DENIED
HANDOFF_REQUESTED
FOLLOWUP_TASK_CREATED
MEMORY_RECALLED
LEARNING_CANDIDATE_CREATED
BUDGET_WARNING
BUDGET_EXHAUSTED
Do not proliferate event types unnecessarily.
New event types require review.
26. Human Narrative Requirements¶
Activity messages MUST be:
- concise;
- factual;
- operational;
- understandable by a sysadmin;
- specific about target;
- explicit when evidence is incomplete;
- explicit when a hypothesis changes.
Example:
TASK-203 · PHP Specialist
PHP-FPM has reached pm.max_children 17 times during the last 15 minutes.
I will now correlate those events with nginx 502 timestamps before proposing a remediation.
Example after failed verification:
TASK-203 · Operator
The initial hypothesis does not fully explain the incident: 502 responses continue after PHP worker pressure returned to normal.
I will inspect database latency during the same time window.
Example plan change:
TASK-203 · Operator
The evidence now points to long-running WooCommerce queries as the primary cause.
PHP-FPM saturation appears to be secondary.
Next I will validate the affected query pattern before proposing an index change.
This is the desired level of narration.
27. Activity Emission Rules¶
A task MUST NOT remain operationally silent during meaningful state changes.
Emit semantic activity when:
- task starts;
- investigation direction changes;
- relevant evidence is found;
- a hypothesis is created or invalidated;
- diagnosis materially changes;
- a remediation plan is produced;
- an action begins;
- action fails;
- validation passes/fails;
- human approval is required;
- task becomes blocked;
- retry occurs;
- task completes.
Do NOT emit events for every low-level command.
Semantic Activity MUST remain signal-rich.
28. Task Current Summary¶
In addition to immutable activity history, every Task SHALL expose mutable operational summary fields:
Example:
current_summary: >
PHP-FPM saturation is confirmed, but current evidence suggests
it is secondary to long-running WooCommerce database queries.
next_action: >
Correlate slow query timestamps with nginx upstream failures.
These fields SHALL be shown directly on the Kanban card/detail UI.
29. Activity vs Audit vs Telemetry¶
These systems MUST remain distinct.
Activity¶
Answers:
Human-oriented.
Audit¶
Answers:
What action actually happened?
Who caused it?
What target was affected?
Was it approved?
What was the result?
Security/compliance-oriented.
Telemetry¶
Answers:
Engineering-oriented.
Hindsight¶
Answers:
Memory-oriented.
The separation is:
| Plane | Primary purpose |
|---|---|
| TaskBoard | What work remains? |
| Activity | What is happening now? |
| Audit | What actions actually occurred? |
| Telemetry | How is the runtime behaving technically? |
| Hindsight | What durable knowledge was learned? |
No plane SHALL be overloaded to replace another.
30. Evidence¶
Activity events may reference technical evidence.
Example:
event_type: FINDING
message: >
PHP-FPM reached max_children repeatedly.
evidence_refs:
- evid-1001
- evid-1002
The WebUI SHALL allow a human to drill down from semantic summary into underlying evidence.
Evidence SHOULD contain:
31. Raw Logs and Artifacts¶
Large technical output SHALL NOT be stored inline in semantic activity messages.
SQLite SHALL only contain metadata/reference.
Initial artifact path:
Recommended layout:
/data/artifacts/
└── incidents/
└── INC-104/
└── TASK-203/
├── nginx-errors.log
├── php-fpm.log
├── slow-query.log
└── report.json
Artifact table fields:
Future artifact storage MAY be moved to S3/SeaweedFS without changing domain references.
32. Agent Logging Requirements¶
Every agent/role SHALL produce two distinct forms of logging:
Structured technical logs¶
For engineering:
Semantic Activity¶
For humans.
Example technical log:
Corresponding semantic event:
Both are useful.
Neither replaces the other.
33. Operator Identity¶
The primary orchestrating role SHOULD be represented in the WebUI as:
Internal role:
Example human narrative:
Operator · TASK-203
I am starting an investigation into intermittent 502 errors on shop.example.com.
Specialists may be shown as:
The UI does not need to expose ADK framework internals.
34. Runtime WebUI¶
WPDoctor SHALL include an operator WebUI from early development.
It is not a future SaaS customer portal.
It is an operational UI for developers/operators to observe and control the tenant runtime.
Initial technology recommendation:
Exact frontend framework is implementation-level unless it creates architectural coupling.
Avoid unnecessary complexity.
35. Required WebUI Sections¶
Minimum navigation:
Recommended subsequent sections:
36. Kanban View¶
The Tasks page SHALL provide a Kanban-style board.
Initial columns:
UI MAY merge some internal states visually.
Example card:
TASK-203
Investigate 502
shop.example.com
PHP Specialist
RUNNING · 8m
PHP-FPM saturation confirmed.
Checking DB latency correlation.
Next:
Inspect slow queries
Incident INC-104
Risk R0
Cards SHALL prioritize human understanding over displaying raw internal metadata.
37. Task Detail View¶
Task detail MUST show:
Task ID
Title
Objective
Status
Target
Assigned role
Worker
Risk
Dependencies
Attempts
Current summary
Next action
and tabs/sections:
38. Incident View¶
Incident detail SHOULD aggregate related Task activity into one chronological narrative.
Example:
07:31 Operator
Started investigation.
07:32 PHP Specialist
Detected repeated PHP-FPM worker exhaustion.
07:35 Operator
Initial hypothesis incomplete; expanding investigation to database.
07:38 Database Specialist
Detected long-running WooCommerce queries.
07:40 Operator
Primary cause identified as database query latency.
07:41 Operator
Prepared remediation plan and requested approval.
This should allow an operator to understand the incident without opening every task.
39. Live Activity View¶
WebUI SHALL provide a live semantic event stream.
Example:
07:31 TASK-203 started by Operator
07:32 PHP found FPM saturation
07:33 TASK-211 claimed by Linux
07:34 TASK-199 completed
07:35 TASK-203 hypothesis updated
07:36 TASK-212 waiting for approval
This view is intended as:
40. Real-Time Transport¶
Initial WebUI real-time updates SHOULD use Server-Sent Events.
Endpoint example:
SSE is preferred initially because communication is predominantly:
User actions SHALL use regular HTTP.
Examples:
POST /tasks/{id}/retry
POST /tasks/{id}/cancel
POST /workplans/{id}/pause
POST /approvals/{id}/approve
POST /approvals/{id}/deny
WebSockets MAY be introduced later if genuinely necessary.
41. Web API¶
The runtime SHALL expose a typed internal REST API.
Suggested namespace:
Minimum endpoints:
GET /health
GET /overview
GET /incidents
GET /incidents/{id}
GET /workplans
GET /workplans/{id}
GET /tasks
GET /tasks/{id}
GET /activity
GET /events/stream
GET /hosts
GET /hosts/{id}
GET /sites
GET /sites/{id}
GET /audit
GET /approvals
POST /approvals/{id}/approve
POST /approvals/{id}/deny
POST /tasks/{id}/retry
POST /tasks/{id}/cancel
POST /workplans/{id}/pause
POST /workplans/{id}/resume
POST /workplans/{id}/cancel
Mutation endpoints MUST invoke domain services and policy.
HTTP handlers MUST NOT mutate SQLite state directly.
42. Approvals¶
Human approvals SHALL integrate with TaskBoard.
A task requiring approval transitions:
Approval record SHALL contain:
id
tenant_id
incident_id
workplan_id
task_id
operation
risk
requested_by
requested_at
summary
proposed_action
rollback_plan
status
decided_by
decided_at
decision_comment
The WebUI MUST make pending approvals highly visible.
43. Memory Integration¶
Hindsight remains separate from TaskBoard.
Do NOT store operational queue state in Hindsight.
Correct responsibility split:
At task/incident completion:
SQLite MAY store:
to link incidents/tasks to Hindsight entries.
44. Memory Narration¶
When memory materially influences a task, Activity MAY show:
Historical context recalled:
srv01 has previously experienced IO contention during nightly backups.
I will verify whether the current incident matches that pattern.
Do not expose irrelevant memory recall noise.
45. Runtime Container Layout¶
Initial container:
WPDoctor tenant runtime
│
├── ADK runtime
├── Manager
├── Specialists
├── Work Planner
├── Task Scheduler
├── Operations Engine
├── Policy Engine
├── Web API
├── WebUI
├── SQLite
│ └── /data/wpdoctor.db
│
├── artifact workspace
│ └── /data/artifacts/
│
└── external clients
├── Hindsight
├── Infisical
└── customer SSH hosts
The UI/API may run in the same process initially or as cooperating processes within the same deployment.
Avoid splitting into microservices in v1.
46. Kubernetes Runtime Model¶
Initial Kubernetes recommendation:
One active pod per tenant.
Do NOT attempt active-active SQLite.
If orchestration requires multiple simultaneously writable WPDoctor pods, migrate persistence before scaling.
47. Database Migration Trigger to PostgreSQL¶
SQLite remains valid while all are true:
single active runtime per tenant
single writable node
moderate task concurrency
local persistent filesystem
no distributed scheduler
PostgreSQL migration SHOULD occur when one or more becomes necessary:
multiple active WPDoctor pods per tenant
distributed task workers
active-active HA
central fleet scheduler
large cross-tenant control plane
high concurrent write throughput
complex fleet-wide analytics
Do NOT migrate merely because PostgreSQL is theoretically more scalable.
48. PostgreSQL Compatibility Requirement¶
All domain repositories MUST avoid exposing SQLite-specific semantics to callers.
Example:
may internally use:
The caller sees the same behavior.
49. Security Requirements¶
The WebUI introduces additional security boundaries.
Minimum:
- listen only on configured interface;
- authentication required in non-development mode;
- no raw secrets displayed;
- redact SSH credentials;
- redact DB credentials;
- redact environment secrets;
- CSRF protection where relevant;
- authorization required for approval/mutation endpoints;
- audit all operator mutations.
For development, local-only authentication bypass MAY be configurable.
It MUST NOT be the production default.
50. Semantic Log Security¶
Activity messages MUST NOT include:
Evidence and raw logs must pass redaction where practical.
Remote content remains untrusted.
A malicious WordPress plugin or log line MUST NOT be able to generate trusted Activity instructions.
51. Event Origin¶
Activity events SHALL only be generated through trusted WPDoctor code paths.
Remote systems may provide evidence used to construct an Activity event, but raw remote text MUST NOT be able to directly publish privileged event semantics.
52. Audit Immutability Semantics¶
Activity events may be explanatory.
Audit events represent actual security-relevant facts.
Audit records SHOULD be append-only through application semantics.
Example:
Do not retroactively rewrite audit events.
53. OpenTelemetry¶
WPDoctor SHALL instrument:
workplan lifecycle
task lifecycle
agent invocation
specialist delegation
operation
tool call
SSH command
memory recall
memory retain
policy decision
approval wait
activity event generation
Trace IDs SHOULD be persisted on TaskAttempt and Audit records when available.
This permits navigation:
54. Failure Handling¶
Every failure MUST be represented in three appropriate layers.
Example SSH timeout:
Activity¶
Audit¶
Only if an operational action actually occurred.
Technical log¶
Task state¶
or:
No silent retry loops.
55. Retry Policy¶
Tasks SHALL define retry semantics.
Example fields:
Retries MUST generate Activity events.
Example:
TASK-203 · Retry 2/3
The previous SSH attempt timed out.
A second attempt will be made after 10 seconds.
56. Long-Running Task Heartbeats¶
Long tasks SHALL heartbeat.
Heartbeat SHOULD update:
Do not generate semantic Activity solely for heartbeat noise.
Activity is for meaningful progress.
57. Progress Model¶
Task progress MAY expose:
Only use percentages when meaningful.
Do not fabricate arbitrary percentages for open-ended investigations.
For investigations prefer:
58. Human Intervention¶
Operators SHALL be able to:
Future:
Manual intervention SHALL create Activity and Audit records where relevant.
59. Cancellation¶
Cancellation semantics MUST be explicit.
Cancelling a WorkPlan:
- prevents new tasks from being scheduled;
- requests cancellation of interruptible running tasks;
- does not assume currently executing remote shell commands can always be safely aborted;
- records final state.
Cancellation does NOT imply rollback.
Rollback is separate.
60. Repository Structure Amendment¶
ADR-0017 repository tree SHALL be expanded with:
src/wpdoctor/
│
├── persistence/
│ ├── database.py
│ ├── migrations/
│ └── repositories/
│ ├── tenants.py
│ ├── inventory.py
│ ├── incidents.py
│ ├── workplans.py
│ ├── tasks.py
│ ├── approvals.py
│ ├── activity.py
│ ├── audit.py
│ └── artifacts.py
│
├── work/
│ ├── planner.py
│ ├── scheduler.py
│ ├── worker.py
│ ├── leases.py
│ ├── budgets.py
│ └── recovery.py
│
├── activity/
│ ├── service.py
│ ├── models.py
│ └── event_types.py
│
├── web/
│ ├── api/
│ ├── sse.py
│ └── ui/
│
└── ...
Exact filenames may differ slightly.
Architectural boundaries MUST remain equivalent.
61. Recommended New Domain Models¶
Add:
Existing:
shall integrate through IDs, not deeply nested serialized blobs.
62. Implementation Milestone Amendment¶
ADR-0017 rollout SHALL be revised.
M0 — Core contracts/runtime¶
M1 — SSH / discovery / inventory¶
As ADR-0017.
M2 — Durable Work Orchestration¶
NEW mandatory milestone.
Implement:
WorkPlan
Task
TaskDependency
TaskAttempt
TaskBoard
Scheduler
claim/lease
heartbeat
retry
recovery
budgets
Implement WebUI skeleton.
M3 — Semantic Activity + WebUI¶
Implement:
ActivityEvent
ActivityService
current_summary
next_action
REST API
SSE
Kanban
Task detail
Incident activity
Live activity feed
M4 — Read-only SRE vertical slice¶
Implement first full diagnostic workflows.
M5 — Policy / approvals / controlled mutations¶
As previously defined.
M6 — WordPress performance/lifecycle¶
As previously defined.
M7 — Hindsight / LEARN / curator¶
As previously defined.
M8 — Dogfooding / eval corpus¶
As previously defined.
63. First Vertical Slice Amendment¶
The first 502/PHP-FPM vertical slice SHALL now prove ALL of:
incident creation
↓
WorkPlan creation
↓
Task decomposition
↓
task scheduling
↓
specialist claim
↓
semantic Activity
↓
SSH evidence collection
↓
diagnosis
↓
TaskBoard update
↓
policy
↓
approval if mutation
↓
execution
↓
validation
↓
audit
↓
task completion
↓
WorkPlan completion
↓
LEARN later
The developer MUST NOT bypass TaskBoard for convenience when testing this vertical slice.
64. Example End-to-End Narrative¶
Target desired behavior:
07:31 Operator
INC-104 created.
Intermittent 502 errors on shop.example.com will be investigated.
07:31 Operator
WorkPlan WP-22 created with 4 initial tasks.
07:32 PHP Specialist
TASK-203 started.
I will inspect PHP-FPM state and recent errors.
07:33 PHP Specialist
PHP-FPM reached pm.max_children 17 times during the last 15 minutes.
07:34 Operator
The current evidence suggests worker exhaustion, but I will correlate nginx failures before confirming it as the primary cause.
07:35 Web Specialist
nginx upstream failures match the PHP-FPM saturation windows.
07:36 Operator
The diagnosis currently points to PHP-FPM worker exhaustion.
A database check has been scheduled to determine whether workers are blocked by slow queries.
07:38 Database Specialist
Long-running WooCommerce queries coincide with worker exhaustion.
07:39 Operator
Diagnosis updated.
Slow WooCommerce database queries are the primary cause; PHP-FPM saturation is secondary.
07:40 Operator
A remediation plan has been prepared and requires approval.
07:44 Human Operator
Approved.
07:44 Database Specialist
Remediation started.
07:45 Database Specialist
Database change completed successfully.
07:46 Operator
Validation is running.
07:47 Operator
Validation passed.
No further nginx 502 responses were observed and PHP-FPM worker occupancy returned to normal.
07:47 Operator
TASK-203 completed.
INC-104 resolved.
This is the minimum quality target for semantic observability.
65. Definition of Done for TaskBoard¶
TaskBoard is NOT complete until:
[ ] tasks persist across restart
[ ] dependencies work
[ ] atomic claims work
[ ] leases work
[ ] expired task recovery works
[ ] retries work
[ ] budgets work
[ ] cancellation works
[ ] task attempts are preserved
[ ] multiple specialists can process tasks concurrently
[ ] no duplicate execution occurs in normal runtime operation
66. Definition of Done for Activity Feed¶
Activity is NOT complete until:
[ ] events are persisted
[ ] events are structured
[ ] events reference tasks/incidents
[ ] events can reference evidence
[ ] current_summary exists
[ ] next_action exists
[ ] agents emit meaningful milestones
[ ] failed hypotheses can be narrated
[ ] retries are narrated
[ ] approvals are narrated
[ ] task completion is narrated
[ ] secret leakage tests exist
67. Definition of Done for WebUI¶
WebUI MVP is NOT complete until an operator can:
[ ] view incidents
[ ] view TaskBoard
[ ] inspect one Task
[ ] see current_summary
[ ] see next_action
[ ] follow live Activity
[ ] view evidence
[ ] view task attempts
[ ] view raw artifacts/logs
[ ] inspect audit records
[ ] approve/deny pending operation
[ ] retry failed task
[ ] cancel task
[ ] pause/cancel WorkPlan
68. Tests Required¶
New mandatory tests:
Persistence¶
Scheduler¶
Activity¶
Web API¶
Full integration¶
69. Anti-Patterns Explicitly Forbidden¶
Do not implement:
ADK Session = source of truth
stdout logs = TaskBoard
Hindsight = task queue
LLM prompt = workflow persistence
one giant JSON incident blob
specialists writing SQLite directly
unbounded recursive task generation
long-running DB transactions
active-active SQLite
generic shell output copied wholesale to Activity
chain-of-thought exposed as observability
silent autonomous operations
semantic narration generated only after incident ends
70. Product-Level Consequence¶
These additions intentionally move WPDoctor from:
toward:
The runtime now contains explicit primitives for:
This is a deliberate architectural direction.
71. Relationship with ADK¶
ADK SHALL remain responsible for:
WPDoctor itself SHALL own:
This prevents WPDoctor business state from becoming coupled to ADK internals.
If ADK changes in the future, operational state remains portable.
72. Architectural Principle¶
The primary principle introduced by this ADR is:
Autonomous work that matters must be durable, inspectable, resumable and understandable by a human operator.
A second principle is:
No long-running WPDoctor task should become a black box.
At any point an operator should be able to determine:
what the system is trying to achieve
what tasks exist
what is running
who is working on it
what has been discovered
what hypothesis currently exists
what will happen next
what is blocked
what requires approval
what actions were actually executed
73. Instructions to Implementing Architect / Agent¶
Before implementation:
- Read ADR-0017.
- Read this ADR completely.
- Treat this ADR as an amendment to the orchestration, persistence and observability sections of ADR-0017.
- Do not remove provider-agnostic requirements.
- Do not introduce Wetopi-specific assumptions.
- Preserve repository boundaries.
- Implement SQLite abstraction from day one.
- Implement migrations from day one.
- Implement TaskBoard before broad multi-agent operations.
- Implement Activity as a first-class domain object, not formatted stdout.
- Build the WebUI against the same canonical repositories/API used by runtime services.
- Do not make the WebUI a second source of truth.
- Do not use Hindsight for workflow state.
- Do not expose private chain-of-thought.
- Record any required architectural deviation in a new ADR.
74. First Expected Delivery¶
The first delivery after adopting ADR-0002 SHOULD demonstrate:
start WPDoctor container
↓
SQLite initialized + migrations
↓
create WorkPlan
↓
create dependent Tasks
↓
scheduler claims task
↓
specialist runs
↓
Activity events appear live
↓
task detail updates
↓
runtime killed
↓
runtime restarted
↓
expired work recovered
↓
Task resumes/retries
↓
WebUI shows complete history
A minimal fake/test operation MAY be used before SSH integration for this demonstration.
75. Acceptance Criteria¶
ADR-0002 is considered implemented when:
/data/wpdoctor.dbis the durable operational store.- SQLite runs in WAL mode.
- Repository abstractions isolate persistence.
- schema migrations exist.
- WorkPlans are persistent.
- Tasks are persistent.
- Task dependencies work.
- Task attempts are retained.
- scheduler uses leases.
- expired work is recoverable.
- runtime restart does not lose active plans.
- budgets prevent unbounded work.
- specialists cannot create unlimited recursive tasks.
- ActivityEvents are persistent and structured.
- Tasks expose
current_summary. - Tasks expose
next_action. - semantic events are shown live.
- raw technical logs remain separate.
- Audit remains separate.
- Hindsight remains separate.
- WebUI shows Kanban.
- WebUI shows Task detail.
- WebUI shows Incident narrative.
- WebUI supports live SSE.
- WebUI supports approvals.
- WebUI supports retry/cancel/pause actions.
- secrets are redacted from Activity.
- no private chain-of-thought is required or displayed.
- OpenTelemetry can correlate TaskAttempt to trace.
- first SRE vertical slice uses the durable orchestration path.
76. Final Decision¶
Adopt this ADR before implementing complex WPDoctor multi-agent workflows.
ADR-0017 remains authoritative for:
provider agnosticism
SSH boundary
specialist model
Operations / Skills / Tools
Policy
Hindsight
tenant model
security
WordPress SRE scope
ADR-0002 becomes authoritative for:
runtime persistence
SQLite
WorkPlans
TaskBoard
Scheduler
leases
retries
budgets
durability
semantic Activity
agent narration
WebUI
SSE
operator controls
runtime recovery
SQLite → PostgreSQL evolution
The resulting WPDoctor v1 architecture SHALL be treated as:
A durable, observable, provider-agnostic WordPress SRE runtime, not merely an ADK multi-agent application.
Correspondencia: este documento es el ADR-0018 del Knowledge Plane y corresponde al ADR-0002 del repositorio de producto.