{"_id":"@absolutejs/handoff","name":"@absolutejs/handoff","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@absolutejs/handoff","version":"0.1.0","description":"Correlation, evidence, reconciliation, and visibility primitives for work handed to external systems.","type":"module","license":"MIT","author":{"name":"Alex Kahn"},"repository":{"type":"git","url":"git+https://github.com/absolutejs/handoff.git"},"homepage":"https://github.com/absolutejs/handoff","bugs":{"url":"https://github.com/absolutejs/handoff/issues"},"publishConfig":{"access":"public"},"main":"./dist/index.js","types":"./dist/index.d.ts","absolutejs":{"manifestContract":2},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./manifest":{"types":"./dist/manifest.d.ts","import":"./dist/manifest.js","default":"./dist/manifest.js"},"./manifest.json":"./dist/manifest.json"},"scripts":{"format":"prettier --write \"./**/*.{ts,json,md}\"","typecheck":"tsc --noEmit","test":"bun test","build":"rm -rf dist && bun build src/index.ts src/manifest.ts --outdir dist --target=bun --external @absolutejs/manifest --external @sinclair/typebox && tsc -p tsconfig.build.json && absolute-manifest emit","verify-package":"absolute-manifest verify-package","check:package":"bun run format && bun run typecheck && bun run test && bun run verify-package && bun run build && bun run verify-package --artifacts","release":"bun run check:package && npm publish --access public"},"dependencies":{"@absolutejs/manifest":"0.7.2","@sinclair/typebox":"0.34.52"},"devDependencies":{"@types/bun":"1.3.14","prettier":"3.8.1","typescript":"5.9.3"},"_id":"@absolutejs/handoff@0.1.0","gitHead":"8a4a05696735b8eeaf2f1fdfd7dd4737dd29a701","_nodeVersion":"22.14.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-P9Wr2oyYBcj7mriCV4h9zRlLGijee/7DW8USVkl/m4ovql7zpITy547jy6j8+HC5v5Ocs+TVcMYmrROEEBupNg==","shasum":"39379aab3fefc1b66f84ea01a91ed30924c3d18c","tarball":"https://registry.npmjs.org/@absolutejs/handoff/-/handoff-0.1.0.tgz","fileCount":8,"unpackedSize":15708,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFm1HmS3s1UwslNSX6VbL32vDF7vfQOha/WfawC/GpadAiEAr1KJNaYnd7pvfO+XsXKh73vMwUUlEv0USj2iL/agNo0="}]},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"directories":{},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/handoff_0.1.0_1785371616311_0.3737518515677938"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-30T00:33:36.136Z","0.1.0":"2026-07-30T00:33:36.445Z","modified":"2026-07-30T00:33:36.720Z"},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"description":"Correlation, evidence, reconciliation, and visibility primitives for work handed to external systems.","homepage":"https://github.com/absolutejs/handoff","repository":{"type":"git","url":"git+https://github.com/absolutejs/handoff.git"},"author":{"name":"Alex Kahn"},"bugs":{"url":"https://github.com/absolutejs/handoff/issues"},"license":"MIT","readme":"# `@absolutejs/handoff`\n\nStorage-neutral correlation and evidence for work that leaves your application.\n\nA handoff starts in your code, continues in an external system, and may return\nthrough a callback, reconciliation, or a customer report. `@absolutejs/handoff`\nkeeps those observations joined without pretending your application can inspect\nan external page directly.\n\n## Install\n\n```sh\nbun add @absolutejs/handoff\n```\n\n## Correlation\n\n```ts\nimport {\n  handoffCorrelationFrom,\n  withHandoffCorrelation,\n} from \"@absolutejs/handoff\";\n\nconst metadata = withHandoffCorrelation(\n  { campaign: \"summer\" },\n  crypto.randomUUID(),\n);\n\n// Services with fixed metadata slots can name the slot explicitly.\nconst gatewayFields = withHandoffCorrelation(\n  { field_1: \"campaign\" },\n  crypto.randomUUID(),\n  \"field_20\",\n);\n\nconst correlationId = handoffCorrelationFrom(gatewayFields, \"field_20\");\n```\n\n## Evidence and reconciliation\n\n```ts\nimport { summarizeHandoff } from \"@absolutejs/handoff\";\n\nconst summary = summarizeHandoff([\n  {\n    at: Date.now(),\n    correlationId: \"invoice-123\",\n    operation: \"invoice_payment\",\n    outcome: \"succeeded\",\n    service: \"gateway\",\n    source: \"callback\",\n  },\n  {\n    at: Date.now() + 1,\n    correlationId: \"invoice-123\",\n    message: \"The hosted page displayed an error\",\n    operation: \"invoice_payment\",\n    outcome: \"failed\",\n    service: \"gateway\",\n    source: \"external_surface_report\",\n  },\n]);\n\n// The callback remains authoritative while the customer-visible contradiction\n// remains actionable.\nconsole.log(summary.status); // \"succeeded\"\nconsole.log(summary.contradiction); // true\n```\n\n`external_api`, `callback`, and `reconciliation` evidence is authoritative.\n`external_surface_report` evidence records what a customer or operator saw\nwithout silently overriding external-system truth.\n\n## Recording\n\n`createHandoffRecorder()` accepts optional storage and observer contracts.\nRecording returns per-sink delivery state instead of throwing when an\nobservability sink fails, so visibility cannot break the business operation.\nThe recorder also exposes low-cardinality counters by source and outcome.\n\nMessages and references redact payment-number-shaped text and bearer\ncredentials. Applications must still keep raw callbacks, credentials, payment\ndetails, and customer data in their own protected stores.\n\n## Package boundaries\n\n`@absolutejs/handoff` owns the shared protocol. Domain packages keep their own\nmeaning and adapters:\n\n- Commerce decides what paid, declined, and settled mean.\n- Dispatch decides what sent, bounced, and complained mean.\n- CRM decides what synchronized or conflicted means.\n- Voice and Meeting decide what joined, recorded, and transcribed mean.\n\nThose packages translate external-system evidence into this neutral vocabulary.\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-a606dabab021b759c6186c78ff93f833"}