fix(analysis): require a sealed snapshot for Architecture, remove fabricated metrics - #225
Merged
parthrohit22 merged 2 commits intoJul 27, 2026
Conversation
…ricated metrics Architecture fell back to record.file_tree and invented estimated_lines/ estimated_complexity from file counts when no sealed ri.v1 snapshot existed. It now 404s the same way Dependencies/Review/Insights already do, and every node reports an explicit not_computed size/complexity state instead of a guessed value. Extends the legacy-read-model guard to fail if any analytical consumer reads RepositoryRecord.file_tree.
…mplexity UI Adds the same noSnapshot empty state Dependencies already has to the Architecture page instead of silently rendering an empty graph. Removes the node complexity badge, the Complexity/Est. Lines inspector stats, and the Complexity/Size heatmap modes, since no producer measures any of them today; 'critical' and 'usage' heatmap modes are recomputed from real graph facts only.
24 tasks
parthrohit22
marked this pull request as ready for review
July 27, 2026 18:48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Architecture was the one flagship product surface still bypassing the sealed
ri.v1snapshot contract: it fell back torecord.file_tree(unsealedrepository metadata) when no snapshot existed, and it invented
estimated_lines/estimated_complexityfrom file counts(
max(len(module.files) * 80, 20), a file-count-derived guess) rather than areal measurement. This PR removes both violations so Architecture behaves
like every other consumer (Dependencies, Review, Insights): a sealed snapshot
or an explicit
missing_snapshot/not_computedstate, never a fabricatednumber.
Linked issue
Closes #217
Roadmap alignment
shipped claim maps to tested fact/evidence contracts."
verify and cite PARTHA evidence; reported false certainty is rare, measured,
and corrected."
the exact violating lines (
architecture.py:133,185, currentdev); thisPR's regression tests (
test_architecture_relationships.py,test_legacy_read_model_guard.py) fail on the old behaviour and pass on thenew one, verified locally (see Testing performed).
What changed
Backend
app/analysis/architecture.py:build_architecturenow requires a sealedsnapshot via
SnapshotQueryService.require_sealed_snapshot_for_current_revisionbefore building anything (raises
NotFoundError→ 404, same contract asDependencies/Review/Insights). Removed the
record.file_treefallback andthe now-dead
_persisted_file_pathshelper.estimated_complexity/estimated_linesare now always"not_computed"for every node(module and dependency) instead of a file-count-derived guess.
app/schemas/architecture.py:ArchNode.estimated_complexity/estimated_lineswidened to accept an explicit"not_computed"statealongside real values, so a future real heuristic can populate them without
another contract break.
app/reports/builders.py: dropped the "Size Class" export row that onlyever printed the fabricated complexity value.
app/api/routes/analysis.py: updated the/architectureOpenAPI 200example to reflect that 200 now always means a sealed snapshot backs the
response (no more "no sealed snapshot" diagnostic in a 200 example).
tests/test_legacy_read_model_guard.py: extended with a new AST guard,test_analytical_consumers_never_read_repository_file_tree, that fails ifany file under
app/{analysis,graph,review,insights,ai,reports}reads.file_tree— the contract test the issue's acceptance criteria asked for.Frontend
useArchitecture.ts/ArchitecturePage.tsx: added the samenoSnapshotempty state Dependencies already has ("No sealed snapshot yet — Run
analysis") instead of the page silently reaching
!architecture.modelwithno useful next action.
ArchitectureNode.tsx,NodeInspector.tsx: removed the complexity badgeand the Complexity/Est. Lines inspector stats — they only ever displayed the
fabricated value. The accessible name no longer claims a complexity that
wasn't measured.
layout.ts,HeatmapControls.tsx,shared/types/architecture.ts: removedthe
complexityandsizeheatmap modes (zero real signal existed foreither);
criticalis recomputed from dependents-count and file-count only,both real graph facts.
Acceptance criteria completed
Dependencies/Review/Insights) when no sealed
ri.v1snapshot exists — no200 fallback graph.
estimated_lines/estimated_complexityvalue not backed by a snapshot fact — every node nowreports
"not_computed".RepositoryRecord.file_treeorrepo_metadatafor analytical output.productSurfaces.test.tsx/accessibility.test.tsxstill pass (verified— neither asserts on Architecture-specific fields, unaffected).
npm run build:frontendand backend pytest pass;test_openapi_contract.pypasses unchanged (no field was removed, only widened).
Testing performed
Screenshots
Not applicable (empty-state text/badge changes only; no new visual surface —
the "No sealed snapshot yet" state reuses the existing
EmptyStatecomponentalready visible on the Dependencies page).
Security and data considerations
None. No auth/owner-scoping change (the 404 path reuses the same owner-scoped
require_sealed_snapshot_for_current_revisionevery other consumer alreadyuses). No new data is stored or logged. No migration.
Dependencies and blocked work
None.
Scope changes or remaining work
None — all acceptance criteria from #217 are complete. Follow-up note: a real
size/complexity heuristic (with a named formula and truth class) could
replace
not_computedin a future issue; this PR deliberately does not addone (explicit non-goal in the issue).
Contributor checklist
devupstream/devupstream/devCloses) is used only because the issue is fully resolved