@plasius/economy 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +190 -11
- package/dist/index.cjs +6793 -2603
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1221 -266
- package/dist/index.d.ts +1221 -266
- package/dist/index.js +6709 -2603
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,10 +4,11 @@ Provider-neutral TypeScript contracts and deterministic invariants for the
|
|
|
4
4
|
Plasius sitewide Token economy.
|
|
5
5
|
|
|
6
6
|
This package models exact TokenSubunit amounts, immutable double-entry journal
|
|
7
|
-
transactions, source lots, family gameplay reservations,
|
|
8
|
-
future spend requests, acquisition
|
|
9
|
-
ports. It intentionally contains no
|
|
10
|
-
database driver, secret, or Azure
|
|
7
|
+
transactions, source lots, family gameplay reservations, purpose-bound learning
|
|
8
|
+
module allowances, early-backer basis, future spend requests, acquisition
|
|
9
|
+
contracts, projections, and persistence ports. It intentionally contains no
|
|
10
|
+
HTTP, authentication, provider SDK, database driver, secret, or Azure
|
|
11
|
+
implementation.
|
|
11
12
|
|
|
12
13
|
## Product boundary
|
|
13
14
|
|
|
@@ -92,6 +93,7 @@ const transaction: LedgerTransactionV1 = {
|
|
|
92
93
|
transactionId: "txn:purchase:1",
|
|
93
94
|
activityType: "purchase",
|
|
94
95
|
status: "settled",
|
|
96
|
+
// Legacy V1 example. V3 writes the domain-separated HMAC digest here.
|
|
95
97
|
idempotencyKey: "intent:1:paid",
|
|
96
98
|
effectiveAt: "2026-07-15T10:00:00.000Z",
|
|
97
99
|
recordedAt: "2026-07-15T10:00:01.000Z",
|
|
@@ -119,13 +121,133 @@ assertBalancedTransaction(transaction);
|
|
|
119
121
|
const payloadForApprovedHashAdapter = canonicalTransactionPayload(transaction);
|
|
120
122
|
```
|
|
121
123
|
|
|
122
|
-
The package produces canonical bytes but deliberately leaves SHA-256
|
|
123
|
-
signing to an approved infrastructure adapter. Metadata keys and
|
|
124
|
-
are ordered with locale-independent UTF-16 code-unit comparison. Their
|
|
124
|
+
The package produces canonical bytes but deliberately leaves SHA-256 hashing
|
|
125
|
+
and any signing to an approved infrastructure adapter. Metadata keys and
|
|
126
|
+
posting IDs are ordered with locale-independent UTF-16 code-unit comparison. Their
|
|
125
127
|
validated ASCII alphabet makes that ordering identical to PostgreSQL
|
|
126
128
|
`COLLATE "C"`; adapters must hash the exact UTF-8 bytes returned by
|
|
127
129
|
`canonicalTransactionPayload()`.
|
|
128
130
|
|
|
131
|
+
## Audit receipts and integrity verification
|
|
132
|
+
|
|
133
|
+
`AuditedEconomyCommandEnvelopeV1` is a standalone, fingerprint-only V3
|
|
134
|
+
contract. It binds actor, subject, principal type, delegated
|
|
135
|
+
relationship/version, sanitized capability/flag/assurance evidence, route,
|
|
136
|
+
build, region, writer fence, correlation, causation, and payload. It never
|
|
137
|
+
extends the legacy raw-key envelope.
|
|
138
|
+
|
|
139
|
+
`EconomyHmacFingerprintV1` records an exact domain, key version, and
|
|
140
|
+
`hmac-sha256:` digest. Raw idempotency keys, provider event/object IDs,
|
|
141
|
+
callback bodies, and reconciliation material use distinct domains. Provider
|
|
142
|
+
commands require a canonical `EconomyProviderEvidenceManifestV1`; callback
|
|
143
|
+
signatures and payment data have no contract field.
|
|
144
|
+
|
|
145
|
+
Encrypted operational provider handles remain site-owned.
|
|
146
|
+
`EconomyEncryptedOperationalHandleBindingV1` binds only their purpose,
|
|
147
|
+
provider, AES-256-GCM label, key version, ciphertext-content hash, and
|
|
148
|
+
encryption-context hash. It contains no ciphertext, nonce, authentication tag,
|
|
149
|
+
plaintext, or Key Vault URI.
|
|
150
|
+
|
|
151
|
+
`EconomyAcceptedCommandReceiptV1` is safe to return after durable acceptance:
|
|
152
|
+
it exposes only receipt, command, and correlation IDs plus the command-envelope
|
|
153
|
+
hash and acceptance time. `EconomyCommandResultReceiptV1` is terminal and
|
|
154
|
+
exclusive:
|
|
155
|
+
|
|
156
|
+
- `completed` requires a transaction ID and its existing canonical hash and
|
|
157
|
+
forbids outcome codes;
|
|
158
|
+
- `failed` requires one bounded safe failure code and forbids transaction
|
|
159
|
+
fields;
|
|
160
|
+
- `no-op` requires one bounded safe no-op code and forbids transaction fields.
|
|
161
|
+
|
|
162
|
+
Every terminal shape retains a result hash. Replay is a processing mode, not a
|
|
163
|
+
command source: `assertExactAuditedEconomyCommandReplay()` requires identical
|
|
164
|
+
canonical bytes and preserves the original source. A collision with different
|
|
165
|
+
bytes is a security conflict.
|
|
166
|
+
|
|
167
|
+
The audit canonicalizers use explicit fixed field order and omit absent optional
|
|
168
|
+
fields. Runtime validators reject unknown fields rather than allowing raw
|
|
169
|
+
evidence to be persisted accidentally. `canonicalTransactionPayload()` is
|
|
170
|
+
unchanged. A V3 transaction stores the HMAC digest in its legacy canonical
|
|
171
|
+
`idempotencyKey` field; the HTTP key is never stored.
|
|
172
|
+
|
|
173
|
+
`EconomyAuthorityHeadV1` and hash-linked
|
|
174
|
+
`EconomyAuthorityCommitManifestV1` cover every immutable record, conditional
|
|
175
|
+
projection replacement, idempotency result, and outbox effect. Manifests
|
|
176
|
+
support only `create` and `conditional-replace`; batches are limited to 80
|
|
177
|
+
operations and 1.5 MiB. The manifest create and head replacement reserve
|
|
178
|
+
two operations, leaving at most 78 canonical record references.
|
|
179
|
+
`assertEconomyAuditGraph()` recomputes the complete command/evidence/receipt/
|
|
180
|
+
transaction/manifest graph and expected head.
|
|
181
|
+
`assertEconomyAuthorityRecoveryEvidence()` additionally recomputes the
|
|
182
|
+
successful prior verification receipt bound by any reopening manifest.
|
|
183
|
+
|
|
184
|
+
First-party commands use one atomic authority boundary. Provider workflows use
|
|
185
|
+
one boundary to durably accept verified evidence before acknowledgement and a
|
|
186
|
+
second boundary to record the externally reconciled completed, failed, or
|
|
187
|
+
no-op result.
|
|
188
|
+
|
|
189
|
+
`verifyJournalChainSegment()` accepts an approved canonical-payload hash
|
|
190
|
+
function, recomputes every transaction hash, checks previous-hash links and
|
|
191
|
+
duplicate transaction IDs, and proves the resulting head against an expected
|
|
192
|
+
head. `EconomyIntegrityVerificationReceiptV1` binds authority, journal, and
|
|
193
|
+
projection verification outcomes. `EconomyIntegrityAnchorManifestV1` defines
|
|
194
|
+
canonical hourly Merkle evidence while signing, keys, and storage remain
|
|
195
|
+
infrastructure responsibilities.
|
|
196
|
+
|
|
197
|
+
## Recoverable acknowledgements and portable receipts
|
|
198
|
+
|
|
199
|
+
The additive recovery protocol protects the acknowledgement boundary without
|
|
200
|
+
turning an evidence store into a second economy writer:
|
|
201
|
+
|
|
202
|
+
- `EconomyRecoveryAcceptanceEnvelopeV1` binds the provider-neutral audited
|
|
203
|
+
command, accepted receipt, HMAC idempotency fingerprint, and an AES-256-GCM
|
|
204
|
+
sealed reconstruction payload before command processing;
|
|
205
|
+
- `EconomyRecoveryCommittedResultV1` binds that exact acceptance to the
|
|
206
|
+
terminal result receipt, authority commit/head, sequence, optional completed
|
|
207
|
+
transaction, and sealed reconstruction payload after the authority commits;
|
|
208
|
+
- `EconomyRegionalEvidenceReceiptV1` is a signed, sequence-addressed,
|
|
209
|
+
hash-chained retention assertion for the byte-identical acceptance or result
|
|
210
|
+
stored in one evidence region; and
|
|
211
|
+
- `EconomyPortableCustomerReceiptV1` binds a positive TokenSubunit amount and
|
|
212
|
+
direction to the completed transaction, result, authority sequence, at least
|
|
213
|
+
two regional evidence receipts, and an optional authority-commit Merkle
|
|
214
|
+
inclusion proof.
|
|
215
|
+
|
|
216
|
+
Every recovery record has a SHA-256 content-addressed ID derived from a
|
|
217
|
+
separate, explicitly ordered canonical body. Detached signatures cover that ID,
|
|
218
|
+
the complete body, and public algorithm/key-version/time metadata. The package
|
|
219
|
+
does not implement hashing, encryption, signing, key lookup, Blob access, or
|
|
220
|
+
identity. Callers supply approved hash and signature-verification functions;
|
|
221
|
+
`assertEconomyRegionalEvidenceChain()`,
|
|
222
|
+
`assertEconomyRegionalEvidenceEquality()`,
|
|
223
|
+
`assertEconomyMerkleInclusion()`, and
|
|
224
|
+
`assertEconomyPortableCustomerReceiptEvidence()` run without a cloud SDK or
|
|
225
|
+
authentication dependency.
|
|
226
|
+
|
|
227
|
+
Recovery validators reject unknown fields. Plaintext records have no field for
|
|
228
|
+
raw idempotency keys, provider/payment facts, callback bodies/signatures,
|
|
229
|
+
storage URIs, payer/household/account identity, email, session data, or exact
|
|
230
|
+
birth data. A portable receipt contains only opaque command/transaction
|
|
231
|
+
references, proof hashes, amount/direction, safe activity, terms version, and
|
|
232
|
+
`cashRedemptionAllowed: false`. The sealed payload's plaintext remains subject
|
|
233
|
+
to the same approved privacy-minimized authority schema; encryption is not
|
|
234
|
+
permission to retain unnecessary data.
|
|
235
|
+
|
|
236
|
+
A consuming service may acknowledge a provider callback after identical
|
|
237
|
+
acceptance evidence is durable in both approved regions, then process it
|
|
238
|
+
asynchronously. A successful browser value command is not customer-acknowledged
|
|
239
|
+
until the authoritative commit and both regional committed-result receipts
|
|
240
|
+
exist. Cross-service writes are not a distributed ACID transaction: exact
|
|
241
|
+
content IDs and idempotent create-only completion make orphan acceptances and
|
|
242
|
+
committed-but-not-yet-acknowledged results recoverable without duplicating
|
|
243
|
+
value.
|
|
244
|
+
|
|
245
|
+
These contracts enable a scoped recoverability claim only after the consuming
|
|
246
|
+
infrastructure proves dual durable writes, locked retention, independent keys,
|
|
247
|
+
monitoring, and tested reconstruction. They do not by themselves establish
|
|
248
|
+
zero RPO, WORM retention, HSM custody, administrator-proof storage, or
|
|
249
|
+
availability.
|
|
250
|
+
|
|
129
251
|
## Source-lot policy and allocations
|
|
130
252
|
|
|
131
253
|
`selectSourceLots()` selects spendable slices in credited-time/lot-ID order and
|
|
@@ -160,6 +282,44 @@ settlements after `evaluatedAt`. The caller must derive both window timestamps
|
|
|
160
282
|
from the entire public cohort and exclude non-production/test lots: staff,
|
|
161
283
|
closed-beta, and test availability must never open or close the public window.
|
|
162
284
|
|
|
285
|
+
## Junior Coder Module Allowances
|
|
286
|
+
|
|
287
|
+
`ModuleAllowanceV1` is a Guardian-funded reservation for one linked child and
|
|
288
|
+
one purpose: purchasing independently sellable Junior Coder module
|
|
289
|
+
entitlements. It is deliberately separate from `GameplayAllocationV1`; callers
|
|
290
|
+
cannot spend gameplay value as a learning allowance or silently move learning
|
|
291
|
+
value into gameplay.
|
|
292
|
+
|
|
293
|
+
The purchase contracts implement the deterministic parts of:
|
|
294
|
+
|
|
295
|
+
```text
|
|
296
|
+
immutable quote -> allowance hold -> pending entitlement
|
|
297
|
+
-> settle spend -> activate entitlement -> durable receipt
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
An immutable quote binds the exact module version, Token price, child,
|
|
301
|
+
Guardian acknowledgement, catalog version, and requirements-manifest version
|
|
302
|
+
plus canonical SHA-256 reference. This makes software-only declarations and
|
|
303
|
+
robotics bills of materials durable pre-purchase evidence even after a live
|
|
304
|
+
manifest changes.
|
|
305
|
+
|
|
306
|
+
`createModuleSpendHold()` moves whole Tokens from available to held value.
|
|
307
|
+
`settleModuleSpendHold()` requires a pending entitlement ID before it can move
|
|
308
|
+
held value to spent value. `releaseModuleSpendHold()` returns failed or expired
|
|
309
|
+
holds to the same Module Allowance. `createModulePurchaseReceipt()` accepts only
|
|
310
|
+
matching quote and settled-hold evidence. `reconcileModulePurchase()` returns
|
|
311
|
+
one forward-safe repair instruction and fails closed to manual review for a
|
|
312
|
+
settled debit without an entitlement or an active paid entitlement without a
|
|
313
|
+
settled debit.
|
|
314
|
+
|
|
315
|
+
These functions produce immutable next-state projections; they do not perform
|
|
316
|
+
authorization or persistence. The consuming service must evaluate
|
|
317
|
+
`learning.junior-coder.purchase.enabled`, enforce Guardian/child capabilities,
|
|
318
|
+
store actor/subject/operation-scoped idempotency evidence, and compare-and-swap
|
|
319
|
+
allowance and hold versions alongside the balanced journal, entitlement,
|
|
320
|
+
receipt, and outbox in a serializable transaction. A disabled feature may still
|
|
321
|
+
release and reconcile existing holds, but must reject new quotes and purchases.
|
|
322
|
+
|
|
163
323
|
## Acquisition and future contracts
|
|
164
324
|
|
|
165
325
|
Purchase intents bind payer, receiving household/wallet, pack, catalog,
|
|
@@ -267,6 +427,15 @@ journal rows directly. The V2 adapter is responsible for:
|
|
|
267
427
|
- managed identity and least-privilege database access; and
|
|
268
428
|
- immutable audit/integrity evidence outside this package.
|
|
269
429
|
|
|
430
|
+
`EconomyPersistencePortV3` is additive and retains every V2 economic primitive.
|
|
431
|
+
It removes V2's raw-key idempotency operations from its unit and replaces them
|
|
432
|
+
with `EconomyAuditedIdempotencyScopeV1` and
|
|
433
|
+
`EconomyAuditedIdempotencyResultV1`. It adds audited commands, evidence
|
|
434
|
+
manifests, encrypted-handle bindings, receipts, authority commits/head CAS,
|
|
435
|
+
integrity receipts, and anchor manifests. Its journal method accepts
|
|
436
|
+
`AuditedChainedEconomicJournalTransactionV1`, whose legacy idempotency slot is
|
|
437
|
+
type-narrowed to an HMAC digest. V1 and V2 remain exported unchanged.
|
|
438
|
+
|
|
270
439
|
## Development
|
|
271
440
|
|
|
272
441
|
```bash
|
|
@@ -282,10 +451,20 @@ Coverage must remain at least 80%, and every changed source file must appear in
|
|
|
282
451
|
LCOV. Generated property tests cover exact arithmetic, double-entry balance,
|
|
283
452
|
projection rebuilds, idempotency, reversals, lot isolation, and allocation
|
|
284
453
|
non-negativity. npm publication is performed only by the approved GitHub CD
|
|
285
|
-
workflow.
|
|
454
|
+
workflow on configurable trusted self-hosted runners. Release LCOV and the
|
|
455
|
+
CycloneDX SBOM remain retained even when an external coverage or npm provenance
|
|
456
|
+
service is unavailable. Release tags and GitHub Releases use a current-repository
|
|
457
|
+
GitHub App token with explicit Contents and Workflows write permissions; npm
|
|
458
|
+
publication continues to use only the protected `NPM_TOKEN`. Both release jobs
|
|
459
|
+
install a checksum-pinned GitHub CLI under `RUNNER_TEMP`. A requested version
|
|
460
|
+
bump reuses the current version only when neither npm nor GitHub records it as a
|
|
461
|
+
completed release; use `bump=none` for deliberate recovery of prepared metadata.
|
|
462
|
+
Publication checks out the verified current release-branch HEAD so that recovery
|
|
463
|
+
always includes the reviewed workflow tooling.
|
|
286
464
|
|
|
287
465
|
## Security
|
|
288
466
|
|
|
289
|
-
Do not include raw
|
|
290
|
-
|
|
291
|
-
|
|
467
|
+
Do not include raw idempotency keys, provider identifiers, provider callback
|
|
468
|
+
bodies or signatures, payment details, personal data, encrypted-handle
|
|
469
|
+
ciphertext, or secrets in contracts, metadata, tests, examples, or logs.
|
|
470
|
+
Report vulnerabilities privately according to [SECURITY.md](./SECURITY.md).
|