LLM Control Plane: Phase 0 (remediation merge) + Phase 1 (kernel)#16
LLM Control Plane: Phase 0 (remediation merge) + Phase 1 (kernel)#16cryptoxdog wants to merge 10 commits into
Conversation
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
…le 1) PR #16's CI run surfaced 5-6 pre-existing failing governance workflows, confirmed (via `gh run list --branch main`) to already be failing on main since they were imported in PR #3 — unrelated to this PR's own diff, but blocking this PR's checks, so fixed here as part of the remediation loop. Root cause 1 (9 files): every `uses: Quantum-L9/l9-ci-core/.github/ workflows/*.yml@v1` reference targets a tag that does not exist in that repo — `gh api repos/Quantum-L9/l9-ci-core/tags` shows only `v0.1.0` is published. Re-pinned all 9 refs to `@v0.1.0`; verified each target workflow file exists at that tag via the GitHub API before committing. Root cause 2 (l9-node-ts-monorepo.yml, self-contained, no external repo involved): `install-and-typecheck` ran `npm run typecheck`, but package.json only defines `verify:types` — fixed to call the real script name. `test-by-segment` ran `npx jest --testPathPattern=...` across a non-existent unit/integration split, but this package has no Jest dependency and uses Vitest exclusively with a flat tests/ directory — replaced with a single `test` job running `npm test`. Known deferred item (not fixed, documented instead): `L9 Analysis` (.github/workflows/l9-analysis.yml) pins l9-ci-core to a direct commit SHA (not a tag) and still fails — captured logs show the failure is `ModuleNotFoundError: No module named 'yaml'` inside l9-ci-core's own `provision-sdk` action (missing `pyyaml` in that action's pip install step). This is a defect in the external Quantum-L9/l9-ci-core / l9-ci-sdk repositories, not in any file this repo owns — no local fix is possible; recommend filing against Quantum-L9/l9-ci-core. Local verify (blocking gate, re-run after these changes): build, verify:types, lint (0 errors), test (137/137), npm audit --audit-level=high --omit=dev (0 vulnerabilities) — all green. YAML syntax of every edited workflow validated with python3 -c "yaml.safe_load(...)". Co-authored-by: Cursor <cursoragent@cursor.com>
l9-ci-core's security.yml@v0.1.0 reusable workflow does not declare a run-npm-audit input (only python-version, source-dir, l9-ci-install-command). Passing it caused a workflow-call input validation startup_failure in both l9-security.yml and the embedded security job in l9-node-ts-monorepo.yml. npm audit already runs separately in ci.yml. Co-authored-by: Cursor <cursoragent@cursor.com>
#16 cycle 3) GitHub Actions rejects a reusable-workflow call at startup (0 jobs, opaque "workflow file issue" / startup_failure) when a called job's declared `permissions:` exceed what the caller grants. l9-ci-core's security.yml, scorecard.yml, and pr-pipeline.yml's internal security/sbom/scorecard jobs request security-events:write, id-token:write, and/or pull-requests:read, but none of our wrapper workflows declared elevated permissions (repo default is read-only), so every call to them failed at resolution time before any job ran. Also drop `src-directory` from l9-governance.yml: trio-governance.yml@ v0.1.0 does not declare that input (only python-version, changed-files, policy-path, baseline-path, classifier-path, the three trio token secret-name inputs, pr-labels, labels-known), so passing it caused the same class of startup_failure independent of the permissions issue. Fixed: - l9-security.yml: add job-level permissions (contents:read, security-events:write, pull-requests:read) - l9-scorecard.yml: add job-level permissions (security-events:write, id-token:write, contents:read, actions:read) - l9-node-ts-monorepo.yml: same permissions on its embedded security/scorecard jobs - l9-pr-pipeline.yml: add job-level permissions (contents:read, security-events:write, pull-requests:read, id-token:write) and remove undeclared run-security/working-directory inputs - l9-governance.yml: remove undeclared src-directory input Not fixed (documented as out of scope for this PR, tracked separately): l9-pr-pipeline.yml, l9-governance.yml, and l9-pre-commit.yml still require Python-only governance infrastructure that does not exist in this Node/TypeScript repo (.github/governance/ quality-thresholds.yaml, rule-modes.yaml, audit-policy.yml, audit-baseline.json, a Python classifier script, a .pre-commit-config.yaml, and the closed-source `l9-ci` pip package). Creating that infra is a repo-governance decision, not a Control Plane PR concern. Co-authored-by: Cursor <cursoragent@cursor.com>
…cycle 4) pr-pipeline.yml@v0.1.0's embedded scorecard job requires security-events:write, id-token:write, contents:read, AND actions:read. Cycle 3 granted the first three but missed actions:read, so the call still failed at startup (0 jobs) even after the other permission fixes. Co-authored-by: Cursor <cursoragent@cursor.com>
…le 5)
SonarCloud's PR analysis failed the Security Rating and Reliability
Rating gates (both required >= A) on two real findings introduced by
this branch's CI-workflow edits and Phase 1 code:
- .github/workflows/{l9-security,l9-scorecard,l9-node-ts-monorepo,
l9-pr-pipeline}.yml: pin the Quantum-L9/l9-ci-core reusable-workflow
reference to its resolved commit SHA instead of the floating v0.1.0
tag (supply-chain integrity — a moved/deleted tag can silently swap
in different code). Applied the same pin to the remaining l9-ci-core
callers (l9-governance, l9-nightly, l9-pre-commit, l9-release,
l9-sbom) for consistency, even though Sonar did not flag those files
as changed in this diff.
- src/control-plane/hashing.ts: canonicalize()'s Object.keys(...).sort()
relied on the default sort comparator. Sonar's suggested fix
(String.localeCompare) would make key ordering — and therefore the
content hash — depend on runtime locale/ICU data, which breaks the
cross-machine determinism this module exists to guarantee. Used an
explicit ordinal comparator instead and documented why
localeCompare is deliberately not used here.
Verified: npm run verify:types, npm run lint (0 errors), npm test
(137/137 passing) all still green after this change.
Co-authored-by: Cursor <cursoragent@cursor.com>
CI Remediation Summary (l9-PR-remediation)Ran 5 fix/verify cycles against this PR's CI. Result: every Fixed (in scope, verified green)
Verified locally after every change:
Not fixable from this repo (confirmed external root causes — no code change here can resolve these)
All five clusters trace back to the same family of issue: Fixing these for real requires either (a) publishing the |
4337c23 to
20f35bb
Compare
3b8de4e to
cf27fb6
Compare
Transplanted-From: 1091f6b (remediation pack 2026-07-20)
Transplanted-From: 5c935b2 (remediation pack 2026-07-20)
Transplanted-From: 7653e0e (remediation pack 2026-07-20)
Transplanted-From: 146cccc (remediation pack 2026-07-20)
Transplanted-From: 9e977b5 (remediation pack 2026-07-20)
Transplanted-From: b358108 (remediation pack 2026-07-20)
Transplanted-From: a5665db (remediation pack 2026-07-20)
Transplanted-From: 5bf7793 (remediation pack 2026-07-20)
Transplanted-From: 16d5458 (remediation pack 2026-07-20)
Transplanted-From: 0513d3b (remediation pack 2026-07-20)
cf27fb6 to
96de61a
Compare
|


Summary
Executes the first two steps of the 7-phase LLM Control Plane build plan:
fix/unified-remediation-phases-1-7(18 closed audit findings: family-safe model downgrade, circuit breaker, Zod validation, pricing table, error-redaction, router-only-egress lint rule) into this branch as the baseline for the Control Plane build. Resolved 6 conflicts (eslint.config.js,package.json,src/index.ts,src/types.ts,tests/budget.test.ts,tests/router.test.ts) — all mechanical/cosmetic, no semantic disputes.src/control-plane/—TaskProfile,LLMRoutePlan,LLMExecutionRecord,LLMFeedbackSignalschemas (all SHA-256 content-hashed),PolicyEngine/LLMProviderAdapterinterfaces (no implementation — later phases), and deterministic builder functions for each schema.Architectural decision (documented in
docs/control-plane-architecture.md): the new kernel lives undersrc/control-plane/and is reachable only via a new./control-planepackage.json subpath export. It is not wired intosrc/index.ts— the legacyL9LLMRouterremains the package's default public API. The plan's own Phase 8 is the explicit cutover step; wiring the two together now would pre-empt that decision mid-build.What is NOT included in this PR
Phases 2-8 of the build plan are not built:
L9LLMRoutercutoverEach remaining phase is its own ~10-file nuclear contract (schemas + interfaces + implementation + 10 tests + config + docs) — out of scope for a single autonomous pass. This PR intentionally stops at a clean, fully-validated checkpoint (Phase 0 + Phase 1) rather than partially building later phases.
Test plan
All commands run locally against this branch, output captured in
src/control-plane/validation-results.md:npm cinpm run build— exit 0npm run verify:types— exit 0npm run lint— 0 errors, 2 pre-existing warnings (unrelatedas anycasts insrc/index.ts, predate this PR)npm test— 137/137 passing across 21 files (120 pre-existing + 17 newtests/control-plane/*, covering all 10 Phase 1 contract-required assertions)npm audit --audit-level=high --omit=dev— 0 vulnerabilitiesMade with Cursor