Skip to content

zaino: re-vendor to upstream 0.10.0 (chain-store refactor) - #79

Merged
aphelionz merged 9 commits into
mainfrom
subtree-update/zaino-2026-09-15
Sep 15, 2026
Merged

aphelionz merged 9 commits into
mainfrom
subtree-update/zaino-2026-09-15

Conversation

@aphelionz

Copy link
Copy Markdown
Member

Re-vendors zaino/ from 07695fac5e (2026-08-19) to upstream 0.10.0 (f1d2befe62, tagged 2026-09-11), 265 commits.

Motivated by the 2026-09-15 upstream watch. This component had been held since 08-19 because there was no pinnable target; 0.10.0 is one.

Why the tag, not dev

dev is an ancestor of 0.10.0, three commits behind it, so the tag is strictly the better pin per MAINTENANCE.md rather than a compromise. Worth correcting the record: the 09-07 watch reported that 0.9.0 was not an ancestor of dev. That is no longer true, and 0.10.0 supersedes the question.

What upstream did

  • Split the finalised state out of zaino-state into backend crates: zaino-chain-store, zaino-chain-store-zainodb, zaino-encoding, zaino-primitives, zaino-chain-head-service.
  • feat!: remove zcashd support entirely (8c823f6108).
  • Deleted chain_index/non_finalised_state.rs; its writer task moved to zaino-chain-head-service.

Conflicts, and how they resolved

Three, far fewer than the file-name intersection predicted. chain_index.rs auto-merged, and our sync-patience patch survived intact.

File Resolution
chain_index/non_finalised_state.rs Accepted upstream's deletion (modify/delete)
Dockerfile Ours
README.md Ours

The deleted module retires two [zero] patches, by deletion rather than by judgement. fae256572a existed to un-mask UpdateError::DatabaseHole so the reorg-walk error reached the operator; that variant and its "could not determine best chain" message no longer appear anywhere upstream. 1c1c3029ea's edits there were rustfmt fallout, and its behavioural half in chain_index.rs was already superseded by 41d4342ded. Nothing in the merged tree references the module.

Dockerfile is ours because upstream reinstated DL3008-style exact apt pins on the builder stage. 62c6efac5d unpinned them deliberately: Debian point releases delete superseded versions from the bookworm suite, so the pins rot and break fresh builds while layer caching hides the rot until the worst moment.

README.md is ours to keep the Shielded Labs Signal disclosure group (05aa97cc87, b2b8ca74be) over upstream's Matrix and zingodisclosure@proton.me contacts.

Our sync-patience patch is still required

41d4342ded (the synced_once startup grace over the 10-failure budget) auto-merged and is still load-bearing: upstream's loop at 0.10.0 still escalates to CriticalError after max_consecutive_failures with no startup exemption. The chain-store refactor's typed FeatureUnavailable does not cover this case. Both sync-loop budget tests pass.

Two side changes that need a look

**[zero] chore(zaino): treat zaino's own crates as first-party in the vet store.** The store was initialized with cargo vet init's defaults, marking every workspace crate audit-as-crates-io = true. That is wrong for a fork, and it failed the gate here on five first-party crates whose only change was a version number. Set false, matching the zebra policy MAINTENANCE.md already documents. Also drops policy entries for zaino-testutilsandzingo_test_vectors(removed from the graph) and exemptsserde_arrays0.2.0 atsafe-to-run, a dev-only dependency of zaino-chain-store-zainodb`. This is a trust decision, hence its own commit.

**skill(update-subtree): test zaino with nextest.** The skill ran cargo test --workspace, which fails ~49 chain_indextests on"a global default trace dispatcher has already been set". Their helper does try_init().unwrap(), which can only succeed once per process; upstream CI uses cargo nextest(process per test) and never sees it. The same tree is 758/758 green under nextest. This is a harness artifact, not a regression, and the note in the skill says so, so a future run does not patch vendored code to "fix" it. Two stale rows corrected in the same commit: orchard trackedfeat/ironwood(merged intomain`, shipped as 0.15.x) and zcashd is retired from the watch.

Testing

  • cargo nextest run --workspace --no-default-features: 758 passed, 0 failed, 3 skipped.
  • cargo vet --locked: green (134 fully audited, 4 partially audited, 478 exempted).
  • cargo check --workspace --all-targets: clean.

Note

This branch and #78 both add an ## Unreleased CHANGELOG section, so whichever merges second will conflict there trivially.

🤖 Generated with Claude Code

Mark Henderson and others added 5 commits September 15, 2026 08:49
62e74097d7 Merge pull request #1535 from zingolabs/rc-0.10.0
c9d25de82a build: bump crate versions and section changelogs for 0.10.0
75ef86d0cd Merge pull request #1533 from zingolabs/dev
ff735e994e Merge pull request #1534 from zingolabs/chore/backport-0.9.0-into-dev
b5bee6555f build(live-tests): record zaino-proto 0.5.0 in the lockfile
d3804dee07 docs(zaino-proto): drop the unreleased ShieldedProtocol::Ironwood entry
e239ce876e docs(zaino-state): move the chain-store entry out of the released 0.8.0 section
cb092daf1b Merge 0.9.0 (stable) into dev
7bd73b4e47 Merge pull request #1531 from zingolabs/fix/restore-deleted-adrs
06f7a3747e docs: restore ADRs 0002-0004 deleted in #1265
12dd84a779 Merge pull request #1265 from zingolabs/feat_migrate_tests
c53526d1d0 test fixes and cleanup
d461a98b6c update ztest CI workflow
9fd5bb9b3a test: migrate the live suite to the ztest k8s harness
5eefa018bb Merge pull request #1462 from zingolabs/feat/release-pipeline
aeca5cd6a4 Merge pull request #1521 from zingolabs/fix/pr1462-review-findings
6bc26e132b fix(ci): apply the sync PR's labels at creation and exempt it from the rename bot
5cb654d515 fix(ci): resolve the workflow findings from the review of PR #1462
03e5f84d55 fix(relman): resolve the review findings pinned by the failing tests
1e5eb5473f test(relman): pin the review findings of PR #1462 with failing tests
7d20d67504 feat(backport-sentinel): gate auto-merge behind RELMAN_BACKPORT_AUTOMERGE (default off)
8b7acdf00d feat(release): first-cut gate-suite manifest with real test classification
ecccf0dbcd docs(release): specify suite-membership criterion, manifest schema, answer envelope
2aadb6bf4e docs(release): mark the rc-gate publisher as a reference, not a live producer
317b9406de docs(release): record the wired rc-gate publisher and manual deployment sign-off
99dfdcdc1f feat(release): wire the rc-gate signal publisher and a manual deployment sign-off
b27a3183d7 docs(adr): one ledger — fold decision_records/ into docs/adr/
905ac06560 docs(adr): record the release-pipeline decision as ADR-0016; periodic flow becomes ADR-0015
28fd6f588f docs(release): reclassify the release documents as specifications under docs/release/
251530d726 Merge branch 'dev' into feat/release-pipeline
1f1251a2d7 docs: state the decision-record ledger rule and the relationship to docs/adr/
c183129c77 docs(release): consolidate the trust model in implementation.md
51279f81fc docs(release): restore periodic.md as a superseded record
78eec7261c Merge pull request #1502 from zingolabs/pr1483-review-fixes
5c402b231b feat(chain-store-zainodb): instrument the whole read path via a labelled DB_READ_SECONDS{op}
94c238d3bd chore(metrics): drop mempool metric names that no crate emits
03c23afe99 refactor(chain-store): seal per-port CAPABILITY so no backend can override it
0a90745b44 refactor(chain-store-zainodb): split backend-state from capability refusal and type FeatureUnavailable
fdccaf650d Merge pull request #1483 from zingolabs/feat/isolate_finalised_state_plus_ports_rebased
b17bc5d711 Merge remote-tracking branch 'origin/dev' into feat/isolate_finalised_state_plus_ports_rebased
d27ec93038 Merge pull request #1498 from zingolabs/fix/source-macros-description
7c03ef7aa1 fix(zaino-source-macros): add description required for crates.io publish
2aa88789cd Merge pull request #1497 from zingolabs/build/bump-0.9.0
78030dd44c build: bump crate versions and section changelogs for 0.9.0
0dc6658eb5 Merge pull request #1496 from zingolabs/rc/0.9.0
afd609eeb5 Merge pull request #1395 from zingolabs/remove_zcashd
8c823f6108 feat!: remove zcashd support entirely
c89fb9b10b docs(chain-store): record the review's changes in the usage guides
07b018862e refactor(chain-index): split the chain-store adapter into reading and driving
0ce6a95a9f refactor(chain-store-zainodb): rename ports to adapter and split it up
6a034327c8 fix: typo
43e9c5df31 feat(chain-store-zainodb): instrument the finalised read path
552e736133 refactor(chain-store): hold PoolFilter's pools as a set
860100d5eb refactor(chain-store): return a typed, checked net value from address effects
e5e9014636 refactor(chain-store): read a store's advertised capability off the port
6199c39f2a fix(metrics): define each metric name once, in the crate that emits it
97cbbf4882 refactor(chain-store-zainodb): share one header mapping between both directions
94d86c4a0a fix(state): route a store error by naming it, not by excluding one case
5196467088 fix(chain-index): tell a client an unbuilt index is not a server fault
c641b1d2e5 fix(chain-store): name a corrupt row as corruption, not as a missing one
df533932b2 fix(chain-store-zainodb): hand the backend's cause across the port boundary
c4182e98a1 refactor(chain-store): let a store error carry its cause
d9ac7bc2e4 fix(chain-index): log a finalised compact-block read failure before falling back
aa7f3f9fa6 fix(chain-index): propagate the store's typed error from get_tx_out_set_info
fb7512b444 fix(chain-store-zainodb): map a routing refusal to the capability it denied
1e6a0f7f5e Merge branch 'dev' into feat/isolate_finalised_state_plus_ports_rebased
96489cddfa Merge pull request #1487 from zingolabs/fix/chain-head-domain-not-found-exhaustive
76b352612c chain-head-service: match named domain not-found variant exhaustively
09b4a66f2b docs: ADR 0012, changelogs and usage guides for the chain store
e21ba0cbb3 test(chain-store-zainodb): move the finalised-state suites into the backend crate
5f311bf399 refactor(state): read the finalised state through the chain store
43f74d9218 feat(chain-store-zainodb): implement the chain-store ports
93d4425141 feat(chain-store-zainodb): move the finalised state into the backend crate
63706dfd2a feat(chain-store-zainodb): move the persisted types into the backend crate
2c5f4884b1 fix(chain-store): name the validator questions the store actually asks
7290559c84 feat(chain-store): add zaino-chain-store, the ChainStore domain crate
cd2804049b Merge pull request #1475 from zingolabs/dev
a7e5179e3e Merge branch 'dev' into feat/release-pipeline
e642c6a66e  feat(primitives): add the chain store's shared vocabulary
a1a84883f8 feat(encoding): add zaino-encoding
3d1f954c47 refactor(state): move MempoolInfo into zaino-primitives
31a84a4b5e fix(state): repair the experimental feature set and build it in CI
29e2792e79 fix(state): map the current schema version to its capability set
09aa206d0f add golden vector tests to ensure code is moved correctly
4379113f02 Merge pull request #1473 from zingolabs/chore/backport_0_8_0_onto_dev_with_conflict_fixes
06c596e63f Merge remote-tracking branch 'origin/dev' into chore/backport_0_8_0_onto_dev_with_conflict_fixes
69fe29006a Merge pull request #1459 from zingolabs/feat/resilient-seam
197c56bf34 Merge branch 'dev' into feat/resilient-seam
5b5b75d570 Merge pull request #1471 from zingolabs/fix/ironwood_proto
ae7e88ff5d Merge branch 'dev' into feat/resilient-seam
2ec2904492 docs(source): route consumers who want their own retrying at the seal
11e0f29eeb docs(chain-index): note first ValidatorClient use and the OneShot punt
fc32ce7570 fix(chain-index): wrap boot source in ValidatorClient for adopt_network
2c035f4713 Merge pull request #1467 from zingolabs/add_sync_plus_concurrency_tests
4097f229df merge conflicts
4e529f2002 test and fmt fixs
b3314e93b7 Merge branch 'fix_chain_head_premature_ready' (PR #1470)
3de102c186 refactor: anchor the status cell at Syncing directly
9f915e905a refactor: anchor the status cell at Syncing directly
30aa68b0a5 refactor: express store as apply with a constant closure
54132da867 refactor: express store as apply with a constant closure
fa1263cab2 refactor: pure status-transition rule applied by compare-and-swap
3b0438d64e refactor: pure status-transition rule applied by compare-and-swap
76057b6863 fix: publish chain-head Ready only after the first catch-up tick
cc30eb28eb fix: publish chain-head Ready only after the first catch-up tick
0ad4cb82f5 Merge branch 'dev' into feat/release-pipeline
0c6cd52f5f Merge branch 'dev' into feat/resilient-seam
b819583a1a Add Ironwood subtree root RPC plumbing
c9e363a105 docs: replace machine-specific paths with placeholders
82f74dc12b docs(perf): final concurrency figures — 5,000 at 100% in both modes
25e1a15120 fix(zaino-state): raise the LMDB reader ceiling off its floor
a48a6c4a96 test(zaino-bench): cover the spawn-ramp arithmetic
fdf7044526 fix(zaino-bench): hold every connection open until the round starts
56bc55263e docs(perf): record concurrency and serve-rate measurements
24de8ea11f update concurrency test
621cf11275 docs(perf): record the first full mainnet sync measurement
14720e7413 perf(zaino-state): assemble blocks concurrently, not just fetch them
d7268feea4 perf(zaino-state): fetch blocks concurrently during bulk sync
b7e479b8df perf(zaino-state): pipeline bulk-sync batch commits with block building
67b63100b5 fix sync test reading
7ab2a61355 fixes
df666723aa feat(zaino-bench): benchmark harness for sync time, concurrency, and serve rate
4bec33f57c refactor(rc-gate): decouple the gate from its suite (named-signal indirection)
32849c7ea5 Merge pull request #1466 from zingolabs/sync/stable-to-dev
73c8c59be7 Merge branch 'dev' into sync/stable-to-dev
489522d16a docs(deployment-gate): validation is a dial (warm-tip fixtures ↔ full-sync), automated and/or manual
fe696af8c6 ci(cutover): wire rc-gate's e2e precondition; flag release.yaml
c3a2877fd4 change(relman): drop the `v` from per-crate version tags
bf97bc1866 feat(deployment-gate): build the GitHub side of the bridge
88db176857 Merge pull request #1457 from zingolabs/fix/release_0_8_0/slow_accumulator_build_and_fs_switchover
2bdd892ec5 ci(changeset-rename): pass PR head ref via env (script-injection hardening)
6566471fc5 ci(release-pr): label bot PRs for scannability
0fca7a61db fix(backport-sentinel): self-heal auto-merge; retry past the mergeability race
c8cbfaa920 ci(release-pr): hyperlink tag/commit refs in the timeline comments
9855e5e906 ci(hotfix-notice): quote the fix subject, not the merge commit
dc02499ae4 ci(release-pr): append-only comment timeline + live body snapshot
eb81bac918 test(sandbox): add hotfix stage (land a fix directly on rc)
1447d1e313 test(sandbox): add reset stage to the cycle driver
bf58af89f6 test(sandbox): step-by-step cycle driver for live pipeline demos
cc8fbf5cc7 Merge remote-tracking branch 'origin/feat/release-pipeline' into feat/release-pipeline
59d19e5009 test(sandbox): drive consume→ledger→bless→sentinel end-to-end check
0bcde265a4 feat(relman): consumed-UID ledger for backport-independent dedup
236f57927f Merge branch 'dev' into feat/release-pipeline
cd86d27349 style(it): fix shellcheck findings in the changeset-check harness
328308cfb4 feat(backport-sentinel): auto-merge the sync PR, self-dissolving when clean
a9bb2ab3da test(sandbox): deploy + drive a targeted backport-sentinel check
b12414d190 ci(backport-sentinel): carry stable back into dev after a release/hotfix
5be3befa45 docs(pipeline): blessing marks changesets consumed, not clears
1c7d78d429 feat(relman): give every changeset an immutable UID at creation
9eb28a6902 refactor(source): name the resilient wrapper for what it is, ValidatorClient
68f4971529 feat(relman): mark changesets consumed instead of erasing them
ad644c07b3 ci(blessing): pre-flight publishability check before any commit/tag/release
cacfd65013 style(relman-core): rustfmt cycle_status
1a37076a3c docs(readme): add Release pipeline badges
6971a1d8de ci(release-pr-body): gather cycle status and render the dashboard
5754b22e06 docs+tools: make the deployment-gate testable without waiting days
cac7f0d6e1 feat(relman): render release-cycle dashboard in pr-body
50bcb97120 feat(relman-core): add CycleStatus input type
2f2b4bea2d ci(blessing): derive tags/publish-plan before clearing changesets; add GitHub Release
cac7830876 ci: release-pr-body creates the PR via the App token
5a307128fa ci: rename bot pushes via App token so the dev-gate re-runs
82899cf599 test(relman): local act+podman integration test for changeset-check
68067b9ea8 ci(relman): run changeset-check via setup-relman, not cargo run
b0401b53df ci(relman): add setup-relman composite action
e93a80cde4 tools: add fork pipeline-sandbox setup script
5a65cc42c5 ci: add RELMAN_PUBLISH_DRY_RUN toggle to blessing
bc8b531606 docs(release): rename test-type "soak" to "deployment"
8ae6e73dcc ci: drop last RELEASE_TOKEN mention in blessing comment
cc3efa01fd ci: use a GitHub App token (not a PAT) for protected-branch pushes
6b004c5a6a ci(release): add blessing workflow (release on merge to stable)
bae59a3ce1 ci(release): add rc-gate advancement and release-PR-body workflows
9c80ecee8c ci(release): add CODEOWNERS template and pr-<N> changeset rename bot
3e2368fa39 relman: rustfmt the new changeset test bodies
2cead556e1 relman: wire changeset rename/clear CLI commands
627930fe81 relman: add rename_to_pr/clear/list to Changesets port
6976beaec2 relman: add rename/remove to ChangesetStore port
fbbd5713cc ci: wire relman into CI (lint/test + advisory dev-gate changeset check)
a166e756fc relman-cli: warn on stderr about skipped unfilled changeset templates
9e4c6f7cea relman-core+domain: tolerate unfilled templates in aggregation, flag in check
7eb569b054 relman-core: distinguish unfilled changeset templates from malformed
ab72abbdc9 docs(source): document the two-layer resilient ports; fmt the series
8f860def42 feat(source): forward subscriptions through Resilient + assert the port bound
337e12d0f7 feat(source): derive resilient twins for all idempotent ports
db46766489 feat(source): add #[resilient_port] proc-macro + seal the resilient ports
46d149a59d refactor(source): rename SendRawTransaction port to OneShotSendRawTransaction
f629877c6f refactor(state): finish OneShotGetRawMempoolTransaction ref updates
a711886c03 refactor(source): rename GetTxOut port to OneShotGetTxOut
f9409c3219 refactor(source): rename GetTreestate port to OneShotGetTreestate
d6c936b8c9 refactor(source): rename GetSpentInfo/GetSubtreeRoots ports to OneShot*
355265a01f refactor(source): rename GetRawBlock/GetRawBlockByHash/GetRawBlockHeader ports to OneShot*
521cea456a refactor(source): rename GetNodeInfo port to OneShotGetNodeInfo
dc2684566e refactor(source): rename GetMiningInfo port to OneShotGetMiningInfo
e1db71096d refactor(source): rename GetMempoolTxids port to OneShotGetMempoolTxids
99d3a56409 refactor(source): rename GetMempoolSourceTip port to OneShotGetMempoolSourceTip
ac87dbf0f2 refactor(source): rename GetDifficulty/GetMempoolMetadata ports to OneShot*
a26d38ded7 refactor(source): rename GetPreIndexCompactBlock port to OneShotGetPreIndexCompactBlock
3884950ad4 refactor(source): rename GetChainTips/GetCommitmentTreeRoots ports to OneShot*
25966df7f4 refactor(source): rename GetChainTip port to OneShotGetChainTip
8bae538e8f refactor(source): rename GetBlockSubsidy/GetBlockVerbose/GetBlockchainInfo ports to OneShot*
c5f5eea94c refactor(source): rename GetBlockHeader port to OneShotGetBlockHeader
18a6d24445 refactor(source): rename GetBlockDeltas port to OneShotGetBlockDeltas
e38df93517 refactor(source): rename GetBlockByHash port to OneShotGetBlockByHash
c55666cbde refactor(source): rename GetBlock port to OneShotGetBlock
b5c74e5e9d refactor(source): rename GetBestBlockHeight port to OneShotGetBestBlockHeight
1c02fb41f0 refactor(source): rename GetAddressTxids/GetAddressUtxos ports to OneShot*
775580f222 refactor(source): rename GetAddressBalance/GetAddressDeltas ports to OneShot*
3757275ca0 feat(relman): add --version flag and walk-up relman.toml discovery
f6f93fb1e8 relman: wire tags, pr-body, publish-plan CLI commands
3a5f430ac8 relman: ReleaseArtifacts port + service (tags, pr-body, publish-plan)
e8a524f1b7 relman: add CycleId, Tag, TagPlan, PublishPlan core types
5ea373e85b relman: wire relman changelog [--dry-run] command
46304e86cd relman: add FsChangelogStore filesystem adapter
56215d40d8 relman: add ChangelogService implementing the Changelog port
bc2daa695b relman: add pure Keep-a-Changelog render functions
a44cf7c325 relman: add ChangelogStore + Changelog ports and MapChangelogStore mock
3266ba01a1 relman: wire `relman bump [--dry-run]` command
2ca7daf144 relman: add BumpService applying a derived BumpTable
e95cd3c569 relman: add toml_edit ManifestEditor adapter
a2e4ae1544 relman: add ManifestEditor + ApplyBump ports and recording mock
cacbf8a754 relman: add `relman versions` command and wire VersionService
3b722221e0 relman: add CargoMetadataWorkspace adapter
ac18dfb1c3 relman: add VersionService deriving direct + transitive bumps
6e6bd1278f relman: add Workspace driven port and Versions driving port
51d83c4216 relman: add Version, Bump, BumpTable core types
2a29ef9400 relman: update lockfile for relman-domain -> relman-config edge
2f3addfc2a relman: wire changeset check command through the CLI and composition root
a95d9667be relman-adapters: add GitVcs implementing the Vcs port via git diff
de04ce4a09 relman-domain: add ChangesetCheckService enforcing changeset coverage
b47c00ee9e relman-core: add Vcs port and changeset-check driving port
5cc0132fd3 relman: wire changeset new command through the CLI and composition root
4103885db5 relman-adapters: add crate with FsChangesetStore and RandomSlugSource
51f8cacc9a relman-domain: add ChangesetService implementing the Changesets port
778a5d2ab8 relman-core: add in-memory changeset store and slug source mocks
5bf988ff70 relman-core: add Slug type and changeset ports
c6e722c587 relman-core: add Changeset model with TOML parse/serialize
0e9c79d470 relman-core: add Description and ChangeEntry changeset value types
1859ef1c86 relman-core: add ChangeKind and Section changeset value types
5d01a6cfca feat(relman): govern all 17 publishable crates
eda3225556 Add repo-root relman.toml with the 13 governed targets
573d8d9b0e relman-config: parse relman.toml into typed ReleaseConfig
a5451295a5 relman-core: add CrateName, WorkspacePath, ReleaseOptions, Target newtypes
b648657c1f Merge pull request #1440 from zingolabs/feat/isolate_nfs
d48dcec3a2 review fixes: upgrade test u8 and make conversion fallible
194f2f6ce3 feat(relman): scaffold isolated hexagonal CLI skeleton (slice 0)
452dfc5a15 docs(release): relman hexagon structure + relman.toml target manifest
88dee0faaa docs(release): add implementation architecture sub-spec
cc56c9ab36 docs(release): add changeset format sub-spec
dd5802213b docs(release): tool home is a sibling relman crate, not workbench
97be9f4acf docs(release): record impl approach and workflow teardown
f6ce191954 docs(release): redesign release pipeline spec
aeac94abab fix: makers test cont.
7d0e8cff73 fix: makers test
f751366160 add fs ephemeral and txoutset build logging
c780a9ba10 docs(state): keep the chain head entries in Unreleased
e8c64e7e64 refactor(chain-head-service): let the snapshot own its generation rule
a935d74898 refactor(state): convert the tree-size cast instead of truncating
679193b5c0 refactor(chain-head): make illegal config unrepresentable
e4d037e12c docs(chain-head-service): shutdown aborts, it does not await
4942a0c33c docs(chain-head-service): state who owns the writer task's lifetime
079e01501e refactor(primitives): promote one epoch type instead of two identical ones
5b6382fb9b refactor(chain-head): delete the error variants nothing produces
1df807ad1e docs: record the chain head separation and the crates it arrived with
00902f5ae7 refactor(state): remove the non-finalised state and read the chain head
80e070d637 feat(chain-head-service): move the non-finalised state into its own runtime
2333f74785 feat(chain-head): add zaino-chain-head, the ChainHead domain crate

git-subtree-dir: zaino
git-subtree-split: 62e74097d7ee52a81a8c6386c43d51bc8b756715
Squashed 'zaino/' changes from 07695fac5e..f1d2bef (265 commits), pinned
to the 0.10.0 release tag (2026-09-11) rather than the dev branch: dev is an
ancestor of the tag, three commits behind it, so the tag is the strictly
better pin per MAINTENANCE.md.

Upstream split the finalised state out of zaino-state into a family of
backend crates (zaino-chain-store, zaino-chain-store-zainodb, zaino-encoding,
zaino-primitives, zaino-chain-head-service), removed zcashd support entirely,
and deleted chain_index/non_finalised_state.rs.

Conflict resolutions:

- zaino/packages/zaino-state/src/chain_index/non_finalised_state.rs
  (modify/delete): accepted upstream's deletion. Our two [zero] commits on
  this file are obsolete by deletion, not by judgement. fae2565 un-masked
  UpdateError::DatabaseHole so the reorg-walk error reached the operator;
  that variant and its "could not determine best chain" message no longer
  exist anywhere upstream, and the writer task moved to
  zaino-chain-head-service. 1c1c302's edits here were rustfmt fallout, and
  its behavioural half in chain_index.rs was already superseded by
  41d4342. Nothing in the merged tree references the module.

- zaino/Dockerfile: ours. Upstream reinstated DL3008-style exact apt pins for
  the builder stage; 62c6efa unpinned them deliberately because Debian
  point releases delete superseded versions from the bookworm suite, so the
  pins rot and break fresh builds while layer caching hides the rot.

- zaino/README.md: ours. Keep the Shielded Labs Signal disclosure group
  (05aa97c, b2b8ca7) over upstream's Matrix/zingodisclosure contacts.

chain_index.rs auto-merged and our sync-patience patch (41d4342, the
synced_once startup grace over the 10-failure budget) survived intact. It is
still needed: upstream's loop at 0.10.0 still escalates to CriticalError after
max_consecutive_failures with no startup exemption.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…et store

The store was initialized by 122ff5d with `cargo vet init`'s defaults,
which mark every workspace crate `audit-as-crates-io = true`. That is wrong
for a fork: our zaino diverges from the published crates (41d4342, the
sync-patience startup grace), so the registry copies are not what we build,
and every upstream version bump demands fresh exemptions for zaino's own
code. The 0.10.0 pull made that concrete, failing the gate on five
first-party crates that only changed version number.

Set them `false`, matching the zebra policy MAINTENANCE.md already documents
under "Supply-chain audits": first-party code is reviewed through our PR
process, not audited as a registry copy.

Also drop the policy entries for zaino-testutils and zingo_test_vectors,
which the chain-store refactor removed from the graph, and exempt
serde_arrays 0.2.0 at safe-to-run. serde_arrays is a dev-dependency of the
new zaino-chain-store-zainodb crate, test-only and never shipped, which is
why the weaker criteria applies.

`cargo vet --locked`: 134 fully audited, 4 partially audited, 478 exempted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… rows

Three fixes found while pulling zaino to 0.10.0:

- zaino's test command was `cargo test --workspace`, which fails ~49
  chain_index tests on "a global default trace dispatcher has already been
  set". The tests call a `try_init().unwrap()` helper that can only succeed
  once per process; upstream CI runs `cargo nextest` (process per test) and so
  never hits it. The same tree is 758/758 green under nextest. Match upstream's
  runner and say so in the notes, so the next run does not read a harness
  artifact as a regression and patch vendored code to "fix" it.
- orchard tracked `feat/ironwood`, which was merged into `main` and shipped as
  the 0.15.x line. SUBTREES.md was already corrected; this row was not.
- zcashd is retired from the watch and has no remote.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings September 15, 2026 13:03
The zeronym hub and shim path-depend on the vendored
zaino/packages/zaino-proto, so the 0.10.0 pull moved it 0.4.0 -> 0.6.0 and
left both lockfiles stale. Their images build with `cargo fetch --locked`,
which refuses to update a lock, so the reproduce job failed at
Containerfile:126 before compiling anything.

One line each, the path dep's version. Both manifests keep
`default-features = false` on zaino-proto, so the feature set the Containerfile
comment warns about is unchanged and nothing else re-resolved.

zallet/backends/zaino is unaffected: it takes the zaino crates from crates.io
("0.4"), not from this subtree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical and moderate findings affect synchronization, concurrency, migration safety, release tooling, and generated changesets.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Re-vendors Zaino to upstream 0.10.0, adopting the chain-store refactor and removing legacy zcashd support.

Changes:

  • Adds chain-store and chain-head architecture while preserving Zero-specific synchronization behavior.
  • Updates release, sandbox, CI, vet-policy, Docker, and documentation tooling.
  • Validation reports 758 passing nextest tests, clean cargo vet, and successful workspace checks.

Final findings remain unresolved:

  • [critical, 1 vote] Chain-head advancement can publish an incomplete snapshot when an intermediate block is missing.
  • [critical, 1 vote] Concurrent build_to calls can bypass the single-flight check.
  • [critical, 1 vote] Routed writes can overlap full-mode migration after acquiring a backend.
  • [critical, 1 vote] Same-epoch mempool thaw can omit Added events.
  • [moderate, 1 vote] Relman bump and changelog paths are not resolved from the repository root.
  • [moderate, 1 vote] Changeset discovery ignores the restored consumed ledger.
  • [moderate, 1 vote] Sandbox ruleset updates do not send the complete ruleset representation.
  • [moderate, 1 vote] Both sandbox-cycle changeset-generation paths accept unescaped TOML descriptions.
  • [nit, 3 votes] Validator-height documentation contains a malformed link.
File summaries
File Review
zaino/zainod-heights-from-validator-spec.md Reviewed — nit noted
zaino/tools/workbench/src/bin/get-zebra-git-ref.rs Reviewed
zaino/tools/workbench/src/bin/check-published-versions.rs Reviewed
zaino/tools/workbench/src/bin/check-code-duplication.rs Reviewed
zaino/tools/test-runner/Cargo.toml Reviewed
zaino/tools/test-runner/Cargo.lock Reviewed
zaino/tools/scripts/sandbox-common.sh Reviewed — moderate finding
zaino/tools/scripts/init-podman-volumes.sh Reviewed
zaino/tools/scripts/helpers.sh Reviewed
zaino/tools/scripts/get-ci-image-tag.sh Reviewed
zaino/tools/scripts/functions.sh Reviewed
zaino/tools/scripts/container-test-save-failures.sh Reviewed
zaino/tools/scripts/container-test-retry-failures.sh Reviewed
zaino/tools/scripts/container-nextest-workspace.sh Reviewed
zaino/tools/scripts/check-matching-zebras.sh Reviewed
zaino/tools/relman/README.md Reviewed
zaino/tools/relman/crates/domain/src/services/about.rs Reviewed
zaino/tools/relman/crates/domain/src/services.rs Reviewed
zaino/tools/relman/crates/domain/src/lib.rs Reviewed
zaino/tools/relman/crates/domain/Cargo.toml Reviewed
zaino/tools/relman/crates/core/src/types/target.rs Reviewed
zaino/tools/relman/crates/core/src/types/tag_plan.rs Reviewed
zaino/tools/relman/crates/core/src/types/release_options.rs Reviewed
zaino/tools/relman/crates/core/src/types/about.rs Reviewed
zaino/tools/relman/crates/core/src/types.rs Reviewed
zaino/tools/relman/crates/core/src/ports.rs Reviewed
zaino/tools/relman/crates/core/src/mocks/workspace.rs Reviewed
zaino/tools/relman/crates/core/src/mocks/vcs.rs Reviewed
zaino/tools/relman/crates/core/src/mocks/uid_source.rs Reviewed
zaino/tools/relman/crates/core/src/mocks/slug_source.rs Reviewed
zaino/tools/relman/crates/core/src/mocks/fixtures.rs Reviewed
zaino/tools/relman/crates/core/src/mocks/consumed_ledger_store.rs Reviewed
zaino/tools/relman/crates/core/src/mocks/clock.rs Reviewed
zaino/tools/relman/crates/core/src/mocks.rs Reviewed
zaino/tools/relman/crates/core/src/lib.rs Reviewed
zaino/tools/relman/crates/core/Cargo.toml Reviewed
zaino/tools/relman/crates/config/src/lib.rs Reviewed
zaino/tools/relman/crates/config/src/error.rs Reviewed
zaino/tools/relman/crates/config/Cargo.toml Reviewed
zaino/tools/relman/crates/cli/src/warn.rs Reviewed
zaino/tools/relman/crates/cli/src/lib.rs Reviewed
zaino/tools/relman/crates/cli/src/context.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/versions.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/tags.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/publish_plan.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/changeset/rename.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/changeset/new.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/changeset/clear.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/changeset/check.rs Reviewed
zaino/tools/relman/crates/cli/src/commands/about.rs Reviewed
zaino/tools/relman/crates/cli/src/commands.rs Reviewed
zaino/tools/relman/crates/cli/src/app.rs Reviewed
zaino/tools/relman/crates/cli/Cargo.toml Reviewed
zaino/tools/relman/crates/app/Cargo.toml Reviewed
zaino/tools/relman/crates/adapters/src/random_uid_source.rs Reviewed
zaino/tools/relman/crates/adapters/src/lib.rs Reviewed
zaino/tools/relman/crates/adapters/Cargo.toml Reviewed
zaino/supply-chain/config.toml Reviewed
zaino/packages/zainod/src/indexer.rs Reviewed
zaino/packages/zainod/src/config.rs Reviewed
zaino/packages/zainod/README.md Reviewed
zaino/packages/zainod/CHANGELOG.md Reviewed
zaino/packages/zainod/Cargo.toml Reviewed
zaino/packages/zaino-status/usage.md Reviewed
zaino/packages/zaino-status/CHANGELOG.md Reviewed
zaino/packages/zaino-status/Cargo.toml Reviewed
zaino/packages/zaino-state/src/stream.rs Reviewed
zaino/packages/zaino-state/src/chain_index/chain_store/driving.rs Reviewed
zaino/packages/zaino-source/src/send_raw_transaction.rs Reviewed
zaino/packages/zaino-source/src/get_tx_out.rs Reviewed
zaino/packages/zaino-source/src/get_treestate.rs Reviewed
zaino/packages/zaino-source/src/get_treestate_by_hash.rs Reviewed
zaino/packages/zaino-source/src/get_transaction.rs Reviewed
zaino/packages/zaino-source/src/get_subtree_roots.rs Reviewed
zaino/packages/zaino-source/src/get_raw_mempool_transaction.rs Reviewed
zaino/packages/zaino-source/src/get_raw_block.rs Reviewed
zaino/packages/zaino-source/src/get_raw_block_header.rs Reviewed
zaino/packages/zaino-source/src/get_peer_info.rs Reviewed
zaino/packages/zaino-source/src/get_node_info.rs Reviewed
zaino/packages/zaino-source/src/get_network_sol_ps.rs Reviewed
zaino/packages/zaino-source/src/get_mining_info.rs Reviewed
zaino/packages/zaino-source/src/get_mempool_txids.rs Reviewed
zaino/packages/zaino-source/src/get_mempool_source_tip.rs Reviewed
zaino/packages/zaino-source/src/get_mempool_metadata.rs Reviewed
zaino/packages/zaino-source/src/get_difficulty.rs Reviewed
zaino/packages/zaino-source/src/get_compact_block.rs Reviewed
zaino/packages/zaino-source/src/get_commitment_tree_roots.rs Reviewed
zaino/packages/zaino-source/src/get_chain_tips.rs Reviewed
zaino/packages/zaino-source/src/get_chain_tip.rs Reviewed
zaino/packages/zaino-source/src/get_blockchain_info.rs Reviewed
zaino/packages/zaino-source/src/get_block.rs Reviewed
zaino/packages/zaino-source/src/get_block_verbose.rs Reviewed
zaino/packages/zaino-source/src/get_block_subsidy.rs Reviewed
zaino/packages/zaino-source/src/get_block_header.rs Reviewed
zaino/packages/zaino-source/src/get_block_deltas.rs Reviewed
zaino/packages/zaino-source/src/get_block_by_hash.rs Reviewed
zaino/packages/zaino-source/src/get_best_block_height.rs Reviewed
zaino/packages/zaino-source/src/get_address_utxos.rs Reviewed
zaino/packages/zaino-source/src/get_address_txids.rs Reviewed
zaino/packages/zaino-source/src/get_address_deltas.rs Reviewed
zaino/packages/zaino-source/src/get_address_balance.rs Reviewed
zaino/packages/zaino-source/Cargo.toml Reviewed
zaino/packages/zaino-source-zebra/usage.md Reviewed
zaino/packages/zaino-source-zebra/CHANGELOG.md Reviewed
zaino/packages/zaino-source-zebra/Cargo.toml Reviewed
zaino/packages/zaino-source-zebra-rpc/usage.md Reviewed
zaino/packages/zaino-source-zebra-rpc/tests/block_parity.rs Reviewed
zaino/packages/zaino-source-zebra-rpc/src/parse.rs Reviewed
zaino/packages/zaino-source-zebra-rpc/examples/smoke.rs Reviewed
zaino/packages/zaino-source-zebra-rpc/examples/fetch_fixtures.rs Reviewed
zaino/packages/zaino-source-zebra-rpc/CHANGELOG.md Reviewed
zaino/packages/zaino-source-zebra-rpc/Cargo.toml Reviewed
zaino/packages/zaino-source-zebra-readstate/CHANGELOG.md Reviewed
zaino/packages/zaino-source-zebra-readstate/Cargo.toml Reviewed
zaino/packages/zaino-source-macros/CHANGELOG.md Reviewed
zaino/packages/zaino-source-macros/Cargo.toml Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/subtrees.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/hashes.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/chain_tips.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/blockchain_info.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/block_subsidy.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/block_header.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/block_deltas.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/address_queries.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire/address_deltas.rs Reviewed
zaino/packages/zaino-serve/src/rpc/jsonrpc/wire.rs Reviewed
zaino/packages/zaino-serve/src/rpc/grpc/service.rs Reviewed
zaino/packages/zaino-serve/CHANGELOG.md Reviewed
zaino/packages/zaino-serve/Cargo.toml Reviewed
zaino/packages/zaino-rpc/usage.md Reviewed
zaino/packages/zaino-rpc/src/retry.rs Reviewed
zaino/packages/zaino-rpc/src/error.rs Reviewed
zaino/packages/zaino-rpc/CHANGELOG.md Reviewed
zaino/packages/zaino-rpc/Cargo.toml Reviewed
zaino/packages/zaino-proto/README.md Reviewed
zaino/packages/zaino-proto/CHANGELOG.md Reviewed
zaino/packages/zaino-proto/Cargo.toml Reviewed
zaino/packages/zaino-primitives/src/types/shielded_pool.rs Reviewed
zaino/packages/zaino-primitives/src/types/rpc/peer_info.rs Reviewed
zaino/packages/zaino-primitives/src/types/rpc/mining_info.rs Reviewed
zaino/packages/zaino-primitives/src/types/rpc/address_deltas.rs Reviewed
zaino/packages/zaino-primitives/src/types/rpc.rs Reviewed
zaino/packages/zaino-primitives/src/types/outpoint.rs Reviewed
zaino/packages/zaino-primitives/src/types/mempool_info.rs Reviewed
zaino/packages/zaino-primitives/src/types/equihash_solution.rs Reviewed
zaino/packages/zaino-primitives/src/types/chain_state_epoch.rs Reviewed
zaino/packages/zaino-primitives/src/types/block.rs Reviewed
zaino/packages/zaino-primitives/src/types/address_delta.rs Reviewed
zaino/packages/zaino-primitives/src/types.rs Reviewed
zaino/packages/zaino-primitives/CHANGELOG.md Reviewed
zaino/packages/zaino-primitives/Cargo.toml Reviewed
zaino/packages/zaino-mempool/usage.md Reviewed
zaino/packages/zaino-mempool/src/lib.rs Reviewed
zaino/packages/zaino-mempool/src/event.rs Reviewed
zaino/packages/zaino-mempool/src/entry.rs Reviewed
zaino/packages/zaino-mempool/docs/mempool_lifecycle.md Reviewed
zaino/packages/zaino-mempool/CHANGELOG.md Reviewed
zaino/packages/zaino-mempool/Cargo.toml Reviewed
zaino/packages/zaino-mempool-service/src/coherence/reconcile.rs Reviewed
zaino/packages/zaino-mempool-service/src/coherence/publish.rs Reviewed — critical finding
zaino/packages/zaino-mempool-service/src/coherence.rs Reviewed
zaino/packages/zaino-mempool-service/CHANGELOG.md Reviewed
zaino/packages/zaino-mempool-service/Cargo.toml Reviewed
zaino/packages/zaino-encoding/CHANGELOG.md Reviewed
zaino/packages/zaino-encoding/Cargo.toml Reviewed
zaino/packages/zaino-convert-zebra/CHANGELOG.md Reviewed
zaino/packages/zaino-convert-zebra/Cargo.toml Reviewed
zaino/packages/zaino-consensus/src/lib.rs Reviewed
zaino/packages/zaino-consensus/CHANGELOG.md Reviewed
zaino/packages/zaino-consensus/Cargo.toml Reviewed
zaino/packages/zaino-common/src/config/validator.rs Reviewed
zaino/packages/zaino-common/src/config/storage.rs Reviewed
zaino/packages/zaino-common/CHANGELOG.md Reviewed
zaino/packages/zaino-common/Cargo.toml Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/primitives/block_index.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/primitives.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/helpers.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/db/transaction.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/db/shielded.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/db/primitives.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/db/commitment.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/db/address.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/db.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/types/block_context.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/tests/finalised_state/migrations.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/tests/finalised_state.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/tests.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/support.rs Reviewed
zaino/packages/zaino-chain-store-zainodb/src/stream.rs Reviewed
zaino/packages/zaino-chain-head/src/error.rs Reviewed
zaino/packages/zaino-chain-head/Cargo.toml Reviewed
zaino/packages/zaino-chain-head-service/src/metric_names.rs Reviewed
zaino/packages/zaino-chain-head-service/src/lib.rs Reviewed
zaino/packages/zaino-chain-head-service/Cargo.toml Reviewed
zaino/packages/zaino-bench/Cargo.toml Reviewed
zaino/packages/zaino-address/usage.md Reviewed
zaino/packages/zaino-address/src/validated.rs Reviewed
zaino/packages/zaino-address/src/lib.rs Reviewed
zaino/packages/zaino-address/src/classify.rs Reviewed
zaino/packages/zaino-address/CHANGELOG.md Reviewed
zaino/packages/zaino-address/Cargo.toml Reviewed
zaino/nix/package.nix Reviewed
zaino/live-tests/zaino-testutils/src/validator_oracle.rs Reviewed
zaino/live-tests/zaino-testutils/src/rpc.rs Reviewed
zaino/live-tests/zaino-testutils/src/legacy_parser/block.rs Reviewed
zaino/live-tests/zaino-testutils/src/legacy_parser.rs Reviewed
zaino/live-tests/test_binaries/bins/.gitinclude Reviewed
zaino/live-tests/clientless/tests/test_vectors.rs Reviewed
zaino/live-tests/Cargo.toml Reviewed
zaino/flake.nix Reviewed
zaino/docs/use_cases.md Reviewed
zaino/docs/updating_zebra_crates.md Reviewed
zaino/docs/rpc_api.md Reviewed
zaino/docs/logging.md Reviewed
zaino/docs/internal_spec.md Reviewed
zaino/docs/example_configs/zebrad_config_3.1.0.toml Reviewed
zaino/docs/example_configs/zainod.toml Reviewed
zaino/docs/example_configs/zainod-bench-mainnet-ephemeral.toml Reviewed
zaino/docs/docker.md Reviewed
zaino/docs/adr/README.md Reviewed
zaino/docs/adr/0015-periodic-release-flow.md Reviewed
zaino/docs/adr/0010-mempool-subsystem-separation.md Reviewed
zaino/docs/adr/0008-source-ports-and-domain-primitives.md Reviewed
zaino/docs/adr/0003-live-test-taxonomy-and-two-crate-split.md Reviewed
zaino/CONTRIBUTING.md Reviewed
zaino/CONTEXT.md Reviewed
zaino/.gitignore Reviewed
zaino/.github/workflows/publish-dry-run.yml Reviewed
zaino/.github/workflows/final-tag-on-stable.yml Reviewed
zaino/.github/workflows/compute-tag.yml Reviewed
zaino/.github/workflows/auto-tag-rc.yml Reviewed
zaino/.github/ISSUE_TEMPLATE/bug_report.yaml Reviewed
zaino/.github/CODEOWNERS Reviewed
zaino/.env.testing-artifacts Reviewed
zaino/.dupes-ignore.toml Reviewed
zaino/.dockerignore Reviewed
SUBTREES.md Reviewed
CHANGELOG.md Reviewed
Review details
  • Files reviewed: 87/533 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread zaino/packages/zaino-chain-head-service/src/service.rs
Comment on lines 1072 to +1074
let db_height = db_height_opt.unwrap_or(GENESIS_HEIGHT);
let sync_is_long_running =
height.0.saturating_sub(db_height.0) > LONG_RUNNING_SYNC_THRESHOLD;
height.0.saturating_sub(db_height.0) > self.cfg.store.background_build_threshold();

impl<M: Mempool, N: NfsEpochObserver> super::CoherenceService<M, N> {
pub(super) fn publish_live(
&self,
prev: &CoherentSnapshot,
core: Arc<MempoolSnapshot>,
observed: ObservedTips,
epoch: NonFinalizedEpoch,
epoch: ChainStateEpoch,
) {
// Serving live: the freeze clock (if any) stops here.
let was_frozen = matches!(prev.mode, MempoolMode::Frozen { .. });
Comment on lines +143 to +147
- **the legacy full node as validator**: the legacy e2e path (`devtool_the legacy full node.rs`) drives
the legacy full node, whose `getblockchaininfo` also reports an `upgrades` map. Prefer
making the adoption path validator-generic so the legacy full node rides along; if its
map shape differs materially, scope this spec to zebrad and record the
divergence in the zcashd test docs.
divergence in the legacy full-node test docs.
Copilot AI review requested due to automatic review settings September 15, 2026 13:21
Mark Henderson and others added 2 commits September 15, 2026 09:28
The zaino 0.10.0 re-vendor moves the path-dependency zaino-proto 0.4.0 to
0.6.0, which both zeronym binaries link. Per each deploy/README.md's own
determinism-ingredients list, a subtree pull touching
zaino/packages/zaino-proto moves the binary and therefore the published hash,
so the reproduce jobs correctly failed against a stale baseline.

Determinism itself is intact, which is the part that matters: each new hash
agreed across FOUR cold builds on TWO independent x86_64 runners (two runs of
two builds each), and both jobs reported SELF-CONSISTENT with zebra/ and
zaino/ clean. Only the published value was stale.

  zero-indexer-shim  7375176d… -> da0b12a6…
  zero-indexer-hub   4c985bd7… -> e3ca33f0…

Measured from committed source (ab40208), per the README's "commit first,
then measure" rule: the values come from the CI runs on that commit, not from
a working tree.

No shim or hub source change: src/ and Cargo.toml are untouched and Cargo.lock
moves by exactly the one path-dep version line. This is the same class as the
77fa2dc4… row, the 0.8.0 pull's bump to 0.4.0, except that one also needed two
.into() call sites where the Bytes payload type changed; 0.4.0 to 0.6.0 needs
none.

Recorded in the shim's table as a new current row with the old one demoted to
superseded. The hub's README keeps no such table and points at
EXPECTED_SHA256, so it needs no prose change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous commit inserted it under the StageX image-digest table, which is
a different three-column table earlier in the same file. No value changed;
EXPECTED_SHA256 was correct throughout.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical and moderate issues remain in release automation, chain-head/store behavior, CI tooling, and documentation.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

zaino/.github/workflows/rc-gate.yml:225

  • If the deployment POST fails after the RC tag was pushed, this warning lets the workflow finish without dispatching the soak. A rerun sees that tag at the same RC_SHA, sets cut=false, and skips this dispatch step, so the RC can remain permanently untested. Retry or independently reconcile the deployment for an existing RC tag instead of gating dispatch only on a newly cut tag.
  • Files reviewed: 87/536 changed files
  • Comments generated: 4
  • Review effort level: Lite

- name: Push release commit
run: |
set -euo pipefail
git push origin "HEAD:refs/heads/stable"
Comment thread zaino/packages/zaino-chain-head-service/src/service.rs
// serves its reads through the ephemeral passthrough it holds a
// reference to, so the watermark standing still for the duration is
// the correct description of what the primary can answer.
refresh_watermark(&router).await;
tag_vars+="-ZEBRA_$ZEBRA_VERSION-DEVTOOL_${devtool_rev:0:12}"
tag_vars+="-CONTAINER_$container_hash"
echo "$tag_vars"
echo "RUST_$RUST_VERSION-CONTAINER_$container_hash"
Copilot AI review requested due to automatic review settings September 15, 2026 13:37
@aphelionz

Copy link
Copy Markdown
Member Author

On the Copilot review

All eight findings are in vendored upstream code, not in this PR's authored change. Checked rather than asserted: every flagged file returns zero results for git log --grep='^\[zero\]' -- <file>.

Flagged file [zero] commits
zaino-chain-head-service/src/service.rs 0
zaino-chain-store-zainodb/src/store.rs 0
zaino-mempool-service/src/coherence/publish.rs 0
zainod-heights-from-validator-spec.md 0
.github/workflows/blessing.yml 0
tools/scripts/get-ci-image-tag.sh 0

Our actual delta in this subtree is six files: Dockerfile, .dockerignore, README.md, zaino-proto/build.rs, chain_index.rs, and the supply-chain/ store. The review read 265 commits of upstream history as authored change, which is the expected failure mode for a subtree re-vendor and not a criticism of the findings themselves.

Two of them are real, and I verified both rather than dismissing them on scope:

  • u8 recursion counter (service.rs:488). Confirmed by resolving the constants: default max_retained_depth is 1011, so the guard cannot trip before the counter overflows at 255. Needs a >255-block reorg, so near-unreachable on mainnet. Detail.
  • Partial advance published as success (service.rs:409). A None from block_at_height breaks the loop and returns Ok. This one sits on a path we have already been bitten by: a syncing validator advertising a tip it cannot serve is exactly what 41d4342ded exists to survive. Detail.

Both are being filed at zingolabs/zaino and will flow back on the next subtree pull. Neither is patched here: per MAINTENANCE.md a general bugfix is upstream-bound, and carrying one would add permanent divergence to a refactor we have just taken, which is the cost this whole re-vendor was meant to avoid.

The remaining six (single-flight race, watermark provenance, mempool same-epoch thaw, relman paths, sandbox ruleset, CI image tag) are also upstream and unreviewed by me in depth. The doc-link nit is in a vendored .md and is upstream's to fix.

Nothing here is a regression against our previous zaino 0.8.0 import in code we own. Validation on this branch is unchanged: 758/758 nextest, cargo vet --locked green, and the zeronym hub and shim build and pass their suites plus the real-mixnet smoke against the new zaino-proto.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical and moderate findings remain in release workflows, changeset handling, runtime ordering, and sandbox cleanup.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (4)

Previously missed (1) — in code that hasn't changed since the last review.

zaino/.github/CODEOWNERS:16

  • This default owner is an unresolved placeholder, so GitHub cannot request a reviewer for any path covered by *; CODEOWNER-based approval requirements can therefore never be satisfied as documented. Replace it with a real team or user before relying on this file for the release branch rules.

zaino/.github/workflows/release-pr-body.yml:32

  • The manual workflow_dispatch path checks out the dispatch ref, which defaults to the repository's default branch rather than release-ready. It then derives the release body from that branch's manifests and changesets while only refreshing the ledger from stable, so a maintainer dispatching this workflow without explicitly selecting release-ready can overwrite the standing PR with a body for the wrong tree. Check out release-ready explicitly for both push and manual runs.
    zaino/docs/release/pipeline.md:231
  • The release-gate documentation still claims that zcashd_support, clientless::json_server, and e2e::devtool_zcashd exist, but the re-vendored live-test workspace has no such feature or binaries. This makes the documented suite membership impossible to reproduce; remove this feature-axis paragraph and the corresponding table rows.
    zaino/docs/updating_zebra_crates.md:40
  • The changed guidance says the root Zebra pin reaches every workspace member, but live-tests/ is a separate workspace with its own manifests and lockfile. Following this section can update only the production workspace and leave the live-test validator dependency on a different version; describe the two pin sets separately.
  • Files reviewed: 87/536 changed files
  • Comments generated: 6
  • Review effort level: Lite

Comment on lines 14 to +16
- '[0-9]+.[0-9]+.[0-9]+'
- '[0-9]+.[0-9]+.[0-9]+-rc.[0-9]+'
- 'zainod-[0-9]+.[0-9]+.[0-9]+'
Comment on lines +73 to +75
if !file.starts_with(changesets_dir) {
return None;
}
Comment on lines +39 to +43
set_enforcement "$DEV_RULESET" disabled
set_enforcement "$RR_RULESET" disabled
set_enforcement "$STABLE_RULESET" disabled

# 2. Clean slate: delete all cycle/prerelease/crate tags + any GitHub Release, so
Comment on lines +32 to +35
for r in "$DEV_RULESET" "$RC_RULESET" "$RR_RULESET" "$STABLE_RULESET"; do set_enforcement "$r" disabled; done
for b in dev rc release-ready stable; do git push -f "$REMOTE" "${base}:refs/heads/${b}"; done
delete_pipeline_tags_and_releases
for r in "$DEV_RULESET" "$RC_RULESET" "$RR_RULESET" "$STABLE_RULESET"; do set_enforcement "$r" active; done
Comment on lines +31 to +32
set_enforcement "$DEV_RULESET" disabled
set_enforcement "$STABLE_RULESET" disabled
Comment on lines +38 to +42
# zcashd_support feature axis (orthogonal): clientless::json_server and
# e2e::devtool_zcashd are `#![cfg(feature = "zcashd_support")]`; the default
# --no-default-features build holds zero of their tests. They run only in a
# zcashd-feature build (rc-tier by size there); the filtersets below target
# the default build and do not touch them.
Resolves the expected CHANGELOG conflict: #78 (lightwalletd CVEs) and this
branch each opened an `## Unreleased` section. Both sets of entries are kept,
folded into one section under Security / Changed / Removed. No content dropped
from either side.

SUBTREES.md auto-merged; the lightwalletd un-pin note and the zaino 0.10.0 pin
note are both present.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings September 15, 2026 13:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved review findings remain in release automation, relman tooling, sandbox scripts, and documentation.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (3)

zaino/.github/workflows/blessing.yml:245

  • Pushing the release commit before the tag, GitHub Release, and crate-publish steps makes any later failure unrecoverable: stable now contains consumed changesets and bumped versions, so a rerun computes the next cycle and exits at the empty publish plan, while a partial upload cannot resume from plan.txt because it was only in RUNNER_TEMP. A transient tag/release/crates.io failure therefore strands the release; publish the plan before this push, or persist and explicitly resume the in-flight cycle from the release commit/tag.
    zaino/.github/workflows/rc-gate.yml:226
  • A deployment-creation failure is swallowed after the RC tag has already been pushed. Because the next run sees that tag at the same rc SHA, need.cut becomes false and this deployment is never retried, leaving the release permanently stuck without a soak. Make deployment dispatch retryable for an existing tag (and fail the job on an unhandled API error), or create the deployment before making the tag the idempotency marker.
    zaino/.github/workflows/release-pr-body.yml:110
  • Every RC is written as deployment = "pending", and neither deployment-advance.yml nor this workflow reads the GitHub Deployment status afterward. Consequently the release PR continues to report pending even after a successful or failed deployment, so its deployment dashboard is permanently stale. Populate this field from the Deployment status for each RC (or update the status snapshot when deployment_status arrives).
  • Files reviewed: 87/536 changed files
  • Comments generated: 4
  • Review effort level: Lite

Comment on lines +260 to +263
if git rev-parse -q --verify "refs/tags/$tag" >/dev/null; then
echo "Tag $tag already exists; skipping."
continue
fi
Comment on lines +80 to +86
impl ChangesetCommandError {
/// The process exit status this error maps to.
pub fn exit_code(&self) -> u8 {
match self {
Self::CheckMalformed { .. } => EXIT_CHECK_MALFORMED,
_ => EXIT_CHECK_FAILED,
}
Comment on lines +240 to +242
fn publish_plan(&self) -> Result<PublishPlan, ArtifactError> {
let table = self.versions.derive()?;
Ok(PublishPlan::new(self.topo_order(&table)?))
Comment on lines +17 to +19
# The tags the release pipeline creates: `cycle-<N>`, `cycle-<N>-rc.<M>`, and
# the per-crate `<crate>-X.Y.Z` provenance tag (no `v`).
PIPELINE_TAG_PATTERN='^cycle-|-[0-9]+\.[0-9]+\.[0-9]+$'
@aphelionz

Copy link
Copy Markdown
Member Author

Second and third Copilot batches: same scope point, plus these are inert here

Ten further findings since the summary above, bringing the total to eighteen. Same check as before, same result: zero [zero] commits on every flagged file.

Flagged file [zero] commits
.github/workflows/release.yaml 0
.github/workflows/blessing.yml 0
tools/relman/crates/core/src/types/slug.rs 0
tools/relman/crates/cli/src/commands/changeset.rs 0
tools/relman/crates/domain/src/services/release_artifacts.rs 0
tools/scripts/sandbox-common.sh 0
tools/scripts/sandbox-cycle.sh 0
tools/scripts/sandbox-bless-ledger-check.sh 0
tools/scripts/sandbox-sentinel-check.sh 0
.release/gate-suites.toml 0

This batch is narrower than the first, though. All ten are zaino's own release-engineering machinery: relman, the sandbox blessing cycle, their tag/publish workflows and gate manifest. That matches what the 0.10.0 window actually contained, which the upstream watch digested as release engineering almost entirely.

None of it executes in this repository, and that is checkable rather than assumed:

  • GitHub Actions only reads workflows from the repository root .github/workflows/. Vendored zaino/.github/workflows/* is inert. Confirmed against the run history: the only workflows that have ever run here are our own ten (cargo-vet, images, release, z3-regtest, z3-smoke, zebra-bench, zeronym-guards, the two reproduce jobs, and Copilot Review). No blessing, no zaino release, no changeset-check.
  • grep -rn 'relman\|sandbox-cycle\|sandbox-common\|blessing' .github/ deploy/ docker/ qa/ returns nothing. We do not invoke any of it.

So the failure modes described (a sandbox left with branch protection disabled, a changeset check evaded by a nested path, publish = false ignored in a publish plan, glob-versus-regex tag filters skipping a release) are real concerns for zingolabs' release process, and cannot fire in Zero's.

Not filing these upstream either, deliberately. The two I did file, zingolabs/zaino#1551 and zingolabs/zaino#1552, are in the node's service code: they can affect a running node, they are on a path we have been bitten by, and I verified both against the source. This batch is in-flight tooling its owners are actively iterating on right now; ten drive-by issues on someone's release pipeline is noise, not contribution. If any of it later starts gating something we depend on, it changes category and we revisit.

No code change here. Validation unchanged: 758/758 nextest, cargo vet --locked green, reproduce jobs green after the re-baseline, CHANGELOG conflict with #78 resolved keeping both sides.

@aphelionz
aphelionz merged commit 31afbf6 into main Sep 15, 2026
28 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.

2 participants