Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
66c0769
test(coverage): require requirements directory lock discovery
seonghobae Aug 5, 2026
a2ecb21
ci: stage bounded requirements-directory lock repair
seonghobae Aug 5, 2026
af33520
ci(coverage): harden requirements lock repair
seonghobae Aug 5, 2026
847d476
ci: add bounded requirements-directory lock transformer
seonghobae Aug 5, 2026
9eab8bf
ci: finalize requirements-directory locks on PR reopen
seonghobae Aug 5, 2026
7daecc8
ci: correct RED lineage delta contract
seonghobae Aug 5, 2026
e1c7747
ci: repair requirements-directory locks from exact RED lineage
seonghobae Aug 6, 2026
e4daf4d
ci: remove redundant reopen branch writer
seonghobae Aug 6, 2026
34f905a
ci: retrigger focused requirements-directory repair
seonghobae Aug 6, 2026
4411934
chore(ci): verify PR 785 repair without workflow-file push
seonghobae Aug 6, 2026
011342f
fix(coverage): materialize requirements directory locks
seonghobae Aug 6, 2026
9b2660b
test(coverage): reject unpinned requirements-directory locks
seonghobae Aug 6, 2026
cb1ccb5
ci: add PR 785 global hash directive repair
seonghobae Aug 6, 2026
5967bb2
ci: trigger PR 785 hash directive repair
seonghobae Aug 6, 2026
78f4e1c
chore(coverage): remove branch-writing repair workflow
seonghobae Aug 7, 2026
c2e67b3
chore(coverage): remove repair trigger artifact
seonghobae Aug 7, 2026
d1082fb
ci: add bounded PR 785 hash boundary applier
seonghobae Aug 7, 2026
d2faf32
ci: trigger bounded PR 785 hash repair
seonghobae Aug 7, 2026
d40fc5b
test(coverage): define global hash directive trust boundary
seonghobae Aug 7, 2026
19dd0a8
chore(ci): remove PR 785 repair trigger
seonghobae Aug 7, 2026
e1cb447
chore(ci): remove PR 785 repair workflow
seonghobae Aug 7, 2026
70951de
docs(coverage): document global hash directive boundary
seonghobae Aug 7, 2026
6f37b3e
ci: add pointer-based PR 785 finalizer
seonghobae Aug 7, 2026
ea9a72b
ci: trigger pointer-based PR 785 finalizer
seonghobae Aug 7, 2026
15a8735
test(coverage): reject unpinned global-hash requirements
github-actions[bot] Aug 7, 2026
bf815ad
docs(coverage): preserve current-main changelog for requirements locks
seonghobae Aug 9, 2026
299f74d
test(coverage): reject unsafe requirements candidates before material…
seonghobae Aug 9, 2026
3be0a9d
fix(coverage): validate trusted requirement lines before materialization
seonghobae Aug 10, 2026
b2aa5f7
test(coverage): cover bounded requirements include grammar
seonghobae Aug 10, 2026
98aaae0
docs(coverage): specify trusted requirements grammar and proof boundary
seonghobae Aug 10, 2026
aff1d04
docs(coverage): record trusted requirements grammar hardening
seonghobae Aug 10, 2026
9ed86e6
docs(coverage): cite CWE-494 for requirements-directory locks
seonghobae Aug 13, 2026
d9a6de7
fix(coverage): require include targets to be candidate lock paths
seonghobae Aug 13, 2026
efd2ae8
fix(coverage): reject dotted include lock paths
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
4 changes: 4 additions & 0 deletions .github/workflows/trusted-uv-materializer-quality-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:
- "scripts/ci/materialize_base_python_requirements.py"
- "tests/conftest.py"
- "tests/test_materialize*.py"
- "tests/test_requirements_directory_lock_materialization.py"
- "tests/test_trusted_uv*.py"
- "tests/test_uv*.py"
- "tests/test_repository_branch_coverage_*.py"
Expand All @@ -20,6 +21,7 @@ on:
- "scripts/ci/materialize_base_python_requirements.py"
- "tests/conftest.py"
- "tests/test_materialize*.py"
- "tests/test_requirements_directory_lock_materialization.py"
- "tests/test_trusted_uv*.py"
- "tests/test_uv*.py"
- "tests/test_repository_branch_coverage_*.py"
Expand Down Expand Up @@ -126,6 +128,7 @@ jobs:
python -m coverage run -m pytest \
tests/test_materialize_base_python_requirements.py \
tests/test_materialize_uv_export_hash_contract.py \
tests/test_requirements_directory_lock_materialization.py \
tests/test_trusted_uv_download_contract.py \
tests/test_trusted_uv_portability_and_streaming.py \
tests/test_uv_export_isolation_contract.py \
Expand Down Expand Up @@ -153,6 +156,7 @@ jobs:
scripts/ci/materialize_base_python_requirements.py \
tests/test_materialize_base_python_requirements.py \
tests/test_materialize_uv_export_hash_contract.py \
tests/test_requirements_directory_lock_materialization.py \
tests/test_trusted_uv_download_contract.py \
tests/test_trusted_uv_portability_and_streaming.py \
tests/test_uv_export_isolation_contract.py \
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

<!-- 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).
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).
Trusted requirement includes must be normalized relative POSIX lock paths; `./` and `//` are rejected.
27 changes: 26 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,29 @@ 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.

## Requirements-directory lock gate

```mermaid
flowchart TD
Base["Authenticated base-commit blob"]
Path{"Direct child of a requirements/ directory, or conventional lock name?"}
Grammar{"Every non-directive line is an exact == SHA-256 pin or a bounded -r include?"}
Preflight{"Independent pip --require-hashes closure succeeds?"}
Accept["Materialize into the coverage image"]
Reject["Leave the file out of the networked build context"]

Base --> Path
Path -->|"no"| Reject
Path -->|"yes"| Grammar
Grammar -->|"no"| Reject
Grammar -->|"yes"| Preflight
Preflight -->|"no"| Reject
Preflight -->|"yes"| Accept
```

A global `--require-hashes` directive is not integrity evidence. CWE-494
forbids downloading code without verifying origin and digest.

## Control-plane data flow

```mermaid
Expand Down Expand Up @@ -123,4 +146,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/trusted-requirements-directory-lock-discovery.md`](docs/doctoring/trusted-requirements-directory-lock-discovery.md)
— current increment's lock-discovery decision and APA 7th citations.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ Semantic Versioning where the repository publishes a release.
- 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.
- Materialize complete hash-pinned `requirements/ci.txt` and other direct `requirements/*.txt` base-owned closures so isolated OpenCode coverage imports repository runtime dependencies without trusting pull-request metadata or broadening network access.
- 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.
- Corrected the conflict-ordering regression contract to select the conflict-specific snapshot and verification after the ordinary path adopted the same trusted helper.
- Hardened base-owned Python requirements materialization so candidate package lines require exact `==` pins with complete SHA-256 hashes and requirement includes use only normalized relative candidate lock paths; `./` and doubled-slash targets, range pins, malformed digests, pip option lines, URL/absolute/traversing/home/query/fragment/backslash/option-like includes, and include lines carrying extra inline options are rejected before the trusted build context.

### Security

Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ Details: `README.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, requirements-directory lock discovery, hourly NVIDIA NIM
repair, 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
103 changes: 103 additions & 0 deletions docs/doctoring/trusted-requirements-directory-lock-discovery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Trusted requirements-directory lock discovery

## Decision

The central OpenCode coverage image materializes dependency closures only from
regular files in the authenticated pull-request base commit. In addition to the
conventional `requirements*.txt` and `requirements.lock` names, it recognizes a
`.txt` file that is a **direct child** of a directory named `requirements`, such
as `requirements/ci.txt` or `services/scoring_service/requirements/package.txt`.

The path rule grants candidate status only. A global `--require-hashes`
directive is not trust evidence by itself. Every non-directive logical line must
be either:

- an exact package `==` requirement with one or more complete 64-hex SHA-256
`--hash=` values; or
- a two-token `-r` / `--requirement` include naming a bounded relative
candidate lock path (`requirements*.txt`, `requirements.lock`, or a
direct `.txt` child of a `requirements/` directory).

The include grammar rejects absolute paths, `..` traversal, URL/scheme syntax,
query or fragment syntax, shell-home expansion, Windows-style separators,
option-like targets, and additional inline options or hashes. Package lines
using ranges such as `>=`, truncated/non-SHA-256-looking hash values, index or
other option lines, local/direct references, and other syntax that merely
contains a `--hash=` substring do not gain trusted candidate status.

This parser is a **pre-materialization eligibility boundary**, not a dependency
solver. The exact trusted source path is recorded in the manifest and the
existing installer separately preflights every candidate as an independently
installable `pip --require-hashes` closure. That second proof remains mandatory:
pip's hash-checking mode intentionally fails when a requirement participating in
the installation is not fully hashed. Syntax qualification therefore cannot
substitute for dependency-closure proof.

CWE-494 forbids downloading source or an executable from a remote location
without verifying origin and integrity (MITRE, 2026). A global
`--require-hashes` directive therefore cannot promote an unpinned or
range-pinned line into the networked coverage image.

Unpinned notes, directive-only files, input files, deeper descendants, symbolic
links, pull-request-only files, malformed Git tree entries, and unsafe include
syntax remain excluded from the networked coverage image.

## Operational reason

Concrete environment locks are frequently organized below a `requirements`
directory and use role names such as `ci.txt` or `package.txt`. Ignoring those
safe base-owned locks leaves isolated coverage without runtime dependencies even
when the repository maintains a complete generated closure. The resulting import
failure measures the coverage image rather than the changed production code.

Conversely, treating the presence of the substring `--hash=` as trust evidence
would let a range requirement, malformed digest, pip option, or path/URL include
cross the materialization boundary. The accepted design therefore combines
base-commit provenance, a narrow grammar, and an independent pip closure
preflight rather than relying on file names or hash-looking text alone.

## Verification

- A failing contract first proved that `requirements/ci.txt` was undiscoverable.
- A later RED security contract proved that range requirements, malformed
digests, pip option lines, absolute/traversing includes, and includes carrying
extra inline options could be materialized by the earlier substring test.
- Direct `requirements/*.txt` and nested-service equivalents remain eligible.
- A deeper `requirements/nested/ci.txt` path and unrelated `docs/ci.txt` remain
ineligible.
- Exact `==` package pins with complete SHA-256 hashes are accepted; `>=` and
malformed/truncated hash forms are rejected.
- Bounded relative includes such as `--requirement requirements-other.txt` and
`-r requirements/other.txt` are accepted. Current-directory prefixes
(`./requirements/other.txt`), empty path components (`requirements//other.txt`),
URL, absolute, traversal, home-expansion, query/fragment, backslash, and
option-like forms are rejected.
- A global `--require-hashes` directive combined with an unpinned requirement is
rejected rather than promoted into the networked coverage image.
- Only qualifying base-owned candidates are emitted from realistic temporary Git
bases; unpinned `.in`, note, and hostile direct-child files remain absent.
- Exact-head Python 3.14 quality requires the focused suite, complete central
suite, 100% production statement and branch coverage, 100% public docstrings,
compilation, and security/supply-chain workflows. Python 3.10 compatibility
remains a separate minimum-runtime contract.

## References

MITRE. (2026). *CWE-494: Download of code without integrity check*.
https://cwe.mitre.org/data/definitions/494.html

Python Packaging Authority. (2026). *Install requires vs requirements files*.
Python Packaging User Guide. Retrieved August 10, 2026, from
https://packaging.python.org/en/latest/discussions/install-requires-vs-requirements/

Python Packaging Authority. (2026). *Repeatable installs*. pip documentation.
Retrieved August 10, 2026, from
https://pip.pypa.io/en/latest/topics/repeatable-installs/

Python Packaging Authority. (2026). *Requirements file format*. pip
26.1.2 documentation. Retrieved August 10, 2026, from
https://pip.pypa.io/en/stable/reference/requirements-file-format/

Python Packaging Authority. (2026). *Secure installs*. pip 26.1.2
documentation. Retrieved August 10, 2026, from
https://pip.pypa.io/en/stable/topics/secure-installs/
2 changes: 0 additions & 2 deletions scripts/ci/materialize_base_python_requirements.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,6 @@ def _is_bounded_requirement_include(line: str) -> bool:
and ".." not in include_path.parts
and _is_candidate_lock_path(include_path)
)


def _requirement_lines(content: bytes) -> list[str]:
"""Return logical requirement lines, joining backslash line-continuations.

Expand Down
Loading
Loading