AC-039: CURRENT-SDLC v1.1 release hardening - #11
Merged
Merged
Conversation
Closes the CURRENT-SDLC v1.1 requirements that AC-038 recorded as open, without changing any runtime semantics. SECURITY.md: TRL 4 maturity boundary, main-only support statement, bounded Critical/High/Medium/Low triage policy, responsible-disclosure expectations, and an explicit statement that a passing scanner is not an audit. The private reporting route is recorded as NOT ESTABLISHED with the exact owner action needed; no address or channel was invented. Dependency advisory monitoring: .github/workflows/security.yml audits the controlled dependency set with pip-audit on push, PR and a weekly schedule, with no severity threshold and no ignore list. It also asserts advisory COVERAGE: the auditor silently drops a pin it cannot resolve and still exits 0, so an unaudited pin now fails the job rather than passing as 'no known vulnerabilities'. .github/dependabot.yml covers pip and github-actions version updates; Dependabot security alerts remain a provider setting the owner must enable, which is why the repository- controlled gate exists. Least privilege: both existing workflows now declare permissions: contents: read explicitly rather than inheriting the default token grant. Immutable action pinning: actions/checkout and actions/setup-python are pinned to the commit SHAs their v4 and v5 tags resolved to, with the version retained in a comment. Dependency identity: constraints.txt fixes the resolved closure and CI installs with -c. exceptiongroup and tomli are pinned because pytest pulls them in on Python 3.10 only, which would otherwise let the two matrix jobs resolve different sets. packaging is held at 25.0 because 26.3 has no advisory coverage and would be silently unauditable; pytest requires only packaging>=22. Hash pinning is not used and not claimed: pip cannot combine --require-hashes with an editable install. falsify.py: public falsification harness. Five cases through the real CLI - valid ALLOW, undeclared action, stale fact, untampered receipt, tampered receipt binding - each against a declared expected disposition, failing on a mismatch in either direction. CI runs it. docs/VERSIONING.md: declares the public interface surface (six commands, consumer flags, exit semantics, Python entry points, receipt fields, reason codes, file formats, workflow surface), states that 0.0.1 is a never-published placeholder and the commit SHA is the only reliable identity, and declines to claim SemVer since it is not implemented. CONTRIBUTING.md: states that no unsolicited contribution workflow exists, including that licensing makes acceptance terms unsettled. No CLA, review SLA, or governance model is invented. pyproject.toml: adds License :: Other/Proprietary License as the machine-readable statement that this is not open source. No SPDX identifier is declared, because none would be true. Choosing a license remains an owner decision. No test or guard was weakened; 342 passed throughout. No vulnerability finding was suppressed. No runtime or architectural semantics changed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Emwzah7sNdUGzJGDwbSCam
…ependency environment The controlled dependency set changes the environment the implementation runs against, so the AC-035A figures stopped being measurements of the current system. Re-ran the full AC-035/AC-035A battery and recorded it under a new result identity. benchmarks/: DUT_BASE_SHA rebound to the commit carrying the dependency control; results now written under a RESULT_SET_ID prefix so a new run cannot overwrite an earlier run's provenance. Added capture_dependency_identity(), which records declared-versus-installed versions so a run that did not measure the controlled set is detectable rather than assumed. docs/BENCHMARKS-AC-039.md: the current measurement. docs/BENCHMARKS.md is preserved byte-for-byte as the AC-035A record, under a banner marking it superseded and pointing forward. AC-035-*.json results are untouched. docs/RELEASE-READINESS.md: AC-039 addendum covering security completeness, supply-chain integrity, the vulnerability-gate result, API/version integrity, machine-readable licensing, public falsification, release-artifact applicability, and revised dispositions for U1, U5, U8, U9, U10, U11, U12, U13. New finding U14: pip-audit silently drops a pin whose exact version the advisory service has no record of, still reporting no vulnerabilities and exiting 0 even under --strict. Found by checking the auditor's output against its input rather than trusting its exit code. Closed by asserting coverage in the workflow and by pinning a version that is actually covered - not by an allowlist. Claim audit across README, AGENTS, SECURITY, CONTRIBUTING and docs/: no production-ready claim, no audit or certification claim, no reason-code stability overclaim, no branch-protection enforcement overclaim, no open-source claim, and no stale benchmark presented as a current measurement. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Emwzah7sNdUGzJGDwbSCam
… figures Phase 12 requires the refreshed measurement to describe the frozen tree, not an intermediate commit. The documentation changes in the previous commit touched README.md, which is a declared device-under-test path, so the guard correctly refused to treat the earlier results as describing this tree. DUT_BASE_SHA is rebound to 389e9ff and the full battery re-run; the guard reports verified: true with zero modified DUT paths, and dependency identity reports matches_declared_set: true. Figures in docs/BENCHMARKS-AC-039.md, docs/TRL-ASSESSMENT.md and docs/RELEASE-READINESS.md updated to this run. 7/7 E2E, 38/38 adversarial, 342 tests, determinism stable, observed sustained end-to-end throughput median 1697.5 ops/sec (min 1688.4, max 1710.8). Worth recording: the observed end-to-end median came in ABOVE the latency-derived reciprocal this run (1697.5 vs 1657.9), which is a useful demonstration that the derived figure is arithmetic rather than measurement and can err in either direction. Both are reported separately, as before. The guard was not loosened and DUT_PATHS was not trimmed to avoid the drift; the DUT was rebound and the measurement re-taken. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Emwzah7sNdUGzJGDwbSCam
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the CURRENT-SDLC v1.1 release requirements AC-038 recorded as open: Security Completeness, Supply-Chain Integrity, API/Version Integrity, Machine-Readable Licensing, and Public Falsification. No runtime or architectural semantics changed.
Security
SECURITY.md— TRL 4 maturity boundary,main-only support statement, bounded Critical/High/Medium/Low triage policy, responsible-disclosure expectations, and an explicit statement that a passing scanner is not an audit and establishes nothing about this project's own code.The private reporting route is recorded as NOT ESTABLISHED, with the exact owner action named. GitHub Private Vulnerability Reporting could not be confirmed as enabled — the repository metadata reachable from this project's tooling does not expose that setting, so its state is unknown, not enabled. No address or channel was invented; one that does not demonstrably reach someone silently swallows reports.
Supply chain
.github/workflows/security.ymlauditsconstraints.txtwithpip-audit==2.10.1on push, PR, and weekly. No severity threshold and no ignore list: any known advisory fails the job, which is stricter than the HIGH/CRITICAL floor..github/dependabot.ymlforpipandgithub-actions. Dependabot security alerts remain a provider setting the owner must enable, which is why the repository-controlled gate exists.permissions: contents: readrather than inheriting the default grant.actions/checkout@11d5960a…(v4.4.0),actions/setup-python@a26af69b…(v5.6.0), resolved from authoritative tag state.constraints.txtfixes the closure; CI installs with-c.exceptiongroupandtomliare pinned because pytest pulls them in on 3.10 only, which would otherwise let the two matrix jobs resolve different sets.Hash pinning is not used and not claimed: pip cannot combine
--require-hasheswith an editable install, which is this project's only supported install shape.Vulnerability gate result: 0 advisories across 8 pinned distributions. Nothing suppressed, no exception self-authorized.
New finding — U14
pip-auditsilently drops a pin whose exact version the advisory service has no record of, reports "No known vulnerabilities found", and exits 0 — even under--strict. Found by checking the auditor's output against its input rather than trusting its exit code:packaging==26.3resolved and installed but was never audited.Closed non-suppressively: the workflow now asserts coverage (no allowlist), and
packagingis held at25.0, which is covered.pytestrequires onlypackaging>=22, so this is the stricter choice.Versioning and licensing
docs/VERSIONING.mddeclares the public interface surface and states plainly that0.0.1is a never-published placeholder — the commit SHA is the only reliable identity. SemVer is not claimed, because it is not implemented. The one commitment made is that reason codes will not change meaning silently under the same version.pyproject.tomladdsLicense :: Other/Proprietary License— the machine-readable statement that this is not open source. No SPDX identifier is declared, because none would be true. Choosing a license remains BLOCKED-OWNER-DECISION.Public falsification
python3 falsify.py— five cases through the real CLI, each against a declared expected disposition, failing on a mismatch in either direction. 5/5 matched. CI runs it.PASS/OK/ exit 0, receipt issuedREFUSED/RUN_UNCLASSIFIED_ACTION/ exit 1, no receiptREFUSED/RUN_FACT_STALE/ exit 1, no receiptPASS/OK/ exit 0REFUSED/VEIP_RECEIPT_MISMATCH/ exit 1Refreshed measurement
The controlled dependency set changes the environment, so the AC-035A figures stopped being measurements of the current system. Full battery re-run and recorded under a new result identity in
docs/BENCHMARKS-AC-039.md;docs/BENCHMARKS.mdandAC-035-*.jsonare preserved unmodified under a superseded banner.DUT
389e9ff,verified: true,matches_declared_set: true. 7/7 E2E · 38/38 adversarial · 342 tests · determinism stable · observed sustained end-to-end throughput median 1697.5 ops/sec.The guard was not loosened and
DUT_PATHSwas not trimmed to avoid drift — the DUT was rebound and the measurement re-taken.Also
CONTRIBUTING.mdstates that no unsolicited contribution workflow exists, including that licensing makes acceptance terms unsettled. No CLA, review SLA, or governance model invented.Release-artifact provenance remains NOT APPLICABLE: no package, binary, container, installer, SDK, or Release artifact exists, and this PR creates none.
Generated by Claude Code