yarramate 1.0.0 → 1.1.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.
@@ -135,6 +135,23 @@ export type IncrementalCompilationResult = ({
135
135
  readonly incremental: boolean;
136
136
  readonly cache: CompilationCache;
137
137
  };
138
+ /**
139
+ * A succession entry: a bare predecessor id, or one with the respect in which
140
+ * it was superseded.
141
+ *
142
+ * The scope is load-bearing rather than decorative. A model claimed that Zoekt
143
+ * superseded the Elasticsearch indexer, unqualified, while the source it was
144
+ * built from says Zoekt "handles only code search and does not replace
145
+ * Elasticsearch". The prose carried the qualifier and the field could not, and
146
+ * `ask --compare` reads the field, so the declared target architecture became
147
+ * the deletion of a component that is not being deleted (ADR 0109).
148
+ */
149
+ export type NativeSuccession = string | {
150
+ readonly subject: string;
151
+ readonly inRespectOf: string;
152
+ };
153
+ export declare const successionSubject: (entry: NativeSuccession) => string;
154
+ export declare const successionScope: (entry: NativeSuccession) => string | undefined;
138
155
  export { ATTESTATION_PREDICATE_PREFIX, attestationClaimValue, parseAttestationClaimValue, parseConstraintExpectsValue, type AttestationClaimParts, type ConstraintExpectsParts, } from './graph-claims.js';
139
156
  interface ResolvedPosition {
140
157
  readonly line: number;
@@ -8,15 +8,39 @@ export interface EvidenceObservedValue {
8
8
  readonly key: string;
9
9
  readonly value: string;
10
10
  }
11
+ /**
12
+ * One search a provider ran and found nothing at, recorded so a reader can
13
+ * re-run it. yarramate never executes it: the engine has no access to the
14
+ * subject tree, and gaining one would be a different decision (ADR 0107).
15
+ */
16
+ export type SearchProbe = {
17
+ readonly glob: string;
18
+ } | {
19
+ readonly grep: string;
20
+ readonly paths?: readonly string[];
21
+ };
22
+ /**
23
+ * A figure quoted in an evidence message, with how it was produced, so a
24
+ * reader can tell a measured number from a remembered one and re-derive it at
25
+ * a later commit.
26
+ */
27
+ export interface Measurement {
28
+ readonly value: string;
29
+ readonly method: string;
30
+ }
31
+ interface ObservationProvenance {
32
+ readonly searched?: readonly SearchProbe[];
33
+ readonly measured?: readonly Measurement[];
34
+ }
11
35
  export type EvidenceObservation = ({
12
36
  readonly subject: string;
13
37
  readonly result: EvidenceResult;
14
38
  readonly evidence: EvidenceLocator;
15
- } & Partial<EvidenceObservedValue>) | ({
39
+ } & ObservationProvenance & Partial<EvidenceObservedValue>) | ({
16
40
  readonly claim: string;
17
41
  readonly result: EvidenceResult;
18
42
  readonly evidence: EvidenceLocator;
19
- } & Partial<EvidenceObservedValue>);
43
+ } & ObservationProvenance & Partial<EvidenceObservedValue>);
20
44
  export interface EvidenceDocument {
21
45
  readonly format: 'yarramate/evidence/v1';
22
46
  readonly id: string;
@@ -60,3 +84,4 @@ export type EvidenceWorkspaceEvaluationResult = {
60
84
  export declare function loadEvidence(source: WorkspaceSource): EvidenceLoadResult;
61
85
  export declare function evaluateEvidence(graph: SemanticGraph, evidence: EvidenceDocument): EvidenceEvaluationResult;
62
86
  export declare function evaluateEvidenceWorkspace(graph: SemanticGraph, evidenceDocuments: readonly EvidenceDocument[]): EvidenceWorkspaceEvaluationResult;
87
+ export {};
@@ -232,6 +232,42 @@ the notation module is the rendering vocabulary for that mode; the element
232
232
  vocabulary and relationship table themselves are implemented in the core
233
233
  profile (ADR 0097).
234
234
 
235
+ ## Evaluating question catalogues off Node
236
+
237
+ The interrogation engine is public API. A consumer that compiles a workspace
238
+ itself can load a catalogue and evaluate it without the CLI:
239
+
240
+ ```ts
241
+ import {
242
+ evaluateCatalogue,
243
+ loadQuestionCatalogue,
244
+ INTERROGATION_SEMANTICS_VERSION,
245
+ } from 'yarramate/interrogation'
246
+ ```
247
+
248
+ **Import the subpath, not the package entry, wherever the runtime is not
249
+ Node.** The `.` barrel reaches `node:fs`, `node:path` and `node:child_process`
250
+ through workspace loading, the filesystem source store and git-derived
251
+ attestation staleness, so taking the engine from there drags Node in behind it.
252
+ `yarramate/interrogation` carries the engine alone and is pinned free of Node
253
+ built-ins by the same test that guards `yarramate/adapter/visual-graph`. The
254
+ same names are also exported from `.` for Node consumers.
255
+
256
+ `evaluateCatalogue` returns the report without its `workspace`, which the
257
+ caller supplies:
258
+
259
+ ```ts
260
+ const report = { workspace: id, ...evaluateCatalogue(catalogue, graph, profileContext) }
261
+ ```
262
+
263
+ The report carries `semantics`, the version of condition evaluation, which
264
+ changes only when an existing question's answer can change for an unchanged
265
+ model ([ADR 0106](adr/0106-a-report-says-which-engine-answered.md)). A consumer
266
+ that **persists** answers should store it beside them: equal means a flipped
267
+ answer is about the model and belongs in front of a user, different means the
268
+ engine moved and the right response is to re-baseline silently rather than
269
+ reopen someone's queue.
270
+
235
271
  ### Mount the visual editor
236
272
 
237
273
  Mount the packaged editor when the consuming product owns the sources and
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yarramate",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Tool-neutral semantic architecture engine and guided methodology",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -54,6 +54,10 @@
54
54
  "types": "./dist/notation/archimate.d.ts",
55
55
  "import": "./dist/notation/archimate.js"
56
56
  },
57
+ "./interrogation": {
58
+ "types": "./dist/interrogation-entry.d.ts",
59
+ "import": "./dist/interrogation-entry.js"
60
+ },
57
61
  "./visual-app": {
58
62
  "types": "./dist/visual-app-lib/editor.d.ts",
59
63
  "import": "./dist/visual-app-lib/editor.js"
@@ -522,6 +522,7 @@
522
522
  "format",
523
523
  "workspace",
524
524
  "catalogue",
525
+ "semantics",
525
526
  "summary",
526
527
  "waves"
527
528
  ],
@@ -535,6 +536,9 @@
535
536
  "catalogue": {
536
537
  "type": "string"
537
538
  },
539
+ "semantics": {
540
+ "type": "string"
541
+ },
538
542
  "summary": {
539
543
  "type": "object"
540
544
  },
@@ -875,6 +879,10 @@
875
879
  },
876
880
  "notObserved": {
877
881
  "type": "integer"
882
+ },
883
+ "unsupportedAbsences": {
884
+ "type": "integer",
885
+ "minimum": 0
878
886
  }
879
887
  },
880
888
  "additionalProperties": false
@@ -950,6 +958,10 @@
950
958
  "notObserved": {
951
959
  "type": "integer"
952
960
  },
961
+ "unsupportedAbsences": {
962
+ "type": "integer",
963
+ "minimum": 0
964
+ },
953
965
  "subjectsWithoutEvidence": {
954
966
  "type": "integer"
955
967
  },
@@ -127,6 +127,24 @@
127
127
  "supersedes": {
128
128
  "$ref": "#/$defs/successionReferences"
129
129
  },
130
+ "forbids": {
131
+ "description": "Relationship shapes this subject rules out, checked against the graph. A constraint nothing tests is a comment. Deliberately narrow: forbid a relationship kind between named endpoints, with exceptions, which covers \"everything goes through X\" and needs no traversal.",
132
+ "type": "array",
133
+ "minItems": 1,
134
+ "items": {
135
+ "type": "object",
136
+ "additionalProperties": false,
137
+ "required": ["relationship"],
138
+ "anyOf": [{ "required": ["from"] }, { "required": ["to"] }],
139
+ "properties": {
140
+ "relationship": { "type": "string", "minLength": 1 },
141
+ "from": { "type": "string", "minLength": 1 },
142
+ "to": { "type": "string", "minLength": 1 },
143
+ "exceptFrom": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } },
144
+ "exceptTo": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 } }
145
+ }
146
+ }
147
+ },
130
148
  "constraints": {
131
149
  "type": "array",
132
150
  "items": {
@@ -237,7 +255,18 @@
237
255
  "minItems": 1,
238
256
  "uniqueItems": true,
239
257
  "items": {
240
- "$ref": "#/$defs/reference"
258
+ "oneOf": [
259
+ { "$ref": "#/$defs/reference" },
260
+ {
261
+ "type": "object",
262
+ "additionalProperties": false,
263
+ "required": ["subject", "inRespectOf"],
264
+ "properties": {
265
+ "subject": { "$ref": "#/$defs/reference" },
266
+ "inRespectOf": { "$ref": "#/$defs/nonEmptyText" }
267
+ }
268
+ }
269
+ ]
241
270
  }
242
271
  },
243
272
  "relationship": {
@@ -27,6 +27,44 @@
27
27
  }
28
28
  },
29
29
  "$defs": {
30
+ "searchProbe": {
31
+ "description": "One search a provider performed and found nothing at. Recorded so a reader can re-run it; yarramate does not execute it.",
32
+ "type": "object",
33
+ "additionalProperties": false,
34
+ "oneOf": [{ "required": ["glob"] }, { "required": ["grep"] }],
35
+ "properties": {
36
+ "glob": {
37
+ "type": "string",
38
+ "minLength": 1,
39
+ "description": "A path glob that matched nothing, e.g. PRAEFECT_*"
40
+ },
41
+ "grep": {
42
+ "type": "string",
43
+ "minLength": 1,
44
+ "description": "A pattern that matched nothing."
45
+ },
46
+ "paths": {
47
+ "type": "array",
48
+ "minItems": 1,
49
+ "items": { "type": "string", "minLength": 1 },
50
+ "description": "Paths the search covered. Absent means the whole tree."
51
+ }
52
+ }
53
+ },
54
+ "measurement": {
55
+ "description": "A figure quoted in an evidence message, with how it was produced. Recorded so a reader can re-derive it rather than trust it; yarramate does not execute the method.",
56
+ "type": "object",
57
+ "additionalProperties": false,
58
+ "required": ["value", "method"],
59
+ "properties": {
60
+ "value": { "type": "string", "minLength": 1 },
61
+ "method": {
62
+ "type": "string",
63
+ "minLength": 1,
64
+ "description": "How the value was obtained, precisely enough to reproduce."
65
+ }
66
+ }
67
+ },
30
68
  "id": {
31
69
  "type": "string",
32
70
  "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$"
@@ -77,6 +115,18 @@
77
115
  "not-observed"
78
116
  ]
79
117
  },
118
+ "searched": {
119
+ "type": "array",
120
+ "minItems": 1,
121
+ "items": { "$ref": "#/$defs/searchProbe" },
122
+ "description": "What was searched and found empty. Meaningful on a not-observed result, which is the one result that asserts a negative about a tree nobody read exhaustively."
123
+ },
124
+ "measured": {
125
+ "type": "array",
126
+ "minItems": 1,
127
+ "items": { "$ref": "#/$defs/measurement" },
128
+ "description": "Figures quoted in the message, with how each was produced."
129
+ },
80
130
  "key": {
81
131
  "$ref": "#/$defs/observationKey"
82
132
  },
@@ -4,7 +4,7 @@
4
4
  "title": "YarraMate interrogation report",
5
5
  "type": "object",
6
6
  "additionalProperties": false,
7
- "required": ["format", "workspace", "catalogue", "summary", "waves"],
7
+ "required": ["format", "workspace", "catalogue", "semantics", "summary", "waves"],
8
8
  "properties": {
9
9
  "format": {
10
10
  "const": "yarramate/interrogation-report/v1"
@@ -17,6 +17,11 @@
17
17
  "type": "string",
18
18
  "minLength": 1
19
19
  },
20
+ "semantics": {
21
+ "type": "string",
22
+ "minLength": 1,
23
+ "description": "The version of condition evaluation that produced this report, as distinct from the package version. It changes only when an existing question's answer can change for an unchanged model, so a consumer holding stored answers can tell an engine change from a model change. Absent on reports produced before yarramate 1.1.0."
24
+ },
20
25
  "summary": {
21
26
  "type": "object",
22
27
  "additionalProperties": false,
@@ -104,9 +104,7 @@
104
104
  "description": "Which subjects a subject-scope question applies to. Field vocabulary mirrors the projection query selector (ADR 0017).",
105
105
  "type": "object",
106
106
  "additionalProperties": false,
107
- "required": [
108
- "kinds"
109
- ],
107
+
110
108
  "properties": {
111
109
  "kinds": {
112
110
  "type": "array",
@@ -491,6 +489,19 @@
491
489
  "const": "unconstrained-kind"
492
490
  }
493
491
  }
492
+ },
493
+ {
494
+ "type": "object",
495
+ "additionalProperties": false,
496
+ "description": "The subject supersedes a predecessor that is still current, and does not say in what respect. A succession that replaced its predecessor outright says so by the predecessor being gone; one where both remain is usually partial, and the respect is the part a reader needs (ADR 0109).",
497
+ "required": [
498
+ "condition"
499
+ ],
500
+ "properties": {
501
+ "condition": {
502
+ "const": "unscoped-succession"
503
+ }
504
+ }
494
505
  }
495
506
  ]
496
507
  },
@@ -30,7 +30,12 @@
30
30
  "unknown": { "type": "integer", "minimum": 0 },
31
31
  "notObserved": { "type": "integer", "minimum": 0 },
32
32
  "subjectsWithoutEvidence": { "type": "integer", "minimum": 0 },
33
- "staleAttestations": { "type": "integer", "minimum": 0 },
33
+ "unsupportedAbsences": {
34
+ "type": "integer",
35
+ "minimum": 0,
36
+ "description": "not-observed observations that name no search. A not-observed asserts a negative about a tree nobody read exhaustively, and is the one result whose message nothing can check; this counts the ones offering a reader nothing to re-run."
37
+ },
38
+ "staleAttestations": { "type": "integer", "minimum": 0 },
34
39
  "unconfirmedAttestations": { "type": "integer", "minimum": 0 },
35
40
  "expectationsCompared": { "type": "integer", "minimum": 0 },
36
41
  "expectationsWithoutObservation": { "type": "integer", "minimum": 0 }