Specifications
System requirements, data contracts and acceptance criteria.
How the product fits together
Planning, staffing and reporting use the same saved work. A change to a Program feeds its Portfolio, Capacity views and dashboards.
Blueprints and planning inputs
Work, effort, dependencies, start dates and target dates.
People and places
Organizations, partners, Sites, roles and weekly availability.
Advisory evidence
Publisher reports, affected products and dated threat scores.
Set the plan, assign people and add review work
Shared workspace
Programs contain Projects and Milestones. Tasks, owners, progress, blockers and decisions stay attached to that work.
Read the same work and review the effects of changes
Plan and deliver
Programs track work and dates. Portfolio compares delivery. Capacity shows staffing gaps and the effects of reallocating people.
Analyze and report
Dashboards explore current data. Reports combine visuals and text for PDF, Web or Slides. Saved editions retain the captured result.
Access, discussion and history
Organization and resource permissions apply across views. Conversations keep discussion with the work; Audit Log records supported actions.
Engineering architecture
Runtime components, trust boundaries and data paths.
Scope and actors
The system serves security leaders, delivery teams and service providers with work across Organizations and Sites.
| Requirement | Contract | Acceptance |
|---|---|---|
| SCP-01: Delivery management | The system must support plans, work updates, staffing, advisory review, charts and reports from saved Program records. | Trace a Program from creation through a work update, a staffing review and a report. Each view must refer to the same saved work. |
| SCP-02: Product limits | The system must not present work completion or a forecast as a security test, certification or assurance result. | Progress, health and advisory outputs must state their own measures. Missing evidence must not count as a security result. |
Data model and calculation rules
Saved inputs and versioned catalogs define the planning baseline. Language-model output must not set the schedule.
| Requirement | Contract | Acceptance |
|---|---|---|
| DAT-01: Work hierarchy | Organizations own Programs. Programs contain Projects and Milestones; Tasks and Subtasks divide the work further. Site executions retain separate progress. | The same-named work in different Organizations or Sites must remain distinct in updates, grouping, reports and access checks. |
| CAL-01: Progress and effort | Effort uses person-days. Completion percentage uses completed person-days divided by total person-days. Milestone counts are a separate measure. | Check each percentage against the source effort. A Task or Subtask must not count as an extra Milestone. Empty or invalid totals must not produce a false percentage. |
| CAL-02: Dates and forecasts | Target, forecast and actual dates must remain distinct. Forecasts use the saved work, dependencies and capacity; the generated baseline must remain available. | Change an input and compare the new forecast with the saved baseline. Use the recorded actual result for completed work where that measure calls for one. |
Capacity and allocation
Capacity is time available per week. It is not headcount, total effort or elapsed duration.
| Requirement | Contract | Acceptance |
|---|---|---|
| CAP-01: Scope and units | Capacity views must name the person, Program, Site and time period shown. Weekly capacity uses person-days per week; capacity through a target uses total person-days. | Check a scoped view against its saved assignments. Check that weekly and through-target measures are not added or compared as if they use the same unit. |
| CAP-02: Allocation changes | An allocation draft must retain its source and receiving work. Review must show the consequences before a saved commitment changes. | Apply must save the reviewed values. Cancel must leave assignments unchanged. An old draft must not replace newer assignments. |
| CAP-03: Reduced availability | Reducing a person’s available time must keep their current commitments and show any shortfall. | Reduce availability below committed time. The commitment must remain recorded and the shortfall must be visible. |
Analytics and report contracts
Analytics is one library. Dashboards, editable reports and captured editions are distinct record types.
| Requirement | Contract | Acceptance |
|---|---|---|
| ANA-01: Visual scope | Every visual must retain its source scope, measures, period and display settings. Settings chosen for one visual must survive changes to Dashboard settings. | Change the Dashboard scope or period and inspect both inherited and overridden visuals. A selection in one chart must not silently alter unrelated charts. |
| ANA-02: Independent composition | A Report must own its text, visuals, ordering, dimensions and format settings. Editing it must not modify its source Dashboard or another Report. | Edit, resize, save and reopen a Report. Compare the source Dashboard and a second Report before and after the change. |
| ANA-03: Layout and retention | PDF uses paper dimensions; Slides uses an aspect ratio. Pagination must retain all text and table rows. Charts must remain whole and clear of page footers. | Compare editor, preview and generated output using long text, continued tables, maps and charts. Check content retention, headings, clipping and page use. |
| ANA-04: Captured and live results | A captured edition must retain its data and source revisions. Live Web content may read current authorized data using its saved composition. | Change source work after capture. The captured edition must stay unchanged; a live view must use current access and its stated time basis. |
Persistence and failure behavior
An unsaved edit, saved definition and completed capture must remain distinct states.
| Requirement | Contract | Acceptance |
|---|---|---|
| SAV-01: Version conflicts | Writes must check the expected saved revision. A conflict must preserve the newer record and offer recovery for the local draft. | Submit competing changes. The stale write must fail without overwriting the newer version. Reload must not be described as a merge. |
| SAV-02: Interrupted operations | Commands that support retries must keep the same operation ID. A retry must recover the prior result without creating a duplicate. | Interrupt a save and retry. Check for one saved result and a clear status, including partial or failed work. |
| SAV-03: Editions and artifacts | Completed editions must retain captured content and private visual artifacts. Corrections and withdrawn editions must keep their link to the earlier result. | Reopen retained editions after later edits. Check correction links, withdrawn editions and access to stored files. |
Runtime and trust boundaries
The browser presents work; server handlers validate requests, enforce access and save changes.
| Requirement | Contract | Acceptance |
|---|---|---|
| RUN-01: Application services | The browser presents work and holds unsaved edits. Application services validate requests, check current access and save records. Private file storage holds report images and rendered files behind the same access checks. | Test saved changes and file reads in the hosted app. A page rendered in the browser does not establish that these services work. |
| RUN-02: External evidence | Advisory collection must retain publisher identity and source dates. Failed refreshes must distinguish dated evidence from unavailable data. | Test fresh, stale, empty and failed feeds. Preserve score dates and missing values. An advisory must not change Program work without a reviewed save. |
| RUN-03: Portable files | Program JSON files must pass schema and integrity validation before import. CSV and Markdown files must not be described as complete Program backups. | Import valid, invalid and unsupported files. Rejected imports must preserve saved work. Verify exports against the selected source scope. |
Acceptance and open verification
These are requirements for a qualified build. Source checks alone cannot establish that the app works or that its layout is usable.
| Requirement | Contract | Acceptance |
|---|---|---|
| QUA-01: Shared workflows | Demo and signed-in work must use the same components, rules and handlers. Demo isolation may change seed data and external effects only. | Test work within one Organization and across Organizations. Check that one Program family or demo does not create a separate capability. |
| QUA-02: Usability and timing | Supported tasks must retain keyboard access, clear state and usable layouts. Timing targets are under 200 ms for routine interactions and 500 ms for Report rendering. | Measure the complete action with a normal range of data. The recorded 507 ms Report load has a specific accepted exception; it does not change other targets. |
| QUA-03: Remaining acceptance | Full report layout and signed-in task checks remain open for this local build. | Review the editor, preview and output, then check normal signed-in tasks. A working demo or first-page walkthrough cannot close those criteria. |
MCP: read-only assistant access
An opt-in read-only Model Context Protocol (MCP) pilot exposes three tools. Tests cover local behavior. Hosted sign-in, revoked access and the full ChatGPT flow still need live checks.
| Requirement | Contract | Acceptance |
|---|---|---|
| MCP-01: Transport and discovery | When enabled, HTTPS /mcp accepts stateless Streamable HTTP with protocol version 2026-07-28 and JSON responses. POST requests use MCP-Protocol-Version, Mcp-Method and Mcp-Name headers. The _meta keys are io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientInfo and io.modelcontextprotocol/clientCapabilities. Supported methods are server/discover, tools/list and tools/call. No resources, prompts, subscriptions or legacy initialization are exposed. GET /.well-known/oauth-protected-resource/mcp publishes the resource, authorization issuer and openid identity scope. | Discover exactly the three registered tools. Reject unsupported methods and mismatched resource origins. A disabled endpoint returns 404. |
| MCP-02: Deployment configuration | MCP_ENABLED must be true and Global settings must allow MCP connections. The versioned, audited global policy is off by default, including legacy settings without an explicit Owner choice. The server checks it before dispatch and before returning a result without caching the value. An Owner-blocked request returns mcp-disabled. MCP_RESOURCE_URL must be the exact HTTPS /mcp URL without query, fragment or credentials. MCP_AUTHKIT_ISSUER is an HTTPS origin. MCP_CLIENT_ID and the secret MCP_CLIENT_SECRET identify the confidential client. MCP_CURSOR_KEY is a base64url value of 32 bytes. MCP_CLIENT_ORIGINS defaults to https://chatgpt.com; the application origin is included. Existing application identity and data bindings are also required. | Reject incomplete configuration. Keep client secrets and cursor keys in secret configuration. Qualify the actual hosted client and consent flow before enabling customer connections. |
| MCP-03: Identity and current authority | Bearer tokens require a valid RS256 signature, configured issuer, exact resource audience and client, expiry, user, consent, token and Organization identities, and openid. The identity scope grants no application read permission. Token activity and current membership are checked before and after a read. Application grants determine visibility. Browser session cookies do not authorize MCP. | Expired, revoked or mismatched identities return no Program data. Reject unapproved browser origins. Final checks reduce stale authorization; they do not promise instantaneous revocation. |
| MCP-04: Tools and exact scope | search_programs accepts optional query, unitId, siteId and cursor. get_program_overview requires organizationId, programId and executionScope. list_program_milestones requires the same identity and accepts status and cursor. executionScope is {kind: "program-wide"} or {kind: "site", siteId}. Milestone lists contain planned work. Status values are planned, inProgress, blocked and complete. Custom states use inProgress with a separate statusLabel. Unknown input properties are rejected. | Require full visibility of the selected execution. Omit partial executions from search. Never substitute Program-wide data for a missing Site. A different Organization or inaccessible target returns not-found. |
| MCP-05: Bounds and changing data | Search and Milestone lists return up to 10 items per page with nextCursor. There is no page-size input or total count. Opaque cursors bind identity, consent, Organization, tool, scope, filters and relevant source revisions. Source or access changes require a fresh query. MCP uses prepared application state and never provisions, migrates or repairs it. | Terminate with nextCursor null. Reject tampered or mismatched cursors. Return changed-state with restartRequired true when the bound source or access state changes. |
| MCP-06: Source facts and exclusions | Results carry readAt, providerCheckedAt, accessCheckedAt, revision and savedAt. Overviews also carry reportDate, sourceEffectiveDate, freshness and the saved Site time zone when known. Missing dates stay null. Progress includes its state, and an unavailable forecast includes a reason. The pilot excludes mutations, sharing, sending, exports, Reports, conversations, attachments, contact details and personal account Programs. | Compare returned facts with the same saved execution in the application. A read must leave stored work unchanged. Source age over 30 calendar days marks the overview stale; a read does not refresh external evidence. |
| MCP-07: Failure and recovery | Application read errors return isError content. Their codes are not-found, preparation-required, invalid-cursor, changed-state, authentication-required, mcp-disabled and temporarily-unavailable. Input validation can return plain text. An unknown tool can return a protocol error. Pre-dispatch authentication failure returns 401 with an authorization metadata challenge. An Owner-blocked connection returns 403 before dispatch. Other outer failures return 503. Errors contain no request ID. | Reconnect for lost authorization, prepare missing application state through its normal path, and restart pagination after changed-state. Preserve the last dated result through a temporary failure. |

