Repository navigation
feat(report)!: target commit, remediation, simplified Markdown, and an always-numeric spend estimate (#1268) - #1276
Conversation
Add required run_metadata.target_commit (hex SHA-1/SHA-256 or null) read from the sealed data-governance record, render it as the Run summary Commit row in place of Source run ID, keep it through the public projection, and add the optional run.json spend_estimate contract with the shared formatEstimatedSpendUsd formatter (#1268). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…and numeric spend Update the final-report prompt, output-contract templates, prompt structure tests, reference docs, and CHANGELOG for the Commit row, removed diagnostic sections, Remediation, readable inline code, and the always-numeric spend estimate (#1268). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…te (#1268) Resolve each model's catalog price only from the provider its ID routes to (OpenRouter for gateway IDs, the first-party provider otherwise), reject all-zero rates except :free, strip context aliases for lookup, and return per-model provenance. Add the spend estimator with the dated fallback table, default attempt usage, unaccounted-attempt imputation and source-run lineage; synchronize run.json#spend_estimate with accounting on every pass, including runs whose agent attempts reported no usage; and make the live report-start metrics numeric from the same estimator. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…on and readable inline code (#1268) Stop rendering Scoped coverage evidence and Artifact validation warnings in report.md (report.json and the public warning companions keep them), state unmeasured or incomplete scoped coverage in a fixed notice after the Run summary, end every production issue with Remediation (the carried recommendation or a fixed fallback), and render finding prose with findingProse so backtick spans stay inline code while publicProse stays frozen for every other field. The public projection now redacts a path written after a literal backslash, a word-starting pipe, or a literal <, and its Markdown re-scan no longer reads the renderer's own escapes as path syntax. The final-report gate now rejects a scoped coverage section or exact-scope score with REPORT_COVERAGE_EVIDENCE_MARKDOWN_UNEXPECTED, a report row that adds a recommendation its source lacks fails both report loops, and public bundles require both warning companions when the report carries warnings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…report Project the report-start spend from run.json spend_estimate (or the live estimate), add an imputed estimate for the in-flight report attempt, keep tokens, spend and partial_pricing from one source, restate spend from spend_estimate in terminal and unchecked presentations, require the numeric estimated_spend pattern, persist a host-only copy of the projection for restarted verifiers, and align ultrafuzz report diagnostics (#1268). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… secret re-scans, and tables (#1268) - Start-of-block escapes apply only where finding prose opens a block (description, Remediation, Proof of Concept steps, disposition entries), so a title opening with `[` or a redacted leading path keeps its index link. - The Markdown path re-scan treats `\*`, `` \` ``, `<`, and `>` after a slash, and `>` before one, as the renderer's escapes; `>` is now a path boundary in report.json, so a real path after `>` is still redacted. - The speculative secret pass reads one rendered unit at a time (each line split at table pipes and bold delimiters, each fenced block whole) while positive detections still read the whole document, so prose ending in `token:` no longer fails the public projection. - Finding titles in the provenance table, prior dispositions, and the non-production outcomes table render as finding prose with pipes escaped. - An unselected reference-expectation property ID holding `<` or `>` renders as escaped text instead of raw HTML inside a code span. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ult usage at base rates (#1268) The spend estimate joined attempts to usage by (workflow run, node, iteration, attempt), so after `resume --retry-failed` / `--reset-node` two occurrences sharing an attempt number collapsed into one imputation, and usage on either one hid the other. It also skipped attempts of a workflow run that a replay or fork replaced while still pricing that run's usage, so the estimate dropped and could claim completeness. - An occurrence is now an attempt-ledger entry (workflow_run_id, source_event_sequence). A usage event belongs to the occurrence of its workflow run, Smithers task, iteration, and attempt whose start and terminal events span its sequence; each occurrence is priced from its own latest snapshot and an executed agent occurrence with none is imputed, across every workflow run of the run. The Smithers task ID is `node:<strategy_attempt_id>`, which every task manifest enforces. - `spend_estimate.unaccounted_attempts.entries` carry `workflow_run_id` and `source_event_sequence` and are unique by them (schema, semantic check, builder, docs). - Default-usage imputation prices catalog models at base rates; the 2,000,000-token default total no longer selects a context tier. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…v4 route lookup (#1268) Accounting v4 records pricing_catalog.status "available" when the catalog was fetched (or no model had a route) yet some models stay unresolved; route-exclusive pricing makes that common. The Modal worker-result gate rejected that state, failing status.json/result.json writes and reads. Drop the rule; uncosted events of an unresolved model still require usage.partial_pricing through the existing unpriced-event check, and the unavailable/disabled consistency rules stay. The #1268 changelog bullet now says v4 keeps its labels and semantics but looks up newly priced models through the route-exclusive catalog, so some models an aggregator used to price are now unresolved in v4. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…c path redaction Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
| const occurrences = spendEstimateAttemptOccurrences(replayNodeAttempts(input.layout).entries, input.usageEntries); | ||
| const unaccountedAttempts = occurrences.unaccounted; | ||
| const previous = input.metadata.spend_estimate; | ||
| if (input.usageEntries.length === 0 && unaccountedAttempts.length === 0) return { changed: previous !== undefined }; |
There was a problem hiding this comment.
Source spend disappears When a continuation has a source run but no local usage or executed agent attempts, this return skips the source-run estimate. The continuation’s synchronized
run.json then has no spend_estimate or spend lineage, even if the source run has a persisted estimate.
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/runtime/src/workflow-sync.ts
Line: 1493
Comment:
**Source spend disappears** When a continuation has a source run but no local usage or executed agent attempts, this return skips the source-run estimate. The continuation’s synchronized `run.json` then has no `spend_estimate` or spend lineage, even if the source run has a persisted estimate.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.…iation-spend - Take #1275's deletion of data-governance.ts and its test - Read the final report's target_commit from the task's normalized source revision instead of the removed governance record - Drop the verifier harness's governance environment and binding Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Delete spend-estimate.ts, final-report-run-summary.ts and their tests: no default attempt usage, mean imputation or report-start self-imputation - Remove run.json#spend_estimate (schema, types, semantics, start-run strip) and restore base single-pass accounting synchronization - Remove restated_run_metadata and the host-only final-report run metadata record; a restarted verifier re-derives the projection as on base - Report start copies accounting v4's USD amount, else the source run's for an unsynchronized continuation, else the direct run's live usage, else zero usage; runtime presentations restate only from accounting - Live metric spend is numeric (no +) and counts unpriced attempts - `ultrafuzz report` no longer demands a + suffix and accepts $0.00 - Drop catalog provenance and zero-rate bookkeeping from pricing results Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- report@3 target_commit is a lowercase 40-hex commit or null; the 64-hex branch belonged to the removed governance record - Document it as task.sourceRevision / run.json source_revision - Contract and renderer tests no longer accept a 64-hex commit Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ce table inside accounting v4
- Add ultrafuzz.fallback-pricing.2026-10-05: the models.dev cost objects
of gpt-5.5, claude-opus-4-8, kimi-k3 and deepseek-v4-pro, priced
through the same route lookup, so gateway and unknown IDs stay unpriced
- resolveLiveModelPricing prices what the catalog left unpriced from the
table whatever the catalog status and records metadata.fallback
- Accounting v4 snapshots and pins those rates in model_prices, keeps the
models unresolved and records pricing_catalog.fallback {table, models};
stats, evals and Modal reprice from the same snapshot
- Validate fallback in the stored accounting reader and the run.json schema
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- New run.json root member attempts_without_usage {attempts,
cumulative_count}: executed agent attempt occurrences with no usage
event in their own event window, across every workflow run of the run
- cumulative_count adds the source run's count; the member is absent at
zero, written on every pass (including an empty usage ledger), and kept
across workflow replacement since each pass recomputes it
- Split sourceRunMetadata out of the source accounting reader
- Schema, type and semantics (unique occurrences, count >= list length)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- runSummaryUsage, in terminal-report-projection.ts, is the one reader of the Run summary's usage figures for the report-start projection and both runtime presentations: v4's USD amount, partial_pricing and unpriced event count, plus run.json's attempts_without_usage count - Runtime presentations restate the accounting fields together and the attempts-without-usage count on its own; without accounting the agent's copy stays - report@3 run_metadata gains optional attempts_without_usage and unpriced_attempts (positive integers) - report.md renders "(excludes N agent attempt(s) whose usage was not recorded or could not be priced)" after the spend and "Models used: `none` (no model usage was recorded)" for an empty list Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…an error - A changed or omitted recommendation on a $.issues row, which report.md renders as the issue's Remediation, now fails verification in both the severity-classified and the bounded report loops - It stays a warning on non_production_outcomes, which never render it - An added recommendation stays an error on every row Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…the same boundaries as rooted paths - A differential fuzz (2,000 path-heavy prose inputs per build, five fields, four seeds) showed the PR publishing `\~/secret`, `*C:\Users\bob\key` and `\C:\...` unredacted where the base renderer failed closed - Patterns 3-5 now start after `;`, `>`, `\`, `*` or a word-starting `|` like the `/`-rooted pattern (which still excludes `*`, so `**` globs stay readable); the Markdown re-scan and the slash-run normalizers mirror it with the renderer-escape lookbehinds and the escaped `\~` - Against the PR head: 433 leaking inputs fixed, none added, no new fail-closed projections and no fixed-point failures Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…nd the source-revision commit - artifacts-reports.md: Commit is the run's source revision; Estimated spend is v4's USD amount with the exclusion clause; pricing order with the versioned fallback table; where run.json records pricing_catalog, completeness and attempts_without_usage; the component-rate gap - final-report prompt: the agent only copies run_metadata; no spend or imputation prose; the renderer writes the clause and the none line - cli.md, config docs and the Modal guide follow the new behaviour - Rewrite the #1268 CHANGELOG bullet, with the cross-release caveat Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- report.json target_commit equals run.json source_revision and the fixture HEAD, and report.md shows it - run.json lists the SIGKILLed attempts without usage, gpt-5.5 is priced from the fallback table, and the spend line is v4's formatted amount with the exclusion clause - ultrafuzz stats reports the same spend Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…orm and satisfy strict lint - report.schema.json states the counts as exclusiveMinimum 0, as the zod export renders positive integers - Split the long run-summary usage harness test and drop non-null assertions from the new run-documents test Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- mergedPricingCatalogMetadata names the fallback table once, next to the models it priced, instead of guarding the table twice Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- When Moonshot does not list kimi-k3, accounting keeps it unresolved and prices it from the fallback table, never at another provider's rate Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sage - The resumed-report test's two report attempts recorded no usage, so the terminal publication restates attempts_without_usage and the spend line counts them Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…arrow the runtime export - Live report-start metric: with no usage events, report `$0.00` excluding every attempt instead of no figure and no count - Count attempts Smithers aggregated without a usage event in unpriced_attempts - Re-export only runSummaryUsage from terminal-report-projection - Docs: superseded-occurrence and late-usage gaps of attempts_without_usage, event count equals attempt count, sub-floor rounding of formatEstimatedSpendUsd Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…iation-spend Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…on note
- Owner decision (2026-10-06): report.md carries no "(excludes N agent
attempts ...)" note; `Estimated spend` is `$X`, or `$X+` when the amount
is probably low, and never `unavailable`
- reportSpendIsProbablyLow / reportEstimatedSpend in @ultrafuzz/artifacts
decide the `+`: partial_pricing true, or attempts_without_usage or
unpriced_attempts present; the counts stay in run.json and report.json
- report@3: estimated_spend matches ^\$(?:0|[1-9][0-9]*)\.[0-9]{2,10}\+?$,
and an Ajv if/then/else plus a Zod refinement reject a `+` that disagrees
with those fields
- The report-start projection, terminal and unchecked restatements apply the
rule after restating the counts, so a report-start `+` drops once the
whole run is fully priced
- The renderer prints estimated_spend verbatim and its Markdown check
requires the spend row to equal it; the exclusion clause is gone
- `ultrafuzz report` expects the `+` whenever run.json says the amount is
probably low, and still accepts $0.00
- Tests: contract parity for the `+` rule, renderer, projections, unchecked
reports, CLI diagnostics, campaign e2e, and a coverage-scan check that
`$38.72+` is not read as a score
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- artifacts-reports.md: the `+` rule and its three conditions, examples without an exclusion note, restatement resets the `+`, v4's own label never reaches the report - cli.md: `ultrafuzz report` expects the `+` when run.json says the amount is probably low - final-report prompt: copy the spend with its `+` exactly and never add a note - CHANGELOG #1268 bullet follows Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…iation-spend Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-spend Resolve the CHANGELOG.md conflict by keeping both breaking-change entries. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Comments Outside DiffThese findings could not be posted inline.
|
…-spend Resolve the CHANGELOG.md conflict by keeping both breaking-change entries. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Summary
Implements #1268. The final report now:
Commitrow;report.md;### Remediationsection and renders backtick spans in finding prose as inline code;Estimated spend, taken from accounting v4, with a trailing+when the amount is probably low.The prompt, report contract, renderer, gates,
ultrafuzz reportdiagnostics, docs and tests change together.Source run IDrow is replaced by- Commit: <hash>.report.jsonrun_metadata.target_commitis required: the run's source revision (run.jsonsource_revision, the commit every task worktree is created from), a lowercase 40-hex string, ornullwhen the run recorded none.nullrenders as- Commit: `none` (no Git commit was recorded for the evaluated target).source_run_idandsource_run_idsstay inreport.jsononly.report.mdno longer renders## Scoped coverage evidenceor## Artifact validation warnings.report.jsonkeepscoverage_evidenceandrun_metadata.artifact_validation_warnings.report.md(REPORT_COVERAGE_EVIDENCE_MARKDOWN_UNEXPECTED) instead of requiring the section.artifact-validation-warnings.jsonand.mdwhenever the report carries warnings.### Remediation: the source finding'srecommendation, or a fixed sentence saying no remediation was recorded.recommendation. On a production row, adding, changing or omitting it is a verification error. On a non-production row, adding one is an error and changing or omitting one is a warning.What changed vs the original PR
run.json#spend_estimateestimator is removed. There is no imputation, no default attempt usage, and no self-imputation of the report task.restated_run_metadataand the host-only projection copy are gone too. The amount is always accounting v4'saccounting.cumulative.estimated_spend_usd, the same numberultrafuzz stats, evals and Modal read.ultrafuzz.fallback-pricing.2026-10-05holds the models.dev list prices of that date forgpt-5.5,claude-opus-4-8,kimi-k3anddeepseek-v4-pro. v4 uses it for a model the catalog left unpriced, whether the catalog is available, unavailable or disabled. It looks models up through the same routes, so gateway and unknown IDs stay unpriced. The rates are pinned inpricing_catalog.model_prices, andpricing_catalog.fallbackrecords the table and the models it priced.run.jsongainsattempts_without_usage(attempts,cumulative_count), the executed agent attempts with no usage event of their own, including source runs.report.jsonrun_metadatagains the optional countsattempts_without_usageandunpriced_attempts.$Xor$X+. Following the owner decision of 2026-10-06,report.mdcarries no note about excluded attempts. The structured counts stay inrun.jsonandreport.json, and they decide the+.target_commitcomes from the run's source revision. refactor!: remove campaign data governance (#1269) #1275 removed the data-governance record the original PR read. The 64-hex form is gone.spend_estimateis gone, v4's cumulative accounting already includes source runs, and a continuation without its own accounting uses its source run's accounting.ultrafuzz reportdiagnostics accept$0.00, never expectunavailable, and expect the+wheneverrun.jsonsays the amount is probably low.unstable.Spend rule
Amount. Accounting v4's
estimated_spend_usd, with two decimals from one cent up and four to ten decimals below one cent (for example$38.72and$0.0012). It is$0.00when nothing was priced and neverunavailable.Pricing order. For each attempt's latest usage event, v4 uses the first of: the cost the adapter recorded, the price from the model's catalog route, or the fallback table.
The
+. The spend ends in+exactly when at least one of these holds:partial_pricingis true;attempts_without_usageis present (some attempts recorded no usage);unpriced_attemptsis present (some usage could not be priced).The
+means "there is probably more". With no+, everything recorded was priced and every attempt recorded usage.Where it is enforced.
reportSpendIsProbablyLowandreportEstimatedSpendin@ultrafuzz/artifactsare the only place the+is decided.ultrafuzz reportall use them. The restatements set the+again after they restate the counts.report@3schema enforces the rule in both Ajv (if/then/else) and Zod. The pattern is^\$(?:0|[1-9][0-9]*)\.[0-9]{2,10}\+?$.run_metadata.estimated_spendexactly.Accounting v4's own label is unchanged. Its
estimated_spend($x+orunavailable) stays inrun.jsonforstats, and benchmark analysis passes it through as before. It never reaches the report.Breaking changes
ultrafuzz/report@3and therun.jsonschema change in place:run_metadata.target_commitis required.+against the counts.run.jsongainsattempts_without_usageandpricing_catalog.fallback.run.jsonthat this release has synchronized. Finish a run launched on an earlier release with that release.report.md, so its scores are not comparable across this release..ultrafuzz/prompts/review/final-report.mdand rerunultrafuzz init.Tests
+rule for each of the three conditions (contract-fixtures.test.ts). The shared formatter's output is valid with and without+.+. An unavailable, annotated, mismatched or+-inconsistent spend is rejected, and the counts are never rendered. The public projection is a fixed point (final-report-markdown.test.ts).+for partial pricing, unpriced attempts, attempts without usage, and accounting that priced nothing, and adds none for fully priced accounting (generated-workflow-verifier.test.ts).+again, including dropping a report-start+when the whole run was fully priced (terminal-report-projection.test.ts,unverified-report.test.ts,runtime.test.ts).$38.72+,$0.00+or$0.0008+as a coverage score (artifact-gates.test.ts).ultrafuzz reportflags a missing+and a spend above accounting, and accepts$0.00+and a fully priced spend without+(cli.test.ts). The campaign e2e checks thatreport.mdshows the v4 amount with+for the SIGKILLed attempts.pnpm -w format:check,lint,lint:strict:ci,docs:check,typecheckandknipall pass.runtime.test.jsreport publication, republication and accounting tests 7/7.generated-workflow-verifier: 122/124. The 2 failures ("a missing or unrenderable prompt fails only its own task at assert-task-inputs" and "generated Smithers verification marker root must be a canonical directory") fail the same way with the test code from before this change on Node 24.9.campaign-resume): 1/1.Closes #1268.
🤖 Generated with Claude Code
The PR appears safe to merge; no outstanding blocking finding was established.
Fix with agent prompt
Summary
The PR changes final-report presentation and accounting, and the latest revision replaces selector-filtered prompt authorities with per-attempt indexes of admitted ancestor outputs.
+.Reviews (3) · Last reviewed commit: "Merge branch 'unstable' into fix/1268-fi..."