Repository navigation
feat(antd, antd-go): ADR-0006 manifest endpoints: build, decode and link - #346
Conversation
…570)
Daemon callers (Indelible, the SDKs) can now build and read `.ant`
manifests and `ant://` links without re-implementing the format. antd
keeps no state: encoding, validation, content addresses, link form and
the portable path rules all come from ant-core's manifest module
(ant-core 0.13.0, first shipped on this branch's repin).
REST:
- POST /v1/manifests/build: entries of `data_map` (hex, embedded) or
`address` (public), optional name and torrent info hashes. `size` is
recorded as given, as ant-core's builder does. With `embed_roots`
(default true) a shrunk DataMap is resolved and its root embedded when
it is at most 64 KiB, as `embeddable_data_map` decides. Returns the
`.ant` bytes, the link when it fits 1,500 bytes, and each entry's
effective name and content address. Every invalid entry is named in
the 400 (`entries[i]: ...`).
- POST /v1/manifests/decode: `.ant` bytes or any link (manifest link,
file link, bare address). Embedded entries return their DataMap in the
hex form the download routes accept. `resolve` fetches DataMaps and
wrapper records for exact sizes; one entry's failure is reported in
its `error`, not as a failed call.
gRPC: ManifestService (manifests.proto), Build and Decode, unary. A
manifest is one document of at most 64 MiB, produced and parsed whole,
so requests are accepted up to the REST body limit (100 MiB) instead of
being framed into a stream.
antd-go: BuildManifest, DecodeManifest, DecodeManifestLink on both
clients (gRPC raises its per-call receive limit), stubs regenerated with
protoc 34.1. OpenAPI and llms docs updated.
Verified:
- antd: 126 unit tests (13 new, against an in-memory network), fmt,
clippy -D warnings.
- antd-go: tests, go vet, golangci-lint v1.64.8.
- Live on mainnet with `ant` 0.3.11-rc.1:
- a manifest the CLI built from two public videos decodes; rebuilding
it from the decoded root DataMaps gives the CLI's exact bytes;
- rebuilding from the link's shrunk DataMaps (wrapper records fetched
over the network) also gives the CLI's exact bytes;
- the CLI shows and downloads both entries from antd-built manifests
(54,903,201 and 11,572,127 bytes);
- resolve reports exact sizes and a per-entry not-found error;
- REST and gRPC (via antd-go) produce identical bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The manifest endpoints now stack on the pointer API instead of beside it, so the two features' overlap is resolved once, here, and the pointer fan-out PRs never see it. Every conflict was both features adding an entry at the same spot, so both are kept, pointers first: - antd/build.rs: both protos are compiled. - antd/src/grpc/mod.rs: both services are imported and registered. - antd/src/rest/mod.rs: both route modules. - antd/src/types.rs: both type sections. - antd-go/grpc_client.go: both service clients. - antd-go/scripts/generate-protos.sh: PROTOS lists both. - llms.txt, llms-full.txt: both REST tables and both gRPC sections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The manifest operations' OpenAPI descriptions said "added in antd 0.16.0". The release number isn't set yet, so say "the antd release after 0.15.0", the wording the pointer and SDK docs settled on. The same guess in llms-full.txt is reworded by the docs PR stacked on this one, so it's left alone here to keep that PR's diff clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings up #325's move from the rc.1 pin to the released ant-core 0.13.0 (ant-cli-v0.3.11) and ant-protocol 5.0.0. No conflicts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Brings up #325's final ant-cli-v0.3.11 repin via #326 and #346. antd/Cargo.toml and antd/Cargo.lock conflicted on the ant-core and ant-protocol pins; both keep this branch's side, the DEV PIN on WithAutonomi/ant-client#229 with its ant-protocol [patch], because the SHA-256 change needs #229 and ships with it. No other conflicts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Hermes review handoff — ant-sdk #346Review record: Linked Linear ticket: V2-1570. The PR head was read again before posting and still matches the reviewed revision. Required whole-PR panel coverage remains incomplete; this post is not approval. WithAutonomi/ant-sdk #346 — bounded reviewRecommendation: NO NEW MATERIAL BLOCKER CONFIRMED; approval gate remains incomplete. This is an advisory review comment, not a formal GitHub APPROVE/REQUEST_CHANGES review or permission to merge.
FindingsThe daemon delegates manifest encoding/validation to its pinned ant-core, preserves root/shrunk-map policy, canonicalizes names, bounds resolver concurrency at eight, and carries the same build/decode defaults across REST and gRPC. Local manifest tests pass. No new blocker was verified in the #346 delta. The branch still inherits #326's paid-finalize defect; fix and retest the stack in order. Non-blocking: wide integer precision in the Go REST clientThe new manifest methods reuse the existing untyped JSON helpers. A parent-executed This occurs beyond 2^53 bytes; no realistic blocking workload was demonstrated. Do not promote it to a release blocker solely because the synthetic boundary is executable. A typed JSON decoder or Panel dissent resolved against full sourceQwen requested changes because manifest REST handlers allegedly had no body bound. This claim is false: the routes at The server's 100 MiB gRPC setting is a receive cap, not a 100 MiB send cap. The Go 256 MiB receive allowance does not itself conflict with that setting. The pinned codec's send default and the manifest's own 64 MiB bound are separate controls. No unbounded-body DoS finding is accepted from the panel output. Links:
Execution and CI evidence
Actual original panel participationThe design was two independent roles (correctness and adversarial) for each of GLM 5.3/OpenRouter, local Qwen 3.8 27B, and local DS4 Flash. Production evidence was split into complete named scopes, so a role/model required multiple receipts to cover a whole PR. A receipt is not an extra independent model.
UNCERTAIN is unresolved, not approval. Missing, truncated and timed-out seats do not agree. These counts include complete UNCERTAIN opinions and therefore do not mean complete substantive sign-off. No whole-PR six-seat consensus exists. Recommendations without a verified defect remain provisional. Scope-by-scope receipts
Changed-file scope and classification manifest{
"pr": 346,
"head": "4cf292a4761fe07e0db82ba270c177382a4ef7b5",
"base": "d66e50df085c26afb0134b6c857afeaef62303ef",
"changed_file_count": 19,
"files": [
{
"path": "antd-go/grpc_client.go",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd-go/grpc_client_test.go",
"classification": "tests",
"scope": null
},
{
"path": "antd-go/manifest.go",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd-go/manifest_test.go",
"classification": "tests",
"scope": null
},
{
"path": "antd-go/proto/antd/v1/manifests.pb.go",
"classification": "generated",
"scope": null
},
{
"path": "antd-go/proto/antd/v1/manifests_grpc.pb.go",
"classification": "generated",
"scope": null
},
{
"path": "antd-go/scripts/generate-protos.sh",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/build.rs",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/openapi.yaml",
"classification": "docs",
"scope": null
},
{
"path": "antd/proto/antd/v1/manifests.proto",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/src/grpc/mod.rs",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/src/grpc/service.rs",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/src/main.rs",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/src/manifests.rs",
"classification": "production",
"scope": "manifest-core"
},
{
"path": "antd/src/rest/manifests.rs",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/src/rest/mod.rs",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "antd/src/types.rs",
"classification": "production",
"scope": "manifest-transports-go"
},
{
"path": "llms-full.txt",
"classification": "docs",
"scope": null
},
{
"path": "llms.txt",
"classification": "docs",
"scope": null
}
],
"scopes": [
{
"pr": 346,
"scope": "manifest-core",
"head": "4cf292a4761fe07e0db82ba270c177382a4ef7b5",
"base": "d66e50df085c26afb0134b6c857afeaef62303ef",
"evidence": "/Users/studio1/.hermes/cache/scratch/ant-sdk-review-evidence/346/panel-evidence/manifest-core.txt",
"bytes": 40099,
"files": [
"antd/src/manifests.rs"
]
},
{
"pr": 346,
"scope": "manifest-transports-go",
"head": "4cf292a4761fe07e0db82ba270c177382a4ef7b5",
"base": "d66e50df085c26afb0134b6c857afeaef62303ef",
"evidence": "/Users/studio1/.hermes/cache/scratch/ant-sdk-review-evidence/346/panel-evidence/manifest-transports-go.txt",
"bytes": 34833,
"files": [
"antd-go/grpc_client.go",
"antd-go/manifest.go",
"antd-go/scripts/generate-protos.sh",
"antd/build.rs",
"antd/proto/antd/v1/manifests.proto",
"antd/src/grpc/mod.rs",
"antd/src/grpc/service.rs",
"antd/src/main.rs",
"antd/src/rest/manifests.rs",
"antd/src/rest/mod.rs",
"antd/src/types.rs"
]
}
]
}Linear review comment: https://linear.app/autonominetwork/issue/V2-1570/antd-manifest-endpoints-adr-0006-build-decode-and-link-over-rest-grpc#comment-b2032716 |
…nto the integration preview
dirvine
left a comment
There was a problem hiding this comment.
APPROVE — current head after #326 merged
Reviewed head: 532ae15cc2d9595e97d9162b9cfe741958b54653.
Reviewed merge base: 3a2a29aebb8b4f966444c170b360a61f2cdfe31d; target main captured at cea236950084f8738106cc37247c148f0b411d18.
No material blocker remains from this review. The pointer cancellation correction from merged #326 is present. All 19 manifest-change file blobs are identical to the previously inspected feature revision; the inherited change and exact-head checks were reviewed separately. This replaces the earlier provisional/comment-only handoff with a formal verdict, not permission to merge.
Verified checks
- Exact-head
cargo test --lockedfor antd: 148 passed, 0 failed. - Changed handwritten Rust sources:
rustfmt --check --edition 2021exited 0. - Exact-head antd-go:
go test -json ./...,go vet ./..., andgo test -race ./...each exited 0. - GitHub CI at publication: 15 successful, 2 skipped, none failed or pending. Skipped CI jobs are not passing checks; the Go race check was run locally.
Review coverage and dissent
6/12 scoped role opinions completed: 5 APPROVE and 1 UNCERTAIN, from 2/3 named models. Partial panel; no full-team consensus. There are two production scopes, each with correctness/adversarial roles and three requested models; these are not twelve independent models.
- Manifest core: Qwen completed both roles (correctness APPROVE, adversarial UNCERTAIN). GLM and DS4 did not complete either role after one same-model retry each.
- Transports/Go/OpenAPI: GLM and Qwen completed both roles, all APPROVE. DS4 did not complete either role after one same-model retry each.
- Missing seats ended with incomplete termination or bounded wall/request timeout. They are not votes.
Qwen's core UNCERTAIN remains recorded, not relabelled APPROVE. Its concerns were missing caller/dependency context and then-pending tests, not a demonstrated failing path. Parent inspection confirms REST validates entries before build, gRPC does the same, and parse_entries enforces the entry cap. The pinned ant-core 0.13.0 codec rejects bytes above 64 MiB before decoding, and the daemon preserves the inspected core error categories. Current-head tests now pass. The compiler run proves the exercised toolchain, not an untested oldest-supported Rust version. No material defect was confirmed from those uncertainties.
Non-blocking limits and follow-ups
- The earlier unbounded-REST-body finding is refuted: these routes inherit the router-wide 100 MiB body limit. gRPC's 100 MiB receive cap and the Go client's 256 MiB receive allowance are different controls. Finite caps do not establish peak-memory behaviour under concurrent load.
- Go REST's inherited float64 JSON decoding can lose uint64 size precision above 2^53; gRPC is exact. Keep the typed/UseNumber-decoding follow-up. No realistic blocking workload was shown.
- Whole-manifest operations and network reads for root embedding/resolve remain potentially expensive. No paid/live-network E2E, production finalize fault-injection, load test, or full SDK/platform matrix was run by this review. Author-reported live checks are not counted as my execution.
- Generated output was checked separately through prior source/descriptor inspection, exact blob equality and current drift CI; it was not all sent to every production reviewer. Standalone tests/docs were inspected separately.
No merge, release, #347 approval, or Linear state change is authorised or performed by this verdict.
main now has the manifest endpoint docs (#346) and the 16 pointer SDK PRs. The one conflict is llms-full.txt's Go method list, where #339 adds the pointer methods and #346 added the manifest methods at the same spot. Kept both, pointers first, as in the integration preview (#367). The merge's diff against main equals #339's own diff (19 files, +1214/-11), so nothing else changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This is stacked on the pointer API PR, #326, which is stacked on the ant-core 0.13.0 repin (#325). It needs nothing beyond ant-core 0.13.0. The SHA-256 work, which waits on ant-client#229, is a separate PR stacked on this one: #347. Linear: V2-1570.
Daemon callers (Indelible, the SDKs) can now build and read ADR-0006
.antmanifests andant://links without re-implementing the format. antd keeps no state. Encoding, validation, content addresses, the link form and the portable path rules all come from ant-core's manifest module.REST
POST /v1/manifests/builddata_map(hex, embedded) oraddress(public), plus an optional name and torrent info hashes.sizeis recorded as given, as ant-core's builder does.embed_roots(default true), a shrunk DataMap is resolved, and its root is embedded when it is at most 64 KiB, asembeddable_data_mapdecides..antbytes, the link when it fits in 1,500 bytes, and each entry's effective name and content address.entries[i]: ...).POST /v1/manifests/decode.antbytes or any link (manifest link, file link or bare address).resolve: fetches DataMaps and wrapper records for exact sizes. One entry's failure goes in that entry'serror; it doesn't fail the call.gRPC
ManifestService(manifests.proto), withBuildandDecodeas unary calls.antd-go
BuildManifest,DecodeManifestandDecodeManifestLink, on both clients. The gRPC client raises its per-call receive limit.Of the SDKs, only antd-go has client methods. It's the client Indelible, the first consumer, uses. The other SDKs don't have
manifests.protostubs yet.Stacking
This is based on #326, not #325, because the two features add entries at the same spot in 8 files:
antd/build.rsantd/src/grpc/mod.rsantd/src/rest/mod.rsantd/src/types.rsantd-go/grpc_client.goantd-go/scripts/generate-protos.shllms.txtllms-full.txtMerge commit 6c907ed resolves them once by keeping both sides, pointers first. The pointer fan-out PRs (#327–#343) never see the overlap.
Merge order: #325 → #326 → this PR → #347.
Verified
From the original commit:
-D warnings.go vet, and golangci-lint v1.64.8.ant0.3.11-rc.1 (the final 0.3.11 only re-versions it):resolvereports exact sizes and a per-entry not-found error.On this branch after the merge, with the same commands CI runs:
-D warnings,cargo doc, andcargo test --locked. All 147 tests pass, pointer and manifest tests together.go vet,go test, and golangci-lint v1.64.8.CI note. Until #326 picks up the two CI fixes already on #325 (the rustls 0.23.46 bump from main, and the notices fix c226153), this PR inherits #326's two red checks: Security audit and Third-party notices. Neither is caused by this change.
🤖 Generated with Claude Code