{"_id":"@atlasent/contract-parity","_rev":"2-094d3de51403d009653fd2c3307a5c95","name":"@atlasent/contract-parity","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.2":{"name":"@atlasent/contract-parity","version":"0.1.2","keywords":["atlasent","policy","parity","contract","conformance"],"license":"MIT","_id":"@atlasent/contract-parity@0.1.2","maintainers":[{"name":"wacas-as","email":"waqas@atlasent.io"},{"name":"bettyc","email":"betty@pegasus.ac"}],"homepage":"https://github.com/AtlaSent-Systems-Inc/atlasent#readme","bugs":{"url":"https://github.com/AtlaSent-Systems-Inc/atlasent/issues"},"dist":{"shasum":"b7482725befb071aceac1880c29ec264f3a7cfef","tarball":"https://registry.npmjs.org/@atlasent/contract-parity/-/contract-parity-0.1.2.tgz","fileCount":8,"integrity":"sha512-DCZnJNjoasnAcF0lfAmIgohYg454RprFmtAIxdLnvnx129z+W2m4D9+BE23IpGUK8OE2jWwjRl1lqduxc8nOag==","signatures":[{"sig":"MEQCIHbCxnfXNZ1EyB68EPhaiRZDhDp+os5smvZnMGBtKETCAiBjg7iILorAEnQCyliNnVuXod2xJf3ZTQvN53ZZ3t8rzw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":17492},"main":"./src/index.ts","type":"module","types":"./src/index.ts","module":"./src/index.ts","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts","default":"./src/index.ts"}},"gitHead":"89ac9fa56fe7dcdca4a94896979e7573b8358a47","scripts":{"generate":"node scripts/generate-vectors.mjs","check-pack":"bash scripts/check-pack.sh"},"_npmUser":{"name":"bettyc","email":"betty@pegasus.ac"},"repository":{"url":"git+https://github.com/AtlaSent-Systems-Inc/atlasent.git","type":"git","directory":"packages/contract-parity"},"_npmVersion":"10.8.2","description":"Canonical cross-runtime policy parity vectors + reference runner. Every AtlaSent runtime that evaluates policy (V1 wire, control-plane, SDK replay) MUST run this suite in CI. Vendoring out is forbidden — import this package instead so the contract stays s","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/contract-parity_0.1.2_1779255706202_0.5662877980680654","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-05-20T05:41:46.038Z","modified":"2026-06-03T08:00:03.639Z","0.1.2":"2026-05-20T05:41:46.344Z"},"bugs":{"url":"https://github.com/AtlaSent-Systems-Inc/atlasent/issues"},"license":"MIT","homepage":"https://github.com/AtlaSent-Systems-Inc/atlasent#readme","keywords":["atlasent","policy","parity","contract","conformance"],"repository":{"url":"git+https://github.com/AtlaSent-Systems-Inc/atlasent.git","type":"git","directory":"packages/contract-parity"},"description":"Canonical cross-runtime policy parity vectors + reference runner. Every AtlaSent runtime that evaluates policy (V1 wire, control-plane, SDK replay) MUST run this suite in CI. Vendoring out is forbidden — import this package instead so the contract stays s","maintainers":[{"email":"betty@pegasus.ac","name":"bettyc"}],"readme":"# @atlasent/contract-parity\n\nCanonical cross-runtime policy parity vectors + reference runner for the\nAtlaSent platform.\n\n**Related gate:** [`V1_GATES.md` § G1](../../V1_GATES.md#g1--policy-engine-parity-contract-between-runtimes)\n**Prose spec:** [`POLICY_PARITY_CONTRACT.md`](../../POLICY_PARITY_CONTRACT.md)\n**Vector source:** [`contract/parity/vectors/`](../../contract/parity/vectors)\n\nEvery AtlaSent runtime that evaluates policy (V1 wire in `atlasent-api`,\ncontrol-plane in `atlasent-control-plane`, SDK offline replay in\n`atlasent-sdk`) MUST run this suite in CI. The vectors here are the single\nsource of truth — vendoring out is forbidden, import this package instead\nso the contract stays single-sourced.\n\n## Install\n\n```bash\nnpm install --save-dev @atlasent/contract-parity\n```\n\n## Usage\n\nAdapt your runtime's evaluate function to the `EvaluateAdapter` shape,\nthen call `runParity`:\n\n```ts\nimport { runParity } from \"@atlasent/contract-parity\";\nimport { StubPolicyEngine } from \"./policyEngine.js\";\n\nconst engine = new StubPolicyEngine();\n\nconst { passed, failed, total, results } = await runParity({\n  engine: \"stub\",\n  evaluate: (input) => engine.evaluate(input),\n});\n\nif (failed > 0) {\n  for (const r of results.filter((r) => !r.ok)) {\n    console.error(`✗ ${r.name}`, r);\n  }\n  process.exit(1);\n}\n```\n\nOr inside vitest:\n\n```ts\nimport { describe, expect, it } from \"vitest\";\nimport { vectorsForEngine } from \"@atlasent/contract-parity\";\nimport { StubPolicyEngine } from \"./policyEngine.js\";\n\nconst engine = new StubPolicyEngine();\n\ndescribe(\"Policy parity — stub vectors\", () => {\n  for (const v of vectorsForEngine(\"stub\")) {\n    it(v.name, async () => {\n      const outcome = await engine.evaluate(v.input);\n      expect(outcome.decision).toBe(v.expected.decision);\n      const reasonsText = (outcome.reasons ?? []).join(\"\\n\");\n      for (const needle of v.expected.reasons_includes ?? []) {\n        expect(reasonsText).toContain(needle);\n      }\n    });\n  }\n});\n```\n\n## Exports\n\n- `VECTORS` — the full array of `ParityVector` objects.\n- `vectorsForEngine(engine: \"stub\" | \"opa\"): ParityVector[]` — vectors\n  whose `engine` matches, including `any`.\n- `runParity({ engine, evaluate, log? })` — reference runner, returns\n  `{ passed, failed, total, results }`. Asserts `decision` matches and\n  every `reasons_includes` substring appears in the runtime's actual\n  `reasons[]`.\n- `ParityVector`, `EvaluateAdapter`, `RunParityResult` types.\n\n## How vectors stay in sync with the canonical JSON\n\nVectors live canonically at [`contract/parity/vectors/*.json`](../../contract/parity/vectors).\n`scripts/generate-vectors.mjs` runs at `prebuild` and writes\n`src/vectors.generated.ts` from the JSON sources. The generated file is\ncommitted so reviewers can diff vector changes without running the build,\nand so the published package contains the data even if a downstream\nbuild forgets the prebuild step.\n\nIf you change vectors:\n\n1. Edit `contract/parity/vectors/*.json` (the canonical source).\n2. Run `pnpm --filter @atlasent/contract-parity generate` (or just\n   `pnpm --filter @atlasent/contract-parity build` which prebuilds).\n3. Commit both the JSON and the regenerated `vectors.generated.ts`.\n4. Bump the package's semver appropriately:\n   - **patch** — added a vector (contract becomes stricter, additive).\n   - **minor** — added a new exported helper or vector with new shape (back-compat).\n   - **major** — removed/renamed a vector or changed schema (breaking).\n\n## Vector schema\n\nSee [`contract/parity/schema.json`](../../contract/parity/schema.json) for\nthe JSON Schema (draft-07) the source files validate against. Required\nfields: `name`, `engine`, `input.{action, resource.type, subject}`,\n`expected.decision`. Optional: `expected.reasons_includes`,\n`expected.permit`.\n\n## Release process\n\nPublishing is automated via\n[`.github/workflows/contract-parity-release.yml`](../../.github/workflows/contract-parity-release.yml)\non a tag of the form `contract-parity-v<semver>`:\n\n```bash\n# from a clean main with the version bumped in package.json\ngit tag contract-parity-v0.1.0\ngit push origin contract-parity-v0.1.0\n```\n\nThe workflow:\n\n1. Regenerates `src/vectors.generated.ts` from the canonical JSON.\n2. Builds `dist/` (cjs + esm + dts) via `tsup` (pulled in via `npx -y`\n   so the workspace lockfile doesn't need a dedicated devDep).\n3. Verifies all three dist artifacts exist.\n4. Packs the tarball and uploads as a workflow artifact (always).\n5. Publishes to npm with provenance attestation (only on tag push or\n   workflow_dispatch with `dry_run=false`).\n\n`workflow_dispatch` defaults to `dry_run: true` so manual runs only pack,\nnever publish. Set `dry_run: false` explicitly to publish without a tag.\n\nRequires the repository secret `NPM_TOKEN` (publish rights to the\n`@atlasent` scope).\n\n## Consumer migration status\n\nv0.1.0 of this package supersedes the **inlined** vector copies in:\n\n- `atlasent-control-plane/api/src/lib/policyEngine.parity.test.ts`\n- `atlasent-api/supabase/functions/v1-evaluate/parity.test.ts`\n\nBoth migrations are tracked under\n[`V1_GATES.md` G1](../../V1_GATES.md#g1--policy-engine-parity-contract-between-runtimes)\n\"Deferred follow-ups\" and will land in two follow-up PRs once v0.1.0 is\npublished to npm.\n","readmeFilename":"README.md"}