6. Insight Object spec
The Insight Object is the atom of every deliverable. A slide, a portal card, a Diagnostic Room view, and a manager pack are all renderings of Insight Objects. If a claim is not an Insight Object, it does not reach the client.
6.1 Design rules
- Evidence before prose. An Insight Object is created from evidence references; the text is written on top of them.
- Numbers are bound, not typed. Every number in the title, claim, or so-what must match a bound EvidenceRef value. The claim linter blocks free-typed numbers.
- AI drafts; people approve. Model-authored objects start as
draft_aiand carry provenance. Only a Partner can move an object topartner_approved. - Partner voice stays on the page. Approved text is frozen. Regeneration creates a new version; it never overwrites approved text.
- Safe at render time. Evidence is re-checked against the anonymity engine every time it is rendered.
6.2 Fields
| Field | Type | Required | Notes |
|---|---|---|---|
| id, version | uuid, int | ✓ | Version increments on any content edit |
| engagement_id, wave_id | → | ✓ | Multi-wave insights reference the latest wave; compare waves in evidence |
| type | enum | ✓ | finding, driver, contradiction, bright_spot, risk, drift, structure |
| title | string ≤ 90 chars | ✓ | A full sentence stating the finding. "Supervisors are the constraint, not the shop floor." |
| claim | string ≤ 280 chars | ✓ | The evidential statement, with bound numbers |
| so_what | string ≤ 400 chars | ✓ | Consequence for the business, in client terms |
| evidence[] | EvidenceRef[] | ✓ ≥ 1 | See §6.3 |
| methods | set | computed | Which of quant, text, video, interview, document, structure the evidence spans |
| confidence | enum | computed, overridable with reason | high, medium, low (§6.4) |
| constructs[] | practice/dimension codes | ✓ | Ties the insight to the pack |
| segments[] | cut definitions | Where the finding applies; all k-checked | |
| recommended_moves[] | → Recommendation | From the pack library. Free-text moves allowed but flagged off_pack |
|
| commercial_links[] | → ServiceOffering | Visible to firm roles only | |
| monday_move | string ≤ 160 chars | The one action to start this week | |
| audience | set | ✓ | partner, em, analyst, client_sponsor, client_exec, client_manager, all_staff |
| client_visibility | enum | ✓ | firm_only, client_exec, client_all |
| author_type | enum | ✓ | ai, human, ai_edited |
| provenance | object | when ai | model id, prompt template version, input evidence hash, run id, ts |
| status | enum | ✓ | §6.5 |
| owner_id | → User | ✓ | Analyst or EM accountable for the object |
| reviewer_id, approver_id | → User | Approver must hold Partner role on the engagement | |
| review_notes[] | thread | Kept with version history | |
| k_check | object | computed | {passed, checked_at, failing_refs[]} |
| lint | object | computed | {unbound_numbers[], causal_language[], off_pack_moves[], borderline_band_claims[]} |
| supersedes_id | → InsightObject | For re-cut or regenerated findings | |
| spine_position | int | Position in the narrative, if on the spine |
6.3 EvidenceRef
| kind | Fields | Rendered as |
|---|---|---|
metric |
scorecard_id, target, value, n, ci, comparison {vs, delta, sig, effect_size} | Chart or stat line with footnote |
heatmap |
scorecard_ids[], targets[], highlighted_cells[] | Mini heatmap |
driver |
driver_run_id, practice_codes[], shares[], ci[] | Importance bars |
theme |
theme_id, prevalence, intensity, segment_skew, confidence | Theme card |
quote |
quote_id, permission_tier, segment_label | Pull quote with attribution band ("Operator, Plant C") |
clip |
clip_id, consent_tier, t_start, t_end | Video player or transcript fallback |
interview |
interview_id, segment ids, role band | Excerpt |
document |
document_id, page/section, excerpt | Excerpt with source |
structure |
structure_snapshot_id, metric (span, layers, cost band), cut | Structure chart |
contradiction |
left_ref, right_ref, strength | Side-by-side |
Minimum evidence for publication:
| Type | Minimum |
|---|---|
| finding | 1 metric + (1 quote or 1 theme) |
| driver | 1 driver ref + 1 metric |
| contradiction | 2 refs from different methods + strength ≥ medium |
| bright_spot | 1 metric vs rest-of-org (significant) + 1 quote or clip |
| drift | 1 metric with ≥ 2 prior waves or 1 prior wave with significant decline |
| structure | 1 structure ref + 1 metric in the same cut |
6.4 Confidence
Computed, shown, and overridable only with a written reason (logged).
| Level | Rule |
|---|---|
| High | ≥ 2 methods converge; the quant component is "meaningful" under §5.6 (or a driver share CI excludes zero); text theme confidence ≥ medium; n ≥ 100 in the relevant cut |
| Medium | One method meets the High bar alone, or two methods converge but one is weak (e.g., theme confidence low, n 30–99) |
| Low | Single method below the High bar, emergent theme without validation, or any borderline band claim |
Low-confidence objects can be published only to firm_only, or to the client with the visible label "Hypothesis — to test."
6.5 States and transitions
┌──────────── reject (reason) ────────────┐
▼ │
draft_ai ─► draft ─► in_review ─► reviewed ─► partner_approved ─► published
│ ▲ │ │ │ │
│ └─ edit ──┴── edit ────┘ │ │
│ (any edit after approval returns to reviewed)
└─► discarded └─► withdrawn ◄──┘
superseded (by a newer object)
| Transition | Who | Guard |
|---|---|---|
| → draft_ai | Insight pipeline | Evidence resolves; provenance recorded |
| draft_ai → draft | Analyst | Takes ownership; may edit |
| draft → in_review | Analyst / EM | Lint clean or waivers recorded; minimum evidence met |
| in_review → reviewed | EM | Reviewer ≠ owner |
| reviewed → partner_approved | Partner on engagement | k_check passed; confidence ≥ medium or labeled hypothesis; approver ≠ owner |
| partner_approved → published | Partner / EM | Target surface chosen; render-time k_check passes |
| any → withdrawn | Partner | Reason required; published copies replaced with "Withdrawn on |
| edit after approval | Any editor | Status returns to reviewed; published version stays live until the new one is approved |
6.6 Linter rules
| Rule | Blocks | Example |
|---|---|---|
| Unbound number | in_review | "72% of managers…" with no metric evidence at 72 |
| Causal language on associational evidence | in_review (waivable by Partner) | "drives", "causes", "because of" with driver evidence |
| Borderline band claim | partner_approved | "moved into top quartile" when band_borderline |
| Sub-k segment | partner_approved | Segment in segments[] fails k |
| Quote tier mismatch | published | internal quote in a client_exec object |
| Off-pack move | in_review (waivable) | Recommendation not in library |
| External norm unlabeled | published | External comparison rendered without "indicative" stamp |
6.7 AI generation contract
The insight pipeline may draft Insight Objects. It must:
- Read only de-identified inputs: Scorecards, driver runs, themes, redacted quotes, transcripts, and structure stats for this workspace.
- Propose from evidence outward: select evidence first, then write title/claim/so-what referencing EvidenceRef IDs.
- Choose
recommended_movesonly from the pack library, matched by (practice, band) triggers. - Emit no numbers that are not in the bound evidence.
- Never cross workspaces. Book comparisons arrive as percentiles only.
- Record provenance on every draft.
Firm-level ai_processing_opt_in and client contract flags govern whether any client content may be used to improve models. Default: no. Runtime drafting uses providers under zero-retention terms.
6.8 Harvest to Pattern Library
When an engagement closes, Partners can promote approved Insight Objects to the firm's Pattern Library. Promotion strips client identifiers, keeps the constructs, band pattern, title language, and recommended moves, and records the number of engagements where the pattern recurred. Patterns become suggested language for future drafts. This is how the firm's judgement compounds.