@staratlas/dev-sage
v0.55.0
Published
`TheOneFleetStateHandler` and `StopSubwarp` both settle subwarp Pilot XP through the same Character-level budget. Use the generic handler to advance state (it continues an unfinished subwarp); use `StopSubwarp` to stop at the settled position. Once a trip
Maintainers
Keywords
Readme
@staratlas/dev-sage
Fleet settlement with career XP
TheOneFleetStateHandler and StopSubwarp both settle subwarp Pilot XP through
the same Character-level budget. Use the generic handler to advance state (it
continues an unfinished subwarp); use StopSubwarp to stop at the settled
position. Once a trip has arrived, either resolves it to Idle without a second
award. Warp XP remains paid at departure, not arrival.
On XP-v1 Games (Game.version == 2), supply the controlling character and:
xpBudget: writableCareerXpBudgetPDA, seeds["CareerXpBudget", game, character].xpBudgetConfig: readonlyXpBudgetConfigPDA, seeds["XpBudgetConfig", game].
The generic handler's account order is funder, fleet, game, system?, asteroid?,
character?, systemProgram?, xpBudget?, xpBudgetConfig?. The first six accounts
and optional trailing rent System Program preserve existing legacy callers.
Keep program-ID placeholders for absent optionals before a supplied account.
StopSubwarp's account list is unchanged. An updated binding exposes the new
handler tail; older bindings must explicitly append System Program (or a
program-ID placeholder), then the two XP accounts. This requires the updated
program to be deployed; a binding update alone cannot fix the old handler.
Legacy Games (version == 0) must omit XP accounts. Sealed Games (version == 1)
still reject XP-writing settlement. On XP-v1, omitting the budget/config fails
closed; an exhausted budget permits movement to settle with zero XP, never a
legacy fallback. The generic handler also forwards the same XP context when
resolving mining; existing asteroid/Character requirements still apply.
Bundled Game decoder correction
This release line includes the upstream prefixed-array decoder allocation fix
through a publisher-side patch to the locked codec dependency. The rebuilt ESM
and CommonJS artifacts execute the correction; consumers need no local patch,
Buffer workaround or Kit 8 migration. The declared Kit peer range remains
^6.1.0, and isolated packed-package checks install Kit 6.10.0.
Main is the 0.53 account/instruction contract, not a drop-in 0.52 backport. The separate 0.52.1 compatibility release preserves the published 0.52 source/IDL. Do not select a binding solely by this performance correction: match the deployed program's account/instruction contract. No release is published by opening a PR.
From clients, run pnpm install --frozen-lockfile, pnpm build,
pnpm typecheck, pnpm lint, and pnpm test. Tests include an isolated packed
SDK installation, both public conditional exports, full decoded-value digests,
truncated-input parity and a copied-byte allocation budget. prepublishOnly
also runs the packed check. These are Node checks, not browser memory claims or
an exhaustive malformed-input proof; consumer/browser integration remains a
separate validation boundary.
Publisher-owned ship-model catalog, schema v1
The opt-in JSON subpath is:
@staratlas/dev-sage/ship-models/zink-ptr-15615.jsonIt is not imported by the main SDK entry point and contains no duplicated ship stats. Consumers may load it lazily and index references to their existing immutable definitions. No additional RPC request is performed by this artifact.
This is an explicit, publisher-owned membership/default mapping for one validated
catalog, not a universal hundred-ID allocation rule or a latest alias.
Its reference capture is pre-reset; its presence in a new SDK does not establish
that it matches a current deployment.
Identity and validity
scopeidentifies the chain genesis hash, program ID and Game address. All three must match the consumer's deployment context.modelIdis the publisher's model ID (ShipMintIdin authoring), not the configuration ID calledShipIdin the on-chain schema.modelKeyis the canonical publisher registry key;displayNameis cosmetic.configurationIdsexplicitly identifies active members. A member's liveShip.mintmust equal its model's deployment-specificmint.defaultConfigurationIdis an explicit member ID, ornullif no default is specified. Never infer it from order, minimum ID, name or ID arithmetic.referencerecords the capture slot, ship-definition sequence, account hash and publisher/program source revisions. The sequence is provenance, not an assertion that this is the current live Game.identityDigestis SHA-256 of UTF-8JSON.stringifyof every active[configurationId, mint]tuple, sorted ascending by numeric configuration ID, with no whitespace. It covers the complete active catalog, notmintToIdhistory. Reject duplicate active IDs before hashing.
Before enabling grouped lookup, require schema version 1, matching scope and identity digest, unique model IDs/keys, exactly one membership for every active configuration, matching live mints, and defaults belonging to their model. Unknown schema versions, missing/new/reassigned configurations or incompatible scope must make this mapping unavailable. Individual config lookup, full listing and Fleet decoding must remain available independently.
Rebuild the lazy index when the Game/definitions identity or sequence changes, and when the catalog revision changes. A stats-only change may retain a valid identity digest, but references in the rebuilt index must point to the new definition objects. A reset requires revalidation even if the Game address is unchanged. Checking only a remembered sequence number is insufficient.
Publisher updates
The publisher registry policy preserves existing model/config IDs and never reuses retired IDs. Additions get explicit registry assignments, not IDs computed by consumers. New/removed configurations, model mint/default changes or membership changes require a new catalog revision; publish a new scoped JSON artifact rather than silently changing an already published catalog ID. Removed configurations disappear from active membership but remain reserved in the authoring registry. Do not repurpose an existing model key for another model.
The program's admin APIs are not a permanence guarantee: removal exists, mint history is retained, and a deleted ID is not protected by a permanent tombstone. Existing configuration updates reject changed mints. Consumers must still apply the catalog validity checks instead of assuming every deployment/upgraded program enforces the publisher policy.
Provenance and maintenance
The initial catalog joins publisher id_registries/ship.json and
id_registries/ship_config.json with _c4_ship_meta/c4_config_id authoring
records, the publisher's generated default_config_ids.json, and the captured
Game's active mints. It was cross-checked against the authored zink configuration.
All 61 models, 2,928 members and 61 defaults agree. Source revisions are pinned
in the JSON. No name matching or ID arithmetic was used for this join.
For a new catalog, use those explicit publisher records, resolve the target
deployment mints, record a new scope/reference/digest, and validate complete
active membership before adding its package export. pnpm test:ship-models
verifies the committed catalog against the public Game fixture and exercises
incompatible deployment, membership, default, schema and mint controls. The
publisher-only verifier is not an exported Node-dependent runtime SDK helper.
