yarramate 0.7.1 → 0.8.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.
- package/catalogues/core-enrichment.yaml +292 -9
- package/dist/apply-command.js +35 -1
- package/dist/design-command.js +2 -0
- package/dist/interrogate-command.d.ts +2 -0
- package/dist/interrogate-command.js +14 -8
- package/package.json +1 -1
- package/schema/yarramate-design-step.schema.json +3 -0
- package/schema/yarramate-interrogation-report.schema.json +1 -0
- package/schema/yarramate-question-catalogue.schema.json +5 -0
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
format: yarramate/question-catalogue/v1
|
|
2
2
|
id: core-enrichment
|
|
3
|
-
version: "0.
|
|
3
|
+
version: "0.5"
|
|
4
4
|
profile: yarramate/core@0.1
|
|
5
5
|
presentation:
|
|
6
6
|
title: Core enrichment interview
|
|
7
7
|
description: >-
|
|
8
|
-
The guided design path: motivation, business,
|
|
9
|
-
cross-cutting hygiene
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
The guided design path: motivation, business, application, technology,
|
|
9
|
+
and implementation waves plus cross-cutting hygiene. Each question
|
|
10
|
+
states the decision its answer changes; a question that cannot is
|
|
11
|
+
deleted, not softened. Adequacy is enforced by linkage depth and
|
|
12
|
+
attestation, never by reading words. Versioning is additive within a
|
|
13
|
+
major version: every question records the catalogue version it arrived
|
|
14
|
+
in (ADR 0063), and a completed interview honestly reopens when the
|
|
15
|
+
path deepens.
|
|
13
16
|
|
|
14
17
|
waves:
|
|
15
18
|
- id: motivation
|
|
@@ -23,6 +26,16 @@ waves:
|
|
|
23
26
|
description: >-
|
|
24
27
|
How declared services are realized, performed, and fed with
|
|
25
28
|
information.
|
|
29
|
+
- id: technology
|
|
30
|
+
name: Technology
|
|
31
|
+
description: >-
|
|
32
|
+
Where the declared applications actually run and what materializes
|
|
33
|
+
them.
|
|
34
|
+
- id: implementation
|
|
35
|
+
name: Implementation
|
|
36
|
+
description: >-
|
|
37
|
+
How the planned architecture becomes real: work, deliverables, and
|
|
38
|
+
the plateaus between here and there.
|
|
26
39
|
- id: hygiene
|
|
27
40
|
name: Model hygiene
|
|
28
41
|
description: Cross-cutting completeness that keeps every wave honest.
|
|
@@ -31,6 +44,7 @@ questions:
|
|
|
31
44
|
# ---- motivation ----------------------------------------------------------
|
|
32
45
|
- id: outcome-missing
|
|
33
46
|
wave: motivation
|
|
47
|
+
since: "0.1"
|
|
34
48
|
scope: workspace
|
|
35
49
|
trigger:
|
|
36
50
|
- condition: no-subject-of-kind
|
|
@@ -50,6 +64,7 @@ questions:
|
|
|
50
64
|
|
|
51
65
|
- id: stakeholders-missing
|
|
52
66
|
wave: motivation
|
|
67
|
+
since: "0.1"
|
|
53
68
|
scope: workspace
|
|
54
69
|
trigger:
|
|
55
70
|
- condition: no-subject-of-kind
|
|
@@ -68,6 +83,7 @@ questions:
|
|
|
68
83
|
|
|
69
84
|
- id: constraints-missing
|
|
70
85
|
wave: motivation
|
|
86
|
+
since: "0.1"
|
|
71
87
|
scope: workspace
|
|
72
88
|
trigger:
|
|
73
89
|
- condition: no-subject-of-kind
|
|
@@ -86,6 +102,7 @@ questions:
|
|
|
86
102
|
|
|
87
103
|
- id: goal-unrealized
|
|
88
104
|
wave: motivation
|
|
105
|
+
since: "0.1"
|
|
89
106
|
scope: subject
|
|
90
107
|
subjects:
|
|
91
108
|
kinds:
|
|
@@ -105,11 +122,14 @@ questions:
|
|
|
105
122
|
authority: either
|
|
106
123
|
resolution: >-
|
|
107
124
|
Add realization relationships from the fulfilling capability or
|
|
108
|
-
service,
|
|
125
|
+
service, record the aspirational status in the goal's description,
|
|
126
|
+
or retire the goal (status: retired) to record that it no longer
|
|
127
|
+
steers design.
|
|
109
128
|
|
|
110
129
|
|
|
111
130
|
- id: goal-no-driver
|
|
112
131
|
wave: motivation
|
|
132
|
+
since: "0.3"
|
|
113
133
|
scope: subject
|
|
114
134
|
subjects:
|
|
115
135
|
kinds:
|
|
@@ -137,6 +157,7 @@ questions:
|
|
|
137
157
|
|
|
138
158
|
- id: driver-influences-nothing
|
|
139
159
|
wave: motivation
|
|
160
|
+
since: "0.3"
|
|
140
161
|
scope: subject
|
|
141
162
|
subjects:
|
|
142
163
|
kinds:
|
|
@@ -158,6 +179,7 @@ questions:
|
|
|
158
179
|
|
|
159
180
|
- id: stakeholder-unconcerned
|
|
160
181
|
wave: motivation
|
|
182
|
+
since: "0.3"
|
|
161
183
|
scope: subject
|
|
162
184
|
subjects:
|
|
163
185
|
kinds:
|
|
@@ -180,6 +202,7 @@ questions:
|
|
|
180
202
|
|
|
181
203
|
- id: requirement-unrealized
|
|
182
204
|
wave: motivation
|
|
205
|
+
since: "0.3"
|
|
183
206
|
scope: subject
|
|
184
207
|
subjects:
|
|
185
208
|
kinds:
|
|
@@ -198,11 +221,15 @@ questions:
|
|
|
198
221
|
roadmap.
|
|
199
222
|
authority: either
|
|
200
223
|
resolution: >-
|
|
201
|
-
Add realization from the fulfilling service, component, or
|
|
202
|
-
|
|
224
|
+
Add realization from the fulfilling service, component, or
|
|
225
|
+
behavior; to descope instead, retire the requirement (status:
|
|
226
|
+
retired) — retirement preserves the decision on record and closes
|
|
227
|
+
the question (ADR 0064). Delete only when the history itself is
|
|
228
|
+
noise.
|
|
203
229
|
|
|
204
230
|
- id: principle-unapplied
|
|
205
231
|
wave: motivation
|
|
232
|
+
since: "0.3"
|
|
206
233
|
scope: subject
|
|
207
234
|
subjects:
|
|
208
235
|
kinds:
|
|
@@ -225,6 +252,7 @@ questions:
|
|
|
225
252
|
|
|
226
253
|
- id: assessment-unlinked
|
|
227
254
|
wave: motivation
|
|
255
|
+
since: "0.3"
|
|
228
256
|
scope: subject
|
|
229
257
|
subjects:
|
|
230
258
|
kinds:
|
|
@@ -243,6 +271,7 @@ questions:
|
|
|
243
271
|
|
|
244
272
|
- id: motivation-unattested
|
|
245
273
|
wave: motivation
|
|
274
|
+
since: "0.3"
|
|
246
275
|
scope: subject
|
|
247
276
|
subjects:
|
|
248
277
|
kinds:
|
|
@@ -268,6 +297,7 @@ questions:
|
|
|
268
297
|
# ---- business ------------------------------------------------------------
|
|
269
298
|
- id: service-consumer-unknown
|
|
270
299
|
wave: business
|
|
300
|
+
since: "0.1"
|
|
271
301
|
scope: subject
|
|
272
302
|
subjects:
|
|
273
303
|
kinds:
|
|
@@ -291,6 +321,7 @@ questions:
|
|
|
291
321
|
|
|
292
322
|
- id: owner-missing
|
|
293
323
|
wave: business
|
|
324
|
+
since: "0.1"
|
|
294
325
|
scope: subject
|
|
295
326
|
subjects:
|
|
296
327
|
kinds:
|
|
@@ -313,6 +344,7 @@ questions:
|
|
|
313
344
|
|
|
314
345
|
- id: actor-unassigned
|
|
315
346
|
wave: business
|
|
347
|
+
since: "0.1"
|
|
316
348
|
scope: subject
|
|
317
349
|
subjects:
|
|
318
350
|
kinds:
|
|
@@ -335,6 +367,7 @@ questions:
|
|
|
335
367
|
|
|
336
368
|
- id: information-unaccessed
|
|
337
369
|
wave: business
|
|
370
|
+
since: "0.1"
|
|
338
371
|
scope: subject
|
|
339
372
|
subjects:
|
|
340
373
|
kinds:
|
|
@@ -358,6 +391,7 @@ questions:
|
|
|
358
391
|
|
|
359
392
|
- id: no-service-declared
|
|
360
393
|
wave: business
|
|
394
|
+
since: "0.1"
|
|
361
395
|
scope: workspace
|
|
362
396
|
trigger:
|
|
363
397
|
- condition: no-subject-of-kind
|
|
@@ -378,6 +412,7 @@ questions:
|
|
|
378
412
|
|
|
379
413
|
- id: service-realizes-no-motivation
|
|
380
414
|
wave: business
|
|
415
|
+
since: "0.3"
|
|
381
416
|
scope: subject
|
|
382
417
|
subjects:
|
|
383
418
|
kinds:
|
|
@@ -405,6 +440,7 @@ questions:
|
|
|
405
440
|
|
|
406
441
|
- id: process-untriggered
|
|
407
442
|
wave: business
|
|
443
|
+
since: "0.3"
|
|
408
444
|
scope: subject
|
|
409
445
|
subjects:
|
|
410
446
|
kinds:
|
|
@@ -427,6 +463,7 @@ questions:
|
|
|
427
463
|
|
|
428
464
|
- id: business-service-unrealized
|
|
429
465
|
wave: business
|
|
466
|
+
since: "0.3"
|
|
430
467
|
scope: subject
|
|
431
468
|
subjects:
|
|
432
469
|
kinds:
|
|
@@ -460,6 +497,7 @@ questions:
|
|
|
460
497
|
# ---- application ---------------------------------------------------------
|
|
461
498
|
- id: app-service-unrealized
|
|
462
499
|
wave: application
|
|
500
|
+
since: "0.3"
|
|
463
501
|
scope: subject
|
|
464
502
|
subjects:
|
|
465
503
|
kinds:
|
|
@@ -490,6 +528,7 @@ questions:
|
|
|
490
528
|
|
|
491
529
|
- id: component-realizes-nothing
|
|
492
530
|
wave: application
|
|
531
|
+
since: "0.3"
|
|
493
532
|
scope: subject
|
|
494
533
|
subjects:
|
|
495
534
|
kinds:
|
|
@@ -515,6 +554,7 @@ questions:
|
|
|
515
554
|
|
|
516
555
|
- id: behavior-unassigned
|
|
517
556
|
wave: application
|
|
557
|
+
since: "0.3"
|
|
518
558
|
scope: subject
|
|
519
559
|
subjects:
|
|
520
560
|
kinds:
|
|
@@ -546,6 +586,7 @@ questions:
|
|
|
546
586
|
|
|
547
587
|
- id: event-triggers-nothing
|
|
548
588
|
wave: application
|
|
589
|
+
since: "0.3"
|
|
549
590
|
scope: subject
|
|
550
591
|
subjects:
|
|
551
592
|
kinds:
|
|
@@ -568,6 +609,7 @@ questions:
|
|
|
568
609
|
|
|
569
610
|
- id: information-unowned
|
|
570
611
|
wave: application
|
|
612
|
+
since: "0.3"
|
|
571
613
|
scope: subject
|
|
572
614
|
subjects:
|
|
573
615
|
kinds:
|
|
@@ -589,6 +631,7 @@ questions:
|
|
|
589
631
|
|
|
590
632
|
- id: planned-design-unattested
|
|
591
633
|
wave: application
|
|
634
|
+
since: "0.3"
|
|
592
635
|
scope: subject
|
|
593
636
|
subjects:
|
|
594
637
|
kinds:
|
|
@@ -612,9 +655,246 @@ questions:
|
|
|
612
655
|
topic "design-review" (revoke by deleting it when the design
|
|
613
656
|
changes).
|
|
614
657
|
|
|
658
|
+
# ---- technology ----------------------------------------------------------
|
|
659
|
+
- id: component-unhosted
|
|
660
|
+
wave: technology
|
|
661
|
+
since: "0.4"
|
|
662
|
+
scope: subject
|
|
663
|
+
subjects:
|
|
664
|
+
kinds:
|
|
665
|
+
- yarramate/core@0.1#applicationComponent
|
|
666
|
+
kindMatching: exact
|
|
667
|
+
statuses:
|
|
668
|
+
- planned
|
|
669
|
+
- current
|
|
670
|
+
trigger:
|
|
671
|
+
- condition: missing-linkage
|
|
672
|
+
kinds:
|
|
673
|
+
- yarramate/core@0.1#serving
|
|
674
|
+
- yarramate/core@0.1#assignment
|
|
675
|
+
direction: incoming
|
|
676
|
+
counterpartKinds:
|
|
677
|
+
- yarramate/core@0.1#node
|
|
678
|
+
- yarramate/core@0.1#device
|
|
679
|
+
- yarramate/core@0.1#systemSoftware
|
|
680
|
+
- yarramate/core@0.1#technologyService
|
|
681
|
+
question: >-
|
|
682
|
+
Where does {subject.name} run?
|
|
683
|
+
materiality: >-
|
|
684
|
+
The hosting boundary decides latency, failure domain, scaling
|
|
685
|
+
model, and data residency; a component with no declared runtime is
|
|
686
|
+
deployed by whoever gets there first. Matching is exact by intent:
|
|
687
|
+
profile-derived module kinds inherit their deployable parent's
|
|
688
|
+
hosting rather than answering separately.
|
|
689
|
+
authority: either
|
|
690
|
+
resolution: >-
|
|
691
|
+
Add the node, device, or system software that hosts it with a
|
|
692
|
+
serving or assignment relationship into the component.
|
|
693
|
+
|
|
694
|
+
- id: node-serves-nothing
|
|
695
|
+
wave: technology
|
|
696
|
+
since: "0.4"
|
|
697
|
+
scope: subject
|
|
698
|
+
subjects:
|
|
699
|
+
kinds:
|
|
700
|
+
- yarramate/core@0.1#node
|
|
701
|
+
- yarramate/core@0.1#device
|
|
702
|
+
- yarramate/core@0.1#systemSoftware
|
|
703
|
+
trigger:
|
|
704
|
+
- condition: missing-relationship
|
|
705
|
+
kinds:
|
|
706
|
+
- yarramate/core@0.1#serving
|
|
707
|
+
- yarramate/core@0.1#assignment
|
|
708
|
+
direction: outgoing
|
|
709
|
+
question: >-
|
|
710
|
+
What does {subject.name} host or serve?
|
|
711
|
+
materiality: >-
|
|
712
|
+
Declared infrastructure that serves nothing is either cost without
|
|
713
|
+
purpose or missing the links that justify it; both change the
|
|
714
|
+
deployment budget.
|
|
715
|
+
authority: either
|
|
716
|
+
resolution: >-
|
|
717
|
+
Add serving or assignment relationships to the applications and
|
|
718
|
+
behavior it hosts, or remove it.
|
|
719
|
+
|
|
720
|
+
- id: technology-service-unrealized
|
|
721
|
+
wave: technology
|
|
722
|
+
since: "0.4"
|
|
723
|
+
scope: subject
|
|
724
|
+
subjects:
|
|
725
|
+
kinds:
|
|
726
|
+
- yarramate/core@0.1#technologyService
|
|
727
|
+
statuses:
|
|
728
|
+
- planned
|
|
729
|
+
- current
|
|
730
|
+
trigger:
|
|
731
|
+
- condition: missing-linkage
|
|
732
|
+
kinds:
|
|
733
|
+
- yarramate/core@0.1#realization
|
|
734
|
+
direction: incoming
|
|
735
|
+
counterpartKinds:
|
|
736
|
+
- yarramate/core@0.1#node
|
|
737
|
+
- yarramate/core@0.1#systemSoftware
|
|
738
|
+
- yarramate/core@0.1#technologyFunction
|
|
739
|
+
- yarramate/core@0.1#technologyProcess
|
|
740
|
+
question: >-
|
|
741
|
+
What provides {subject.name}?
|
|
742
|
+
materiality: >-
|
|
743
|
+
A technology service with no realizing node or behavior is a
|
|
744
|
+
dependency assumed rather than provided; outages and upgrades have
|
|
745
|
+
no owner in the model.
|
|
746
|
+
authority: either
|
|
747
|
+
resolution: >-
|
|
748
|
+
Add realization from the node, system software, or technology
|
|
749
|
+
behavior that provides the service.
|
|
750
|
+
|
|
751
|
+
- id: artifact-unassigned
|
|
752
|
+
wave: technology
|
|
753
|
+
since: "0.4"
|
|
754
|
+
scope: subject
|
|
755
|
+
subjects:
|
|
756
|
+
kinds:
|
|
757
|
+
- yarramate/core@0.1#artifact
|
|
758
|
+
kindMatching: exact
|
|
759
|
+
trigger:
|
|
760
|
+
- condition: missing-relationship
|
|
761
|
+
kinds:
|
|
762
|
+
- yarramate/core@0.1#assignment
|
|
763
|
+
- yarramate/core@0.1#realization
|
|
764
|
+
direction: any
|
|
765
|
+
question: >-
|
|
766
|
+
What deploys {subject.name}, and what does it materialize?
|
|
767
|
+
materiality: >-
|
|
768
|
+
An artifact with no deployment target and nothing it realizes is a
|
|
769
|
+
build output the architecture cannot place; release engineering
|
|
770
|
+
starts from exactly these links.
|
|
771
|
+
authority: either
|
|
772
|
+
resolution: >-
|
|
773
|
+
Assign the artifact to the node that deploys it and add realization
|
|
774
|
+
to the component or data it materializes.
|
|
775
|
+
|
|
776
|
+
# ---- implementation ------------------------------------------------------
|
|
777
|
+
- id: workpackage-delivers-nothing
|
|
778
|
+
wave: implementation
|
|
779
|
+
since: "0.4"
|
|
780
|
+
scope: subject
|
|
781
|
+
subjects:
|
|
782
|
+
kinds:
|
|
783
|
+
- yarramate/core@0.1#workPackage
|
|
784
|
+
trigger:
|
|
785
|
+
- condition: missing-relationship
|
|
786
|
+
kinds:
|
|
787
|
+
- yarramate/core@0.1#realization
|
|
788
|
+
- yarramate/core@0.1#aggregation
|
|
789
|
+
direction: outgoing
|
|
790
|
+
question: >-
|
|
791
|
+
What does {subject.name} produce?
|
|
792
|
+
materiality: >-
|
|
793
|
+
Work with no deliverable cannot be accepted or declared done; the
|
|
794
|
+
deliverable link is what makes progress reviewable rather than
|
|
795
|
+
reported.
|
|
796
|
+
authority: either
|
|
797
|
+
resolution: >-
|
|
798
|
+
Add realization from the work package to its deliverables.
|
|
799
|
+
|
|
800
|
+
- id: workpackage-unassigned
|
|
801
|
+
wave: implementation
|
|
802
|
+
since: "0.4"
|
|
803
|
+
scope: subject
|
|
804
|
+
subjects:
|
|
805
|
+
kinds:
|
|
806
|
+
- yarramate/core@0.1#workPackage
|
|
807
|
+
trigger:
|
|
808
|
+
- condition: missing-linkage
|
|
809
|
+
kinds:
|
|
810
|
+
- yarramate/core@0.1#assignment
|
|
811
|
+
direction: incoming
|
|
812
|
+
counterpartKinds:
|
|
813
|
+
- yarramate/core@0.1#businessActor
|
|
814
|
+
- yarramate/core@0.1#businessRole
|
|
815
|
+
question: >-
|
|
816
|
+
Who is committed to {subject.name}?
|
|
817
|
+
materiality: >-
|
|
818
|
+
An unassigned work package is a plan without capacity; commitment
|
|
819
|
+
is the difference between a roadmap and a wish list.
|
|
820
|
+
authority: human
|
|
821
|
+
resolution: >-
|
|
822
|
+
Add assignment from the actor or role that owns the work.
|
|
823
|
+
|
|
824
|
+
- id: deliverable-realizes-nothing
|
|
825
|
+
wave: implementation
|
|
826
|
+
since: "0.4"
|
|
827
|
+
scope: subject
|
|
828
|
+
subjects:
|
|
829
|
+
kinds:
|
|
830
|
+
- yarramate/core@0.1#deliverable
|
|
831
|
+
kindMatching: exact
|
|
832
|
+
trigger:
|
|
833
|
+
- condition: missing-relationship
|
|
834
|
+
kinds:
|
|
835
|
+
- yarramate/core@0.1#realization
|
|
836
|
+
direction: outgoing
|
|
837
|
+
question: >-
|
|
838
|
+
What does {subject.name} make real?
|
|
839
|
+
materiality: >-
|
|
840
|
+
A deliverable that realizes no architecture element is effort
|
|
841
|
+
disconnected from the design; its acceptance criteria cannot be
|
|
842
|
+
stated architecturally.
|
|
843
|
+
authority: either
|
|
844
|
+
resolution: >-
|
|
845
|
+
Add realization from the deliverable to the plateau, requirement,
|
|
846
|
+
or element it brings into being.
|
|
847
|
+
|
|
848
|
+
- id: plateau-aggregates-nothing
|
|
849
|
+
wave: implementation
|
|
850
|
+
since: "0.4"
|
|
851
|
+
scope: subject
|
|
852
|
+
subjects:
|
|
853
|
+
kinds:
|
|
854
|
+
- yarramate/core@0.1#plateau
|
|
855
|
+
trigger:
|
|
856
|
+
- condition: missing-relationship
|
|
857
|
+
kinds:
|
|
858
|
+
- yarramate/core@0.1#aggregation
|
|
859
|
+
- yarramate/core@0.1#composition
|
|
860
|
+
direction: outgoing
|
|
861
|
+
question: >-
|
|
862
|
+
Which architecture does {subject.name} stabilize?
|
|
863
|
+
materiality: >-
|
|
864
|
+
A plateau that aggregates nothing describes no state anyone can
|
|
865
|
+
stand on; migration planning needs to know what is stable when.
|
|
866
|
+
authority: either
|
|
867
|
+
resolution: >-
|
|
868
|
+
Aggregate the elements that are current during this plateau, or use
|
|
869
|
+
architecture states instead and remove it.
|
|
870
|
+
|
|
871
|
+
- id: gap-unaddressed
|
|
872
|
+
wave: implementation
|
|
873
|
+
since: "0.4"
|
|
874
|
+
scope: subject
|
|
875
|
+
subjects:
|
|
876
|
+
kinds:
|
|
877
|
+
- yarramate/core@0.1#gap
|
|
878
|
+
trigger:
|
|
879
|
+
- condition: missing-relationship
|
|
880
|
+
kinds:
|
|
881
|
+
- yarramate/core@0.1#association
|
|
882
|
+
- yarramate/core@0.1#realization
|
|
883
|
+
direction: any
|
|
884
|
+
question: >-
|
|
885
|
+
What closes {subject.name}?
|
|
886
|
+
materiality: >-
|
|
887
|
+
A named gap nothing addresses is a known risk with no plan; either
|
|
888
|
+
work closes it or the acceptance of it should be on record.
|
|
889
|
+
authority: human
|
|
890
|
+
resolution: >-
|
|
891
|
+
Associate the gap with the plateaus it separates and the
|
|
892
|
+
deliverable that closes it, or record the decision to accept it.
|
|
893
|
+
|
|
615
894
|
# ---- hygiene -------------------------------------------------------------
|
|
616
895
|
- id: concept-isolated
|
|
617
896
|
wave: hygiene
|
|
897
|
+
since: "0.1"
|
|
618
898
|
scope: subject
|
|
619
899
|
subjects:
|
|
620
900
|
kinds:
|
|
@@ -640,6 +920,7 @@ questions:
|
|
|
640
920
|
|
|
641
921
|
- id: concept-undescribed
|
|
642
922
|
wave: hygiene
|
|
923
|
+
since: "0.1"
|
|
643
924
|
scope: subject
|
|
644
925
|
subjects:
|
|
645
926
|
kinds:
|
|
@@ -663,6 +944,7 @@ questions:
|
|
|
663
944
|
|
|
664
945
|
- id: status-missing
|
|
665
946
|
wave: hygiene
|
|
947
|
+
since: "0.1"
|
|
666
948
|
scope: subject
|
|
667
949
|
subjects:
|
|
668
950
|
kinds:
|
|
@@ -685,6 +967,7 @@ questions:
|
|
|
685
967
|
|
|
686
968
|
- id: states-undefined
|
|
687
969
|
wave: hygiene
|
|
970
|
+
since: "0.1"
|
|
688
971
|
scope: workspace
|
|
689
972
|
trigger:
|
|
690
973
|
- condition: no-state-defined
|
package/dist/apply-command.js
CHANGED
|
@@ -123,7 +123,24 @@ const itemMap = (source, collection, id) => {
|
|
|
123
123
|
};
|
|
124
124
|
// The indent item fields sit at, read off the item's own first field.
|
|
125
125
|
const fieldIndentOf = (source, map) => indentAt(source, nodeRange(map.items[0].key)[0]);
|
|
126
|
+
// A flow-style item (`- { id: x, ... }`) cannot take block field lines;
|
|
127
|
+
// splicing them after it corrupts the sequence (Codex dogfood finding,
|
|
128
|
+
// 2026-08-01). The whole item is rewritten as a block mapping with the
|
|
129
|
+
// mutation applied — churn confined to the item being edited.
|
|
130
|
+
const rewriteFlowItem = (source, map, mutate) => {
|
|
131
|
+
const mutated = mutate(map.toJSON());
|
|
132
|
+
const [start, valueEnd] = nodeRange(map);
|
|
133
|
+
const fieldIndent = indentAt(source, start);
|
|
134
|
+
const rendered = reindent(stringify(mutated, { lineWidth: 0 }).trimEnd(), fieldIndent);
|
|
135
|
+
return splice(source, start, valueEnd, rendered);
|
|
136
|
+
};
|
|
126
137
|
const setScalarField = (source, map, key, value) => {
|
|
138
|
+
if (map.flow) {
|
|
139
|
+
return rewriteFlowItem(source, map, (fields) => ({
|
|
140
|
+
...fields,
|
|
141
|
+
[key]: value,
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
127
144
|
const indent = fieldIndentOf(source, map);
|
|
128
145
|
const rendered = reindent(valueText(value), indent + 2);
|
|
129
146
|
const pair = pairFor(map, key);
|
|
@@ -134,6 +151,15 @@ const setScalarField = (source, map, key, value) => {
|
|
|
134
151
|
return splice(source, start, valueEnd, rendered);
|
|
135
152
|
};
|
|
136
153
|
const appendListField = (source, map, key, additions) => {
|
|
154
|
+
if (map.flow) {
|
|
155
|
+
return rewriteFlowItem(source, map, (fields) => ({
|
|
156
|
+
...fields,
|
|
157
|
+
[key]: [
|
|
158
|
+
...(fields[key] ?? []),
|
|
159
|
+
...additions,
|
|
160
|
+
],
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
137
163
|
const indent = fieldIndentOf(source, map);
|
|
138
164
|
const pair = pairFor(map, key);
|
|
139
165
|
if (pair === undefined) {
|
|
@@ -163,11 +189,19 @@ const appendListField = (source, map, key, additions) => {
|
|
|
163
189
|
return splice(source, start, valueEnd, `\n${sequenceEntries(merged, indent + 2)}`);
|
|
164
190
|
};
|
|
165
191
|
// Retraction (#115): delete the field's whole entry, from the start of its
|
|
166
|
-
// key line through the end of its value's last line.
|
|
192
|
+
// key line through the end of its value's last line. A flow item is
|
|
193
|
+
// rewritten instead — line-based deletion there would take the whole item
|
|
194
|
+
// with it.
|
|
167
195
|
const removeField = (source, map, key) => {
|
|
168
196
|
const pair = pairFor(map, key);
|
|
169
197
|
if (pair === undefined)
|
|
170
198
|
return undefined;
|
|
199
|
+
if (map.flow) {
|
|
200
|
+
return rewriteFlowItem(source, map, (fields) => {
|
|
201
|
+
const { [key]: _removed, ...rest } = fields;
|
|
202
|
+
return rest;
|
|
203
|
+
});
|
|
204
|
+
}
|
|
171
205
|
const start = lineStartOf(source, nodeRange(pair.key)[0]);
|
|
172
206
|
const valueEnd = pair.value === null || pair.value === undefined
|
|
173
207
|
? nodeRange(pair.key)[2]
|
package/dist/design-command.js
CHANGED
|
@@ -33,6 +33,7 @@ const selectStep = (report, subjectFilter) => {
|
|
|
33
33
|
question: question.question,
|
|
34
34
|
materiality: question.materiality,
|
|
35
35
|
resolution: question.resolution,
|
|
36
|
+
...(question.since === undefined ? {} : { since: question.since }),
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
const subjects = subjectFilter === undefined
|
|
@@ -49,6 +50,7 @@ const selectStep = (report, subjectFilter) => {
|
|
|
49
50
|
question: first.question,
|
|
50
51
|
materiality: question.materiality,
|
|
51
52
|
resolution: question.resolution,
|
|
53
|
+
...(question.since === undefined ? {} : { since: question.since }),
|
|
52
54
|
subject: {
|
|
53
55
|
id: first.id,
|
|
54
56
|
...(first.name === undefined ? {} : { name: first.name }),
|
|
@@ -44,6 +44,7 @@ export interface CatalogueQuestion {
|
|
|
44
44
|
readonly materiality: string;
|
|
45
45
|
readonly resolution: string;
|
|
46
46
|
readonly authority: 'human' | 'agent' | 'either';
|
|
47
|
+
readonly since?: string;
|
|
47
48
|
}
|
|
48
49
|
export interface QuestionCatalogue {
|
|
49
50
|
readonly format: 'yarramate/question-catalogue/v1';
|
|
@@ -74,6 +75,7 @@ interface ReportQuestion {
|
|
|
74
75
|
readonly question: string;
|
|
75
76
|
readonly materiality: string;
|
|
76
77
|
readonly resolution: string;
|
|
78
|
+
readonly since?: string;
|
|
77
79
|
readonly subjects?: readonly OpenSubject[];
|
|
78
80
|
}
|
|
79
81
|
export interface InterrogationReport {
|
|
@@ -12,12 +12,6 @@ const indexGraph = (graph) => {
|
|
|
12
12
|
const stateSubjects = new Set(graph.claims
|
|
13
13
|
.filter(({ predicate }) => predicate === 'yarramate/state/type')
|
|
14
14
|
.map(({ subject }) => subject));
|
|
15
|
-
// Architecture states carry concept subjects in the graph but are not
|
|
16
|
-
// enrichment targets; the catalogue interrogates the model, not the
|
|
17
|
-
// planning overlay.
|
|
18
|
-
const concepts = new Set(graph.subjects
|
|
19
|
-
.filter(({ id, type }) => type === 'concept' && !stateSubjects.has(id))
|
|
20
|
-
.map(({ id }) => id));
|
|
21
15
|
const claimsBySubject = new Map();
|
|
22
16
|
const kindOf = new Map();
|
|
23
17
|
const nameOf = new Map();
|
|
@@ -50,6 +44,16 @@ const indexGraph = (graph) => {
|
|
|
50
44
|
}
|
|
51
45
|
}
|
|
52
46
|
}
|
|
47
|
+
// Architecture states carry concept subjects in the graph but are not
|
|
48
|
+
// enrichment targets; the catalogue interrogates the model, not the
|
|
49
|
+
// planning overlay. Retired concepts are excluded for the same reason
|
|
50
|
+
// (ADR 0064): retirement is the recorded decision that a subject left
|
|
51
|
+
// the design conversation, so no question stays open against it.
|
|
52
|
+
const concepts = new Set(graph.subjects
|
|
53
|
+
.filter(({ id, type }) => type === 'concept' &&
|
|
54
|
+
!stateSubjects.has(id) &&
|
|
55
|
+
statusOf.get(id) !== 'retired')
|
|
56
|
+
.map(({ id }) => id));
|
|
53
57
|
return {
|
|
54
58
|
concepts,
|
|
55
59
|
claimsBySubject,
|
|
@@ -175,6 +179,7 @@ export function evaluateCatalogue(catalogue, graph, profileContext) {
|
|
|
175
179
|
question: question.question.trim(),
|
|
176
180
|
materiality: question.materiality.trim(),
|
|
177
181
|
resolution: question.resolution.trim(),
|
|
182
|
+
...(question.since === undefined ? {} : { since: question.since }),
|
|
178
183
|
};
|
|
179
184
|
if (question.scope === 'workspace') {
|
|
180
185
|
const isOpen = question.trigger.every((condition) => conditionHolds(index, condition, undefined, profileContext));
|
|
@@ -253,12 +258,13 @@ export function renderInterrogationReport(report) {
|
|
|
253
258
|
lines.push(` closed ${question.id}`);
|
|
254
259
|
continue;
|
|
255
260
|
}
|
|
261
|
+
const sinceMarker = question.since === undefined ? '' : ` [since ${question.since}]`;
|
|
256
262
|
if (question.subjects === undefined) {
|
|
257
|
-
lines.push(` OPEN ${question.id} — ${question.question}`);
|
|
263
|
+
lines.push(` OPEN ${question.id}${sinceMarker} — ${question.question}`);
|
|
258
264
|
lines.push(` why: ${question.materiality}`);
|
|
259
265
|
continue;
|
|
260
266
|
}
|
|
261
|
-
lines.push(` OPEN ${question.id} (${question.subjects.length} ${question.subjects.length === 1 ? 'subject' : 'subjects'})`);
|
|
267
|
+
lines.push(` OPEN ${question.id}${sinceMarker} (${question.subjects.length} ${question.subjects.length === 1 ? 'subject' : 'subjects'})`);
|
|
262
268
|
for (const subject of question.subjects) {
|
|
263
269
|
lines.push(` ask: "${subject.question}" [authority: ${question.authority}]`);
|
|
264
270
|
}
|
package/package.json
CHANGED
|
@@ -392,6 +392,11 @@
|
|
|
392
392
|
"resolution": {
|
|
393
393
|
"description": "Guidance for how an accepted answer should land as native authoring (which claim, relationship, or state to add).",
|
|
394
394
|
"$ref": "#/$defs/nonEmptyText"
|
|
395
|
+
},
|
|
396
|
+
"since": {
|
|
397
|
+
"description": "The catalogue version this question first appeared in. Lets consumers distinguish 'the catalogue deepened' from 'the model regressed' when a completed interview reopens (ADR 0063).",
|
|
398
|
+
"type": "string",
|
|
399
|
+
"pattern": "^[0-9]+\\.[0-9]+$"
|
|
395
400
|
}
|
|
396
401
|
},
|
|
397
402
|
"allOf": [
|