Skip to content

Derive per-file change facts from captured comparisons - #22

Merged
rcosteira79 merged 11 commits into
mainfrom
feat/briefing-grounding-part-1-derive-change-facts-per-changed-file
Nov 4, 2026
Merged

rcosteira79 merged 11 commits into
mainfrom
feat/briefing-grounding-part-1-derive-change-facts-per-changed-file

Conversation

@rcosteira79

Copy link
Copy Markdown
Collaborator

What

  • loadChangeFacts(comparison) reports, for every changed file of a captured comparison, its language, a completeness state, and facts parsed from both sides: changed declarations, calls added or removed on changed lines with their enclosing declaration, and test names marked by whether a change touches them.
  • Every changed line of a TypeScript, TSX or Kotlin file sits inside a fact's range or in the file's unattributed ranges.
  • Completeness says why facts are missing: an unsupported language, or a skip as generated, oversized, unreadable, unparseable, over the time limit or over the analysis limit. A capped list reports how many it shows of how many.
  • The declaration diff in src/semantic-diff.ts now exports its language table, language detection, parser and declaration recogniser, and names which limit stopped an analysis.
  • GLOSSARY.md is committed, and the CI jobs that run bun test fetch full history.

Why

An agent writes every claim in a Briefing, and the server proves only that a cited excerpt exists in the captured tree. Nothing tells the reader which parts of the diff the story never mentions. A later trust layer needs facts the server derives itself from the captured trees, and these are the first. Nothing consumes them yet.

Decisions and trade-offs

Choice Why
Only leaf tests become test facts, not describe blocks A block-level fact would attribute every changed line inside it
Caps keep old-side facts first: 1,000 calls and 500 tests per file The completeness state reports the cut, so it is never silent
Test titles keep the literal's raw source text, escapes included A decoded title would no longer match the line it came from
Each analysed file is parsed a second time for calls and tests The declaration diff keeps its trees private; sharing them would change its interface
Each language keeps its own test-path rule A TypeScript helper under src/test/ is not a test by path alone

Most needs scrutiny: the changed-line partition in src/change-facts.ts:74 — check that a skipped file lists every changed line and that each fact range is matched against its own side. No ADR was added or amended on this branch.

How to test

From this branch, print the facts for one historical change:

bun -e 'import { loadChangeFacts } from "./src/change-facts.ts"; import { historicalComparison } from "./tests/comparison-fixtures.ts"; for (const f of (await loadChangeFacts(await historicalComparison("57bf907", "27b7e44"))).files) console.log(f.path, f.completeness.state, f.symbols.length, f.calls.length, f.tests.length, JSON.stringify(f.unattributed));'

You should see src/types.ts skipped, README.md and package.json unsupported, and tests/ui.test.ts listing test facts. Pick one file you know and judge whether its unattributed ranges are the lines you would expect no fact to explain. Then open this pull request's foundation job and confirm its checkout fetched full history.

@rcosteira79
rcosteira79 added this pull request to stack #25 October 29, 2026 12:47
@rcosteira79
rcosteira79 force-pushed the feat/briefing-grounding-part-1-derive-change-facts-per-changed-file branch from 6fa7791 to 48e5b64 Compare November 4, 2026 17:35
@rcosteira79
rcosteira79 merged commit b803264 into main Nov 4, 2026
22 of 25 checks passed
@rcosteira79
rcosteira79 deleted the feat/briefing-grounding-part-1-derive-change-facts-per-changed-file branch November 4, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant