Repository navigation
0.14.1: a small, documented public surface (exports map, dismissCMB, openStore, semanticEncoder switch) - #54
Conversation
…er switch
An embedding host (XMesh) reached into lib/ by path because the package declared no
public surface. This declares a small one, and adds the three things it was missing:
- package.json "exports": ".", "./core" (ten CMB-library names, constants frozen),
"./decision-log" (DecisionLog), "./store" (openStore), "./package.json". Every other
path is refused with ERR_PACKAGE_PATH_NOT_EXPORTED. Bins unchanged.
- node.dismissCMB(key) (MMP 6.4), gated on the same earned authority as validateCMB
(6.5), returning { ok, reason? }. MemoryStore.dismissCMB takes the caller's authority
the same way and no longer returns nothing.
- openStore(cmbsDir, name): the store of a stopped identity, never created, a frozen
handle of get / validateCMB / dismissCMB.
- semanticEncoder: 'eager' | 'off' and SYM_SEMANTIC_ENCODER=off. Requiring sym no
longer starts the model load; a node starts it when built, unless the process is off.
Off: nothing loads, SVAF and section 15.8 measure in the n-gram kernel, remix() mints with
its lineage, unverified, at once.
- svafEvaluator and cliHostMode documented in the constructor JSDoc and tested.
The stock-nodes gate driver reaches NullDiscovery by its place on disk and now also
asserts the surface on the installed tarball.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VMk5HbMaz4oD7zoakvPyA6
…code README "Public API" says, for each subpath, what is promised and what is not. docs/reference.md has the recipes, what replaces each deep import a host used, the host options and the semantic encoder switch. CHANGELOG 0.14.1 lists the subpaths and says the exports map refuses deep imports, which were never supported. SECURITY.md says an opened stopped store cannot check the authority its caller states. docs/reference.md now ships, because the shipped README and CHANGELOG point at it. tests/public-surface.test.js packs the tarball, unpacks it with the repository's dependencies beside it, and checks, on that copy: every documented subpath resolves and exports exactly the documented names (also by name from ESM), no underscore name, a private path is refused with ERR_PACKAGE_PATH_NOT_EXPORTED by require, require.resolve and import, the main entry, ./package.json and both bins work, and the README names what the code exports. Eleven mutations (an extra name, a missing one, an underscore name, a new subpath, a lib/ wildcard, no exports map, no ./package.json, a dropped main name, a DecisionLog method, an unfrozen constant, a README that drifts) must each be reported. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VMk5HbMaz4oD7zoakvPyA6
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VMk5HbMaz4oD7zoakvPyA6
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 61b7541226
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| (function readEnvironment() { | ||
| const v = process.env.SYM_SEMANTIC_ENCODER; |
There was a problem hiding this comment.
Read the environment setting when the node is built
When a host requires the package, then sets process.env.SYM_SEMANTIC_ENCODER = 'off' before constructing its first node, this module-level IIFE has already captured the old value. The constructor consequently remains in eager mode and starts the heavy model load, despite the documented contract that the environment variable may be set before the first node is built. Re-read or otherwise apply the environment setting at node construction time.
Useful? React with 👍 / 👎.
…comparison 0.14.0 removed a stale socket file only if its inode number was still the one it had probed. Linux reuses a removed file's inode number at once, so the guard passed for a socket another daemon had just bound: tests/ipc-listen-exclusive failed on Linux CI (main, Node 20 and 22) and passed on macOS. Reproduced in a Linux container; the same inode number came back after unlink and bind. The removal and the rebind now hold a start lock beside the socket (a directory naming its owner's pid; a dead owner's, or one older than 10 s, is broken). The test runs eight starters at one stale file, checks that a live holder's lock is respected, and that a dead owner's and a reused-pid lock are broken. It passes on Linux (Node 20 and 22) and on macOS; without the lock four of the tests fail. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VMk5HbMaz4oD7zoakvPyA6
sym 0.14.1: a small, documented public surface
XMesh reached into
lib/by package path because 0.14.0 declared noexportsmap. This declares one, with only what XMesh's C0 work (sym-bot/xmesh#47,test/sym-boundary.test.ts) showed it needs, each name documented with what it promises and what it does not (README "Public API", docs/reference.md). Additive for everything that was supported; the wire is unchanged.The surface
@sym-bot/symSymNode,migrateStores,version,rooms,emit,MeshAgent,llm/claude,identity,relocation,invite,platform@sym-bot/sym/corecreateCMB,renderContent,CAT7_CATEGORIES,FIELD_WEIGHT_PROFILES,encode,encodeCategory,encodeForSVAF,categoryKeyV1,kernelId,verifyCMB(the two constants are frozen copies; named imports work from ESM)@sym-bot/sym/decision-logDecisionLog@sym-bot/sym/storeopenStore(cmbsDir, name)@sym-bot/sym/package.jsonAnything else is refused with
ERR_PACKAGE_PATH_NOT_EXPORTED(require, require.resolve, import). Bins unchanged.The three things XMesh had no public API for
node.dismissCMB(key)(MMP 6.4) takes the same earned authority asvalidateCMB(6.5, validator or above) and returns{ ok, reason? }.MemoryStore.dismissCMBtakes the caller's authority the same way (it was ungated and returned nothing; nothing in sym called it).openStorenever creates the directory (ENOSTORE) and returns a frozen handle ofget/validateCMB/dismissCMB. The store is found with the main entry'sidentity.nodeDirById(identity.nodeIdForName(name))+cmbs. The handle cannot check the authority its caller states (a store is files); README and SECURITY.md say so.semanticEncoder: 'eager' | 'off'andSYM_SEMANTIC_ENCODER=off. Off: nothing loads the model, SVAF and 15.8 measure in the n-gram kernel,remix()mints with its lineage, unverified, at once (does not wait for a model that will never load).svafEvaluatorandcliHostModeare documented (constructor JSDoc, README, docs/reference.md) and tested.Decisions to look at
require, so a constructor option could never say no. The load now starts when a node is built or when the kernel is first used. Every host builds a node, so the default behaviour is unchanged in practice; a process that only requires sym (sym --version) loads nothing.'off'is a process setting: any node built with it (or the env var) turns it off for every node and it stays off; a later'eager'does not turn it back on (the node says so).dismissCMBis gated (validator or above), as the spec says (6.5), rather than exposing the old ungated store method..d.ts; XMesh keeps its own ambient declarations, renamed to the new subpaths.docs/reference.mdnow ships in the tarball, because the shipped README and CHANGELOG point at it.Compatibility (the exports map restricts deep imports, which were never supported)
Hit by 0.14.1 when they move to it, none shipped:
feat/0.12.0-sym-014(draft Release 0.13.14 — a peer's admission verdict is observable as it lands #47): the 7 blocked sites move to the subpaths above (the daemon IPC client is dropped by XMesh); its tests deep-importlib/core/index.js(signCMB, assertionIdV2_0...),lib/core/verified-receipt.js,lib/core/state-root,lib/core/context-encoder.js,lib/memory-storeand need the exportedpackage.jsonto find the file by path.sym-014-relayfixandsym-relayfixbranches: the same stock-nodes gate driver importslib/discovery.jsby package path (fixed here in main's copy).xmesh-world-coreandxmesh-grid-web(pinned to sym 0.13.9):proof/level1.tsandtest/oracle.test.tsdeep-importcmb-encoder,cmb-signing,context-encoder,lineage-tether,tether-attestation. Not shipped; hit only if they bump.sym-mesh-channelmain (fix/0.10.2): its tests importlib/node.js,lib/core/cmb-encoder.js,lib/core/cmb-signing.js; itsserver.jsandbin/install.jsfall back tolib/rooms.jsonly whensdk.roomsis missing (never, on 0.14).Not hit: sym-mesh-channel 0.10.1 and XMesh 0.11.0 (both depend on
^0.13), the published sym-mesh-channel 0.11.0 (main export and./package.jsononly), xmesh-core, xmesh-grid-api, sym-llm-sidecar, sym-core, xmesh-station, xmesh-release (^0.13.15), xmesh-agent (retired,^0.13.16). xmesh-world-web's handover scripts load sym by absolute file path, whichexportsdoes not restrict.Verification
npm test: 1472 tests, 1469 pass, 0 fail, 3 skipped (run under the shared heavy lock).npm run gate:stock-nodes: passed, and now also asserts the surface on the installed tarball.npm audit: 0 vulnerabilities.npm pack --dry-run: 87 files, 576 kB.public-surface(packs the tarball, checks every documented subpath and its exact names, private paths refused, main entry/package.json/both bins, README names what the code exports; 11 mutations must each be reported),lifecycle-dismiss,semantic-encoder-switch(child processes with a counting stand-in for the model, so "nothing loads" is a count of zero),host-options. Mutating the code under each (load ignores off, dismiss ungated, node asserts authority, cliHostMode ignored) fails the matching test.Not merged, published or tagged.
🤖 Generated with Claude Code
https://claude.ai/code/session_01VMk5HbMaz4oD7zoakvPyA6