Skip to content
Draft
4 changes: 4 additions & 0 deletions .github/workflows/hourly-nvidia-nim-review-repair.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- .github/workflows/pr-review-fix-scheduler.yml
- .github/workflows/pr-review-autofix.yml
- .github/workflows/clearfolio-hourly-review-repair.yml
- .github/workflows/inkspan-hourly-review-repair.yml
- .github/workflows/hourly-nvidia-nim-review-repair.yml
- scripts/ci/pr_review_conflict_scope.py
- tests/test_pr_review_conflict_scope.py
Expand All @@ -14,12 +15,14 @@ on:
- tests/test_pr_review_autofix_nvidia_nim_contract.py
- docs/automation/hourly-review-repair.md
- docs/doctoring/clearfolio-hourly-review-caller.md
- docs/doctoring/inkspan-hourly-review-caller.md
- docs/doctoring/hourly-nvidia-nim-autofix.md
push:
paths:
- .github/workflows/pr-review-fix-scheduler.yml
- .github/workflows/pr-review-autofix.yml
- .github/workflows/clearfolio-hourly-review-repair.yml
- .github/workflows/inkspan-hourly-review-repair.yml
- .github/workflows/hourly-nvidia-nim-review-repair.yml
- scripts/ci/pr_review_conflict_scope.py
- tests/test_pr_review_conflict_scope.py
Expand All @@ -28,6 +31,7 @@ on:
- tests/test_pr_review_autofix_nvidia_nim_contract.py
- docs/automation/hourly-review-repair.md
- docs/doctoring/clearfolio-hourly-review-caller.md
- docs/doctoring/inkspan-hourly-review-caller.md
- docs/doctoring/hourly-nvidia-nim-autofix.md

permissions:
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/inkspan-hourly-review-repair.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Inkspan Hourly Review Repair

on:
schedule:
# Offset from other product heartbeats to reduce shared-runner congestion.
- cron: "37 * * * *"

concurrency:
group: inkspan-hourly-review-repair
cancel-in-progress: true

permissions:
contents: read

jobs:
dispatch-review-repair:
permissions:
actions: write
contents: read
issues: write
pull-requests: read
statuses: read
uses: ./.github/workflows/pr-review-fix-scheduler.yml
with:
target_repository: ContextualWisdomLab/inkspan
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 }}
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,30 @@ Semantic Versioning where the repository publishes a release.
- Added exact-base `uv.lock` materialization that reconstructs standalone nested projects with a checksum-pinned official `uv` exporter, isolated frozen/offline execution, strict exact-pin and SHA-256 output validation, and complete Python 3.10/3.14 quality evidence.
- Added a permanent exact-head contract workflow for the hourly review-repair scheduler, immutable reusable-workflow source, NVIDIA NIM model boundary, credential isolation, and fail-closed unattended-agent permissions.
- 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 Inkspan hourly caller at minute 37 with an explicit protected `main` target, one-dispatch budget, one-hour same-head retry floor, product-specific single-flight concurrency, and no copied repair implementation in the product repository.

### Changed

- 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, and other CWL services.
- Run the bounded Inkspan PR review-feedback repair caller at minute 37 of every hour, offset from Clearfolio while sharing the same product-neutral scheduler and independent concurrency group.
- Use NVIDIA NIM `mistralai/mistral-nemotron` for scheduled repair and `nvidia/nemotron-3-nano-30b-a3b` for bounded helper work instead of GitHub Models in the write-capable autofix worker.

### Fixed

- Bound both trusted-uv quality jobs to `github.event.pull_request.head.sha` and added a permanent two-checkout regression contract so exact-head compatibility, coverage, docstring, and compilation claims cannot silently measure GitHub's generated pull-request merge revision.
- Made Strix treat only a single LiteLLM provider-error line containing NVIDIA NIM context and model-catalog 404 evidence as cross-model fallback evidence, rejecting cross-line signal assembly and provider-like target source literals; moved the public default to Nemotron 3 Super 120B and added a second NVIDIA hosted candidate before GitHub Models without neutralizing reported vulnerabilities.
- Bind reusable scheduler implementation to the validated called-workflow repository, SHA, ref, and file path, and verify the checked-out commit before executing privileged scheduler logic.
- Removed the ambiguous central-repository schedule fallback that could scan `.github` instead of Clearfolio when no external variable was configured; the active product caller now names Clearfolio explicitly while the reusable engine retains caller and dispatch overrides.
- Removed the ambiguous central-repository schedule fallback that could scan `.github` instead of Clearfolio when no external variable was configured; active product callers now name Clearfolio and Inkspan explicitly while the reusable engine retains caller and dispatch overrides.

### Security

- Snapshot the post-merge worktree before OpenCode conflict repair and reject every model-caused changed, created, deleted, or retargeted path outside Git's exact conflict allowlist before staging or push.
- Keep the Clearfolio caller read-only at workflow scope and grant Actions/Issues write access only to the single reusable-scheduler job, preventing future sibling jobs from inheriting mutation authority.
- Keep the Clearfolio and Inkspan callers read-only at workflow scope and grant Actions/Issues write access only to each caller's single reusable-scheduler job, preventing sibling jobs from inheriting mutation authority.
- Bind `NVIDIA_NIM_API_KEY` only to the two OpenCode model execution steps, fail closed when the secret is absent, and remove GitHub and Actions OIDC credentials from both model subprocesses.
- Deny unnecessary non-file OpenCode interactions and preserve the independent read-only reviewer workflow and its credential/model-pool contract byte-for-byte.
- Pin the repository-dispatch autofix helper checkout to the exact workflow-run SHA rather than a moving default branch.
- Pass only `PR_REVIEW_MERGE_TOKEN` and `OPENCODE_APPROVE_TOKEN` from the Clearfolio schedule caller; do not use `secrets: inherit` and do not expose the NVIDIA model credential to the queue-scanning workflow.
- Pass only `PR_REVIEW_MERGE_TOKEN` and `OPENCODE_APPROVE_TOKEN` from product schedule callers; do not use `secrets: inherit` and do not expose the NVIDIA model credential to queue-scanning workflows.

### Documentation

- Added operator and APA 7 doctoring records for the hourly cadence, immutable source identity, NVIDIA NIM provider and secret boundary, model-process credential isolation, modular MSA ownership, product-specific caller activation, verification contract, and rollback.
- Added operator and APA 7 doctoring records for the hourly cadence, immutable source identity, NVIDIA NIM provider and secret boundary, model-process credential isolation, modular MSA ownership, Clearfolio and Inkspan product-caller activation, verification contracts, and rollback.
129 changes: 129 additions & 0 deletions docs/doctoring/inkspan-hourly-review-caller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Inkspan Hourly Review-Repair Caller Boundary

## Decision

Inkspan's one-hour review → repair → revalidation support heartbeat is owned by
a dedicated central caller workflow,
`.github/workflows/inkspan-hourly-review-repair.yml`. The product-neutral engine
remains `.github/workflows/pr-review-fix-scheduler.yml`; it contains no Inkspan
repository literal and no product-specific schedule.

This split preserves both deployment forms required by CWL. Inkspan remains a
standalone product repository, while the central `.github` control plane owns
shared repair orchestration that naruon and other products may reuse without
copying privileged workflow logic. A scheduled workflow executes in the
repository that contains it, so the caller must name `ContextualWisdomLab/inkspan`
explicitly rather than relying on the central repository as an implicit target.

## Product caller

The Inkspan caller runs at minute 37 of every hour. The offset separates its
heartbeat from the Clearfolio caller and reduces avoidable shared-runner bursts.
It invokes the local reusable workflow with explicit, reviewable values:

```yaml
target_repository: ContextualWisdomLab/inkspan
base_branch: main
max_prs: "50"
max_dispatches: "1"
retry_hours: "1"
```

The caller and reusable engine both use `cancel-in-progress: true`. Queue
inspection is therefore single-flight at both the product and engine boundary.
One invocation may dispatch at most one autofix, and the same exact PR head is
not retried more often than once per hour.

## Modular MSA contract

The caller contains product identity and cadence only. The reusable scheduler
continues to own PR inventory, exact-head retry bookkeeping, dispatch bounds,
and the handoff to the separately reviewed repair plane. Inkspan does not copy
OpenCode configuration, reviewer identities, model credentials, merge policy,
or branch-update logic into its product repository.

This architecture allows Inkspan to run independently while remaining suitable
for naruon `compose` and `ui.panel` integration. Product integration changes do
not alter the scheduler's security or credential boundary, and scheduler
changes do not add a runtime dependency to Inkspan.

## Credential and privilege boundary

The caller passes exactly the two established optional scheduler credentials:

- `PR_REVIEW_MERGE_TOKEN`;
- `OPENCODE_APPROVE_TOKEN`.

It does not use `secrets: inherit`. It does not receive
`NVIDIA_NIM_API_KEY`, because queue inspection and workflow dispatch are not
model execution. The NVIDIA credential remains scoped only to the two model
execution steps in the separately reviewed `PR Review Autofix` workflow.
`COPILOT_GITHUB_TOKEN` and GitHub Models are not introduced.

Workflow scope is read-only. The single reusable-workflow job receives only the
required Actions and Issues write permissions plus read access to Contents,
Pull Requests, and Statuses. Omitted scopes remain unavailable. No sibling job
inherits write authority.

The repair worker cannot approve a PR, merge a PR, publish a release, alter a
reviewer credential chain, weaken branch protection, or convert a failed or
missing check into success.

## Failure behavior

Missing scheduler credentials cause target inspection or dispatch to fail
closed; they do not redirect work to `.github`. A missing NVIDIA credential
later stops the repair worker before model execution. Neither case weakens
independent review, required checks, unresolved-thread policy, or branch
protection.

Scheduled workflows become active only from the protected default branch. This
caller is not production automation while its stacked pull request or its
prerequisite scheduler PR remains unmerged.

## Verification contract

Permanent tests require all of the following:

1. the Inkspan caller contains the exact hourly cron;
2. the caller invokes the local reusable scheduler;
3. `ContextualWisdomLab/inkspan` and protected `main` are explicit;
4. dispatch and same-head retry bounds remain one;
5. caller concurrency remains single-flight;
6. only the two established scheduler secrets cross the caller boundary;
7. `secrets: inherit`, `COPILOT_GITHUB_TOKEN`, direct NVIDIA credential binding,
approval, merge, release, and protection mutation are absent;
8. workflow scope remains read-only and required write permissions are confined
to the reusable-scheduler job; and
9. the caller remains independent from the Clearfolio caller while sharing the
same product-neutral engine.

Repository acceptance still requires exact-current-head workflow, security,
supply-chain, automated-review, independent-review, unresolved-thread, and
branch-protection evidence.

## Rollback

Rollback removes only the Inkspan caller, its static contract, doctoring, and
changelog entry. It leaves the reusable scheduler, Clearfolio caller, OpenCode
repair workflow, Noema/OpenCode reviewer identities, and credential chains
unchanged. Rollback must not replace the explicit target with the central
repository fallback or copy privileged scheduler implementation into Inkspan.

## References (APA 7th edition)

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

GitHub, Inc. (n.d.-b). *Reusing workflows*. GitHub Docs. Retrieved August 6,
2026, from
https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/reuse-automations/reuse-workflows

GitHub, Inc. (n.d.-c). *Workflow syntax for GitHub Actions: Jobs.<job_id>.secrets*.
GitHub Docs. Retrieved August 6, 2026, from
https://docs.github.com/en/enterprise-cloud@latest/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idsecrets

GitHub, Inc. (n.d.-d). *Workflow syntax for GitHub Actions: Jobs.<job_id>.permissions*.
GitHub Docs. Retrieved August 6, 2026, from
https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax#jobsjob_idpermissions
Loading
Loading