← Design · c123

intents-pr5-plan.md

Thread `intents-pr5`: plan (2026-11-05)

From intents-pr5-prompt.md and intents-pr5-evaluation.md. Status: Phases 0–8 are built, committed locally, not pushed and not deployed. Mark's review comes next: intents-pr5-review.md.

Home: c123 owns this thread, because its scope says "we review against them when they land" and the framework definitions are its own.

  • c128 owns the Reports phase, and reads c123's definition rather than making its own.
  • c126 is coordinated with on the Policies phase, since c123 "owns the framework parts of these pages".
  • c125 owns the tour files, so tour copy changes go through that thread.

Stays in the lab: the shared world and the composed mocks. No layer release and no qdash port until the pages are reviewed.

Mark's rule (2026-11-05)

Posture reports only on what Qpoint can know and govern. This covers all posture, not just percentages. It never claims how much of a framework is met in the abstract, and things Qpoint has no relevance to stay out of the measure.

Merging PR 5 wasn't meant to settle anything over the Nov 4 metric. Where Mark's rulings below differ from the intent, his rulings hold in the lab, and the difference is his to raise with Peterson.

Decisions first

Rulings are marked. The rest have a default, and the plan runs on the defaults unless Mark changes them.

#QuestionDefaultWhy
D1Which calculation does posture use, inside what Qpoint can know?Ruled by Mark, 2026-11-05: two metrics, not one. Enforcement Posture: how much of the work toward ideal is done. A mapping is at its ideal when its policy reaches the strongest mode it can: Enforce, or Observe if it can only observe. Done everything possible reads 100%. Exceptions: a separate metric, led by direction: active, tighten, loosen, expiring. Established OWASP LLM: 40%, 10 of 25 mappings at ideal, 10 policies left; 7 exceptions (3 tighten, 2 loosen, 2 neutral)"The score should guide them in how much work towards ideal they have left." To confirm: an enforceable policy at Observe counts as not yet at ideal, with no partial credit. The lab departs from PR 5 here (one % per framework; limited-relevance mappings left out), so the intent needs to reflect it
D2Commit posture-score first?Done, Mark's ruling. Two local commits on main, not pushed: posture-score as built, and the Findings fixed-layout edits on their ownThe replacement reads as a diff, and the Nov 4 version stays recoverable
D3Does tracking stage policies?Ruled by Mark: no, tracking changes nothing, and a separate button does the staging. F8 retires as written. The framework page offers "Add these 16 policies to the draft at Observe" as its own deliberate step, showing what will change firstKeeps the fast start and frameworks as the way in (c118 A6, Q10), without a reporting click changing configuration. Goes a little beyond PR 5, which only describes linking to policies
D4Does anything replace the bulk route?Settled by D3. "10 policies to change" links to those policies, filtered to this framework, and the staging button sits beside it. Only Off policies move, and only to Observe. Enforce stays a choice made per policy"Enable Required Policies" changed live state from a tile. This goes through the draft and previews first
D5A posture reading on each row?Ruled with D6: yes, the small bar with its %. Each row counts its own mappings, on the same rule as the bandMark asked for a per-row bar on Nov 4
D6Bar coloursRuled by Mark: green at 100%, orange for work left, red only when a policy in that row is Off. The number always sits beside the barHis Nov 4 rule of red under 25% would mark a careful rollout red: on NIST with a pilot running, 8 of 15 rows, 6 of them with nothing Off
D7What happens to Compliance Score?Ruled by Mark: keep it as built. Severity box with seeded checks, marked projected, on listing and detail. Options A–F stay behind ?v.score=, with A the default until he picksSits against the knowable-only rule until the backend counts checks, so the seeded base stays visibly marked and needs a real source before any qdash port. PR 6 rules out a compliance score, so this also differs from the intent, and it stays out of Reports unless he says otherwise
D8The shared termRuled by Mark: Controls, on every framework. The column reads Control and sections read Controls, replacing Items and Name. Each framework's own word can appear in its descriptionOne shared word across the table. PR 5 asks to preserve source terms, so this is another difference from the intent
D9Catalog in the labRuled by Mark: all five, as now. OWASP LLM, OWASP Agentic, NIST AI RMF, ISO 27001 and SOC 2PR 5 proposes three and leaves approval open, so the lab's list isn't a release decision
D10What do untracked frameworks show?Ruled by Mark: name and description only; posture appears once tracked. Assumed: the same holds for Compliance Score and Exceptions, and framework detail still lists controls and mapped policies, with no posture, Score or historyPR 5 keeps untracked frameworks inspectable with their mappings, and says retained samples mustn't read as current
D11Reports: which, and in what form?Ruled by Mark: PR 6's four, as living pages. Inventory, Findings, Compliance and Executive Summary replace Posture, Inventory and Deployment status. Living reports stay over PDF. This reverses his Nov 3 rulings that Findings is a section of Posture and that the Board folds into the catalog. The framework section changes firstOne clear reader per report, and "Posture" stops meaning three things. PR 6 merged the same day; it makes on-demand PDFs the only format, so living reports differ from the intent, and that's his to raise
D12Is it a rebuild?No, ruled by D11. The living report page, readers, sections, basis tags and shared window all stay. A PDF, if offered, is a fixed snapshot downloaded from the pagePR 6's real need is a document a reader without an account can keep, with its filters and data cutoff
D13What is the score called?Ruled by Mark: Enforcement Posture. The policy pills column, which he named that on Nov 4, becomes PoliciesSays what's measured, and 100% can't be read as "compliant"

Phases

Mark reviews the whole result at the end (2026-11-05) rather than page by page. Illustrator follows his notes if he wants it.

0. Rulings and snapshot

  • Mark rules D1–D13.
  • Done: 0d01a2ea9c (posture-score as built) and b228984aea (Findings fixed layout), both local.
  • Update CYCLE.md's objective: F8, the four states, "no percentage", evidence as described rather than counted.

1. The model: one calculation (built 2026-11-05)

The pages don't read this until Phases 3 and 4, so the Nov 4 functions stay until then. labelsAbridged replaced officialTitle.

All in governance-fixture.ts, so listing, detail, policy and report read one function (R3, and PR 5's "same calculation").

  • enforcementPosture(framework, world): each addressable mapping is one unit, at its ideal when its policy reaches the strongest mode it can. Returns the % at ideal, counts by mode, the distinct policies left to change, and available: false when nothing is mapped. It reads the policy's own mode, never exceptions.
  • exceptionsRead(framework, world): active, tighten, loosen and expiring, from live() exceptions on the mapped policies, each counted once.
  • Framework fields: sourceUrl, mappingRevision with an applicability date, native group on each requirement, optional officialTitle.
  • Tracking as a preference: tracked plus an audit log with actor, time and previous and new state.
  • Fill SOC 2 mappings, grouped by Trust Services category, from the CC3, CC6, CC7, CC9 and PI1 areas in research/frameworks-dossier.md. NIST gets its four functions as groups.
  • postureHistory(framework, world): replays config versions and exception dates, seeded further back to match c128's twelve months. Each point carries edition, mapping revision and whether it's reconstructed. Includes one mapping change, so the mark has something to mark, and an unavailable range.
  • Rewrite: policyPosture, requirementPosture and frameworkPosture give way to the above, and the 0.25 and 10-point weights go. ComplianceBar stays, with D6's colours. scoreOf, SCORE_VARIANTS and ComplianceScoreCell stay (D7). scoreOf reads how many people each policy reaches from policyPosture, so that part has to survive the rewrite.
  • Keep or trim: coverage() stays only as long as Gaps and the record pages read it.
  • New check: scripts/c123-metrics-check.mts is rewritten around D1 and PR 5's counting examples:
    • an observe-only policy at Observe is at ideal; an enforceable one at Observe isn't
    • limited-relevance mappings stay out of the measure
    • exceptions never move the %
    • red only with a policy Off
    • a duplicate pair adds nothing
    • a policy on three controls gives three units
    • an exception on a many-control policy counts once
    • expired, revoked and pending exceptions are excluded
    • a draft change moves nothing
    • nothing mapped is unavailable
    • history uses the mode at that time

Also update governance-model.vue and add a note to c114's object-model.md: Edition, Mapping Revision, Organization Framework Preference, Posture Snapshot.

2. Tracking leaves the draft (built 2026-11-05)

  • Add framework-track to OPERATIONAL in useGovernanceMock.ts, and drop its draftKey, sameAsLive and KIND_LABEL handling.
  • Track and Untrack apply at once, and the page moves immediately.
  • Verbs everywhere: Track, Untrack, Tracked, Untracked. Untrack still asks first, and says what it hides and that no policy changes.
  • Check in the browser that a draft change moves neither metric; the script can't reach the draft.
  • Show the audit: a quiet "Tracked by Dana, Oct 3" on detail, with the log behind it.
  • Add the separate staging step (D3): a button on framework detail that lists the framework's Off policies, then adds them to the draft at Observe as ordinary mode-set lines. It's hidden when nothing is Off, and Untrack never undoes it.

3. Compliance listing (built 2026-11-05)

  • Tracked row: name, publisher, edition and description; kind; Enforcement Posture; Exceptions; Compliance Score (D7); Untrack.
  • Untracked row: name, publisher, edition and description; kind; Track. No posture, Score or Exceptions (D10).
  • Posture cell: ComplianceBar with the %, then "10 of 25 at ideal · 10 policies left". An Exceptions cell beside it: "7 active: 3 tighten, 2 loosen, 2 match the default". Exceptions never move the bar.
  • Sections: Tracked frameworks and Untracked frameworks.
  • SOC 2's state before mappings, and any other empty one: "No mapped policies".
  • Rewrite the subtitle and intro copy; remove Add. The seeded-counts footnote stays with the Score.

4. Framework detail (built 2026-11-05)

The order follows PR 5's four parts.

  1. Understand: source link, edition, mapping revision. One line on what a mapping means. An "Excluded from active reporting" note when untracked, where the page shows controls and mapped policies only (D10).
  2. Posture band: the posture score and the exceptions metric as separate machines, with mode counts. Say that 100% means Qpoint's part is done, not that the framework is met (F1). A proper "How this is worked out" with the worked example, and D4's link. A "Preview: includes N proposed changes" label under ?preview=draft.
  3. Controls: native group rows that don't duplicate units; ID, short label and official title; policy pills; rationale and limits on every row; D5's bar; D7's Compliance Score. Columns read Control · Policies · Enforcement Posture · Compliance Score. Exception counts open a small panel with scope and override.
  4. Over time: stacked DataHistoryGraph of the three modes, exception annotations, marks at mapping revisions, reconstructed ranges marked, unavailable hatched. It follows the shared window (c128 D5).
  5. Below: "Not mapped by Qpoint" replaces Gaps and discloses the fixed v1 scope. A short "Supporting evidence" block describes Sessions, Finding resolution and configuration history, with no units. The footnote is rewritten: evidence, not a conformity claim (F1).

Empty, minimal, typical, overflow and error scenarios all need to work: SOC 2 before mappings, ISO's small set, withManyRequirements, an untracked framework, and a history with no source data.

5. Policies (with c126) (built 2026-11-05)

  • Remove ControlsFrameworks from /mock/policies, leaving the component in the tree until c126 says otherwise. This closes X1 and X2.
  • Rename the column to "Tracked frameworks", read-only.
  • Revise PolicyFrameworks: source terms, rationale in place of Contributes, Untracked, and links into the composed mock.
  • Policies listing takes ?framework=&mode= for D4's link.
  • Check c126 hasn't moved on: its page-level walk may already be in this file.

6. Reports (with c128) (built 2026-11-05)

6a, first. In reports/posture/Body.vue, "Framework evidence" becomes the posture distribution per tracked framework, read from enforcementPosture and exceptionsRead, with edition, revision, a period start and end comparison, and "if no frameworks are tracked" handled. It stops saying "with evidence".

6b onward: PR 6's four, as living pages (D11), one report at a time, each reviewed before the next:

  1. Catalog: each report's audience, questions and filters, opening a living page with the shared window and Team filter. Download PDF takes a fixed snapshot: white paper, data cutoff, filters up top. No generating queue or history list.
  2. Compliance Report: grown from 6a, plus Enforced / Observed, the Observed-only ranking, exceptions and upcoming expiry. c123's definition, c128's chassis. This one first, because PR 5 has already settled its core.
  3. Findings Report: MTTR and backlog from findingsIn, adding reopened events, reasons, and manual vs policy-driven resolution to reports-c128.ts. SLA goes.
  4. Inventory Report: Inventory and Deployment merge; gap table and the Team breakdown.
  5. Executive Summary: the Board band's sentence and highlights become a report, without a combined number. The catalog band goes or shrinks.
  6. Enforce-pilot recommendations: rule-based, with the evidence shown. Needs seeded monitored-activity counts, so the posture-score backend question about checks and sessions moves here.

Team filter across all four. CSV and JSON come out of c128's D7 for v1. Open for review as each report lands: Data protection, Egress, Spend, shadow installs and versions aren't in PR 6, so each needs a new home or a case for adding it. Compliance Score stays out of Reports (D7). plan.md's Phase 4 and its evidence-pack note get corrected. A note goes in c128's record when each lands.

7. Tours, guide and copy (built 2026-11-05)

  • OWASP close (data/tours/owasp-agentic.ts:396–403): "Track this framework to stage its policies at Observe" is wrong in three places, and the evidence-export mention is out of date. Through c125.
  • Tour chips: Evidenced stays as a mitigation description, not a posture.
  • Check the guide's explain for coverage or tracking wording.
  • governance-parts.ts and the page registry: one noun, one verb.
  • Run node scripts/tours-walk.mjs. It checks draft growth on stages, and no tour stages Track today, so it should hold; the listing's data-qp-ids must survive.

8. Record (2026-11-05)

  • intents-redline.md gets a closing note with the results from the evaluation's table.
  • Before and after captures: there are none since c123's before set, and this is the point to take them, via /capture.
  • CYCLE.md Key Changes per phase, and the story.
  • Layer extraction only once the posture cell has settled; it's a candidate for the unified pantry.
  • Deploy when asked. Port to qdash is a separate step: its /compliance still shows the older model.

How it gets checked

  • scripts/c123-metrics-check.mts, rewritten around D1 and PR 5's counting examples.
  • scripts/tours-walk.mjs.
  • On the running :3000, in the browser: Track and Untrack with no draft line, every framework in established and ?stage=adoption, ?preview=draft labelled, light and dark at 768–1600px, no console errors.
  • A consistency check: one framework's numbers match on listing, detail and report.

The tree is shared with other sessions, so check for foreign staged paths before each commit, and confirm no live executor is in a file before editing it.

Not in this plan

  • Tailoring, baselines, custom frameworks and editable mappings (PR 5 defers these).
  • Exception-adjusted posture (PR 5 names it as future work).
  • Scheduling, sharing links and machine-readable exports (PR 6 defers these).
  • A queue of generated reports (D11: living reports stay).
  • RBAC (PR 6 leaves it to another branch).
  • Sending anything to Peterson.

Qpoint Brand Style Guide