> For the complete documentation index, see [llms.txt](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase29-session04-corroboration-gate/spec.md).

# Session Specification

**Session ID**: `phase29-session04-corroboration-gate` **Phase**: 29 - Trend Finder TrendingAI Comparison Adoption **Status**: Not Started **Created**: 2026-06-19

***

## 1. Session Overview

This session adds a first-class corroboration gate to Trend Finder so a topic supported by several rows from one originating entity is treated differently from a genuinely cross-entity trend. Phase 28 already shipped signal identity, source-local signals, role shares, and consensus/convergence-style context. Phase 29 Sessions 01-03 added editorial cleanup, attention patterns, and aggregate-only reception. Session 04 builds on those paths to identify originator-dominated topics and keep them out of overconfident score and action language.

The implementation must reuse reviewed identity sources only: source-local entity metadata, competitor matching, signal identity/syndication metadata, and the existing source breakdown model. It must not add a collector, entity extractor, identity provider, or social source. When the evidence is dominated by one originating entity, the system should publish a bounded `corroboration` object, surface an `originator-only` caution distinct from `single-source-signal`, and apply score/action caps consistently with `consensusRatio`, role shares, and the existing action-priority framework.

The feature is additive and browser-safe. Legacy payloads should parse with an explicit unavailable corroboration state, static Brief and live surfaces should display concise confirmation context without raw identity internals, and tests should prove both single-entity dominated and multi-entity independent cases.

***

## 2. Objectives

1. Add a schema-defaulted `corroboration` object with independent entity count, role count, dominance state, status, and bounded display fields.
2. Derive corroboration from reviewed source-local, competitor, and signal-identity metadata without adding new identity providers.
3. Add an `originator-only` caution distinct from `single-source-signal` and keep the existing risk-flag ordering deterministic.
4. Down-weight originator-dominated topics and cap action verdicts consistently with source consensus and convergence-style evidence.
5. Surface corroboration in live and static Trend Finder views with concise labels and payload/privacy safety tests.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase28-session01-cross-source-signal-identity-and-dedup` - Provides signal identity and syndication metadata.
* [x] `phase28-session02-signal-quality-score-and-collection-health` - Provides source quality and collection-health context.
* [x] `phase28-session08-action-verdicts-and-consistency-qa` - Provides action verdicts, caps, and consistency QA.
* [x] `phase29-session02-attention-pattern-and-polarity-grid` - Provides current derived-signal surface patterns.
* [x] `phase29-session03-reception-signal-aggregate-only` - Provides the latest risk/action cap pattern and static surface updates.

### Required Tools/Knowledge

* Bun 1.3.14 workflow through `bun run test`.
* Existing Trend Finder runtime order: scoring, source-local signal attachment, source breakdowns, action priority, static Brief projection.
* Current schema defaulting pattern in `src/extensions/trend-finder/schema.ts`.
* Current source identity modules: `source-local-signals.ts`, `competitor-matching.ts`, and `sources/signal-identity.ts`.

### Environment Requirements

* Project dependencies installed with Bun.
* `src/data/live-data.example.json` available for fixture and payload validation.
* No additional source or media compliance approval is needed because this session reuses already-reviewed metadata only.

***

## 4. Scope

### In Scope (MVP)

* Trend Finder can publish corroboration as an additive derived topic field - Implement a short, schema-defaulted object with status, entity counts, role counts, dominance ratio, caution, and display-safe explanation.
* Trend Finder can detect originator domination - Derive entity keys from source-local entities, competitor matches, and signal identity groups with deterministic fallbacks.
* Operators can distinguish source scarcity from originator scarcity - Add `originator-only` as a distinct caution/risk signal from `single-source-signal`.
* Opportunity scores and action verdicts respect weak corroboration - Add a bounded score downrank and action-priority cap/warning for originator-dominated topics.
* Live and static surfaces can explain corroboration - Add view-model labels, source-context summary, static Brief projection/rendering, and bounded docs.
* Release validation can prove safety - Add focused unit, schema, view-model, static Brief, and payload-size checks.

### Out of Scope (Deferred)

* New source adapters, social platforms, or media collection - Reason: Phase 29 keeps broader social reach and media sources compliance-gated.
* New entity extraction or external identity provider - Reason: The session must reuse reviewed identity sources only.
* Industry event clustering - Reason: Session 11 reuses corroboration logic for that separate lens.
* Podcast theme convergence - Reason: Sessions 16-17 own podcast boundary and any gated implementation.
* Replacing `single-source-signal` - Reason: `originator-only` is additive and distinct from source-count scarcity.

***

## 5. Technical Approach

### Architecture

Create a small deterministic corroboration helper under `scripts/lib/ai-runtime/`. It should accept topic evidence IDs plus safe evidence/source metadata and return a bounded result with an explicit unavailable fallback. Entity keys should come from reviewed local metadata in priority order: source-local entity identity, competitor match identity, signal-identity syndication group, then source-level fallback. The helper should count independent entities and distinct source roles, calculate a dominance ratio, and classify the topic as unavailable, originator-only, weak, or confirmed.

Wire the helper in `deriveTopicSourceBreakdowns()` after role shares and consensus are available. That is where Session 02 and Session 03 derived fields already attach attention and reception, so it keeps derived source context in one place. Add `originator-only` to the topic risk flags when corroboration is dominated, and keep flag ordering driven by `TREND_TOPIC_RISK_FLAGS`.

Score changes should be bounded and explainable. Add a `corroboration_gate` score adjustment row and apply only a small downrank or cap to dominated topics; multi-entity confirmed topics should remain unaffected. Action priority should receive the corroboration object or risk flag and cap `originator-only` topics below `act_now`, with warnings and next-step copy that asks for independent confirmation.

Browser and static surfaces should consume projected view-model fields. Do not publish raw entity IDs, private paths, raw source rows, prompts, provider responses, or unreviewed identity details. Keep labels short enough for source summary cards and static Brief tables.

### Design Patterns

* Additive schema evolution: Legacy payloads parse to a default unavailable corroboration state.
* Deterministic derived field: No model call or new source is required.
* Boundary-nearest authorization: Reuse only reviewed metadata already present in normalized evidence.
* Bounded browser projection: Publish counts, status, caution, and display labels rather than raw identity internals.
* Existing cap model: Use action-priority caps and warnings instead of introducing a second verdict system.

### Technology Stack

* TypeScript and Zod for runtime/schema contracts.
* Bun and Vitest for script/runtime tests.
* React 19 view-model and component tests with happy-dom.
* Existing static Brief export, renderer, and privacy scan utilities.

***

## 6. Deliverables

### Files to Create

| File                                                     | Purpose                                                                                                | Est. Lines |
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | ---------- |
| `scripts/lib/ai-runtime/corroboration.ts`                | Deterministic corroboration derivation helper with reviewed identity inputs and bounded status output. | \~220      |
| `scripts/lib/ai-runtime/__tests__/corroboration.test.ts` | Unit coverage for originator-only, weak, confirmed, unavailable, competitor, and syndication cases.    | \~220      |

### Files to Modify

| File                                                                         | Changes                                                                                                                                      | Est. Lines |
| ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `src/extensions/trend-finder/schema.ts`                                      | Add corroboration constants, default object, schema field, `originator-only` risk flag, score-adjustment key, and action cap enum additions. | \~130      |
| `scripts/lib/ai-runtime/source-breakdown.ts`                                 | Attach corroboration after source/role derivation and merge `originator-only` risk flag deterministically.                                   | \~80       |
| `scripts/lib/ai-runtime/scoring.ts`                                          | Apply a bounded corroboration gate adjustment and include the named score adjustment row.                                                    | \~100      |
| `scripts/lib/ai-runtime/action-priority.ts`                                  | Add corroboration-aware action input, cap, warning, and next-step copy with schema-validated fallback.                                       | \~90       |
| `src/extensions/trend-finder/view-model.ts`                                  | Add corroboration labels, tones, risk flag copy, source summary projection, and accessibility text.                                          | \~120      |
| `src/extensions/trend-finder/components/source-breakdown.tsx`                | Render corroboration alongside consensus, builder signal, and role shares without layout shift.                                              | \~50       |
| `scripts/extensions/trend-finder/static-brief-export.ts`                     | Project corroboration into static Brief output using bounded labels and counts only.                                                         | \~50       |
| `scripts/extensions/trend-finder/static-brief-renderer.ts`                   | Render corroboration in escaped static Brief markup and preserve privacy scan compatibility.                                                 | \~35       |
| `scripts/extensions/trend-finder/measure-payload-size.ts`                    | Include corroboration in payload pressure reporting.                                                                                         | \~20       |
| `src/extensions/trend-finder/fixtures.ts`                                    | Add fixture topics covering confirmed and originator-only corroboration states.                                                              | \~40       |
| `scripts/lib/ai-runtime/__tests__/source-breakdown.test.ts`                  | Cover integration of corroboration, consensus, role shares, and risk flag propagation.                                                       | \~90       |
| `scripts/lib/ai-runtime/__tests__/scoring.test.ts`                           | Cover bounded downrank and unaffected confirmed corroboration cases.                                                                         | \~70       |
| `scripts/lib/ai-runtime/__tests__/action-priority.test.ts`                   | Cover action cap behavior for originator-only topics.                                                                                        | \~70       |
| `src/lib/__tests__/trend-finder-schema.test.ts`                              | Cover legacy defaults, enum rejection, and risk flag parsing.                                                                                | \~70       |
| `src/extensions/trend-finder/__tests__/view-model.test.ts`                   | Cover labels, tones, accessibility text, and source summary projection.                                                                      | \~80       |
| `src/extensions/trend-finder/components/__tests__/source-breakdown.test.tsx` | Cover corroboration summary rendering and responsive-safe copy.                                                                              | \~60       |
| `scripts/extensions/trend-finder/__tests__/static-brief-export.test.ts`      | Cover static projection and private identity exclusion.                                                                                      | \~70       |
| `scripts/extensions/trend-finder/__tests__/static-brief-renderer.test.ts`    | Cover escaped renderer output and no raw identity leaks.                                                                                     | \~50       |
| `docs/extensions/trend-finder-scoring.md`                                    | Document corroboration status, score downrank, action cap, and relationship to `single-source-signal`.                                       | \~90       |
| `docs/extensions/trend-finder-ui-surfaces.md`                                | Document live/static corroboration display and privacy boundary.                                                                             | \~50       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] `corroboration` defaults to an explicit unavailable state for legacy payloads.
* [ ] A fixture dominated by one reviewed entity is flagged `originator-only`, down-weighted, and blocked from `act_now`.
* [ ] A multi-entity independent fixture stays confirmed and is not down-weighted by the corroboration gate.
* [ ] `originator-only` is reported distinctly from `single-source-signal`; a topic can have one, both, or neither.
* [ ] Live and static surfaces show concise corroboration labels without raw entity IDs or private identity details.

### Testing Requirements

* [ ] Unit tests written and passing for corroboration derivation, source-breakdown wiring, scoring adjustment, and action caps.
* [ ] Schema/view-model/component tests cover legacy defaults, labels, tones, accessibility labels, and long text safety.
* [ ] Static Brief export/renderer tests cover projected corroboration cells and privacy scan behavior.
* [ ] Payload-size check confirms the extension remains under the 1 MB boundary.
* [ ] Focused test commands recorded in implementation notes during the implement step.

### Non-Functional Requirements

* [ ] Browser payload stays under the 1 MB extension budget.
* [ ] Static Brief and Engine Replay remain browser-safe and do not expose raw source rows, private paths, prompts, provider responses, or raw identity internals.
* [ ] No new source, collector, media boundary, database, hosted storage path, dependency, or third-party transfer is introduced.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] New enum branches use exhaustive handling and explicit fallback behavior.

***

## 8. Implementation Notes

### Key Considerations

* `originator-only` must not replace `single-source-signal`. Source count and independent-origin count are separate quality signals.
* The helper should use reviewed metadata only and should avoid publishing raw entity IDs to browser or static surfaces.
* Corroboration should be derived after source-local and signal-identity metadata exist, but before action recommendations are attached.
* The score downrank should be bounded and represented as a named score adjustment so users can see why a topic moved.
* Static Brief should receive projected labels and counts from the view model or export projection, not raw evidence internals.

### Potential Challenges

* Ambiguous identity metadata: Mitigate with explicit unavailable/weak states rather than guessing entity identity.
* False-positive originator domination: Mitigate by requiring entity evidence dominance and by preserving source-role counts in the explanation.
* Cap ordering drift: Mitigate with action-priority tests that assert dominated topics cannot produce `act_now`.
* Payload pressure: Mitigate by publishing short enum/count fields and bounded display labels only.

### Relevant Considerations

* \[P02] **Extension payloads and labels stay bounded**: Corroboration should be short status/count metadata with explicit unavailable states.
* \[P24] **Browser-safe export and triage boundaries**: Static Brief must not include raw source rows, private paths, local triage notes, or unreviewed identity internals.
* \[P27] **Deterministic fallback before AI enrichment**: Corroboration is deterministic and should not depend on optional analyst output.
* \[P28] **Direct public source scope is narrow**: This session adds no source and does not widen deferred social or media candidates.
* \[P28] **Trend Finder release validation is bundled**: Payload, privacy, docs, and scoped formatting evidence should be recorded during implementation and closeout.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Originator-dominated topics accidentally still receive `act_now` because the action cap runs before corroboration risk is attached.
* Raw entity IDs or unreviewed identity details leak into browser payloads or static Brief output while explaining corroboration.
* Multi-source but single-origin topics get mistaken for genuinely corroborated topics.

***

## 9. Testing Strategy

### Unit Tests

* Add corroboration helper tests for unavailable, originator-only, weak, and confirmed statuses.
* Add tests for source-local entity identity, competitor match identity, signal syndication groups, and source fallback behavior.
* Add source-breakdown tests proving `corroboration`, `consensusRatio`, role shares, and risk flags are attached in deterministic order.
* Add scoring and action-priority tests proving dominated topics are down-weighted and capped while confirmed topics remain unaffected.

### Integration Tests

* Add schema tests for legacy defaults, rejected invalid statuses, and `originator-only` risk flag parsing.
* Add view-model/component tests for live labels, tones, source summary cards, accessibility labels, and long label truncation.
* Add static Brief export/renderer tests for projected corroboration labels and no raw entity ID/private path leakage.

### Manual Testing

* Review fixture Trends cards containing one originator-only topic and one confirmed topic.
* Export a static Brief and confirm corroboration status appears as bounded labels.
* Inspect action verdicts for originator-only topics and confirm they are `monitor`, `review`, or `ignore`, never `act_now`.

### Edge Cases

* Multiple sources syndicate the same originating announcement.
* Multiple rows share one competitor/channel entity but span several source roles.
* Evidence lacks source-local entity metadata but has signal identity/syndication metadata.
* Evidence has no usable identity metadata and should remain unavailable instead of guessed.
* Legacy payload omits `corroboration`, `riskFlags`, or action-cap enum values.

***

## 10. Dependencies

### External Libraries

* Zod: Existing schema validation dependency.
* Vitest: Existing unit and component test runner.
* Playwright: Existing e2e runner if implementation expands browser-visible validation.

### Other Sessions

* **Depends on**: `phase28-session01-cross-source-signal-identity-and-dedup`, `phase28-session08-action-verdicts-and-consistency-qa`, `phase29-session03-reception-signal-aggregate-only`
* **Depended by**: `phase29-session08-required-derived-field-closeout-gate`, `phase29-session11-industry-events-rollup`, `phase29-session14-one-to-watch-surface`, `phase29-session17-podcast-themes-enrichment`

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase29-session04-corroboration-gate/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
