{"_id":"@action-state-group/capsule-emit","_rev":"6-ae15c1c38e305addcb2040c65f9f39a7","name":"@action-state-group/capsule-emit","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@action-state-group/capsule-emit","version":"0.1.0","license":"Apache-2.0","_id":"@action-state-group/capsule-emit@0.1.0","maintainers":[{"name":"actionstategroup","email":"npm@actionstate.ai"}],"homepage":"https://github.com/action-state-group/capsule-emit-ts#readme","bugs":{"url":"https://github.com/action-state-group/capsule-emit-ts/issues"},"dist":{"shasum":"8b2db04c29389e2caebd8d9d83a428cd79e8daf6","tarball":"https://registry.npmjs.org/@action-state-group/capsule-emit/-/capsule-emit-0.1.0.tgz","fileCount":23,"integrity":"sha512-EF4FLY7ynlnGfsrjtiqRMK+1kAXANFeyZsv14Ofb1c7pf1fTBqfuJdhkdZzyA6otceaxX2RuJL8cLE3fMNbRcQ==","signatures":[{"sig":"MEQCID/rCmxF9ADrCVyO2V0PkU+aqvpMxfzsjPpI0IHq/1NqAiBAK+ABM9P3ZxzTXrGwhHjxRmfWkpixPzRLV2uAn0Aodw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":158195},"type":"module","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./aac":{"types":"./dist/aac/index.d.ts","import":"./dist/aac/index.js"}},"gitHead":"d8d4ef25cd295b6a437343974efc49bde59c11a1","scripts":{"lint":"oxlint src test","test":"vitest run --coverage","build":"tsup && tsc -p tsconfig.build.json","check":"npm run format:check && npm run lint && npm run typecheck && npm test","format":"prettier --write .","test:unit":"vitest run --coverage --exclude test/interop.test.ts","typecheck":"tsc --noEmit","format:check":"prettier --check .","test:interop":"vitest run test/interop.test.ts"},"_npmUser":{"name":"actionstategroup","email":"npm@actionstate.ai"},"repository":{"url":"git+https://github.com/action-state-group/capsule-emit-ts.git","type":"git"},"_npmVersion":"11.17.0","description":"TypeScript producer and verifier for AAC format 4","directories":{},"_nodeVersion":"26.5.0","dependencies":{"cborg":"6.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","oxlint":"1.81.0","vitest":"4.1.11","prettier":"3.6.2","typescript":"7.0.2","@types/node":"24.3.0","@vitest/coverage-v8":"4.1.11"},"_npmOperationalInternal":{"tmp":"tmp/capsule-emit_0.1.0_1788399683256_0.5982975016668268","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@action-state-group/capsule-emit","version":"0.1.1","license":"Apache-2.0","_id":"@action-state-group/capsule-emit@0.1.1","maintainers":[{"name":"actionstategroup","email":"npm@actionstate.ai"}],"homepage":"https://github.com/action-state-group/capsule-emit-ts#readme","bugs":{"url":"https://github.com/action-state-group/capsule-emit-ts/issues"},"dist":{"shasum":"054de2070c9b0de56567a404677b0f89d244d275","tarball":"https://registry.npmjs.org/@action-state-group/capsule-emit/-/capsule-emit-0.1.1.tgz","fileCount":23,"integrity":"sha512-dPBj//x8NsEYECKqp4yYwxQOCRVDxPWWzdRuvp9TquT09IZJIasZ1EbTdL3BUwpMv7LO3X0Nr8gB47yqcLMsLQ==","signatures":[{"sig":"MEUCIFkD7cjLJjT31oP31E1HZwXpbIrcEKykwbJn6NeI/dUPAiEArtO1aJpFJcWBywS4bfLGE5clP5KqozRFt2V3MUUnN6w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":159226},"type":"module","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./aac":{"types":"./dist/aac/index.d.ts","import":"./dist/aac/index.js"}},"gitHead":"3139aebafbbd0e70ff41727651f87b3f395a9a71","scripts":{"lint":"oxlint src test","test":"vitest run --coverage","build":"tsup && tsc -p tsconfig.build.json","check":"npm run format:check && npm run lint && npm run typecheck && npm test","format":"prettier --write .","test:unit":"vitest run --coverage --exclude test/interop.test.ts","typecheck":"tsc --noEmit","format:check":"prettier --check .","test:interop":"vitest run test/interop.test.ts"},"_npmUser":{"name":"actionstategroup","email":"npm@actionstate.ai"},"repository":{"url":"git+https://github.com/action-state-group/capsule-emit-ts.git","type":"git"},"_npmVersion":"11.17.0","description":"TypeScript producer and verifier for AAC format 4","directories":{},"_nodeVersion":"26.5.0","dependencies":{"cborg":"6.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","oxlint":"1.81.0","vitest":"4.1.11","prettier":"3.6.2","typescript":"7.0.2","@types/node":"24.3.0","@vitest/coverage-v8":"4.1.11"},"_npmOperationalInternal":{"tmp":"tmp/capsule-emit_0.1.1_1788406591177_0.8336999355879406","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@action-state-group/capsule-emit","version":"0.1.2","license":"Apache-2.0","_id":"@action-state-group/capsule-emit@0.1.2","maintainers":[{"name":"actionstategroup","email":"npm@actionstate.ai"}],"homepage":"https://github.com/action-state-group/capsule-emit-ts#readme","bugs":{"url":"https://github.com/action-state-group/capsule-emit-ts/issues"},"dist":{"shasum":"f0731edf7752e91ab6329a7bf151006d80ae28b7","tarball":"https://registry.npmjs.org/@action-state-group/capsule-emit/-/capsule-emit-0.1.2.tgz","fileCount":23,"integrity":"sha512-YDl+IjDyfjHv3LQ+8cjKbe4pP2KpS7N30qcGvHNeOf71LzLIe4ruSwhl+x3277LuYKMHdvYdkqOqR5DRQzJrqQ==","signatures":[{"sig":"MEYCIQC0UTBxtgkB8OcZbCpGq7sPSrJmXZmG8296Lsec3ePQcAIhAI6pVat4RJuGrSu2zDKhkF6RwJ2kzK7v4GK+mX8gdQV1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@action-state-group%2fcapsule-emit@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":160086},"type":"module","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./aac":{"types":"./dist/aac/index.d.ts","import":"./dist/aac/index.js"}},"gitHead":"9384417db69827c90c202379ddb15a3d34cc7417","scripts":{"lint":"oxlint src test","test":"vitest run --coverage","build":"tsup && tsc -p tsconfig.build.json","check":"npm run format:check && npm run lint && npm run typecheck && npm test","format":"prettier --write .","test:unit":"vitest run --coverage --exclude test/interop.test.ts","typecheck":"tsc --noEmit","format:check":"prettier --check .","test:interop":"vitest run test/interop.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1d7738ad-3e65-451d-9e1b-dede3b4fe7a0"}},"repository":{"url":"git+https://github.com/action-state-group/capsule-emit-ts.git","type":"git"},"_npmVersion":"11.19.0","description":"TypeScript producer and verifier for AAC format 4","directories":{},"_nodeVersion":"24.20.0","dependencies":{"cborg":"6.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","oxlint":"1.81.0","vitest":"4.1.11","prettier":"3.6.2","typescript":"7.0.2","@types/node":"24.3.0","@vitest/coverage-v8":"4.1.11"},"_npmOperationalInternal":{"tmp":"tmp/capsule-emit_0.1.2_1788409067406_0.6233550643865788","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@action-state-group/capsule-emit","version":"0.2.0","license":"Apache-2.0","_id":"@action-state-group/capsule-emit@0.2.0","maintainers":[{"name":"actionstategroup","email":"npm@actionstate.ai"}],"homepage":"https://github.com/action-state-group/capsule-emit-ts#readme","bugs":{"url":"https://github.com/action-state-group/capsule-emit-ts/issues"},"dist":{"shasum":"a577e9356f7bd2b948f516c77dd53cdf18859324","tarball":"https://registry.npmjs.org/@action-state-group/capsule-emit/-/capsule-emit-0.2.0.tgz","fileCount":27,"integrity":"sha512-xnUYR/9kvpw/F4rz51cYJqV4FcyHm831YLbu50tm46COcLWY54Mf+ZQe9CcaNV/Gni4NP7wyqsyT4n5N4n6mFQ==","signatures":[{"sig":"MEUCIQCB2pCFpvlhmKmheKcvAa7RozSfnUu2s0/ZSHV1Ifck9wIgYNo7CJriBhZ/98tR8yl5qTlryW7+c3goqYt9O53/JOo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@action-state-group%2fcapsule-emit@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":185336},"type":"module","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./aac":{"types":"./dist/aac/index.d.ts","import":"./dist/aac/index.js"}},"gitHead":"b53fb4348bb22abf940b7dd55a5ce43228ff9677","scripts":{"lint":"oxlint src test","test":"vitest run --coverage","build":"tsup && tsc -p tsconfig.build.json","check":"npm run format:check && npm run lint && npm run typecheck && npm test","format":"prettier --write .","test:unit":"vitest run --coverage --exclude test/interop.test.ts","typecheck":"tsc --noEmit","format:check":"prettier --check .","test:interop":"vitest run test/interop.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1d7738ad-3e65-451d-9e1b-dede3b4fe7a0"}},"repository":{"url":"git+https://github.com/action-state-group/capsule-emit-ts.git","type":"git"},"_npmVersion":"11.19.0","description":"TypeScript producer and verifier for AAC format 4","directories":{},"_nodeVersion":"24.20.0","dependencies":{"cborg":"6.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","oxlint":"1.81.0","vitest":"4.1.11","prettier":"3.6.2","typescript":"7.0.2","@types/node":"24.3.0","@vitest/coverage-v8":"4.1.11"},"_npmOperationalInternal":{"tmp":"tmp/capsule-emit_0.2.0_1788836558820_0.49067138215077","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@action-state-group/capsule-emit","version":"0.2.1","license":"Apache-2.0","_id":"@action-state-group/capsule-emit@0.2.1","maintainers":[{"name":"actionstategroup","email":"npm@actionstate.ai"}],"homepage":"https://github.com/action-state-group/capsule-emit-ts#readme","bugs":{"url":"https://github.com/action-state-group/capsule-emit-ts/issues"},"dist":{"shasum":"7e2d0ab8b5976d9cfeaacb7d143dce2e3a5b6b0a","tarball":"https://registry.npmjs.org/@action-state-group/capsule-emit/-/capsule-emit-0.2.1.tgz","fileCount":27,"integrity":"sha512-2/XKBEEe0m4TOUAhWH5oE+Q8kA1jQwPmNUr8byn7GW7Vweu6+8HWeGzwokPKPuJeAbNzilQ2ujhIQXDSwJV2kA==","signatures":[{"sig":"MEYCIQC6/Df3/BvJv0ZP8L8oZ6o/+1sRjmcUkARwwnvkwt/nmwIhANm3/yb13hSfV42O4Kj0YbwkVrxhDLUqugtK87JNqj6r","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@action-state-group%2fcapsule-emit@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":183886},"type":"module","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./aac":{"types":"./dist/aac/index.d.ts","import":"./dist/aac/index.js"}},"gitHead":"f54bd5cdba2cfb7f174e0335d9041be6ab91515a","scripts":{"lint":"oxlint src test","test":"vitest run --coverage","build":"tsup && tsc -p tsconfig.build.json","check":"npm run format:check && npm run lint && npm run typecheck && npm test","format":"prettier --write .","test:unit":"vitest run --coverage --exclude test/interop.test.ts","typecheck":"tsc --noEmit","format:check":"prettier --check .","test:interop":"vitest run test/interop.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1d7738ad-3e65-451d-9e1b-dede3b4fe7a0"}},"repository":{"url":"git+https://github.com/action-state-group/capsule-emit-ts.git","type":"git"},"_npmVersion":"11.19.0","description":"TypeScript producer and verifier for AAC format 4","directories":{},"_nodeVersion":"24.20.0","dependencies":{"cborg":"6.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","oxlint":"1.81.0","vitest":"4.1.11","prettier":"3.6.2","typescript":"7.0.2","@types/node":"24.3.0","@vitest/coverage-v8":"4.1.11"},"_npmOperationalInternal":{"tmp":"tmp/capsule-emit_0.2.1_1788939489953_0.3516360052366587","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"@action-state-group/capsule-emit@0.3.0","bugs":{"url":"https://github.com/action-state-group/capsule-emit-ts/issues"},"dist":{"shasum":"64c9845893890789de170e0e9b1f849e057c1831","tarball":"https://registry.npmjs.org/@action-state-group/capsule-emit/-/capsule-emit-0.3.0.tgz","fileCount":45,"integrity":"sha512-KQ6wqvUYo3movt3eZ1eLO7mOAQ2LuGx3mMKThjaH7761EhaXx1j8+b7pcoTbVoWmjurmwgS8pJFkf9k4IGABzw==","signatures":[{"sig":"MEUCIDOoQliqvufykOhlIHhNr5P9TfwxI4MkboOMrAoylav6AiEAqi6kaeH++PlBREnDUGjrcdjZKCQqO8UxYgdRQXUBZ8Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFLm/f2V+o4rqkM2vqLqZj/XaKoC8eSPufh4weC0yJEPAiEAu4ucRd/eunaqv5Sv6yWlDxSZqCOnguc+zAuktvSw6OM="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@action-state-group%2fcapsule-emit@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":262820},"name":"@action-state-group/capsule-emit","type":"module","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./aac":{"types":"./dist/aac/index.d.ts","import":"./dist/aac/index.js"},"./artifact":{"types":"./dist/artifact/index.d.ts","import":"./dist/artifact/index.js"},"./artifact/mysql":{"types":"./dist/artifact/mysql.d.ts","import":"./dist/artifact/mysql.js"},"./artifact/sqlite":{"types":"./dist/artifact/sqlite.d.ts","import":"./dist/artifact/sqlite.js"}},"gitHead":"7bba9e92ec4a02cae57f71004c1360ec71400c3d","license":"Apache-2.0","scripts":{"lint":"oxlint src test","test":"vitest run --coverage","build":"tsup && tsc -p tsconfig.build.json","check":"npm run format:check && npm run lint && npm run typecheck && npm test","format":"prettier --write .","test:unit":"vitest run --coverage --exclude test/interop.test.ts","typecheck":"tsc --noEmit","format:check":"prettier --check .","test:interop":"vitest run test/interop.test.ts"},"version":"0.3.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:1d7738ad-3e65-451d-9e1b-dede3b4fe7a0"}},"homepage":"https://github.com/action-state-group/capsule-emit-ts#readme","repository":{"url":"git+https://github.com/action-state-group/capsule-emit-ts.git","type":"git"},"_npmVersion":"11.19.0","description":"TypeScript producer and verifier for AAC format 4","directories":{},"maintainers":[{"name":"actionstategroup","email":"npm@actionstate.ai"}],"_nodeVersion":"24.20.0","dependencies":{"cborg":"6.1.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"8.5.1","mysql2":"3.24.3","oxlint":"1.81.0","vitest":"4.1.11","prettier":"3.6.2","typescript":"7.0.2","@types/node":"22.20.2","better-sqlite3":"13.0.3","@vitest/coverage-v8":"4.1.11","@testcontainers/mysql":"11.7.2","@types/better-sqlite3":"7.6.13"},"peerDependencies":{"mysql2":">=3","better-sqlite3":">=11","@types/better-sqlite3":">=7"},"peerDependenciesMeta":{"mysql2":{"optional":true},"better-sqlite3":{"optional":true},"@types/better-sqlite3":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/capsule-emit_0.3.0_1789151944686_0.6851715963321146"}}},"time":{"created":"2026-09-03T01:41:23.061Z","modified":"2026-09-11T18:39:05.185Z","0.1.0":"2026-09-03T01:41:23.420Z","0.1.1":"2026-09-03T03:36:31.327Z","0.1.2":"2026-09-03T04:17:47.550Z","0.2.0":"2026-09-08T03:02:38.969Z","0.2.1":"2026-09-09T07:38:10.113Z","0.3.0":"2026-09-11T18:39:04.816Z"},"bugs":{"url":"https://github.com/action-state-group/capsule-emit-ts/issues"},"license":"Apache-2.0","homepage":"https://github.com/action-state-group/capsule-emit-ts#readme","repository":{"url":"git+https://github.com/action-state-group/capsule-emit-ts.git","type":"git"},"description":"TypeScript producer and verifier for AAC format 4","maintainers":[{"name":"actionstategroup","email":"npm@actionstate.ai"}],"readme":"# capsule-emit-ts\n\nTypeScript-native AAC format-4 producer and verifier. The package is ESM-first,\nuses strict TypeScript, preserves signer-independent Capsule IDs, and emits the\nsame attached-payload COSE Producer Envelopes as `capsule-emit-go`.\n\nThe root entry point builds records only. It does not execute actions, generate\nbusiness IDs or timestamps, persist Capsules, retry effects, contact witnesses,\nor authorize signers. Optional verified persistence is available behind the\n[`./artifact`](#artifact-storage) subpath.\n\n## Install\n\nNode.js 22 or newer is required.\n\n```sh\nnpm install @action-state-group/capsule-emit\n```\n\n## Build, sign, and verify\n\n`seal` is the recommended application-facing API. It digests caller-owned JSON,\nbuilds and verifies the format-4 Capsule, then signs its raw 32-byte Capsule ID\nwith an independent Producer Envelope.\n\n```ts\nimport { randomBytes } from \"node:crypto\";\nimport {\n  createEd25519Identity,\n  seal,\n  verifyCapsule,\n  verifyEnvelope,\n} from \"@action-state-group/capsule-emit\";\n\nconst identity = createEd25519Identity(randomBytes(32));\nconst result = seal({\n  capsule: {\n    actionId: \"example/1\",\n    actionType: \"decide\",\n    operator: \"example-org\",\n    developer: \"example-agent@v1\",\n    timestamp: new Date(\"2026-09-02T12:00:00Z\"),\n    disposition: {\n      decision: \"accept\",\n      approver: \"policy\",\n      humanDisposed: false,\n      verdictClass: \"executed\",\n    },\n  },\n  payload: { task: \"publish\", issue: 123 },\n  agentOutput: { accepted: true },\n  model: { provider: \"example\", modelId: \"model-v1\" },\n  runtime: \"example-runtime@1\",\n  identity,\n});\n\nconst capsule = verifyCapsule(result.payload);\nif (capsule.capsuleId !== result.capsuleId) {\n  throw new Error(\"Capsule ID mismatch\");\n}\nconst envelope = verifyEnvelope(result.capsuleId, result.envelope);\nif (!envelope.ok) {\n  throw new Error(\n    `Producer Envelope failed: ${JSON.stringify(envelope.findings)}`,\n  );\n}\nif (\n  !envelope.publicKey ||\n  !Buffer.from(envelope.publicKey).equals(Buffer.from(identity.publicKey))\n) {\n  throw new Error(\"Producer Envelope signer is not authorized\");\n}\n```\n\n`verifyCapsule` validates Capsule identity and Class 1 structure. It does not\nauthenticate local-only `signature` or `key_id` fields. `verifyEnvelope`\nauthenticates the public key carried by the Producer Envelope. Whether that key\nis authorized for an operator, developer, or action remains caller policy.\n\n## Typed construction\n\nUse `build` when the application already owns all typed Capsule fields and wants\nconstruction separate from signing. `received` binds exact opaque bytes under a\ncaller-declared CPB type. `carry` is the same operation with the generic\n`foreign-artifact` type. `who`, `can`, `did`, and `audit` reference already-built\nCapsules in a typed composition without minting or persisting those members.\n\n```ts\nimport { randomBytes } from \"node:crypto\";\nimport {\n  build,\n  buildComposition,\n  can,\n  createEd25519Identity,\n  did,\n  received,\n  seal,\n  sign,\n  who,\n} from \"@action-state-group/capsule-emit\";\n\nconst identity = createEd25519Identity(randomBytes(32));\nconst common = {\n  actionType: \"fyi\" as const,\n  operator: \"example-org\",\n  developer: \"example-agent@v1\",\n  timestamp: \"2026-09-02T12:00:00Z\",\n};\n\nconst identityCapsule = build({\n  ...common,\n  actionId: \"identity/1\",\n  domain: \"identity\",\n});\nconst providerAck = received(\n  { ...common, actionId: \"provider-ack/1\" },\n  new TextEncoder().encode(\"opaque provider acknowledgement\"),\n  \"provider-ack\",\n);\nconst actionCapsule = build({\n  ...common,\n  actionId: \"action/1\",\n  effect: {\n    type: \"example.publish\",\n    status: \"planned\",\n    irreversibilityClass: \"two_way\",\n  },\n});\nconst composition = buildComposition({ ...common, actionId: \"composition/1\" }, [\n  who(identityCapsule),\n  can(providerAck),\n  did(actionCapsule),\n]);\nconst envelope = sign(composition, identity);\n\nconsole.log(providerAck.capsuleId, composition.capsuleId, envelope.length);\n```\n\nThe same composition can use the high-level signing path:\n\n```ts\nconst signedComposition = seal({\n  capsule: { ...common, actionId: \"composition/2\" },\n  members: [who(identityCapsule), can(providerAck), did(actionCapsule)],\n  identity,\n});\n```\n\nComposition members must occupy distinct slots and refer to distinct verified\nformat-4 Capsules. Carried and composed construction rejects explicit agent\ninput/output digests because those records already own their construction\ncommitments.\n\n## Compose with CLL\n\nThis package constructs and verifies AAC records. It does not persist them.\nApplications that also need checkpointed inclusion install the independent CLL\npackage, store the full Capsule and Producer Envelope in application storage,\nand append only the verified 32-byte Capsule ID to CLL.\n\n```ts\nimport { build, verifyCapsule } from \"@action-state-group/capsule-emit\";\nimport { MysqlStore } from \"@action-state-group/cll/mysql\";\n\nconst built = build({\n  actionId: \"deploy-42\",\n  actionType: \"fyi\",\n  operator: \"example-org\",\n  developer: \"example-agent@v1\",\n  timestamp: new Date(),\n});\nverifyCapsule(built.json); // returns verified metadata or throws\n\n// Persist built.json and any Producer Envelope in application storage.\nconst mysqlUrl = process.env.MYSQL_URL;\nif (!mysqlUrl) throw new Error(\"MYSQL_URL is required\");\nconst cll = await MysqlStore.open(mysqlUrl, \"application-log\");\ntry {\n  await cll.append({\n    value: Buffer.from(built.capsuleId, \"hex\"),\n    appendedAt: new Date(),\n  });\n} finally {\n  await cll.close();\n}\n```\n\nNeither package depends on the other. An application that uses both declares\nboth dependencies explicitly.\n\n`capsule-emit` creates no database tables. `MysqlStore.open()` and\n`SqliteStore.open()` create only CLL's internal tables, documented in the\n[`@action-state-group/cll` backend guide](https://github.com/action-state-group/cll-ts#sqlite-and-mysql-tables).\nFull Capsules and Producer Envelopes remain in application-owned storage.\n\n## JSON digests\n\n`digestJSON(value)` returns the lowercase SHA-256 of RFC 8785 JCS bytes. It\nrejects duplicate object names, excessive depth, floats, unsafe integers,\ninvalid UTF-8, and trailing JSON data on strict decoding paths.\n\n```ts\nimport { digestJSON } from \"@action-state-group/capsule-emit\";\n\nconst requestDigest = digestJSON({ issue: 123, operation: \"publish\" });\nconst responseDigest = digestJSON({ accepted: true });\n```\n\nCallers own the JSON shape and assign these values to effect request/response\nfields where appropriate. Raw payload values never enter the Capsule.\n\n## Verification and compatibility\n\nThe `@action-state-group/capsule-emit/aac` subpath exposes strict JSON decoding, current and\nvintage Capsule-ID computation, Class 1 verification, and store verification\nfor persistence adapters. Top-level construction and verification remain\nformat-4-only.\n\n`isV4IrreversibilityClass(value)` tests membership in the four\nirreversibility-class values seeded by AAC draft-04. It deliberately returns\nfalse for future registry extensions without claiming that an extension is\ninvalid.\n\nTests replay the complete upstream AAC corpus, all Producer Envelope vectors,\nand Go/Python authored, received, WHO, DID, and composition fixtures.\n\n## Cross-record references\n\n`Input.references` accepts `{ type, digestAlg, digest, citationPurpose?,\nlogCoordinates? }`. Use the registered type `agent-action-capsule` with\n`SHA-256` and its Capsule ID for an AAC citation. `acted_on` and `responds_to`\nare seeded citation purposes; unknown purposes remain informational. References\ncannot duplicate the same Capsule's chain parent. Foreign digest representations\nbelong to the referenced CPB type and are not restricted to AAC's hex encoding.\n\n`logCoordinates` carries the wire members `log_id`, `leaf_index` and\n`inclusion_proof` together as opaque claims. Class 1 does not authenticate the\nproof or resolve external targets. Undefined references are omitted; `[]` is\npreserved, including its effect on the format-4 Capsule ID.\n\n```ts\nimport { build, verifyCapsule } from \"@action-state-group/capsule-emit\";\n\nconst common = {\n  actionType: \"fyi\" as const,\n  operator: \"example-org\",\n  developer: \"example-agent@v1\",\n  timestamp: \"2026-09-02T12:00:00Z\",\n};\nconst request = build({ ...common, actionId: \"request/1\" });\nconst response = build({\n  ...common,\n  actionId: \"response/1\",\n  references: [\n    {\n      type: \"agent-action-capsule\",\n      digestAlg: \"SHA-256\",\n      digest: request.capsuleId,\n      citationPurpose: \"responds_to\",\n    },\n  ],\n});\nverifyCapsule(response.json);\nconsole.log(request.capsuleId, response.capsuleId);\n```\n\nReferences enter through `Input`, including `seal({ capsule: { ... } })`.\nThere is no separate reference builder or closed purpose enum.\n\n## Artifact storage\n\nThe optional `./artifact` subpath persists exact sealed Capsules, Producer\nEnvelopes, and business originals. The root entry point stays storage-free:\n`better-sqlite3` and `mysql2` are optional peer dependencies, and an application\ninstalls only the backend it imports. TypeScript users of the SQLite backend\nalso install `@types/better-sqlite3` (an optional peer dependency), because\n`better-sqlite3` ships no bundled type declarations; `mysql2` bundles its own. Reads verify Capsule identity, the\nProducer Envelope against caller-owned trusted keys, the storage inventory, and\nevery retained bound original before returning. Records are immutable,\nbyte-identical retries are idempotent, and a divergent write for the same\nCapsule ID throws an `ArtifactError` with `code: \"conflict\"`.\n\n```ts\nimport Database from \"better-sqlite3\";\nimport { PAYLOAD_DIGEST } from \"@action-state-group/capsule-emit/artifact\";\nimport { SqliteArtifactStore } from \"@action-state-group/capsule-emit/artifact/sqlite\";\n\nconst db = new Database(\"artifacts.db\");\ndb.pragma(\"foreign_keys = ON\");\nconst store = new SqliteArtifactStore(db, \"my-namespace\", [trustedPublicKey]);\nawait store.init(); // provision v1 tables once during deployment\n\nawait store.put({\n  capsuleId: sealed.capsuleId,\n  capsule: sealed.payload,\n  producerEnvelope: sealed.envelope,\n  artifacts: [\n    {\n      name: \"payload\",\n      binding: PAYLOAD_DIGEST,\n      content: payloadBytes,\n      state: \"present\",\n    },\n  ],\n});\nconst record = await store.get(sealed.capsuleId);\n```\n\n`./artifact/mysql` exposes the same API over a `mysql2` pool. The inventory\nchecksum is byte-compatible with `capsule-emit-go`, so a Go writer and a\nTypeScript reader interoperate over a shared database. See\n[DESIGN.md](DESIGN.md#artifact-storage) for the full contract.\n\n## Development\n\nThe embedded provisional registry snapshot mirrors\n`agent-action-capsule/python/agent_action_capsule/data/cpb_provisional.json`.\nKnown provisional values change informational diagnostics without increasing\nassurance. Refresh the snapshot from that source; the test suite checks its\nprovenance and content. Raw JCS still normalizes `-0` to `0`; Python's optional\nstrict input verification tier is a separate acceptance policy.\n\nShared reference and vocabulary vectors live in the AAC source checkout under\n`go/verify/testdata/`. The producer-to-CLL check is maintained in\n`capsule-emit-go/scripts/check-producer-cll-interop.sh` and runs in both emitters'\nCI. It covers in-memory append/checkpoint interoperability without witness I/O.\n\n```sh\nnpm install\nnpm run check\nnpm run build\n```\n\nInterop tests expect `agent-action-capsule` and `capsule-emit-go` as sibling\ncheckouts. Override those paths with `AAC_ROOT` and `CAPSULE_EMIT_GO_ROOT`.\n\n## Release\n\nReleases are published from `main` with the manual\n[Publish npm package](https://github.com/action-state-group/capsule-emit-ts/actions/workflows/publish.yml)\nGitHub Action:\n\n1. Update `version` in `package.json` and `package-lock.json`, commit the change,\n   and wait for `main` CI to pass.\n2. In GitHub, open the workflow, choose **Run workflow**, and select `main`.\n3. Verify the workflow published `@action-state-group/capsule-emit` and created\n   the `v<version>` GitHub release and tag on the published commit.\n\nThe npm package must have a GitHub Actions trusted publisher configured for\nthe `action-state-group/capsule-emit-ts` repository and\n`.github/workflows/publish.yml`. No long-lived npm token is required. Re-running\nthe workflow is safe: it skips an existing npm version and verifies that its\nGit tag points to the `gitHead` recorded by npm.\n\nIf npm contains the version but its tag is missing after this workflow has\nchanged, GitHub may reject recovery with the workflow's `GITHUB_TOKEN`. A\nmaintainer with `workflow` scope must create the tag at the npm `gitHead`, then\nrerun the workflow to verify the tag and create any missing GitHub release:\n\n```sh\nversion=0.1.2\ngit_head=$(npm view \"@action-state-group/capsule-emit@$version\" gitHead)\ngit fetch origin --tags\ngit tag -a \"v$version\" \"$git_head\" -m \"Release v$version\"\ngit push origin \"refs/tags/v$version\"\n```\n\n## License\n\nApache-2.0. The upstream Agent Action Capsule dependency is BSD-3-Clause.\n","readmeFilename":"README.md"}