Repository navigation
Release/v1.4.0 - a name of its own - #19
Merged
Merged
Conversation
…ion); open v1.4.0 on the roadmap fixtures/v130 (issue 996) is the unmodified v1.3.0 engine's output at e6aef5c, LF-only, root_digest 931294a2...; it verifies lenient and strict with zero errors and zero warnings, all three attestation checks ok. TestV130Compat mirrors TestV122Compat and adds the attestation-ok test and a fourth tamper case (one byte inside the attestation turns root_digest red): 290 -> 300 passed. No engine, manifest, hook, or skill bytes change. ROADMAP gains the v1.4.0 block per PLAN_v1.4.0 Appendix D; keyless moves to v1.5.0 and attested review to v1.6.0, with the two docs mentions renumbered. PLAN_format_identity.md lands as PLAN_v1.4.0.md, approved 2026-09-19, with dated 2026-09-20 corrections to section 3.3 I1/I8, the 3.4 provenance caveat, the Step 0 roadmap row, and the T0 Files and Acceptance rows (the artifact is src/example_v130.py; v130 is the first fixture to carry an approver e-mail). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…y vs emission; media type; verification requirements) rpack-format.md gains, additively (path and the SLSA buildType heading untouched; two pre-existing lines change so they read as statements about the reference producer: the attestation section's opening sentence and the "Layout contracts" lead-in): a status-and-stability statement, an identity section (format, version, application/vnd.forgeproof.rpack+json, the .rpack collision sentence), a normative validity section written from the engine source (UTF-8 as the one byte-level rule, member table, the exact canonical serialization behind root_digest, the two-member denylist, the canonical-SSHSIG rule), "What binds a verifier" for a present attestation (the four checks the reference verifier performs; extra signature-object members, mediaType, and verificationMaterial are never by themselves grounds for rejection, verificationMaterial is opaque to the format, and a verifier that implements the Sigstore bundle rules may additionally apply them), the emission-profile clause from PLAN_v1.4.0 Appendix B.0, the verification requirements, and a format-bump checklist. docs/media-type.md is new: the single status ledger line (state A: not yet submitted), the RFC 6838 5.6 template, what a registration does and does not change, the editor snippet, the extension note, known limits, the Apple UTI note, and the upstream-submission checklist behind the sign-off gate. Detection recipes follow with the detection files. TestFormatIdentity adds seven tests (300 -> 307 passed): spec path and anchor frozen, canonical form matches the spec (code-point order, compact, lowercase \uXXXX, surrogate pairs), no floats in the four fixtures, the format marker within the first 256 bytes for the four fixtures and a fresh bundle, the forbidden-phrase sweep with the one-ledger-line rule, the attestation-wrapper tolerances the spec states, and a test pinning a documented limitation in both modes: verify resolves recorded artifact paths, and the chain-file name it builds from issue.number, as given. The template's security text therefore says SHOULD confine, says what the reference verifier does and what its verdict discloses, and says the producer's refusal dates from plugin 1.1.0; its cosign sentence states what cosign checks and what only the format's own verification binds. ROADMAP schedules the hardening with v1.5.0. PLAN_v1.4.0 is corrected in place with dated notes: Appendix A is level with the docs template (zero differing lines; OpenSSH 8.1 or later, since ssh-keygen -Y sign/verify first shipped in 8.1 per the openssh.com release notes; the D11 wording rule applied to the template itself; the two paragraphs above), Appendix C and D8 make the schema match the verifier (only dsseEnvelope is required of a present attestation), the real heading level of the buildType anchor, and one release-checklist item: an errata sweep before the tag, because the spec URL is immutable after it. No engine, manifest, hook, skill, or fixture bytes change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
schemas/forgeproof-rpack-1.schema.json is new: JSON Schema 2020-12, $id the v1.4.0 tag-pinned raw URL with a $comment stating the last-changing-release rule. It is PLAN_v1.4.0 Appendix C with description annotations taken from the specification's member table and no further constraining keyword (equal to the Appendix C block modulo descriptions, checked mechanically), less the four "minimum": 0 keywords Appendix C carried, removed from both: the member table says "integer" with no sign restriction, and a released engine (v1.1.0) can emit a negative count in a bundle every verifier passes. It describes the member table and relaxes only where the specification tells verifiers to tolerate something: unknown members at every level, and mediaType / verificationMaterial, which are described but never required or constrained; a present attestation requires only dsseEnvelope. stress/validate_schema.py is the CI driver and the only file that imports jsonschema; the engine and the pytest suite never do. Positives: the four frozen fixtures, a fresh bundle from stress/make_bundle.py, that bundle with an unknown top-level member, and that bundle with mediaType and verificationMaterial removed from its attestation. Negatives: wrong format, missing signature, version 2.0.0, two DSSE signatures, tests_passed 1.5 -- each must produce exactly one error, at the expected instance path, from the expected keyword, so none can pass by failing on something unrelated. It also checks the schema against the 2020-12 metaschema. .github/jsonschema-requirements.txt pins jsonschema==4.26.0 and its five transitive dependencies with hashes, generated by uv pip compile --generate-hashes --universal --python-version 3.11; verified to install with --require-hashes into a throwaway venv, from which the driver ran green (7 positives, 5 negatives, 0 mismatches). No workflow is edited here; the format-identity job arrives with the detection files. TestFormatIdentity adds test_schema_is_structurally_sane, stdlib only (307 -> 308 passed): the 2020-12 $schema, an absolute fragment-free $id ending in the schema's own repo path, format const and version pattern against the engine constants (2.0.0 excluded), attestation not required, no additionalProperties or unevaluatedProperties false anywhere, the attestation sub-schema's required exactly ["dsseEnvelope"], mediaType and verificationMaterial annotation-only, and neither named in any list. Shown red on scratch copies for each of those tolerances and for a broken $id. PLAN_v1.4.0 records, as dated corrections at T3-2 and above Appendix C, the two decisions made after the plan text: what the schema describes, and the added acceptance case; that the requirements file is generated with uv; and the removal of the four minimum keywords from the Appendix C block. No engine, manifest, hook, skill, workflow, or fixture bytes change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ve them against every fixture share/mime/packages/forgeproof-rpack.xml and share/magic/forgeproof are new: PLAN_v1.4.0 Appendix B.1 / B.2, opt-in files that ForgeProof never installs. One departure from the B.1 draft: its header comment spelled the xdg-mime one-liner, whose "--mode" is a double hyphen inside an XML comment. expat rejects that as not well-formed, and update-mime-database 2.1 prints "Failed to parse" and still exits 0, registering nothing. The comment now gives the copy + update-mime-database recipe and points to docs/media-type.md for the one-liner. The magic rule is B.2 verbatim. stress/check_detection.py is the CI driver, stdlib only. It copies both files under a temp dir (inside $RUNNER_TEMP when set), compiles them there (update-mime-database: rc 0, empty output, globs2 and subclasses carry the type; file -C -m), and runs gio info under an isolated XDG_DATA_HOME and file(1) over the four frozen fixtures and a fresh stress/make_bundle.py bundle in six layouts each: as written, CRLF, compact in insertion order, key-sorted, canonical, BOM-prefixed; named issue-1.rpack and noext. The limits are asserted: plain file, with or without -m, says application/json; key-sorted, canonical and BOM copies are text/plain by content and the type by glob; unrelated JSON and RP6L bytes are not claimed; a control run without the XML says text/plain. A missing tool is a failure, never a skip. 109 checks green on WSL Ubuntu 22.04 (shared-mime-info 2.1, gio 2.72.4, file-5.41); each limit shown red on scratch copies when inverted. ci.yml gains the format-identity job: apt-installs shared-mime-info, libglib2.0-bin and file with versions printed, pip-installs the hash-pinned validator, then runs stress/validate_schema.py and stress/check_detection.py. No other job installs any of them. docs/media-type.md gains "Detection files" (user-mode install and uninstall, the no-install recipe, file -e json -m and the built-in JSON precedence, the asserted results, the upstream test-list line) and two Known-limits bullets; the ledger line and the registration template are untouched. PRIVACY.md's "does not" list gains the MIME / .gitattributes / editor-settings line. TestFormatIdentity adds test_detection_files_single_sourced and test_engine_never_mentions_consumer_tools, stdlib only (308 -> 310 passed). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
.gitattributes gains "*.rpack linguist-language=JSON"; the fixtures rule is untouched, and git check-attr shows both attributes on every fixture bundle (text: unset, linguist-language: JSON). No linguist-generated. README gains a "Format identity" section under "The .rpack Bundle" (the specification, the bare type name with a pointer to the ledger, the schema and its $id, the optional .gitattributes line with the prescribed sentence, a pointer to the detection files), one requirement sentence under "Verify a bundle", four fixtures and the v1.3.0 engine in both places that counted three, and the measured test count (290 -> 311, pytest --collect-only). It says the file renders as JSON and says nothing about diffs: that has not been observed. The two "OpenSSH 8.0" lines are left as they are. CHANGELOG gains [1.4.0]: the no-bundle-byte-changed sentence, worded to hold after the release commit (a fresh bundle differs from a v1.3.0 one only where its attestation records the plugin version); four fixtures; the type as proposed with its status in docs/media-type.md; forgeproof-verify v1.1.0 remains current; what the format-identity job asserts, not a result; the schema proven against the four fixtures and fresh bundles only. PRIVACY.md's bundle table gains a Timestamps row, written from the v130 fixture: the bundle carries startedOn / finishedOn inside the attestation payload (v1.3.0+, equal to the first and last chain block times), earlier bundles carry none, and the per-block times live in the chain file beside the bundle. docs/media-type.md gains "GitHub rendering" (the same line and sentence); the editor snippet and the known limits were already there, and the ledger line and the registration template are untouched (0 differing lines against PLAN_v1.4.0 Appendix A). TestFormatIdentity adds test_skills_never_write_repo_config, stdlib only (310 -> 311 passed): no SKILL.md names .gitattributes, update-mime-database, xdg-mime, or files.associations, and the four skills must be found. Shown red on a scratch copy for each token and for a missing skill. No engine, manifest, hook, skill, schema, workflow, or fixture bytes change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…emplate, privacy, changelog
Wording findings logged since Phase 1, resolved before the tag freezes
the spec URL and the schema $id. The engine, hooks, skills, manifest and
fixtures are untouched; no JSON Schema constraint keyword changed.
Spec (rpack-format.md): BCP 14 key-word sentence; version form
1.<minor>.<patch> in Identity; LF after the SSHSIG BEGIN marker stated;
producer-list sentence no longer carries a verifier "must"; base64 rule
and the str() comparison stated as the reference verifier does them;
the MAY on verificationMaterial scoped (empty state {"publicKey": {}}
and mediaType outside it; absent, not an object, empty, or populated
all tolerated); the
three check rows vs the four numbered checks disambiguated; bump
checklist names the drivers' fixture-count pin.
Schema: three description annotations made timeless (no "today", no
"the reference producer emits"); constraints byte-for-byte unchanged;
Appendix C mirrors the two wrapper descriptions.
Registration template (docs/media-type.md == plan Appendix A, 0
differing lines): network-share path opened like any other path on
Windows; producer refusal scoped to the producing platform; chain-file
leg discloses element count and a few member values; "never a
substitute for it" agrees with the spec's MAY; sidecar files named once.
docs/media-type.md: recipes use <plugin-dir> / <your-project>
placeholders; XDG_DATA_HOME prefix on the no-install recipe (also in the
XML comment); file(1) read-limit qualifier; "most files"; "a bundle as
written"; "and diffs" (observed on GitHub).
PRIVACY.md: Last Updated, a 1.4.0 row, and the one read outside the
project that verify performs on a bundle's recorded paths.
README: OpenSSH floor 8.1 (two lines); "and diffs". CHANGELOG: bare
type name (no "proposed"), status parenthesis dropped, OpenSSH line, the
two omitted test names, the five single-sourced files, the plugin-version
footprint, the docs renumber, the exact "nothing new is run" form.
Tests (311 collected, count unchanged): tolerance test gains absent
mediaType and empty / non-object verificationMaterial; $id tag segment
pinned; list-form "file" spelling matched; two more repo-config tokens;
schema driver gains four positives (no attestation, version 1.0.0,
non-string mediaType with non-object verificationMaterial, every integer
count negative) — 11 positives, 5 negatives.
Plan errata (dated 2026-09-22): Appendix A note, Appendix C note, B.1
comment defect and "sorted (indented or minified)", section 10 row (a),
T3-2 version-example note.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
plugin.json and PLUGIN_VERSION move to 1.4.0 together (sync test); the signer-seam docstring at forgeproof.py:530 now names v1.5 (keyless); ROADMAP flips v1.4.0 from Next to Shipped, Last updated 2026-09-22, and drops the word "proposed" from the milestone text so the ledger line in docs/media-type.md stays the only statement of registration status. Engine diff against tag v1.3.0 is exactly those two lines: no bundle, manifest, hook, skill, or fixture byte changes beyond the version. forgeproof-verify v1.1.0 remains current — the verifier is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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.
v1.4.0 — A name of its own
No bundle byte changed. The bundle format stays at 1.1.0; no member is added, removed or re-typed; the code that writes, canonicalizes, signs and verifies a bundle is untouched. The engine diff against
v1.3.0is two lines:PLUGIN_VERSIONand one docstring.What this release adds is around the format, not in it:
skills/run/references/rpack-format.mdgains a stability statement, an exact definition of the canonical serialization behindroot_digest, the four attestation checks that bind a verifier, and an emission profile.$id; permissive on unknown members; validated in CI only — the engine still imports nothing.share/, proven in CI against every fixture and layout, including the documented limits.application/vnd.forgeproof.rpack+json(vendor tree), to be submitted to IANA after the tag. Its status lives in one ledger line indocs/media-type.md; nothing else states a status.fixtures/v130/) from the v1.3.0 engine — the first with an attestation.format identity (schema + detection), now a required check onmain.Tests 290 → 311.
forgeproof-verifyv1.1.0 remains current — the verifier is unchanged.Verification
b1bcae0(ubuntu, macOS, windows, debian python3-only).Merge with a merge commit, not a squash — a squash orphans the SHAs the companion
forgeproof-verifyAction pins.🤖 Generated with Claude Code