From e076eb2df15cdcf3532cd3a281e1e238eece9661 Mon Sep 17 00:00:00 2001 From: nullhack Date: Wed, 8 Jul 2026 05:35:00 -0400 Subject: [PATCH 1/2] feat(pipeline): dedicated simulator agent and skill-first dispatch contract simulate-contracts dispatched to reviewer, priming consistency-checking instead of mental simulation. Repoint to a new simulator agent (mental-execution/compiler lens) and strengthen the dispatched-agent operating contract: load the named skill first, resolve every wikilink to its knowledge file, then follow the skill steps. Bumps plan-flow to 1.7.0 (within pipeline-flow ^1). --- .flowr/flows/plan-flow.yaml | 4 +-- .opencode/agents/simulator.md | 33 ++++++++++++++++++++ .opencode/skills/simulate-contracts/SKILL.md | 2 +- AGENTS.md | 16 ++++++++-- 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 .opencode/agents/simulator.md diff --git a/.flowr/flows/plan-flow.yaml b/.flowr/flows/plan-flow.yaml index 1a5cd4e..e4fd535 100644 --- a/.flowr/flows/plan-flow.yaml +++ b/.flowr/flows/plan-flow.yaml @@ -1,5 +1,5 @@ flow: plan-flow -version: 1.6.0 +version: 1.7.0 exits: - contracts-ready - needs-capture @@ -129,7 +129,7 @@ states: description: > Gate. Answer whether a correct implementation passing every test would yield a complete working system; the final check before build. - dispatch_to: reviewer + dispatch_to: simulator git branch: dev skills: [simulate-contracts] input artifacts: diff --git a/.opencode/agents/simulator.md b/.opencode/agents/simulator.md new file mode 100644 index 0000000..59c85fc --- /dev/null +++ b/.opencode/agents/simulator.md @@ -0,0 +1,33 @@ +--- +description: "Simulator — mentally executes the contract set to disprove the system works before any source .py is written" +mode: subagent +temperature: 0.3 +--- + +# Simulator + +You are the Simulator. Your lens is the contract set as a program to compile in +your head, not a document to audit. You take the tests and source stubs as if +they were already implemented, run the application mentally — entry point to +side effect, hop by hop — and ask the one question that gates the build: *if a +correct implementation made every test pass, would the resulting system +actually work, and work unambiguously?* You are a compiler walking an AST to +prove the program links before any code executes; you are trying to disprove +the system works, and a failure to disprove is the strongest statement you can +make. + +## What you hold + +- Mental execution is the method, not consistency-checking. Confirming the tests reference the spec's findings is a review, not a simulation; the gate is whether a passing implementation would run end-to-end and meet intent. +- The failures that matter live where tools are blind: composition across files, a value in two shapes between the tests that produce and consume it, a side effect no test observes, a behaviour two implementations could both satisfy. Each ships silently to build if you do not catch it by reading across the set. +- A clean tool run is necessary but not sufficient. pyright, stubtest, traceability, no-orphans each police one class of defect; none reads across the contracts the way you do. Silence from tools is not acceptance. + +## What you decide + +You alone decide the simulation verdict: the contract set is coherent, complete, and unambiguous (advance), or a named gap (route back with the precise hop, value, finding, or ambiguity). + +## What you refuse + +- You refuse to substitute a contract↔spec consistency check for mental execution. A review that only confirms tests name the findings is the failure mode this gate exists to prevent. +- You refuse to advance on a clean tool run alone; the walkthrough, the value traces, the spec-diff, and the build-implied sweep are the gate, and each must reach no defect. +- You refuse to soften a gap to be agreeable; a false advance is the most expensive simulation outcome. diff --git a/.opencode/skills/simulate-contracts/SKILL.md b/.opencode/skills/simulate-contracts/SKILL.md index 455d8b9..d4de28a 100644 --- a/.opencode/skills/simulate-contracts/SKILL.md +++ b/.opencode/skills/simulate-contracts/SKILL.md @@ -6,7 +6,7 @@ description: "Compile the contract set in your head — simulate how the real ap # Simulate Contracts 1. Load [[requirements/spec-simulation]], [[software-craft/test-stubs]], [[methodology/simplicity-discipline]] — the simulation method, the test-pair drift rules, and the scope-minimal rule. -2. **Frame the step.** This is NOT a ceremony that validates the model "works" — the model is already a binding input (`data-model.md`), not something this gate ratifies. This step is a **compiler**: it takes the contract set (test `.pyi`, test `.py`, source `.pyi`, the modeled schema, the captured cassettes, the interview) and simulates how the real application would run if a correct implementation made every test pass — the way a compiler walks an AST to prove the program type-checks and links, before any code executes. You are running the program mentally, against the specs, to **disprove or confirm** that it works. The output is a verdict (`accepted`) or a named gap (`needs-test-bodies`, `needs-source-stubs`, `needs-capture`, `needs-elicitation`) — never a clean stamp on a tool run alone. +2. **Frame the step.** This is NOT a ceremony that validates the model "works" — the model is already a binding input (`data-model.md`), not something this gate ratifies. This step is a **compiler**: it takes the contract set (test `.pyi`, test `.py`, source `.pyi`, the modeled schema, the captured cassettes, the interview) and simulates how the real application would run if a correct implementation made every test pass — the way a compiler walks an AST to prove the program type-checks and links, before any code executes. You are running the program mentally, against the specs, to **disprove or confirm** that it works. The output is a verdict (`accepted`) or a named gap (`needs-test-bodies`, `needs-source-stubs`, `needs-capture`, `needs-elicitation`) — never a clean stamp on a tool run alone. This is NOT a code review or a contract↔spec consistency check — confirming the tests reference the findings is the failure mode, not the gate. 3. **Walk the e2e path hop by hop, capturing observations at each hop.** For each hop in the entry-point e2e (entry → adapter → domain → persistence → side effect): - (a) **Walk the hop** — confirm the type handed across matches the type the receiver declares; the value carried matches the shape the producer emits; the side effect the hop performs is one a contract actually specifies. - (b) **Append the observation to `.cache//journal.md` at this hop** — not only the verdict at the end. The journal is a per-hop record, not a summary; an observation recorded at the hop it was made is the evidence the verdict rests on. The content is mandated (per-hop observations exist, in any structure the reviewer chooses); the format is not. diff --git a/AGENTS.md b/AGENTS.md index 37ccd92..db70bca 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -17,14 +17,26 @@ through flowr. ## Driving a state -**Two hats.** AGENTS.md addresses the **orchestrator** — the agent holding the flowr session that drives state to state. A **dispatched agent** (invoked via a state's `dispatch_to`) does one state's work and returns: load the skill, read the inputs, write only the outputs, assert the evidence, and never transition, skip, or hold the todo. If you were invoked to do a state's work, you are the dispatched agent — produce, return, stop. +**Two hats.** AGENTS.md addresses the **orchestrator** — the agent holding the flowr session that drives state to state. A **dispatched agent** (invoked via a state's `dispatch_to`) does one state's work and returns. Its operating contract is ordered and mandatory: + +- **(0) Load the named skill** via the `skill` tool — the skill is the procedure; do not improvise. +- **(1) Execute the skill's Load step** — resolve every `[[wikilink]]` and Read each cited knowledge file before any other step. The skill and its knowledge citations ARE the method; skipping them collapses the work to the agent's native lens. +- **(2) Follow the skill's steps in order** — read every `input artifact`, write only to `output artifacts`, assert only verified evidence. +- **(3) Never transition, skip, or hold the todo** — produce, return, stop (7). + +If you were invoked to do a state's work, you are the dispatched agent. One state at a time. The orchestrator keeps **one todo per state** — the todo *is* this loop: 0. **Create the todo** — `todowrite` the phases below before any other action (8). 1. **Read** — `flowr check --session `; parse `dispatch_to`, `skills`, `input artifacts`, `output artifacts`, `git branch`, `conditions`. 2. **Verify inputs** — every `input artifact` exists on disk. Missing = stop (3). -3. **Dispatch** — invoke `dispatch_to` with the full handoff: skill paths, input artifacts, output artifacts (write only here), evidence keys, and the boundary — *do only this state's work; do not transition, do not skip; the orchestrator moves the flow* (2, 7). It returns the output artifacts and asserted evidence. +3. **Dispatch** — invoke `dispatch_to` with a handoff whose **first instruction** is to load the skill and follow it. Use this template verbatim, filling the slots from `check`: + + > Load the skill `` via the `skill` tool and follow its steps in order, beginning with its Load step — resolve every `[[wikilink]]` and Read each cited knowledge file before working. + > Inputs (read all): ``. Outputs (write only here): ``. Evidence keys to assert (guarded only): ``. Boundary: do only this state's work; do not transition, skip, or hold the todo — the orchestrator moves the flow (2, 7). + + It returns the output artifacts and asserted evidence. 4. **Verify outputs + evidence** — the `output artifacts` were produced; if the transition is guarded, its `conditions` evidence is real (4). 5. **Transition** — `flowr transition --session --evidence k=v …`, then regenerate the todo from the next state's `check`. From e43e9fbe33d43a5facc9c8c26962f91941110e70 Mon Sep 17 00:00:00 2001 From: nullhack Date: Wed, 8 Jul 2026 05:35:00 -0400 Subject: [PATCH 2/2] chore(release): bump version to 10.2.0 --- pyproject.toml | 2 +- uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 6063b87..97c8b05 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "temple8" -version = "10.1.0" +version = "10.2.0" description = "Test-driven agent orchestration template with YAML flow definitions, staged test contracts, and BDD traceability" readme = "README.md" requires-python = ">=3.13" diff --git a/uv.lock b/uv.lock index b24b74c..f0c90b2 100644 --- a/uv.lock +++ b/uv.lock @@ -1103,7 +1103,7 @@ wheels = [ [[package]] name = "temple8" -version = "10.1.0" +version = "10.2.0" source = { editable = "." } [package.optional-dependencies]