@dharma-ai-labs/agent-fabric 0.2.190 → 0.2.192

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 (72) hide show
  1. package/AGENT_FABRIC_ONBOARDING.md +7 -3
  2. package/dist/cliVersionContract.test.d.ts +2 -0
  3. package/dist/cliVersionContract.test.d.ts.map +1 -0
  4. package/dist/cliVersionContract.test.js +17 -0
  5. package/dist/cliVersionContract.test.js.map +1 -0
  6. package/dist/codexSetupLaunchReservation.d.ts +12 -0
  7. package/dist/codexSetupLaunchReservation.d.ts.map +1 -0
  8. package/dist/codexSetupLaunchReservation.js +76 -0
  9. package/dist/codexSetupLaunchReservation.js.map +1 -0
  10. package/dist/codexSetupLaunchReservation.test.d.ts +2 -0
  11. package/dist/codexSetupLaunchReservation.test.d.ts.map +1 -0
  12. package/dist/codexSetupLaunchReservation.test.js +168 -0
  13. package/dist/codexSetupLaunchReservation.test.js.map +1 -0
  14. package/dist/codexSetupOwnedConnection.d.ts +4 -1
  15. package/dist/codexSetupOwnedConnection.d.ts.map +1 -1
  16. package/dist/codexSetupOwnedConnection.js +16 -3
  17. package/dist/codexSetupOwnedConnection.js.map +1 -1
  18. package/dist/codexSetupOwnedConnection.test.js +14 -0
  19. package/dist/codexSetupOwnedConnection.test.js.map +1 -1
  20. package/dist/codexSetupPortalIngress.test.d.ts +2 -0
  21. package/dist/codexSetupPortalIngress.test.d.ts.map +1 -0
  22. package/dist/codexSetupPortalIngress.test.js +383 -0
  23. package/dist/codexSetupPortalIngress.test.js.map +1 -0
  24. package/dist/codexSetupPortalPreparation.d.ts +32 -0
  25. package/dist/codexSetupPortalPreparation.d.ts.map +1 -0
  26. package/dist/codexSetupPortalPreparation.js +131 -0
  27. package/dist/codexSetupPortalPreparation.js.map +1 -0
  28. package/dist/codexSetupPortalPreparation.test.d.ts +2 -0
  29. package/dist/codexSetupPortalPreparation.test.d.ts.map +1 -0
  30. package/dist/codexSetupPortalPreparation.test.js +173 -0
  31. package/dist/codexSetupPortalPreparation.test.js.map +1 -0
  32. package/dist/codexSetupPortalPrompt.test.d.ts +2 -0
  33. package/dist/codexSetupPortalPrompt.test.d.ts.map +1 -0
  34. package/dist/codexSetupPortalPrompt.test.js +141 -0
  35. package/dist/codexSetupPortalPrompt.test.js.map +1 -0
  36. package/dist/codexSetupPortalPromptDigest.d.ts +3 -0
  37. package/dist/codexSetupPortalPromptDigest.d.ts.map +1 -0
  38. package/dist/codexSetupPortalPromptDigest.js +18 -0
  39. package/dist/codexSetupPortalPromptDigest.js.map +1 -0
  40. package/dist/codexSetupPortalPromptDigest.test.d.ts +2 -0
  41. package/dist/codexSetupPortalPromptDigest.test.d.ts.map +1 -0
  42. package/dist/codexSetupPortalPromptDigest.test.js +23 -0
  43. package/dist/codexSetupPortalPromptDigest.test.js.map +1 -0
  44. package/dist/codexSetupPublicStdin.d.ts +6 -0
  45. package/dist/codexSetupPublicStdin.d.ts.map +1 -0
  46. package/dist/codexSetupPublicStdin.js +36 -0
  47. package/dist/codexSetupPublicStdin.js.map +1 -0
  48. package/dist/codexSetupPublicStdin.test.d.ts +2 -0
  49. package/dist/codexSetupPublicStdin.test.d.ts.map +1 -0
  50. package/dist/codexSetupPublicStdin.test.js +40 -0
  51. package/dist/codexSetupPublicStdin.test.js.map +1 -0
  52. package/dist/codexSetupUserPrompt.d.ts +2 -0
  53. package/dist/codexSetupUserPrompt.d.ts.map +1 -1
  54. package/dist/codexSetupUserPrompt.js +13 -7
  55. package/dist/codexSetupUserPrompt.js.map +1 -1
  56. package/dist/index.d.ts +15 -0
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +197 -4
  59. package/dist/index.js.map +1 -1
  60. package/dist/index.test.js +4 -1
  61. package/dist/index.test.js.map +1 -1
  62. package/dist/onboardingContract.test.js +15 -1
  63. package/dist/onboardingContract.test.js.map +1 -1
  64. package/dist/repositorySourceCapture.test.js +15 -0
  65. package/dist/repositorySourceCapture.test.js.map +1 -1
  66. package/dist/schemas/setup-claim-request.schema.json +10 -0
  67. package/dist/schemas/setup-host-preparation-v2.schema.json +171 -0
  68. package/dist/schemas/setup-host-preparation.schema.json +51 -0
  69. package/dist/schemas/setup-launch-reservation.schema.json +29 -0
  70. package/dist/usage.js +1 -1
  71. package/dist/usage.js.map +1 -1
  72. package/package.json +1 -1
@@ -0,0 +1,173 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createHash } from 'node:crypto';
3
+ import { canonicalize } from '@dharma-ai-labs/agent-fabric-contracts';
4
+ import test from 'node:test';
5
+ import { requestCodexSetupHostPreparation } from './codexSetupPortalPreparation.js';
6
+ const now = Date.parse('2030-01-01T00:00:00.000Z');
7
+ const reference = '11111111-1111-4111-8111-111111111111';
8
+ const membership = '22222222-2222-4222-8222-222222222222';
9
+ const binding = { recipientEmail: 'synthetic@example.test', repositoryRemoteUrl: 'https://github.com/example/synthetic.git' };
10
+ const fingerprint = `sha256:${'a'.repeat(64)}`;
11
+ const context = { origin: 'https://www.dharma-ai.io', organizationId: 'org_fixture',
12
+ setupReference: reference, recipientMembershipId: membership, repositoryFingerprint: fingerprint,
13
+ policyRevision: 'policy-v1', scopeDigest: `sha256:${'b'.repeat(64)}`, contractDigest: `sha256:${'c'.repeat(64)}` };
14
+ const contextHash = (value) => createHash('sha256').update('dharma.setup-host-context/v1\0').update(canonicalize({
15
+ cliVersion: value.cliVersion, expiresAt: value.expiresAt, binding: value.binding, context: value.context
16
+ })).digest('hex');
17
+ const originalPin = contextHash({ cliVersion: '0.2.190', expiresAt: '2030-01-01T00:15:00.000Z', binding, context });
18
+ const prompt = '# Dharma Agent Fabric \u2014 one-prompt source setup\n'
19
+ + `Recipient: ${binding.recipientEmail}. Organization: org_fixture.\n`
20
+ + `Selected repository: ${binding.repositoryRemoteUrl}. Fingerprint: ${fingerprint}.\n`
21
+ + `Public setup reference: ${reference}. Fixed expiry: 2030-01-01T00:15:00.000Z.\n`
22
+ + `Preparation context SHA256: ${originalPin}.\n`;
23
+ function fixture() {
24
+ let calls = 0;
25
+ const response = { schema: 'dharma.setup-host-preparation/v1', ok: true, effects: false,
26
+ grantRedeemed: false, approvalRequired: true, sourcePolicyRevalidated: true,
27
+ preparedAt: new Date(now).toISOString(), expiresAt: '2030-01-01T00:15:00.000Z',
28
+ promptSha256: createHash('sha256').update(prompt).digest('hex'), cliVersion: '0.2.190',
29
+ binding: { ...binding }, context: { ...context },
30
+ integrity: { algorithm: 'sha256', kind: 'portal-context', authenticity: 'same-origin-https', contextSha256: originalPin } };
31
+ const input = { origin: response.context.origin, organizationId: 'org_fixture', setupReference: reference,
32
+ cliVersion: '0.2.190', initialUserPrompt: prompt, signal: new AbortController().signal, now: () => now,
33
+ fetcher: (async (url, options) => {
34
+ calls++;
35
+ assert.equal(String(url), 'https://www.dharma-ai.io/api/v1/agent-fabric/bootstrap/setup-claim');
36
+ assert.equal(options?.redirect, 'error');
37
+ assert.deepEqual(JSON.parse(String(options?.body)), { action: 'prepare_host', organizationId: 'org_fixture',
38
+ setupReference: reference, promptSha256: createHash('sha256').update(prompt).digest('hex') });
39
+ assert.equal(options?.credentials, 'omit');
40
+ return new Response(JSON.stringify(response), { headers: { 'content-type': 'application/json' } });
41
+ }) };
42
+ return { response, input, get calls() { return calls; } };
43
+ }
44
+ test('public preparation obtains independent server binding without invoking a provider or enrollment', async () => {
45
+ const f = fixture();
46
+ const result = await requestCodexSetupHostPreparation(f.input);
47
+ assert.equal(f.calls, 1);
48
+ assert.deepEqual(result.binding, binding);
49
+ assert.equal(result.initialUserPrompt, prompt);
50
+ assert.equal(result.effects, false);
51
+ assert.equal(result.portalContextSha256, originalPin);
52
+ });
53
+ test('portal-pinned context is canonical across JSON object key order', async () => {
54
+ const f = fixture();
55
+ f.response.context = Object.fromEntries(Object.entries(f.response.context).reverse());
56
+ assert.equal((await requestCodexSetupHostPreparation(f.input)).portalContextSha256, originalPin);
57
+ });
58
+ test('a replayed intact context cannot extend its fixed expiry', async () => {
59
+ const f = fixture();
60
+ await assert.rejects(requestCodexSetupHostPreparation({ ...f.input, now: () => now + 900001 }));
61
+ assert.equal(f.calls, 1);
62
+ });
63
+ test('credential-shaped prose is rejected before any network admission', async () => {
64
+ const f = fixture();
65
+ const canary = ['dhab', 'synthetic', 'not-a-real-grant'].join('_');
66
+ await assert.rejects(requestCodexSetupHostPreparation({ ...f.input, initialUserPrompt: prompt + canary }));
67
+ assert.equal(f.calls, 0);
68
+ });
69
+ for (const field of ['recipientMembershipId', 'policyRevision', 'scopeDigest', 'contractDigest']) {
70
+ test(`recomputed response integrity cannot substitute the original portal-pinned ${field}`, async () => {
71
+ const f = fixture();
72
+ if (field === 'recipientMembershipId')
73
+ f.response.context[field] = reference;
74
+ else if (field === 'policyRevision')
75
+ f.response.context[field] = 'foreign-policy';
76
+ else
77
+ f.response.context[field] = 'sha256:' + 'f'.repeat(64);
78
+ f.response.integrity.contextSha256 = contextHash(f.response);
79
+ await assert.rejects(requestCodexSetupHostPreparation(f.input), /^Error: codex_setup_portal_preparation_unavailable$/);
80
+ assert.equal(f.calls, 1);
81
+ });
82
+ }
83
+ for (const reason of ['missing', 'duplicate']) {
84
+ test(`a ${reason} original portal context pin is rejected before fetch`, async () => {
85
+ const f = fixture();
86
+ const value = reason === 'missing' ? prompt.replace(`Preparation context SHA256: ${originalPin}.\n`, '')
87
+ : prompt + `Preparation context SHA256: ${originalPin}.\n`;
88
+ await assert.rejects(requestCodexSetupHostPreparation({ ...f.input, initialUserPrompt: value }));
89
+ assert.equal(f.calls, 0);
90
+ });
91
+ }
92
+ test('bounded server clock lead waits without weakening issued-at or expiry validation', async () => {
93
+ const f = fixture();
94
+ let localNow = now, waited = 0;
95
+ f.response.preparedAt = new Date(now + 2208).toISOString();
96
+ const result = await requestCodexSetupHostPreparation({ ...f.input, now: () => localNow,
97
+ ...{ sleep: async (ms) => { waited++; assert.equal(ms, 2208); localNow += ms; } } });
98
+ assert.equal(waited, 1);
99
+ assert.equal(result.intent.issuedAt, f.response.preparedAt);
100
+ assert.equal(f.calls, 1);
101
+ });
102
+ test('excessive server clock lead is rejected without sleeping or provider effects', async () => {
103
+ const f = fixture();
104
+ let waits = 0;
105
+ f.response.preparedAt = new Date(now + 5001).toISOString();
106
+ await assert.rejects(requestCodexSetupHostPreparation({ ...f.input,
107
+ ...{ sleep: async () => { waits++; } } }));
108
+ assert.equal(waits, 0);
109
+ assert.equal(f.calls, 1);
110
+ });
111
+ test('clock wait cancellation cannot authorize a future preparation', async () => {
112
+ const f = fixture(), control = new AbortController();
113
+ f.response.preparedAt = new Date(now + 1000).toISOString();
114
+ await assert.rejects(requestCodexSetupHostPreparation({ ...f.input, signal: control.signal,
115
+ ...{ sleep: async () => { control.abort(); } } }));
116
+ });
117
+ test('clipboard CRLF uses the same public digest while preserving actual native message bytes', async () => {
118
+ const f = fixture(), original = prompt.replace(/\n/g, '\r\n');
119
+ const result = await requestCodexSetupHostPreparation({ ...f.input, initialUserPrompt: original });
120
+ assert.equal(result.initialUserPrompt, original);
121
+ assert.equal(result.initialUserPromptSha256, createHash('sha256').update(original).digest('hex'));
122
+ assert.equal(result.promptSha256, createHash('sha256').update(prompt).digest('hex'));
123
+ });
124
+ for (const cause of ['origin', 'organization', 'reference', 'version', 'prompt-hash', 'recipient', 'repository', 'expired', 'effects', 'unknown']) {
125
+ test(`public preparation rejects ${cause} instead of accepting model-supplied binding`, async () => {
126
+ const f = fixture();
127
+ if (cause === 'origin')
128
+ f.response.context.origin = 'https://foreign.example';
129
+ if (cause === 'organization')
130
+ f.response.context.organizationId = 'org_foreign';
131
+ if (cause === 'reference')
132
+ f.response.context.setupReference = membership;
133
+ if (cause === 'version')
134
+ f.response.cliVersion = '0.2.191';
135
+ if (cause === 'prompt-hash')
136
+ f.response.promptSha256 = 'e'.repeat(64);
137
+ if (cause === 'recipient')
138
+ f.response.binding.recipientEmail = 'other@example.test';
139
+ if (cause === 'repository')
140
+ f.response.binding.repositoryRemoteUrl = 'https://github.com/other/source.git';
141
+ if (cause === 'expired')
142
+ f.response.expiresAt = new Date(now).toISOString();
143
+ if (cause === 'effects')
144
+ f.response.effects = true;
145
+ if (cause === 'unknown')
146
+ f.response.privateField = 'PRIVATE_CANARY';
147
+ await assert.rejects(requestCodexSetupHostPreparation(f.input));
148
+ });
149
+ }
150
+ test('a cancelled preparation makes no network request', async () => {
151
+ const f = fixture();
152
+ await assert.rejects(requestCodexSetupHostPreparation({ ...f.input, signal: AbortSignal.abort() }));
153
+ assert.equal(f.calls, 0);
154
+ });
155
+ for (const cause of ['http-error', 'invalid-json', 'oversized', 'foreign-redirect', 'vendor-error']) {
156
+ test(`transport ${cause} is bounded, not retried and never reflects a response or vendor exception`, async () => {
157
+ const f = fixture();
158
+ let calls = 0;
159
+ const fetcher = (async () => {
160
+ calls++;
161
+ if (cause === 'vendor-error')
162
+ throw Error('PRIVATE_VENDOR_EXCEPTION');
163
+ if (cause === 'http-error')
164
+ return new Response('PRIVATE_RESPONSE', { status: 403 });
165
+ if (cause === 'foreign-redirect')
166
+ return new Response('', { status: 302, headers: { location: 'https://foreign.example' } });
167
+ return new Response(cause === 'invalid-json' ? 'PRIVATE_INVALID_RESPONSE' : 'x'.repeat(65537), { headers: { 'content-type': 'application/json' } });
168
+ });
169
+ await assert.rejects(requestCodexSetupHostPreparation({ ...f.input, fetcher }), error => error instanceof Error && error.message === 'codex_setup_portal_preparation_unavailable');
170
+ assert.equal(calls, 1);
171
+ });
172
+ }
173
+ //# sourceMappingURL=codexSetupPortalPreparation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPortalPreparation.test.js","sourceRoot":"","sources":["../src/codexSetupPortalPreparation.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,EAAC,YAAY,EAAC,MAAM,wCAAwC,CAAC;AACpE,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAC,gCAAgC,EAAC,MAAM,kCAAkC,CAAC;AAElF,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;AACnD,MAAM,SAAS,GAAG,sCAAsC,CAAC;AACzD,MAAM,UAAU,GAAG,sCAAsC,CAAC;AAC1D,MAAM,OAAO,GAAG,EAAC,cAAc,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,0CAA0C,EAAC,CAAC;AAC5H,MAAM,WAAW,GAAG,UAAU,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;AAC/C,MAAM,OAAO,GAAG,EAAC,MAAM,EAAE,0BAA0B,EAAE,cAAc,EAAE,aAAa;IAChF,cAAc,EAAE,SAAS,EAAE,qBAAqB,EAAE,UAAU,EAAE,qBAAqB,EAAE,WAAW;IAChG,cAAc,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,UAAU,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAC,CAAC;AACpH,MAAM,WAAW,GAAG,CAAC,KAAkF,EAAE,EAAE,CACzG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;IAChF,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO;CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9H,MAAM,WAAW,GAAG,WAAW,CAAC,EAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,0BAA0B,EAAE,OAAO,EAAE,OAAO,EAAC,CAAC,CAAC;AAClH,MAAM,MAAM,GAAG,wDAAwD;MACnE,cAAc,OAAO,CAAC,cAAc,gCAAgC;MACpE,wBAAwB,OAAO,CAAC,mBAAmB,kBAAkB,WAAW,KAAK;MACrF,2BAA2B,SAAS,6CAA6C;MACjF,+BAA+B,WAAW,KAAK,CAAC;AACpD,SAAS,OAAO;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,QAAQ,GAAG,EAAC,MAAM,EAAE,kCAAkC,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK;QACpF,aAAa,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI;QAC3E,UAAU,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,0BAA0B;QAC9E,YAAY,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,SAAS;QACtF,OAAO,EAAE,EAAC,GAAG,OAAO,EAAC,EAAE,OAAO,EAAE,EAAC,GAAG,OAAO,EAAC;QAC5C,SAAS,EAAE,EAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,WAAW,EAAC,EAAC,CAAC;IAC3H,MAAM,KAAK,GAAG,EAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc,EAAE,SAAS;QACtG,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAiB,EAAE,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG;QACjH,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;YAC/B,KAAK,EAAE,CAAC;YACR,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,oEAAoE,CAAC,CAAC;YAChG,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YACzC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,EAAC,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa;gBACxG,cAAc,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAC,CAAC,CAAC;YAC/F,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;YAC3C,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAC,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC,EAAC,CAAC,CAAC;QACjG,CAAC,CAAiB,EAAC,CAAC;IACtB,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,KAAK,KAAI,OAAO,KAAK,CAAC,CAAA,CAAC,EAAC,CAAC;AACxD,CAAC;AACD,IAAI,CAAC,iGAAiG,EAAE,KAAK,IAAI,EAAE;IACjH,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,MAAM,gCAAgC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAC/D,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,SAAS,CAAE,MAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,CAAC,KAAK,CAAE,MAAc,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IACxD,MAAM,CAAC,KAAK,CAAE,MAAc,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;AACxD,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;IACjF,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAA8B,CAAC;IACnH,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,gCAAgC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAC;AACnG,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;IAC1E,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,GAAG,MAAM,EAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;IAClF,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnE,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM,EAAC,CAAC,CAAC,CAAC;IACzG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AACH,KAAK,MAAM,KAAK,IAAI,CAAC,uBAAuB,EAAE,gBAAgB,EAAE,aAAa,EAAE,gBAAgB,CAAU,EAAE,CAAC;IAC1G,IAAI,CAAC,8EAA8E,KAAK,EAAE,EAAE,KAAK,IAAI,EAAE;QACrG,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,IAAI,KAAK,KAAK,uBAAuB;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC;aACxE,IAAI,KAAK,KAAK,gBAAgB;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC;;YAC7E,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5D,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC7D,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,qDAAqD,CAAC,CAAC;QACvH,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC;AACD,KAAK,MAAM,MAAM,IAAI,CAAC,SAAS,EAAE,WAAW,CAAU,EAAE,CAAC;IACvD,IAAI,CAAC,KAAK,MAAM,uDAAuD,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,+BAA+B,WAAW,KAAK,EAAE,EAAE,CAAC;YACtG,CAAC,CAAC,MAAM,GAAG,+BAA+B,WAAW,KAAK,CAAC;QAC7D,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAC,CAAC,CAAC,CAAC;QAC/F,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AACL,CAAC;AACD,IAAI,CAAC,kFAAkF,EAAE,KAAK,IAAI,EAAE;IAClG,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IAAC,IAAI,QAAQ,GAAG,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC;IACpD,CAAC,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,MAAM,MAAM,GAAG,MAAM,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ;QACpF,GAAG,EAAC,KAAK,EAAE,KAAK,EAAE,EAAU,EAAE,EAAE,GAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAA,CAAC,EAAC,EAAC,CAAC,CAAC;IAC1F,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACjH,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;IAC9F,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IAAC,IAAI,KAAK,GAAG,CAAC,CAAC;IACnC,CAAC,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK;QAC/D,GAAG,EAAC,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,KAAK,EAAE,CAAC,CAAA,CAAC,EAAC,EAAC,CAAC,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACnD,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;IAC/E,MAAM,CAAC,GAAG,OAAO,EAAE,EAAE,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;IACrD,CAAC,CAAC,QAAQ,CAAC,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM;QACvF,GAAG,EAAC,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA,CAAC,EAAC,EAAC,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AACH,IAAI,CAAC,yFAAyF,EAAE,KAAK,IAAI,EAAE;IACzG,MAAM,CAAC,GAAG,OAAO,EAAE,EAAE,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAG,MAAM,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAC,CAAC,CAAC;IACjG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;IACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,uBAAuB,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAClG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC;AACH,KAAK,MAAM,KAAK,IAAI,CAAC,QAAQ,EAAE,cAAc,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAU,EAAE,CAAC;IAC3J,IAAI,CAAC,8BAA8B,KAAK,8CAA8C,EAAE,KAAK,IAAI,EAAE;QACjG,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,IAAI,KAAK,KAAK,QAAQ;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,yBAAyB,CAAC;QAC9E,IAAI,KAAK,KAAK,cAAc;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,GAAG,aAAa,CAAC;QAChF,IAAI,KAAK,KAAK,WAAW;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,GAAG,UAAU,CAAC;QAC1E,IAAI,KAAK,KAAK,SAAS;YAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAC;QAC3D,IAAI,KAAK,KAAK,aAAa;YAAE,CAAC,CAAC,QAAQ,CAAC,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACtE,IAAI,KAAK,KAAK,WAAW;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,GAAG,oBAAoB,CAAC;QACpF,IAAI,KAAK,KAAK,YAAY;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,mBAAmB,GAAG,qCAAqC,CAAC;QAC3G,IAAI,KAAK,KAAK,SAAS;YAAE,CAAC,CAAC,QAAQ,CAAC,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5E,IAAI,KAAK,KAAK,SAAS;YAAE,CAAC,CAAC,QAAQ,CAAC,OAAO,GAAG,IAAI,CAAC;QACnD,IAAI,KAAK,KAAK,SAAS;YAAG,CAAC,CAAC,QAAoC,CAAC,YAAY,GAAG,gBAAgB,CAAC;QACjG,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC;AACD,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;IAClE,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;IACpB,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,KAAK,EAAE,EAAC,CAAC,CAAC,CAAC;IAClG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AACH,KAAK,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,EAAE,cAAc,CAAU,EAAE,CAAC;IAC7G,IAAI,CAAC,aAAa,KAAK,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC9G,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QAAC,IAAI,KAAK,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;YAC1B,KAAK,EAAE,CAAC;YACR,IAAI,KAAK,KAAK,cAAc;gBAAE,MAAM,KAAK,CAAC,0BAA0B,CAAC,CAAC;YACtE,IAAI,KAAK,KAAK,YAAY;gBAAE,OAAO,IAAI,QAAQ,CAAC,kBAAkB,EAAE,EAAC,MAAM,EAAE,GAAG,EAAC,CAAC,CAAC;YACnF,IAAI,KAAK,KAAK,kBAAkB;gBAAE,OAAO,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,EAAC,QAAQ,EAAE,yBAAyB,EAAC,EAAC,CAAC,CAAC;YACzH,OAAO,IAAI,QAAQ,CAAC,KAAK,KAAK,cAAc,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAC3F,EAAC,OAAO,EAAE,EAAC,cAAc,EAAE,kBAAkB,EAAC,EAAC,CAAC,CAAC;QACrD,CAAC,CAAiB,CAAC;QACnB,MAAM,MAAM,CAAC,OAAO,CAAC,gCAAgC,CAAC,EAAC,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,EAAC,CAAC,EAC1E,KAAK,CAAC,EAAE,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,4CAA4C,CAAC,CAAC;QACrG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codexSetupPortalPrompt.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPortalPrompt.test.d.ts","sourceRoot":"","sources":["../src/codexSetupPortalPrompt.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,141 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createHash } from 'node:crypto';
3
+ import { createServer } from 'node:http';
4
+ import { once } from 'node:events';
5
+ import { canonicalize } from '@dharma-ai-labs/agent-fabric-contracts';
6
+ import test from 'node:test';
7
+ import { requestCodexSetupHostPreparation } from './codexSetupPortalPreparation.js';
8
+ const now = Date.parse('2030-01-01T00:00:00.000Z'), expiresAt = '2030-01-01T00:15:00.000Z';
9
+ const context = { origin: 'https://www.dharma-ai.io', organizationId: 'org_fixture',
10
+ setupReference: '11111111-1111-4111-8111-111111111111', recipientMembershipId: '22222222-2222-4222-8222-222222222222',
11
+ repositoryFingerprint: 'sha256:' + 'a'.repeat(64), policyRevision: 'policy-v1', scopeDigest: 'sha256:' + 'b'.repeat(64), contractDigest: 'sha256:' + 'c'.repeat(64) };
12
+ const binding = { recipientEmail: 'synthetic@example.test', repositoryRemoteUrl: 'https://github.com/example/synthetic.git' };
13
+ const pin = createHash('sha256').update('dharma.setup-host-context/v1\0').update(canonicalize({ cliVersion: '0.2.192', expiresAt, binding, context })).digest('hex');
14
+ const template = '# Dharma Agent Fabric \u2014 one-prompt source setup\n'
15
+ + `Recipient: ${binding.recipientEmail}. Organization: ${context.organizationId}.\n`
16
+ + `Selected repository: ${binding.repositoryRemoteUrl}. Fingerprint: ${context.repositoryFingerprint}.\n`
17
+ + `Public setup reference: ${context.setupReference}. Fixed expiry: ${expiresAt}.\n`
18
+ + `Preparation context SHA256: ${pin}.\n`
19
+ + 'dharma setup codex --portal-prompt-sha256 ' + '0'.repeat(64) + '\n';
20
+ const portalDigest = createHash('sha256').update(template).digest('hex');
21
+ const prompt = template.replace('--portal-prompt-sha256 ' + '0'.repeat(64), '--portal-prompt-sha256 ' + portalDigest);
22
+ function fixture() {
23
+ let calls = 0;
24
+ const response = { schema: 'dharma.setup-host-preparation/v2', ok: true, effects: false, grantRedeemed: false,
25
+ approvalRequired: true, sourcePolicyRevalidated: true, preparedAt: new Date(now).toISOString(), expiresAt,
26
+ promptSha256: createHash('sha256').update(prompt).digest('hex'), cliVersion: '0.2.192', binding: { ...binding }, context: { ...context },
27
+ integrity: { algorithm: 'sha256', kind: 'portal-context', authenticity: 'same-origin-https', contextSha256: pin },
28
+ publicPrompt: prompt, promptSource: 'portal_setup_prompt', portalPromptSha256: portalDigest };
29
+ const input = { origin: context.origin, organizationId: context.organizationId, setupReference: context.setupReference,
30
+ cliVersion: '0.2.192', portalContextSha256: pin, portalPromptSha256: portalDigest,
31
+ signal: new AbortController().signal, now: () => now,
32
+ fetcher: async (url, options) => {
33
+ calls++;
34
+ assert.equal(String(url), context.origin + '/api/v1/agent-fabric/bootstrap/setup-claim');
35
+ assert.equal(options.redirect, 'error');
36
+ assert.equal(options.credentials, 'omit');
37
+ assert.deepEqual(JSON.parse(options.body), { action: 'prepare_host', organizationId: context.organizationId,
38
+ setupReference: context.setupReference, promptSource: 'portal_setup_prompt', contextSha256: pin, portalPromptSha256: portalDigest });
39
+ return new Response(JSON.stringify(response), { headers: { 'content-type': 'application/json' } });
40
+ } };
41
+ return { input, response, get calls() { return calls; } };
42
+ }
43
+ test('canonical portal input is fetched without reading stdin or private native history', async () => {
44
+ const f = fixture(), value = await requestCodexSetupHostPreparation(f.input);
45
+ assert.equal(f.calls, 1);
46
+ assert.equal(value.initialUserPrompt, prompt);
47
+ assert.equal(value.promptProvenance, 'verified_portal_prompt');
48
+ assert.equal(value.nativeOriginalUserPromptAttested, false);
49
+ assert.equal(value.portalContextSha256, pin);
50
+ assert.equal(value.effects, false);
51
+ assert.equal(value.grantRedeemed, false);
52
+ });
53
+ test('the actual client parses canonical portal input over a real HTTP fixture', async () => {
54
+ const f = fixture();
55
+ let requests = 0;
56
+ const server = createServer(async (incoming, outgoing) => {
57
+ const chunks = [];
58
+ for await (const chunk of incoming)
59
+ chunks.push(Buffer.from(chunk));
60
+ const body = JSON.parse(Buffer.concat(chunks).toString('utf8'));
61
+ requests++;
62
+ assert.equal(body.promptSource, 'portal_setup_prompt');
63
+ assert.equal(body.contextSha256, pin);
64
+ assert.equal(body.portalPromptSha256, portalDigest);
65
+ assert.equal('promptSha256' in body, false);
66
+ outgoing.writeHead(200, { 'Content-Type': 'application/json', 'Cache-Control': 'no-store' });
67
+ outgoing.end(JSON.stringify(f.response));
68
+ });
69
+ try {
70
+ server.listen(0, '127.0.0.1');
71
+ await once(server, 'listening');
72
+ const address = server.address();
73
+ assert.ok(address && typeof address !== 'string');
74
+ // Inject only a loopback test transport. Production still requires HTTPS;
75
+ // this test qualifies serialization/parser compatibility, not TLS trust.
76
+ const result = await requestCodexSetupHostPreparation({ ...f.input, fetcher: async (url, options) => {
77
+ assert.equal(String(url), context.origin + '/api/v1/agent-fabric/bootstrap/setup-claim');
78
+ return fetch(`http://127.0.0.1:${address.port}/api/v1/agent-fabric/bootstrap/setup-claim`, options);
79
+ } });
80
+ assert.equal(result.initialUserPrompt, prompt);
81
+ assert.equal(result.promptProvenance, 'verified_portal_prompt');
82
+ assert.equal(result.nativeOriginalUserPromptAttested, false);
83
+ assert.equal(requests, 1);
84
+ }
85
+ finally {
86
+ server.closeAllConnections();
87
+ if (server.listening)
88
+ await new Promise((resolve, reject) => server.close(error => error ? reject(error) : resolve()));
89
+ }
90
+ });
91
+ for (const cause of ['missing-pin', 'bad-digest', 'conflicting-stdin', 'cancelled']) {
92
+ test('invalid portal-input ' + cause + ' stops before any request', async () => {
93
+ const f = fixture();
94
+ if (cause === 'missing-pin')
95
+ delete f.input.portalContextSha256;
96
+ if (cause === 'bad-digest')
97
+ f.input.portalPromptSha256 = 'not-a-digest';
98
+ if (cause === 'conflicting-stdin')
99
+ f.input.initialUserPrompt = prompt;
100
+ if (cause === 'cancelled')
101
+ f.input.signal = AbortSignal.abort();
102
+ await assert.rejects(requestCodexSetupHostPreparation(f.input));
103
+ assert.equal(f.calls, 0);
104
+ });
105
+ }
106
+ for (const cause of ['prompt-change', 'embedded-digest', 'context-change', 'secret', 'oversized', 'foreign-org', 'foreign-reference', 'expired', 'wrong-source', 'v1-downgrade', 'extra-field']) {
107
+ test('portal-input ' + cause + ' is rejected without reflecting response data', async () => {
108
+ const f = fixture();
109
+ if (cause === 'prompt-change') {
110
+ f.response.publicPrompt += 'Unexpected instruction\n';
111
+ f.response.promptSha256 = createHash('sha256').update(f.response.publicPrompt).digest('hex');
112
+ }
113
+ if (cause === 'embedded-digest') {
114
+ f.response.publicPrompt = f.response.publicPrompt.replace('--portal-prompt-sha256 ' + portalDigest, '--portal-prompt-sha256 ' + 'e'.repeat(64));
115
+ f.response.promptSha256 = createHash('sha256').update(f.response.publicPrompt).digest('hex');
116
+ }
117
+ if (cause === 'context-change') {
118
+ f.response.context.policyRevision = 'changed';
119
+ f.response.integrity.contextSha256 = 'e'.repeat(64);
120
+ }
121
+ if (cause === 'secret')
122
+ f.response.publicPrompt += 'dhab_SYNTHETIC_PRIVATE_CANARY';
123
+ if (cause === 'oversized')
124
+ f.response.publicPrompt += 'x'.repeat(32768);
125
+ if (cause === 'foreign-org')
126
+ f.response.context.organizationId = 'org_foreign';
127
+ if (cause === 'foreign-reference')
128
+ f.response.context.setupReference = context.recipientMembershipId;
129
+ if (cause === 'expired')
130
+ f.response.expiresAt = new Date(now).toISOString();
131
+ if (cause === 'wrong-source')
132
+ f.response.promptSource = 'original_user_message';
133
+ if (cause === 'v1-downgrade')
134
+ f.response.schema = 'dharma.setup-host-preparation/v1';
135
+ if (cause === 'extra-field')
136
+ f.response.credential = 'PRIVATE_CANARY';
137
+ await assert.rejects(requestCodexSetupHostPreparation(f.input), error => error instanceof Error && error.message === 'codex_setup_portal_preparation_unavailable');
138
+ assert.equal(f.calls, 1);
139
+ });
140
+ }
141
+ //# sourceMappingURL=codexSetupPortalPrompt.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPortalPrompt.test.js","sourceRoot":"","sources":["../src/codexSetupPortalPrompt.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** The single public checksum argument is zeroed to avoid a self-referential digest. */
2
+ export declare function codexSetupPortalPromptDigest(value: unknown): string;
3
+ //# sourceMappingURL=codexSetupPortalPromptDigest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPortalPromptDigest.d.ts","sourceRoot":"","sources":["../src/codexSetupPortalPromptDigest.ts"],"names":[],"mappings":"AAEA,wFAAwF;AACxF,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAWnE"}
@@ -0,0 +1,18 @@
1
+ import { createHash } from 'node:crypto';
2
+ /** The single public checksum argument is zeroed to avoid a self-referential digest. */
3
+ export function codexSetupPortalPromptDigest(value) {
4
+ const invalid = () => { throw new Error('codex_setup_public_prompt_invalid'); };
5
+ if (typeof value !== 'string' || !value || Buffer.byteLength(value) > 32768
6
+ || Buffer.from(value, 'utf8').toString('utf8') !== value
7
+ || /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f]/.test(value))
8
+ return invalid();
9
+ const text = value.replace(/\r\n/g, '\n');
10
+ if ([...text.matchAll(/--portal-prompt-sha256\b/g)].length !== 1)
11
+ return invalid();
12
+ const matches = [...text.matchAll(/--portal-prompt-sha256 ([a-f0-9]{64})(?=[ \t\n]|$)/g)];
13
+ if (matches.length !== 1)
14
+ return invalid();
15
+ const match = matches[0], at = match.index + match[0].length - 64;
16
+ return createHash('sha256').update(text.slice(0, at) + '0'.repeat(64) + text.slice(at + 64), 'utf8').digest('hex');
17
+ }
18
+ //# sourceMappingURL=codexSetupPortalPromptDigest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPortalPromptDigest.js","sourceRoot":"","sources":["../src/codexSetupPortalPromptDigest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AAEvC,wFAAwF;AACxF,MAAM,UAAU,4BAA4B,CAAC,KAAc;IACzD,MAAM,OAAO,GAAC,GAAQ,EAAE,GAAC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAA,CAAC,CAAC;IAChF,IAAG,OAAO,KAAK,KAAG,QAAQ,IAAE,CAAC,KAAK,IAAE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,GAAC,KAAK;WAC9D,MAAM,CAAC,IAAI,CAAC,KAAK,EAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAG,KAAK;WAClD,gDAAgD,CAAC,IAAI,CAAC,KAAK,CAAC;QAAC,OAAO,OAAO,EAAE,CAAC;IAClF,MAAM,IAAI,GAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAC,IAAI,CAAC,CAAC;IACvC,IAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC,CAAC,MAAM,KAAG,CAAC;QAAC,OAAO,OAAO,EAAE,CAAC;IAC/E,MAAM,OAAO,GAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,qDAAqD,CAAC,CAAC,CAAC;IACxF,IAAG,OAAO,CAAC,MAAM,KAAG,CAAC;QAAC,OAAO,OAAO,EAAE,CAAC;IACvC,MAAM,KAAK,GAAC,OAAO,CAAC,CAAC,CAAE,EAAC,EAAE,GAAC,KAAK,CAAC,KAAM,GAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAC,EAAE,CAAC;IAC3D,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAC,EAAE,CAAC,GAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAC,EAAE,CAAC,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC7G,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codexSetupPortalPromptDigest.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPortalPromptDigest.test.d.ts","sourceRoot":"","sources":["../src/codexSetupPortalPromptDigest.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createHash } from 'node:crypto';
3
+ import test from 'node:test';
4
+ import { codexSetupPortalPromptDigest } from './codexSetupPortalPromptDigest.js';
5
+ const empty = '0'.repeat(64);
6
+ const template = '# Public setup specification\nRun the official entry --portal-prompt-sha256 ' + empty + '\n';
7
+ const expected = createHash('sha256').update(template).digest('hex');
8
+ test('portal prompt checksum masks only its single checksum argument, not other instructions', () => {
9
+ assert.equal(codexSetupPortalPromptDigest(template), expected);
10
+ const filled = template.replace(empty, expected);
11
+ assert.equal(codexSetupPortalPromptDigest(filled), expected);
12
+ assert.equal(codexSetupPortalPromptDigest(filled.replaceAll('\n', '\r\n')), expected);
13
+ assert.notEqual(codexSetupPortalPromptDigest(filled.replace('official', 'foreign')), expected);
14
+ assert.notEqual(codexSetupPortalPromptDigest(filled + 'Extra instruction\n'), expected);
15
+ });
16
+ for (const value of [null, '', template.replace('--portal-prompt-sha256 ', '--unknown '),
17
+ template + template, template.replace(empty, 'g'.repeat(64)), template.replace(empty, empty + 'a'),
18
+ template.replace(empty, empty + '\0'), template + 'x'.repeat(32768)]) {
19
+ test('malformed or ambiguous checksum input is not accepted: ' + String(value).slice(0, 45), () => {
20
+ assert.throws(() => codexSetupPortalPromptDigest(value), /^Error: codex_setup_public_prompt_invalid$/);
21
+ });
22
+ }
23
+ //# sourceMappingURL=codexSetupPortalPromptDigest.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPortalPromptDigest.test.js","sourceRoot":"","sources":["../src/codexSetupPortalPromptDigest.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAC,4BAA4B,EAAC,MAAM,mCAAmC,CAAC;AAE/E,MAAM,KAAK,GAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC3B,MAAM,QAAQ,GAAC,8EAA8E,GAAC,KAAK,GAAC,IAAI,CAAC;AACzG,MAAM,QAAQ,GAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnE,IAAI,CAAC,wFAAwF,EAAC,GAAE,EAAE;IAChG,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,QAAQ,CAAC,EAAC,QAAQ,CAAC,CAAC;IAC9D,MAAM,MAAM,GAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,MAAM,CAAC,EAAC,QAAQ,CAAC,CAAC;IAC5D,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAC,MAAM,CAAC,CAAC,EAAC,QAAQ,CAAC,CAAC;IACpF,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU,EAAC,SAAS,CAAC,CAAC,EAAC,QAAQ,CAAC,CAAC;IAC7F,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAC,MAAM,GAAC,qBAAqB,CAAC,EAAC,QAAQ,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC;AACH,KAAI,MAAM,KAAK,IAAI,CAAC,IAAI,EAAC,EAAE,EAAC,QAAQ,CAAC,OAAO,CAAC,yBAAyB,EAAC,YAAY,CAAC;IAClF,QAAQ,GAAC,QAAQ,EAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAC,KAAK,GAAC,GAAG,CAAC;IAC1F,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAC,KAAK,GAAC,IAAI,CAAC,EAAC,QAAQ,GAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAC,CAAC;IAChE,IAAI,CAAC,yDAAyD,GAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAC,EAAE,CAAC,EAAC,GAAE,EAAE;QAC3F,MAAM,CAAC,MAAM,CAAC,GAAE,EAAE,CAAA,4BAA4B,CAAC,KAAK,CAAC,EAAC,4CAA4C,CAAC,CAAC;IACtG,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { Readable } from 'node:stream';
2
+ /** Agent-supplied public text only; never a terminal password/grant prompt. */
3
+ export declare function readCodexSetupPublicStdin(stream: Readable & {
4
+ isTTY?: boolean;
5
+ }, signal: AbortSignal): Promise<string>;
6
+ //# sourceMappingURL=codexSetupPublicStdin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPublicStdin.d.ts","sourceRoot":"","sources":["../src/codexSetupPublicStdin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAG1C,+EAA+E;AAC/E,wBAAsB,yBAAyB,CAAC,MAAM,EAAE,QAAQ,GAAG;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAqB1H"}
@@ -0,0 +1,36 @@
1
+ import { capturePublicCodexSetupPrompt } from './codexSetupUserPrompt.js';
2
+ /** Agent-supplied public text only; never a terminal password/grant prompt. */
3
+ export async function readCodexSetupPublicStdin(stream, signal) {
4
+ const fail = () => new Error('codex_setup_public_input_unavailable');
5
+ if (stream.isTTY || signal.aborted)
6
+ throw fail();
7
+ const deadline = AbortSignal.any([signal, AbortSignal.timeout(15000)]);
8
+ const cancel = () => stream.destroy(fail());
9
+ deadline.addEventListener('abort', cancel, { once: true });
10
+ const chunks = [];
11
+ let size = 0;
12
+ try {
13
+ for await (const chunk of stream) {
14
+ if (deadline.aborted)
15
+ throw fail();
16
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
17
+ size += bytes.length;
18
+ if (size > 32768)
19
+ throw fail();
20
+ chunks.push(bytes);
21
+ }
22
+ if (deadline.aborted)
23
+ throw fail();
24
+ const bytes = Buffer.concat(chunks), text = bytes.toString('utf8');
25
+ if (!Buffer.from(text, 'utf8').equals(bytes))
26
+ throw fail();
27
+ return capturePublicCodexSetupPrompt(text);
28
+ }
29
+ catch {
30
+ throw fail();
31
+ }
32
+ finally {
33
+ deadline.removeEventListener('abort', cancel);
34
+ }
35
+ }
36
+ //# sourceMappingURL=codexSetupPublicStdin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPublicStdin.js","sourceRoot":"","sources":["../src/codexSetupPublicStdin.ts"],"names":[],"mappings":"AACA,OAAO,EAAC,6BAA6B,EAAC,MAAM,2BAA2B,CAAC;AAExE,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,MAAoC,EAAE,MAAmB;IACvG,MAAM,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACrE,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO;QAAE,MAAM,IAAI,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5C,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAC,IAAI,EAAE,IAAI,EAAC,CAAC,CAAC;IACzD,MAAM,MAAM,GAAa,EAAE,CAAC;IAAC,IAAI,IAAI,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,IAAI,QAAQ,CAAC,OAAO;gBAAE,MAAM,IAAI,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAClE,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC;YACrB,IAAI,IAAI,GAAG,KAAK;gBAAE,MAAM,IAAI,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,QAAQ,CAAC,OAAO;YAAE,MAAM,IAAI,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,EAAE,CAAC;QAC3D,OAAO,6BAA6B,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QAAA,MAAM,IAAI,EAAE,CAAC;IAAA,CAAC;YACf,CAAC;QAAA,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAAA,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=codexSetupPublicStdin.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPublicStdin.test.d.ts","sourceRoot":"","sources":["../src/codexSetupPublicStdin.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ import assert from 'node:assert/strict';
2
+ import { PassThrough, Readable } from 'node:stream';
3
+ import test from 'node:test';
4
+ import { readCodexSetupPublicStdin } from './codexSetupPublicStdin.js';
5
+ const prompt = '# Public setup\r\nOriginal text is preserved.\n';
6
+ test('public stdin preserves valid original bytes across chunks without echo or file transport', async () => {
7
+ const stream = Readable.from([Buffer.from(prompt.slice(0, 8)), Buffer.from(prompt.slice(8))]);
8
+ assert.equal(await readCodexSetupPublicStdin(stream, new AbortController().signal), prompt);
9
+ });
10
+ for (const reason of ['tty', 'cancelled']) {
11
+ test(`public stdin refuses ${reason} before reading`, async () => {
12
+ let reads = 0;
13
+ const stream = new Readable({ read() { reads++; this.push(null); } });
14
+ const control = new AbortController();
15
+ if (reason === 'tty')
16
+ stream.isTTY = true;
17
+ else
18
+ control.abort();
19
+ await assert.rejects(readCodexSetupPublicStdin(stream, control.signal), /^Error: codex_setup_public_input_unavailable$/);
20
+ assert.equal(reads, 0);
21
+ });
22
+ }
23
+ for (const [reason, bytes] of [
24
+ ['oversized', Buffer.alloc(32769, 97)], ['invalid-utf8', Buffer.from([0xc3, 0x28])],
25
+ ['empty', Buffer.alloc(0)], ['credential', Buffer.from(['dhab', 'synthetic', 'never-real'].join('_'))],
26
+ ]) {
27
+ test(`public stdin rejects ${reason} with a constant non-disclosing result`, async () => {
28
+ await assert.rejects(readCodexSetupPublicStdin(Readable.from([bytes]), new AbortController().signal), /^Error: codex_setup_public_input_unavailable$/);
29
+ });
30
+ }
31
+ test('cancellation destroys only the owned waiting public input stream', async () => {
32
+ const stream = new PassThrough(), other = new PassThrough(), control = new AbortController();
33
+ const reading = readCodexSetupPublicStdin(stream, control.signal);
34
+ control.abort();
35
+ await assert.rejects(reading, /^Error: codex_setup_public_input_unavailable$/);
36
+ assert.equal(stream.destroyed, true);
37
+ assert.equal(other.destroyed, false);
38
+ other.destroy();
39
+ });
40
+ //# sourceMappingURL=codexSetupPublicStdin.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codexSetupPublicStdin.test.js","sourceRoot":"","sources":["../src/codexSetupPublicStdin.test.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,8 @@ export type CodexSetupPromptBinding = Readonly<{
5
5
  }>;
6
6
  /** Public fields captured from the independently verified recipient/selection. */
7
7
  export declare function captureCodexSetupPromptBinding(value: unknown): CodexSetupPromptBinding;
8
+ /** Reject credential-bearing public prose before network or persistence. */
9
+ export declare function capturePublicCodexSetupPrompt(value: unknown): string;
8
10
  /** Presentation consistency only. The original host intent and lease, never
9
11
  * model-visible prose, remain the authority for every protected setup effect. */
10
12
  export declare function captureCodexSetupUserPrompt(value: unknown, intent: Readonly<CodexSetupIntent>, suppliedBinding?: unknown): string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"codexSetupUserPrompt.d.ts","sourceRoot":"","sources":["../src/codexSetupUserPrompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAI/D,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAEtG,kFAAkF;AAClF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CAmBtF;AAED;iFACiF;AACjF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CA4B7I"}
1
+ {"version":3,"file":"codexSetupUserPrompt.d.ts","sourceRoot":"","sources":["../src/codexSetupUserPrompt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAI/D,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAAC,cAAc,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAA;CAAC,CAAC,CAAC;AAEtG,kFAAkF;AAClF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CAmBtF;AAED,4EAA4E;AAC5E,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAepE;AAED;iFACiF;AACjF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,eAAe,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAiB7I"}
@@ -29,11 +29,8 @@ export function captureCodexSetupPromptBinding(value) {
29
29
  }
30
30
  return Object.freeze({ recipientEmail, repositoryRemoteUrl });
31
31
  }
32
- /** Presentation consistency only. The original host intent and lease, never
33
- * model-visible prose, remain the authority for every protected setup effect. */
34
- export function captureCodexSetupUserPrompt(value, intent, suppliedBinding) {
35
- if (value === undefined)
36
- return undefined;
32
+ /** Reject credential-bearing public prose before network or persistence. */
33
+ export function capturePublicCodexSetupPrompt(value) {
37
34
  const invalid = () => { throw new Error('codex_setup_public_prompt_invalid'); };
38
35
  if (typeof value !== 'string' || !value || Buffer.byteLength(value, 'utf8') > 32_768
39
36
  || Buffer.from(value, 'utf8').toString('utf8') !== value
@@ -49,7 +46,16 @@ export function captureCodexSetupUserPrompt(value, intent, suppliedBinding) {
49
46
  || /\b(?:gh[pousr]_|github_pat_|sk_live_|sk_test_)[A-Za-z0-9_]{12,}|\bBearer\s+[A-Za-z0-9_.+-]{8,}/i.test(value)
50
47
  || /\b[A-Za-z0-9_]*(?:password|passwd|secret|api_key|access_token|refresh_token|credentials?|token)(?:_[A-Za-z0-9_]+)?["']?\s*[:=]\s*["']?[^\s"',;]+/i.test(value))
51
48
  return invalid();
52
- const binding = captureCodexSetupPromptBinding(suppliedBinding), lines = value.split(/\r?\n/);
49
+ return value;
50
+ }
51
+ /** Presentation consistency only. The original host intent and lease, never
52
+ * model-visible prose, remain the authority for every protected setup effect. */
53
+ export function captureCodexSetupUserPrompt(value, intent, suppliedBinding) {
54
+ if (value === undefined)
55
+ return undefined;
56
+ const prompt = capturePublicCodexSetupPrompt(value);
57
+ const invalid = () => { throw new Error('codex_setup_public_prompt_invalid'); };
58
+ const binding = captureCodexSetupPromptBinding(suppliedBinding), lines = prompt.split(/\r?\n/);
53
59
  const only = (prefix) => {
54
60
  const selected = lines.filter(line => line.startsWith(prefix));
55
61
  if (selected.length !== 1)
@@ -62,6 +68,6 @@ export function captureCodexSetupUserPrompt(value, intent, suppliedBinding) {
62
68
  || only('Public setup reference: ') !== `Public setup reference: ${intent.setupReference}. Fixed expiry: ${intent.expiresAt}.`) {
63
69
  return invalid();
64
70
  }
65
- return value;
71
+ return prompt;
66
72
  }
67
73
  //# sourceMappingURL=codexSetupUserPrompt.js.map