Entities and fields
Mode: reference.
The persisted schema for each Tollgate governance entity. Field names are exactly
as stored. Enum values come from packages/methodology/src/constants.js; the
persisted shapes come from the resolvers in src/index.js.
Conventions
Section titled “Conventions”| Convention | Meaning |
|---|---|
accountId fields |
Store a Jira accountId (not a name). Display names are resolved from Jira only at render time. |
| Date / timestamp | ISO strings. “ISO date” = YYYY-MM-DD; “ISO timestamp” = full datetime. |
| Nullable number | Empty / negative / non-numeric input normalises to null. |
| Sanitised text | Trimmed and length-capped (the cap is noted per field, e.g. ≤ 2000). |
| Work packages, R/I/O, decisions, changes | Stored in the Custom Entity Store (one record each). Business Case and Project Status are single KVS objects. See Data and storage model. |
Work Package
Section titled “Work Package”| Field | Type | Allowed values / notes |
|---|---|---|
id |
string (UUID) | Generated if absent. |
projectKey |
string | Owning Jira project. |
name |
string | Required, ≤ 200 chars, unique per project. |
type |
string | null | Free text, ≤ 200 (e.g. Delivery, Infrastructure, “Adoption / Change”, “Build”). |
ownerAccountId |
string | null | Jira user. |
plannedStartDate |
ISO date | null | Baseline plan. |
plannedEndDate |
ISO date | null | Baseline plan. |
actualStartDate |
ISO date | null | |
actualEndDate |
ISO date | null | |
actualEnd |
ISO date | null | Alias mirror of actualEndDate. |
forecastStartDate |
ISO date | null | |
forecastEndDate |
ISO date | null | Used for schedule-variance derivation. |
status |
enum | Not Started, In Progress, Blocked, Complete. Default Not Started. |
rag |
enum | Red, Amber, Green, Blue, None. Default None. |
budgetBaseline |
number | null | Non-negative. |
budgetForecast |
number | null | Non-negative. |
budgetActual |
number | null | Non-negative. |
commentary |
string | null | ≤ 2000. |
linkedIssueKeys |
string[] | Jira issue keys (upper-cased, typically Epics). |
sortOrder |
number | null | Manual display order for Register/Timeline; null falls back to date-then-name. |
budgetBaselineLockedAt |
ISO timestamp | null | Set when the budget baseline is locked (Initiation). Null = still setting up. |
plannedDatesBaselineLockedAt |
ISO timestamp | null | Set when the planned-dates baseline is locked. |
createdAt |
ISO timestamp | |
updatedAt |
ISO timestamp | |
updatedByAccountId |
string | Actor. |
Business Case (Charter)
Section titled “Business Case (Charter)”A single KVS object per project. Grouped below by concern.
Thesis core
Section titled “Thesis core”| Field | Type | Allowed values / notes |
|---|---|---|
projectKey |
string | |
businessProblem |
string | Sanitised. |
outcome |
string | Sanitised. (Legacy objectives surfaces here on read.) |
returnExpected |
string | The as-promised return (prose). |
scopeInBounds |
string | What it will deliver (in scope). |
scopeBoundaries |
string | Explicit exclusions (out of scope). |
theme |
string | Free-text investment theme (see defaults below). |
designPrinciples |
array | Normalised list. |
supportingLinks |
array | Each {id, label, url, type, pageId?, spaceKey?, templateKind?}; url http(s) only; type = confluence | link. |
decisionAuthority |
object | null | The sponsor: {accountId, displayName, avatarUrl}. |
projectManager |
object | null | {accountId, displayName, avatarUrl}. |
customerRep |
object | null | Single seat. |
supplierRep |
object | null | Single seat. |
steeringCommittee |
array | Members {id, accountId, displayName, role}. |
financialCase |
object | normaliseAndComputeFinancialCase; default {mode: 'none'}. Carries mode, builtin.computed, boardPaperPageId, timestamps. |
updatedAt / updatedByAccountId |
ISO timestamp / string | Stamped on every save. |
Adoption & Change quartet (BCM at outset)
Section titled “Adoption & Change quartet (BCM at outset)”The four inputs gated at business-case submission — the one deliberate hard gate.
| Field | Type | Allowed values / notes |
|---|---|---|
adoptionAffected |
string | Who/what is affected. |
adoptionKpi |
string | The adoption KPI. |
adoptionOwner |
object | null | {accountId, displayName, avatarUrl}. |
changeSaturation |
enum | None, Low, Modest, High. Invalid/missing → Unknown. |
adoptionGap is derived, not stored: true when any of adoptionAffected,
adoptionKpi, adoptionOwner.accountId is missing, or changeSaturation is
missing/Unknown.
Approval lifecycle
Section titled “Approval lifecycle”| Field | Type | Allowed values / notes |
|---|---|---|
approvalStatus |
enum | Exploring, Draft, Submitted, Approved, ClosingSubmitted, Closed, Archived, InRealisation, Realised, NotRealised, InMaintenance. Default Exploring. |
version |
number | Default 1. |
submittedAt |
ISO timestamp | null | Set on submit. |
approvedAt / approvedByAccountId |
ISO timestamp | null / string | null | Set on approve. |
approvalComment / approvalRationale |
string | |
returnNotes |
array | Each {id, section, ask, severity, addressed}. Sections and severities below. |
returnedAt |
ISO timestamp | null | |
archivedAt / archivedByAccountId / archiveReason / archivedFromStatus |
ISO timestamp | null / string | null / string / enum | null | Kill-with-dignity metadata. |
Return-note sections: businessProblem, outcome, returnExpected,
adoption, sponsor, steeringCommittee, theme, general.
Return-note severities: Blocker, Significant, Minor.
Initiation / first-steerco scaffolding
Section titled “Initiation / first-steerco scaffolding”Set by dedicated resolvers, not the thesis form.
| Field | Type | Notes |
|---|---|---|
firstSteercoScheduledFor |
ISO date | null | |
firstSteercoAttendees |
array | Default []. |
firstSteercoHeldAt |
ISO timestamp | null |
Close-out (closeOut sub-object)
Section titled “Close-out (closeOut sub-object)”closeOut defaults to null. Top-level closure stamps closedAt /
closedByAccountId. The body carries:
| Field | Type | Allowed values / notes |
|---|---|---|
asBuiltOutcome |
string | ≤ 2000 — what was actually delivered, in the sponsor’s words. |
asBuiltReturn |
string | ≤ 2000 — with deltas vs the approved case. |
asBuiltReturnValue |
number | null | Optional revised numeric return. |
asBuiltEndDate |
ISO date | Optional. |
scopeDispositions |
map {[wpId]: {disposition, note}} |
disposition ∈ DeliveredAsChartered, DeliveredReduced, DeliveredExpanded, Dropped, Deferred. |
rioDispositions |
map {[riskId]: {disposition, note}} |
disposition ∈ Closed, TransferredToBau, Accepted, Pursued, Dropped. |
pendingDispositions |
{decisions: {...}, changes: {...}} |
disposition ∈ Adjudicated, Withdrawn, ApprovedAsShipped, DeferredToBau. |
lessons |
{worked, differently, nextSponsor} |
Three free-text fields (each ≤ 2000). |
bauHandover |
object | {state, ownerAccountId, ownerDisplayName, acknowledgedAt, acknowledgedByAccountId, escalatedAt, escalationReason}; state ∈ Pending, Acknowledged, Escalated (default Pending). |
commentary |
string | ≤ 2000. |
startedAt / submittedAt |
ISO timestamp | Lifecycle stamps. |
Close-out return notes (separate list): {id, section, ask, severity, addressed}; sections ∈ asBuiltOutcome, asBuiltReturn, scopeDispositions,
rioDispositions, lessons, bauHandover, general.
Benefits Realisation
Section titled “Benefits Realisation”| Field | Type | Allowed values / notes |
|---|---|---|
returnRealised |
string | Prose, not numeric. The realised return as judged by the sponsor. |
realisationSummary |
string | |
realisationLessons |
string | Elevated on NotRealised. |
realisationConfidence |
enum | High, Modest, Low, Unknown (default Unknown). |
realisationDate |
ISO date | null | Plan field (“measured by” date). |
kpiResolution |
object | null | {resolvedAt, resolvedBy, resolvedValue, met, notes}. |
brOwner |
string | null | |
realisationStartedAt |
ISO timestamp | null | |
realisationDecidedAt / realisationDecidedByAccountId |
ISO timestamp | null / string | null | |
maintenanceStartedAt / maintenanceRetiredAt |
ISO timestamp | null | |
lastRealisationReviewAt |
ISO timestamp | null |
The BR review cadence (brCadence) is not a Business Case field — it is an
optional override on Project Status.
R·I·O item (Risk / Opportunity / Materialised)
Section titled “R·I·O item (Risk / Opportunity / Materialised)”The unified downside/upside register. In prose this register is called Risks;
the direction field records whether an item is a Risk or an Opportunity.
| Field | Type | Allowed values / notes |
|---|---|---|
id |
string (UUID) | |
projectKey |
string | |
title |
string | ≤ 200. |
description |
string | ≤ 2000. |
ownerAccountId |
string | null | |
status |
enum | Open, Closed (anything not Closed → Open). |
direction |
enum | Risk, Opportunity. |
materialised |
boolean | Only meaningful when direction = Risk; forced false for Opportunity. |
impact |
number | null | 1–5. |
likelihood |
number | null | 1–5. |
residualImpact |
number | null | 1–5. |
residualLikelihood |
number | null | 1–5. |
treatment |
enum | null | Risk: Mitigate, Avoid, Transfer, Accept. Opportunity: Pursue, Enhance, Share, Ignore. |
mitigation |
string | ≤ 2000. Treatment plan; doubles as acceptance rationale. |
acceptedByAccountId / acceptedAt / acceptanceRationale |
string | null / ISO timestamp | null / string | Stamped on first transition to treatment = Accept. |
createdAt / updatedAt / updatedByAccountId |
ISO timestamp / ISO timestamp / string | null | |
imported |
boolean | Present (true) only on bulk-imported rows. |
Decision
Section titled “Decision”Append-only log. New entries are prepended.
| Field | Type | Allowed values / notes |
|---|---|---|
id |
string (UUID) | |
projectKey |
string | |
decision |
string | Required, ≤ 200. |
decisionNotes |
string | ≤ 2000. |
madeOn |
ISO date | Defaults to today. |
madeByAccountId |
string | null | Defaults to the raiser. |
rationale |
string | ≤ 2000. On reject, holds the required reason. |
ownerAccountId |
string | null | |
approverAccountId |
string | null | The per-decision approval gate. |
riskId |
string | null | Provenance: seeded from a materialised risk. |
treatedRiskId |
string | null | Live back-link to the risk this decision treats. |
evidenceLinks |
array | Same shape as Business Case supportingLinks. |
status |
enum | Proposed, Approved, Rejected, Withdrawn. Created as Proposed. |
decidedAt |
ISO timestamp | null | Set on adjudication. |
decidedByAccountId |
string | null | Set on adjudication. |
createdAt / createdByAccountId |
ISO timestamp / string | |
updatedAt |
ISO timestamp | Added on adjudication. |
imported |
boolean | Present on bulk-imported rows. |
Adjudication rules: reject requires a reason; Withdrawn only by the creator;
Approve/Reject only by the named approverAccountId (self-approval allowed).
Legacy decisions with no approver fall back to edit permission.
Change (change request)
Section titled “Change (change request)”| Field | Type | Allowed values / notes |
|---|---|---|
id |
string (UUID) | |
projectKey |
string | |
summary |
string | Required, ≤ 200. |
reason |
string | ≤ 2000 — the requester’s justification. |
dimensions |
string[] | Subset of Scope, Budget, Schedule, Quality, Other (de-duped). Inferred when empty (budget impact → Budget, schedule → Schedule). |
impactTimeline |
string | ≤ 2000 — human label (e.g. “+2 weeks”). |
impactScheduleDays |
number | null | Signed day delta. |
impactBudget |
number | null | Signed (savings allowed). |
targetWorkPackageId |
string | null | Optional anchor to one work package. |
proposerAccountId |
string | null | Audit field; defaults to the raiser. |
approverAccountId |
string | null | Named approver. |
status |
enum | Proposed, Approved, Rejected, Withdrawn. Created as Proposed. |
decidedAt |
ISO timestamp | null | Set on adjudication. |
decidedByAccountId |
string | null | Set on adjudication. |
decisionComment |
string | Set on adjudication (distinct from reason); reject reason required. |
createdAt / createdByAccountId / updatedAt |
ISO timestamp / string / ISO timestamp | |
imported |
boolean | Present on bulk-imported rows. |
Project Status
Section titled “Project Status”A single KVS object per project.
| Field | Type | Allowed values / notes |
|---|---|---|
projectKey |
string | |
overallRag |
enum | Red, Amber, Green, Blue, None. Default None. Manual (not derived). |
phase |
string | Free text (no enum validation). Default Initiation. |
notes |
string | null | |
reportingCadence |
enum | Daily, Weekly, Monthly. Default Monthly. |
structuredCommentary |
object | null | {keyMessages, keyRisks, decisionsRequired}. |
projectMetrics |
any | null | Pass-through. |
costRagOverride |
enum | null | Red/Amber/Green/Blue/None, else null. Null = use the derived value. |
scheduleRagOverride |
enum | null | As above. |
scopeRagOverride |
enum | null | As above. |
riskRagOverride |
enum | null | As above. |
outcomeConfidence |
enum | null | High, Modest, Low, Unknown. Read fallback Unknown. |
adoptionConfidence |
enum | null | As above. |
revisedForecast |
number | null | PM top-down EAC override. |
pmKeyMessage |
string | PM-authored steering key message. |
lastUpdatedAt |
ISO timestamp | |
lastUpdatedByAccountId |
string | |
initiationStartedAt |
ISO timestamp | null | Set on charter approval. |
initiationCompletedAt |
ISO timestamp | null | Set on acknowledgement / first steerco held. |
initiationDismissals |
map | {[checklistItemId]: ISO timestamp}. |
brCadence |
enum | null | Monthly, Quarterly, Annual — per-project BR review override. |
Investment themes
Section titled “Investment themes”theme is free text on the Business Case. The default canonical set
(CANONICAL_THEMES) that admins may rename / disable / add to site-wide (bounded
by a cap of 12):
Cost Out, Revenue Growth, Productivity, Risk & Compliance,
Customer Experience, Strategic.