% Copyright (c) 2026 Rana Umar Nadeem, Samrah Mumtaz, Muhammad Imran # Failure Analysis When an iteration holds a failed task, the orchestrator diagnoses the first failed result with `mace.triage.triage()` and feeds the diagnosis into the next plan. Other failed tasks in that level get a row in the `tasks` table and no triage. ## Triage `triage(result, llm, tools=(), objective="", rtl_edits=False, narrowing="")` makes one LLM call. The orchestrator passes the run's objective, which leads the prompt: it can name what a build needs, such as an RTL define the failed plan left out. The prompt gives the task's id, kind, and instruction, the build outcome, the run verdict, and the build's `sims` flags, which name its RTL defines and cache sizes. A line of changes from the defaults picks out the plan's own choices among them: the RTL defines it adds, each cache whose geometry differs, and a crossbar interconnect (`changes_from_defaults()`). A failed build adds the failure reason, its error lines (see [PitonBuildArtifact](../04_chia_openpiton/workspace_node.md)), and the last 1500 characters of its stderr, or of its stdout when stderr is empty, as `sims` leaves it. A failed run adds the last 1500 characters of the simulation log and up to 8000 characters of the status log. When the build carried RTL edits, the prompt then adds their diff, up to 3000 characters, and the feedback line below adds it too. For an `rtl` task whose agent recorded no edit, the prompt says so and quotes up to 600 characters of the agent's reply. The prompt then says what the next plan can change: the build configuration only (RTL defines, cache sizes and associativity), or, under `LoopOptions(rtl_edits=True)`, also files under `piton/design/` (`ACTIONS_NO_RTL`, `ACTIONS_RTL`). Without RTL edits, a failure no configuration can fix gets the label `needs_rtl_change`. It adds that each change from the defaults is a candidate cause, to rule out before blaming the design. The prompt asks for two directive lines: ```text DIAGNOSIS: FIX: ``` `parse_diagnosis()` returns the last `DIAGNOSIS:` value, lowercased, and `parse_fix()` the last `FIX:` value; a missing fix is recorded as empty. `KNOWN_DIAGNOSES` lists the six labels, but any label is recorded. Without a `DIAGNOSIS:` line, triage raises `TriageError`, and the orchestrator records `unknown` with the fix `retry with more context`. A failed `unit_test` build whose output contains `%Error-PINNOTFOUND` skips the LLM call and gets `testbench_mismatch`, with a fix aimed at the testbench's port connections rather than the module. The orchestrator narrows a failed `config` or `workload` task before it triages it (see [Fixed Checks](fixed_checks.md)). When the probes name the change to undo, triage does not run, and the failure is recorded as `config_change` with that fix. When they settle nothing, `narrowing` adds the probes' note to the end of the context above, so triage knows which causes the rebuilds ruled out. ## Diagnostic Tools When Ray is initialized, the orchestrator starts a `PitonToolServer` named `triage-` on the first checkout for each triage. It stops the previous server first and hands the new one the failed task's build and run. It exposes four read-only tools: | Tool | Returns | |---|---| | `grep` | Regex matches from the run's `sim.log`, `status.log`, or `fake_uart.log` | | `collect` | Small text files from the run directory, by glob | | `compare_to_fixture` | The first divergence between `sim.log` and a reference transcript in `chia_openpiton/test/fixtures/` | | `symbol_check` | `objdump -f` and `-t` output for the run's `diag.exe`, beside its `symbol.tbl` | A task that failed at build has no run, and the tools report an error for it. Triage gets the caller's tools plus this server. If the server fails to start, the run goes on without it. The last server also serves the post-mortem and stops when the run ends. See [Tool Server](../04_chia_openpiton/tool_server.md). ## Replanning `record_failure()` writes the diagnosis to the `failures` table, and `replan_feedback()` writes a note for the run's feedback history: ```text Task () failed (build succeeded: , run verdict: ). Changes from the defaults: What the build and simulation reported: Triage, an LLM's reading of this evidence: diagnosis=