Commit Graph

2 Commits

Author SHA1 Message Date
shankar0123 3c81531398 ci: OpenAPI parity reconciliation + codegen scaffolding (Phase 5 — ARCH-H1 / ARCH-M6)
Phase 5 reconciliation: the audit's headline framing 'ARCH-H1 = 62-route
OpenAPI gap' was a measurement scoping error. Every one of the 209
unique router routes is already accounted for — 154 in api/openapi.yaml,
55 in api/openapi-handler-exceptions.yaml. The existing
openapi-handler-parity.sh CI guard already enforces this and passes
clean today. The audit subtracted operation-count from route-count
without accounting for the documented exceptions YAML.

Where real work remains (and what this PR does about it)
=========================================================

Of the 64 documented exceptions, 35 are legitimate wire-protocol
carve-outs that MUST stay (SCEP RFC 8894 × 8 entries, ACME RFC 8555
default + per-profile × 27 entries — they're protocol contracts, not
REST resources). The remaining 29 are REST-shaped routes whose
OpenAPI ops were deferred during their original Bundle 2 /
audit-2026-05-10 / 2026-05-11 work:

  - auth/sessions (3)
  - auth/oidc admin (9)
  - auth/breakglass admin (4)
  - auth/users mgmt (3)
  - auth/runtime-config (1)
  - auth/demo-residual/cleanup (1)
  - audit/export (1)
  - auth/logout (1)
  - auth/breakglass/login (1)
  - auth/oidc {login,callback,bcl} (3)
  - oidc/providers/{id}/jwks-status (1)
  - + 2 other auth-flow routes

Burn-down plan in 3 sprints (documented in
api/openapi-handler-exceptions.yaml header):
  Sprint A: Cluster 1 — sessions + oidc admin (12 ops)
  Sprint B: Cluster 2 — breakglass + users + runtime-config (8 ops)
  Sprint C: Cluster 3 — audit/export + auth flows (9 ops)

This PR does NOT author the 29 OpenAPI ops; each needs request/
response schemas, not placeholders, and the design work is too
large for one PR. The reconciliation here is documentation + a CI
guard that will fail any future schema-drift, plus the scaffolding
needed for sub-phase 5b.

Sub-phase 5b: codegen scaffolding
==================================

Adds the orval scaffolding without running npm install (sandbox
disk-full; first 'npm install' + 'npm run generate' happens on the
operator's workstation):

  - web/orval.config.ts — codegen config emits react-query hooks
    from api/openapi.yaml into web/src/api/generated/
  - web/package.json — adds orval@^7.0.0 devDep + 'generate' npm script
  - web/CODEGEN.md — operator-facing migration doc:
    first-time setup, per-consumer migration pattern, burn-down plan,
    CI-guard rules
  - scripts/ci-guards/openapi-codegen-drift.sh — blocks the build
    when api/openapi.yaml changes but web/src/api/generated/ wasn't
    regenerated alongside. Currently no-op (the directory doesn't
    exist yet); activates from the first 'npm run generate' run.

The legacy web/src/api/client.ts stays in tree per the phase prompt's
'do not delete in same PR as codegen' rule. Consumers migrate one
page at a time as their OpenAPI ops land; client.ts deletion is a
SEPARATE follow-up PR after the last consumer migrates.

Updates to existing guard + exceptions YAML
============================================

  - scripts/ci-guards/openapi-handler-parity.sh header rewritten
    with the Phase 5 reconciliation numbers (220/158/64/0) and the
    wire-protocol vs REST-deferred classification.
  - api/openapi-handler-exceptions.yaml header rewritten with the
    35/29 split + the 3-sprint burn-down plan. Each exception entry
    is unchanged; the header now documents which entries are
    permanent (wire-protocol) vs temporary (REST-deferred).

Sandbox limitations + operator follow-up
=========================================

  - 'npm install' was NOT run from the sandbox (sessions volume
    99%-full, 142 MB free). The operator runs 'cd web && npm install'
    on their workstation; this lands orval@^7.0.0 in node_modules,
    then 'cd web && npm run generate' produces the initial
    web/src/api/generated/ tree.
  - First per-consumer migration (suggested: web/src/pages/AuthSettings
    or one of the operator-decision pages) lands in a follow-up PR
    after npm install completes.
  - The 29-op OpenAPI burn-down is a 2-sprint effort tracked under
    ARCH-H1 in cowork/certctl-architecture-diligence-audit.html.

All CI guards (openapi-handler-parity, openapi-codegen-drift, plus
every existing guard) verified clean by running each individually.

Closes:
  - cowork/certctl-architecture-diligence-audit.html#fix-ARCH-H1
    (reconciliation: gap is 0 with exceptions accounted for; burn-down
    plan documented for follow-up sprints)
  - cowork/certctl-architecture-diligence-audit.html#fix-ARCH-M6
    (codegen scaffolding shipped; client.ts deletion follows in a
    subsequent PR after consumers migrate)
2026-05-13 20:24:20 +00:00
shankar0123 b7a3162028 ci-pipeline-cleanup Phases 7-9: image-and-supply-chain job
Bundle: ci-pipeline-cleanup, Phases 7-9 / frozen decisions 0.8 + 0.10 + 0.11.

NEW image-and-supply-chain job (Ubuntu, ~3 min). Three steps:

PHASE 7 — Digest validity
scripts/ci-guards/digest-validity.sh resolves every @sha256:<digest>
ref in deploy/**/*.{yml,Dockerfile*} against its registry. Closes the
H-001 lying-field gap that Bundle II hit (11 fabricated digests passed
H-001's regex-only check and failed docker pull in CI).
Sandbox verification: 16/16 digests in deploy/* + Dockerfiles all
return HTTP 200 from registry-1.docker.io / ghcr.io / mcr.microsoft.com.

PHASE 8 — Docker build smoke (all 4 Dockerfiles)
Per frozen decision 0.10: build Dockerfile, Dockerfile.agent,
deploy/test/f5-mock-icontrol/Dockerfile, deploy/test/libest/Dockerfile.
Catches syntax errors + COPY path drift before tag-time release.yml.
The test-sidecar Dockerfiles are load-bearing for vendor-e2e — a
syntax error there silently breaks the e2e suite.

PHASE 9 — OpenAPI ↔ handler operationId parity
scripts/ci-guards/openapi-handler-parity.sh extracts router routes
(r.mux.Handle / r.Register "METHOD /path" syntax — Go 1.22+ ServeMux),
extracts OpenAPI operations (paths × HTTP methods), and fails if any
router route has no operationId AND is not documented in the new
api/openapi-handler-exceptions.yaml.

Verified gap at HEAD c48a82c4 (root-caused):
  142 router routes, 136 OpenAPI operations
  6 router-only routes — all SCEP wire-protocol endpoints (RFC-shaped,
    not REST). Documented in api/openapi-handler-exceptions.yaml with
    one-line why: justifications.
  0 OpenAPI-only operations.

Going forward: any new gap fails the build unless documented.

Status checks per push: now 7 (was 8 after Phase 5+6 dropped windows;
this Phase adds 1 = +1 net). Final acceptance gate target.

ci.yml: 383 → 432 lines (+49 for the new job + steps).
2026-04-30 20:50:52 +00:00