yarramate 1.9.0 → 1.10.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.
@@ -178,6 +178,16 @@ export interface ReportQuestion {
178
178
  readonly scope: 'workspace' | 'subject';
179
179
  readonly authority: 'human' | 'agent' | 'either';
180
180
  readonly open: boolean;
181
+ /**
182
+ * Whether the question was asked at all (#375, ADR 0132). Absent means
183
+ * true; only a subject-scoped question whose selector matched NO subject
184
+ * carries `asked: false`. Without it, never-asked and answered were
185
+ * byte-identical (`open: false`), and a host summing closed questions
186
+ * read an empty model as a satisfied interview — completion inferred
187
+ * from an empty set, the exact reading ADR 0125 refuses one level up by
188
+ * not evaluating a closed wave's questions at all.
189
+ */
190
+ readonly asked?: boolean;
181
191
  readonly question: string;
182
192
  readonly materiality: string;
183
193
  readonly resolution: string;
@@ -517,7 +517,16 @@ patternMemberships) {
517
517
  }
518
518
  return { ...base, open: isOpen };
519
519
  }
520
- const matches = selectSubjects(index, question.subjects, profileContext).filter((id) => question.trigger.every((condition) => conditionHolds(index, condition, id, profileContext, evidence, patternMemberships)));
520
+ // Selection and trigger filtering are separate reads on purpose
521
+ // (#375, ADR 0132): a selector matching nobody means the question
522
+ // was never asked, and reporting that as a closed question said it
523
+ // had been asked and answered — completion inferred from an empty
524
+ // set, the reading ADR 0125 refuses one level up.
525
+ const selected = selectSubjects(index, question.subjects, profileContext);
526
+ if (selected.length === 0) {
527
+ return { ...base, open: false, asked: false };
528
+ }
529
+ const matches = selected.filter((id) => question.trigger.every((condition) => conditionHolds(index, condition, id, profileContext, evidence, patternMemberships)));
521
530
  if (matches.length === 0) {
522
531
  return { ...base, open: false };
523
532
  }
@@ -859,6 +868,13 @@ export function renderInterrogationReport(report) {
859
868
  continue;
860
869
  }
861
870
  for (const question of wave.questions) {
871
+ if (question.asked === false) {
872
+ // Never asked is not closed (#375): `closed` says answered, and a
873
+ // selector that matched nobody asked nothing — the question-level
874
+ // twin of the wave's own "not yet" line above.
875
+ lines.push(` unasked ${question.id} — nothing it selects exists yet`);
876
+ continue;
877
+ }
862
878
  if (!question.open) {
863
879
  lines.push(` closed ${question.id}`);
864
880
  continue;
@@ -92499,14 +92499,20 @@ function rce(e, t, n, r, i, a) {
92499
92499
  open: i
92500
92500
  };
92501
92501
  }
92502
- let i = Fw(o, e.subjects, n).filter((t) => e.trigger.every((e) => Bw(o, e, t, n, r, a)));
92503
- return i.length === 0 ? {
92502
+ let i = Fw(o, e.subjects, n);
92503
+ if (i.length === 0) return {
92504
+ ...t,
92505
+ open: !1,
92506
+ asked: !1
92507
+ };
92508
+ let l = i.filter((t) => e.trigger.every((e) => Bw(o, e, t, n, r, a)));
92509
+ return l.length === 0 ? {
92504
92510
  ...t,
92505
92511
  open: !1
92506
- } : (s += i.length, c += 1, {
92512
+ } : (s += l.length, c += 1, {
92507
92513
  ...t,
92508
92514
  open: !0,
92509
- subjects: i.map((t) => {
92515
+ subjects: l.map((t) => {
92510
92516
  let n = o.nameOf.get(t);
92511
92517
  return {
92512
92518
  id: t,
@@ -178,6 +178,16 @@ export interface ReportQuestion {
178
178
  readonly scope: 'workspace' | 'subject';
179
179
  readonly authority: 'human' | 'agent' | 'either';
180
180
  readonly open: boolean;
181
+ /**
182
+ * Whether the question was asked at all (#375, ADR 0132). Absent means
183
+ * true; only a subject-scoped question whose selector matched NO subject
184
+ * carries `asked: false`. Without it, never-asked and answered were
185
+ * byte-identical (`open: false`), and a host summing closed questions
186
+ * read an empty model as a satisfied interview — completion inferred
187
+ * from an empty set, the exact reading ADR 0125 refuses one level up by
188
+ * not evaluating a closed wave's questions at all.
189
+ */
190
+ readonly asked?: boolean;
181
191
  readonly question: string;
182
192
  readonly materiality: string;
183
193
  readonly resolution: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yarramate",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Tool-neutral semantic architecture engine and guided methodology",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -133,6 +133,10 @@
133
133
  "open": {
134
134
  "type": "boolean"
135
135
  },
136
+ "asked": {
137
+ "type": "boolean",
138
+ "description": "Whether the question was asked at all (#375, ADR 0132). Absent means true; only a subject-scoped question whose selector matched no subject carries asked: false. Without it, never-asked and answered were byte-identical (open: false), and a host summing closed questions read an empty model as a satisfied interview."
139
+ },
136
140
  "question": {
137
141
  "type": "string",
138
142
  "minLength": 1