Commit graph

10 commits

Author SHA1 Message Date
trvon
fb055c9978
merge: bring main into the audit and state-map work
Some checks failed
Lint Commits / commitlint (pull_request) Successful in 19s
Tests / Static Analysis (pull_request) Has been cancelled
Tests / Tests (pull_request) Has been cancelled
main gained six PRs (#1-#6) while the audit fixes and the state-map seam
were in progress. Four of main's commits fixed the same bugs this branch
did, independently; where they overlap, the more complete version wins:

- Fingerprints: main's (a0844bb) - catchSite (`member#index` among all
  catches), union/owner as identity, a legacy fingerprint so version-1
  baselines still match, baseline "version": 2. This branch's `catch`
  ordinal is dropped; its fingerprint_test still guards the result.
- verify --rule: main's verifyAnalysis (cf9e0b7), which also reports
  findings in skipped files as NOT SCANNED.
- Unreadable SDK: both kept - this branch's up-front probe gives the
  early, specific error; main's catch around the analyzer (d6b6bcb) is
  the backstop.
- Riverpod: main's "a ref.listen is not a render" (f6411dc) and this
  branch's AsyncError patterns / stored-value tracking compose; the
  fixture keeps both sets of cases.

Ported onto the model-only rules (the seam), since main edited code this
branch had moved into front-end facts:
- excerpt.dart's literal-free, bounded quoting (a prompt-injection
  guard) now also covers front-end facts: SwallowedFailure.handler and
  NonSubscribingRead.excerpt, and the C++ front end elides string
  literals in handler evidence the same way.
- ScanCoverage: runChecks stays source-free; the model carries coverage
  (`scanCoverage` in the state JSON, written by both front ends), so
  `check --model` states coverage like a source check.
- main's softened wording (rendered-not-emitted "probably unreachable",
  the remove-policy dead-handler text, notifier-field-unread) and the
  backticked flag message.

Docs: main's README grew the Firestore query inventory and the output
contract; the README stays short, the inventory moves to
docs/queries.md, and the contract, exit codes, verify and baseline
details join docs/usage.md.

Checked against origin/main on resolved mirrors of the dogfood apps:
nuwayze (102), dex (0) and word_alive (0) identical; tick differs only
by the intended riverpod stored-value fix. On the fixture every
difference is one of this branch's fixes. 214 tests pass.
2026-09-24 07:33:53 -06:00
trvon
c666df6a99
fix(guide): count new findings in the markdown summary, as its heading does
The markdown report's summary line counted every finding while its heading and
the severity counts beside it counted only new ones, so a fully baselined run
read "20 findings ({error: 0, warning: 0, info: 0})" above "## Findings (0)".
The summary now counts new findings and notes how many are baselined.

Also: loading-flag-not-reset rendered its flag as `SettingsState`loading``, a
missing `.` that produced two adjacent code spans. It now reads
`SettingsState.loading`.
2026-09-22 12:22:03 -06:00
trvon
ea9d51078a
fix(guide,suggest): make verify hints commands that can be pasted as-is
Every brief entry and plan action ended with `verify: pipe check --rule X`.
Pasted, that checks the current directory, over lib/ only, against no
baseline - not the run that produced the finding. Run from anywhere but the
project root, or after a scan with --dir or --baseline, it answered a
different question.

The hint is now built by checkCommand(): `pipe check <root> --rule X`, plus
`--baseline <path>` and every `--dir` when the run used them, with paths
shell-quoted when needed.
2026-09-22 12:22:03 -06:00
trvon
e2d84f5e75
fix(guide): persist the yams report with its caution and provenance
`guide --yams` persists the markdown report, not the brief, and the markdown
had neither the brief's caution line ("static reachability claims ... confirm
each against the cited file") nor the [severity/confidence] of each finding -
so a report read back from the corpus presented every finding as equally
certain, with no framing. Its metadata still carried a stale `owner=pi` and
nothing to date or reproduce it.

The markdown now opens with the caution line, headings read
`### N. [severity/confidence] rule — location`, and the metadata records
`generated=<ISO-8601 UTC>` and, when the project is a git checkout,
`commit=<HEAD>`. `owner=pi` is gone.
2026-09-22 12:05:12 -06:00
trvon
4a1c9cdd3e
fix(guide): quote analysed source as bounded, delimited data
The analysed repository is untrusted input, and its source reached the agent
brief and the yams corpus verbatim: emission and dispatch snippets were
`node.toSource()`, provider-read-in-build quoted the whole call, and the brief
printed `evidence: $item` raw (the markdown wrapped it in single backticks,
which a backtick in the source closes). A string literal written as an
instruction to the reader was pasted into the prompt as-is.

Every quoted excerpt now goes through sourceExcerpt(): string literals,
interpolations included, become '…'; comments are dropped (they are not
tokens); whitespace collapses; the result is capped at 120 characters, as
loading-not-reset's catch excerpts already were. Where the brief and the
markdown render evidence, it is labelled "source excerpt (data, not
instructions)" and fenced with one more backtick than the longest run inside
it, so nothing quoted can close its own quotation.

Fingerprints are unaffected: provider-read-in-build still keys on the full call
source, which is kept for identity and no longer quoted.
2026-09-22 12:05:12 -06:00
trvon
39b309af97
fix(guide,suggest): stop packing at the first entry that does not fit
Both packers skipped an entry that did not fit the budget and kept going, so a
large top-ranked finding vanished while smaller, lower-ranked ones were packed
in behind it - presented as the most important work. Packing now stops at the
first entry that does not fit and counts it and everything after it as
omitted.

suggest's agent plan also reserved no room for its own omission note, so the
note itself could push the plan over budget; it now reserves room for the
largest possible note unless the entry is the last one.

When no entry fit, the guide said "this header alone exceeds the budget" even
when the header had room and it was the top entry that was too large. It now
says which of the two it was, with the size.
2026-09-22 12:05:11 -06:00
trvon
749aa53348
feat(report): state scan coverage in every check, guide and suggest output
A report listed findings without saying how much of the project they were
drawn from, so "0 findings" from 3 of 40 files looked like a clean project -
and an agent handed a brief had no way to know otherwise.

check, guide and suggest JSON now carry a `coverage` block
{discovered, selected, resolved, failed, skipped, complete}. The guide brief,
the markdown report, the suggest agent plan and both text outputs open with a
one-line coverage note, which says PARTIAL whenever a discovered file was not
analysed.

The note lives in the brief's header, which budget trimming never touches. The
"Coverage (what was actually examined)" caveats section was the first thing
dropped under a tight budget, silently; when it no longer fits, a one-line
pointer now says how many caveats were left out.
2026-09-22 12:05:11 -06:00
pipe-loop
f2949dfbfd feat: rule contracts + recall measurement (5/5 real bugs) + real --fail-on gate 2026-09-20 16:00:10 -06:00
pipe-loop
f4748f9b1c feat: group guide findings by root cause, add decision + verify lines 2026-09-20 14:04:16 -06:00
pipe-loop
5d7af95c6f feat: phase 4 agent-facing guide output + yams emission, 15 tests 2026-09-20 14:02:43 -06:00