@davesheffer/hunch 1.32.8 → 1.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/cli/index.js +2 -0
- package/dist/cli/serve.js +28 -2
- package/dist/cli/state.d.ts +3 -0
- package/dist/cli/state.js +150 -0
- package/dist/client/state.d.ts +82 -14
- package/dist/client/state.js +16 -2
- package/dist/client/stateProof.d.ts +4 -0
- package/dist/client/stateProof.js +17 -0
- package/dist/constitution/behaviorEvaluator.js +1 -1
- package/dist/constitution/schema.d.ts +2 -2
- package/dist/core/automaticReviewMemory.d.ts +5 -0
- package/dist/core/conventionDelivery.d.ts +8 -0
- package/dist/core/conventionDelivery.js +52 -0
- package/dist/core/fieldProvenance.d.ts +8 -0
- package/dist/core/fieldProvenance.js +72 -0
- package/dist/core/recordVisibility.d.ts +9 -0
- package/dist/core/recordVisibility.js +25 -0
- package/dist/core/stateCanonical.d.ts +3 -0
- package/dist/core/stateCanonical.js +34 -0
- package/dist/core/stateContract.d.ts +122 -7
- package/dist/core/stateContract.js +26 -31
- package/dist/core/stateDelivery.d.ts +3 -3
- package/dist/core/stateDelivery.js +10 -1
- package/dist/core/stateHttp.d.ts +280 -0
- package/dist/core/stateHttp.js +17 -0
- package/dist/core/stateProof.d.ts +13 -0
- package/dist/core/stateProof.js +34 -0
- package/dist/core/stateRecords.d.ts +127 -0
- package/dist/core/stateRecords.js +48 -0
- package/dist/core/types.d.ts +146 -4
- package/dist/core/types.js +8 -2
- package/dist/extractors/git.js +3 -10
- package/dist/mcp/server.js +10 -4
- package/dist/serve/app.d.ts +2 -0
- package/dist/serve/app.js +71 -30
- package/dist/serve/config.d.ts +16 -0
- package/dist/serve/config.js +27 -7
- package/dist/serve/operator.d.ts +4 -0
- package/dist/serve/operator.js +223 -0
- package/dist/serve/stateProof.d.ts +15 -0
- package/dist/serve/stateProof.js +105 -0
- package/dist/store/changeLedger.d.ts +6 -0
- package/dist/store/hunchStore.d.ts +4 -2
- package/dist/store/hunchStore.js +18 -19
- package/dist/store/stateAccess.d.ts +13 -0
- package/dist/store/stateAccess.js +85 -0
- package/dist/store/stateBinding.d.ts +13 -18
- package/dist/store/stateBinding.js +161 -52
- package/dist/store/stateCapture.js +10 -2
- package/dist/store/stateError.d.ts +12 -0
- package/dist/store/stateError.js +12 -0
- package/dist/store/statePartition.d.ts +9 -0
- package/dist/store/statePartition.js +30 -0
- package/package.json +5 -1
- package/server.json +2 -2
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/** HTTP-only response shapes. Verb and record schemas remain in stateContract. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const HttpCapabilitiesSchema: z.ZodObject<{
|
|
4
|
+
protocol: z.ZodLiteral<"nuryel.state/1">;
|
|
5
|
+
capabilities: z.ZodArray<z.ZodString>;
|
|
6
|
+
repository: z.ZodObject<{
|
|
7
|
+
kind: z.ZodEnum<{
|
|
8
|
+
repository: "repository";
|
|
9
|
+
organization: "organization";
|
|
10
|
+
team: "team";
|
|
11
|
+
user: "user";
|
|
12
|
+
}>;
|
|
13
|
+
id: z.ZodString;
|
|
14
|
+
}, z.core.$strict>;
|
|
15
|
+
partitions: z.ZodArray<z.ZodEnum<{
|
|
16
|
+
repository: "repository";
|
|
17
|
+
organization: "organization";
|
|
18
|
+
team: "team";
|
|
19
|
+
user: "user";
|
|
20
|
+
}>>;
|
|
21
|
+
principal: z.ZodObject<{
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
kind: z.ZodEnum<{
|
|
24
|
+
service: "service";
|
|
25
|
+
human: "human";
|
|
26
|
+
agent: "agent";
|
|
27
|
+
}>;
|
|
28
|
+
grants: z.ZodArray<z.ZodObject<{
|
|
29
|
+
kind: z.ZodEnum<{
|
|
30
|
+
repository: "repository";
|
|
31
|
+
organization: "organization";
|
|
32
|
+
team: "team";
|
|
33
|
+
user: "user";
|
|
34
|
+
}>;
|
|
35
|
+
id: z.ZodString;
|
|
36
|
+
}, z.core.$strict>>;
|
|
37
|
+
}, z.core.$strict>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export declare const HttpHealthSchema: z.ZodObject<{
|
|
40
|
+
ok: z.ZodBoolean;
|
|
41
|
+
version: z.ZodString;
|
|
42
|
+
protocol: z.ZodLiteral<"nuryel.state/1">;
|
|
43
|
+
partitions: z.ZodArray<z.ZodString>;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export declare const HttpReadResponseSchema: z.ZodObject<{
|
|
46
|
+
conventions: z.ZodOptional<z.ZodObject<{
|
|
47
|
+
advisory: z.ZodLiteral<true>;
|
|
48
|
+
items: z.ZodArray<z.ZodObject<{
|
|
49
|
+
ref: z.ZodObject<{
|
|
50
|
+
facet: z.ZodEnum<{
|
|
51
|
+
decisions: "decisions";
|
|
52
|
+
constraints: "constraints";
|
|
53
|
+
bugs: "bugs";
|
|
54
|
+
findings: "findings";
|
|
55
|
+
receipts: "receipts";
|
|
56
|
+
commitments: "commitments";
|
|
57
|
+
derived: "derived";
|
|
58
|
+
entities: "entities";
|
|
59
|
+
relationships: "relationships";
|
|
60
|
+
conventions: "conventions";
|
|
61
|
+
}>;
|
|
62
|
+
id: z.ZodString;
|
|
63
|
+
record_hash: z.ZodString;
|
|
64
|
+
scope: z.ZodObject<{
|
|
65
|
+
kind: z.ZodEnum<{
|
|
66
|
+
repository: "repository";
|
|
67
|
+
organization: "organization";
|
|
68
|
+
team: "team";
|
|
69
|
+
user: "user";
|
|
70
|
+
}>;
|
|
71
|
+
id: z.ZodString;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
}, z.core.$strict>;
|
|
74
|
+
key: z.ZodString;
|
|
75
|
+
conflict: z.ZodBoolean;
|
|
76
|
+
currentness: z.ZodEnum<{
|
|
77
|
+
stale: "stale";
|
|
78
|
+
recorded: "recorded";
|
|
79
|
+
}>;
|
|
80
|
+
}, z.core.$strict>>;
|
|
81
|
+
truncated: z.ZodBoolean;
|
|
82
|
+
}, z.core.$strict>>;
|
|
83
|
+
schema: z.ZodLiteral<"nuryel.state.read/1">;
|
|
84
|
+
receipt_id: z.ZodString;
|
|
85
|
+
scope: z.ZodObject<{
|
|
86
|
+
kind: z.ZodEnum<{
|
|
87
|
+
repository: "repository";
|
|
88
|
+
organization: "organization";
|
|
89
|
+
team: "team";
|
|
90
|
+
user: "user";
|
|
91
|
+
}>;
|
|
92
|
+
id: z.ZodString;
|
|
93
|
+
}, z.core.$strict>;
|
|
94
|
+
state_of_record: z.ZodNullable<z.ZodObject<{
|
|
95
|
+
subject: z.ZodString;
|
|
96
|
+
current: z.ZodArray<z.ZodObject<{
|
|
97
|
+
facet: z.ZodEnum<{
|
|
98
|
+
decisions: "decisions";
|
|
99
|
+
constraints: "constraints";
|
|
100
|
+
bugs: "bugs";
|
|
101
|
+
findings: "findings";
|
|
102
|
+
receipts: "receipts";
|
|
103
|
+
commitments: "commitments";
|
|
104
|
+
derived: "derived";
|
|
105
|
+
entities: "entities";
|
|
106
|
+
relationships: "relationships";
|
|
107
|
+
conventions: "conventions";
|
|
108
|
+
}>;
|
|
109
|
+
id: z.ZodString;
|
|
110
|
+
record_hash: z.ZodString;
|
|
111
|
+
scope: z.ZodObject<{
|
|
112
|
+
kind: z.ZodEnum<{
|
|
113
|
+
repository: "repository";
|
|
114
|
+
organization: "organization";
|
|
115
|
+
team: "team";
|
|
116
|
+
user: "user";
|
|
117
|
+
}>;
|
|
118
|
+
id: z.ZodString;
|
|
119
|
+
}, z.core.$strict>;
|
|
120
|
+
}, z.core.$strict>>;
|
|
121
|
+
in_force: z.ZodArray<z.ZodObject<{
|
|
122
|
+
facet: z.ZodEnum<{
|
|
123
|
+
decisions: "decisions";
|
|
124
|
+
constraints: "constraints";
|
|
125
|
+
bugs: "bugs";
|
|
126
|
+
findings: "findings";
|
|
127
|
+
receipts: "receipts";
|
|
128
|
+
commitments: "commitments";
|
|
129
|
+
derived: "derived";
|
|
130
|
+
entities: "entities";
|
|
131
|
+
relationships: "relationships";
|
|
132
|
+
conventions: "conventions";
|
|
133
|
+
}>;
|
|
134
|
+
id: z.ZodString;
|
|
135
|
+
record_hash: z.ZodString;
|
|
136
|
+
scope: z.ZodObject<{
|
|
137
|
+
kind: z.ZodEnum<{
|
|
138
|
+
repository: "repository";
|
|
139
|
+
organization: "organization";
|
|
140
|
+
team: "team";
|
|
141
|
+
user: "user";
|
|
142
|
+
}>;
|
|
143
|
+
id: z.ZodString;
|
|
144
|
+
}, z.core.$strict>;
|
|
145
|
+
}, z.core.$strict>>;
|
|
146
|
+
done: z.ZodArray<z.ZodObject<{
|
|
147
|
+
facet: z.ZodEnum<{
|
|
148
|
+
decisions: "decisions";
|
|
149
|
+
constraints: "constraints";
|
|
150
|
+
bugs: "bugs";
|
|
151
|
+
findings: "findings";
|
|
152
|
+
receipts: "receipts";
|
|
153
|
+
commitments: "commitments";
|
|
154
|
+
derived: "derived";
|
|
155
|
+
entities: "entities";
|
|
156
|
+
relationships: "relationships";
|
|
157
|
+
conventions: "conventions";
|
|
158
|
+
}>;
|
|
159
|
+
id: z.ZodString;
|
|
160
|
+
record_hash: z.ZodString;
|
|
161
|
+
scope: z.ZodObject<{
|
|
162
|
+
kind: z.ZodEnum<{
|
|
163
|
+
repository: "repository";
|
|
164
|
+
organization: "organization";
|
|
165
|
+
team: "team";
|
|
166
|
+
user: "user";
|
|
167
|
+
}>;
|
|
168
|
+
id: z.ZodString;
|
|
169
|
+
}, z.core.$strict>;
|
|
170
|
+
}, z.core.$strict>>;
|
|
171
|
+
observed: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
172
|
+
facet: z.ZodEnum<{
|
|
173
|
+
decisions: "decisions";
|
|
174
|
+
constraints: "constraints";
|
|
175
|
+
bugs: "bugs";
|
|
176
|
+
findings: "findings";
|
|
177
|
+
receipts: "receipts";
|
|
178
|
+
commitments: "commitments";
|
|
179
|
+
derived: "derived";
|
|
180
|
+
entities: "entities";
|
|
181
|
+
relationships: "relationships";
|
|
182
|
+
conventions: "conventions";
|
|
183
|
+
}>;
|
|
184
|
+
id: z.ZodString;
|
|
185
|
+
record_hash: z.ZodString;
|
|
186
|
+
scope: z.ZodObject<{
|
|
187
|
+
kind: z.ZodEnum<{
|
|
188
|
+
repository: "repository";
|
|
189
|
+
organization: "organization";
|
|
190
|
+
team: "team";
|
|
191
|
+
user: "user";
|
|
192
|
+
}>;
|
|
193
|
+
id: z.ZodString;
|
|
194
|
+
}, z.core.$strict>;
|
|
195
|
+
}, z.core.$strict>>>;
|
|
196
|
+
observed_truncated: z.ZodOptional<z.ZodBoolean>;
|
|
197
|
+
observed_page: z.ZodOptional<z.ZodObject<{
|
|
198
|
+
snapshot_hash: z.ZodString;
|
|
199
|
+
total: z.ZodNumber;
|
|
200
|
+
next_cursor: z.ZodNullable<z.ZodObject<{
|
|
201
|
+
snapshot_hash: z.ZodString;
|
|
202
|
+
offset: z.ZodNumber;
|
|
203
|
+
}, z.core.$strict>>;
|
|
204
|
+
}, z.core.$strict>>;
|
|
205
|
+
relationships_truncated: z.ZodOptional<z.ZodBoolean>;
|
|
206
|
+
depends_on: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
207
|
+
kind: z.ZodLiteral<"record">;
|
|
208
|
+
id: z.ZodString;
|
|
209
|
+
record_hash: z.ZodString;
|
|
210
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
211
|
+
kind: z.ZodEnum<{
|
|
212
|
+
repository: "repository";
|
|
213
|
+
organization: "organization";
|
|
214
|
+
team: "team";
|
|
215
|
+
user: "user";
|
|
216
|
+
}>;
|
|
217
|
+
id: z.ZodString;
|
|
218
|
+
}, z.core.$strict>>;
|
|
219
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
220
|
+
kind: z.ZodLiteral<"external">;
|
|
221
|
+
ref: z.ZodObject<{
|
|
222
|
+
system: z.ZodString;
|
|
223
|
+
object_type: z.ZodString;
|
|
224
|
+
object_key: z.ZodString;
|
|
225
|
+
version: z.ZodOptional<z.ZodString>;
|
|
226
|
+
content_hash: z.ZodOptional<z.ZodString>;
|
|
227
|
+
observed_at: z.ZodString;
|
|
228
|
+
locator: z.ZodOptional<z.ZodString>;
|
|
229
|
+
}, z.core.$strict>;
|
|
230
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
231
|
+
kind: z.ZodLiteral<"schema">;
|
|
232
|
+
name: z.ZodString;
|
|
233
|
+
fingerprint: z.ZodString;
|
|
234
|
+
}, z.core.$strict>], "kind">>;
|
|
235
|
+
invalidated_by: z.ZodArray<z.ZodString>;
|
|
236
|
+
}, z.core.$strict>>;
|
|
237
|
+
denied_scopes: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
238
|
+
kind: z.ZodEnum<{
|
|
239
|
+
repository: "repository";
|
|
240
|
+
organization: "organization";
|
|
241
|
+
team: "team";
|
|
242
|
+
user: "user";
|
|
243
|
+
}>;
|
|
244
|
+
id: z.ZodString;
|
|
245
|
+
}, z.core.$strict>>>;
|
|
246
|
+
records: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
247
|
+
scopes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
248
|
+
kind: z.ZodEnum<{
|
|
249
|
+
repository: "repository";
|
|
250
|
+
organization: "organization";
|
|
251
|
+
team: "team";
|
|
252
|
+
user: "user";
|
|
253
|
+
}>;
|
|
254
|
+
id: z.ZodString;
|
|
255
|
+
}, z.core.$strict>>>;
|
|
256
|
+
receipts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
257
|
+
scope: z.ZodObject<{
|
|
258
|
+
kind: z.ZodEnum<{
|
|
259
|
+
repository: "repository";
|
|
260
|
+
organization: "organization";
|
|
261
|
+
team: "team";
|
|
262
|
+
user: "user";
|
|
263
|
+
}>;
|
|
264
|
+
id: z.ZodString;
|
|
265
|
+
}, z.core.$strict>;
|
|
266
|
+
receipt_id: z.ZodString;
|
|
267
|
+
}, z.core.$strict>>>;
|
|
268
|
+
envelope: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
269
|
+
}, z.core.$strict>;
|
|
270
|
+
export declare const StateProblemSchema: z.ZodObject<{
|
|
271
|
+
type: z.ZodString;
|
|
272
|
+
title: z.ZodString;
|
|
273
|
+
status: z.ZodNumber;
|
|
274
|
+
detail: z.ZodString;
|
|
275
|
+
conflict: z.ZodOptional<z.ZodObject<{
|
|
276
|
+
incumbent_id: z.ZodString;
|
|
277
|
+
reason: z.ZodString;
|
|
278
|
+
}, z.core.$strip>>;
|
|
279
|
+
issues: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
280
|
+
}, z.core.$strip>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** HTTP-only response shapes. Verb and record schemas remain in stateContract. */
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { CapabilityNegotiationSchema, PrincipalSchema, ReadResponseSchema, ScopeSchema, STATE_CONTRACT_VERSION } from './stateContract.js';
|
|
4
|
+
export const HttpCapabilitiesSchema = CapabilityNegotiationSchema.extend({
|
|
5
|
+
repository: ScopeSchema, partitions: z.array(ScopeSchema.shape.kind),
|
|
6
|
+
principal: PrincipalSchema.pick({ id: true, kind: true, grants: true }),
|
|
7
|
+
}).strict();
|
|
8
|
+
export const HttpHealthSchema = z.object({
|
|
9
|
+
ok: z.boolean(), version: z.string(), protocol: z.literal(STATE_CONTRACT_VERSION), partitions: z.array(z.string()),
|
|
10
|
+
}).strict();
|
|
11
|
+
// Delivery has its own richer assertion and receipt checks in delivery.ts.
|
|
12
|
+
export const HttpReadResponseSchema = ReadResponseSchema.extend({ envelope: z.record(z.string(), z.unknown()) });
|
|
13
|
+
export const StateProblemSchema = z.object({
|
|
14
|
+
type: z.string(), title: z.string(), status: z.number().int(), detail: z.string(),
|
|
15
|
+
conflict: z.object({ incumbent_id: z.string(), reason: z.string() }).optional(), issues: z.array(z.string()).optional(),
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=stateHttp.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const STATE_PROOF_CAPABILITY = "nuryel.auth.dpop/1";
|
|
3
|
+
export declare const ProofPublicKeySchema: z.ZodObject<{
|
|
4
|
+
kty: z.ZodLiteral<"OKP">;
|
|
5
|
+
crv: z.ZodLiteral<"Ed25519">;
|
|
6
|
+
x: z.ZodString;
|
|
7
|
+
}, z.core.$strict>;
|
|
8
|
+
export type ProofPublicKey = z.infer<typeof ProofPublicKeySchema>;
|
|
9
|
+
export declare const PublicOriginSchema: z.ZodString;
|
|
10
|
+
export declare const tokenProofHash: (value: string) => string;
|
|
11
|
+
export declare function proofThumbprint(input: unknown): string;
|
|
12
|
+
export declare function proofPublicKey(pem: string): ProofPublicKey;
|
|
13
|
+
export declare function proofTarget(value: string): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** DPoP resource-server profile: RFC 9449, RFC 7638 and RFC 8037. Ed25519 only. */
|
|
2
|
+
import { createHash, createPublicKey } from 'node:crypto';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
export const STATE_PROOF_CAPABILITY = 'nuryel.auth.dpop/1';
|
|
5
|
+
export const ProofPublicKeySchema = z.object({ kty: z.literal('OKP'), crv: z.literal('Ed25519'), x: z.string().regex(/^[A-Za-z0-9_-]{43}$/) }).strict().superRefine((key, ctx) => {
|
|
6
|
+
if (Buffer.from(key.x, 'base64url').toString('base64url') !== key.x)
|
|
7
|
+
ctx.addIssue({ code: 'custom', message: 'public key encoding must be canonical base64url' });
|
|
8
|
+
});
|
|
9
|
+
export const PublicOriginSchema = z.string().url().refine(value => {
|
|
10
|
+
const url = new URL(value);
|
|
11
|
+
return url.protocol === 'https:' && url.origin === value && !url.username && !url.password;
|
|
12
|
+
}, 'public_origin must be an HTTPS origin without a path, credentials, query or fragment');
|
|
13
|
+
export const tokenProofHash = (value) => createHash('sha256').update(value, 'ascii').digest('base64url');
|
|
14
|
+
export function proofThumbprint(input) {
|
|
15
|
+
const key = ProofPublicKeySchema.parse(input);
|
|
16
|
+
return createHash('sha256').update(JSON.stringify({ crv: key.crv, kty: key.kty, x: key.x })).digest('base64url');
|
|
17
|
+
}
|
|
18
|
+
export function proofPublicKey(pem) {
|
|
19
|
+
if (pem.trimStart().startsWith('{'))
|
|
20
|
+
return ProofPublicKeySchema.parse(JSON.parse(pem));
|
|
21
|
+
const key = createPublicKey(pem);
|
|
22
|
+
if (key.asymmetricKeyType !== 'ed25519')
|
|
23
|
+
throw new Error('proof keys must use Ed25519');
|
|
24
|
+
return ProofPublicKeySchema.parse(key.export({ format: 'jwk' }));
|
|
25
|
+
}
|
|
26
|
+
export function proofTarget(value) {
|
|
27
|
+
const url = new URL(value);
|
|
28
|
+
if (url.protocol !== 'https:' || url.username || url.password)
|
|
29
|
+
throw new Error('key-bound requests require an HTTPS URL without credentials');
|
|
30
|
+
url.search = '';
|
|
31
|
+
url.hash = '';
|
|
32
|
+
return url.href;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=stateProof.js.map
|
|
@@ -87,6 +87,11 @@ export declare const DependencyRefSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
87
87
|
export type DependencyRef = z.infer<typeof DependencyRefSchema>;
|
|
88
88
|
/** done — a side effect that happened. Never replayable as a read; idempotency is explicit. */
|
|
89
89
|
export declare const ActionReceiptSchema: z.ZodObject<{
|
|
90
|
+
visibility: z.ZodOptional<z.ZodObject<{
|
|
91
|
+
owner: z.ZodString;
|
|
92
|
+
readers: z.ZodArray<z.ZodString>;
|
|
93
|
+
writers: z.ZodArray<z.ZodString>;
|
|
94
|
+
}, z.core.$strict>>;
|
|
90
95
|
schema: z.ZodLiteral<"nuryel.receipt/1">;
|
|
91
96
|
id: z.ZodString;
|
|
92
97
|
scope: z.ZodObject<{
|
|
@@ -161,6 +166,11 @@ export declare const ActionReceiptSchema: z.ZodObject<{
|
|
|
161
166
|
export type ActionReceipt = z.infer<typeof ActionReceiptSchema>;
|
|
162
167
|
/** committed — an obligation with a due date and an in-force window. */
|
|
163
168
|
export declare const CommitmentSchema: z.ZodObject<{
|
|
169
|
+
visibility: z.ZodOptional<z.ZodObject<{
|
|
170
|
+
owner: z.ZodString;
|
|
171
|
+
readers: z.ZodArray<z.ZodString>;
|
|
172
|
+
writers: z.ZodArray<z.ZodString>;
|
|
173
|
+
}, z.core.$strict>>;
|
|
164
174
|
schema: z.ZodLiteral<"nuryel.commitment/1">;
|
|
165
175
|
id: z.ZodString;
|
|
166
176
|
scope: z.ZodObject<{
|
|
@@ -203,9 +213,37 @@ export declare const CommitmentSchema: z.ZodObject<{
|
|
|
203
213
|
}, z.core.$strip>;
|
|
204
214
|
}, z.core.$strict>;
|
|
205
215
|
export type Commitment = z.infer<typeof CommitmentSchema>;
|
|
216
|
+
export declare const FieldSelectorSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
217
|
+
kind: z.ZodLiteral<"json_pointer">;
|
|
218
|
+
path: z.ZodString;
|
|
219
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
220
|
+
kind: z.ZodLiteral<"text">;
|
|
221
|
+
start: z.ZodNumber;
|
|
222
|
+
end: z.ZodNumber;
|
|
223
|
+
}, z.core.$strict>], "kind">;
|
|
224
|
+
export type FieldSelector = z.infer<typeof FieldSelectorSchema>;
|
|
225
|
+
/** Hash references stay attached to the same sources if dependencies are reordered. */
|
|
226
|
+
export declare const FieldProvenanceSchema: z.ZodObject<{
|
|
227
|
+
selector: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
228
|
+
kind: z.ZodLiteral<"json_pointer">;
|
|
229
|
+
path: z.ZodString;
|
|
230
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
231
|
+
kind: z.ZodLiteral<"text">;
|
|
232
|
+
start: z.ZodNumber;
|
|
233
|
+
end: z.ZodNumber;
|
|
234
|
+
}, z.core.$strict>], "kind">;
|
|
235
|
+
value_hash: z.ZodString;
|
|
236
|
+
dependency_hashes: z.ZodArray<z.ZodString>;
|
|
237
|
+
}, z.core.$strict>;
|
|
238
|
+
export type FieldProvenance = z.infer<typeof FieldProvenanceSchema>;
|
|
206
239
|
/** current — a statement that is true now, and on what it rests. Dependencies are mandatory:
|
|
207
240
|
* a derived statement without them cannot be invalidated and therefore cannot be trusted. */
|
|
208
241
|
export declare const DerivedStateSchema: z.ZodObject<{
|
|
242
|
+
visibility: z.ZodOptional<z.ZodObject<{
|
|
243
|
+
owner: z.ZodString;
|
|
244
|
+
readers: z.ZodArray<z.ZodString>;
|
|
245
|
+
writers: z.ZodArray<z.ZodString>;
|
|
246
|
+
}, z.core.$strict>>;
|
|
209
247
|
schema: z.ZodLiteral<"nuryel.derived/1">;
|
|
210
248
|
id: z.ZodString;
|
|
211
249
|
scope: z.ZodObject<{
|
|
@@ -249,6 +287,18 @@ export declare const DerivedStateSchema: z.ZodObject<{
|
|
|
249
287
|
name: z.ZodString;
|
|
250
288
|
fingerprint: z.ZodString;
|
|
251
289
|
}, z.core.$strict>], "kind">>;
|
|
290
|
+
field_provenance: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
291
|
+
selector: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
292
|
+
kind: z.ZodLiteral<"json_pointer">;
|
|
293
|
+
path: z.ZodString;
|
|
294
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
295
|
+
kind: z.ZodLiteral<"text">;
|
|
296
|
+
start: z.ZodNumber;
|
|
297
|
+
end: z.ZodNumber;
|
|
298
|
+
}, z.core.$strict>], "kind">;
|
|
299
|
+
value_hash: z.ZodString;
|
|
300
|
+
dependency_hashes: z.ZodArray<z.ZodString>;
|
|
301
|
+
}, z.core.$strict>>>;
|
|
252
302
|
transform_version: z.ZodString;
|
|
253
303
|
computed_at: z.ZodString;
|
|
254
304
|
valid_to: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
@@ -287,6 +337,11 @@ export type DerivedState = z.infer<typeof DerivedStateSchema>;
|
|
|
287
337
|
* id, lifecycle, provenance), with provenance pointers instead of mirrored content. Stored in
|
|
288
338
|
* an index file, like resources, because kind-qualified ids are not safe file names. */
|
|
289
339
|
export declare const ExternalEntitySchema: z.ZodObject<{
|
|
340
|
+
visibility: z.ZodOptional<z.ZodObject<{
|
|
341
|
+
owner: z.ZodString;
|
|
342
|
+
readers: z.ZodArray<z.ZodString>;
|
|
343
|
+
writers: z.ZodArray<z.ZodString>;
|
|
344
|
+
}, z.core.$strict>>;
|
|
290
345
|
schema: z.ZodLiteral<"nuryel.entity/1">;
|
|
291
346
|
id: z.ZodString;
|
|
292
347
|
kind: z.ZodString;
|
|
@@ -328,6 +383,11 @@ export declare const ExternalEntitySchema: z.ZodObject<{
|
|
|
328
383
|
export type ExternalEntity = z.infer<typeof ExternalEntitySchema>;
|
|
329
384
|
/** relationship — rides the same identity rule as the graph's edges. Index-file stored. */
|
|
330
385
|
export declare const StateRelationshipSchema: z.ZodObject<{
|
|
386
|
+
visibility: z.ZodOptional<z.ZodObject<{
|
|
387
|
+
owner: z.ZodString;
|
|
388
|
+
readers: z.ZodArray<z.ZodString>;
|
|
389
|
+
writers: z.ZodArray<z.ZodString>;
|
|
390
|
+
}, z.core.$strict>>;
|
|
331
391
|
schema: z.ZodLiteral<"nuryel.relationship/1">;
|
|
332
392
|
id: z.ZodString;
|
|
333
393
|
from: z.ZodString;
|
|
@@ -381,3 +441,70 @@ export declare const DnaFacetRefSchema: z.ZodObject<{
|
|
|
381
441
|
}, z.core.$strict>;
|
|
382
442
|
export declare const entityId: typeof resourceId;
|
|
383
443
|
export declare const relationshipId: typeof edgeId;
|
|
444
|
+
export declare const CONVENTION_SCHEMA_VERSION: "nuryel.convention/1";
|
|
445
|
+
/** Explicit conventions are advisory records. Acceptance records human review, never policy authority. */
|
|
446
|
+
export declare const ConventionSchema: z.ZodObject<{
|
|
447
|
+
schema: z.ZodLiteral<"nuryel.convention/1">;
|
|
448
|
+
id: z.ZodString;
|
|
449
|
+
scope: z.ZodObject<{
|
|
450
|
+
kind: z.ZodEnum<{
|
|
451
|
+
repository: "repository";
|
|
452
|
+
organization: "organization";
|
|
453
|
+
team: "team";
|
|
454
|
+
user: "user";
|
|
455
|
+
}>;
|
|
456
|
+
id: z.ZodString;
|
|
457
|
+
}, z.core.$strict>;
|
|
458
|
+
key: z.ZodString;
|
|
459
|
+
value: z.ZodString;
|
|
460
|
+
status: z.ZodEnum<{
|
|
461
|
+
stale: "stale";
|
|
462
|
+
proposed: "proposed";
|
|
463
|
+
accepted: "accepted";
|
|
464
|
+
withdrawn: "withdrawn";
|
|
465
|
+
}>;
|
|
466
|
+
sources: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
467
|
+
kind: z.ZodLiteral<"record">;
|
|
468
|
+
id: z.ZodString;
|
|
469
|
+
record_hash: z.ZodString;
|
|
470
|
+
scope: z.ZodOptional<z.ZodObject<{
|
|
471
|
+
kind: z.ZodEnum<{
|
|
472
|
+
repository: "repository";
|
|
473
|
+
organization: "organization";
|
|
474
|
+
team: "team";
|
|
475
|
+
user: "user";
|
|
476
|
+
}>;
|
|
477
|
+
id: z.ZodString;
|
|
478
|
+
}, z.core.$strict>>;
|
|
479
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
480
|
+
kind: z.ZodLiteral<"external">;
|
|
481
|
+
ref: z.ZodObject<{
|
|
482
|
+
system: z.ZodString;
|
|
483
|
+
object_type: z.ZodString;
|
|
484
|
+
object_key: z.ZodString;
|
|
485
|
+
version: z.ZodOptional<z.ZodString>;
|
|
486
|
+
content_hash: z.ZodOptional<z.ZodString>;
|
|
487
|
+
observed_at: z.ZodString;
|
|
488
|
+
locator: z.ZodOptional<z.ZodString>;
|
|
489
|
+
}, z.core.$strict>;
|
|
490
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
491
|
+
kind: z.ZodLiteral<"schema">;
|
|
492
|
+
name: z.ZodString;
|
|
493
|
+
fingerprint: z.ZodString;
|
|
494
|
+
}, z.core.$strict>], "kind">>;
|
|
495
|
+
valid_from: z.ZodString;
|
|
496
|
+
valid_to: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
497
|
+
review_by: z.ZodString;
|
|
498
|
+
provenance: z.ZodObject<{
|
|
499
|
+
source: z.ZodString;
|
|
500
|
+
confidence: z.ZodNumber;
|
|
501
|
+
evidence: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
502
|
+
last_verified: z.ZodOptional<z.ZodString>;
|
|
503
|
+
}, z.core.$strip>;
|
|
504
|
+
visibility: z.ZodOptional<z.ZodObject<{
|
|
505
|
+
owner: z.ZodString;
|
|
506
|
+
readers: z.ZodArray<z.ZodString>;
|
|
507
|
+
writers: z.ZodArray<z.ZodString>;
|
|
508
|
+
}, z.core.$strict>>;
|
|
509
|
+
}, z.core.$strict>;
|
|
510
|
+
export type Convention = z.infer<typeof ConventionSchema>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RecordVisibilitySchema } from "./recordVisibility.js";
|
|
1
2
|
/**
|
|
2
3
|
* nuryel.state/1 — the RECORD schemas (the facets that are new record kinds in the store).
|
|
3
4
|
*
|
|
@@ -13,6 +14,7 @@
|
|
|
13
14
|
import { z } from "zod";
|
|
14
15
|
import { edgeId, resourceId } from "./ids.js";
|
|
15
16
|
import { ProvenanceSchema, isCredentialFreeValue } from "./provenance.js";
|
|
17
|
+
import { assertFieldProvenance } from "./fieldProvenance.js";
|
|
16
18
|
export const RECEIPT_SCHEMA_VERSION = "nuryel.receipt/1";
|
|
17
19
|
export const COMMITMENT_SCHEMA_VERSION = "nuryel.commitment/1";
|
|
18
20
|
export const DERIVED_SCHEMA_VERSION = "nuryel.derived/1";
|
|
@@ -73,6 +75,7 @@ export const DependencyRefSchema = z.discriminatedUnion("kind", [
|
|
|
73
75
|
// ---- facets ------------------------------------------------------------------------------
|
|
74
76
|
/** done — a side effect that happened. Never replayable as a read; idempotency is explicit. */
|
|
75
77
|
export const ActionReceiptSchema = z.object({
|
|
78
|
+
visibility: RecordVisibilitySchema.optional(),
|
|
76
79
|
schema: z.literal(RECEIPT_SCHEMA_VERSION),
|
|
77
80
|
id: z.string().regex(/^nrc_[a-f0-9]{24}$/),
|
|
78
81
|
scope: ScopeSchema,
|
|
@@ -96,6 +99,7 @@ export const ActionReceiptSchema = z.object({
|
|
|
96
99
|
}).strict();
|
|
97
100
|
/** committed — an obligation with a due date and an in-force window. */
|
|
98
101
|
export const CommitmentSchema = z.object({
|
|
102
|
+
visibility: RecordVisibilitySchema.optional(),
|
|
99
103
|
schema: z.literal(COMMITMENT_SCHEMA_VERSION),
|
|
100
104
|
id: z.string().regex(/^ncm_[a-f0-9]{24}$/),
|
|
101
105
|
scope: ScopeSchema,
|
|
@@ -113,9 +117,20 @@ export const CommitmentSchema = z.object({
|
|
|
113
117
|
valid_to: z.string().regex(ISO).nullable().default(null),
|
|
114
118
|
provenance: ProvenanceSchema,
|
|
115
119
|
}).strict();
|
|
120
|
+
export const FieldSelectorSchema = z.discriminatedUnion("kind", [
|
|
121
|
+
z.object({ kind: z.literal("json_pointer"), path: z.string().max(2048).regex(/^(?:\/(?:[^~/]|~[01])*)*$/) }).strict(),
|
|
122
|
+
z.object({ kind: z.literal("text"), start: z.number().int().min(0).max(20_000), end: z.number().int().min(1).max(20_000) }).strict(),
|
|
123
|
+
]);
|
|
124
|
+
/** Hash references stay attached to the same sources if dependencies are reordered. */
|
|
125
|
+
export const FieldProvenanceSchema = z.object({
|
|
126
|
+
selector: FieldSelectorSchema,
|
|
127
|
+
value_hash: z.string().regex(SHA256),
|
|
128
|
+
dependency_hashes: z.array(z.string().regex(SHA256)).min(1).max(256),
|
|
129
|
+
}).strict();
|
|
116
130
|
/** current — a statement that is true now, and on what it rests. Dependencies are mandatory:
|
|
117
131
|
* a derived statement without them cannot be invalidated and therefore cannot be trusted. */
|
|
118
132
|
export const DerivedStateSchema = z.object({
|
|
133
|
+
visibility: RecordVisibilitySchema.optional(),
|
|
119
134
|
schema: z.literal(DERIVED_SCHEMA_VERSION),
|
|
120
135
|
id: z.string().regex(/^nds_[a-f0-9]{24}$/),
|
|
121
136
|
scope: ScopeSchema,
|
|
@@ -123,6 +138,8 @@ export const DerivedStateSchema = z.object({
|
|
|
123
138
|
content: z.string().min(1).max(20_000),
|
|
124
139
|
content_hash: z.string().regex(SHA256),
|
|
125
140
|
dependencies: z.array(DependencyRefSchema).min(1).max(256),
|
|
141
|
+
/** Optional exact field/text citations; absence means no field-level mapping is recorded. */
|
|
142
|
+
field_provenance: z.array(FieldProvenanceSchema).min(1).max(128).optional(),
|
|
126
143
|
transform_version: z.string().max(128),
|
|
127
144
|
computed_at: z.string().regex(ISO),
|
|
128
145
|
valid_to: z.string().regex(ISO).nullable().default(null),
|
|
@@ -136,12 +153,19 @@ export const DerivedStateSchema = z.object({
|
|
|
136
153
|
}).strict().superRefine((record, ctx) => {
|
|
137
154
|
if (record.review && record.state !== 'stale')
|
|
138
155
|
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['review'], message: 'withdrawal review belongs only to a stale observation' });
|
|
156
|
+
try {
|
|
157
|
+
assertFieldProvenance(record);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, path: ['field_provenance'], message: error.message });
|
|
161
|
+
}
|
|
139
162
|
});
|
|
140
163
|
const AttributeValue = z.union([z.string().max(2048), z.number().finite(), z.boolean(), z.null()]);
|
|
141
164
|
/** entity — a customer, an incident, a thread: a non-code node, Landscape-shaped (kind-qualified
|
|
142
165
|
* id, lifecycle, provenance), with provenance pointers instead of mirrored content. Stored in
|
|
143
166
|
* an index file, like resources, because kind-qualified ids are not safe file names. */
|
|
144
167
|
export const ExternalEntitySchema = z.object({
|
|
168
|
+
visibility: RecordVisibilitySchema.optional(),
|
|
145
169
|
schema: z.literal(ENTITY_SCHEMA_VERSION),
|
|
146
170
|
id: z.string().min(3).max(2048),
|
|
147
171
|
kind: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/),
|
|
@@ -176,6 +200,7 @@ export const ExternalEntitySchema = z.object({
|
|
|
176
200
|
});
|
|
177
201
|
/** relationship — rides the same identity rule as the graph's edges. Index-file stored. */
|
|
178
202
|
export const StateRelationshipSchema = z.object({
|
|
203
|
+
visibility: RecordVisibilitySchema.optional(),
|
|
179
204
|
schema: z.literal(RELATIONSHIP_SCHEMA_VERSION),
|
|
180
205
|
id: z.string().regex(/^edge_[a-f0-9]+$/),
|
|
181
206
|
from: z.string().min(1).max(2048),
|
|
@@ -203,4 +228,27 @@ export const DnaFacetRefSchema = z.object({
|
|
|
203
228
|
}).strict();
|
|
204
229
|
export const entityId = resourceId;
|
|
205
230
|
export const relationshipId = edgeId;
|
|
231
|
+
export const CONVENTION_SCHEMA_VERSION = "nuryel.convention/1";
|
|
232
|
+
/** Explicit conventions are advisory records. Acceptance records human review, never policy authority. */
|
|
233
|
+
export const ConventionSchema = z.object({
|
|
234
|
+
schema: z.literal(CONVENTION_SCHEMA_VERSION),
|
|
235
|
+
id: z.string().regex(/^ncv_[a-f0-9]{24}$/),
|
|
236
|
+
scope: ScopeSchema,
|
|
237
|
+
key: z.string().regex(/^[a-z][a-z0-9._-]{0,127}$/),
|
|
238
|
+
value: z.string().trim().min(1).max(1200),
|
|
239
|
+
status: z.enum(["proposed", "accepted", "stale", "withdrawn"]),
|
|
240
|
+
sources: z.array(DependencyRefSchema).min(1).max(8),
|
|
241
|
+
valid_from: z.string().regex(ISO),
|
|
242
|
+
valid_to: z.string().regex(ISO).nullable().default(null),
|
|
243
|
+
review_by: z.string().regex(ISO),
|
|
244
|
+
provenance: ProvenanceSchema,
|
|
245
|
+
visibility: RecordVisibilitySchema.optional(),
|
|
246
|
+
}).strict().superRefine((record, ctx) => {
|
|
247
|
+
if (!Number.isFinite(Date.parse(record.valid_from)) || !Number.isFinite(Date.parse(record.review_by)) || Date.parse(record.review_by) <= Date.parse(record.valid_from))
|
|
248
|
+
ctx.addIssue({ code: 'custom', message: 'review_by must be a valid instant after valid_from' });
|
|
249
|
+
if (record.sources.some(source => source.kind === 'schema' || (source.kind === 'external' && !source.ref.version && !source.ref.content_hash)))
|
|
250
|
+
ctx.addIssue({ code: 'custom', path: ['sources'], message: 'conventions require exact record hashes or versioned/hashed external sources' });
|
|
251
|
+
if (record.status === 'accepted' && !record.provenance.source.split('+').includes('human_confirmed'))
|
|
252
|
+
ctx.addIssue({ code: 'custom', path: ['status'], message: 'accepted conventions require human-confirmed provenance' });
|
|
253
|
+
});
|
|
206
254
|
//# sourceMappingURL=stateRecords.js.map
|