diff --git a/.github/workflows/hourly-nvidia-nim-review-repair.yml b/.github/workflows/hourly-nvidia-nim-review-repair.yml index cfd47e5c57..5cd0b096f6 100644 --- a/.github/workflows/hourly-nvidia-nim-review-repair.yml +++ b/.github/workflows/hourly-nvidia-nim-review-repair.yml @@ -1,5 +1,14 @@ -name: Hourly NVIDIA NIM Review Repair +name: Contextual Orchestrator Review Repair Quality CI +# Compatibility boundary: keep this historical file path so the existing GitHub +# Actions workflow registry identity is updated in place instead of leaving an +# orphaned enabled workflow ID. The display name and executable responsibility +# are authoritative: this is a read-only PR/push quality gate, not an hourly +# writer and not a direct NVIDIA NIM executor. +# +# Hourly execution is owned by the thin product callers and the reusable +# scheduler; write-capable repair is owned by pr-review-autofix.yml, whose model +# execution is routed through contextual-orchestrator/orchestrator/free. on: pull_request: paths: @@ -32,6 +41,9 @@ on: - tests/test_contextual_orchestrator_review_sidecar_contract.py - docs/doctoring/contextual-orchestrator-vendored-sidecar.md - docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md + - docs/doctoring/review-repair-quality-workflow-identity.md + - docs/product-technical-gap-baseline.md + - CHANGELOG.md - tests/test_bandscope_hourly_review_caller.py - tests/test_disksage_hourly_review_caller.py - tests/test_inkspan_hourly_review_caller.py @@ -106,6 +118,9 @@ on: - tests/test_contextual_orchestrator_review_sidecar_contract.py - docs/doctoring/contextual-orchestrator-vendored-sidecar.md - docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md + - docs/doctoring/review-repair-quality-workflow-identity.md + - docs/product-technical-gap-baseline.md + - CHANGELOG.md - tests/test_bandscope_hourly_review_caller.py - tests/test_disksage_hourly_review_caller.py - tests/test_inkspan_hourly_review_caller.py @@ -154,12 +169,12 @@ permissions: contents: read concurrency: - group: hourly-nvidia-nim-review-repair-${{ github.event.pull_request.number || github.ref }} + group: contextual-orchestrator-review-repair-quality-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true jobs: contract: - name: Hourly cadence, immutable source, NIM credential, and conflict scope + name: Scheduler, contextual-orchestrator, writer, and conflict-scope contracts runs-on: ubuntu-24.04 timeout-minutes: 20 steps: @@ -180,7 +195,7 @@ jobs: run: >- python -m pip install --disable-pip-version-check --require-hashes -r requirements-opencode-review-ci-hashes.txt - - name: Verify hourly scheduler and NVIDIA NIM autofix contracts + - name: Verify scheduler and contextual-orchestrator review-repair contracts run: | set -euo pipefail python -m pytest -q \ @@ -232,4 +247,4 @@ jobs: tests/test_pr_review_autofix_context_head_binding.py \ tests/test_pr_review_autofix_nvidia_nim_contract.py \ tests/test_pr_review_autofix_writer_security_contract.py - git diff --check + git diff --check \ No newline at end of file diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 885d2d0eac..8038c3632e 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -48,7 +48,7 @@ only established scheduler credentials, and grants job-scoped only established scheduler credentials, and grants job-scoped `id-token: write`. The reusable engine stays product-neutral. -## Hourly NVIDIA NIM repair gate +## Hourly contextual-orchestrator repair gate ```mermaid flowchart TD @@ -56,7 +56,7 @@ flowchart TD Sched["Central reusable scheduler"] Bind{"Exact-head, same-repo, writer authority, sealed paths?"} Worker["repository_dispatch worker at github.sha"] - NIM["NVIDIA NIM repair model"] + Gateway["contextual-orchestrator sidecar: orchestrator/free"] Recheck{"Post-edit exact-head revalidation?"} Push["Push same-repository head"] Hold["Leave the tree unchanged"] @@ -65,15 +65,17 @@ flowchart TD Sched --> Bind Bind -->|"no"| Hold Bind -->|"yes"| Worker - Worker --> NIM - NIM --> Recheck + Worker --> Gateway + Gateway --> Recheck Recheck -->|"no"| Hold Recheck -->|"yes"| Push ``` The worker checks out helpers at `${{ github.sha }}` so a later default-branch -push cannot replace privileged scripts after dispatch (CWE-367). Repair binds -`NVIDIA_NIM_API_KEY`, never `COPILOT_GITHUB_TOKEN`. +push cannot replace privileged scripts after dispatch (CWE-367). Repair provisions the vendored +contextual-orchestrator gateway sidecar (ADR-0003), which auto-discovers upstream models from five +KV-registered provider secrets including `NVIDIA_NIM_API_KEY`; it never binds one provider +directly, and never uses `COPILOT_GITHUB_TOKEN`. Product callers stagger Clearfolio at minute 23, DiskSage at minute 37, and fast-mlsirm at minute 49. Each caller is read-only, dispatches at most one @@ -109,7 +111,7 @@ sequenceDiagram participant MS as Merge scheduler PR->>RW: pull_request_target on trusted base - RW->>OC: bounded evidence + NVIDIA NIM / OpenCode + RW->>OC: bounded evidence + contextual-orchestrator/orchestrator/free / OpenCode OC->>SV: PoC command in isolated copy SV-->>OC: redacted stdout/stderr + command metadata OC-->>PR: APPROVE or request changes @@ -135,9 +137,15 @@ sequenceDiagram - Logs and review receipts redact credential shapes (tokens, bearer values, known provider prefixes). They do not mask operational PII that the control plane must process. -- LLM and scheduled agents bind `NVIDIA_NIM_API_KEY` (env may be - `NVIDIA_API_KEY`). They never use `COPILOT_GITHUB_TOKEN`. Existing - review-agent key schemes stay unchanged. +- Every LLM-bearing review and scheduled-repair workflow routes model traffic + through the vendored contextual-orchestrator gateway. OpenCode and Noema remain + independent read-only verdict controls with their existing credential mappings, + while the write-capable scheduled repair worker uses + `contextual-orchestrator/orchestrator/free`; sharing the gateway does not merge + their credentials, privileges, or verdict authority. The gateway discovers + eligible upstream routes from the credentials actually available to that + workflow instead of binding a provider directly. None of these paths uses + `COPILOT_GITHUB_TOKEN`. - Rust remains the psychometric arithmetic owner. Repair never substitutes Python for scoring math. - Downloaded SBOM and distribution bytes are inert. The signing job does diff --git a/docs/automation/hourly-review-repair.md b/docs/automation/hourly-review-repair.md index 7227249584..8994a0fc10 100644 --- a/docs/automation/hourly-review-repair.md +++ b/docs/automation/hourly-review-repair.md @@ -12,13 +12,19 @@ engine**. contextual-orchestrator, Inkspan, or another CWL service with an explicit repository and base branch. - `pr-review-autofix.yml` is the bounded write-capable worker. It uses OpenCode - with NVIDIA NIM and does not approve or merge pull requests. - -Orgmetra's caller remains provider-neutral. The intended model boundary is the -contextual-orchestrator gateway: provider keys stay in its KV registry and -automatic model discovery selects upstream models. A caller schedule is not -evidence that gateway credentials, discovery, or a live OpenCode tool loop are -available; those facts require exact worker-run evidence. + routed through the vendored contextual-orchestrator gateway and does not approve or merge pull + requests. + +Every product caller, Orgmetra included, is provider-neutral by construction: the worker's model +boundary is the contextual-orchestrator gateway (ADR-0003). Available provider credentials (Bytez, +NVIDIA NIM primary/sub, OpenRouter, and the separately governed OpenAI credential) stay in the +sidecar's process-local registry; discovery selects only routes eligible for the requested virtual +model policy. An individual provider credential may be absent without making the gateway invalid. +For scheduled repair, the fail-closed `contextual-orchestrator/orchestrator/free` path proceeds with +remaining eligible providers and fails only when required gateway configuration is unavailable or +discovery yields no eligible free-tier route. A caller schedule is not evidence that gateway +configuration, discovery, or a live OpenCode tool loop are available; those facts require exact +worker-run evidence. Merge eligibility remains owned by the separate merge scheduler, branch protection, required checks, independent review, and unresolved-thread policy. @@ -43,9 +49,10 @@ The scheduled heartbeat is `23 * * * *`. Repository-scoped concurrency and not overlap its successor. At most one repair dispatch is created per run. The caller passes only the established `PR_REVIEW_MERGE_TOKEN` and -`OPENCODE_APPROVE_TOKEN` scheduler credentials. It does not receive or forward -`NVIDIA_NIM_API_KEY`; the model credential is scoped exclusively to the two -OpenCode execution steps in the separately reviewed autofix worker. +`OPENCODE_APPROVE_TOKEN` scheduler credentials. It does not receive or forward any of the five +gateway provider secrets; those are scoped exclusively to the sidecar-provisioning step in the +separately reviewed autofix worker (see +[`docs/doctoring/hourly-nvidia-nim-autofix.md`](../doctoring/hourly-nvidia-nim-autofix.md)). ## Orgmetra execution contract @@ -199,7 +206,11 @@ organization-level queue inspection and bounded repair dispatch. When a scheduled run fails, classify the result before rerunning: - no actionable file-scoped feedback: expected no-op; -- missing `NVIDIA_NIM_API_KEY`: central secret configuration failure; +- missing required sidecar configuration (`CONTEXTUAL_ORCHESTRATOR_BASE_URL` or + `CONTEXTUAL_ORCHESTRATOR_TOKEN_FILE`): central gateway configuration failure; +- one or more individual provider credentials absent: continue discovery with + the credentials that are available; classify a model-admission failure only + if the requested policy has no eligible route after discovery; - head changed: safe optimistic-concurrency refusal; inspect the new head rather than retrying predecessor evidence; - out-of-scope or ignored-path change: treat as a security failure and preserve @@ -225,8 +236,9 @@ Permanent tests prove: - the dispatch budget and same-head retry floor remain one; - caller and reusable-workflow secrets are explicit and never use `secrets: inherit`; -- immutable source, NVIDIA-only model authentication, child-process credential - stripping, live-head guards, and independent reviewer identity remain intact; +- immutable source, gateway-only model authentication (never a directly bound provider key), + child-process credential stripping, live-head guards, and independent reviewer identity remain + intact; - ordinary and conflict repair share the complete ignored-inclusive snapshot and NUL-delimited allowlist boundary; - the RCA and remediation-feasibility gate prevents speculative or diff --git a/docs/doctoring/hourly-nvidia-nim-autofix.md b/docs/doctoring/hourly-nvidia-nim-autofix.md index 6b05c6bd60..2fdbaa2b68 100644 --- a/docs/doctoring/hourly-nvidia-nim-autofix.md +++ b/docs/doctoring/hourly-nvidia-nim-autofix.md @@ -1,12 +1,32 @@ # Hourly NVIDIA NIM Review-Autofix Boundary +## Status (2026-08-31 correction) + +This record's original "Provider contract" and "Credential boundary" sections described the +write-capable autofix worker binding NVIDIA NIM directly (`NVIDIA_API_KEY: ${{ +secrets.NVIDIA_NIM_API_KEY }}`, hard-coded model `mistralai/mistral-small-4-119b-2603`). That +architecture is superseded: per +[ADR-0003](../adr/0003-contextual-orchestrator-vendored-free-zdr.md) (accepted 2026-08-27, amended +2026-08-30) and the org's 2026-08-18 gateway decision, the worker now provisions the vendored +`contextual-orchestrator` review sidecar +(`scripts/ci/contextual_orchestrator_review_sidecar.sh`) and routes through the fail-closed +zero-cost virtual model id `contextual-orchestrator/orchestrator/free`, which auto-discovers +upstream models across all five KV-registered provider credentials rather than binding any one of +them directly. `NVIDIA_NIM_API_KEY` (and its `_SUB` sibling) is now one of five provider secrets +feeding that discovery, not a dedicated per-step model binding. The two sections below are +corrected to match the current `.github/workflows/pr-review-autofix.yml`, pinned by +`tests/test_pr_review_autofix_nvidia_nim_contract.py::test_scheduled_autofix_routes_through_contextual_orchestrator`. +Every other section of this record — write-scope snapshotting, the sealed allowlist, `.git` +denial, hook suppression, and the explicit push destination — is a provider-independent control +and remains current. + ## Decision Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include; a lone `--require-hashes` line is not lock evidence. -The write-capable scheduled pull-request autofix agent uses OpenCode with the -NVIDIA NIM API and the organization Actions secret `NVIDIA_NIM_API_KEY`. The -independent read-only review agent remains unchanged and continues to use its +The write-capable scheduled pull-request autofix agent uses OpenCode, routed through the vendored +`contextual-orchestrator` gateway (see "Status" above), rather than a directly bound provider +credential. The independent read-only review agent remains unchanged and continues to use its existing credential and model-pool contract. This separation is intentional. Review and repair have different privileges: @@ -60,21 +80,22 @@ open state, same-repository branch, base ref and SHA, and head ref and SHA. ## Provider contract -The pinned OpenCode runtime enables only `nvidia-nim` through the -OpenAI-compatible adapter and NVIDIA hosted endpoint: +The pinned OpenCode runtime enables only `contextual-orchestrator` through the +OpenAI-compatible adapter, pointed at the vendored sidecar's loopback gateway: ```text -https://integrate.api.nvidia.com/v1 +{env:CONTEXTUAL_ORCHESTRATOR_BASE_URL} ``` -The primary repair model is `mistralai/mistral-small-4-119b-2603`. The -`ci-autofix` agent and its model configuration both request high reasoning -through OpenCode's provider-option contract (`reasoningEffort: "high"`). NVIDIA's -Mistral Small 4 NIM API documents the corresponding request behavior as -`reasoning_effort: "high"`, which enables the model's reasoning mode. The small -model used for bounded helper work remains `nvidia/nemotron-3-nano-30b-a3b` and -is not a fallback provider. GitHub Models configuration, identifiers, base URLs, -and model-auth fallbacks are absent from the scheduled autofix execution path. +Both `model` and `small_model` request the fail-closed zero-cost virtual model id +`contextual-orchestrator/orchestrator/free`. The `ci-autofix` agent and its model configuration +both request high reasoning through OpenCode's provider-option contract +(`reasoningEffort: "high"`). The sidecar's own `discover_all_models()` auto-discovers upstream +models across all five KV-registered provider credentials (Bytez, NVIDIA NIM ×2, OpenRouter, +OpenAI) and ranks them free-first, cost-evidence-ranked, ZDR-prioritized (ADR-0003); the worker +never pins one hard-coded upstream model id directly, so no single upstream provider's outage can +take down scheduled repair. GitHub Models configuration, identifiers, base URLs, and model-auth +fallbacks remain absent from the scheduled autofix execution path. The high-reasoning setting is deliberate for write-capable review repair. This workflow optimizes correctness, evidence quality, and controllability rather than @@ -84,17 +105,23 @@ writer role and remains subject to exact-head regression evidence. ## Credential boundary -The organization secret is bound as: +The five organization provider secrets are bound only in the sidecar-provisioning step: ```yaml -NVIDIA_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }} +BYTEZ_API_KEY: ${{ secrets.BYTEZ_API_KEY }} +NVIDIA_NIM_API_KEY: ${{ secrets.NVIDIA_NIM_API_KEY }} +NVIDIA_NIM_API_KEY_SUB: ${{ secrets.NVIDIA_NIM_API_KEY_SUB }} +OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }} +OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} ``` -It is present only on the two steps that execute OpenCode: ordinary -review-feedback repair and merge-conflict repair. Metadata collection, -checkout, context preparation, validation, commit, and push do not receive the -NVIDIA credential. A missing key is a fatal configuration error rather than a -signal to choose another provider. +None of the five appear anywhere in the workflow after that step. The sidecar registers them into +its own process-local KV and exposes only a loopback gateway URL and a short-lived bearer token +(`CONTEXTUAL_ORCHESTRATOR_BASE_URL`, `CONTEXTUAL_ORCHESTRATOR_TOKEN_FILE`) to the two steps that +execute OpenCode: ordinary review-feedback repair and merge-conflict repair. Metadata collection, +checkout, context preparation, validation, commit, and push do not receive any of the five provider +secrets or the gateway token. A missing gateway environment variable is a fatal configuration error +rather than a signal to choose another provider. The ordinary model execution step does not bind a GitHub write token. Its later commit-and-push step may mutate only with `PR_REVIEW_MERGE_TOKEN`, @@ -113,11 +140,11 @@ env -u GITHUB_TOKEN -u GH_TOKEN \ -u ACTIONS_ID_TOKEN_REQUEST_TOKEN -u ACTIONS_ID_TOKEN_REQUEST_URL ``` -The child receives the NVIDIA model credential and non-secret execution -controls, but cannot call GitHub APIs or mint an Actions OIDC token. GitHub -credentials remain available only to reviewed shell logic before or after the -child process. The key is never written to repository files, generated prompts, -command arguments, or ordinary logs. +The child receives the gateway URL/token and non-secret execution controls, but cannot call GitHub +APIs or mint an Actions OIDC token, and never receives any of the five upstream provider secrets +directly. GitHub credentials remain available only to reviewed shell logic before or after the +child process. No provider key is ever written to repository files, generated prompts, command +arguments, or ordinary logs. ## OpenCode repair sandbox @@ -276,9 +303,11 @@ quality, security, review, and protection gate again. Automated tests prove: 1. the caller retains its approved one-hour cadence; -2. OpenCode enables only NVIDIA NIM, uses the exact Mistral Small 4 writer with - high reasoning, and receives the model key only in its two execution steps; -3. missing model credentials fail closed and model children receive no GitHub or +2. OpenCode enables only `contextual-orchestrator`, routes through the + `contextual-orchestrator/orchestrator/free` virtual model id with high reasoning, and the + sidecar's five provider secrets never appear outside the sidecar-provisioning step (see + "Status" above); +3. missing gateway configuration fails closed and model children receive no GitHub or OIDC write credential; 4. mutation-capable ordinary and conflict paths accept only established explicit secrets or the exchanged OpenCode app token, never `github.token`, and fail @@ -303,7 +332,7 @@ Automated tests prove: ## Scheduling and activation -The NVIDIA worker does not create a second repair scheduler. It is consumed by +The gateway-routed worker does not create a second repair scheduler. It is consumed by the hourly central review-fix scheduler and product caller. Scheduled workflows run only from the protected default branch, so feature-branch checks do not make the heartbeat active. Activation requires protected integration and accepted-main @@ -311,18 +340,20 @@ verification. ## Rollback -Rollback must revert the NVIDIA transport, ordinary and conflict repair scope -contracts, review-derived control-plane path exclusion, `.git` denial, ignored-path -inventory, hook suppression, explicit push destination, tests, operator guidance, +Rollback must revert the gateway transport (`contextual_orchestrator_review_sidecar.sh` +provisioning and the `contextual-orchestrator/orchestrator/free` model binding), ordinary and +conflict repair scope contracts, review-derived control-plane path exclusion, `.git` denial, +ignored-path inventory, hook suppression, explicit push destination, tests, operator guidance, doctoring, and changelog as one reviewed change. A partial rollback that restores review-thread authority over `.github/` or `scripts/ci/`, ordinary diff-only validation, model-mutable Git metadata, repository hooks, GitHub-token model authentication, or a mutable helper checkout is unsafe. -If NVIDIA NIM is unavailable, scheduled repair must fail closed while read-only -review, required checks, manual maintenance, and protected merge policy remain -available. Rollback is not permission to bypass independent approval or release -gates. +If the contextual-orchestrator gateway sidecar cannot be provisioned (missing +`CONTEXTUAL_ORCHESTRATOR_BASE_URL`/`CONTEXTUAL_ORCHESTRATOR_TOKEN_FILE`, or discovery finds zero +eligible free-tier routes across all five provider credentials), scheduled repair must fail closed +while read-only review, required checks, manual maintenance, and protected merge policy remain +available. Rollback is not permission to bypass independent approval or release gates. ## References @@ -342,17 +373,6 @@ https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-a GitHub, Inc. (n.d.-b). *Secrets reference*. GitHub Docs. Retrieved August 7, 2026, from https://docs.github.com/en/actions/reference/security/secrets -NVIDIA Corporation. (n.d.-a). *LLM APIs*. NVIDIA API Catalog. Retrieved August -7, 2026, from https://docs.api.nvidia.com/nim/reference/llm-apis - -NVIDIA Corporation. (2026). *Query the Mistral-Small-4-119B-2603 API*. NVIDIA -NIM for Vision Language Models. Retrieved August 8, 2026, from -https://docs.nvidia.com/nim/vision-language-models/1.7.0/examples/mistral-small-4-119b-2603/api.html - -NVIDIA Corporation. (n.d.-c). *NVIDIA / nemotron-3-nano-30b-a3b*. NVIDIA API -Catalog. Retrieved August 7, 2026, from -https://docs.api.nvidia.com/nim/re/reference/nvidia-nemotron-3-nano-30b-a3b - OpenCode. (2026a). *Permissions*. https://opencode.ai/docs/permissions OpenCode. (2026b, July 28). *Providers*. https://opencode.ai/docs/providers diff --git a/docs/doctoring/review-repair-quality-workflow-identity.md b/docs/doctoring/review-repair-quality-workflow-identity.md new file mode 100644 index 0000000000..2fe4b01ac9 --- /dev/null +++ b/docs/doctoring/review-repair-quality-workflow-identity.md @@ -0,0 +1,78 @@ +# Review-repair quality workflow identity RCA + +## Status + +Recorded 2026-09-01 against protected `ContextualWisdomLab/.github` `main@b4f7b082536d2be8dceab0a40a484161b50e5acd` and repair PR #1573. + +## Incident + +The central workflow at `.github/workflows/hourly-nvidia-nim-review-repair.yml` was named **Hourly NVIDIA NIM Review Repair**, but the executable source contradicted both halves of that identity: + +- it had no `schedule` trigger and therefore did not own an hourly writer cadence; +- it had read-only `contents: read` permission and executed only repository contract tests, coverage, docstring checks, `compileall`, and `git diff --check`; +- it did not invoke OpenCode or any model provider; +- the write-capable repair boundary already lived in `.github/workflows/pr-review-autofix.yml` and routed OpenCode through the vendored contextual-orchestrator sidecar with the virtual model `contextual-orchestrator/orchestrator/free`. + +The stale identity survived the earlier direct-NIM-to-gateway migration because executable worker routing and the focused quality gate evolved independently. Draft PR #1527 corrected prose only and explicitly left workflow behavior and identity unchanged, so it could not close this control-plane naming/responsibility gap. + +## Root cause + +The repository conflated three separate responsibilities under one historical label: + +1. **Cadence ownership** — thin product-specific `*-hourly-review-repair.yml` callers own schedules. +2. **Repair execution** — `pr-review-fix-scheduler.yml` selects bounded work and `pr-review-autofix.yml` owns the write-capable exact-head repair worker. +3. **Contract verification** — `.github/workflows/hourly-nvidia-nim-review-repair.yml` is a PR/push-only read-only quality gate. + +When direct NVIDIA NIM execution was retired in favor of ADR-0003's contextual-orchestrator gateway, responsibility (2) was migrated but responsibility (3)'s display identity and explanatory contract were not. The result was executable metadata that suggested a scheduled direct-provider writer where none existed. + +A second lifecycle defect became visible during repair. GitHub retains workflow registry identities after YAML paths disappear; this repository already tracks that control-plane fact in #1026. Creating a replacement workflow path and deleting the historical path would therefore create a new workflow ID while risking an orphaned old ID. That is not a safe rename. + +## Repair + +PR #1573 keeps the historical path `.github/workflows/hourly-nvidia-nim-review-repair.yml` as a **registry-identity compatibility boundary** while changing the workflow itself to the truthful display name **Contextual Orchestrator Review Repair Quality CI**. The workflow remains PR/push-only and `contents: read`; no hourly schedule or second writer is added. + +The path is deliberately not customer or architecture terminology. The display name, comments, job name, tests, and doctoring carry the current responsibility. No replacement `.github/workflows/contextual-orchestrator-review-repair-quality.yml` remains in the final tree. + +The underlying writer remains unchanged: + +```text +hourly product caller + -> pr-review-fix-scheduler.yml + -> repository_dispatch: pr-review-autofix + -> pr-review-autofix.yml + -> contextual-orchestrator sidecar + -> contextual-orchestrator/orchestrator/free +``` + +The sidecar continues to register the existing five provider credentials (`BYTEZ_API_KEY`, `NVIDIA_NIM_API_KEY`, `NVIDIA_NIM_API_KEY_SUB`, `OPENROUTER_API_KEY`, `OPENAI_API_KEY`) into its process-local provider registry. Provider keys are not promoted to workflow identity and no direct-provider fallback is introduced. + +## TDD and hosted evidence + +The first PR commit, `6279b0c8fe7f41f2ec61be728da41d9c2c599e84`, changed `tests/test_hourly_scheduler_runtime_budget.py` before implementation and rejected the old display identity. Its initial hypothesis also required a new path. That source-level RED correctly exposed the identity defect, but the later workflow-lifecycle inspection showed that deleting the old path would violate the repository's own orphan-workflow governance boundary. The test was refined rather than preserving an unsafe implementation hypothesis: it now requires the stable historical path, forbids a replacement path, and requires the contextual-orchestrator display/worker contract. + +An intermediate replacement-path implementation produced hosted run `33491072818`. The workflow itself materialized and executed 2,253 passing tests with 100% reported production coverage, but one existing fake-dispatch fixture failed with bash exit 141/SIGPIPE because the fake `gh` process did not drain `--input -`. That is independent of the workflow identity repair. PR #1573 incorporates the exact one-line fixture root repair from closed #1561 (`cat >/dev/null`) while leaving production dispatch behavior unchanged. + +All intermediate replacement-path runs are predecessor evidence only. Final acceptance requires exact-current-head execution through the preserved workflow registry identity and terminal success; queued, pending, skipped, cancelled, or predecessor evidence is non-passing. + +## Security and governance boundary + +- No secret, reviewer identity, merge authority, branch-protection rule, or status is changed. +- No direct NVIDIA NIM HTTP endpoint or hard-coded provider model is introduced. +- The quality workflow remains `contents: read` only. +- The write-capable worker remains exact-head-bound and governed by its existing sealed path, revalidation, credential stripping, and protected push contracts. +- The stable workflow path avoids manufacturing an untracked orphan Actions identity. +- Queued, pending, skipped, cancelled, predecessor-head, or stale evidence is not treated as passing. + +## Rollback + +Rollback is a normal revert of the display/contract correction only after proving that doing so does not reintroduce misleading provider/cadence ownership. Do not delete/recreate the workflow path merely to rename it, restore a direct-NIM execution path, add a duplicate hourly schedule, or weaken the contextual-orchestrator fail-closed contract. + +## References + +ContextualWisdomLab. (2026). *ADR-0003: Contextual-orchestrator vendored free/ZDR review routing*. `docs/adr/0003-contextual-orchestrator-vendored-free-zdr.md`. + +ContextualWisdomLab. (2026). *Inventory orphaned workflow identities* (Issue/PR #1026). GitHub repository governance evidence. + +GitHub. (n.d.). *Workflow syntax for GitHub Actions*. GitHub Docs. https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions + +GitHub. (n.d.). *Events that trigger workflows*. GitHub Docs. https://docs.github.com/actions/using-workflows/events-that-trigger-workflows \ No newline at end of file diff --git a/tests/test_hourly_scheduler_runtime_budget.py b/tests/test_hourly_scheduler_runtime_budget.py index 02b4fa05b2..bf24b15183 100644 --- a/tests/test_hourly_scheduler_runtime_budget.py +++ b/tests/test_hourly_scheduler_runtime_budget.py @@ -7,6 +7,9 @@ CLEARFOLIO = Path(".github/workflows/clearfolio-hourly-review-repair.yml") DISKSAGE = Path(".github/workflows/disksage-hourly-review-repair.yml") QUALITY = Path(".github/workflows/hourly-nvidia-nim-review-repair.yml") +REPLACEMENT_QUALITY = Path( + ".github/workflows/contextual-orchestrator-review-repair-quality.yml" +) def _read(path: Path) -> str: @@ -45,3 +48,19 @@ def test_quality_gate_tracks_runtime_budget_contract() -> None: quality = _read(QUALITY) assert quality.count("tests/test_hourly_scheduler_runtime_budget.py") == 3 + + +def test_review_repair_quality_workflow_has_truthful_identity() -> None: + """Keep the stable workflow ID while retiring its direct-NIM identity.""" + assert QUALITY.is_file() + assert not REPLACEMENT_QUALITY.exists() + + quality = _read(QUALITY) + assert quality.startswith("name: Contextual Orchestrator Review Repair Quality CI\n") + assert "schedule:" not in quality + assert "name: Hourly NVIDIA NIM Review Repair" not in quality + assert "Hourly cadence, immutable source, NIM credential, and conflict scope" not in quality + assert "registry identity is updated in place" in quality + assert ".github/workflows/pr-review-autofix.yml" in quality + assert "contextual-orchestrator/orchestrator/free" in quality + assert "tests/test_pr_review_autofix_nvidia_nim_contract.py" in quality