@melra/receipt-schema 0.3.0-alpha.10 → 0.3.0-alpha.12

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.
package/README.md CHANGED
@@ -9,7 +9,7 @@ npm install @melra/receipt-schema
9
9
  ```
10
10
 
11
11
  ```ts
12
- import { createCertificate, redactStructuredValue, sha256 } from "@melra/receipt-schema";
12
+ import { createCertificate, redactSecrets, redactStructuredValue, sha256 } from "@melra/receipt-schema";
13
13
  ```
14
14
 
15
15
  A receipt records one action: the operation, the policy decision, the evidence
@@ -20,8 +20,14 @@ rather than trusted.
20
20
  `canonicalJson` sorts keys and normalises formatting before hashing, so the same
21
21
  logical value always produces the same digest across processes and platforms.
22
22
 
23
- `redactStructuredValue` strips credential-shaped values — tokens, keys, auth
24
- headers, connection strings — from anything before it is persisted. Raw output
23
+ `redactStructuredValue` strips credential-shaped values from anything before
24
+ it is persisted: fields named like secrets (`authorization`, `headers`,
25
+ `cookie`, `token`, `password`, `env`, `content`, `stdout`, …) are replaced
26
+ whole, URL query strings and fragments are dropped, and every other string goes
27
+ through `redactSecrets`. `SECRET_PATTERNS` — PEM private keys, AWS key IDs,
28
+ JWTs, Slack and GitHub tokens, common API keys, bearer tokens, and
29
+ password/secret assignments — is the one list memory and terminal output use
30
+ too, so a new secret format is added here once. Raw output
25
31
  goes to the live caller only; the durable copy is the redacted one. A new field
26
32
  that can carry a secret must pass through this, or through the memory package's
27
33
  equivalent, before it reaches storage.
package/dist/index.d.ts CHANGED
@@ -1,8 +1,72 @@
1
- export type CertificateResult = "VERIFIED_SUCCESS" | "PARTIAL" | "FAILED" | "CANCELLED" | "WAITING_APPROVAL" | "WAITING_USER" | "POLICY_BLOCKED" | "BUDGET_EXHAUSTED";
1
+ /**
2
+ * Secret shapes redacted wherever MELRA persists free text: receipts and task
3
+ * records here, memory values, and terminal output. One list, exported, because
4
+ * three private copies had drifted apart and none of them knew a PEM private
5
+ * key or an AWS access key id; GovBench found memory storing both verbatim.
6
+ *
7
+ * Only high-confidence shapes belong here. A pattern that fires on ordinary
8
+ * text corrupts the record it was meant to protect, so a secret without a
9
+ * recognisable shape is left to the field-name rule in redactStructuredValue.
10
+ */
11
+ export declare const SECRET_PATTERNS: ReadonlyArray<readonly [RegExp, string]>;
12
+ /** Every SECRET_PATTERNS match in `text` replaced, and which kinds were found. */
13
+ export declare function redactSecrets(text: string): {
14
+ value: string;
15
+ redactions: string[];
16
+ };
17
+ /**
18
+ * A command's arguments with the credentials taken out and everything else
19
+ * kept, so a receipt still says what ran (#122). A credential-named flag loses
20
+ * its value, attached or as the next argument; so do `-pPASSWORD`, the password
21
+ * half of `-u user:pass`, credential-named `NAME=value` assignments, auth
22
+ * headers, and URL userinfo. Every argument then goes through SECRET_PATTERNS.
23
+ */
24
+ export declare function redactArgv(argv: readonly string[]): {
25
+ value: string[];
26
+ redactions: string[];
27
+ };
28
+ export type CertificateResult = "VERIFIED_SUCCESS" | "PARTIAL" | "FAILED" | "CANCELLED" | "WAITING_APPROVAL" | "WAITING_USER" | "POLICY_BLOCKED" | "BUDGET_EXHAUSTED"
29
+ /** The effect may or may not have happened. Neither claim is available yet. */
30
+ | "RECOVERY_REQUIRED";
31
+ /**
32
+ * How the kernel knows an evidence item is true, weakest first.
33
+ *
34
+ * A caller reading a receipt has to be able to tell the actor's own word apart
35
+ * from the world's answer, because that difference is the whole value of
36
+ * verification. Derived from the item type by `evidenceStrength`, never
37
+ * declared by the caller — evidence a caller could label `independent` itself
38
+ * would prove nothing.
39
+ */
40
+ export type EvidenceStrength =
41
+ /** The adapter reported it. The actor grading its own homework. */
42
+ "execution"
43
+ /** The kernel re-read the target after the fact. */
44
+ | "state"
45
+ /** Confirmed through a different channel than the one that acted. */
46
+ | "independent"
47
+ /** A judgement about meaning. Probabilistic; never sole evidence for a destructive effect. */
48
+ | "semantic";
49
+ export declare function evidenceStrength(type: string): EvidenceStrength;
2
50
  export interface EvidenceItem {
3
51
  type: string;
4
52
  passed: boolean;
5
53
  summary: string;
54
+ /**
55
+ * How the item is known. Optional only because receipts written before
56
+ * strengths existed do not carry one; every item written now does, and
57
+ * `evidenceStrength(item.type)` recovers it for the ones that do not.
58
+ */
59
+ strength?: EvidenceStrength;
60
+ /**
61
+ * The question could not be asked — an unreachable provider, a probe the
62
+ * runtime does not have — as opposed to being asked and answered no.
63
+ *
64
+ * `passed` stays false either way, because unproven is not proven. The flag
65
+ * exists so a caller can tell the two apart: a provider that answered "no
66
+ * such refund" is evidence the effect did not happen, and a provider that
67
+ * did not answer is evidence of nothing at all.
68
+ */
69
+ inconclusive?: boolean;
6
70
  source?: string;
7
71
  digest?: string;
8
72
  }
@@ -18,6 +82,21 @@ export interface ActionReceipt {
18
82
  */
19
83
  principal?: string;
20
84
  effect: "read" | "mutate" | "destructive";
85
+ /**
86
+ * What was promised about how many times this could run — the same value the
87
+ * plan showed, so an auditor reads the promise beside the outcome instead of
88
+ * inferring it from the effect. A string rather than the protocol's union
89
+ * because this package deliberately has no dependencies; `protocol` owns the
90
+ * vocabulary and derives every value written here.
91
+ */
92
+ executionGuarantee?: string;
93
+ /**
94
+ * How the kernel that ran this effect was deployed — `developer` or
95
+ * `enforced`. An auditor reading a receipt should not have to ask whether the
96
+ * boundary that governed it was the only door or one of several. A string for
97
+ * the same reason as `executionGuarantee`: `protocol` owns the vocabulary.
98
+ */
99
+ mode?: string;
21
100
  policyDecision: {
22
101
  outcome: "allow" | "deny" | "confirm";
23
102
  policyVersion: string;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,SAAS,GACT,QAAQ,GACR,WAAW,GACX,kBAAkB,GAClB,cAAc,GACd,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,aAAa,CAAC;IAC1C,cAAc,EAAE;QACd,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;QACtC,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iBAAiB,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG;IACrD,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,CAyDA;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAYpD;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAE7C;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,GAAG,eAAe,GAAG,QAAQ,CAAC,GAC9E,oBAAoB,CAQtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,13 +1,121 @@
1
1
  // Copyright 2026 XAGI Labs Private Limited
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  import { createHash, randomUUID } from "node:crypto";
4
- const SENSITIVE_KEY = /^(?:args?|authorization|constraints|content|cookie|env|goal|headers?|pass(?:word|wd)?|secret|std(?:out|err)|text|token|api[_-]?key|values?)$/i;
5
- const SECRET_PATTERNS = [
4
+ const SENSITIVE_KEY = /^(?:arg|authorization|constraints|content|cookie|env|goal|headers?|pass(?:word|wd)?|secret|std(?:out|err)|text|token|api[_-]?key|values?)$/i;
5
+ /**
6
+ * Secret shapes redacted wherever MELRA persists free text: receipts and task
7
+ * records here, memory values, and terminal output. One list, exported, because
8
+ * three private copies had drifted apart and none of them knew a PEM private
9
+ * key or an AWS access key id; GovBench found memory storing both verbatim.
10
+ *
11
+ * Only high-confidence shapes belong here. A pattern that fires on ordinary
12
+ * text corrupts the record it was meant to protect, so a secret without a
13
+ * recognisable shape is left to the field-name rule in redactStructuredValue.
14
+ */
15
+ export const SECRET_PATTERNS = [
16
+ // A whole PEM private key block, and a truncated one (output cut mid-key).
17
+ [
18
+ /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z0-9]+ )*PRIVATE KEY-----/g,
19
+ "[REDACTED_PRIVATE_KEY]",
20
+ ],
21
+ [/-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY-----[\s\S]*/g, "[REDACTED_PRIVATE_KEY]"],
22
+ [/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/g, "[REDACTED_AWS_KEY_ID]"],
23
+ [/\beyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/g, "[REDACTED_JWT]"],
24
+ [/\bxox[abposr]-[A-Za-z0-9-]{10,}\b/g, "[REDACTED_SLACK_TOKEN]"],
6
25
  [/\bgh[opurs]_[A-Za-z0-9]{20,}\b/g, "[REDACTED_GITHUB_TOKEN]"],
7
26
  [/\b(?:sk|pk|api)[-_][a-z0-9_-]{16,}\b/gi, "[REDACTED_API_KEY]"],
8
27
  [/\bBearer\s+[A-Za-z0-9._~+/-]+=*\b/gi, "Bearer [REDACTED_TOKEN]"],
9
28
  [/\b(password|passwd|secret)\s*[:=]\s*\S+/gi, "$1=[REDACTED]"],
10
29
  ];
30
+ /** Every SECRET_PATTERNS match in `text` replaced, and which kinds were found. */
31
+ export function redactSecrets(text) {
32
+ let value = text;
33
+ const redactions = [];
34
+ for (const [pattern, replacement] of SECRET_PATTERNS) {
35
+ const before = value;
36
+ value = value.replace(pattern, replacement);
37
+ if (value !== before && !redactions.includes(replacement))
38
+ redactions.push(replacement);
39
+ }
40
+ return { value, redactions };
41
+ }
42
+ // A flag whose value is a credential, `--token x` or `--token=x`, matched on
43
+ // the flag's name because the value itself may have no recognisable shape.
44
+ const SECRET_FLAG = /^(--?(?:[a-z0-9]+[-_])*(?:token|password|passwd|pass|secret|api[-_]?key|apikey|auth|authorization|credentials?|cookie|private[-_]?key))(?:=([\s\S]*))?$/i;
45
+ // `-u user:pass` / `--user user:pass` (curl, wget): only the part after the
46
+ // colon is a secret, and `sort -u`, `git add -u` take no value at all.
47
+ const USER_FLAG = /^(?:-u|--user)$/;
48
+ // `-pPASSWORD` (mysql and friends). Never the next argument: `mkdir -p dir`,
49
+ // `ssh -p 22`. A remainder under three characters is read as bundled short
50
+ // flags (`-pv`, `-pr`), not a password.
51
+ const ATTACHED_PASSWORD = /^-p(.{3,})$/s;
52
+ // `NAME=value` with a credential-like name, as `env FOO_TOKEN=x cmd` passes it.
53
+ const SECRET_ASSIGNMENT = /^([A-Za-z_][A-Za-z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PASS|AUTH|CREDENTIALS?))=[\s\S]*$/i;
54
+ // A header given as one argument, as `curl -H 'Authorization: Bearer x'` does.
55
+ const SECRET_HEADER = /^((?:proxy-)?authorization|cookie|[a-z0-9-]*(?:token|api-?key|secret))\s*:[\s\S]*$/i;
56
+ // Credentials inside a URL or connection string: `postgres://user:pass@host`.
57
+ const URL_CREDENTIALS = /(\/\/)[^\s/@:]+:[^\s/@]+@/g;
58
+ const REDACTED_ARG = "[REDACTED_SENSITIVE_ARG]";
59
+ function redactOneArg(arg, previous) {
60
+ if (previous !== undefined) {
61
+ const flag = SECRET_FLAG.exec(previous);
62
+ if (flag !== null && flag[2] === undefined)
63
+ return REDACTED_ARG;
64
+ if (USER_FLAG.test(previous) && arg.includes(":")) {
65
+ return `${arg.slice(0, arg.indexOf(":"))}:${REDACTED_ARG}`;
66
+ }
67
+ }
68
+ const flag = SECRET_FLAG.exec(arg);
69
+ if (flag?.[2] !== undefined)
70
+ return `${flag[1]}=${REDACTED_ARG}`;
71
+ if (ATTACHED_PASSWORD.test(arg))
72
+ return `-p${REDACTED_ARG}`;
73
+ if (SECRET_ASSIGNMENT.test(arg))
74
+ return arg.replace(SECRET_ASSIGNMENT, `$1=${REDACTED_ARG}`);
75
+ if (SECRET_HEADER.test(arg))
76
+ return arg.replace(SECRET_HEADER, `$1: ${REDACTED_ARG}`);
77
+ return arg.replace(URL_CREDENTIALS, `$1${REDACTED_ARG}@`);
78
+ }
79
+ /**
80
+ * A command's arguments with the credentials taken out and everything else
81
+ * kept, so a receipt still says what ran (#122). A credential-named flag loses
82
+ * its value, attached or as the next argument; so do `-pPASSWORD`, the password
83
+ * half of `-u user:pass`, credential-named `NAME=value` assignments, auth
84
+ * headers, and URL userinfo. Every argument then goes through SECRET_PATTERNS.
85
+ */
86
+ export function redactArgv(argv) {
87
+ const redactions = new Set();
88
+ const value = argv.map((arg, index) => {
89
+ const out = redactOneArg(arg, index === 0 ? undefined : argv[index - 1]);
90
+ if (out !== arg)
91
+ redactions.add(REDACTED_ARG);
92
+ const redacted = redactSecrets(out);
93
+ for (const kind of redacted.redactions)
94
+ redactions.add(kind);
95
+ return redacted.value;
96
+ });
97
+ return { value, redactions: [...redactions] };
98
+ }
99
+ /**
100
+ * Only the types that outrank `execution` are listed. An unrecognised type —
101
+ * an older receipt, a predicate added without a decision here — reads as the
102
+ * weakest claim rather than silently borrowing a stronger one.
103
+ */
104
+ const STRONGER_THAN_EXECUTION = {
105
+ file_exists: "state",
106
+ file_absent: "state",
107
+ file_hash: "state",
108
+ // Not the adapter's word: the kernel read a durable commit that outlives the
109
+ // process that wrote it.
110
+ idempotency: "state",
111
+ // The only item here the acting channel did not produce: a separate request
112
+ // whose answer comes from the provider's state rather than from the call that
113
+ // changed it.
114
+ http_resource_matches: "independent",
115
+ };
116
+ export function evidenceStrength(type) {
117
+ return STRONGER_THAN_EXECUTION[type] ?? "execution";
118
+ }
11
119
  export function redactStructuredValue(value) {
12
120
  const redactions = new Set();
13
121
  const redactWholeValue = (current) => {
@@ -27,6 +135,17 @@ export function redactStructuredValue(value) {
27
135
  if (key !== undefined && SENSITIVE_KEY.test(key)) {
28
136
  return redactWholeValue(current);
29
137
  }
138
+ if (key === "args") {
139
+ // Arguments are what a receipt most needs to show, so only their
140
+ // credentials go; anything that is not a list of strings goes whole.
141
+ if (!Array.isArray(current) || !current.every((item) => typeof item === "string")) {
142
+ return redactWholeValue(current);
143
+ }
144
+ const redacted = redactArgv(current);
145
+ for (const kind of redacted.redactions)
146
+ redactions.add(kind);
147
+ return redacted.value;
148
+ }
30
149
  if (key === "url" && typeof current === "string") {
31
150
  try {
32
151
  const url = new URL(current);
@@ -42,14 +161,10 @@ export function redactStructuredValue(value) {
42
161
  }
43
162
  }
44
163
  if (typeof current === "string") {
45
- let redacted = current;
46
- for (const [pattern, replacement] of SECRET_PATTERNS) {
47
- const before = redacted;
48
- redacted = redacted.replace(pattern, replacement);
49
- if (redacted !== before)
50
- redactions.add(replacement);
51
- }
52
- return redacted;
164
+ const redacted = redactSecrets(current);
165
+ for (const kind of redacted.redactions)
166
+ redactions.add(kind);
167
+ return redacted.value;
53
168
  }
54
169
  if (Array.isArray(current)) {
55
170
  return current.map((item) => visit(item));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,sCAAsC;AAEtC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,aAAa,GACjB,+IAA+I,CAAC;AAClJ,MAAM,eAAe,GAA4B;IAC/C,CAAC,iCAAiC,EAAE,yBAAyB,CAAC;IAC9D,CAAC,wCAAwC,EAAE,oBAAoB,CAAC;IAChE,CAAC,qCAAqC,EAAE,yBAAyB,CAAC;IAClE,CAAC,2CAA2C,EAAE,eAAe,CAAC;CAC/D,CAAC;AA6DF,MAAM,UAAU,qBAAqB,CAAC,KAAc;IAIlD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,MAAM,gBAAgB,GAAG,CAAC,OAAgB,EAAW,EAAE;QACrD,UAAU,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,4BAA4B,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC;gBACrC,QAAQ;gBACR,4BAA4B;aAC7B,CAAC,CACH,CAAC;QACJ,CAAC;QACD,OAAO,4BAA4B,CAAC;IACtC,CAAC,CAAC;IACF,MAAM,KAAK,GAAG,CAAC,OAAgB,EAAE,GAAY,EAAW,EAAE;QACxD,IAAI,GAAG,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACjD,OAAO,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,GAAG,KAAK,KAAK,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACjD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC7B,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,IAAI,GAAG,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;oBACzC,UAAU,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;oBACvC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC;oBAChB,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;gBAChB,CAAC;gBACD,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,6DAA6D;YAC/D,CAAC;QACH,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,IAAI,QAAQ,GAAG,OAAO,CAAC;YACvB,KAAK,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,IAAI,eAAe,EAAE,CAAC;gBACrD,MAAM,MAAM,GAAG,QAAQ,CAAC;gBACxB,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBAClD,IAAI,QAAQ,KAAK,MAAM;oBAAE,UAAU,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACpD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC;gBACtD,QAAQ;gBACR,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC;aAC5B,CAAC,CACH,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAChD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC;IACzC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACnD,CAAC;IACD,MAAM,MAAM,GAAG,KAAgC,CAAC;IAChD,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SAC3B,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;SACpE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAA+E;IAE/E,MAAM,aAAa,GAAG,UAAU,EAAE,CAAC;IACnC,MAAM,IAAI,GAAG;QACX,aAAa,EAAE,OAAgB;QAC/B,aAAa;QACb,GAAG,KAAK;KACT,CAAC;IACF,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;AAC3C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@melra/receipt-schema",
3
- "version": "0.3.0-alpha.10",
3
+ "version": "0.3.0-alpha.12",
4
4
  "description": "Canonical receipts, redaction, and execution certificates for MELRA.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -24,6 +24,6 @@
24
24
  "build": "tsc -p tsconfig.json",
25
25
  "clean": "rm -rf dist",
26
26
  "test": "vitest run --passWithNoTests",
27
- "typecheck": "tsc -p tsconfig.json --noEmit"
27
+ "typecheck": "tsc -p tsconfig.test.json"
28
28
  }
29
29
  }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":""}
@@ -1,38 +0,0 @@
1
- // Copyright 2026 XAGI Labs Private Limited
2
- // SPDX-License-Identifier: Apache-2.0
3
- import { describe, expect, it } from "vitest";
4
- import { canonicalJson, createCertificate, redactStructuredValue, sha256, } from "./index.js";
5
- describe("receipt and certificate primitives", () => {
6
- it("canonicalizes object keys before hashing", () => {
7
- expect(canonicalJson({ b: 2, a: { d: 4, c: 3 } })).toBe('{"a":{"c":3,"d":4},"b":2}');
8
- expect(sha256({ b: 2, a: 1 })).toBe(sha256({ a: 1, b: 2 }));
9
- });
10
- it("binds the certificate digest to every public field", () => {
11
- const certificate = createCertificate({
12
- taskId: "cff6c496-88b9-442b-b6ef-6f63f57364a3",
13
- goal: "Verify a deterministic outcome",
14
- result: "VERIFIED_SUCCESS",
15
- policyVersion: "1",
16
- receiptIds: ["3f5676d5-1c17-4670-8fa1-ddd55170d5a0"],
17
- evidence: [
18
- { type: "result_equals", passed: true, summary: "matched" },
19
- ],
20
- createdAt: "2026-07-28T00:00:00.000Z",
21
- });
22
- const { digest, ...unsigned } = certificate;
23
- expect(digest).toBe(sha256(unsigned));
24
- expect(digest).toMatch(/^[a-f0-9]{64}$/);
25
- });
26
- it("redacts secret-shaped strings and sensitive fields recursively", () => {
27
- const redacted = redactStructuredValue({
28
- page: "password=hunter2",
29
- nested: { authorization: "Bearer should-never-persist" },
30
- values: ["ghp_123456789012345678901234"],
31
- });
32
- expect(redacted.value.page).not.toContain("hunter2");
33
- expect(redacted.value.nested.authorization).toBe("[REDACTED_SENSITIVE_FIELD]");
34
- expect(redacted.value.values[0]).not.toContain("ghp_");
35
- expect(redacted.redactions.length).toBeGreaterThanOrEqual(2);
36
- });
37
- });
38
- //# sourceMappingURL=index.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,sCAAsC;AAEtC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,GACP,MAAM,YAAY,CAAC;AAEpB,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CACrD,2BAA2B,CAC5B,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,WAAW,GAAG,iBAAiB,CAAC;YACpC,MAAM,EAAE,sCAAsC;YAC9C,IAAI,EAAE,gCAAgC;YACtC,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,GAAG;YAClB,UAAU,EAAE,CAAC,sCAAsC,CAAC;YACpD,QAAQ,EAAE;gBACR,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE;aAC5D;YACD,SAAS,EAAE,0BAA0B;SACtC,CAAC,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,GAAG,WAAW,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,MAAM,QAAQ,GAAG,qBAAqB,CAAC;YACrC,IAAI,EAAE,kBAAkB;YACxB,MAAM,EAAE,EAAE,aAAa,EAAE,6BAA6B,EAAE;YACxD,MAAM,EAAE,CAAC,8BAA8B,CAAC;SACzC,CAOA,CAAC;QACF,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACrD,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAC9C,4BAA4B,CAC7B,CAAC;QACF,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACvD,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}