fix(guide,suggest): word agent guidance no stronger than the evidence #2

Merged
trevon merged 13 commits from docs/honest-agent-guidance into main 2026-09-22 21:19:58 +00:00
4 changed files with 31 additions and 4 deletions
Showing only changes of commit c666df6a99 - Show all commits

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`.
trvon 2026-09-22 12:02:49 -06:00
Signed by: trevon
GPG key ID: 38686EA797D7A8A7

View file

@ -598,9 +598,11 @@ Guidance buildGuidance({
..writeln()
..write(coverageLine == null ? '' : '$coverageLine\n\n')
..writeln(
// New findings only, matching the heading below and countBySeverity,
// which already counted only new ones.
'${flow.unions.length} blocs/cubits, ${summary['stateVariants']} state '
'variants, ${report.findings.length} findings '
'(${report.countBySeverity}).',
'variants, ${report.newFindings.length} new findings '
'(${report.countBySeverity})$baselinedNote.',
)
..writeln()
..writeln('## Findings (${ranked.length})');

View file

@ -1172,8 +1172,9 @@ class _FlagLoadingCollector extends RecursiveAstVisitor<void> {
severity: PipeSeverity.warning,
confidence: setsFlagTrue && !awaitedTrySeen ? 'high' : 'medium',
message:
'$owner.$member awaits work after putting ${flag.name}`$fieldList` '
'into its loading state, and no catch clause surfaces a failure, so '
'$owner.$member awaits work after putting '
'`${flag.name}.$fieldList` into its loading state, and no catch '
'clause surfaces a failure, so '
'the UI can keep showing its loading state after an error.',
file: project.relative(path),
line: lineInfo.getLocation(body.offset).lineNumber,

View file

@ -39,6 +39,9 @@ void main() {
expect(hits.single.confidence, 'high');
expect(hits.single.evidence, isNotEmpty);
expect(hits.single.remediation, isNotNull);
// The flag reads as one code span, `FlagState.loading`, not as
// `FlagState` immediately followed by a second span.
expect(hits.single.message, contains('`FlagState.'));
});
test('flag findings carry no false positive for guarded code', () {

View file

@ -200,6 +200,27 @@ void main() {
);
});
test('the markdown summary counts the same findings as its heading', () {
// The summary counted every finding while the 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})" over "## Findings (0)".
final baselined = runChecks(
project: analysis.project,
outcomes: analysis.run.outcomes,
flow: analysis.flow,
baseline: {
for (final finding in analysis.report.findings) finding.fingerprint,
},
);
final md = buildGuidance(
root: analysis.project.root,
flow: analysis.flow,
report: baselined,
).markdown;
expect(md, contains(' 0 new findings '));
expect(md, contains('## Findings (0)'));
});
test('json summary exposes counts and suppression notes', () {
final summary = guidance().summary;
expect(summary['findings'], analysis.report.findings.length);