Skip to content
Merged
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
76 changes: 75 additions & 1 deletion .github/workflows/opencode-review-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -726,8 +726,82 @@ jobs:
--only-binary=:all: \
-r /tmp/requirements-opencode-review-ci-hashes.txt \
&& rm -f /tmp/requirements-opencode-review-ci-hashes.txt
COPY install-base-python-locks.py /usr/local/libexec/install-base-python-locks.py
COPY base-python-requirements /tmp/base-python-requirements
RUN set -eu; \
mkdir -p /opt/base-vcs-dependencies; \
site_packages="$(python3 -c 'import site; print(site.getsitepackages()[0])')"; \
path_file="${site_packages}/opencode-base-vcs-dependencies.pth"; \
: >"$path_file"; \
Comment thread
seonghobae marked this conversation as resolved.
dependency_index=0; \
dependency_list=/tmp/base-vcs-dependencies.tsv; \
jq -r '.[] | [.import_name, .repository, .commit] | @tsv' \
/tmp/base-python-requirements/vcs-manifest.json >"$dependency_list"; \
while IFS="$(printf '\t')" read -r import_name repository commit; do \
destination="$(printf '/opt/base-vcs-dependencies/dependency-%03d' "$dependency_index")"; \
git init --quiet "$destination"; \
git -C "$destination" remote add origin \
"https://github.com/ContextualWisdomLab/${repository}.git"; \
git -C "$destination" -c protocol.version=2 fetch \
--quiet --no-tags --depth=1 origin "$commit"; \
test "$(git -C "$destination" rev-parse FETCH_HEAD)" = "$commit"; \
Comment thread
seonghobae marked this conversation as resolved.
git -C "$destination" checkout --quiet --detach FETCH_HEAD; \
test "$(git -C "$destination" rev-parse HEAD)" = "$commit"; \
Comment thread
seonghobae marked this conversation as resolved.
rm -rf -- "$destination/.git"; \
import_root=''; \
python_root=''; \
candidate_count=0; \
for candidate in \
"$destination/src/$import_name" \
"$destination/src/$import_name.py" \
"$destination/$import_name" \
"$destination/$import_name.py"; do \
if [ -e "$candidate" ] || [ -L "$candidate" ]; then \
import_root="$candidate"; \
candidate_count=$((candidate_count + 1)); \
fi; \
done; \
if [ "$candidate_count" -ne 1 ]; then \
printf 'locked VCS source %s has a missing or ambiguous import root for %s\n' \
"$repository" "$import_name" >&2; \
exit 1; \
fi; \
if [ -L "$import_root" ] \
|| { [ -d "$import_root" ] \
&& { [ ! -f "$import_root/__init__.py" ] \
|| [ -L "$import_root/__init__.py" ]; }; }; then \
printf 'locked VCS source %s has a namespace or linked import root for %s\n' \
"$repository" "$import_name" >&2; \
exit 1; \
fi; \
if find "$destination" -type l -print -quit | grep -q .; then \
printf 'locked VCS source %s contains a symbolic-link layout\n' \
"$repository" >&2; \
exit 1; \
fi; \
if find "$destination" -type f \
\( -name '*.so' -o -name '*.pyd' -o -name '*.dll' -o -name '*.dylib' \) \
-print -quit | grep -q .; then \
printf 'locked VCS source %s contains a compiled extension\n' \
"$repository" >&2; \
exit 1; \
fi; \
if find "$destination" -type d \
\( -name '*.dist-info' -o -name '*.egg-info' \) \
-print -quit | grep -q .; then \
printf 'locked VCS source %s contains installed distribution metadata\n' \
"$repository" >&2; \
exit 1; \
fi; \
case "$import_root" in \
"$destination/src/"*) python_root="$destination/src" ;; \
*) python_root="$destination" ;; \
esac; \
printf '%s\n' "$python_root" >>"$path_file"; \
Comment thread
seonghobae marked this conversation as resolved.
dependency_index=$((dependency_index + 1)); \
done <"$dependency_list"; \
Comment thread
seonghobae marked this conversation as resolved.
rm -f -- "$dependency_list"; \
chmod -R a+rX /opt/base-vcs-dependencies "$path_file"
COPY install-base-python-locks.py /usr/local/libexec/install-base-python-locks.py
Comment thread
seonghobae marked this conversation as resolved.
RUN python3 -I /usr/local/libexec/install-base-python-locks.py \
--requirements-root /tmp/base-python-requirements \
&& rm -rf /tmp/base-python-requirements \
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pr-review-merge-scheduler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -485,14 +485,14 @@ jobs:
GH_TOKEN: ${{ secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || steps.scheduler_app_token.outputs.token || github.token }}
TARGET_REPOSITORY: ${{ steps.targeted_dispatch.outputs.repository }}
TARGET_DEFAULT_BRANCH: ${{ steps.targeted_dispatch.outputs.base_branch }}
SCHEDULER_ACTIONS_TOKEN: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.target_repository != '' && (secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || steps.scheduler_app_token.outputs.token) || github.token }}
SCHEDULER_ACTIONS_TOKEN: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.target_repository != '' && github.event.client_payload.target_repository != github.repository && (secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || steps.scheduler_app_token.outputs.token) || github.token }}
# Same-repository dispatch credential: when this scheduler runs inside
# ContextualWisdomLab/.github (the repository the required workflows are
# dispatched on), the runner token can dispatch them without any
# cross-repository PAT. The scheduler only uses it when
# GITHUB_REPOSITORY equals the dispatch repository.
SCHEDULER_DISPATCH_TOKEN: ${{ github.token }}
SCHEDULER_READ_TOKEN: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.target_repository != '' && (secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || steps.scheduler_app_token.outputs.token) || github.token }}
SCHEDULER_READ_TOKEN: ${{ github.event_name == 'repository_dispatch' && github.event.client_payload.target_repository != '' && github.event.client_payload.target_repository != github.repository && (secrets.PR_REVIEW_MERGE_TOKEN || secrets.OPENCODE_APPROVE_TOKEN || steps.scheduler_app_token.outputs.token) || github.token }}
Comment thread
seonghobae marked this conversation as resolved.
SCHEDULER_MUTATION_TOKEN_SOURCE: ${{ secrets.PR_REVIEW_MERGE_TOKEN != '' && 'PR_REVIEW_MERGE_TOKEN' || secrets.OPENCODE_APPROVE_TOKEN != '' && 'OPENCODE_APPROVE_TOKEN' || steps.scheduler_app_token.outputs.available == 'true' && 'opencode-app' || 'github-token' }}
SCHEDULER_REQUIRED_WORKFLOW_REPOSITORY: ContextualWisdomLab/.github
SCHEDULER_ALLOW_CROSS_REPO_REPOSITORY_DISPATCH: ${{ (secrets.PR_REVIEW_MERGE_TOKEN != '' || secrets.OPENCODE_APPROVE_TOKEN != '') && 'true' || 'false' }}
Expand Down
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
<!-- CWL-ENTRY -->
> **Agents: read the master context FIRST.** Before any work, read [`docs/CWL-MASTER-CONTEXT.md`](docs/CWL-MASTER-CONTEXT.md) (mission · naruon-as-platform + inter-component UML · cross-cutting disciplines · conventions · roadmap · current state), the live **GitHub Project #1** <https://github.com/orgs/ContextualWisdomLab/projects/1> (work/roadmap source of truth), the full spec **ContextualWisdomLab/naruon#974**, and operate the Project per [`docs/agent-github-project-protocol.md`](docs/agent-github-project-protocol.md). The repo/Project — not any private agent memory — is the source of truth.

Materialize accepts only exact SHA-256 pins or a bounded relative `-r` include (no `.`/`..`); a lone `--require-hashes` directive is not trust evidence. See [`docs/doctoring/hourly-nvidia-nim-autofix.md`](docs/doctoring/hourly-nvidia-nim-autofix.md).
Materialize accepts only exact SHA-256 pins, a bounded relative `-r` include
(no `.`/`..`), or an organization-owned HTTPS Git source pinned to a full
commit and exposed without running build hooks; a lone `--require-hashes`
directive is not trust evidence. See
[`docs/doctoring/opencode-exact-vcs-dependency-evidence.md`](docs/doctoring/opencode-exact-vcs-dependency-evidence.md).
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).
Expand Down
10 changes: 10 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ 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.
An exact-base `uv.lock` may additionally expose source from an organization-owned
GitHub repository pinned to a full commit: the secret-free image build verifies
the fetched revision and makes its source importable without running package
build or installation hooks. Pull-request execution remains networkless.
Root-level lock files are independent environments unless an explicit include
relationship says otherwise; only one unambiguous two-file supplement pair may
be recovered together, so unrelated toolchains cannot create a synthetic
resolver conflict.

## Related durable documents

Expand All @@ -157,6 +165,8 @@ trusted `uv` exporter is downloaded from the literal GitHub Releases URL for
— current increment's repair-worker decision and APA 7th citations.
- [`docs/doctoring/opencode-llm-review-publication.md`](docs/doctoring/opencode-llm-review-publication.md)
— LLM probe publication without inventing observed proof.
- [`docs/doctoring/opencode-exact-vcs-dependency-evidence.md`](docs/doctoring/opencode-exact-vcs-dependency-evidence.md)
— import-only exact source dependencies for networkless coverage.
- [`docs/doctoring/fast-mlsirm-hourly-review-caller.md`](docs/doctoring/fast-mlsirm-hourly-review-caller.md)
— product-specific psychometric repair heartbeat and scientific gates.
- [`docs/doctoring/exact-artifact-sbom-attestation.md`](docs/doctoring/exact-artifact-sbom-attestation.md)
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ Semantic Versioning where the repository publishes a release.

## [Unreleased]

- Fix OpenCode coverage evidence for exact-base, organization-owned Python VCS
dependencies without weakening registry hashes or the networkless PR sandbox,
reject namespace, ambiguous, linked, native-extension, and installed-metadata
layouts, and make exact roots readable by the unprivileged coverage user.

### Added

- Added an hourly organization commercial-readiness coordinator that discovers writable repositories, honors enabled dedicated writer leases and fully paginated live writer runs, refetches exact repository/workflow/run/PR state before dispatch, rotates bounded review-repair and opt-in NVIDIA OpenCode product-development targets, fails nonzero on fleet-wide inspection or dispatch outages, retains three-day JSON receipts, and keeps the existing 15-minute merge scheduler authoritative.
Expand Down Expand Up @@ -40,6 +45,18 @@ Semantic Versioning where the repository publishes a release.

### Fixed

- Used the receiving repository's workflow token for same-repository scheduler
Actions inventory and read calls, while retaining the established mutation
credential chain. An exhausted organization-wide OpenCode App installation
budget can no longer prevent a central `.github` PR from dispatching its
exact-head review; cross-repository targets still require an explicit
credential.
- Kept independently valid root-level Python lock environments separate during
trusted base coverage installation. A directory with more than two candidate
locks no longer collapses unrelated OpenCode, security, and application
environments into one impossible resolver transaction; incomplete hash
closures remain skipped, while each complete hash-pinned closure installs
independently.
- Rotated `org-queue-sweep`'s repository walk order by the workflow's own run number before applying the shared organization-wide review-dispatch/branch-update budget, so a fixed early repository in the unsorted `gh api /orgs/{org}/repos` walk order can no longer permanently starve every later repository's ready, all-green, zero-open-thread pull requests of the single per-tick dispatch (`ContextualWisdomLab/.github#1219`). The total per-tick budget is unchanged; only which repository consumes it rotates.
- Forward `trigger_reviews=true` explicitly from the trusted OpenCode mention wrapper to the authoritative scheduler while retaining GitHub's ten-key dispatch limit. Source-comment identity remains bound in the verified invocation claim and durable ledger instead of occupying an unused scheduler field, so a successfully routed `@opencode-agent` request now dispatches review work rather than entering queue maintenance with reviews disabled.
- Allowed an allowlisted base repository's open fork-head PR to enter the central exact-head OpenCode review path. The scheduler and privileged reviewer still re-read the live PR, bind base/head refs and SHAs, reject malformed repository identities, keep fork source as untrusted data, preserve the existing maintainer-writable update rule, and reserve the final external-head merge for a maintainer.
Expand Down
32 changes: 32 additions & 0 deletions docs/doctoring/fork-head-review-dispatch.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,31 @@ repository match, exact-head revalidation before OIDC/model work, canonical
head-repository validation, and the absence of the former same-repository
guard.

## Same-repository credential isolation

Targeted scheduler runs `32556458196` and `32556607016` revalidated
`.github#1210` at the exact current head, then stopped before review dispatch
because their general Actions inventory read used an exhausted organization-wide
OpenCode App installation token. The scheduler already carried the receiving
repository's `github.token`, but selected the App for every targeted dispatch,
including the same repository.

Same-repository `SCHEDULER_ACTIONS_TOKEN` and `SCHEDULER_READ_TOKEN` now use the
job-scoped `github.token`. Cross-repository reads retain the explicit PAT/App
chain, and `GH_TOKEN` retains the existing mutation chain, so this does not
grant the workflow token sibling-repository access or make it authoritative for
branch mutation. This separates the repository-local rate-limit bucket from the
shared App installation bucket and follows GitHub's documented authentication
rate-limit scopes (GitHub, Inc., n.d.-c). The existing
`SCHEDULER_DISPATCH_TOKEN` remains the repository token because GitHub explicitly
permits `repository_dispatch` created with `GITHUB_TOKEN` to start a workflow
(GitHub, Inc., n.d.-d).

The static regression requires both read and Actions-control expressions to
distinguish a same-repository target from a cross-repository target. The full
Python suite, 100% statement/branch/docstring gates, and the CI-budget Strix
shell gate remain authoritative before publication.

## APA 7th references

GitHub, Inc. (n.d.-a). *REST API endpoints for pull requests*. GitHub Docs.
Expand All @@ -50,6 +75,13 @@ GitHub, Inc. (n.d.-b). *Secure use reference*. GitHub Docs. Retrieved August
22, 2026, from
https://docs.github.com/en/actions/reference/security/secure-use

GitHub, Inc. (n.d.-c). *Rate limits for the REST API*. GitHub Docs. Retrieved
August 22, 2026, from
https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api

GitHub, Inc. (n.d.-d). *GITHUB_TOKEN*. GitHub Docs. Retrieved August 22, 2026,
from https://docs.github.com/en/actions/concepts/security/github_token

Souppaya, M., Scarfone, K., & Dodson, D. (2022). *Secure Software Development
Framework (SSDF) version 1.1: Recommendations for mitigating the risk of
software vulnerabilities* (NIST Special Publication 800-218). National
Expand Down
Loading
Loading