Design document — draft, July 2026
Contents:
- Overview
- Components
- Drafting Table
- Specification Toolkit
- Kits
ears-manager- WMS Adapter
- Source Control Manager
- Content Storage Model
- Validation Rules
- Job Site
- Cross-Cutting Concerns
- Related Documents
This document identifies the major system components that ProtoBot needs to be built from, and the interfaces between them. The goal is to drive design decisions about what to build, what to reuse, and where the hard integration problems are.
For the user-facing flow and phase details, see user-interaction-flow.md.
flowchart LR
User["Human"]
subgraph ProtoBot["ProtoBot"]
DT["Drafting Table"]
Toolkit["Specification Toolkit"]
Kits["Kits"]
EM["ears-manager"]
WMSA["WMS Adapter"]
SCM["Source Control Manager"]
Valid["Validation Rules"]
JS["Job Site"]
end
subgraph ProjectSystems["Project systems"]
Repo["Canonical project repo"]
WMS["Selected WMS backend"]
end
User <--> DT
Toolkit -. "loads into" .-> DT
Kits -. "imported through" .-> DT
Valid -. "workflow rules" .-> DT
Valid -. "transition rules" .-> WMSA
Valid -. "workflow rules" .-> JS
DT <--> EM
DT <--> WMSA
DT <--> SCM
JS <--> EM
JS <--> WMSA
JS -. "merge commit (read)" .-> SCM
SCM -. "reads" .-> EM
SCM -->|"branches / commits / PRs"| Repo
EM <-->|"registered specifications"| Repo
JS <-->|"source / patches / merges"| Repo
WMSA <--> WMS
This diagram intentionally stops at component boundaries. The Job Site's control plane, isolated execution domains, and external runtime services are shown in Job Site.
ProtoBot has eight primary logical components and reusable asset families:
- Drafting Table — The environment where the human and an AI agent collaborate during Sketching and Dimensioning. It combines a frontend (web UI or TUI) with an agent harness that runs the specification work. Different Drafting Table implementations can be swapped in; what they share is the Specification Toolkit, the Validation Rules, the WMS Adapter API, and the Source Control Manager.
- Specification Toolkit — The portable set of skills, tools, and prompts that encode how to do Sketching and Dimensioning. Shared across all Drafting Table implementations — it's the domain logic that makes any compatible harness capable of driving the specification process.
- Kits — Versioned imports that currently provide proposed EARS/interface content and Inspector definitions. Exact packaging and additional capabilities remain open.
ears-manager— A CLI tool that is the programmatic interface to the specification store. Manages the file-based spec database (EARS requirements, interfaces, change sets), enforces EARS formatting rules, and validates referential integrity. Used by agents via the Specification Toolkit, by CI for verification, by humans directly, and read by the Source Control Manager.- WMS Adapter — A thin, pluggable integration layer over the chosen work management backend (GitHub Issues/Projects, GitLab, Jira, Beads, Trello). Translates ProtoBot's work item model to/from the backend's native concepts. One implementation is active per project. Backend translators remain deliberately thin; the stable API boundary uses shared Validation Rules to enforce atomic lifecycle transitions.
- Source Control Manager (SCM) — The deterministic component that
turns the user's decision about a governed object into Git and Git
host state: commits, pushes, pull requests, refresh merges, and the
initialization branch. The Drafting Table is designed to reach Git
and the Git host only through it, apart from the change-set branch
that
ears-manager change-set createcuts (change-set create); the guard enforces this on the calls it checks (Permitted Git operations). The Job Site reads approved merge commits through the SCM. It never decides content. - Validation Rules — Domain logic that enforces well-formedness
on work item state transitions. Shared across the Drafting
Table and the Job Site — both use these rules when writing to the
WMS. Not a running service; the MVP uses a versioned declarative
ruleset and deterministic evaluator.
(Spec-level validation — EARS formatting, referential integrity —
is handled by
ears-manager, not here.) - Job Site — The autonomous execution engine that runs Workers and Inspectors to turn approved requirements into working, tested prototypes. Its control plane materializes complete work-item contracts and dispatches them by pulling ready items from the WMS when execution capacity is available.
The Drafting Table is where the human sits down with an AI agent to do the architectural and specification work — Sketching (Phase 1) and Dimensioning (Phase 2). It is also where the user receives notifications about blocked work items and resolves them.
A Drafting Table implementation consists of two parts: a frontend (what the user sees and interacts with) and an agent harness (what runs the model, executes tools, manages the conversation). Different implementations provide both parts together, but all load the same Specification Toolkit and talk to the same WMS API and the same Source Control Manager.
Web Drafting Table — A web application similar to IdeaBot. The frontend is a browser-based UI; the harness is a hosted agent runtime running server-side. This is the natural choice when the user wants persistent access, push notifications for blocked work items, and no local setup.
- Provides its own agent harness (hosted runtime).
- Can push notifications to the user (blocked work items, Job Site status updates) at any time via the persistent browser connection.
- Needs a deployment target (cluster or hosted service).
TUI Drafting Table — A terminal-based interface using an existing coding agent like OpenCode or Claude Code as the harness. The user launches it locally; the harness runs on their machine and connects to the WMS via MCP or API, and to a local Source Control Manager via MCP.
- The harness already exists (OpenCode, Claude Code, etc.) — the Drafting Table is the Specification Toolkit loaded into it plus WMS and Source Control Manager connectivity.
- Blocked-work notifications use a pull model: on session start, the harness checks the WMS for blocked items and presents them. ("You have 2 work items blocked on undefined behavior — resolve now or continue with other work?")
- For urgency between sessions, external notification channels (email, Slack) can alert the user that something needs attention. The TUI itself doesn't need to be the notification mechanism.
- Any coding-agent harness can host the TUI Drafting Table through a harness binding. The shared adapter core — a manifest, the Drafting Table role, the permitted shell operations, and one guard command that bindings wire into the pre-tool-call path as an optional early layer — is defined in Agent Harness Adapter Contract. Each binding records its per-call hook failure behavior; a hook that does not run can leave guard-only checks unenforced. The first bindings are OpenCode, Claude Code, and Codex.
- Host the conversational interaction between user and agent during Sketching (producing the Sketch: Vision + Architecture) and Dimensioning (producing the Schematic: approved EARS requirements).
- Present the agent's gap-closing suggestions and allow the user to accept, modify, or reject them.
- Surface blocked work items from the WMS and let the user resolve them (add a requirement or approve an out-of-scope declaration).
- Display work item status from the WMS so the user has visibility into what the Job Site is doing.
- To WMS Adapter (via API/MCP): Reads build work-item state for display, queries blocked items, and submits reviewed resolution or change-set references. The Materializer validates those inputs and performs the expected-state transition during contract refresh.
- To
ears-manager: Reads and writes every registered specification artifact, including Vision/Architecture prose and external interface IDLs. The Drafting Table is not meant to edit spec files directly; the guard refuses such edits on the calls it checks, and what a call without a guard decision can still do is stated in What the harness layer stops. - To Source Control Manager (via MCP): Reads repository state,
commits, pushes, and opens PRs containing artifacts produced through
ears-manager, through the SCM's Drafting Table face (Source Control Manager). The Drafting Table is given no Git or Git host command of its own; the guard refuses them on the calls it checks, and what still blocks them on a call without a guard decision is stated per binding in Permitted Git operations. Branch naming, commit content, PR preparation, and the permitted Git operations are defined in Git and Project-Repository Integration. - To User: Conversational interface for Sketching and Dimensioning. Displays Job Site progress/status. Surfaces blocked work items.
- From IdeaBot: Receives IdeaBot output as input to Sketching (handoff format is an open question Q4).
- Async escalation UX. The web implementation can push; the TUI MVP pulls on session start or resume, which is sufficient for that local contract. Which external channel (email, Slack, webhook, or web push) hosted deployments require remains open. See open question Q2.
- Session continuity across implementations. A user might start Dimensioning in the TUI and continue in the web UI (or vice versa). The TUI MVP resumes from the proposed change set and specification state on its Git branch plus WMS records and pointers; conversation history is not authoritative or required. Whether a web implementation additionally transfers optional conversation context remains open.
The decided MVP gap-surfacing and interface-ordering semantics are in the Drafting Table UX.
The Specification Toolkit is the portable domain logic that any Drafting Table implementation loads to become capable of driving Sketching and Dimensioning. It is not a running service — it is a shared asset consumed by the agent harness.
- Skills — Structured instructions for the agent: how to conduct a Sketching session (elicit Vision, enumerate interfaces, identify interface types), how to conduct Dimensioning (translate Architecture into EARS requirements, surface spec gaps, handle each EARS pattern type).
- Tool definitions — MCP tool schemas for interacting with the
WMS Adapter (creating/reading/updating work items, querying blocked
items) and with the Source Control Manager's Drafting Table face
(repository state, the initialization branch, resume, commit,
publish, and refresh).
ears-manageris a CLI that the agent runs through the harness's shell tool; the skills describe its commands (adding, listing, and validating specifications on the active change-set or build-work-item branch). - Prompts — System prompts, templates, and reference material: EARS pattern definitions, the interface-type taxonomy, the undesired-behavior taxonomy, gap-closing heuristics, the specification hierarchy (Vision → Architecture → Interface → Requirement), and change-set impact analysis.
The repository packages eliciting-requirements as a general-purpose,
host-independent EARS capability under .agents/skills/. ProtoBot uses this
capability during Dimensioning, but it is broader than ProtoBot and does not
own ProtoBot storage, change sets, approval, or lifecycle behavior. The same
repository path contains process skills such as pull-request, rebase-pr,
and review-pr; those are maintenance tooling, not Toolkit domain content.
The Toolkit also packages drafting-specifications as the ProtoBot session
protocol: it coordinates start/resume, review checkpoints, and the mapping from
accepted elicitation candidates to governed operations. It is separate from
eliciting-requirements, which remains host-independent, and from repository
process skills, which are not Toolkit capabilities. The protocol names
ears-manager, the WMS Adapter, and the Source Control Manager as distinct
boundaries; it owns no persistent store and names no harness-specific tool or
configuration. The same protocol is loaded by single-player and multi-player
TUI bindings and the hosted Web runtime; each deployment retains its own
session and credential-isolation boundary. The Toolkit holds no downstream
credential or authoritative session state.
The final cross-harness packaging boundary remains an open question: the
.agents/skills/ layout is shared by current bindings, while distribution to
projects outside the ProtoBot repository and Toolkit versioning remain open.
- Harness-agnostic. The toolkit must work in any compatible agent harness — OpenCode, Claude Code, a hosted web runtime, or future harnesses. This means no dependencies on harness-specific APIs beyond standard tool execution and prompt loading.
- Three runtime service dependencies: WMS Adapter,
ears-manager, and the Source Control Manager. Work item lifecycle state lives in the WMS backend (via the adapter). Specification content lives in the project's git repo (on contributor or change-set branches before approval and build-work-item branches during execution), accessed exclusively throughears-manager. Commits, pushes, PRs, refresh merges, and the initialization branch are made through the SCM;ears-manager change-set createcuts change-set branches (change-set create). The toolkit does not maintain its own state store. - Versioned and testable. The toolkit should be versioned alongside the WMS Adapter API and the Source Control Manager's tool and result schema it targets. Changes to EARS patterns, gap-closing heuristics, or the specification hierarchy should be testable independently of any particular Drafting Table implementation.
- To agent harness: Versioned skills/prompts plus standard tool definitions; no harness-specific state API is required.
- To WMS Adapter: Request/work-item queries, expected-version transitions, blocked-work resolution, and status display.
- To
ears-manager: All registered specification reads/writes, comparison, impact analysis, and validation. - To Source Control Manager: Repository state, commits, pushes, PRs, and refresh for the current change set.
- From Kits/project policy: Reviewed Inspector/spec imports and policy context; the Toolkit does not activate remote content implicitly.
- Toolkit packaging format. What does the toolkit look like on
disk? A directory of markdown skills + JSON tool schemas (like
OpenCode's skill system)? A plugin/extension package? The answer
depends partly on what the target harnesses support. The on-disk
half is resolved for every harness:
Agent Harness Adapter Contract
decides skills as
<name>/SKILL.mddirectories under.agents/skills/and tool definitions as MCP servers. Still open: how the toolkit reaches a project other than ProtoBot, and how it is versioned. - Tool surface split. The toolkit reaches three systems: the WMS
Adapter through MCP tools (work item lifecycle CRUD and queries),
the spec store through the
ears-managerCLI, which the skills describe and the agent runs through the harness's shell tool, and Git and the Git host through the Source Control Manager's MCP tools. The WMS Adapter tools handle work item lifecycle;ears-managerhandles all spec read/write operations and cuts change-set branches; the SCM handles commits, pushes, PRs, refresh merges, and the initialization branch. The agent should not need to manipulate spec files or run Git directly. Whetherears-manageralso moves to tools, so that the role needs no shell at all, is open with #30.
A Kit is a reusable, versioned import for a standard project concern, such as Python conventions, Kubernetes deployment, CI, or packaging. The exact package format and full capability model are intentionally open until ProtoBot has implementation experience.
The currently established Kit contents are:
- EARS/interface content: proposed interface definitions and requirements for the concern; and
- Inspector definitions: specialist Inspectors and activation rules relevant to that concern.
Importing a Kit never changes an approved project implicitly. EARS and interface content becomes a normal proposed change set with provenance and human review. Inspector definitions become a proposed project-policy change; activation is visible and reviewable. An upgrade is another explicit diff, not an in-place remote update.
Projects may use ProtoBot-provided, organization-provided, or project-local Kits. Every import records source, version, digest, and provenance in the project control namespace. Whether Kits also package agent skills, projection defaults, build/test conventions, mutation operators, or internal test controls remains an open question. No Kit may broaden sandbox, credential, network, or repository permissions without a separate policy review.
- To
ears-manager: Imports EARS/interface content as a proposed change set with Kit provenance. - To project policy: Proposes Inspector definitions/activation rules; project review controls activation.
- To Kit source: Resolves pinned source/version/digest without executing unreviewed content.
- Kit package and trust format. Archive, OCI artifact, git ref, or another format? How are signatures, compatibility, dependencies, and organization trust policy represented?
- Additional modules. Which implementation experience justifies adding skills or execution policy beyond the currently understood EARS/interfaces and Inspector definitions?
ears-manager is a CLI tool that serves as the programmatic
interface to the specification store. It abstracts the underlying
file format (currently one-file-per-record YAML per
ADR-0001),
manages change sets, and enforces EARS methodology rules
deterministically. Semantic impact analysis still requires agent and
human judgment, but its inputs and approved result are structured.
The stable caller boundary is defined in the CLI Integration Contract. This component document describes responsibilities and data ownership; the contract document defines the command grammar, result envelopes, diagnostics, exit statuses, and golden fixture.
It is used by these callers:
- Agents (via the Specification Toolkit) — the Drafting Table
agent calls
ears-manager requirement add,ears-manager interface add, and change-set commands during Dimensioning. The Job Site receives changed and applicable requirement IDs in the build work-item contract and resolves them at its immutable specification commit viaears-manager requirement list/ears-manager requirement show. Workers also receive the full approved Schematic for context. See ongoing obligations and open question Q19. - CI —
ears-manager checkruns on every branch push to validate that spec files are well-formed, all EARS statements match required templates, referential integrity holds, every registered artifact path/canonical-content delta has a matchingartifact_operations[]entry with the sameartifact_idin a proposed change set, every artifact registered on the default branch remains registered, and each proposed change set'sbase_commitmatches the resolved default-branch head. - Job Site Materializer — reads the approved manifest and requirement records at the immutable specification commit recorded in a build work-item contract.
- Source Control Manager — reads a change set's paths, comparison,
impact candidates, and validation result to stage a commit and render
a PR body, and a change set's manifest and status at a commit to
resume its branch and to find its merge commit. It writes nothing
through
ears-manager. - Humans — a developer or architect can run
ears-managerdirectly to inspect or change registered specification artifacts without involving an agent.
- CLI: Stable machine/human command surface used by the Toolkit, Job Site, CI, and maintainers.
- Specification working tree: Registered artifact paths in the current change-set/build branch; no independent service database.
- Git refs (read): The local default branch and the remote-tracking
default branch of each canonical remote, read to tell approved from
proposed change sets
(approval rule)
and to check that each proposed
base_commitequals that default-branch head, and to compare registered artifact paths and canonical content with the default-branch tree for artifact-operation consistency (check);ears-managernever fetches. - Git refs (write):
change-set createcuts and checks out the change-set branch at the local default-branch head, and after a failed write checks the original branch out again and deletes the branch it cut (change-set create). It runs no hook and nofsmonitorprogram. - Validator registry: Code-controlled, extensible format-specific
IDL/prose/schema checks selected by stable names in the artifact registry.
New formats, such as Smithy, add a registry entry and controlled adapter.
An adapter may invoke an approved external tool such as
protocormarkdownlint, but the executable and arguments are fixed in code; caller-supplied commands are never executed. - Outputs: Deterministic structured results, diagnostics, diffs, impact candidates, and non-zero validation status for CI.
The table describes the target ears-manager subcommand surface. EM-04,
EM-05, EM-06, and EM-07 implement a subset; see the
ears-manager CLI first-release
scope.
| Subcommand | Purpose |
|---|---|
ears-manager project init |
Initialize .protobot/project.yaml, seed version-1 schema keys, store paths, store integrity digests, and opaque artifact entries, and write a version-1 .protobot/projection.yaml that classifies the registered specification paths and the configured store directories as shared. It creates no store directory and no artifact content. |
ears-manager check |
Validate all spec files: project configuration and store integrity, projection classification (projection.invalid, projection.unclassified), EARS formatting, required fields, applicability metadata, change-set integrity, referential integrity, registered artifact path/canonical-content deltas against proposed artifact_operations[] (artifact.operation_missing), continued registration of default-branch artifacts (artifact.unregistered), and proposed base_commit freshness against the default-branch head (BASE_NOT_ON_DEFAULT, DEFAULT_MOVED, BASE_COMMIT_STALE). Exit non-zero on failure. Suitable for CI gates. |
ears-manager requirement add |
Add a new EARS requirement with interface or project-wide applicability selectors and optional narrower scopes. Validates the EARS statement and metadata before writing. |
ears-manager requirement list/show |
Read requirements at the working tree or an immutable --at revision. |
ears-manager requirement update/retire |
Modify requirements through a proposed change set. |
ears-manager interface add |
Register a new interface in the Architecture within the active proposed change set. |
ears-manager interface list/show |
Read interfaces at the working tree or an immutable --at revision. |
ears-manager interface update |
Modify interfaces through a proposed change set. |
ears-manager artifact put |
Create/update a registered Vision, Architecture, or external interface-IDL artifact within the active change set. Records kind/path/digest, adds the shared projection entry of a newly registered path, and invokes the selected code-controlled validator adapter without requiring ears-manager to understand every format. |
ears-manager artifact get/list |
Read a registered opaque/prose/IDL artifact by ID or unique kind through the governed path registry. |
ears-manager change-set create/list/show/update |
Create, inspect, and update a proposed change set. Records its base revision, intent, affected scope, requirement operations, and reviewed impact dispositions. EM-04 implemented minimal creation; EM-05 adds list/show/update; #206 adds a show read at an immutable --at revision; EM-07 makes create cut and check out the change-set branch (change-set create). Approved change sets are immutable. |
ears-manager change-set compare |
Compare a proposed change set with the current Schematic and open deltas. Reports exact duplicates, stable-ID changes with optional before and after values, declared conflicts/supersession, and dependency cycles for agent/user review. |
ears-manager impact |
Read-only comparison of a proposed change set with the Schematic that produces potentially applicable requirements from scope intersections and explicit relationships. Reviewed dispositions are written by change-set update. |
- EARS formatting. Each requirement statement must match one of the six EARS patterns (ubiquitous, event-driven, state-driven, unwanted behavior, optional feature, and complex/combined). The tool validates the statement against its declared pattern type via keyword-based regex and rejects text that does not match.
- Required metadata. Each requirement must have a stable ID, at
least one machine-queryable applicability selector, an EARS pattern
type, and provenance. Most selectors name interfaces; project-wide
and environmental requirements use an explicit project selector.
Narrower project-defined capability or resource selectors may refine
either scope. Each requirement also declares a verification mode;
implementation-awarerequires rationale. Missing fields are rejected. Requirements contain no mutable workflow state. - Referential integrity. Requirement applicability metadata
references interfaces defined in the Architecture. Explicit
requirement relationships and change-set references must resolve.
The minimum relationship vocabulary is
depends-on,conflicts-with,supersedes, andrelated-to;depends-onandsupersedesmust be acyclic, and asupersedestarget must be retired. Dangling references are flagged. - Change-set integrity. Change-set manifests have valid base commits, timestamps, operations, retire-target states, and complete mechanical impact assessments while proposed. Approved manifests retain their reviewed historical assessments and are not invalidated by later records.
- Project and repository configuration. Schema versions, configured store paths and integrity digests, canonical remotes, review modes, and branch prefixes are validated before records are trusted.
- Projection classification.
.protobot/projection.yamlmust declareversion: 1and use the manifest format of theears-managerCLI contract; otherwise it isprojection.invalid. Every registered specification path and every configured store directory must be covered asshared; otherwise it isprojection.unclassified. - Artifact governance. Vision, Architecture, interface IDL, and
interface-prose files are registered by kind, path, digest, owner, and
validator. Structured requirement, interface, and change-set records use
the
storesblock, per-store integrity digests, and their ADR-0003 layout. Opaque prose and external IDLs still pass throughears-managerfor change-set membership and path/transaction control; controlled validator adapters invoke approved format-specific tools.checkcompares registered artifact paths and canonical content with the default-branch tree, requires a matchingartifact_idinartifact_operations[]in any proposed change set for a delta, and rejects unregistration. This validates manifest association, not whetherartifact putwas invoked; no other component reimplements the check. - File format consistency.
ears-managerensures one-file-per-record YAML files (ADR-0001) are syntactically valid and follow the expected schema.
A change set is a durable specification transaction, not a permanent owner or grouping of requirements. It is mutable while proposed and immutable after approval. Its machine-readable manifest records:
- the immutable base specification commit and user intent;
- specification operations, including interface/Architecture changes and
requirement operations in the changed set (
add,revise, orretire); - affected interfaces and optional narrower applicability scopes;
- whether implementation work is required, with rationale; and
- the impact assessment, including each candidate's
applicableornot-applicabledisposition, rationale, and whether it was found mechanically or added through semantic review, and the base commit it was recorded against.
ears-manager impact generates a conservative candidate applicable set
from interface and scope intersections plus explicit requirement
relationships. It is deterministic and should prefer false positives to
missed obligations. The Dimensioning agent examines the change
semantically and may add candidates that metadata alone cannot find. A
human approves the changed set and all impact dispositions together.
The CLI returns deterministic candidates without mutating the manifest. The
Toolkit records the complete reviewed set, including semantic additions,
through change-set update; each entry carries a disposition, rationale, and
origin. See the CLI Integration Contract.
Active requirements added or revised by the changed set plus the included
applicable requirements form the binding delivery-obligation set.
Retired requirements remain in the audit delta but are not obligations.
Recording exclusions prevents the same conservative false positives from
being reconsidered without context on every run.
Impact candidate completeness is evaluated only for proposed change sets,
which ears-manager tells from approved ones by its
approval rule. An
approved manifest is
immutable historical evidence; later requirement changes must not invalidate
its stored assessment. Approved-manifest validation checks stored entry
shape and references without recomputing the current candidate set.
An approved change set materializes one build work item by default. If the
approved change set declares implementation_required: false, it records a
durable omitted reservation instead. The materializer reruns deterministic
analysis at the resulting specification commit and creates the item in
blocked if any candidate
lacks a reviewed disposition. The work item freezes the approved changed
and applicable IDs at that commit. Requirements have no lifecycle state
and are never claimed. The work-item contract separately records changed
operations and active delivery obligations.
Future splitting or combining requires a reviewed delivery plan and a
new impact assessment rather than an autonomous regrouping decision.
If an applicable requirement was introduced or revised by another build
work item that has not completed, the new item records a dependency and
cannot dispatch first. When that dependency completes, the materializer
applies every pre-claim eligibility check in the decided contract-refresh
policy. A passing refresh appends the new baseline/contract version and
moves to ready-for-building; a failing refresh remains blocked for an
impact amendment or is superseded. This preserves the
distinction between specification applicability and whether the current
code baseline has evidence of conformance.
The resulting approved commit cannot be embedded in the manifest that it contains. After merge, the WMS records the change-set ID and resulting merge commit as coordination and audit metadata. Together, the manifest's base commit and the WMS merge-commit reference identify the exact before and after specifications and form the materialization idempotency input.
- Deterministic, not AI-driven.
ears-manageris conventional code — a linter/validator/CRUD tool, not an LLM. It enforces rules mechanically. The agent decides what requirements to write;ears-managerensures they're well-formed. - Statically linked Go binary. The
ears-managerexecutable is implemented in Go and has zero runtime dependencies for its core storage and validation behavior. Optional controlled validator adapters may require approved tools such asprotocormarkdownlintin the execution environment; those tools are selected by registry name, never by caller-supplied commands. - Format-agnostic interface. Callers interact via subcommands, not by reading/writing files directly. This means the underlying storage format can change without breaking agents, CI, or human workflows. The initial format is one-file-per-record YAML (ADR-0001).
- Single write gate for specification artifacts. All registered spec
reads/writes go through
ears-manager. It directly understands the requirement/interface registry and delegates validation for opaque prose or external IDLs. No other component modifies spec files directly. This eliminates split transactions and inconsistent artifact ownership without forcing one parser to understand every IDL.
See the CLI Integration Contract for the stable machine-readable and human-readable interface used by all of these callers.
- Spec directory layout. The record format is decided (one file per record, ADR-0001), and the minimum directory hierarchy and filename mapping are defined by ADR-0003.
- Query richness. How far do the resource-specific
listcommands go? Simple filtering (by interface, applicability scope, or pattern type)? Or richer queries like "requirements with no usable scope" or "interfaces with no requirements"? Richer queries make the agent's job easier but increaseears-manager's complexity.
The WMS Adapter is a thin, pluggable integration layer between ProtoBot and the user's chosen work management backend. It is deliberately thin: it translates ProtoBot's work item model to/from the backend's native concepts (issues, cards, tickets) and handles durable, atomic operations. Shared Validation Rules run at its API boundary; the backend-specific translator does not reimplement those rules, determine pipeline routing, or manage dispatch.
One adapter implementation is active per project. Unlike the Drafting Table (where multiple implementations may be used simultaneously — e.g., TUI and web for the same project), the WMS backend is a per-project choice. A project is one prototype/canonical repo; one ProtoBot deployment may host many projects and adapter configurations.
Each adapter maps ProtoBot's build work-item model onto a backend:
| Backend | Native concept | Atomic work-item claim |
|---|---|---|
| GitHub Issues/Projects | One issue per build work item | Conditional state update using an expected version, or an external coordinator if the issue API cannot provide compare-and-swap. Assignment alone is not a claim. |
| GitLab | One issue per build work item | Same contract as GitHub. |
| Jira | One issue per build work item | Conditional transition using issue versioning, or an external coordinator. Assignment alone is not a claim. |
| Beads | One bead per build work item plus dependency links | bd update --claim provides native atomic compare-and-swap; bd ready returns claimable work. |
| Trello | One card per build work item | Requires an external coordinator unless the backend can provide a conditional transition. |
- Store and retrieve work item lifecycle state: pipeline phase, blocked/ready status, owner/lease, dependencies, change type, provenance, immutable Git references, and finding-ledger events.
- Store and retrieve request backlog metadata: intent/rationale reference, human-owned business priority, owner, refinement state, and typed request relationships. Specification content remains in Git.
- Persist materialized work idempotently: atomically create-or-return
the complete contract already assembled by the Job Site Materializer, or a
durable
omittedreservation when implementation is not required, under a stable materialization key and a distinct per-operation idempotency key. Dispatch must never observe a partial item. - Transition work items atomically: compare the expected current state before applying a claim or any other lifecycle mutation.
- Translate between ProtoBot's work item model and the backend's native data model.
- Expose a uniform API (the WMS Adapter API) so that callers (Drafting Table, Job Site) don't need to know which backend is in use.
The adapter does not:
- Store work item content (specs, code, tests, inspection reports). That lives in the git repo. See Content Storage Model below.
- Determine pipeline entry point (that's a Validation Rules concern).
- Decide readiness from a caller's query alone. The Job Site may query and preflight readiness, but the WMS boundary evaluates the current record with Validation Rules before an authoritative claim or refresh.
- Push work to the Job Site (the Job Site pulls).
The Adapter API is the stable contract that the Drafting Table and the Job Site both talk to. Build work-item state persists in the issue tracker while specification content lives in the git repo. The Drafting Table reads that state for status and blocked-work UX; the Job Site owns execution transitions.
The API surface below includes both Drafting Table operations (requests and queries) and Job Site/Materializer operations. The Drafting Table subset is defined in the Drafting Table WMS Integration Contract and is not authorized to invoke the execution-lifecycle operations below.
The API surface includes:
- Requests: Create/read/refine requests; update business priority only for an authorized human maintainer; query by refinement state, owner, priority, or typed relationship; and link a request to its change set or direct true-bug build work item.
- Materialization: Create or return a build work item, or a durable
omittedreservation when implementation is not required, by stable materialization key and a distinct per-operation idempotency key. The operation writes its source specification and code commits, source change set or bug report, changed and applicable requirement IDs, impact dispositions, dependencies, and provenance as one durable contract or reservation. - Lifecycle transitions: Update state only when the caller supplies
the expected current state and monotonically increasing contract
version. Claiming compares
ready-for-buildingand atomically writesbuilding, owner identity, renewable lease, and a new fencing token. Every Job Site execution mutation and Job Site merge operation must present that token. Reconciler recovery operations use Git/WMS reconciliation proof instead; they cannot issue an execution lease or mutate the implementation branch. A stale owner or duplicate claim fails without mutation even if the item later cycles through the same state. - Blocked-work resolution submissions: Durable
blocked-work.submit-resolutionandblocked-work.acknowledgerecords as defined in the Drafting Table WMS Integration Contract. These writes do not change work-item lifecycle state,contract_version, ordependencies. - Lifecycle preflight: Advisory
lifecycle.preflightusing the shared Validation Rules evaluator; never an authoritative mutation. - Queries: Read items by ID, state, dependency, owner, or idempotency key, including "all ready items" and "all blocked items."
- Git references: Record source specification and code commits, content branch, resulting merge commit, and reconciliation state.
- Conformance evidence references: On completion, associate each delivery-obligation requirement ID with immutable test/inspection artifacts naming the source specification and tested candidate commits. The completion envelope pairs their digests with the resulting merge commit.
- Idempotent completion: Complete only a
mergingitem whose tested product-tree digest, sealed Inspection Run, post-attestation integration head, target, and contract version match. A Job Site completion also requires the current fencing token. A reconciler replay after Git already merged instead requires the WMS-observed merge envelope and reconciliation evidence; the reconciler does not present a live Job Site fence. Repeating the operation with the same resulting merge commit returns the prior result; a different result is rejected for reconciliation. - Finding ledger: Create a finding by stable producer idempotency key and append evidence, routing, disposition, confirmation, and resolution events with both a stable event idempotency key and expected finding version. A replayed event returns its original result; concurrent writers never replace a finding or a shared report.
- Atomic finding decisions: Append the finding event, transition the work item when needed, and enqueue a sanitized Worker task in one transaction/outbox operation using expected finding, work-item, and contract versions. Backends without a native transaction require the same external coordinator used for atomic work-item claims.
Requirements are declarative specification records and have no mutable workflow status. Coordination belongs to the build work item:
stateDiagram-v2
state "ready-for-building" as Ready
[*] --> Waiting: materialize with dependencies
[*] --> Ready: materialize without dependencies
[*] --> Blocked: unresolved impact
Waiting --> Ready: refresh baseline and revalidate
Waiting --> Blocked: revalidation needs review
Ready --> Blocked: revalidation needs review
Ready --> Building: atomic claim
Building --> Inspecting: tests pass
Building --> Blocked: specification question
Inspecting --> Blocked: specification question
Inspecting --> Building: defects or final-test failure
Blocked --> Ready: resolve, refresh, revalidate
Inspecting --> Merging: inspection and final tests pass
Merging --> Building: Job Site merge conflict, refresh required
Merging --> Completed: merge recorded or reconciled
Merging --> Ready: reconciled conflict or no Git mutation, rerun all gates
Building --> Ready: lease expired, Git reconciled
Inspecting --> Ready: lease expired, Git reconciled
Waiting --> Abandoned
Ready --> Abandoned
Building --> Abandoned
Inspecting --> Abandoned
Blocked --> Abandoned
Completed --> [*]
Abandoned --> [*]
waitingmeans the durable contract exists but another build work item must complete first.ready-for-buildingmeans the contract is complete, all impact candidates are dispositioned, and dependencies are resolved.buildingis owned by one Job Site under a lease acquired by atomic compare-and-swap. Lease renewal and all writes require the current fencing token.inspectingmeans generated code and tests pass and independent review is underway. Findings or a failed final test within the frozen obligation set return the same item tobuildingwithout changing its contract. A finding outside that set transitions toblockedfor an impact amendment.blockedrecords unresolved impact, specification/policy questions, or reconciliation failures and releases any execution lease. Ordinary unresolved dependencies usewaiting. Resolution refreshes the contract and returns it toready-for-building.completedrecords the resulting merge commit and an immutable completion envelope that references the pre-merge evidence artifacts. It does not mutate requirements.mergingrecords the tested candidate commit and proposed target before mutating Git. It cannot be abandoned. If the Git merge succeeds but the completion write fails, reconciliation idempotently transitions this state tocompleted; a Job Site-owned conflict returns it tobuilding. A reconciler can instead return a conflicted or unmutated item toready-for-building, where a new owner must rerun all test and inspection gates.abandonedis terminal and is rejected if Git or reconciliation metadata shows that integration may already have occurred. Restarting canceled logical work creates a replacement item with a new materialization key and explicitly retargets any dependents.
Expired execution leases do not authorize immediate reuse. The
reconciler first inspects the branch and integration metadata, then
increments the contract version and returns a recoverable building or
inspecting item to ready-for-building. The next claim receives a new
fencing token, preventing the old owner from affecting it.
Every adapter must provide the same atomic materialization and transition
semantics. It may use a backend primitive or an external coordinator,
but issue, ticket, or card assignment by itself is insufficient.
ears-manager knows nothing about WMS workflow state; it stores and
validates the specification content referenced by each work-item
contract. Change-set validation tells proposed from approved change sets by
the ears-manager
approval rule, so
immutable approved manifests are not re-evaluated against later
specification state.
- Adapter API granularity. How rich does the query surface need to be? Simple key-value CRUD, or structured queries like "all blocked items with their blocking reason"? Richer queries reduce round-trips but may be hard to map onto simpler backends (Trello).
- Notification channels. The WMS backend knows when work items are blocked (the Job Site or Drafting Table sets that state). For time-sensitive escalations, should there be an optional notification layer (email, Slack, webhook) on top of the adapter, or is that the Drafting Table's responsibility to poll?
The Source Control Manager (SCM) is the deterministic component that
turns the user's decision about a governed object into Git and Git
host state. The agent decides when, on the user's word. The SCM
decides how: which branch, which files, which message, which PR, and
whether the action is allowed at all. It is the split that ProtoBot
already uses for specifications, with ears-manager, and for work
items, with the WMS Adapter.
The stable caller boundary is defined in the Source Control Manager contract. This section describes its faces, responsibilities, and interfaces.
The SCM is a core with one narrow face per role. The role is fixed by the face that a caller gets:
| Face | Role | Callers | Operations |
|---|---|---|---|
| Drafting Table | drafting-table |
The TUI Drafting Table in any harness, over MCP stdio; the Web Drafting Table, behind the Gate | repo_state, branch_init, branch_resume, commit, publish, refresh |
| Approved-state read | materializer, reconciler |
register-approved-change-set and the Materializer; the Materializer/Dispatcher's recovery |
approved_merge |
| Job Site | job-site |
The Integration/Merge service | Future; not designed (Q21) |
- Resolve the project and its repository from the working tree, never from a caller.
- Apply the ref policy of the caller's role. No operation takes a free ref, path, remote, or message.
- Stage exactly the change set's files after the pre-stage digest
check, and write the commit subject and the
Change-Set:trailer. - Push without force, and create or update the PR with a body rendered
by code from
ears-manageroutput. - Merge the default branch in with a merge commit, or abort on a conflict and name the files.
- Report structured failures and one audit record per call.
The SCM does not:
- decide or write specification content, which is
ears-manager's; - approve or merge a specification PR, delete a branch, or discard an edit, which a person does;
- transition work items or open issues, which the WMS Adapter and the Job Site do; or
- keep a store of its own.
- To callers: The MCP tools of the Drafting Table face, and a CLI,
source-control-manager, for people and services. - To
ears-manager: Reads only: change-set paths, comparison, impact, validation, and a change-set manifest at a commit. - To the project repository:
git, with argument lists, never through a shell, and with no Git hook. - To the Git host: One host adapter per host. The first is GitHub,
through
gh. - To the Gate, in hosted modes: The trusted authorization context and the broker-issued credential (Authentication and Credential Isolation).
- Deterministic, not AI-driven. Like
ears-manager, the SCM is conventional code. The same state and request give the same decision, commands, and rendered text; a commit hash also depends on Git's own inputs, such as dates and identity. - Governed objects, not refs. Every operation takes a change set,
or nothing, and derives its refs, files, and PR from it. The one
exception is the checked prefix and default branch at initialization,
before any project records them. A generic
git_push(ref)would be a shell with a new name. - Clean or refuse. A failure leaves the repository as it was, and a state that no operation covers is refused with a diagnostic.
- Job Site face. Whether the Integration/Merge service uses a Job Site face of the SCM, with which operations, leases, and identity, is Q21.
Project content lives in the project's git repo, not in the issue tracker. Approved specifications live on main. Each build work item gets its own branch for code and tests; the issue tracker holds work-item lifecycle state and immutable Git references.
ProtoBot mandates only a .protobot/ control namespace, not a universal
language/source/test layout:
| Path | Owner and purpose |
|---|---|
.protobot/project.yaml |
Project identity, configured artifact paths, non-secret WMS/backend references, the canonical remote, default branch and declared review mode (git-integration.md), schema versions, store paths, and store integrity digests. |
.protobot/projection.yaml |
Deny-by-default path classification for Worker and attestation projections, versioned by its own version key (format version 1, defined by the ears-manager CLI contract). ears-manager writes the shared class for a registered specification path and, at initialization, for each configured store directory (git-integration.md); every other entry, and the restoration of a missing entry, is reviewed project policy. |
.protobot/policy.yaml |
Required Inspectors, WIP/scheduling policy, sandbox profile, and other reviewed project policy. |
.protobot/kits.lock |
Optional Kit source/version/digest/provenance locks. |
.protobot/interfaces/ |
One YAML file per structured interface record, unless a project registers another relative path in project.yaml. |
.protobot/change-sets/ |
Immutable approved change-set manifests, one flat file per change set, named cs-<nnnnn>.yaml (git-integration.md). |
.protobot/test-catalog.jsonl |
Stable test IDs, requirement links, verification modes, control surfaces, and validity metadata. |
.protobot/attestations/ |
Finding snapshots/reports, conformance metadata, and canonical demo manifests; always attestation-only. |
project.yaml points to the project's Vision, Architecture/interface
IDLs, and structured stores wherever project conventions put them. The
defaults that ears-manager proposes are .protobot/requirements/,
.protobot/interfaces/, and .protobot/change-sets/, which keep the
files it manages together and leave the rest of the tree to the project
(git-integration.md); a project
may register different relative paths.
ears-manager is the exclusive write gate for every registered
specification artifact: it owns structured requirements, the interface
registry, relationships, change-set manifests, and store integrity
digests, and delegates prose/IDL validation to controlled adapters. The
Job Site owns the test catalog and attestation snapshots. ProtoBot
configuration never contains credentials.
Source and test trees may follow Go, Python, TypeScript, existing-project, or future optional Kit conventions. The committed projection manifest is authoritative regardless of those conventions. CI rejects edits by a component or Worker outside its owned/allowlisted paths. This gives existing projects an adoption path without weakening role isolation.
flowchart TD
subgraph "Issue Tracker (lifecycle)"
WI["WI-042: Add config UI\nState: building\nBranch: wi/042-config-ui"]
end
subgraph "Git Repo"
Main["main\n(approved specs + completed code)"]
Branch["wi/042-config-ui\n(in-progress code + tests)"]
Branch -- "merge on completion" --> Main
end
WI -. "references" .-> Branch
- During Sketching/Dimensioning, the contributor writes specification artifacts (Vision, Architecture, EARS requirements, and a change-set manifest) on a branch and opens a PR against main. On merge, an idempotent materializer creates one complete build work-item contract from the approved change set unless the reviewed manifest explicitly says no implementation work is required.
- Materializing a work item records the source specification/code
commit, changed and applicable requirement IDs, impact dispositions,
dependencies, and materialization key. After dependencies resolve, the
materializer runs the complete pre-claim refresh policy. It appends a
refreshed contract and moves to
ready-for-buildingonly on success; otherwise it blocks or supersedes the item. The Job Site claims only a ready item and creates a branch off its recorded source commit (e.g.,wi/042-config-ui). - During Building, Workers commit in ephemeral projections and the Job Site imports validated patches to the integration branch. Inspectors read the private candidate and append Finding Ledger events; they never write a shared report file.
- On completion (all tests pass, Inspectors clear, final test
pass succeeds), the
wi/branch merges to main via merge commit. Code, tests, the sealed JSONL finding snapshot, rendered inspection report, and evidence references land on main. The WMS Adapter marks the work itemcompletedand records the resulting merge commit plus conformance-evidence references. - Blocked/abandoned work items are branches whose corresponding issue is marked blocked or abandoned. The branch is inert until the issue state changes. Abandoned branches can be archived or deleted.
| Concern | Where it lives | Why |
|---|---|---|
| Which work items exist, their pipeline phase, blocked status | Issue tracker | Issue trackers are built for this. |
| Approved specifications (Sketch, EARS, change sets) | main branch (via PR merge) | Structured, versionable, diffable, and CI-lintable. Requirements have no workflow state. |
| Draft specifications (pre-approval) | Contributor branch (PR) | Branch-and-PR workflow on the canonical repository (Change-set branches). |
| In-progress code and tests | Work item branch (wi/) |
Created by the Job Site for Building/Inspecting. |
| Live Inspector findings | Append-only finding ledger via WMS boundary | Supports atomic parallel writes, stable identity, routing, and rechecks. |
| Finding evidence and report snapshots | Integration artifact store, then work-item branch | Content-addressed raw evidence stays integration-only; deterministic JSONL and Markdown views are committed before merge. |
| Conformance evidence artifacts | Work item branch, referenced by WMS | Name requirement, specification, and tested candidate commits without self-referencing the later merge commit. |
| Completed specs + code | main branch (via work item merge) | Canonical state of the project. |
- Work-item state tracks progress. Requirements are immutable at a
given specification commit and have no workflow markers. The WMS
exposes durable build work items in
waiting,ready-for-building,building,inspecting,blocked,merging,completed, orabandoned. The Job Site claims an entire ready item atomically. - Impact is approved with intent. Each approved change set records both changed requirements and unchanged applicable obligations. A build work item snapshots both sets and their specification commit; neither set carries lifecycle state.
- Conformance is commit-scoped evidence. Branch artifacts record
which requirement IDs were verified against which specification and
tested candidate commits. The WMS completion envelope adds the
resulting merge commit and evidence digests. A later change produces
new evidence rather than resetting a global
implementedmarker. - Sketch updates are regular work items. Updating the Vision or Architecture follows the same branch → review → merge lifecycle as any other change. No special case needed.
- CI can validate branches. Spec format, well-formedness,
proposed
base_commitfreshness, and consistency checks run on branch pushes, just like code linting. - Concurrent work items don't conflict until merge. Each work item has its own branch. Conflicts surface at merge time, which is when they need to be resolved anyway.
- The integration repository reads from the branch. The Job Site checks out the work item's branch in a private integration repository. Workers receive role-specific projections of its recorded source commit, never that full checkout. There is no ambiguity about which specification or code baseline a projection represents.
- Regressions reveal missing impact. Each work item must move the project from one working state to another. If it breaks a previously passing test for a requirement outside the frozen obligation set, the item blocks for an impact amendment rather than silently expanding its contract. Once the requirement is dispositioned as applicable and a new contract version is appended, fixing the regression is the same item's responsibility. The branch cannot merge until every test in the active requirement-selected catalog passes, including valid pre-existing tests.
- Concurrent work items follow the standard dev branch model.
The Job Site should prefer picking non-overlapping work items, but
when concurrent items do touch the same areas, the standard
refresh-before-merge workflow applies. The Job Site first evaluates
current main under the pre-merge policy below. A blocked result requires
an impact amendment. An accepted result merges main into the integration
branch, returns the item to
building, and reruns every gate; conflicts or regressions are the delivering Job Site's responsibility to resolve.
A work item never silently follows a moving branch. Every refresh context uses the same eligibility checks:
- no active delivery requirement, affected interface/IDL, applicability selector/relationship, or source change-set intent changed;
- no relevant
.protobot/policy, projection, Kit lock, or active test- catalog entry changed; ears-manager impactproduces no new or changed candidate disposition;- changed implementation/test paths and declared scopes are disjoint from the work item's projected/touched paths and scopes, except for recorded dependency results; and
- all dependencies are completed and reconciled.
If any check fails, the item moves to blocked for a reviewed impact
amendment. A changed requirement or incompatible intent may supersede the
item entirely rather than refresh it.
- Pre-claim baseline refresh: after dependencies complete and before
the first claim, the Materializer appends a contract version with the
new source commit/check evidence, regenerates the projection and active-
test plans, and moves the item from
waitingtoready-for-building. No build branch or execution gates exist yet. - Blocked-item resume: the control plane evaluates eligibility and
appends the new source/contract version without touching the existing
integration branch. It then transitions
blockedtoready-for-building. A Job Site must acquire a new lease/fencing token through the normal atomic claim before it merges the recorded main commit into that branch, regenerates projections/test selection, and resumes Building. - Pre-merge revalidation: an active Job Site with the current lease
evaluates again after a successful Inspection Run. On success it
appends the contract version, merges latest main under the current
fence, atomically replaces that fence, regenerates projections/test
selection, and returns to
building. On failure it transitions toblockedand releases the lease.
Every existing-branch refresh reruns build, full active tests, mutation, and a new Inspection Run. A path-disjoint result never waives these gates.
- Spec directory layout. The record format is decided (one file per record, ADR-0001), and the minimum directory hierarchy and filename mapping are defined by ADR-0003.
- Branch naming and lifecycle. The change-set half is resolved:
Git and Project-Repository Integration
decides
cs/<nnnnn>-<slug>, creation atchange-set create, and deletion after merge. Still open for build work items: the convention forwi/branch names (e.g.,wi/<id>-<slug>), when the Job Site creates them (on work item creation or on first content write), and the cleanup policy for completed/abandoned branches.
Merge commits, not squash or rebase. The latest main is merged into the work-item branch during final refresh (see concurrent work items above), preserving the Job Site iteration DAG. The final merge commit preserves where overlaps exist and, critically, does not destroy the intermediate commits created by the Drafting Table and the Job Site. Every operation is auditable: Dimensioning edits to EARS, each Job Site triage cycle's fixes, Inspector-driven rework. This history is essential for optimization work (understanding how many cycles the Job Site needed, what Inspectors flagged, where Workers struggled).
ProtoBot keeps one canonical hosted repository per project. For each build work item, the Job Site creates three temporary local repositories in separate sandbox filesystems:
- Worker A repository (test projection): approved specifications, interface contracts, shared test/build protocol, and canonical tests that remain valid for unchanged requirements. It contains no implementation source, implementation history, or implementation Git objects.
- Worker B repository (implementation projection): approved specifications, interface contracts, shared build protocol, and the implementation baseline. It contains no canonical test source, test history, or test Git objects. Worker B may create private scratch checks, but they are destroyed with the sandbox and never merged or counted as independent evidence.
- Integration repository: a full checkout of the canonical source commit. Only the Job Site integration and Triage components can access it. Workers have no filesystem, Git, credential, or network path to this repository.
Each Worker projection is created by exporting allowlisted files from
the source commit into a new git init repository with a synthetic root
commit. It has its own object database, no Git alternates, no canonical
remote, and no repository credentials. Snapshot export rather than
sparse checkout is required because sparse paths do not prevent reading
excluded objects. The repositories are local temporary directories in
single-player mode and ephemeral sandbox volumes in hosted mode; they
are not separate GitHub/GitLab projects.
A versioned projection manifest classifies project paths as
shared, test, implementation, integration-only, or
attestation-only. Attestation paths can be committed after inspection
but are excluded from product-tree digests, builds, packages, and Worker
views. Unclassified paths are denied by default. A kit may provide
conventions for a language or stack only if that capability is defined in
the future; the manifest committed to the project is always the
authoritative policy. Sandbox filesystem policy independently enforces
the exported view.
Every canonical test has a stable test ID and a machine-readable
verifies list of requirement IDs plus the specification commit against
which it was generated. Before projection or baseline execution, the Job
Site classifies the existing suite:
- Tests mapped only to unchanged active requirements remain valid.
- Any test mapped to a revised or retired requirement is quarantined. Worker A regenerates the affected coverage from the current specification; the stale test is not exposed to Worker B or executed as a gate.
- A test spanning changed and unchanged requirements is quarantined as a unit, and replacement coverage must preserve every still-active requirement it referenced.
- Unmapped legacy tests remain integration-only and require an Inspector disposition. They cannot silently fail a Worker or be deleted merely to make the build pass.
- Implementation-aware tests also declare the internal control surfaces they use. They are quarantined whenever the work item changes one of those surfaces, even if the requirement text is unchanged, and are routed to the Implementation-aware Test Worker after a new candidate exists.
Quarantine is a logical, commit-scoped test-catalog decision; stale files may remain in Git history but are excluded from test discovery and CI for that specification commit. The selected active catalog, not every test file present in the repository, defines the executable regression suite.
Worker B receives self-correction without seeing canonical tests through an opaque baseline validation runner. The runner executes the valid unchanged-requirement suite in the integration environment and returns only sanitized feedback described below. Worker A sees valid prior test source and the test harness, but never implementation source.
Workers commit inside their projections. The Job Site exports path-restricted patch bundles, verifies that every path is allowed for the role, and applies them to full-baseline integration-side branches. At each cycle, those branches merge into the work-item branch with merge commits before build and test execution. Commit trailers and trace data record the projection commit IDs, patch digests, cycle number, and sanitized triage decision. Thus the canonical integration DAG preserves the exact Worker contributions and iteration history without making the full DAG visible to either Worker.
Every supported sandbox/backend must pass the sandbox conformance suite in the Job Site Sandbox Contract and the #172 integration-level suite. The integration-level suite proves that each Worker cannot:
- enumerate the other Worker or integration repository's refs;
- read a known forbidden commit with
git cat-fileor recover it as an unreachable/reflog object; - read forbidden current or historical paths;
- use a remote, credential, Git alternate, shared object cache, or network endpoint to fetch the canonical or peer repository.
The Patch/Ownership Validator rejects patches outside a role's allowlisted paths. These tests run for both the initial project and later work items, so previously merged implementation and test artifacts remain separated.
Triage and the baseline validation runner can see the combined integration environment, but Workers receive only a structured, auditable allowlist:
- outcome (
pass,fail, orblocked), fault classification (test, implementation, or both), and retry budget; - affected requirement IDs and a reason stated only in terms of the approved requirement or interface contract;
- identifiers and diagnostics for artifacts owned by the recipient, such as Worker A's test syntax error or Worker B's compiler error; and
- a request to regenerate or revise the recipient's own artifact.
Feedback must exclude peer files, paths, diffs, commits, object IDs, assertions, expected values, actual system outputs, combined stack traces, code behavior, raw test logs, mutation details, and raw Inspector findings. Worker A cannot receive observations produced by the implementation; Worker B cannot receive canonical test source or test-derived oracle details. If a reason cannot be expressed safely, the sanitizer returns only the requirement ID and a generic regeneration request. Every raw input, sanitized output, and redaction decision is recorded for evaluation, but only the sanitized record crosses the Worker boundary.
Validation Rules are the domain logic that enforces well-formedness on work items and state transitions. They answer questions like:
- Does this work item have approved requirements before it can move
to
ready-for-building? - Has
ears-managersuccessfully validated registered artifacts and requirement/interface references for the work-item specification commit? - Is a blocked item's escalation actually resolved before unblocking?
- What pipeline entry point does this change type require? (Undefined/changes → Dimensioning; contradictions → the Building pipeline directly after WMS materialization. See Incremental Development.)
Validation Rules use the versioned declarative validation-rules/v1
ruleset and deterministic evaluator. The Drafting Table and Job Site
apply them before writes for early feedback.
The WMS API boundary then atomically verifies the expected current state
and allowed transition before mutating the backend. That boundary may be
implemented inside the adapter service or as a mandatory validation
gateway in front of thin backend translators.
The MVP contract for this boundary is the versioned declarative
validation-rules/v1 ruleset and deterministic evaluator in the
Validation Rules Contract. The shipped MVP
evaluator is the backend-neutral Go package wms/validation, and the
first adapter that enforces it is the in-memory fake adapter
(wms/memory) used by the conformance and fixture tests. The evaluator's
decision is advisory during preflight and authoritative only when the WMS
boundary evaluates the fresh record and commits the conditional mutation.
Duplicating validation in every GitHub, Jira, Beads, or other backend translator would cause the implementations to drift. Caller-only validation is also insufficient: direct API/MCP callers can bypass it, and validation followed by a separate write has a time-of-check/time-of- use race. A single shared rule definition provides early caller feedback and authoritative enforcement at the write boundary without duplicating business logic in each translator.
The line between Validation Rules and ears-manager is:
ears-managerhandles spec-level validation: EARS formatting, required metadata, referential integrity between requirements, interfaces, explicit relationships, and change sets; impact dispositions; and file format consistency. These are rules about the content of specifications.- Validation Rules handle lifecycle validation: work item
state transitions, pipeline entry point determination, readiness
checks (e.g., "are all requirements approved before moving to
ready-for-building?"). These are rules about the workflow around specifications.
- Caller library/schema: Drafting Table, Materializer, Job Site, and Finding Router evaluate proposed commands for early diagnostics.
- WMS write boundary: Receives command, trusted authorization context, expected state/version/fencing token, and current record; atomically returns allowed transition or structured rejection.
- Rule version: Every decision records the exact rule/policy version for replay and audit.
- Future bindings. The MVP uses a declarative state-machine ruleset
with a deterministic evaluator, shipped as the backend-neutral Go
package
wms/validation. A WIT binding or separate service may improve portability later, but none may change the decision or rejection semantics defined by the Validation Rules Contract.
The Job Site is the autonomous execution engine — the entire background phase (Building + Inspecting). It pulls work items whose delivery obligations reference approved requirements at an immutable specification commit, including true-bug items with an empty changed set, and produces working, tested, inspected code.
flowchart TB
Repo["Canonical project repo"]
EM["ears-manager"]
WMS["Validated WMS API"]
subgraph Control["Job Site trusted control plane"]
Intake["Materialize / Dispatch"]
Boundary["Projection / Validation Gateway"]
Integration["Private Integration\nBuild / Test / Mutation"]
Triage["Triage / Feedback Sanitizer"]
Ledger["Finding Ledger / Router"]
end
subgraph Execution["Execution backend + isolated sandboxes"]
WorkerA["Worker A\nTests"]
WorkerB["Worker B\nCode"]
Aware["Optional implementation-aware\ntest Worker"]
Inspectors["Inspectors"]
end
Repo -->|"approved changes / source"| Intake
Intake <-->|"specs / impact"| EM
Intake <-->|"work-item lifecycle"| WMS
Intake --> Boundary
Repo -->|"source + project policy"| Boundary
Boundary -->|"role projections"| WorkerA & WorkerB
WorkerA & WorkerB -->|"patch bundles"| Boundary
Boundary -->|"validated patches"| Integration
Integration -->|"test failures"| Triage
Triage -->|"sanitized fixes"| WorkerA & WorkerB
Integration -->|"optional internal-test work"| Aware
Aware -->|"test patch"| Boundary
Integration -->|"read-only candidate"| Inspectors
Inspectors -->|"findings / completion"| Ledger
Integration -->|"mutation survivors"| Ledger
Ledger -->|"sanitized rework"| Triage
Ledger -->|"sealed findings"| Integration
Ledger <-->|"finding events"| WMS
Integration -->|"status / completion"| WMS
Integration <-->|"attestations / merge"| Repo
This diagram groups projection, catalog, baseline, patch-validation, and sandbox-adapter details behind their main responsibility. Worker and Inspector arrows carry projections, patches, read-only candidates, or sanitized tasks — never access to the private integration repository.
- Materialization: Receive an approved-change-set registration or
true-bug intake event. Resolve the exact manifest through
ears-manager, rerun deterministic impact analysis, resolve dependencies, construct the complete versioned contract, and call the WMS Adapter's idempotent materialization operation. This control-plane function runs independently of Worker capacity. - Dispatch: Query the WMS Adapter for work items in
ready-for-buildingstate and pull them when the Job Site has capacity. The Job Site decides what to work on and when using reviewed project scheduling policy. Human business priority is authoritative; the Job Site applies dependencies, aging, WIP, resource/risk fit, and conflict avoidance without changing it. There is no external push scheduler. - Run Worker A (test generator) and Worker B (code generator) concurrently from the same changed and applicable EARS requirements, under strict dual-model isolation using ephemeral role-projected repositories.
- Quarantine tests invalidated by revised or retired requirements, run the unchanged-requirement suite through the opaque baseline validator, and enforce requirement-to-test traceability.
- Merge Worker outputs, build a runnable artifact, and execute the test suite against it.
- Triage test failures (bad test, bad code, or both) and route fixes back to the appropriate Worker(s).
- Loop the triage → fix → retest cycle until all tests pass.
- Hand passing code to Inspector agents (Security, Test Completeness, Code Quality, and potentially others depending on project type).
- Atomically append Inspector and mutation findings to the Finding Ledger. Route code/test defects through the feedback sanitizer; undefined behavior blocks the work item and escalates through the Drafting Table. Raw findings never cross a Worker boundary.
- Run a final test pass after Inspectors clear, then produce the output prototype, demo artifacts, and commit-scoped conformance evidence.
- Run mutation testing as a hidden quality audit. One ledger finding is created per survivor; Mutation Inspectors disposition it without exposing mutant details to generating Workers.
- Enforce isolation and safety constraints at the sandbox level (not just via prompts): prevent Workers from seeing each other's files, refs, or Git objects; reject out-of-role patches; prevent shortcutting (e.g., mocking instead of real implementations); and enforce network policy (allow package registries and docs, block repository access and exfiltration).
- Apply Validation Rules before writing state transitions to the WMS Adapter.
The Job Site includes these sub-components:
- Materializer/Dispatcher: Converts approved change sets and bug reports into complete WMS contracts, reconciles Git/WMS operations, and atomically claims ready work for available execution slots.
- Workers (A and B): The agents that generate tests and code. Each runs in a separate sandbox against an ephemeral role projection; neither receives the canonical remote or repository credentials.
- Implementation-aware Test Worker: An optional exception path for requirements whose declared verification mode needs internal controls. It receives read-only implementation plus writable test paths after a candidate exists, cannot modify code, and is subject to independent Inspector and hidden-mutation gates.
- Projector/Test Catalog: Builds deny-by-default role repositories, validates test-to-requirement metadata, and quarantines stale tests.
- Baseline Validator: Runs the opaque unchanged-requirement suite in the private integration environment and submits raw results to the shared Feedback Sanitizer.
- Patch/Ownership Validator: Treats every execution-backend patch bundle as untrusted, verifies digest/signature and role-owned paths, and passes only accepted patches to Integration.
- Feedback Sanitizer: The single Worker-facing boundary for Baseline, Triage, and Finding Router tasks; it enforces the decided allowlist and records redactions.
- Triage mechanism: Something needs to look at test failures and decide fault. This could be another agent, a heuristic, or a hybrid. It runs only in the private integration environment and passes every Worker-directed decision through the Feedback Sanitizer. See open question Q15.
- Finding Ledger/Router: Accepts idempotent append-only events from parallel Inspectors, derives current status and report views, and emits recipient-specific tasks through the feedback sanitizer.
- Inspector roster: Which Inspectors run depends on the project. A CLI tool doesn't need an Accessibility Inspector. This could be derived from Architecture interface types, proposed by imported Kits, or explicitly selected by the user in project policy. Spec Conformance is mandatory whenever any delivery obligation uses implementation-aware verification. See open question Q12.
- Build/merge infrastructure: The merge step is not just "put files together" — it must build Worker B's code into a runnable artifact (container, listening API, CLI binary) and start it so Worker A's tests can execute against it. See open question Q8.
- Mutation Inspector: Receives hidden survivor details in the private
integration environment and proposes explicit
test-gap,spec-gap,equivalent, ortooling-invaliddispositions. Dismissal outcomes require independent confirmation.
Each Inspecting pass begins with an immutable Inspection Run manifest
bound to the work-item contract version, candidate commit, and a
product_tree_digest over every path that can affect build, execution, or
packaging. It lists
the required Inspector principal/version/independence policy, required
mutation campaign/configuration, prior findings that must be rechecked,
and the finding-ledger sequence at start. Each required producer appends
a signed producer-completed event even when it found nothing. Mutation
completion includes its campaign manifest and counts.
Inspectors run in parallel and never edit one shared report. Each emits a machine-readable finding with these required fields:
- stable
finding_idand produceridempotency_key; - Inspection Run, work-item, contract version, and candidate commit;
- producer identity/version, category, severity, and subject fingerprint;
- one or more requirement IDs, or an explicit
spec-gapscope when no approved requirement exists; - current status derived from events; and
- content-addressed evidence references and digests.
The first create for an idempotency key atomically allocates or returns
the stable finding. All later changes are immutable events such as
evidence-added, routed, disposition-proposed, confirmed,
disputed, resolved, recheck-passed, reopened, or
obsolescence-proposed, scope-exclusion-proposed, or
scope-exclusion-confirmed. Every event has its own stable idempotency
key and create-or-return semantics in addition to the expected finding
version. Thus a successful append whose response is lost can be retried
without duplicating a route, confirmation, or resolution. The Ledger
assigns a global sequence and records actor, timestamp, Inspection Run,
candidate/contract version, and rationale.
Non-mutation findings use explicit dispositions too:
implementation-defect, test-defect, both-defective,
omitted-applicable, spec-gap, or not-a-defect. The first three route
to the appropriate Worker(s), the next two block for reviewed
specification/impact work, and not-a-defect requires independent
Inspector confirmation before dismissal. Mutation findings use the more
specific vocabulary below.
Legal finding states are enforced at the write boundary:
| State | Legal next states and required actor/evidence |
|---|---|
open |
An Inspector proposes a disposition. Worker-actionable defects atomically route; omitted-applicable/spec-gap atomically block; a dismissal enters confirmation-pending; a missing mutation subject may enter obsolescence-pending. |
routed |
A rechecking Inspector may mark resolved for the current candidate, reopened, or propose subject obsolescence. Task delivery itself uses the outbox. |
blocked |
A rechecking Inspector may mark resolved after the dependency/requirement update, reopened, propose subject obsolescence, or enter scope-exclusion-pending after an approved out-of-scope declaration. |
confirmation-pending |
A matching independent vote produces dismissed-confirmed; a nonmatching vote enters disputed without routing or blocking. |
disputed |
A third independent Inspector votes. Once two votes match, the Router chooses routed for any Worker-actionable defect, blocked for omitted impact/spec gaps, or dismissed-confirmed for a confirmed no-defect/equivalent/tooling dismissal. |
scope-exclusion-pending |
Independent Mutation and Spec Conformance Inspectors must confirm that behavior is wholly inside the approved exclusion; then it becomes scope-excluded-confirmed. Any rejection returns it to blocked. |
obsolescence-pending |
A Mutation Inspector and independent Spec Conformance Inspector must confirm that the current candidate no longer contains the subject and still satisfies its mapped obligations; then it becomes superseded-confirmed. |
resolved, dismissed-confirmed, scope-excluded-confirmed, or superseded-confirmed |
Terminal only for the verified candidate. A later Inspection Run requires recheck-passed to bind the terminal result to its candidate, or reopened to return to open. |
The policy prevents an Inspector from confirming its own proposal. "Independent" requires a different principal and sandbox/session, no shared conversation state, and the configured independent model/provider class; retries of the same principal do not count as another vote. Inspectors recheck every prior finding ID listed by the Inspection Run, not merely findings whose derived status is currently open.
Routing uses the WMS transaction/outbox operation: finding event,
work-item transition, and sanitized task enqueue either commit together
or not at all. Delivery is idempotent by task key, and reconciliation
replays undelivered outbox entries. A work item therefore cannot remain
executable with a ledger finding that says it is blocked, or become
building without its routed task.
An Inspection Run can seal only when every required producer has completed, its mutation campaign is complete, every prior finding has a recheck event for the current candidate, and all current findings are terminal. Sealing atomically records the Ledger high-watermark; later events for that run are rejected. Rework creates a new run for the new candidate, so a resolution from an older candidate cannot satisfy the completion gate vacuously.
After sealing and before merging, the Job Site writes a deterministically
ordered JSONL snapshot and rendered Markdown inspection report under a
projection-manifest path classified attestation-only. Sandbox/build
policy prevents that namespace from entering source, tests, generated
artifacts, package inputs, or Worker projections. The Job Site recomputes
product_tree_digest after committing the snapshot and refuses merge if
it changed. Thus the commit can carry attestations without changing the
candidate that the sealed run certified. The JSONL is the machine view;
Markdown is never a source of truth. Raw evidence remains integration-
only and is referenced by digest.
The later merging envelope records both the sealed Inspection Run and
product digest plus the post-attestation integration-head commit. This
explicitly proves that only excluded attestation paths changed after the
candidate commit inspected by the run.
Each mutation campaign emits a signed completion manifest containing the
source specification, implementation-tree digest, active-test-catalog
digest, tool/operator versions, deterministic seed, environment, and
complete mutant inventory. A stable mutant_id hashes the implementation
subject: tool/operator semantic version, stable module/symbol/AST identity,
and transformation. A candidate-specific mutant_instance_id adds the
original target-node digest. Test-only and unrelated implementation
changes therefore preserve the instance ID when the mutated subject is
unchanged, while the campaign's full implementation digest still proves
which tree was tested.
Killed-mutant entries record the test IDs, requirement IDs, and declared control surfaces that detected them. Every implementation-aware test must have campaign evidence that it kills at least one eligible, non-equivalent mutation of each internal control surface it claims to verify. If the selected mutation tool cannot challenge a required surface, the gate is unsatisfied. Project/backend configuration must supply a suitable operator or test-control mechanism rather than treating missing evidence as a pass; a future Kit capability may assist but is not required or assumed.
Each surviving mutant starts as an open ledger finding whose subject is
the canonical mutant/instance IDs. Only Inspectors may disposition it:
| Disposition | Required action and completion evidence |
|---|---|
test-gap |
Route a sanitized requirement-level task to the appropriate test Worker. Resolve only when a rerun shows the same mutant is killed. |
spec-gap |
Block and create a linked Dimensioning change set. The user adds a requirement or approves an explicit out-of-scope declaration. Added requirements require mutation rerun; an exclusion becomes scope-excluded-confirmed only when independent Mutation and Spec Conformance Inspectors verify the mutant affects nothing outside that declared boundary. Human input resolves scope, not mutant mechanics. |
equivalent |
A second independent Inspector must confirm that the mutation causes no externally observable behavior change for any reachable input/state. An observable change outside approved requirements is spec-gap, not equivalent. Internal refactoring with identical external behavior may be equivalent. Both rationales and evidence remain in the Ledger. |
tooling-invalid |
Record a reproducible mutation-runner/operator failure and obtain independent Inspector confirmation. Quarantine that operator/version for the affected construct. |
If implementation rework changes or removes the target node, the old
finding cannot be called killed or equivalent. It enters
obsolescence-pending; a Mutation Inspector and independent Spec
Conformance Inspector must confirm from the complete current campaign
that the subject is absent, its mapped requirements still conform, and
all replacement mutants for those requirements/control surfaces are
terminal. Only then is superseded-confirmed valid for the current
candidate.
There is no accepted-risk or aggregate-score bypass. If a required
confirmation disagrees, a third independent Inspector acts as tie-breaker;
two matching dispositions determine the result. Failure to obtain two
matching dispositions within the Inspector retry budget leaves the
finding open; the work item cannot complete and is abandoned/replaced
after its normal retry policy rather than escalated to a human code
reviewer.
Completion requires a sealed current-candidate Inspection Run, a complete
campaign manifest, implementation-aware effectiveness links, and every
survivor finding terminal: test-gap killed, spec-gap resolved and
rerun or explicitly excluded with two-Inspector confirmation, a
two-Inspector confirmed equivalent/tooling-invalid dismissal, or
confirmed subject supersession under the rule above. Mutation score
remains an evaluation metric, not a substitute for individual
disposition.
- To WMS Adapter: Queries for ready work items (pull-based dispatch). Reports status updates (in progress, tests passing, inspection underway, done), resulting Git commits, and evidence references. Atomically appends Finding Ledger events and pushes escalations that block work items.
- To project repo: Maintains the private integration checkout, creates role-projected temporary repositories, imports validated patch bundles, writes inspection/evidence artifacts, and merges to main on completion. A Job Site face of the Source Control Manager may take these Git mutations later (Q21).
- To Source Control Manager: The Materializer and the single-player
registration command read the merge commit of an approved change set
through
approved_merge. - To CI / Build System: Needs build and test execution infrastructure. May need self-contained CI for parallel prototype experiments.
- Outputs: Prototype artifacts, demo artifacts (showboat docs, animated GIFs, screenshots), Finding Ledger snapshots, and rendered inspection reports.
- Fullsend integration depth. Fullsend is the first Job Site backend, but ProtoBot retains materialization, WMS abstraction, role projections, dual-worker integration, Triage sanitization, and evidence semantics. Which Fullsend extension points can host those functions unchanged, and which require a ProtoBot orchestration layer or upstream Fullsend contribution?
- Projection-manifest migration. New projects can use tool-generated or project-authored default path classes; a future Kit capability may assist. Existing repositories may mix tests and implementation or generate source during builds. What migration and validation UX helps a user produce a deny-by-default projection manifest without misclassifying files?
- Isolated vs. implementation-aware tests. Some requirements can't be practically tested at the interface boundary (timing, caching, internal state). The exception Worker and compensating gates are decided; what fraction of requirements need this path, which standard internal-control interfaces should projects/backends define, and should a future Kit capability package any of them? See open question Q9.
- HU-02 compliance gate. Does merging code to main count as a "write action" under Red Hat's AIA/HU-02? The multi-player workflow places the human checkpoint at PR merge (specs landing on main). Everything after is autonomous execution of approved intent. This may satisfy HU-02, but needs confirmation. See open question Q13.
These are not components in themselves but affect the design of multiple components.
Architectural constraint: Every agentic component in the system must be independently evaluable. Learning where the inefficiencies are and being able to measurably improve them is a high priority. This must be supported in the architecture from the beginning, not retrofitted.
This means each component needs:
- Defined inputs and outputs that can be captured and replayed. If you can't feed a component a known input and measure its output, you can't eval it.
- Structured trace data recorded during operation — not just "did it succeed" but how it got there: how many iterations, what decisions were made, where time was spent, what was discarded.
- Isolation boundaries that allow component-level testing. You should be able to eval the Triage mechanism without running the full Job Site, or eval gap-closing heuristics without a live Dimensioning session.
Project-level requirements and Job Site evaluation use the evaluation corpus contract. That contract records separately attributable requirements-quality, Job Site conformance, and end-to-end outcomes; keeps holdout behavior checks out of Worker projections; and validates locally without a hosted cluster or external service credentials. It does not replace the eliciting-requirements skill corpus.
Per-component eval surfaces:
| Component | Key eval questions | Data source |
|---|---|---|
| Sketching agent (Toolkit) | Does it elicit a complete Architecture? Does it surface unstated assumptions? | Recorded Sketching sessions (input descriptions → produced Sketches) |
| Dimensioning agent (Toolkit) | Does it produce complete EARS coverage? How many gaps does it surface vs. miss? | Recorded Dimensioning sessions; compare agent-surfaced gaps against gaps found later by Inspectors |
| Worker A (test generator) | Do generated tests actually verify the requirements? What's the mutation kill rate? | Generated test suites vs. EARS requirements; mutation testing results |
| Worker B (code generator) | Does generated code pass independently-generated tests on first try? How many triage cycles? | Integration-cycle history and Worker patch bundles (cycle count, fix types) |
| Triage mechanism | Does it correctly attribute failures to tests, code, or both? | Triage decisions vs. actual root causes (measurable when the fix confirms or contradicts the triage) |
| Inspectors | Do they catch real defects? What's the false positive rate? Do they miss things mutation testing catches? | Finding Ledger events/dispositions vs. mutation results and later rework |
| Gap-closing heuristics | How often does the Job Site or Inspector discover undefined behavior that Dimensioning should have caught? | Async escalation frequency; "unspecified" bin in the undesired-behavior taxonomy |
The git history is a natural eval dataset. The merge-commit and integration-cycle history preservation decisions (see Content Storage Model) were made partly for this reason: the full iteration history of every work item — Dimensioning edits, Job Site cycles, Inspector findings, rework — is recorded in git and available for analysis without additional instrumentation.
Open design questions:
- Trace format and storage. What structured trace data does each component emit beyond git commits? Logs? OpenTelemetry spans? Something custom? Where is it stored and how is it queried? For the TUI Drafting Table, the interim trace source is the harness's own session record (Adapter contract — Traces); a harness-neutral format is still open.
- Eval harness. How do you run an eval? Feed a component recorded inputs and compare outputs against a reference? The fixture and result contract is the evaluation corpus. The Eval Hub and Agent Eval Harness are existing Red Hat eval infrastructure — should a live runner use them, or does the component-level eval need something different?
- Baseline establishment. What's the first set of evals to build? The Job Site cycle count (how many triage iterations before tests pass) is probably the easiest high-signal metric to start with, since the git history captures it directly.
Specifications and code are decoupled on main. Approved change sets land on main via normal PR merge. The merge registration idempotently materializes a complete build work item in the WMS, including its changed and applicable requirement IDs. The Job Site claims ready work items, not requirements. Code lands on main when a work-item branch merges, at which point the WMS completes the item and records commit-scoped conformance evidence.
Main can therefore contain approved specifications not yet reflected in
code. This gap is represented by waiting, ready-for-building, or
active build work items, not by mutable status on requirements. The WMS
work-item queue is the project's explicit, queryable delivery backlog.
sequenceDiagram
actor Contributor
actor Reviewer
participant Repo as Main Repo
participant MAT as Materializer
participant WMS as WMS Adapter
participant JS as Job Site
Contributor->>Repo: Open PR with change set
Reviewer->>Repo: Review specs, merge PR
Repo->>MAT: Register approved change set<br/>(merge commit + idempotency key)
MAT->>Repo: Read manifest at merge commit
MAT->>WMS: Materialize complete work item<br/>(waiting, blocked, or ready)
JS->>WMS: Query ready work items
JS->>WMS: Claim work item (atomic CAS)
JS->>Repo: Create private wi/ integration branch
JS->>JS: Run projected Workers<br/>and append Inspector findings
JS->>WMS: Enter merging<br/>(tested candidate + evidence digests)
JS->>Repo: On completion: merge wi/ branch<br/>to main
JS->>WMS: Complete work item<br/>(merge commit + evidence)
- Contributor writes a change set (via Drafting Table +
ears-manager) and opens a PR against main through the Source Control Manager. The contributor needs push access to the canonical repository: the SCM pushes a change-set branch there only, and registration accepts only a PR whose head is in that repository (Host adapter boundary). A fork-and-PR route for specifications is not designed. - Reviewer reviews the specs using GitHub's standard review
tools (line comments, request changes, approve) and merges the
PR. This is the human approval gate — standard branch
protection rules, CODEOWNERS, and required reviews all apply.
CI runs
ears-manager checkas a merge gate to validate spec well-formedness, registered artifact path/canonical-content deltas against proposedartifact_operations[], continued registration of default-branch artifacts, and proposedbase_commitfreshness. - The change set lands on main. A registration hook calls the Job Site materializer with the change-set ID, resulting merge commit, stable materialization key, and the distinct deterministic registration idempotency key.
- The materializer constructs the contract. It reads the manifest
at that commit, reruns deterministic impact analysis, resolves
dependencies, and calls the WMS's atomic create-or-return operation.
One approved change set creates one build work item by default, or a
durable
omittedreservation when it has no implementation effect. A created item starts inwaitingwhen it has dependencies,blockedwhen impact review remains, andready-for-buildingotherwise. Dispatch cannot observe an incomplete contract. - The Job Site queries ready work items and atomically claims one by
compare-and-swap. It creates the
wi/branch from the recorded source commit and runs the Building/Inspecting pipeline. - On completion, the Job Site first transitions the item to
mergingwith the tested candidate commit and evidence digests. It then merges thewi/branch to main and idempotently records the resulting merge commit andcompletedstate. Requirements themselves are not mutated.
Both registration and completion are reconciled across Git and WMS. If a Git merge succeeds but its WMS write fails, a reconciler finds the merge by change-set/work-item metadata and retries the same idempotent operation. It never creates duplicate work or repeats a completed merge.
A true-bug report enters through the same materializer without a change set. It supplies the violated requirement IDs and affected scope. The materializer runs deterministic impact analysis and conservatively marks every candidate applicable; exclusions require a reviewed impact change set.
- Standard GitHub permissions. PR merge is the approval gate, which is exactly what branch protection rules, CODEOWNERS, and required reviews are designed for. No custom label-based permission scheme needed.
- Standard contributor workflow. Branch, commit, open PR, get review, merge. No special labels, no "don't merge — only label it" confusion.
- Change sets are not ownership containers. A requirement can be introduced by one change set, revised by another, and retired by a third. The initial one-change-set/one-work-item delivery boundary does not create a lasting requirement-to-feature relationship.
- Explicit backlog. Durable build work items are the project's approved backlog, visible and queryable in the WMS without attaching transient state to requirements.
- Traceability. Every requirement has clear provenance: which PR merged it, who approved the merge, when. Standard git/GitHub audit trail connects that approval to the work-item contract, tested candidate, resulting merge commit, and evidence artifacts.
- HU-02 compliance. The human confirmed the intent (the specs) by merging the PR — a more recognized, auditable approval action than applying a label. Everything after is autonomous execution of that approved intent.
When the Job Site discovers undefined behavior during Building or Inspecting, it cannot resolve this autonomously — it needs human input:
- Job Site opens an issue in the main repo describing the undefined behavior. The work item is marked blocked in the WMS.
- Any team member writes the missing spec changes and opens a linked change-set PR against main (the normal contribution flow).
- Reviewer merges the PR. The blocked-work resolution submission records a planned dependency on the linked change-set build work when implementation is required; that edge is not written onto the blocked work item.
- After the planned dependency completes, Materializer
resolve-blockobserves it during full refresh and performs the singleblocked -> ready-for-buildingtransition. The original item returns toready-for-buildingonly after all pre-claim checks pass; otherwise it remains blocked for an impact amendment or is superseded. A previously executing item follows the blocked-item resume path, obtains a new fenced claim before touching its branch, and reruns all execution gates.
This uses the same PR → merge flow as initial contributions — no special escalation mechanism needed.
In single-player mode, the contributor has write access and merges
their own PRs without a reviewer
(Git and Project-Repository
Integration).
A local register-approved-change-set command or hook performs the same
idempotent WMS materialization as the multi-player merge hook. It reads
the merge commit through the Source Control Manager, so no agent
carries it (Approved-state read
face).
The merge is not sufficient by itself. The difference is ceremony, not
architecture.
- Future split/combine strategy. The initial contract is one approved change set to one build work item by default; an omitted reservation is the explicit no-implementation result. Splitting large change sets or combining several of them could improve throughput, but interactions between the new boundaries require a reviewed delivery plan and fresh impact analysis. What rules and UX should govern that review?
- Bot account model. The Job Site needs a GitHub identity with
write access for creating
wi/branches and merging completed work. GitHub App? Bot account? Machine user? Each has different permission scoping, rate limits, and audit characteristics. The Drafting Table's Git writes act as the user, through the Source Control Manager; the Job Site's identity is part of Q21.
The first Job Site backend is Fullsend, using its OpenShell-based execution path. A direct OpenShell backend is the fallback and the preferred base for a custom ProtoBot Job Site. This is an implementation strategy, not an architectural dependency: both adapters implement the same ProtoBot Job Site Sandbox Contract. Because both still depend on OpenShell, a separate portable containment profile is the required sandbox fallback for platform incompatibility or failed OpenShell acceptance tests.
The portable profile may use rootless Podman/OCI containers locally and Kata, KubeVirt, or another microVM boundary when hosted. It must pair filesystem/process isolation with an external egress policy proxy and credential broker; running a plain container is not sufficient. The profile is usable only after it passes the same suite below, including per-executable/per-destination L7 controls. Until then, an OpenShell failure disables autonomous execution on that platform.
ProtoBot continues to own the control plane around Fullsend:
- The Materializer/Dispatcher creates WMS contracts and coordinates projection creation. The Projector/Test Catalog alone reads canonical source to emit signed role projections; the Baseline Validator operates only in the private integration environment.
- Fullsend's privileged pre-phase receives only those bundles, verifies and stages them, and cannot read the canonical repository. Its post-phase returns path-restricted patch bundles. Neither phase nor the sandboxed agent receives Git/WMS mutation credentials; ProtoBot's Patch/Ownership Validator checks the untrusted return before Integration applies it.
- ProtoBot's private integration loop combines Worker outputs, runs the active test catalog, sanitizes Triage feedback, and records conformance evidence. Fullsend may host these stages only if its extension points preserve the same boundaries.
- Fullsend's Review fan-out is a candidate host for Inspectors, subject to ProtoBot's finding and feedback contracts.
OpenCode remains the first Drafting Table harness. Job Site Workers use the harnesses supported by the selected execution backend; OpenCode is not a Job Site prerequisite unless a Fullsend OpenCode runtime is added.
The versioned, backend-neutral contract is the
Job Site Sandbox Contract (jobsite-sandbox/v1).
The local test adapter and sandbox conformance suite live in
source-control-manager/internal/jobsite. Prompts are not a security
boundary. The sandbox is the primary enforcement mechanism for
safeguards.
The sandbox conformance suite owns these API-boundary controls:
- Filesystem API: no host, peer Worker, canonical repo, or integration-repo reads and no writes outside projected paths.
- Git API: the negative ref/object/history/remote checks in Worker repository projections.
- Network: deny by default; allow only an approved executable to an approved destination, protocol, method, and L7 path. Tests must reject the same destination from another binary plus DNS, direct-IP, redirect, raw-socket, alternate-port, and TLS-bypass attempts.
- Credentials: no downstream credential appears in a sandbox file, environment variable, process argument, log, response body, or agent- readable proxy state. A boundary broker injects credentials only after authorization and strips them before responses return.
- Lifecycle API: sandbox-lease expiry and process termination stop further session operations.
- Resource limits: wall-clock, CPU, memory, process-count, writable-disk, and writable-file limits fail closed.
- Auditability: policy version, sandbox/backend version, executable digest, authorization decision, allowed request, denial, and cleanup result are tied to the work-item trace.
Each runtime must also pass an integration-level suite that checks the actual Worker execution boundary. #172 owns that suite for Fullsend/OpenShell. It must reject host/peer reads; mount, namespace, ptrace, privilege, device, and forbidden-syscall escapes; Git checks run from inside the agent process; agent-readable proxy and log state; and leftover mounts, network policy, or broker sessions. The portable profile requires an assigned integration-level owner before it can enable autonomous execution.
If a backend or platform cannot pass both suites, the Job Site refuses
autonomous execution. It must not silently switch to a weaker profile.
Fullsend's use of OpenShell is therefore validated as effective behavior,
not accepted transitively by product name. The API-level checks,
local test adapter, and structured ConformanceReport are defined by
the Job Site Sandbox Contract.
MCP/API servers terminate inbound client tokens and use server-owned, least-privilege credentials downstream (the Alcove Bridge/Gate pattern). OAuth 2.1 is the ESS-required baseline. The inbound identity is never replaced by the service identity for authorization or audit.
At every mutation boundary, a Gate:
- Validates token signature, issuer, audience, expiry, and subject.
- Maps the trusted subject and work-item contract to an authorization context: project, role, work item/change set, allowed refs, actions, and expiry. For the Source Control Manager's Drafting Table face, it maps the trusted subject and the proposed change set that the Web session record names, and adds the subject's Git author, a name and an email from the identity provider, for an operation that creates a commit. Caller-supplied project or branch claims are not trusted.
- Authorizes the requested action against that context and the current WMS contract version. A proposed change set has no WMS contract version, so for the Source Control Manager's Drafting Table face the Gate checks the change set instead.
- Obtains a project/action-scoped downstream credential from an external broker. Git hosting should use short-lived installation/service tokens where available; the Gate enforces branch restrictions that the token format cannot express. For Git, requests carry no ref, so the Source Control Manager behind the Gate enforces them on every ref it writes.
- Records both the original caller and downstream service actor with the project, role, work item, action, ref, issuer/audience, policy version, idempotency key, and resulting WMS/Git object.
Workers and implementation-aware test agents receive no Git or WMS mutation role. Only the Materializer, Integration/Merge service, WMS control plane, and Source Control Manager receive narrowly scoped actions required by their current contract. Inspector identities can read the private integration snapshot and append findings but cannot modify code or tests.
For Git and the Git host, the mutation boundary is the Source Control Manager. The Drafting Table is the only agent with a Git mutation role, and it exercises it only through the SCM's Drafting Table face. In hosted modes that face runs behind the Gate, which applies the steps above with the differences that the SCM's Authorization states.
Authorization acceptance tests cover wrong issuer/audience, expired or forged tokens, cross-project access, role escalation, wrong work item or ref, unauthorized action, stale contract/fencing token, downstream token scope, credential-exfiltration attempts, and complete caller attribution for every WMS or Git mutation.
ProtoBot shares IdeaBot's CMDB record but its autonomous code-generation design likely rates High risk on the AI Agent Risk Evaluator — higher than IdeaBot — requiring a fresh AIA submission. The main design-relevant control is HU-02 (Agentic Authorization): human confirmation before write/deploy actions. The multi-player workflow places the human checkpoint at PR merge time (when specs land on main). Everything after is autonomous execution of approved intent. Whether this satisfies HU-02 for the subsequent automated code merge needs confirmation.
- Vision — Purpose, intended users, desired outcomes, prototype scope, and non-goals
- Overview — What ProtoBot is, guiding principles, and workflow summary
- Architecture — External interface inventory, pluggable boundaries, persistent state, and environmental constraints
- Validation Rules Contract — Lifecycle states, authorization, transitions, rejection semantics, and acceptance matrix
- Drafting Table WMS Integration Contract — Backend-neutral request, query, linking, and blocked-resolution operations
- Job Site Sandbox Contract — Backend-neutral sandbox conformance suite, local test adapter, and Fullsend/OpenShell mapping
- WMS Implementations — Backend-neutral wire types and operation surfaces, the Go lifecycle evaluator, the in-memory fake adapter used by the conformance and fixture tests, and the first backend translator over GitHub Issues
- Git and Project-Repository Integration — Project identification, branches, commits, PR preparation, and approved specification state
- Source Control Manager — The Git and Git host boundary: faces, operations, authorization, and failures
- Agent Harness Adapter Contract — Harness-neutral adapter core, governed tools, the guard, and harness obligations
- OpenCode Harness Binding — The first harness binding
- Claude Code Harness Binding — The second harness binding
- Codex Harness Binding — The third harness binding
- User Interaction Flow — Phase details and sequence diagrams
- Drafting Table UX — Stable interaction contract for the first local Drafting Table
ears-managerCLI Integration Contract — Command grammar, results, diagnostics, and impact review- Open Design Questions — Unresolved design questions across all areas
- Evaluation Corpus Schema and Result Contract — Versioned fixtures, holdout isolation, and stage-attributed results
- Related Work — Red Hat internal projects, external factory projects, and lessons learned