knosky 0.6.3 → 0.7.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/CHANGELOG.md +149 -93
- package/CREDITS.md +14 -14
- package/LICENSE.md +76 -76
- package/LIMITATIONS.md +33 -23
- package/PRIVACY.md +30 -30
- package/README.md +170 -117
- package/SECURITY.md +78 -46
- package/action/post-comment.mjs +94 -89
- package/action.yml +62 -62
- package/bin/knosky.mjs +279 -105
- package/core/CONTRACT.md +70 -70
- package/core/append-only-checkpoint.mjs +215 -0
- package/core/audit-writer.mjs +317 -0
- package/core/benchmark-results.mjs +225 -225
- package/core/bundle.mjs +178 -178
- package/core/churn.mjs +23 -23
- package/core/ci.mjs +268 -268
- package/core/comparison.mjs +189 -189
- package/core/config.mjs +189 -189
- package/core/constants.mjs +13 -13
- package/core/contract.mjs +123 -123
- package/core/cross-repo.mjs +111 -111
- package/core/decision-codes.mjs +92 -0
- package/core/destination.mjs +161 -161
- package/core/district-classification.mjs +111 -0
- package/core/doctor-scorecard.mjs +369 -0
- package/core/domain-store.mjs +347 -0
- package/core/edges.mjs +43 -43
- package/core/escalate.mjs +68 -68
- package/core/freshness.mjs +198 -194
- package/core/fs-indexer.mjs +218 -218
- package/core/key-store.mjs +348 -348
- package/core/layout.mjs +46 -46
- package/core/ledger.mjs +176 -141
- package/core/local-ipc-identity.mjs +500 -0
- package/core/lod.mjs +155 -155
- package/core/mode-b.mjs +410 -0
- package/core/multi-model-benchmark.mjs +405 -405
- package/core/net-lockdown.mjs +421 -0
- package/core/onboarding.mjs +223 -223
- package/core/operator-auth.mjs +317 -0
- package/core/overlays.mjs +45 -45
- package/core/policy-lattice.mjs +142 -0
- package/core/pr-comment.mjs +198 -198
- package/core/protocol-spec.mjs +460 -460
- package/core/provenance.mjs +320 -0
- package/core/retrieve.mjs +63 -63
- package/core/route.mjs +304 -304
- package/core/schema.mjs +275 -275
- package/core/signing-tiers.mjs +1265 -0
- package/core/swarm-bench.mjs +106 -0
- package/core/swarm-coordinator.mjs +867 -0
- package/core/trust-root-rekey.mjs +410 -0
- package/mcp/server.mjs +264 -108
- package/package.json +56 -46
- package/renderer/art/kenney/buildingTiles_sheet.xml +130 -130
- package/renderer/art/kenney/cityDetails_sheet.xml +12 -12
- package/renderer/art/kenney/landscapeTiles_sheet.xml +129 -129
- package/renderer/art/kenney/sheet_allCars.xml +545 -545
- package/renderer/build-rich.mjs +43 -43
- package/renderer/city.template.html +808 -808
- package/ssot/decision-codes.json +133 -0
- package/ssot/ladder-l0-l3.md +232 -0
- package/ssot/tool-menu.json +130 -0
package/core/protocol-spec.mjs
CHANGED
|
@@ -1,460 +1,460 @@
|
|
|
1
|
-
// KnoSky machine-readable protocol spec (SAT-462).
|
|
2
|
-
// Exports authoritative JSON Schema (Draft 2020-12) objects for every protocol artifact.
|
|
3
|
-
// Pure ESM, no dependencies — the objects are plain JSON-serializable data.
|
|
4
|
-
//
|
|
5
|
-
// Four schemas are published:
|
|
6
|
-
// ROUTE_SCHEMA — the `route` artifact written by kc_route / kcRoute()
|
|
7
|
-
// INTENT_MANIFEST_SCHEMA — the `intent-manifest` artifact written by kc_bundle / kcBundle()
|
|
8
|
-
// CONFIG_SCHEMA — the `.knosky/config.yml` file (after YAML → JS object parse)
|
|
9
|
-
// CITY_SCHEMA — the city-data v2 envelope (core/CONTRACT.md)
|
|
10
|
-
//
|
|
11
|
-
// These complement, and must stay consistent with, the runtime validators in:
|
|
12
|
-
// core/schema.mjs (route + intent-manifest)
|
|
13
|
-
// core/config.mjs (config)
|
|
14
|
-
// core/contract.mjs (city)
|
|
15
|
-
//
|
|
16
|
-
// Protocol version constants (mirrors runtime constants in schema.mjs / config.mjs).
|
|
17
|
-
export const PROTOCOL_VERSION = '1.0'; // knosky_protocol field value
|
|
18
|
-
export const CITY_SCHEMA_VERSION = '2.0'; // schema_version field value
|
|
19
|
-
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
// Reusable sub-schemas
|
|
22
|
-
// ---------------------------------------------------------------------------
|
|
23
|
-
|
|
24
|
-
/** A path entry inside route[] / alternates[]: either a bare string or an object with a `path` field. */
|
|
25
|
-
const PATH_ENTRY = {
|
|
26
|
-
oneOf: [
|
|
27
|
-
{ type: 'string', minLength: 1 },
|
|
28
|
-
{
|
|
29
|
-
type: 'object',
|
|
30
|
-
required: ['path'],
|
|
31
|
-
properties: {
|
|
32
|
-
path: { type: 'string', minLength: 1 },
|
|
33
|
-
},
|
|
34
|
-
additionalProperties: true,
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/** A KnoSky secret-scan result object embedded in the intent-manifest. */
|
|
40
|
-
const SECRET_SCAN_RESULT = {
|
|
41
|
-
type: 'object',
|
|
42
|
-
required: ['status'],
|
|
43
|
-
properties: {
|
|
44
|
-
status: { type: 'string', enum: ['clean', 'blocked'] },
|
|
45
|
-
detail: { type: 'string' },
|
|
46
|
-
},
|
|
47
|
-
additionalProperties: true,
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/** A provenance object embedded in every city node. */
|
|
51
|
-
const PROVENANCE = {
|
|
52
|
-
type: 'object',
|
|
53
|
-
required: ['store', 'ref'],
|
|
54
|
-
properties: {
|
|
55
|
-
store: { type: 'string', minLength: 1 },
|
|
56
|
-
ref: { type: 'string', minLength: 1 },
|
|
57
|
-
source_rev: { type: 'string' },
|
|
58
|
-
fetched_at: { type: 'string' },
|
|
59
|
-
},
|
|
60
|
-
additionalProperties: true,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
// ROUTE_SCHEMA
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* JSON Schema (Draft 2020-12) for the KnoSky `route` artifact.
|
|
69
|
-
* Produced by kc_route / kcRoute(). Must agree with validateRouteDoc() in core/schema.mjs.
|
|
70
|
-
*
|
|
71
|
-
* @type {object}
|
|
72
|
-
*/
|
|
73
|
-
export const ROUTE_SCHEMA = {
|
|
74
|
-
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
75
|
-
$id: 'https://knosky.com/schemas/route.json',
|
|
76
|
-
title: 'KnoSky Route',
|
|
77
|
-
description:
|
|
78
|
-
'Advisory navigation route produced by kc_route. ' +
|
|
79
|
-
'Structural metadata only — never code analysis. ' +
|
|
80
|
-
'Always advisory: the `advisory` field is invariantly true.',
|
|
81
|
-
type: 'object',
|
|
82
|
-
required: [
|
|
83
|
-
'knosky_protocol',
|
|
84
|
-
'artifact_type',
|
|
85
|
-
'advisory',
|
|
86
|
-
'generated_at',
|
|
87
|
-
'destination',
|
|
88
|
-
'route',
|
|
89
|
-
'alternates',
|
|
90
|
-
'caveats',
|
|
91
|
-
'confidence',
|
|
92
|
-
],
|
|
93
|
-
additionalProperties: true,
|
|
94
|
-
properties: {
|
|
95
|
-
knosky_protocol: {
|
|
96
|
-
type: 'string',
|
|
97
|
-
const: '1.0',
|
|
98
|
-
description: 'Protocol version. Always "1.0" for this schema.',
|
|
99
|
-
},
|
|
100
|
-
artifact_type: {
|
|
101
|
-
type: 'string',
|
|
102
|
-
const: 'route',
|
|
103
|
-
description: 'Discriminator field. Always "route" for this artifact.',
|
|
104
|
-
},
|
|
105
|
-
advisory: {
|
|
106
|
-
type: 'boolean',
|
|
107
|
-
const: true,
|
|
108
|
-
description: 'Invariantly true — routes are advisory, never authoritative.',
|
|
109
|
-
},
|
|
110
|
-
generated_at: {
|
|
111
|
-
type: 'string',
|
|
112
|
-
format: 'date-time',
|
|
113
|
-
description: 'ISO-8601 timestamp at which this document was generated.',
|
|
114
|
-
},
|
|
115
|
-
source_rev: {
|
|
116
|
-
type: ['string', 'null'],
|
|
117
|
-
description: 'VCS revision (e.g. git commit SHA) of the city index used. Null when unknown.',
|
|
118
|
-
},
|
|
119
|
-
destination: {
|
|
120
|
-
type: 'string',
|
|
121
|
-
description: 'The navigation target string supplied by the caller.',
|
|
122
|
-
},
|
|
123
|
-
route: {
|
|
124
|
-
type: 'array',
|
|
125
|
-
items: PATH_ENTRY,
|
|
126
|
-
description: 'Ordered primary waypoints. Each entry is a path string or { path, id, reason, score }.',
|
|
127
|
-
},
|
|
128
|
-
alternates: {
|
|
129
|
-
type: 'array',
|
|
130
|
-
items: PATH_ENTRY,
|
|
131
|
-
description: 'Alternate waypoints beyond the primary route limit.',
|
|
132
|
-
},
|
|
133
|
-
caveats: {
|
|
134
|
-
type: 'array',
|
|
135
|
-
items: { type: 'string' },
|
|
136
|
-
description:
|
|
137
|
-
'Advisory notes. Always contains at least the mandatory advisory caveat. ' +
|
|
138
|
-
'May include churn, coverage, and staleness warnings.',
|
|
139
|
-
},
|
|
140
|
-
confidence: {
|
|
141
|
-
type: 'number',
|
|
142
|
-
minimum: 0,
|
|
143
|
-
maximum: 1,
|
|
144
|
-
description: 'Estimated confidence of the route [0..1]. 0 = no signal; ~0.95 = direct file match.',
|
|
145
|
-
},
|
|
146
|
-
tests: {
|
|
147
|
-
type: 'array',
|
|
148
|
-
items: { type: 'object' },
|
|
149
|
-
description: 'Test files in the candidate neighbourhood (informational).',
|
|
150
|
-
},
|
|
151
|
-
docs: {
|
|
152
|
-
type: 'array',
|
|
153
|
-
items: { type: 'object' },
|
|
154
|
-
description: 'Documentation files in the candidate neighbourhood (informational).',
|
|
155
|
-
},
|
|
156
|
-
},
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
// ---------------------------------------------------------------------------
|
|
160
|
-
// INTENT_MANIFEST_SCHEMA
|
|
161
|
-
// ---------------------------------------------------------------------------
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* JSON Schema (Draft 2020-12) for the KnoSky `intent-manifest` artifact.
|
|
165
|
-
* Produced by kc_bundle / kcBundle(). Must agree with validateIntentManifest() in core/schema.mjs.
|
|
166
|
-
*
|
|
167
|
-
* @type {object}
|
|
168
|
-
*/
|
|
169
|
-
export const INTENT_MANIFEST_SCHEMA = {
|
|
170
|
-
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
171
|
-
$id: 'https://knosky.com/schemas/intent-manifest.json',
|
|
172
|
-
title: 'KnoSky Intent Manifest',
|
|
173
|
-
description:
|
|
174
|
-
'Shareable, verifiable file-set manifest produced by kc_bundle. ' +
|
|
175
|
-
'Each path entry carries a SHA-256 digest. ' +
|
|
176
|
-
'The secret_scan field signals whether the manifest was produced by a clean or blocked scan.',
|
|
177
|
-
type: 'object',
|
|
178
|
-
required: [
|
|
179
|
-
'knosky_protocol',
|
|
180
|
-
'artifact_type',
|
|
181
|
-
'advisory',
|
|
182
|
-
'generated_at',
|
|
183
|
-
'paths',
|
|
184
|
-
'edges',
|
|
185
|
-
'secret_scan',
|
|
186
|
-
],
|
|
187
|
-
additionalProperties: true,
|
|
188
|
-
properties: {
|
|
189
|
-
knosky_protocol: {
|
|
190
|
-
type: 'string',
|
|
191
|
-
const: '1.0',
|
|
192
|
-
description: 'Protocol version. Always "1.0" for this schema.',
|
|
193
|
-
},
|
|
194
|
-
artifact_type: {
|
|
195
|
-
type: 'string',
|
|
196
|
-
const: 'intent-manifest',
|
|
197
|
-
description: 'Discriminator field. Always "intent-manifest" for this artifact.',
|
|
198
|
-
},
|
|
199
|
-
advisory: {
|
|
200
|
-
type: 'boolean',
|
|
201
|
-
const: true,
|
|
202
|
-
description: 'Invariantly true.',
|
|
203
|
-
},
|
|
204
|
-
generated_at: {
|
|
205
|
-
type: 'string',
|
|
206
|
-
format: 'date-time',
|
|
207
|
-
description: 'ISO-8601 timestamp at which this document was generated.',
|
|
208
|
-
},
|
|
209
|
-
paths: {
|
|
210
|
-
type: 'array',
|
|
211
|
-
items: {
|
|
212
|
-
type: 'object',
|
|
213
|
-
required: ['path', 'sha256'],
|
|
214
|
-
properties: {
|
|
215
|
-
path: {
|
|
216
|
-
type: 'string',
|
|
217
|
-
minLength: 1,
|
|
218
|
-
description: 'Repo-relative path. Must not be absolute or contain ".." segments.',
|
|
219
|
-
},
|
|
220
|
-
sha256: {
|
|
221
|
-
type: 'string',
|
|
222
|
-
description: 'Hex-encoded SHA-256 digest of the file at bundle time. Empty string when unreadable.',
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
additionalProperties: true,
|
|
226
|
-
},
|
|
227
|
-
description: 'Ordered list of files covered by this manifest.',
|
|
228
|
-
},
|
|
229
|
-
edges: {
|
|
230
|
-
type: 'array',
|
|
231
|
-
items: { type: 'object' },
|
|
232
|
-
description: 'Dependency edges among the covered files.',
|
|
233
|
-
},
|
|
234
|
-
expiry: {
|
|
235
|
-
type: ['string', 'null'],
|
|
236
|
-
description: 'ISO-8601 expiry timestamp, or null for no expiry.',
|
|
237
|
-
},
|
|
238
|
-
secret_scan: {
|
|
239
|
-
...SECRET_SCAN_RESULT,
|
|
240
|
-
description:
|
|
241
|
-
'Result of the fail-closed secret scan run at bundle time. ' +
|
|
242
|
-
'"clean" means no secret-like values were detected; ' +
|
|
243
|
-
'"blocked" means the scan found a pattern match and the bundle should not be shared.',
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
// ---------------------------------------------------------------------------
|
|
249
|
-
// CONFIG_SCHEMA
|
|
250
|
-
// ---------------------------------------------------------------------------
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* JSON Schema (Draft 2020-12) for a KnoSky project config object
|
|
254
|
-
* (`.knosky/config.yml`, parsed to a JS object by loadConfig()).
|
|
255
|
-
* Must agree with validateConfig() in core/config.mjs.
|
|
256
|
-
*
|
|
257
|
-
* @type {object}
|
|
258
|
-
*/
|
|
259
|
-
export const CONFIG_SCHEMA = {
|
|
260
|
-
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
261
|
-
$id: 'https://knosky.com/schemas/config.json',
|
|
262
|
-
title: 'KnoSky Project Config',
|
|
263
|
-
description:
|
|
264
|
-
'KnoSky project configuration. Read from `.knosky/config.yml`; ' +
|
|
265
|
-
'missing fields default to the values shown in `default`. ' +
|
|
266
|
-
'Unknown keys are rejected by validateConfig().',
|
|
267
|
-
type: 'object',
|
|
268
|
-
required: [
|
|
269
|
-
'knosky_protocol',
|
|
270
|
-
'telemetry',
|
|
271
|
-
'absolute_paths',
|
|
272
|
-
'fail_on_secret',
|
|
273
|
-
'allow_excerpts',
|
|
274
|
-
'max_excerpt_chars',
|
|
275
|
-
'categories',
|
|
276
|
-
'ignore',
|
|
277
|
-
],
|
|
278
|
-
additionalProperties: false,
|
|
279
|
-
properties: {
|
|
280
|
-
knosky_protocol: {
|
|
281
|
-
type: 'string',
|
|
282
|
-
const: '1.0',
|
|
283
|
-
default: '1.0',
|
|
284
|
-
description: 'Protocol version. Must be "1.0".',
|
|
285
|
-
},
|
|
286
|
-
telemetry: {
|
|
287
|
-
type: 'boolean',
|
|
288
|
-
default: false,
|
|
289
|
-
description: 'Whether to emit telemetry. Defaults to false (never sends data out).',
|
|
290
|
-
},
|
|
291
|
-
absolute_paths: {
|
|
292
|
-
type: 'boolean',
|
|
293
|
-
default: false,
|
|
294
|
-
description: 'Embed absolute filesystem paths in the city output. Defaults to false (basename only).',
|
|
295
|
-
},
|
|
296
|
-
fail_on_secret: {
|
|
297
|
-
type: 'boolean',
|
|
298
|
-
default: true,
|
|
299
|
-
description: 'Abort the build if a secret-like value is detected. Defaults to true (fail-closed).',
|
|
300
|
-
},
|
|
301
|
-
allow_excerpts: {
|
|
302
|
-
type: 'boolean',
|
|
303
|
-
default: false,
|
|
304
|
-
description: 'Include file-content excerpts in the index. Defaults to false.',
|
|
305
|
-
},
|
|
306
|
-
max_excerpt_chars: {
|
|
307
|
-
type: 'integer',
|
|
308
|
-
minimum: 0,
|
|
309
|
-
default: 0,
|
|
310
|
-
description: 'Maximum characters per excerpt. 0 = no excerpts even when allow_excerpts is true.',
|
|
311
|
-
},
|
|
312
|
-
categories: {
|
|
313
|
-
type: 'array',
|
|
314
|
-
items: { type: 'string' },
|
|
315
|
-
default: [],
|
|
316
|
-
description: 'Explicit category (district) labels. Empty array = derived automatically.',
|
|
317
|
-
},
|
|
318
|
-
ignore: {
|
|
319
|
-
type: 'array',
|
|
320
|
-
items: { type: 'string' },
|
|
321
|
-
default: [],
|
|
322
|
-
description: 'Additional glob-style ignore patterns (appended to the built-in defaults and .gitignore).',
|
|
323
|
-
},
|
|
324
|
-
},
|
|
325
|
-
};
|
|
326
|
-
|
|
327
|
-
// ---------------------------------------------------------------------------
|
|
328
|
-
// CITY_SCHEMA
|
|
329
|
-
// ---------------------------------------------------------------------------
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* JSON Schema (Draft 2020-12) for a KnoSky city-data v2 envelope.
|
|
333
|
-
* Produced by the fs-indexer and consumed by the renderer / MCP server.
|
|
334
|
-
* Must agree with validateCity() + NODE_FIELD_ALLOWLIST in core/contract.mjs.
|
|
335
|
-
*
|
|
336
|
-
* @type {object}
|
|
337
|
-
*/
|
|
338
|
-
export const CITY_SCHEMA = {
|
|
339
|
-
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
340
|
-
$id: 'https://knosky.com/schemas/city.json',
|
|
341
|
-
title: 'KnoSky City Data (v2)',
|
|
342
|
-
description:
|
|
343
|
-
'N-category city-data envelope (contract v2). ' +
|
|
344
|
-
'Contains pointers and projections only — never full file bodies (decision D-146). ' +
|
|
345
|
-
'See core/CONTRACT.md for narrative spec.',
|
|
346
|
-
type: 'object',
|
|
347
|
-
required: ['schema_version', 'generated_at', 'categories', 'nodes'],
|
|
348
|
-
additionalProperties: true,
|
|
349
|
-
properties: {
|
|
350
|
-
schema_version: {
|
|
351
|
-
type: 'string',
|
|
352
|
-
const: '2.0',
|
|
353
|
-
description: 'City contract version. Always "2.0" for this schema.',
|
|
354
|
-
},
|
|
355
|
-
generated_at: {
|
|
356
|
-
type: 'string',
|
|
357
|
-
format: 'date-time',
|
|
358
|
-
description: 'ISO-8601 timestamp at which the city was built.',
|
|
359
|
-
},
|
|
360
|
-
source: {
|
|
361
|
-
type: 'object',
|
|
362
|
-
required: ['kind', 'ref'],
|
|
363
|
-
properties: {
|
|
364
|
-
kind: { type: 'string', enum: ['fs', 'github', 'board', 'legacy'] },
|
|
365
|
-
ref: { type: 'string' },
|
|
366
|
-
rev: { type: 'string' },
|
|
367
|
-
},
|
|
368
|
-
additionalProperties: false,
|
|
369
|
-
description: 'Where the city was built from.',
|
|
370
|
-
},
|
|
371
|
-
categories: {
|
|
372
|
-
type: 'array',
|
|
373
|
-
items: {
|
|
374
|
-
type: 'object',
|
|
375
|
-
required: ['id', 'label', 'order'],
|
|
376
|
-
properties: {
|
|
377
|
-
id: { type: 'string', minLength: 1 },
|
|
378
|
-
label: { type: 'string', minLength: 1 },
|
|
379
|
-
color: { type: 'string' },
|
|
380
|
-
order: { type: 'integer', minimum: 0 },
|
|
381
|
-
},
|
|
382
|
-
additionalProperties: false,
|
|
383
|
-
},
|
|
384
|
-
description: 'N-category manifest. Replaces the hardcoded 4-district v1 model.',
|
|
385
|
-
},
|
|
386
|
-
node_count: {
|
|
387
|
-
type: 'integer',
|
|
388
|
-
minimum: 0,
|
|
389
|
-
description: 'Expected number of nodes. Must equal nodes.length when present.',
|
|
390
|
-
},
|
|
391
|
-
nodes: {
|
|
392
|
-
type: 'array',
|
|
393
|
-
items: {
|
|
394
|
-
type: 'object',
|
|
395
|
-
required: ['id', 'kind', 'title', 'category', 'links', 'provenance'],
|
|
396
|
-
// additionalProperties:false enforces the serialization allowlist from contract.mjs.
|
|
397
|
-
additionalProperties: false,
|
|
398
|
-
properties: {
|
|
399
|
-
id: {
|
|
400
|
-
type: 'string',
|
|
401
|
-
minLength: 1,
|
|
402
|
-
description: 'Stable, source-derived node identifier.',
|
|
403
|
-
},
|
|
404
|
-
kind: {
|
|
405
|
-
type: 'string',
|
|
406
|
-
description: 'Node kind: decision, spec, file, dir, doc, …',
|
|
407
|
-
},
|
|
408
|
-
title: {
|
|
409
|
-
type: 'string',
|
|
410
|
-
description: 'Short projection title (scrubbed; never a full file body).',
|
|
411
|
-
},
|
|
412
|
-
summary: {
|
|
413
|
-
type: 'string',
|
|
414
|
-
maxLength: 200,
|
|
415
|
-
description:
|
|
416
|
-
'Short excerpt projection (≤ 200 chars, scrubbed; never a full file body).',
|
|
417
|
-
},
|
|
418
|
-
category: {
|
|
419
|
-
type: 'string',
|
|
420
|
-
description: 'Category id. Must match an entry in the top-level categories[] manifest.',
|
|
421
|
-
},
|
|
422
|
-
status: { type: 'string' },
|
|
423
|
-
fact_date: { type: 'string' },
|
|
424
|
-
tags: {
|
|
425
|
-
type: 'array',
|
|
426
|
-
items: { type: 'string' },
|
|
427
|
-
},
|
|
428
|
-
headings: {
|
|
429
|
-
type: 'array',
|
|
430
|
-
items: { type: 'string' },
|
|
431
|
-
},
|
|
432
|
-
links: {
|
|
433
|
-
type: 'array',
|
|
434
|
-
items: { type: 'string' },
|
|
435
|
-
description: 'Edges to other node ids.',
|
|
436
|
-
},
|
|
437
|
-
churn: {
|
|
438
|
-
description: 'Recent-change signal. Object with `c` (commit count) or a plain number.',
|
|
439
|
-
},
|
|
440
|
-
provenance: {
|
|
441
|
-
...PROVENANCE,
|
|
442
|
-
description: 'Back-pointer to the live source. Fields: store (required), ref (required).',
|
|
443
|
-
},
|
|
444
|
-
visibility: {
|
|
445
|
-
type: 'string',
|
|
446
|
-
enum: ['internal', 'public'],
|
|
447
|
-
},
|
|
448
|
-
sensitive: {
|
|
449
|
-
type: 'boolean',
|
|
450
|
-
description: 'Scrub/flag marker. True when a sensitive-term match was found.',
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
},
|
|
454
|
-
description:
|
|
455
|
-
'All nodes in the city. Node fields are strictly limited to the serialization allowlist ' +
|
|
456
|
-
'(id, kind, title, summary, category, status, fact_date, tags, headings, links, churn, ' +
|
|
457
|
-
'provenance, visibility, sensitive).',
|
|
458
|
-
},
|
|
459
|
-
},
|
|
460
|
-
};
|
|
1
|
+
// KnoSky machine-readable protocol spec (SAT-462).
|
|
2
|
+
// Exports authoritative JSON Schema (Draft 2020-12) objects for every protocol artifact.
|
|
3
|
+
// Pure ESM, no dependencies — the objects are plain JSON-serializable data.
|
|
4
|
+
//
|
|
5
|
+
// Four schemas are published:
|
|
6
|
+
// ROUTE_SCHEMA — the `route` artifact written by kc_route / kcRoute()
|
|
7
|
+
// INTENT_MANIFEST_SCHEMA — the `intent-manifest` artifact written by kc_bundle / kcBundle()
|
|
8
|
+
// CONFIG_SCHEMA — the `.knosky/config.yml` file (after YAML → JS object parse)
|
|
9
|
+
// CITY_SCHEMA — the city-data v2 envelope (core/CONTRACT.md)
|
|
10
|
+
//
|
|
11
|
+
// These complement, and must stay consistent with, the runtime validators in:
|
|
12
|
+
// core/schema.mjs (route + intent-manifest)
|
|
13
|
+
// core/config.mjs (config)
|
|
14
|
+
// core/contract.mjs (city)
|
|
15
|
+
//
|
|
16
|
+
// Protocol version constants (mirrors runtime constants in schema.mjs / config.mjs).
|
|
17
|
+
export const PROTOCOL_VERSION = '1.0'; // knosky_protocol field value
|
|
18
|
+
export const CITY_SCHEMA_VERSION = '2.0'; // schema_version field value
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Reusable sub-schemas
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
/** A path entry inside route[] / alternates[]: either a bare string or an object with a `path` field. */
|
|
25
|
+
const PATH_ENTRY = {
|
|
26
|
+
oneOf: [
|
|
27
|
+
{ type: 'string', minLength: 1 },
|
|
28
|
+
{
|
|
29
|
+
type: 'object',
|
|
30
|
+
required: ['path'],
|
|
31
|
+
properties: {
|
|
32
|
+
path: { type: 'string', minLength: 1 },
|
|
33
|
+
},
|
|
34
|
+
additionalProperties: true,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** A KnoSky secret-scan result object embedded in the intent-manifest. */
|
|
40
|
+
const SECRET_SCAN_RESULT = {
|
|
41
|
+
type: 'object',
|
|
42
|
+
required: ['status'],
|
|
43
|
+
properties: {
|
|
44
|
+
status: { type: 'string', enum: ['clean', 'blocked'] },
|
|
45
|
+
detail: { type: 'string' },
|
|
46
|
+
},
|
|
47
|
+
additionalProperties: true,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/** A provenance object embedded in every city node. */
|
|
51
|
+
const PROVENANCE = {
|
|
52
|
+
type: 'object',
|
|
53
|
+
required: ['store', 'ref'],
|
|
54
|
+
properties: {
|
|
55
|
+
store: { type: 'string', minLength: 1 },
|
|
56
|
+
ref: { type: 'string', minLength: 1 },
|
|
57
|
+
source_rev: { type: 'string' },
|
|
58
|
+
fetched_at: { type: 'string' },
|
|
59
|
+
},
|
|
60
|
+
additionalProperties: true,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// ROUTE_SCHEMA
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* JSON Schema (Draft 2020-12) for the KnoSky `route` artifact.
|
|
69
|
+
* Produced by kc_route / kcRoute(). Must agree with validateRouteDoc() in core/schema.mjs.
|
|
70
|
+
*
|
|
71
|
+
* @type {object}
|
|
72
|
+
*/
|
|
73
|
+
export const ROUTE_SCHEMA = {
|
|
74
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
75
|
+
$id: 'https://knosky.com/schemas/route.json',
|
|
76
|
+
title: 'KnoSky Route',
|
|
77
|
+
description:
|
|
78
|
+
'Advisory navigation route produced by kc_route. ' +
|
|
79
|
+
'Structural metadata only — never code analysis. ' +
|
|
80
|
+
'Always advisory: the `advisory` field is invariantly true.',
|
|
81
|
+
type: 'object',
|
|
82
|
+
required: [
|
|
83
|
+
'knosky_protocol',
|
|
84
|
+
'artifact_type',
|
|
85
|
+
'advisory',
|
|
86
|
+
'generated_at',
|
|
87
|
+
'destination',
|
|
88
|
+
'route',
|
|
89
|
+
'alternates',
|
|
90
|
+
'caveats',
|
|
91
|
+
'confidence',
|
|
92
|
+
],
|
|
93
|
+
additionalProperties: true,
|
|
94
|
+
properties: {
|
|
95
|
+
knosky_protocol: {
|
|
96
|
+
type: 'string',
|
|
97
|
+
const: '1.0',
|
|
98
|
+
description: 'Protocol version. Always "1.0" for this schema.',
|
|
99
|
+
},
|
|
100
|
+
artifact_type: {
|
|
101
|
+
type: 'string',
|
|
102
|
+
const: 'route',
|
|
103
|
+
description: 'Discriminator field. Always "route" for this artifact.',
|
|
104
|
+
},
|
|
105
|
+
advisory: {
|
|
106
|
+
type: 'boolean',
|
|
107
|
+
const: true,
|
|
108
|
+
description: 'Invariantly true — routes are advisory, never authoritative.',
|
|
109
|
+
},
|
|
110
|
+
generated_at: {
|
|
111
|
+
type: 'string',
|
|
112
|
+
format: 'date-time',
|
|
113
|
+
description: 'ISO-8601 timestamp at which this document was generated.',
|
|
114
|
+
},
|
|
115
|
+
source_rev: {
|
|
116
|
+
type: ['string', 'null'],
|
|
117
|
+
description: 'VCS revision (e.g. git commit SHA) of the city index used. Null when unknown.',
|
|
118
|
+
},
|
|
119
|
+
destination: {
|
|
120
|
+
type: 'string',
|
|
121
|
+
description: 'The navigation target string supplied by the caller.',
|
|
122
|
+
},
|
|
123
|
+
route: {
|
|
124
|
+
type: 'array',
|
|
125
|
+
items: PATH_ENTRY,
|
|
126
|
+
description: 'Ordered primary waypoints. Each entry is a path string or { path, id, reason, score }.',
|
|
127
|
+
},
|
|
128
|
+
alternates: {
|
|
129
|
+
type: 'array',
|
|
130
|
+
items: PATH_ENTRY,
|
|
131
|
+
description: 'Alternate waypoints beyond the primary route limit.',
|
|
132
|
+
},
|
|
133
|
+
caveats: {
|
|
134
|
+
type: 'array',
|
|
135
|
+
items: { type: 'string' },
|
|
136
|
+
description:
|
|
137
|
+
'Advisory notes. Always contains at least the mandatory advisory caveat. ' +
|
|
138
|
+
'May include churn, coverage, and staleness warnings.',
|
|
139
|
+
},
|
|
140
|
+
confidence: {
|
|
141
|
+
type: 'number',
|
|
142
|
+
minimum: 0,
|
|
143
|
+
maximum: 1,
|
|
144
|
+
description: 'Estimated confidence of the route [0..1]. 0 = no signal; ~0.95 = direct file match.',
|
|
145
|
+
},
|
|
146
|
+
tests: {
|
|
147
|
+
type: 'array',
|
|
148
|
+
items: { type: 'object' },
|
|
149
|
+
description: 'Test files in the candidate neighbourhood (informational).',
|
|
150
|
+
},
|
|
151
|
+
docs: {
|
|
152
|
+
type: 'array',
|
|
153
|
+
items: { type: 'object' },
|
|
154
|
+
description: 'Documentation files in the candidate neighbourhood (informational).',
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
// INTENT_MANIFEST_SCHEMA
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* JSON Schema (Draft 2020-12) for the KnoSky `intent-manifest` artifact.
|
|
165
|
+
* Produced by kc_bundle / kcBundle(). Must agree with validateIntentManifest() in core/schema.mjs.
|
|
166
|
+
*
|
|
167
|
+
* @type {object}
|
|
168
|
+
*/
|
|
169
|
+
export const INTENT_MANIFEST_SCHEMA = {
|
|
170
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
171
|
+
$id: 'https://knosky.com/schemas/intent-manifest.json',
|
|
172
|
+
title: 'KnoSky Intent Manifest',
|
|
173
|
+
description:
|
|
174
|
+
'Shareable, verifiable file-set manifest produced by kc_bundle. ' +
|
|
175
|
+
'Each path entry carries a SHA-256 digest. ' +
|
|
176
|
+
'The secret_scan field signals whether the manifest was produced by a clean or blocked scan.',
|
|
177
|
+
type: 'object',
|
|
178
|
+
required: [
|
|
179
|
+
'knosky_protocol',
|
|
180
|
+
'artifact_type',
|
|
181
|
+
'advisory',
|
|
182
|
+
'generated_at',
|
|
183
|
+
'paths',
|
|
184
|
+
'edges',
|
|
185
|
+
'secret_scan',
|
|
186
|
+
],
|
|
187
|
+
additionalProperties: true,
|
|
188
|
+
properties: {
|
|
189
|
+
knosky_protocol: {
|
|
190
|
+
type: 'string',
|
|
191
|
+
const: '1.0',
|
|
192
|
+
description: 'Protocol version. Always "1.0" for this schema.',
|
|
193
|
+
},
|
|
194
|
+
artifact_type: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
const: 'intent-manifest',
|
|
197
|
+
description: 'Discriminator field. Always "intent-manifest" for this artifact.',
|
|
198
|
+
},
|
|
199
|
+
advisory: {
|
|
200
|
+
type: 'boolean',
|
|
201
|
+
const: true,
|
|
202
|
+
description: 'Invariantly true.',
|
|
203
|
+
},
|
|
204
|
+
generated_at: {
|
|
205
|
+
type: 'string',
|
|
206
|
+
format: 'date-time',
|
|
207
|
+
description: 'ISO-8601 timestamp at which this document was generated.',
|
|
208
|
+
},
|
|
209
|
+
paths: {
|
|
210
|
+
type: 'array',
|
|
211
|
+
items: {
|
|
212
|
+
type: 'object',
|
|
213
|
+
required: ['path', 'sha256'],
|
|
214
|
+
properties: {
|
|
215
|
+
path: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
minLength: 1,
|
|
218
|
+
description: 'Repo-relative path. Must not be absolute or contain ".." segments.',
|
|
219
|
+
},
|
|
220
|
+
sha256: {
|
|
221
|
+
type: 'string',
|
|
222
|
+
description: 'Hex-encoded SHA-256 digest of the file at bundle time. Empty string when unreadable.',
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
additionalProperties: true,
|
|
226
|
+
},
|
|
227
|
+
description: 'Ordered list of files covered by this manifest.',
|
|
228
|
+
},
|
|
229
|
+
edges: {
|
|
230
|
+
type: 'array',
|
|
231
|
+
items: { type: 'object' },
|
|
232
|
+
description: 'Dependency edges among the covered files.',
|
|
233
|
+
},
|
|
234
|
+
expiry: {
|
|
235
|
+
type: ['string', 'null'],
|
|
236
|
+
description: 'ISO-8601 expiry timestamp, or null for no expiry.',
|
|
237
|
+
},
|
|
238
|
+
secret_scan: {
|
|
239
|
+
...SECRET_SCAN_RESULT,
|
|
240
|
+
description:
|
|
241
|
+
'Result of the fail-closed secret scan run at bundle time. ' +
|
|
242
|
+
'"clean" means no secret-like values were detected; ' +
|
|
243
|
+
'"blocked" means the scan found a pattern match and the bundle should not be shared.',
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
// ---------------------------------------------------------------------------
|
|
249
|
+
// CONFIG_SCHEMA
|
|
250
|
+
// ---------------------------------------------------------------------------
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* JSON Schema (Draft 2020-12) for a KnoSky project config object
|
|
254
|
+
* (`.knosky/config.yml`, parsed to a JS object by loadConfig()).
|
|
255
|
+
* Must agree with validateConfig() in core/config.mjs.
|
|
256
|
+
*
|
|
257
|
+
* @type {object}
|
|
258
|
+
*/
|
|
259
|
+
export const CONFIG_SCHEMA = {
|
|
260
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
261
|
+
$id: 'https://knosky.com/schemas/config.json',
|
|
262
|
+
title: 'KnoSky Project Config',
|
|
263
|
+
description:
|
|
264
|
+
'KnoSky project configuration. Read from `.knosky/config.yml`; ' +
|
|
265
|
+
'missing fields default to the values shown in `default`. ' +
|
|
266
|
+
'Unknown keys are rejected by validateConfig().',
|
|
267
|
+
type: 'object',
|
|
268
|
+
required: [
|
|
269
|
+
'knosky_protocol',
|
|
270
|
+
'telemetry',
|
|
271
|
+
'absolute_paths',
|
|
272
|
+
'fail_on_secret',
|
|
273
|
+
'allow_excerpts',
|
|
274
|
+
'max_excerpt_chars',
|
|
275
|
+
'categories',
|
|
276
|
+
'ignore',
|
|
277
|
+
],
|
|
278
|
+
additionalProperties: false,
|
|
279
|
+
properties: {
|
|
280
|
+
knosky_protocol: {
|
|
281
|
+
type: 'string',
|
|
282
|
+
const: '1.0',
|
|
283
|
+
default: '1.0',
|
|
284
|
+
description: 'Protocol version. Must be "1.0".',
|
|
285
|
+
},
|
|
286
|
+
telemetry: {
|
|
287
|
+
type: 'boolean',
|
|
288
|
+
default: false,
|
|
289
|
+
description: 'Whether to emit telemetry. Defaults to false (never sends data out).',
|
|
290
|
+
},
|
|
291
|
+
absolute_paths: {
|
|
292
|
+
type: 'boolean',
|
|
293
|
+
default: false,
|
|
294
|
+
description: 'Embed absolute filesystem paths in the city output. Defaults to false (basename only).',
|
|
295
|
+
},
|
|
296
|
+
fail_on_secret: {
|
|
297
|
+
type: 'boolean',
|
|
298
|
+
default: true,
|
|
299
|
+
description: 'Abort the build if a secret-like value is detected. Defaults to true (fail-closed).',
|
|
300
|
+
},
|
|
301
|
+
allow_excerpts: {
|
|
302
|
+
type: 'boolean',
|
|
303
|
+
default: false,
|
|
304
|
+
description: 'Include file-content excerpts in the index. Defaults to false.',
|
|
305
|
+
},
|
|
306
|
+
max_excerpt_chars: {
|
|
307
|
+
type: 'integer',
|
|
308
|
+
minimum: 0,
|
|
309
|
+
default: 0,
|
|
310
|
+
description: 'Maximum characters per excerpt. 0 = no excerpts even when allow_excerpts is true.',
|
|
311
|
+
},
|
|
312
|
+
categories: {
|
|
313
|
+
type: 'array',
|
|
314
|
+
items: { type: 'string' },
|
|
315
|
+
default: [],
|
|
316
|
+
description: 'Explicit category (district) labels. Empty array = derived automatically.',
|
|
317
|
+
},
|
|
318
|
+
ignore: {
|
|
319
|
+
type: 'array',
|
|
320
|
+
items: { type: 'string' },
|
|
321
|
+
default: [],
|
|
322
|
+
description: 'Additional glob-style ignore patterns (appended to the built-in defaults and .gitignore).',
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
// ---------------------------------------------------------------------------
|
|
328
|
+
// CITY_SCHEMA
|
|
329
|
+
// ---------------------------------------------------------------------------
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* JSON Schema (Draft 2020-12) for a KnoSky city-data v2 envelope.
|
|
333
|
+
* Produced by the fs-indexer and consumed by the renderer / MCP server.
|
|
334
|
+
* Must agree with validateCity() + NODE_FIELD_ALLOWLIST in core/contract.mjs.
|
|
335
|
+
*
|
|
336
|
+
* @type {object}
|
|
337
|
+
*/
|
|
338
|
+
export const CITY_SCHEMA = {
|
|
339
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
340
|
+
$id: 'https://knosky.com/schemas/city.json',
|
|
341
|
+
title: 'KnoSky City Data (v2)',
|
|
342
|
+
description:
|
|
343
|
+
'N-category city-data envelope (contract v2). ' +
|
|
344
|
+
'Contains pointers and projections only — never full file bodies (decision D-146). ' +
|
|
345
|
+
'See core/CONTRACT.md for narrative spec.',
|
|
346
|
+
type: 'object',
|
|
347
|
+
required: ['schema_version', 'generated_at', 'categories', 'nodes'],
|
|
348
|
+
additionalProperties: true,
|
|
349
|
+
properties: {
|
|
350
|
+
schema_version: {
|
|
351
|
+
type: 'string',
|
|
352
|
+
const: '2.0',
|
|
353
|
+
description: 'City contract version. Always "2.0" for this schema.',
|
|
354
|
+
},
|
|
355
|
+
generated_at: {
|
|
356
|
+
type: 'string',
|
|
357
|
+
format: 'date-time',
|
|
358
|
+
description: 'ISO-8601 timestamp at which the city was built.',
|
|
359
|
+
},
|
|
360
|
+
source: {
|
|
361
|
+
type: 'object',
|
|
362
|
+
required: ['kind', 'ref'],
|
|
363
|
+
properties: {
|
|
364
|
+
kind: { type: 'string', enum: ['fs', 'github', 'board', 'legacy'] },
|
|
365
|
+
ref: { type: 'string' },
|
|
366
|
+
rev: { type: 'string' },
|
|
367
|
+
},
|
|
368
|
+
additionalProperties: false,
|
|
369
|
+
description: 'Where the city was built from.',
|
|
370
|
+
},
|
|
371
|
+
categories: {
|
|
372
|
+
type: 'array',
|
|
373
|
+
items: {
|
|
374
|
+
type: 'object',
|
|
375
|
+
required: ['id', 'label', 'order'],
|
|
376
|
+
properties: {
|
|
377
|
+
id: { type: 'string', minLength: 1 },
|
|
378
|
+
label: { type: 'string', minLength: 1 },
|
|
379
|
+
color: { type: 'string' },
|
|
380
|
+
order: { type: 'integer', minimum: 0 },
|
|
381
|
+
},
|
|
382
|
+
additionalProperties: false,
|
|
383
|
+
},
|
|
384
|
+
description: 'N-category manifest. Replaces the hardcoded 4-district v1 model.',
|
|
385
|
+
},
|
|
386
|
+
node_count: {
|
|
387
|
+
type: 'integer',
|
|
388
|
+
minimum: 0,
|
|
389
|
+
description: 'Expected number of nodes. Must equal nodes.length when present.',
|
|
390
|
+
},
|
|
391
|
+
nodes: {
|
|
392
|
+
type: 'array',
|
|
393
|
+
items: {
|
|
394
|
+
type: 'object',
|
|
395
|
+
required: ['id', 'kind', 'title', 'category', 'links', 'provenance'],
|
|
396
|
+
// additionalProperties:false enforces the serialization allowlist from contract.mjs.
|
|
397
|
+
additionalProperties: false,
|
|
398
|
+
properties: {
|
|
399
|
+
id: {
|
|
400
|
+
type: 'string',
|
|
401
|
+
minLength: 1,
|
|
402
|
+
description: 'Stable, source-derived node identifier.',
|
|
403
|
+
},
|
|
404
|
+
kind: {
|
|
405
|
+
type: 'string',
|
|
406
|
+
description: 'Node kind: decision, spec, file, dir, doc, …',
|
|
407
|
+
},
|
|
408
|
+
title: {
|
|
409
|
+
type: 'string',
|
|
410
|
+
description: 'Short projection title (scrubbed; never a full file body).',
|
|
411
|
+
},
|
|
412
|
+
summary: {
|
|
413
|
+
type: 'string',
|
|
414
|
+
maxLength: 200,
|
|
415
|
+
description:
|
|
416
|
+
'Short excerpt projection (≤ 200 chars, scrubbed; never a full file body).',
|
|
417
|
+
},
|
|
418
|
+
category: {
|
|
419
|
+
type: 'string',
|
|
420
|
+
description: 'Category id. Must match an entry in the top-level categories[] manifest.',
|
|
421
|
+
},
|
|
422
|
+
status: { type: 'string' },
|
|
423
|
+
fact_date: { type: 'string' },
|
|
424
|
+
tags: {
|
|
425
|
+
type: 'array',
|
|
426
|
+
items: { type: 'string' },
|
|
427
|
+
},
|
|
428
|
+
headings: {
|
|
429
|
+
type: 'array',
|
|
430
|
+
items: { type: 'string' },
|
|
431
|
+
},
|
|
432
|
+
links: {
|
|
433
|
+
type: 'array',
|
|
434
|
+
items: { type: 'string' },
|
|
435
|
+
description: 'Edges to other node ids.',
|
|
436
|
+
},
|
|
437
|
+
churn: {
|
|
438
|
+
description: 'Recent-change signal. Object with `c` (commit count) or a plain number.',
|
|
439
|
+
},
|
|
440
|
+
provenance: {
|
|
441
|
+
...PROVENANCE,
|
|
442
|
+
description: 'Back-pointer to the live source. Fields: store (required), ref (required).',
|
|
443
|
+
},
|
|
444
|
+
visibility: {
|
|
445
|
+
type: 'string',
|
|
446
|
+
enum: ['internal', 'public'],
|
|
447
|
+
},
|
|
448
|
+
sensitive: {
|
|
449
|
+
type: 'boolean',
|
|
450
|
+
description: 'Scrub/flag marker. True when a sensitive-term match was found.',
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
description:
|
|
455
|
+
'All nodes in the city. Node fields are strictly limited to the serialization allowlist ' +
|
|
456
|
+
'(id, kind, title, summary, category, status, fact_date, tags, headings, links, churn, ' +
|
|
457
|
+
'provenance, visibility, sensitive).',
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
};
|