Skip to content

feat: storage lease + audit family, node key lifecycle, GPU job hints (roadmap v0.3–v0.5)#5

Merged
NetworkTheoryAppliedResearchInstitute merged 4 commits into
mainfrom
feat/lease-keylife-gpu
Jul 13, 2026
Merged

feat: storage lease + audit family, node key lifecycle, GPU job hints (roadmap v0.3–v0.5)#5
NetworkTheoryAppliedResearchInstitute merged 4 commits into
mainfrom
feat/lease-keylife-gpu

Conversation

@NetworkTheoryAppliedResearchInstitute

Copy link
Copy Markdown
Contributor

Completes the roadmap additions so SCP covers the full substrate scope — the 'complete the protocol first, thread the consumers around it' directive. Stacked on #3 (listing fields); merge order #4 (CI) → #3 → this.

Storage lease + audit — new lease package (SPEC §4.7–4.10)

Storage is a lease, not a job: StorageLease (coordinator-signed; opaque 32-byte ShardRef + quantized SizeClass only — the wire never carries true sizes or content), LeaseDecline/LeaseRelease (node-signed exits; local_policy opt-out; sovereignty includes leaving), and the audit pair: unsigned pull-fetched ProofChallenge + node-signed self-contained ProofResponse — the storage counterpart of JobReport, the fact storage payout derives from. Digest formula standardized (SHA-256(Nonce‖Offset‖Length‖range)), byte-identical to what Cloudy's internal/storage precomputes at seal time. (LeaseID, Nonce) single-use ⇒ replays dead.

Node key lifecycle — identity/keylife.go (SPEC §4.11–4.12)

KeyRotation signed by the current key (successor self-installation fails — tested), strict Seq monotonicity. KeyRevocation signed by the dying key, honored unconditionally; re-enrollment out-of-band. Closes the first-write-wins-forever gap.

GPU job hints — employment (SPEC §4.3)

JobSpec.GPUAPI + GPUMinVRAMMB, advisory like PrinterKind — assignments can now request what listings advertise.

Coordinator surface

StorageCoordinator + KeyLifecycleCoordinator as optional capability interfaces (type-asserted), so SoHoLINK can bump without implementing storage on day one.

Verification

  • 12 golden message vectors (was 6), regenerated; count guard updated.
  • Python reproducer: 55/55 ALL MATCH — six new encoders written from SPEC field orders, independently reproducing every canonical byte sequence and signature.
  • Full suite green locally (serialized — parallel go test still trips WDAC on the dev box); PR ci: Go build/vet/test + Python conformance gate #4's CI is the authoritative gate.

After merge

Tag v0.2.0 (one tag for the whole pre-consumer window rather than v0.2/0.3/0.4/0.5 separately — fewer coordinated bumps), then bump Cloudy + SoHoLINK in lockstep. Named follow-up: httpjson transport routes for the new families ride with the SoHoLINK-side implementation.

🤖 Generated with Claude Code

CapabilityListing gains first-class storage and GPU advertisement so
phones, TVs, and NAS nodes can join as storage/GPU contributors:

- WorkloadOptIn gains Storage (advisory, same SPEC 5.1 discipline as
  Compute/Print; mirrors the coordinator's existing
  compute/storage/printing opt-out trichotomy).
- Capacity gains StorageCommitMB: long-lived storage committed to the
  network (shard hosting), deliberately distinct from DiskMB job
  scratch. Encryption, sharding, and audit of stored data are
  frontend/agent concerns outside the protocol; the wire never carries
  stored content.
- New GPUs []GPUCapability{API, Model, VRAMMB}, mirroring Printers.
  Advertising a GPU is the opt-in; API in {vulkan, nnapi, cuda, metal}.
- JobSpec.Workload doc comment admits "storage".

CanonicalBytes changes (GPUs after Printers; StorageCommitMB after
DiskMB; OptIn.Storage after OptIn.Print): a breaking v0 encoding
change while v0 is declared UNSTABLE. testdata/vectors.json
regenerated; testdata/reproduce_spec.py updated and passing 43/43
against the new golden file. Consumers (Cloudy, SoHoLINK) must bump
in lockstep; tag v0.2.0 at merge.

Signed-off-by: Jodson Graves <info@ntari.org>
Completes the roadmap additions (Development/SCP-completion-roadmap.md
v0.3-v0.5) so the protocol covers the full substrate scope before its
consumers calcify around gaps.

Storage lease + audit (new package lease, SPEC 4.7-4.10). Storage is a
LEASE, not a job: StorageLease is the coordinator-signed offer (opaque
32-byte ShardRef + quantized SizeClass only -- the wire never carries
true sizes or content; encryption/padding/sharding stay frontend-side),
fee terms inline, renewal = same LeaseID with strictly higher Seq.
LeaseDecline/LeaseRelease are the node's signed exits (local_policy
remains the opt-out path; sovereignty includes leaving). ProofChallenge
is UNSIGNED and pull-fetched (commits no one); ProofResponse is the
node-signed, self-contained possession fact -- the storage counterpart
of JobReport -- with the digest formula standardized as
SHA-256(Nonce || uint64be(Offset) || uint64be(Length) || range),
byte-identical to the expectation Cloudy precomputes at seal time.
(LeaseID, Nonce) is single-use at the verifier: replays are dead.

Node key lifecycle (identity/keylife.go, SPEC 4.11-4.12). KeyRotation
is signed by the CURRENT key (a rotation signed by the successor is
self-installation and must fail -- tested); strictly monotonic Seq per
node. KeyRevocation is signed by the key being killed and MUST be
honored unconditionally -- a thief can produce one too, and the safe
reading is always 'stop trusting it'; re-enrollment is out-of-band.
Closes the 'first-write-wins forever' gap before real member hardware.

GPU job hints (employment, SPEC 4.3). JobSpec gains advisory GPUAPI +
GPUMinVRAMMB routing hints, same discipline as PrinterKind, so
assignments can request what listings can now advertise.

Coordinator surface: StorageCoordinator and KeyLifecycleCoordinator are
OPTIONAL capability interfaces, not new Coordinator methods, so a
coordinator adopts compute/print without implementing storage yet;
consumers discover support by type assertion.

Breaking v0 canonical change (Assignment gains two fields; six new
domain tags). Vectors regenerated: 12 message cases; the stdlib-only
Python reproducer gained the six encoders and passes 55/55 against the
new golden file. Transport httpjson routes for the new families ride
with the SoHoLINK-side implementation (named follow-up).

Signed-off-by: Jodson Graves <info@ntari.org>
…proof bounds

Addresses the protocol findings from the 2026-07-09 substrate audit.

M3 — KeyRotation.Verify now rejects a rotation naming a malformed successor
(NewPublicKey != 32 bytes, or unknown Algo), matching the operator rotation
path. Broader: all message Verify methods route through the new
canon.VerifySig, which guards public-key AND signature length before
ed25519.Verify — a wrong-length key on the wire can no longer panic a verifier
(it did before; only the operator path was guarded).

M4 — KeyRevocation.Verify(trustedPub) now requires RevokedPublicKey ==
trustedPub and self-signature by that key, closing the victim-revocation
vector (a stranger's self-signed revocation naming a victim's NodeID fails
against the victim's trusted key). SPEC §4.12 'honor unconditionally' wording
superseded by the mandatory trusted-key binding.

L4 — canon.Buffer.Time latches canon.ErrTimeOutOfRange (via Buffer.Err()) and
appends nothing instead of silently wrapping an out-of-range instant; new
canon.ValidTime for producers. SPEC §3 documents the enforcement. Closes the
584-year aliasing conformance defect.

L5 — new lease.ProofOverShard bounds-checks Offset/Length before slicing so a
malicious challenge yields lease.ErrChallengeRange, not a node-side slice
panic. ProofDigest (the raw primitive, byte-identical to the vectors) is
unchanged.

L10 — StorageLease.SizeClass is now a named lease.SizeClass type documenting
the 'agreed quantized class, never a true size' §5 invariant (intent-marking,
not value-enforcing — class values remain frontend policy).

NIT — OperatorRotation.Verify checks duplicate-key then algo-mismatch in two
ordered passes, so the returned error is deterministic regardless of map
iteration order.

NO canonical-byte change: all 55 conformance vectors still match the Python
reproducer byte-for-byte; new regression tests cover each guard. Still bound
for the v0.2.0 tag.

Signed-off-by: Jodson Graves <info@ntari.org>
@NetworkTheoryAppliedResearchInstitute
NetworkTheoryAppliedResearchInstitute changed the base branch from feat/storage-gpu-listing to main July 13, 2026 10:36
Signed-off-by: Jodson Graves <info@ntari.org>

# Conflicts:
#	employment/employment.go
@NetworkTheoryAppliedResearchInstitute
NetworkTheoryAppliedResearchInstitute merged commit 10868fa into main Jul 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant