320
implementation statements seeded for a Level 2 assessment, one per objective
0
model calls anywhere in this phase: every document is rendered from the data
4
documents, one button each: client SSP, working copy, evidence package, plan of action
2
reasons the freeze refused the synthetic run: statements unconfirmed, no system owner
The whole pipeline
One renderer, four exports, one freeze, all on the isolated runner. Only the portal publish leaves it.
Read or step
Files or rows written
The three Word documents come from the same renderer, so they can't disagree about what is final or which evidence qualifies. The plan-of-action spreadsheet reads the POA&M rows directly. Nothing in this phase changes a mark or the score.
1
Author: one statement per objective
The SSP isn't written; it is assembled from statements a person has confirmed.
- Seed at kickoff. Every objective gets a draft implementation statement, taken from the standard library statement that satisfies it and worded with the client's values. A failed seed is logged and doesn't stop kickoff; the "Seed statements" button reruns it.
- Bind what implements it. The seed links the governing documents (any document the objective's evidence cites, plus a name match on the library statement's owning document) and, for objectives about what is done rather than written, the client technologies named for the requirement.
- Edit and confirm. The consultant rewrites each statement to match how the client actually does it, then sets it Confirmed. A confirmed statement is never touched by a later seed, and one confirmed with no text doesn't count.
- Substitute again at render time. Statements seeded before a value existed still read with the client's names, because the renderer fills tokens a second time. A confirmed statement with a token that has no value, or a value nobody has confirmed, blocks the freeze.
The statement text, its mechanism and its status are fields on the assessment's objective rows, not a separate table, so a statement can't drift away from the objective it describes.
2
Gate: two locks, for two readers
The SSP can't look finished before it is.
Confirmation holds the headline. Until every assessable objective's statement is Confirmed, the client SSP opens with "DRAFT: N of M implementation statements confirmed", and each unconfirmed statement prints as a marked draft. Objectives under a requirement marked not applicable aren't counted.
Completeness holds the working copy and the archive. A second list of blockers prints at the top of the working copy as "DRAFT: NOT FOR SUBMISSION" and refuses the freeze. The client SSP never shows this list, because a delivered SSP never refers to evidence or its absence.
| Blocker | Why it blocks |
| An objective in scope not yet assessed | The plan would describe a control nobody has looked at |
| An objective marked MET with no qualifying evidence | Qualifying means human-verified and sufficient; a claim isn't proof |
| An asset whose scope category is unset or still under review | The boundary the SSP describes isn't settled |
| A client document not yet reviewed, or unreadable | Statements may cite language nobody has checked |
| Not applicable with no rationale | An assessor will ask why |
| No system owner, or no organization identity on file | The SSP has to name who is responsible |
| An objective row cut off from the reference objective it assesses | Nobody can tell what it claims |
| A statement marked Confirmed with no text | It would print nothing and still count |
| A confirmed statement with a placeholder that has no client value | The placeholder would print literally |
| A confirmed statement using a client value nobody has confirmed | A value read out of a document would ship as if the client had said it |
Why two locks. A client SSP whose statements are all confirmed can still sit on an assessment with gaps. The headline answers "is the plan written?"; the blocker list answers "does the assessment support it?". Freezing needs both.
3
Package: four documents, each for one reader
The client SSP stays lean; the detail goes where the people who need it will look.
| Document | For | What it carries | Button |
| SSP (client), Word | The client, and whoever they hand it to | System identification with the SPRS score and its basis, the system environment, the documentation register, and each requirement family with its statements and points. The plan of action is a pointer, not a table. | Export SSP (client) |
| SSP working copy, Word | The consultant | Everything above, plus the blocker list, proposed library language, coverage counts and appendices, including evidence excluded from the package. | Export SSP (working copy) |
| Objective Evidence Package, Word | An assessor | Per objective, the evidence behind it. Only quotes verified word for word against their source are included. | Export Objective Evidence Package |
| Plan of action, spreadsheet | The client's remediation owner | One row per POA&M, closed ones included: control, requirement, failing objectives, status, target date, remediation plan, notes. A requirement that can't be deferred has no POA&M, so it isn't here; the SSP's score basis names it. | Export POA&M (spreadsheet) |
Each export renders Markdown, converts it with pandoc and attaches the file to its own field on the assessment row, so the client and working copies never overwrite each other. The SPRS score is the real one, 110 minus the deductions, with a basis line that counts NOT MET and not-yet-assessed requirements and names any NOT MET requirement that can't be deferred to a plan of action. Frameworks other than NIST SP 800-171 get no score.
A separate button in the client portal publishes the client SSP there. It runs on the second runner, the one with internet access, because it uploads to the portal's storage; it calls no model.
4
Freeze: a version the next one is compared against
The posture-change record is the difference between two frozen documents.
- Refuse unless ready. The freeze runs only when the SSP is final and the blocker list is empty. Otherwise it fails with every reason listed, and the failure alerts.
- Freeze the client version. The Markdown of the client SSP is the record. The Word file is converted from that exact Markdown, uploaded first, and written in the same step as the version, so a failed upload leaves no half-made version.
- Hash and snapshot. A SHA-256 of the Markdown, the SPRS score, the frameworks and the confirmed-statement count go into a new row of
SSP_Versions, labeled v1, v2 and so on.
- Diff against the last version. A line-by-line diff of the previous frozen Markdown against the new one is stored with it: what moved, what newly passed, what regressed. The generation time is left out of the comparison, so freezing an unchanged SSP again is refused as a duplicate.
Milestones: the SSP and its evidence, frozen together
Three more buttons call a milestone: a formal assessment, the annual affirmation, or a plan-of-action closeout. Each runs the same gate and the same freeze, then adds the evidence. A milestone is always recorded, even when the SSP hasn't changed, because the milestone itself is the event.
- Collect the evidence behind each MET. The same qualifying rule the SSP uses: accepted, sufficient, a verified quote where there is one, and not superseded.
- Hash every artifact. Each attached file, and each client document that quoted evidence cites, is downloaded and hashed with SHA-256.
- Write the manifest. Objectives, evidence and artifacts as JSON on the version, with its own hash; a CSV of artifact name, hash value and algorithm, the list a certification assessment asks for.
- Package it for the client. One zip: the frozen SSP, the manifest, every artifact and a README on how to check a hash. It is uploaded first and written with the version in one step.
- Move to Maintain. A formal assessment sets the engagement stage to Maintaining.
Superseded, never deleted. When the client sends a newer artifact for the same request and it is accepted, the older one is linked to its replacement and stops counting. The file stays. If the replacement is later rejected, the older one counts again.
Each client scope keeps one living assessment, so every milestone (a formal assessment, the annual affirmation, a plan-of-action closeout) re-freezes the same record and the diffs line up year over year.
Immutable by convention. The freeze only ever adds rows; nothing edits or deletes one. The database can't lock a row, so the hash is how a later reader proves the stored text is what was frozen.
Decision log
The calls that shaped delivery, and when they were made.
| Decision | Why | When |
| Lean client SSP; evidence in a companion package; the plan of action as a spreadsheet | Each reader gets one document, and the SSP reads as a plan rather than a workpaper | 2026-07-27 |
| The client SSP never refers to evidence or its absence | Completeness is the consultant's working signal, not something to hand the client | 2026-07-31 |
| Statements as fields on the objective rows, Draft to Confirmed as the lock | The statement stays with its objective, and confirmation is one visible switch | 2026-07-31 |
| Render from data, with no model | The library is strong seed text, every line is traceable, and nothing overclaims | 2026-07-31 |
| One shared finality check and one evidence check | The banner, the package and the freeze can never disagree | 2026-07-31 |
| Freeze the Markdown, final and unblocked only; Word is a copy | Two versions a year apart can be compared line by line | 2026-07-31 |
| A separate attachment field for the working copy | The two SSP variants were overwriting each other | 2026-09-17 |
| One living assessment per client scope | Each freeze diffs against the last on the same record | 2026-09-30 |
| Freeze the evidence with the SSP at a called milestone: SHA-256 per artifact, a manifest, a zip for the client | 32 CFR 170.15 to 170.18 have the client keep the evidence artifacts six years from the CMMC Status Date; certification assessments also want them hashed and listed | 2026-10-01 |
| Compare versions without the generation time; convert the archived Word file from the frozen text and write it with the row; block placeholders, unconfirmed values and empty confirmations | A re-freeze an hour later recorded a version whose only change was the time, and a final SSP could carry a placeholder | 2026-10-01 |
Known gaps
- No single bundle. The four documents are four buttons and four attachments; nothing zips them with the score into one deliverable.
- The diff is stored as text, with no rendered side-by-side view.
- A large package can exceed the upload limit. The zip goes up as one file; a client with gigabytes of evidence would need another delivery route. The call fails loudly rather than leave a version without its package.
- The package reaches the client by hand. It sits on the version for the consultant to hand over; the client portal doesn't offer it yet.
- No real client SSP has been frozen yet; the freeze and the milestone have been proven on test assessments only.