From 0446195cc30e0ae856f88c7c57866fdffbc1bbeb Mon Sep 17 00:00:00 2001 From: ayush00git Date: Sat, 20 Jun 2026 19:10:35 +0530 Subject: [PATCH] docs: bugs md updated --- BUGD-BY-D.md | 6 +- BUGS.md | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 299 insertions(+), 3 deletions(-) diff --git a/BUGD-BY-D.md b/BUGD-BY-D.md index 09bb0ee..4a43ade 100644 --- a/BUGD-BY-D.md +++ b/BUGD-BY-D.md @@ -310,7 +310,7 @@ Correctly seeded secrets appear absent at runtime. --- -## Bug #09: Node.js requirement differs between docs and package +## Bug #09: Node.js requirement differs between docs and package (unconfirmed) **Severity:** Medium **Category:** Documentation gap @@ -365,7 +365,7 @@ Registration prerequisites are ambiguous. --- -## Bug #11: Write-contract guide references a sample repo without a URL +## Bug #11: Write-contract guide references a sample repo without a URL (unconfirmed) **Severity:** Medium **Category:** Onboarding / documentation gap @@ -544,7 +544,7 @@ Causes search and navigation confusion. --- -## Bug #17: Telegram support channel is plain text, not a link +## Bug #17: Telegram support channel is plain text, not a link (unconfirmed) **Severity:** Low **Category:** Documentation gap diff --git a/BUGS.md b/BUGS.md index 9116f64..199fabb 100644 --- a/BUGS.md +++ b/BUGS.md @@ -1,6 +1,7 @@ # BUGS.md — Terminal 3 SDK / docs friction log Verified against the [official ADK docs](https://docs.terminal3.io/developers/adk/overview/what-is-adk). Only confirmed issues listed. +For detailed reproduction steps and full write-ups, see [BUGD-BY-D.md](./BUGD-BY-D.md). --- @@ -33,3 +34,298 @@ and captured it in `tools/step3-smoke.ts`. [walkthrough](https://docs.terminal3.io/developers/adk/get-started/walkthrough/invoke-contract) covers `execute()` / `executeAndDecode()` but not the underlying crypto primitives. + +## #3 — `require("@terminal3/t3n-sdk")` fails — CJS entry broken + +`package.json` declares `"type": "module"` **and** maps +`exports["."].require` → `./dist/index.js`. Node therefore treats that file as +ESM, but the file uses CJS `exports[…]` assignments — producing +`ReferenceError: exports is not defined` on `require()`. Since `npm init -y` +creates CJS projects by default, the standard Node onboarding path is broken +out of the box. + +**Proof:** Inspected locally installed `@terminal3/t3n-sdk` (v3.5.2, same +structure in 3.9.0). `package.json` contains `"type": "module"` alongside +`"exports": { ".": { "require": "./dist/index.js" } }`. The tail of +`dist/index.js` confirms `exports[_0x2eb335(…)]=…` CJS-style assignments, +while `dist/index.esm.js` uses `export { … }` ESM syntax — confirming they +are meant to be separate module formats, but `"type": "module"` forces Node to +evaluate both as ESM. + +## #4 — Numbered walkthrough skips mandatory KV map and secret setup + +The official 4-step walkthrough (Write → Build → Register → Invoke) never +includes creating the `secrets` KV map or seeding the API key. The contract's +`book-offer` function reads `duffel_api_key` from `z::secrets`, so +following the walkthrough literally yields a runtime error: +`duffel_api_key not found in z::secrets`. + +The required setup lives only in the Quick Tips sidebar pages +([Create Tenant KV Maps](https://docs.terminal3.io/developers/adk/tips/create-kv-maps), +[Seed API key](https://docs.terminal3.io/developers/adk/tips/seed-api-key)), +which are not referenced in the numbered flow. + +**Proof:** The +[register-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/register-contract) +page mentions `secrets` and `contractId` only in the troubleshooting section at +the bottom and links to the tips pages — but does not include an actual +provisioning step. The +[invoke-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/invoke-contract) +page jumps straight to `executeAndDecode()`. Meanwhile, the +[write-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/write-contract) +page's Rust sample (`get_api_key()`) will error if the map is not pre-populated. + +## #5 — `invoke-contract.md` uses undefined `userClient` + +The egress-authorization snippet on the +[invoke-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/invoke-contract) +page calls `userClient.execute(...)`, but `userClient` is never imported, +constructed, or defined on this page or in any earlier walkthrough/setup page. +The +[dev-env setup](https://docs.terminal3.io/developers/adk/get-started/prerequisites/set-up-dev-env) +guide creates only `t3n` (`T3nClient`) and `tenant` (`TenantClient`). Section 2 +of the same invoke page creates `agentClient` — still not `userClient`. +Additionally, `agentDid`, `TENANT_SCRIPT`, and `scriptVersion` are used without +any prior definition or import guidance. + +**Proof:** Searched all four walkthrough pages (write, build, register, invoke) +and the dev-env setup page for `userClient` — zero definitions. The only +clients ever constructed are `t3n`, `tenant`, and `agentClient`. Copy-pasting +the egress-authorization snippet is a compile/runtime dead end. + +## #6 — npm README contradicts official ADK onboarding docs + +The `@terminal3/t3n-sdk` package README and the ADK +[setup guide](https://docs.terminal3.io/developers/adk/get-started/prerequisites/set-up-dev-env) +present incompatible first-client configurations: + +| Topic | npm README | ADK setup guide | +|---|---|---| +| Install cmd | `pnpm add @terminal3/t3n-sdk` | `npm install @terminal3/t3n-sdk` | +| Key env var | `T3N_DEMO_KEY` | `T3N_API_KEY` | +| Node URL | `baseUrl: "https://t3n-node.example.com"` (hardcoded) | `setEnvironment("testnet")` (no baseUrl) | +| Token claim | not mentioned | ADK [claim page](https://docs.terminal3.io/developers/adk/get-started/prerequisites/request-test-tokens) | + +**Proof:** Compared `node_modules/@terminal3/t3n-sdk/README.md` (locally +installed v3.5.2) with the ADK setup guide. The README's Quick Start uses +`process.env.T3N_DEMO_KEY!` and passes a placeholder `baseUrl`, while the ADK +guide uses `process.env.T3N_API_KEY!` with `setEnvironment("testnet")` and no +`baseUrl`. A developer following the README will use the wrong env var and an +unroutable example URL. + +## #7 — ESM `import` samples lack module-type guidance + +The ADK +[setup guide](https://docs.terminal3.io/developers/adk/get-started/prerequisites/set-up-dev-env) +uses `import { T3nClient, … } from "@terminal3/t3n-sdk"` (ESM syntax) but +never explains that a default Node project (`npm init -y`) is CommonJS. Running +the sample verbatim in a fresh project produces +`SyntaxError: Cannot use import statement outside a module`. The page contains +no mention of `"type": "module"`, `.mts`, `.mjs`, or any ESM configuration step. + +**Proof:** Searched the full +[set-up-dev-env](https://docs.terminal3.io/developers/adk/get-started/prerequisites/set-up-dev-env) +page for `"type"`, `module`, `esm`, `.mts`, `.mjs`, and `import statement` — +zero results. The code samples use `import { … }` and top-level `await`, both +of which require ESM mode, but no configuration guidance is provided. + +## #8 — OpenAPI specifications in `llms.txt` return 404 + +The [llms.txt](https://docs.terminal3.io/llms.txt) documentation index +advertises two OpenAPI spec URLs that do not resolve: + +| URL | Status | +|---|---| +| `https://docs.terminal3.io/terminal-3-openapi.yml` | **404** | +| `https://docs.terminal3.io/api-reference/openapi.json` | **404** | + +**Proof:** Verified with `curl -s -o /dev/null -w "%{http_code}"` against both +endpoints — both return HTTP 404. The `llms.txt` file lists them under an +`## OpenAPI Specs` heading, implying they should be live specs for automated +client generation and API discovery. + +## #9 — Placeholder outbound-call Rust sample is incompatible with the walkthrough + +The Rust snippet on the +[placeholders-outbound-calls](https://docs.terminal3.io/developers/adk/tips/placeholders-outbound-calls) +tips page uses different bindings, types, and field names than the +[write-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/write-contract) +walkthrough for the same `http-with-placeholders` API: + +| Aspect | Tips page | Walkthrough | +|---|---|---| +| Import | `crate::bindings::t3n::host::http_with_placeholders` | `crate::host::interfaces::http_with_placeholders as hwp` | +| HTTP method | `method: "POST".to_string()` (String) | `method: hwp::Verb::Post` (enum) | +| Body field | `body: Some(...)` | `payload: Some(...)` | +| Headers | `headers: vec![...]` (Vec) | `headers: Some(duffel_headers(...))` (Option) | + +**Proof:** Compared the code blocks on both pages side-by-side. The tips page +snippet will not compile against the bindings generated by the walkthrough's +`wit_bindgen::generate!` macro — it produces unresolved-module, wrong-field, +and type-mismatch errors. These are fundamentally incompatible Rust type +signatures for the same host interface. + +## #10 — Seed-key guide documents the wrong KV map read path + +The [seed-api-key](https://docs.terminal3.io/developers/adk/tips/seed-api-key) +tips page states that the contract reads the key back with +`kv_store::get("secrets", "duffel_api_key")` (using the short map name +`"secrets"`). However, the +[write-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/write-contract) +walkthrough uses the tenant-qualified name: + +```rust +let map_name = format!("z:{}:secrets", hex::encode(&tid)); +let bytes = kv_store::get(&map_name, b"duffel_api_key"); +``` + +The walkthrough's own design rules state: _"kv-store calls take the full +`z::` name. Build it at runtime from `tenant_context::tenant_did()`."_ +The short `"secrets"` name in the tips page will not resolve at runtime. + +**Proof:** The same tips page's *seeding* snippet correctly uses +`tenant.canonicalName("secrets")` (which produces `z::secrets`), but then +documents the *read* path as the bare string `"secrets"` — contradicting both +itself and the walkthrough. + +## #11 — Registration guide references nonexistent "steps 4 and 5" + +The [register-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/register-contract) +page says: _"If you have not created one yet, complete step 4 and 5 of +[set up the dev environment](https://docs.terminal3.io/developers/adk/get-started/prerequisites/set-up-dev-env) +first."_ However, the setup page uses unnumbered section headings ("Get your API +key and DID", "Install Rust + WASM toolchain", "Install the SDK", "Set up the +SDK", "Authenticate to T3N testnet") — there are no explicit steps 4 or 5 to +follow. + +**Proof:** The dev-env page's subtitle is "Quick 4 steps" (implying 4 sections, +not 5), but the body presents them as unnumbered headings. A developer reading +"complete step 4 and 5" has to guess that these probably mean "Set up the SDK" +and "Authenticate to T3N testnet" — but the numbering doesn't align (4 steps +total, not 5+). + +## #12 — Onboarding does not document `tenant.tenant.claim()` + +The ADK [overview](https://docs.terminal3.io/developers/adk/overview/what-is-adk) +lists `claim()` as a key capability, and the SDK type declarations expose it: + +```typescript +declare class TenantNamespace { + claim(): Promise; + me(): Promise; +} +``` + +However, the +[dev-env setup](https://docs.terminal3.io/developers/adk/get-started/prerequisites/set-up-dev-env) +guide goes straight from `t3n.authenticate()` to constructing a `TenantClient` +without ever calling `await tenant.tenant.claim()`. The register-contract +troubleshooting section warns about `tenant not found` errors — the exact +symptom of skipping the admission step — but neither page explains how or when +to call `claim()`. + +**Proof:** Searched the full dev-env setup page for `claim` — the only match is +a link to the "claim page" for API keys, not the `tenant.tenant.claim()` SDK +call. The SDK's `TenantClient` exposes `this.tenant = new TenantNamespace(this)` +with a `claim()` method, but no onboarding step invokes it. A developer who +follows the setup literally may hit `tenant not found` at registration time. + +## #13 — `contracts.register()` return type is `unknown`; walkthrough accesses `.contract_id` + +The SDK types `register()` (and `publish()`) as `Promise`: + +```typescript +publish(input: ContractPublishInput): Promise; +register(input: ContractPublishInput): Promise; +``` + +But the [register-contract](https://docs.terminal3.io/developers/adk/get-started/walkthrough/register-contract) +walkthrough does `const contractId = result.contract_id;` — which is a +TypeScript strict-mode error (`'result' is of type 'unknown'`). No response +interface is exported. + +**Proof:** Inspected `node_modules/@terminal3/t3n-sdk/dist/index.d.ts`. Both +`publish` and `register` return `Promise`. The type exports list +includes `ContractPublishInput` (the input) but no corresponding response type. +The walkthrough's `result.contract_id` access requires an unsafe `as any` cast +to compile. + +## #14 — npm README OTP example calls browser-only `prompt()` in Node + +The `@terminal3/t3n-sdk` README's OTP flow uses `prompt()` to collect the +verification code: + +```typescript +const code = await prompt(`Code sent to ${requested.contact}: `); +await client.otpVerify({ otpCode: code, ... }); +``` + +Node.js has no global `prompt` — verified locally: + +``` +$ node -e "console.log(typeof prompt)" +undefined +``` + +The example crashes with `ReferenceError: prompt is not defined` before +`otpVerify()` is ever called. + +**Proof:** Tested on the current system's Node. The README does mention +`runOtpThenUserInput` with a `getOtpCode` callback as an alternative at the +bottom, but the primary copy-paste example uses `prompt()` which is +browser-only. A Node-compatible approach (`readline/promises` or an explicit +callback) should be the primary example in an SDK README that targets Node. + +## #15 — Internal link to DID documentation returns 404 + +The [Smart VCs](https://docs.terminal3.io/intro/components/vc) intro page links +to `https://docs.terminal3.io/documentation/preliminaries/web-standards/dids` +for DID background. That URL returns HTTP 404. + +**Proof:** `curl -s -o /dev/null -w "%{http_code}"` against the DID URL returns +`404`. The VC page itself (HTTP 200) contains the link text _"DIDs are used to +represent credential subjects"_ pointing to the broken path. No redirect or +alternative DID page exists at the legacy `/documentation/` prefix. + +## #16 — "Developer key" naming hides the Ethereum private-key requirement + +The [claim page](https://docs.terminal3.io/developers/adk/get-started/prerequisites/request-test-tokens) +says _"Copy and store your developer key"_, and the setup guide stores it as +`T3N_API_KEY`. But the code immediately passes it to Ethereum cryptographic +functions: + +```typescript +const address = eth_get_address(T3N_API_KEY); +handlers: { EthSign: metamask_sign(address, undefined, T3N_API_KEY) }, +``` + +Neither the claim page nor the setup guide explains that this "key" is a +secp256k1 Ethereum private key (32-byte hex), not a rotatable API token. A +developer supplying an opaque token or non-hex string gets +`Invalid Ethereum private key` with no diagnostic context. + +**Proof:** Searched the claim page and dev-env setup page for "private key", +"Ethereum", "secp256k1", "hex", and "0x" — zero results. The only descriptor +is "developer key" / "API key", which conventionally implies a revocable +service credential, not a cryptographic signing key requiring custody +precautions. + +## #17 — `publish` and `register` terminology is inconsistent + +The ADK [overview](https://docs.terminal3.io/developers/adk/overview/what-is-adk) +lists `publish` as the key capability for deploying contracts, while the +[walkthrough step 3](https://docs.terminal3.io/developers/adk/get-started/walkthrough/register-contract) +is titled "Register your TEE contract" and calls `tenant.contracts.register()`. +The SDK exports both methods with the identical input type and no explanation of +their relationship: + +```typescript +publish(input: ContractPublishInput): Promise; +register(input: ContractPublishInput): Promise; +``` + +**Proof:** The overview's capability table shows `publish` (no mention of +`register`). The walkthrough exclusively uses `register`. The SDK type +declarations export both on `TenantContractsNamespace` with the same +`ContractPublishInput` signature. No docs page explains whether they are +aliases, sequential operations, or distinct actions.