SnowOps — Gap Register
Identified gaps in the original plan and their resolutions.
| # | Gap | Impact | Resolution | Closed In |
|---|---|---|---|---|
| G1 | No brownfield / terraform import strategy — all F-modules were greenfield-only |
Blocks Day-30/90 clients; modules only useful for new environments | F12 brownfield import library; F-modules must ship with import blocks; Brownfield-Safe principle added to §2 | M3 |
| G2 | CI/CD is 100% GitHub Actions — no Azure DevOps path | Blocks enterprise Azure-centric clients running ADO | C5 (ADO Pipelines equivalent of C1); M2 scoped as "GitHub Actions only" with explicit constraint | M3 |
| G3 | F0 contracts unbuilt but F1–F6 already shipped — modules don't implement the cloud-agnostic interface | Violates "Cloud-Agnostic by Construction" principle; AWS parity impossible without contracts | F0 sequenced as first item in M2a; F1+F6 tech debt tracked; no new F-module before F0 | M2a |
| G4 | No module versioning or client upgrade path | Every patch requires manual coordination; no way to pin a module version | F11 (module versioning + private registry); semver per module; consumer pin strategy | M3 |
| G5 | No maturity-tiered entry points — both packages assume greenfield | Day-30/90 clients forced into full engagement even when they only need 3 assets | Maturity entry point table in §3.6; Quick-Win [QW] tier; D-series and C-series explicitly portable onto existing repos |
M1 (QW) / M3 (brownfield) |
| G6 | K8s / AKS assumption baked into Baseline — no path for Container Apps / App Service clients | Non-K8s clients can't adopt D4/F3/F8 and have no container security layer | D4/F3/F8 scoped as "AKS clients" with explicit note; non-K8s clients get I1 (image scanning) + F4 (ACR) as container security baseline | M2a |
| G7 | Evidence collection is entirely Advanced-tier — Baseline clients get zero automated evidence | Baseline clients can't satisfy a single auditor question with machine-generated evidence | E0 (lightweight compliance snapshot) created as new Baseline-tier asset; emitted on every C1 apply | M2b |
| G8 | Ticketing is hardcoded (Linear/Jira) across E6, I5, K4, P3 | Different implementation for every client ticketing platform | E7 TicketPlatform interface + adapters (Jira, GitHub Issues, Linear, Azure DevOps Boards); E6/I5/K4/P3 updated to use E7 |
M3 |
| G9 | V2 (architecture diagrams) and V3 (runbook generator) are Advanced-only | Baseline clients receive no documentation of what was built for them | V2 and V3 promoted to Baseline [B]; assigned to M2b |
M2b |
| G10 | No "SnowOps-operated" vs "client-owned" distinction — unclear what happens to client infra if engagement ends | Client adoption and offboarding unclear; hidden dependency on SnowOps repo | Ownership taxonomy added (§3.7): [SO/CO/CA/SH] tags on every asset; docs/client-guides/ with handover guides per milestone |
M1 (taxonomy); ongoing per asset |
| G11 | G (discovery) findings not linked to F (remediation modules) | Discovery report creates urgency but no clear remediation path | G2 rule pack extended to include remediation_asset_id per finding; G3 roadmap links to specific §4 catalog entries |
M1 |
| G12 | No waiver/exception mechanism for OPA policy rules | D3 blocks every brownfield adoption at first terraform plan; no incremental migration path |
D5 (policy waiver engine): time-boxed exceptions with PR-linked audit trail and CI expiry enforcement | M2b |
| G13 | AWS-first prospects can't use the discovery tool (G) | Free audit offer doesn't work for ~30–40% of ICP | G7 (AWS discovery mode); M1/M2/M3 scoped as Azure-only with explicit constraint; G7 in M4 | M4 |
| G14 | No client self-service capability — all onboarding requires SnowOps to run it | Slows engagement start; clients can't self-validate prerequisites | B6 (self-service bootstrap script); clients run it pre-engagement to validate permissions and prerequisites | M3 |
Gaps — Identified in v0.55 Repo Review (2026-06-04)
Surfaced by a full-repo review. G15–G17, G19, G20 closed in the same pass; G18 seeded (see Status column).
| # | Gap | Impact | Resolution | Status |
|---|---|---|---|---|
| G15 | B1 automated test failed. apps/github-onboarder/src/load-template.test.ts asserted an exact file list for templates/client-repo/.github/workflows/, but 3 workflows were added since (aks-deploy.yml, container-build-sign.yml, sp-inventory-rotation.yml). B1 is marked code_complete. |
Violated DoD #2 (automated test passes). A "code-complete" asset had a red test. | Test rewritten to compute the expected tree from an independent on-disk walk + assert anchor files; resilient to future template additions. 38/38 pass. | ✅ Closed (v0.55 review) |
| G16 | No CI gate ran apps/* unit tests on PR. Per-app deploy workflows existed, but nothing ran npm test across all apps; github-onboarder (B1) had no workflow at all. |
Regressions landed silently — G15 went unnoticed; DoD #2 unverifiable in CI. | Added .github/workflows/app-tests.yml — dynamically discovers every apps/* with a test script (scaffolds auto-skipped), runs npm ci + typecheck --if-present + npm test in a matrix on PRs touching apps/**. |
✅ Closed (v0.55 review) |
| G17 | CLAUDE.md §2 repo layout was stale. Missing: apps/github-onboarder/ (B1), apps/cost-cleanup/ (U3), apps/soar-playbooks/ (K3), modules/aws/, modules/gcp/, trust-center/, waivers/, docs/adr/, docs/packages/, policy/azure-policy/, policy/checkov/, tests/pipeline-integration/. |
Index unreliable; B1's real implementation was invisible in the layout. | §2 refreshed with all missing dirs. | ✅ Closed (v0.55 review) |
| G18 | Zero ADRs despite 50 logged decisions. docs/adr/ was .gitkeep only, but DoD #5 and §3 PR conventions both require "ADR if architectural". |
Architectural rationale not captured per the repo's own convention. | Seeded docs/adr/: README (convention + index), 0000-template.md, and ADRs 0001 (cloud-agnostic contracts), 0002 (Kyverno), 0003 (OIDC federation), 0004 (TF state on Blob). Remaining: backfill ADRs for other architectural D-rows as they're touched. |
🟧 Seeded; ongoing |
| G19 | F7 live/ "failed" its own format gate. live/validate.sh reported unformatted HCL, yet F7 is code_complete. Root cause: the script used deprecated terragrunt hclfmt/--terragrunt-* flags that current terragrunt rejects — a false positive. HCL was already clean. |
A code-complete asset appeared to ship unformatted HCL on every validate run. | validate.sh updated to the modern terragrunt hcl fmt --check (with legacy fallback) and promoted from a warning to a hard failure. Now passes. |
✅ Closed (v0.55 review) |
| G20 | U3 (apps/cost-cleanup/) and K3 (apps/soar-playbooks/) are README-only scaffolds whose READMEs described asset behavior as if present, while both are postponed. |
Implied a capability that does not exist. | Both READMEs now carry a "⚠️ SCAFFOLD — postponed (not yet implemented)" banner; layout (§2) tags them as scaffolds too. | ✅ Closed (v0.55 review) |