@dsh-enhanced/assistant-growth-contract 0.1.47 → 0.1.49

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,155 @@
1
+ import { createPublicKey, verify } from 'node:crypto';
2
+ import { canonicalGrowthJson } from './canonical.js';
3
+ import { validatePluginRevisionParentBinding } from './revision-verification.js';
4
+ const domain = 'assistant-growth/revision-regression/v1\0';
5
+ const digest = /^[a-f0-9]{64}$/u;
6
+ const identifier = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$/u;
7
+ const keys = ['protocol', 'verificationId', 'authority', 'plan', 'parent', 'source', 'contractDigest',
8
+ 'schemaDigest', 'environment', 'model', 'candidateVerificationDigest', 'sourceDigest',
9
+ 'schemaCompatibilityDigest', 'budget', 'observations', 'verifiedAt', 'expiresAt'];
10
+ function fail(label) { throw new Error(`invalid plugin revision regression ${label}`); }
11
+ function record(value, expected, label) {
12
+ if (!value || typeof value !== 'object' || Array.isArray(value)
13
+ || Object.getPrototypeOf(value) !== Object.prototype || Object.getOwnPropertySymbols(value).length
14
+ || !Object.values(Object.getOwnPropertyDescriptors(value)).every(item => item.enumerable && 'value' in item)
15
+ || Object.keys(value).sort().join('\0') !== [...expected].sort().join('\0'))
16
+ fail(label);
17
+ return value;
18
+ }
19
+ function id(value, label) {
20
+ if (typeof value !== 'string' || !identifier.test(value) || value.normalize('NFC') !== value)
21
+ fail(label);
22
+ }
23
+ function sha(value, label) {
24
+ if (typeof value !== 'string' || !digest.test(value))
25
+ fail(label);
26
+ }
27
+ function integer(value, label, min, max) {
28
+ if (!Number.isSafeInteger(value) || Number(value) < min || Number(value) > max)
29
+ fail(label);
30
+ }
31
+ function text(value, label, maximum = 500) {
32
+ if (typeof value !== 'string' || !value || !value.isWellFormed() || value.normalize('NFC').trim() !== value
33
+ || Buffer.byteLength(value) > maximum || /[\p{Cc}]/u.test(value))
34
+ fail(label);
35
+ }
36
+ function rows(value) {
37
+ if (!Array.isArray(value) || value.length < 2 || value.length > 8
38
+ || Object.getPrototypeOf(value) !== Array.prototype || Object.getOwnPropertySymbols(value).length
39
+ || Object.getOwnPropertyNames(value).length !== value.length + 1
40
+ || !Object.entries(Object.getOwnPropertyDescriptors(value)).every(([key, entry]) => key === 'length'
41
+ || /^(0|[1-9][0-9]*)$/u.test(key) && entry.enumerable && 'value' in entry)
42
+ || !Array.from({ length: value.length }, (_, index) => Object.hasOwn(value, index)).every(Boolean))
43
+ fail('observation array');
44
+ return value;
45
+ }
46
+ export function validateRevisionRegressionAcceptanceAuthorityRef(value) {
47
+ const ref = record(value, ['protocol', 'authorityId', 'keyId', 'authorityDigest', 'namePrefix', 'expiresAt'], 'authority');
48
+ if (ref.protocol !== 'assistant-growth/revision-regression-acceptance-authority/v1')
49
+ fail('authority protocol');
50
+ id(ref.authorityId, 'authorityId');
51
+ id(ref.keyId, 'keyId');
52
+ sha(ref.authorityDigest, 'authorityDigest');
53
+ if (typeof ref.namePrefix !== 'string' || ref.namePrefix.length < 2 || ref.namePrefix.length > 48
54
+ || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*-$/u.test(ref.namePrefix))
55
+ fail('namePrefix');
56
+ integer(ref.expiresAt, 'authority expiry', 1, 8_640_000_000_000_000);
57
+ }
58
+ export function validatePluginRevisionRegressionRequest(value) {
59
+ const request = record(value, ['protocol', 'planId'], 'request');
60
+ if (request.protocol !== 'assistant-growth/revision-regression-request/v1')
61
+ fail('request protocol');
62
+ id(request.planId, 'request planId');
63
+ }
64
+ export function validatePluginRevisionRegressionCertificate(value) {
65
+ const item = record(value, [...keys, 'signature'], 'certificate');
66
+ if (item.protocol !== 'assistant-growth/revision-regression/v1')
67
+ fail('protocol');
68
+ id(item.verificationId, 'verificationId');
69
+ validateRevisionRegressionAcceptanceAuthorityRef(item.authority);
70
+ const authority = item.authority;
71
+ const plan = record(item.plan, ['id', 'digest', 'name', 'sourceTreeDigest', 'sourcePatchDigest', 'artifactSha256',
72
+ 'artifactBytes', 'generatorDigest'], 'plan');
73
+ id(plan.id, 'plan id');
74
+ if (typeof plan.name !== 'string' || plan.name.length > 64 || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(plan.name)
75
+ || !plan.name.startsWith(authority.namePrefix))
76
+ fail('plan name');
77
+ for (const key of ['digest', 'sourceTreeDigest', 'sourcePatchDigest', 'artifactSha256', 'generatorDigest'])
78
+ sha(plan[key], key);
79
+ integer(plan.artifactBytes, 'artifact bytes', 1, 512 * 1024);
80
+ validatePluginRevisionParentBinding(item.parent);
81
+ const source = record(item.source, ['referenceDigest', 'ownerDigest', 'growthRunDigest'], 'source');
82
+ for (const key of ['referenceDigest', 'ownerDigest', 'growthRunDigest'])
83
+ sha(source[key], key);
84
+ for (const key of ['contractDigest', 'schemaDigest', 'candidateVerificationDigest', 'sourceDigest',
85
+ 'schemaCompatibilityDigest'])
86
+ sha(item[key], key);
87
+ const environment = record(item.environment, ['node', 'cordis', 'tools', 'systemPrompt'], 'environment');
88
+ for (const key of ['node', 'cordis', 'tools', 'systemPrompt']) {
89
+ if (typeof environment[key] !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9.+-]{0,63}$/u.test(environment[key]))
90
+ fail(key);
91
+ }
92
+ const model = record(item.model, ['provider', 'model',
93
+ ...(item.model && typeof item.model === 'object' && Object.hasOwn(item.model, 'reasoningEffort') ? ['reasoningEffort'] : [])], 'model');
94
+ text(model.provider, 'provider');
95
+ text(model.model, 'model');
96
+ if (Object.hasOwn(model, 'reasoningEffort'))
97
+ text(model.reasoningEffort, 'reasoningEffort');
98
+ const budget = record(item.budget, ['maxCases', 'maxDurationMs', 'maxRuns'], 'budget');
99
+ integer(budget.maxCases, 'cases', 2, 8);
100
+ integer(budget.maxDurationMs, 'duration', 1_000, 1_800_000);
101
+ integer(budget.maxRuns, 'runs', 2 + 2 * Number(budget.maxCases), 64);
102
+ const observations = rows(item.observations);
103
+ if (observations.length > Number(budget.maxCases))
104
+ fail('observations exceed budget');
105
+ const cases = new Set(), jobs = new Set();
106
+ for (const entry of observations) {
107
+ const observation = record(entry, ['caseId', 'parent', 'candidate'], 'observation');
108
+ id(observation.caseId, 'caseId');
109
+ if (cases.has(String(observation.caseId)))
110
+ fail('duplicate case');
111
+ cases.add(String(observation.caseId));
112
+ for (const side of ['parent', 'candidate']) {
113
+ const result = record(observation[side], ['jobId', 'operationDigest', 'observationDigest'], `${side} observation`);
114
+ id(result.jobId, `${side} jobId`);
115
+ sha(result.operationDigest, `${side} operationDigest`);
116
+ sha(result.observationDigest, `${side} observationDigest`);
117
+ if (jobs.has(String(result.jobId)))
118
+ fail('duplicate observation job');
119
+ jobs.add(String(result.jobId));
120
+ }
121
+ }
122
+ integer(item.verifiedAt, 'verifiedAt', 1, 8_640_000_000_000_000);
123
+ integer(item.expiresAt, 'expiresAt', 1, 8_640_000_000_000_000);
124
+ if (Number(item.expiresAt) <= Number(item.verifiedAt) || Number(item.expiresAt) > authority.expiresAt)
125
+ fail('certificate expiry');
126
+ if (typeof item.signature !== 'string' || !/^[A-Za-z0-9_-]{86}$/u.test(item.signature)
127
+ || Buffer.from(item.signature, 'base64url').length !== 64
128
+ || Buffer.from(item.signature, 'base64url').toString('base64url') !== item.signature)
129
+ fail('signature');
130
+ if (Buffer.byteLength(canonicalGrowthJson(item)) > 65_536)
131
+ fail('certificate bytes');
132
+ }
133
+ export function pluginRevisionRegressionSigningPayload(value) {
134
+ const body = record(value, keys, 'signing body');
135
+ validatePluginRevisionRegressionCertificate({ ...body, signature: 'A'.repeat(86) });
136
+ return domain + canonicalGrowthJson(body);
137
+ }
138
+ /** Signature and authority equality only; consumers must recheck parent certificate bindings, provenance and source currency. */
139
+ export function verifyPluginRevisionRegressionCertificate(value, authority, publicKey, now = Date.now()) {
140
+ try {
141
+ validateRevisionRegressionAcceptanceAuthorityRef(authority);
142
+ validatePluginRevisionRegressionCertificate(value);
143
+ if (!Number.isSafeInteger(now) || value.verifiedAt > now || value.expiresAt <= now
144
+ || canonicalGrowthJson(value.authority) !== canonicalGrowthJson(authority))
145
+ return false;
146
+ const { signature, ...body } = value;
147
+ const key = createPublicKey(publicKey);
148
+ return key.asymmetricKeyType === 'ed25519'
149
+ && verify(null, Buffer.from(pluginRevisionRegressionSigningPayload(body)), key, Buffer.from(signature, 'base64url'));
150
+ }
151
+ catch {
152
+ return false;
153
+ }
154
+ }
155
+ //# sourceMappingURL=revision-regression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-regression.js","sourceRoot":"","sources":["../src/revision-regression.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { type PluginCreationVerificationCertificate } from './creation-verification.js';
2
+ /** Owner policy frozen before a revision candidate can be written. */
3
+ export interface RevisionAcceptanceAuthorityRef {
4
+ protocol: 'assistant-growth/revision-acceptance-authority/v1';
5
+ authorityId: string;
6
+ keyId: string;
7
+ authorityDigest: string;
8
+ namePrefix: string;
9
+ expiresAt: number;
10
+ }
11
+ /** Exact adopted version and retained source on which the revision is based. */
12
+ export interface PluginRevisionParentBinding {
13
+ planId: string;
14
+ certificateDigest: string;
15
+ artifactSha256: string;
16
+ sourceArchiveDigest: string;
17
+ sourceDigest: string;
18
+ }
19
+ export type PluginRevisionVerificationCertificate = Omit<PluginCreationVerificationCertificate, 'protocol' | 'authority'> & {
20
+ protocol: 'assistant-growth/revision-verification/v1';
21
+ authority: RevisionAcceptanceAuthorityRef;
22
+ parent: PluginRevisionParentBinding;
23
+ };
24
+ /** Host-only request; the producer must reread the current parent and candidate. */
25
+ export interface PluginRevisionVerificationRequest {
26
+ protocol: 'assistant-growth/revision-verification-request/v1';
27
+ planId: string;
28
+ }
29
+ export type PluginRevisionVerificationResult = {
30
+ status: 'verified';
31
+ certificate: PluginRevisionVerificationCertificate;
32
+ } | {
33
+ status: 'rejected' | 'unknown';
34
+ reason: string;
35
+ };
36
+ export declare function validateRevisionAcceptanceAuthorityRef(value: unknown): asserts value is RevisionAcceptanceAuthorityRef;
37
+ export declare function validatePluginRevisionParentBinding(value: unknown): asserts value is PluginRevisionParentBinding;
38
+ export declare function validatePluginRevisionVerificationCertificate(value: unknown): asserts value is PluginRevisionVerificationCertificate;
39
+ export declare function pluginRevisionVerificationSigningPayload(value: Omit<PluginRevisionVerificationCertificate, 'signature'>): string;
40
+ /** Signature and authority equality only; consumers must also recheck provenance and parent currency. */
41
+ export declare function verifyPluginRevisionVerificationCertificate(value: unknown, authority: RevisionAcceptanceAuthorityRef, publicKey: string, now?: number): value is PluginRevisionVerificationCertificate;
42
+ //# sourceMappingURL=revision-verification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-verification.d.ts","sourceRoot":"","sources":["../src/revision-verification.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,qCAAqC,EAAE,MAAM,4BAA4B,CAAA;AAEhF,sEAAsE;AACtE,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,mDAAmD,CAAA;IAC7D,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,MAAM,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,gFAAgF;AAChF,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,MAAM,CAAA;IACd,iBAAiB,EAAE,MAAM,CAAA;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,MAAM,qCAAqC,GAAG,IAAI,CAAC,qCAAqC,EAAE,UAAU,GAAG,WAAW,CAAC,GAAG;IAC1H,QAAQ,EAAE,2CAA2C,CAAA;IACrD,SAAS,EAAE,8BAA8B,CAAA;IACzC,MAAM,EAAE,2BAA2B,CAAA;CACpC,CAAA;AAED,oFAAoF;AACpF,MAAM,WAAW,iCAAiC;IAChD,QAAQ,EAAE,mDAAmD,CAAA;IAC7D,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,gCAAgC,GACxC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,qCAAqC,CAAA;CAAE,GAC1E;IAAE,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAiBtD,wBAAgB,sCAAsC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,8BAA8B,CAWtH;AAED,wBAAgB,mCAAmC,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,2BAA2B,CAOhH;AAED,wBAAgB,6CAA6C,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,qCAAqC,CAYpI;AAED,wBAAgB,wCAAwC,CAAC,KAAK,EAAE,IAAI,CAAC,qCAAqC,EAAE,WAAW,CAAC,GAAG,MAAM,CAIhI;AAED,yGAAyG;AACzG,wBAAgB,2CAA2C,CAAC,KAAK,EAAE,OAAO,EACxE,SAAS,EAAE,8BAA8B,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,KAAK,IAAI,qCAAqC,CAWhI"}
@@ -0,0 +1,82 @@
1
+ import { createPublicKey, verify } from 'node:crypto';
2
+ import { canonicalGrowthJson } from './canonical.js';
3
+ import { validatePluginCreationVerificationCertificate } from './creation-verification.js';
4
+ const domain = 'assistant-growth/revision-verification/v1\0';
5
+ const digest = /^[a-f0-9]{64}$/u;
6
+ const identifier = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,199}$/u;
7
+ const certificateKeys = ['protocol', 'verificationId', 'authority', 'plan', 'parent', 'source', 'contractDigest',
8
+ 'schemaDigest', 'environment', 'model', 'budget', 'sessions', 'observations', 'reviewDigest', 'verifiedAt', 'expiresAt'];
9
+ function fail(label) { throw new Error(`invalid plugin revision verification ${label}`); }
10
+ function record(value, keys, label) {
11
+ if (!value || typeof value !== 'object' || Array.isArray(value)
12
+ || Object.getPrototypeOf(value) !== Object.prototype || Object.getOwnPropertySymbols(value).length
13
+ || !Object.values(Object.getOwnPropertyDescriptors(value)).every(item => item.enumerable && 'value' in item)
14
+ || Object.keys(value).sort().join('\0') !== [...keys].sort().join('\0'))
15
+ fail(label);
16
+ return value;
17
+ }
18
+ export function validateRevisionAcceptanceAuthorityRef(value) {
19
+ const ref = record(value, ['protocol', 'authorityId', 'keyId', 'authorityDigest', 'namePrefix', 'expiresAt'], 'authority');
20
+ if (ref.protocol !== 'assistant-growth/revision-acceptance-authority/v1')
21
+ fail('authority protocol');
22
+ for (const key of ['authorityId', 'keyId']) {
23
+ if (typeof ref[key] !== 'string' || !identifier.test(ref[key]) || ref[key].normalize('NFC') !== ref[key])
24
+ fail(key);
25
+ }
26
+ if (typeof ref.authorityDigest !== 'string' || !digest.test(ref.authorityDigest))
27
+ fail('authorityDigest');
28
+ if (typeof ref.namePrefix !== 'string' || ref.namePrefix.length < 2 || ref.namePrefix.length > 48
29
+ || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*-$/u.test(ref.namePrefix))
30
+ fail('namePrefix');
31
+ if (!Number.isSafeInteger(ref.expiresAt) || Number(ref.expiresAt) < 1
32
+ || Number(ref.expiresAt) > 8_640_000_000_000_000)
33
+ fail('authority expiry');
34
+ }
35
+ export function validatePluginRevisionParentBinding(value) {
36
+ const parent = record(value, ['planId', 'certificateDigest', 'artifactSha256', 'sourceArchiveDigest', 'sourceDigest'], 'parent');
37
+ if (typeof parent.planId !== 'string' || !identifier.test(parent.planId)
38
+ || parent.planId.normalize('NFC') !== parent.planId)
39
+ fail('parent planId');
40
+ for (const key of ['certificateDigest', 'artifactSha256', 'sourceArchiveDigest', 'sourceDigest']) {
41
+ if (typeof parent[key] !== 'string' || !digest.test(parent[key]))
42
+ fail(`parent ${key}`);
43
+ }
44
+ }
45
+ export function validatePluginRevisionVerificationCertificate(value) {
46
+ const item = record(value, [...certificateKeys, 'signature'], 'certificate');
47
+ if (item.protocol !== 'assistant-growth/revision-verification/v1')
48
+ fail('protocol');
49
+ const authority = item.authority;
50
+ validateRevisionAcceptanceAuthorityRef(authority);
51
+ validatePluginRevisionParentBinding(item.parent);
52
+ const { parent: _parent, ...creationShape } = item;
53
+ validatePluginCreationVerificationCertificate({ ...creationShape,
54
+ protocol: 'assistant-growth/creation-verification/v1',
55
+ authority: { ...authority, protocol: 'assistant-growth/creation-acceptance-authority/v1' },
56
+ });
57
+ if (Buffer.byteLength(canonicalGrowthJson(item)) > 65_536)
58
+ fail('certificate bytes');
59
+ }
60
+ export function pluginRevisionVerificationSigningPayload(value) {
61
+ const body = record(value, certificateKeys, 'signing body');
62
+ validatePluginRevisionVerificationCertificate({ ...body, signature: 'A'.repeat(86) });
63
+ return domain + canonicalGrowthJson(body);
64
+ }
65
+ /** Signature and authority equality only; consumers must also recheck provenance and parent currency. */
66
+ export function verifyPluginRevisionVerificationCertificate(value, authority, publicKey, now = Date.now()) {
67
+ try {
68
+ validateRevisionAcceptanceAuthorityRef(authority);
69
+ validatePluginRevisionVerificationCertificate(value);
70
+ if (!Number.isSafeInteger(now) || value.verifiedAt > now || value.expiresAt <= now
71
+ || canonicalGrowthJson(value.authority) !== canonicalGrowthJson(authority))
72
+ return false;
73
+ const { signature, ...body } = value;
74
+ const key = createPublicKey(publicKey);
75
+ return key.asymmetricKeyType === 'ed25519'
76
+ && verify(null, Buffer.from(pluginRevisionVerificationSigningPayload(body)), key, Buffer.from(signature, 'base64url'));
77
+ }
78
+ catch {
79
+ return false;
80
+ }
81
+ }
82
+ //# sourceMappingURL=revision-verification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revision-verification.js","sourceRoot":"","sources":["../src/revision-verification.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /** Original source provenance survives a new conversation Session, never owner rotation. */
2
+ export interface SourceOwnerReceipt {
3
+ readonly receiptVersion: 2;
4
+ readonly authorityId: string;
5
+ readonly authorityHash: string;
6
+ readonly principalId: string;
7
+ readonly principalRecordId: string;
8
+ readonly principalVersion: number;
9
+ readonly workspace: string;
10
+ readonly agentPreset: string;
11
+ readonly bindingVersion: number;
12
+ readonly generation: number;
13
+ }
14
+ /** Only a current authenticated route may continue an older source's finite authority.
15
+ * This does not renew a grant, change immutable evidence, or authorize a caller Agent. */
16
+ export declare function isSourceOwnerContinuation(current: SourceOwnerReceipt, original: SourceOwnerReceipt): boolean;
17
+ //# sourceMappingURL=source-owner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-owner.d.ts","sourceRoot":"","sources":["../src/source-owner.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAA;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAA;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED;0FAC0F;AAC1F,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,kBAAkB,GAAG,OAAO,CAc5G"}
@@ -0,0 +1,19 @@
1
+ /** Only a current authenticated route may continue an older source's finite authority.
2
+ * This does not renew a grant, change immutable evidence, or authorize a caller Agent. */
3
+ export function isSourceOwnerContinuation(current, original) {
4
+ const stable = ['authorityId', 'authorityHash', 'principalId', 'principalRecordId',
5
+ 'workspace', 'agentPreset'];
6
+ for (const receipt of [current, original]) {
7
+ if (!receipt || receipt.receiptVersion !== 2
8
+ || stable.some(key => typeof receipt[key] !== 'string' || !receipt[key] || receipt[key].trim() !== receipt[key])
9
+ || !/^[a-f0-9]{64}$/u.test(receipt.authorityHash)
10
+ || ![receipt.principalVersion, receipt.bindingVersion, receipt.generation]
11
+ .every(value => Number.isSafeInteger(value) && value > 0))
12
+ return false;
13
+ }
14
+ return stable.every(key => current[key] === original[key])
15
+ && current.principalVersion === original.principalVersion
16
+ && current.generation >= original.generation
17
+ && (current.generation !== original.generation || current.bindingVersion === original.bindingVersion);
18
+ }
19
+ //# sourceMappingURL=source-owner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-owner.js","sourceRoot":"","sources":["../src/source-owner.ts"],"names":[],"mappings":"AAcA;0FAC0F;AAC1F,MAAM,UAAU,yBAAyB,CAAC,OAA2B,EAAE,QAA4B;IACjG,MAAM,MAAM,GAAG,CAAC,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB;QAChF,WAAW,EAAE,aAAa,CAAU,CAAA;IACtC,KAAK,MAAM,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC1C,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,cAAc,KAAK,CAAC;eACvC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;eAC7G,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;eAC9C,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,UAAU,CAAC;iBACvE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;YAAE,OAAO,KAAK,CAAA;IAC7E,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,GAAG,CAAC,CAAC;WACrD,OAAO,CAAC,gBAAgB,KAAK,QAAQ,CAAC,gBAAgB;WACtD,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU;WACzC,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ,CAAC,UAAU,IAAI,OAAO,CAAC,cAAc,KAAK,QAAQ,CAAC,cAAc,CAAC,CAAA;AACzG,CAAC"}
@@ -0,0 +1,76 @@
1
+ import { type CreationAcceptanceAuthorityRef } from './creation-verification.js';
2
+ import { type RevisionAcceptanceAuthorityRef } from './revision-verification.js';
3
+ import { type RevisionRegressionAcceptanceAuthorityRef } from './revision-regression.js';
4
+ /** Private Host provenance, never candidate input or a semantic acceptance oracle. */
5
+ export interface SourceGrowthRunBinding {
6
+ protocol: 'assistant-growth/source-run/v1';
7
+ runId: string;
8
+ intentDigest: string;
9
+ configDigest: string;
10
+ ownerDigest: string;
11
+ source: {
12
+ outcomeId: string;
13
+ projection: {
14
+ subjectKind: 'foreground-turn';
15
+ subjectRef: string;
16
+ version: number;
17
+ digest: string;
18
+ disposition: 'upsert';
19
+ evidenceOutcomeId?: string;
20
+ };
21
+ sourceDigest: string;
22
+ };
23
+ model: {
24
+ provider: string;
25
+ model: string;
26
+ reasoningEffort?: string;
27
+ };
28
+ modelOrigin: 'explicit-growth-override' | 'inherited-owner-task';
29
+ /** Owner policy frozen before the first author model call; absent on historical runs. */
30
+ creationAcceptance?: CreationAcceptanceAuthorityRef;
31
+ /** Independent owner policy for revising an adopted version; absent on historical runs. */
32
+ revisionAcceptance?: RevisionAcceptanceAuthorityRef;
33
+ /** Independent parent-behavior policy; absent on historical runs and never inferred from revisionAcceptance. */
34
+ revisionRegressionAcceptance?: RevisionRegressionAcceptanceAuthorityRef;
35
+ budget: {
36
+ budgetId: string;
37
+ amount: number;
38
+ maxModelCalls: number;
39
+ maxToolCalls: number;
40
+ maxOutputTokens: number;
41
+ maxDurationMs: number;
42
+ maxPlansPerWake: number;
43
+ };
44
+ native: {
45
+ owner: 'assistant-growth-usage';
46
+ automationId: string;
47
+ definitionHash: string;
48
+ occurrenceId: string;
49
+ };
50
+ sessionId: string;
51
+ toolContractDigest: string;
52
+ executionContractDigest: string;
53
+ createdAt: number;
54
+ /** Generation and enqueue deadline, not a renewed build/adoption allowance. */
55
+ generationDeadlineAt: number;
56
+ /** Original durable source window; later stages also need their own grants. */
57
+ expiresAt: number;
58
+ }
59
+ export interface SourceGrowthRunRequest {
60
+ runId: string;
61
+ intentDigest: string;
62
+ }
63
+ /** Transient Host provider absence, distinct from an invalidated durable run. */
64
+ export declare class SourceGrowthRunUnavailableError extends Error {
65
+ }
66
+ export interface SourceGrowthRunProducer {
67
+ protocol: 'assistant-growth-source-run-producer/v1';
68
+ /** Reread the durable run and current owner/source/config; no fallback. */
69
+ inspect(input: SourceGrowthRunRequest): SourceGrowthRunBinding | undefined;
70
+ }
71
+ /** Strict shape checking is necessary but does not authenticate the producer. */
72
+ export declare function validateSourceGrowthRunBinding(value: unknown): asserts value is SourceGrowthRunBinding;
73
+ /** Matches the existing Control Plane evidence canonicalization, including absent optional feedback. */
74
+ export declare function sourceGrowthEvidenceDigest(value: unknown): string;
75
+ export declare function sourceGrowthRunDigest(binding: SourceGrowthRunBinding): string;
76
+ //# sourceMappingURL=source-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-run.d.ts","sourceRoot":"","sources":["../src/source-run.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,KAAK,8BAA8B,EAAE,MAAM,4BAA4B,CAAA;AACxH,OAAO,EAA0C,KAAK,8BAA8B,EAAE,MAAM,4BAA4B,CAAA;AACxH,OAAO,EAAoD,KAAK,wCAAwC,EAAE,MAAM,0BAA0B,CAAA;AAE1I,sFAAsF;AACtF,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,gCAAgC,CAAA;IAC1C,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,EAAE;YACV,WAAW,EAAE,iBAAiB,CAAA;YAC9B,UAAU,EAAE,MAAM,CAAA;YAClB,OAAO,EAAE,MAAM,CAAA;YACf,MAAM,EAAE,MAAM,CAAA;YACd,WAAW,EAAE,QAAQ,CAAA;YACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;SAC3B,CAAA;QACD,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IACpE,WAAW,EAAE,0BAA0B,GAAG,sBAAsB,CAAA;IAChE,yFAAyF;IACzF,kBAAkB,CAAC,EAAE,8BAA8B,CAAA;IACnD,2FAA2F;IAC3F,kBAAkB,CAAC,EAAE,8BAA8B,CAAA;IACnD,gHAAgH;IAChH,4BAA4B,CAAC,EAAE,wCAAwC,CAAA;IACvE,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,aAAa,EAAE,MAAM,CAAA;QACrB,YAAY,EAAE,MAAM,CAAA;QACpB,eAAe,EAAE,MAAM,CAAA;QACvB,aAAa,EAAE,MAAM,CAAA;QACrB,eAAe,EAAE,MAAM,CAAA;KACxB,CAAA;IACD,MAAM,EAAE;QACN,KAAK,EAAE,wBAAwB,CAAA;QAC/B,YAAY,EAAE,MAAM,CAAA;QACpB,cAAc,EAAE,MAAM,CAAA;QACtB,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,SAAS,EAAE,MAAM,CAAA;IACjB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,uBAAuB,EAAE,MAAM,CAAA;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,+EAA+E;IAC/E,oBAAoB,EAAE,MAAM,CAAA;IAC5B,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,sBAAsB;IAAG,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE;AAC/E,iFAAiF;AACjF,qBAAa,+BAAgC,SAAQ,KAAK;CAAG;AAC7D,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,yCAAyC,CAAA;IACnD,2EAA2E;IAC3E,OAAO,CAAC,KAAK,EAAE,sBAAsB,GAAG,sBAAsB,GAAG,SAAS,CAAA;CAC3E;AAsBD,iFAAiF;AACjF,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,IAAI,sBAAsB,CAuDtG;AAED,wGAAwG;AACxG,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAsBjE;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAG7E"}
@@ -0,0 +1,145 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { assertExactGrowthKeys, isGrowthRecord } from './canonical.js';
3
+ import { validateCreationAcceptanceAuthorityRef } from './creation-verification.js';
4
+ import { validateRevisionAcceptanceAuthorityRef } from './revision-verification.js';
5
+ import { validateRevisionRegressionAcceptanceAuthorityRef } from './revision-regression.js';
6
+ /** Transient Host provider absence, distinct from an invalidated durable run. */
7
+ export class SourceGrowthRunUnavailableError extends Error {
8
+ }
9
+ const digest = /^[a-f0-9]{64}$/u;
10
+ function invalid(label) { throw new Error(`invalid source growth run ${label}`); }
11
+ function record(value, keys, label) {
12
+ if (!isGrowthRecord(value))
13
+ invalid(label);
14
+ if (Object.getOwnPropertySymbols(value).length
15
+ || !Object.values(Object.getOwnPropertyDescriptors(value)).every(item => item.enumerable && 'value' in item))
16
+ invalid(label);
17
+ assertExactGrowthKeys(value, keys, `source growth run ${label}`);
18
+ return value;
19
+ }
20
+ function text(value, label, limit = 500) {
21
+ if (typeof value !== 'string' || !value || value.length > limit || value.normalize('NFC').trim() !== value
22
+ || /[\p{Cc}]/u.test(value))
23
+ invalid(label);
24
+ }
25
+ function hash(value, label) {
26
+ if (typeof value !== 'string' || !digest.test(value))
27
+ invalid(label);
28
+ }
29
+ function integer(value, label, minimum = 1) {
30
+ if (!Number.isSafeInteger(value) || Number(value) < minimum)
31
+ invalid(label);
32
+ }
33
+ /** Strict shape checking is necessary but does not authenticate the producer. */
34
+ export function validateSourceGrowthRunBinding(value) {
35
+ const binding = record(value, ['protocol', 'runId', 'intentDigest', 'configDigest', 'ownerDigest', 'source',
36
+ 'model', 'modelOrigin', 'budget', 'native', 'sessionId', 'toolContractDigest', 'executionContractDigest',
37
+ 'createdAt', 'generationDeadlineAt', 'expiresAt',
38
+ ...(isGrowthRecord(value) && Object.hasOwn(value, 'creationAcceptance') ? ['creationAcceptance'] : []),
39
+ ...(isGrowthRecord(value) && Object.hasOwn(value, 'revisionAcceptance') ? ['revisionAcceptance'] : []),
40
+ ...(isGrowthRecord(value) && Object.hasOwn(value, 'revisionRegressionAcceptance') ? ['revisionRegressionAcceptance'] : [])], 'binding');
41
+ if (binding['protocol'] !== 'assistant-growth/source-run/v1')
42
+ invalid('protocol');
43
+ for (const key of ['runId', 'sessionId'])
44
+ text(binding[key], key);
45
+ for (const key of ['intentDigest', 'configDigest', 'ownerDigest', 'toolContractDigest', 'executionContractDigest'])
46
+ hash(binding[key], key);
47
+ const source = record(binding['source'], ['outcomeId', 'projection', 'sourceDigest'], 'source');
48
+ text(source['outcomeId'], 'outcomeId');
49
+ hash(source['sourceDigest'], 'sourceDigest');
50
+ if (!isGrowthRecord(source['projection']))
51
+ invalid('projection');
52
+ const projection = record(source['projection'], ['subjectKind', 'subjectRef', 'version', 'digest', 'disposition',
53
+ ...(Object.hasOwn(source['projection'], 'evidenceOutcomeId') ? ['evidenceOutcomeId'] : [])], 'projection');
54
+ if (projection['subjectKind'] !== 'foreground-turn' || projection['disposition'] !== 'upsert')
55
+ invalid('projection kind');
56
+ text(projection['subjectRef'], 'subjectRef');
57
+ integer(projection['version'], 'projection version');
58
+ hash(projection['digest'], 'projection digest');
59
+ if (Object.hasOwn(projection, 'evidenceOutcomeId'))
60
+ text(projection['evidenceOutcomeId'], 'evidenceOutcomeId');
61
+ if (!isGrowthRecord(binding['model']))
62
+ invalid('model');
63
+ const model = record(binding['model'], ['provider', 'model',
64
+ ...(Object.hasOwn(binding['model'], 'reasoningEffort') ? ['reasoningEffort'] : [])], 'model');
65
+ text(model['provider'], 'provider');
66
+ text(model['model'], 'model');
67
+ if (Object.hasOwn(model, 'reasoningEffort'))
68
+ text(model['reasoningEffort'], 'reasoningEffort');
69
+ if (!['explicit-growth-override', 'inherited-owner-task'].includes(String(binding['modelOrigin'])))
70
+ invalid('model origin');
71
+ const budget = record(binding['budget'], ['budgetId', 'amount', 'maxModelCalls', 'maxToolCalls',
72
+ 'maxOutputTokens', 'maxDurationMs', 'maxPlansPerWake'], 'budget');
73
+ text(budget['budgetId'], 'budgetId');
74
+ for (const key of ['amount', 'maxModelCalls', 'maxToolCalls', 'maxOutputTokens', 'maxDurationMs', 'maxPlansPerWake'])
75
+ integer(budget[key], key);
76
+ const native = record(binding['native'], ['owner', 'automationId', 'definitionHash', 'occurrenceId'], 'native');
77
+ if (native['owner'] !== 'assistant-growth-usage' || native['automationId'] !== binding['runId'])
78
+ invalid('native owner or identity');
79
+ text(native['occurrenceId'], 'occurrenceId');
80
+ hash(native['definitionHash'], 'definitionHash');
81
+ for (const key of ['createdAt', 'generationDeadlineAt', 'expiresAt']) {
82
+ integer(binding[key], key, 0);
83
+ if (Number(binding[key]) > 8_640_000_000_000_000)
84
+ invalid(key);
85
+ }
86
+ if (Number(binding['createdAt']) >= Number(binding['generationDeadlineAt'])
87
+ || Number(binding['generationDeadlineAt']) > Number(binding['expiresAt'])
88
+ || Number(binding['generationDeadlineAt']) - Number(binding['createdAt']) > Number(budget['maxDurationMs']))
89
+ invalid('deadline');
90
+ if (Object.hasOwn(binding, 'creationAcceptance')) {
91
+ validateCreationAcceptanceAuthorityRef(binding['creationAcceptance']);
92
+ if (binding['creationAcceptance'].expiresAt < Number(binding['createdAt']))
93
+ invalid('creation acceptance expiry');
94
+ }
95
+ if (Object.hasOwn(binding, 'revisionAcceptance')) {
96
+ validateRevisionAcceptanceAuthorityRef(binding['revisionAcceptance']);
97
+ if (binding['revisionAcceptance'].expiresAt < Number(binding['createdAt']))
98
+ invalid('revision acceptance expiry');
99
+ }
100
+ if (Object.hasOwn(binding, 'revisionRegressionAcceptance')) {
101
+ validateRevisionRegressionAcceptanceAuthorityRef(binding['revisionRegressionAcceptance']);
102
+ if (binding['revisionRegressionAcceptance'].expiresAt < Number(binding['createdAt']))
103
+ invalid('revision regression acceptance expiry');
104
+ }
105
+ }
106
+ /** Matches the existing Control Plane evidence canonicalization, including absent optional feedback. */
107
+ export function sourceGrowthEvidenceDigest(value) {
108
+ const active = new Set();
109
+ let nodes = 0;
110
+ function visit(item, depth) {
111
+ if (++nodes > 32_768 || depth > 64)
112
+ invalid('evidence size');
113
+ if (item === null || typeof item === 'string' || typeof item === 'boolean')
114
+ return JSON.stringify(item);
115
+ if (typeof item === 'number' && Number.isFinite(item)
116
+ && (!Number.isInteger(item) || Number.isSafeInteger(item)))
117
+ return JSON.stringify(item);
118
+ if (typeof item !== 'object' || active.has(item))
119
+ invalid('evidence value');
120
+ active.add(item);
121
+ try {
122
+ if (Array.isArray(item))
123
+ return `[${item.map(entry => visit(entry, depth + 1)).join(',')}]`;
124
+ if (!isGrowthRecord(item))
125
+ invalid('evidence object');
126
+ const entries = Object.entries(item).filter(([, entry]) => entry !== undefined)
127
+ .sort(([left], [right]) => left.localeCompare(right));
128
+ if (entries.some(([key]) => ['__proto__', 'constructor', 'prototype'].includes(key)))
129
+ invalid('evidence key');
130
+ return `{${entries.map(([key, entry]) => `${JSON.stringify(key)}:${visit(entry, depth + 1)}`).join(',')}}`;
131
+ }
132
+ finally {
133
+ active.delete(item);
134
+ }
135
+ }
136
+ const canonical = visit(value, 0);
137
+ if (Buffer.byteLength(canonical) > 1_048_576)
138
+ invalid('evidence bytes');
139
+ return createHash('sha256').update(canonical).digest('hex');
140
+ }
141
+ export function sourceGrowthRunDigest(binding) {
142
+ validateSourceGrowthRunBinding(binding);
143
+ return sourceGrowthEvidenceDigest(binding);
144
+ }
145
+ //# sourceMappingURL=source-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-run.js","sourceRoot":"","sources":["../src/source-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,sCAAsC,EAAuC,MAAM,4BAA4B,CAAA;AACxH,OAAO,EAAE,sCAAsC,EAAuC,MAAM,4BAA4B,CAAA;AACxH,OAAO,EAAE,gDAAgD,EAAiD,MAAM,0BAA0B,CAAA;AAuD1I,iFAAiF;AACjF,MAAM,OAAO,+BAAgC,SAAQ,KAAK;CAAG;AAO7D,MAAM,MAAM,GAAG,iBAAiB,CAAA;AAChC,SAAS,OAAO,CAAC,KAAa,IAAW,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAA,CAAC,CAAC;AAChG,SAAS,MAAM,CAAC,KAAc,EAAE,IAAuB,EAAE,KAAa;IACpE,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAC1C,IAAI,MAAM,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,MAAM;WACzC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,IAAI,OAAO,IAAI,IAAI,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAC9H,qBAAqB,CAAC,KAAK,EAAE,IAAI,EAAE,qBAAqB,KAAK,EAAE,CAAC,CAAA;IAChE,OAAO,KAAK,CAAA;AACd,CAAC;AACD,SAAS,IAAI,CAAC,KAAc,EAAE,KAAa,EAAE,KAAK,GAAG,GAAG;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,KAAK;WACrG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,CAAA;AAC9C,CAAC;AACD,SAAS,IAAI,CAAC,KAAc,EAAE,KAAa;IACzC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,KAAK,CAAC,CAAA;AACtE,CAAC;AACD,SAAS,OAAO,CAAC,KAAc,EAAE,KAAa,EAAE,OAAO,GAAG,CAAC;IACzD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO;QAAE,OAAO,CAAC,KAAK,CAAC,CAAA;AAC7E,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,8BAA8B,CAAC,KAAc;IAC3D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ;QACzG,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,oBAAoB,EAAE,yBAAyB;QACxG,WAAW,EAAE,sBAAsB,EAAE,WAAW;QAChD,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtG,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtG,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;IACzI,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,gCAAgC;QAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IACjF,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC;QAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IACjE,KAAK,MAAM,GAAG,IAAI,CAAC,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,yBAAyB,CAAC;QAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IAC3I,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC/F,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC,CAAA;IACtC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC,CAAA;IAC5C,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAChE,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa;QAC9G,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;IAC5G,IAAI,UAAU,CAAC,aAAa,CAAC,KAAK,iBAAiB,IAAI,UAAU,CAAC,aAAa,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,iBAAiB,CAAC,CAAA;IACzH,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC,CAAA;IAC5C,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,oBAAoB,CAAC,CAAA;IACpD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,mBAAmB,CAAC,CAAA;IAC/C,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,mBAAmB,CAAC;QAAE,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC,CAAA;IAC9G,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,OAAO;QACzD,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAC/F,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAA;IACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAA;IAC7B,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,iBAAiB,CAAC;QAAE,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,CAAA;IAC9F,IAAI,CAAC,CAAC,0BAA0B,EAAE,sBAAsB,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAC3H,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,cAAc;QAC7F,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,CAAC,EAAE,QAAQ,CAAC,CAAA;IACnE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC,CAAA;IACpC,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,EAAE,cAAc,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,CAAC;QAAE,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAA;IAC/I,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,cAAc,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC/G,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,wBAAwB,IAAI,MAAM,CAAC,cAAc,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,0BAA0B,CAAC,CAAA;IACpI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC,CAAA;IAC5C,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,CAAA;IAChD,KAAK,MAAM,GAAG,IAAI,CAAC,WAAW,EAAE,sBAAsB,EAAE,WAAW,CAAC,EAAE,CAAC;QACrE,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAA;QAC7B,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,qBAAqB;YAAE,OAAO,CAAC,GAAG,CAAC,CAAA;IAChE,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;WACtE,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;WACtE,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IAClI,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,oBAAoB,CAAC,EAAE,CAAC;QACjD,sCAAsC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACrE,IAAK,OAAO,CAAC,oBAAoB,CAAoC,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAAE,OAAO,CAAC,4BAA4B,CAAC,CAAA;IACvJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,oBAAoB,CAAC,EAAE,CAAC;QACjD,sCAAsC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAA;QACrE,IAAK,OAAO,CAAC,oBAAoB,CAAoC,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAAE,OAAO,CAAC,4BAA4B,CAAC,CAAA;IACvJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,8BAA8B,CAAC,EAAE,CAAC;QAC3D,gDAAgD,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAA;QACzF,IAAK,OAAO,CAAC,8BAA8B,CAA8C,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAAE,OAAO,CAAC,uCAAuC,CAAC,CAAA;IACtL,CAAC;AACH,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,0BAA0B,CAAC,KAAc;IACvD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAA;IAChC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,SAAS,KAAK,CAAC,IAAa,EAAE,KAAa;QACzC,IAAI,EAAE,KAAK,GAAG,MAAM,IAAI,KAAK,GAAG,EAAE;YAAE,OAAO,CAAC,eAAe,CAAC,CAAA;QAC5D,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACvG,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;eAChD,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QACzF,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAC3E,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAChB,IAAI,CAAC;YACH,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;gBAAE,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;YAC3F,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;gBAAE,OAAO,CAAC,iBAAiB,CAAC,CAAA;YACrD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;iBAC5E,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;YACvD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAAE,OAAO,CAAC,cAAc,CAAC,CAAA;YAC7G,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAA;QAC5G,CAAC;gBAAS,CAAC;YAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAAC,CAAC;IACnC,CAAC;IACD,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;IACjC,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,SAAS;QAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IACvE,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAA+B;IACnE,8BAA8B,CAAC,OAAO,CAAC,CAAA;IACvC,OAAO,0BAA0B,CAAC,OAAO,CAAC,CAAA;AAC5C,CAAC"}
package/lib/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const version = "0.1.47";
1
+ export declare const version = "0.1.49";
2
2
  //# sourceMappingURL=version.d.ts.map
package/lib/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '0.1.47';
1
+ export const version = '0.1.49';
2
2
  //# sourceMappingURL=version.js.map