Federal Modernization Workbook
Chapter 07 — The Weekly Digest and Evidence
The digest is for the people who act; the evidence is for the people who check. Both come from the same runs, so neither can drift from what was actually read.
The digest and the evidence chain behind the guide’s G7 Digest and evidence. You start with what the guide’s evidence table asks the ISSO to keep. Then you read the digest’s five sections, the evidence record, the chain and the stage check that the runbook’s go/no-go uses. Lab 1 builds a week of runs from the fixtures, writes the digest, records three runs, checks the chain, shows the stage check naming the steps still missing, and changes a recorded file to watch the check fail. Lab 2 runs the same against a test environment’s run folders.
Goal and audience
Goal. By the end of this chapter you can write the weekly digest from a collection and the routing state, record every run as evidence the ISSO can verify with a hash, and say which of a stage’s steps have a passing record.
Audience. Developers who maintain the kit, the ISSO who owns G7, and the owners who read the digest. You should have run Chapter 06’s Lab 1.
Start with the guide’s evidence table
What the guide asks for
The guide’s Evidence section lists, gate by gate, what the ISSO keeps: each provider’s raw output, the notices and the manifest; the task payloads, routing table and state; the digests, preflight results and evidence records with records.csv and SHA256SUMS. It maps them to SA-9, SI-5, CM-3, CM-4, CP-2, RA-3, CA-7, AU-9 and SR-8, and to the KSIs FedRAMP lists for them. It says the kit’s records support those controls, and the assessor decides them. Book 15’s Chapter 14 says who reads the digest and what they do with it.
What it leaves to you
Each row is pinned by a test in tests/DigestEvidence.Tests.ps1.
| What the guide names | Why naming isn’t enough | What the kit adds |
|---|---|---|
| “The digest goes to the owners” | Owners read a page, not a JSON file | digest.md in five sections, and digest.csv with each notice’s route and owner |
| “Every run is in the evidence” | A folder of files can be changed after the fact | Each run folder checked against its manifest, copied under runs/, and recorded with every file’s SHA-256 |
| A list of controls and KSIs per gate | Someone has to say which run supports which | Each record names its steps and their controls and KSIs, from config/requirements.json |
| Records kept over time | A record removed from the middle goes unnoticed | Each record holds the SHA-256 of the record before it |
| A go/no-go | Which steps still lack evidence? | -Check -Stage lists every step the stage needs, pass or fail |
The verdict. Keep the guide’s table as the list. Build the digest and the chain, because a list of files isn’t evidence until someone can check it.
The code
The digest
Invoke-PnDigest.ps1 (New-PnDigest) reads a collection and the routing state and writes digest.md, digest.csv and a manifest:
- Open notices by provider, counted by kind and action required.
- Action required, soonest due first, with the assignment group the routing named (or
digestwhen no task). - Maintenance and changes starting in the next 30 days.
- New in the last 7 days, by first-seen time in the state.
- Closed or no longer listed in the last 7 days, including notices the provider stopped listing.
The window lengths are parameters (-Days, -UpcomingDays) and come from the settings’ digest block in the scheduled run.
The evidence record
Invoke-PnEvidence.ps1 (Write-PnEvidence) records one run folder: it re-hashes every file its manifest lists, copies the folder to runs/<NNNN>-<task>, and writes records/<NNNN>-<task>.json with the time, environment, mode, change record, the command, the result (Pass only if every file matches its manifest), the steps it covers with their controls and KSIs, the claim language, every file’s SHA-256 and the previous record’s SHA-256. It appends records.csv and rewrites SHA256SUMS, one sha256 path line per file, which sha256sum -c can check.
| Run | Steps it covers |
|---|---|
| A collection | COL-<PROVIDER> for each provider read, NORMALIZE |
| A routing run | ROUTE, and CONTINGENCY if a payload asks for a plan review |
| A digest | DIGEST |
| The runbook’s pre-flight, scheduled run, alert plan, rollback | PRE, RUN, ALERTS, RB |
| Every record | EVIDENCE |
-Check verifies SHA256SUMS against every file and walks the chain; -Check -Stage test (or production) adds a row for each step the stage needs: test needs PRE, RUN, ROUTE and DIGEST, and production adds ALERTS. Any failing row exits 1.
The tests
tests/DigestEvidence.Tests.ps1: the digest’s sections and counts, the record’s fields and claim language, the chain, a changed file, a removed record, a failed run, a stage’s missing steps, and the requirements catalog itself.
Lab 1 records fictional runs. The evidence chain protects files from undetected change; it doesn’t decide a control. Keep the evidence folder on agency storage with the access the ISSO sets.
Lab 1: fixtures, no tenant
You need PowerShell 7.1 or later with Pester 5. Work in examples/provider-notices.
Every command in this lab, in order, from examples/provider-notices. Each step below says what it does and what to look for.
# Step 1: Make a week of runs
./Invoke-PnCollect.ps1 -SettingsPath tests/fixtures/settings.lab.json -FixturePath tests/fixtures/day1 -AsOf 2026-11-09T12:00:00Z -OutputPath out/day1
./Invoke-PnRoute.ps1 -NoticesPath out/day1/notices.json -RoutingPath config/routing.json -StatePath out/state.json -OutputPath out/day1-route -AsOf 2026-11-09T12:00:00Z
./Invoke-PnCollect.ps1 -SettingsPath tests/fixtures/settings.lab.json -FixturePath tests/fixtures/day2 -AsOf 2026-11-16T12:00:00Z -OutputPath out/day2
./Invoke-PnRoute.ps1 -NoticesPath out/day2/notices.json -RoutingPath config/routing.json -StatePath out/state.json -OutputPath out/day2-route -AsOf 2026-11-16T12:00:00Z
# Step 2: Write the digest for the second week
./Invoke-PnDigest.ps1 -NoticesPath out/day2/notices.json -StatePath out/state.json -OutputPath out/digest -AsOf 2026-11-16T12:00:00Z
# Step 3: Read it as the owners will
Get-Content out/digest/digest.md
# Step 4: Record three runs as evidence
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -RunPath out/day2 -AsOf 2026-11-16T12:00:00Z
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -RunPath out/day2-route -AsOf 2026-11-16T12:00:00Z
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -RunPath out/digest -AsOf 2026-11-16T12:00:00Z
# Step 5: Check the chain
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -Check
# Step 6: Check the test stage's coverage
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -Check -Stage test
# Step 7: Read the records' index
Import-Csv out/evidence/records.csv | Format-Table sequence, task, result, steps
# Step 8: Change a recorded file and check again
Add-Content -Path out/evidence/runs/0003-digest/digest.md -Value 'edited after it was recorded'
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -Check
# Step 9: Run the kit's whole test suite
Invoke-Pester -Path tests -Output None -PassThru | Select-Object PassedCount, FailedCount
# After the steps
Remove-Item -Recurse -Force outMake a week of runs. Chapter 06’s two collections and routings, in one go:
./Invoke-PnCollect.ps1 -SettingsPath tests/fixtures/settings.lab.json -FixturePath tests/fixtures/day1 -AsOf 2026-11-09T12:00:00Z -OutputPath out/day1 ./Invoke-PnRoute.ps1 -NoticesPath out/day1/notices.json -RoutingPath config/routing.json -StatePath out/state.json -OutputPath out/day1-route -AsOf 2026-11-09T12:00:00Z ./Invoke-PnCollect.ps1 -SettingsPath tests/fixtures/settings.lab.json -FixturePath tests/fixtures/day2 -AsOf 2026-11-16T12:00:00Z -OutputPath out/day2 ./Invoke-PnRoute.ps1 -NoticesPath out/day2/notices.json -RoutingPath config/routing.json -StatePath out/state.json -OutputPath out/day2-route -AsOf 2026-11-16T12:00:00ZWhat the terminal shows, run on the kit’s fixtures (the same output as text) Write the digest for the second week:
./Invoke-PnDigest.ps1 -NoticesPath out/day2/notices.json -StatePath out/state.json -OutputPath out/digest -AsOf 2026-11-16T12:00:00ZDigest: 16 open, 8 need action, 5 starting in the next 30 days, 2 new, 4 closed or no longer listed Written to out/digest: digest.md, digest.csv, manifest.jsonWhat the terminal shows, run on the kit’s fixtures (the same output as text) Read it as the owners will. Look at the action-required table: soonest first, each with its owner, and the two with no date at the bottom as
not stated:Get-Content out/digest/digest.mdWhat the terminal shows, run on the kit’s fixtures (the same output as text) Record three runs as evidence:
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -RunPath out/day2 -AsOf 2026-11-16T12:00:00Z ./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -RunPath out/day2-route -AsOf 2026-11-16T12:00:00Z ./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -RunPath out/digest -AsOf 2026-11-16T12:00:00ZWhat the terminal shows, run on the kit’s fixtures (the same output as text) Each prints its steps, controls and KSIs. The routing run adds
CONTINGENCYand CP-2, because a payload asked for a plan review.Check the chain:
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -CheckSUMS Pass 25 files match SHA256SUMS CHAIN Pass 3 records, chain unbrokenWhat the terminal shows, run on the kit’s fixtures (the same output as text) Check the test stage’s coverage. A lab has no pre-flight or scheduled run, so those two steps fail and the command exits 1, which is what a go/no-go would see:
./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -Check -Stage testWhat the terminal shows, run on the kit’s fixtures (the same output as text) Read the records’ index:
Import-Csv out/evidence/records.csv | Format-Table sequence, task, result, stepsWhat the terminal shows, run on the kit’s fixtures (the same output as text) Change a recorded file and check again. Both checks fail, and name the file:
Add-Content -Path out/evidence/runs/0003-digest/digest.md -Value 'edited after it was recorded' ./Invoke-PnEvidence.ps1 -EvidencePath out/evidence -CheckWhat the terminal shows, run on the kit’s fixtures (the same output as text) Run the kit’s whole test suite:
Invoke-Pester -Path tests -Output None -PassThru | Select-Object PassedCount, FailedCountWhat the terminal shows, run on the kit’s fixtures (the same output as text)
Expected result: PassedCount 140 and FailedCount 0, and an evidence folder whose SHA256SUMS you could hand to the ISSO, before step 8 changed it. Delete out when you’re done:
Remove-Item -Recurse -Force outLab 2: a test environment’s runs
Use the run folders from any earlier chapter’s Lab 2 in a test tenant, account, tenancy or project, never production, kept on agency storage. Work in examples/provider-notices. You’ll replace: <run-folder> (a collection’s output folder from an earlier chapter’s Lab 2, such as out/azure-test, kept until this lab is done), <evidence-folder> (a new folder for this lab’s evidence), <state-file> (a new routing state file, such as out/state-test.json) and <change-record> (the test change record’s number).
Every command in this lab, in order, from examples/provider-notices. Each step below says what it does and what to look for.
# Step 1: Route and digest the test collection
./Invoke-PnRoute.ps1 -NoticesPath <run-folder>/notices.json -RoutingPath config/routing.json -StatePath <state-file> -OutputPath <run-folder>-route
./Invoke-PnDigest.ps1 -NoticesPath <run-folder>/notices.json -StatePath <state-file> -OutputPath <run-folder>-digest
# Step 2: Record all three, with the change record, and check the chain
./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -RunPath <run-folder> -ChangeRecord <change-record>
./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -RunPath <run-folder>-route -ChangeRecord <change-record>
./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -RunPath <run-folder>-digest -ChangeRecord <change-record>
./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -Check
# Step 3: Back it out
Remove-Item -Recurse -Force <run-folder>-route, <run-folder>-digestRoute and digest the test collection, with the lab’s routing and a new state file:
./Invoke-PnRoute.ps1 -NoticesPath <run-folder>/notices.json -RoutingPath config/routing.json -StatePath <state-file> -OutputPath <run-folder>-route ./Invoke-PnDigest.ps1 -NoticesPath <run-folder>/notices.json -StatePath <state-file> -OutputPath <run-folder>-digestRecord all three, with the change record, and check the chain:
./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -RunPath <run-folder> -ChangeRecord <change-record> ./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -RunPath <run-folder>-route -ChangeRecord <change-record> ./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -RunPath <run-folder>-digest -ChangeRecord <change-record> ./Invoke-PnEvidence.ps1 -EvidencePath <evidence-folder> -CheckGive the digest to the test environment’s owners and ask whether each action-required row reached the right person.
Back it out. The evidence of a test stage is kept with its change record; delete only the copies outside agency storage:
Remove-Item -Recurse -Force <run-folder>-route, <run-folder>-digest
Verified facts
| Item | Value | Source |
|---|---|---|
| Controls | SA-9 c, SI-5 a/c/d, CM-3 b/f, CM-4, CP-2 e, SR-8, RA-3 f, CA-7 d–f, AU-9: statement parts as the kit’s catalog paraphrases them | 1 |
| KSIs | KSI-SCR-MON cites SA-9, SI-5, SR-8, RA-3; KSI-SCR-MIT cites SA-9 and RA-3; KSI-CMT-LMC and KSI-CMT-RVP cite CM-3; KSI-RPL-ARP cites CP-2; KSI-MLA-EVC cites CA-7 and RA-3 | 2 |
| AU-9 to KSI-MLA-OSM | The privileged access guide’s mapping | Privileged access guide |
The catalog’s text and the KSIs’ related controls were read for the guide on November 9, 2026; this chapter adds none.
Federal requirements and evidence
The digest and the evidence are what the guide’s G7 checks. The mappings are the kit’s config/requirements.json.3 4
| What the output proves | Requirement it supports | KSI it aligns to | Who keeps it |
|---|---|---|---|
The owners got the week’s notices, with what needs action, by when and who owns it (Lab 1, steps 2 and 3; Lab 2, step 1: digest.md, digest.csv) |
SI-5 c; SA-9 c; RA-3 f | KSI-SCR-MON, KSI-SCR-MIT | The owners; the ISSO files each week’s digest |
Each run is recorded with its steps, controls and KSIs, every file’s hash and the previous record’s hash (Lab 1, step 4; Lab 2, step 2: records/, records.csv) |
CA-7; AU-9 | KSI-MLA-EVC, KSI-MLA-OSM | The ISSO |
The folder is unchanged since it was recorded, and a change is caught (Lab 1, steps 5 and 8: SHA256SUMS, -Check) |
AU-9 | KSI-MLA-OSM | The ISSO |
The stage’s steps each have a passing record, or the gap is named (Lab 1, step 6: -Check -Stage) |
CA-7 | KSI-MLA-EVC | The ISSO, at the go/no-go |
KSIs are FedRAMP 20x indicators for cloud service providers; the agency lines its evidence up with them and doesn’t report them (Book 00, Appendix B). Each record carries that sentence as its claim. The kit’s records support these controls; the agency’s assessor decides them. Which output supports which indicator is the program’s mapping (design guidance).
Dangers
| Danger | What happens | The guard |
|---|---|---|
| The weekly run stops silently | No digest, no evidence, no tasks | The chain shows the gap in dates; the go/no-go fails without a passing RUN record |
| A recorded file edited later | The evidence no longer shows what was read | SHA256SUMS and each record’s file hashes; -Check names the file |
| A record removed from the middle | A bad week disappears | Each record holds the previous record’s hash |
| The digest sent outside the agency | Which clouds and services matter, published | The digest is written for the agency’s owners and kept on agency storage |
| A pass read as a control decision | Someone tells an auditor the control is done | Each record’s claim says it supports the controls and the assessor decides |
Checklist
Footnotes
National Institute of Standards and Technology, SP 800-53 Rev. 5 OSCAL catalog, release 5.2.0, https://github.com/usnistgov/oscal-content/blob/main/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json (read November 9, 2026; carried from the provider notices guide’s verification log).↩︎
FedRAMP, “Key Security Indicators,” FedRAMP Consolidated Rules for 2026, https://www.fedramp.gov/2026/providers/20x/key-security-indicators/ (read November 9, 2026; carried from the provider notices guide’s verification log).↩︎
National Institute of Standards and Technology, SP 800-53 Rev. 5 OSCAL catalog, release 5.2.0, https://github.com/usnistgov/oscal-content/blob/main/nist.gov/SP800-53/rev5/json/NIST_SP-800-53_rev5_catalog.json (read November 9, 2026; carried from the provider notices guide’s verification log).↩︎
FedRAMP, “Key Security Indicators,” FedRAMP Consolidated Rules for 2026, https://www.fedramp.gov/2026/providers/20x/key-security-indicators/ (read November 9, 2026; carried from the provider notices guide’s verification log).↩︎









