@dsh-enhanced/assistant-goals 0.1.67 → 0.1.68

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.
@@ -0,0 +1,158 @@
1
+ import { acceptanceDigest, acceptanceProtocolForTask, createTaskAcceptanceContract } from '@dsh-enhanced/task-acceptance-contract';
2
+ const HEX = /^[a-f0-9]{64}$/u;
3
+ const ID = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/u;
4
+ const PREPARER = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/u;
5
+ /**
6
+ * The published assistant-verifier build may predate the prepared-contract API,
7
+ * so Goals recognizes it structurally instead of requiring a rebuilt .d.ts.
8
+ * A registration without the method is a fail-closed older peer.
9
+ */
10
+ export function preparedRegistration(registration) {
11
+ const candidate = registration;
12
+ return typeof candidate.prepareOwnerContract === 'function' ? candidate : undefined;
13
+ }
14
+ function fail(message) { throw new Error(`assistant-goals: ${message}`); }
15
+ const plain = (value) => value !== null && typeof value === 'object'
16
+ && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype && Object.getOwnPropertySymbols(value).length === 0;
17
+ const integer = (value, min = 0, max = Number.MAX_SAFE_INTEGER) => typeof value === 'number' && Number.isSafeInteger(value) && value >= min && value <= max;
18
+ const frozen = (value) => {
19
+ if (value !== null && typeof value === 'object') {
20
+ for (const child of Object.values(value))
21
+ frozen(child);
22
+ Object.freeze(value);
23
+ }
24
+ return value;
25
+ };
26
+ function bounds(value) {
27
+ if (!plain(value) || Object.keys(value).length !== 2 || !Object.hasOwn(value, 'maxDurationMs') || !Object.hasOwn(value, 'maxEvidenceBytes')
28
+ || !integer(value.maxDurationMs, 1, 300_000) || !integer(value.maxEvidenceBytes, 1, 1_048_576)) {
29
+ fail('owner acceptance bounds are invalid');
30
+ }
31
+ return frozen({ maxDurationMs: value.maxDurationMs, maxEvidenceBytes: value.maxEvidenceBytes });
32
+ }
33
+ function preparer(value) {
34
+ if (!plain(value) || Object.keys(value).length !== 2 || !Object.hasOwn(value, 'id') || !Object.hasOwn(value, 'digest')
35
+ || typeof value.id !== 'string' || !PREPARER.test(value.id) || typeof value.digest !== 'string' || !HEX.test(value.digest)) {
36
+ fail('owner acceptance preparer is invalid');
37
+ }
38
+ return frozen({ id: value.id, digest: value.digest });
39
+ }
40
+ function criteria(value, label) {
41
+ if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype || Object.getOwnPropertySymbols(value).length !== 0) {
42
+ fail(`owner acceptance ${label} are invalid`);
43
+ }
44
+ return frozen(value);
45
+ }
46
+ /** Reuse the shared wire validator so prepared criteria obey the same bounds as real contracts. */
47
+ function assertCriteria(criteriaValue, taskKind, boundsValue, objective) {
48
+ const definitionDigest = '0'.repeat(64);
49
+ const task = taskKind === 'goal-outcome'
50
+ ? { kind: 'goal-outcome', ref: 'owner-acceptance-validation', goal: { id: 'owner-acceptance', definitionVersion: 1,
51
+ definitionDigest, assessmentId: 'owner-acceptance-validation', sessionId: 'owner-acceptance', nativeGoalId: 'owner-acceptance' } }
52
+ : { kind: 'goal-step', ref: 'owner-acceptance-validation', goal: { id: 'owner-acceptance', definitionVersion: 1,
53
+ definitionDigest, stepId: 'owner-acceptance', runId: 'owner-acceptance-validation', sessionId: 'owner-acceptance',
54
+ nativeGoalId: 'owner-acceptance', nativeRevision: 1 } };
55
+ try {
56
+ createTaskAcceptanceContract({ protocol: acceptanceProtocolForTask(task, criteriaValue),
57
+ id: 'acceptance-owner-acceptance-validation', scope: { workspace: '/owner-acceptance', preset: 'primary' },
58
+ owner: { principalRecordId: 'owner-acceptance', principalVersion: 1 }, task,
59
+ objective: objective.length > 0 ? objective : 'owner acceptance',
60
+ profile: { id: 'owner-prepared', version: 1, digest: '0'.repeat(64) }, issuedAt: 0,
61
+ expiresAt: Math.max(1_000, boundsValue.maxDurationMs + 1), criteria: criteriaValue, bounds: boundsValue });
62
+ }
63
+ catch (error) {
64
+ fail(`owner acceptance criteria are invalid: ${error instanceof Error ? error.message : 'invalid criteria'}`);
65
+ }
66
+ }
67
+ /** Validate one Host-only seal request before any verifier or native side effect. */
68
+ export function validateOwnerPreparedAcceptanceInput(value, stepMaxDurationMs) {
69
+ if (!plain(value))
70
+ fail('owner acceptance input must be a plain object');
71
+ const keys = Object.keys(value);
72
+ if (keys.some(key => !['criteria', 'stepCriteria', 'bounds', 'validityMs', 'preparer'].includes(key))
73
+ || !Object.hasOwn(value, 'criteria') || !Object.hasOwn(value, 'bounds') || !Object.hasOwn(value, 'validityMs') || !Object.hasOwn(value, 'preparer')) {
74
+ fail('owner acceptance input has an invalid shape');
75
+ }
76
+ const criteriaValue = criteria(value.criteria, 'criteria');
77
+ const stepCriteriaValue = value.stepCriteria === undefined ? criteriaValue : criteria(value.stepCriteria, 'step criteria');
78
+ const boundsValue = bounds(value.bounds);
79
+ if (!integer(value.validityMs, 1_000, 86_400_000))
80
+ fail('owner acceptance validity is invalid');
81
+ const preparerValue = preparer(value.preparer);
82
+ const window = stepMaxDurationMs + 2 * boundsValue.maxDurationMs;
83
+ if (value.validityMs <= window)
84
+ fail('owner acceptance validity must cover the configured native round and verification');
85
+ assertCriteria(criteriaValue, 'goal-outcome', boundsValue, 'owner acceptance');
86
+ assertCriteria(stepCriteriaValue, 'goal-step', boundsValue, 'owner acceptance');
87
+ return frozen({ criteria: criteriaValue, stepCriteria: stepCriteriaValue, bounds: boundsValue, validityMs: value.validityMs, preparer: preparerValue });
88
+ }
89
+ export const NATURAL_LANGUAGE_PREPARER_ID = 'assistant-goals-owner-turn';
90
+ /**
91
+ * Resolve the model-proposed acceptance carried by the live owner goal_create
92
+ * call. Criteria remain a candidate proposal: the Goals wire/policy checks run
93
+ * here and the independent verifier decides decidability when sealing. The
94
+ * default validity covers the configured round plus verification and is bounded
95
+ * to the verifier's 1s-24h window.
96
+ */
97
+ export function resolveOwnerPreparedAcceptanceInput(value, stepMaxDurationMs) {
98
+ if (!plain(value))
99
+ fail('owner acceptance must be a plain object');
100
+ const keys = Object.keys(value);
101
+ if (keys.some(key => !['criteria', 'bounds', 'validity_ms'].includes(key))
102
+ || !Object.hasOwn(value, 'criteria') || !Object.hasOwn(value, 'bounds'))
103
+ fail('owner acceptance input has an invalid shape');
104
+ const boundsValue = bounds(value.bounds);
105
+ const validityMs = value.validity_ms === undefined
106
+ ? Math.min(Math.max(boundsValue.maxDurationMs + 60_000, 1_800_000), 86_400_000)
107
+ : value.validity_ms;
108
+ const criteriaValue = criteria(value.criteria, 'criteria');
109
+ return validateOwnerPreparedAcceptanceInput({
110
+ criteria: criteriaValue, bounds: boundsValue, validityMs,
111
+ preparer: { id: NATURAL_LANGUAGE_PREPARER_ID,
112
+ digest: acceptanceDigest({ protocol: 'assistant-goals/natural-language-acceptance/v1', criteria: criteriaValue, bounds: boundsValue }) },
113
+ }, stepMaxDurationMs);
114
+ }
115
+ /** Strict exact-key validation of one persisted seal; any drift fails closed. */
116
+ export function validateOwnerAcceptanceSeal(value) {
117
+ if (!plain(value))
118
+ fail('seal is invalid');
119
+ const keys = ['goalId', 'definition', 'objective', 'criteria', 'stepCriteria', 'bounds', 'validityMs', 'preparer', 'outcome', 'preparedProfileDigest', 'outcomeExpiresAt', 'at'];
120
+ if (Object.keys(value).length !== keys.length || !keys.every(key => Object.hasOwn(value, key)))
121
+ fail('seal has an invalid shape');
122
+ const goalId = value.goalId;
123
+ if (typeof goalId !== 'string' || !ID.test(goalId))
124
+ fail('seal goal identity is invalid');
125
+ if (!plain(value.definition) || Object.keys(value.definition).length !== 3 || !Object.hasOwn(value.definition, 'version')
126
+ || !Object.hasOwn(value.definition, 'digest') || !Object.hasOwn(value.definition, 'objective')
127
+ || !integer(value.definition.version, 1) || typeof value.definition.digest !== 'string' || !HEX.test(value.definition.digest)
128
+ || typeof value.definition.objective !== 'string' || value.definition.objective.length < 1 || value.definition.objective.length > 16_384
129
+ || value.definition.digest !== acceptanceDigest({ objective: value.definition.objective }))
130
+ fail('seal definition is invalid');
131
+ if (typeof value.objective !== 'string' || value.objective !== value.definition.objective)
132
+ fail('seal objective is invalid');
133
+ const criteriaValue = criteria(value.criteria, 'criteria');
134
+ const stepCriteriaValue = criteria(value.stepCriteria, 'step criteria');
135
+ const boundsValue = bounds(value.bounds);
136
+ if (!integer(value.validityMs, 1_000, 86_400_000))
137
+ fail('seal validity is invalid');
138
+ const preparerValue = preparer(value.preparer);
139
+ if (!plain(value.outcome) || Object.keys(value.outcome).length !== 2 || !Object.hasOwn(value.outcome, 'contractId')
140
+ || !Object.hasOwn(value.outcome, 'contractDigest') || typeof value.outcome.contractId !== 'string'
141
+ || !ID.test(value.outcome.contractId) || typeof value.outcome.contractDigest !== 'string' || !HEX.test(value.outcome.contractDigest)) {
142
+ fail('seal handle is invalid');
143
+ }
144
+ if (typeof value.preparedProfileDigest !== 'string' || !HEX.test(value.preparedProfileDigest))
145
+ fail('seal prepared profile digest is invalid');
146
+ if (!integer(value.outcomeExpiresAt) || !integer(value.at))
147
+ fail('seal timestamps are invalid');
148
+ if (value.outcomeExpiresAt <= value.at || value.outcomeExpiresAt - value.at > value.validityMs)
149
+ fail('seal expiry is invalid');
150
+ assertCriteria(criteriaValue, 'goal-outcome', boundsValue, value.definition.objective);
151
+ assertCriteria(stepCriteriaValue, 'goal-step', boundsValue, value.definition.objective);
152
+ return frozen(JSON.parse(JSON.stringify({
153
+ goalId, definition: value.definition, objective: value.objective, criteria: criteriaValue, stepCriteria: stepCriteriaValue,
154
+ bounds: boundsValue, validityMs: value.validityMs, preparer: preparerValue, outcome: value.outcome,
155
+ preparedProfileDigest: value.preparedProfileDigest, outcomeExpiresAt: value.outcomeExpiresAt, at: value.at,
156
+ })));
157
+ }
158
+ //# sourceMappingURL=owner-acceptance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-acceptance.js","sourceRoot":"","sources":["../src/owner-acceptance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,wCAAwC,CAAA;AAKlI,MAAM,GAAG,GAAG,iBAAiB,CAAA;AAC7B,MAAM,EAAE,GAAG,uCAAuC,CAAA;AAClD,MAAM,QAAQ,GAAG,uCAAuC,CAAA;AA+CxD;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,YAAwC;IAC3E,MAAM,SAAS,GAAG,YAA+E,CAAA;IACjG,OAAO,OAAO,SAAS,CAAC,oBAAoB,KAAK,UAAU,CAAC,CAAC,CAAC,SAAsC,CAAC,CAAC,CAAC,SAAS,CAAA;AAClH,CAAC;AAED,SAAS,IAAI,CAAC,OAAe,IAAW,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAA,CAAC,CAAC;AACxF,MAAM,KAAK,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;OAC1G,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAA;AACnI,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,gBAAgB,EAAmB,EAAE,CAC1F,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,GAAG,CAAA;AAC1F,MAAM,MAAM,GAAG,CAAI,KAAQ,EAAK,EAAE;IAChC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAAC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,KAAgC,CAAC;YAAE,MAAM,CAAC,KAAK,CAAC,CAAC;QAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAAC,CAAC;IAC7J,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,kBAAkB,CAAC;WACtI,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC;QACjG,IAAI,CAAC,qCAAqC,CAAC,CAAA;IAC7C,CAAC;IACD,OAAO,MAAM,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,CAAC,CAAA;AACjG,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc;IAC9B,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC;WACjH,OAAO,KAAK,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7H,IAAI,CAAC,sCAAsC,CAAC,CAAA;IAC9C,CAAC;IACD,OAAO,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAA;AACvD,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc,EAAE,KAAa;IAC7C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,SAAS,IAAI,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClI,IAAI,CAAC,oBAAoB,KAAK,cAAc,CAAC,CAAA;IAC/C,CAAC;IACD,OAAO,MAAM,CAAC,KAAuC,CAAC,CAAA;AACxD,CAAC;AAED,mGAAmG;AACnG,SAAS,cAAc,CAAC,aAA6C,EAAE,QAAsC,EAC3G,WAAgC,EAAE,SAAiB;IACnD,MAAM,gBAAgB,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IACvC,MAAM,IAAI,GAA2B,QAAQ,KAAK,cAAc;QAC9D,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,6BAA6B,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;gBAChH,gBAAgB,EAAE,YAAY,EAAE,6BAA6B,EAAE,SAAS,EAAE,kBAAkB,EAAE,YAAY,EAAE,kBAAkB,EAAE,EAAE;QACpI,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,6BAA6B,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;gBAC7G,gBAAgB,EAAE,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,6BAA6B,EAAE,SAAS,EAAE,kBAAkB;gBACjH,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,CAAC,EAAE,EAAE,CAAA;IAC3D,IAAI,CAAC;QACH,4BAA4B,CAAC,EAAE,QAAQ,EAAE,yBAAyB,CAAC,IAAI,EAAE,aAAa,CAAC;YACrF,EAAE,EAAE,wCAAwC,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,EAAE,SAAS,EAAE;YAC1G,KAAK,EAAE,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC,EAAE,EAAE,IAAI;YAC3E,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB;YAChE,OAAO,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC;YAClF,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,aAAa,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAA;IAC9G,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,0CAA0C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAA;IAC/G,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,oCAAoC,CAAC,KAAc,EAAE,iBAAyB;IAC5F,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,+CAA+C,CAAC,CAAA;IACxE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;WAChG,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;QACtJ,IAAI,CAAC,6CAA6C,CAAC,CAAA;IACrD,CAAC;IACD,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC1D,MAAM,iBAAiB,GAAG,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,EAAE,eAAe,CAAC,CAAA;IAC1H,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC;QAAE,IAAI,CAAC,sCAAsC,CAAC,CAAA;IAC/F,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC9C,MAAM,MAAM,GAAG,iBAAiB,GAAG,CAAC,GAAG,WAAW,CAAC,aAAa,CAAA;IAChE,IAAI,KAAK,CAAC,UAAU,IAAI,MAAM;QAAE,IAAI,CAAC,mFAAmF,CAAC,CAAA;IACzH,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAA;IAC9E,cAAc,CAAC,iBAAiB,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAA;IAC/E,OAAO,MAAM,CAAC,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAA;AACzJ,CAAC;AAED,MAAM,CAAC,MAAM,4BAA4B,GAAG,4BAA4B,CAAA;AAExE;;;;;;GAMG;AACH,MAAM,UAAU,mCAAmC,CAAC,KAAc,EAAE,iBAAyB;IAC3F,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,yCAAyC,CAAC,CAAA;IAClE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC/B,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;WACrE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC;QAAE,IAAI,CAAC,6CAA6C,CAAC,CAAA;IAC9H,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACxC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,KAAK,SAAS;QAChD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,aAAa,GAAG,MAAM,EAAE,SAAS,CAAC,EAAE,UAAU,CAAC;QAC/E,CAAC,CAAC,KAAK,CAAC,WAAW,CAAA;IACrB,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC1D,OAAO,oCAAoC,CAAC;QAC1C,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU;QACxD,QAAQ,EAAE,EAAE,EAAE,EAAE,4BAA4B;YAC1C,MAAM,EAAE,gBAAgB,CAAC,EAAE,QAAQ,EAAE,gDAAgD,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,EAAE;KAC3I,EAAE,iBAAiB,CAAC,CAAA;AACvB,CAAC;AACD,iFAAiF;AACjF,MAAM,UAAU,2BAA2B,CAAC,KAAc;IACxD,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAC1C,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAA;IAChL,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAAE,IAAI,CAAC,2BAA2B,CAAC,CAAA;IACjI,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;IAC3B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,IAAI,CAAC,+BAA+B,CAAC,CAAA;IACzF,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,SAAS,CAAC;WACpH,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,WAAW,CAAC;WAC3F,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,OAAO,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;WAC1H,OAAO,KAAK,CAAC,UAAU,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,GAAG,MAAM;WACrI,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,gBAAgB,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;QAAE,IAAI,CAAC,4BAA4B,CAAC,CAAA;IAChI,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,UAAU,CAAC,SAAS;QAAE,IAAI,CAAC,2BAA2B,CAAC,CAAA;IAC5H,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;IAC1D,MAAM,iBAAiB,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,EAAE,eAAe,CAAC,CAAA;IACvE,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACxC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,CAAC;QAAE,IAAI,CAAC,0BAA0B,CAAC,CAAA;IACnF,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;IAC9C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC;WAC9G,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,gBAAgB,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ;WAC/F,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QACvI,IAAI,CAAC,wBAAwB,CAAC,CAAA;IAChC,CAAC;IACD,IAAI,OAAO,KAAK,CAAC,qBAAqB,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC;QAAE,IAAI,CAAC,yCAAyC,CAAC,CAAA;IAC9I,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,IAAI,CAAC,6BAA6B,CAAC,CAAA;IAC/F,IAAI,KAAK,CAAC,gBAAgB,IAAI,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,UAAU;QAAE,IAAI,CAAC,wBAAwB,CAAC,CAAA;IAC9H,cAAc,CAAC,aAAa,EAAE,cAAc,EAAE,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IACtF,cAAc,CAAC,iBAAiB,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;IACvF,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QACtC,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB;QAC1H,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO;QAClG,qBAAqB,EAAE,KAAK,CAAC,qBAAqB,EAAE,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE;KAC3G,CAAC,CAA4B,CAAC,CAAA;AACjC,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { GoalRecord } from './types.js';
2
+ import { type GoalOwnerIntent, type GoalOwnerIntentSupplier } from './owner-intent.js';
3
+ type StoredIntent = Readonly<{
4
+ intent: GoalOwnerIntent;
5
+ definitionDigest: string;
6
+ }>;
7
+ /**
8
+ * Budget-facing supplier lookup for one business goal.
9
+ *
10
+ * A missing ledger or a missing row means "no frozen owner intent" and never
11
+ * rejects. A row whose definition digest no longer matches the live goal
12
+ * definition means the binding expired (for example after an out-of-band native
13
+ * edit); that must fail closed instead of silently dropping the supplier pin.
14
+ */
15
+ export declare function goalOwnerIntentSupplier(store: GoalOwnerIntentStore | undefined, record: Pick<GoalRecord, 'id' | 'definition'>): GoalOwnerIntentSupplier | undefined;
16
+ /**
17
+ * Side ledger binding one frozen owner intent to one business goal id.
18
+ *
19
+ * The intent digest and the goal definition digest are recorded separately:
20
+ * the intent is immutable, while the definition digest fences the exact
21
+ * objective revision the owner authorized at creation time. Reopening the
22
+ * database revalidates every row, so an edited or truncated side file fails
23
+ * closed instead of silently producing a different objective.
24
+ */
25
+ export declare class GoalOwnerIntentStore {
26
+ #private;
27
+ constructor(path: string);
28
+ /** Idempotent by exact intent and definition digest; a different frozen intent conflicts. */
29
+ record(intent: GoalOwnerIntent, id: string, definitionDigest: string): GoalOwnerIntent;
30
+ get(id: string): GoalOwnerIntent | undefined;
31
+ /** Row plus the exact definition digest it was frozen against; undefined when absent. */
32
+ inspect(id: string): StoredIntent | undefined;
33
+ close(): void;
34
+ }
35
+ export {};
36
+ //# sourceMappingURL=owner-intent-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-intent-store.d.ts","sourceRoot":"","sources":["../src/owner-intent-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,OAAO,EAA2B,KAAK,eAAe,EAAE,KAAK,uBAAuB,EAAE,MAAM,mBAAmB,CAAA;AAK/G,KAAK,YAAY,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAOnF;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,oBAAoB,GAAG,SAAS,EAC7E,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG,uBAAuB,GAAG,SAAS,CAQpF;AAED;;;;;;;;GAQG;AACH,qBAAa,oBAAoB;;gBAEnB,IAAI,EAAE,MAAM;IAgCxB,6FAA6F;IAC7F,MAAM,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,eAAe;IAkBtF,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAC5C,yFAAyF;IACzF,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAE7C,KAAK,IAAI,IAAI;CACd"}
@@ -0,0 +1,136 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ import { acceptanceDigest } from '@dsh-enhanced/task-acceptance-contract';
3
+ import { GoalStoreError } from './types.js';
4
+ import { prepareGoalStoreDatabaseFile } from './store.js';
5
+ import { validateGoalOwnerIntent } from './owner-intent.js';
6
+ const HEX = /^[a-f0-9]{64}$/u;
7
+ const goalId = (value) => typeof value === 'string' && /^[A-Za-z0-9][A-Za-z0-9._:-]{0,511}$/u.test(value);
8
+ const integer = (value) => Number.isSafeInteger(value) && value >= 0;
9
+ function fail(code) { throw new GoalStoreError(code); }
10
+ function parse(value) { try {
11
+ return JSON.parse(value);
12
+ }
13
+ catch {
14
+ return fail('schema');
15
+ } }
16
+ /**
17
+ * Budget-facing supplier lookup for one business goal.
18
+ *
19
+ * A missing ledger or a missing row means "no frozen owner intent" and never
20
+ * rejects. A row whose definition digest no longer matches the live goal
21
+ * definition means the binding expired (for example after an out-of-band native
22
+ * edit); that must fail closed instead of silently dropping the supplier pin.
23
+ */
24
+ export function goalOwnerIntentSupplier(store, record) {
25
+ if (store === undefined)
26
+ return undefined;
27
+ const stored = store.inspect(record.id);
28
+ if (stored === undefined)
29
+ return undefined;
30
+ if (stored.definitionDigest !== record.definition.digest) {
31
+ throw new Error('assistant-goals: frozen owner intent is stale for the current goal definition');
32
+ }
33
+ return stored.intent.supplier;
34
+ }
35
+ /**
36
+ * Side ledger binding one frozen owner intent to one business goal id.
37
+ *
38
+ * The intent digest and the goal definition digest are recorded separately:
39
+ * the intent is immutable, while the definition digest fences the exact
40
+ * objective revision the owner authorized at creation time. Reopening the
41
+ * database revalidates every row, so an edited or truncated side file fails
42
+ * closed instead of silently producing a different objective.
43
+ */
44
+ export class GoalOwnerIntentStore {
45
+ #database;
46
+ constructor(path) {
47
+ if (path !== ':memory:')
48
+ prepareGoalStoreDatabaseFile(path);
49
+ this.#database = new DatabaseSync(path, { enableForeignKeyConstraints: true });
50
+ try {
51
+ this.#database.exec('PRAGMA foreign_keys = ON; PRAGMA busy_timeout = 250; PRAGMA journal_mode = WAL; PRAGMA synchronous = FULL;');
52
+ const version = this.#database.prepare('PRAGMA user_version').get().user_version;
53
+ const tables = this.#database.prepare("SELECT name FROM sqlite_schema WHERE type = 'table' AND name NOT LIKE 'sqlite_%' ORDER BY name").all().map(row => row.name);
54
+ if (version === 0 && tables.length === 0)
55
+ this.#database.exec(`BEGIN IMMEDIATE; CREATE TABLE goal_owner_intents (goal_id TEXT PRIMARY KEY, intent_json TEXT NOT NULL, intent_digest TEXT NOT NULL, definition_digest TEXT NOT NULL, recorded_at INTEGER NOT NULL) STRICT; PRAGMA user_version = 1; COMMIT;`);
56
+ else if (version !== 1 || tables.length !== 1 || tables[0] !== 'goal_owner_intents')
57
+ fail('schema');
58
+ const columns = this.#database.prepare('PRAGMA table_info(goal_owner_intents)').all().map(row => row.name);
59
+ const sql = this.#database.prepare("SELECT sql FROM sqlite_schema WHERE type = 'table' AND name = 'goal_owner_intents'").get()?.sql;
60
+ if (JSON.stringify(columns) !== JSON.stringify(['goal_id', 'intent_json', 'intent_digest', 'definition_digest', 'recorded_at']) || !sql || !/\bSTRICT\b/u.test(sql))
61
+ fail('schema');
62
+ const check = this.#database.prepare('PRAGMA quick_check').get();
63
+ if (check.quick_check !== 'ok')
64
+ fail('schema');
65
+ for (const row of this.#database.prepare('SELECT goal_id, intent_json, intent_digest, definition_digest, recorded_at FROM goal_owner_intents').all())
66
+ this.#row(row);
67
+ if (path !== ':memory:')
68
+ prepareGoalStoreDatabaseFile(path);
69
+ }
70
+ catch (error) {
71
+ this.#database.close();
72
+ throw error;
73
+ }
74
+ }
75
+ #row(row) {
76
+ if (!goalId(row.goal_id) || typeof row.intent_digest !== 'string' || !HEX.test(row.intent_digest)
77
+ || typeof row.definition_digest !== 'string' || !HEX.test(row.definition_digest) || !integer(row.recorded_at))
78
+ fail('schema');
79
+ let intent;
80
+ try {
81
+ intent = validateGoalOwnerIntent(parse(row.intent_json));
82
+ }
83
+ catch {
84
+ fail('schema');
85
+ }
86
+ if (acceptanceDigest(intent) !== row.intent_digest)
87
+ fail('schema');
88
+ return Object.freeze({ intent, definitionDigest: row.definition_digest });
89
+ }
90
+ #get(id) {
91
+ const row = this.#database.prepare('SELECT goal_id, intent_json, intent_digest, definition_digest, recorded_at FROM goal_owner_intents WHERE goal_id = ?').get(id);
92
+ return row === undefined ? undefined : this.#row(row);
93
+ }
94
+ /** Idempotent by exact intent and definition digest; a different frozen intent conflicts. */
95
+ record(intent, id, definitionDigest) {
96
+ let value;
97
+ try {
98
+ value = validateGoalOwnerIntent(intent);
99
+ }
100
+ catch {
101
+ fail('invalid-input');
102
+ }
103
+ if (!goalId(id) || typeof definitionDigest !== 'string' || !HEX.test(definitionDigest))
104
+ fail('invalid-input');
105
+ return this.#transaction(() => {
106
+ const existing = this.#get(id);
107
+ if (existing !== undefined) {
108
+ if (acceptanceDigest(existing.intent) !== acceptanceDigest(value) || existing.definitionDigest !== definitionDigest)
109
+ fail('conflict');
110
+ return existing.intent;
111
+ }
112
+ try {
113
+ this.#database.prepare('INSERT INTO goal_owner_intents(goal_id, intent_json, intent_digest, definition_digest, recorded_at) VALUES (?, ?, ?, ?, ?)')
114
+ .run(id, JSON.stringify(value), acceptanceDigest(value), definitionDigest, Date.now());
115
+ }
116
+ catch {
117
+ fail('conflict');
118
+ }
119
+ return this.#get(id).intent;
120
+ });
121
+ }
122
+ get(id) { return goalId(id) ? this.#get(id)?.intent : fail('invalid-input'); }
123
+ /** Row plus the exact definition digest it was frozen against; undefined when absent. */
124
+ inspect(id) { return goalId(id) ? this.#get(id) : fail('invalid-input'); }
125
+ #transaction(operation) { this.#database.exec('BEGIN IMMEDIATE'); try {
126
+ const result = operation();
127
+ this.#database.exec('COMMIT');
128
+ return result;
129
+ }
130
+ catch (error) {
131
+ this.#database.exec('ROLLBACK');
132
+ throw error;
133
+ } }
134
+ close() { this.#database.close(); }
135
+ }
136
+ //# sourceMappingURL=owner-intent-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-intent-store.js","sourceRoot":"","sources":["../src/owner-intent-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import type { Agent } from '@deepseek-ai/dsh-agent';
2
+ import type { ToolExecution } from '@deepseek-ai/dsh-tools';
3
+ import type { ForegroundToolCallAttestation, OwnerForegroundToolInput } from '@dsh-enhanced/assistant-delivery';
4
+ import type { GoalScope } from './types.js';
5
+ /** Frozen identity of the authenticated owner request that authorized one native goal. */
6
+ export declare const OWNER_INTENT_PROTOCOL = "assistant-goals/owner-intent/v1";
7
+ /** Complete persisted human input is bounded; larger input cannot be proven in one intent. */
8
+ export declare const MAX_OWNER_INTENT_INPUT_BYTES = 65536;
9
+ /** Delivery serves at most 8192 bytes per page; Goals asks for a fixed conservative page. */
10
+ export declare const OWNER_INTENT_PAGE_BYTES = 4096;
11
+ export interface GoalOwnerIntentSupplier {
12
+ provider: string;
13
+ model: string;
14
+ reasoningEffort?: string;
15
+ }
16
+ export interface GoalOwnerIntent {
17
+ protocol: typeof OWNER_INTENT_PROTOCOL;
18
+ /** Delivery source digest: task, original envelope, full human text and frozen model state. */
19
+ sourceDigest: string;
20
+ inputSha256: string;
21
+ inputBytes: number;
22
+ fullTextDigest: string;
23
+ text: string;
24
+ objective: {
25
+ text: string;
26
+ start: number;
27
+ end: number;
28
+ };
29
+ owner: {
30
+ principalRecordId: string;
31
+ principalVersion: number;
32
+ };
33
+ scope: {
34
+ workspace: string;
35
+ preset: string;
36
+ };
37
+ sessionId: string;
38
+ binding: {
39
+ id: string;
40
+ version: number;
41
+ generation: number;
42
+ };
43
+ call: {
44
+ id: string;
45
+ toolName: string;
46
+ argumentsDigest: string;
47
+ };
48
+ supplier: GoalOwnerIntentSupplier;
49
+ turn: number;
50
+ at: number;
51
+ }
52
+ /** Host-only proof surface consumed by Goals; never reachable from model tool arguments. */
53
+ export interface GoalOwnerIntentDelivery {
54
+ inspectOwnerForegroundToolCallForAgent(agent: Agent, input: Readonly<{
55
+ callId: string;
56
+ toolName: string;
57
+ argumentsJson: string;
58
+ }>): Readonly<ForegroundToolCallAttestation> | undefined;
59
+ readOwnerForegroundToolInputForAgent(agent: Agent, input: Readonly<{
60
+ callId: string;
61
+ toolName: string;
62
+ argumentsJson: string;
63
+ offset?: number;
64
+ maxBytes?: number;
65
+ }>): Readonly<OwnerForegroundToolInput> | undefined;
66
+ }
67
+ export interface BuildGoalOwnerIntentInput {
68
+ delivery: GoalOwnerIntentDelivery;
69
+ agent: Agent;
70
+ execution: ToolExecution;
71
+ scope: GoalScope;
72
+ /** Total persisted-input byte bound, for focused tests; production uses the maximum. */
73
+ maxBytes?: number;
74
+ }
75
+ /**
76
+ * Locate the model-supplied objective inside the authenticated owner text.
77
+ *
78
+ * The objective must already be trimmed, non-empty and UTF-8 clean, and it
79
+ * must occur verbatim in the owner text. Repeated occurrences are permitted but
80
+ * only the first occurrence is frozen: the intent pins exactly one canonical
81
+ * span so later consumers can prove which owner words authorized the goal.
82
+ * Absence fails closed; paraphrases and normalized text are not owner quotes.
83
+ */
84
+ export declare function ownerIntentObjectiveSpan(text: string, objective: string): {
85
+ start: number;
86
+ end: number;
87
+ };
88
+ /**
89
+ * Freeze the authenticated owner request behind one live goal_create call.
90
+ *
91
+ * The proof is read twice (once before pagination and once after each read and
92
+ * at the end) and pagination is byte-exact: every page must carry the same
93
+ * task/call/model-state identity and the reassembled text must match the
94
+ * delivery full-text digest and byte count. Missing, forged, PTC, settled or
95
+ * concurrently changed calls fail closed; no intent is returned.
96
+ */
97
+ export declare function buildGoalOwnerIntent(input: BuildGoalOwnerIntentInput): GoalOwnerIntent;
98
+ /** Strict exact-key validation of one persisted intent; any drift fails closed. */
99
+ export declare function validateGoalOwnerIntent(value: unknown): GoalOwnerIntent;
100
+ //# sourceMappingURL=owner-intent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owner-intent.d.ts","sourceRoot":"","sources":["../src/owner-intent.ts"],"names":[],"mappings":"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"}