docs: plan workflow console and interrupt contracts

This commit is contained in:
lda
2026-07-01 05:47:27 +07:00 Verified
parent a1007c49a9
commit cdffb1d620
7 changed files with 2043 additions and 32 deletions
+31
View File
@@ -22,6 +22,37 @@ The durable product path is now `wf-rpc-server` plus neutral `wf_config` /
`wf_server` composition. The old `wf-mcp` script remains a legacy/special-purpose
MCP entrypoint and compatibility surface.
## Active Initiative: Workflow Console And Defense Demo
The next product-facing push is a local-first web console and defense demo that
shows the lifecycle without forcing viewers to read raw JSON. It connects to a
loopback `wf-rpc-server` through JSON-RPC, displays lifecycle records and traces,
and runs a prepared `lda.chat` report workflow with a typed human approval
interrupt.
Design contracts:
- [`workflow console, agent demo, and defense presentation`](superpowers/specs/2026-07-01-workflow-console-agent-demo.md)
- [`self-describing interrupt contracts`](superpowers/specs/2026-07-01-self-describing-interrupt-contracts.md)
Implementation order:
1. Add self-describing interrupt request/resume schemas to the core run/inspect
contract.
2. Add a deterministic `examples/lda_report_workflow/` case study with local
document, report, and issue-board sources.
3. Add a top-level `web/` Astro/Effect app with loopback JSON-RPC connection and
method registry.
4. Add console read/inspect views for sources, drafts, artifacts, deployments,
runs, traces, and raw RPC drawers.
5. Add lifecycle autoplay, typed approval, issue-board output, and replay.
6. Add a constrained demo agent that invokes one prepared recipe macro.
7. Add presentation and appendix routes for the 15-minute defense.
Boundaries: this is not a production admin panel, generic visual workflow
editor, scheduler, external Google Drive/mail integration, or benchmark evidence
for free-form autonomous planning.
## Priority 1: Product Smoke And Status UX
The platform is usable enough to test as a product. Next work should focus on
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,308 @@
# Self-Describing Interrupt Contracts
Date: 2026-07-01
Status: Approved direction. Needs an executable implementation plan before code
changes.
Related:
- [Current roadmap](../../current_roadmap.md)
- [Persisted run/resume contract](2026-06-03-persisted-run-resume-contract.md)
- [Workflow console, agent demo, and defense presentation](2026-07-01-workflow-console-agent-demo.md)
- [Thesis system design](../../thesis/system-design-implementation.md)
## Purpose
Make human-in-the-loop workflow pauses self-describing. A client inspecting an
interrupted run should know:
- what kind of interrupt occurred;
- what payload was sent to the user;
- which resume outcomes are valid;
- what JSON shape a resume payload must have;
- how to validate the response before sending `resume_run`.
This is required for the Workflow Console and useful for CLI, JSON-RPC, MCP, and
agent clients. It prevents every client from needing workflow-specific code just
to render and answer an approval step.
## Current Gap
The current core interrupt model has useful mechanics but not a complete public
contract.
- `InterruptNode` stores `kind`, request bindings, resume bindings, and resume
outcomes.
- Runtime builds an `InterruptRequest` with id, frame id, node id, kind,
payload, route, and resumability.
- `workflow.runs.inspect` serializes the current runtime interrupt request.
- Resume validates the selected outcome against `InterruptNode.outcomes` and
applies resume bindings.
What is missing is a machine-readable schema for the request payload and resume
payload. A client can see data, but it cannot know whether the response should
be `{ "approved": true }`, `{ "selected_issue_ids": [...] }`, or something else
without reading workflow code or challenge-specific docs.
This is close to the LangGraph-style `interrupt(value)` and `Command(resume=...)`
pattern: flexible and simple, but the response contract is mostly app
convention. `wf` should keep the flexibility while making the contract explicit.
## Design Summary
Add JSON Schema contracts to interrupt nodes and carry them through persisted run
inspection and resume validation.
```mermaid
sequenceDiagram
participant Runtime
participant Store
participant Client
Runtime->>Runtime: Build request payload from interrupt.request bindings
Runtime->>Runtime: Validate payload against request_schema
Runtime->>Store: Persist interrupted run checkpoint
Client->>Store: inspect_run(run_id)
Store-->>Client: payload, outcomes, request_schema, resume_schema
Client->>Client: Render form from resume_schema
Client->>Store: resume_run(run_id, payload, outcome)
Store->>Runtime: Validate resume payload against resume_schema
Runtime->>Runtime: Apply interrupt.resume bindings
```
## Core Model
Extend `InterruptNode` with two optional schema fields:
```python
class InterruptNode(BaseModel):
id: str
type: Literal["interrupt"]
kind: str
request: list[InputBinding] = Field(default_factory=list)
resume: list[OutputBinding] = Field(default_factory=list)
outcomes: list[str] = Field(default_factory=lambda: ["submitted"])
request_schema: JsonSchemaObject = Field(default_factory=_object_schema)
resume_schema: JsonSchemaObject = Field(default_factory=_object_schema)
```
The default schema is a permissive object schema:
```json
{
"type": "object",
"additionalProperties": true
}
```
This preserves existing persisted workflow documents and current examples. New
authoring helpers should emit explicit schemas whenever they can.
## Runtime Request Contract
When an interrupt node executes:
1. Build the request payload using existing `request` bindings.
2. Validate the built payload against `request_schema`.
3. If validation fails, fail the run with a structured execution error. This is
a workflow contract bug, not a human pause.
4. Persist the interrupted run with an `InterruptRequest` that includes:
- interrupt id;
- frame id;
- node id;
- kind;
- payload;
- resumable flag;
- child interrupt route when present;
- outcomes;
- request schema;
- resume schema;
- `typed=true` when the schema was explicitly declared.
The runtime should not infer request schemas from payload values. Inference
would make the public contract depend on one execution instance rather than the
workflow definition.
## Resume Contract
Before mutating run state, `resume_run` validates:
1. the run is currently interrupted;
2. the selected resume outcome is declared by the interrupt node;
3. the resume payload satisfies the interrupt node's `resume_schema`.
Only after those checks pass should the runtime apply `resume` bindings and
advance the graph. Invalid resume payloads must not consume the interruption or
write partial state changes.
Resume validation should use the same JSON Schema validation helper used by
workflow validation where possible. Do not hand-roll schema validation.
## Public Inspect Shape
`workflow.runs.inspect` should expose the interrupt contract directly:
```json
{
"status": "interrupted",
"interrupt": {
"id": "interrupt:review",
"frame_id": "frame_1",
"node_id": "review",
"kind": "issue_review",
"payload": {
"report_markdown": "# lda.chat Thesis And Project Readiness Report",
"proposed_issues": []
},
"outcomes": ["submitted", "cancelled"],
"request_schema": {
"type": "object",
"properties": {
"report_markdown": {"type": "string"},
"proposed_issues": {"type": "array"}
},
"required": ["report_markdown", "proposed_issues"]
},
"resume_schema": {
"type": "object",
"properties": {
"approved": {"type": "boolean"},
"selected_issue_ids": {
"type": "array",
"items": {"type": "string"}
},
"comment": {"type": "string"}
},
"required": ["approved", "selected_issue_ids"],
"additionalProperties": false
},
"typed": true,
"resumable": true
}
}
```
The schema snapshot is part of the interrupted run's public contract. A client
should not need to reload the mutable artifact or inspect Python source code to
answer the interrupt.
## Authoring Contract
Raw workflow plans may specify `request_schema` and `resume_schema` directly on
interrupt nodes.
Authoring helpers may provide convenience wrappers:
- direct JSON Schema dictionaries;
- Pydantic models converted through `model_json_schema()`;
- a small built-in helper for common approval forms.
The stored workflow should still contain ordinary JSON Schema dictionaries.
Python type objects must not leak into persisted artifacts.
The first planned demo uses:
- `kind="issue_review"`;
- a request schema containing rendered report markdown and proposed issues;
- a resume schema containing approval, selected issue ids, and optional comment;
- outcomes `submitted` and `cancelled`.
## Validation Contract
Workflow validation should catch static interrupt contract errors:
- `request_schema` and `resume_schema` must be valid JSON Schema documents;
- schemas must describe JSON objects for V1;
- request binding targets must be valid local payload paths;
- resume binding sources must be valid local payload paths;
- resume binding destinations must write to declared state fields;
- every declared resume outcome that is routed must be known by the node.
V1 does not need full static proof that every request binding output satisfies
`request_schema`. Runtime validation still protects execution. Static validation
can become stricter later if it remains useful and maintainable.
## CLI And RPC Behavior
CLI and RPC should surface schema failures as ordinary structured product
errors, not Python tracebacks.
Recommended behavior:
- `wf run inspect <run_id>` includes the interrupt schemas in JSON output.
- Compact/text output summarizes `kind`, valid outcomes, and required resume
fields.
- `wf run resume <run_id> --input ...` validates before mutation and reports
missing/invalid resume fields.
- `wf explain` gains cards for interrupt request-schema and resume-schema
validation failures if new diagnostic codes are added.
## Compatibility
Existing workflows without explicit schemas remain valid.
- Missing `request_schema` or `resume_schema` is treated as a permissive object
schema.
- Public inspect can include `typed=false` for legacy interrupts.
- New authoring helpers and examples should emit explicit schemas.
- No migration is required for stored artifacts.
Compatibility here is justified because raw workflow plans and saved artifacts
are a documented external/persisted contract.
## Workflow Console Usage
The Workflow Console uses this contract to render generic human approval forms:
1. inspect the interrupted run;
2. read `interrupt.kind` and `interrupt.resume_schema`;
3. choose a kind-specific renderer when available;
4. fall back to a generic JSON Schema form;
5. validate locally for user feedback;
6. send the resume payload through JSON-RPC;
7. display server-side validation errors if the schema check still fails.
The console may provide a custom renderer for `issue_review`, but the custom
renderer must still emit a payload accepted by `resume_schema`.
## Non-Goals
- New interrupt execution semantics.
- Multi-user approval workflow.
- Authentication, authorization, or audit identity.
- Scheduling or event-triggered resumes.
- A full JSON Schema UI standard.
- Semantic compatibility analysis between schema revisions.
- LangGraph API compatibility.
## Implementation Slices
1. Extend core models and persistence-safe serialization.
2. Validate request and resume schemas using the existing schema validation
library path.
3. Carry interrupt schemas and outcomes into `InterruptRequest` and
`workflow.runs.inspect`.
4. Validate resume payloads before state mutation.
5. Add authoring/builder helpers and schema discovery output.
6. Update CLI docs, skills, and examples.
7. Add the `issue_review` interrupt to the prepared `lda.chat` report workflow.
## Test Plan
- Core model accepts explicit schemas and defaults legacy nodes.
- Invalid interrupt schemas are rejected by workflow validation.
- Runtime validates a request payload before persisting interruption.
- Resume rejects invalid payloads without mutating run state.
- Resume rejects unknown outcomes before mutating run state.
- `workflow.runs.inspect` includes schemas, outcomes, typed flag, and payload.
- JSON-RPC and CLI resume return structured errors for invalid payloads.
- Draft/raw-plan compilation preserves interrupt schemas.
- Builder/Pydantic convenience emits plain JSON Schema in saved workflows.
## Success Criteria
The contract is complete when an external client can inspect an interrupted run,
render a correct form, submit a valid resume payload, and explain invalid
responses without reading workflow source code or hard-coding that workflow's
interrupt shape.
@@ -0,0 +1,428 @@
# Workflow Console, Agent Demo, And Defense Presentation
Date: 2026-07-01
Status: Approved direction. Implementation is split into prerequisite slices.
Related:
- [Current roadmap](../../current_roadmap.md)
- [Workflow API architecture](../../wf_api_architecture.md)
- [Persisted run/resume contract](2026-06-03-persisted-run-resume-contract.md)
- [Self-describing interrupt contracts](2026-07-01-self-describing-interrupt-contracts.md)
- [Thesis system design](../../thesis/system-design-implementation.md)
## Purpose
Build one local-first web application that serves three related needs:
1. a reusable Workflow Console for inspecting a running `wf` JSON-RPC server;
2. a reliable defense demonstration of the complete workflow lifecycle;
3. a compact thesis presentation with live-demo and recorded-replay routes.
The application also demonstrates where an agent belongs in the product. A
constrained agent translates a natural-language request into typed parameters
for a prepared recipe. The workflow substrate remains responsible for drafts,
artifacts, deployments, runs, interrupts, traces, validation, and source
bindings.
The demo agent is an integration client, not new evidence for general agent
planning ability. The audited challenge campaign remains the evidence for how
generic external agents interact with the public product surface.
## Product Boundary
Create a top-level `web/` package rather than putting product code under
`docs/presentation/`.
```text
web/
package.json
astro.config.mjs
src/
pages/
connect.astro
console/
demo/
replay/
presentation/
appendix/
components/
agent/
lifecycle/
rpc/
trace/
workflow-graph/
presentation/
```
The first release is a local-development Workflow Console. It is not a
production admin panel and does not claim authentication, authorization,
multi-user administration, or safe access to arbitrary remote servers.
## System Architecture
```mermaid
flowchart TB
Browser[Astro and React UI]
Routes[Astro server routes]
Agent[DemoAgent service]
Recipe[Prepared ReportRecipe]
Job[LifecycleJob service]
Rpc[WorkflowRpc service]
Server[wf JSON-RPC server]
Events[Job event stream]
Browser --> Routes
Routes --> Agent
Routes --> Job
Agent --> Recipe
Recipe --> Job
Job --> Rpc
Rpc --> Server
Job --> Events
Events --> Browser
```
All workflow operations use the existing public JSON-RPC API. No Python-side
demo endpoint, direct store mutation, or privileged workflow path is added.
The web app should not shell out to `wf` for normal operation. The CLI is an
operator frontend: it resolves config, parses files and flags, formats output,
and sometimes aggregates several calls for human convenience. The console needs
the lower-level JSON-RPC request/response stream so it can show exact protocol
evidence, avoid shell quoting and encoding failures, and keep raw calls aligned
with interpreted UI state.
## TypeScript And Effect Boundary
Use Effect for server-side orchestration and protocol handling:
- `Schema` decodes JSON-RPC envelopes and selected result projections;
- services and `Layer`s provide connection configuration, RPC, recipes, jobs,
replay storage, and the model gateway;
- tagged errors distinguish connection, protocol, decoding, workflow,
timeout, and demo-state failures;
- `SubscriptionRef` or `Stream` publishes lifecycle events;
- scoped fibers run and cancel autoplay;
- timeouts and retries apply only where semantically safe.
Do not spread Effect through every React component. React components consume
ordinary view models and event streams. Astro route handlers are the
`Effect.runPromise` boundary.
Mutation calls such as artifact creation, deployment saving, run start, and
resume are never retried blindly. Health and idempotent read calls may use a
small bounded retry policy.
## Connection Model
The connection page accepts a JSON-RPC URL such as
`http://127.0.0.1:8765/rpc`.
1. The Astro server validates the URL.
2. The first slice accepts only loopback hosts.
3. `workflow.health` verifies the endpoint.
4. The connection is retained for the browser session.
5. Astro proxies JSON-RPC calls server-side to avoid browser CORS coupling.
6. Every call records its raw request, raw response, interpreted result,
duration, and equivalent CLI command.
Allowing arbitrary remote targets would turn the proxy into an SSRF surface and
requires a separate security design.
## JSON-RPC Method Registry
Represent mapped operations declaratively. Each entry contains:
- JSON-RPC method name;
- Effect schema for parameters and selected result fields;
- human explanation;
- equivalent CLI formatter;
- interpretation function;
- mutation/idempotency classification.
The initial read surface maps:
- `workflow.health`;
- source list, inspect, and diagnose;
- capability list and inspect;
- draft-workspace list, get, validate, and compile;
- artifact list and inspect;
- deployment list, inspect, and validate;
- run list, inspect, and trace.
The prepared demo additionally maps:
- draft-workspace create from capability and patch;
- draft validation and compilation;
- artifact creation from a workspace;
- deployment save and validation;
- run start, inspect, trace, and resume.
Mapping a method does not grant special authority. The Workflow Console and the
prepared demo are ordinary users of the same registry.
## Workflow Console
The first console is read/inspect-focused. It provides:
- source and capability inventory;
- draft workspace list, graph, revision, and diagnostics;
- artifact versions and required source bindings;
- deployment binding and readiness state;
- run status, output, interrupt, and bounded trace;
- raw JSON-RPC request/response drawers.
Generic visual workflow editing is not part of the first initiative. The
prepared demo performs controlled mutations through the same public RPC
registry. A future editor can reuse the graph and inspector components.
## Visual Interaction Model
The UI uses focus modes instead of showing every panel simultaneously:
- **Lifecycle:** Draft, Artifact, Deployment, Run, and Trace records.
- **Graph:** interactive workflow graph with semantic zoom.
- **Execution:** active nodes and trace progression over the same graph.
- **Output:** rendered readiness report and created issues.
- **Raw:** collapsible JSON-RPC request and response drawer.
Use an interactive graph component, expected to be `@xyflow/react`, inside an
Astro React island. Static presentation diagrams remain Mermaid.
A small graph embedded in a lifecycle card can expand into the primary canvas.
Selecting a node opens a side drawer with capability, source, bindings,
outcomes, and trace data. Selecting a lifecycle record zooms back out.
## Lifecycle Job And Autoplay
The agent calls one macro tool. The macro creates a lifecycle job and returns a
job id. The TypeScript job then executes public JSON-RPC operations.
```mermaid
sequenceDiagram
actor User
participant Agent
participant Macro as create_workspace_report
participant Job as LifecycleJob
participant RPC as Workflow JSON-RPC
participant UI
User->>Agent: Request readiness report
Agent->>Macro: Typed recipe parameters
Macro->>Job: Create operation queue
Macro-->>Agent: job id accepted
Job-->>UI: Switch to lifecycle view
loop Autoplay operations
Job->>RPC: Execute next public operation
RPC-->>Job: Raw result
Job-->>UI: Event, reason, raw data, interpreted data
end
Job-->>UI: Pause for typed approval
User->>Job: Approve selected issues
Job->>RPC: Resume run
RPC-->>Job: Final report and trace
Job-->>Agent: Structured completion result
Agent-->>User: Summarize result
```
Autoplay:
- advances one operation at a time;
- allows Pause and Next;
- pauses automatically on errors, interrupts, and completion;
- never approves a human interrupt automatically;
- supports no backward step in live mode;
- supports previous, next, and timeline scrubbing in replay mode.
The chat collapses while the lifecycle and graph views carry the operation. It
returns after completion, when the agent summarizes the structured result.
## Attribution And Honesty
The UI distinguishes agent activity from orchestration activity.
- Agent card: `create_workspace_report({...})`.
- Orchestrator card: concrete JSON-RPC method, reason, equivalent CLI, raw
response, and interpreted result.
Do not present orchestrated sub-operations as independent agent tool calls. Do
not present recorded text as a live model response. Replay mode is visibly
labeled.
## Demo Agent
The agent is intentionally constrained:
- one prepared report recipe;
- typed recipe parameters;
- one macro tool;
- no shell, repository reads, code search, or subagents;
- bounded output and timeout;
- replaceable model gateway;
- recorded replay fallback.
The first model gateway may use the OpenCode API directly, but the application
depends only on a `DemoAgent` service contract. Exact provider selection belongs
to the agent-integration slice.
The demo agent is not compared with the benchmark agents. Benchmark agents test
public-surface discovery and free-form operation; the demo agent illustrates a
product integration built on that surface.
## Prepared `lda.chat` Report Workflow
Create a separate example rather than expanding the existing minimal report
case study:
```text
examples/lda_report_workflow/
documents/
project-brief.md
architecture-notes.md
evaluation-findings.md
risk-register.md
roadmap.md
document_source.py
report_source.py
issue_board_source.py
workflow.plan.json
run-input.json
wf.config.json
```
Python sources:
- `local.lda_docs`: list and read deterministic project documents;
- `local.lda_report`: analyse documents, combine findings, classify risks,
render, and finalise the report;
- `local.issue_board`: create, list, and reset local demo issues.
The issue board is JSON-backed with atomic writes. It is a deterministic local
demo source, not a production tracker.
Workflow shape:
```mermaid
flowchart TB
List[List lda.chat documents]
Each{For each document}
Analyse[Analyse document]
Combine[Combine findings]
Risks{Material risks found?}
RiskSection[Build risk section]
NoRisks[Record no material risks]
Render[Render readiness report]
Review[Typed issue-review interrupt]
Selected{For each selected issue}
Create[Create issue]
Finalise[Finalise report]
Revision[Record revision request]
List --> Each
Each -->|loop| Analyse
Analyse --> Each
Each -->|done| Combine
Combine --> Risks
Risks -->|yes| RiskSection
Risks -->|no| NoRisks
RiskSection --> Render
NoRisks --> Render
Render --> Review
Review -->|submitted| Selected
Review -->|cancelled| Revision
Selected -->|loop| Create
Create --> Selected
Selected -->|done| Finalise
```
The report is titled **lda.chat Thesis And Project Readiness Report** and covers
achievements, architecture status, evaluation evidence, material risks, and
next actions.
The interrupt request includes the rendered report and proposed issues. The
resume payload contains approval, selected issue ids, and an optional comment.
The UI selects all issues by default and allows individual deselection.
## Self-Describing Interrupt Dependency
The current interrupt payload exposes `kind` and data but not a complete
machine-readable response contract. The Workflow Console requires explicit
request and resume schemas so it can render and validate arbitrary interrupts
without reading workflow code.
The prerequisite contract is defined in
[Self-describing interrupt contracts](2026-07-01-self-describing-interrupt-contracts.md).
## Replay And Failure Handling
Every lifecycle event envelope records:
- operation id and stage;
- JSON-RPC method and parameters;
- raw response or error;
- interpreted result;
- equivalent CLI;
- reason and duration;
- resulting lifecycle ids.
Recorded mode replays these same envelopes. Live failure offers a visible switch
to the matching recording. The presentation does not restart in a different UI
or hide the failure.
## Defense Presentation
The defense has 15 minutes of presentation and 15 minutes of questions. Target
9-10 slides and no more than three minutes of live demo.
Routes:
- `/presentation`: primary slides;
- `/demo`: live agent and lifecycle presenter;
- `/replay`: recorded fallback;
- `/appendix`: backup architecture, evaluation, and implementation slides.
The presentation transitions directly into the demo and back. The exact slide
library is selected in the presentation slice; the route and shared component
boundaries are fixed by this design.
## Implementation Order
1. Self-describing interrupt request/resume contracts.
2. Deterministic `lda.chat` report workflow and Python sources.
3. `web/` Astro and Effect foundation, connection flow, and RPC registry.
4. Workflow Console read/inspect views, graph, trace, and raw drawers.
5. Lifecycle job, autoplay, typed approval, issue board, and replay.
6. Constrained demo agent and replaceable model gateway.
7. Defense presentation and appendix routes.
Each slice gets its own executable implementation plan. Do not combine the
Python contract change, web foundation, agent integration, and presentation
into one implementation pass.
## Non-Goals
- Production authentication or authorization.
- Arbitrary remote RPC proxying.
- A general visual workflow editor.
- Scheduling or event triggers.
- Google Drive, email, or other external service dependencies.
- Free-form autonomous workflow synthesis in the live defense demo.
- Treating the demo agent as benchmark evidence.
## Success Criteria
The initiative is complete when:
1. a local user can connect the console to a loopback workflow RPC server;
2. lifecycle records and traces are readable without scrolling raw JSON;
3. raw request/response evidence remains available beside interpretation;
4. the prepared recipe runs through draft, artifact, deployment, run,
interrupt, resume, issue creation, output, and trace;
5. interrupt forms are generated from public contracts;
6. live and replay modes render the same event model;
7. the constrained agent invokes one macro tool and receives the final result;
8. the three-minute demo has a tested replay fallback;
9. the presentation explains the agent/substrate boundary without overstating
autonomous planning.
+51 -30
View File
@@ -114,9 +114,10 @@ workflows as outcome-routed graphs and manages them through a
Draft--Artifact--Deployment--Run lifecycle. A neutral source-provider boundary
projects built-in, Model Context Protocol, and Python capabilities into the same
workflow surface, while structured diagnostics and repair guidance support
agent-operable authoring through CLI and JSON-RPC interfaces. Here, "AI Agent"
names the agent-facing project context; the submitted implementation is the
workflow substrate exposed to external agents.
agent-operable authoring through CLI and JSON-RPC interfaces. An external agent
interface can be layered over these operations; this thesis focuses on the
lower-level substrate that makes such an interface useful rather than proposing
a new autonomous planning algorithm.
The implementation is evaluated through automated conformance tests, a
deterministic three-node report workflow, a browser-interaction workflow, and a
@@ -140,13 +141,14 @@ comparison.
# Introduction
In the thesis title, "AI Agent" refers to the broader `lda.chat`
agent-facing automation project. The submitted implementation focuses on the
workflow substrate that such agents use: a typed runtime and lifecycle layer
exposed through CLI and API surfaces. Experimental agent-harness work exists in
adjacent project work, but it is outside the submitted implementation boundary;
this report evaluates the substrate rather than claiming a production
autonomous agent brain.
`lda.chat` is positioned as an AI-agent-facing workflow platform. An agent
interface can be implemented as a surrounding layer that combines a chat or web
front end, a planner graph, and `wf` CLI/API operations exposed as tools. This
thesis focuses on the workflow substrate beneath that layer: typed lifecycle
records, source bindings, validation, execution, diagnostics, traces, and
resumability boundaries. The contribution is therefore the infrastructure that
lets external agents and human operators create reusable workspace workflows,
not a new autonomous planning algorithm.
This report assumes a setting in which external LLM agents are used as workflow
authors and operators, and asks what platform substrate they need for reusable
@@ -172,7 +174,7 @@ Python source examples.
**Scope of claims.** This report does not claim production security, broad or
representative external-agent evaluation, arbitrary mid-node crash recovery,
scheduling, role-based access control, general workflow parallelism, or a
bundled autonomous agent brain. It reports a bounded, manually audited
bundled autonomous planning layer. It reports a bounded, manually audited
36-trial agent-operability campaign. Claims about planner efficiency remain
design hypotheses: the campaign was not a controlled retry-reduction or token
efficiency experiment.
@@ -787,10 +789,13 @@ The implementation is organized into focused packages with clear boundaries:
| `wf_platform` | Neutral source DTOs, source visibility, permission metadata, and policy |
| `wf_artifacts` | Artifact, deployment, and run models; file-backed stores; validation |
| `wf_api` | Application surface: capabilities, drafts, artifacts, deployments, runs |
| `wf_config` | Neutral workflow configuration models and config loading |
| `wf_server` | `WorkflowServer` composition from config, stores, and source providers |
| `wf_transport_rpc_http` | JSON-RPC over HTTP transport for CLI and future clients |
| `wf_mcp` | Legacy MCP frontend, broker/admin compatibility, and migration shims |
| `wf_sources_mcp` | MCP upstream source implementation and persistent runtime pool |
| `wf_sources_python` | Trusted in-process Python source loading and `NodeSpec`-to-`NodeDef` projection |
| `wf_openapi` | Experimental OpenAPI source provider for typed HTTP operations |
| `wf_cli` | CLI commands driving the JSON-RPC transport |
: Package responsibilities in the implementation. {#tbl:package-responsibilities}
@@ -1034,6 +1039,16 @@ core provider-agnostic.
(Evidence: `src/wf_sources_python/`, `tests/wf_sources_python/test_loader.py`.)
## Experimental OpenAPI Source Provider
The repository also contains an experimental `wf_openapi` source provider. It
parses OpenAPI documents, projects HTTP operations into typed `NodeSpec`
contracts, and executes calls through HTTP request/response validation. This
shows the provider boundary can extend beyond MCP and trusted Python sources,
but it is not used by the thesis case study or agent challenge evaluation.
(Evidence: `src/wf_openapi/`, `tests/openapi/`.)
# Case Study: Deterministic Report Workflow
The thesis case study is a document/report preparation workflow backed by local
@@ -1145,13 +1160,14 @@ wf draft create report_ws --capability local.report.extract_report
That command is intentionally a best-effort bootstrap, not a complete workflow
synthesizer. Focused edit commands such as `wf draft set-name`,
`wf draft set-input`, and `wf draft set-output` cover common schema and mapping
edits without forcing an agent to write RFC 6902 JSON Patch by hand. Structural
edits to an existing draft, such as adding `read_notes` before `extract_report`
and `render_markdown_report` after it, still use `wf draft patch`. The
raw-plan import path is the alternative route when the author already has a
complete plan: it bypasses the draft workspace and creates the artifact
directly.
`wf draft set-input`, `wf draft set-output`, `wf draft bind`,
`wf draft add-step`, `wf draft branch`, `wf draft handle`, and
`wf draft set-workflow-output` cover common schema, mapping, step, and routing
edits without forcing an agent to write RFC 6902 JSON Patch by hand. Raw
`wf draft patch` remains the escape hatch for structural edits that focused
commands do not yet cover. The raw-plan import path is the alternative route
when the author already has a complete plan: it bypasses the draft workspace
and creates the artifact directly.
The tested thesis path imports the complete three-node plan as an immutable
artifact:
@@ -1627,8 +1643,9 @@ deployment concerns beyond the controlled system-design evidence in this report.
- **No visual workflow editor.** The platform is driven through CLI and API
surfaces; no graphical editor exists yet.
- **No bundled autonomous agent brain.** The platform serves external agents;
it does not include a built-in agent.
- **External planner boundary.** The platform serves external agents through
public workflow operations; an integrated autonomous planning layer is not
part of the current prototype.
- **No general fork/gather.** Fork and gather workflow control is future work.
@@ -1660,17 +1677,19 @@ operational foundation or expands its feature scope.
## Longer-Term Capability Expansion
- **OpenAPI or fetch-style source provider.** Broader HTTP integration through
a new source family, complementing MCP and Python sources.
- **OpenAPI or fetch-style source provider stabilization.** The repository has
an experimental OpenAPI source family; future work is hardening, operator
documentation, auth integration, and broader HTTP coverage rather than the
first proof of concept.
- **LLM nodes as typed source capabilities.** LLM calls exposed as
`NodeSpec` contracts, allowing planners to compose LLM steps into workflows
without making the core runtime model-aware.
- **Integrated agent harness.** Adjacent experimental work can be integrated
once the substrate boundary is stable. That future layer would provide the
autonomous planning loop that drives the workflow lifecycle; it remains
outside the implementation and evidence claims of this report.
- **Agent interface and planner loop.** Add a surrounding layer that combines a
chat or web interface, a planner graph, and `wf` operations exposed as tools.
This layer can drive the implemented workflow lifecycle without moving
planning logic into the core runtime.
- **Scheduler and daemon operations.** Offline scheduling for deployments,
cron-triggered runs, and server daemon lifecycle.
@@ -1714,8 +1733,8 @@ demonstrates the architecture; the thesis contribution is the platform design
and evidence that the design can work across multiple source families under
controlled conditions. The implemented contribution is therefore the durable,
typed workflow substrate required by an agent-facing automation system; the
autonomous planning layer remains outside the submitted implementation
boundary.
agent interface and autonomous planning loop can be layered over it as future
work.
<!-- References -->
# References {#sec:refs .unnumbered}
@@ -1786,8 +1805,10 @@ draft set-output report_ws --revision 3 --step call `
--map title=state.title --map summary=state.summary
```
Structural edits, such as adding `read_notes` before `extract_report` and
`render_markdown_report` after it, use `draft patch` or a complete raw plan.
For structural growth, prefer focused helpers such as `draft add-step`,
`draft branch`, `draft handle`, and `draft bind` when they cover the intended
edit. Use `draft patch` only as the low-level fallback, or import a complete
raw plan when the full graph is already available.
## Draft Validation
-2
View File
@@ -37,8 +37,6 @@
{\Large\bfseries Design and Implementation of lda.chat:\par}
\vspace{0.18cm}
{\Large\bfseries An AI Agent for Automating and Creating Workspace Workflows\par}
\vspace{0.45cm}
{\small\itshape Implementation boundary: this thesis evaluates the workflow substrate used by external agents, not a bundled autonomous agent brain.\par}
\vfill
\begin{tabular}{@{}r@{\hspace{0.5em}}l@{}}
External Supervisor: & \textbf{Eng. Trần Văn Trường}\\
+8
View File
@@ -43,6 +43,7 @@ Examples that belong in `wf_api`:
`WorkflowRunSurface`
- `WorkflowCapabilityApi`
- `WorkflowDraftApi`
- `WorkflowDraftAuthoringApi`
- `WorkflowArtifactApi`
- `WorkflowDeploymentApi`
- `WorkflowRunApi`
@@ -154,6 +155,7 @@ contract itself.
WorkflowApi
capabilities: WorkflowCapabilityApi
drafts: WorkflowDraftApi
draft_authoring: WorkflowDraftAuthoringApi
artifacts: WorkflowArtifactApi
deployments: WorkflowDeploymentApi
runs: WorkflowRunApi
@@ -164,6 +166,12 @@ they define application-facing response contracts consumed by multiple
frontends. Internally, they should prefer typed models from `wf_core`,
`wf_artifacts`, and `wf_platform`, then serialize at the boundary.
`WorkflowDraftApi` owns draft workspace lifecycle, validation, compilation,
JSON Patch application, and focused low-level map edits. `WorkflowDraftAuthoringApi`
is the semantic authoring layer above it: capability-aware bootstrap, bind,
add-step, branch, handle, and remove helpers lower intent into ordinary draft
workspace patches while preserving revision checks.
## Relationship To wf_core
`wf_core` is lower-level than `wf_api`.