{"_id":"@bedrockgovernance/attest","name":"@bedrockgovernance/attest","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@bedrockgovernance/attest","version":"0.1.0","description":"Capture what an AI model was asked and what it produced, at the moment of generation, and record it as an immutable entry in the Bedrock advice ledger.","license":"Apache-2.0","author":{"name":"Luke Bettridge"},"homepage":"https://bedrockgovernance.com/docs/concepts/attest","repository":{"type":"git","url":"git+https://github.com/bedrockgovernance/attest.git"},"bugs":{"url":"https://github.com/bedrockgovernance/attest/issues"},"keywords":["bedrock","attestation","ledger","audit","immutable","ai","llm","provenance","consumer-duty","fca","compliance","ai-sdk"],"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./ai-sdk":{"types":"./dist/ai-sdk.d.ts","default":"./dist/ai-sdk.js"}},"engines":{"node":">=18"},"scripts":{"build":"tsc","typecheck":"tsc --noEmit","test":"vitest run --coverage","test:watch":"vitest","lint":"eslint --ext .ts src/","prepare":"tsc"},"dependencies":{},"peerDependencies":{"@ai-sdk/provider":">=2","ai":">=5"},"peerDependenciesMeta":{"@ai-sdk/provider":{"optional":true},"ai":{"optional":true}},"devDependencies":{"@ai-sdk/provider":"^3.0.0","@types/node":"^20.0.0","@typescript-eslint/eslint-plugin":"^7.0.0","@typescript-eslint/parser":"^7.0.0","@vitest/coverage-v8":"^1.2.0","ai":"^6.0.0","eslint":"^8.56.0","typescript":"^5.3.0","vitest":"^1.2.0"},"gitHead":"2d80f15e30eefe4f8e5490d87f42d8e1a3f25b4e","_id":"@bedrockgovernance/attest@0.1.0","_nodeVersion":"25.8.1","_npmVersion":"11.12.1","dist":{"integrity":"sha512-y+S3YXiFgvLeMeFSPkWtcoksx5KXxdunmvM8YtihW888RTPm4aaHRincb3AgSMFT091RZEtTAG3/r7Eqikq0yg==","shasum":"3cd0e42d3e06bb1843409618914b6ee8b8a3aa3a","tarball":"https://registry.npmjs.org/@bedrockgovernance/attest/-/attest-0.1.0.tgz","fileCount":29,"unpackedSize":61562,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIC1M2omn0ldNBqvHuZ2Uq3agtz/LOI+SYhhI0/Dak9sQAiBp1kMA+G9P64ZFKWuZEAjX5Xa0EENacadpsnbWFH3aZA=="}]},"_npmUser":{"name":"lukebettridge","email":"luke.bettridge@outlook.com"},"directories":{},"maintainers":[{"name":"lukebettridge","email":"luke.bettridge@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/attest_0.1.0_1783938522648_0.10441580606707723"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-13T10:28:42.489Z","0.1.0":"2026-07-13T10:28:42.799Z","modified":"2026-07-13T10:28:43.022Z"},"maintainers":[{"name":"lukebettridge","email":"luke.bettridge@outlook.com"}],"description":"Capture what an AI model was asked and what it produced, at the moment of generation, and record it as an immutable entry in the Bedrock advice ledger.","homepage":"https://bedrockgovernance.com/docs/concepts/attest","keywords":["bedrock","attestation","ledger","audit","immutable","ai","llm","provenance","consumer-duty","fca","compliance","ai-sdk"],"repository":{"type":"git","url":"git+https://github.com/bedrockgovernance/attest.git"},"author":{"name":"Luke Bettridge"},"bugs":{"url":"https://github.com/bedrockgovernance/attest/issues"},"license":"Apache-2.0","readme":"# @bedrockgovernance/attest\n\n> Record what an AI model was asked and what it produced, at the moment\n> of generation, as an immutable entry in the\n> [Bedrock](https://bedrockgovernance.com) advice ledger.\n\n`@bedrockgovernance/attest` captures a **generation**, the event of a\nmodel producing text that helps shape a piece of financial advice, and\nnotarises it into the firm's ledger. Where CRM integrations ingest the\n*finished* advice document after it exists, attestation captures the\nmodel call at its source: the system prompt, the conversation, the\nretrieved context, the guardrails, and the output, hashed and chained\nat the instant they are used.\n\nThe client has no runtime dependencies. The optional AI SDK middleware\nlives in a separate entry point (`@bedrockgovernance/attest/ai-sdk`), so\nimporting the core never pulls in the AI SDK.\n\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\n## Install\n\n```sh\nnpm install @bedrockgovernance/attest\n```\n\n## Quickstart\n\n### Attest explicitly\n\nHand Bedrock the generation bundle yourself:\n\n```ts\nimport { Bedrock } from '@bedrockgovernance/attest';\n\nconst bedrock = new Bedrock({ apiKey: process.env.BEDROCK_API_KEY! });\n\nconst { generationId } = await bedrock.attest({\n  // A stable id you already hold that scopes this drafting\n  // conversation, e.g. a chat or thread id. Reuse it on every\n  // generation in the same conversation so they group together.\n  correlationId: chatId,\n  clientReference: 'CLI-41269355',\n  adviser: { name: 'Jane Smith', fcaRef: 'JXS01234' },\n  model: { provider: 'anthropic', name: 'claude-opus-4-8' },\n  instructions,\n  input,\n  retrievedContext,\n  output: { content: draft, finishReason: 'stop' },\n});\n```\n\nOnly `correlationId`, `model`, `input` and `output` are required.\n`input` is what the model saw for this call: a single prompt string, or\nthe role-tagged messages sent. `instructions` (the system prompt) is\noptional but worth including whenever your call has one. Everything else\nis optional too, included when your pipeline has it.\n\n### Attest automatically with the AI SDK\n\nWrap your model once and every `generateText` / `streamText` call is\nnotarised, with no change to your generation code:\n\n```ts\nimport { wrapLanguageModel } from 'ai';\nimport { anthropic } from '@ai-sdk/anthropic';\nimport { attestMiddleware } from '@bedrockgovernance/attest/ai-sdk';\n\nconst model = wrapLanguageModel({\n  model: anthropic('claude-opus-4-8'),\n  middleware: attestMiddleware({ bedrock, correlationId: chatId, adviser }),\n});\n```\n\nThe middleware posts the attestation in the background after the model\nresponds, so it never adds latency to the call. Attestation failures\nare surfaced through an optional `onError` callback and never affect the\nmodel result. When `onError` is omitted the middleware will log a console\nwarning by default so background attestation failures are discoverable\nunless you handle them explicitly.\n\n## Grouping generations\n\nA single piece of advice is rarely one model call, and the calls are\noften exploratory chat turns rather than drafts of the final document.\n`correlationId` is how you group them: pass a stable id you already own\n(a chat, thread, or case id) on every `attest()` call that belongs to\nthe same conversation. It does not need to be globally unique, only\nstable across the conversation. Bedrock stitches conversations into a\npiece of advice on the platform side, so the id does not have to survive\nto review time.\n\n## API\n\n- `new Bedrock({ apiKey, baseUrl?, fetch? })` — construct a client. The\n  `apiKey` is sent as the `x-bedrock-key` header. `baseUrl` defaults to\n  the production API; `fetch` defaults to the global `fetch` (Node 18+).\n- `bedrock.attest(generation)` — validate the bundle and record it via\n  `POST /v1/generations`. Resolves to `{ generationId, correlationId,\n  outputHash, recordedAt }`.\n- `attestMiddleware(options)` (from `@bedrockgovernance/attest/ai-sdk`) —\n  an AI SDK `LanguageModelV2Middleware` that attests every call.\n- `validateGeneration(generation)` — the same local validation `attest`\n  runs, exported for reuse.\n\n**Errors:** `BedrockValidationError` (invalid bundle or config, thrown\nbefore any request), `BedrockApiError` (non-2xx response, carrying\n`status`, `code` and `requestId`), and their base `BedrockError`.\n\n## License\n\n[Apache 2.0](./LICENSE). See [`SECURITY.md`](./SECURITY.md) for\nvulnerability reporting.\n","readmeFilename":"README.md","_rev":"1-d4bd617c46376d7a513aaed474983930"}