What's New
Stay up to date with framework changes, new controls, and playbook additions. The full changelog is mirrored below from the repo root CHANGELOG.md.
Get Notified
Star the repository and use Watch > Releases to receive update notifications.
[Unreleased]
Added
- Automation honesty guard (
scripts/check_automation_honesty.py). New required step in themanifest / index / nav driftjob asserting that each control's manifestautomationclaim is backed by wired evaluators:fullrequires every check to resolve to a registeredEVALUATORSentry inassessment/engine/score.py,partialrequires at least one. Understating automation never fails, because an understated claim is the fail-closed direction — the reviewer is asked for evidence the engine could in principle have collected. Pre-existing drift (43 controls) is recorded inassessment/manifest/automation-honesty-baseline.json, which is a one-way ratchet:--writerefuses to add control IDs that are not already listed, so a newly introduced overclaim cannot be regenerated away. The same job now also runsassessment/manifest/generate_manifest.py --check, socontrols.jsonmust stay derivable from its generator. Covered byscripts/test_check_automation_honesty.py(32 tests). - Playwright container pin-drift guard (
scripts/check_playwright_pin_drift.py). New required check (folded into themanifest / index / nav driftjob) asserting every workflowcontainer.image: mcr.microsoft.com/playwright:<tag>pin (e2e.yml,update-snapshots.yml) matches the@playwright/testversion inpackage.json, ignoring the distro suffix and the unrelated@axe-core/playwrightpackage. Runtime-install workflows (e2e-smoke.yml,prod-smoke*.yml) are out of scope by design. Closes the #583 class of failure where a Dependabot minor bump silently skews a pinned image against the client. Covered byscripts/test_check_playwright_pin_drift.py(9 tests). - Dependabot auto-merge (
.github/workflows/dependabot-automerge.yml, repo varDEPENDABOT_AUTOMERGE). Kill-switch-gatedpull_request_targetworkflow (never checks out PR code) that enablesgh pr merge --auto --squashfor minor/patch + security Dependabot updates; majors are labelledneeds-review. The merge is still gated on every required check (including the pin-drift guard), so the semver level is not the safety boundary — the required checks are. Off by default; activated viaDEPENDABOT_AUTOMERGE=true. - Regulatory Monitor state-only auto-merge (
.github/workflows/regulatory-monitoring.yml, repo varREGULATORY_STATE_AUTOMERGE). Mirrors the Learn Monitor pattern — concurrency group,add-pathsrestricted todata/monitor-state.json(.backup)+reports/monitoring/*.md, consolidation of supersededmonitoring/regulatory-<run>PRs, and a fail-closed file allowlist — with a stricter gate: it auto-merges a state-only baseline PR only when 0 CRITICAL and 0 HIGH items, computed from a fail-closedautomerge_eligiblesignal (an empty/unparseable count is never read as "0", so a report-format drift can never slip an unreviewed item through). CRITICAL/HIGH PRs keepneeds-reviewfor a human, and consolidation never closes aneeds-reviewPR. Off by default; activated viaREGULATORY_STATE_AUTOMERGE=true. e2e-fullmain-breakage alert (.github/workflows/e2e.yml,notify-e2e-failurejob).e2e-fullis label-gated off PRs and intentionally not a required check (making it required would deadlock unlabelled PRs), so a failure onmaincould otherwise go unseen. On a failed mainpushor the dailyschedulerun, the job now opens — or comments on — a single dedupede2e-full-brokenissue (creating the label if missing), withissues: writescoped to that job only. Idempotent: never spams duplicates.- Runbook: Stage 2 redirect auto-merge activation (
.github/AUTODOC-RUNBOOK.md). Maintainer-only documentation of how to activate the (already-merged, gated-OFF) redirect auto-merge: theAUTOMERGE_ENABLEDmaster switch andAUTOMERGE_MIN_SAMPLES/MIN_WEEKS/MIN_AGREEMENT/WINDOW_DAYSthresholds, the activation steps (makeautodoc-redirect-verifya required check, then flipAUTOMERGE_ENABLEDafter weeks of merged-as-is agreement), the kill-switch, and a note that the automated auto-revert workflow is deferred by design (revert detection is already in place). - Redirect auto-merge unlock gate + agreement ledger (Stage 2 s2-1, part 1 —
scripts/autodoc_automerge.py). Second half of Stage 2, built gated OFF. A fail-closed multi-condition gate decides whether the runner may enable GitHub auto-merge on a deterministic redirect PR: it requires the master switchAUTOMERGE_ENABLED=trueand at leastAUTOMERGE_MIN_SAMPLESterminal samples spanningAUTOMERGE_MIN_WEEKSweeks and a merged-exactly-as-is rate ≥AUTOMERGE_MIN_AGREEMENTand zero post-merge reverts in the window (all thresholds env-tunable, conservative defaults — decide-late). The agreement ledger (data/autodoc-automerge-ledger.json) records each auto-drafted redirect PR and its human outcome; "merged exactly as-is" is classified by re-running the same independent verifier the CI gate uses (autodoc_redirect_ci_verify) on the merged diff and confirming it is a clean swap of the same old→new URLs (a human edit counts asmerged_edited, not agreement). The runner now records each redirect PR, reconciles past sample outcomes each run, and enables GitHub auto-merge only when the gate unlocks — so even when unlocked, auto-merge still fires only after the requiredautodoc-redirect-verifycheck is green (never bypassing CI). Off by default and inert untilAUTOMERGE_ENABLED=trueplus accumulated agreement. Covered byscripts/test_autodoc_automerge.py(16 tests, incl. future-dated/unreconciled-ledger poisoning guards) + auto-merge integration tests inscripts/test_autodoc_runner.py. - Independent CI re-verification for redirect PRs (Stage 2 backstop —
scripts/autodoc_redirect_ci_verify.py,.github/workflows/autodoc-redirect-verify.yml). First half of Stage 2 (per-category redirect auto-merge), built ready but inert. A newpull_request_targetworkflow runs on every PR and self-shims: for any PR that is not a runner redirect PR (head notautodoc/*or missing theautodoclabel) it reports success immediately, so it is safe to enable as a required status check without deadlocking normal PRs. For a runner redirect PR it re-derives the clean-swap verdict from the actual PR diff (read via API, verifier run from the base checkout — never PR code) and fails closed unless the diff is exactly one removed + one added table row indocs/reference/microsoft-learn-urls.mddiffering only in one well-formed-URL cell. This is the independent gate that Stage 2 auto-merge will be conditioned on (re-checking the diff on GitHub's side rather than trusting the runner's own pre-PR verification). It does not become a required check or change human-merge behavior until auto-merge is wired and enabled. Covered byscripts/test_autodoc_redirect_ci_verify.py(16 tests: clean swap, hunk-aware parsing (hidden ---/++ lines, second-file-after-hunk), wrong/multiple files, two-line, extra-cell, non-table, non-URL cell, trailing-junk URL, identical URLs, cell-count mismatch, CLI exit codes). - Autodoc scheduler + activation runbook (Phase 3 — pipeline complete).
scripts/Register-AutodocTask.ps1registers the daily Windows Scheduled Task that runs the unattended runner (pruning stale worktrees first; PSScriptAnalyzer-clean). The maintainer runbook.github/AUTODOC-RUNBOOK.mdis finalized: full component table, the twoAUTODOC_ENABLEDswitches (the local env var that gates the runner vs the repo variable that gates the CI verify gate / F5), end-to-end provisioning (Copilot CLI EMU login,judepergit creds, register task, set both switches), operations (disable/inspect/dry-run, stale-worktree cleanup, escalation), and a portability section for onboardingFSI-CopilotGov/FSI-CopilotGov-Solutions(via per-repoautodoc_routeallowlists and theAUTODOC_REPOenv var). The published description (docs/reference/learn-monitor-ai-enhancement.md) is flipped to implemented. With this, the local-CLI pivot is complete; the pipeline remains off by default. - Unattended autodoc runner (
scripts/autodoc_runner.py). Phase 2 of the local-CLI pivot — the orchestration engine. On a schedule it reads the latest Learn Monitor report, routes each change (autodoc_route), and for every autodraft change: drafts a minimal doc edit with the GitHub Copilot CLI (headless), gates it through the deterministic verifier (autodoc_verify_gate) and the independent cross-model review (autodoc_cli_review, a different Copilot model family), and — only when both pass — opens a pull request for a human to merge. Failures retry a bounded number of times (autodoc_retry.decide, default 2) then escalate to a human; human-routed changes are never drafted (escalation issue only); per-change failures are fault-isolated; idempotent via thedata/autodoc-ledger.jsonfingerprint ledger. Off by default —run()is a no-op unlessAUTODOC_ENABLED=true. All side effects (draft/verify/review/git/PR/escalate) are isolated module functions so the orchestration is unit-tested by monkeypatching; covered byscripts/test_autodoc_runner.py(25 tests: combine-conclusion matrix, contract extraction, both-pass→PR, draft-needs-human/empty-diff→escalate, deterministic-needs-human→escalate, retry-then-succeed, exceed-fix-cycles→escalate, review-fail→escalate, base-branch restoration, disabled no-op, human-route escalation, fault isolation). - Independent cross-model autodoc reviewer (
scripts/autodoc_cli_review.py). Phase 2 of the local-CLI pivot: the faithfulness check that replaces the retired third-party LLM verifier. It re-reviews a drafted doc edit with a different GitHub Copilot model family (passed via--model) so the author never grades its own work, treating the Learn change report as source-of-truth and the diff's added lines as the claims to verify. The single Copilot CLI call is isolated behind a mockable runner; everything fails closed — an exec failure yieldsneeds_human, any malformed/non-conforming model output yieldsfail(never a silentpass). The reviewer runs withwrite/shelltools denied so it cannot mutate the repo. Covered byscripts/test_autodoc_cli_review.py(17 tests: prompt assembly, tolerant JSON extraction, fail-closed coercion, runner mocking, exit codes). - Autonomous Learn Monitor documentation pipeline — workflow layer (Stage 1, opt-in). Wires the merged scaffolding into a runnable, fail-closed, human-merge-gated pipeline, off by default (
AUTODOC_ENABLEDrepo variable):scripts/autodoc_route.py(classify the latest Learn report → an authoring contract per change, fingerprint-idempotent viadata/autodoc-ledger.json);autodoc-verify.yml+scripts/autodoc_verify_gate.py(shim-aware required check running the deterministic verifier, hardenedpull_request_target, fails closed); bounded retry/escalation decision logic inscripts/autodoc_retry.py. Maintainer operations + provisioning in.github/AUTODOC-RUNBOOK.md; published description updated indocs/reference/learn-monitor-ai-enhancement.md. The F5 baseline-deferral ledger (advance the monitor baseline only when the downstream doc task is terminal) is implemented and gated off (scripts/autodoc_defer.py,scripts/autodoc_advance.py,.github/workflows/learn-monitor-advance.yml) — a byte-identical no-op unlessAUTODOC_ENABLED=true. Each piece independently reviewed (cross-family owl-mode) before merge. .github/CODEOWNERS— human review gate for compliance-sensitive paths. Names@judeperas required reviewer for customer-facing compliance content (docs/controls/,docs/reference/,docs/framework/,docs/playbooks/,mkdocs.yml), the control manifest, and the autonomous-pipeline safety machinery (scripts/autodoc_*.py, workflows). Scaffolding for the autonomous Learn Monitor pipeline's human-merge gate (Stage 1). Note: this becomes an enforced gate only once branch protection onmainis set to "Require review from Code Owners" (a tracked admin prerequisite —maincurrently requires 11 status checks but no code-owner review).- Deterministic, fail-closed autodoc routing classifier (
scripts/autodoc_classifier.py). First component of the autonomous Learn Monitor documentation pipeline (Stage 1). Parses a Learn Monitor change report and decides, per change, whether it is mechanically safe for an agent to draft a doc edit (route="autodraft", human still merges) or must be analyzed by a human (route="human"), plus a much stricterautomerge_eligibleflag for a future Stage 2. The decision is deterministic (no LLM) and fail-closed: regulatory citations, dates/deadlines, retention durations, license SKUs, deprecations, policy language, overclaim words, and any edit to existing control prose always route to a human, regardless of the monitor's own (noisy) CRITICAL/HIGH/MEDIUM tier. Covered by 20 unit/integration tests (scripts/test_autodoc_classifier.py) including real report fixtures. Implements the June 2026 council review's top finding (the form-vs-meaning classifier gap). - Autodoc canary / poison-pill guard (
scripts/autodoc_canary.py). A standing safety guard that feeds deliberately bad changes (hallucinated citation, fabricated retention duration, overclaim, deprecation, license-SKU change, control-prose edit, CRITICAL tier, future deadline) through the routing gate and fails loudly (exit 1) if any is mis-promoted for unattended handling — the deterministic half of the "who verifies the verifier" control. Extension point reserved for the future cross-vendor LLM verifier. Covered byscripts/test_autodoc_canary.py. - Control 2.27 — Consumption-Entitlement Governance (Pillar 2 — Management). New framework control governing who is entitled to consume metered and premium Microsoft Copilot capabilities — enforcing a switch-on-pathway entitlement contract per agent consumption pathway, applying per-agent spend caps, and running a pre-enforcement coverage-gap ("who would be blocked") analysis before any spend control is activated. Pairs with Control 3.5 (cost reporting) and is distinct from Control 2.26 (agent identity governance) and Control 1.18 (functional RBAC). Documents the companion
copilot-billing-governancesolution's entitlement contract. Catalog expands from 78 to 79 controls (Pillar 2 from 26 to 27). Added toassessment/manifest/controls.json,CONTROL-INDEX.md,mkdocs.yml, and the Pillar 2 index; the four implementation playbooks are tracked as follow-up work. Resolves #440. - Consolidated 9 Learn Monitor daily drift reports (2026-05-27 through 2026-06-04) from bot PRs #343–#383 into main via consolidation PR #385. Superseded PRs closed;
data/monitor-state.jsonupdated to newest cumulative state.
Fixed
- Controls claimed automation the engine never performed (
assessment/manifest/generate_manifest.py,controls.json). Control 1.2 publishedautomation: fullwhile only 1 of its 3 checks (agent_inventory_exists) had a registered evaluator —auth_mode_configuredandno_orphaned_agentswere declared in the manifest but never implemented, so they silently returnedunknownwhile the report implied full automated coverage. Controls 1.8 and 1.10 publishedautomation: partialwith zero working evaluators (sentinel_agent_alerts_exist,comm_compliance_policy_exists). All three now follow the repo's established fail-closed shapes: 1.2 drops topartialwith 1.2.b/1.2.c converted to explicit manual gates (pass_condition: ""+collection_methods: ["Manual"], mirroring 1.11.b/c) plus a newmanual_questioncovering authentication-mode and orphaned-owner evidence; 1.8 and 1.10 drop tomanualwith emptychecks/collection_methodsand(0, 0)zone thresholds (mirroring 1.15), their manual questions extended to absorb the evidence the removed checks claimed to gather. Controls 1.4 and 1.6 were audited in the same pass and confirmed already honest — no change. Becausezone_thresholdsare derived from the auto-evaluable check count, 1.2's Zone 3min_checks_passedfalls from an unreachable 3 to 1, with the two manual gates capping maturity below the zone target until attested.docs/reference/assessment-coverage.mdanddocs/javascripts/control-explorer-data.jsonregenerated accordingly (unimplemented checks 76→72). Resolves judeper/OceanSquad#263. - Nine controls claimed "no companion solution" while the pinned solutions lock mapped one (
docs/controls/,scripts/verify_solutions_docs.py). Control 1.2 asserted that no companion solution existed, butassessment/manifest/controls.json,assessment/data/solutions-lock.json, anddocs/reference/solutions-index.mdall mapped it toagent-365-lifecycle-governance— and the companion repository's canonicalsolutions.jsonconfirms that mapping upstream, so the manifest was right and the control document was wrong. The sentinel even contradicted thesolutions-index.md#coverage-scopeanchor it linked to. A full 79-control enumeration found the same contradiction in 1.1, 1.2, 1.13, 1.25, 2.6, 2.17, 2.24, 3.7, and 4.3; each now carries anAutomation Availableblock naming the mapped solutions.verify_solutions_docs.pygains a fourth check that fails when a control declares no companion solution while the lock maps one — deliberately a contradiction guard, not a completeness guard, so it neither forces a control to enumerate every mapped solution nor forbids cross-referencing an unmapped one. Covered by 2 new tests (7 total). Resolves judeper/OceanSquad#260. e2e-fullwas fully broken onmainby a Playwright pin skew (.github/workflows/e2e.yml,update-snapshots.yml). A Dependabot minor bump set@playwright/testto1.61.1while the pinned container stayedv1.60.0-noble, so all 81 tests failed atbrowserType.launch. It was invisible at PR time (e2e-full is skipped on PRs; e2e-smoke self-heals vianpx playwright install). Bumped both container pins tov1.61.1-nobleand added the pin-drift guard (see Added) so the skew cannot silently recur.- WCAG 2.1 AA color-contrast violations on customer-facing docs (
docs/stylesheets/control-bluf.css,docs/stylesheets/extra.css). Restoringe2e-fullun-masked 12 axecolor-contrastfailures the broken suite had hidden: BLUF metadata labels /+N morechips (#717171→#696969),.bluf__actionlinks (an intended#005A9Eoverride that.md-typeset aspecificity had been overriding back to#0078D4), homepage job-card links (#0078D4→#005A9Eon the warm#faf8f5card surface), and the dark-palette print button (white on#429CE3→#005A9E, 7.10:1). Verified 12→0 across both palettes viatests/e2e/32-docs-a11y.spec.mjs. - Dead PyRIT install link (
docs/playbooks/control-implementations/2.5/portal-walkthrough.md). The…/PyRIT/getting-started/install/URL returned 404 after PyRIT's documentation reorganization; repointed to the stable repository README. Clears the recurringmarkdown-link-check(Link Validation) failure onmain. - Baseline advance could silently advance the wrong URL and lose a real change (
scripts/autodoc_advance.py,scripts/autodoc_defer.py,.github/workflows/learn-monitor-advance.yml). The deferred-baseline advance matched a closedautodocissue to a pending change via GitHub's tokenized{url} in:bodysearch — so a short watchlist URL's tokens could subset an unrelated closed issue, advancing the wrong baseline and deleting a still-open URL's pending blob (silent data loss). It now matches a closed issue to a change by an exact(url, content_hash)identity plumbed end-to-end (detection → reportContent-Hash:→ contract →Source:/Content-Hash:issue lines, with a fallback to the autodraft tracking issue's JSON contract), only treats issues closed as COMPLETED as terminal, and keys pending blobs by(url, content_hash)so a second change to one URL no longer overwrites/orphans the first. A tribunal owl-review caught and closed a follow-on coverage gap (the parser missing the autodraft tracking-issue format); new regression tests inscripts/test_autodoc_advance.pypin each defect. - Regulatory monitor never persisted state, and would have burst on first persist (
scripts/regulatory_monitor.py). It calledsave_state_atomic(STATE_FILE, state)with the arguments swapped (signature is(state, state_path)), raising aTypeErrorthe workflow'scontinue-on-errorswallowed — so the regulatory monitor had never saved state (zero persisted regulatory reports). Fixed the call order (+ a non---dry-runregression test) and added first-run baseline suppression (mirroringlearn_monitor) so the first persisted run records the baseline silently instead of flagging ~30 days of items as new. - Admin-proof required-check deadlock (
.github/workflows/required-check-shims.yml+ newrequired-check-shim-mkdocs.yml,.github/workflows/python-quality.yml). A single sharedpaths-ignore(the union of two real workflows'paths:) was not an exact complement of either, so a PR touching only e.g.tests/spa/**,playwright.config.mjs,VERSION, oroverrides/**triggered neither the real check nor its shim and could never merge (even by an admin). Split into two shims, eachpaths-ignoremirroring exactly its own real workflow'spaths:, and extendedpython-quality.ymlpaths (data/**,tests/**,package.json,playwright.config.mjs,overrides/**, …) so the five named quality checks always report. Verified with three throwaway probe PRs (each reached 11/11 required checks). - Redirect target host was not validated (
scripts/autodoc_runner.py,scripts/autodoc_redirect_ci_verify.py). A poisoned upstream redirect could land an attacker-controlled URL indocs/reference/microsoft-learn-urls.mdas a clean single-cell swap. The runner and the independent CI verifier now enforce a fail-closed Microsoft-domain allowlist (learn.microsoft.com/microsoft.com/*.microsoft.com) on the new target host (taken fromurlparse().hostname, so credential tricks and subdomain spoofs are rejected); off-domain targets escalate / fail the verifier. Landed before enabling Stage-2 auto-merge anywhere. find_affected_controlsunder-reported affected files; monitor scripts had no offline smoke test (scripts/monitoring_shared.py,scripts/learn_monitor.py,scripts/regulatory_monitor.py). Adopted fromFSI-CopilotGovwhile making FSI-AgentGov the canonical pipeline: a cross-cutting scan over sibling playbook folders (governance-operations, compliance-and-audit, incident-and-risk, agent-lifecycle) so a detected change reports all affected docs; a true offline--dry-runearly-exit; and a newscripts/test_monitor_smoke.py.- Autodoc scheduled task runs against a dedicated, auto-synced checkout (
scripts/Register-AutodocTask.ps1). The runner reads the latest Learn Monitor report from its checkout, but the monitor publishes reports via a PR that merges tomain— so a task pointed at the operator's working tree would only ever see whatever report that tree last had (and the operator actively uses it for feature-branch work, making an in-placegit pullunsafe). The registration script now clones a dedicated checkout the task fully owns (-CheckoutPath, default sibling<repo>.autodoc), seeding its idempotency ledger from the operator's repo. Each run the task hard-syncs that checkout toorigin/<base>(fetch+checkout+reset --hard, each fail-closed) before invoking the runner, so it always processes the newest merged report — and never touches the operator's branches, working tree, or uncommitted changes.reset --hardleaves untracked files in place, so the ledger persists. To prevent ever hard-resetting the wrong tree, the script only operates on a checkout it created (marked with a.git/autodoc-ownedsentinel) and refuses to adopt any pre-existing checkout — robust against path aliases (junctions/symlinks, 8.3 short paths) that a string comparison would miss. Surfaced while wiring up unattended operation after the first supervised live run. - Autodoc scheduled-task GitHub auth (
scripts/Register-AutodocTask.ps1). The runner uses baregit push originandgh, which on an EMU-licensed machine resolve to the active EMU account (judep_microsoft) and are denied write access (HTTP 403) — the Windows Credential Manager overrides with the EMU token even whenjudeperis logged in. The scheduled-task command now authenticates every write as a new-PushAccountparameter (defaultjudeper): at task time it reads that account's token from the gh keyring (gh auth token --user judeper— no static secret stored) intoGH_TOKEN, and the dedicated checkout's local.git/configroutes git's github.com credentials throughgh auth git-credential, sogitandghboth authenticate with that token. (The credential override lives in the checkout config file rather thanGIT_CONFIG_*env vars because the Task Scheduler's Windows PowerShell 5.1 host drops an empty-string env var, which made git reportmissing config value GIT_CONFIG_VALUE_0; the file-based empty-helper reset works reliably and survivesgit reset --hard.) Scoped to the dedicated checkout, so the operator's interactive git/gh accounts are untouched. Token resolution is fail-closed: if the keyring token can't be resolved at task time, the task throws before the runner starts (rather than lettingGH_TOKENfall back empty to the denied EMU account). The runbook gains a one-time label-creation prerequisite step (the runner attachesautodoc/escalatelabels and fails closed if a label is missing). Surfaced by the first supervised live (non-dry-run) execution. - Redirect changes can now pass the verifier (
scripts/autodoc_route.py). Redirect autodrafts editdocs/reference/microsoft-learn-urls.md, whose section headings are topic names (Copilot Studio,Microsoft Purview, …) — not the generic control headings the contract assigned, so the deterministic verifier'ssection_allowlistcheck blocked every redirect edit and they always escalated. The redirect contract now setsallowed_headingsto the target file's own headings (extracted with the same markdown-it-py oracle the verifier uses, so they match exactly); the other five checks (path-allowlist, diff-minimality, claim-support, FSI language, fingerprint) still gate the edit. Fails closed if the file can't be read. Surfaced by a controlled live dry-run. - Autodoc runner draft timeout too tight (
scripts/autodoc_runner.py). A live Opus draft exploring a fresh ~1,280-file worktree can take 10+ minutes; the 600s default timed out mid-draft (the same change completed under 600s on another run — it sits right at the boundary). Raised the default draft timeout to 1200s (review to 300s) and exposed--draft-timeout/--review-timeoutCLI flags for tuning. Surfaced by the second controlled dry-run. - Autodoc runner worktree cleanup (
scripts/autodoc_runner.py). The per-changefinallycleanup rangit checkout --force maininside the disposable linked worktree, which git rejects withfatal: 'main' is already used by worktree …(exit 128) because the base branch is checked out in the primary worktree. It now detaches (git checkout --force --detach main). Found by the first controlled live dry-run (mocked unit tests stubgit, so they could not surface it); the draft → deterministic verify → cross-model review path itself worked end-to-end. - Replaced non-rendering Material shortcode markup on the homepage quick-start cards (
docs/index.md) with plain text labels so GitHub Pages no longer displays literal:material-*:tokens.
Changed
- Redirect changes are handled deterministically, with no LLM (
scripts/autodoc_runner.py). A URL redirect is a mechanical string swap, and the URL list (microsoft-learn-urls.md) stores entries as table rows (| Title | URL | Date |) — so an LLM draft + prose verifier was the wrong tool (it failedclaim_supportbecause swapping the URL marks the whole row's title/date as unsupported "new claims"). The runner now detects redirect changes and applies the exactsource_url→new-URL replacement itself, verifies the staged diff is a clean URL-only swap confined to the URL list, and opens a human-merge PR — escalating if the URL isn't found, the new URL is already present, the new or old URL contains non-URL-legal/table-breaking characters, the swap isn't clean, or the URLs can't be parsed. In a live dry-run this took ~6 seconds and reachedpr_opened(vs ~13 min of flaky LLM drafting that always escalated). No cross-model review is needed (there's no model output to review). The replacement is boundary-aware (a compiledre.escape(old_url)+ negative-lookahead on URL-continuation characters), so a redirect of a URL that is a prefix of a sibling (e.g..../environment-groupsvs.../environment-groups-rules) swaps only the exact URL and never corrupts the longer sibling; the same boundary rule guards the "new URL already present" ambiguity check so a sibling prefix does not trigger a spurious escalation. As an independent backstop, the clean-diff guard is structural (table-cell based, not a stringreplace): every removed row's URL cell must equal the old URL exactly and differ from the matching added row only by that cell becoming the new URL, so a prefix-corrupted sibling is rejected even if the regex had let it through. - Autodoc draft + review are faster and Windows-safe (
scripts/autodoc_runner.py,scripts/autodoc_cli_review.py). The draft now inlines the current content of the allowed file(s) (capped at 60 KB each) into the prompt and tells the model not to explore the rest of the worktree — cutting a live Opus draft from ~18 min to ~3 min per attempt. Both the draft and the review now pass their (potentially large) prompt to the Copilot CLI via stdin instead of a-pargument, avoiding the Windows command-line length limit (WinError 206). Found while validating the pipeline with controlled live dry-runs. - Autodoc pipeline pivots from GitHub's cloud coding agent to a local, unattended GitHub Copilot CLI drafter. GitHub's cloud coding agent cannot drive this pipeline on these repositories: the enterprise Copilot license lives on an EMU account that is barred from the public personal repo, and GitHub disallows cloud-agent automations on public repositories. The drafter is therefore the GitHub Copilot CLI itself (the EMU license provides reasoning; the
judepertoken performs all repo writes — independent auths), run headless on a schedule, with independent review performed by a different Copilot model family rather than a third-party API. Phase 1 of the pivot (this change): retires the cloud-agent workflows (learn-autodoc-route.yml,autodoc-fix-retry.yml) and the Anthropic LLM verifier (scripts/autodoc_llm_verify.py), and makes theautodoc-verify.ymlCI gate deterministic-only (drops theANTHROPIC_API_KEYdependency). Routing (autodoc_route.py), the deterministic verifier, the canary, the retry/escalation decision logic, and the F5 ledger are all retained. The pipeline remains off by default (AUTODOC_ENABLED). - Learn Monitor PRs now self-consolidate and auto-merge (Stage 0 monitoring hardening).
.github/workflows/learn-monitor.ymlgained two steps after PR creation: (1) close older bot-createdmonitoring/learn-<n>PRs as superseded (the newest carries the cumulativedata/monitor-state.jsonbaseline), and (2) enable squash auto-merge on the new PR once the required checks pass. Safety constraints: PR creation usesadd-pathsso the branch can only containdata/monitor-state.json(.backup)andreports/monitoring/**; auto-merge re-validates that every changed file matches that allowlist (else it labelsneeds-reviewand skips); consolidation closes only PRs carrying thelearn-watchlabel, matching the exact^monitoring/learn-[0-9]+$pattern, with a strictly lower run number (never a human PR sharing the prefix); both steps are gated by theLEARN_STATE_AUTOMERGEkill-switch and the workflow runs under aconcurrencygroup. Documented indocs/reference/learn-monitor-guide.md. Addresses the recurring monitoring-PR pile-up (#447). - Added explicit Markdown authoring guidance in
README.mdandCONTRIBUTING.mdto avoid:material-*:shortcodes in page content under the current CSP-safe MkDocs emoji configuration.
[1.6.2] — May 11, 2026 (Frontier Readiness auto-evaluator wave)
Release theme: Six-PR wave wiring telemetry-driven auto-scoring for the Frontier Readiness assessment, taking auto-evaluable coverage from 0/25 (0%) to 6/25 (24%). After this release, the Frontier auto-evaluable backlog is structurally exhausted — the remaining 19 questions (76%) are facilitator-only by design (board attestation, written policy text, executive interviews, regulatory committee minutes, business strategy alignment) and cannot be honestly derived from M365/PPAC/Sentinel/SharePoint telemetry.
Upgrade safety: No breaking changes. No control IDs renamed. Schema additions only on the Frontier manifest (six entries flipped to auto_evaluable: true with new notes fields). Assessment engine grows by six evaluator functions plus 21 new tests; existing 78-control assessment behaviour unchanged. Safe to upgrade in place.
Honesty principle: Every evaluator added in this wave is partial-capped — none ever returns "yes". Each Frontier question has at least one facilitator-only sub-claim (governance maturity, written attestation, named executive sponsor) that telemetry cannot verify, so auto-scoring asserts only what telemetry can support and explicitly names the residual facilitator burden in evidence strings. The honest assessment-coverage report at docs/reference/frontier-assessment-coverage.md reflects this structural floor — it is not a roadmap target to "improve."
Coverage progression
| Wave | PRs | Auto | Manual | % Auto |
|---|---|---|---|---|
| Pre-evaluators (v1.6.1) | — | 0 | 25 | 0% |
| Q16 + Q17 framework | #215, #216 | 2 | 23 | 8% |
| Q13 partial-cap pattern | #218 | 3 | 22 | 12% |
| Q01 word-boundary regex | #219 | 4 | 21 | 16% |
| Q18 + Q03 closeout | #220 | 6 | 19 | 24% |
PR #215 — Q16 + Q17 evaluator framework
Established the Frontier evaluator infrastructure: assessment/engine/score_frontier.py with _load_collected_json helper, EVALUATORS registry, compute_evaluator_coverage API, and the first two evaluators:
- Q16 (
zone_classification_present) — pure auto: PPAC environment Tags / Group naming for Zone 1/2/3 classification - Q17 (
audit_log_retention_meets_finra) — pure auto: M365 audit retention policies via Purview audit-log search export
Coverage matrix infrastructure (docs/reference/frontier-assessment-coverage.md) and CI gating (scripts/generate_coverage_matrix.py --type frontier --check) added in this PR.
PR #216 — PPAC environment-group enrichment
Extended assessment/collectors/Collect-PPAC.ps1 with two new sections:
- Section 8 — Environment Groups via BAP API (
Id,DisplayName,Description,CreatedTime,EnvironmentCount) - Section 9 — per-environment tag/group enrichment (
EnvironmentGroupId,Tags)
These sections back the 3-way correlation in PR #220 (Q18) and improve Q16's signal precision.
PR #218 — Q13 partial-cap pattern
Q13 (zone_classification_with_audit_supervision_and_model_risk) — established the partial-cap pattern that the rest of the wave inherits. Combines Q16's PPAC zone signal with Q17's audit signal and Purview supervision policy presence. Returns "partial" when telemetry signals are present but caps there because model-risk-management governance attestation is facilitator-only.
Pattern features replicated by Q18 + Q03:
- _metadata.errors short-circuit per source
- None only when ALL sources unavailable
- Evidence string explicitly names every missing signal AND every facilitator-only caveat
- NEVER_returns_yes test invariant
PR #219 — Q01 + Graph job-title enumeration
Q01 (ai_initiative_owner_identified) — keyword search over Graph user job titles for AI leadership signals (CDO, Chief AI Officer, Chief AI Risk Officer, VP AI, Head of AI, etc.). Required collector extension:
- Collect-Graph.ps1 §7 added: AI Leadership Job Titles via two narrow
Get-MgUserstartswithqueries + post-filter (Graph API does not supportcontainson job-title)
Word-boundary regex (r'\bVP\b', r'\bCDO\b') used for short acronyms to prevent false positives like "VPC" or "CDOs". Capped at "partial" because mere title presence does not confirm active sponsorship.
PR #220 — Q18 + Q03 closeout (this release)
Q18 (env_groups_with_inventory_siem_rag_and_lineage, L300 Tech & Data) — 3-way telemetry correlation across:
- PPAC environment groups (Sections 8+9 from #216)
- Sentinel SIEM data connectors (Office365Enabled, McasEnabled, TotalConnectors)
- SharePoint item-level permission scan (itemLevelPermissions[].SampledItems + groundingCrossRef.ApprovedFound)
Telemetry gap explicitly acknowledged: automated agent inventory is not collected by any current collector. Q18 evidence string names this as "agent inventory not collected (out of scope)" rather than silently degrading. RAG-integrity validation + data lineage documentation are flagged as facilitator-only.
Q03 (enterprise_ai_strategy_published_with_portfolio, L300 AI Strategy & Experience) — SharePoint site-name heuristic against 8 multi-word strategic keywords (ai strategy, ai governance, ai council, ai portfolio, agent portfolio, frontier, executive sponsor, governance committee). All keywords are multi-word so plain substring matching avoids the false-positive risk that Q01 had to navigate for short acronyms. Capped at "partial" because "published" is telemetry-verifiable but "with portfolio" + "active governance" are facilitator-only.
Generator update: scripts/generate_coverage_matrix.py _FRONTIER_EVALUATOR_CANDIDATES list emptied — Q03 + Q18 removed because they are no longer "future." The list is now structurally complete; any new Frontier evaluator wiring would require an explicit governance decision to relax the facilitator-only floor.
Test additions across the wave
- v1.6.1 baseline: 72 tests
- After #215: 81 tests (+9 for Q16 + Q17)
- After #218: 85 tests (+4 for Q13)
- After #219: 93 tests (+8 for Q01)
- After #220: 114 tests (+21 for Q18 + Q03) — release-time count for v1.6.2 PR-wave-220
- Current suite (post-release additions): 140 tests (verified 2026-05-16)
All six evaluators ship with NEVER_returns_yes invariant tests, evidence-string assertions, and facilitator-override (driver-level upgrade/downgrade) tests.
Validation gates (all six PRs)
Every PR in this wave passed the full gauntlet locally and in CI:
pytest assessment/tests/ -qruff check assessment scriptsgenerate_coverage_matrix.py --type frontier --checkgenerate_coverage_matrix.py --check(78-control assessment)check_manifest_doc_drift.py --checkverify_language_rules.py
PowerShell static analysis (PSScriptAnalyzer) gated PR #216 (collector changes). All other PRs were Python-only.
Files changed (cumulative across the wave)
assessment/engine/score_frontier.py— new module, 6 evaluators + helpers + EVALUATORS registryassessment/manifest/frontier-readiness.json— 6 entries flippedauto_evaluable: truewithnotesassessment/tests/test_score_frontier.py— 6 evaluator test classes (~1300 lines)assessment/tests/fixtures/— 14+ new fixtures (PPAC env-group variants, Sentinel connector variants, SharePoint variants)assessment/collectors/Collect-PPAC.ps1— Sections 8+9 added (#216)assessment/collectors/Collect-Graph.ps1— Section 7 added (#219)docs/reference/frontier-assessment-coverage.md— auto-regenerated; final state 6/25 (24%) Auto, 19/25 (76%) Manual, 0 Unimplementedscripts/generate_coverage_matrix.py—--type frontiermode +_FRONTIER_EVALUATOR_CANDIDATESretired
Forward-looking note
The Frontier auto-evaluable backlog is closed. Future Frontier work belongs in three categories:
- Facilitator playbooks — published guidance on how to evidence the 19 facilitator-only questions during an actual Frontier engagement
- Driver/pattern coverage docs — narrative guidance mapping each Frontier transformation pattern to which controls in the 78-control framework it leans on
- Telemetry honesty maintenance — keeping the 6 existing evaluators current as collectors evolve (e.g., if Microsoft adds an "agent inventory" Graph endpoint, Q18's evidence string would need an update)
No further Frontier evaluator wiring is planned. The 76% manual floor is a feature, not a defect.
Post-release triage fix cycle (2026-05-17)
Triage of 3 independent external audits (51 unified findings + 8 rubber-duck additions = 59 total). 12 PRs merged on 2026-05-17. No VERSION bump — fixes stay under v1.6.2.
Regulatory correctness
- PR-3 (#273): Added SR 26-2 / OCC 2026-13 generative-AI scope caveat to docs/reference/regulatory-mappings.md and docs/framework/regulatory-framework.md. The interagency MRM guidance issued April 17, 2026 explicitly excludes generative AI and agentic AI from scope per primary-source verification. Re-characterized GenAI-specific control mappings (Controls 2.11, 2.16, 2.20, 3.10) as analogous principles rather than direct regulatory obligations.
- PR-4 (#280): Added NAIC Model Bulletin on Use of AI by Insurance Companies (December 2023), NFA Compliance Rule 2-9 (FCM/IB/CPO/CTA supervisory baseline), SEC Regulation S-P (including the May 2024 30-day NPI notification amendments). Upgraded NYDFS Part 500 surfacing in regulatory-framework.md. Added OCC Bulletin 2023-17 number to existing Interagency Third-Party Guidance citations.
- PR-6 (#281): Resolved 624 sector-specific TODO placeholders in assessment/manifest/controls.json (replaced with null per schema preservation). Canonicalized 61 stale OCC-2011-12 / Fed-SR-11-7 machine-readable codes to OCC-2026-13 / Fed-SR-26-2.
Assessment engine
- PR-5 (#276): Fixed 8 of 11 evaluator drift (6 manifest pass_condition strings rewired, 2 preserved for future wiring). Added collector payload normalization layer in score.py. Regenerated frontier-assessment-coverage.md (correctly shows 6/25 = 24% — previously stale at 0%). Documented SPA vs Python engine semantic divergence in assessment/README.md and docs/assessment/index.md. Auto-evaluable controls: 1/78 → 7/78.
Customer-facing surfaces
- PR-1 (#271): Fixed count drift on home page (5 → 6 Regulatory Frameworks) + Solutions Integration repo-structure block + Summary Statistics block.
- PR-2 (#275): ~240 playbook footer canonicalizations + 6 stale non-playbook stamps brought to canonical v1.6.2 / May 2026.
- PR-7 (#274): Refreshed all 6 Excel templates from v1.4.0 — April 2026 to v1.6.2 — May 2026. Restored 20 dashboard rollup formulas (governance-maturity-dashboard.xlsx). Added missing controls 2.26 / 1.29 / 4.8 / 4.9 to docs/downloads/index.md. Hardened scripts/verify_excel_templates.py.
- PR-8 (#279): Corrected Control 1.1 SEC 17a-4(f) overclaim to align with Control 1.7's capture-vs-preservation framing. Removed duplicate AIAppInteraction bullet from Control 1.7.
- PR-11 (#270): Corrected static SVG pillar counts in solutions-integration-overview.svg (28/24/12/7 → 29/26/14/9).
- PR-13 (#269): Replaced 2 redirecting Microsoft Learn URLs across 8 files.
- PR-15 (#282): Final footer cleanup on 7 top-level customer-facing pages that PR-2's playbook-scoped sweep didn't reach.
Hygiene
- PR-14 (#272): Clarified CHANGELOG.md test-count narrative (114 release-time vs 140 current). Also added CHANGELOG.md to python-quality.yml paths trigger so changelog-only PRs satisfy branch protection.
Companion repository (FSI-AgentGov-Solutions) - 5 GitHub issues drafted and posted at #143–#147 for future work (MRM Automation regulatory refresh, solutions inventory reconciliation, version drift between site and repo, preview-vs-live status, canonical control-coverage metadata export).
Audit artifacts (private, gitignored)
- All 3 external audits + 12 verification tracks + 8 enumeration follow-ups + Phase 3 rubber-duck critique + unified findings register (59 findings) + fix plan + final QA + handoff brief stored in maintainers-local/audits/2026-05-16/ for internal record.
Net findings disposition: 30 confirmed-fixed / 13 rejected (audits read stale corpus state) / 9 deferred-informational / 7 pending external Microsoft product-surface research.
Pending user actions (not blocking customer handoff)
- Forward 7 Microsoft product-surface researcher prompts to specialized researcher (maintainers-local/audits/2026-05-16/findings/track-j-msft-research-prompts.md)
- Review 5 companion-repo issues #143–#147 in FSI-AgentGov-Solutions
[1.6.1] — May 10, 2026 (Microsoft Learn drift patch)
Release theme: Documentation-only patch responding to upstream Microsoft Learn changes detected by the Learn Monitor (run 114, 2026-05-10). Five follow-up issues were filed (#205–#209); four resulted in doc updates; one (#205) was investigated and closed not planned (the framework had never adopted the deprecated terminology). Five parallel Sonnet agents in five git worktrees executed the fixes simultaneously, validating the worktree-per-agent pattern at scale.
Upgrade safety: No breaking changes. No schema changes. No control IDs renamed. No file additions. Pure documentation patches across 5 controls + 5 playbooks + license-requirements.md. Safe to upgrade in place.
Issue #206 — Analytics retention + 7-area effectiveness (#211, 3a936123)
Modified:
docs/controls/pillar-3-reporting/3.2-usage-analytics-and-activity-monitoring.md— Data Availability info box: 180-day analytics, 28-day session detailsdocs/controls/pillar-2-management/2.5-testing-validation-and-quality-assurance.md— retention windows admonitiondocs/controls/pillar-2-management/2.6-model-risk-management-sr-26-2.md— retention admonition in §Platform-Enabled Monitoring; footer to May 2026docs/controls/pillar-2-management/2.9-agent-performance-monitoring-and-optimization.md— retention admonition in §Verification Criteriadocs/controls/pillar-3-reporting/3.10-hallucination-feedback-loop.md— retention admonition after Feedback Capture tabledocs/playbooks/control-implementations/2.5/portal-walkthrough.md— new §9.8 covering 7-area effectiveness panel structure (added "Knowledge source use")docs/playbooks/control-implementations/2.6/portal-walkthrough.md— retention admonition in §3.1
Net change: +49 / −4 lines.
Issue #207 — IRM DLP workload caveats + role groups (#212, 7a026bb1)
Modified:
docs/controls/pillar-1-security/1.12-insider-risk-detection-and-response.md—!!! warning "IRM DLP workload limitations"admonition listing 5 unsupported workloads (Teams, Endpoint DLP, M365 Copilot, Power BI, on-premises repositories); 3 verbatim role groups cited from Microsoft Learn (Insider Risk Management,Insider Risk Management Analysts,Insider Risk Management Investigators); cross-references to controls 1.5, 1.6, 1.10, 1.13docs/playbooks/control-implementations/1.12/portal-walkthrough.md— workload caveat surfaced in walkthrough
Net change: +72 / −2 lines.
Issue #208 — BCDR retention defaults + RPO/RTO surfacing (#213, 8cb6bbec)
Modified:
docs/controls/pillar-2-management/2.4-business-continuity-and-disaster-recovery.md— retention table corrected: 7-day default ALL environments; extended retention up to 28 days requires production Managed Environments. Surfaces RPO/RTO from new Microsoft FAQ: within-region near-zero RPO + <5min RTO; cross-region typical replication lag <15mindocs/playbooks/control-implementations/2.4/portal-walkthrough.md— retention defaults aligneddocs/playbooks/control-implementations/2.4/troubleshooting.md— footerdocs/images/2.4/EXPECTED.md— screenshot specs aligned to new defaults
Net change: +25 / −15 lines.
Issue #209 — Agent 365 license deadline 2026-07-01 (#214, cbfbb463)
Modified:
docs/controls/pillar-1-security/1.8-runtime-protection-and-external-threat-detection.md—!!! dangerdeadline callout: AI Agent Inventory in Defender for Cloud Apps requires Agent 365 after 2026-07-01; orgs without Agent 365 lose AI Agent Inventory visibility entirelydocs/controls/pillar-3-reporting/3.7-ppac-security-posture-assessment.md— deadline callout for Defender for Cloud Apps cross-reference (walkthrough Step 8)docs/playbooks/control-implementations/1.8/portal-walkthrough.md— danger admonition in walkthroughdocs/playbooks/control-implementations/3.7/portal-walkthrough.md— danger admonition in walkthroughdocs/reference/license-requirements.md— two new rows for controls 1.8 / 3.7 documenting the Agent 365 transition
Net change: +60 / −10 lines.
Issue #205 — Sensitivity labels Entra group classification migration (closed not planned)
Investigated, no changes required. Exhaustive grep across the entire framework for Entra group classification, Convert Entra group classification, Classic Azure AD classification, and Convert classic group classifications returned zero matches. The framework had never adopted the deprecated terminology. Three classification-adjacent terms (DLP connector classification, Entra group membership for DLP scoping, SharePoint classic sites) were verified unrelated. Issue closed with audit comment; branch never pushed.
Workflow validation
- 5 parallel Sonnet agents in 5 git worktrees — zero filesystem race conditions, zero merge conflicts, all 5 agents independently ran
mkdocs build --strictagainst the same global Python install with no contention. Wall time per agent: 9–12 minutes. - Empty-commit pattern (#205) — agent created an audit-trail commit when investigation found nothing to fix; orchestrator chose to skip the empty PR and close the issue directly with the investigation comment instead.
- CI gates per PR — 8/8 required checks green (mkdocs --strict, verify_language_rules, verify_controls, drift, coverage matrix, ruff, pytest, codeql) before merge.
Hard rules
- Tier-1 banlist enforced — 0 banned-phrase hits across all 4 PRs.
- 78-control catalog unchanged. Pillar structure unchanged. Zone model unchanged.
- No manifest changes.
controls.jsonbyte-identical to v1.6.0. - No solutions catalog changes. Companion repo untouched.
- Documentation-only patch. No code changes to
assessment/,scripts/, or workflows.
Validation at release
| Gate | Result |
|---|---|
mkdocs build --strict |
0 warnings |
verify_language_rules.py |
0 banned phrases |
verify_controls.py |
78 controls pass |
check_manifest_doc_drift.py --check |
78=78=78 |
generate_coverage_matrix.py --check |
current |
generate_pattern_coverage.py --check (with companion repo) |
current (78 controls, 35 solutions) |
ruff check |
all pass |
pytest assessment/tests/ |
56 passed |
[1.6.0] — May 10, 2026 (Solutions Discoverability Release)
Release theme: Make the 35 companion solutions discoverable by Microsoft CAPE alignment metadata. Phase 6a tagged every solution README in the companion repo with applicable_patterns, applicable_drivers, and coe_function frontmatter; Phase 6b consumed those tags in the framework repo to enrich the Solutions Index and the Pattern Coverage matrix. No control catalog changes; no schema changes.
Upgrade safety: No breaking changes. No control IDs renamed. No controls.json schema changes. Safe to upgrade in place. Existing Solutions Index consumers that grep on existing column headers continue to work — three new columns (Patterns, Drivers, CoE) were appended before Summary.
Phase 6a — Companion repo tagging (judeper/FSI-AgentGov-Solutions #134, d1d6f653)
Added (in companion repo):
- YAML frontmatter on all 35 production solution READMEs with
applicable_patterns(subset of P1–P6),applicable_drivers(subset of the 5 canonical Capability Drivers, snake_case IDs), andcoe_function(one of govern / enable / optimize / scale) - Tag derivation:
applicable_patternsfrompattern_criticalfield in frameworkcontrols.jsonfor each solution's primary controls (with purpose-based inference wherepattern_criticalwas empty across all primary controls);applicable_driversfrom union of primary controls'applicable_drivers;coe_functionmapped peragentic-coe.mddefinitions - 282 frontmatter insertions across 35 files; zero README content changes
- Distribution: govern=20, optimize=8, enable=4, scale=2
Phase 6b — Framework repo consumption (#210, 45dd2cfc)
Added:
docs/reference/solutions-index.md— three new columns (Patterns, Drivers, CoE) on the 35-solution table; same fields added to per-solution detail blocks; new "Discovering by CAPE alignment" intro section linking to framework documentsdocs/reference/pattern-coverage.md— regenerated with newSolutions countcolumn on the coverage summary and a new "Solutions per pattern" section listing all 84 pattern declarations across the 35 solutions
Modified:
scripts/generate_pattern_coverage.py— new--solutions-repoCLI flag (also honors$FSI_SOLUTIONS_REPOenv var) for parsing companion repo frontmatter via pyyaml; graceful skip when companion repo unavailable.github/workflows/python-quality.yml— new drift step clones companion repo and runsgenerate_pattern_coverage.py --checkto keeppattern-coverage.mdin sync with companion frontmatterCHANGELOG.md— this entry
Solutions count per pattern
| Pattern | Solutions |
|---|---|
| P1 — Employee AI Enablement | 14 |
| P2 — Business Expert Empowerment | 9 |
| P3 — Workplace & IT Services | 5 |
| P4 — Core Business Process Transformation | 25 |
| P5 — External Engagement | 19 |
| P6 — AI-First Capabilities | 12 |
| Total declarations | 84 |
Hard rules and brand boundary
- Tier-1 banlist enforced — "ensures compliance", "guarantees", "will prevent", "eliminates risk" remain banned across all docs (0 hits at release).
- No control IDs renamed, no manifest schema breaks.
controls.jsonunchanged from v1.5.0. - 78-control catalog unchanged. Pillar structure unchanged. Zone model unchanged.
- Companion repo as authoritative source — Pattern/Driver/CoE assignments live in companion repo READMEs; framework repo regenerates
pattern-coverage.mdfrom those tags via CI gate. Single source of truth.
Validation at release
| Gate | Result |
|---|---|
mkdocs build --strict |
0 warnings |
verify_language_rules.py |
0 banned phrases |
verify_controls.py |
78 controls pass |
check_manifest_doc_drift.py --check |
78=78=78 |
generate_coverage_matrix.py --check (controls + frontier) |
current |
generate_pattern_coverage.py --check (with companion repo) |
current (78 controls, 35 solutions) |
ruff check |
all pass |
pytest assessment/tests/ |
56 passed |
[1.5.0] — May 10, 2026 (Microsoft Alignment Release)
Release theme: FSI translation layer for Microsoft CAPE (Copilot Acceleration Engineering) materials. Adds vocabulary crosswalks, framework layer for CAPE concepts, assessment-engine support for CAPE Frontier Readiness scoring, and partner-facing reference docs (CSA + diagram catalog) — all as additive, non-breaking content.
Upgrade safety: No breaking changes. No schema breaks. No control IDs renamed. Safe to upgrade in place. Existing controls.json schema is backward-compatible (only field additions). Existing assessment runs continue to work; CAPE Frontier scoring is opt-in via new -AssessmentType parameter.
Phase 1 — Reference layer (#199, f3e8edc4)
Added:
docs/reference/microsoft-cape-crosswalk.md— bridge document mapping the 6 CAPE patterns to FSI controls and regulatory exposure per patterndocs/reference/cco-quick-reference.md— pocket lookup for compliance officers
Modified:
docs/framework/regulatory-framework.md— CAPE pattern annotationsdocs/reference/glossary.md— CAPE vocabulary additionsdocs/reference/role-catalog.md— expanded role entriesscripts/verify_language_rules.py— added Tier-2 banlist (CAPE vendor-marketing language) with<!-- verify-language-rules: allow-second-tier -->CSA annotation support
Phase 2 — Framework layer (#201, 429ab90c)
Added:
docs/framework/transformation-patterns.md— canonical 6-pattern framework summary with Pattern 6 D3 guardraildocs/framework/agentic-capability-drivers.md— Microsoft's 5 Capability Drivers and maturity modeldocs/framework/agentic-coe.md— standalone CoE blueprint with 4 functions (Govern/Enable/Optimize/Scale), CoE shapes, anti-patterns, and federation guardrail
Modified:
docs/framework/agent-lifecycle.md,governance-fundamentals.md,index.md,operating-model.md— CAPE concept integration and cross-referencesdocs/reference/microsoft-cape-crosswalk.md— Phase 2 additionsdocs/reference/role-catalog.md— CoE role additions
Phase 3 — Assessment integration (#202, 0adf51df)
Added:
assessment/manifest/frontier-readiness.json— 25 questions × 5 drivers × 5 maturity levelsassessment/engine/score_frontier.py— full Frontier Readiness scoring algorithmassessment/collectors/Collect-Frontier.ps1— interactive + batch collectorassessment/tests/test_score_frontier.py— 30 tests (56 total green at release)docs/reference/pattern-coverage.md— 78×6 generated control × pattern matrixdocs/reference/frontier-assessment-coverage.md— honest coverage report (0% auto v1; all Frontier scoring is manual-questionnaire-driven)scripts/generate_pattern_coverage.py— coverage matrix generator
Modified:
assessment/manifest/controls.json— 78 controls tagged withapplicable_drivers,applicable_patterns,pattern_critical(additive fields; backward-compatible)assessment/engine/report.py— added--type controls|frontier|bothflag with new report generatorsassessment/run-assessment.ps1— added-AssessmentTypeand-FrontierAnswersFileparametersassessment/README.md— decision tree, Frontier Quick Start, maturity scalescripts/generate_coverage_matrix.py— added--type controls|frontierflag
Phase 4 — Partner-facing reference (#203, 294ae358)
Added:
docs/reference/csa-quick-reference.md— Microsoft FSI CSA pocket lookup (197 lines)docs/reference/csa-positioning-guide.md— long-form CSA positioning narrative (390 lines)
Phase 5 — Diagrams + Release closeout (this release)
Added:
- 5 net-new Mermaid diagrams embedded in framework and reference docs: Pattern × Zone matrix, CoE structure by pattern, Decision rights framework, CAPE 90-day × FSI Phase timeline, Agent lifecycle 7-stage
docs/reference/diagram-catalog.md— catalog of all repo diagrams (60+ existing + 5 new) with audience, use-case, and format columnsdocs/images/diagrams/source/cape/*.mmd— editable Mermaid source files for CSA customer-deck exportCHANGELOG.md— this entry
Hard rules and brand boundary
This release adopts CAPE vocabulary as a translation layer, not as endorsement. FSI-AgentGov remains an independent FSI governance framework. Microsoft is not a publisher, sponsor, or reviewer of this content.
- Tier-1 banlist enforced — "ensures compliance", "guarantees", "will prevent", "eliminates risk" remain banned across all docs (0 hits at release).
- Tier-2 banlist (CAPE vendor-marketing language: "self-improving", "autonomous decision-making", etc.) is suspended only inside CSA-facing reference docs via the
<!-- verify-language-rules: allow-second-tier -->annotation, where CSAs need to teach customers to reframe the language. - Pattern 6 D3 guardrail and Federation guardrail appear verbatim in all partner-facing reference docs.
- No control IDs renamed, no manifest schema breaks.
controls.jsongained 3 additive fields (applicable_drivers,applicable_patterns,pattern_critical). - 78-control catalog unchanged. Pillar structure unchanged. Zone model unchanged.
Validation at release
| Gate | Result |
|---|---|
mkdocs build --strict |
0 warnings |
verify_language_rules.py |
0 banned phrases |
verify_controls.py |
78 controls pass |
check_manifest_doc_drift.py --check |
78=78=78 |
generate_coverage_matrix.py --check (controls + frontier) |
current |
generate_pattern_coverage.py --check |
current |
ruff check |
all pass |
pytest assessment/tests/ |
56 passed |
[1.4.2] — April 30, 2026 (Phase B′ Triage Fixes)
Patch release closing out the three P2 items deferred from v1.4.1. Markdown export customer header now escapes special characters so admin-entered names render correctly in raw source (#168); the vendored xlsx.full.min.js is marked binary in .gitattributes so Windows checkouts no longer flip its SRI hash via CRLF normalization (#169); and two locally-flaky Playwright specs (14-fetch-failure, 28-perf-budget) are hardened with deterministic ordering and a more realistic perf threshold (#170). Phase B″ triage report (#171) confirmed 0 P0/P1 findings — recommended ship. See CHANGELOG-v1.4.md for the full entry.
[1.4.1] — April 30, 2026 (E2E Test Infrastructure & SPA Hardening)
Quality + assurance release. No control catalog changes. Ships an end-to-end Playwright test suite (~60 specs across smoke, regression, edge cases, accessibility, and production probes), 4 new CI workflows (including SheetJS supply-chain SRI verification and post-deploy production smoke), branch protection as code, and 12+ assessment SPA hardening fixes covering saved-list integrity, storage quotas, formula-injection defenses, prototype-pollution guards, CSP allowlist enforcement, and per-assessment filter namespacing. See CHANGELOG-v1.4.md for the full entry.
[1.4.0] — April 2026 (Assessment Tool Unification & Solutions Bridge)
Added
- Unified manifest schema: Single source of truth (
assessment/manifest/controls.json) for Python scoring engine and assessment SPA with 11 additive fields per control - Solutions bridge: Cross-repository integration with FSI-AgentGov-Solutions v1.4.0 via committed
solutions-lock.json(35 solutions indexed) - 10 SPA enhancements: How-to-verify drawer (E1), zone auto-exclusion (E2), collector evidence import (E3), role filter (E4), sector calibration for 8 institution types (E5), priority starter set of 5 foundation controls (E6), Next Session Agenda export (E7), inline evidence/notes capture (E8), facilitator mode with hints and time budgets (E9), 7 per-role pre-session homework pages (E10)
- Harvest script:
scripts/harvest_manifest_extension.pyscaffolds v1.4 fields from existing control docs with TODO placeholders for author-judgment content - 3 validators: Manifest schema validator, solutions lock validator, and lock refresh script with tag pinning
- Portal export envelope (v1.4.1-prep, additive): SPA
exportJSONandexportRoleSectionnow emit a_metadatablock (framework version, export schema version, manifest commit hint, pillar names, schema type) plus_computedScores(pillar/overall percentages and counts) and a derivedassessmentStatusenum (draft/in-progress/final). Existing top-level state keys are preserved, so v1.3.x consumers continue to work unchanged. Importer silently drops snapshot fields and recomputes on next export. See CHANGELOG-v1.4.md andassessment/data/README.md.
Changed
- Control count normalization: Fixed stale "71 controls" / "72 controls" references to "78 controls" across all documentation
- Version bump: 1.3.3 → 1.4.0 across README, mkdocs.yml, CITATION.cff, and meta references
Breaking Changes
- Assessment SPA export schema: JSON export format incompatible with v1.3.x—no migration tool provided; recommend completing in-progress v1.3 assessments before upgrading or re-running from scratch with v1.4 collector import
| Version | Period | File |
|---|---|---|
| v1.6.x (current) | May 2026 | CHANGELOG.md |
| v1.5.x | May 2026 | CHANGELOG.md |
| v1.4.x | April 2026 | CHANGELOG-v1.4.md |
| v1.3.x | March–April 2026 | CHANGELOG-v1.3.md |
| v1.1.x | December 2025 | CHANGELOG-v1.1.md |
| v1.2.x and earlier | October 2025 – March 2026 | Archived — see git history prior to April 2026 |