211 lines
11 KiB
Markdown
211 lines
11 KiB
Markdown
# DGR-025 evidence — exact artifact and runtime recipe identity
|
|
|
|
**Completed:** 2026-07-17
|
|
**Branch:** `ralph/fable-architecture-loop` (Claude Fable architecture lane)
|
|
**Authority:** `.scratch/distributed-gguf-runtime/prd.json`
|
|
**Dependencies:** DGR-018 (`evidence/DGR-018/README.md` — canonical backlog schema and
|
|
issue projection), DGR-021 (`evidence/DGR-021/README.md` — versioned activation
|
|
envelope). Both read before changing code.
|
|
|
|
## Objective
|
|
|
|
Ensure the tracker and worker only combine numerically and operationally
|
|
compatible shards: fingerprint every axis that moves the numbers, bind shards to
|
|
exact half-open ranges, fail closed on any mismatch, and keep uncertified
|
|
recipes registered-but-dark.
|
|
|
|
## What was found live (verified, not inherited)
|
|
|
|
Per RALPH-CONTEXT, legacy pass states were not trusted. The DGR-003-lineage
|
|
identity core was inspected and exercised live before any change:
|
|
|
|
- `packages/node/meshnet_node/runtime_recipe.py` — node-side identity:
|
|
domain-separated digests (`meshnet.model-artifact.v1`,
|
|
`meshnet.runtime-recipe.v1`, `meshnet.shard-binding.v1`) over the source
|
|
artifact SHA (`source_digest`, with split artifacts bound to their exact
|
|
source via `DerivativeBinding`), tokenizer revision (pin-enforced),
|
|
architecture adapter + architecture/config digest, boundary and protocol
|
|
schema versions, backend, weight quantization, activation/compute dtypes, and
|
|
KV dtype/layout (`RECIPE_AXES`). Shard ranges are half-open
|
|
(`shard_start`/`shard_end`, end-exclusive, protocol convention) with no
|
|
topology or quant constants anywhere; `check_route` accepts any tiling of
|
|
`[0, layer_count)`. Route, handshake (`check_handshake`), and session-open
|
|
(`check_session_open`) checks fail closed with structured `RouteMismatch`
|
|
reasons mapped to specific protocol error codes (`handshake_error`).
|
|
- `packages/tracker/meshnet_tracker/recipe.py` — deliberately independent
|
|
tracker re-derivation (no `meshnet_node` import); declared fingerprints are
|
|
recomputed, never trusted (`parse_identity`, `FingerprintMismatch`). The
|
|
`CertificationLedger` keeps every registered recipe dark until a real
|
|
distributed forward — at least 2 distinct nodes, whole-model coverage,
|
|
non-synthetic, tokens actually generated — certifies it; dark recipes may
|
|
route only to certify.
|
|
- The two implementations are pinned by committed conformance vectors
|
|
(`tests/data/recipe_fingerprint_vectors.json`).
|
|
|
|
Live verification of that pre-existing core before changes:
|
|
`PYTHONPATH=packages/node:packages/tracker python3 -m pytest -q tests/test_runtime_recipe_identity.py`
|
|
→ `45 passed`; plus `tests/test_native_identity_emission.py`,
|
|
`tests/test_tracker_capability_admission.py`, `tests/test_node_admission.py`
|
|
→ `59 passed`.
|
|
|
|
## Gap found and closed (this story's change)
|
|
|
|
**The `runtime_version` recipe axis was a label, not a pin.** It was an opaque
|
|
caller-supplied string: nothing derived it from the DGR-027 lock manifest, and
|
|
neither identity implementation rejected a moving reference (`"latest"` was
|
|
accepted), so two workers could run different llama.cpp pins or patch stacks
|
|
under one label and still agree on the recipe digest. The acceptance criterion
|
|
explicitly requires fingerprinting the "runtime pin/patch stack".
|
|
|
|
### Changed files
|
|
|
|
- `packages/node/meshnet_node/runtime_pin.py` (new) — derives the canonical
|
|
`runtime_version` axis value from the DGR-027 lock workspace
|
|
(`packages/node/native/llama`):
|
|
`<runtime>@<40-hex upstream commit>+patchstack.<sha256>` where the stack
|
|
digest commits, under the `meshnet.runtime-patch-stack.v1` domain, to the
|
|
*ordered* `(patch name, patch bytes sha256)` stack. Fails closed on: missing
|
|
or malformed `UPSTREAM_LOCK.json`, unknown schema version, non-40-hex/moving
|
|
commit, `UPSTREAM_COMMIT` disagreement, any disagreement among the lock's
|
|
`patch_series`, `patches/series`, and `patches/SHA256SUMS`, a missing patch
|
|
file, or a patch whose bytes don't match their recorded digest. Reads the
|
|
committed manifest only; fetching/patching stays with
|
|
`scripts/llama_cpp_dependency.py` (DGR-027).
|
|
- `packages/node/meshnet_node/runtime_recipe.py` — `runtime_version` is now
|
|
pin-enforced (`_require_pin`) exactly like `tokenizer_revision`; for the
|
|
llama.cpp backend it must also match the canonical
|
|
`llama.cpp@<40-hex>+patchstack.<64-hex>` grammar.
|
|
- `packages/node/meshnet_node/native_backend.py` — the production native
|
|
identity seam no longer accepts a caller-supplied runtime string. It derives
|
|
`runtime_version` directly through `load_runtime_pin()` from the committed
|
|
lock and rejects a non-llama backend at this llama.cpp-specific boundary.
|
|
- `packages/tracker/meshnet_tracker/recipe.py` — the independent tracker
|
|
implementation applies the same backend-specific grammar before re-deriving
|
|
the recipe digest, so forged operator labels cannot register or certify.
|
|
- `tests/test_runtime_pin_identity.py` and
|
|
`tests/test_native_identity_emission.py` — deterministic tests cover lock
|
|
derivation, production native emission, and node/tracker rejection of the
|
|
forged values from independent review. Conformance vectors were regenerated
|
|
through `scripts/gen_recipe_fingerprint_vectors.py` for the tightened wire
|
|
contract.
|
|
|
|
### Backlog-consistency repair (pre-existing damage, honestly recorded)
|
|
|
|
`tests/test_ralph_prd_schema.py` had 4 pre-existing failures before this story
|
|
touched anything, left by prior sessions and the alternate-history merge:
|
|
|
|
- DGR-022 and DGR-027 were marked `passes: true` without `completionNotes` and
|
|
without regenerated issue projections. Added their `completionNotes`
|
|
(explicitly labeled as added during this repair, content drawn from their own
|
|
evidence READMEs) and regenerated
|
|
`issues/022-…` / `issues/027-…` via `scripts/ralph_prd_schema.py render`.
|
|
- Three pre-DGR legacy GLM alpha issue files (`18-…`, `19-…`, `20-…`,
|
|
committed 2026-07-14, before DGR-018 established the generated-only
|
|
convention; they carry no authority disclaimer because they are *not*
|
|
generated from prd.json) were relocated via `git mv` to
|
|
`issues/legacy/` — preserved as provenance, out of the generated namespace.
|
|
|
|
### prd.json
|
|
|
|
Marked `DGR-025.passes = true` with `completionNotes`; regenerated
|
|
`issues/025-define-exact-artifact-and-runtime-recipe-identity.md`.
|
|
|
|
## Acceptance criteria → evidence
|
|
|
|
1. **Fingerprint all axes** — `RECIPE_AXES` + `ArtifactIdentity` cover source
|
|
artifact SHA, tokenizer revision, architecture adapter/version (adapter axis
|
|
+ architecture/config digest), boundary schema (boundary + protocol schema
|
|
versions), backend, quant, activation/compute dtype, KV/state layout; the
|
|
runtime pin/patch stack is now committed via the derived `runtime_version`
|
|
axis (`runtime_pin.py`). Verified by `test_runtime_recipe_identity.py` and
|
|
`test_runtime_pin_identity.py`.
|
|
2. **Exact half-open range, no hardcoded topology/quant** — `ShardIdentity`
|
|
end-exclusive ranges, `DerivativeBinding` coverage checks, `check_route`
|
|
tiling over arbitrary layouts; quant/dtype values are open strings
|
|
(dynamic recipe inputs). Verified by `test_runtime_recipe_identity.py`
|
|
(routes of 1, 2, and 5 shards; no product constants).
|
|
3. **Fail closed on any mismatch** — artifact, adapter, boundary/schema, cache
|
|
layout, backend, and runtime mismatches each produce structured
|
|
`RouteMismatch` reasons and protocol error codes; the tracker recomputes
|
|
digests and rejects inconsistent claims; moving runtime references are now
|
|
rejected on both sides.
|
|
4. **Registered-but-dark** — `CertificationLedger`: unknown recipes cannot be
|
|
certified, registered recipes are dark, only a real ≥2-distinct-node
|
|
whole-model non-synthetic forward promotes; verified by
|
|
`test_runtime_recipe_identity.py` / `test_tracker_capability_admission.py`.
|
|
5. **Gates + this handoff** — below.
|
|
|
|
## Commands and results
|
|
|
|
```bash
|
|
PYTHONPATH=packages/node:packages/tracker python3 -m pytest -q tests/test_runtime_pin_identity.py
|
|
```
|
|
```text
|
|
23 passed in 0.15s
|
|
```
|
|
|
|
```bash
|
|
PYTHONPATH=packages/node:packages/tracker python3 -m pytest -q \
|
|
tests/test_runtime_pin_identity.py tests/test_runtime_recipe_identity.py \
|
|
tests/test_native_identity_emission.py tests/test_tracker_capability_admission.py \
|
|
tests/test_node_admission.py tests/test_node_capability.py tests/test_recipe_benchmark.py
|
|
```
|
|
```text
|
|
202 passed, 1 warning in 5.38s
|
|
```
|
|
|
|
```bash
|
|
PYTHONPATH=packages/node:packages/tracker python3 -m pytest -q tests/test_ralph_prd_schema.py
|
|
```
|
|
```text
|
|
108 passed
|
|
```
|
|
(4 failed before this story's backlog repair; 0 after.)
|
|
|
|
```bash
|
|
python3 -m compileall -q packages tests # exit 0
|
|
git diff --check # exit 0
|
|
python3 scripts/ralph_prd_schema.py validate .scratch/distributed-gguf-runtime/prd.json
|
|
# OK: 55 stories validated.
|
|
```
|
|
|
|
Default tests are model-download-free, API-credit-free, and GPU-free; no model
|
|
artifact was touched and nothing was written under `/home`.
|
|
|
|
## Limitations
|
|
|
|
- The production native identity seam now derives the manifest pin and cannot
|
|
accept an operator-supplied runtime label. It still cannot attest that the
|
|
running binary was built from those locked bytes. Embedding the patched-tree
|
|
hash at build time and echoing it through the DGR-022 status contract belongs
|
|
with DGR-028+/DGR-031; real distributed certification remains the final trust
|
|
boundary.
|
|
- The DGR-027-recorded blocker stands: `0002-dense-llama-owned-range-loader.patch`
|
|
does not apply cleanly against the pin (DGR-028). That does not affect this
|
|
story: the identity commits to the patch *bytes as committed*, which is
|
|
precisely what makes a later repaired patch a *different* runtime identity.
|
|
- No native/CMake change was made, so the native build/CTest gate is not
|
|
applicable; no llama.cpp patch content was changed, so apply/check/reverse
|
|
verification is not applicable (and is blocked by the DGR-028 defect anyway).
|
|
- Tracker routing, load balancing, billing, telemetry, and relay semantics are
|
|
untouched; the only behavior change outside the new module is the stricter
|
|
(fail-closed) rejection of moving `runtime_version` values.
|
|
|
|
## Dependency handoff
|
|
|
|
- **DGR-026** (split-GGUF provisioning): bind each provisioned split via
|
|
`DerivativeBinding` to the exact source digest recorded in its hashed
|
|
manifest; the per-split `shard_binding_digest` is what certification pins.
|
|
- **DGR-031** (`ShardEngine`): construct worker identity through
|
|
`shard_identity_from_native_report` and populate `runtime_version` from
|
|
`meshnet_node.runtime_pin.load_runtime_pin().runtime_version` — never from an
|
|
operator string. A build-time echo of the patched-tree hash through the
|
|
status contract would close the manifest-vs-binary gap noted above.
|
|
- **DGR-041** (capability registration): the tracker already re-derives and
|
|
fail-closes on presented identities (`parse_identity`); register recipes
|
|
through the `CertificationLedger` so they arrive dark.
|
|
- **DGR-044** (DeepSeek V4 Flash target): pin the target's artifact identity
|
|
the same way `glm_alpha_artifact` does — read locked manifests, never restate
|
|
digests — and note `layer_count` must count the routed transformer stack the
|
|
route tiles, excluding MTP (reserved for beta).
|