Files
zeekay fb2b7f6d5c zip declares its ops in Rust, and projects them with the Go one's projector
A Rust developer writes Rust handlers, with Rust types and Rust doc comments,
and gets every projection from that source — the same deal a Go developer has
had. No .zap is written by hand and no Go program declares a Rust service's
ops.

The split falls on a measured seam. What is native per language is DECLARING an
op and RUNNING it; what is shared is the projection logic, driven from a neutral
description of the registry.

  Manifest      the registry with the Go taken out: ops, types, fields, wire
                names, prose. App.Manifest fills one in by reflection; a
                proc-macro fills one in as a Rust crate compiles.
  Project*      the OpenAPI document, the MCP tool list, the CLI and the ZAP
                IDL, read off a Manifest. Go's own three now go through them —
                the whole existing suite is the oracle — so Go keeps no private
                path for them and the other languages cannot rot.
  cmd/zipc      the build-time projector. It reads a manifest, or the fragments
                a compiler wrote, and writes the four documents.
  rust/         zip in Rust: #[zip::ops] on an impl block, #[derive(zip::Wire)]
                on a type, a router, a JSON binder, an HTTP door and a ZAP door.
                The wire is generated by zapgen from wire.zap; nothing here
                spells a byte offset by hand and nothing links Go.

The layout rule moved out of the manifest and into the projector, so the offsets
in a .zap are derived once for all three languages rather than three times;
TestProjectZAPMatchesRegistry pins that derivation against the layout the Go
encoder actually writes.

One service, written twice — corpus/info in Go and rust/examples/info in Rust,
fourteen ops each — is the gate. The OpenAPI document, the MCP tool list and the
CLI command tree come out byte-identical, and the ZAP schema agrees on every
struct, type and offset; it differs only where a field carries the declaring
language's own case convention and where the ledger names a type the way the
person who must change it would grep for it.
2026-09-15 11:41:56 -07:00

181 lines
4.2 KiB
JSON

[
{
"annotations": {
"readOnlyHint": true
},
"description": "Bootstrapped reports whether a chain has finished bootstrapping on this node.",
"inputSchema": {
"properties": {
"chain": {
"description": "Chain is the alias or id of the chain to ask about.",
"type": "string"
}
},
"required": [
"chain"
],
"type": "object"
},
"name": "get_chain_bootstrapped"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "ChainID resolves a chain's alias to the id it names.",
"inputSchema": {
"properties": {
"alias": {
"description": "Alias is the name the chain answers to, such as \"X\".",
"type": "string"
}
},
"required": [
"alias"
],
"type": "object"
},
"name": "get_chain_id"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "Chains are the chains this node is running, which is a subset of the chains\nthe P-Chain knows about.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_chains"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "Fees are the transaction fees this node charges, in nLUX.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_fees"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "LPs is where the network's stake stands on every current Lux Proposal.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_lps"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "NetworkID is the number of the network this node is on.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_network_id"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "NetworkName is the name of the network this node is on.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_network_name"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "Identity is this node's id, with the proof it holds the staking key that id is\nderived from.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_node_id"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "Address is where this node tells its peers to reach it.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_node_ip"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "NodeVersion is what this node is running: its own release, the database format\nit reads, and the VM protocol it speaks.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_node_version"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "Peers are the nodes this one is connected to. A list of node ids narrows the\nanswer to those, and no list asks for all of them.",
"inputSchema": {
"properties": {
"nodeIDs": {
"description": "NodeIDs are the peers to answer for; none asks for all of them.",
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"name": "get_peers"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "Upgrades is the upgrade schedule this node runs.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_upgrades"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "Uptime is how much of the network, by stake, reports having seen this node up.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_uptime"
},
{
"annotations": {
"readOnlyHint": true
},
"description": "VMs are the virtual machines installed on this node, and the feature\nextensions its UTXO chains understand.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "get_vms"
}
]