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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## [0.2.14] — 2026-09-09

- Pin measure-mirror v0.41.2 and provenance-mirror v0.3.1 to their exact tagged
commits; test the corrected provenance contract through the MCP wrapper.
- Align README/tool tables and canonical/anchoring guides with the actual verification
paths, release pins and installation/reconnect boundary.

- Gate and outsider CLI recompute MIRROR-SPEC content hashes and links from a
single snapshot. Missing, empty, malformed, duplicate-key and tampered ledgers fail closed.
- Publish requires a reasoned retraction or explicit `action=result` with
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ Windsurf, any MCP client.

### Verification depth and gate migration (0.2.14)

Release pins: measure-mirror **v0.41.2**, action-mirror **v0.4.0**, and
provenance-mirror **v0.3.1**. Exact tag commits are recorded in
[`pyproject.toml`](pyproject.toml) and checked by CI. Updating the checkout alone
does not refresh an already installed dependency or a running MCP process.
Reinstall the package and reconnect the client after an upgrade; do not rewrite ledgers.

`mirror-stack-verify` now recomputes both content hashes and chain links; pointer-only
fixtures do not certify integrity. Legacy 16-hex seals are accepted with a warning.
`stack_verify_all` labels checks `HASH_RECOMPUTED`, `LOCAL_SNAPSHOT`, or `HEAD_WITNESS`.
Expand Down Expand Up @@ -79,8 +85,8 @@ reporting a resolved result, including a failure; it does not certify scientific
| `am_record` | 🪪 actions | seal an action; `target=<claim_id>` ties it to a claim |
| `am_witness` | 🪪 | pin a peer's ledger head (catches whole-file replacement) |
| `am_verify` | 🪪 | verify an action ledger's hash chain |
| `pm_verify` | 🔎 provenance | verify a file's provenance across 5 signals |
| `stack_verify_all` | 🪞🔎🪪 | whole stack in one call: chain (L1) + anchors (L3) + witness (L2) |
| `pm_verify` | 🔎 provenance | inspect 5 provenance/integrity signals; marker-only results are PROVENANCE-UNVERIFIED, never signature verification |
| `stack_verify_all` | 🪞🔎🪪 | supplied ledgers only: hash integrity (L1), optional local snapshots (L3) and pinned-head witness comparisons (L2); scope is reported |

(More granular `measure-mirror` probes are reachable via `mm_verify` — it dispatches by data key.)

Expand Down
9 changes: 7 additions & 2 deletions docs/ANCHORING.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,13 @@ ots upgrade manifest.json.ots
ots info manifest.json.ots # shows BitcoinBlockHeaderAttestation(<height>) + merkle root
```

A self-contained re-runnable script (`ots_anchor.sh`) lives alongside the standard ledgers in the
[Mirror Stack conventions](https://github.com/mirror-stack/measure-mirror/tree/main/stack).
The packaged implementation is
[`mirror_stack_mcp/ots_anchor.py`](../mirror_stack_mcp/ots_anchor.py).
Machine-local cron scripts are deployment-specific and are not shipped in the conventions directory.

The outsider `mirror-stack-verify` CLI recomputes ledger hashes but checks a supplied
OTS proof separately. It does not currently verify ledger-to-proof binding, so its
output correctly leaves this ledger's external-clock precedence unverified.

## Notes

Expand Down
6 changes: 4 additions & 2 deletions docs/STACK_CANONICAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,7 @@ measure_mirror.mm.linkage_check(path) -> (ok, message, entries) ← CANONICAL
measure-mirror's own SHA-256 seal. Not duplicated — a different, mm-specific
check used by `verify_self`'s L1 seal step.

Because `linkage_check` is the single source, the two verifiers cannot diverge;
a conformance/regression test on each side asserts they agree.
Because `linkage_check` is the single source, its two adapters cannot diverge;
a conformance/regression test on each side asserts they agree. This equivalence
does not mean the outsider CLI still performs linkage-only verification: since
0.2.14 its entry point uses `integrity.read_verified()` and recomputes hashes too.
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ dependencies = [
# action-mirror and provenance-mirror pins were labelled "v0.2.0" while
# sitting TWO commits before that tag, so an install got the pre-org-migration
# docs (stale `bhyi4/` self-references, SPEC v1.0) under a v0.2.0 label.
"measure-mirror @ git+https://github.com/mirror-stack/measure-mirror@7f8259bd3f424c5091a37be953dca669884ee7e0", # v0.41.1 — (auto-pin: was v0.41.0 11f1d768; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.40.0 3d9b007e; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.39.0 9784bce4; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.38.1 aa850516; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.38.0 815e6184; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.37.0 989da84e; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.36.0 bce68bbd; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.35.0 183c7259; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.34.0 c6965151; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.33.0 895ad803; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.32.0 21ca2893; verify via CI test_pins_are_releases + fixtures) — ㉘ vacuous both-directions on real runs (computed matched-null certificate); catalog count sync 72 + KO count guards
"action-mirror @ git+https://github.com/mirror-stack/action-mirror@22eb4c5b09578f443b59d12a8455c5493b6064ed", # v0.4.0 — (auto-pin: was v0.3.0 d59ea1df; verify via CI test_pins_are_releases + fixtures) — (auto-pin: was v0.2.0 15b0c5b7; verify via CI test_pins_are_releases + fixtures) — full 64-hex SHA-256 seals (security; legacy 16-hex verify via prefix match); org migration + SPEC v1.1 references
"provenance-mirror @ git+https://github.com/mirror-stack/provenance-mirror@92b8e6ebf948bbb671d20282de99ea9886b8607c", # v0.3.0 — (auto-pin: was v0.2.0 2d1d52d2; verify via CI test_pins_are_releases + fixtures) — full 64-hex SHA-256 seals (security; legacy 16-hex verify via prefix match); org migration + SPEC v1.1 references
"measure-mirror @ git+https://github.com/mirror-stack/measure-mirror@219058aff61f2e6c0ea84041fd47a3b616ba3d85", # v0.41.2 — explicit verification depth
"action-mirror @ git+https://github.com/mirror-stack/action-mirror@22eb4c5b09578f443b59d12a8455c5493b6064ed", # v0.4.0 — unchanged released action core
"provenance-mirror @ git+https://github.com/mirror-stack/provenance-mirror@d41df098979e84a81469eeec1a3e3b1d471c90ef", # v0.3.1 — unverified hints and synchronized guides
]

[project.optional-dependencies]
Expand Down
11 changes: 11 additions & 0 deletions tests/test_provenance_release_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""The installed MCP dependency must emit the corrected provenance contract."""
from mirror_stack_mcp import server


def test_mcp_uses_unverified_provenance_dependency(tmp_path):
path = tmp_path / "marker.txt"
path.write_bytes(b"ordinary text c2pa, no manifest or signature")
result = server.pm_verify(str(path), str(tmp_path / "pm.jsonl"))
assert result["verdict"] == "PROVENANCE-UNVERIFIED"
assert result["verification"]["signature_verified"] is False
assert result["ledger_entry"]["verdict"] == result["verdict"]
Loading