Skip to content
Open
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
34 changes: 34 additions & 0 deletions .github/workflows/afipc-hourly-review-repair.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: aFIPC Hourly Review Repair

on:
schedule:
# Minute 2 avoids pg-llm-batch (1), codec-carver (5), Wardnet (7),
# naruon (11), pg-erd-cloud (13), orchestrator (17), noema (19),
# Clearfolio (23), Keyverse (29), Scopeweave (31), DiskSage (37),
# Appguardrail (41), newsdom-api (43), Inkspan (47), fast-mlsirm (49),
# BandScope (53), and semantic-data-portal (59).
- cron: "2 * * * *"

concurrency:
group: afipc-hourly-review-repair
# A later heartbeat must not cancel an in-flight FIPC or calibration RCA.
cancel-in-progress: false

permissions:
contents: read

jobs:
dispatch-review-repair:
permissions:
contents: read
id-token: write
uses: ./.github/workflows/pr-review-fix-scheduler.yml
with:
target_repository: ContextualWisdomLab/aFIPC
base_branch: master
max_prs: "50"
max_dispatches: "1"
retry_hours: "2"
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 @@ -16,6 +16,7 @@ on:
- .github/workflows/nonnest2-hourly-review-repair.yml
- .github/workflows/originweave-hourly-review-repair.yml
- .github/workflows/quarantine-sandbox-hourly-review-repair.yml
- .github/workflows/afipc-hourly-review-repair.yml
- scripts/ci/pr_review_conflict_scope.py
- scripts/ci/pr_review_autofix_context.py
- tests/test_bandscope_hourly_review_caller.py
Expand All @@ -27,6 +28,7 @@ on:
- tests/test_nonnest2_hourly_review_caller.py
- tests/test_originweave_hourly_review_caller.py
- tests/test_quarantine_sandbox_hourly_review_caller.py
- tests/test_afipc_hourly_review_caller.py
- tests/test_hourly_autofix_context_quality_gate.py
- tests/test_pr_review_conflict_scope.py
- tests/test_pr_review_conflict_scope_control_files.py
Expand All @@ -51,6 +53,7 @@ on:
- docs/doctoring/nonnest2-hourly-review-caller.md
- docs/doctoring/originweave-hourly-review-caller.md
- docs/doctoring/quarantine-sandbox-hourly-review-caller.md
- docs/doctoring/afipc-hourly-review-caller.md
push:
paths:
- .github/workflows/pr-review-fix-scheduler.yml
Expand All @@ -66,6 +69,7 @@ on:
- .github/workflows/nonnest2-hourly-review-repair.yml
- .github/workflows/originweave-hourly-review-repair.yml
- .github/workflows/quarantine-sandbox-hourly-review-repair.yml
- .github/workflows/afipc-hourly-review-repair.yml
- scripts/ci/pr_review_conflict_scope.py
- scripts/ci/pr_review_autofix_context.py
- tests/test_bandscope_hourly_review_caller.py
Expand All @@ -77,6 +81,7 @@ on:
- tests/test_nonnest2_hourly_review_caller.py
- tests/test_originweave_hourly_review_caller.py
- tests/test_quarantine_sandbox_hourly_review_caller.py
- tests/test_afipc_hourly_review_caller.py
- tests/test_hourly_autofix_context_quality_gate.py
- tests/test_pr_review_conflict_scope.py
- tests/test_pr_review_conflict_scope_control_files.py
Expand All @@ -101,6 +106,7 @@ on:
- docs/doctoring/nonnest2-hourly-review-caller.md
- docs/doctoring/originweave-hourly-review-caller.md
- docs/doctoring/quarantine-sandbox-hourly-review-caller.md
- docs/doctoring/afipc-hourly-review-caller.md

permissions:
contents: read
Expand Down Expand Up @@ -157,6 +163,7 @@ jobs:
tests/test_nonnest2_hourly_review_caller.py \
tests/test_originweave_hourly_review_caller.py \
tests/test_quarantine_sandbox_hourly_review_caller.py \
tests/test_afipc_hourly_review_caller.py \
tests/test_pr_review_conflict_scope_control_files.py \
tests/test_hourly_autofix_context_quality_gate.py \
tests/test_pr_review_conflict_scope_git_executable.py \
Expand Down
5 changes: 5 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ only established scheduler credentials, and grants job-scoped

`nonnest2-hourly-review-repair.yml` is a thin, read-only caller at minute
16. It names `ContextualWisdomLab/nonnest2` and protected `master`, maps
## aFIPC hourly caller

`afipc-hourly-review-repair.yml` is a thin, read-only caller at minute
2. It names `ContextualWisdomLab/aFIPC` and protected `master`, maps
Comment on lines +39 to +42

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 New section heading splits an existing paragraph in the architecture document

The new aFIPC section heading and text are inserted in the middle of the nonnest2 paragraph (ARCHITECTURE.md:39-42), so the nonnest2 description is cut off after the word "maps" and its closing sentence is stolen by the aFIPC section.
Impact: Readers of the architecture document see a broken nonnest2 entry that ends mid-sentence, and the aFIPC entry inherits nonnest2's leftover text.

How the mid-paragraph insertion garbles both sections

Before the change the nonnest2 block read: "...protected master, maps only established scheduler credentials, and grants job-scoped id-token: write. The reusable engine stays product-neutral." The added lines ARCHITECTURE.md:39-42 inject ## aFIPC hourly caller and its opening sentence between "maps" (line 38) and "only established scheduler credentials" (line 43). The nonnest2 paragraph now ends abruptly at "maps", and the trailing "only established... product-neutral." now belongs to the aFIPC section. The aFIPC block should be placed as a separate section after the nonnest2 paragraph ends at line 44.

Prompt for agents
In ARCHITECTURE.md the new '## aFIPC hourly caller' section (lines 39-42) was inserted into the middle of the '## nonnest2 hourly caller' paragraph, between 'protected `master`, maps' (line 38) and 'only established scheduler credentials' (line 43). This truncates the nonnest2 description and makes the aFIPC section absorb nonnest2's closing sentence. Move the four aFIPC lines so they form a standalone section placed after the nonnest2 paragraph fully ends (after the 'The reusable engine stays product-neutral.' line at line 44), and give the aFIPC section its own complete sentence mirroring the other callers (i.e. ending with 'only established scheduler credentials, and grants job-scoped `id-token: write`. The reusable engine stays product-neutral.').
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

only established scheduler credentials, and grants job-scoped
`id-token: write`. The reusable engine stays product-neutral.

Expand Down Expand Up @@ -111,6 +115,7 @@ CI installs Python tools only with `pip install --require-hashes`. Contract
tests pin workflow structure and governance prose so drift fails closed. The
trusted `uv` exporter is downloaded from the literal GitHub Releases URL for
`uv` 0.12.1; `releases.astral.sh` is not the network sink.
tests pin workflow structure and governance prose so drift fails closed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Duplicate leftover sentence fragment in the architecture quality-gates section

A duplicate copy of the sentence "tests pin workflow structure and governance prose so drift fails closed." is appended (ARCHITECTURE.md:118) right after the existing quality-gates paragraph, so the same statement now appears twice.
Impact: The quality-gates section of the architecture document contains a redundant, dangling sentence that duplicates the line above it.

Duplicated line

The existing paragraph already contains "Contract tests pin workflow structure and governance prose so drift fails closed." at ARCHITECTURE.md:114-115. The added line 118 repeats the fragment verbatim after the uv sentence, leaving a stray one-line duplicate before the '## Related durable documents' heading.

Prompt for agents
Delete the duplicated line 118 in ARCHITECTURE.md ('tests pin workflow structure and governance prose so drift fails closed.'), which repeats text already present in the quality-gates paragraph at lines 114-115.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


## Related durable documents

Expand Down
3 changes: 3 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ Details: `docs/pr-review-and-merge-procedure.md` and `PR_GOVERNANCE_AUDIT.md`.
dependency sets (see below). `requirements-strix-ci-overrides.txt` documents one deliberate
`uv pip compile --override` (strix-agent's declared `cryptography<49` vs. this repo's
`cryptography==50.0.0` security pin; see #952) — re-verify it whenever strix-agent bumps again.
dependency sets (see below).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Duplicate fragment inserted into a requirements bullet

The phrase "dependency sets (see below)." is duplicated (CLAUDE.md:67) at the end of the requirements bullet, repeating text already at the start of the same bullet.
Impact: The requirements bullet in the contributor guide contains a stray duplicated fragment.

Duplicated fragment

The bullet already opens with "pinned CI dependency sets (see below)." at CLAUDE.md:63-64. The added line 67 repeats "dependency sets (see below)." after the strix-override sentence, dangling before the next fuzz/ bullet.

Prompt for agents
Delete the duplicated line 67 in CLAUDE.md ('  dependency sets (see below).'), which repeats text already present at the start of the same requirements bullet.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

- `fuzz/` + `.clusterfuzzlite/` — Atheris fuzz targets for the review-output normalizer and the
ClusterFuzzLite discovery marker.
- `docs/` — master context, Project protocol, `org-required-workflow-rollout.md`,
Expand Down Expand Up @@ -100,6 +101,7 @@ e.g.:
uv pip compile --generate-hashes --python-version 3.12 --python-platform x86_64-manylinux_2_28 requirements-bandit-ci.txt -o requirements-bandit-ci-hashes.txt
uv pip compile --generate-hashes --python-version 3.12 --python-platform x86_64-manylinux_2_28 requirements-pip-audit-ci.txt -o requirements-pip-audit-ci-hashes.txt
uv pip compile --generate-hashes --python-version 3.13 --python-platform x86_64-manylinux_2_28 --override requirements-strix-ci-overrides.txt --output-file requirements-strix-ci-hashes.txt requirements-strix-ci.txt
uv pip compile --generate-hashes --python-version 3.13 --python-platform x86_64-manylinux_2_28 --output-file requirements-strix-ci-hashes.txt requirements-strix-ci.txt

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Documentation lists a regenerate command that drops the required security override

A second copy of the strix hash-regeneration command is added (CLAUDE.md:104) that omits the --override requirements-strix-ci-overrides.txt flag, so following it regenerates the strix lock without the deliberate cryptography override the repo requires.
Impact: Anyone following the documented command would rebuild the strix requirements lock without the mandated security override, silently reverting the cryptography pin decision.

Conflicting duplicate compile command

Line 103 correctly documents the command with --override requirements-strix-ci-overrides.txt. The added line 104 duplicates it but omits the override flag entirely. CLAUDE.md:64-66 and the Structure section describe the override as a deliberate, documented decision (strix-agent's cryptography<49 vs. this repo's cryptography==50.0.0 pin), so the overrideless command directly contradicts it.

Prompt for agents
Delete the duplicated strix compile command at CLAUDE.md line 104. It repeats line 103 but omits the '--override requirements-strix-ci-overrides.txt' flag, which contradicts the documented deliberate override (cryptography pin) described elsewhere in CLAUDE.md.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

./scripts/ci/compile_opencode_review_lock.sh
```

Expand All @@ -118,6 +120,7 @@ repeatable compile command.
- **100% coverage and 100% docstrings on `scripts/ci/`** are hard gates, not aspirations. New helper
code needs matching tests and docstrings.
- **Product hourly callers** stay thin. Do not hard-code OriginWeave, naruon, or Keyverse
- **Product hourly callers** stay thin. Do not hard-code aFIPC, naruon, or Keyverse
Comment on lines 122 to +123

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Duplicated hourly-caller bullet leaves a broken sentence in the contributor guide

A second "Product hourly callers" bullet is added (CLAUDE.md:123) for aFIPC, leaving the original OriginWeave bullet (line 122) dangling without its "into pr-review-fix-scheduler.yml..." continuation, which now attaches only to the new bullet.
Impact: The contributor guide shows two near-identical bullets, one of which ends abruptly as an incomplete sentence.

Duplicated bullet

Before the change the bullet read "Do not hard-code OriginWeave, naruon, or Keyverse into pr-review-fix-scheduler.yml...". The added line 123 ("Do not hard-code aFIPC, naruon, or Keyverse") is inserted between line 122 and its continuation at line 124 ("into pr-review-fix-scheduler.yml..."). As a result line 122 now ends at "Keyverse" with no continuation, and the continuation binds to the aFIPC bullet. The intent was to replace OriginWeave with aFIPC (or add aFIPC to the same list), not to leave a truncated duplicate bullet.

Suggested change
- **Product hourly callers** stay thin. Do not hard-code OriginWeave, naruon, or Keyverse
- **Product hourly callers** stay thin. Do not hard-code aFIPC, naruon, or Keyverse
- **Product hourly callers** stay thin. Do not hard-code aFIPC, naruon, or Keyverse
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

into `pr-review-fix-scheduler.yml`. The model credential remains `NVIDIA_NIM_API_KEY`
on the worker, never `COPILOT_GITHUB_TOKEN`.
- **`pull_request_target` trust boundary.** The required review workflows run the *base branch's*
Expand Down
140 changes: 140 additions & 0 deletions docs/doctoring/afipc-hourly-review-caller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# aFIPC hourly review-repair caller

검토 기준일: **2026-08-17**

## Decision

ContextualWisdomLab operates one protected hourly caller for
`ContextualWisdomLab/aFIPC` (Fixed-Item Parameter Calibration — the
psychometric calibration engine consumed by fast-mlsirm). The caller
runs at minute 2, delegates to the product-neutral central review-fix
scheduler, inspects at most 50 open pull requests targeting protected
`master`, and dispatches at most one bounded repair per heartbeat.

A paying buyer of calibrated judge-item measurement would feel live
aFIPC pull requests stalling while hourly NVIDIA NIM repair scanned only
Clearfolio, DiskSage, and fast-mlsirm. Live heads such as
ContextualWisdomLab/aFIPC#259 (integer-coercion DoS),
ContextualWisdomLab/aFIPC#263 (integer-overflow validation),
ContextualWisdomLab/aFIPC#261 (FIPC ADRs), and
ContextualWisdomLab/aFIPC#262 (NA-omit hot path) target `master` and
never enter those other callers.

The caller does not implement review or mutation logic itself. aFIPC
remains standalone; fast-mlsirm consumes its calibration without owning
the R runtime. Privileged automation stays in
`ContextualWisdomLab/.github`.

## Root-cause analysis and remediation feasibility

The reusable worker performs exact-head root-cause analysis and tests
remediation feasibility before it edits. The reusable worker must:

1. Refetch the exact live head, base, reviews, checks, changed paths, and
writer state.
2. Establish the causal chain rather than repeat the terminal symptom.
3. Enumerate materially distinct minimal remedies.
4. Reject remedies that lack writer authority, cross sealed paths, require
unavailable credentials or protected-setting changes, violate stack
order, cannot be verified, or do not alter the diagnosed cause.
5. Dispatch at most one feasible repair. Otherwise leave the tree
unchanged.

A queued or pending check remains a merge blocker but is not itself a
code finding. The independent non-author approval remains an external
authorization gate and is never synthesized by the repair worker. The
worker cannot approve, merge, release, resolve review findings by
inference, change protection, or manufacture passing checks.

## Cadence and concurrency

The caller uses a single concurrency group and `cancel-in-progress: false`.
This preserves an in-flight bounded RCA instead of discarding FIPC
evidence when the next hourly heartbeat arrives. The reusable scheduler
cancels only its own superseded short queue scan.

The caller sets a **two-hour same-head retry floor**. Central OpenCode and
NVIDIA NIM work, plus integer-bound or calibration analysis, can
legitimately approach two hours. An hourly redispatch of the same
unchanged head would create duplicate writer pressure rather than faster
remediation.

GitHub scheduled workflows can be delayed under load and execute only
from the default branch. The cron expression is a heartbeat, not a
real-time SLA.

## Credential and model boundary

The caller keeps workflow `GITHUB_TOKEN` at `contents: read` and grants
the reusable job `id-token: write` so the central scheduler can mint the
OpenCode GitHub App token from GitHub OIDC when the mapped PAT is absent
(GitHub, n.d.-c). It maps only `PR_REVIEW_MERGE_TOKEN` and
`OPENCODE_APPROVE_TOKEN`. It never uses `secrets: inherit`, receives
`NVIDIA_NIM_API_KEY`, or introduces `COPILOT_GITHUB_TOKEN`. CWE-250
forbids executing the caller with write or model privileges it does not
need (MITRE, 2026).

Model execution remains inside the central worker. The model credential
is the GitHub Secret `NVIDIA_NIM_API_KEY`; the caller does not receive or
forward it.

Before protected-master activation, the repository variable
`OPENCODE_REPOSITORY_DISPATCH_TARGETS` must contain the exact
`ContextualWisdomLab/aFIPC` target. Missing or mismatched
configuration fails before mutation credential materialization.

## Security, standalone operation, and modularity

The caller adds no aFIPC runtime dependency, database object, network
endpoint, tenant authority, or product credential. aFIPC continues to
run as a standalone R calibration package. fast-mlsirm and other CWL
services may consume its estimates, but they cannot weaken its
exact-head, approval, or security gates.

## Verification and rollback

Machine-checkable contracts require the exact target/base, minute 2
cadence, non-cancelling single-flight group, one dispatch, two-hour
retry floor, explicit secret mapping, read-only contents plus job-scoped
`id-token: write`, focused path-filter coverage, and absence of model or
Copilot credentials. Independent `pull_request`, `push`, and `compileall`
path blocks must each name the caller, doctoring, or contract they own.

After source integration, closure requires a scheduled or manual
protected-master consumer run proving the exact aFIPC repository and
`master` base. Source checks alone are not protected-master operational acceptance.
Merge still requires zero unresolved valid findings and a
qualifying independent non-author approval.

Rollback removes the aFIPC caller, its focused test, doctoring, and
central path-filter/documentation entries. It must not remove scheduler
dispatch validation or affect independent product callers.

## APA 7th references

GitHub, Inc. (n.d.-a). *Events that trigger workflows*. GitHub Docs.
Retrieved August 17, 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
17, 2026, from
https://docs.github.com/en/actions/how-tos/sharing-automations/reuse-workflows

GitHub, Inc. (n.d.-c). *Automatic token authentication*. GitHub Docs.
Retrieved August 17, 2026, from
https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token

MITRE. (2026). *CWE-250: Execution with unnecessary privileges*.
https://cwe.mitre.org/data/definitions/250.html

National Institute of Standards and Technology. (2022). *Secure software
development framework (SSDF) version 1.1: Recommendations for mitigating
the risk of software vulnerabilities* (NIST Special Publication 800-218).
https://doi.org/10.6028/NIST.SP.800-218

NVIDIA. (n.d.). *NVIDIA NIM for large language models documentation*.
Retrieved August 17, 2026, from
https://docs.nvidia.com/nim/large-language-models/latest/

OpenCode. (n.d.). *OpenCode documentation*. Retrieved August 17, 2026,
from https://opencode.ai/docs/
Loading
Loading