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
34 changes: 34 additions & 0 deletions .github/review-notes/dependency-hotfix-admission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Scoped dependency hotfix admission follow-up

This follow-up implements the Requirements admission requested after
[nold-ai/specfact-cli#782](https://github.com/nold-ai/specfact-cli/pull/782)
merged into dev. Its merge commit is
`3cf72e848a2b5a233d3f599898d6983319d375de`. The original three Requirements
checks remain failed. Security Audit passed with the exact temporary MCP
advisory exception. A merge does not convert the failed provenance into proof.

The companion protected-policy proposal is
[nold-ai/.github#4](https://github.com/nold-ai/.github/pull/4).
The implementation evaluates a separately approved HumanApprovedLateCycle
state at all three core CI boundaries. The original native report remains
failed and unchanged. Every boundary independently checks the exact source,
head/tree, policy revision, evidence, live human permission and expiry.
A previous decision sidecar grants no authority to another run.

The original eleven dependency cases remain required. Three new workflow
control cases cover native report preservation, enforced policy failures,
scoped routing and an isolated CI-only native evidence attester. Their real
pre-code workflow refusal is retained in the change's TDD evidence. The
admission implementation has independent technical review and local verification.
Protected deployment and live CI attestation verification remain pending.

This follow-up changes CI controls and their specification and tests. It does
not change application runtime, dependency pins, core version or signed module
assets. It does not supply historical native RED, suppress other findings or
authorize a protected deployment or merge. Signing is CI/CD-only. The owner
will review the exact deployment and grant payloads after implementation.

A later dependency-only package hotfix still starts from published v0.55.4
commit `d579970565530c3fd7b98bad4de90cf874c2a99d`, with a release payload check
that excludes unrelated unreleased dev runtime changes. This CI follow-up is
not a package release or a promotion of all dev commits.
591 changes: 574 additions & 17 deletions .github/workflows/requirements-evidence.yml

Large diffs are not rendered by default.

307 changes: 307 additions & 0 deletions openspec/changes/isolate-semgrep-security-runtime/TDD_EVIDENCE.md

Large diffs are not rendered by default.

113 changes: 111 additions & 2 deletions openspec/changes/isolate-semgrep-security-runtime/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

## Decision

Reuse the existing exact advisory register. Do not alter the audit engine,
workflow requirements, package identities or resolver behavior. Delete the
Reuse the existing exact advisory register. Do not alter the audit engine, package identities or resolver behavior.
The owner separately authorized narrowly scoped Requirements admission and
core CI integration on 2026-10-21. Delete the
rejected fork rather than maintain inactive producer infrastructure.

## Data
Expand Down Expand Up @@ -40,3 +41,111 @@ Earlier native replacement planning and the rejected producer remain in Git
history. Their tests, mappings, candidate attestations and publication approvals
do not establish acceptance for this scope. Companion-module migration is only
needed if a future change replaces/removes the official integration.

## Scoped CI admission

Policy PR #4 owns one live evaluator in immutable protected policy code. Core
invokes it at the producer, fresh and final Requirements reconciliation
boundaries. Its output is audit data only. Every boundary independently reads
the live exact-head grant, permission, current subject and retained evidence.
No consumer trusts an earlier sidecar as a bearer credential.

The domain has distinct NativeProvenance, HumanApprovedLateCycle and Refused
outcomes. Admission preserves the byte-identical failed native report, including
incomplete maturity and missing historical RED. Code Review consumes that real
failed report through its existing signed schema-2 interface. Its own failures
remain blocking. No signed module changes are required.

The canonical separate grant binds repository, the live numeric direct follow-up PR, issue780, change, dev
base, head branch/commit/tree, immutable policy revision, exact eleven dependency selectors and three admission controls,
source/aggregate mapping and plan identities, native run/attempt/artifact and
raw hashes, authenticated executed producer source, explicitly missing native
RED, the exact allowed provenance finding and expiry. It is unedited, unique,
issued by a currently authorized write/admin human, and at most seven days old.
The current execution independently passes every selector and matches semantic
plan/mapping identities. Historical and current byte hashes remain separate.

All JSON, archive, XML and network inputs are bounded. Duplicate/unknown fields,
unsafe archive members, malformed or skipped tests, extra findings, changed
subject/policy, stale/revoked authority, network uncertainty and expiry refuse.
No API run head SHA is claimed to prove executed workflow revision. Use verified
GitHub CI provenance when the API does not authenticate that identity. Signing
and attestation generation occur only in CI/CD. No local signing is permitted.

The implementation is prepared and reviewed before protected activation. It
must refuse before owner-approved deployment and the distinct final human grant.
Rollback disables the scoped protected policy and restores refusal while keeping
all native reports and ordinary CI gates. The generic exact-head authority and
the MCP advisory register remain separate capabilities.

Implementation sequence is updated specification, behavioral failing workflow
fixture, policy/core implementation, passing hostile-input and native-path
controls, independent review, normal hooks and CI. No immutable failed artifact
is relabelled RED or rewritten. The final deployment packet records exact code
revisions, new evidence, approval payloads, rollback and remaining owner actions.

The owner merged dependency PR #782 before this CI implementation was ready,
then authorized a separate follow-up. Current subject is the unique open dev PR
on `codex/dependency-hotfix-admission`, independently obtained through GitHub.
Its numeric PR identity is an exact canonical grant field. It inherits no old
head/tree authority. The still-open issue #780 and this active change retain
scope and tracking. The merged dependency payload remains separate from the
CI control continuation.

The isolated origin attester is restricted to the same-repository dev follow-up
on the exact admission branch. Forks and unrelated subjects skip that extra job
and retain their ordinary native Requirements checks. GitHub does not grant
fork pull-request jobs the attestation write permissions required by this job.

## Exact-ID artifact transport correction (2026-10-21)

The pinned download action applies greatest-ID-per-name filtering before explicit
ID selection. Authenticated run 39589983181 has fresh producer ID 12341352657
below old same-name ID 12341630570. One YAML-anchored inline standard-library
Python program replaces the three current-run transfers. It runs through
`/usr/bin/python3 -I -S`, never imports candidate checkout code, and preserves
artifact names, destinations, native consumers and the fourteen-case mapping.

A typed artifact subject binds repository name and numeric ID, run, head, name,
ID, destination and optional upload digest. REST metadata and exact ZIP are
fetched directly by ID. Execution artifacts require the existing independent
upload digest; producer artifacts require authenticated REST SHA-256. Transport
has HTTPS-only bounded redirects with no forwarded credentials, size bounds,
read timeouts and a total deadline. Digest verification precedes ZIP parsing.

Only portable flat regular files enter private staging; compressed bytes are
limited to 16 MiB, each file to 16 MiB, total expansion to 64 MiB, and membership
to 128 files. These exceed the observed producer's 6,582-byte ZIP and 70,093-byte
expansion; retained execution is 1,913 compressed bytes and 4,102 expanded bytes.
The verified ZIP stays in bounded memory (at most 16 MiB of archive bytes); this
avoids another filesystem lifecycle before extraction. Directory
file descriptors and no-follow opens protect parents. All members validate
before exclusive hard-link publication; existing unrelated context survives.
Publication is atomic per file, not for the whole set. An interrupted run may
leave partial evidence and retries then refuse collisions. Fresh jobs are the
recovery path. No new helper, dependency, protected policy or permission exists.

Tests execute the resolved YAML body with test-only HTTP doubles. Local RED
replays the actual pinned filter over authenticated REST records. Final live
exact-ID verification, independent review, normal hooks and fresh exact-head
authority remain required before CI acceptance. Parent owns internal wiki sync.

## Attested synthetic merge identity correction (2026-10-21)

At core head `4b25241e`, authenticated native origin records workflow revision
`21cca82b`, while the live PR merge revision is `6636108b`. Both have the exact
head, tree and ordered base/head parents, and valid GitHub signatures. Their
unsigned signed-payload text differs only in the author/committer time-zone
encoding, producing different commit IDs. The deployed policy rejects this at
`origin-source`, before a new grant can even be prepared.

Prepare a separately reviewed protected-policy correction. The equivalent-merge
path must bind both authenticated commit IDs, valid signatures, the exact
reviewed full tree and ordered two-parent ancestry containing the current head.
It retains actual attested signer/source digest and unchanged workflow bytes.
It never rewrites origin metadata, substitutes workflow SHA or weakens the human
subject binding. Strict negative controls cover wrong parents, tree, head,
signature, metadata and workflow bytes. Genuine current CI refusal is retained
before code. A new immutable core policy pin follows review, and owner approval
is required before protected deployment. The original deployed revision remains
unchanged until that approval.
27 changes: 26 additions & 1 deletion openspec/changes/isolate-semgrep-security-runtime/proposal.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ prevents a compatible upgrade. Official Semgrep 1.182.0 still requires
release exists. Expiry, unrelated advisories and other versions fail closed.
- Preserve strict audits of all three committed requirement graphs, independent
SAST, module signatures, protected authority and CI/CD-only signing.
- Implement the owner-requested scoped late-cycle admission in policy PR #4 and
its CI-only core integration. Keep the failed native report intact. A separate
exact-head human grant may admit only missing historical failing-first proof
for the eleven dependency scenarios and three new admission control cases. It grants no dependency-audit waiver,
native RED claim, merge, release or local signing.
- Authenticate the retained native evidence and execute the same immutable
protected evaluator at producer, fresh and final reconciliation. Every
consumer independently verifies live scope, approval, permission and expiry.
Policy activation, protected deployment and merging require owner approval.

## Capabilities

Expand All @@ -31,7 +40,8 @@ prevents a compatible upgrade. Official Semgrep 1.182.0 still requires

### Modified Capabilities

None.
- CI Requirements admission for only issue #780 and the direct admission follow-up to merged PR #782. Application runtime
and the ordinary native-provenance path retain their existing contracts.

## Impact

Expand Down Expand Up @@ -63,6 +73,21 @@ promotion is authorized. Final commit/tree authority remains separate.
- Only the exact reviewed MCP finding is waived before expiry. Every other
advisory, audit error, skipped dependency or expired record remains blocking.
- Required quality, review, CI and human authority gates remain enforced.
- Scoped admission is distinct from native proof, refuses all extra findings and
cannot transfer across heads, trees, policies, mappings or expired approvals.
- Genuine pre-code failures and adversarial controls verify the new admission
implementation separately from the dependency scenarios being admitted.

Sources checked 2026-10-21: [official Semgrep metadata](https://pypi.org/pypi/semgrep/json),
[upstream MCP advisory](https://github.com/modelcontextprotocol/python-sdk/security/advisories/GHSA-84m7-p3x7-pcfv).

## Direct follow-up after dependency merge

On 2026-10-21 the owner merged dependency PR #782 as dev commit
`3cf72e848a2b5a233d3f599898d6983319d375de`, then explicitly authorized a
separate core admission follow-up alongside policy PR #4. This continuation
uses branch `codex/dependency-hotfix-admission`, the same still-open issue #780,
and the exact numeric follow-up PR from live GitHub metadata. Its separate
human grant must bind that PR's own head/tree and authentic evidence. The old
PR #782 grant cannot transfer. The follow-up changes CI controls and their
verification, without changing merged dependency pins or application runtime.
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,39 @@ requirements:
selector:
runner: pytest
node_id: tests/unit/scripts/test_security_audit_gate.py::test_committed_mcp_exception_is_exact_and_time_bounded[future-review]
openspec:isolate-semgrep-security-runtime:isolated-scanner-runtime:admit-only-the-explicitly-approved-late-cycle-provenance-gap:
rationale: Enforce the owner-authorized CI-only admission independently from the dependency advisory exception and native proof.
stakeholder_refs:
- nold-ai/specfact-cli#780
touchpoints:
- id: requirements-workflow
kind: config_file
locator: .github/workflows/requirements-evidence.yml
- id: scoped-admission-controls
kind: test
locator: tests/unit/scripts/test_requirements_late_cycle_workflow.py
verification_cases:
- case_id: ADMISSION-NATIVE-BYTES-AND-ENFORCEMENT
scenario_id: admit-only-the-explicitly-approved-late-cycle-provenance-gap
method: test
intent: Exercise all three real reconciliation boundaries, preserve raw native bytes and enforce policy exit codes.
observable: Native success remains independent and scoped failure proceeds only through the enforced separate decision.
selector:
runner: pytest
node_id: tests/unit/scripts/test_requirements_late_cycle_workflow.py::test_all_three_lanes_preserve_native_bytes_and_enforce_policy_exit
- case_id: ADMISSION-SCOPE-AND-PROOF-GUARDS
scenario_id: admit-only-the-explicitly-approved-late-cycle-provenance-gap
method: test
intent: Reject invalid PR contexts and other branches and preserve invalid native RED refusal.
observable: Unapproved scope and invalid native proof cannot silently acquire admission.
selector:
runner: pytest
node_id: tests/unit/scripts/test_requirements_late_cycle_workflow.py::test_fresh_and_final_preserve_scope_and_invalid_red_guards
- case_id: ADMISSION-ISOLATED-NATIVE-ORIGIN
scenario_id: admit-only-the-explicitly-approved-late-cycle-provenance-gap
method: test
intent: Require an isolated CI-only origin attester with immutable official actions and no candidate execution.
observable: The manifest validates native artifact metadata and CI wires an isolated attestation step after producer failure.
selector:
runner: pytest
node_id: tests/unit/scripts/test_requirements_late_cycle_workflow.py::test_origin_attestation_survives_producer_failure
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"schema_version": "1",
"decision": "accepted",
"reviewer_id": "Codex:/root/expanded_selector_map_review",
"reviewer_role": "independent AI code reviewer",
"recorded_at": "2026-10-21T08:58:05.627991+00:00",
"reference": "https://github.com/nold-ai/specfact-cli/pull/782",
"mapping_digest": "sha256:9be3a10b220655e55c299b9b3d69c2be0c0b029b1db1c0942abfea1ea6c4f86d"
"reviewer_id": "Codex:/root/admission_final_mapping_acceptance",
"reviewer_role": "independent AI technical mapping reviewer",
"recorded_at": "2026-10-21T10:34:11.586358+00:00",
"reference": "https://github.com/nold-ai/specfact-cli/issues/780",
"mapping_digest": "sha256:c3fd8ebfa8b872f5ba12eee146ae2bdf9fa60a4c9c9a318450d528c4b4215318"
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,57 @@ or expiry. No Semgrep fork or conflicting dependency override SHALL be adopted.
- **GIVEN** the reviewed record with a different version, advisory, skipped subject or date after expiry
- **WHEN** the existing audit gate evaluates that input
- **THEN** it returns a failure instead of suppressing the finding.

### Requirement: Admit only the explicitly approved late-cycle provenance gap

For only issue #780 and the owner-authorized direct follow-up to merged PR #782
on branch `codex/dependency-hotfix-admission`, CI MAY
admit missing historical failing-first proof through a separately approved
HumanApprovedLateCycle decision from immutable protected policy code. Every
producer, fresh and final boundary SHALL independently authenticate its inputs,
exact subject and policy, live human permission and unedited bounded approval.
The native report SHALL remain failed and byte-identical. Admission SHALL NOT
claim native RED, verified provenance, waive other findings, alter application
runtime, bypass Code Review, or authorize protected deployment or merge.

#### Scenario: Exact scoped admission retains the failed native report

- **GIVEN** authenticated exact-head evidence, all eleven dependency selectors and three admission controls passing, and a separate unexpired human grant
- **WHEN** the immutable protected evaluator runs independently at each CI boundary
- **THEN** it emits HumanApprovedLateCycle with the raw failed native report unchanged and keeps the independent Code Review gate enforced.

#### Scenario: Substitution or expired authority remains blocking

- **GIVEN** missing or changed policy, subject, evidence, selectors, permission, grant, expiry, or an additional failed obligation
- **WHEN** any CI boundary evaluates admission
- **THEN** it refuses and preserves the original report and every required check.

#### Scenario: Ordinary native proof retains its existing gate

- **GIVEN** valid complete native failing-first proof outside the scoped exception
- **WHEN** Requirements reconciles it
- **THEN** the existing native success path remains independent of late-cycle approval.

#### Scenario: Unrelated and fork pull requests do not start the attester

- **GIVEN** a fork, another repository, base or branch, or an absent native artifact
- **WHEN** CI evaluates the origin attester job
- **THEN** it skips that job and retains ordinary Requirements enforcement without requesting signing permissions for that subject.

#### Scenario: Exact artifact IDs survive same-name reruns

- **GIVEN** the bound producer or execution artifact ID and another artifact with the same name and a greater numeric ID
- **WHEN** any of the three current-run evidence transfers restores its artifact
- **THEN** it retrieves the requested immutable ID directly, authenticates repository numeric identity, run, head, name, expiry, SHA-256 and size, and requires the independent execution upload digest.

#### Scenario: Artifact bytes enter only as bounded inert evidence

- **GIVEN** authenticated exact-ID metadata and ZIP bytes
- **WHEN** the shared isolated workflow-owned program restores evidence
- **THEN** credentialed transport remains on the fixed GitHub API, HTTPS redirects never forward the token, digest verification precedes bounded flat regular-file extraction, all files validate in staging before exclusive publication, and unsafe paths, links, collisions or uncertain inputs fail closed while preserving unrelated context.

#### Scenario: Authenticated equivalent synthetic merge revisions

- **GIVEN** an attested workflow revision and current GitHub PR merge revision have different IDs but the same exact reviewed full tree and ordered two-parent ancestry
- **WHEN** the scoped policy verifies historical native origin for the unchanged head
- **THEN** it may accept that equivalent signed merge only after authenticated commit identity, valid signatures, exact head/tree/parents, unchanged workflow bytes and the existing exact source-digest attestation verification pass; mismatched ancestry, content, signatures or source still refuse.
Loading
Loading