Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
cf014e8
test(coverage): specify nested npm metadata lock validation
seonghobae Aug 6, 2026
6032fa9
ci: add nested npm materializer trigger
seonghobae Aug 6, 2026
4b2fcee
ci: trigger nested npm metadata materializer
seonghobae Aug 6, 2026
202a91e
ci: add PR 807 materializer blank-line repair
seonghobae Aug 7, 2026
de6e8b0
ci: trigger PR 807 materializer repair
seonghobae Aug 7, 2026
3136fc7
chore(coverage): remove npm metadata materializer trigger
seonghobae Aug 7, 2026
f1439a7
chore(coverage): remove PR 807 repair trigger
seonghobae Aug 7, 2026
7a3221e
chore(coverage): remove npm metadata materializer workflow
seonghobae Aug 7, 2026
cb1024b
chore(coverage): remove PR 807 repair workflow
seonghobae Aug 7, 2026
f428ccc
chore(coverage): remove npm metadata trigger workflow
seonghobae Aug 7, 2026
9c298d7
test(coverage): define canonical-pin contract for nested npm metadata
seonghobae Aug 7, 2026
ae9d029
ci(coverage): add permanent nested npm metadata quality gate
seonghobae Aug 7, 2026
e1e0751
chore(coverage): implement nested npm metadata pins once
seonghobae Aug 7, 2026
b6efc22
chore(coverage): remove PR 807 implementation writer
seonghobae Aug 7, 2026
c03a634
chore(coverage): stage reviewed nested metadata implementation
seonghobae Aug 7, 2026
8873048
chore(coverage): apply reviewed nested metadata implementation
seonghobae Aug 7, 2026
3e0eafa
ci(coverage): run bounded nested-metadata finalizer
seonghobae Aug 7, 2026
9c542f6
chore(coverage): remove PR-controlled npm metadata writer
seonghobae Aug 7, 2026
0ce11b7
chore(coverage): remove PR-controlled npm metadata patcher
seonghobae Aug 7, 2026
94ab4f8
fix(coverage): resolve nested npm metadata through canonical pins
seonghobae Aug 7, 2026
65bfbc5
docs(coverage): define canonical npm metadata pin inheritance
seonghobae Aug 7, 2026
0c74964
chore(changelog): record canonical npm metadata pin validation
seonghobae Aug 7, 2026
675994f
fix(coverage): preserve legacy npm diagnostics before version gate
seonghobae Aug 7, 2026
62ee8d9
test(coverage): complete npm validator branch evidence
seonghobae Aug 7, 2026
d4303cc
Merge branch 'main' into fix/npm-nested-metadata-lock-validation
opencode-agent[bot] Aug 7, 2026
1dee3d2
docs(coverage): align npm explicit-port policy
seonghobae Aug 7, 2026
8185f10
test(security): reject symlinked materialization parents
seonghobae Aug 7, 2026
e2d9bbd
fix(security): reject symlinked materialization paths
seonghobae Aug 7, 2026
df190e3
fix(security): preserve symlink rejection contract
seonghobae Aug 7, 2026
8579d21
test(coverage): exercise non-directory output component rejection
seonghobae Aug 7, 2026
342c6bc
chore(npm): stage descriptor-safe output part 00
seonghobae Aug 7, 2026
ed07a11
chore(npm): stage descriptor-safe output part 01
seonghobae Aug 7, 2026
f06176e
chore(npm): stage descriptor-safe output part 02
seonghobae Aug 7, 2026
770f2d3
chore(npm): stage descriptor-safe output part 03
seonghobae Aug 7, 2026
a5a61c3
chore(npm): stage descriptor-safe output part 04
seonghobae Aug 7, 2026
7b1a08f
chore(stack): reconcile npm metadata validation with main
seonghobae Aug 7, 2026
e2fc933
test(coverage): reproduce JavaScript materializer output races
seonghobae Aug 7, 2026
c3f8f3e
test(coverage): run JavaScript output-race regressions
seonghobae Aug 7, 2026
e17af4c
fix(coverage): pin JavaScript materializer output descriptors
seonghobae Aug 7, 2026
245fe2f
test(coverage): close JavaScript materializer security branches
seonghobae Aug 7, 2026
96c2043
test(security): prove descriptor ancestry and cleanup races
seonghobae Aug 7, 2026
0d7b3e6
ci(security): execute descriptor ancestry regressions
seonghobae Aug 7, 2026
e584fba
fix(coverage): harden JavaScript materializer descriptor ancestry
seonghobae Aug 7, 2026
fbd26a4
test(coverage): preserve dir-fd capability under race instrumentation
seonghobae Aug 7, 2026
b736d83
test(coverage): preserve bounded descriptor-open failure
seonghobae Aug 7, 2026
802e90d
test(coverage): cover descriptor cleanup edge branches
seonghobae Aug 7, 2026
07fd3da
test(coverage): execute descriptor edge regressions
seonghobae Aug 7, 2026
6bbc93a
test(security): prove ancestor creation and complete rollback
seonghobae Aug 7, 2026
f851385
test(coverage): exercise existing relative directory
seonghobae Aug 7, 2026
56c368b
test(coverage): execute existing-directory regression
seonghobae Aug 7, 2026
f60beed
test(security): remove capability-masking fixture
seonghobae Aug 7, 2026
f3ef0af
fix(security): separate dir-fd capability identity from instrumentation
seonghobae Aug 7, 2026
6e0d854
fix(materializer): pin output creation and rollback
seonghobae Aug 11, 2026
59042bb
chore(stack): merge current protected main
seonghobae Aug 11, 2026
c07fce9
docs(coverage): cite RFC 3986 for npm registry origin pins
seonghobae Aug 13, 2026
8e7d0bc
fix(coverage): accept only bounded relative requirement includes
seonghobae Aug 13, 2026
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
136 changes: 136 additions & 0 deletions .github/workflows/npm-nested-metadata-validation-quality-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
name: npm Nested Metadata Validation Quality CI

on:
pull_request:
branches: [main]
paths:
- ".github/workflows/npm-nested-metadata-validation-quality-ci.yml"
- "scripts/ci/materialize_base_javascript_packages.py"
- "tests/conftest.py"
- "tests/test_javascript_materializer_creation_cleanup_security.py"
- "tests/test_javascript_materializer_descriptor_ancestry.py"
- "tests/test_javascript_materializer_existing_directory_coverage.py"
- "tests/test_javascript_materializer_output_edge_coverage.py"
- "tests/test_javascript_materializer_output_security.py"
- "tests/test_materialize_base_javascript_packages.py"
- "tests/test_npm_nested_metadata_lock_validation.py"
- "docs/doctoring/npm-nested-metadata-canonical-pins.md"
- "requirements-opencode-review-ci-hashes.txt"
- "CHANGELOG.md"
push:
branches: [main]
paths:
- ".github/workflows/npm-nested-metadata-validation-quality-ci.yml"
- "scripts/ci/materialize_base_javascript_packages.py"
- "tests/conftest.py"
- "tests/test_javascript_materializer_creation_cleanup_security.py"
- "tests/test_javascript_materializer_descriptor_ancestry.py"
- "tests/test_javascript_materializer_existing_directory_coverage.py"
- "tests/test_javascript_materializer_output_edge_coverage.py"
- "tests/test_javascript_materializer_output_security.py"
- "tests/test_materialize_base_javascript_packages.py"
- "tests/test_npm_nested_metadata_lock_validation.py"
- "docs/doctoring/npm-nested-metadata-canonical-pins.md"
- "requirements-opencode-review-ci-hashes.txt"
- "CHANGELOG.md"

concurrency:
group: npm-nested-metadata-quality-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
python-310-compatibility:
name: Python 3.10 compatibility
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout exact source revision
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- name: Set up Python 3.10
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.10"
- name: Compile implementation and contracts
run: |
python -m compileall -q \
scripts/ci/materialize_base_javascript_packages.py \
tests/conftest.py \
tests/test_javascript_materializer_descriptor_ancestry.py \
tests/test_javascript_materializer_existing_directory_coverage.py \
tests/test_javascript_materializer_output_edge_coverage.py \
tests/test_javascript_materializer_output_security.py \
tests/test_materialize_base_javascript_packages.py \
tests/test_npm_nested_metadata_lock_validation.py

python-314-quality:
name: Python 3.14 complete quality
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- name: Harden runner
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
with:
egress-policy: audit
- name: Checkout exact source revision
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- name: Set up Python 3.14
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.14"
cache: pip
cache-dependency-path: requirements-opencode-review-ci-hashes.txt
- name: Install exact hash-locked quality tooling
run: >-
python -m pip install --disable-pip-version-check --require-hashes
-r requirements-opencode-review-ci-hashes.txt
- name: Run focused tests with complete production branch coverage
run: |
python -m coverage erase
python -m coverage run --branch -m pytest -q \
tests/test_javascript_materializer_creation_cleanup_security.py \
tests/test_javascript_materializer_descriptor_ancestry.py \
tests/test_javascript_materializer_existing_directory_coverage.py \
tests/test_javascript_materializer_output_edge_coverage.py \
tests/test_javascript_materializer_output_security.py \
tests/test_materialize_base_javascript_packages.py \
tests/test_npm_nested_metadata_lock_validation.py
python -m coverage report \
--include=scripts/ci/materialize_base_javascript_packages.py \
--show-missing \
--fail-under=100
- name: Enforce complete production docstrings and compilation
run: |
python -m interrogate --fail-under 100 scripts/ci/materialize_base_javascript_packages.py
python -m compileall -q \
scripts/ci/materialize_base_javascript_packages.py \
tests/conftest.py \
tests/test_javascript_materializer_creation_cleanup_security.py \
tests/test_javascript_materializer_descriptor_ancestry.py \
tests/test_javascript_materializer_existing_directory_coverage.py \
tests/test_javascript_materializer_output_edge_coverage.py \
tests/test_javascript_materializer_output_security.py \
tests/test_materialize_base_javascript_packages.py \
tests/test_npm_nested_metadata_lock_validation.py
- name: Run complete central regression suite
run: |
python -m coverage erase
python -m coverage run -m pytest tests -q
python -m coverage report --show-missing --fail-under=100
- name: Verify clean patches
run: git diff --check
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@

<!-- 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/npm-nested-metadata-canonical-pins.md`](docs/doctoring/npm-nested-metadata-canonical-pins.md).
99 changes: 99 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Architecture — ContextualWisdomLab `.github`

This repository is the organization control plane. It is not naruon and it
does not own product data. Sibling products remain standalone modules; this
repo publishes org profile assets, reusable required workflows, and the
review/merge schedulers those products consume.

## System context

```mermaid
flowchart LR
Buyer["Commercial buyer / reviewer"]
Agents["Agents on AGENTS.md"]
Project["GitHub Project #1"]
Hub["This repo: org .github"]
Products["Owned products<br/>naruon · orchestrator · engines"]
Runner["Required workflows in each repo context"]

Buyer --> Hub
Agents --> Project
Agents --> Hub
Project --> Hub
Hub --> Runner
Runner --> Products
Products -->|"standalone or as module"| Buyer
```

## Nested npm metadata pins

```mermaid
flowchart TD
Entry["packages map entry"]
Link{"workspace link?"}
Fields{"resolved and integrity?"}
Root{"canonical root?"}
Accept["Accept after HTTPS SHA-512 pin"]
Reject["Fail closed"]

Entry --> Link
Link -->|"yes"| Accept
Link -->|"no"| Fields
Fields -->|"both"| Accept
Fields -->|"one"| Reject
Fields -->|"neither"| Root
Root -->|"yes"| Reject
Root -->|"no"| Accept
```

An explicit port, userinfo, query, or fragment is not the default npm
registry origin. Publication uses no-follow, descriptor-relative opens.

## Control-plane data flow

```mermaid
sequenceDiagram
participant PR as Pull request
participant RW as Required workflows
participant OC as OpenCode reviewer
participant SV as sandboxed_verify / web E2E
participant MS as Merge scheduler

PR->>RW: pull_request_target on trusted base
RW->>OC: bounded evidence + NVIDIA NIM / OpenCode
OC->>SV: PoC command in isolated copy
SV-->>OC: redacted stdout/stderr + command metadata
OC-->>PR: APPROVE or request changes
MS->>PR: merge only on current-head approval + green checks
```

## Trust boundaries

- Required review workflows execute **base-branch** scripts. A PR that edits
those workflows cannot widen its own `pull_request_target` token.
- Reviewer agents stay `edit: deny`. They judge; they do not implement.
- Sandbox helpers copy the workspace, drop secret environment values unless
explicitly allowlisted by **name**, and run subprocesses with `shell=False`.
- 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.

## Quality gates

`scripts/ci/` ships with 100% statement/branch coverage and 100% docstrings.
CI installs Python tools only with `pip install --require-hashes`. Contract
tests pin workflow structure and governance prose so drift fails closed.

## Related durable documents

- [`docs/CWL-MASTER-CONTEXT.md`](docs/CWL-MASTER-CONTEXT.md) — mission and
ecosystem.
- [`docs/agent-github-project-protocol.md`](docs/agent-github-project-protocol.md)
— Project #1 operation.
- [`PR_GOVERNANCE_AUDIT.md`](PR_GOVERNANCE_AUDIT.md) — live review/merge
contract.
- [`docs/doctoring/npm-nested-metadata-canonical-pins.md`](docs/doctoring/npm-nested-metadata-canonical-pins.md)
— current increment's lockfile decision and APA 7th citations.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Semantic Versioning where the repository publishes a release.

### Fixed

- Materialized base Python locks only when every package line is an exact SHA-256 pin or a bounded relative `-r`/`--requirement` include. A lone `--require-hashes` directive, a dotted include such as `./lock.txt`, or `-r other-hashes.txt` no longer enters the trusted build context.
- Accepted npm v2/v3 metadata-only nested workspace and peer locations only when one exact scoped or unscoped canonical root package carries the same version, HTTPS npm-registry tarball, and canonical SHA-512 integrity, while continuing to reject malformed identities, partial pins, metadata-only roots, alternate origins, and version drift. The decision record now cites RFC 3986 so an explicit port, userinfo, query, or fragment cannot masquerade as the default npm registry origin.
- Recorded the org control-plane architecture, including nested npm metadata pins, so agents reconstruct the lockfile trust boundary from the repo instead of private memory.
- Made JavaScript lock evidence publication fail before mutation without descriptor/no-follow capabilities, create every output component from pinned directory descriptors, and roll back only inode-matched entries from a freshly owned project subtree after late write failure.
- Bounded the Strix quality self-test's deterministic timeout fixtures to 3-second process and 5-second fake-sleep budgets so exact-head policy evidence completes inside the existing job limit without changing production Strix scanner timeouts, providers, credentials, or review semantics.
- Allowed commas and ASCII parentheses in the bounded Strix changed-file path policy so legal tracked Packrat fixtures can receive exact-head security analysis, while rejecting raw `..` components before normalization and keeping controls, backslashes, whitespace ambiguity, and shell punctuation fail-closed.
- Bound each review-agent invocation key to the wrapper's complete canonical payload, including the base branch and requesting actor; altered fields with a valid-format key now fail before durable-leader election or forwarding, and wrapper write permission is job-scoped.
Expand Down
4 changes: 3 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ Details: `README.md` and `PR_GOVERNANCE_AUDIT.md`.
- `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`,
`scorecard-governance.md`, SBOM inventory.
`scorecard-governance.md`, SBOM inventory. Doctoring records live under
`docs/doctoring/`. [`ARCHITECTURE.md`](ARCHITECTURE.md) is the control-plane
diagram for review, nested npm metadata pins, 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
Loading
Loading