plan-verify 0.0.0-stage → 0.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.
Files changed (222) hide show
  1. package/.github/workflows/ci.yml +48 -0
  2. package/README.md +1431 -2
  3. package/assets/icon.png +0 -0
  4. package/assets/logo-mark.png +0 -0
  5. package/assets/logo.png +0 -0
  6. package/examples/checkout.ears.md +74 -0
  7. package/examples/order-always.ears.md +3 -0
  8. package/examples/order-awkward.ears.md +8 -0
  9. package/examples/order-bad.json +1 -0
  10. package/examples/order-chain.ears.md +9 -0
  11. package/examples/order-chosen.ears.md +7 -0
  12. package/examples/order-clear.ears.md +8 -0
  13. package/examples/order-combined.ears.md +10 -0
  14. package/examples/order-conflict.ears.md +8 -0
  15. package/examples/order-covered.ears.md +9 -0
  16. package/examples/order-duplicate.ears.md +8 -0
  17. package/examples/order-fail.json +5 -0
  18. package/examples/order-misuse.ears.md +7 -0
  19. package/examples/order-negation.ears.md +7 -0
  20. package/examples/order-pass.json +5 -0
  21. package/examples/order-quantity.ears.md +8 -0
  22. package/examples/order-redundant.ears.md +9 -0
  23. package/examples/order-repair.ears.md +9 -0
  24. package/examples/order-repeat.ears.md +13 -0
  25. package/examples/order-same.ears.md +3 -0
  26. package/examples/order-status.ears.md +7 -0
  27. package/examples/order-unanswered.ears.md +8 -0
  28. package/examples/order-unhandled.ears.md +8 -0
  29. package/examples/order-unmeasured.ears.md +10 -0
  30. package/examples/order-unused.ears.md +13 -0
  31. package/examples/order-vacuous.ears.md +9 -0
  32. package/examples/order-vague.ears.md +7 -0
  33. package/examples/order-wide.ears.md +5 -0
  34. package/examples/order-wording.ears.md +8 -0
  35. package/examples/order.ears.md +7 -0
  36. package/examples/payment-if.ears.md +7 -0
  37. package/examples/plan-to-problems/README.md +54 -0
  38. package/examples/plan-to-problems/expected-problems.md +25 -0
  39. package/examples/plan-to-problems/generate.mjs +186 -0
  40. package/examples/plan-to-problems/generated.ears.md +27 -0
  41. package/examples/plan-to-problems/lint.json +576 -0
  42. package/examples/plan-to-problems/plan.md +5 -0
  43. package/examples/plan-to-problems/planted.txt +5 -0
  44. package/examples/plan-to-problems/problems.md +112 -0
  45. package/examples/status-placed.ears.md +3 -0
  46. package/package.json +25 -4
  47. package/scripts/install-scriptc.sh +16 -0
  48. package/skills/plan-verify/SKILL.md +1515 -0
  49. package/src/check.ts +250 -0
  50. package/src/decide.ts +1324 -0
  51. package/src/ears.ts +1520 -0
  52. package/src/jsonvalue.ts +228 -0
  53. package/src/lint.ts +1245 -0
  54. package/src/main.ts +273 -0
  55. package/src/policy.ts +148 -0
  56. package/src/repair.ts +567 -0
  57. package/src/report.ts +329 -0
  58. package/src/scenarios.ts +149 -0
  59. package/src/smt.ts +97 -0
  60. package/src/solver.ts +868 -0
  61. package/src/spec.ts +307 -0
  62. package/src/term.ts +331 -0
  63. package/src/text.ts +95 -0
  64. package/test/fixtures/malformed.ears.md +3 -0
  65. package/test/fixtures/unknown-phrase.ears.md +5 -0
  66. package/test/golden/check-fail-json.exit +1 -0
  67. package/test/golden/check-fail-json.stderr +0 -0
  68. package/test/golden/check-fail-json.stdout +13 -0
  69. package/test/golden/check-fail.exit +1 -0
  70. package/test/golden/check-fail.stderr +0 -0
  71. package/test/golden/check-fail.stdout +7 -0
  72. package/test/golden/check-pass-json.exit +1 -0
  73. package/test/golden/check-pass-json.stderr +0 -0
  74. package/test/golden/check-pass-json.stdout +6 -0
  75. package/test/golden/check-pass.exit +1 -0
  76. package/test/golden/check-pass.stderr +0 -0
  77. package/test/golden/check-pass.stdout +3 -0
  78. package/test/golden/emit-smt-json-usage.exit +1 -0
  79. package/test/golden/emit-smt-json-usage.stderr +0 -0
  80. package/test/golden/emit-smt-json-usage.stdout +4 -0
  81. package/test/golden/emit-smt-json.exit +1 -0
  82. package/test/golden/emit-smt-json.stderr +0 -0
  83. package/test/golden/emit-smt-json.stdout +5 -0
  84. package/test/golden/emit-smt.exit +1 -0
  85. package/test/golden/emit-smt.stderr +0 -0
  86. package/test/golden/emit-smt.stdout +10 -0
  87. package/test/golden/help.exit +1 -0
  88. package/test/golden/help.stderr +0 -0
  89. package/test/golden/help.stdout +8 -0
  90. package/test/golden/lint-awkward.exit +1 -0
  91. package/test/golden/lint-awkward.stderr +0 -0
  92. package/test/golden/lint-awkward.stdout +29 -0
  93. package/test/golden/lint-chain.exit +1 -0
  94. package/test/golden/lint-chain.stderr +0 -0
  95. package/test/golden/lint-chain.stdout +56 -0
  96. package/test/golden/lint-checkout.exit +1 -0
  97. package/test/golden/lint-checkout.stderr +0 -0
  98. package/test/golden/lint-checkout.stdout +301 -0
  99. package/test/golden/lint-clean.exit +1 -0
  100. package/test/golden/lint-clean.stderr +0 -0
  101. package/test/golden/lint-clean.stdout +9 -0
  102. package/test/golden/lint-clear.exit +1 -0
  103. package/test/golden/lint-clear.stderr +0 -0
  104. package/test/golden/lint-clear.stdout +9 -0
  105. package/test/golden/lint-conflict-json.exit +1 -0
  106. package/test/golden/lint-conflict-json.stderr +0 -0
  107. package/test/golden/lint-conflict-json.stdout +80 -0
  108. package/test/golden/lint-conflict.exit +1 -0
  109. package/test/golden/lint-conflict.stderr +0 -0
  110. package/test/golden/lint-conflict.stdout +41 -0
  111. package/test/golden/lint-duplicate.exit +1 -0
  112. package/test/golden/lint-duplicate.stderr +0 -0
  113. package/test/golden/lint-duplicate.stdout +14 -0
  114. package/test/golden/lint-gap.exit +1 -0
  115. package/test/golden/lint-gap.stderr +0 -0
  116. package/test/golden/lint-gap.stdout +12 -0
  117. package/test/golden/lint-misuse.exit +1 -0
  118. package/test/golden/lint-misuse.stderr +0 -0
  119. package/test/golden/lint-misuse.stdout +18 -0
  120. package/test/golden/lint-negation.exit +1 -0
  121. package/test/golden/lint-negation.stderr +0 -0
  122. package/test/golden/lint-negation.stdout +13 -0
  123. package/test/golden/lint-quantity.exit +1 -0
  124. package/test/golden/lint-quantity.stderr +0 -0
  125. package/test/golden/lint-quantity.stdout +41 -0
  126. package/test/golden/lint-redundant.exit +1 -0
  127. package/test/golden/lint-redundant.stderr +0 -0
  128. package/test/golden/lint-redundant.stdout +14 -0
  129. package/test/golden/lint-repair-json.exit +1 -0
  130. package/test/golden/lint-repair-json.stderr +0 -0
  131. package/test/golden/lint-repair-json.stdout +127 -0
  132. package/test/golden/lint-repair.exit +1 -0
  133. package/test/golden/lint-repair.stderr +0 -0
  134. package/test/golden/lint-repair.stdout +54 -0
  135. package/test/golden/lint-repeat.exit +1 -0
  136. package/test/golden/lint-repeat.stderr +0 -0
  137. package/test/golden/lint-repeat.stdout +48 -0
  138. package/test/golden/lint-status.exit +1 -0
  139. package/test/golden/lint-status.stderr +0 -0
  140. package/test/golden/lint-status.stdout +44 -0
  141. package/test/golden/lint-unanswered.exit +1 -0
  142. package/test/golden/lint-unanswered.stderr +0 -0
  143. package/test/golden/lint-unanswered.stdout +12 -0
  144. package/test/golden/lint-unhandled.exit +1 -0
  145. package/test/golden/lint-unhandled.stderr +0 -0
  146. package/test/golden/lint-unhandled.stdout +12 -0
  147. package/test/golden/lint-unmeasured.exit +1 -0
  148. package/test/golden/lint-unmeasured.stderr +0 -0
  149. package/test/golden/lint-unmeasured.stdout +13 -0
  150. package/test/golden/lint-unused-json.exit +1 -0
  151. package/test/golden/lint-unused-json.stderr +0 -0
  152. package/test/golden/lint-unused-json.stdout +37 -0
  153. package/test/golden/lint-unused.exit +1 -0
  154. package/test/golden/lint-unused.stderr +0 -0
  155. package/test/golden/lint-unused.stdout +25 -0
  156. package/test/golden/lint-vacuous-json.exit +1 -0
  157. package/test/golden/lint-vacuous-json.stderr +0 -0
  158. package/test/golden/lint-vacuous-json.stdout +27 -0
  159. package/test/golden/lint-vacuous.exit +1 -0
  160. package/test/golden/lint-vacuous.stderr +0 -0
  161. package/test/golden/lint-vacuous.stdout +19 -0
  162. package/test/golden/lint-vague.exit +1 -0
  163. package/test/golden/lint-vague.stderr +0 -0
  164. package/test/golden/lint-vague.stdout +21 -0
  165. package/test/golden/lint-wide.exit +1 -0
  166. package/test/golden/lint-wide.stderr +0 -0
  167. package/test/golden/lint-wide.stdout +9 -0
  168. package/test/golden/lint-wording.exit +1 -0
  169. package/test/golden/lint-wording.stderr +0 -0
  170. package/test/golden/lint-wording.stdout +21 -0
  171. package/test/golden/malformed-scenario.exit +1 -0
  172. package/test/golden/malformed-scenario.stderr +1 -0
  173. package/test/golden/malformed-scenario.stdout +0 -0
  174. package/test/golden/malformed-spec.exit +1 -0
  175. package/test/golden/malformed-spec.stderr +1 -0
  176. package/test/golden/malformed-spec.stdout +0 -0
  177. package/test/golden/policy-counterexample.exit +1 -0
  178. package/test/golden/policy-counterexample.stderr +0 -0
  179. package/test/golden/policy-counterexample.stdout +13 -0
  180. package/test/golden/policy-covered.exit +1 -0
  181. package/test/golden/policy-covered.stderr +0 -0
  182. package/test/golden/policy-covered.stdout +19 -0
  183. package/test/golden/policy-holds.exit +1 -0
  184. package/test/golden/policy-holds.stderr +0 -0
  185. package/test/golden/policy-holds.stdout +3 -0
  186. package/test/golden/policy-json.exit +1 -0
  187. package/test/golden/policy-json.stderr +0 -0
  188. package/test/golden/policy-json.stdout +34 -0
  189. package/test/golden/policy-status.exit +1 -0
  190. package/test/golden/policy-status.stderr +0 -0
  191. package/test/golden/policy-status.stdout +16 -0
  192. package/test/golden/policy-vacuous.exit +1 -0
  193. package/test/golden/policy-vacuous.stderr +0 -0
  194. package/test/golden/policy-vacuous.stdout +3 -0
  195. package/test/golden/policy-wide.exit +1 -0
  196. package/test/golden/policy-wide.stderr +0 -0
  197. package/test/golden/policy-wide.stdout +15 -0
  198. package/test/golden/policy.exit +1 -0
  199. package/test/golden/policy.stderr +0 -0
  200. package/test/golden/policy.stdout +19 -0
  201. package/test/golden/scenarios-json.exit +1 -0
  202. package/test/golden/scenarios-json.stderr +0 -0
  203. package/test/golden/scenarios-json.stdout +75 -0
  204. package/test/golden/scenarios-status.exit +1 -0
  205. package/test/golden/scenarios-status.stderr +0 -0
  206. package/test/golden/scenarios-status.stdout +24 -0
  207. package/test/golden/scenarios.exit +1 -0
  208. package/test/golden/scenarios.stderr +0 -0
  209. package/test/golden/scenarios.stdout +26 -0
  210. package/test/golden/unit.exit +1 -0
  211. package/test/golden/unit.stderr +0 -0
  212. package/test/golden/unit.stdout +2 -0
  213. package/test/golden/unknown-phrase.exit +1 -0
  214. package/test/golden/unknown-phrase.stderr +1 -0
  215. package/test/golden/unknown-phrase.stdout +0 -0
  216. package/test/golden/usage.exit +1 -0
  217. package/test/golden/usage.stderr +9 -0
  218. package/test/golden/usage.stdout +0 -0
  219. package/test/run-all.ts +499 -0
  220. package/test/soundness.ts +375 -0
  221. package/test/unit.ts +1352 -0
  222. package/tsconfig.json +15 -0
@@ -0,0 +1,9 @@
1
+ spec: examples/order-clear.ears.md
2
+ conflicts: 0
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,80 @@
1
+ {
2
+ "ok": false,
3
+ "spec": "examples/order-conflict.ears.md",
4
+ "conflicts": [
5
+ {
6
+ "ids": [
7
+ "R2",
8
+ "R3"
9
+ ],
10
+ "minimal": true,
11
+ "everySituation": false,
12
+ "summary": "R2 and R3 cannot both hold.",
13
+ "clash": "They clash when an order was submitted.",
14
+ "requirements": [
15
+ {
16
+ "id": "R2",
17
+ "line": 7,
18
+ "sentence": "When an order is submitted, the Order System shall fulfill the order."
19
+ },
20
+ {
21
+ "id": "R3",
22
+ "line": 8,
23
+ "sentence": "When an order is submitted, the Order System shall not fulfill the order."
24
+ }
25
+ ],
26
+ "situation": [
27
+ {
28
+ "name": "order_submitted",
29
+ "value": "true"
30
+ }
31
+ ],
32
+ "requires": [
33
+ {
34
+ "id": "R2",
35
+ "text": "that the order was fulfilled"
36
+ },
37
+ {
38
+ "id": "R3",
39
+ "text": "that the order was not fulfilled"
40
+ }
41
+ ],
42
+ "example": [
43
+ {
44
+ "name": "order_submitted",
45
+ "value": "true"
46
+ },
47
+ {
48
+ "name": "order_fulfilled",
49
+ "value": "true"
50
+ }
51
+ ],
52
+ "keeps": [
53
+ "R2"
54
+ ],
55
+ "breaks": "R3",
56
+ "fix": "Suggested fix: ask which requirement should win. To keep R2, remove R3. To keep R3, remove R2.",
57
+ "repairs": [
58
+ {
59
+ "kind": "drop",
60
+ "id": "R2",
61
+ "text": "One repair is to drop R2 and keep R3 as written.",
62
+ "sentence": "When an order is submitted, the Order System shall not fulfill the order."
63
+ },
64
+ {
65
+ "kind": "drop",
66
+ "id": "R3",
67
+ "text": "One repair is to drop R3 and keep R2 as written.",
68
+ "sentence": "When an order is submitted, the Order System shall fulfill the order."
69
+ }
70
+ ]
71
+ }
72
+ ],
73
+ "gaps": [],
74
+ "misuse": [],
75
+ "wording": [],
76
+ "redundant": [],
77
+ "duplicate": [],
78
+ "vacuous": [],
79
+ "unused": []
80
+ }
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,41 @@
1
+ spec: examples/order-conflict.ears.md
2
+ conflicts: 1
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ conflict {R2, R3}
12
+ R2 and R3 cannot both hold.
13
+
14
+ R2 line 7
15
+ When an order is submitted, the Order System shall fulfill the order.
16
+
17
+ R3 line 8
18
+ When an order is submitted, the Order System shall not fulfill the order.
19
+
20
+ They clash when an order was submitted.
21
+ R2 requires that the order was fulfilled.
22
+ R3 requires that the order was not fulfilled.
23
+
24
+ Example scenario:
25
+ {
26
+ "order_submitted": true,
27
+ "order_fulfilled": true
28
+ }
29
+ This scenario keeps R2 and breaks R3.
30
+
31
+ Suggested fix: ask which requirement should win. To keep R2, remove R3. To keep R3, remove R2.
32
+
33
+ Candidate repairs follow. This report does not choose one.
34
+
35
+ repair drop R2
36
+ One repair is to drop R2 and keep R3 as written.
37
+ When an order is submitted, the Order System shall not fulfill the order.
38
+
39
+ repair drop R3
40
+ One repair is to drop R3 and keep R2 as written.
41
+ When an order is submitted, the Order System shall fulfill the order.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,14 @@
1
+ spec: examples/order-duplicate.ears.md
2
+ conflicts: 0
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 1
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ duplicate R2 line 7
12
+ R2 duplicates R1. The condition and the response are the same.
13
+ When an order is submitted, the Order System shall fulfill the order.
14
+ Suggested fix: remove R2, or ask whether it was meant to differ from R1. Do not delete it until the PM agrees.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,12 @@
1
+ spec: examples/order.ears.md
2
+ conflicts: 0
3
+ gaps: 1
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ gap order_fulfilled
12
+ Nothing says whether the order was fulfilled when an order was submitted and inventory was not available. Suggested fix: add a requirement for this situation, and ask what the system shall do. Do not choose the response.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,18 @@
1
+ spec: examples/order-misuse.ears.md
2
+ conflicts: 0
3
+ gaps: 0
4
+ misuse: 1
5
+ wording: 0
6
+ redundant: 1
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ misuse R4 line 6
12
+ "payment fails" is an unwanted event. Write if ... then, not when.
13
+ When payment fails, the Order System shall reject the order.
14
+
15
+ redundant R4 line 6
16
+ R4 adds nothing. Whenever the other requirements hold, R4 holds too.
17
+ When payment fails, the Order System shall reject the order.
18
+ Suggested fix: remove R4, or ask whether it was meant to say something the others do not already require. Do not delete it until the PM agrees.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,13 @@
1
+ spec: examples/order-negation.ears.md
2
+ conflicts: 0
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 1
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ wording line 6
12
+ The trigger is a bare negation. Write a positive condition, such as "When a non-member asks", or declare a positive event.
13
+ When not a member asks to take a copy home, the Desk shall not allow the loan.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,41 @@
1
+ spec: examples/order-quantity.ears.md
2
+ conflicts: 1
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ conflict {R4, R5}
12
+ R4 and R5 cannot both hold.
13
+
14
+ R4 line 7
15
+ When an order is submitted, the Order System shall accept at most 10 units.
16
+
17
+ R5 line 8
18
+ When an order is submitted, the Order System shall accept 12 units.
19
+
20
+ They clash when an order was submitted.
21
+ R4 requires that at most 10 units were accepted.
22
+ R5 requires that 12 units were accepted.
23
+
24
+ Example scenario:
25
+ {
26
+ "order_submitted": true,
27
+ "quantity": 0
28
+ }
29
+ This scenario keeps R4 and breaks R5.
30
+
31
+ Suggested fix: ask which requirement should win. To keep R4, remove R5. To keep R5, remove R4.
32
+
33
+ Candidate repairs follow. This report does not choose one.
34
+
35
+ repair drop R4
36
+ One repair is to drop R4 and keep R5 as written.
37
+ When an order is submitted, the Order System shall accept 12 units.
38
+
39
+ repair drop R5
40
+ One repair is to drop R5 and keep R4 as written.
41
+ When an order is submitted, the Order System shall accept at most 10 units.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,14 @@
1
+ spec: examples/order-redundant.ears.md
2
+ conflicts: 0
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 1
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ redundant R2 line 8
12
+ R2 adds nothing. Whenever the other requirements hold, R2 holds too.
13
+ When an order is submitted and inventory is available, the Order System shall fulfill the order.
14
+ Suggested fix: remove R2, or ask whether it was meant to say something the others do not already require. Do not delete it until the PM agrees.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,127 @@
1
+ {
2
+ "ok": false,
3
+ "spec": "examples/order-repair.ears.md",
4
+ "conflicts": [
5
+ {
6
+ "ids": [
7
+ "R1",
8
+ "R2"
9
+ ],
10
+ "minimal": true,
11
+ "everySituation": false,
12
+ "summary": "R1 and R2 cannot both hold.",
13
+ "clash": "They clash when the copy was in the building, the copy was out on loan, and a member asks to take a copy home.",
14
+ "requirements": [
15
+ {
16
+ "id": "R1",
17
+ "line": 8,
18
+ "sentence": "While the copy is in the building, when a member asks to take a copy home, the Desk shall allow the loan."
19
+ },
20
+ {
21
+ "id": "R2",
22
+ "line": 9,
23
+ "sentence": "While the copy is out on loan, when a member asks to take a copy home, the Desk shall not allow the loan."
24
+ }
25
+ ],
26
+ "situation": [
27
+ {
28
+ "name": "copy_in_building",
29
+ "value": "true"
30
+ },
31
+ {
32
+ "name": "copy_on_loan",
33
+ "value": "true"
34
+ },
35
+ {
36
+ "name": "borrow_requested",
37
+ "value": "true"
38
+ }
39
+ ],
40
+ "requires": [
41
+ {
42
+ "id": "R1",
43
+ "text": "that the loan was allowed"
44
+ },
45
+ {
46
+ "id": "R2",
47
+ "text": "that the loan was not allowed"
48
+ }
49
+ ],
50
+ "example": [
51
+ {
52
+ "name": "copy_in_building",
53
+ "value": "true"
54
+ },
55
+ {
56
+ "name": "copy_on_loan",
57
+ "value": "true"
58
+ },
59
+ {
60
+ "name": "borrow_requested",
61
+ "value": "true"
62
+ },
63
+ {
64
+ "name": "loan_allowed",
65
+ "value": "true"
66
+ }
67
+ ],
68
+ "keeps": [
69
+ "R1"
70
+ ],
71
+ "breaks": "R2",
72
+ "fix": "Suggested fix: ask which requirement should win. To keep R1, remove R2. To keep R2, remove R1.",
73
+ "repairs": [
74
+ {
75
+ "kind": "drop",
76
+ "id": "R1",
77
+ "text": "One repair is to drop R1 and keep R2 as written.",
78
+ "sentence": "While the copy is out on loan, when a member asks to take a copy home, the Desk shall not allow the loan."
79
+ },
80
+ {
81
+ "kind": "drop",
82
+ "id": "R2",
83
+ "text": "One repair is to drop R2 and keep R1 as written.",
84
+ "sentence": "While the copy is in the building, when a member asks to take a copy home, the Desk shall allow the loan."
85
+ },
86
+ {
87
+ "kind": "strengthen",
88
+ "id": "R1",
89
+ "text": "One repair is to add \"and the copy is not out on loan\" to the condition of R1. R2 stays as written.",
90
+ "sentence": "While the copy is in the building, when a member asks to take a copy home and the copy is not out on loan, the Desk shall allow the loan."
91
+ },
92
+ {
93
+ "kind": "strengthen",
94
+ "id": "R2",
95
+ "text": "One repair is to add \"and the copy is not in the building\" to the condition of R2. R1 stays as written.",
96
+ "sentence": "While the copy is out on loan, when a member asks to take a copy home and the copy is not in the building, the Desk shall not allow the loan."
97
+ }
98
+ ]
99
+ }
100
+ ],
101
+ "gaps": [
102
+ {
103
+ "output": "loan_allowed",
104
+ "situation": [
105
+ {
106
+ "name": "copy_in_building",
107
+ "value": "true"
108
+ },
109
+ {
110
+ "name": "copy_on_loan",
111
+ "value": "true"
112
+ },
113
+ {
114
+ "name": "borrow_requested",
115
+ "value": "false"
116
+ }
117
+ ],
118
+ "text": "Nothing says whether the loan was allowed when the copy was in the building, the copy was out on loan, and not a member asks to take a copy home. Suggested fix: add a requirement for this situation, and ask what the system shall do. Do not choose the response."
119
+ }
120
+ ],
121
+ "misuse": [],
122
+ "wording": [],
123
+ "redundant": [],
124
+ "duplicate": [],
125
+ "vacuous": [],
126
+ "unused": []
127
+ }
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,54 @@
1
+ spec: examples/order-repair.ears.md
2
+ conflicts: 1
3
+ gaps: 1
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ conflict {R1, R2}
12
+ R1 and R2 cannot both hold.
13
+
14
+ R1 line 8
15
+ While the copy is in the building, when a member asks to take a copy home, the Desk shall allow the loan.
16
+
17
+ R2 line 9
18
+ While the copy is out on loan, when a member asks to take a copy home, the Desk shall not allow the loan.
19
+
20
+ They clash when the copy was in the building, the copy was out on loan, and a member asks to take a copy home.
21
+ R1 requires that the loan was allowed.
22
+ R2 requires that the loan was not allowed.
23
+
24
+ Example scenario:
25
+ {
26
+ "copy_in_building": true,
27
+ "copy_on_loan": true,
28
+ "borrow_requested": true,
29
+ "loan_allowed": true
30
+ }
31
+ This scenario keeps R1 and breaks R2.
32
+
33
+ Suggested fix: ask which requirement should win. To keep R1, remove R2. To keep R2, remove R1.
34
+
35
+ Candidate repairs follow. This report does not choose one.
36
+
37
+ repair drop R1
38
+ One repair is to drop R1 and keep R2 as written.
39
+ While the copy is out on loan, when a member asks to take a copy home, the Desk shall not allow the loan.
40
+
41
+ repair drop R2
42
+ One repair is to drop R2 and keep R1 as written.
43
+ While the copy is in the building, when a member asks to take a copy home, the Desk shall allow the loan.
44
+
45
+ repair strengthen R1
46
+ One repair is to add "and the copy is not out on loan" to the condition of R1. R2 stays as written.
47
+ While the copy is in the building, when a member asks to take a copy home and the copy is not out on loan, the Desk shall allow the loan.
48
+
49
+ repair strengthen R2
50
+ One repair is to add "and the copy is not in the building" to the condition of R2. R1 stays as written.
51
+ While the copy is out on loan, when a member asks to take a copy home and the copy is not in the building, the Desk shall not allow the loan.
52
+
53
+ gap loan_allowed
54
+ Nothing says whether the loan was allowed when the copy was in the building, the copy was out on loan, and not a member asks to take a copy home. Suggested fix: add a requirement for this situation, and ask what the system shall do. Do not choose the response.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,48 @@
1
+ spec: examples/order-repeat.ears.md
2
+ conflicts: 1
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 1
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ conflict {R1, R2}
12
+ R1 and R2 cannot both hold.
13
+
14
+ R1 line 8
15
+ When an order is submitted, the Order System shall fulfill the order.
16
+
17
+ R2 line 9
18
+ When an order is submitted, the Order System shall not fulfill the order.
19
+
20
+ They clash when an order was submitted and inventory was not available.
21
+ R1 requires that the order was fulfilled.
22
+ R2 requires that the order was not fulfilled.
23
+
24
+ Example scenario:
25
+ {
26
+ "order_submitted": true,
27
+ "inventory_available": false,
28
+ "order_fulfilled": true,
29
+ "order_closed": false
30
+ }
31
+ This scenario keeps R1 and breaks R2.
32
+
33
+ Suggested fix: ask which requirement should win. To keep R1, remove R2. To keep R2, remove R1.
34
+
35
+ Candidate repairs follow. This report does not choose one.
36
+
37
+ repair drop R1
38
+ One repair is to drop R1 and keep R2 as written.
39
+ When an order is submitted, the Order System shall not fulfill the order.
40
+
41
+ repair drop R2
42
+ One repair is to drop R2 and keep R1 as written.
43
+ When an order is submitted, the Order System shall fulfill the order.
44
+
45
+ redundant R5 line 12
46
+ R5 adds nothing. Whenever the requirements outside a conflict hold, R5 holds too.
47
+ When an order is submitted and inventory is available, the Order System shall close the order.
48
+ Suggested fix: remove R5, or ask whether it was meant to say something the others do not already require. Do not delete it until the PM agrees.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,44 @@
1
+ spec: examples/order-status.ears.md
2
+ conflicts: 1
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 1
10
+
11
+ conflict {R6, R7}
12
+ R6 and R7 cannot both hold.
13
+
14
+ R6 line 6
15
+ The Order System shall mark the order shipped.
16
+
17
+ R7 line 7
18
+ The Order System shall mark the order cancelled.
19
+
20
+ They clash in every situation.
21
+ R6 requires that the order was shipped.
22
+ R7 requires that the order was cancelled.
23
+
24
+ Example scenario:
25
+ {
26
+ "status": "shipped"
27
+ }
28
+ This scenario keeps R6 and breaks R7.
29
+
30
+ Suggested fix: ask which requirement should win. To keep R6, remove R7. To keep R7, remove R6.
31
+
32
+ Candidate repairs follow. This report does not choose one.
33
+
34
+ repair drop R6
35
+ One repair is to drop R6 and keep R7 as written.
36
+ The Order System shall mark the order cancelled.
37
+
38
+ repair drop R7
39
+ One repair is to drop R7 and keep R6 as written.
40
+ The Order System shall mark the order shipped.
41
+
42
+ unused Status.placed
43
+ Status.placed is never mentioned.
44
+ Suggested fix: use placed in a requirement, or remove it from Status.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,12 @@
1
+ spec: examples/order-unanswered.ears.md
2
+ conflicts: 0
3
+ gaps: 1
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ gap payment_declined
12
+ No requirement states a response when "payment fails". Suggested fix: add an if ... then requirement, and ask what the system shall do. Do not choose the response.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,12 @@
1
+ spec: examples/order-unhandled.ears.md
2
+ conflicts: 0
3
+ gaps: 1
4
+ misuse: 0
5
+ wording: 0
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ gap order_cancelled
12
+ No requirement handles "an order is cancelled". Suggested fix: add a requirement that says what the system shall do, or remove the event.
@@ -0,0 +1 @@
1
+ 1
File without changes
@@ -0,0 +1,13 @@
1
+ spec: examples/order-unmeasured.ears.md
2
+ conflicts: 0
3
+ gaps: 0
4
+ misuse: 0
5
+ wording: 1
6
+ redundant: 0
7
+ duplicate: 0
8
+ vacuous: 0
9
+ unused: 0
10
+
11
+ wording line 4
12
+ "as needed" is too vague to test. Replace it with something a scenario can check.
13
+ output order_fulfilled: Bool "Handle it as needed." phrase "fulfill the order" outcome "the order was fulfilled" / "the order was not fulfilled"
@@ -0,0 +1 @@
1
+ 1
File without changes