Changelog

Notable product changes.

All notable changes to cyberplate-sat-loop are documented in this file.

Format follows Keep a Changelog.
Product acceptance detail for Curiosity: docs/product/CURIOSITY-MVP.md.

[Unreleased]

Added — Advanced chapter HUD (mock) — 2026-08-30

Quest Log discovery is the Advanced on-ramp. Mock Home shows the chapter
strip. Sidebar accents Quest Log until a journal session is ready for
the register wizard. Org mode is still the only nav lock. G4 stays a
launch gate, not a hidden tile. US-ITM-015 stays on the map, unrendered.

  • Honesty — demo progress on fixture data. Not audit evidence. Persist still renders nothing. Default mock org is already Advanced and mid-loop. Snapshot throws omit chrome. Trainee Classrooms has no operator HUD.

Changed — Enterprise gate opens Settings — 2026-08-30

Enterprise-mode required card follows manage_organization. Org admin
gets Open in Settings to the Organization tab. Everyone else gets Back
to Classrooms. Unauthorized-role failure CTA uses the same Classrooms
noun. Server still refuses the mode flip without that operation.

Added — Mock chapter cues (sidebar + toast) — 2026-08-30

Simple chapters stay table-driven. Mock shell accents the next nav item
and fires a one-shot visual toast when a chapter becomes done. Org mode
is still the only nav lock. Quest Log is not the toast stack.

  • Honesty — demo progress. Not audit evidence. Not a notification product. No sound. Persist still renders nothing.

Added — Simple-loop chapter HUD (mock) — 2026-08-30

Progression sits inside org mode, not beside it. Mock HUD on Classrooms and
Loop names the open Simple chapter. Settings soft-nudge when flipped to Simple.
OrgMode stays smb | enterprise. Advanced is a copy label. Persist renders
nothing.

  • Honesty — demo progress on fixture data. Not audit evidence. Not an entitlement grant. Flip stays available.

Added — Hosted self-loop persist — 2026-08-30

One loop on the dogfood org. Paste-the-text extract, freeze FKs, ack events,
private PDF path, Library door on SMB. Assign to Me uses the same Microsoft
login. Hosted apply policy_kernel (0033) on nhiytgnlnxgqbgocsiaf.
Watermark stays. Chip 3 parked.

  • Honesty — paste can diverge from PDF bytes. Drafts are dumb templates. Not audit evidence. Not Entra. Not mail.

Changed — Founder lock A freeze-only Assign — 2026-08-30

Frozen triple is the product. Rooms Assign no longer pins quiz-phishing-basics.
Hosted /library is an honest halt instead of a stack throw. Choose PDF is a
pointer label over a hidden file input. Smoke north star is PDF → artifact.
Living quiz completion stays museum. Chip 2 persist remains freeze FKs only.

  • Honesty — mock freeze, not custody. Stranger may believe: acknowledged version X, submitted the frozen three questions, received this server score.

Added — Mock kernel PDF to inspectable artifact — 2026-08-30

Unaided mock walk: one policy PDF, freeze, Assign to Me, acknowledgment,
watermarked artifact. Artifact shows who, when, source hash, ack of version
X, and server score. Banner is NOT AUDIT EVIDENCE. Assign to Me stores the
frozen triple; it does not resolve a current quiz. Honest Rooms Assign
unchanged. Hosted persist Chip 2–3 remains Escalate.

  • Honesty — fixture extract and in-memory freeze. Mock is not audit evidence. Grey Assign still means no freeze, not a missing catalog.

Changed — Evidence kernel Chip 1 honest Assign — 2026-08-30

Rooms Assign no longer says quiz authoring arrives in Phase 2. Grey Assign
means this workspace has no frozen policy intervention, and no quiz to attach.
That is intentional. We do not invent a catalog. Mock still pins
quiz-phishing-basics and links to /library/policy. Empty Content shows
"No content in this room." Chip 2–3 hosted persist remains Escalate.

  • Kernel blueprintdocs/build/contracts/document-understanding-evidence/90-day-kernel.md (nouns, refuse list, RLS/watermark, Wait for GO). No SQL.
  • Honesty — mock /library/policy is the walkable demo. Hosted grey Assign is correct. Not audit evidence.

Added — Library content local-first lane (L0a-L3) — 2026-07-26

First implementation pass for the local-first Library content blueprint: deterministic
launch snapshots, offline-capable local shell, portable bundle contract, and locked
honesty copy across add/learn/evidence touchpoints.

  • L0a service boundary — introduced core launch-idempotency and library creation services; launch now records persisted idempotency metadata and rejects key/input conflicts.
  • L0b offline shell — added /local client-rendered local subtree with IndexedDB command layer and service-worker navigation fallback (/local-shell-sw.js).
  • L0c portable bundle — added canonical portable bundle schema/serialization + import prep rules (create_new_org / replace_local_org), completion consistency checks, and local export/import controls with privacy warning.
  • L1 add URL flow — added Library add-URL form + server action, validation (scheme/credentials/ duplicate checks), source inference (YouTube vs External), and manage-campaigns gate behavior.
  • L2 launch projection — campaign launch now fail-closes on missing/duplicate library IDs and projects ordered immutable snapshot content items into trainee assignments.
  • L3 golden path tests — added focused unit/e2e proofs for portable bundle, library add, campaign content projection, offline local shell, and full library-content golden path assertions.

Added — Local segmentation lab (Slices A–D) — 2026-07-16

Dev-only dual-profile population lab for segmentation dogfood (not production).

  • schema / seedseg_lab_* org/tag/behavior tables; SME (~280) and enterprise (16k) profiles via LAB_PROFILE; npm run lab:seed (wipes population + saved lab segments on each run).
  • BridgeMOCK_POPULATION=sme maps SME CSV into mock campaign cast size (separate from lab Postgres tags).
  • enrichment — mapping-v1 job/group rules materialize org units, tags, and behavior facts into seg_lab_*.
  • v2 rules — strict SegmentRuleV2, trusted v1→v2 adapter, explainable preview requiring evaluation_as_of, session guards on lab API routes.
  • org-tree + capped heatmap — allowlisted axes, 20×20 / 400 cells + other, cell→builder next action.
  • routes / nav — lab UI at /lab/segmentation; People stays at /organization/population. With SEGMENTATION_LAB=1, Operate shows Segmentation lab via runtime inject (not static secondary nav).
  • docsdocs/build/ledger/local-segmentation-lab.md; proof: validate:slice-*-* scripts.

Changed — Human Risk Register single create flow — 2026-07-06

Collapsed the register's three overlapping create surfaces into one to reduce clutter
and keep the register table the focus of the page.

  • removed
    • components/register-create-form.tsx (quick-add) — duplicated every guided field.
    • The permanently-disabled "Evaluation session" toolbar stub.
  • changed
    • components/register-view.tsx — single + Add risk button opens the guided wizard (open-state lifted here); the register no longer auto-opens a form on load; the table, filters, and a single merged meta line always render. Import / Export JSON / Reset demo seed moved into one "Data" overflow menu.
    • components/register-guided-wizard.tsx — now a controlled panel (no internal open/closed state, no "Start guided entry" button), with Cancel, Escape dismissal, auto-scroll into view on open (respecting prefers-reduced-motion), and full-width to share one visual spine with the table. The exit is now a clearly bordered Cancel button next to the wizard title (previously a faint header link that scrolled off-screen on narrow widths).
    • components/register-boot-sequence.tsx — same auto-scroll/focus treatment; remains the empty-register / ?boot=1 first-run version of the single flow.
    • tests/e2e/register.spec.ts, tests/e2e/quest-log.spec.ts — updated to the single guided flow, the "Data" menu, and removal of the evaluation-session stub.
  • docs: docs/product/SURFACE-CANON.md, docs/build/STATE.md.

Added — Five-surface canon lock (Alignment Phase A, docs only)

Decision: Lock product vocabulary before nav implementation; canon leads menu.

Docs-only minimum surface canon for five primary surfaces (Cockpit, Human Risk
Register, Campaigns, Evidence Inbox, Quest Log). No shell or route code changed
in this batch.

  • added
    • docs/product/SURFACE-CANON.md — minimum canon lock, route strategy (/evidence-inbox canonical, /calendar legacy alias), security non-goal, non-enterprise nav count rule, Phase B guard obligations.
    • docs/GATES.md — Gate Five-Surface Canon (Alignment Phase A) proof rows.
    • docs/AUTHORIZATION-MATRIX.md — five-surface canon route/operation mapping.
  • changed
    • docs/product/BUILD-SEQUENCE.md — canon in required artifacts, guardrails, and documentation precedence.
    • README.md — surface canon link and execution-status alignment with gate log.

Added — SAT Loop Builder contract layer (docs/config only)

Docs-first operating interface for turning intent into bounded build artifacts
without runtime side effects. This adds a builder mirror to existing review
orchestration and enforces human-governed evidence transitions.

  • added
    • Doctrine contract:
    • docs/product/HUMAN-RISK-EVIDENCE-LOOP-DOCTRINE.md
    • Builder templates:
    • docs/product/templates/decision-packet.template.md
    • docs/product/templates/risk-record.template.md
    • docs/product/templates/intervention-plan.template.md
    • docs/product/templates/evidence-record.template.md
    • docs/product/templates/agent-output.template.md
    • docs/product/templates/human-review.template.md
    • docs/product/templates/release-note.template.md
    • docs/product/templates/builder-run.template.md
    • Builder examples:
    • docs/product/examples/example-decision-packet.md
    • docs/product/examples/example-risk-record.md
    • docs/product/examples/example-agent-output.md
    • docs/product/examples/example-evidence-record.md
    • docs/product/examples/example-builder-run.md
    • Builder skill/orchestrator/specialists:
    • .cursor/skills/sat-loop-builder/SKILL.md
    • .cursor/agents/sat-loop-builder-orchestrator.md
    • .cursor/agents/builder/01-research.md07-release.md
    • Trust cross-reference:
    • docs/trust/agentic-workflow-governance.md
    • Operator docs:
    • docs/product/SAT-LOOP-BUILDER-README.md
    • docs/product/runs/README.md
  • changed
    • docs/product/BUILD-SEQUENCE.md now includes builder-loop contract readiness checks.
    • docs/PROJECT.md now lists sat-loop-builder as the build-coordination pair to sat-loop-orchestra.
  • contract highlights
    • Explicit sat-loop-builder invocation rules and run modes (full, focused, guardrail, research-critique).
    • Evidence state transition guards and approval gates.
    • Builder-run ledger contract (structured decision trace, not transcript).
    • Disagreement preservation and claim-candidate handling requirements.
  • boundary
    • Docs/config scaffolding only.
    • No runtime behavior, migrations, API route changes, server actions, or UI behavior changes.

Added — Trust Pack v0 package (docs/governance only)

Canonical trust documentation package to make Cyberplate externally assessable
before questionnaire exchange, without over-claiming implementation maturity.

  • added
    • Trust doctrine + package index:
    • docs/trust/00-README.md
    • docs/trust/00-principles.md
    • Core trust docs:
    • docs/trust/01-vendor-security-overview.md
    • docs/trust/02-deployment-models.md
    • docs/trust/03-shared-responsibility-model.md
    • docs/trust/04-data-flow-and-data-inventory.md
    • docs/trust/05-ai-agent-governance.md
    • Trust knowledge model docs:
    • docs/trust/06-questionnaire-answer-bank.md
    • docs/trust/07-evidence-map.md
    • docs/trust/08-control-map.md
    • docs/trust/09-trust-boundaries.md
    • docs/trust/10-known-limitations.md
    • Machine-readable package manifest:
    • docs/trust/trust-manifest.yaml
  • changed
    • docs/GATES.md extended with Gate TrustPack-v0 objective gate criteria.
  • principles
    • Claim-safe trust language tiering established:
    • implemented
    • planned
    • not_available_yet
    • Evidence maturity lifecycle established:
    • draft, internal, reviewed, approved, auditable, customer_shareable
  • boundary
    • This package is documentation/governance scaffolding only.
    • No schema, migration, runtime, or feature behavior changes were included.
  • fixed
    • Trust Pack traceability pass: evidence IDs, questionnaire linkages, deployment slug aliases, and control-map framework tags aligned across docs/trust/*.
    • Trust Pack operational hardening: named approver, Gate TrustPack-v0 GREEN sign-off, expanded answer bank (10 records), shared-responsibility evidence IDs, and reviewed maturity for core implemented evidence.

Added — ITM Enforceable Contract Gate phase (docs/gates only)

Documentation/governance hardening phase to make IT Manager architecture work
enforceable before any schema or feature implementation.

  • added
    • ITM scaffolding canon docs:
    • docs/architecture/ITM-FOUNDATION-ARCHITECTURE.md
    • docs/architecture/DECISIONS.md (ADR-ITM-001..008 canonical owners)
    • docs/product/STORY-REGISTRY.md
    • docs/product/BUILD-SEQUENCE.md
    • .cursor/rules/sat-loop-stories.mdc
    • Product index links for ITM scaffolding in docs/product/README.md.
  • changed
    • Hardened all 8 ITM contracts into Decision / Invariant / Primitives / Acceptance tests format.
    • Added explicit canonical ADR ownership mapping per contract (C1..C8 -> ADR-ITM-001..008).
    • Extended docs/GATES.md Gate ITM-Contracts with atomic proof rows.
    • Defined documentation precedence and sequence-vs-precedence semantics across architecture/build/rule docs.
  • enforced
    • Cursor guardrails now require pre-read order and dependency checks before any US-ITM-* work.
    • Stop conditions explicitly cover migrations, SQL execution, server actions, UI routes/components, feature behavior, gate bypass, and invented dependencies without TODO markers.
    • ADR canonical ownership is now explicitly referenced by lower-precedence docs.
  • blocked
    • This phase explicitly blocks:
    • migration creation/modification
    • SQL execution
    • server action implementation
    • UI implementation
    • feature behavior implementation
  • proof artifacts
    • docs/GATES.md -> Gate ITM-Contracts rows define proof obligations for decisions, invariants, primitives, acceptance-test obligations, dependency mapping, precedence, stop conditions, and docs-only boundary.
    • docs/architecture/DECISIONS.md is canonical for contract definitions; architecture/build/rule docs reference it by precedence.
  • next gate
    • Gate ITM-Foundation (design of schema primitives + contract tests) may start only after Gate ITM-Contracts is explicitly GREEN.
  • status
    • Status: Gate ITM-Contracts is GREEN by human sign-off. This gate covered documentation/governance only; no migrations, SQL execution, server actions, UI, or product features were implemented.
    • Acceptance tests are documented as obligations; implemented test files are not part of this phase.
    • No migrations, SQL execution, server actions, UI implementation, or product feature behavior were implemented in this phase.

Added — In-repo UI kit + campaign accordion (working tree)

Canonical Cyberplate UI reference inside SAT Loop, plus a multi-open accordion
for the campaign wizard. Contract: docs/design-system/UI-KIT.md,
docs/design-system/BRAND-UI-AUDIT.md.

  • UI
    • /styleguide — live token + component gallery (dark/light, Gate 0 --sa2-*)
    • components/shell/accordion.tsx — multi-open panels with grid-template-rows slide; honors prefers-reduced-motion
    • Campaign wizard converted from single-step activeStep to multi-open accordion (components/campaign-wizard.tsx)
    • components/shell/cyberplate-button.tsx — blue slide tier + silver tool-tier CTA primitive aligned to website/fake-mailer doctrine
  • CSS (app/globals.css)
    • Accordion, brand button slide, HRR table/modal, wizard nav/track tokens
    • Reconciled low-risk token gaps from website + HRC visual guide audit
  • Docs

Changed — Cockpit reframed around evidence loop (not launch-first)

Primary cockpit action is now a guided loop CTA instead of a bare
"Launch campaign" button. Role-aware steps walk signals → critical driver →
open questions → response choice, with spotlight targeting on real panels.

  • UI
    • components/cockpit/cockpit-loop-cta.tsx — overlay tour + docked guide card; resume state no longer stale after casual dismiss
    • Cockpit quest-log panel copy tightened (active questions, journal state)
    • PageShell action slot uses loop CTA for managers/admins
  • Tests
    • tests/e2e/cockpit.spec.ts updated for new CTA + tour behavior

Added — Guided InfoHint spotlight

Contextual help that guides instead of dumping prose: underlined trigger,
dimmed backdrop spotlight on the target panel, docked structured guide card
(label/value facts + next action).

  • UI (components/shell/info-hint.tsx)
    • Portal-rendered guide placement (right/left/bottom fallback)
    • Alarm banner level hints refactored to structured facts
  • Tests
    • Covered via updated cockpit e2e flows

Fixed — SSR date locale hydration

Date formatting now uses a consistent locale on server and client so alarm
and register timestamps do not mismatch after hydration.

Added — Route transition reveal + loading fallback

Single-owner pathname observer in root layout; no stacked full-screen overlays.

  • UI
    • app/_components/route-transition-observer.tsx + route-reveal-overlay.tsx + aperture-logo.tsx — compositor-only reveal keyed on usePathname()
    • app/(app)/loading.tsx — real pending fallback (role="status", aria-live="polite"), simpler pulse (not full zoom reveal)
    • CSS keyframes: .sa2-route-content--reveal, .sa2-route-reveal*, .sa2-loading-logo; reduced-motion fallbacks
  • Marketing
    • app/(marketing)/page.tsx capability-first copy reframe + hero window mockup hooks; Cyberplate logo assets in public/

Changed — Bottom HUD alarm + mobile navigation

Alarm moved from header lamp to a persistent bottom HUD; header simplified.

  • UI
    • components/shell/alarm-hud.tsx — bottom threat strip with expandable detail
    • components/shell/threat-bars.tsx, components/shell/disclosure-block.tsx
    • components/shell/mobile-nav-drawer.tsx — responsive nav drawer
    • Removed header AlarmLamp; alarm popover/detail via HeaderPopover
    • components/shell/app-header.tsx — nav grouping and organization pass
  • Domain (lib/hrr/display.ts)
    • Shared HRR risk display helpers for driver/HUD consistency
  • Tests
    • tests/e2e/alarm.spec.ts, tests/e2e/mobile-nav.spec.ts, tests/e2e/header-popover.spec.ts, tests/unit/alarm-driver.test.ts

Added — Decision Core Phase A (readiness → decision brief gate)

Closes "no decision, no simulation" at the decision brief layer: a brief
cannot be created unless a ready readiness gate exists for the org + scenario.

  • Data model (migration 0010_decision_core_phase_a.sql)
    • decision_briefs.scenario_id, .owner, .deadline
    • create_decision_brief RPC rejects with readiness_not_approved when no ready gate exists
  • UI (/loop/[stage])
    • Decision-brief create blocked/hidden with clear reason when gate not ready; primary CTA per state; FailureState on denied
  • Authz (lib/authz/matrix.ts)
    • run_readiness_gate, create_decision, close_decision ops added
  • Tests
    • supabase/tests/sql/0010_decision_core_phase_a.test.sql, tests/e2e/smoke.spec.ts decision-path coverage

Changed — Cockpit, register, completions explorer overhaul

Major awareness-cockpit and operator-surface pass before the evidence-loop CTA.

  • UI
    • components/shell/alarm-driver.tsx, alarm-banner.tsx, awareness-program.tsx — two-beat cockpit narrative (alarm then program)
    • components/completions/completions-explorer.tsx + tree/rows — sortable, segment-importance-weighted completion explorer
    • Register guided wizard refactor (register-guided-wizard.tsx, wizard-nav-pills.tsx, wizard-slide.tsx)
  • Domain
    • lib/domain/cockpit.ts, completions-tree.ts, completions-sort.ts, segment-importance.ts, alarm.ts
  • Docs
    • docs/product/SOLO-N1-OPERATING-PLAYBOOK.md added
  • Tests
    • tests/e2e/completions.spec.ts, unit coverage for cockpit/completions

Added — App shell, register import, demo onboarding (Jul 4 foundation)

Layout/navigation refactor, mock demo entry, and register/campaign operator tools
that underpin the Jul 4–5 feature slices.

  • UI
    • AppHeader + BrandLockup; animated sun/moon theme toggle
    • Demo onboarding experience for mock mode; serial Playwright mock runs
    • Register CSV import + reset; campaign wizard enhancements
    • Human Risk Register UI polish (register-view.tsx, dim cards)
  • Shell
    • Audit/communication pages streamlined with shared shell components

Added — HeaderPopover for alarm/header interactions

Reusable anchored popover primitive for alarm detail and header menus
(components/shell/header-popover.tsx).

Changed — Gate overrides replace global Overkill mode

Removed the global "Overkill mode" header toggle + persistent cockpit
banner. Planning-gate softening (G2 control, G4 risk link, G5 alarm fit) is
now per gate, per campaign draft instead of a session-wide bypass; G1
(owner) stays permanently hard-blocked either way. Contract:
docs/product/GATE-OVERRIDES.md.

  • UI
    • Cadence pills below the current alarm's minimum are greyed with a lock icon and an inline "Override this gate" control + tooltip (components/campaign-wizard.tsx, components/gate-override-control.tsx)
    • Planning gate checklist rows for failed G2/G4 gates carry the same inline override control (components/planning-gate-checklist.tsx)
    • Removed OverkillToggle / OverkillBanner from the app header and layout; deleted components/overkill-toggle.tsx
  • Domain (lib/domain/planning-gates.ts)
    • evaluateCampaignPlanningGates(input, { overrideGateIds }) replaces the { overkill: boolean } option; OVERRIDABLE_GATE_IDS excludes G1/G3
    • Server (createAndLaunchCampaign) validates overrides against the same enum and re-evaluates gates itself before accepting any override
  • Audit
    • Retired the planning.overkill_bypass ops-log event; replaced with one planning.gate_override event per overridden gate ({ gate_id, reason })
  • Removed
    • MOCK_OVERKILL_COOKIE / getOverkillMode() (lib/auth/mock-session.ts) and the sa2-overkill-mode cookie
  • Docs
    • docs/product/OVERKILL-MODE.md replaced by docs/product/GATE-OVERRIDES.md
    • docs/product/PLANNING-GATES.md, docs/product/US-DEMO-001-acceptance.md, docs/GATES.md updated to the per-gate model

Added — Quest Log + guided HRR entry (mock-first slice)

The discovery loop that feeds the register: one journal entry fans out into
idiographic (org-specific human risk) and nomothetic (standardized
email-security) question tracks; the answers converge on one guided Human
Risk Register row. Contract: docs/product/QUEST-LOG-CONTRACT.md.

  • UI
    • /quest-log (Advanced nav) — two-column shell: quest queue left, journal capture + open-question answering right; ready-state CTA deep-links to the guided register entry (/register?guided=1&session=<id>)
    • Cockpit Quest log panel with open-question count
    • Guided register entry on /register: five dim-card steps (accountant self-check interaction — max two cards open, answered cards collapse and re-open on click), pre-filled from Quest Log answers; existing form relabeled Quick add — skip the guided path
    • Evaluation session toolbar stub on the register: visible, disabled, “planned for a later release” (roadmap placeholder only)
  • Domain (lib/domain/quest-loop.ts, rule v1, deterministic — no LLM)
    • Fixed follow-up set: 6 idiographic (department, process, € band, owner, title, why-in-register) + 3 nomothetic (email path, scenario family, probe recency)
    • readyForHrrWizard gate = minimum idiographic set answered
    • Nomothetic bridge: the email-path answer maps to a ReadinessSignal and records a readiness gate via decideReadiness (Contract 2); the probe question deep-links to /loop/probe
    • Wizard prefill mapping in lib/hrr/prefill-from-quest.ts (€ band → impact suggestion, reviewer-overridable)
  • Data (mock-first; Supabase tables deferred)
    • QuestJournalEntry / QuestQuestion / QuestSessionSummary contracts + adapter methods; journal creation also seals a curiosity snapshot (sourceSnapshotId) so the traceability/hash story holds
    • SupabaseAdapter throws quest_log_not_migrated; quest surfaces degrade gracefully outside mock mode
    • Audit events for journal creation, question generation, and every answer (metadata only — never raw text)
  • Tests
    • tests/unit/quest-loop.test.ts — generation, readiness rules, signal mapping, prefill (12 cases)
    • tests/e2e/quest-log.spec.ts — journal → answers → guided wizard → register row happy path

Added — CISO Curiosity intake (MVP slice)

Compressed from a phase-2-shaped design into a shippable v1: capture → immutable
source → one pipeline run → draft candidates → human review → manual
promote / link / archive.

  • UI (/curiosity, /curiosity/[id], cockpit summary panel, nav link)
    • Text capture with alertness-driven prompt
    • Optional private draft (author + org admin only; pipeline deferred until “Process now”)
    • Reviewer queue: approve, reject, archive, add to register, link to existing risk
    • Traceability view: sealed source, pipeline run, candidates, links
  • Domain (lib/domain/curiosity.ts)
    • Keyword prefilter (rule v1), deterministic MVP extractor seam, confidence bands
    • Routing gates (severity × confidence, escalation, duplicate suggestion)
    • Decision vs conditional escalation: “if X, escalate” → monitoring_item, not decision_record
    • Simple duplicate detection (normalized title overlap; no embeddings)
    • Eight durable snapshot states; internal steps live in pipeline_runs
  • Data model (migration 0009_curiosity_engine.sql)
    • curiosity_snapshots — immutable sealed source (server SHA-256)
    • curiosity_pipeline_runs — prefilter + extractor output + confidence + explainability in one row
    • curiosity_candidates — canonical contract with suggestedTarget
    • curiosity_linksduplicates | created_from | related_to
    • RPCs: create_curiosity_snapshot, run_curiosity_pipeline, review_curiosity_candidate
  • Authz (lib/authz/matrix.ts)
    • ciso_viewer: capture + read; cannot promote/review
    • org_admin / delegated consultant: review + promote
    • Trainees: no curiosity access (oversight-only reads)
  • Tests
    • tests/unit/curiosity.test.ts — domain, routing, extractor, mock adapter (26 cases)
    • supabase/tests/sql/0009_curiosity.test.sql — RLS, immutability, authz, promotion audit

Changed

  • Collapsed curiosity schema from seven artifact tables to four (+ existing audit_log)
  • Review decisions narrowed to: approve | reject | archive | promote_to_risk | link_to_risk
  • Candidate fields aligned to one contract: type, rationale, suggestedTarget (was split across extraction/review rows)

Removed (explicit post-MVP)

  • Voice / transcription capture
  • curiosity_follow_ups, curiosity_reviews, separate prefilter/extraction tables
  • Follow-up question loops and request_follow_up reviewer action
  • Trend detection, weak-signal aging, embeddings, cadence automation
  • Granular persisted pipeline states (confidence_scored, awaiting_human_review, etc.)

Security

  • Raw snapshot text never in audit detail, ops logs, or notifications (ids/metadata only)
  • Private drafts hidden from other oversight roles until released
  • RLS deny-by-default; no client writes; seal trigger on snapshots
  • Promotion to human_risks only via review_curiosity_candidate (server-scored L×I)

---

[0.1.0] — prior baseline

Security Awareness / Human-Risk Evidence Loop: mock-first SMB loop (rooms,
branching quiz, completion records, demo evidence pack), Phase 1 tenant auth +
RLS, human risk register, cockpit, evidence engine, probe safety — see
docs/GATES.md and README.md.

[Unreleased]: https://github.com/cyberplate/cyberplate-sat-loop/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/cyberplate/cyberplate-sat-loop/releases/tag/v0.1.0