kibi-cli 0.11.3 → 0.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/commands/check.d.ts.map +1 -1
  2. package/dist/commands/check.js +99 -3
  3. package/dist/commands/migrate.d.ts.map +1 -1
  4. package/dist/commands/migrate.js +155 -1
  5. package/dist/extractors/manifest.d.ts +2 -1
  6. package/dist/extractors/manifest.d.ts.map +1 -1
  7. package/dist/extractors/manifest.js +3 -0
  8. package/dist/extractors/markdown.d.ts +1 -1
  9. package/dist/extractors/markdown.d.ts.map +1 -1
  10. package/dist/public/schemas/entity.d.ts +1 -127
  11. package/dist/public/schemas/entity.d.ts.map +1 -1
  12. package/dist/public/schemas/entity.js +88 -2
  13. package/dist/public/schemas/relationship.d.ts.map +1 -1
  14. package/dist/public/schemas/relationship.js +1 -0
  15. package/dist/schemas/entity.schema.json +90 -4
  16. package/dist/traceability/staged-diagnostics.d.ts +1 -1
  17. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  18. package/dist/traceability/symbol-extract.d.ts +1 -1
  19. package/dist/traceability/symbol-extract.d.ts.map +1 -1
  20. package/dist/traceability/symbol-extract.js +34 -4
  21. package/dist/traceability/temp-kb.d.ts.map +1 -1
  22. package/dist/traceability/temp-kb.js +2 -6
  23. package/dist/types/entities.d.ts +11 -2
  24. package/dist/types/entities.d.ts.map +1 -1
  25. package/dist/types/relationships.d.ts +1 -1
  26. package/dist/types/relationships.d.ts.map +1 -1
  27. package/dist/utils/schema-version.d.ts +1 -1
  28. package/dist/utils/schema-version.js +1 -1
  29. package/package.json +9 -3
  30. package/src/public/schemas/entity.ts +98 -5
  31. package/src/public/schemas/relationship.ts +1 -0
  32. package/src/schemas/entity.schema.json +90 -4
  33. package/src/schemas/relationship.schema.json +1 -0
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AA2EA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAiVD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmU/B"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AA2EA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA8bD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA0V/B"}
@@ -15,7 +15,7 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
- import { existsSync } from "node:fs";
18
+ import { existsSync, readFileSync } from "node:fs";
19
19
  import * as path from "node:path";
20
20
  import { getBranchOverride, isCliTraceOrDebugEnabled } from "../env.js";
21
21
  import { extractFromManifest, extractFromManifestString, } from "../extractors/manifest.js";
@@ -43,6 +43,8 @@ function getMatchGroup(match, index = 1) {
43
43
  function buildManifestLookup(stagedFiles) {
44
44
  const manifestLookup = new Map();
45
45
  const manifestResults = [];
46
+ const authoredSymbolResults = [];
47
+ const stagedAuthoredSymbolResults = [];
46
48
  // Pre-populate lookup from working-tree manifests so that code-only changes
47
49
  // (where symbols.yaml is not staged) still resolve to the correct symbol IDs
48
50
  // and relationships already defined on disk.
@@ -54,6 +56,7 @@ function buildManifestLookup(stagedFiles) {
54
56
  try {
55
57
  const entries = extractFromManifest(absSymbolsPath);
56
58
  for (const entry of entries) {
59
+ authoredSymbolResults.push(entry);
57
60
  const sourceFile = entry.sourceFile || entry.entity.source || absSymbolsPath;
58
61
  const key = `${sourceFile}:${entry.entity.title}`;
59
62
  manifestLookup.set(key, {
@@ -95,6 +98,13 @@ function buildManifestLookup(stagedFiles) {
95
98
  entity: entry.entity,
96
99
  relationships: entry.relationships,
97
100
  });
101
+ const authoredSymbolResult = {
102
+ entity: entry.entity,
103
+ relationships: entry.relationships,
104
+ ...(entry.sourceFile !== undefined ? { sourceFile: entry.sourceFile } : {}),
105
+ };
106
+ authoredSymbolResults.push(authoredSymbolResult);
107
+ stagedAuthoredSymbolResults.push(authoredSymbolResult);
98
108
  const sourceFile = entry.sourceFile || entry.entity.source || manifestFile.path;
99
109
  const key = `${sourceFile}:${entry.entity.title}`;
100
110
  manifestLookup.set(key, {
@@ -114,7 +124,79 @@ function buildManifestLookup(stagedFiles) {
114
124
  // Ignore manifest parsing errors
115
125
  }
116
126
  }
117
- return { manifestLookup, manifestResults };
127
+ return {
128
+ manifestLookup,
129
+ manifestResults,
130
+ authoredSymbolResults,
131
+ stagedAuthoredSymbolResults,
132
+ };
133
+ }
134
+ const GRANULARITY_RELATIONSHIP_TYPES = new Set([
135
+ "implements",
136
+ "covered_by",
137
+ "executable_for",
138
+ ]);
139
+ const ALLOWED_GRANULARITY_REASONS = new Set([
140
+ "config-artifact",
141
+ "module-level-behavior",
142
+ "extractor-miss",
143
+ "legacy-link",
144
+ ]);
145
+ function hasTraceabilityRelationship(result) {
146
+ return result.relationships.some((relationship) => GRANULARITY_RELATIONSHIP_TYPES.has(relationship.type));
147
+ }
148
+ function hasValidGranularityReason(result) {
149
+ const reason = result.entity.granularity_reason;
150
+ return (typeof reason === "string" && ALLOWED_GRANULARITY_REASONS.has(reason));
151
+ }
152
+ function createSymbolGranularityDiagnostics(options) {
153
+ const diagnostics = [];
154
+ for (const result of options.manifestResults) {
155
+ if (!result.sourceFile)
156
+ continue;
157
+ if (!hasTraceabilityRelationship(result))
158
+ continue;
159
+ if (hasValidGranularityReason(result))
160
+ continue;
161
+ const granularSymbols = getGranularSymbolsForSourceFile(result.sourceFile, options.symbolsByFile, options.sourceContentByFile);
162
+ if (granularSymbols.length === 0)
163
+ continue;
164
+ const granularNames = [...new Set(granularSymbols.map((s) => s.name))].sort();
165
+ if (granularNames.includes(result.entity.title))
166
+ continue;
167
+ diagnostics.push({
168
+ id: "symbol_granularity_violation",
169
+ severity: "error",
170
+ files: [result.entity.source, result.sourceFile],
171
+ docs: ["docs/symbol-traceability-taxonomy.md"],
172
+ message: `Symbol ${result.entity.id} links ${result.sourceFile} coarsely while granular symbols are available: ${granularNames.join(", ")}`,
173
+ suggestion: "Move ownership/coverage/test relationships to the narrow function/class/type symbol, or add granularity_reason with config-artifact, module-level-behavior, extractor-miss, or legacy-link when the coarse symbol is intentional.",
174
+ });
175
+ }
176
+ return diagnostics;
177
+ }
178
+ function getGranularSymbolsForSourceFile(sourceFile, symbolsByFile, sourceContentByFile) {
179
+ const stagedContent = sourceContentByFile.get(sourceFile);
180
+ if (stagedContent !== undefined) {
181
+ return extractSymbolsFromStagedFile({
182
+ path: sourceFile,
183
+ status: "M",
184
+ hunkRanges: [{ start: 1, end: Number.MAX_SAFE_INTEGER }],
185
+ content: stagedContent,
186
+ });
187
+ }
188
+ const absolutePath = path.isAbsolute(sourceFile)
189
+ ? sourceFile
190
+ : path.resolve(process.cwd(), sourceFile);
191
+ if (!existsSync(absolutePath)) {
192
+ return [];
193
+ }
194
+ return extractSymbolsFromStagedFile({
195
+ path: sourceFile,
196
+ status: "M",
197
+ hunkRanges: [{ start: 1, end: Number.MAX_SAFE_INTEGER }],
198
+ content: readFileSync(absolutePath, "utf8"),
199
+ });
118
200
  }
119
201
  const KIBI_ENTITY_TYPES = new Set([
120
202
  "req",
@@ -317,7 +399,7 @@ export async function checkCommand(options) {
317
399
  console.log("No staged files found.");
318
400
  return { exitCode: 0 };
319
401
  }
320
- const { manifestLookup, manifestResults } = buildManifestLookup(stagedFiles);
402
+ const { manifestLookup, manifestResults, authoredSymbolResults, stagedAuthoredSymbolResults, } = buildManifestLookup(stagedFiles);
321
403
  const symbolsManifestPath = loadConfig(process.cwd()).paths.symbols ?? KIBI_SYMBOLS_MANIFEST_PATH;
322
404
  const sourceFiles = stagedFiles.filter((file) => !file.path.endsWith(".md") && !isStagedManifestPath(file.path));
323
405
  const markdownFiles = stagedFiles.filter((f) => f.path.endsWith(".md"));
@@ -341,8 +423,12 @@ export async function checkCommand(options) {
341
423
  }
342
424
  const allSymbols = [];
343
425
  const symbolsByFile = new Map();
426
+ const sourceContentByFile = new Map();
344
427
  for (const f of sourceFiles) {
345
428
  try {
429
+ if (f.content !== undefined) {
430
+ sourceContentByFile.set(f.path, f.content);
431
+ }
346
432
  const symbols = extractSymbolsFromStagedFile(f, manifestLookup);
347
433
  symbolsByFile.set(f.path, symbols);
348
434
  if (symbols?.length) {
@@ -367,6 +453,16 @@ export async function checkCommand(options) {
367
453
  symbolsManifestPath,
368
454
  });
369
455
  const stagedKibiDiagnostics = collectStagedKibiDiagnostics(stagedKibiEvidence);
456
+ const stagedAuthoredSymbolSet = new Set(stagedAuthoredSymbolResults);
457
+ const stagedSourcePaths = new Set(sourceFiles.map((file) => file.path));
458
+ const activeGranularityResults = authoredSymbolResults.filter((result) => stagedAuthoredSymbolSet.has(result) ||
459
+ (result.sourceFile !== undefined &&
460
+ stagedSourcePaths.has(result.sourceFile)));
461
+ stagedKibiDiagnostics.push(...createSymbolGranularityDiagnostics({
462
+ manifestResults: activeGranularityResults,
463
+ symbolsByFile,
464
+ sourceContentByFile,
465
+ }));
370
466
  if (allSymbols.length === 0 && stagedEntityResults.length === 0) {
371
467
  console.log("No exported symbols or staged entities found in staged files.");
372
468
  return { exitCode: 0 };
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAkCA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAsJD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgH/B"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAqCA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AA2VD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgI/B"}
@@ -17,7 +17,10 @@
17
17
  */
18
18
  import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
19
19
  import * as path from "node:path";
20
+ import { load as parseYAML } from "js-yaml";
21
+ import { extractSymbolsFromStagedFile } from "../traceability/symbol-extract.js";
20
22
  import { resolveActiveBranch } from "../utils/branch-resolver.js";
23
+ import { DEFAULT_CONFIG } from "../utils/config.js";
21
24
  import { LATEST_KB_SCHEMA_VERSION, getSchemaVersionStatus, normalizeSchemaVersion, } from "../utils/schema-version.js";
22
25
  const MIGRATION_AUDIT_VERSION = 1;
23
26
  function printWarning(message) {
@@ -83,9 +86,12 @@ function loadRawConfigDocument(cwd) {
83
86
  }
84
87
  }
85
88
  function writeJsonAtomically(filePath, value) {
89
+ writeTextAtomically(filePath, `${JSON.stringify(value, null, 2)}\n`);
90
+ }
91
+ function writeTextAtomically(filePath, content) {
86
92
  mkdirSync(path.dirname(filePath), { recursive: true });
87
93
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
88
- writeFileSync(tempPath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
94
+ writeFileSync(tempPath, content, "utf8");
89
95
  renameSync(tempPath, filePath);
90
96
  }
91
97
  function formatSchemaVersion(rawSchemaVersion, normalized) {
@@ -105,10 +111,146 @@ function buildMigrationAuditRecord(args) {
105
111
  fromVersion: args.fromVersion,
106
112
  migratedAt: args.migratedAt,
107
113
  status: "applied",
114
+ symbolGranularityLegacyLinks: args.symbolGranularityLegacyLinks,
108
115
  toVersion: LATEST_KB_SCHEMA_VERSION,
109
116
  warning: args.warning,
110
117
  };
111
118
  }
119
+ const TRACEABILITY_RELATIONSHIP_TYPES = new Set([
120
+ "implements",
121
+ "covered_by",
122
+ "executable_for",
123
+ ]);
124
+ function hasTraceabilityRelationship(symbol) {
125
+ if (Array.isArray(symbol.links) && symbol.links.length > 0) {
126
+ return true;
127
+ }
128
+ if (!Array.isArray(symbol.relationships)) {
129
+ return false;
130
+ }
131
+ return symbol.relationships.some((relationship) => {
132
+ if (relationship === null ||
133
+ typeof relationship !== "object" ||
134
+ Array.isArray(relationship)) {
135
+ return false;
136
+ }
137
+ const type = relationship.type;
138
+ return typeof type === "string" && TRACEABILITY_RELATIONSHIP_TYPES.has(type);
139
+ });
140
+ }
141
+ function getGranularNames(cwd, sourceFile) {
142
+ const absolutePath = path.isAbsolute(sourceFile)
143
+ ? sourceFile
144
+ : path.join(cwd, sourceFile);
145
+ if (!existsSync(absolutePath)) {
146
+ return new Set();
147
+ }
148
+ const symbols = extractSymbolsFromStagedFile({
149
+ path: sourceFile,
150
+ status: "M",
151
+ hunkRanges: [{ start: 1, end: Number.MAX_SAFE_INTEGER }],
152
+ content: readFileSync(absolutePath, "utf8"),
153
+ });
154
+ return new Set(symbols.map((symbol) => symbol.name));
155
+ }
156
+ function addLegacyReasonsToManifestText(content, symbolIds) {
157
+ if (symbolIds.size === 0)
158
+ return content;
159
+ const lines = content.split("\n");
160
+ const output = [];
161
+ let activeId = null;
162
+ let activeHasReason = false;
163
+ let activePropertyIndent = "";
164
+ const flushLegacyReason = () => {
165
+ if (activeId !== null &&
166
+ symbolIds.has(activeId) &&
167
+ !activeHasReason &&
168
+ activePropertyIndent.length > 0) {
169
+ output.push(`${activePropertyIndent}granularity_reason: legacy-link`);
170
+ activeHasReason = true;
171
+ }
172
+ };
173
+ for (const line of lines) {
174
+ const idMatch = line.match(/^(\s*)-\s+id:\s+(.+)\s*$/);
175
+ if (idMatch) {
176
+ flushLegacyReason();
177
+ activeId = idMatch[2]?.trim() ?? null;
178
+ activeHasReason = false;
179
+ activePropertyIndent = `${idMatch[1] ?? ""} `;
180
+ }
181
+ if (activeId !== null && /^\s+granularity_reason:\s+/.test(line)) {
182
+ activeHasReason = true;
183
+ }
184
+ if (activeId !== null &&
185
+ symbolIds.has(activeId) &&
186
+ !activeHasReason &&
187
+ /^\s+status:\s+/.test(line)) {
188
+ const indent = line.match(/^\s*/)?.[0] ?? "";
189
+ output.push(`${indent}granularity_reason: legacy-link`);
190
+ activeHasReason = true;
191
+ }
192
+ output.push(line);
193
+ }
194
+ flushLegacyReason();
195
+ return output.join("\n");
196
+ }
197
+ function migrateSymbolGranularity(options) {
198
+ const configuredSymbolsPath = options.config.paths?.symbols ?? DEFAULT_CONFIG.paths.symbols;
199
+ if (typeof configuredSymbolsPath !== "string") {
200
+ return { count: 0, manifestPath: null };
201
+ }
202
+ const manifestPath = path.isAbsolute(configuredSymbolsPath)
203
+ ? configuredSymbolsPath
204
+ : path.join(options.cwd, configuredSymbolsPath);
205
+ if (!existsSync(manifestPath)) {
206
+ return { count: 0, manifestPath };
207
+ }
208
+ const manifestContent = readFileSync(manifestPath, "utf8");
209
+ const parsed = parseYAML(manifestContent);
210
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
211
+ return { count: 0, manifestPath };
212
+ }
213
+ const manifest = parsed;
214
+ if (!Array.isArray(manifest.symbols)) {
215
+ return { count: 0, manifestPath };
216
+ }
217
+ let count = 0;
218
+ const migratedSymbolIds = new Set();
219
+ const granularNamesByFile = new Map();
220
+ for (const symbol of manifest.symbols) {
221
+ if (symbol === null || typeof symbol !== "object" || Array.isArray(symbol)) {
222
+ continue;
223
+ }
224
+ const record = symbol;
225
+ if (typeof record.sourceFile !== "string")
226
+ continue;
227
+ if (typeof record.title !== "string")
228
+ continue;
229
+ if (typeof record.id !== "string")
230
+ continue;
231
+ if (record.granularity_reason !== undefined)
232
+ continue;
233
+ if (!hasTraceabilityRelationship(record))
234
+ continue;
235
+ let granularNames = granularNamesByFile.get(record.sourceFile);
236
+ if (granularNames === undefined) {
237
+ granularNames = getGranularNames(options.cwd, record.sourceFile);
238
+ granularNamesByFile.set(record.sourceFile, granularNames);
239
+ }
240
+ if (granularNames.size === 0 || granularNames.has(record.title)) {
241
+ continue;
242
+ }
243
+ count += 1;
244
+ if (!options.dryRun) {
245
+ record.granularity_reason = "legacy-link";
246
+ migratedSymbolIds.add(record.id);
247
+ }
248
+ }
249
+ if (count > 0 && !options.dryRun) {
250
+ writeTextAtomically(manifestPath, addLegacyReasonsToManifestText(manifestContent, migratedSymbolIds));
251
+ }
252
+ return { count, manifestPath };
253
+ }
112
254
  // implements REQ-003
113
255
  export async function migrateCommand(options = {}) {
114
256
  const cwd = process.cwd();
@@ -156,9 +298,17 @@ export async function migrateCommand(options = {}) {
156
298
  return { exitCode: 0 };
157
299
  }
158
300
  const fromVersionLabel = formatSchemaVersion(rawSchemaVersion, normalizedVersion);
301
+ const symbolGranularityMigration = migrateSymbolGranularity({
302
+ cwd,
303
+ config,
304
+ dryRun: options.dryRun || !options.yes,
305
+ });
159
306
  if (options.dryRun) {
160
307
  console.log(`dry run: would migrate ${configPathRelative} schemaVersion from ${fromVersionLabel} to ${LATEST_KB_SCHEMA_VERSION}.`);
161
308
  console.log(`dry run: would write migration audit metadata to ${auditPathRelative}.`);
309
+ if (symbolGranularityMigration.count > 0) {
310
+ console.log(`dry run: would mark ${symbolGranularityMigration.count} legacy coarse symbol link(s) in ${toRelativePath(cwd, symbolGranularityMigration.manifestPath ?? "symbols.yaml")}.`);
311
+ }
162
312
  console.log("Re-run with --yes to apply these changes.");
163
313
  return { exitCode: 0 };
164
314
  }
@@ -179,9 +329,13 @@ export async function migrateCommand(options = {}) {
179
329
  configPath: configPathRelative,
180
330
  fromVersion: configStatus.currentVersion,
181
331
  migratedAt,
332
+ symbolGranularityLegacyLinks: symbolGranularityMigration.count,
182
333
  warning: migrationWarning,
183
334
  }));
184
335
  console.log(`Migrated ${configPathRelative} schemaVersion from ${fromVersionLabel} to ${LATEST_KB_SCHEMA_VERSION}.`);
336
+ if (symbolGranularityMigration.count > 0) {
337
+ console.log(`Marked ${symbolGranularityMigration.count} existing coarse symbol link(s) as legacy-link.`);
338
+ }
185
339
  console.log(`Wrote migration audit metadata to ${auditPathRelative}.`);
186
340
  console.log("Migration complete. Future 'kibi migrate' runs will be a no-op.");
187
341
  return { exitCode: 0 };
@@ -11,6 +11,7 @@ export interface ExtractedEntity {
11
11
  priority?: string;
12
12
  severity?: string;
13
13
  text_ref?: string;
14
+ granularity_reason?: string;
14
15
  }
15
16
  export interface ExtractedRelationship {
16
17
  type: string;
@@ -20,7 +21,6 @@ export interface ExtractedRelationship {
20
21
  export interface ExtractionResult {
21
22
  entity: ExtractedEntity;
22
23
  relationships: ExtractedRelationship[];
23
- /** The per-symbol source code file, distinct from the manifest file path. */
24
24
  sourceFile?: string;
25
25
  }
26
26
  export declare class ManifestError extends Error {
@@ -38,6 +38,7 @@ export interface ManifestSymbolRecord {
38
38
  priority?: string;
39
39
  severity?: string;
40
40
  text_ref?: string;
41
+ granularity_reason?: string;
41
42
  created_at?: string;
42
43
  updated_at?: string;
43
44
  links?: Array<string | {
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAc,SAAQ,KAAK;IAG7B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM;CAK1B;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAwHD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAmBpB;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAmBxB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKxE;AAsCD,wBAAgB,iCAAiC,CAC/C,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,GACvB,oBAAoB,EAAE,CAWxB"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"AA6BA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,aAAc,SAAQ,KAAK;IAG7B,QAAQ,EAAE,MAAM;gBADvB,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM;CAK1B;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,aAAa,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA2HD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,gBAAgB,EAAE,CAmBpB;AAED,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,oBAAoB,EAAE,CAmBxB;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKxE;AAsCD,wBAAgB,iCAAiC,CAC/C,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,GACvB,oBAAoB,EAAE,CAWxB"}
@@ -96,6 +96,9 @@ function extractFromManifestSymbolRecords(manifestSymbols, filePath) {
96
96
  ...(symbol.priority !== undefined ? { priority: symbol.priority } : {}),
97
97
  ...(symbol.severity !== undefined ? { severity: symbol.severity } : {}),
98
98
  ...(symbol.text_ref !== undefined ? { text_ref: symbol.text_ref } : {}),
99
+ ...(symbol.granularity_reason !== undefined
100
+ ? { granularity_reason: symbol.granularity_reason }
101
+ : {}),
99
102
  };
100
103
  const sourceFile = symbol.sourceFile ?? symbol.source;
101
104
  return {
@@ -11,6 +11,7 @@ export interface ExtractedEntity {
11
11
  priority?: string;
12
12
  severity?: string;
13
13
  text_ref?: string;
14
+ granularity_reason?: string;
14
15
  verification_scope?: "unit" | "integration" | "end_to_end";
15
16
  verification_perspective?: "internal" | "consumer";
16
17
  fact_kind?: "subject" | "property_value" | "observation" | "meta";
@@ -38,7 +39,6 @@ export interface ExtractedRelationship {
38
39
  export interface ExtractionResult {
39
40
  entity: ExtractedEntity;
40
41
  relationships: ExtractedRelationship[];
41
- /** The per-symbol source code file, distinct from the manifest file path. */
42
42
  sourceFile?: string;
43
43
  }
44
44
  export declare class FrontmatterError extends Error {
@@ -1 +1 @@
1
- {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"AAwDA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,YAAY,CAAC;IAC3D,wBAAwB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAEnD,SAAS,CAAC,EAAE,SAAS,GAAG,gBAAgB,GAAG,aAAa,GAAG,MAAM,CAAC;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IACtD,UAAU,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA2BD,qBAAa,gBAAiB,SAAQ,KAAK;IAOhC,QAAQ,EAAE,MAAM;IANlB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;gBAG5B,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;IAYM,QAAQ;CAUlB;AA8DD,wBAAgB,sBAAsB,CAEpC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAkDV;AAmRD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAElB;AAGD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAatE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjE;AASD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQpE"}
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"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"}
@@ -1,129 +1,3 @@
1
- declare const entitySchema: {
2
- $id: string;
3
- title: string;
4
- type: string;
5
- properties: {
6
- id: {
7
- type: string;
8
- };
9
- title: {
10
- type: string;
11
- };
12
- status: {
13
- type: string;
14
- enum: string[];
15
- };
16
- created_at: {
17
- type: string;
18
- };
19
- updated_at: {
20
- type: string;
21
- };
22
- source: {
23
- type: string;
24
- };
25
- tags: {
26
- type: string;
27
- items: {
28
- type: string;
29
- };
30
- };
31
- owner: {
32
- type: string;
33
- };
34
- priority: {
35
- type: string;
36
- };
37
- severity: {
38
- type: string;
39
- };
40
- links: {
41
- type: string;
42
- items: {
43
- type: string;
44
- };
45
- };
46
- text_ref: {
47
- type: string;
48
- };
49
- sourceFile: {
50
- type: string;
51
- };
52
- type: {
53
- type: string;
54
- enum: string[];
55
- };
56
- fact_kind: {
57
- type: string;
58
- enum: string[];
59
- };
60
- subject_key: {
61
- type: string;
62
- };
63
- property_key: {
64
- type: string;
65
- };
66
- operator: {
67
- type: string;
68
- enum: string[];
69
- };
70
- value_type: {
71
- type: string;
72
- enum: string[];
73
- };
74
- value_string: {
75
- type: string;
76
- };
77
- value_int: {
78
- type: string;
79
- };
80
- value_number: {
81
- type: string;
82
- };
83
- value_bool: {
84
- type: string;
85
- };
86
- unit: {
87
- type: string;
88
- };
89
- scope: {
90
- type: string;
91
- };
92
- polarity: {
93
- type: string;
94
- enum: string[];
95
- };
96
- closed_world: {
97
- type: string;
98
- };
99
- valid_from: {
100
- type: string;
101
- };
102
- valid_to: {
103
- type: string;
104
- };
105
- canonical_key: {
106
- type: string;
107
- };
108
- };
109
- required: string[];
110
- allOf: {
111
- if: {
112
- properties: {
113
- type: {
114
- const: string;
115
- };
116
- };
117
- };
118
- else: {
119
- not: {
120
- anyOf: {
121
- required: string[];
122
- }[];
123
- };
124
- };
125
- }[];
126
- additionalProperties: boolean;
127
- };
1
+ declare const entitySchema: Record<string, unknown>;
128
2
  export default entitySchema;
129
3
  //# sourceMappingURL=entity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/public/schemas/entity.ts"],"names":[],"mappings":"AAwBA,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqHjB,CAAC;AAEF,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/public/schemas/entity.ts"],"names":[],"mappings":"AA+EA,QAAA,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA2JzC,CAAC;AAEF,eAAe,YAAY,CAAC"}