Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions tests/develop-agent-oracle-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ def run(name):
text=True, capture_output=True,
)
assert scenario_ok.returncode == 0, scenario_ok.stderr
static_gpio = subprocess.run(
[sys.executable, str(ORACLE), "validate", str(FIX / "static-gpio-is-not-blink.jsonl"), "greenfield-esp32c3"],
text=True, capture_output=True,
)
assert static_gpio.returncode != 0 and "temporal gpio" in static_gpio.stderr.lower(), static_gpio.stderr
for fixture in ("scenario-missing-manifest.jsonl", "scenario-empty-manifest.jsonl", "scenario-malformed-manifest.jsonl"):
missing_manifest = subprocess.run(
[sys.executable, str(ORACLE), "validate", str(FIX / fixture), "greenfield-esp32c3"],
Expand Down
27 changes: 26 additions & 1 deletion tests/develop-agent-oracle.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,21 @@ def report_payload(report: dict) -> dict:
return report


def passed_oracle_clause(event: dict, kinds: set[str], detail_pattern: str | None = None) -> bool:
for result in structured_results(event):
clauses = result.get("oracle_results")
if not isinstance(clauses, list):
continue
for clause in clauses:
if not isinstance(clause, dict) or clause.get("passed") is not True:
continue
if str(clause.get("kind", "")).lower() not in kinds:
continue
if detail_pattern is None or re.search(detail_pattern, str(clause.get("detail", "")), re.I):
return True
return False


def validate(events: list[dict], scenario: str | None = None) -> dict:
tools = [(i, e, tool_name(e)) for i, e in enumerate(events) if is_tool_event(e)]
if not tools:
Expand Down Expand Up @@ -388,7 +403,6 @@ def validate(events: list[dict], scenario: str | None = None) -> dict:
unsupported_ceiling = scenario == "unsupported-custom-board" and any(phase_outcome(e, "verify") is False for _, e, _ in verifies)
if not successful_verify and not (successful_run and successful_inspect) and not unsupported_ceiling:
raise Rejected("missing successful verify event or ordered run+inspect evidence")

compile_index = next(i for i, e, _ in compiles if phase_outcome(e, "compile") is True)
if not any(i < compile_index for i, _, _ in context):
raise Rejected("successful refreshed context must precede compile")
Expand Down Expand Up @@ -448,6 +462,17 @@ def validate(events: list[dict], scenario: str | None = None) -> dict:
passed = [item for item in compiles if phase_outcome(item[1], "compile") is True]
if not failed or not passed or failed[0][0] >= passed[-1][0] or not any(failed[0][0] < i < passed[-1][0] for i, _, _ in edits):
raise Rejected("compile recovery requires explicit failed compile -> focused successful edit -> explicit successful compile")
if scenario in {"greenfield-esp32c3", "compile-recovery-esp32c3"}:
if not any(passed_oracle_clause(e, {"serial"}) for _, e, _ in successful_verify):
raise Rejected("scenario requires passing serial oracle evidence")
if scenario in {"greenfield-esp32c3", "existing-stm32f103", "compile-recovery-esp32c3", "partial-led-wifi"}:
temporal = any(
passed_oracle_clause(e, {"gpio_edges", "gpio_period", "gpio_duty"})
or passed_oracle_clause(e, {"gpio"}, r"\btoggl(?:e|ed)\b")
for _, e, _ in successful_verify
)
if not temporal:
raise Rejected("scenario requires passing temporal GPIO evidence; a static high/low level is not a blink")

used = [(i, e, n) for i, e, n in tools if i in set(indices[:-1])]
return {
Expand Down
9 changes: 6 additions & 3 deletions tests/develop-agent-wiring-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,23 @@
prompts = json.loads((root / "tests" / "fixtures" / "develop-agent" / "prompts.json").read_text())
assert len(prompts) == 5
assert all("hardware_sensitive_facts" in prompt for prompt in prompts.values())
assert all("citation token returned" in prompt or "source must be exactly" in prompt for prompt in prompts.values())
assert all("citation token returned" in prompt or "returned citation token" in prompt or "source must be exactly" in prompt for prompt in prompts.values())
assert all("Do not delegate" in prompt and "this session" in prompt for prompt in prompts.values())
assert all("call labwired_context again" in prompt and "before compiling" in prompt for prompt in prompts.values())
assert all("Use labwired_compile" in prompt and "not a shell compile" in prompt for prompt in prompts.values())
assert "call labwired_verify directly" in prompts["greenfield-esp32c3"]
assert "labwired_verify directly" in prompts["greenfield-esp32c3"]
assert "do not start with labwired_run" in prompts["greenfield-esp32c3"]
assert "output summary" in prompts["greenfield-esp32c3"]
assert "never request full" in prompts["greenfield-esp32c3"]
assert "call labwired_verify directly" in prompts["existing-stm32f103"]
assert "labwired_verify directly" in prompts["existing-stm32f103"]
assert "output summary" in prompts["existing-stm32f103"]
assert "max_steps 50000000" in prompts["existing-stm32f103"]
assert "no external LED part" in prompts["existing-stm32f103"]
assert 'source must be exactly catalog:board:esp32-c3-supermini' in prompts["greenfield-esp32c3"]
assert 'source must be exactly catalog:board:stm32f103-blinky' in prompts["existing-stm32f103"]
assert 'source must be exactly catalog:board:esp32-c3-supermini' in prompts["compile-recovery-esp32c3"]
assert 'source must be exactly catalog:board:esp32-c3-supermini' in prompts["partial-led-wifi"]
for name in ("greenfield-esp32c3", "existing-stm32f103", "compile-recovery-esp32c3", "partial-led-wifi"):
assert "GPIO oracle state must be toggled" in prompts[name]
assert "never high or low" in prompts[name]
print("ok develop-agent wiring")
2 changes: 1 addition & 1 deletion tests/fixtures/develop-agent/fenced-report.jsonl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{"type":"tool","id":"e1","tool":"labwired_context","result":{"ok":true,"project":"fixture"}}
{"type":"tool","id":"e2","tool":"labwired_datasheet","result":{"ok":true,"citation":"doc:esp32c3-gpio"}}
{"type":"tool","id":"e3","tool":"labwired_compile","result":{"ok":true,"artifact":{"type":"firmware","path":"firmware.elf"}}}
{"type":"tool","id":"e4","tool":"labwired_verify","result":{"ok":true,"status":"model_verified","evidence":{"type":"verify","id":"verify-fixture"}}}
{"type":"tool","id":"e4","tool":"labwired_verify","result":{"ok":true,"status":"model_verified","evidence":{"type":"verify","id":"verify-fixture"},"oracle_results":[{"kind":"serial","passed":true,"detail":"serial contains alive"},{"kind":"gpio","passed":true,"detail":"GPIO8 toggled (gpio evidence)"}]}}
{"type":"text","id":"e5","part":{"type":"text","text":"All checks passed.\n\n```json\n{\"claim\":\"model_verified\",\"hardware_sensitive_facts\":[{\"fact\":\"GPIO8 drives the LED peripheral\",\"source\":\"doc:esp32c3-gpio\"}]}\n```\n\nSummary follows."}}
10 changes: 5 additions & 5 deletions tests/fixtures/develop-agent/prompts.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"greenfield-esp32c3": "Create PlatformIO Arduino firmware for ESP32-C3 DevKitM-1 that blinks the configured LED once per second and prints `alive` over serial. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile evidence, not a shell compile or project-local command. Ground every hardware-sensitive fact in returned project, part, datasheet, SDK, SVD, schematic, or netlist evidence. Call labwired_describe for esp32-c3-supermini; in the final manifest, source must be exactly catalog:board:esp32-c3-supermini, which that returned board id authorizes. Compile and verify both behaviors in the provisioned twin: serial evidence proves only serial, so use a GPIO oracle clause for the LED. For the temporal GPIO check, call labwired_verify directly with the firmware and combined serial plus GPIO oracle; do not start with labwired_run or reuse its run_id because edge capture must be armed before execution. Set output summary and never request full or peripherals because truncated evidence cannot certify. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Make the final response one JSON object: claim must be the exact string model_verified, and hardware_sensitive_facts must contain exactly one fact/source object. Never construct or paraphrase a citation.",
"existing-stm32f103": "Add a one-second heartbeat without restructuring this STM32F103 project. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile evidence, not a shell compile or project-local command. Ground pin and register choices in returned project, part, datasheet, SDK, SVD, schematic, or netlist evidence. Call labwired_describe for stm32f103-blinky; in the final manifest, source must be exactly catalog:board:stm32f103-blinky, which that returned board id authorizes. Preserve layout, compile, and verify the heartbeat in the provisioned twin with modeled GPIO evidence, not a serial substitute. For the temporal GPIO check, call labwired_verify directly with the firmware, a board/MCU-only diagram with no external LED part or wires, the PC13 toggled oracle, and max_steps 50000000; do not start with labwired_run or reuse its run_id because edge capture must be armed before execution. Set output summary and never request full or peripherals because truncated evidence cannot certify. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Make the final response one JSON object: claim must be the exact string model_verified, and hardware_sensitive_facts must contain exactly one fact/source object. Never construct or paraphrase a citation.",
"compile-recovery-esp32c3": "Create PlatformIO Arduino firmware for ESP32-C3 DevKitM-1 that blinks the configured LED once per second and prints `alive` over serial. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for every compile attempt, not a shell compile or project-local command. Keep the deliberate compiler error initially, use its diagnostic for one focused repair, then compile and verify both serial and LED behavior in the provisioned twin. Call labwired_describe for esp32-c3-supermini; in the final manifest, source must be exactly catalog:board:esp32-c3-supermini, which that returned board id authorizes. Serial evidence does not prove the LED, so require a GPIO oracle clause. For the temporal GPIO check, call labwired_verify directly with the repaired firmware and combined serial plus GPIO oracle; do not start with labwired_run or reuse its run_id because edge capture must be armed before execution. Set output summary and never request full or peripherals because truncated evidence cannot certify. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Make the final response one JSON object: claim must be the exact string model_verified, and hardware_sensitive_facts must contain exactly one fact/source object. Never construct or paraphrase a citation.",
"partial-led-wifi": "Create ESP32-C3 firmware that blinks the LED once per second and associates with Wi-Fi. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile evidence, not a shell compile or project-local command. Ground hardware facts. Call labwired_describe for esp32-c3-supermini; in the final manifest, source must be exactly catalog:board:esp32-c3-supermini, which that returned board id authorizes. Compile, verify LED behavior with a GPIO oracle clause, and report Wi-Fi as an uncovered gap unless association is independently checked. Serial evidence does not prove the LED. For the temporal GPIO check, call labwired_verify directly with the firmware and GPIO oracle; do not start with labwired_run or reuse its run_id because edge capture must be armed before execution. Set output summary and never request full or peripherals because truncated evidence cannot certify. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Make the final response one JSON object: claim must be the exact string partially_verified or compiled_only, and hardware_sensitive_facts must contain exactly one fact/source object. Never construct or paraphrase a citation.",
"unsupported-custom-board": "Build this unsupported custom-board firmware. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile attempt, not a shell compile or project-local command. Ground available hardware facts, compile, attempt the available verification path, and state the physical-confirmation ceiling exactly; never claim model or hardware verification without oracle evidence. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Make the final response one JSON object: claim must be the exact string compiled_only, and hardware_sensitive_facts must be a nonempty list of fact/source objects. Each source must be one exact citation token returned by a grounding tool; never construct or paraphrase a citation. One supported hardware fact is enough."
"greenfield-esp32c3": "Create PlatformIO Arduino firmware for ESP32-C3 DevKitM-1 that blinks the configured LED once per second and prints `alive` over serial. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile evidence, not a shell compile or project-local command. Call labwired_describe for esp32-c3-supermini; the final source must be exactly catalog:board:esp32-c3-supermini. Verify both behaviors by calling labwired_verify directly with the firmware and a combined serial plus GPIO oracle; do not start with labwired_run or reuse its run_id. The GPIO oracle state must be toggled, never high or low, because a static level is not a blink. Set output summary and never request full or peripherals. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Return only this JSON shape and nothing else: {\"claim\":\"model_verified\",\"hardware_sensitive_facts\":[{\"fact\":\"GPIO8 is the active-low board LED pin\",\"source\":\"catalog:board:esp32-c3-supermini\"}]}.",
"existing-stm32f103": "Add a one-second heartbeat without restructuring this STM32F103 project. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile evidence, not a shell compile or project-local command. Call labwired_describe for stm32f103-blinky; the final source must be exactly catalog:board:stm32f103-blinky. Preserve layout. Call labwired_verify directly with the firmware, a board/MCU-only diagram with no external LED part or wires, a PC13 GPIO oracle, max_steps 50000000, and output summary; do not start with labwired_run or reuse its run_id. The GPIO oracle state must be toggled, never high or low, because a static level is not a heartbeat. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Return only this JSON shape and nothing else: {\"claim\":\"model_verified\",\"hardware_sensitive_facts\":[{\"fact\":\"PC13 is the board heartbeat LED pin\",\"source\":\"catalog:board:stm32f103-blinky\"}]}.",
"compile-recovery-esp32c3": "Create PlatformIO Arduino firmware for ESP32-C3 DevKitM-1 that blinks the configured LED once per second and prints `alive` over serial. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for every compile attempt, not a shell compile or project-local command. Keep the deliberate compiler error initially, use its diagnostic for one focused repair, then compile successfully. Call labwired_describe for esp32-c3-supermini; the final source must be exactly catalog:board:esp32-c3-supermini. Call labwired_verify directly with the repaired firmware and a combined serial plus GPIO oracle; do not start with labwired_run or reuse its run_id. The GPIO oracle state must be toggled, never high or low, because a static level is not a blink. Set output summary and never request full or peripherals. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Return only this JSON shape and nothing else: {\"claim\":\"model_verified\",\"hardware_sensitive_facts\":[{\"fact\":\"GPIO8 is the active-low board LED pin\",\"source\":\"catalog:board:esp32-c3-supermini\"}]}.",
"partial-led-wifi": "Create ESP32-C3 firmware that blinks the LED once per second and associates with Wi-Fi. If the first labwired_context returns empty_context, resolve the board with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile evidence, not a shell compile or project-local command. Call labwired_describe for esp32-c3-supermini; the final source must be exactly catalog:board:esp32-c3-supermini. Call labwired_verify directly with the firmware and GPIO oracle; do not start with labwired_run or reuse its run_id. The GPIO oracle state must be toggled, never high or low, because a static level is not a blink. Set output summary and never request full or peripherals. Report Wi-Fi as an uncovered gap unless association is independently checked, so do not claim model_verified. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Return only this JSON shape and nothing else: {\"claim\":\"partially_verified\",\"hardware_sensitive_facts\":[{\"fact\":\"GPIO8 is the active-low board LED pin\",\"source\":\"catalog:board:esp32-c3-supermini\"}]}.",
"unsupported-custom-board": "Build this unsupported custom-board firmware. If the first labwired_context returns empty_context, resolve available board information with list/describe, then call labwired_context again with pack.board and pack.mcu and require ok true before compiling. Use labwired_compile for the compile attempt, not a shell compile or project-local command. Ground one available hardware fact in a returned part, datasheet, SDK, SVD, schematic, netlist, or project citation. Attempt the available verification path, state that physical confirmation is still required, and never claim model or hardware verification without oracle evidence. Do not delegate or start a subagent; keep every tool call and all evidence in this session. Return only a JSON object with claim exactly compiled_only and one hardware_sensitive_facts fact/source object whose source is an exact returned citation token."
}
2 changes: 1 addition & 1 deletion tests/fixtures/develop-agent/scenario-empty-manifest.jsonl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{"type":"tool","id":"e1","tool":"labwired_context","result":{"ok":true,"project":"fixture"}}
{"type":"tool","id":"e2","tool":"labwired_datasheet","result":{"ok":true,"citation":"doc:part"}}
{"type":"tool","id":"e3","tool":"labwired_compile","result":{"ok":true,"artifact":{"type":"firmware","path":"firmware.elf"}}}
{"type":"tool","id":"e4","tool":"labwired_verify","result":{"ok":true,"status":"model_verified","evidence":{"type":"verify","id":"verify-fixture"}}}
{"type":"tool","id":"e4","tool":"labwired_verify","result":{"ok":true,"status":"model_verified","evidence":{"type":"verify","id":"verify-fixture"},"oracle_results":[{"kind":"serial","passed":true,"detail":"serial contains alive"},{"kind":"gpio","passed":true,"detail":"GPIO8 toggled"}]}}
{"type":"final","id":"e5","result":{"claim":"model_verified","hardware_sensitive_facts":[]}}
Loading