sememe 0.4.25 → 0.4.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A local meaning layer for Solana bytes. `sememe pull <program>` fetches and verifies a program interface; every process on the machine can then decode instructions, accounts, and events offline.
4
4
 
5
- **Status: v0.4.25 — published on the npm registry AND as a git tag. Pull/store plus an offline decoder for instructions, Anchor event self-CPIs and account state, verified against real mainnet programs; union decode across a program's on-chain IDL and its adopted first-party published copy (`sememe adopt` + `sememe decode --union`); the fingerprint lockfile ships (`sememe lock` + `sememe verify`); the decode path installs zero runtime dependencies. The ecosystem-wide measured coverage is 88.8% (18,967/21,350 payloads across 6 finalized blocks, 2026-11-13; 96.4% on the curated watchlist, 63.8% outside it; byte-exact re-encode on 93.1% of decoded). The honest limits ride with every number: zero external users so far — publish is not consumption — one machine, no audit.**
5
+ **Status: v0.4.26 — published on the npm registry AND as a git tag. Pull/store plus an offline decoder for instructions, Anchor event self-CPIs and account state, verified against real mainnet programs; union decode across a program's on-chain IDL and its adopted first-party published copy (`sememe adopt` + `sememe decode --union`); the fingerprint lockfile ships (`sememe lock` + `sememe verify`); the decode path installs zero runtime dependencies. The ecosystem-wide measured coverage is 88.8% (18,967/21,350 payloads across 6 finalized blocks, 2026-11-13; 96.4% on the curated watchlist, 63.8% outside it; byte-exact re-encode on 93.1% of decoded). The honest limits ride with every number: zero external users so far — publish is not consumption — one machine, no audit.**
6
6
 
7
7
  Everything below the fold is what you run. The full measurement and qualification history — every number, artifact, defect found and fixed, and every honest limit — was moved verbatim to [docs/measured-history.md](https://github.com/auroraxo/sememe/blob/main/docs/measured-history.md) on 2026-11-13; nothing was deleted.
8
8
 
@@ -56,7 +56,7 @@ Measured on that sample (2026-11-04): 1,000 checked transactions, 6,337 payloads
56
56
  ## Install (as a consumer, not a contributor)
57
57
 
58
58
  ```bash
59
- npm install github:auroraxo/sememe#v0.4.25 # tagged release; no npm account needed
59
+ npm install github:auroraxo/sememe#v0.4.26 # tagged release; no npm account needed
60
60
  ```
61
61
 
62
62
  ```js
@@ -75,14 +75,14 @@ The **library** refuses the same way: importing `sememe/pull` or `sememe/gap` wi
75
75
  **From an install (not a clone), the CLI is `npx sememe …`** — npm exec resolves the package's own `bin` from `node_modules`; the bare command `sememe` is not on your `PATH` after a plain `npm install`, and `node bin/sememe.mjs` works only inside a clone of the repository (both measured 2026-11-05 from a real tarball install). The consumer journey from the install, verbatim:
76
76
 
77
77
  ```bash
78
- npm install github:auroraxo/sememe#v0.4.25 @solana/web3.js # acquisition needs the peer
78
+ npm install github:auroraxo/sememe#v0.4.26 @solana/web3.js # acquisition needs the peer
79
79
  npx sememe pull whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc --store ./store
80
80
  npx sememe decode whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc 2b04ed0b1ac91e62a40d0100000000000100000000000000af331ba8327fbb35b1c4feff00000000010001010000000601 --store ./store
81
81
  ```
82
82
 
83
83
  `./store` is the local content-addressed store the error `no sememe store at ./store: run "sememe pull" first` tells you to create — the `pull` above is that creation step; the vendored programs (System, ComputeBudget, SPL Token, Token-2022, Raydium AMM v4, SPL Associated Token Account) need no store at all: `npx sememe decode-native 11111111111111111111111111111111 <payload>` answers offline from the pinned upstream tables. If you ever point the decoder at a store directory that does not exist yet, the refusal names the fix; `npx sememe` is the form of that fix that runs where you are. Measured 2026-11-05 from the packed tarball of this tree: install (zero deps) → `npx sememe pull` (live mainnet) → `npx sememe decode` (byte-exact, live-pulled object byte-identical to the fixture store object `0b886e37…660f`).
84
84
 
85
- Publishing to the npm registry changed on 2026-11-12: the `sememe` name is now live on registry.npmjs.org (first shipped as 0.4.21; the measured registry install of `sememe@0.4.22` into an empty app decoded the Whirlpool fixture payload `swap_v2`, `roundTripByteExact: true`). `npm install sememe` and `npm install github:auroraxo/sememe#v0.4.25` deliver the same product files from the same code: the files allowlist already ships none of this repository's tests, fixtures or qualification harness (pinned by `test/package.test.mjs`), so the git tag remains the release artifact — `test/package.test.mjs` (the contract above), `tools/e2e-package-consumer.mjs` (a real install into an empty directory) and `test/install-surface.test.mjs` (the shipped README's install commands run verbatim from the packed tarball) keep both channels honest.
85
+ Publishing to the npm registry changed on 2026-11-12: the `sememe` name is now live on registry.npmjs.org (first shipped as 0.4.21; the measured registry install of `sememe@0.4.22` into an empty app decoded the Whirlpool fixture payload `swap_v2`, `roundTripByteExact: true`). `npm install sememe` and `npm install github:auroraxo/sememe#v0.4.26` deliver the same product files from the same code: the files allowlist already ships none of this repository's tests, fixtures or qualification harness (pinned by `test/package.test.mjs`), so the git tag remains the release artifact — `test/package.test.mjs` (the contract above), `tools/e2e-package-consumer.mjs` (a real install into an empty directory) and `test/install-surface.test.mjs` (the shipped README's install commands run verbatim from the packed tarball) keep both channels honest.
86
86
 
87
87
  ## Working now: pin the answers (`sememe lock` + `sememe verify`, 2026-11-05)
88
88
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sememe",
3
- "version": "0.4.25",
3
+ "version": "0.4.26",
4
4
  "description": "Local, fingerprint-verified Solana program interfaces: pull an IDL once, then decode instructions, accounts and events offline. Zero dependencies on the decode path. Ships derived wire tables for System, ComputeBudget, SPL Token, Token-2022 (incl. its token-metadata fallback), Raydium AMM v4 and the SPL Associated Token Account, pinned to upstream Rust.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/codec.mjs CHANGED
@@ -365,7 +365,7 @@ function decodeAt(type, cur, ctx, path, depth) {
365
365
  // keeps the strict prefix codec byte for byte.
366
366
  if (ctx.__countFromHeader && ctx.__countFromHeader.vectorPath === path) {
367
367
  const length = ctx.__countFromHeader.count;
368
- const elementSize = ctx.__countFromHeader.pointBytes;
368
+ const elementSize = ctx.__countFromHeader.elementBytes;
369
369
  const needed = length * elementSize;
370
370
  if (needed > cur.remaining) {
371
371
  // The measured count does not fit the remaining bytes: this is NOT a
@@ -1167,7 +1167,7 @@ export function decodeInstructionData(idl, data, { allowTrailing, trailing, abse
1167
1167
  countArg: headerRule.countArg,
1168
1168
  vectorArg: headerRule.vectorArg,
1169
1169
  vectorPath: `${instruction.name}.${headerRule.vectorArg}`,
1170
- pointBytes: headerRule.pointBytes,
1170
+ elementBytes: headerRule.elementBytes,
1171
1171
  instruction: instruction.name,
1172
1172
  };
1173
1173
  }
@@ -1365,7 +1365,7 @@ export function encodeInstructionData(idl, name, args, { absent } = {}) {
1365
1365
  countArg: headerRule.countArg,
1366
1366
  vectorArg: headerRule.vectorArg,
1367
1367
  vectorPath: `${instruction.name}.${headerRule.vectorArg}`,
1368
- pointBytes: headerRule.pointBytes,
1368
+ elementBytes: headerRule.elementBytes,
1369
1369
  instruction: instruction.name,
1370
1370
  };
1371
1371
  }
@@ -49,21 +49,25 @@
49
49
  // tail after the points is 8 bytes for all 144 (an undeclared field the IDL
50
50
  // does not name — reported as trailing, never invented).
51
51
 
52
- const POINT_BYTES = 21;
53
-
54
52
  /**
55
53
  * The measured count-from-header table, keyed by program address.
56
54
  *
57
55
  * Every entry is a program+instruction pair whose wire layout was measured
58
56
  * against chain-accepted payloads with a committed artifact; nothing here is
59
- * inferred from an IDL claim or from a shape match.
57
+ * inferred from an IDL claim or from a shape match. `elementBytes` is the
58
+ * measured size of ONE vector element — a property of the element TYPE the
59
+ * measurement walked, never a global constant: CurvePointInput is 21 bytes
60
+ * (research/hadro-vec-wire-2026-11-13.json: 144/144 payloads fit n x 21),
61
+ * SpreadTriggerInput is 66 (research/live-layout-scan-hadro-witness-
62
+ * 2026-11-14.json: 2/2 chain-accepted live payloads numTriggers=5 x 66 =
63
+ * 330 body bytes, trailingBytes 0).
60
64
  */
61
65
  export const COUNT_FROM_HEADER = {
62
66
  HADRoNbLovyqhCsocfYQYB7QdfCAAinN9HTePvBCVDQ8: {
63
- source: 'research/hadro-vec-wire-2026-11-13.json',
64
67
  instructions: {
65
- setCurve: { countArg: 'numPoints', vectorArg: 'points' },
66
- setRiskCurve: { countArg: 'numPoints', vectorArg: 'points' },
68
+ setCurve: { countArg: 'numPoints', vectorArg: 'points', elementBytes: 21, source: 'research/hadro-vec-wire-2026-11-13.json' },
69
+ setRiskCurve: { countArg: 'numPoints', vectorArg: 'points', elementBytes: 21, source: 'research/hadro-vec-wire-2026-11-13.json' },
70
+ updateSpreadConfig: { countArg: 'numTriggers', vectorArg: 'triggers', elementBytes: 66, source: 'research/live-layout-scan-hadro-witness-2026-11-14.json' },
67
71
  },
68
72
  },
69
73
  };
@@ -79,10 +83,10 @@ export const COUNT_FROM_HEADER = {
79
83
  *
80
84
  * @param {object} idl the IDL being decoded (must carry `address`)
81
85
  * @param {string} name the instruction name being decoded/encoded
82
- * @returns {{countArg: string, vectorArg: string, pointBytes: number}|null}
86
+ * @returns {{countArg: string, vectorArg: string, elementBytes: number, source: string}|null}
83
87
  */
84
88
  export function countFromHeader(idl, name) {
85
89
  const entry = COUNT_FROM_HEADER[idl?.address]?.instructions?.[name];
86
90
  if (!entry) return null;
87
- return { ...entry, pointBytes: POINT_BYTES };
91
+ return { ...entry };
88
92
  }