yarramate 0.8.1 → 0.9.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/dist/ask-command.js +93 -3
- package/dist/changed.d.ts +17 -0
- package/dist/changed.js +111 -0
- package/dist/cli-support.d.ts +1 -1
- package/dist/cli-support.js +1 -1
- package/dist/export-command.js +60 -10
- package/package.json +1 -1
- package/schema/yarramate-ask-result.schema.json +483 -115
package/dist/ask-command.js
CHANGED
|
@@ -4,6 +4,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
import { parseDocument } from 'yaml';
|
|
5
5
|
import { compareArchitectureStates, } from './architecture-state.js';
|
|
6
6
|
import { renderBrief } from './brief.js';
|
|
7
|
+
import { deriveChangedSubjects } from './changed.js';
|
|
7
8
|
import { runCheckCommand } from './check-command.js';
|
|
8
9
|
import { diagnosticJson, humanDiagnostics, usage, } from './cli-support.js';
|
|
9
10
|
import { compileWorkspaceWithProfileContext, } from './compiler.js';
|
|
@@ -124,6 +125,7 @@ export function runAskCommand(options, cwd) {
|
|
|
124
125
|
let kinds = false;
|
|
125
126
|
let advise = false;
|
|
126
127
|
let compare;
|
|
128
|
+
let changed;
|
|
127
129
|
let budget;
|
|
128
130
|
let kindFilter;
|
|
129
131
|
let statusFilter;
|
|
@@ -172,7 +174,8 @@ export function runAskCommand(options, cwd) {
|
|
|
172
174
|
if (option === '--budget' ||
|
|
173
175
|
option === '--kind' ||
|
|
174
176
|
option === '--status' ||
|
|
175
|
-
option === '--catalogue'
|
|
177
|
+
option === '--catalogue' ||
|
|
178
|
+
option === '--changed') {
|
|
176
179
|
const value = options[index + 1];
|
|
177
180
|
if (value === undefined || value.startsWith('-')) {
|
|
178
181
|
return { exitCode: 2, stdout: '', stderr: usage };
|
|
@@ -183,6 +186,12 @@ export function runAskCommand(options, cwd) {
|
|
|
183
186
|
}
|
|
184
187
|
budget = Number(value);
|
|
185
188
|
}
|
|
189
|
+
else if (option === '--changed') {
|
|
190
|
+
if (changed !== undefined) {
|
|
191
|
+
return { exitCode: 2, stdout: '', stderr: usage };
|
|
192
|
+
}
|
|
193
|
+
changed = value;
|
|
194
|
+
}
|
|
186
195
|
else if (option === '--kind') {
|
|
187
196
|
if (kindFilter !== undefined) {
|
|
188
197
|
return { exitCode: 2, stdout: '', stderr: usage };
|
|
@@ -223,9 +232,12 @@ export function runAskCommand(options, cwd) {
|
|
|
223
232
|
(advise && exclusiveModes > 0) ||
|
|
224
233
|
(advise && query.length === 0) ||
|
|
225
234
|
(query.length > 0 && exclusiveModes > 0) ||
|
|
235
|
+
(changed !== undefined &&
|
|
236
|
+
(query.length > 0 || exclusiveModes > 0 || advise)) ||
|
|
226
237
|
((kindFilter !== undefined || statusFilter !== undefined) && !subjects) ||
|
|
227
238
|
(cataloguePath !== undefined && !open && !advise) ||
|
|
228
|
-
(budget !== undefined &&
|
|
239
|
+
(budget !== undefined &&
|
|
240
|
+
(json || (query.length === 0 && !advise && changed === undefined)))) {
|
|
229
241
|
return { exitCode: 2, stdout: '', stderr: usage };
|
|
230
242
|
}
|
|
231
243
|
try {
|
|
@@ -263,7 +275,8 @@ export function runAskCommand(options, cwd) {
|
|
|
263
275
|
!open &&
|
|
264
276
|
!kinds &&
|
|
265
277
|
!advise &&
|
|
266
|
-
compare === undefined
|
|
278
|
+
compare === undefined &&
|
|
279
|
+
changed === undefined) {
|
|
267
280
|
const checked = runCheckCommand([workspacePath, '--json'], cwd);
|
|
268
281
|
const checkPayload = JSON.parse(checked.stdout);
|
|
269
282
|
if (!checkPayload.ok) {
|
|
@@ -544,6 +557,83 @@ export function runAskCommand(options, cwd) {
|
|
|
544
557
|
};
|
|
545
558
|
return emit(result, renderInterrogationReport(ordered));
|
|
546
559
|
}
|
|
560
|
+
// --changed: the review slice (ADR 0065). Git says what changed; the
|
|
561
|
+
// engine maps changed lines to subjects and renders their connected
|
|
562
|
+
// neighbourhood, plus a coverage note when a changed subject appears
|
|
563
|
+
// in no authored projection.
|
|
564
|
+
if (changed !== undefined) {
|
|
565
|
+
const documentIdByPath = new Map(graph.documents.map(({ id, source }) => [source, id]));
|
|
566
|
+
const derived = deriveChangedSubjects(cwd, changed, workspace.documents.map((path) => ({
|
|
567
|
+
path,
|
|
568
|
+
source: readFileSync(resolve(cwd, path), 'utf8'),
|
|
569
|
+
documentId: documentIdByPath.get(path) ?? path,
|
|
570
|
+
})));
|
|
571
|
+
if (!derived.ok) {
|
|
572
|
+
return { exitCode: 2, stdout: '', stderr: `${derived.message}\n` };
|
|
573
|
+
}
|
|
574
|
+
const endpoints = new Set();
|
|
575
|
+
for (const relationshipId of derived.changed.relationships) {
|
|
576
|
+
const claim = graph.claims.find((candidate) => candidate.id === relationshipId && 'ref' in candidate.object);
|
|
577
|
+
if (claim !== undefined && 'ref' in claim.object) {
|
|
578
|
+
endpoints.add(claim.subject);
|
|
579
|
+
endpoints.add(claim.object.ref);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
const seeds = [
|
|
583
|
+
...new Set([...derived.changed.concepts, ...endpoints]),
|
|
584
|
+
].sort();
|
|
585
|
+
const changedIds = [
|
|
586
|
+
...derived.changed.concepts,
|
|
587
|
+
...derived.changed.relationships,
|
|
588
|
+
];
|
|
589
|
+
const covered = new Set();
|
|
590
|
+
for (const projectionPath of workspace.projections) {
|
|
591
|
+
const loaded = loadProjection({
|
|
592
|
+
path: projectionPath,
|
|
593
|
+
source: readFileSync(resolve(cwd, projectionPath), 'utf8'),
|
|
594
|
+
});
|
|
595
|
+
if (!loaded.ok)
|
|
596
|
+
continue;
|
|
597
|
+
const membership = evaluateProjection(graph, loaded.projection, compilation.profileContext);
|
|
598
|
+
for (const subject of membership.subjects) {
|
|
599
|
+
covered.add(subject.id);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
const uncovered = changedIds.filter((id) => !covered.has(id));
|
|
603
|
+
const coverage = {
|
|
604
|
+
projections: workspace.projections.length,
|
|
605
|
+
uncovered,
|
|
606
|
+
};
|
|
607
|
+
const evaluated = sliceProjection(graph, seeds, `Review slice ${changed}`, compilation.profileContext);
|
|
608
|
+
const result = {
|
|
609
|
+
format: 'yarramate/ask-result/v1',
|
|
610
|
+
workspace: workspace.id,
|
|
611
|
+
mode: 'slice',
|
|
612
|
+
addressing: 'changed',
|
|
613
|
+
seeds,
|
|
614
|
+
changed: derived.changed,
|
|
615
|
+
coverage,
|
|
616
|
+
result: evaluated,
|
|
617
|
+
};
|
|
618
|
+
if (changedIds.length === 0) {
|
|
619
|
+
return emit(result, `No model subjects changed in ${changed}.\n`);
|
|
620
|
+
}
|
|
621
|
+
const rendered = budget === undefined
|
|
622
|
+
? renderBrief(evaluated, compilation.profileContext)
|
|
623
|
+
: renderBudgetedContext(evaluated, budget);
|
|
624
|
+
const lines = [
|
|
625
|
+
`Review slice ${changed} — ${plural(derived.changed.concepts.length, 'concept')}, ` +
|
|
626
|
+
`${plural(derived.changed.relationships.length, 'relationship')} changed (workspace ${workspace.id})`,
|
|
627
|
+
'',
|
|
628
|
+
rendered.trimEnd(),
|
|
629
|
+
'',
|
|
630
|
+
uncovered.length === 0
|
|
631
|
+
? `Review coverage: every changed subject appears in at least one of the ${coverage.projections} authored projections.`
|
|
632
|
+
: `Review coverage: ${uncovered.length} of ${changedIds.length} changed subjects appear in no authored projection:` +
|
|
633
|
+
`\n${uncovered.map((id) => ` ${id}`).join('\n')}`,
|
|
634
|
+
];
|
|
635
|
+
return emit(result, `${lines.join('\n')}\n`);
|
|
636
|
+
}
|
|
547
637
|
// Slice and advice both start from seeds. A single query term that
|
|
548
638
|
// names a projection file is precise addressing; anything else runs
|
|
549
639
|
// through free-text seeding, where exact subject ids win.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ChangedSubjects {
|
|
2
|
+
readonly range: string;
|
|
3
|
+
readonly concepts: readonly string[];
|
|
4
|
+
readonly relationships: readonly string[];
|
|
5
|
+
}
|
|
6
|
+
export type ChangedResult = {
|
|
7
|
+
readonly ok: true;
|
|
8
|
+
readonly changed: ChangedSubjects;
|
|
9
|
+
} | {
|
|
10
|
+
readonly ok: false;
|
|
11
|
+
readonly message: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function deriveChangedSubjects(cwd: string, range: string, documents: ReadonlyArray<{
|
|
14
|
+
readonly path: string;
|
|
15
|
+
readonly source: string;
|
|
16
|
+
readonly documentId: string;
|
|
17
|
+
}>): ChangedResult;
|
package/dist/changed.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { isMap, isScalar, isSeq, parseDocument } from 'yaml';
|
|
3
|
+
const lineOfOffset = (lineStarts, offset) => {
|
|
4
|
+
let low = 0;
|
|
5
|
+
let high = lineStarts.length - 1;
|
|
6
|
+
while (low < high) {
|
|
7
|
+
const mid = (low + high + 1) >> 1;
|
|
8
|
+
if (lineStarts[mid] <= offset)
|
|
9
|
+
low = mid;
|
|
10
|
+
else
|
|
11
|
+
high = mid - 1;
|
|
12
|
+
}
|
|
13
|
+
return low + 1;
|
|
14
|
+
};
|
|
15
|
+
const itemSpans = (source) => {
|
|
16
|
+
const lineStarts = [0];
|
|
17
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
18
|
+
if (source[index] === '\n')
|
|
19
|
+
lineStarts.push(index + 1);
|
|
20
|
+
}
|
|
21
|
+
const document = parseDocument(source);
|
|
22
|
+
const root = document.contents;
|
|
23
|
+
if (!isMap(root))
|
|
24
|
+
return [];
|
|
25
|
+
const spans = [];
|
|
26
|
+
for (const collection of ['concepts', 'relationships', 'states']) {
|
|
27
|
+
const pair = root.items.find((candidate) => isScalar(candidate.key) && candidate.key.value === collection);
|
|
28
|
+
if (pair === undefined || !isSeq(pair.value))
|
|
29
|
+
continue;
|
|
30
|
+
for (const item of pair.value.items) {
|
|
31
|
+
if (!isMap(item))
|
|
32
|
+
continue;
|
|
33
|
+
const idPair = item.items.find((field) => isScalar(field.key) && field.key.value === 'id');
|
|
34
|
+
if (idPair === undefined ||
|
|
35
|
+
!isScalar(idPair.value) ||
|
|
36
|
+
typeof idPair.value.value !== 'string') {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const range = item
|
|
40
|
+
.range;
|
|
41
|
+
if (range === undefined)
|
|
42
|
+
continue;
|
|
43
|
+
spans.push({
|
|
44
|
+
id: idPair.value.value,
|
|
45
|
+
collection,
|
|
46
|
+
startLine: lineOfOffset(lineStarts, range[0]),
|
|
47
|
+
// range[1] can extend past the trailing newline; anchor the end
|
|
48
|
+
// on the last content character instead.
|
|
49
|
+
endLine: lineOfOffset(lineStarts, Math.max(range[0], range[1] - 1)),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return spans;
|
|
54
|
+
};
|
|
55
|
+
// New-side line ranges from `git diff --unified=0`. A pure deletion has a
|
|
56
|
+
// zero count; it still touches the position it collapsed onto.
|
|
57
|
+
const changedLineRanges = (diff) => {
|
|
58
|
+
const ranges = [];
|
|
59
|
+
for (const match of diff.matchAll(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@/gm)) {
|
|
60
|
+
const start = Number(match[1]);
|
|
61
|
+
const count = match[2] === undefined ? 1 : Number(match[2]);
|
|
62
|
+
ranges.push(count === 0 ? [Math.max(start, 1), Math.max(start, 1)] : [start, start + count - 1]);
|
|
63
|
+
}
|
|
64
|
+
return ranges;
|
|
65
|
+
};
|
|
66
|
+
export function deriveChangedSubjects(cwd, range, documents) {
|
|
67
|
+
const probe = spawnSync('git', ['-C', cwd, 'rev-parse', '--git-dir'], {
|
|
68
|
+
encoding: 'utf8',
|
|
69
|
+
});
|
|
70
|
+
if (probe.status !== 0) {
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
message: '--changed requires the workspace to live in a git repository',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const concepts = new Set();
|
|
77
|
+
const relationships = new Set();
|
|
78
|
+
for (const document of documents) {
|
|
79
|
+
const diffed = spawnSync('git', ['-C', cwd, 'diff', '--unified=0', range, '--', document.path], { encoding: 'utf8' });
|
|
80
|
+
if (diffed.status !== 0) {
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
message: `git diff failed for range "${range}": ${(diffed.stderr ?? '').trim()}`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const ranges = changedLineRanges(diffed.stdout ?? '');
|
|
87
|
+
if (ranges.length === 0)
|
|
88
|
+
continue;
|
|
89
|
+
const spans = itemSpans(document.source);
|
|
90
|
+
for (const span of spans) {
|
|
91
|
+
if (span.collection === 'states')
|
|
92
|
+
continue;
|
|
93
|
+
const touched = ranges.some(([from, to]) => from <= span.endLine && to >= span.startLine);
|
|
94
|
+
if (!touched)
|
|
95
|
+
continue;
|
|
96
|
+
const qualified = `${document.documentId}#${span.id}`;
|
|
97
|
+
if (span.collection === 'concepts')
|
|
98
|
+
concepts.add(qualified);
|
|
99
|
+
else
|
|
100
|
+
relationships.add(qualified);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
ok: true,
|
|
105
|
+
changed: {
|
|
106
|
+
range,
|
|
107
|
+
concepts: [...concepts].sort(),
|
|
108
|
+
relationships: [...relationships].sort(),
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
}
|
package/dist/cli-support.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface CliResult {
|
|
|
7
7
|
export declare const isMainModule: (moduleUrl: string, entrypoint: string | undefined) => boolean;
|
|
8
8
|
export declare const packageVersion: string;
|
|
9
9
|
export declare const versionResult: (binary: string) => CliResult;
|
|
10
|
-
export declare const usage = "Usage:\n yarramate init <directory> [--no-pointer]\n yarramate design <workspace.yaml> [--subject <document-id>#<local-id>] [--catalogue <catalogue.yaml>] [--json]\n yarramate apply <operations.yaml> <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> \"<free text>\" | <document-id>#<local-id> ... | <projection.yaml> [--budget <tokens>] [--json]\n yarramate ask <workspace.yaml> --subjects [--kind <term>] [--status <status>] [--json]\n yarramate ask <workspace.yaml> --kinds [--json]\n yarramate ask <workspace.yaml> --advise \"<topic>\" [--budget <tokens>] [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --next [--json]\n yarramate ask <workspace.yaml> --open [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --compare <from-state> <to-state> [--json]\n yarramate check <source.yaml> [source.yaml ...] [--json] [--strict]\n yarramate reconcile <workspace.yaml>\n yarramate export graph <workspace.yaml> [--out <file>]\n yarramate export markdown <projection.yaml> <workspace.yaml> [--out <file>]\n yarramate export briefs <projection.yaml> <workspace.yaml> --out <directory> [--budget <tokens>]\n yarramate export likec4 <likec4-project.yaml> <output-dir> <workspace.yaml>\n";
|
|
10
|
+
export declare const usage = "Usage:\n yarramate init <directory> [--no-pointer]\n yarramate design <workspace.yaml> [--subject <document-id>#<local-id>] [--catalogue <catalogue.yaml>] [--json]\n yarramate apply <operations.yaml> <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> \"<free text>\" | <document-id>#<local-id> ... | <projection.yaml> [--budget <tokens>] [--json]\n yarramate ask <workspace.yaml> --subjects [--kind <term>] [--status <status>] [--json]\n yarramate ask <workspace.yaml> --kinds [--json]\n yarramate ask <workspace.yaml> --advise \"<topic>\" [--budget <tokens>] [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --next [--json]\n yarramate ask <workspace.yaml> --open [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --compare <from-state> <to-state> [--json]\n yarramate ask <workspace.yaml> --changed <git-range> [--budget <tokens>] [--json]\n yarramate check <source.yaml> [source.yaml ...] [--json] [--strict]\n yarramate reconcile <workspace.yaml>\n yarramate export graph <workspace.yaml> [--out <file>]\n yarramate export markdown <projection.yaml> <workspace.yaml> [--out <file>]\n yarramate export markdown --changed <git-range> <workspace.yaml> [--out <file>]\n yarramate export briefs <projection.yaml> <workspace.yaml> --out <directory> [--budget <tokens>]\n yarramate export briefs --changed <git-range> <workspace.yaml> --out <directory> [--budget <tokens>]\n yarramate export likec4 <likec4-project.yaml> <output-dir> <workspace.yaml>\n";
|
|
11
11
|
export declare const diagnosticJson: (diagnostics: unknown) => string;
|
|
12
12
|
export declare const checkResultJson: (ok: boolean, diagnostics: unknown, counted?: {
|
|
13
13
|
readonly documents: number;
|
package/dist/cli-support.js
CHANGED
|
@@ -23,7 +23,7 @@ export const versionResult = (binary) => ({
|
|
|
23
23
|
stdout: `${binary} ${packageVersion}\n`,
|
|
24
24
|
stderr: '',
|
|
25
25
|
});
|
|
26
|
-
export const usage = 'Usage:\n yarramate init <directory> [--no-pointer]\n yarramate design <workspace.yaml> [--subject <document-id>#<local-id>] [--catalogue <catalogue.yaml>] [--json]\n yarramate apply <operations.yaml> <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> "<free text>" | <document-id>#<local-id> ... | <projection.yaml> [--budget <tokens>] [--json]\n yarramate ask <workspace.yaml> --subjects [--kind <term>] [--status <status>] [--json]\n yarramate ask <workspace.yaml> --kinds [--json]\n yarramate ask <workspace.yaml> --advise "<topic>" [--budget <tokens>] [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --next [--json]\n yarramate ask <workspace.yaml> --open [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --compare <from-state> <to-state> [--json]\n yarramate check <source.yaml> [source.yaml ...] [--json] [--strict]\n yarramate reconcile <workspace.yaml>\n yarramate export graph <workspace.yaml> [--out <file>]\n yarramate export markdown <projection.yaml> <workspace.yaml> [--out <file>]\n yarramate export briefs <projection.yaml> <workspace.yaml> --out <directory> [--budget <tokens>]\n yarramate export likec4 <likec4-project.yaml> <output-dir> <workspace.yaml>\n';
|
|
26
|
+
export const usage = 'Usage:\n yarramate init <directory> [--no-pointer]\n yarramate design <workspace.yaml> [--subject <document-id>#<local-id>] [--catalogue <catalogue.yaml>] [--json]\n yarramate apply <operations.yaml> <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> [--json]\n yarramate ask <workspace.yaml> "<free text>" | <document-id>#<local-id> ... | <projection.yaml> [--budget <tokens>] [--json]\n yarramate ask <workspace.yaml> --subjects [--kind <term>] [--status <status>] [--json]\n yarramate ask <workspace.yaml> --kinds [--json]\n yarramate ask <workspace.yaml> --advise "<topic>" [--budget <tokens>] [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --next [--json]\n yarramate ask <workspace.yaml> --open [--catalogue <catalogue.yaml>] [--json]\n yarramate ask <workspace.yaml> --compare <from-state> <to-state> [--json]\n yarramate ask <workspace.yaml> --changed <git-range> [--budget <tokens>] [--json]\n yarramate check <source.yaml> [source.yaml ...] [--json] [--strict]\n yarramate reconcile <workspace.yaml>\n yarramate export graph <workspace.yaml> [--out <file>]\n yarramate export markdown <projection.yaml> <workspace.yaml> [--out <file>]\n yarramate export markdown --changed <git-range> <workspace.yaml> [--out <file>]\n yarramate export briefs <projection.yaml> <workspace.yaml> --out <directory> [--budget <tokens>]\n yarramate export briefs --changed <git-range> <workspace.yaml> --out <directory> [--budget <tokens>]\n yarramate export likec4 <likec4-project.yaml> <output-dir> <workspace.yaml>\n';
|
|
27
27
|
export const diagnosticJson = (diagnostics) => `${JSON.stringify({
|
|
28
28
|
format: 'yarramate/diagnostic-result/v1',
|
|
29
29
|
diagnostics,
|
package/dist/export-command.js
CHANGED
|
@@ -4,6 +4,7 @@ import { dirname, join, resolve } from 'node:path';
|
|
|
4
4
|
import { fileURLToPath } from 'node:url';
|
|
5
5
|
import { parseDocument } from 'yaml';
|
|
6
6
|
import { renderBrief } from './brief.js';
|
|
7
|
+
import { deriveChangedSubjects } from './changed.js';
|
|
7
8
|
import { humanDiagnostics, usage } from './cli-support.js';
|
|
8
9
|
import { compileWorkspaceWithProfileContext, } from './compiler.js';
|
|
9
10
|
import { serializeSemanticGraph } from './graph.js';
|
|
@@ -23,6 +24,7 @@ const parseExportOptions = (options) => {
|
|
|
23
24
|
const positionals = [];
|
|
24
25
|
let out;
|
|
25
26
|
let budget;
|
|
27
|
+
let changed;
|
|
26
28
|
let json = false;
|
|
27
29
|
for (let index = 0; index < options.length; index += 1) {
|
|
28
30
|
const option = options[index];
|
|
@@ -30,7 +32,9 @@ const parseExportOptions = (options) => {
|
|
|
30
32
|
json = true;
|
|
31
33
|
continue;
|
|
32
34
|
}
|
|
33
|
-
if (option === '--out' ||
|
|
35
|
+
if (option === '--out' ||
|
|
36
|
+
option === '--budget' ||
|
|
37
|
+
option === '--changed') {
|
|
34
38
|
const value = options[index + 1];
|
|
35
39
|
if (value === undefined || value.startsWith('-'))
|
|
36
40
|
return undefined;
|
|
@@ -39,6 +43,11 @@ const parseExportOptions = (options) => {
|
|
|
39
43
|
return undefined;
|
|
40
44
|
out = value;
|
|
41
45
|
}
|
|
46
|
+
else if (option === '--changed') {
|
|
47
|
+
if (changed !== undefined)
|
|
48
|
+
return undefined;
|
|
49
|
+
changed = value;
|
|
50
|
+
}
|
|
42
51
|
else {
|
|
43
52
|
if (budget !== undefined || !/^[1-9][0-9]*$/.test(value)) {
|
|
44
53
|
return undefined;
|
|
@@ -56,6 +65,7 @@ const parseExportOptions = (options) => {
|
|
|
56
65
|
positionals,
|
|
57
66
|
...(out === undefined ? {} : { out }),
|
|
58
67
|
...(budget === undefined ? {} : { budget }),
|
|
68
|
+
...(changed === undefined ? {} : { changed }),
|
|
59
69
|
json,
|
|
60
70
|
};
|
|
61
71
|
};
|
|
@@ -103,12 +113,14 @@ export function runExportCommand(options, cwd) {
|
|
|
103
113
|
stderr: delegated.stderr ?? '',
|
|
104
114
|
};
|
|
105
115
|
}
|
|
106
|
-
const
|
|
116
|
+
const usesChanged = parsed.changed !== undefined;
|
|
117
|
+
const expectedPositionals = kind === 'graph' || usesChanged ? 1 : 2;
|
|
107
118
|
const workspacePath = parsed.positionals[expectedPositionals - 1];
|
|
108
|
-
const projectionPath = kind === 'graph' ? undefined : parsed.positionals[0];
|
|
119
|
+
const projectionPath = kind === 'graph' || usesChanged ? undefined : parsed.positionals[0];
|
|
109
120
|
if (parsed.positionals.length !== expectedPositionals ||
|
|
110
121
|
workspacePath === undefined ||
|
|
111
122
|
parsed.json ||
|
|
123
|
+
(usesChanged && kind === 'graph') ||
|
|
112
124
|
(parsed.budget !== undefined && kind !== 'briefs') ||
|
|
113
125
|
(kind === 'briefs' && parsed.out === undefined)) {
|
|
114
126
|
return { exitCode: 2, stdout: '', stderr: usage };
|
|
@@ -151,13 +163,51 @@ export function runExportCommand(options, cwd) {
|
|
|
151
163
|
stderr: '',
|
|
152
164
|
};
|
|
153
165
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
166
|
+
let result;
|
|
167
|
+
if (parsed.changed !== undefined) {
|
|
168
|
+
// Review slices derive from git (ADR 0065): changed subjects seed
|
|
169
|
+
// the connected neighbourhood the reviewer inspects.
|
|
170
|
+
const documentIdByPath = new Map(compilation.graph.documents.map(({ id, source }) => [source, id]));
|
|
171
|
+
const derived = deriveChangedSubjects(cwd, parsed.changed, workspace.documents.map((path) => ({
|
|
172
|
+
path,
|
|
173
|
+
source: readFileSync(resolve(cwd, path), 'utf8'),
|
|
174
|
+
documentId: documentIdByPath.get(path) ?? path,
|
|
175
|
+
})));
|
|
176
|
+
if (!derived.ok) {
|
|
177
|
+
return { exitCode: 2, stdout: '', stderr: `${derived.message}\n` };
|
|
178
|
+
}
|
|
179
|
+
const endpoints = new Set();
|
|
180
|
+
for (const relationshipId of derived.changed.relationships) {
|
|
181
|
+
const claim = compilation.graph.claims.find((candidate) => candidate.id === relationshipId && 'ref' in candidate.object);
|
|
182
|
+
if (claim !== undefined && 'ref' in claim.object) {
|
|
183
|
+
endpoints.add(claim.subject);
|
|
184
|
+
endpoints.add(claim.object.ref);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const seeds = [
|
|
188
|
+
...new Set([...derived.changed.concepts, ...endpoints]),
|
|
189
|
+
].sort();
|
|
190
|
+
result = evaluateProjection(compilation.graph, {
|
|
191
|
+
format: 'yarramate/projection/v1',
|
|
192
|
+
id: 'review-slice',
|
|
193
|
+
version: '0.0',
|
|
194
|
+
query: { subjects: seeds, relationships: 'connected' },
|
|
195
|
+
presentation: {
|
|
196
|
+
title: `Review slice ${parsed.changed}`,
|
|
197
|
+
description: `Connected neighbourhood of the subjects changed in ` +
|
|
198
|
+
`${parsed.changed}.`,
|
|
199
|
+
},
|
|
200
|
+
}, compilation.profileContext);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
const loadedProjection = loadProjection({
|
|
204
|
+
path: projectionPath,
|
|
205
|
+
source: readFileSync(resolve(cwd, projectionPath), 'utf8'),
|
|
206
|
+
});
|
|
207
|
+
if (!loadedProjection.ok)
|
|
208
|
+
return failed(loadedProjection.diagnostics);
|
|
209
|
+
result = evaluateProjection(compilation.graph, loadedProjection.projection, compilation.profileContext);
|
|
210
|
+
}
|
|
161
211
|
if (kind === 'markdown') {
|
|
162
212
|
const rendered = renderProjectionMarkdown(result);
|
|
163
213
|
if (parsed.out === undefined) {
|
package/package.json
CHANGED
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
"title": "YarraMate ask result",
|
|
5
5
|
"description": "One envelope for every consumed-now read: orientation, roster, slice, advice, next, open questions, and state comparison, discriminated by mode.",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": [
|
|
7
|
+
"required": [
|
|
8
|
+
"format",
|
|
9
|
+
"workspace",
|
|
10
|
+
"mode"
|
|
11
|
+
],
|
|
8
12
|
"properties": {
|
|
9
13
|
"format": {
|
|
10
14
|
"const": "yarramate/ask-result/v1"
|
|
@@ -29,18 +33,34 @@
|
|
|
29
33
|
"oneOf": [
|
|
30
34
|
{
|
|
31
35
|
"type": "object",
|
|
32
|
-
"required": [
|
|
36
|
+
"required": [
|
|
37
|
+
"mode",
|
|
38
|
+
"ok",
|
|
39
|
+
"check",
|
|
40
|
+
"backlog"
|
|
41
|
+
],
|
|
33
42
|
"properties": {
|
|
34
43
|
"format": true,
|
|
35
44
|
"workspace": true,
|
|
36
|
-
"mode": {
|
|
37
|
-
|
|
45
|
+
"mode": {
|
|
46
|
+
"const": "orientation"
|
|
47
|
+
},
|
|
48
|
+
"ok": {
|
|
49
|
+
"type": "boolean"
|
|
50
|
+
},
|
|
38
51
|
"check": {
|
|
39
52
|
"type": "object",
|
|
40
|
-
"required": [
|
|
53
|
+
"required": [
|
|
54
|
+
"ok",
|
|
55
|
+
"diagnostics"
|
|
56
|
+
],
|
|
41
57
|
"properties": {
|
|
42
|
-
"ok": {
|
|
43
|
-
|
|
58
|
+
"ok": {
|
|
59
|
+
"type": "boolean"
|
|
60
|
+
},
|
|
61
|
+
"diagnostics": {
|
|
62
|
+
"type": "array"
|
|
63
|
+
},
|
|
44
64
|
"counted": {
|
|
45
65
|
"type": "object",
|
|
46
66
|
"required": [
|
|
@@ -50,10 +70,18 @@
|
|
|
50
70
|
"states"
|
|
51
71
|
],
|
|
52
72
|
"properties": {
|
|
53
|
-
"documents": {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
73
|
+
"documents": {
|
|
74
|
+
"type": "integer"
|
|
75
|
+
},
|
|
76
|
+
"concepts": {
|
|
77
|
+
"type": "integer"
|
|
78
|
+
},
|
|
79
|
+
"relationships": {
|
|
80
|
+
"type": "integer"
|
|
81
|
+
},
|
|
82
|
+
"states": {
|
|
83
|
+
"type": "integer"
|
|
84
|
+
}
|
|
57
85
|
},
|
|
58
86
|
"additionalProperties": false
|
|
59
87
|
}
|
|
@@ -65,28 +93,47 @@
|
|
|
65
93
|
},
|
|
66
94
|
"design": {
|
|
67
95
|
"type": "object",
|
|
68
|
-
"required": [
|
|
96
|
+
"required": [
|
|
97
|
+
"catalogue",
|
|
98
|
+
"open"
|
|
99
|
+
],
|
|
69
100
|
"properties": {
|
|
70
|
-
"catalogue": {
|
|
71
|
-
|
|
101
|
+
"catalogue": {
|
|
102
|
+
"type": "string",
|
|
103
|
+
"minLength": 1
|
|
104
|
+
},
|
|
105
|
+
"open": {
|
|
106
|
+
"type": "integer",
|
|
107
|
+
"minimum": 0
|
|
108
|
+
}
|
|
72
109
|
},
|
|
73
110
|
"additionalProperties": false
|
|
74
111
|
},
|
|
75
112
|
"backlog": {
|
|
76
113
|
"type": "object",
|
|
77
|
-
"required": [
|
|
114
|
+
"required": [
|
|
115
|
+
"planned",
|
|
116
|
+
"current",
|
|
117
|
+
"retired"
|
|
118
|
+
],
|
|
78
119
|
"properties": {
|
|
79
120
|
"planned": {
|
|
80
121
|
"type": "array",
|
|
81
|
-
"items": {
|
|
122
|
+
"items": {
|
|
123
|
+
"$ref": "#/$defs/nextSubject"
|
|
124
|
+
}
|
|
82
125
|
},
|
|
83
126
|
"current": {
|
|
84
127
|
"type": "array",
|
|
85
|
-
"items": {
|
|
128
|
+
"items": {
|
|
129
|
+
"$ref": "#/$defs/conceptEntry"
|
|
130
|
+
}
|
|
86
131
|
},
|
|
87
132
|
"retired": {
|
|
88
133
|
"type": "array",
|
|
89
|
-
"items": {
|
|
134
|
+
"items": {
|
|
135
|
+
"$ref": "#/$defs/conceptEntry"
|
|
136
|
+
}
|
|
90
137
|
}
|
|
91
138
|
},
|
|
92
139
|
"additionalProperties": false
|
|
@@ -96,36 +143,119 @@
|
|
|
96
143
|
},
|
|
97
144
|
{
|
|
98
145
|
"type": "object",
|
|
99
|
-
"required": [
|
|
146
|
+
"required": [
|
|
147
|
+
"mode",
|
|
148
|
+
"total",
|
|
149
|
+
"subjects"
|
|
150
|
+
],
|
|
100
151
|
"properties": {
|
|
101
152
|
"format": true,
|
|
102
153
|
"workspace": true,
|
|
103
|
-
"mode": {
|
|
104
|
-
|
|
154
|
+
"mode": {
|
|
155
|
+
"const": "roster"
|
|
156
|
+
},
|
|
157
|
+
"total": {
|
|
158
|
+
"type": "integer",
|
|
159
|
+
"minimum": 0
|
|
160
|
+
},
|
|
105
161
|
"subjects": {
|
|
106
162
|
"type": "array",
|
|
107
|
-
"items": {
|
|
163
|
+
"items": {
|
|
164
|
+
"$ref": "#/$defs/conceptEntry"
|
|
165
|
+
}
|
|
108
166
|
}
|
|
109
167
|
},
|
|
110
168
|
"additionalProperties": false
|
|
111
169
|
},
|
|
112
170
|
{
|
|
113
171
|
"type": "object",
|
|
114
|
-
"required": [
|
|
172
|
+
"required": [
|
|
173
|
+
"mode",
|
|
174
|
+
"addressing",
|
|
175
|
+
"result"
|
|
176
|
+
],
|
|
115
177
|
"properties": {
|
|
116
178
|
"format": true,
|
|
117
179
|
"workspace": true,
|
|
118
|
-
"mode": {
|
|
180
|
+
"mode": {
|
|
181
|
+
"const": "slice"
|
|
182
|
+
},
|
|
119
183
|
"addressing": {
|
|
120
|
-
"enum": [
|
|
184
|
+
"enum": [
|
|
185
|
+
"free-text",
|
|
186
|
+
"subjects",
|
|
187
|
+
"projection",
|
|
188
|
+
"changed"
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
"topic": {
|
|
192
|
+
"type": "string",
|
|
193
|
+
"minLength": 1
|
|
121
194
|
},
|
|
122
|
-
"topic": { "type": "string", "minLength": 1 },
|
|
123
195
|
"seeds": {
|
|
124
196
|
"type": "array",
|
|
125
|
-
"items": {
|
|
197
|
+
"items": {
|
|
198
|
+
"type": "string",
|
|
199
|
+
"minLength": 1
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
"matched": {
|
|
203
|
+
"type": "integer",
|
|
204
|
+
"minimum": 0
|
|
205
|
+
},
|
|
206
|
+
"result": {
|
|
207
|
+
"$ref": "#/$defs/projectionResult"
|
|
126
208
|
},
|
|
127
|
-
"
|
|
128
|
-
|
|
209
|
+
"changed": {
|
|
210
|
+
"type": "object",
|
|
211
|
+
"required": [
|
|
212
|
+
"range",
|
|
213
|
+
"concepts",
|
|
214
|
+
"relationships"
|
|
215
|
+
],
|
|
216
|
+
"properties": {
|
|
217
|
+
"range": {
|
|
218
|
+
"type": "string",
|
|
219
|
+
"minLength": 1
|
|
220
|
+
},
|
|
221
|
+
"concepts": {
|
|
222
|
+
"type": "array",
|
|
223
|
+
"items": {
|
|
224
|
+
"type": "string",
|
|
225
|
+
"minLength": 1
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
"relationships": {
|
|
229
|
+
"type": "array",
|
|
230
|
+
"items": {
|
|
231
|
+
"type": "string",
|
|
232
|
+
"minLength": 1
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
"additionalProperties": false
|
|
237
|
+
},
|
|
238
|
+
"coverage": {
|
|
239
|
+
"type": "object",
|
|
240
|
+
"required": [
|
|
241
|
+
"projections",
|
|
242
|
+
"uncovered"
|
|
243
|
+
],
|
|
244
|
+
"properties": {
|
|
245
|
+
"projections": {
|
|
246
|
+
"type": "integer",
|
|
247
|
+
"minimum": 0
|
|
248
|
+
},
|
|
249
|
+
"uncovered": {
|
|
250
|
+
"type": "array",
|
|
251
|
+
"items": {
|
|
252
|
+
"type": "string",
|
|
253
|
+
"minLength": 1
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"additionalProperties": false
|
|
258
|
+
}
|
|
129
259
|
},
|
|
130
260
|
"additionalProperties": false
|
|
131
261
|
},
|
|
@@ -142,36 +272,84 @@
|
|
|
142
272
|
"properties": {
|
|
143
273
|
"format": true,
|
|
144
274
|
"workspace": true,
|
|
145
|
-
"mode": {
|
|
146
|
-
|
|
275
|
+
"mode": {
|
|
276
|
+
"const": "advice"
|
|
277
|
+
},
|
|
278
|
+
"topic": {
|
|
279
|
+
"type": "string",
|
|
280
|
+
"minLength": 1
|
|
281
|
+
},
|
|
147
282
|
"seeds": {
|
|
148
283
|
"type": "array",
|
|
149
|
-
"items": {
|
|
284
|
+
"items": {
|
|
285
|
+
"type": "string",
|
|
286
|
+
"minLength": 1
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
"matched": {
|
|
290
|
+
"type": "integer",
|
|
291
|
+
"minimum": 0
|
|
292
|
+
},
|
|
293
|
+
"slice": {
|
|
294
|
+
"type": "string",
|
|
295
|
+
"minLength": 1
|
|
150
296
|
},
|
|
151
|
-
"matched": { "type": "integer", "minimum": 0 },
|
|
152
|
-
"slice": { "type": "string", "minLength": 1 },
|
|
153
297
|
"openQuestions": {
|
|
154
298
|
"type": "array",
|
|
155
299
|
"items": {
|
|
156
300
|
"type": "object",
|
|
157
|
-
"required": [
|
|
301
|
+
"required": [
|
|
302
|
+
"wave",
|
|
303
|
+
"id",
|
|
304
|
+
"authority",
|
|
305
|
+
"question",
|
|
306
|
+
"materiality"
|
|
307
|
+
],
|
|
158
308
|
"properties": {
|
|
159
|
-
"wave": {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
"
|
|
164
|
-
|
|
309
|
+
"wave": {
|
|
310
|
+
"type": "string",
|
|
311
|
+
"minLength": 1
|
|
312
|
+
},
|
|
313
|
+
"id": {
|
|
314
|
+
"type": "string",
|
|
315
|
+
"minLength": 1
|
|
316
|
+
},
|
|
317
|
+
"authority": {
|
|
318
|
+
"enum": [
|
|
319
|
+
"human",
|
|
320
|
+
"agent",
|
|
321
|
+
"either"
|
|
322
|
+
]
|
|
323
|
+
},
|
|
324
|
+
"question": {
|
|
325
|
+
"type": "string",
|
|
326
|
+
"minLength": 1
|
|
327
|
+
},
|
|
328
|
+
"materiality": {
|
|
329
|
+
"type": "string",
|
|
330
|
+
"minLength": 1
|
|
331
|
+
},
|
|
332
|
+
"subject": {
|
|
333
|
+
"type": "string",
|
|
334
|
+
"minLength": 1
|
|
335
|
+
}
|
|
165
336
|
},
|
|
166
337
|
"additionalProperties": false
|
|
167
338
|
}
|
|
168
339
|
},
|
|
169
340
|
"reconciliation": {
|
|
170
341
|
"type": "object",
|
|
171
|
-
"required": [
|
|
342
|
+
"required": [
|
|
343
|
+
"summary",
|
|
344
|
+
"findings"
|
|
345
|
+
],
|
|
172
346
|
"properties": {
|
|
173
|
-
"summary": {
|
|
174
|
-
|
|
347
|
+
"summary": {
|
|
348
|
+
"$ref": "#/$defs/reconciliationSummary"
|
|
349
|
+
},
|
|
350
|
+
"findings": {
|
|
351
|
+
"type": "array"
|
|
352
|
+
}
|
|
175
353
|
},
|
|
176
354
|
"additionalProperties": false
|
|
177
355
|
}
|
|
@@ -180,34 +358,62 @@
|
|
|
180
358
|
},
|
|
181
359
|
{
|
|
182
360
|
"type": "object",
|
|
183
|
-
"required": [
|
|
361
|
+
"required": [
|
|
362
|
+
"mode",
|
|
363
|
+
"subjects"
|
|
364
|
+
],
|
|
184
365
|
"properties": {
|
|
185
366
|
"format": true,
|
|
186
367
|
"workspace": true,
|
|
187
|
-
"mode": {
|
|
368
|
+
"mode": {
|
|
369
|
+
"const": "next"
|
|
370
|
+
},
|
|
188
371
|
"subjects": {
|
|
189
372
|
"type": "array",
|
|
190
|
-
"items": {
|
|
373
|
+
"items": {
|
|
374
|
+
"$ref": "#/$defs/nextSubject"
|
|
375
|
+
}
|
|
191
376
|
}
|
|
192
377
|
},
|
|
193
378
|
"additionalProperties": false
|
|
194
379
|
},
|
|
195
380
|
{
|
|
196
381
|
"type": "object",
|
|
197
|
-
"required": [
|
|
382
|
+
"required": [
|
|
383
|
+
"mode",
|
|
384
|
+
"report"
|
|
385
|
+
],
|
|
198
386
|
"properties": {
|
|
199
387
|
"format": true,
|
|
200
388
|
"workspace": true,
|
|
201
|
-
"mode": {
|
|
389
|
+
"mode": {
|
|
390
|
+
"const": "open"
|
|
391
|
+
},
|
|
202
392
|
"report": {
|
|
203
393
|
"type": "object",
|
|
204
|
-
"required": [
|
|
394
|
+
"required": [
|
|
395
|
+
"format",
|
|
396
|
+
"workspace",
|
|
397
|
+
"catalogue",
|
|
398
|
+
"summary",
|
|
399
|
+
"waves"
|
|
400
|
+
],
|
|
205
401
|
"properties": {
|
|
206
|
-
"format": {
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
"
|
|
210
|
-
|
|
402
|
+
"format": {
|
|
403
|
+
"const": "yarramate/interrogation-report/v1"
|
|
404
|
+
},
|
|
405
|
+
"workspace": {
|
|
406
|
+
"type": "string"
|
|
407
|
+
},
|
|
408
|
+
"catalogue": {
|
|
409
|
+
"type": "string"
|
|
410
|
+
},
|
|
411
|
+
"summary": {
|
|
412
|
+
"type": "object"
|
|
413
|
+
},
|
|
414
|
+
"waves": {
|
|
415
|
+
"type": "array"
|
|
416
|
+
}
|
|
211
417
|
},
|
|
212
418
|
"additionalProperties": false
|
|
213
419
|
}
|
|
@@ -216,22 +422,48 @@
|
|
|
216
422
|
},
|
|
217
423
|
{
|
|
218
424
|
"type": "object",
|
|
219
|
-
"required": [
|
|
425
|
+
"required": [
|
|
426
|
+
"mode",
|
|
427
|
+
"conceptKinds",
|
|
428
|
+
"relationshipKinds",
|
|
429
|
+
"extensions"
|
|
430
|
+
],
|
|
220
431
|
"properties": {
|
|
221
432
|
"format": true,
|
|
222
433
|
"workspace": true,
|
|
223
|
-
"mode": {
|
|
434
|
+
"mode": {
|
|
435
|
+
"const": "kinds"
|
|
436
|
+
},
|
|
224
437
|
"conceptKinds": {
|
|
225
438
|
"type": "array",
|
|
226
439
|
"items": {
|
|
227
440
|
"type": "object",
|
|
228
|
-
"required": [
|
|
441
|
+
"required": [
|
|
442
|
+
"id",
|
|
443
|
+
"name",
|
|
444
|
+
"layer",
|
|
445
|
+
"aspect"
|
|
446
|
+
],
|
|
229
447
|
"properties": {
|
|
230
|
-
"id": {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
"
|
|
448
|
+
"id": {
|
|
449
|
+
"type": "string",
|
|
450
|
+
"minLength": 1
|
|
451
|
+
},
|
|
452
|
+
"name": {
|
|
453
|
+
"type": "string",
|
|
454
|
+
"minLength": 1
|
|
455
|
+
},
|
|
456
|
+
"layer": {
|
|
457
|
+
"type": "string",
|
|
458
|
+
"minLength": 1
|
|
459
|
+
},
|
|
460
|
+
"aspect": {
|
|
461
|
+
"type": "string",
|
|
462
|
+
"minLength": 1
|
|
463
|
+
},
|
|
464
|
+
"inspiredBy": {
|
|
465
|
+
"type": "string"
|
|
466
|
+
}
|
|
235
467
|
},
|
|
236
468
|
"additionalProperties": false
|
|
237
469
|
}
|
|
@@ -240,19 +472,34 @@
|
|
|
240
472
|
"type": "array",
|
|
241
473
|
"items": {
|
|
242
474
|
"type": "object",
|
|
243
|
-
"required": [
|
|
475
|
+
"required": [
|
|
476
|
+
"id",
|
|
477
|
+
"intent"
|
|
478
|
+
],
|
|
244
479
|
"properties": {
|
|
245
|
-
"id": {
|
|
246
|
-
|
|
480
|
+
"id": {
|
|
481
|
+
"type": "string",
|
|
482
|
+
"minLength": 1
|
|
483
|
+
},
|
|
484
|
+
"intent": {
|
|
485
|
+
"type": "string",
|
|
486
|
+
"minLength": 1
|
|
487
|
+
},
|
|
247
488
|
"sourceAspects": {
|
|
248
489
|
"type": "array",
|
|
249
|
-
"items": {
|
|
490
|
+
"items": {
|
|
491
|
+
"type": "string"
|
|
492
|
+
}
|
|
250
493
|
},
|
|
251
494
|
"targetAspects": {
|
|
252
495
|
"type": "array",
|
|
253
|
-
"items": {
|
|
496
|
+
"items": {
|
|
497
|
+
"type": "string"
|
|
498
|
+
}
|
|
254
499
|
},
|
|
255
|
-
"repair": {
|
|
500
|
+
"repair": {
|
|
501
|
+
"type": "string"
|
|
502
|
+
}
|
|
256
503
|
},
|
|
257
504
|
"additionalProperties": false
|
|
258
505
|
}
|
|
@@ -261,13 +508,27 @@
|
|
|
261
508
|
"type": "array",
|
|
262
509
|
"items": {
|
|
263
510
|
"type": "object",
|
|
264
|
-
"required": [
|
|
511
|
+
"required": [
|
|
512
|
+
"id",
|
|
513
|
+
"type",
|
|
514
|
+
"lineage"
|
|
515
|
+
],
|
|
265
516
|
"properties": {
|
|
266
|
-
"id": {
|
|
267
|
-
|
|
517
|
+
"id": {
|
|
518
|
+
"type": "string",
|
|
519
|
+
"minLength": 1
|
|
520
|
+
},
|
|
521
|
+
"type": {
|
|
522
|
+
"enum": [
|
|
523
|
+
"concept",
|
|
524
|
+
"relationship"
|
|
525
|
+
]
|
|
526
|
+
},
|
|
268
527
|
"lineage": {
|
|
269
528
|
"type": "array",
|
|
270
|
-
"items": {
|
|
529
|
+
"items": {
|
|
530
|
+
"type": "string"
|
|
531
|
+
}
|
|
271
532
|
}
|
|
272
533
|
},
|
|
273
534
|
"additionalProperties": false
|
|
@@ -278,21 +539,45 @@
|
|
|
278
539
|
},
|
|
279
540
|
{
|
|
280
541
|
"type": "object",
|
|
281
|
-
"required": [
|
|
542
|
+
"required": [
|
|
543
|
+
"mode",
|
|
544
|
+
"comparison"
|
|
545
|
+
],
|
|
282
546
|
"properties": {
|
|
283
547
|
"format": true,
|
|
284
548
|
"workspace": true,
|
|
285
|
-
"mode": {
|
|
549
|
+
"mode": {
|
|
550
|
+
"const": "compare"
|
|
551
|
+
},
|
|
286
552
|
"comparison": {
|
|
287
553
|
"type": "object",
|
|
288
|
-
"required": [
|
|
554
|
+
"required": [
|
|
555
|
+
"format",
|
|
556
|
+
"from",
|
|
557
|
+
"to",
|
|
558
|
+
"added",
|
|
559
|
+
"removed",
|
|
560
|
+
"retained"
|
|
561
|
+
],
|
|
289
562
|
"properties": {
|
|
290
|
-
"format": {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
"
|
|
294
|
-
|
|
295
|
-
|
|
563
|
+
"format": {
|
|
564
|
+
"const": "yarramate/state-comparison/v1"
|
|
565
|
+
},
|
|
566
|
+
"from": {
|
|
567
|
+
"type": "string"
|
|
568
|
+
},
|
|
569
|
+
"to": {
|
|
570
|
+
"type": "string"
|
|
571
|
+
},
|
|
572
|
+
"added": {
|
|
573
|
+
"type": "array"
|
|
574
|
+
},
|
|
575
|
+
"removed": {
|
|
576
|
+
"type": "array"
|
|
577
|
+
},
|
|
578
|
+
"retained": {
|
|
579
|
+
"type": "array"
|
|
580
|
+
}
|
|
296
581
|
},
|
|
297
582
|
"additionalProperties": false
|
|
298
583
|
}
|
|
@@ -303,30 +588,67 @@
|
|
|
303
588
|
"$defs": {
|
|
304
589
|
"conceptEntry": {
|
|
305
590
|
"type": "object",
|
|
306
|
-
"required": [
|
|
591
|
+
"required": [
|
|
592
|
+
"id",
|
|
593
|
+
"kind"
|
|
594
|
+
],
|
|
307
595
|
"properties": {
|
|
308
|
-
"id": {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
"
|
|
596
|
+
"id": {
|
|
597
|
+
"type": "string",
|
|
598
|
+
"minLength": 1
|
|
599
|
+
},
|
|
600
|
+
"kind": {
|
|
601
|
+
"type": "string",
|
|
602
|
+
"minLength": 1
|
|
603
|
+
},
|
|
604
|
+
"name": {
|
|
605
|
+
"type": "string"
|
|
606
|
+
},
|
|
607
|
+
"status": {
|
|
608
|
+
"enum": [
|
|
609
|
+
"planned",
|
|
610
|
+
"current",
|
|
611
|
+
"retired"
|
|
612
|
+
]
|
|
613
|
+
},
|
|
614
|
+
"description": {
|
|
615
|
+
"type": "string"
|
|
616
|
+
}
|
|
313
617
|
},
|
|
314
618
|
"additionalProperties": false
|
|
315
619
|
},
|
|
316
620
|
"nextSubject": {
|
|
317
621
|
"type": "object",
|
|
318
|
-
"required": [
|
|
622
|
+
"required": [
|
|
623
|
+
"id",
|
|
624
|
+
"kind",
|
|
625
|
+
"dependsOn",
|
|
626
|
+
"requiredBy",
|
|
627
|
+
"evidence"
|
|
628
|
+
],
|
|
319
629
|
"properties": {
|
|
320
|
-
"id": {
|
|
321
|
-
|
|
322
|
-
|
|
630
|
+
"id": {
|
|
631
|
+
"type": "string",
|
|
632
|
+
"minLength": 1
|
|
633
|
+
},
|
|
634
|
+
"kind": {
|
|
635
|
+
"type": "string",
|
|
636
|
+
"minLength": 1
|
|
637
|
+
},
|
|
638
|
+
"name": {
|
|
639
|
+
"type": "string"
|
|
640
|
+
},
|
|
323
641
|
"dependsOn": {
|
|
324
642
|
"type": "array",
|
|
325
|
-
"items": {
|
|
643
|
+
"items": {
|
|
644
|
+
"type": "string"
|
|
645
|
+
}
|
|
326
646
|
},
|
|
327
647
|
"requiredBy": {
|
|
328
648
|
"type": "array",
|
|
329
|
-
"items": {
|
|
649
|
+
"items": {
|
|
650
|
+
"type": "string"
|
|
651
|
+
}
|
|
330
652
|
},
|
|
331
653
|
"evidence": {
|
|
332
654
|
"type": "object",
|
|
@@ -338,28 +660,58 @@
|
|
|
338
660
|
"notObserved"
|
|
339
661
|
],
|
|
340
662
|
"properties": {
|
|
341
|
-
"observations": {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
"
|
|
345
|
-
|
|
663
|
+
"observations": {
|
|
664
|
+
"type": "integer"
|
|
665
|
+
},
|
|
666
|
+
"confirmed": {
|
|
667
|
+
"type": "integer"
|
|
668
|
+
},
|
|
669
|
+
"contradicted": {
|
|
670
|
+
"type": "integer"
|
|
671
|
+
},
|
|
672
|
+
"unknown": {
|
|
673
|
+
"type": "integer"
|
|
674
|
+
},
|
|
675
|
+
"notObserved": {
|
|
676
|
+
"type": "integer"
|
|
677
|
+
}
|
|
346
678
|
},
|
|
347
679
|
"additionalProperties": false
|
|
348
680
|
},
|
|
349
|
-
"cycle": {
|
|
681
|
+
"cycle": {
|
|
682
|
+
"const": true
|
|
683
|
+
}
|
|
350
684
|
},
|
|
351
685
|
"additionalProperties": false
|
|
352
686
|
},
|
|
353
687
|
"projectionResult": {
|
|
354
688
|
"type": "object",
|
|
355
|
-
"required": [
|
|
689
|
+
"required": [
|
|
690
|
+
"format",
|
|
691
|
+
"projection",
|
|
692
|
+
"documents",
|
|
693
|
+
"subjects",
|
|
694
|
+
"claims"
|
|
695
|
+
],
|
|
356
696
|
"properties": {
|
|
357
|
-
"format": {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
"
|
|
361
|
-
|
|
362
|
-
|
|
697
|
+
"format": {
|
|
698
|
+
"const": "yarramate/projection-result/v1"
|
|
699
|
+
},
|
|
700
|
+
"projection": {
|
|
701
|
+
"type": "string"
|
|
702
|
+
},
|
|
703
|
+
"presentation": {
|
|
704
|
+
"type": "object"
|
|
705
|
+
},
|
|
706
|
+
"documents": {
|
|
707
|
+
"type": "array"
|
|
708
|
+
},
|
|
709
|
+
"subjects": {
|
|
710
|
+
"type": "array"
|
|
711
|
+
},
|
|
712
|
+
"claims": {
|
|
713
|
+
"type": "array"
|
|
714
|
+
}
|
|
363
715
|
},
|
|
364
716
|
"additionalProperties": false
|
|
365
717
|
},
|
|
@@ -376,14 +728,30 @@
|
|
|
376
728
|
"subjectsWithoutEvidence"
|
|
377
729
|
],
|
|
378
730
|
"properties": {
|
|
379
|
-
"evidenceDocuments": {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
"
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
"
|
|
386
|
-
|
|
731
|
+
"evidenceDocuments": {
|
|
732
|
+
"type": "integer"
|
|
733
|
+
},
|
|
734
|
+
"observations": {
|
|
735
|
+
"type": "integer"
|
|
736
|
+
},
|
|
737
|
+
"confirmed": {
|
|
738
|
+
"type": "integer"
|
|
739
|
+
},
|
|
740
|
+
"findings": {
|
|
741
|
+
"type": "integer"
|
|
742
|
+
},
|
|
743
|
+
"contradicted": {
|
|
744
|
+
"type": "integer"
|
|
745
|
+
},
|
|
746
|
+
"unknown": {
|
|
747
|
+
"type": "integer"
|
|
748
|
+
},
|
|
749
|
+
"notObserved": {
|
|
750
|
+
"type": "integer"
|
|
751
|
+
},
|
|
752
|
+
"subjectsWithoutEvidence": {
|
|
753
|
+
"type": "integer"
|
|
754
|
+
}
|
|
387
755
|
},
|
|
388
756
|
"additionalProperties": false
|
|
389
757
|
}
|