Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Contextual Orchestrator Hourly Review Repair

on:
schedule:
# Minute 17 avoids Clearfolio (23), DiskSage (37), and fast-mlsirm (49).
- cron: "17 * * * *"

concurrency:
group: contextual-orchestrator-hourly-review-repair
# A later heartbeat must not cancel an in-flight queue decision or repair.
cancel-in-progress: false

permissions:
contents: read

jobs:
dispatch-review-repair:
permissions:
contents: read
uses: ./.github/workflows/pr-review-fix-scheduler.yml
with:
target_repository: ContextualWisdomLab/contextual-orchestrator
base_branch: main
max_prs: "50"
max_dispatches: "1"
retry_hours: "1"
secrets:
PR_REVIEW_MERGE_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }}
OPENCODE_APPROVE_TOKEN: ${{ secrets.OPENCODE_APPROVE_TOKEN }}
7 changes: 7 additions & 0 deletions .github/workflows/hourly-nvidia-nim-review-repair.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
- .github/workflows/fast-mlsirm-hourly-review-repair.yml
- .github/workflows/github-hourly-review-repair.yml
- .github/workflows/governance-risk-compliance-hourly-review-repair.yml
- .github/workflows/contextual-orchestrator-hourly-review-repair.yml
- .github/workflows/hourly-nvidia-nim-review-repair.yml
- .github/workflows/nonnest2-hourly-review-repair.yml
- .github/workflows/originweave-hourly-review-repair.yml
Expand All @@ -23,6 +24,7 @@ on:
- tests/test_fast_mlsirm_hourly_review_caller.py
- tests/test_github_hourly_conflict_repair.py
- tests/test_governance_risk_compliance_hourly_review_caller.py
- tests/test_contextual_orchestrator_hourly_review_caller.py
- tests/test_hourly_scheduler_runtime_budget.py
- tests/test_nonnest2_hourly_review_caller.py
- tests/test_originweave_hourly_review_caller.py
Expand All @@ -47,6 +49,7 @@ on:
- docs/doctoring/fast-mlsirm-hourly-review-caller.md
- docs/doctoring/github-hourly-conflict-repair.md
- docs/doctoring/governance-risk-compliance-hourly-review-caller.md
- docs/doctoring/contextual-orchestrator-hourly-review-caller.md
- docs/doctoring/hourly-nvidia-nim-autofix.md
- docs/doctoring/nonnest2-hourly-review-caller.md
- docs/doctoring/originweave-hourly-review-caller.md
Expand All @@ -62,6 +65,7 @@ on:
- .github/workflows/fast-mlsirm-hourly-review-repair.yml
- .github/workflows/github-hourly-review-repair.yml
- .github/workflows/governance-risk-compliance-hourly-review-repair.yml
- .github/workflows/contextual-orchestrator-hourly-review-repair.yml
- .github/workflows/hourly-nvidia-nim-review-repair.yml
- .github/workflows/nonnest2-hourly-review-repair.yml
- .github/workflows/originweave-hourly-review-repair.yml
Expand All @@ -73,6 +77,7 @@ on:
- tests/test_fast_mlsirm_hourly_review_caller.py
- tests/test_github_hourly_conflict_repair.py
- tests/test_governance_risk_compliance_hourly_review_caller.py
- tests/test_contextual_orchestrator_hourly_review_caller.py
- tests/test_hourly_scheduler_runtime_budget.py
- tests/test_nonnest2_hourly_review_caller.py
- tests/test_originweave_hourly_review_caller.py
Expand All @@ -97,6 +102,7 @@ on:
- docs/doctoring/fast-mlsirm-hourly-review-caller.md
- docs/doctoring/github-hourly-conflict-repair.md
- docs/doctoring/governance-risk-compliance-hourly-review-caller.md
- docs/doctoring/contextual-orchestrator-hourly-review-caller.md
- docs/doctoring/hourly-nvidia-nim-autofix.md
- docs/doctoring/nonnest2-hourly-review-caller.md
- docs/doctoring/originweave-hourly-review-caller.md
Expand Down Expand Up @@ -153,6 +159,7 @@ jobs:
tests/test_fast_mlsirm_hourly_review_caller.py \
tests/test_github_hourly_conflict_repair.py \
tests/test_governance_risk_compliance_hourly_review_caller.py \
tests/test_contextual_orchestrator_hourly_review_caller.py \
tests/test_hourly_scheduler_runtime_budget.py \
tests/test_nonnest2_hourly_review_caller.py \
tests/test_originweave_hourly_review_caller.py \
Expand Down
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include (
Conflict-scope roots fail closed when the immediate parent directory is a symbolic link.
OriginWeave hourly NVIDIA NIM repair is a thin caller at minute 10. See [`docs/doctoring/originweave-hourly-review-caller.md`](docs/doctoring/originweave-hourly-review-caller.md).
nonnest2 hourly NVIDIA NIM repair is a thin caller at minute 16. See [`docs/doctoring/nonnest2-hourly-review-caller.md`](docs/doctoring/nonnest2-hourly-review-caller.md).
The contextual-orchestrator hourly repair caller runs at minute 17. See [`docs/doctoring/contextual-orchestrator-hourly-review-caller.md`](docs/doctoring/contextual-orchestrator-hourly-review-caller.md).
11 changes: 7 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ 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`.

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
repair, and delegates all privileged logic to the same sealed scheduler.
Product callers stagger contextual-orchestrator at minute 17, Clearfolio at
minute 23, DiskSage at minute 37, and fast-mlsirm at minute 49. Each caller
is read-only, dispatches at most one repair, and delegates all privileged
logic to the same sealed scheduler.

## Control-plane data flow

Expand Down Expand Up @@ -125,4 +126,6 @@ trusted `uv` exporter is downloaded from the literal GitHub Releases URL for
- [`docs/doctoring/hourly-nvidia-nim-autofix.md`](docs/doctoring/hourly-nvidia-nim-autofix.md)
— current increment's repair-worker decision and APA 7th citations.
- [`docs/doctoring/fast-mlsirm-hourly-review-caller.md`](docs/doctoring/fast-mlsirm-hourly-review-caller.md)
— product-specific psychometric repair heartbeat and scientific gates.
— product-specific psychometric repair heartbeat and scientific gates.
- [`docs/doctoring/contextual-orchestrator-hourly-review-caller.md`](docs/doctoring/contextual-orchestrator-hourly-review-caller.md)
— LLM routing-hub hourly caller, allowlist, and CWE-269 boundary.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Semantic Versioning where the repository publishes a release.
- Added a dedicated Clearfolio hourly caller that invokes the product-neutral central scheduler with the exact repository, protected base branch, one-dispatch budget, one-hour retry floor, single-flight concurrency, and only the established scheduler credentials.
- Added a dedicated DiskSage hourly caller that invokes the same product-neutral RCA and remediation-feasibility scheduler with an exact repository target, one-dispatch budget, two-hour same-head retry floor, non-cancelling single-flight heartbeat, and explicit established scheduler credentials.
- Added a dedicated fast-mlsirm hourly caller that preserves Rust-owned psychometric arithmetic while dispatching at most one exact-head, root-cause-driven repair with a two-hour same-head retry floor.
- Added a dedicated contextual-orchestrator hourly caller that invokes the product-neutral RCA scheduler for `ContextualWisdomLab/contextual-orchestrator` at minute 17 with a one-dispatch budget, one-hour same-head retry floor, non-cancelling single-flight heartbeat, and only the established scheduler credentials.

### Changed

Expand All @@ -26,6 +27,7 @@ Semantic Versioning where the repository publishes a release.
- Run the bounded Clearfolio PR review-feedback repair caller at minute 23 of every hour while keeping the shared scheduler free of product-specific timers and repository names for modular reuse by naruon, contextual-orchestrator, Inkspan, and other CWL services.
- Run the bounded DiskSage repair heartbeat at minute 37 of every hour, dispatch no more than one exact-head repair, and wait two hours before redispatching an unchanged head so legitimate OpenCode or NVIDIA NIM latency does not create duplicate writers.
- Run the bounded fast-mlsirm repair heartbeat at minute 49 of every hour with one-dispatch scope and a two-hour same-head floor, without weakening true-parameter recovery, CPU/GPU parity, skipped-test, or Rust-ownership gates.
- Run the bounded contextual-orchestrator repair heartbeat at minute 17 of every hour so the LLM routing hub receives NVIDIA NIM review repair without sharing a runner burst with Clearfolio, DiskSage, or fast-mlsirm.
- Use NVIDIA NIM `mistralai/mistral-small-4-119b-2603` with explicit high reasoning for scheduled repair and `nvidia/nemotron-3-nano-30b-a3b` for bounded helper work instead of GitHub Models in the write-capable autofix worker.
- Apply one NUL-delimited exact-path and complete pre/post-worktree verification contract to both ordinary review repair and merge-conflict repair rather than relying on a visible post-model diff for the ordinary path.

Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ Details: `docs/pr-review-and-merge-procedure.md` and `PR_GOVERNANCE_AUDIT.md`.
- `docs/` — master context, Project protocol, `org-required-workflow-rollout.md`,
`scorecard-governance.md`, SBOM inventory. Doctoring records live under
`docs/doctoring/`. [`ARCHITECTURE.md`](ARCHITECTURE.md) is the control-plane
diagram for review, hourly NVIDIA NIM repair, and merge trust boundaries.
diagram for review, hourly NVIDIA NIM repair (including contextual-orchestrator
minute 17), and merge trust boundaries.
- `.jules/` — recorded performance (`bolt.md`) and security (`sentinel.md`) learnings from past work
on `scripts/ci/`; worth scanning before optimizing or hardening those scripts.

Expand Down
25 changes: 25 additions & 0 deletions docs/automation/hourly-review-repair.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ engine**.

- `clearfolio-hourly-review-repair.yml` owns Clearfolio's heartbeat at minute 23
of every hour.
- `contextual-orchestrator-hourly-review-repair.yml` owns the LLM routing hub's
heartbeat at minute 17 with a one-hour same-head retry floor.
- `pr-review-fix-scheduler.yml` is the reusable, product-neutral scheduler
module. It has no product-specific timer and can be called by naruon,
contextual-orchestrator, Inkspan, or another CWL service with an explicit
Expand Down Expand Up @@ -39,6 +41,26 @@ The caller passes only the established `PR_REVIEW_MERGE_TOKEN` and
`NVIDIA_NIM_API_KEY`; the model credential is scoped exclusively to the two
OpenCode execution steps in the separately reviewed autofix worker.

## contextual-orchestrator execution contract

The contextual-orchestrator caller is a thin consumer of the same reusable
scheduler:

```yaml
target_repository: ContextualWisdomLab/contextual-orchestrator
base_branch: main
max_prs: "50"
max_dispatches: "1"
retry_hours: "1"
```

It runs at `17 * * * *`, uses its own non-cancelling single-flight group, and
passes only the two established scheduler credentials. Before activation on
protected `main`, `OPENCODE_REPOSITORY_DISPATCH_TARGETS` must include the exact
contextual-orchestrator repository. A missing target mapping fails before any
mutation credential is materialized; it never falls back to a broader
repository scope.

## Reusable target-selection contract

The shared scheduler resolves its target in this order:
Expand Down Expand Up @@ -195,6 +217,9 @@ Permanent tests prove:

- the Clearfolio caller owns exactly one hourly schedule and names the exact
repository and protected base branch;
- the contextual-orchestrator caller owns its distinct minute-17 schedule,
exact repository, protected base, non-cancelling concurrency, and explicit
secret contract;
- the shared scheduler contains no product-specific timer or repository name;
- the dispatch budget and same-head retry floor remain one;
- caller and reusable-workflow secrets are explicit and never use
Expand Down
85 changes: 85 additions & 0 deletions docs/doctoring/contextual-orchestrator-hourly-review-caller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# contextual-orchestrator hourly review-repair caller

Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include; a lone `--require-hashes` line is not lock evidence.

## Decision and operating boundary

The central repository owns a thin scheduled caller for
`ContextualWisdomLab/contextual-orchestrator`, the LLM token-cost optimizer,
upstream load balancer, and routing hub. It runs at minute 17 each hour so it
does not share a runner burst with Clearfolio (23), DiskSage (37), or
fast-mlsirm (49). It calls the product-neutral `pr-review-fix-scheduler.yml`
with protected base `main`, a one-dispatch budget, and a one-hour same-head
retry floor.

The caller contains product identity, cadence, and explicit reusable-workflow
inputs only. Queue classification, exact-head binding, root-cause analysis,
remediation feasibility, retry markers, and repair dispatch remain central.
contextual-orchestrator continues to own routing, cost review, and release
semantics and remains independently operable as a standalone module.

## Authority and secret contract

The caller keeps `GITHUB_TOKEN` at `contents: read` and maps only
`PR_REVIEW_MERGE_TOKEN` and `OPENCODE_APPROVE_TOKEN`. It deliberately does not
grant `id-token: write`: the established mapped scheduler credentials remain
the authority, while the optional OIDC exchange stays unavailable and
fail-closed. It never uses `secrets: inherit`, receives `NVIDIA_NIM_API_KEY`,
or introduces `COPILOT_GITHUB_TOKEN`. CWE-269 forbids granting the caller the
worker's write or model privileges (MITRE, 2026). Model credentials remain
scoped to the separately reviewed repair worker. The worker cannot approve,
merge, release, change protection, or manufacture passing evidence.

Before protected-main activation, the repository variable
`OPENCODE_REPOSITORY_DISPATCH_TARGETS` must contain the exact
`ContextualWisdomLab/contextual-orchestrator` target. Missing or mismatched
configuration fails before mutation credential materialization. GitHub App
installation and both mapped credentials must also remain limited to approved
repositories.

## Failure and recovery

A missing target allowlist entry, credential, or exact-head evidence is a
non-passing configuration state. Operators correct the bounded configuration
and rerun the unchanged protected source; they do not widen a token, inherit all
secrets, bypass protection, or perturb a clean PR head merely to trigger review.
A newer heartbeat does not cancel an in-flight decision. Same-head retry
markers and the per-PR writer lease prevent duplicate repair writers.

After source integration, closure requires a scheduled or manual protected-main
consumer run that proves the exact contextual-orchestrator target, read-only
caller token, bounded dispatch decision, and fail-closed credential behavior.
Source checks alone are not protected-main operational acceptance. Merge also
retains every required security check, zero unresolved valid findings, and a
qualifying independent non-author approval.

## Verification and rollback

Machine-checkable contracts require the exact target, minute 17 cadence,
non-cancelling single-flight group, one dispatch, one-hour retry floor, explicit
secret mapping, read-only permissions, central path-filter coverage, absence
of OIDC elevation, absence of model or Copilot credentials, and absence of
any target checkout or pull-request execution trigger. The full owned suite and
security/review gates must pass on the unchanged exact head.

Rollback removes the contextual-orchestrator caller, its focused test,
doctoring, and the associated central path-filter/documentation entries. It
must not remove the reusable scheduler's dispatch validation or affect the
independent Clearfolio, DiskSage, and fast-mlsirm callers.

## APA 7th references

MITRE. (2026). *CWE-269: Improper privilege management*.
https://cwe.mitre.org/data/definitions/269.html

GitHub, Inc. (n.d.-a). *Events that trigger workflows*. GitHub Docs. Retrieved
August 16, 2026, from
https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule

GitHub, Inc. (n.d.-b). *Reuse workflows*. GitHub Docs. Retrieved August 16,
2026, from
https://docs.github.com/en/actions/how-tos/sharing-automations/reuse-workflows

GitHub, Inc. (n.d.-c). *Workflow syntax for GitHub Actions: Permissions*.
GitHub Docs. Retrieved August 16, 2026, from
https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#permissions
84 changes: 84 additions & 0 deletions tests/test_contextual_orchestrator_hourly_review_caller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
"""Contract tests for contextual-orchestrator's bounded hourly review-repair caller."""

from pathlib import Path


CALLER = Path(".github/workflows/contextual-orchestrator-hourly-review-repair.yml")
DOCTORING = Path("docs/doctoring/contextual-orchestrator-hourly-review-caller.md")
QUALITY_WORKFLOW = Path(".github/workflows/hourly-nvidia-nim-review-repair.yml")
SCHEDULER = Path(".github/workflows/pr-review-fix-scheduler.yml")


def _read(path: Path) -> str:
"""Return one repository contract file as UTF-8 text."""
return path.read_text(encoding="utf-8")


def test_orchestrator_caller_is_hourly_bounded_and_non_cancelling() -> None:
"""The orchestrator receives one bounded repair opportunity without cancellation."""
caller = _read(CALLER)

assert 'cron: "17 * * * *"' in caller
assert "group: contextual-orchestrator-hourly-review-repair" in caller
assert "cancel-in-progress: false" in caller
assert "uses: ./.github/workflows/pr-review-fix-scheduler.yml" in caller
assert "target_repository: ContextualWisdomLab/contextual-orchestrator" in caller
assert "base_branch: main" in caller
assert 'max_prs: "50"' in caller
assert 'max_dispatches: "1"' in caller
assert 'retry_hours: "1"' in caller


def test_orchestrator_caller_preserves_read_only_explicit_secret_scope() -> None:
"""The queue scanner maps established credentials without model secrets."""
caller = _read(CALLER)
workflow_scope, jobs_scope = caller.split("\njobs:\n", maxsplit=1)

assert "\npermissions:\n contents: read\n" in workflow_scope
assert "\n permissions:\n contents: read\n" in jobs_scope
assert "id-token: write" not in caller
assert "PR_REVIEW_MERGE_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN }}" in caller
assert "OPENCODE_APPROVE_TOKEN: ${{ secrets.OPENCODE_APPROVE_TOKEN }}" in caller
assert "secrets: inherit" not in caller
assert "NVIDIA_NIM_API_KEY" not in caller
assert "COPILOT_GITHUB_TOKEN" not in caller
assert "actions/checkout" not in caller
assert "pull_request:" not in caller
for forbidden in (
"actions: write",
"contents: write",
"issues: write",
"pull-requests: write",
"statuses: write",
):
assert forbidden not in caller


def test_orchestrator_target_is_not_hard_coded_in_shared_scheduler() -> None:
"""Product identity remains in the thin caller rather than the engine."""
assert "ContextualWisdomLab/contextual-orchestrator" not in _read(SCHEDULER)


def test_orchestrator_doctoring_records_fail_closed_activation() -> None:
"""Operators retain target-allowlist and acceptance prerequisites."""
doctoring = _read(DOCTORING)

for phrase in (
"ContextualWisdomLab/contextual-orchestrator",
"OPENCODE_REPOSITORY_DISPATCH_TARGETS",
"independent non-author approval",
"NVIDIA_NIM_API_KEY",
"COPILOT_GITHUB_TOKEN",
"protected-main operational acceptance",
"APA 7th references",
):
assert phrase in doctoring


def test_focused_quality_workflow_tracks_orchestrator_contracts() -> None:
"""Caller, test, and doctoring edits always rerun the focused gate."""
quality = _read(QUALITY_WORKFLOW)

assert quality.count(".github/workflows/contextual-orchestrator-hourly-review-repair.yml") == 2
assert quality.count("docs/doctoring/contextual-orchestrator-hourly-review-caller.md") == 2
assert quality.count("tests/test_contextual_orchestrator_hourly_review_caller.py") == 3
Loading