Phase 4
Governance Wireframes

Source: c114 governance-phase2 — Phase 2, the surface map as blocks · 2026-10-09

Grey boxes, bob-wire grain: the eight surfaces the intents imply, each as blocks in reading order, with the intent that asks for each block. One rule from surface-map.md: every object has one home, every relationship one traversal, and every state change renders through the same lifecycle organ. Nothing here is styled; the argument is page shape.

Govern rail, proposed

Findings first (the journey starts in Observe); Policies & Frameworks as one area with three views; Groups a view, not a rail item.

today
Policies · "Control Center"ComplianceFindingsReportsSecurity Posture · Data Protection · Campaigns · Alerts EXP
proposed
Findings /findingsPolicies & Frameworks /policiesPoliciesFrameworksGroups/compliance → /policies?view=frameworks · /framework and /policies/detail keep their routes · /policies/groups deep-linksReportsSecurity Posture · Data Protection · Campaigns · Alerts EXP
S1

Finding detail

/findings/detail?findingId=

The spine. Evidence above the line, lifecycle below it, the response on the side. A finding read without opening the session.

[finding][investigate][resolve][reeval]
1. Breadcrumb + header · Resolve ▾ · Open session[finding]

Findings / policy / F-A. Title = policy name · resource. Joins the sticky band.

Resolve ▾Ignore…Create exception…Open session
2. Band[finding] [investigate]
Status
Severity at generation · now
Policy → S3
Applies via
Enforcement for this subject
Detected
3. What happened · evidence, immutable[finding] [session]
the evidence sentence
user · team · device · agent · account
the resource
Open at 14:09 in Session 1 → timeline point
4. Why it violates[finding] [scope]
the condition, in words
policy version that evaluated it
scope paths that reached the subject
exceptions considered, and why not
5. Lifecycle · the organ[resolve] [reeval] [ignore]

Rows append; reopen, expiry and revoke are rows, never edits.

current state · derived
timeactorwhat → statecause → Change
6. Related findings · same policy[investigate] [finding]
findingsubjectstatusdetected
"see all" → S2 filtered by policy · "a scope or exception change would affect N of these" → S3
7. Respond · aside[investigate]
Allow · exception for a scope → S8bresolves 1 of 2
Remediate · ticket seamstays open
Block · enforce for a scope → S6resolves 1 once confirmed
Ignore · this finding → S8resolves 1
carries over

c79 finding-detail-v1 (occurrence stream, audit record), finding-disposition-v1 (verb row); qdash AdjudicationCard, FindingsMembers; layer PageHeader, StickyBand, NavJumpPills, SeverityTag.

new

The organ (to extract), the Respond aside with reach counts, the "applies via" path, evidence / state as two blocks.

states the mock renders

Unknown id · only its detect row · F-A at the end of the story (five rows) · a sanitization finding with 40 related and 12 rows.

S2

Findings

/findings

Open work first, grouped by the policy producing it. One table with two shapes; the switch never changes the filters.

[findings][investigate][reeval]
1. Header[findings]

Findings — open, grouped by policy (the default named in the subtitle).

2. Cards · open by severityqdash today
Critical
High
Medium
Low
3. Listing bar[findings]

Open on by default; Resolved includable; Open off + Resolved on = resolved only. Grouped ⇄ Individual on an ink switch; column picker on the right.

Open ✓Resolvedpolicyseverityteam / usersearchGrouped ⇄ Individualcolumns
4. Grouped table · one row per policy[findings]
policy → S3count (filters)severityopen / resolvedlast detected
expand → members: id · subject · resource · detected · status / resolution · last event · row → S1
5. Individual table · the same members, flat[findings]
finding → S1policysubjectresourcedetectedstatus
carries over

qdash /findings (FindingsFilterBar, FindingsLedger already group by control), design findings-regroup-v2, findings-status-column-v1; layer DataListingBar, UxTableListExpandRow, StateEmpty, FilterNoMatches.

new

Status filter semantics, the Grouped ⇄ Individual switch, the group header as a link to the policy.

states the mock renders

Nothing open (resolved count as the hint) · filtered to nothing · the fixture, 19 in 2 groups · 400 findings in 9 groups, one collapsed.

S3

Policy detail

/policies/detail?policyId=

Everything that hangs off a Policy, configured in its context: severity, where it applies, enforcement per scope, exceptions, groups, frameworks, findings, history.

[policy][severity][scope][enforce]G1[catalog]
1. Breadcrumb + header[policy]

Policies & Frameworks / name · category · "Qpoint policy · v3".

ObserveEnforce
2. Band[severity] [policy]
Effective severity High · recommended Medium · Reset
State
Open / Resolved → S2
Enforcement summary
Groups
Frameworks
3. Jump pillsc104
DefinitionWhere it appliesEnforcementExceptionsGroupsFrameworksFindingsHistory
4. Definition[policy]
what it tests
why it matters
what fails
what enforcement does
"Show condition" → the Rule (internal)
5. Where it applies · Scope[scope]
scopevia (direct / group → S7)specificityenforcement here
overlap callouts · Add scope → S6 · "Effective for a person" probe (the D1 function, conflicts shown)
6. Enforcement · per scope[enforce]
scopelevelreachtoggle → S6
observe-before-enforce guidance per scope: "3 open findings · 1 exception in this scope"
7. ExceptionsG1 [scope]
allowscopereasonuntilbyrevoke
Add exception → S8b
8. Groups that include this policy[groups]
Engineering AI Controls → S7
Finance AI Controls → S7
9. Frameworks · mapped requirements[framework]
OWASP LLM Top 10 · LLM03:2025 Supply Chain → S5
what this policy contributes
10. Findings[policy]
Open
Resolved
highest open severity
see all → S2
11. History · the organ[severity] [scope] [enforce] [reeval]

Overrides, scope changes, enforcement changes, exceptions, versions. Anchors are the targets of S1's cause links.

current state · derived
timeactorwhat → statecause → Change
carries over

qdash PolicyDetail (layer PolicyConfigShell), PolicyConfig shapes; design control-detail (definition / response split), policy-catalog-v3 (inline exceptions).

new

Recommended-vs-configured severity pair (to extract), the scope paths table, per-scope enforcement rows with reach, the organ.

states the mock renders

Unknown id · applied nowhere (Add scope) · P-MCP (override, two groups, exception, scoped enforcement) · P-SENS-SANITIZE (org-wide confirmed, 16 findings, 3 frameworks).

S4

Policies & Frameworks

/policies · ?view=policies | frameworks | groups

One area, three distinct lists on an ink switch. The framework strip that activated policies retires; coverage is derived.

[catalog][severity][groups][framework]
1. Header + view switch[catalog]
PoliciesFrameworksGroups
2. Policies view · listing bar + table by category[catalog] [severity]
policy → S3severity (configured · recommended · Reset)capabilitystateframeworksopen findings
group by: category (default) · Policy Group
3. Frameworks view[catalog] [framework]
framework → S5publisher · versiontypetrackedrequirementscoverage fully / partially / notopen findings
"Tracked" = track without changing any policy (proposal for the activation question)
4. Groups view[groups]

S7's list, embedded.

carries over

qdash ControlsPolicies (categories, toggles), ComplianceFrameworksListing; design policy-catalog v1–v3, compliance-frameworks, framework-listing; layer UxTabGroup, DataListingBar, ComplianceTag.

new

The three-view area; the inline Reset. Retired: the global framework strip, the "Control Center" title, custom controls and the evidence packet (to Reports).

states the mock renders

Frameworks with none tracked · policies filtered to nothing · typical · 60 policies in 9 categories.

S5

Framework detail

/framework?frameworkId=

Where the gaps are. Capability, configuration and findings kept distinct per requirement; nothing hidden; a risk taxonomy is not a compliance standard.

[framework][catalog]
1. Back + header + summary band[framework]

name · publisher · version · type called out · tracked toggle

requirements
fully
partially
not addressable
open findings via mapped policies
2. What coverage means · disclosure[framework]

Derived from mapped Qpoint capability, never asserted. Qpoint alone satisfies nothing unless explicitly supported.

3. Requirements table[framework]
source id · labelcoveragemapped policies → S3 (capability · org config · open → S2)gap reason
filter by coverage state · gap reasons: no policy · not in scope · observed not enforced · procedural
4. Gaps · requirements with no policy[framework]
LLM01:2025 Prompt Injection — no Qpoint policy
A.6.3 Awareness training — procedural
carries over

qdash FrameworkHeader, FrameworkRequirements; design framework-detail (addressability column).

new

Coverage states and gap reasons replace the completeness bar; per-control toggles leave (configuration happens on the Policy).

states the mock renders

Untracked · zero mapped policies · OWASP LLM (fixture) · ISO 27001 with 93 requirements, filter on.

S6

Scope & enforcement change

sheet

One flow for both, because the preview is the same: what will this touch, before the button.

[scope][enforce][reeval][groups]
sheet · opened from S3 Where it applies · S3 Enforcement · S7 Scope
1. Choose[scope] [enforce]
dimension
value
specificity (shown)
enforcement: observe ⇄ enforce
the action, in words
2. Preview · derived, before apply[scope] [enforce] [reeval]
affected population · count + sample
broadens / narrows
overlapping paths · conflicts (D1)
findings that re-evaluate: 2 resolve · 1 reopens (D2)
observe first? open findings · exceptions in scope
expected reach (D3)
3. Apply[scope] [enforce]

The audit line as it will appear in History. Result: a Change; S3 rows update; enforcement counts configured → confirmed.

Apply changeCancel
carries over

design policy-config-egress-allowlist (scoped entries); layer UxModal.

new

The change-preview panel (to extract; reused by S7 and S8b).

states the mock renders

Scope with no population (warn) · already covered by a group (duplicate path) · a conflict · typical (Team Legal added; Finance enforced).

S7

Policy Groups

/policies/groups · /policies/groups/detail?groupId=

Populations, not duplication. A group references policies and carries a scope; overlaps are named, never hidden.

[groups][scope][enforce]
1. List[groups]
group → detailpurposepoliciesscopestateenforcement summaryopen findings
New group · Duplicate
2. Detail · header[groups]

name · purpose · state

DuplicateRetire (keeps history)
3. Scope[groups] [scope]
Team: Engineering
population
change → S6
4. Policies · references, never copies[groups]
policy → S3severitycapabilityenforcement in this scopeopen findings
Add policies · picker over the catalog
5. Overlaps[groups] [scope]
other groups sharing members: Corporate AI Baseline · 3 shared policies · 1 conflict
effective policies for a person in scope (the probe)
6. History · the organ[groups]

Membership, scope and state changes.

current state · derived
timeactorwhat → statecause → Change
carries over

Nothing in qdash; design framework-picker-ideas (compact pickers); the S3 blocks.

new

The whole surface. Lifecycle states (draft · active · disabled · retired) are the open question.

states the mock renders

No groups ("policies apply directly until you need populations") · a draft with no scope · Engineering (overlaps the baseline) · retired, read-only with its history.

S8

Resolve with Ignore · Create exception

sheets

The decided flow from the Ignore intent, and the missing Exceptions intent drafted as its secondary action.

[ignore][resolve][investigate]G1
sheet · opened from S1 Resolve ▾ · an S2 row
1. Ignore · finding summary[ignore]
id · policy · subject · resource (read-only)
2. Reason · optional[ignore]

Blank → "Providing a reason is a best practice for compliance…" with Confirm · Cancel · Don't ask again (per practitioner).

reason
3. Duration · required[ignore]
Until a dateIndefinite
4. Ignore finding[ignore]

After success: Done (primary) · Create an exception (secondary). The policy is untouched; future matching activity still evaluates.

Ignore findingCancel→ Done→ Create an exception
5. Create exception · G1, drafted[scope] [enforce] [ignore]
policy (fixed)
allow · the resource
scope · defaults to the team
reason
duration
6. Preview · the S6 panel[reeval] [enforce]
2 open findings match this resource · 1 in scope would resolve as Allowed
enforcement is active here · allowed activity will not be blocked
7. ApplyG1

A Change; re-evaluation runs; S1's organ gains its row. Resolved: Enforced has no sheet — it is a system row linked to its Change (D3).

Create exceptionCancel
carries over

design finding-disposition-v1 (reason / expiry capture), policy-config-agent-registration (carve-out with reason + expiry); layer UxModal, UxInput, UxSelect.

new

The warning with Don't ask again; the Done / Create an exception pair; the exception builder with the preview.

states the mock renders

Blank reason (the warning) · indefinite · F-C until 31 Oct (fixture) · an exception that would resolve 0 findings.

Intents × surfaces

● primary · ○ secondary. Every intent has one primary surface; nothing is homeless. Re-evaluation has no page: it is organ rows and preview counts.

IntentS1S2S3S4S5S6S7S8Session
[session] Review a session○●
[investigate] Investigate and respond●○○○○
[finding] View a finding's details●
[findings] View all findings○●
[catalog] View policies and frameworks○●○○
[policy] View a policy's details●○
[framework] View a framework's details○○●
[scope] Configure policy scope●●○
[severity] Configure policy severity●○
[enforce] Enable / disable enforcement○●●○
[groups] Manage policy groups○○○●
[ignore] Resolve with Ignore○○●
[resolve] Resolve a finding●●
[reeval] Re-evaluate after change●○○●○○
G1 Manage exceptions (missing)●●

Composition notes

  • Scope, Enforcement, Exceptions and Change are not pages. They are configuration of a Policy and read in its context; a top-level Scopes page would be engine parts exposed.
  • One flow for scope and enforcement changes (S6), because the preview is the same: population, broadens or narrows, overlaps and conflicts, findings that would re-evaluate. S8b reuses the preview.
  • The organ is the same component in the same place on S1, S3 and S7, and the Apply step of every sheet shows the row it will gain.
  • Frameworks stop activating policies. The strip that drove the Control Center goes; coverage is derived from mappings and configuration happens on the Policy.
  • The eight mocks follow in this order; each renders the fixture world's four states (empty · minimal · typical · overflow).

Qpoint Brand Style Guide