harness-everything 0.47.3 → 0.47.5

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 (37) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +24 -0
  4. package/behavioral-evals/README.md +27 -0
  5. package/behavioral-evals/case-validator.js +22 -1
  6. package/behavioral-evals/cases/baseline-profile-lookup-json-only.yaml +23 -0
  7. package/behavioral-evals/cases/baseline-tdd-workflow.yaml +4 -0
  8. package/behavioral-evals/run.js +257 -6
  9. package/behavioral-evals/transcript-parser.js +43 -0
  10. package/benchmarks/issue290-pilot/metrics.test.py +60 -2
  11. package/ci/mechanism-2s-tdd-quality.test.js +149 -6
  12. package/ci/test-behavioral-case-validation.js +362 -3
  13. package/code-review/SKILL.md +1 -1
  14. package/code-review/references/review-playbook.md +9 -0
  15. package/opencode-plugin/plugin.json +1 -1
  16. package/package.json +1 -1
  17. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  18. package/plugins/harness-everything/plugin.json +1 -1
  19. package/plugins/harness-everything/skills/code-review/SKILL.md +1 -1
  20. package/plugins/harness-everything/skills/code-review/references/review-playbook.md +9 -0
  21. package/plugins/harness-everything/skills/tdd/SKILL.md +1 -1
  22. package/plugins/harness-everything/skills/tdd/fixtures/quality-scenarios.json +10 -2
  23. package/plugins/harness-everything/skills/tdd/references/quality-model.md +2 -0
  24. package/plugins/harness-everything/skills/tdd/schemas/quality-evidence.schema.json +21 -0
  25. package/plugins/harness-everything/skills/tdd/schemas/quality-report.schema.json +2 -0
  26. package/plugins/harness-everything/skills/tdd/scripts/quality-gate.js +165 -1
  27. package/plugins/harness-everything/skills/zoom-out/SKILL.md +1 -1
  28. package/plugins/harness-everything/skills/zoom-out/references/circuit-breaker.md +1 -0
  29. package/sbom.cdx.json +7 -7
  30. package/tdd/SKILL.md +1 -1
  31. package/tdd/fixtures/quality-scenarios.json +10 -2
  32. package/tdd/references/quality-model.md +2 -0
  33. package/tdd/schemas/quality-evidence.schema.json +21 -0
  34. package/tdd/schemas/quality-report.schema.json +2 -0
  35. package/tdd/scripts/quality-gate.js +165 -1
  36. package/zoom-out/SKILL.md +1 -1
  37. package/zoom-out/references/circuit-breaker.md +1 -0
@@ -55,9 +55,9 @@ class ReadMetricTest(unittest.TestCase):
55
55
 
56
56
 
57
57
  class AccountingTest(unittest.TestCase):
58
- def episode(self, root, engine='claude', workload='profile-lookup', events=None):
58
+ def episode(self, root, engine='claude', workload='profile-lookup', events=None, usage=None):
59
59
  row = {'model': {'engine': engine, 'model': 'fixture'}, 'workload': workload,
60
- 'grader': {'pass': False}, 'usage': None, 'router_attributed': True}
60
+ 'grader': {'pass': False}, 'usage': usage, 'router_attributed': True}
61
61
  (root/'analysis.json').write_text(json.dumps(row))
62
62
  (root/'manifest.json').write_text('{}')
63
63
  (root/'transcript.jsonl').write_text('\n'.join(json.dumps(e) for e in (events or [])))
@@ -81,6 +81,64 @@ class AccountingTest(unittest.TestCase):
81
81
  self.assertIsNone(row['api_equivalent_cost_usd'])
82
82
  self.assertIn('unknown', row['child_usage_observability'])
83
83
 
84
+ def codex_episode(self, root, spawn):
85
+ usage = {'input_tokens': 3000, 'cached_input_tokens': 700, 'output_tokens': 130,
86
+ 'cache_write_input_tokens': 0}
87
+ self.episode(root, engine='codex', usage=usage,
88
+ events=[{'type': 'thread.started', 'thread_id': 'T1'}])
89
+ rollout = root/'.codex'/'sessions'/'2026'/'10'/'14'/'rollout-T1.jsonl'
90
+ rollout.parent.mkdir(parents=True)
91
+ lines = []
92
+ if spawn:
93
+ lines.append({'type': 'response_item', 'payload': {'type': 'function_call', 'name': 'spawn_agent',
94
+ 'call_id': 'c1', 'arguments': json.dumps({'task_name': 'cold_verifier',
95
+ 'fork_turns': 'none', 'reasoning_effort': 'high'})}})
96
+ lines.append({'type': 'response_item', 'payload': {'type': 'function_call_output',
97
+ 'call_id': 'c1', 'output': '{"agent_id": "w1"}'}})
98
+ counters = [
99
+ ({'input_tokens': 1000, 'cached_input_tokens': 200, 'output_tokens': 50, 'cache_write_input_tokens': 0},
100
+ {'input_tokens': 1000, 'cached_input_tokens': 200, 'output_tokens': 50, 'cache_write_input_tokens': 0}),
101
+ ({'input_tokens': 3000, 'cached_input_tokens': 700, 'output_tokens': 130, 'cache_write_input_tokens': 0},
102
+ {'input_tokens': 2000, 'cached_input_tokens': 500, 'output_tokens': 80, 'cache_write_input_tokens': 0}),
103
+ ]
104
+ for total, last in counters:
105
+ lines.append({'type': 'event_msg', 'payload': {'type': 'token_count',
106
+ 'info': {'total_token_usage': total, 'last_token_usage': last}}})
107
+ rollout.write_text('\n'.join(json.dumps(x) for x in lines))
108
+
109
+ def test_codex_spawn_agent_child_cost_is_unknown_not_zero(self):
110
+ with tempfile.TemporaryDirectory() as directory:
111
+ root = Path(directory)
112
+ self.codex_episode(root, spawn=True)
113
+ with patch.object(Path, 'home', return_value=root):
114
+ row = analyze.inspect_episode(root, documents={})
115
+ self.assertIsNone(row['api_equivalent_cost_usd'])
116
+ self.assertIsNone(row['api_equivalent_input_cost_usd'])
117
+ self.assertIsNone(row['reconstructed_total_cost_usd'])
118
+ self.assertIn('unknown', row['child_usage_observability'])
119
+ self.assertEqual(len(row['private_collaboration_dispatch']), 1)
120
+ dispatch = row['private_collaboration_dispatch'][0]
121
+ self.assertEqual(dispatch['tool'], 'spawn_agent')
122
+ self.assertEqual(dispatch['arguments']['task_name'], 'cold_verifier')
123
+ self.assertEqual(len(dispatch['outputs']), 1)
124
+ # Parent cost is measured and retained; worker cost is never zero-filled.
125
+ self.assertIsInstance(row['parent_api_equivalent_input_cost_usd'], float)
126
+ self.assertAlmostEqual(row['parent_api_equivalent_input_cost_usd'], 0.000237)
127
+ self.assertIsInstance(row['parent_api_equivalent_cost_usd'], float)
128
+ self.assertAlmostEqual(row['parent_api_equivalent_cost_usd'], 0.000302)
129
+
130
+ def test_codex_without_spawn_keeps_measured_cost_and_no_unknown_child(self):
131
+ with tempfile.TemporaryDirectory() as directory:
132
+ root = Path(directory)
133
+ self.codex_episode(root, spawn=False)
134
+ with patch.object(Path, 'home', return_value=root):
135
+ row = analyze.inspect_episode(root, documents={})
136
+ self.assertEqual(row['private_collaboration_dispatch'], [])
137
+ self.assertEqual(row['child_usage_observability'], 'no attributable native spawn in inspected parent rollout')
138
+ self.assertAlmostEqual(row['api_equivalent_input_cost_usd'], 0.000237)
139
+ self.assertAlmostEqual(row['api_equivalent_cost_usd'], 0.000302)
140
+ self.assertAlmostEqual(row['reconstructed_total_cost_usd'], 0.000302)
141
+
84
142
  def test_polyglot_grader_timeout_is_retained_failure(self):
85
143
  with tempfile.TemporaryDirectory() as directory:
86
144
  root = Path(directory)
@@ -3,7 +3,7 @@ const os = require('os');
3
3
  const path = require('path');
4
4
  const { spawnSync } = require('child_process');
5
5
  const helper = require('./test-helper');
6
- const { evaluateEvidence } = require('../tdd/scripts/quality-gate');
6
+ const { evaluateEvidence, quotedExpectedValue } = require('../tdd/scripts/quality-gate');
7
7
 
8
8
  console.log('\n[2s] TDD quality evidence gate (issue #58)...');
9
9
 
@@ -15,7 +15,7 @@ const classes = {
15
15
  };
16
16
 
17
17
  const scenarioCatalog = JSON.parse(fs.readFileSync(path.join(helper.root, 'tdd', 'fixtures', 'quality-scenarios.json'), 'utf8'));
18
- const requiredScenarios = ['PASS', 'unit profile', 'integration profile', 'weighted integration failure', 'weighted unit failure', 'NON_CONFORMANT', 'SOURCE_DEFECT', 'SOURCE_CONFLICT', 'malformed input', 'unexpected input', 'error handling', 'nondeterministic output', 'auditable N/A', 'skipped test'];
18
+ const requiredScenarios = ['PASS', 'unit profile', 'integration profile', 'weighted integration failure', 'weighted unit failure', 'NON_CONFORMANT', 'SOURCE_DEFECT', 'SOURCE_CONFLICT', 'SOURCE_DEFECT without sourceEvidence', 'SOURCE_CONFLICT without sourceEvidence', 'SOURCE_CONFLICT node-versus-value', 'SOURCE_CONFLICT agreeing expectations', 'SOURCE_CONFLICT two-source evidence', 'SOURCE_CONFLICT relabelled expected', 'SOURCE_CONFLICT verified literal disagreement', 'SOURCE_CONFLICT unrelated assertions', 'malformed input', 'unexpected input', 'error handling', 'nondeterministic output', 'auditable N/A', 'skipped test'];
19
19
  helper.check('2s. fixture catalog covers every required outcome', requiredScenarios.every(name => scenarioCatalog.scenarios.some(scenario => scenario.name === name)));
20
20
 
21
21
  function checks(prefix, names) {
@@ -134,15 +134,158 @@ helper.check('2s. unequal repeated integration output is rejected', nondetermini
134
134
  const nonConformant = evaluate(req => { req.sourceConformance = 'NON_CONFORMANT'; });
135
135
  helper.check('2s. implementation/source mismatches fail', nonConformant.result === 'FAIL' && nonConformant.mandatoryGates.noSourceMismatch === false);
136
136
 
137
- const sourceDefect = evaluate(req => { req.sourceValidity = 'SOURCE_DEFECT'; req.sourceNotes = 'The approved example appears internally wrong.'; });
137
+ const sourceDefect = evaluate(req => {
138
+ req.sourceValidity = 'SOURCE_DEFECT';
139
+ req.sourceNotes = 'The approved example appears internally wrong.';
140
+ req.sourceEvidence = [{ source: 'docs/example.md', assertion: 'expect(output.value).toEqual(3)', expected: 3, observed: 2 }];
141
+ });
138
142
  helper.check('2s. source defects are reported separately without inventing a mismatch', sourceDefect.result === 'PASS' && sourceDefect.requirements[0].sourceValidity === 'SOURCE_DEFECT');
143
+ helper.check(
144
+ '2s. source defect evidence is reviewer-required: an implementation mismatch alone does not validate a source defect',
145
+ sourceDefect.result === 'PASS' &&
146
+ sourceDefect.requirements[0].sourceEvidenceStatus === 'REVIEWER_REQUIRED' &&
147
+ !sourceDefect.errors.some(e => /sourceEvidence/.test(e))
148
+ );
149
+ const sourceDefectUncheckable = evaluate(req => {
150
+ req.sourceValidity = 'SOURCE_DEFECT';
151
+ req.sourceNotes = 'The approved example appears internally wrong.';
152
+ req.sourceEvidence = [{ source: 'docs/example.md', assertion: 'expect(output.value).toEqual(computeExpected())', expected: 3, observed: 2 }];
153
+ });
154
+ helper.check(
155
+ '2s. source defect with a non-checkable quote is REVIEWER_REQUIRED without a sourceEvidence error',
156
+ sourceDefectUncheckable.requirements[0].sourceEvidenceStatus === 'REVIEWER_REQUIRED' &&
157
+ !sourceDefectUncheckable.errors.some(e => /sourceEvidence/.test(e))
158
+ );
159
+ const sourceDefectNoEvidence = evaluate(req => { req.sourceValidity = 'SOURCE_DEFECT'; req.sourceNotes = 'Appears wrong.'; });
160
+ helper.check('2s. source defects without quoted sourceEvidence are rejected', sourceDefectNoEvidence.result === 'FAIL' && sourceDefectNoEvidence.errors.some(e => /sourceEvidence/.test(e)));
139
161
 
140
- const sourceConflict = evaluate(req => {
162
+ const sourceConflictAdr = { type: 'ADR', path: 'docs/adr/001.md', section: 'Contract', status: 'AUTHORITATIVE' };
163
+ const conflictFrom = (req, sourceEvidence) => {
141
164
  req.sourceValidity = 'SOURCE_CONFLICT';
142
165
  req.sourceNotes = 'ADR-1 and SPEC-2 disagree.';
143
- req.additionalSources = [{ type: 'ADR', path: 'docs/adr/001.md', section: 'Contract', status: 'AUTHORITATIVE' }];
144
- });
166
+ req.additionalSources = [clone(sourceConflictAdr)];
167
+ if (sourceEvidence !== undefined) req.sourceEvidence = sourceEvidence;
168
+ };
169
+
170
+ const sourceConflict = evaluate(req => conflictFrom(req, [
171
+ { source: 'docs/example.md', subject: 'list.head', assertion: 'expect(list.head).toEqual(1)', expected: 1, observed: { value: 1, next: null } },
172
+ { source: 'docs/adr/001.md', subject: 'list.head', assertion: 'expect(list.head).toBeInstanceOf(Element)', expected: 'Element', observed: { value: 1, next: null } }
173
+ ]));
145
174
  helper.check('2s. unresolved authoritative source conflicts fail', sourceConflict.result === 'FAIL' && sourceConflict.mandatoryGates.noSourceConflict === false && sourceConflict.dimensions.sourceTraceability.traced === 2);
175
+ helper.check(
176
+ '2s. two-source conflict with an unreadable quote is REVIEWER_REQUIRED, not an error; only the conflict gate stays closed',
177
+ !sourceConflict.errors.some(e => /sourceEvidence/.test(e)) &&
178
+ sourceConflict.requirements[0].sourceEvidenceStatus === 'REVIEWER_REQUIRED' &&
179
+ Object.entries(sourceConflict.requirements[0].mandatoryGates).filter(([, passed]) => !passed).map(([name]) => name).join() === 'noSourceConflict'
180
+ );
181
+
182
+ // expected must match the literal in its quote; a relabelled expectation cannot manufacture a conflict.
183
+ const relabelledExpected = evaluate(req => conflictFrom(req, [
184
+ { source: 'docs/example.md', subject: 'list.head', assertion: 'expect(list.head).toEqual(1)', expected: 1, observed: 2 },
185
+ { source: 'docs/adr/001.md', subject: 'list.head', assertion: 'expect(list.head).toEqual(1)', expected: 3, observed: 2 }
186
+ ]));
187
+ helper.check('2s. an expected value that contradicts its quoted literal is rejected, not a conflict', relabelledExpected.result === 'FAIL' && relabelledExpected.errors.some(e => /expected does not match the value in the quoted assertion/.test(e)));
188
+
189
+ const relabelledDefect = evaluate(req => {
190
+ req.sourceValidity = 'SOURCE_DEFECT';
191
+ req.sourceNotes = 'Appears wrong.';
192
+ req.sourceEvidence = [{ source: 'docs/example.md', assertion: 'expect(output.value).toEqual(3)', expected: 4, observed: 2 }];
193
+ });
194
+ helper.check('2s. a source defect whose expected value contradicts its quoted literal is rejected', relabelledDefect.result === 'FAIL' && relabelledDefect.errors.some(e => /expected does not match the value in the quoted assertion/.test(e)));
195
+
196
+ const verifiedConflict = evaluate(req => conflictFrom(req, [
197
+ { source: 'docs/example.md', subject: 'list.head.value', assertion: 'expect(list.head.value).toBe(1)', expected: 1, observed: 2 },
198
+ { source: 'docs/adr/001.md', subject: 'list.head.value', assertion: "expect(list.head.value).toBe('1')", expected: '1', observed: 2 }
199
+ ]));
200
+ helper.check(
201
+ '2s. a literal disagreement across two sources is VERIFIED; only the conflict gate stays closed',
202
+ !verifiedConflict.errors.some(e => /sourceEvidence/.test(e)) &&
203
+ verifiedConflict.requirements[0].sourceEvidenceStatus === 'VERIFIED' &&
204
+ Object.entries(verifiedConflict.requirements[0].mandatoryGates).filter(([, passed]) => !passed).map(([name]) => name).join() === 'noSourceConflict'
205
+ );
206
+
207
+ const checkableCases = [
208
+ ['expect(list.head).toEqual(1)', { checkable: true, value: 1 }],
209
+ ["expect(output.name).toBe('a')", { checkable: true, value: 'a' }],
210
+ ['assert.strictEqual(x, null)', { checkable: true, value: null }],
211
+ ['expect(list.items).toEqual([1,2])', { checkable: true, value: [1, 2] }],
212
+ ['assert.deepEqual(x, [1, 2])', { checkable: true, value: [1, 2] }],
213
+ ['expect(list.head).toEqual({a:1})', { checkable: false }],
214
+ ['expect(list.head).toBeInstanceOf(Element)', { checkable: false }],
215
+ ['expect(list.head).toEqual(new Element())', { checkable: false }],
216
+ ['the head is 1', { checkable: false }],
217
+ // assert.* expected value is the second argument; an optional third argument is the message.
218
+ ['assert.equal(x, 1, "head")', { checkable: true, value: 1 }],
219
+ ['assert.strictEqual(f(a, b), "z")', { checkable: true, value: 'z' }],
220
+ ["assert.deepStrictEqual(x, [1, 2], 'm')", { checkable: true, value: [1, 2] }],
221
+ ['assert.equal(x, "a,b")', { checkable: true, value: 'a,b' }],
222
+ ['assert.equal(x)', { checkable: false }],
223
+ ['assert.equal(x, 1, 2, 3)', { checkable: false }],
224
+ // Negated and resolved modifiers are not expected values and must stay non-checkable.
225
+ ['expect(x).not.toEqual(1)', { checkable: false }],
226
+ ['expect(x).resolves.toBe(1)', { checkable: false }],
227
+ // One trailing semicolon is tolerated.
228
+ ['expect(list.head).toEqual(1);', { checkable: true, value: 1 }]
229
+ ];
230
+ helper.check(
231
+ '2s. quotedExpectedValue reads only the recognised shapes with literal values',
232
+ checkableCases.every(([assertion, expected]) => JSON.stringify(quotedExpectedValue(assertion)) === JSON.stringify(expected))
233
+ );
234
+
235
+ const relabelledWithSemicolon = evaluate(req => conflictFrom(req, [
236
+ { source: 'docs/example.md', subject: 'list.head', assertion: 'expect(list.head).toEqual(1);', expected: 1, observed: 2 },
237
+ { source: 'docs/adr/001.md', subject: 'list.head', assertion: 'expect(list.head).toEqual(1);', expected: 3, observed: 2 }
238
+ ]));
239
+ helper.check('2s. a relabelled expectation with a trailing semicolon is rejected, not a conflict', relabelledWithSemicolon.result === 'FAIL' && relabelledWithSemicolon.errors.some(e => /expected does not match the value in the quoted assertion/.test(e)));
240
+
241
+ const assertMessageEntry = evaluate(req => conflictFrom(req, [
242
+ { source: 'docs/example.md', subject: 'list.head', assertion: 'assert.equal(list.head, 1, "head")', expected: 1, observed: 2 },
243
+ { source: 'docs/adr/001.md', subject: 'list.head', assertion: 'assert.equal(list.head, 1, "head")', expected: 3, observed: 2 }
244
+ ]));
245
+ helper.check(
246
+ '2s. an assert.* message argument is not read as the expected value; only the relabelled entry errors',
247
+ !assertMessageEntry.errors.some(e => /sourceEvidence\[0\]\.expected does not match/.test(e)) &&
248
+ assertMessageEntry.errors.some(e => /sourceEvidence\[1\]\.expected does not match the value in the quoted assertion/.test(e))
249
+ );
250
+
251
+ const conflictWithoutEvidence = evaluate(req => conflictFrom(req));
252
+ helper.check('2s. source conflicts without quoted sourceEvidence are rejected', conflictWithoutEvidence.result === 'FAIL' && conflictWithoutEvidence.errors.some(e => /sourceEvidence/.test(e)));
253
+
254
+ const nodeVersusValue = evaluate(req => conflictFrom(req, [
255
+ { source: 'docs/example.md', subject: 'list.head.value', assertion: 'expect(list.head.value).toEqual(1)', expected: 1, observed: { value: 1, next: null } },
256
+ { source: 'docs/example.md', subject: 'list.head.next.value', assertion: 'expect(list.head.next.value).toEqual(2)', expected: 2, observed: { value: 2, next: null } }
257
+ ]));
258
+ helper.check('2s. node-versus-value conflict citing one spec is rejected as a source conflict', nodeVersusValue.result === 'FAIL' && nodeVersusValue.errors.some(e => /two distinct authoritative sources/.test(e)));
259
+
260
+ const agreeingExpectations = evaluate(req => conflictFrom(req, [
261
+ { source: 'docs/example.md', subject: 'output.value', assertion: 'expect(output.value).toEqual(1)', expected: 1, observed: 2 },
262
+ { source: 'docs/adr/001.md', subject: 'output.value', assertion: 'expect(output.value).toEqual(1)', expected: 1, observed: 2 }
263
+ ]));
264
+ helper.check('2s. mismatch with agreeing expectations is not a source conflict', agreeingExpectations.result === 'FAIL' && agreeingExpectations.errors.some(e => /disagree across sources/.test(e)));
265
+
266
+ // Unequal expectations about unrelated targets in two sources are not a conflict.
267
+ const unrelatedAssertions = evaluate(req => conflictFrom(req, [
268
+ { source: 'docs/example.md', subject: 'foo', assertion: 'expect(foo).toEqual(1)', expected: 1, observed: 2 },
269
+ { source: 'docs/adr/001.md', subject: 'bar', assertion: 'expect(bar).toEqual(3)', expected: 3, observed: 4 }
270
+ ]));
271
+ helper.check('2s. unrelated assertions from two sources are rejected as a source conflict', unrelatedAssertions.result === 'FAIL' && unrelatedAssertions.errors.some(e => /same subject/.test(e)));
272
+
273
+ // The subject must be claimed explicitly and be the target the quote constrains.
274
+ const subjectMissing = evaluate(req => conflictFrom(req, [
275
+ { source: 'docs/example.md', assertion: 'expect(foo).toEqual(1)', expected: 1, observed: 2 },
276
+ { source: 'docs/adr/001.md', assertion: 'expect(bar).toEqual(3)', expected: 3, observed: 2 }
277
+ ]));
278
+ helper.check('2s. source conflict evidence without a subject is rejected', subjectMissing.result === 'FAIL' && subjectMissing.errors.some(e => /subject must name the contract target/.test(e)));
279
+ const subjectRelabelled = evaluate(req => conflictFrom(req, [
280
+ { source: 'docs/example.md', subject: 'foo', assertion: 'expect(foo).toEqual(1)', expected: 1, observed: 2 },
281
+ { source: 'docs/adr/001.md', subject: 'foo', assertion: 'expect(bar).toEqual(3)', expected: 3, observed: 2 }
282
+ ]));
283
+ helper.check('2s. a subject absent from the quoted assertion cannot manufacture a conflict', subjectRelabelled.result === 'FAIL' && subjectRelabelled.errors.some(e => /subject must appear as a whole target/.test(e)));
284
+ const nestedTarget = evaluate(req => conflictFrom(req, [
285
+ { source: 'docs/example.md', subject: 'list.head', assertion: 'expect(list.head.value).toEqual(1)', expected: 1, observed: 2 },
286
+ { source: 'docs/adr/001.md', subject: 'list.head', assertion: 'expect(list.head).toBeInstanceOf(Element)', expected: 'Element', observed: 2 }
287
+ ]));
288
+ helper.check('2s. a nested property is not the same subject as its parent', nestedTarget.result === 'FAIL' && nestedTarget.errors.some(e => /subject must appear as a whole target/.test(e)));
146
289
 
147
290
  const inferred = evaluate(req => { req.source = { type: 'INFERENCE', status: 'INFERRED', inferenceBasis: 'Observed public API and user-approved acceptance criteria.' }; });
148
291
  helper.check('2s. inferred expectations remain explicit and traceable', inferred.result === 'PASS' && inferred.dimensions.sourceTraceability.percentage === 100);