Skip to content

V1.1.0 SDK & Documentation - #15

Merged
kamescg merged 134 commits into
mainfrom
update/v1.1.0-alpha
Oct 28, 2026
Merged

kamescg merged 134 commits into
mainfrom
update/v1.1.0-alpha

Conversation

@kamescg

@kamescg kamescg commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor

Public identity packages and v1.1.0 SDK/CLI

Adds sixteen public ESM packages for canonical identifiers, classification/provider resolution, deterministic atom construction, protocol/periphery interactions, dynamic-fee math, deployment metadata, and SDK/CLI workflows. The release plan publishes fifteen changed packages to alpha; schema-org is already published and unchanged.

Core artifacts now match @0xintuition/contracts-v2@1.1.0-alpha.1, including the updated MigrationMode surface. Router artifacts match the separate @0xintuition/contracts-v2-periphery@1.1.0-alpha.0 package. Registry verification binds installed ABI/bytecode modules to exact lockfile integrities. release:check passes. Deployment compatibility and SDK mathematical parity require separate validation.

The public tree contains developer documentation, source, specifications, tests, and release tooling. Internal planning/session documents have been removed, public links updated, and npm publication checks reject assistant instructions and hidden working notes in tarballs. Existing public agent-facing SDK/CLI APIs remain available.

Validation

  • Frozen install, contract registry verification, candidate artifact fingerprints, and release-version availability checks pass.
  • Package/publication guards, provenance tampering tests, and supply-chain policy tests pass. Release-age exceptions bind only the two exact contract versions/integrities and expire November 2, 2026.
  • Clean-room tarball build/install/import/type checks pass for all public packages, including the SDK and CLI.
  • Conformance: 1,027 pass, 23 TODO, zero unexpected failures. The reference comparison still records 98 known differences; fixtures were not rewritten.
  • Latest hosted CI status is shown in this PR's checks. No browser or live transaction validation is claimed.

Remaining before merging to main

Keep this umbrella PR in draft until those gates are satisfied. Passing artifact checks does not satisfy identity migration or consumer acceptance.

Getting started · Artifact provenance · Release guide · Conformance evidence

kamescg and others added 15 commits August 10, 2026 12:00
- Add the iid-v1.1.0-alpha planning packet (PR stack, package contracts,
  release runbook, acceptance matrix), including the recorded authoritative
  private reference source for porting.
- Restore the private root package version to 0.0.0; the release train is
  labeled by branch/PR name, not by the root version.
- Add scripts/package-registry.mjs as the single source of package order and
  packaging metadata, with topological-order and exact-internal-version
  assertions; pack-dry-run and smoke-tarballs now consume it instead of
  duplicated hard-coded arrays.
- Support documentation-only packages in tarball assertions ahead of iid-spec.
- Add a PR template with package/identity/fixture impact, contract artifact,
  target versions, and rollout notes fields.

Identity impact: none — existing golden bytes unchanged

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Port the IID specification from the private reference
  (0xIntuition/intuition-v2 @ 8b9e9aa11): explainer and spec sections
  00-09, with private-monorepo references replaced by public links.
- Author the 26 per-scheme normative documents and the scheme registry
  index, each with grammar, ordered canonicalization, validation rules,
  test vectors, and known limitations grounded in the reference
  canonicalizers.
- Add the versioned machine-readable conformance corpus: 145 vectors
  across canonicalization (positive+negative for every scheme), NORM-1,
  gen1 (with exact preimages), parsing (colon-bearing values, int:src:*
  guard), validation/anchor-eligibility, and the registry snapshot,
  plus their JSON schema. All vectors generated from and asserted
  against the reference implementation; spec-stated golden values
  (ISBN upconversion, gen1 movie r4) cross-checked.
- Add implementation-notes.md recording the resolved parser
  value-grammar deviation the public port fixes.
- Add a fixture/document integrity test (schema shape, coverage,
  unique IDs, link resolution, private-reference leak guard).
- Register iid-spec as the first, docs-only entry in the central
  package registry; teach guard-direct-publish docs-only rules.

Identity impact: none — existing golden bytes unchanged

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Port the reference implementation from the private source
  (0xIntuition/intuition-v2 @ 8b9e9aa11): all 26 scheme canonicalizers,
  NORM-1, gen1 preimage/hash, geohash, UUIDv5/podcast-guid, keccak16.
- Fix the parser value character class to the spec grammar (%x21-7E):
  space and non-ASCII values now reject as malformed, matching the
  normative parse vectors (recorded in iid-spec implementation-notes).
- Redesign the identity-ladder contract around the public declarative
  source/recipe types (field, same-as, url-origin, geohash,
  podcast-guid, and the frozen named derivations) and implement the
  pure declarative derivation engine that interprets them; ladders are
  serializable data, never callbacks.
- Add the typed inspection API (inspectIntuitionId) distinguishing
  malformed / unknown-scheme / noncanonical, with canonical repair for
  read paths, plus anchor-eligibility reasons (class-c vs polymorphic).
- Execute the full 145-vector conformance corpus from
  @0xintuition/iid-spec in the test suite (212 tests) alongside ported
  and new engine tests.
- Register iid second in the central package registry.

Identity impact: none — no existing golden bytes change; all
spec-stated golden values (ISBN upconversion, gen1 movie r4)
reproduce exactly.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* refactor(classifications): consume public IID identity contracts (P03)

- Replace the duplicated identity type definitions (IdentityClass,
  IdentitySchemeName, IdentityDerivationName, IdentityValueSource,
  IdentityRecipeField, IdentityRung) with re-exports from
  @0xintuition/iid; IdentitySchemeName remains as a compatibility alias
  of SchemeName. IdentitySpec stays local as the classification
  embedding of a ladder.
- Derive IDENTITY_SCHEME_CLASS and IDENTITY_SCHEME_TYPING from the iid
  scheme registry instead of hand-maintained tables, keeping the
  existing export names for consumers.
- Add exact dependency @0xintuition/iid@0.1.0-alpha.0 (and the viem
  peer it implies); bump classifications to 0.1.0-alpha.1.
- Update the primitives exact pin to classifications@0.1.0-alpha.1 and
  carry primitives at its release target 0.1.0-alpha.1.
- Generated ladder data, provenance checks, creation profiles, and
  legacy JSON-LD outputs are unchanged; all 39 classification tests
  and the 12-package clean-room smoke pass.

Identity impact: none — existing golden bytes unchanged

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(classifications): expose identityLadderFor in the iid engine shape

The registry and the primitives builder consume ladders through the
deriveIntuitionId(ladder, values) contract; this exposes each
classification's declared ladder in exactly that shape (slug-namespaced
for gen1), completing the P03 scope item.

Identity impact: none — existing golden bytes unchanged

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style: sort classification index exports

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…20)

- Port the pure semantic bridge from the private reference
  (0xIntuition/intuition-v2 @ 8b9e9aa11, PR #1115): scheme->
  classification table (direct, value-typed, explicit-unmapped),
  provider capability plans, canonical-input leniency, and identifier
  hints.
- Adapt IidClassification to public classification fields (slug,
  schemaType, displayName, category); the private AtomCategory does
  not port — runtime label policy belongs in application adapters.
- Classification is total over unambiguous schemes with ratified
  outcomes: iswc explicitly unmapped; caip19 narrows to canonical
  eip155/erc20 only; mbid release folds to music-album, label to
  company, work unmapped; olid A->person, W/M->book; gen1 slug
  authoritative when the classification exists.
- Provider plans are deterministic, open/no-key-first capability
  identifiers; value-aware narrowing for acct/purl/caip10/caip19.
- Port and adapt the five test suites (42 tests): totality, ladder
  coherence (registry as read-side inverse of ladders), vocabulary
  grounding via schema-org, provider ordering/narrowing, hints, and
  live golden-path fixtures through the real ladders.
- Register iid-registry after classifications in the release registry.

Identity impact: none — existing golden bytes unchanged

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Add buildIidAnchor, the supported high-level path from a
  classification's field values to on-chain-ready atom bytes:
  interprets the declarative identity ladder through @0xintuition/iid,
  selects the strongest legal representation profile (P0 when
  anchor-eligible, otherwise a deterministic P1 payload with frozen key
  order carrying @type, identifier, and the fired recipe's fields),
  computes the atom ID through @0xintuition/ids, and returns the
  registry's classification and ordered provider plan.
- Class C and polymorphic-scheme identifiers floor at P1; requesting
  p0 for them is a structured error, never a silent downgrade.
- Add ordered, trimmed, exact-deduplicated URI-context manifest
  construction with offline policy limits (5 x 700 bytes) and optional
  caller-supplied live limits; URI context never changes atom bytes or
  atom ID.
- Add recognizeAtomData: classifies canonical IID anchors vs JSON
  payloads without reclassifying arbitrary strings; isValidAtomData
  now accepts valid canonical IID anchors as atom data.
- Add exact deps @0xintuition/iid@0.1.0-alpha.0 and
  @0xintuition/iid-registry@0.1.0-alpha.0, the ./anchor subpath
  export, README section, and 10 anchor tests including the golden P0
  ISRC byte/ID fixture (140 primitives tests total).
- Legacy JSON-LD builders unchanged; all existing snapshots stable.

Identity impact: none — existing golden bytes unchanged; new golden
P0 ISRC fixture values generated from the shipped ids package and
pinned in tests.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Port the reference implementation from the private source
  (0xIntuition/intuition-v2 @ 8b9e9aa11): all 26 scheme canonicalizers,
  NORM-1, gen1 preimage/hash, geohash, UUIDv5/podcast-guid, keccak16.
- Fix the parser value character class to the spec grammar (%x21-7E):
  space and non-ASCII values now reject as malformed, matching the
  normative parse vectors (recorded in iid-spec implementation-notes).
- Redesign the identity-ladder contract around the public declarative
  source/recipe types (field, same-as, url-origin, geohash,
  podcast-guid, and the frozen named derivations) and implement the
  pure declarative derivation engine that interprets them; ladders are
  serializable data, never callbacks.
- Add the typed inspection API (inspectIntuitionId) distinguishing
  malformed / unknown-scheme / noncanonical, with canonical repair for
  read paths, plus anchor-eligibility reasons (class-c vs polymorphic).
- Execute the full 145-vector conformance corpus from
  @0xintuition/iid-spec in the test suite (212 tests) alongside ported
  and new engine tests.
- Register iid second in the central package registry.

Identity impact: none — no existing golden bytes change; all
spec-stated golden values (ISBN upconversion, gen1 movie r4)
reproduce exactly.

Signed-off-by: Kames Geraghty <sudo+github@kames.me>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
- Add dynamic-fee-curve.ts: tier ladder, tier lookup, piecewise deposit-fee
  quote, and withdrawal-fee rate mirroring the on-chain
  DynamicFeeFlatPriceCurve tier math; the top tier reports as unbounded.
- Add the gross-up solvers (grossUpAtomCreate, grossUpAtomDeposit,
  grossUpTripleCreate, grossUpTripleDeposit) that solve the gross wallet
  debit for an exact net deposit, plus GrossDepositQuote and the
  DynamicFeeConfig / DynamicFeeTierOverride / DynamicFeeTierLadderEntry
  types.
- Export the new surface from the package index; existing exports keep
  their signatures and bodies.
- Raise the vitest timeout so CI hardware variance does not fail correct
  tests.

Ported from the private reference implementation at feat/intuition-app
@ 1b877506d; source imports converted to the package's .js style.

Identity impact: none — curves carries no atom bytes.
…atom (P14)

- Add auth-user-atom.ts: deterministic IntuitionAuthUser atom data from a
  hashed user id (authUserIdHash, createAuthUserAtomData,
  serializeAuthUserAtomData, authUserAtomDataHex, calculateAuthUserAtomId)
  with the derivation version pinned in the payload.
- Add i-atom.ts: the shared first-person subject atom whose identity is the
  exact byte `I`; I_SUBJECT_ID is computed from calculateAtomId at module
  load and pinned by test.
- Export the new surface from the package index and cover it in the
  public-entrypoints test.

Ported from the private reference implementation at feat/intuition-app
@ 1b877506d; source imports converted to the package's .js style. The
OAuth atom context URL is deliberately left unchanged pending a ruling.

Identity impact: additive only — calculateAtomId, calculateTripleId,
createPredicateAtomData and every existing constant keep their bytes;
the new constants reproduce the reference values exactly.
…dBridgeRouter artifacts (P08)

- Add the FeeProxy ABI and bytecode and the fee-proxy wrappers:
  createAtomsWithUrisVia (+ calldata encoder), registerAffiliate,
  affiliateConfig, isAffiliateActive, previewCreationFee, pendingRefund,
  claimRefund, and the FeeGuard type.
- Add getFeeProxyAddressFromChainId over a periphery-local FeeProxy
  deployment map (empty until a deployment exists; the helper throws).
- Regenerate the TrustSwapAndBridgeRouter ABI and bytecode from the
  deployed contract and move the Base-mainnet address to
  0xE485D9a5Dc39774b7A80864B625969Cf9d93E5D7. The ownership, initializer
  and configuration-setter entries in the previous ABI never existed on
  the deployed contract (owner() reverts at both addresses); the
  swapAndBridgeWithERC20 / swapAndBridgeWithETH wrappers now take the
  required deadline argument.
- Keep INTUITION_MAINNET_CHAIN_ID sourced from @0xintuition/deployments.
- Remove a stray non-source file from src/contracts.

Ported from the private reference implementation at feat/intuition-app
@ 1b877506d.

Breaking: the two swap wrappers gain a required deadline argument, and the
router ABI export drops stale administrative entries.

Identity impact: none. Periphery carries no atom bytes.
…eeFlatPriceCurve, BondingCurveRegistry, approvals, createFor, multicall) (P15)

Additive port of the intuition-v2 protocol modules that shipped the app,
onto the train's existing P06/P07 surface:

- contracts: add AtomWarden and DynamicFeeFlatPriceCurve ABI + bytecode
  artifacts (verbatim from v2); existing artifacts, provenance record and
  MultiVaultMigrationMode exports untouched (R3)
- types: ApprovalTypes const object + alias (erasable, not an enum)
- multivault: approveEncode, createAtomsFor(+Encode), createTriplesFor(+Encode),
  isApprovedToCreate/Deposit/Redeem, multicall(+Encode); comment-only deltas
  on approve/redeem/redeemBatch
- core/atom-warden (29 wrappers), core/dynamic-fee-flat-price-curve (14),
  core/bonding-curve-registry (2), events/dynamic-fee-flat-price-curve (3)
- root barrel exports for the four new modules; public-entrypoints test
  covers the 58 new functions, the artifacts, all approval combinations and
  the createFor/multicall calldata
- README sections for each new surface

No deployments/networks/utils ported; wrappers take addresses through
ReadConfig/WriteConfig (R4). P07 files unchanged. No version or dependency
changes; the version freeze is a separate commit.

Gates: protocol 124 tests, typecheck, check, build; react typecheck against
the built dist; pack dry run. Review pair round 1: spec MERGE-READY; the
adversarial pass reported one Major finding on the three new event parsers
(no emitter-address filter), which is the same pattern every existing
multivault parser in this package uses and is inherited from the port
source; it is recorded for a package-wide follow-up rather than fixed
here.
…c amendment and reference implementation (P16)

Ports intuition-v2's typed-wd identity onto the release train as one unit,
because the iid conformance test executes the iid-spec vectors.

iid-spec
- schemes/wd.md: value grammar `^(?:<slug>:)?Q[1-9]\d*$`, ordered
  canonicalization for typed forms, value-typed scheme typing (bare
  polymorphic; typed with an active EntitySchema binding unambiguous and
  P0-eligible; dormant binding valid but not mintable), the closed
  binding table with pinned revisions, typed vectors, ladder-rung note
- spec/07 §7.3: value-typed schemes defined; wd rows split bare/typed
- spec/09 §9.3.1: additive value-grammar extensions (in-place MINOR
  ratification under four conditions); wd is the first instance
- conformance: value-typed corpus support (`valueTyped` on scheme
  entries, optional per-vector `typing`, validator effective-typing
  guards); 18 new wd vectors; all 145 base vectors unchanged apart from
  one note; scheme typing entries unchanged
- README / schemes README updated

iid
- wd-entityschema-bindings.ts: the 11 pinned bindings (film,
  television-series, human active), deep-frozen table/rows/anchorQids,
  frozen slug list, membership guards
- schemes.ts: typed-aware wd canonicalizer (URL forms never infer a slug,
  ASCII slug lowercased and must be registered, QID uppercased); the
  ratified whitespace trim is kept for every form; SCHEME_TYPING.wd stays
  polymorphic
- types.ts: `wdSlug` on the declarative scheme rung, `dormant-wd-binding`
  ineligibility reason, `wdSlug` on the valid inspection branch
- parse.ts: per-value inspection for typed wd (active → unambiguous and
  eligible; dormant → ineligible)
- derive.ts: typed derivation on the declarative engine (active slug
  only, same-slug check, bare-prefixing, length bound); slugless wd rungs
  keep minting bare values and bare values only
- index.ts exports; README section; tests re-expressed against
  declarative ladders, fence test replaced by a positive export test

Ruled: R1 (typed-wd canonical for the packages). Default-in-effect,
pending ratification: R17 (§9.3.1), D-P16-1..5. No version or
dependency changes; the version freeze is a separate commit.

Gates: iid-spec 163 vectors; iid 263 tests, typecheck, check, build;
iid-registry 42, iid-ladder 12, classifications 38, primitives 140
against the rebuilt dist; pack dry run. Review: round 1 pair found three
real issues (trim regression, typed values minting through slugless
rungs, mutable bindings table), fixed; round-2 combined re-review found
no new defect.
…s and pinned P31 closure (P16b)

Second typed-wd unit, stacked on the iid/iid-spec amendment. Ports the
intuition-v2 iid-ladder machinery onto the train's package form:

- wd-p31-closure.ts: pinned active-binding P31 closure with its SHA-256
  (generated from the intuition-v2 control-plane artifact; verbatim)
- category-rungs.ts: IdentityCategory / IdentityRungToken, the shared
  create+seed IDENTITY_CATEGORY_RUNG_POLICY, WIKIDATA_P31_IDENTITY_POLICY,
  resolveWikidataP31Identity, schemeOrderForIdentityCategory (with an
  own-property guard so inherited names such as `constructor` read as
  unknown categories instead of throwing; deliberate hardening over v2)
- identity-rung-iid.ts: iidForIdentityRung alias projection
- ladder.ts: typed-wd hints (wdSlug, conflict detection, active-only
  minting, bare and dormant wd never mint), isMintableWdIid on the
  int:-shaped provider path and registered handles, provider-handle
  promotion into strong selection under a classification order, and
  canonicalization of raw strong identifiers at ingest (R19)
- provider-prefixes.ts: additive rows and comments only
- index.ts exports; README sections; tests converted from bun:test to
  vitest and re-expressed on the train's fixtures

Held out under R16 (provider-local IID emission): no generic IID shape,
no provider-local minting branch, and the train's `unregistered` handle
status / `unregistered-provider` reason are unchanged; 44 v2 emission
cases are listed in the lane report, not ported.

iid: adds the `isCanonicalNodeIid` node-boundary predicate (verbatim
from v2) that the alias helper needs; exported with tests. No version
or dependency changes.

Gates: iid 266 tests; iid-ladder 123 tests, typecheck, check, build;
iid-registry 42, classifications 38, primitives 140 against the rebuilt
dist; pack dry run. Review: round-1 pair (one inherited crash fixed,
category-order subtype question raised as R20, provider-promotion
conflict bypass recorded as inherited from v2); round-2 re-review found
no new defect.
…ed gate and emit the wdSlug hint (P16c)

Third typed-wd unit, stacked on the iid-ladder port. The registry
learns the value-typed scheme concept the spec and iid already carry,
instead of intuition-v2's scheme-level flip (D-P16-2):

- types.ts: ValueTypedScheme = 'wd' and ClassifiableScheme =
  UnambiguousScheme | ValueTypedScheme; UnambiguousScheme unchanged
- classification-map.ts: SCHEME_CLASSIFICATIONS keyed by
  ClassifiableScheme with a value-typed wd entry; resolveWdSlug
  resolves only ACTIVE EntitySchema bindings and maps the binding's
  schema type to a slug by scanning CLASSIFICATION_SPECS (memoized;
  the train has no getClassificationByType)
- classification.ts: the gate is "unambiguous, or value-typed";
  bare and dormant-slug wd values stay read-only, active typed values
  classify through their canonical form
- hints.ts: wdHints splits typed values into { wd, wikidata, wdSlug };
  bare values keep { wd, wikidata }
- index.ts exports; README shows the bare and typed results
- tests: totality suite amended to unambiguous + ['wd'] with a
  value-typed sibling case; typed-wd cases ported into classification,
  fixtures, hints, ladder-coherence and providers

SCHEME_TYPING.wd stays 'polymorphic'; listUnambiguousSchemeClassifications
output unchanged; providers.ts and canonical.ts untouched; no
classifications change. The atomCategory re-key and spec.identity.rungs
shape are held out under R2. No version or dependency changes.

Gates: iid-registry 46 tests, typecheck, check, build; iid-ladder 123,
classifications 38, primitives 140 against the rebuilt dist; pack dry
run. Review: spec conformance found no defect (base preservation over
all 26 schemes, ~20k comparisons, zero mismatches; wd table matches the
port source); adversarial found no finding at any severity (gate soundness over the nine polymorphic non-wd schemes, all 11 bindings, noncanonical forms, hint round-trip through the built ladder, totality drift, public surface, and a 555-combination hunt).
…003bc1 — music identity policy, podcast feed-URL normalization, ISNI URL form (P16 refresh)

Second commit on the typed-wd PR: this week's reference changes, folded
into the open PR per JP (10/3) instead of a follow-up.

iid
- music-identity-policy.ts (new, verbatim): MUSIC_IDENTITY_RUNG_POLICY
  (artist → MusicGroup: isni, mbid:artist, wd, spotify:artist;
  music-album → MusicAlbum: mbid:release-group, wd, spotify:album) and
  isPlainWdPrimaryAllowed(schemaType). The iid-ladder refresh consumes
  it for policy-gated plain-QID primaries (R23).
- uuid5.ts: normalizePodcastFeedUrl (folds scheme/host case, strips the
  scheme and trailing slashes, preserves userinfo, port, path and query
  bytes). derivePodcastGuid unchanged.
- schemes.ts: the ISNI canonicalizer also accepts the
  https://isni.org/isni/<id> URL form (with or without www., host
  case-insensitive), stripping it to the bare form before the existing
  canonicalization. Every existing canonical output is byte-identical.
- index.ts exports; README section; two new tests (feed normalization
  preserves bytes; isni.org evidence canonicalizes, wrong hosts and
  checksums rejected).

iid-spec (R24)
- schemes/isni.md: accepted input forms note; the URL form is an
  additive value-grammar extension under §9.3.1 (previously invalid
  input becomes valid, canonical bytes unchanged), provenance
  intuition-v2 develop @ 83a003bc1.
- conformance: four additive ISNI vectors (canonicalization,
  validation); no existing vector changed. Corpus: 167 vectors.

Typed-wd itself is unchanged: SCHEME_TYPING, the bindings table,
parse.ts and derive.ts are untouched. No version or dependency changes.

Gates: iid-spec corpus 167 vectors OK; iid 270 tests, typecheck, check,
build; iid-ladder 12, iid-registry 42, classifications 38, primitives
140 against the rebuilt dist; pack dry run.
… coherence (P16c refresh)

Folds this week's intuition-v2 develop test delta (through 83a003bc1)
into the open PR: the music-album classification spec carries a
MusicBrainz rung and no recording-level ISRC rung; release and
release-group MBIDs parse to their canonical lowercase form and classify
as music-album, recordings as music-recording. The train already
behaves this way; the only adaptation is the spec's `identity.ladder`
shape in place of the reference's `identity.rungs`, consistent with the
rest of this PR. Registry: 49 tests, typecheck, check.
…ely as a whole, including the /isni/ path (P16 refresh review)

The adversarial review of the refresh found the spec note narrower than
the ported canonicalizer: the regex's case-insensitive flag folds the
whole prefix, so `https://isni.org/ISNI/<id>` is accepted, exactly as the
reference implementation accepts it. No behavior change on the train;
the scheme doc now states the whole-prefix fold, the corpus gains a
vector for the upper-case path form (168 vectors), and the schemes test
asserts it (iid 271 tests).
kamescg and others added 25 commits October 22, 2026 11:17
Merge duplicate dynamic-fee and gross-up sections, retain bounded solver details, and list all root exports by source module. Validation: documentation imports resolve against dist.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Use JSON import attributes and provide a readFileSync/createRequire alternative for Node environments without import attributes. Validation: documentation imports resolve against package exports.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Remove the unnecessary direct viem install from iid-ladder guidance, normalize Install/License headings, and explain classifications inherits its viem peer requirement via iid.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…17074

List all primitive subpaths, all 15 schema-org root exports, and the exact case-sensitive generated type subpath contract. Validation: documentation import checker.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Add the three atom runtime ownership rows using the existing migration documentation. Clarify deprecated CLI plan aliases. The duplicate SDK/CLI layer row was removed in ENG-17072; atom runtime package files are untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Choose 0.1.0-alpha.0 for deployments, curves, periphery, and CLI; update all exact dependent pins and the release plan. Document the train policy. Registry metadata derives versions from manifests, avoiding a second hard-coded version list. Validation: bun install and registry:check.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Use stable caret ranges and retain exact prerelease pins in runtime, peer, and dev dependencies. Enforce the policy centrally and in packed manifests; release preflight checks the recorded stable baseline. Document when dependent releases are necessary. Include docs import validation in tarball smoke. Validation: registry:check, registry:test, release:registry:test.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Keep the shared normalizer because existing sources and generators still use extensionless imports. Document the preferred .js convention and the migration prerequisite for removal.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Decode the IID-spec fixture directory URL before reading files. Reconcile remaining release prose with the selected stable-caret and exact-prerelease policy. The excluded atom runtime tests contain similar URL-path assumptions; final CI parity is run from a clean checkout without spaces, without editing those packages.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Fresh-checkout validation found a remaining curves-only type import in getConfig and an SDK test still using root bytecode. Derive the config result from the canonical ABI and update the test to deployments/bytecode. Annotate the generic event parser and receipt/context helpers so the union event declaration does not inline the complete ABI.

Validation: workspace build and 116 SDK tests. Protocol baseline -> current npm pack --dry-run --json: 780 -> 513 files; 186631 -> 73478 packed bytes; 2787979 -> 460455 unpacked bytes. Dist 2732436 -> 402112 bytes; current measurement also includes ENG-17074 declaration-map removal.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…-17069

Add redactProviderDiagnostic and apply it in createPluginError so every
errors[] entry the engine emits is credential-free before any consumer
persists or returns it. The helper strips query strings, fragments and
userinfo from URLs (verbatim or percent-encoded), redacts credential
parameters and headers (plain, quoted, JSON-escaped), bare Bearer/Basic
tokens, and scheme-less userinfo. Mirrors the Core hotfix so both lineages
stay identical.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s, make promtool optional (ENG-17075)

Stop emitting .d.ts.map from pipeline-runtime so the repo-wide tarball smoke
check (no dangling declaration maps) passes once both prerequisite branches
merge. Reword the metrics contract comments without references to private
repositories or internal worker names. Remove the unpinned apt install from
CI and let the promtool-backed tests skip wherever promtool is absent; the
pure exposition checks still run everywhere. Give createLadder a named
Ladder return type, tighten the README wording on minted handles, and list
the app modules that need an Effect adapter against this package.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ges ENG-17074

deployments, curves and periphery already have 0.1.0-alpha.0 on the registry, so
the candidate moves to 0.1.0-alpha.1 with every exact pin, the release plan and
the release notes following; cli stays 0.1.0-alpha.0 because it has never been
published. Record the registry dist-tag state and the release-owner decision on
`latest`, and hold the Core-lineage atom packages out of the plan until the
application-lineage rebuild lands.

Also: envelope metadata reports the SDK as its source package now that the SDK
owns the builders; the triple-id helpers return to the SDK root beside
calculateAtomId (the app imports them there); document the getConfig return type
change in the protocol migration notes and the envelope builders in the SDK README.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
# Conflicts:
#	docs/release.md
#	packages/iid-ladder/README.md
#	release-plan.json
#	scripts/package-registry.mjs
#	scripts/package-registry.test.mjs
…sts ENG-17074

Bun does not rewrite workspace dependency range strings on an incremental
install, so the cli, periphery and sdk entries still carried the old
0.1.0 and 4.0.0 ranges. Patch exactly those strings to the manifest values;
frozen and incremental installs both report no changes.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
fix(providers): redact credentials from HTTP errors (ENG-17069)
…der-policy

feat: add Effect-free pipeline runtime and provider-local ladder policy (ENG-17075)
chore: prepare packages for publication (ENG-17072, ENG-17073, ENG-17074)
…artifacts

chore(periphery): remove the stale FeeProxy ABI and bytecode copy

@jonathanprozzi jonathanprozzi left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review at 5bb870e — not ready to publish or merge yet: 7 findings (6 Major, 1 Minor)

Scope: everything since my 19 Oct pass at 925a7b8, i.e. #45–#49 plus the atom-* alpha.1 reconcile (41 commits, 1,043 files), with the already-reviewed parity PRs #35–#44 treated as the base. Two independent passes: a conformance pass against the release plan, the package docs and the reference implementation's in-tree copies (both the commit the train README says it copied from and the reference's current tip), and an adversarial pass that executed reference-vs-train differentials and replayed the reference test suites against the built train packages. Everything below was reproduced by running the real built modules; the assembled gates were run natively afterwards (section at the end).

Findings

1. collectAtomIdentifiers drops provider-local identifiers, and the ported test now expects the loss.
packages/atom-classification/src/collect-atom-identifiers.ts:73 substitutes the normative ladder projector for the reference's application handle projector without binding providerLocalHandles: 'mint', so the projector rejects Spotify's unregistered scheme; :142 then overwrites the emitted identifierSet. Real built output for a MusicAlbum with identifier: int:spotify:album:4uLU… and hints [album, mbid, int:imdb:tt0133093]: reference [mbid, album, imdb], train [mbid, imdb]; with the album as the only identifier, []. The reference test at .port-source line 19 expects the album; the train's collect-atom-identifiers.test.ts:19 was rewritten to omit it. The enrichment port binds the policy correctly (atom-enrichment/src/identifier-rung-projection.ts:22), so this is a one-site omission. No README, CHANGELOG or conformance ruling declares it. Reference suite against the train: 1 pass, 1 fail.

2. Ambient credentials bypass the injected environment, and the fingerprint cannot tell.
createProcessingRuntime({ env: {}, cache: { provider: 'none' } }) with no ambient TMDB_API_KEY: the default TMDB plugin's supports() is false. Set only the process's ambient TMDB_API_KEY and it becomes true with the identical fingerprint processing-v1:895048…. The constructors fall back to process.env when the mapped key is undefined (atom-enrichment/src/plugins/providers/tmdb/index.ts:36, :162; same pattern in atom-classification/src/plugins/imdb/index.ts:167 and atom-enrichment/src/plugins/providers/youtube/index.ts:147), while atom-runtime/src/fingerprint.ts:46 hashes only config.env. The env-injection guards pass because they allow reads inside *FromEnv helpers; they do not check that ordinary constructors never call them. The pickProcessingEnv allow-list itself is complete (all 17 reference provider names forwarded; the ten filtered names are consumer controls consumed earlier).

3. Credentials survive in transport errors and nested causes.
Through the built fetchJson with six planted markers: HTTP 401, userinfo rejection and the engine's structured plugin-error projection are clean (47/47 redaction tests pass; engine.ts:591/:601). But a transport rejection carrying request diagnostics propagates unchanged from __shared__/http.ts:284 (markers 1–5 in message/stack, 1–6 on structured inspection), and a resolver failure is kept as cause (http.ts:455, constructor :126), where marker 6 survives. ProviderHttpError is on the public root surface (src/index.ts:146). Sanitise at the provider boundary including nested causes, with a regression through the resolver-failure path.

4. 279 dangling declaration maps ship in the four runtime packages, and the smoke gate exempts them.
declarationMap: true at tsconfig.build.json:9 in atom-parser (9 maps), atom-classification (99), atom-enrichment (164) and atom-runtime (7); npm-packlist selects them and each points at ../src/…, which is not published. scripts/smoke-tarballs.mjs:105 explicitly exempts atom-* from the map prohibition that 990a457 added for everyone else. Disable the maps and remove the exemption so a selected dangling map fails the gate.

5. Missing promtool now silently skips validation, including in CI.
The reference test required promtool when CI is set (.port-source pinned prometheus-exposition.test.ts:101); the train replaced that with a boolean-type assertion and skipIf(!promtoolAvailable()) on both substantive checks (pipeline-runtime/src/testing/prometheus-exposition.test.ts:101, :105, :116). The provisioning step from 8e614e1 is not in the current workflow (.github/workflows/ci.yml:32-41). Executed with CI=true and no binary: 10 pass, 0 fail, 2 skip. Provision it and fail closed in CI, or record the ruling.

6. Parser deviates from the reference pin without a recorded ruling.
Executed against the pinned reference modules in memory: parseAtom('did:example:123', {remoteFetch:false}) is url on the reference and plain_string on the train (atom-parser/src/detect.ts:215, HTTP(S)-only recognition); parseAtom('éé', {maxInputBytes:3}) is plain_string on the reference and throws INPUT_TOO_LARGE on the train (parse.ts:22, UTF-8 bytes vs UTF-16 length). Both are described in the README but not as parity rulings. Also stale: the README and migration runbook say DNS is not resolved or pinned (README.md:257, docs/atom-runtime-migration.md:94) while remote.ts:137/:258 now resolves, validates and pins an address. The bounded-read behaviour itself is sound: loopback, private, redirect-to-loopback, oversized, slow-body, data:/file:/ftp: all match the reference, and slow DNS is now bounded by the deadline where the reference was not.

7. Minor: the returned runtime exposes mutable preset factories after its fingerprint is fixed.
runtime.enrichment.presetFactories.default = () => [] takes the default inventory from 24 plugins to zero while runtime.fingerprint is unchanged (atom-runtime/src/runtime.ts:124, :133, :172). Freeze or snapshot the effective composition.

Also: three example workspace lock records disagree with their manifests (bun.lock:21, :32, :33 vs examples/atom-classification-plugin/package.json:24 and examples/hackathon-quickstart/package.json:16), which the registry validator does not cover because examples are not in the plan.

What checks out

All 20 release-plan entries match manifests and publishConfig.tag; internal ranges agree with bun.lock; publish order is valid; no workspace:/catalog:/file: in any selected manifest; React accepts protocol@4.0.0; CLI's 15 plan builders are function-identical aliases of the SDK's. The alpha.0→alpha.1 relabel is justified by the registry: curves, deployments, periphery already have 0.1.0-alpha.0 published; cli, iid, atom-parser are unpublished (404), as the release guide says. Focused conformance harness: 881 pass, 0 fail, 3 declared differences, 0 TODO (the PR body's "1,027 / 23 TODO / 98 differences" is historical; all 95 retired ids are still registered in the proof inventory and no conformance file changed since 925a7b8). The d8e665… default fingerprint reproduces; changing a TTL or preset changes it. Every one of 1,285 JavaScript export targets imports under Node 22 and Bun 1.3.11; no declaration import escapes its package. Replaying 102 reference suites against the built train: 1,196 pass, 49 fail, of which finding 1 is the only real divergence; the rest are reference-snapshot drift that the reference's own tip already matches (iTunes ISRC edge, MusicBrainz UA, TMDB query shape) or fixtures needing application files, servers or live transport. The earlier parity verdicts (#35, #37, #39, #40, #41, #43, #34) all still hold under fresh probes; #42's "75 agreements / 6 divergences" is superseded by 81 / 0 / 0. Supply-chain guard passes; the two release-age exceptions are bound to exact version, integrity and removal date 2026-11-02.

Consumer seams

The reference application's six SDK root imports and seven protocol root imports all exist on the built tree; primitives/anchor, identityLadderFor, getClassification(slug)?.atomCategory resolve. The Core service pins atom-parser/classification/enrichment at 0.1.0-alpha.0; this tree is alpha.1 after ef23b61 and the two are not interchangeable: parseAtom('int:isbn:…') is plain_string on alpha.0 and iid on alpha.1, NBSP handling flips, atomTypeSchema drops artist/music-album, rawInputKindSchema gains iid, the classification default preset grows from 16 to 27 plugins (adds int, Wikidata, Goodreads, Letterboxd, Places, OpenLibrary, Steam, CoinGecko, CoinMarketCap, Etsy, Shopify), and 31 + 47 root exports plus ~30 subpaths are added. MUSICBRAINZ_USER_AGENT is new in alpha.1. Nothing was removed. Core needs to adopt alpha.1 explicitly before "consumer acceptance" can be claimed.

Assembled gates run natively on this head

Run from a clean worktree at 5bb870e with a frozen install, Node 25 / Bun 1.3.11, after the sandboxed passes finished.

Gate Result
release:check pass
build pass
typecheck pass
check pass
pack:dry-run pass
smoke:tarballs pass (clean-room install of every public alpha tarball)
guard:supply-chain pass
test pass with --continue --concurrency=4: 38/38 tasks, 5,634 tests, 0 failed, 2 skipped (the two promtool checks from finding 5). At full concurrency one run failed only pipeline-runtime provider-request-observation.provider-observer.test.ts ("measures the duration from dialed, not from begin", a 40 ms bound after a 5 ms sleep) and 33/33 pass in three isolated reruns, so that is a load-sensitive timing bound, not a product defect.
registry (npm view) curves, deployments, periphery: 0.1.0-alpha.0 published; schema-org@0.1.0-alpha.0 published; cli, iid, atom-parser: not on the registry
publication guard probe a planted dist/.codex/working-note.md fails the guard as intended; a planted dist/.env in the same tarball is accepted, because scripts/package-registry.mjs:71 matches agent directories and AGENTS/CLAUDE/GEMINI/SKILL.md only. Worth adding dotfile credentials (.env*, .npmrc) to that rule since files: ["dist"] selects anything under dist/.

Fix order: 1 (restore the reference assertion first, then bind the policy), 3, 2, 4, 5 as gate fixes, 6 as a recorded ruling. Happy to re-run the differentials and the reference-suite replay on the next head.

@kamescg kamescg changed the title feat: public identity packages and v1.1.0 SDK/CLI V1.1.0 SDK & Documentation Oct 28, 2026
@kamescg
kamescg marked this pull request as ready for review October 28, 2026 16:25
@kamescg
kamescg merged commit dfc80ca into main Oct 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants