Skip to content

Commit c898c7a

Browse files
committed
fix(requirements): preserve final review context
Authenticate the exact-root final artifact independently of planning receipts. Retain full protected-base review, immutable provider proof validation and all authority, signature and execution gates. Refs #760, #768
1 parent 94fcc52 commit c898c7a

11 files changed

Lines changed: 321 additions & 27 deletions

File tree

‎.github/workflows/requirements-evidence.yml‎

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ jobs:
9696
policy_ref="origin/dev"
9797
if git cat-file -e "${policy_ref}:scripts/requirements_stack_context.py" 2>/dev/null; then
9898
if git cat-file -e "${policy_ref}:scripts/requirements_planning_context.py" 2>/dev/null; then
99-
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py | tar -x -C "$policy_root"
99+
if git cat-file -e "${policy_ref}:scripts/requirements_review_context.py" 2>/dev/null; then
100+
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py scripts/requirements_review_context.py | tar -x -C "$policy_root"
101+
else
102+
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py | tar -x -C "$policy_root"
103+
fi
100104
else
101105
git archive "$policy_ref" -- scripts/requirements_stack_context.py | tar -x -C "$policy_root"
102106
fi
@@ -1077,7 +1081,11 @@ jobs:
10771081
policy_ref="origin/dev"
10781082
if git cat-file -e "${policy_ref}:scripts/requirements_stack_context.py" 2>/dev/null; then
10791083
if git cat-file -e "${policy_ref}:scripts/requirements_planning_context.py" 2>/dev/null; then
1080-
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py | tar -x -C "$policy_root"
1084+
if git cat-file -e "${policy_ref}:scripts/requirements_review_context.py" 2>/dev/null; then
1085+
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py scripts/requirements_review_context.py | tar -x -C "$policy_root"
1086+
else
1087+
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py | tar -x -C "$policy_root"
1088+
fi
10811089
else
10821090
git archive "$policy_ref" -- scripts/requirements_stack_context.py | tar -x -C "$policy_root"
10831091
fi
@@ -1964,13 +1972,20 @@ jobs:
19641972
id: run-code-review
19651973
continue-on-error: true
19661974
env:
1975+
GH_TOKEN: ${{ github.token }}
19671976
REVIEW_BASE_BRANCH: ${{ github.base_ref }}
19681977
run: |
19691978
set -euo pipefail
19701979
validator_site="${REQUIREMENTS_VALIDATOR_ROOT}/lib/python3.12/site-packages"
19711980
isolated_specfact=("${REQUIREMENTS_VALIDATOR_ROOT}/bin/python" -I -S -c 'import sys; site_packages, trusted_core = sys.argv[1:3]; del sys.argv[1:3]; sys.path.append(site_packages); sys.path.insert(0, trusted_core); from specfact_cli.cli import cli_main; cli_main()' "$validator_site" "$TRUSTED_REQUIREMENTS_CORE")
19721981
requirements_context="artifacts/requirements-evidence/requirements-evidence-consumer.json"
19731982
[[ -s "$requirements_context" ]]
1983+
if [[ -n "${PLANNING_BASE_COMMIT:-}" ]]; then
1984+
requirements_context="${RUNNER_TEMP}/authenticated-root-review-proof.json"
1985+
python3 -I -S "${RUNNER_TEMP}/trusted-stack-context/scripts/requirements_review_context.py" \
1986+
--context "${RUNNER_TEMP}/trusted-stack-context/context.json" \
1987+
--event "$GITHUB_EVENT_PATH" --output "$requirements_context"
1988+
fi
19741989
if [[ ! "$REVIEW_BASE_BRANCH" =~ ^[A-Za-z0-9._/-]+$ ]]; then
19751990
printf 'Invalid Code Review base branch: %s\n' "$REVIEW_BASE_BRANCH" >&2
19761991
exit 1
@@ -2089,7 +2104,11 @@ jobs:
20892104
policy_ref="origin/dev"
20902105
if git cat-file -e "${policy_ref}:scripts/requirements_stack_context.py" 2>/dev/null; then
20912106
if git cat-file -e "${policy_ref}:scripts/requirements_planning_context.py" 2>/dev/null; then
2092-
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py | tar -x -C "$policy_root"
2107+
if git cat-file -e "${policy_ref}:scripts/requirements_review_context.py" 2>/dev/null; then
2108+
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py scripts/requirements_review_context.py | tar -x -C "$policy_root"
2109+
else
2110+
git archive "$policy_ref" -- scripts/requirements_stack_context.py scripts/requirements_planning_context.py | tar -x -C "$policy_root"
2111+
fi
20932112
else
20942113
git archive "$policy_ref" -- scripts/requirements_stack_context.py | tar -x -C "$policy_root"
20952114
fi
@@ -2824,11 +2843,19 @@ jobs:
28242843
id: run-final-code-review
28252844
continue-on-error: true
28262845
env:
2846+
GH_TOKEN: ${{ github.token }}
28272847
REVIEW_BASE_BRANCH: ${{ github.base_ref }}
28282848
shell: bash
28292849
run: |
28302850
set -euo pipefail
28312851
printf 'review-required=false\n' >> "$GITHUB_OUTPUT"
2852+
requirements_context="${RUNNER_TEMP}/final-requirements.json"
2853+
if [[ -n "${PLANNING_BASE_COMMIT:-}" ]]; then
2854+
requirements_context="${RUNNER_TEMP}/authenticated-root-final-review-proof.json"
2855+
python3 -I -S "${RUNNER_TEMP}/trusted-stack-context/scripts/requirements_review_context.py" \
2856+
--context "${RUNNER_TEMP}/trusted-stack-context/context.json" \
2857+
--event "$GITHUB_EVENT_PATH" --output "$requirements_context"
2858+
fi
28322859
[[ "$REVIEW_BASE_BRANCH" =~ ^[A-Za-z0-9._/-]+$ ]]
28332860
review_base_commit="$(git merge-base "origin/${REVIEW_BASE_BRANCH}" HEAD)"
28342861
[[ "$review_base_commit" =~ ^[0-9a-f]{40}$ ]]
@@ -2853,7 +2880,7 @@ jobs:
28532880
--enforcement full \
28542881
--json \
28552882
--out "${RUNNER_TEMP}/final-code-review.json" \
2856-
--requirements-evidence "${RUNNER_TEMP}/final-requirements.json"
2883+
--requirements-evidence "$requirements_context"
28572884
28582885
- name: Upload final Code Review evidence artifact
28592886
if: always() && steps.run-final-code-review.outputs.review-required == 'true'

‎CHANGELOG.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ All notable changes to this project will be documented in this file.
1010

1111
---
1212

13+
## [0.55.9] - 2026-10-12
14+
15+
### Security
16+
17+
- Authenticate unchanged finalized root Requirements proof for inherited Code Review on closed native
18+
planning children. Verify live root/context, artifact provenance, digest and bounded report identity.
19+
Preserve full review against protected dev and reject forged, non-final or stale context.
20+
21+
### Fixed
22+
23+
- Keep child planning receipts separate from execution proof so independently validated planning layers
24+
retain the immutable Code Review provider's finalized-proof requirement.
25+
1326
## [0.55.8] - 2026-10-12
1427

1528
### Security
Lines changed: 72 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,75 @@
1-
# Authored finalized review context controls
1+
# Finalized inherited review context evidence
22

3-
Date: 2026-10-12 (Europe/Berlin). Protected baseline c6af68a0, signed specification 34620aa7
4-
and compatibility specification 2557eb1b precede these unchanged authored controls.
5-
Owner djm81 approved the exact two-selector mapping a0ec5078 and prerequisite head grants.
3+
Date: 2026-10-12 (Europe/Berlin). Protected base c6af68a0 after reviewed #767. Signed specification
4+
34620aa7 precedes authored controls. Canonical two-selector mapping a0ec5078 was accepted by owner djm81.
65

7-
Actual #743 run 38303860784 passes planned reconciliation but rejects its planned receipt as finalized
8-
Code Review proof. Both actual consumer shells reproduce that defect locally: two genuine failures,
9-
zero errors/skips. The ordinary frozen-provider final positive control passes. Test fixtures model
10-
Git and artifact boundaries and are not published as execution proof.
6+
## Genuine failing-before evidence
117

12-
Authored test SHA256: ee736256f43eaf546bb93c763bdd8f5d4540e20a1bcb1cb75b3fe44d8dd2109c.
13-
The correction is preserved locally and is absent from this authored commit. Genuine native RED remains
14-
pending. Final execution, all required CI and completed review remain mandatory before separate merge
15-
approval. Target #719/#743/#751 remain unmerged.
8+
Actual #743 run 38303860784 passes authenticated planned reconciliation, then the immutable Code Review
9+
provider rejects its planning report: finalized proof requires execution_proof.run_stage=final.
10+
The final clean authored control bytes reproduce two genuine failures in 3.60 seconds, zero errors/skips,
11+
against protected behavior. The ordinary genuine-final positive control passes. Fixtures are explicitly
12+
synthetic Git/service boundary inputs and are never published as actual passing execution proof.
13+
14+
## Initial local passing candidate
15+
16+
Both actual independent/final workflow review shells now pass with the frozen provider final-context
17+
reader. They preserve full inherited protected-dev Python paths, full enforcement and unchanged genuine
18+
root proof bytes, leaving planning receipts unchanged. Producer-only, foreign/incomplete proof, foreign
19+
artifact repository, expiry, corruption, ambiguity, oversized metadata, stale root checks and changed live
20+
native head all fail closed. Ordinary finalized context remains accepted. Source helper bytes come only
21+
from protected origin/dev; live native/event resolution and root checks are repeated before retrieval.
22+
23+
Full smart suite: 3313 passed, ten skips, two existing dependency warnings, 197.71 seconds. Raw JUnit
24+
contains 3323 cases with zero failures/errors. All 787 tracked source/test/script/workflow/tool/delivery
25+
inputs match before/after execution. Expected failure/timeout/coverage console diagnostics originate in
26+
passing negative smart-test harness controls, not failing cases.
27+
28+
Format/lint, zero-error canonical typing (1522 existing warnings), YAML, strict selected OpenSpec,
29+
documentation, contracts/scenarios, three frozen audits, licenses, trust, Bandit/Semgrep and four strict
30+
manifest signatures pass. No signed module asset changed. Local SpecFact helper/test review has zero
31+
findings after resolving all new complexity/shape/type advisories; no rule or threshold is suppressed.
32+
Frozen delivery, coherent 0.55.9 source/lock metadata and exact CI export payload parity pass. Strict
33+
PyPI-ahead confirms 0.55.9 > 0.55.4. Proof-bound provider pins and all review/authority gates are retained.
34+
Repository YAML command retains existing mapping/archive style diagnostics; its successful exit is not
35+
claimed as zero formatting diagnostics. Newly authored mapping validates at planned maturity with no findings.
36+
37+
## Pending required publication
38+
39+
Owner acceptance/grants and genuine native RED are retained; unchanged-test signed implementation, exact-head provenance/final execution, required CI and completed
40+
review remain required. Local results do not substitute for those gates. Separate owner merge authorization
41+
is still required after final hosted validation. Target #719/#743/#751 remain unmerged. After protected
42+
integration, reprove root on the new base and validate both planning consumers before final readiness.
43+
44+
Full touched-Python review independently retains three unchanged promotion-fixture advisories
45+
(one naming warning and two fixture-shape information findings), exactly matching protected c6af68a0.
46+
Explicit exception: these pre-existing fixtures are outside the correction, and changing them would
47+
expand accepted proof/control scope. No new finding or rule suppression is accepted.
48+
49+
## Final compatibility-preserving candidate
50+
51+
Primary frozen provider lifecycle explicitly supports `passing-after-legacy-tdd-ledger`. Signed
52+
compatibility specification precedes a real one-failure/one-pass control: ordinary approved legacy
53+
context passes the immutable provider, while the transport-only RED field restriction rejects it.
54+
The correction removes that invented restriction and retains the provider's complete proof/basis
55+
validation, authentic exact root, artifact integrity, full inherited review and unchanged planning receipts.
56+
57+
Final clean authored bytes again reproduce two genuine failures against protected workflow behavior
58+
with zero errors/skips before restoration. Both complete actual workflow/provider controls pass, including
59+
ordinary and inherited RED/approved legacy contexts and all forgery cases. New helper/test review has
60+
zero findings; canonical types still have zero errors and the same 1522 existing warnings.
61+
62+
The full suite was repeated after this behavior correction: 3313 passed, ten skips, two existing warnings,
63+
198.52 seconds. Raw JUnit has zero failures/errors; all 787 inputs are unchanged. Test SHA256
64+
ee736256f43eaf546bb93c763bdd8f5d4540e20a1bcb1cb75b3fe44d8dd2109c. Final native proof and protected integration remain pending.
65+
66+
## Genuine native authored RED retained
67+
68+
Signed authored head `94fcc52b066d2c519727beb13165edd0da5eab14`, native run `38313685016`,
69+
artifact `11775304337` (`requirements-evidence`) reproduce two real mapped failures, zero errors/skips.
70+
Reconciler reports red/pass with no findings; the overall workflow correctly requires implementation
71+
and final execution. Artifact service SHA256 `327620bb69480d3b8246dc906a7d29e8546504ca458c1427691aeaff7120806c`
72+
and JUnit SHA256 `099c2f7c2cea3df69ff9017120bfd303bb410208253ed3d47bde8d8355024e20` verify.
73+
Authored test bytes retain SHA256 `ee736256f43eaf546bb93c763bdd8f5d4540e20a1bcb1cb75b3fe44d8dd2109c` unchanged.
74+
Exact mapping acceptance is recorded as djm81; verified signed authored-head authority comment 6133340014.
75+
Native final execution, required CI and completed review remain required before separate merge approval.

‎openspec/changes/fix-planning-review-proof-context/tasks.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22

33
- [x] 1.1 Verify actual #743 failure, protected baseline, issue metadata and dedicated worktree.
44
- [x] 1.2 Specify separate planning and finalized review contexts; mirror privately and validate strictly.
5-
- [ ] 1.3 Commit signed specification before authored controls.
5+
- [x] 1.3 Commit signed specification before authored controls.
66

77
## 2. Proof
88

9-
- [ ] 2.1 Execute actual workflow/provider controls and retain genuine failing-before evidence.
9+
- [x] 2.1 Execute actual workflow/provider controls and retain genuine failing-before evidence.
1010
- [x] 2.2 Obtain exact mapping acceptance and signed-head grant authorization.
11-
- [ ] 2.3 Publish authored controls and retain genuine native RED.
11+
- [x] 2.3 Publish authored controls and retain genuine native RED.
1212

1313
## 3. Delivery
1414

15-
- [ ] 3.1 Authenticate immutable root artifact context without reducing review scope or enforcement.
16-
- [ ] 3.2 Run applicable full quality/security/delivery/review/signature/version gates.
15+
- [x] 3.1 Authenticate immutable root artifact context without reducing review scope or enforcement.
16+
- [x] 3.2 Run applicable full quality/security/delivery/review/signature/version gates.
1717
- [ ] 3.3 Verify final signed-head native proof, authority and completed review.
1818
- [ ] 3.4 Obtain separate protected merge authorization after all required checks pass.
1919

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "specfact-cli"
7-
version = "0.55.8"
7+
version = "0.55.9"
88
description = "AI-bloat defense CLI for Python teams. Run deterministic code review, cleanup forecasts, and spec/contract evidence for AI-assisted and brownfield delivery."
99
readme = "README.md"
1010
requires-python = ">=3.11"

0 commit comments

Comments
 (0)