npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@plasius/economy

v0.11.6

Published

Provider-neutral Token economy contracts and deterministic ledger invariants for Plasius

Readme

@plasius/economy

Provider-neutral TypeScript contracts and deterministic invariants for the Plasius sitewide Token economy.

This package models exact TokenSubunit amounts, immutable double-entry journal transactions, source lots, family gameplay reservations, purpose-bound learning module allowances, early-backer basis, future spend requests, acquisition contracts, projections, and persistence ports. It intentionally contains no HTTP, authentication, provider SDK, database driver, secret, or Azure implementation.

Product boundary

  • 1 public Token = 1,000 TokenSubunits.
  • The nominal product reference is 1 Token = £0.10; it is not a redemption, transfer, investment, or cash-equivalence promise.
  • Amounts use bigint internally and canonical base-10 strings in contracts.
  • Tokens have no cash-redemption value and do not replace PP, ESP, TIS, or DIS.
  • Gameplay conversion, spending, and subscriptions are policy decisions owned by consuming services and are disabled in the baseline product.

Requirements

  • Node.js 24 or later
  • TypeScript with NodeNext-compatible module resolution

Install

npm install @plasius/economy

Exact amounts

import {
  parseTokenSubunits,
  serializeTokenSubunits,
  wholeTokensToSubunits,
} from "@plasius/economy";

const packGrant = wholeTokensToSubunits(50n);
const wireAmount = serializeTokenSubunits(packGrant); // "50000"
const restored = parseTokenSubunits(wireAmount); // 50000n

Non-canonical values such as "01", decimals, exponent notation, and values outside signed PostgreSQL bigint range are rejected. Runtime validators also reject non-string JSON values rather than coercing numbers into wire amounts.

ActivityEntryV1 contains both a stable source (shopify, ayet, bitlabs, google-ad-manager, subscription, event, competition, or adjustment) and a bounded display-oriented sourceLabel. Filters and reconciliation must use source; localized UI must use sourceLabel.

New read adapters should return the discriminated WalletActivityEntryV1. economic rows may be held, settled, or read-model-derived reversed; workflow rows alone may be pending or failed. The additive EconomicJournalTransactionV1 narrows immutable journal writes to held or settled. A reversed display state is derived from a compensating transaction; the original journal row is never rewritten.

Baseline GBP catalog

BASELINE_GBP_REFERENCE_RATE is versioned product-copy metadata with cashRedemptionAllowed: false. assertFlatTokenCatalog() proves that a catalog uses the declared flat nominal ratio. The initial immutable catalog facts are:

| Pack ID | Price | Grant | |---|---:|---:| | gbp_5_50_v1 | £5 | 50 Tokens | | gbp_10_100_v1 | £10 | 100 Tokens | | gbp_25_250_v1 | £25 | 250 Tokens | | gbp_50_500_v1 | £50 | 500 Tokens |

The default server ceilings are £50 per order and £100 per payer and household over 30 days. A consuming service may apply a lower household control but must not raise these defaults without a separately versioned policy decision.

Google rewarded web

GoogleRewardedWebGrantClaimV1 deliberately labels GPT browser completion as client-claimed; Google rewarded web has no server-side verification contract. GoogleRewardedWebReconciliationV1 separately proves final paid-impression, eligible-net-revenue, nominal-liability, and reserve coverage.

The audited authority treats google-ad-manager as a provider command source. Final reports use authenticated-retrieval evidence with a bounded retrieval scheme and verification time; they cannot be represented as signed callbacks. Legacy Shopify, ayeT, and BitLabs signed-evidence canonical bytes remain unchanged. Google reward credits consequently require the provider-acceptance and provider-result authority boundaries and produce rewarded-ad activity.

createGoogleRewardedWebQuote() uses exact integer GBP micros and issues one whole Token only when conservative eligible net is at least 125,000 micros for the 100,000-micro nominal liability. The completion bundle has no package default. google-ad-manager source lots must be same-user-only and retain an opaque internal claim identifier; the package exposes no Token transfer to a linked account.

A parent-owned household service may eventually provide dependent family access without moving Tokens or assigning the entitlement. That journey is outside this V1 contract and must stay separately flagged off until Google has approved its exact policy treatment in writing.

Balanced journal transactions

import {
  assertBalancedTransaction,
  canonicalTransactionPayload,
  serializeTokenSubunits,
  type LedgerTransactionV1,
} from "@plasius/economy";

const transaction: LedgerTransactionV1 = {
  schemaVersion: "1",
  transactionId: "txn:purchase:1",
  activityType: "purchase",
  status: "settled",
  // Legacy V1 example. V3 writes the domain-separated HMAC digest here.
  idempotencyKey: "intent:1:paid",
  effectiveAt: "2026-07-15T10:00:00.000Z",
  recordedAt: "2026-07-15T10:00:01.000Z",
  metadata: { catalogVersion: "gbp-v1" },
  postings: [
    {
      schemaVersion: "1",
      postingId: "post:1",
      transactionId: "txn:purchase:1",
      accountId: "account:purchase-clearing",
      amount: serializeTokenSubunits(-50_000n),
    },
    {
      schemaVersion: "1",
      postingId: "post:2",
      transactionId: "txn:purchase:1",
      accountId: "account:household-treasury",
      lotId: "lot:shopify:1",
      amount: serializeTokenSubunits(50_000n),
    },
  ],
};

assertBalancedTransaction(transaction);
const payloadForApprovedHashAdapter = canonicalTransactionPayload(transaction);

The package produces canonical bytes but deliberately leaves SHA-256 hashing and any signing to an approved infrastructure adapter. Metadata keys and posting IDs are ordered with locale-independent UTF-16 code-unit comparison. Their validated ASCII alphabet makes that ordering identical to PostgreSQL COLLATE "C"; adapters must hash the exact UTF-8 bytes returned by canonicalTransactionPayload().

Audit receipts and integrity verification

AuditedEconomyCommandEnvelopeV1 is a standalone, fingerprint-only V3 contract. It binds actor, subject, principal type, delegated relationship/version, sanitized capability/flag/assurance evidence, route, build, region, writer fence, correlation, causation, and payload. It never extends the legacy raw-key envelope.

EconomyHmacFingerprintV1 records an exact domain, key version, and hmac-sha256: digest. Raw idempotency keys, provider event/object IDs, callback bodies, and reconciliation material use distinct domains. Provider commands require a canonical EconomyProviderEvidenceManifestV1; callback signatures and payment data have no contract field.

Encrypted operational provider handles remain site-owned. EconomyEncryptedOperationalHandleBindingV1 binds only their purpose, provider, AES-256-GCM label, key version, ciphertext-content hash, and encryption-context hash. It contains no ciphertext, nonce, authentication tag, plaintext, or Key Vault URI.

EconomyAcceptedCommandReceiptV1 is safe to return after durable acceptance: it exposes only receipt, command, and correlation IDs plus the command-envelope hash and acceptance time. EconomyCommandResultReceiptV1 is terminal and exclusive:

  • completed requires a transaction ID and its existing canonical hash and forbids outcome codes;
  • failed requires one bounded safe failure code and forbids transaction fields;
  • no-op requires one bounded safe no-op code and forbids transaction fields.

Every terminal shape retains a result hash. Replay is a processing mode, not a command source: assertExactAuditedEconomyCommandReplay() requires identical canonical bytes and preserves the original source. A collision with different bytes is a security conflict.

The audit canonicalizers use explicit fixed field order and omit absent optional fields. Runtime validators reject unknown fields rather than allowing raw evidence to be persisted accidentally. canonicalTransactionPayload() is unchanged. A V3 transaction stores the HMAC digest in its legacy canonical idempotencyKey field; the HTTP key is never stored.

EconomyAuthorityHeadV1 and hash-linked EconomyAuthorityCommitManifestV1 cover every immutable record, conditional projection replacement, idempotency result, and outbox effect. Manifests support only create and conditional-replace; batches are limited to 80 operations and 1.5 MiB. The manifest create and head replacement reserve two operations, leaving at most 78 canonical record references. assertEconomyAuditGraph() recomputes the complete command/evidence/receipt/ transaction/manifest graph and expected head. assertEconomyAuthorityRecoveryEvidence() additionally recomputes the successful prior verification receipt bound by any reopening manifest.

First-party commands use one atomic authority boundary. Provider workflows use one boundary to durably accept verified evidence before acknowledgement and a second boundary to record the externally reconciled completed, failed, or no-op result.

Dual-approved operator adjustments

OperatorAdjustmentPreviewV1 is the immutable value plan prepared by a trusted site adapter. It binds the target account and component to the server-resolved wallet, target and offset ledger accounts, deterministic source lot, positive TokenSubunit magnitude, bounded reason, hashed ticket reference, transfer/refund policy, and expiry. Browser and MCP callers may request an account and component, but their wallet or ledger identifiers are never authority.

OperatorAdjustmentProposalV1 records the first operator's pending proposal. OperatorAdjustmentDecisionV1 requires another stable account and binds the exact preview and proposal hashes. OperatorAdjustmentExecutionV1 links an approved plan to its source lot, immutable journal transaction and terminal result receipt. A correction is a new reverse-credit proposal tied to the original lot and transaction; the package exposes no set-balance or delete operation.

The package validates and canonicalizes these records but deliberately does not resolve platform owners, perform MFA step-up, evaluate capabilities or flags, hash ticket references, persist proposals, or execute transactions. Those controls stay in the consuming authority adapter.

verifyJournalChainSegment() accepts an approved canonical-payload hash function, recomputes every transaction hash, checks previous-hash links and duplicate transaction IDs, and proves the resulting head against an expected head. EconomyIntegrityVerificationReceiptV1 binds authority, journal, and projection verification outcomes. EconomyIntegrityAnchorManifestV1 defines canonical hourly Merkle evidence while signing, keys, and storage remain infrastructure responsibilities.

Recoverable acknowledgements and portable receipts

The additive recovery protocol protects the acknowledgement boundary without turning an evidence store into a second economy writer:

  • EconomyRecoveryAcceptanceEnvelopeV1 binds the provider-neutral audited command, accepted receipt, HMAC idempotency fingerprint, and an AES-256-GCM sealed reconstruction payload before command processing;
  • EconomyRecoveryCommittedResultV1 binds that exact acceptance to the terminal result receipt, authority commit/head, sequence, optional completed transaction, and sealed reconstruction payload after the authority commits;
  • EconomyRegionalEvidenceReceiptV1 is a signed, sequence-addressed, hash-chained retention assertion for the byte-identical acceptance or result stored in one evidence region; and
  • EconomyPortableCustomerReceiptV1 binds a positive TokenSubunit amount and direction to the completed transaction, result, authority sequence, at least two regional evidence receipts, and an optional authority-commit Merkle inclusion proof.

Every recovery record has a SHA-256 content-addressed ID derived from a separate, explicitly ordered canonical body. Detached signatures cover that ID, the complete body, and public algorithm/key-version/time metadata. The package does not implement hashing, encryption, signing, key lookup, Blob access, or identity. Callers supply approved hash and signature-verification functions; assertEconomyRegionalEvidenceChain(), assertEconomyRegionalEvidenceEquality(), assertEconomyMerkleInclusion(), and assertEconomyPortableCustomerReceiptEvidence() run without a cloud SDK or authentication dependency.

Recovery validators reject unknown fields. Plaintext records have no field for raw idempotency keys, provider/payment facts, callback bodies/signatures, storage URIs, payer/household/account identity, email, session data, or exact birth data. A portable receipt contains only opaque command/transaction references, proof hashes, amount/direction, safe activity, terms version, and cashRedemptionAllowed: false. The sealed payload's plaintext remains subject to the same approved privacy-minimized authority schema; encryption is not permission to retain unnecessary data.

A consuming service may acknowledge a provider callback after identical acceptance evidence is durable in both approved regions, then process it asynchronously. A successful browser value command is not customer-acknowledged until the authoritative commit and both regional committed-result receipts exist. Cross-service writes are not a distributed ACID transaction: exact content IDs and idempotent create-only completion make orphan acceptances and committed-but-not-yet-acknowledged results recoverable without duplicating value.

These contracts enable a scoped recoverability claim only after the consuming infrastructure proves dual durable writes, locked retention, independent keys, monitoring, and tested reconstruction. They do not by themselves establish zero RPO, WORM retention, HSM custody, administrator-proof storage, or availability.

Source-lot policy and allocations

selectSourceLots() selects spendable slices in credited-time/lot-ID order and enforces household-allocatable, same-user-only, and non-transferable policies. createGameplayAllocation(), boostGameplayAllocation(), and reclaimGameplayAllocation() require exact whole Tokens and return new immutable states.

Selection is only a deterministic proposal. The persistence adapter must lock the source rows, revalidate them, append the balanced transaction, update the projection, save idempotency evidence, and append the outbox event within one serializable database transaction.

VersionedSourceLotV1 and SourceLotMovementV1 make allocation, boost, reclaim, spend, hold, release, refund, chargeback, and reversal changes explicit. applySourceLotMovement() proves the signed amount deltas, refund-state transition, and exact optimistic-version increment. A V2 persistence adapter must append the movement evidence and compare-and-swap the projection as one operation.

Early backers

evaluateEarlyBacker() calculates provisional pre_utility_backer_v1 status from net retained paid lots. It uses an inclusive public launch and exclusive first-public-spend cutoff. It does not express or promise a reward entitlement.

Existing evaluateEarlyBacker() behavior is preserved for V1 consumers. The approved additive evaluateEarlyBackerBySettlementV2() policy treats settledAt as the sole inclusive-launch/exclusive-cutoff qualification event; purchase and credit timestamps remain ordering/provenance facts. It ignores settlements after evaluatedAt. The caller must derive both window timestamps from the entire public cohort and exclude non-production/test lots: staff, closed-beta, and test availability must never open or close the public window.

Junior Coder Module Allowances

ModuleAllowanceV1 is a Guardian-funded reservation for one linked child and one purpose: purchasing independently sellable Junior Coder module entitlements. It is deliberately separate from GameplayAllocationV1; callers cannot spend gameplay value as a learning allowance or silently move learning value into gameplay.

The purchase contracts implement the deterministic parts of:

immutable quote -> allowance hold -> pending entitlement
  -> settle spend -> activate entitlement -> durable receipt

An immutable quote binds the exact module version, Token price, child, Guardian acknowledgement, catalog version, and requirements-manifest version plus canonical SHA-256 reference. This makes software-only declarations and robotics bills of materials durable pre-purchase evidence even after a live manifest changes.

createModuleSpendHold() moves whole Tokens from available to held value. settleModuleSpendHold() requires a pending entitlement ID before it can move held value to spent value. releaseModuleSpendHold() returns failed or expired holds to the same Module Allowance. createModulePurchaseReceipt() accepts only matching quote and settled-hold evidence. reconcileModulePurchase() returns one forward-safe repair instruction and fails closed to manual review for a settled debit without an entitlement or an active paid entitlement without a settled debit.

These functions produce immutable next-state projections; they do not perform authorization or persistence. The consuming service must evaluate learning.junior-coder.purchase.enabled, enforce Guardian/child capabilities, store actor/subject/operation-scoped idempotency evidence, and compare-and-swap allowance and hold versions alongside the balanced journal, entitlement, receipt, and outbox in a serializable transaction. A disabled feature may still release and reconcile existing holds, but must reject new quotes and purchases.

Acquisition and future contracts

Purchase intents bind payer, receiving household/wallet, pack, catalog, expected GBP price, grant, and an expiry. assertOpenPurchaseIntent() is for checkout creation; a late provider webhook must instead be reconciled against the immutable purchase facts and provider purchase time.

Reward conversion contracts retain signed provider-event IDs, server rate/FX versions, exact payout values, and beneficiary/wallet IDs. ayeT and BitLabs lots are structurally restricted to same-user-only; changing a provider-earned lot to household-allocatable is rejected.

Deterministic paid-acquisition lifecycle

PurchaseIntentLifecycleV1 adds receipts and optimistic versions around the unchanged PurchaseIntentV1. reducePurchaseIntentTransitions() canonicalizes out-of-order checkout, payment, credit, expiry, cancellation, and dispute evidence. Exact retries collapse, conflicting ID reuse fails, and one intent can emit at most one stable intent-ID-scoped credit instruction. The transition name is checkout-bound; the published compatible intent status remains checkout-created.

reserveRollingPurchaseCaps() mirrors one exact GBP-minor-unit reservation into payer and household aggregates. Both expected versions must match and both returned versions must be committed in one serializable transaction. Settlement keeps the amount in the rolling window; release and expiry free it. Exact command replays are no-ops, including after finalization. GBP minor units use canonical non-negative signed-64-bit strings through parseGbpMinorUnits() and serializeGbpMinorUnits().

PaidLotLifecycleV1 separately preserves early-backer retained basis:

  • a dispute hold leaves retained basis unchanged;
  • a dispute win releases only the hold;
  • refunds, lost disputes, direct chargebacks, and the one permitted reversal reduce retained basis exactly;
  • partial outcomes retain their unreversed remainder;
  • createEarlyBackerRetentionFromPaidLot() supplies a current PaidLotRetentionV1 for recalculation.

Retained basis is not a spendable-balance claim. Before a compensation commits, the authoritative service must atomically reclaim allocated-but-unused value, reject value already spent or otherwise unavailable, append balanced journal postings, update source-lot/lifecycle projections, save idempotency evidence, and append the outbox. This package contains none of those provider or persistence adapters.

These contracts do not enable checkout. The site must still enforce economy.tokens.shopify.enabled, payer/household authorization, legal gates, provider-signature verification, and server-derived purchase facts.

BASELINE_MONTHLY_SUBSCRIPTION_PLAN preserves the provider-neutral future £10 monthly/100 Token shape with enabled: false. Spend-request contracts likewise exist for future use but this package does not enable their creation.

Balance, lifetime, and portfolio reads

WalletBalanceProjectionV1 stores exclusive spendable, reserved, and held buckets. createWalletBalanceSummary() splits each wallet's spendable amount into independently usable whole-Token available value and a sub-Token rewardProgress remainder. WalletBalanceDeltaV1 is an atomic add, never an absolute balance replacement.

Lifetime counters are monotonic gross flows. Settled purchase/subscription credits add to bought; rewarded-ad, offerwall, event, and competition credits add to earned; source-wallet allocation/boost debits add to allocated; returns add to reclaimed; spend debits add to spent; and refund, chargeback, or reversal debits add to reversed. A reversal does not subtract from the earlier bought/earned counter.

EconomyQueryPortV1 keeps single-wallet reads and introduces an explicit WalletPortfolioReadScopeV1. A host portfolio may contain both a household treasury and a same-user-only personal reward wallet, and every component keeps its wallet ID, role, beneficiary, summary, and lifetime snapshot. Portfolio totals are display-only column sums: progress is deliberately not promoted across wallets, even if the sum reaches 1,000 TokenSubunits, because source and transfer restrictions may differ. Authorization must happen before the server constructs a portfolio scope.

createPersonalWalletInitializationState() supplies the exact baseline needed before a self account can read a portfolio: deterministic document IDs, one account-owned personal WalletV1, a single-component scope, exact-zero balance and lifetime projections, no activity entries, and a privacy-minimized wallet.initialized.v1 outbox intent. The caller provides SHA-256 and must commit the state with audited receipts, idempotency, the authority manifest and conditional head advance in one ACID boundary.

initialize-wallet exists only in EconomyAuditedCommandTypeV1; legacy V1/V2 command unions remain unchanged. It accepts a direct self-account browser principal only and terminates with WALLET_INITIALIZED or WALLET_ALREADY_INITIALIZED as a no-economic result. It never creates a double-entry transaction or Token activity row and does not authorize value or provider writes.

initialize-admin-reporting is also additive to the audited command union. It is restricted to a service principal and the system source so a host can bind one create-only reporting bootstrap to its normal authority head, manifest, receipt, and idempotency evidence. It does not authorize a balance mutation or replace an existing reporting projection.

Activity reads use bounded opaque cursor pagination in stable descending (occurredAt, activityId) order. Each row retains the component walletId whose signed display amount it represents. Cursor contents and signatures are adapter concerns; assertWalletActivityPageForPortfolio() proves that a result never expands the authorized portfolio scope.

Pseudonymous Admin reporting

AdminEconomyReportingQueryPortV1 defines provider-neutral global summary, pseudonymous wallet balance, activity, and trend results for governed finance operations. It does not grant access or query a database. A host must authenticate the caller, enforce the stored rollout flags economy.admin-history.enabled and mcp.admin-economy-history.enabled as applicable, re-check the finance capability, and use a least-privilege reporting projection.

The global summary is an identifier-free point-read projection. It contains exact available, reserved, held, reward-progress and lifetime totals, wallet counts, and the canonical positive authority sequence through which the projection is current. Wallet balance pages contain separate audience-bound wallet and subject aliases, a closed component/status code, exact non-negative amounts, update time, and authority sequence. They are capped at 100 rows and support stable available-descending or update-time-descending pagination.

Activity rows are deliberately narrow:

  • timestamp, normalized type/status/source, and exact signed TokenSubunits;
  • a closed non-identifying label code that the presentation layer maps to localized text; and
  • distinct opaque row and subject aliases produced by a versioned, audience- and purpose-separated HMAC adapter.

The label-code allowlist is token-acquisition, token-spend, token-reversal, token-hold, token-activity-failed, token-system-adjustment, and token-activity-unclassified. A label must also be valid for its activity type.

Failure rows may use exact zero when a failed workflow has no related economic transaction or attempted amount. Zero remains invalid for every economically meaningful activity type.

The validator accepts only plain enumerable data properties and rejects serialization hooks and undeclared properties, including raw account, wallet, transaction, order, payment, provider-event, idempotency, and journal-integrity identifiers. It also rejects provider-specific source names and free-form labels. Result metadata fixes rawIdentifiersIncluded to false.

Activity pages are capped at 100 rows. Cursor values use a versioned c1. base64url confidentiality-protected opaque format and cannot contain raw identifiers. A resumed request carries both that value and its trusted, server-decoded binding to the original window, sort, filters, pseudonym audience, and version. Result metadata echoes the normalized filter. The deterministic default reporting window is 30 days and the interactive maximum is 365 days.

Hourly trends are limited to 31 days and daily trends may cover the maximum window. The result ceiling is 3,720 points, covering all five activity types through the maximum hourly window. Trend cohorts with fewer than five distinct subjects contain only a suppression marker.

Reported trend points carry either a calculated 28-window same-time conventional median/MAD indicator or an explicit unavailable result. Only non-suppressed baseline cohorts may enter the calculation. Median and MAD values use reduced exact rational TokenSubunits with denominators up to two, so no floating point or rounding is introduced. Indicators are review alerts only and never mutate the ledger. Routine contracts contain no identity-resolution operation.

Persistence ports

EconomyPersistencePort remains exported unchanged for existing consumers. New authoritative services should implement EconomyPersistencePortV2, whose unit of work deliberately omits V1's whole-projection overwrite. Runtime roles should execute approved posting procedures but must not update or delete journal rows directly. The V2 adapter is responsible for:

  • serializable row locking and optimistic versions;
  • exact owner-constrained wallet access and household/child-constrained allocation compare-and-swap;
  • immutable accepted-command and workflow-event append;
  • actor/subject/command-scoped idempotency plus unique transaction and provider-event constraints;
  • active regional writer-fence validation and locked canonical chain-head extension;
  • atomic wallet balance and monotonic lifetime deltas;
  • atomic source-lot movement append, refund-state update, and version advance;
  • transactional outbox append;
  • managed identity and least-privilege database access; and
  • immutable audit/integrity evidence outside this package.

EconomyPersistencePortV3 is additive and retains every V2 economic primitive. It removes V2's raw-key idempotency operations from its unit and replaces them with EconomyAuditedIdempotencyScopeV1 and EconomyAuditedIdempotencyResultV1. It adds audited commands, evidence manifests, encrypted-handle bindings, receipts, authority commits/head CAS, integrity receipts, and anchor manifests. Its journal method accepts AuditedChainedEconomicJournalTransactionV1, whose legacy idempotency slot is type-narrowed to an HMAC digest. V1 and V2 remain exported unchanged.

Development

npm ci
npm run lint
npm run typecheck
npm run build
npm run test:coverage
npm run pack:check

Coverage must remain at least 80%, and every changed source file must appear in LCOV. Generated property tests cover exact arithmetic, double-entry balance, projection rebuilds, idempotency, reversals, lot isolation, and allocation non-negativity. npm publication is performed only by the approved GitHub CD workflow from the protected main branch. The final publication job runs on a GitHub-hosted runner so npm can validate its short-lived OIDC identity and record provenance; it has no long-lived npm write-token fallback. Release LCOV and the CycloneDX SBOM remain retained even when an external coverage service is unavailable. Release tags and GitHub Releases use a current-repository GitHub App token with explicit Contents and Workflows write permissions. A requested version bump reuses the current version only when neither npm nor GitHub records it as a completed release; use bump=none for deliberate recovery of prepared metadata. Publication checks out the verified current release-branch HEAD so that recovery always includes the reviewed workflow tooling.

Security

Do not include raw idempotency keys, provider identifiers, provider callback bodies or signatures, payment details, personal data, encrypted-handle ciphertext, or secrets in contracts, metadata, tests, examples, or logs. Report vulnerabilities privately according to SECURITY.md.

Release integrity

Production package publication runs only from .github/workflows/cd.yml on protected main. The job verifies that the prepared commit is still the current main commit and has an exact successful ci.yml push result before it mutates release state. Public package CI runs on GitHub-hosted capacity so it cannot execute on company-managed runners. npm publication runs on GitHub-hosted Node.js 24 with npm 11.5.1 or newer, uses the protected production environment and short-lived npm OIDC with provenance, and has no long-lived npm write-token fallback. Rollback disables CD; it never rewrites published package history.