320
objective rows for a Level 2 assessment: 125 Define, 195 Perform
110
requirement rows created up front, before anything is marked
16
actions behind one Run Action field on the assessment
0
rows deleted by a re-run: it only adds what is missing
The whole pipeline
One field on the assessment row, one gate, one job on the isolated runner.
Call or read
Rows written
At kickoff the same job runs once per target level without anyone pressing anything, straight after the assessment row is created and its CMMC level linked. Pressing it by hand is for widening the scope later.
1
Declare: the scope is a link
Which frameworks are linked decides what every later phase checks.
The template holds the whole library: 8 frameworks, 1,735 requirements and 4,569 assessment objectives, from NIST SP 800-171 Rev 2 and Rev 3 through CMMC Levels 1 to 3 and NIST SP 800-53. An assessment row in a client base owns none of it. It points at the frameworks in scope through its Frameworks link, and populate copies only the pointers it needs.
Reference rows vs the client's rows
Objective ID, AO Type, family and text are lookups through the link, read live rather than copied, so a correction to the reference rows in this base shows up in the assessment without a re-run.
Why populating is the scope declaration
- Document review (Phase 3) refuses to run without it. A review always runs against one assessment. With none populated, the job stops and says so, because "is this policy covered?" has no meaning until the list of things to cover exists.
- Review reads only what populate created. The objectives a document is checked against are the Define objectives that have a row in this assessment, and every match is written as evidence linked to those rows.
- So the link decides the work. Linking one more framework, then re-running populate, is how scope grows. Nothing downstream needs changing.
What a CMMC level scaffolds
| Framework linked | Requirement rows | Objective rows |
| CMMC 2.0 Level 1 | 15 | 59 |
| CMMC 2.0 Level 2 | 110 | 320 (125 Define, 195 Perform) |
| CMMC 2.0 Level 3 | 24 | 80 |
Live counts from the reference library, 30 September 2026.
2
Populate: the job, step by step
Read the chain, add what's missing, never remove anything.
The trigger
- The consultant sets
Run Action on the assessment row to "Populate objectives". A NocoDB webhook fires on the update.
- n8n's gate maps the value to a fixed job name from a whitelist of 16. An unknown value stops there, and a blank one ends the loop. Only the two jobs that need the internet or a language model go to the runner with egress; populate goes to the isolated one.
- The runner checks the field is still set, takes the lock for this job and base, clears the field and reads it back, then runs the job with the assessment's row id and the client base.
The job, in run order
- Read the linked frameworks. None linked means the job stops and asks for one.
- Collect the requirements that belong to those frameworks, then the objectives under those requirements.
- Skip what exists. Rows already in this assessment are matched by the objective they point at, so a re-run adds only the new ones.
- Insert the objective rows in batches of 100, each starting at "Not Yet Assessed".
- Create the requirement rows now, empty. The Phase 2e triage records the client's claim ("do you do this?") on each requirement before any objective is proven, so those rows have to exist first. The later recompute patches them rather than creating them.
- Create the Review Console: an eight-line to-do list for the whole engagement (review findings, verify submissions, resolve discrepancies, send requests, mark objectives, scope out, set partial credit, close POA&Ms), each with a count and a link. It is created here and only refreshed afterwards.
A re-run is always safe. It never deletes, and it keys every row on what it points at, so pressing it twice, or after linking another framework, only fills the gaps. Unlinking a framework leaves its rows in place.
Two frameworks, one control
Link CMMC Level 2 and NIST SP 800-171 Rev 2 together and populate creates both sets of rows; it does not merge them. The merge happens where it matters, at document review: requirements joined by an "Equivalent" mapping in the crosswalk (110 such pairs) are reviewed once, and the evidence lands on both.
3
Hand-off: what the scaffold feeds
Every later phase reads or writes these rows.
| Row | Next written by | What lands on it |
| Requirement rows | Phase 2e triage | Claimed Status, how, and where the claim came from |
| Objective rows (Define) | Phase 3 document review | Proposed evidence from the client's policies, for a person to accept or reject |
| Objective rows | Phases 4 and 5 | Evidence, then MET or NOT MET with its basis |
| Objective rows | Statement seeding, at kickoff or by button | A Draft implementation statement from the policy library, with the client's values filled in; never overwrites a Confirmed one |
| Requirement rows | Recompute, on every objective edit | Status and SPRS points |
How objective status rolls up to a requirement
- Any objective NOT MET: the requirement is NOT MET.
- Otherwise, any objective still Not Yet Assessed: the requirement is Not Yet Assessed.
- Otherwise: MET. Points are earned only on MET, and never on a requirement marked not applicable.
That rule is why an unassessed objective can never make a requirement look MET, and why the SPRS score only rises on proof.
Decision log
The calls that shaped the scaffold, and when they were made.
| Decision | Why | When |
| Build the assessment tables before a live client | Get the structure right on synthetic data, not on a client's time | 2026-07-17 |
| One base holds one client, so no client column | Isolation by base, not by filter | 2026-07-17 |
| Populate on a button, not on every change | A person decides when a sweep runs; nothing runs from a laptop | 2026-07-20 |
| Create requirement rows at populate | Triage needs somewhere to record claims before anything is proven | 2026-07-21 |
| Kickoff runs populate and creates the console | A new client base opens with its checklist already in place | 2026-07-29 |
| Busy means retry, then alert | A press during a run should wait, not vanish | 2026-08-20 |
| The runner clears the trigger, confirmed by read-back | A failed clear once turned one press into 64 runs | 2026-09-17 |
| One living assessment per client scope | Carried through the Maintain phase and frozen at milestones, not re-created each year | 2026-09-30 |
Known gaps
- Withdrawn requirements aren't filtered. Populate doesn't check a requirement's status, so linking a framework with withdrawn requirements (NIST SP 800-171 Rev 3, 800-172 Rev 3 and 800-53 all have some) creates requirement rows that nothing will ever fill in. The three CMMC levels have none, so a CMMC assessment is unaffected.
- No merge across frameworks at populate. Two linked frameworks give two row sets; equivalent controls are only collapsed at document review.
- The Review Console counts the whole base. With more than one assessment in a base, its counts blend them.
- Parameter values aren't filled in. Objective text is copied as written, so Rev 3 text still shows its organization-defined parameter placeholders.
- No carry-forward between revisions. An assessment against a new framework revision starts blank rather than inheriting proven results.
- The SPRS score is computed for Rev 2 and CMMC Level 2 only.