@attestry/sdk 0.6.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.
Files changed (99) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +1269 -0
  3. package/dist/client.d.ts +58 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +74 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/constants.d.ts +7 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +43 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/errors.d.ts +16 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +41 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/index.d.ts +17 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +20 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lines-parser.d.ts +50 -0
  20. package/dist/lines-parser.d.ts.map +1 -0
  21. package/dist/lines-parser.js +211 -0
  22. package/dist/lines-parser.js.map +1 -0
  23. package/dist/ndjson-parser.d.ts +57 -0
  24. package/dist/ndjson-parser.d.ts.map +1 -0
  25. package/dist/ndjson-parser.js +245 -0
  26. package/dist/ndjson-parser.js.map +1 -0
  27. package/dist/resources/abac-policies.d.ts +1034 -0
  28. package/dist/resources/abac-policies.d.ts.map +1 -0
  29. package/dist/resources/abac-policies.js +1519 -0
  30. package/dist/resources/abac-policies.js.map +1 -0
  31. package/dist/resources/audit-log.d.ts +588 -0
  32. package/dist/resources/audit-log.d.ts.map +1 -0
  33. package/dist/resources/audit-log.js +629 -0
  34. package/dist/resources/audit-log.js.map +1 -0
  35. package/dist/resources/batch.d.ts +845 -0
  36. package/dist/resources/batch.d.ts.map +1 -0
  37. package/dist/resources/batch.js +1074 -0
  38. package/dist/resources/batch.js.map +1 -0
  39. package/dist/resources/chat.d.ts +151 -0
  40. package/dist/resources/chat.d.ts.map +1 -0
  41. package/dist/resources/chat.js +124 -0
  42. package/dist/resources/chat.js.map +1 -0
  43. package/dist/resources/check.d.ts +348 -0
  44. package/dist/resources/check.d.ts.map +1 -0
  45. package/dist/resources/check.js +543 -0
  46. package/dist/resources/check.js.map +1 -0
  47. package/dist/resources/compliance-check.d.ts +330 -0
  48. package/dist/resources/compliance-check.d.ts.map +1 -0
  49. package/dist/resources/compliance-check.js +402 -0
  50. package/dist/resources/compliance-check.js.map +1 -0
  51. package/dist/resources/decisions.d.ts +1208 -0
  52. package/dist/resources/decisions.d.ts.map +1 -0
  53. package/dist/resources/decisions.js +1362 -0
  54. package/dist/resources/decisions.js.map +1 -0
  55. package/dist/resources/evidence-pack.d.ts +1080 -0
  56. package/dist/resources/evidence-pack.d.ts.map +1 -0
  57. package/dist/resources/evidence-pack.js +1789 -0
  58. package/dist/resources/evidence-pack.js.map +1 -0
  59. package/dist/resources/gate.d.ts +613 -0
  60. package/dist/resources/gate.d.ts.map +1 -0
  61. package/dist/resources/gate.js +737 -0
  62. package/dist/resources/gate.js.map +1 -0
  63. package/dist/resources/incidents.d.ts +136 -0
  64. package/dist/resources/incidents.d.ts.map +1 -0
  65. package/dist/resources/incidents.js +229 -0
  66. package/dist/resources/incidents.js.map +1 -0
  67. package/dist/resources/regulatory-changes.d.ts +307 -0
  68. package/dist/resources/regulatory-changes.d.ts.map +1 -0
  69. package/dist/resources/regulatory-changes.js +365 -0
  70. package/dist/resources/regulatory-changes.js.map +1 -0
  71. package/dist/resources/safe-input-read.d.ts +21 -0
  72. package/dist/resources/safe-input-read.d.ts.map +1 -0
  73. package/dist/resources/safe-input-read.js +57 -0
  74. package/dist/resources/safe-input-read.js.map +1 -0
  75. package/dist/resources/ship-gate.d.ts +475 -0
  76. package/dist/resources/ship-gate.d.ts.map +1 -0
  77. package/dist/resources/ship-gate.js +727 -0
  78. package/dist/resources/ship-gate.js.map +1 -0
  79. package/dist/resources/vision.d.ts +540 -0
  80. package/dist/resources/vision.d.ts.map +1 -0
  81. package/dist/resources/vision.js +1036 -0
  82. package/dist/resources/vision.js.map +1 -0
  83. package/dist/retry.d.ts +103 -0
  84. package/dist/retry.d.ts.map +1 -0
  85. package/dist/retry.js +224 -0
  86. package/dist/retry.js.map +1 -0
  87. package/dist/sse-parser.d.ts +64 -0
  88. package/dist/sse-parser.d.ts.map +1 -0
  89. package/dist/sse-parser.js +271 -0
  90. package/dist/sse-parser.js.map +1 -0
  91. package/dist/transport.d.ts +142 -0
  92. package/dist/transport.d.ts.map +1 -0
  93. package/dist/transport.js +455 -0
  94. package/dist/transport.js.map +1 -0
  95. package/dist/types.d.ts +61 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +3 -0
  98. package/dist/types.js.map +1 -0
  99. package/package.json +44 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/resources/check.ts"],"names":[],"mappings":"AAwFA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA2ClD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;;;;;;OAeG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;;;;;OAeG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;;;;;;;;;OAYG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;OASG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,cAAc;IAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAwLG;IACH,GAAG,CACD,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,aAAa,CAAC;CA8N1B"}
@@ -0,0 +1,543 @@
1
+ // ─── Check resource ─────────────────────────────────────────────────────────
2
+ //
3
+ // Wraps the CI/CD compliance-check surface (session 16):
4
+ //
5
+ // - POST /api/v1/check Body: {systemId: <UUID>, frameworks?: string[]}
6
+ //
7
+ // Fourth non-decisions resource on `@attestry/sdk`. Sibling to
8
+ // `IncidentsResource`, `DecisionsResource`, `ChatResource`,
9
+ // `AuditLogResource`, `RegulatoryChangesResource`,
10
+ // `ComplianceCheckResource`. Single public method today (`run`); the
11
+ // resource class exists as the landing pad for future check methods
12
+ // if/when the kernel adds them (resource-class-per-kernel-resource
13
+ // convention, carry-forward invariant #43).
14
+ //
15
+ // Method name `run` rather than `check` — `client.check.check(...)`
16
+ // would be awkward; `run` mirrors the verb pattern of `chat.send`,
17
+ // `decisions.ingest`, `auditLog.export`. User-confirmed at session
18
+ // start.
19
+ //
20
+ // **Multi-permission UNION auth scope**: the kernel route gates on
21
+ // `requireApiKeyWithPermission(request, READ_ASSESSMENTS, READ_SYSTEMS)`
22
+ // which is OR semantics — `permissions.ts:53-55` uses `Array.some()`,
23
+ // NOT `.every()`. A key with EITHER permission (or `ADMIN`, or empty
24
+ // permissions for backwards-compat) succeeds. **HTTP 401** for
25
+ // no/invalid API key; **HTTP 403** for an authenticated key that has
26
+ // NEITHER required permission. Pin BOTH branches separately.
27
+ // Carry-forward invariant #45 (no re-discovery this round — same shape
28
+ // as `complianceCheck.check`).
29
+ //
30
+ // **First SDK route to PRE-VALIDATE every Zod closed-spec rule
31
+ // synchronously**. Other Zod-bodied SDK routes (e.g.,
32
+ // `incidents.create`) pass input through without SDK-side validation,
33
+ // so a 422 from Zod has been a consumer-visible surface there since
34
+ // v0.1. In `check.run` the kernel uses `parseBody(request,
35
+ // checkSchema)` where `checkSchema` is `z.object({systemId:
36
+ // z.string().uuid(), frameworks: z.array(z.string().min(1).max(100))
37
+ // .max(20).optional()})`. The SDK pre-validates EVERY closed-spec
38
+ // rule synchronously (UUID format, string length 1-100, array length
39
+ // cap 20). The SDK's runtime checks always run regardless of
40
+ // TypeScript types — `as any` casts do NOT bypass them. So 422 from
41
+ // this route reaches consumers ONLY via kernel-side rule changes the
42
+ // SDK hasn't synced to. Codifies new invariant candidate #49
43
+ // (pre-validate Zod closed-spec rules SDK-side) and #51 (POST + Zod
44
+ // body — pre-rejected TypeError is the primary path, kernel 422 is
45
+ // the fallback for rules the SDK hasn't synced to).
46
+ //
47
+ // **Asymmetric cross-org error code**: cross-org `systemId` returns
48
+ // **404** (kernel's `and(eq id, eq orgId)` at route.ts:42-51 followed
49
+ // by "System not found" — mirror of `decisions.retrieve` +
50
+ // `complianceCheck.check`'s systemId branch). Partial carry-forward
51
+ // of #47 (no orgName twin here, so only the 404 half applies).
52
+ //
53
+ // **Three silent kernel-side truncations** (faithful courier — SDK
54
+ // does NOT mask):
55
+ // 1. `issues` capped at 20 (`gaps.slice(0, 20)` at route.ts:90).
56
+ // 2. `assessments` capped at 100 (`.limit(100)` at route.ts:62).
57
+ // 3. `attestations` capped at 50 (`.limit(50)` at route.ts:100).
58
+ // Each documented in JSDoc + README + drift-pinned. New invariant
59
+ // candidate #50 (multi-silent-truncation enumeration).
60
+ //
61
+ // **`score` defaults to 0 (NOT null) when no completed assessment
62
+ // exists** (route.ts:84 — `typeof scores?.overallScore === "number"
63
+ // ? scores.overallScore : 0`). Asymmetric with
64
+ // `complianceCheck.check` which used `null` for "no data".
65
+ // Consumers cannot distinguish "scored zero" from "no completed
66
+ // assessment" via `score` alone — must check `lastAssessedAt ===
67
+ // null` to differentiate. Kernel surface gap, documented prominently.
68
+ //
69
+ // **`compliant` threshold stricter than `complianceCheck.check`**:
70
+ // here `compliant === activeAttestations > 0 && overallScore >= 70 &&
71
+ // issues.length === 0` (three conjuncts). Because `score` defaults
72
+ // to 0 (not null), a system with no completed assessment automatically
73
+ // has `compliant: false` here, even when active attestations exist.
74
+ //
75
+ // **NO URIError defense on body fields** — POST body uses
76
+ // `JSON.stringify`, which handles lone UTF-16 surrogates by emitting
77
+ // them as literal `\uDxxx` escapes. The URIError defect class
78
+ // (carry-forward invariant #32) applies only to query-string paths
79
+ // (`encodeURIComponent`); this route has no query string and a fixed
80
+ // path. `assertEncodableQueryString` is NOT invoked here — explicit
81
+ // asymmetry vs `complianceCheck.check` / decisions / incidents /
82
+ // audit-log / regulatory-changes. Documented as D4.
83
+ //
84
+ // Sync JSON request/response: reuses `client._request` and the
85
+ // existing `{success:true, data}` envelope-unwrap (carry-forward
86
+ // invariant #9). NO new SDK primitive needed. Returns
87
+ // `Promise<CheckResponse>`.
88
+ import { AttestryError } from "../errors.js";
89
+ import { readInputField } from "./safe-input-read.js";
90
+ // Module-load snapshot of `Object.hasOwn` — defends against a
91
+ // late-loading hostile/buggy npm dependency that overrides the global
92
+ // (e.g., `Object.hasOwn = () => true`). Without the snapshot, the
93
+ // prototype-pollution defense below uses whatever Object.hasOwn the
94
+ // dependency replaced it with at request time. Snapshotting at module
95
+ // load captures the original implementation BEFORE most consumer
96
+ // code has a chance to monkey-patch.
97
+ //
98
+ // Caveat: this is partial. If the hostile dependency is imported
99
+ // BEFORE @attestry/sdk in the consumer's load graph, the snapshot
100
+ // captures the bad version. Consumers ordering imports
101
+ // SDK-then-untrusted-deps benefit; the reverse ordering does not.
102
+ // Combined with `Object.hasOwn` itself being immune to
103
+ // `obj.hasOwnProperty = ...` overrides (per MDN), this gives a
104
+ // layered defense.
105
+ //
106
+ // Mirror of `complianceCheck.check`'s pattern (hostile review session
107
+ // 15 LOW #2). Generalizes #48 beyond XOR branching: prototype
108
+ // pollution can lie about presence of ANY field where presence affects
109
+ // SDK control flow (here: `systemId` required-vs-missing, `frameworks`
110
+ // provided-vs-not). See build-round audit doc D5.
111
+ const objectHasOwn = Object.hasOwn;
112
+ // UUID format regex — RFC 4122 hyphenated form (8-4-4-4-12 hex,
113
+ // case-insensitive). Matches Zod's `z.string().uuid()` regex
114
+ // effectively (the `\b` word-boundaries in Zod's version are
115
+ // redundant between hex chars and hyphens). Drift-pinned in
116
+ // `sdk-drift.test.ts` spec-diff-round Pin so a kernel-side switch to
117
+ // a different UUID flavor (ULID, KSUID, etc.) fires before consumer
118
+ // regressions.
119
+ //
120
+ // Pre-validation here gives consumers a synchronous `TypeError` for
121
+ // malformed UUID input — faster + clearer than waiting for the
122
+ // kernel's 422 with `fieldErrors`. D2 deviation from
123
+ // `complianceCheck.check` (which deferred to kernel's `isValidUuid`
124
+ // returning 400). Codifies new invariant #49 (Zod-schema-validated
125
+ // input — pre-validate closed-spec rules SDK-side).
126
+ const UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
127
+ /**
128
+ * `check` resource — sibling to `IncidentsResource`,
129
+ * `DecisionsResource`, `ChatResource`, `AuditLogResource`,
130
+ * `RegulatoryChangesResource`, `ComplianceCheckResource`. Today
131
+ * wraps a single endpoint (`run`); the class is the landing pad for
132
+ * future check methods if the kernel adds them
133
+ * (resource-class-per-kernel-resource convention, invariant #43).
134
+ */
135
+ export class CheckResource {
136
+ client;
137
+ constructor(client) {
138
+ this.client = client;
139
+ }
140
+ /**
141
+ * Run a CI/CD compliance check for a single system. Returns a flat
142
+ * 6-field summary: `{compliant, score, issues, activeAttestations,
143
+ * lastAssessedAt, checkedAt}`. Sync JSON request/response — no
144
+ * pagination, no streaming.
145
+ *
146
+ * **Multi-permission UNION auth scope**: kernel uses
147
+ * `requireApiKeyWithPermission(req, READ_ASSESSMENTS, READ_SYSTEMS)`
148
+ * which is OR semantics (`Array.some()` at
149
+ * `permissions.ts:53-55`). A key with EITHER permission (or
150
+ * `ADMIN`, or null/empty permissions for backwards-compat)
151
+ * succeeds. **HTTP 401** for no/invalid API key, **HTTP 403** for
152
+ * an authenticated key that has NEITHER required permission. Pin
153
+ * BOTH branches separately. Carry-forward invariant #45 (same
154
+ * shape as `complianceCheck.check`).
155
+ *
156
+ * **Asymmetric cross-org error code** (carry-forward #47, partial):
157
+ * cross-org `systemId` returns **404** — the kernel's
158
+ * `and(eq id, eq orgId)` at route.ts:42-51 collapses
159
+ * cross-org to "System not found" (mirror of
160
+ * `decisions.retrieve`). Consumers writing defensive error-handling
161
+ * logic must recognize: a 404 may be "not your org" OR "genuine
162
+ * missing UUID". No 403-via-orgName twin here (no orgName input
163
+ * mode).
164
+ *
165
+ * **THREE silent kernel-side truncations** (faithful courier;
166
+ * documented as kernel surface gaps — JSDoc + README + drift
167
+ * pinned). New invariant candidate #50:
168
+ * 1. `issues` — `.slice(0, 20)` at route.ts:90. If the latest
169
+ * completed assessment has >20 gaps, the 21st+ are invisible.
170
+ * 2. `assessments` row-population — `.limit(100)` at route.ts:62.
171
+ * If the system has >100 assessments, the kernel's JS-side
172
+ * `.sort()` operates on the first 100 only; the "latest
173
+ * completed" may be missed.
174
+ * 3. `attestations` row-population — `.limit(50)` at
175
+ * route.ts:100. If the system has >50 attestation rows,
176
+ * `activeAttestations` may be undercounted.
177
+ *
178
+ * **`score` defaults to 0 (NOT null) — kernel surface gap**:
179
+ * route.ts:84 — `typeof scores?.overallScore === "number" ?
180
+ * scores.overallScore : 0`. Consumers MUST check `lastAssessedAt
181
+ * === null` to distinguish "no completed assessment yet" from
182
+ * "scored zero / fails compliance". Asymmetric with
183
+ * `complianceCheck.check`'s null-on-no-data.
184
+ *
185
+ * **`frameworks` filter is OR-overlap, NOT AND-all-required** —
186
+ * route.ts:67-71 uses `aFrameworks.some((fw) =>
187
+ * body.frameworks!.some(...))`. An assessment matches if its
188
+ * `frameworks` array intersects the filter (at least one in
189
+ * common), not if it covers ALL of them. Consumers wanting AND
190
+ * semantics must filter post-hoc.
191
+ *
192
+ * Errors — ordered by kernel firing precedence (rate-limit → auth
193
+ * → Zod body validation → DB lookup → internal). A request with
194
+ * multiple problems surfaces ONLY the highest-precedence one. For
195
+ * example: a request with bad auth AND a malformed body surfaces
196
+ * 401, not 422; a request with valid auth + bad body AND a cross-
197
+ * org systemId surfaces 422, not 404.
198
+ * - `AttestryAPIError` (status 429) — rate limit FIRES FIRST
199
+ * (auto-retried by default — invariant #18; per-IP rate-limit
200
+ * key `v1-check:${ip}`).
201
+ * - `AttestryAPIError` (status 401) — no API key OR invalid key.
202
+ * Fires AFTER rate-limit but BEFORE input validation.
203
+ * - `AttestryAPIError` (status 403) — authenticated key has
204
+ * NEITHER `READ_ASSESSMENTS` nor `READ_SYSTEMS` (the
205
+ * permission-check branch). Single test case — the union-auth
206
+ * pattern collapses three intuition-suggesting cases to one.
207
+ * - `AttestryAPIError` (status 422) — Zod schema rejection
208
+ * (kernel's `BodyParseError` surface — `parseBody(request,
209
+ * checkSchema)` failed). **Fires BEFORE the systemId/cross-
210
+ * org 404 lookup**, so a request with bad UUID format AND
211
+ * cross-org-correct UUID surfaces 422 (the kernel's Zod
212
+ * `.uuid()` reject), not 404. `apiErr.details` carries the
213
+ * full kernel error body verbatim (the transport does NOT
214
+ * strip the `{success:false, ...}` envelope on error responses
215
+ * — only the `{success:true, data}` envelope on success). The
216
+ * wire shape is: `{success: false, error: "Validation failed.",
217
+ * details: Array<{path: string; message: string}>}` — `error`
218
+ * is the literal string
219
+ * "Validation failed." (with trailing period), `details` is
220
+ * an array (NOT a keyed map) of `{path, message}` pairs
221
+ * derived from Zod's `result.error.errors`. Consumers
222
+ * reading field-by-field errors should iterate
223
+ * `apiErr.details.details` (the kernel's `details` array
224
+ * nested under the SDK's parsed-body wrapper). **The SDK
225
+ * pre-validates all closed-spec rules** (UUID format,
226
+ * framework element length 1-100, array length ≤20) AND the
227
+ * runtime checks always run regardless of TypeScript types —
228
+ * `as any` casts do NOT bypass them. So 422 reaches consumers
229
+ * ONLY via kernel rule changes the SDK hasn't synced to (e.g.,
230
+ * a future kernel tightening that adds a new Zod rule the SDK
231
+ * hasn't yet learned to pre-validate). New invariant candidate
232
+ * #51.
233
+ * - `AttestryAPIError` (status 404) — system not found OR
234
+ * cross-org systemId (kernel collapses to "System not found",
235
+ * route.ts:53-54). Fires AFTER Zod validation (422).
236
+ * - `AttestryAPIError` (status 500) — internal kernel error
237
+ * (scrubbed message via `internalErrorResponse`).
238
+ * - `AttestryError` ("request aborted by caller") — caller-
239
+ * supplied `options.signal` fired (pre-aborted or mid-flight).
240
+ * - `AttestryError` (P2 hardening) — kernel response failed
241
+ * SDK-side shape validation (not an object, wrong type on any
242
+ * of the 6 documented fields).
243
+ * - `AttestryAPIError` (P3 hardening) — kernel response had a
244
+ * wrong Content-Type (transport-level guard before body
245
+ * parsing).
246
+ * - `TypeError` (synchronous, no fetch issued) — input failed
247
+ * SDK-side validation (null / array / non-object input,
248
+ * missing systemId, invalid UUID format, frameworks array too
249
+ * long, frameworks element wrong type or length).
250
+ *
251
+ * **Notably ABSENT**:
252
+ * - **No 400** — all input validation is Zod (422). The "missing
253
+ * required field" 400 from compliance-check is irrelevant
254
+ * (single required field; SDK pre-rejects as TypeError).
255
+ * - **No 413** — body size limit not explicit; the kernel's
256
+ * `parseBody` may have one but it isn't documented and the
257
+ * SDK doesn't pin it.
258
+ * - **No 402** — read-only, doesn't count against
259
+ * decisionsPerMonth quota.
260
+ *
261
+ * **SDK-side validation** (synchronous `TypeError`, no fetch
262
+ * issued):
263
+ * - `input` itself: required; must be a non-null, non-array
264
+ * object.
265
+ * - `input.systemId`: required own-property (Object.hasOwn
266
+ * defends against prototype pollution lying about presence —
267
+ * generalization of invariant #48); must be a non-empty
268
+ * string; must match the RFC 4122 hyphenated UUID format
269
+ * (D2 — SDK pre-validates closed-spec rule). No
270
+ * lone-surrogate URIError defense (D4 — POST body uses
271
+ * JSON.stringify, not encodeURIComponent).
272
+ * - `input.frameworks` (when provided): must be an array of
273
+ * ≤20 strings, each of length 1-100. SDK pre-validates each
274
+ * rule (D3 — closed-spec rules mirror Zod). Array is
275
+ * snapshotted via `Array.from` for TOCTOU defense (Proxy /
276
+ * getter inputs can't yield different values across
277
+ * validate-vs-send).
278
+ *
279
+ * **Response-shape validation** (P2 hardening — D6, stricter than
280
+ * `complianceCheck.check`'s 3-field top-level):
281
+ * - Rejects with `AttestryError` if the kernel response isn't a
282
+ * non-null, non-array object.
283
+ * - Rejects if `compliant` isn't a boolean.
284
+ * - Rejects if `score` isn't a number.
285
+ * - Rejects if `issues` isn't an array.
286
+ * - Rejects if `activeAttestations` isn't a number.
287
+ * - Rejects if `lastAssessedAt` isn't a string OR null.
288
+ * - Rejects if `checkedAt` isn't a string.
289
+ * - Each response field read goes through the module-load
290
+ * `objectHasOwn` snapshot (symmetric to the input-side
291
+ * prototype-pollution defense — D5 generalized to the response
292
+ * boundary). A hostile npm dep that pollutes
293
+ * `Object.prototype.<field>` cannot mask a kernel regression
294
+ * where the field is missing — the SDK requires the field to
295
+ * be a kernel-emitted own property.
296
+ * - Per-issue-string shape (open string) is faithful-courier —
297
+ * NOT validated.
298
+ *
299
+ * **Transport-shape validation** (P3 hardening):
300
+ * - Rejects with `AttestryAPIError` if the kernel responds with
301
+ * a non-`application/json` Content-Type.
302
+ *
303
+ * @example Basic check
304
+ * ```ts
305
+ * const result = await client.check.run({
306
+ * systemId: "11111111-1111-1111-1111-111111111111",
307
+ * });
308
+ * if (result.compliant) {
309
+ * console.log("OK to deploy — score:", result.score);
310
+ * } else if (result.lastAssessedAt === null) {
311
+ * console.warn("No completed assessment yet — score=0 is the default, not a failing grade");
312
+ * } else {
313
+ * console.warn("Compliance gaps:", result.issues);
314
+ * }
315
+ * ```
316
+ *
317
+ * @example Filtered by frameworks (OR-overlap)
318
+ * ```ts
319
+ * const euOnly = await client.check.run({
320
+ * systemId: "11111111-1111-1111-1111-111111111111",
321
+ * frameworks: ["EU_AI_ACT", "ISO_42001"],
322
+ * });
323
+ * ```
324
+ */
325
+ run(input, options) {
326
+ // Top-level shape — input is REQUIRED. typeof null === "object"
327
+ // and typeof [] === "object", so guard both explicitly.
328
+ if (input === null ||
329
+ typeof input !== "object" ||
330
+ Array.isArray(input)) {
331
+ throw new TypeError("check.run: `input` must be a non-null object with `systemId`");
332
+ }
333
+ // Snapshot each field's value EXACTLY ONCE up front via the
334
+ // own-property indexer, then operate only on the locals
335
+ // downstream. Three motivations:
336
+ // 1. **Prototype-pollution defense (generalization of #48)**:
337
+ // `Object.prototype.systemId = "<some-uuid>"` (set somewhere
338
+ // else in the consumer's process) DOES NOT trick the SDK
339
+ // into silently sending the polluted value when the user
340
+ // passes `{}`. `Object.hasOwn` only checks own properties
341
+ // (ES2022, Node 16.9+ — below the SDK's Node 18 floor). Use
342
+ // the module-load snapshot (`objectHasOwn`) so a
343
+ // late-loading dep that overrides the global doesn't defeat
344
+ // the defense (mirror of `complianceCheck.check`'s hostile-
345
+ // review LOW #2 fix).
346
+ // 2. **TOCTOU defense**: a Proxy or getter-defining input could
347
+ // yield DIFFERENT values across multiple reads of the same
348
+ // field. Snapshotting once collapses validate-then-send to a
349
+ // single read per field; the validated value is provably the
350
+ // value sent.
351
+ // 3. An explicit `{systemId: "..."}` (no `frameworks`) is
352
+ // treated as frameworks-omitted — `objectHasOwn` correctly
353
+ // returns false on the missing key.
354
+ const hasSystemId = objectHasOwn(input, "systemId");
355
+ const systemIdRaw = hasSystemId
356
+ ? readInputField(input, "systemId", "check.run")
357
+ : undefined;
358
+ const hasFrameworks = objectHasOwn(input, "frameworks");
359
+ const frameworksRaw = hasFrameworks
360
+ ? readInputField(input, "frameworks", "check.run")
361
+ : undefined;
362
+ // systemId is REQUIRED. Reject missing-or-undefined first with a
363
+ // clear "required" message; subsequent checks assume present.
364
+ if (!hasSystemId || systemIdRaw === undefined) {
365
+ throw new TypeError("check.run: `systemId` is required");
366
+ }
367
+ if (typeof systemIdRaw !== "string" || systemIdRaw.length === 0) {
368
+ throw new TypeError("check.run: `systemId` must be a non-empty string");
369
+ }
370
+ // UUID format pre-validation (D2 — SDK matches kernel's Zod
371
+ // `z.string().uuid()` closed-spec rule). Faster + clearer than
372
+ // waiting for kernel 422 + fieldErrors decoding. Drift-pinned so
373
+ // a future Zod regex change (e.g., adding v7 ULID support) trips
374
+ // the suite.
375
+ if (!UUID_REGEX.test(systemIdRaw)) {
376
+ throw new TypeError("check.run: `systemId` must be an RFC 4122 hyphenated UUID " +
377
+ "(matched regex: /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-" +
378
+ "[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/)");
379
+ }
380
+ // frameworks — optional. When provided, MUST mirror Zod:
381
+ // - Array (not other iterable).
382
+ // - Length ≤20.
383
+ // - Each element a string of length 1-100.
384
+ // Snapshot via Array.from up front so a Proxy whose `.length` or
385
+ // `[i]` changes between reads can't slip past validation. The
386
+ // snapshot is then sent verbatim as the body field — no
387
+ // re-read.
388
+ let validatedFrameworks;
389
+ if (hasFrameworks && frameworksRaw !== undefined) {
390
+ if (!Array.isArray(frameworksRaw)) {
391
+ throw new TypeError(`check.run: \`frameworks\` must be an array when provided ` +
392
+ `(got ${describeType(frameworksRaw)})`);
393
+ }
394
+ const snapshot = Array.from(frameworksRaw);
395
+ if (snapshot.length > 20) {
396
+ throw new TypeError(`check.run: \`frameworks\` array exceeds the kernel's max ` +
397
+ `length of 20 (got ${snapshot.length})`);
398
+ }
399
+ for (let i = 0; i < snapshot.length; i++) {
400
+ const elem = snapshot[i];
401
+ if (typeof elem !== "string") {
402
+ throw new TypeError(`check.run: \`frameworks[${i}]\` must be a string ` +
403
+ `(got ${describeType(elem)})`);
404
+ }
405
+ if (elem.length === 0) {
406
+ throw new TypeError(`check.run: \`frameworks[${i}]\` must be a non-empty string`);
407
+ }
408
+ if (elem.length > 100) {
409
+ throw new TypeError(`check.run: \`frameworks[${i}]\` exceeds the kernel's max ` +
410
+ `length of 100 chars (got ${elem.length})`);
411
+ }
412
+ }
413
+ // Cast: we've validated every element is a string.
414
+ validatedFrameworks = snapshot;
415
+ }
416
+ // Construct the body. Omit `frameworks` entirely when not
417
+ // provided — the kernel's Zod schema marks it `.optional()` and a
418
+ // missing key is the cleanest representation. (JSON.stringify
419
+ // would also drop `undefined`-valued keys, but explicit
420
+ // construction is clearer.)
421
+ const body = {
422
+ systemId: systemIdRaw,
423
+ };
424
+ if (validatedFrameworks !== undefined) {
425
+ body.frameworks = validatedFrameworks;
426
+ }
427
+ return this.client
428
+ ._request({
429
+ method: "POST",
430
+ path: "/api/v1/check",
431
+ body,
432
+ options,
433
+ })
434
+ .then((result) => {
435
+ // P2 hardening: validate every documented field type. The
436
+ // check response is FLAT — all 6 fields are top-level (no
437
+ // nested wrapper like `complianceCheck.check`'s `systems[]`).
438
+ // A kernel-side regression that emits the wrong type on any
439
+ // field would let a malformed shape reach consumers, who
440
+ // crash downstream with a confusing TypeError. Catch at the
441
+ // SDK boundary with a clear AttestryError naming the
442
+ // specific field.
443
+ if (result === null ||
444
+ typeof result !== "object" ||
445
+ Array.isArray(result)) {
446
+ throw new AttestryError(`check.run: expected an object response from the kernel ` +
447
+ `(got ${describeType(result)})`);
448
+ }
449
+ const obj = result;
450
+ // **Prototype-pollution defense on the RESPONSE side**
451
+ // (symmetric to the input-side D5 generalization of #48).
452
+ // Snapshot each response field via `objectHasOwn` so a hostile
453
+ // npm dep that pollutes `Object.prototype.<field> = <value>`
454
+ // (e.g., `Object.prototype.compliant = true`) cannot mask a
455
+ // kernel regression where the field is missing from the
456
+ // response. Without this defense: kernel-regression-drops-field
457
+ // + prototype-pollution-supplies-default → SDK accepts the
458
+ // polluted value via prototype walk; consumer silently gets a
459
+ // wrong response. With this defense: missing own-property →
460
+ // describeType(undefined) → AttestryError thrown.
461
+ //
462
+ // Found by session-16 SECOND independent hostile review as
463
+ // MEDIUM #3 — symmetric attack to the input-side defense,
464
+ // previously unguarded on the response path.
465
+ const compliant = objectHasOwn(obj, "compliant")
466
+ ? obj.compliant
467
+ : undefined;
468
+ if (typeof compliant !== "boolean") {
469
+ throw new AttestryError(`check.run: expected response.compliant to be a boolean ` +
470
+ `(got ${describeType(compliant)})`);
471
+ }
472
+ const score = objectHasOwn(obj, "score") ? obj.score : undefined;
473
+ if (typeof score !== "number") {
474
+ throw new AttestryError(`check.run: expected response.score to be a number ` +
475
+ `(got ${describeType(score)})`);
476
+ }
477
+ const issues = objectHasOwn(obj, "issues") ? obj.issues : undefined;
478
+ if (!Array.isArray(issues)) {
479
+ throw new AttestryError(`check.run: expected response.issues to be an array ` +
480
+ `(got ${describeType(issues)})`);
481
+ }
482
+ const activeAttestations = objectHasOwn(obj, "activeAttestations")
483
+ ? obj.activeAttestations
484
+ : undefined;
485
+ if (typeof activeAttestations !== "number") {
486
+ throw new AttestryError(`check.run: expected response.activeAttestations to be a number ` +
487
+ `(got ${describeType(activeAttestations)})`);
488
+ }
489
+ const lastAssessedAt = objectHasOwn(obj, "lastAssessedAt")
490
+ ? obj.lastAssessedAt
491
+ : undefined;
492
+ if (lastAssessedAt !== null && typeof lastAssessedAt !== "string") {
493
+ throw new AttestryError(`check.run: expected response.lastAssessedAt to be a string or null ` +
494
+ `(got ${describeType(lastAssessedAt)})`);
495
+ }
496
+ const checkedAt = objectHasOwn(obj, "checkedAt")
497
+ ? obj.checkedAt
498
+ : undefined;
499
+ if (typeof checkedAt !== "string") {
500
+ throw new AttestryError(`check.run: expected response.checkedAt to be a string ` +
501
+ `(got ${describeType(checkedAt)})`);
502
+ }
503
+ return result;
504
+ });
505
+ }
506
+ }
507
+ /**
508
+ * Human-readable type description for error messages. Distinguishes
509
+ * `null` and `array` from generic `object`. Duplicated in
510
+ * `decisions.ts`, `incidents.ts`, `regulatory-changes.ts`,
511
+ * `compliance-check.ts` per project pattern (small helper, leaf-
512
+ * resource modules, no shared module yet).
513
+ *
514
+ * Every branch is reachable in this file:
515
+ * 1. The top-level "expected object" path can see null OR scalar
516
+ * OR array (the negation of "non-null non-array object").
517
+ * 2. The `compliant` / `score` / `activeAttestations` / `checkedAt`
518
+ * type guards can see any non-matching type (including null and
519
+ * array).
520
+ * 3. The `lastAssessedAt` guard can see any type except string OR
521
+ * null (so the null branch is structurally unreachable from
522
+ * THAT call site — null would be filtered by the `!== null`
523
+ * check upstream).
524
+ * 4. The `issues` guard can see any type except array (so the
525
+ * array branch is structurally unreachable from THAT call
526
+ * site).
527
+ * 5. The `frameworks` non-array case can see any non-array type
528
+ * (so the array branch is structurally unreachable from THAT
529
+ * call site).
530
+ * 6. The `frameworks[i]` non-string guard can see any
531
+ * non-string type.
532
+ *
533
+ * Multiple call sites means every branch IS reachable across the
534
+ * module's invocations — no v8-ignore markers needed.
535
+ */
536
+ function describeType(value) {
537
+ if (value === null)
538
+ return "null";
539
+ if (Array.isArray(value))
540
+ return "array";
541
+ return typeof value;
542
+ }
543
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/resources/check.ts"],"names":[],"mappings":"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"}