Skip to content

Stop repeating evidence-role qualifiers on the default view - #80

Merged
blisspixel merged 1 commit into
mainfrom
clean-default-view-evidence-roles
Aug 7, 2026
Merged

Stop repeating evidence-role qualifiers on the default view#80
blisspixel merged 1 commit into
mainfrom
clean-default-view-evidence-roles

Conversation

@blisspixel

Copy link
Copy Markdown
Owner

What

Every human-facing service and provider label carried the record role that established it, inline and in full prose, once per item and often several times per line. The default view now renders those labels bare:

  Provider     Microsoft 365 (MX delivery path) + Proofpoint gateway (MX     →   Provider     Microsoft 365 + Proofpoint gateway
               delivery path)
  Security     Wiz Security (public TXT account indicator)                   →   Security     Wiz Security
  Collaboration Slack (public TXT account indicator),                        →   Collaboration Slack, Atlassian (Jira/Confluence)
                Atlassian (Jira/Confluence) (CNAME endpoint binding)              Evidence roles: --explain

Scope

Surface Change
Default panel, --plain, --md, --chain tree Role qualifiers compacted out; one dim pointer line
--explain, --verbose, --full Unchanged, byte for byte (panel_dense_explain/full/verbose goldens do not move)
--json, --csv, MCP Unchangedprovider is a stable JSON field and keeps the full prose

Compaction never upgrades a claim

  • A match whose role could not be established is omitted from the default view and counted in the pointer line, rather than rendered as a bare vendor name that would read as asserted.
  • The provider row re-hedges as (no supporting record) instead of dropping — it is the panel's only answer to who handles the mail.
  • The two qualifiers that bound the claim rather than name a record type survive shortened: (likely downstream) and (downstream unobserved).

Consequence, recorded in the ADR: the default view is no longer a complete enumeration of catalog matches. Consumers counting rows must use the JSON record.

Governance

ADR-0012 records the claim-discipline invariant change this required. The renderer obligations on runtime.service-label.v1 and runtime.email-topology.v1 are restated to match, and ROADMAP.md / docs/stability.md / docs/limitations.md updated.

Two defects fixed along the way

Both surfaced from the gate, not from the diff:

  1. The subdomain summary was disappearing along with the compacted apex rows — it is CNAME-chain attribution, not an apex catalog label, and now keeps the section alive on its own.
  2. Compaction was shrinking the category count that decides whether the passive-DNS sparseness note fires. That count measures collection richness, not display density, so it is now taken before compaction.

Also

Insight curation moves to formatter/insight_curation.py — editorial policy over insight strings rather than rendering. The file-size ratchet demanded a split rather than a raised cap; panel.py ratchets 1719 → 1615 lines.

Verification

uv run python scripts/check.py — all 27 stages pass, coverage 91.16%. README terminal demo regenerated.

Every human-facing service and provider label carried the record role that
established it, inline and in full prose, once per item and often several
times per line: "Slack (public TXT account indicator)", "Okta (CNAME endpoint
binding)", "Microsoft 365 (MX delivery path)". The answer to "what do they
run" arrived buried under the answer to "how do we know", which the operator
had not asked for yet.

The default panel, --plain, --md, and the --chain tree now render those labels
bare and close the section with one dim line naming the flag that restores the
detail. --explain, --verbose, and --full are unchanged byte for byte, as are
the --json record (including the stable provider field), --csv, and every MCP
payload.

Compaction never upgrades a claim. A match whose role could not be established
is omitted from the default view and counted in that line rather than rendered
as a bare vendor name; the provider row re-hedges as "(no supporting record)"
instead of dropping, since it is the panel's only answer to who handles the
mail; and the two qualifiers that bound the claim rather than name a record
type survive in shortened form as "(likely downstream)" and "(downstream
unobserved)".

ADR-0012 records the claim-discipline invariant change this required, and the
renderer obligations on runtime.service-label.v1 and runtime.email-topology.v1
are restated to match.

Two defects surfaced while wiring this up and are fixed here: the subdomain
summary was disappearing along with the compacted apex rows, and compaction
was shrinking the category count that decides whether the passive-DNS
sparseness note fires, so that count is now taken before compaction.

Insight curation moves to formatter/insight_curation.py. It is editorial
policy over insight strings rather than rendering, and the move ratchets the
panel module's file-size ceiling down from 1719 to 1615 lines.
Copilot AI lite review requested due to automatic review settings August 7, 2026 22:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates recon’s default human-facing outputs to stop repeating evidence-role qualifiers inline on every provider/service label, while keeping evidence/detail surfaces (--explain / --verbose / --full) and machine surfaces (JSON/CSV) consistent with the existing claim-discipline model. It also extracts insight-curation policy into a dedicated module and refreshes goldens/docs to reflect the new default rendering.

Changes:

  • Compact evidence-role qualifiers out of default panel/plain/markdown/service label rendering, and omit unattributed matches from default views with a single pointer line to detail surfaces.
  • Refactor insight curation out of panel.py into formatter/insight_curation.py.
  • Update tests and golden renders to reflect the new default vs detailed rendering split (ADR-0012), plus documentation/ADR/changelog updates.

Reviewed changes

Copilot reviewed 36 out of 37 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_services_label_width.py Adds retained evidence to fixtures so default-view alignment tests still render observable rows.
tests/test_service_disclosure.py Updates assertions to match compacted default labels and retained-detail behavior.
tests/test_panel_assembly.py Adjusts provider-line assertion to compare compacted panel output against structured provider identity.
tests/test_multi_cloud_rollup.py Updates rollup expectations for omission of unattributed legacy matches in default view.
tests/test_merger_error_surfacing.py Adds minimal retained evidence to partial fixtures so default view doesn’t omit the only surviving labels.
tests/test_insights.py Updates fixtures to include retained evidence so Services rows still appear under ADR-0012.
tests/test_ingestion_sanitization.py Switches markdown sanitization tests to the detailed markdown surface to keep hostile labels renderable.
tests/test_formatter.py Adds explicit default vs detailed plain-output expectations, including the new evidence-roles pointer line.
tests/test_formatter_intel_extensions.py Switches grouping-only markdown tests to the detailed markdown surface (fixtures lack evidence).
tests/test_collection_view.py Updates panel provider-line expectations to reflect default compaction vs JSON stability.
tests/test_cache_cross_version_compatibility.py Updates expectations for pre-lineage caches (default omits unattributed; detail retains role-unavailable labels).
tests/test_agentic_ux_compatibility.py Updates helper to forward kwargs and adjusts expectations to default omission + detailed retention.
tests/golden_renders/panel_surface_full.txt Updates golden to reflect default omission/pointer behavior when roles are unavailable.
tests/golden_renders/panel_surface_default.txt Updates golden to reflect compacted labels and evidence-role pointer line.
tests/golden_renders/panel_sparse_default.txt Updates sparse golden to show unattributed omission note.
tests/golden_renders/panel_dense_default.txt Updates dense golden to show compacted provider/services and evidence-role pointer.
tests/golden_renders/markdown_sparse.txt Updates markdown golden to emit omission note instead of role-unavailable bullets.
tests/golden_renders/markdown_rich.txt Updates markdown golden to compact service bullets and add evidence-role pointer line.
tests/golden_renders/markdown_dense.txt Updates markdown golden to compact service bullets and add evidence-role pointer line.
src/recon_tool/formatter/serialize.py Adds detailed flag to plain output; compacts labels by default and emits a single evidence-role/unattributed note.
src/recon_tool/formatter/panel.py Threads “detailed vs default” through key-facts/services rendering; compacts provider/services in default view and adds pointer notes.
src/recon_tool/formatter/markdown.py Adds detailed flag; compacts labels by default and emits a single italic pointer/note line.
src/recon_tool/formatter/insight_curation.py New module holding insight curation policy previously embedded in panel.py.
src/recon_tool/formatter/classify.py Adds compaction helpers for service labels and provider lines (ADR-0012).
src/recon_tool/cli/lookup.py Threads “detailed roles” into --plain/--md output paths based on display options.
scripts/check_file_size.py Updates file-size ratchet baseline for formatter/panel.py.
ROADMAP.md Documents the new default-vs-detail evidence-role visibility rule with ADR reference.
README.md Regenerates demo output to reflect compacted default provider/services lines.
docs/stability.md Documents evidence-role wording/visibility differences between default and detailed surfaces.
docs/limitations.md Updates dual-provider wording to reflect compacted default view vs detailed/JSON behavior.
docs/default-claim-audit.json Updates renderer obligations/producer paths for the new compaction behavior.
docs/assets/terminal-demo.svg Updates terminal demo asset to match the new default output rendering.
docs/adr/README.md Adds ADR-0012 to the ADR index.
docs/adr/0012-default-view-evidence-role-visibility.md New ADR defining default vs detailed evidence-role visibility and omission rules.
CHANGELOG.md Adds release notes describing the default-view compaction and the insight-curation module split.
agents/claude-code/skills/recon/SKILL.md Updates skill documentation snippet to match compacted default provider line.
AGENTS.md Updates agent guidance snippet to match compacted default provider line.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 777 to 778
if not info.services:
return None, 0
Comment on lines +273 to +277
# The MX role is established, so the label is compacted rather than dropped
# and no unattributed-match note appears (ADR-0012).
assert "Email Symantec/Broadcom" in collapsed
assert "role unavailable" not in collapsed
assert "unattributed" not in collapsed
@blisspixel
blisspixel merged commit a6f7d66 into main Aug 7, 2026
28 checks passed
@blisspixel
blisspixel deleted the clean-default-view-evidence-roles branch August 7, 2026 23:35
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.

2 participants