@primust/artifact-core 1.0.0 → 1.3.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 (62) hide show
  1. package/LICENSE +93 -0
  2. package/dist/canonical.d.ts +11 -0
  3. package/dist/canonical.d.ts.map +1 -1
  4. package/dist/canonical.js +92 -0
  5. package/dist/canonical.js.map +1 -1
  6. package/dist/commitment.d.ts +56 -8
  7. package/dist/commitment.d.ts.map +1 -1
  8. package/dist/commitment.js +71 -26
  9. package/dist/commitment.js.map +1 -1
  10. package/dist/commitment.test.js +14 -3
  11. package/dist/commitment.test.js.map +1 -1
  12. package/dist/hierarchical_leaf.d.ts +72 -0
  13. package/dist/hierarchical_leaf.d.ts.map +1 -0
  14. package/dist/hierarchical_leaf.js +144 -0
  15. package/dist/hierarchical_leaf.js.map +1 -0
  16. package/dist/hierarchical_leaf.test.d.ts +15 -0
  17. package/dist/hierarchical_leaf.test.d.ts.map +1 -0
  18. package/dist/hierarchical_leaf.test.js +145 -0
  19. package/dist/hierarchical_leaf.test.js.map +1 -0
  20. package/dist/index.d.ts +9 -1
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +5 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/metadata_source.d.ts +4 -0
  25. package/dist/metadata_source.d.ts.map +1 -0
  26. package/dist/metadata_source.js +54 -0
  27. package/dist/metadata_source.js.map +1 -0
  28. package/dist/metadata_source.test.d.ts +2 -0
  29. package/dist/metadata_source.test.d.ts.map +1 -0
  30. package/dist/metadata_source.test.js +29 -0
  31. package/dist/metadata_source.test.js.map +1 -0
  32. package/dist/reversibility_taxonomy.d.ts +23 -0
  33. package/dist/reversibility_taxonomy.d.ts.map +1 -0
  34. package/dist/reversibility_taxonomy.js +208 -0
  35. package/dist/reversibility_taxonomy.js.map +1 -0
  36. package/dist/reversibility_taxonomy.test.d.ts +2 -0
  37. package/dist/reversibility_taxonomy.test.d.ts.map +1 -0
  38. package/dist/reversibility_taxonomy.test.js +146 -0
  39. package/dist/reversibility_taxonomy.test.js.map +1 -0
  40. package/dist/signing.d.ts.map +1 -1
  41. package/dist/signing.js +30 -6
  42. package/dist/signing.js.map +1 -1
  43. package/dist/trust_edge_mapping.d.ts +12 -0
  44. package/dist/trust_edge_mapping.d.ts.map +1 -0
  45. package/dist/trust_edge_mapping.js +88 -0
  46. package/dist/trust_edge_mapping.js.map +1 -0
  47. package/dist/trust_edge_mapping.test.d.ts +2 -0
  48. package/dist/trust_edge_mapping.test.d.ts.map +1 -0
  49. package/dist/trust_edge_mapping.test.js +86 -0
  50. package/dist/trust_edge_mapping.test.js.map +1 -0
  51. package/dist/types/artifact.d.ts +65 -4
  52. package/dist/types/artifact.d.ts.map +1 -1
  53. package/dist/types/proof_artifact.d.ts +52 -0
  54. package/dist/types/proof_artifact.d.ts.map +1 -0
  55. package/dist/types/proof_artifact.js +12 -0
  56. package/dist/types/proof_artifact.js.map +1 -0
  57. package/dist/validate-artifact.d.ts.map +1 -1
  58. package/dist/validate-artifact.js +88 -10
  59. package/dist/validate-artifact.js.map +1 -1
  60. package/dist/validate-artifact.test.js +16 -2
  61. package/dist/validate-artifact.test.js.map +1 -1
  62. package/package.json +13 -7
@@ -0,0 +1,208 @@
1
+ // Reversibility taxonomy for outbound-action records.
2
+ //
3
+ // TypeScript sibling of
4
+ // `packages/primust-checks/src/primust_checks/reversibility_taxonomy.py`.
5
+ // Both implementations stamp the same `TAXONOMY_VERSION` so a credential
6
+ // classified by either side is comparable.
7
+ //
8
+ // Implements the system-default classification referenced by
9
+ // `docs/v30/foundation/OUTBOUND_ACTION_EVIDENCE_SPEC_v0_1.md` §1.2 and §2.5
10
+ // and `AGENT_MANIFEST_SPEC_v0_1.md` §3.3 (`reversibility_overrides`).
11
+ //
12
+ // SI-1: this module emits only enum / count / hash / typed-reference values.
13
+ // The taxonomy itself is content-free.
14
+ export const TAXONOMY_VERSION = '1.0.0';
15
+ export const REVERSIBILITY_CLASSES = [
16
+ 'reversible',
17
+ 'append_only',
18
+ 'external_side_effect',
19
+ 'irreversible',
20
+ 'unknown',
21
+ ];
22
+ // Type guard for safe parsing of customer-supplied override strings.
23
+ export function isReversibilityClass(v) {
24
+ return typeof v === 'string' && REVERSIBILITY_CLASSES.includes(v);
25
+ }
26
+ // Operation-specific defaults, keyed by `${kind}::${operation}`.
27
+ //
28
+ // Operation strings follow the spec's per-adapter convention; see the
29
+ // Python sibling for the full convention table.
30
+ const DEFAULTS = {
31
+ // ───────── AWS API ─────────
32
+ 'aws_api::GetObject': 'reversible',
33
+ 'aws_api::ListObjects': 'reversible',
34
+ 'aws_api::ListObjectsV2': 'reversible',
35
+ 'aws_api::HeadObject': 'reversible',
36
+ 'aws_api::ListBuckets': 'reversible',
37
+ 'aws_api::DescribeInstances': 'reversible',
38
+ 'aws_api::DescribeDBInstances': 'reversible',
39
+ 'aws_api::GetItem': 'reversible',
40
+ 'aws_api::Query': 'reversible',
41
+ 'aws_api::Scan': 'reversible',
42
+ 'aws_api::PutObject': 'append_only',
43
+ 'aws_api::PutItem': 'append_only',
44
+ 'aws_api::CreateBucket': 'append_only',
45
+ 'aws_api::CreateTable': 'append_only',
46
+ 'aws_api::RunInstances': 'append_only',
47
+ 'aws_api::CreateDBInstance': 'append_only',
48
+ 'aws_api::SendEmail': 'external_side_effect',
49
+ 'aws_api::Publish': 'external_side_effect',
50
+ 'aws_api::SendMessage': 'external_side_effect',
51
+ 'aws_api::Invoke': 'external_side_effect',
52
+ 'aws_api::RebootInstances': 'external_side_effect',
53
+ 'aws_api::StopInstances': 'external_side_effect',
54
+ 'aws_api::StartInstances': 'external_side_effect',
55
+ 'aws_api::DeleteObject': 'irreversible',
56
+ 'aws_api::DeleteObjects': 'irreversible',
57
+ 'aws_api::DeleteBucket': 'irreversible',
58
+ 'aws_api::DeleteTable': 'irreversible',
59
+ 'aws_api::DeleteItem': 'irreversible',
60
+ 'aws_api::TerminateInstances': 'irreversible',
61
+ 'aws_api::DeleteDBInstance': 'irreversible',
62
+ // ───────── Stripe API (per spec §2.5) ─────────
63
+ 'stripe_api::charges.list': 'reversible',
64
+ 'stripe_api::charges.retrieve': 'reversible',
65
+ 'stripe_api::customers.list': 'reversible',
66
+ 'stripe_api::customers.retrieve': 'reversible',
67
+ 'stripe_api::balance.retrieve': 'reversible',
68
+ 'stripe_api::charges.create': 'irreversible',
69
+ 'stripe_api::payment_intents.confirm': 'irreversible',
70
+ 'stripe_api::charges.refund': 'append_only',
71
+ 'stripe_api::customers.create': 'append_only',
72
+ 'stripe_api::subscriptions.create': 'append_only',
73
+ 'stripe_api::invoices.create': 'append_only',
74
+ 'stripe_api::customers.update': 'external_side_effect',
75
+ 'stripe_api::subscriptions.update': 'external_side_effect',
76
+ 'stripe_api::webhooks.create': 'external_side_effect',
77
+ 'stripe_api::customers.delete': 'irreversible',
78
+ 'stripe_api::subscriptions.delete': 'irreversible',
79
+ // ───────── GitHub API ─────────
80
+ 'github_api::GET /repos/{owner}/{repo}': 'reversible',
81
+ 'github_api::GET /repos/{owner}/{repo}/issues': 'reversible',
82
+ 'github_api::GET /repos/{owner}/{repo}/pulls': 'reversible',
83
+ 'github_api::GET /repos/{owner}/{repo}/contents/{path}': 'reversible',
84
+ 'github_api::POST /repos/{owner}/{repo}/issues': 'append_only',
85
+ 'github_api::POST /repos/{owner}/{repo}/pulls': 'append_only',
86
+ 'github_api::POST /repos/{owner}/{repo}/issues/{number}/comments': 'append_only',
87
+ 'github_api::POST /repos/{owner}/{repo}/pulls/{number}/reviews': 'append_only',
88
+ 'github_api::POST /repos/{owner}/{repo}/pulls/{number}/merge': 'external_side_effect',
89
+ 'github_api::PATCH /repos/{owner}/{repo}/issues/{number}': 'reversible',
90
+ 'github_api::PATCH /repos/{owner}/{repo}/pulls/{number}': 'reversible',
91
+ 'github_api::PUT /repos/{owner}/{repo}/contents/{path}': 'append_only',
92
+ 'github_api::DELETE /repos/{owner}/{repo}/contents/{path}': 'irreversible',
93
+ 'github_api::DELETE /repos/{owner}/{repo}': 'irreversible',
94
+ 'github_api::DELETE /repos/{owner}/{repo}/branches/{branch}': 'reversible',
95
+ // ───────── Salesforce REST ─────────
96
+ 'salesforce_rest::GET /sobjects/Account/{id}': 'reversible',
97
+ 'salesforce_rest::GET /sobjects/Task/{id}': 'reversible',
98
+ 'salesforce_rest::GET /query': 'reversible',
99
+ 'salesforce_rest::POST /sobjects/Task': 'append_only',
100
+ 'salesforce_rest::POST /sobjects/Account': 'append_only',
101
+ 'salesforce_rest::POST /sobjects/Lead': 'append_only',
102
+ 'salesforce_rest::POST /sobjects/Contact': 'append_only',
103
+ 'salesforce_rest::POST /sobjects/Opportunity': 'append_only',
104
+ 'salesforce_rest::POST /sobjects/Case': 'append_only',
105
+ 'salesforce_rest::PATCH /sobjects/Account/{id}': 'reversible',
106
+ 'salesforce_rest::PATCH /sobjects/Task/{id}': 'reversible',
107
+ 'salesforce_rest::DELETE /sobjects/Account/{id}': 'irreversible',
108
+ 'salesforce_rest::DELETE /sobjects/Task/{id}': 'irreversible',
109
+ // ───────── Slack ─────────
110
+ 'slack::conversations.history': 'reversible',
111
+ 'slack::conversations.list': 'reversible',
112
+ 'slack::users.list': 'reversible',
113
+ 'slack::chat.postMessage': 'external_side_effect',
114
+ 'slack::chat.postEphemeral': 'external_side_effect',
115
+ 'slack::chat.update': 'external_side_effect',
116
+ 'slack::files.upload': 'append_only',
117
+ 'slack::conversations.invite': 'external_side_effect',
118
+ 'slack::conversations.kick': 'external_side_effect',
119
+ 'slack::conversations.create': 'append_only',
120
+ 'slack::conversations.archive': 'reversible',
121
+ 'slack::chat.delete': 'irreversible',
122
+ // ───────── Kubernetes ─────────
123
+ 'k8s::GET /api/v1/namespaces': 'reversible',
124
+ 'k8s::GET /api/v1/namespaces/{ns}/pods': 'reversible',
125
+ 'k8s::GET /apis/apps/v1/namespaces/{ns}/deployments': 'reversible',
126
+ 'k8s::POST /apis/apps/v1/namespaces/{ns}/deployments': 'append_only',
127
+ 'k8s::POST /api/v1/namespaces/{ns}/configmaps': 'append_only',
128
+ 'k8s::POST /api/v1/namespaces/{ns}/secrets': 'append_only',
129
+ 'k8s::PATCH /apis/apps/v1/namespaces/{ns}/deployments/{name}': 'reversible',
130
+ 'k8s::PATCH /api/v1/namespaces/{ns}/configmaps/{name}': 'reversible',
131
+ 'k8s::DELETE /api/v1/namespaces/{ns}/pods/{name}': 'reversible',
132
+ 'k8s::DELETE /apis/apps/v1/namespaces/{ns}/deployments/{name}': 'irreversible',
133
+ 'k8s::DELETE /api/v1/namespaces/{ns}': 'irreversible',
134
+ 'k8s::DELETE /api/v1/namespaces/{ns}/secrets/{name}': 'irreversible',
135
+ // ───────── Postgres / Snowflake ─────────
136
+ 'postgres::SELECT': 'reversible',
137
+ 'postgres::INSERT': 'append_only',
138
+ 'postgres::UPDATE': 'external_side_effect',
139
+ 'postgres::DELETE': 'irreversible',
140
+ 'postgres::DROP TABLE': 'irreversible',
141
+ 'postgres::TRUNCATE': 'irreversible',
142
+ 'snowflake::SELECT': 'reversible',
143
+ 'snowflake::INSERT': 'append_only',
144
+ 'snowflake::UPDATE': 'external_side_effect',
145
+ 'snowflake::DELETE': 'irreversible',
146
+ 'snowflake::DROP TABLE': 'irreversible',
147
+ // ───────── Vector stores (per spec §1.2) ─────────
148
+ 'pinecone::upsert': 'append_only',
149
+ 'pinecone::delete': 'irreversible',
150
+ 'pinecone::query': 'reversible',
151
+ 'pinecone::fetch': 'reversible',
152
+ 'vector_store::upsert': 'append_only',
153
+ 'vector_store::query': 'reversible',
154
+ 'vector_store::delete': 'irreversible',
155
+ };
156
+ // Per-kind fallback when the exact (kind, op) isn't in DEFAULTS.
157
+ const KIND_DEFAULTS = {
158
+ mcp_tool: 'unknown',
159
+ sdk_tool: 'unknown',
160
+ cli_subprocess: 'unknown',
161
+ anthropic_messages: 'append_only',
162
+ openai_chat: 'append_only',
163
+ bedrock_invoke: 'append_only',
164
+ calibrated_profile: 'append_only',
165
+ approval_gate: 'external_side_effect',
166
+ cli_prompt: 'external_side_effect',
167
+ dashboard_escalation: 'external_side_effect',
168
+ subagent_spawn: 'append_only',
169
+ mcp_sampling: 'append_only',
170
+ cross_org_delegation: 'append_only',
171
+ governance_config_surface: 'external_side_effect',
172
+ filesystem: 'unknown',
173
+ generic_http: 'unknown',
174
+ };
175
+ /**
176
+ * Classify an outbound action by `(target_system_kind, operation)`.
177
+ *
178
+ * Lookup order:
179
+ * 1. Customer override for the exact (kind, op) pair.
180
+ * 2. System default for the exact (kind, op) pair.
181
+ * 3. Per-kind fallback.
182
+ * 4. `'unknown'`.
183
+ */
184
+ export function classify(target_system_kind, operation, options = {}) {
185
+ const key = `${target_system_kind}::${operation}`;
186
+ const override = options.overrides?.[key];
187
+ if (override !== undefined && isReversibilityClass(override)) {
188
+ return override;
189
+ }
190
+ const exact = DEFAULTS[key];
191
+ if (exact !== undefined) {
192
+ return exact;
193
+ }
194
+ return KIND_DEFAULTS[target_system_kind] ?? 'unknown';
195
+ }
196
+ /**
197
+ * True if this kind has real (non-`'unknown'`) classifications in the
198
+ * system defaults. Used by the Phase 1 acceptance gate.
199
+ */
200
+ export function isWedgeSurfaceCovered(target_system_kind) {
201
+ const prefix = `${target_system_kind}::`;
202
+ for (const [k, v] of Object.entries(DEFAULTS)) {
203
+ if (k.startsWith(prefix) && v !== 'unknown')
204
+ return true;
205
+ }
206
+ return false;
207
+ }
208
+ //# sourceMappingURL=reversibility_taxonomy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reversibility_taxonomy.js","sourceRoot":"","sources":["../src/reversibility_taxonomy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reversibility_taxonomy.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reversibility_taxonomy.test.d.ts","sourceRoot":"","sources":["../src/reversibility_taxonomy.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { TAXONOMY_VERSION, REVERSIBILITY_CLASSES, isReversibilityClass, classify, isWedgeSurfaceCovered, } from './reversibility_taxonomy.js';
3
+ describe('reversibility_taxonomy', () => {
4
+ describe('Phase 1 acceptance gate: wedge surfaces', () => {
5
+ const wedge = ['salesforce_rest', 'slack', 'github_api', 'stripe_api', 'k8s', 'aws_api'];
6
+ for (const kind of wedge) {
7
+ it(`${kind} has real (non-unknown) classifications`, () => {
8
+ expect(isWedgeSurfaceCovered(kind)).toBe(true);
9
+ });
10
+ }
11
+ });
12
+ describe('per-spec examples (§2.5)', () => {
13
+ it('stripe charges.create → irreversible', () => {
14
+ expect(classify('stripe_api', 'charges.create')).toBe('irreversible');
15
+ });
16
+ it('stripe customers.update → external_side_effect', () => {
17
+ expect(classify('stripe_api', 'customers.update')).toBe('external_side_effect');
18
+ });
19
+ it('stripe charges.list → reversible', () => {
20
+ expect(classify('stripe_api', 'charges.list')).toBe('reversible');
21
+ });
22
+ it('governance_config_surface default → external_side_effect', () => {
23
+ expect(classify('governance_config_surface', 'edit_settings_json')).toBe('external_side_effect');
24
+ });
25
+ it('vector_store upsert → append_only', () => {
26
+ expect(classify('vector_store', 'upsert')).toBe('append_only');
27
+ });
28
+ });
29
+ describe('AWS', () => {
30
+ it('GetObject → reversible', () => {
31
+ expect(classify('aws_api', 'GetObject')).toBe('reversible');
32
+ });
33
+ it('DeleteBucket → irreversible', () => {
34
+ expect(classify('aws_api', 'DeleteBucket')).toBe('irreversible');
35
+ });
36
+ it('PutObject → append_only', () => {
37
+ expect(classify('aws_api', 'PutObject')).toBe('append_only');
38
+ });
39
+ it('SendEmail → external_side_effect', () => {
40
+ expect(classify('aws_api', 'SendEmail')).toBe('external_side_effect');
41
+ });
42
+ });
43
+ describe('Salesforce', () => {
44
+ it('POST /sobjects/Task → append_only', () => {
45
+ expect(classify('salesforce_rest', 'POST /sobjects/Task')).toBe('append_only');
46
+ });
47
+ it('PATCH /sobjects/Account/{id} → reversible (field audit trail)', () => {
48
+ expect(classify('salesforce_rest', 'PATCH /sobjects/Account/{id}')).toBe('reversible');
49
+ });
50
+ it('DELETE /sobjects/Account/{id} → irreversible', () => {
51
+ expect(classify('salesforce_rest', 'DELETE /sobjects/Account/{id}')).toBe('irreversible');
52
+ });
53
+ });
54
+ describe('Slack', () => {
55
+ it('chat.postMessage → external_side_effect', () => {
56
+ expect(classify('slack', 'chat.postMessage')).toBe('external_side_effect');
57
+ });
58
+ it('conversations.history → reversible', () => {
59
+ expect(classify('slack', 'conversations.history')).toBe('reversible');
60
+ });
61
+ it('chat.delete → irreversible', () => {
62
+ expect(classify('slack', 'chat.delete')).toBe('irreversible');
63
+ });
64
+ });
65
+ describe('Kubernetes', () => {
66
+ it('DELETE pod → reversible (controller recreates)', () => {
67
+ expect(classify('k8s', 'DELETE /api/v1/namespaces/{ns}/pods/{name}')).toBe('reversible');
68
+ });
69
+ it('DELETE deployment → irreversible', () => {
70
+ expect(classify('k8s', 'DELETE /apis/apps/v1/namespaces/{ns}/deployments/{name}')).toBe('irreversible');
71
+ });
72
+ it('DELETE namespace → irreversible', () => {
73
+ expect(classify('k8s', 'DELETE /api/v1/namespaces/{ns}')).toBe('irreversible');
74
+ });
75
+ });
76
+ describe('Postgres', () => {
77
+ it('SELECT → reversible', () => {
78
+ expect(classify('postgres', 'SELECT')).toBe('reversible');
79
+ });
80
+ it('UPDATE → external_side_effect', () => {
81
+ expect(classify('postgres', 'UPDATE')).toBe('external_side_effect');
82
+ });
83
+ it('DELETE → irreversible', () => {
84
+ expect(classify('postgres', 'DELETE')).toBe('irreversible');
85
+ });
86
+ it('DROP TABLE → irreversible', () => {
87
+ expect(classify('postgres', 'DROP TABLE')).toBe('irreversible');
88
+ });
89
+ });
90
+ describe('model surfaces', () => {
91
+ it('anthropic_messages → append_only default', () => {
92
+ expect(classify('anthropic_messages', 'POST /v1/messages')).toBe('append_only');
93
+ });
94
+ it('openai_chat → append_only default', () => {
95
+ expect(classify('openai_chat', 'POST /v1/chat/completions')).toBe('append_only');
96
+ });
97
+ });
98
+ describe('fallback behavior', () => {
99
+ it('unknown kind → unknown', () => {
100
+ expect(classify('not_a_real_kind', 'op')).toBe('unknown');
101
+ });
102
+ it('unmapped op on mcp_tool → unknown (kind default)', () => {
103
+ expect(classify('mcp_tool', 'some_tool_call')).toBe('unknown');
104
+ });
105
+ it('unmapped op on aws → unknown', () => {
106
+ expect(classify('aws_api', 'SomeFutureAction')).toBe('unknown');
107
+ });
108
+ it('human-facing default → external_side_effect', () => {
109
+ expect(classify('approval_gate', 'request')).toBe('external_side_effect');
110
+ });
111
+ });
112
+ describe('customer overrides', () => {
113
+ it('override beats system default', () => {
114
+ expect(classify('stripe_api', 'charges.create', {
115
+ overrides: { 'stripe_api::charges.create': 'reversible' },
116
+ })).toBe('reversible');
117
+ });
118
+ it('invalid override falls back to system default', () => {
119
+ expect(classify('stripe_api', 'charges.create', {
120
+ overrides: { 'stripe_api::charges.create': 'not_a_valid_class' },
121
+ })).toBe('irreversible');
122
+ });
123
+ it('override works for unmapped kind', () => {
124
+ expect(classify('custom_internal_api', 'credit_account', {
125
+ overrides: { 'custom_internal_api::credit_account': 'irreversible' },
126
+ })).toBe('irreversible');
127
+ });
128
+ });
129
+ describe('versioning + SI-1 shape', () => {
130
+ it('TAXONOMY_VERSION is semver', () => {
131
+ expect(TAXONOMY_VERSION).toMatch(/^\d+\.\d+\.\d+$/);
132
+ });
133
+ it('all class values use safe alphabet', () => {
134
+ for (const cls of REVERSIBILITY_CLASSES) {
135
+ expect(cls.replace(/_/g, '')).toMatch(/^[a-z]+$/);
136
+ }
137
+ });
138
+ it('isReversibilityClass type guard works', () => {
139
+ expect(isReversibilityClass('reversible')).toBe(true);
140
+ expect(isReversibilityClass('garbage')).toBe(false);
141
+ expect(isReversibilityClass(null)).toBe(false);
142
+ expect(isReversibilityClass(42)).toBe(false);
143
+ });
144
+ });
145
+ });
146
+ //# sourceMappingURL=reversibility_taxonomy.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reversibility_taxonomy.test.js","sourceRoot":"","sources":["../src/reversibility_taxonomy.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,QAAQ,EACR,qBAAqB,GACtB,MAAM,6BAA6B,CAAC;AAErC,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,CAAC,iBAAiB,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QACzF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,EAAE,CAAC,GAAG,IAAI,yCAAyC,EAAE,GAAG,EAAE;gBACxD,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;QACxC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,CAAC,QAAQ,CAAC,2BAA2B,EAAE,oBAAoB,CAAC,CAAC,CAAC,IAAI,CACtE,sBAAsB,CACvB,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE;QACnB,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;YACrC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;YACjC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;YACvE,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,8BAA8B,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACzF,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,+BAA+B,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5F,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,4CAA4C,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3F,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,CACJ,QAAQ,CAAC,KAAK,EAAE,yDAAyD,CAAC,CAC3E,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;YACzC,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,gCAAgC,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACjF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;YACnC,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,CAAC,QAAQ,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAClF,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAE,2BAA2B,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;QACjC,EAAE,CAAC,wBAAwB,EAAE,GAAG,EAAE;YAChC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,CAAC,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,CACJ,QAAQ,CAAC,YAAY,EAAE,gBAAgB,EAAE;gBACvC,SAAS,EAAE,EAAE,4BAA4B,EAAE,YAAY,EAAE;aAC1D,CAAC,CACH,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,CACJ,QAAQ,CAAC,YAAY,EAAE,gBAAgB,EAAE;gBACvC,SAAS,EAAE,EAAE,4BAA4B,EAAE,mBAAmB,EAAE;aACjE,CAAC,CACH,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,CACJ,QAAQ,CAAC,qBAAqB,EAAE,gBAAgB,EAAE;gBAChD,SAAS,EAAE,EAAE,qCAAqC,EAAE,cAAc,EAAE;aACrE,CAAC,CACH,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACvC,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,KAAK,MAAM,GAAG,IAAI,qBAAqB,EAAE,CAAC;gBACxC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACpD,CAAC;QACH,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;YAC/C,MAAM,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,MAAM,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpD,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/C,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAa9E,6CAA6C;AAC7C,iBAAS,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAM9C;AAED,gCAAgC;AAChC,iBAAS,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CASjD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,UAAU,GACrB;IAAE,YAAY,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAsBxD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,GACzB;IAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAA;CAAE,CAkB7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,MAAM,GACtB,OAAO,CAWT;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,cAAc,EAAE,YAAY,GAAG;IACvD,aAAa,EAAE,YAAY,CAAC;IAC5B,SAAS,EAAE,YAAY,CAAC;IACxB,aAAa,EAAE,UAAU,CAAC;CAC3B,CAyBA;AAGD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAa9E,6CAA6C;AAC7C,iBAAS,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAM9C;AAED,gCAAgC;AAChC,iBAAS,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,CASjD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,UAAU,GACrB;IAAE,YAAY,EAAE,YAAY,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CAsBxD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,IAAI,CAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,UAAU,EAAE,UAAU,EACtB,YAAY,EAAE,YAAY,GACzB;IAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAA;CAAE,CAkB7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,MAAM,GACtB,OAAO,CAmCT;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,cAAc,EAAE,YAAY,GAAG;IACvD,aAAa,EAAE,YAAY,CAAC;IAC5B,SAAS,EAAE,YAAY,CAAC;IACxB,aAAa,EAAE,UAAU,CAAC;CAC3B,CAyBA;AAGD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,CAAC"}
package/dist/signing.js CHANGED
@@ -19,7 +19,7 @@
19
19
  import * as ed from '@noble/ed25519';
20
20
  import { sha512 } from '@noble/hashes/sha512';
21
21
  import { sha256 } from '@noble/hashes/sha256';
22
- import { canonical } from './canonical.js';
22
+ import { canonical, canonicalLegacy } from './canonical.js';
23
23
  // Configure ed25519 to use sha512
24
24
  ed.etc.sha512Sync = (...m) => sha512(ed.etc.concatBytes(...m));
25
25
  /** Generate a cryptographically random hex string */
@@ -117,16 +117,40 @@ export function sign(document, privateKey, signerRecord) {
117
117
  * @returns true if the cryptographic signature is valid
118
118
  */
119
119
  export function verify(document, signatureEnvelope, publicKeyB64Url) {
120
+ let signatureBytes;
121
+ let publicKeyBytes;
120
122
  try {
121
- const canonicalStr = canonical(document);
122
- const hashBytes = sha256(new TextEncoder().encode(canonicalStr));
123
- const signatureBytes = fromBase64Url(signatureEnvelope.signature);
124
- const publicKeyBytes = fromBase64Url(publicKeyB64Url);
125
- return ed.verify(signatureBytes, hashBytes, publicKeyBytes);
123
+ signatureBytes = fromBase64Url(signatureEnvelope.signature);
124
+ publicKeyBytes = fromBase64Url(publicKeyB64Url);
126
125
  }
127
126
  catch {
128
127
  return false;
129
128
  }
129
+ // Try the spec-compliant (ECMA-262) canonical form first; fall back
130
+ // to the legacy Python form that signed VPECs before 2026-04-19.
131
+ // Stored signatures are against whichever form was current at
132
+ // sign-time — new code must still be able to verify legacy VPECs
133
+ // until every customer rolls forward.
134
+ // The legacy form has subtle ambiguity (number formatting, key order)
135
+ // that a malicious prover could exploit; only accept it for signatures
136
+ // claimed to have been produced before the canonical-form cutover.
137
+ const LEGACY_CUTOFF = '2026-04-19';
138
+ const signedAt = signatureEnvelope.signed_at ?? '';
139
+ const legacyAllowed = signedAt !== '' && signedAt.slice(0, 10) < LEGACY_CUTOFF;
140
+ const candidates = legacyAllowed ? [canonical, canonicalLegacy] : [canonical];
141
+ for (const canonFn of candidates) {
142
+ try {
143
+ const canonicalStr = canonFn(document);
144
+ const hashBytes = sha256(new TextEncoder().encode(canonicalStr));
145
+ if (ed.verify(signatureBytes, hashBytes, publicKeyBytes)) {
146
+ return true;
147
+ }
148
+ }
149
+ catch {
150
+ // try next form
151
+ }
152
+ }
153
+ return false;
130
154
  }
131
155
  /**
132
156
  * Rotate a key: create a new kid under the same signer_id.
@@ -1 +1 @@
1
- {"version":3,"file":"signing.js","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"signing.js","sourceRoot":"","sources":["../src/signing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare const MAPPING_VERSION: "1.0.0";
2
+ export declare const TRUST_EDGES: readonly ["A2T", "A2M", "A2H", "A2A", "A2S", "A2D"];
3
+ export type TrustEdge = (typeof TRUST_EDGES)[number];
4
+ /**
5
+ * Resolve the trust edge for a `(target_system_kind, operation)` pair.
6
+ * Returns `null` if the kind is not recognized — callers MUST treat
7
+ * this as a gap (record the kind, do not invent a trust edge).
8
+ */
9
+ export declare function classify(target_system_kind: string, operation: string): TrustEdge | null;
10
+ /** All target_system_kind values this mapping recognizes. */
11
+ export declare function knownKinds(): ReadonlySet<string>;
12
+ //# sourceMappingURL=trust_edge_mapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust_edge_mapping.d.ts","sourceRoot":"","sources":["../src/trust_edge_mapping.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe,EAAG,OAAgB,CAAC;AAEhD,eAAO,MAAM,WAAW,qDAAsD,CAAC;AAC/E,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AA8DrD;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,kBAAkB,EAAE,MAAM,EAC1B,SAAS,EAAE,MAAM,GAChB,SAAS,GAAG,IAAI,CAalB;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,CAEhD"}
@@ -0,0 +1,88 @@
1
+ // Trust-edge mapping for outbound-action records.
2
+ //
3
+ // TypeScript sibling of
4
+ // `packages/primust-checks/src/primust_checks/trust_edge_mapping.py`.
5
+ //
6
+ // Maps `(target_system_kind, operation)` to one of the six trust edges
7
+ // defined in `docs/v30/foundation/OUTBOUND_ACTION_EVIDENCE_SPEC_v0_1.md` §1.2.
8
+ //
9
+ // SI-1: this module emits only enum values. The mapping itself is content-free.
10
+ export const MAPPING_VERSION = '1.0.0';
11
+ export const TRUST_EDGES = ['A2T', 'A2M', 'A2H', 'A2A', 'A2S', 'A2D'];
12
+ // Primary mapping. Two kinds (mcp_tool, governance_config_surface) are
13
+ // contextual and resolved in `classify` below.
14
+ const PRIMARY = {
15
+ // A2T
16
+ sdk_tool: 'A2T',
17
+ cli_subprocess: 'A2T',
18
+ // A2M
19
+ anthropic_messages: 'A2M',
20
+ openai_chat: 'A2M',
21
+ bedrock_invoke: 'A2M',
22
+ calibrated_profile: 'A2M',
23
+ // A2H
24
+ approval_gate: 'A2H',
25
+ cli_prompt: 'A2H',
26
+ dashboard_escalation: 'A2H',
27
+ // A2A
28
+ subagent_spawn: 'A2A',
29
+ mcp_sampling: 'A2A',
30
+ cross_org_delegation: 'A2A',
31
+ // A2S
32
+ aws_api: 'A2S',
33
+ salesforce_rest: 'A2S',
34
+ stripe_api: 'A2S',
35
+ github_api: 'A2S',
36
+ fly_api: 'A2S',
37
+ servicenow_api: 'A2S',
38
+ slack: 'A2S',
39
+ k8s: 'A2S',
40
+ generic_http: 'A2S',
41
+ // A2D
42
+ postgres: 'A2D',
43
+ snowflake: 'A2D',
44
+ pinecone: 'A2D',
45
+ s3: 'A2D',
46
+ filesystem: 'A2D',
47
+ vector_store: 'A2D',
48
+ };
49
+ const MCP_DATA_METHODS = [
50
+ 'resources/read',
51
+ 'resources/list',
52
+ 'prompts/get',
53
+ 'prompts/list',
54
+ ];
55
+ const HTTP_METHOD_PREFIXES = [
56
+ 'GET ',
57
+ 'POST ',
58
+ 'PUT ',
59
+ 'PATCH ',
60
+ 'DELETE ',
61
+ 'HEAD ',
62
+ 'OPTIONS ',
63
+ ];
64
+ /**
65
+ * Resolve the trust edge for a `(target_system_kind, operation)` pair.
66
+ * Returns `null` if the kind is not recognized — callers MUST treat
67
+ * this as a gap (record the kind, do not invent a trust edge).
68
+ */
69
+ export function classify(target_system_kind, operation) {
70
+ if (target_system_kind === 'mcp_tool') {
71
+ if (MCP_DATA_METHODS.some((p) => operation.startsWith(p)))
72
+ return 'A2D';
73
+ if (operation.includes('sampling'))
74
+ return 'A2M';
75
+ return 'A2T';
76
+ }
77
+ if (target_system_kind === 'governance_config_surface') {
78
+ if (HTTP_METHOD_PREFIXES.some((p) => operation.startsWith(p)))
79
+ return 'A2S';
80
+ return 'A2D';
81
+ }
82
+ return PRIMARY[target_system_kind] ?? null;
83
+ }
84
+ /** All target_system_kind values this mapping recognizes. */
85
+ export function knownKinds() {
86
+ return new Set([...Object.keys(PRIMARY), 'mcp_tool', 'governance_config_surface']);
87
+ }
88
+ //# sourceMappingURL=trust_edge_mapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust_edge_mapping.js","sourceRoot":"","sources":["../src/trust_edge_mapping.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,EAAE;AACF,wBAAwB;AACxB,sEAAsE;AACtE,EAAE;AACF,uEAAuE;AACvE,+EAA+E;AAC/E,EAAE;AACF,gFAAgF;AAEhF,MAAM,CAAC,MAAM,eAAe,GAAG,OAAgB,CAAC;AAEhD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAU,CAAC;AAG/E,uEAAuE;AACvE,+CAA+C;AAC/C,MAAM,OAAO,GAA8B;IACzC,MAAM;IACN,QAAQ,EAAE,KAAK;IACf,cAAc,EAAE,KAAK;IAErB,MAAM;IACN,kBAAkB,EAAE,KAAK;IACzB,WAAW,EAAE,KAAK;IAClB,cAAc,EAAE,KAAK;IACrB,kBAAkB,EAAE,KAAK;IAEzB,MAAM;IACN,aAAa,EAAE,KAAK;IACpB,UAAU,EAAE,KAAK;IACjB,oBAAoB,EAAE,KAAK;IAE3B,MAAM;IACN,cAAc,EAAE,KAAK;IACrB,YAAY,EAAE,KAAK;IACnB,oBAAoB,EAAE,KAAK;IAE3B,MAAM;IACN,OAAO,EAAE,KAAK;IACd,eAAe,EAAE,KAAK;IACtB,UAAU,EAAE,KAAK;IACjB,UAAU,EAAE,KAAK;IACjB,OAAO,EAAE,KAAK;IACd,cAAc,EAAE,KAAK;IACrB,KAAK,EAAE,KAAK;IACZ,GAAG,EAAE,KAAK;IACV,YAAY,EAAE,KAAK;IAEnB,MAAM;IACN,QAAQ,EAAE,KAAK;IACf,SAAS,EAAE,KAAK;IAChB,QAAQ,EAAE,KAAK;IACf,EAAE,EAAE,KAAK;IACT,UAAU,EAAE,KAAK;IACjB,YAAY,EAAE,KAAK;CACpB,CAAC;AAEF,MAAM,gBAAgB,GAAG;IACvB,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;IACb,cAAc;CACN,CAAC;AAEX,MAAM,oBAAoB,GAAG;IAC3B,MAAM;IACN,OAAO;IACP,MAAM;IACN,QAAQ;IACR,SAAS;IACT,OAAO;IACP,UAAU;CACF,CAAC;AAEX;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CACtB,kBAA0B,EAC1B,SAAiB;IAEjB,IAAI,kBAAkB,KAAK,UAAU,EAAE,CAAC;QACtC,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QACxE,IAAI,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,OAAO,KAAK,CAAC;QACjD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,kBAAkB,KAAK,2BAA2B,EAAE,CAAC;QACvD,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;QAC5E,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,OAAO,CAAC,kBAAkB,CAAC,IAAI,IAAI,CAAC;AAC7C,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,2BAA2B,CAAC,CAAC,CAAC;AACrF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=trust_edge_mapping.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust_edge_mapping.test.d.ts","sourceRoot":"","sources":["../src/trust_edge_mapping.test.ts"],"names":[],"mappings":""}