Technical Writer Spec (2026-09-21)
Filled by Technical Writer for this trail ticket. Inventory from main @ 65925dc.
Inventory from default branch main at 65925dc (PR 45). There is no develop trunk. There is no docs/ tree yet.
Goal
Shaped in-repo documentation for KeetaNetwork/node-rs so a new engineer can orient, build, and find cross-file invariants without Notion-only knowledge.
Style matches the KeetaNetwork docs bar already used on KeetaNetwork/anchor PR 442 (layout), asset-movement-anchor-sdk PR 253 (inclusion test, page shape, register, STE prose), and testing-suite PR 21 (thin root README, GitHub line-linked examples, Mermaid keyword-safe ids, outside-contributor build notes when a private package gate applies).
The repository is a Cargo workspace of 14 members. The only markdown file is the root README.md, which is a Makefile command dump and is not a thin pointer into docs.
Tree layout (MUST)
| Path |
Role |
Root README.md |
Thin pointer (what the crate/repo is, toolchain pin, build commands, links into docs/) |
docs/README.md |
Overview: cultural map and navigation index |
docs/STANDARD.md |
Documentation Standard. Requirements Language declared once. No page TOC |
docs/ARCHITECTURE.md |
Cross-file invariants, crate boundaries, rejected alternatives |
docs/QUICKSTART.md |
Implementation: install/build/test and first use |
docs/concepts/* |
Only pages that pass the inclusion test |
Do not add per-crate README.md barrel maps. Crate identity lives in each Cargo.toml description plus rustdoc on that crate lib.rs.
Inclusion test (MUST)
A page earns cost only if it holds at least one of: cross-file invariant, rejected alternative, consumer/operator contract, or operator procedure under pressure.
MUST NOT be barrel maps, field tables that only echo rustdoc, or ticket/phase diaries.
First-pass concept candidates (pass on current main)
Write these only if the page still holds a non-rustdoc invariant after the Architecture draft. Drop any candidate that collapses to a field list.
| Path |
Why it passes |
docs/concepts/features-and-no-std.md |
Consumer contract. Workspace crates share std / alloc / der / rasn gates. keetanetwork-asn1 compile_error! requires at least one of der or rasn. keetanetwork-client http requires a runtime (std on native, wasm on wasm32-unknown-unknown). |
docs/concepts/accounts.md |
Cross-file invariant. keetanetwork-account identities (Account, GenericAccount, KeyPairType, identifier accounts) are consumed by block, vote, x509, client, and bindings. |
docs/concepts/blocks.md |
Consumer contract. Block / BlockBuilder / Operation / AccountRef signing and opening-hash rules span keetanetwork-block and the client builder. |
docs/concepts/votes.md |
Cross-file invariant. Vote versus VoteQuote versus VoteStaple / PossiblyExpiredVote rules live in keetanetwork-vote and are re-exported by the client. |
docs/concepts/certificates.md |
Consumer contract. X.509 builders and stores in keetanetwork-x509 plus account CertSigner / CertVerifier plus vote certificate shape. |
docs/concepts/client.md |
Consumer contract. KeetaClient / UserClient / TransactionBuilder. HTTP transport is generated at build time from keetanetwork-client/openapi/keetanet-node.yaml via progenitor and exposed as generated. |
docs/concepts/bindings.md |
Consumer contract. keetanetwork-bindings is the shared projection. keetanetwork-client-wasm is the browser ABI (amounts as decimal strings, errors with error.code). keetanetwork-client-wasi selects exactly one of p1 or p2 per WASI build. |
Pages that fail the inclusion test (MUST NOT add)
- One README per workspace crate that only restates
Cargo.toml and pub use.
- Field tables for
Account, Block, Vote, or OpenAPI types that rustdoc already carries.
- A "node" or "ledger" product page.
keetanetwork-node/src/lib.rs and keetanetwork-ledger/src/lib.rs are three-line crate docs with no types. Name them as stubs on Architecture.
- Ticket or phase diaries. GitHub issues and PRs stay the history home.
- A standalone URI, ops/debug, or publish-runbook page unless a later ask adds an operator procedure that is not already Quickstart.
Page shape (MUST for every shaped docs/** page)
Title, Abstract, Purpose, Body, Falsified by — in that order.
One register per page.
| Register |
Voice |
Typical pages |
| Concept |
Third person |
Overview, Architecture, docs/concepts/* |
| Implementation |
You / imperative |
Quickstart |
| Operations |
Operator under pressure |
None in the first pass unless a later ask adds one |
| Reference |
Lookup |
None in the first pass. rustdoc is the API reference |
Root README.md is not a shaped docs page. It stays a thin pointer in plain English. It MUST NOT redeclare Requirements Language.
docs/STANDARD.md is a shaped page. It MUST NOT include a page-index TOC.
Comments (MUST when touching rustdoc)
/// rustdoc that adds signal the signature cannot carry. No narration. No historical asides. No negative happy-path comments. STE sentence rules including no semicolon-joined independent clauses.
Crate rustdoc today is uneven.
| Crate |
Current rustdoc signal |
keetanetwork-vote |
Strong crate docs plus #![deny(missing_docs)] plus a rustdoc example |
keetanetwork-client |
Crate docs, no_std contract, rustdoc example for KeetaClient |
keetanetwork-block |
Crate docs plus rustdoc example for BlockBuilder |
keetanetwork-client-wasm |
Browser conventions plus a JS example |
keetanetwork-client-wasi |
p1 / p2 feature contract |
keetanetwork-asn1 |
Feature list. The "exactly one of der or rasn" sentence is stale against the compile_error! that requires at least one |
keetanetwork-account, keetanetwork-crypto, keetanetwork-x509 |
One-line or short crate docs. Public types often lack signal beyond the name |
keetanetwork-node, keetanetwork-ledger |
Placeholder crate docs only |
Public surfaces that already have rustdoc examples MUST keep a short snippet and add GitHub line links into tests where a test is the fuller cookbook.
| Public surface |
Example home on main |
KeetaClient / UserClient |
keetanetwork-client/src/lib.rs rustdoc. Tests: keetanetwork-client/tests/e2e.rs, keetanetwork-client/tests/user_signing.rs |
BlockBuilder |
keetanetwork-block/src/lib.rs rustdoc. Tests: keetanetwork-block/tests/e2e.rs, keetanetwork-block/tests/typescript_compat.rs |
VoteBuilder / VoteStaple |
keetanetwork-vote/src/lib.rs rustdoc. Tests: keetanetwork-vote/tests/e2e_node.rs, keetanetwork-vote/tests/typescript_compat.rs, keetanetwork-vote/tests/wire_corruption.rs |
| Account seed / identifier / sign |
keetanetwork-account/tests/account_creation.rs, seed_derivation.rs, identifier_accounts.rs, signatures.rs |
| X.509 builders / bundles |
keetanetwork-x509/tests/builders.rs, bundles.rs, validation.rs |
| Browser wasm client |
keetanetwork-client-wasm/src/lib.rs rustdoc. Playwright: keetanetwork-client-wasm/tests/roundtrip.spec.ts, fee.spec.ts |
| WASI P1 / P2 |
keetanetwork-client-wasi/src/lib.rs. Host tests under keetanetwork-client-wasi/host-tests/tests/ |
There is no examples/ directory. Do not invent one in this pass.
Mermaid (MUST if used)
Never use bare node or participant ids that are Mermaid keywords (graph, end, subgraph, and the rest of the reserved set).
Architecture MAY use one crate-boundary diagram. Prefer ids such as crate_account and crate_client. Never use a bare id graph.
Scope IN
- Docs markdown under the tree above
- rustdoc on public or API surfaces touched by the docs pass
- Fix broken doc links
- Outside-contributor and private-registry build notes. This repo has the same class of gate as testing-suite (
keetanet-node style). Verified on main:
- Rust crates have path workspace deps only.
.cargo/config.toml sets a wasm32-unknown-unknown getrandom cfg. It does not set a private Cargo registry.
keetanetwork-utils/node-harness/.npmrc sets @keetanetwork:registry=https://npm.pkg.github.com.
keetanetwork-utils/node-harness/package.json depends on @keetanetwork/keetanet-node 0.18.2 and @keetanetwork/eslint-config-typescript 1.4.7.
.github/workflows/ci.yml sets registry-url: https://npm.pkg.github.com, scope: '@keetanetwork', and NODE_AUTH_TOKEN for make node-harness, make test-all, make test-wasm, make test-wasi, lint, and coverage.
make test depends on node-harness. A contributor without GitHub Packages read can still cargo check / cargo build and run crate tests that do not enable the node-harness feature.
- Root README rewrite to a thin pointer. Current README documents
make release as a release build. Makefile on tip uses make build release=1 for a release build. make release runs scripts/release.sh and publishes to crates.io. Quickstart MUST state the Makefile truth.
- rust-toolchain pin from
rust-toolchain.toml: channel 1.94.0, components rustfmt, clippy, llvm-tools-preview, targets wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.
- First-use snippet that builds a signed opening block or a
KeetaClient against http://localhost:8080/api, citing the existing rustdoc examples.
Scope OUT
- Runtime behavior, types, signatures, tests, CI config, dependency versions (unless a docs-only path note)
- Broader historical rewrite of untouched pages without ask
- Full rustdoc every private item
- Merging or rebasing branch
docs/add_pat_instructions as the delivery. That branch is 1 commit ahead and 132 behind main. It only patches root README.md with PAT notes and still documents make release as a release build. Absorb the PAT fact into Quickstart on a fresh docs-only PR from current main.
- Adding crate-level README barrels
- Changing
LICENSE, Cargo.toml license, or publish scripts
- Filling
keetanetwork-node or keetanetwork-ledger with product types
Acceptance criteria
Delivery
Docs-only PR against main (default branch and working trunk). Technical Writer owns the pass. Engineer commits if git write is gated.
PR body MUST include the self-check table used on anchor PR 442:
| Check |
Result |
| Inclusion test |
Each shaped page holds a cross-file invariant, a consumer or operator contract, or a setup procedure |
| Page shape |
Every docs/** page has Title, Abstract, Purpose, Body, Falsified by, in that order. Root README stays a thin pointer |
| Register |
Overview, Architecture, and concept pages are Concept. Quickstart is Implementation |
| Falsified by |
Each page names the code changes that invalidate it |
| Requirements Language |
Declared once in docs/STANDARD.md. No per-page repeat. Root README uses plain English |
| Banned words / compliance claims |
No mirror / parity / bake / wire / seam / escape hatch. No STE or RFC compliance claim |
| Examples |
Public call shape is short. Full flows are GitHub line links into tests on the branch tip |
| Layout |
Standard is docs/STANDARD.md with no TOC. Overview is docs/README.md. Architecture is docs/ARCHITECTURE.md |
OPEN questions
Repo-specific items discovered on main at 65925dc. TW or Engineer answers these during the pass. Do not block the tree on them.
SSOT also on draft PR: #48 (do not merge).
Technical Writer Spec (2026-09-21)
Filled by Technical Writer for this trail ticket. Inventory from
main@65925dc.Inventory from default branch
mainat65925dc(PR 45). There is nodeveloptrunk. There is nodocs/tree yet.Goal
Shaped in-repo documentation for
KeetaNetwork/node-rsso a new engineer can orient, build, and find cross-file invariants without Notion-only knowledge.Style matches the KeetaNetwork docs bar already used on KeetaNetwork/anchor PR 442 (layout), asset-movement-anchor-sdk PR 253 (inclusion test, page shape, register, STE prose), and testing-suite PR 21 (thin root README, GitHub line-linked examples, Mermaid keyword-safe ids, outside-contributor build notes when a private package gate applies).
The repository is a Cargo workspace of 14 members. The only markdown file is the root
README.md, which is a Makefile command dump and is not a thin pointer into docs.Tree layout (MUST)
README.mddocs/README.mddocs/STANDARD.mddocs/ARCHITECTURE.mddocs/QUICKSTART.mddocs/concepts/*Do not add per-crate
README.mdbarrel maps. Crate identity lives in eachCargo.tomldescriptionplus rustdoc on that cratelib.rs.Inclusion test (MUST)
A page earns cost only if it holds at least one of: cross-file invariant, rejected alternative, consumer/operator contract, or operator procedure under pressure.
MUST NOT be barrel maps, field tables that only echo rustdoc, or ticket/phase diaries.
First-pass concept candidates (pass on current
main)Write these only if the page still holds a non-rustdoc invariant after the Architecture draft. Drop any candidate that collapses to a field list.
docs/concepts/features-and-no-std.mdstd/alloc/der/rasngates.keetanetwork-asn1compile_error!requires at least one ofderorrasn.keetanetwork-clienthttprequires a runtime (stdon native,wasmonwasm32-unknown-unknown).docs/concepts/accounts.mdkeetanetwork-accountidentities (Account,GenericAccount,KeyPairType, identifier accounts) are consumed by block, vote, x509, client, and bindings.docs/concepts/blocks.mdBlock/BlockBuilder/Operation/AccountRefsigning and opening-hash rules spankeetanetwork-blockand the client builder.docs/concepts/votes.mdVoteversusVoteQuoteversusVoteStaple/PossiblyExpiredVoterules live inkeetanetwork-voteand are re-exported by the client.docs/concepts/certificates.mdkeetanetwork-x509plus accountCertSigner/CertVerifierplus vote certificate shape.docs/concepts/client.mdKeetaClient/UserClient/TransactionBuilder. HTTP transport is generated at build time fromkeetanetwork-client/openapi/keetanet-node.yamlvia progenitor and exposed asgenerated.docs/concepts/bindings.mdkeetanetwork-bindingsis the shared projection.keetanetwork-client-wasmis the browser ABI (amounts as decimal strings, errors witherror.code).keetanetwork-client-wasiselects exactly one ofp1orp2per WASI build.Pages that fail the inclusion test (MUST NOT add)
Cargo.tomlandpub use.Account,Block,Vote, or OpenAPI types that rustdoc already carries.keetanetwork-node/src/lib.rsandkeetanetwork-ledger/src/lib.rsare three-line crate docs with no types. Name them as stubs on Architecture.Page shape (MUST for every shaped
docs/**page)Title, Abstract, Purpose, Body, Falsified by — in that order.
One register per page.
docs/concepts/*Root
README.mdis not a shaped docs page. It stays a thin pointer in plain English. It MUST NOT redeclare Requirements Language.docs/STANDARD.mdis a shaped page. It MUST NOT include a page-index TOC.Comments (MUST when touching rustdoc)
///rustdoc that adds signal the signature cannot carry. No narration. No historical asides. No negative happy-path comments. STE sentence rules including no semicolon-joined independent clauses.Crate rustdoc today is uneven.
keetanetwork-vote#![deny(missing_docs)]plus a rustdoc examplekeetanetwork-clientno_stdcontract, rustdoc example forKeetaClientkeetanetwork-blockBlockBuilderkeetanetwork-client-wasmkeetanetwork-client-wasip1/p2feature contractkeetanetwork-asn1derorrasn" sentence is stale against thecompile_error!that requires at least onekeetanetwork-account,keetanetwork-crypto,keetanetwork-x509keetanetwork-node,keetanetwork-ledgerPublic surfaces that already have rustdoc examples MUST keep a short snippet and add GitHub line links into tests where a test is the fuller cookbook.
mainKeetaClient/UserClientkeetanetwork-client/src/lib.rsrustdoc. Tests:keetanetwork-client/tests/e2e.rs,keetanetwork-client/tests/user_signing.rsBlockBuilderkeetanetwork-block/src/lib.rsrustdoc. Tests:keetanetwork-block/tests/e2e.rs,keetanetwork-block/tests/typescript_compat.rsVoteBuilder/VoteStaplekeetanetwork-vote/src/lib.rsrustdoc. Tests:keetanetwork-vote/tests/e2e_node.rs,keetanetwork-vote/tests/typescript_compat.rs,keetanetwork-vote/tests/wire_corruption.rskeetanetwork-account/tests/account_creation.rs,seed_derivation.rs,identifier_accounts.rs,signatures.rskeetanetwork-x509/tests/builders.rs,bundles.rs,validation.rskeetanetwork-client-wasm/src/lib.rsrustdoc. Playwright:keetanetwork-client-wasm/tests/roundtrip.spec.ts,fee.spec.tskeetanetwork-client-wasi/src/lib.rs. Host tests underkeetanetwork-client-wasi/host-tests/tests/There is no
examples/directory. Do not invent one in this pass.Mermaid (MUST if used)
Never use bare node or participant ids that are Mermaid keywords (
graph,end,subgraph, and the rest of the reserved set).Architecture MAY use one crate-boundary diagram. Prefer ids such as
crate_accountandcrate_client. Never use a bare idgraph.Scope IN
keetanet-nodestyle). Verified onmain:.cargo/config.tomlsets awasm32-unknown-unknowngetrandomcfg. It does not set a private Cargo registry.keetanetwork-utils/node-harness/.npmrcsets@keetanetwork:registry=https://npm.pkg.github.com.keetanetwork-utils/node-harness/package.jsondepends on@keetanetwork/keetanet-node0.18.2and@keetanetwork/eslint-config-typescript1.4.7..github/workflows/ci.ymlsetsregistry-url: https://npm.pkg.github.com,scope: '@keetanetwork', andNODE_AUTH_TOKENformake node-harness,make test-all,make test-wasm,make test-wasi, lint, and coverage.make testdepends onnode-harness. A contributor without GitHub Packages read can stillcargo check/cargo buildand run crate tests that do not enable thenode-harnessfeature.make releaseas a release build.Makefileon tip usesmake build release=1for a release build.make releaserunsscripts/release.shand publishes to crates.io. Quickstart MUST state the Makefile truth.rust-toolchain.toml: channel1.94.0, componentsrustfmt,clippy,llvm-tools-preview, targetswasm32-unknown-unknown,wasm32-wasip1,wasm32-wasip2.KeetaClientagainsthttp://localhost:8080/api, citing the existing rustdoc examples.Scope OUT
docs/add_pat_instructionsas the delivery. That branch is 1 commit ahead and 132 behindmain. It only patches rootREADME.mdwith PAT notes and still documentsmake releaseas a release build. Absorb the PAT fact into Quickstart on a fresh docs-only PR from currentmain.LICENSE,Cargo.tomllicense, or publish scriptskeetanetwork-nodeorkeetanetwork-ledgerwith product typesAcceptance criteria
Makefile/rust-toolchain.toml:1.94.0viarust-toolchain.tomlmake developermake buildorcargo buildmake build release=1(notmake release)make checkorcargo checkmake test(cargo test --all-features --workspaceaftermake node-harness)make test-featmake test-allmake build-wasm/make test-wasmmake build-wasi/make test-wasimake do-docs/make do-docs-cimake releaseis a release buildDelivery
Docs-only PR against
main(default branch and working trunk). Technical Writer owns the pass. Engineer commits if git write is gated.PR body MUST include the self-check table used on anchor PR 442:
docs/**page has Title, Abstract, Purpose, Body, Falsified by, in that order. Root README stays a thin pointerdocs/STANDARD.md. No per-page repeat. Root README uses plain Englishdocs/STANDARD.mdwith no TOC. Overview isdocs/README.md. Architecture isdocs/ARCHITECTURE.mdOPEN questions
Repo-specific items discovered on
mainat65925dc. TW or Engineer answers these during the pass. Do not block the tree on them.keetanetwork-nodeandkeetanetwork-ledgeras empty stubs and does not invent node-runtime behavior.main.LICENSEis Keeta Token Network Community License (v1.0). WorkspaceCargo.tomllicenseisMIT.keetanetwork-utils/node-harness/package.jsonlicenseisKeeta Token Network Community License. Overview MUST cite what the files say. It MUST NOT reconcile them in this docs-only pass.[workspace.package] versionis0.3.0. Member crate versions on tip range from0.2.1(error,utils,ledger,node) to0.6.1(keetanetwork-client-wasi). Cite per-crateCargo.tomlversions. Do not cite the unused workspace package version as the repo version.make release/scripts/release.shcrates.io publish as an operator note, or leave publish undocumented until a later ask?docs/add_pat_instructions(commit520f743, 2026-06-19) is stale. Confirm it is not the delivery branch.make developerinvokesscripts/rustup-init.sh -y --default-toolchain stablewhen rustc is missing.rust-toolchain.tomlthen pins1.94.0for this repo. Quickstart MUST tell the reader the pin wins after clone.keetanetwork-votedeniesmissing_docs. How far does this rustdoc pass go onaccount,crypto, andx509public items? Default: only items the shaped pages name.make test-wasm) and WASI host tests (make test-wasi) need the harness plus extra toolchains (wasm-pack, Playwright, JDK 17 / Maven for Java bindings). Are those first-use Quickstart steps or a later Operations note? Default: name the Make targets and the PAT gate. Do not write a Java binding tutorial unless a later ask adds it.SSOT also on draft PR: #48 (do not merge).