harness-everything 0.47.0 → 0.47.2

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 (116) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.github/workflows/ci.yml +12 -0
  4. package/CHANGELOG.md +18 -0
  5. package/benchmarks/issue290-pilot/README.md +199 -0
  6. package/benchmarks/issue290-pilot/analyze.py +299 -0
  7. package/benchmarks/issue290-pilot/analyze.test.py +146 -0
  8. package/benchmarks/issue290-pilot/check.py +19 -0
  9. package/benchmarks/issue290-pilot/evidence/archive.json +7 -0
  10. package/benchmarks/issue290-pilot/evidence/group-summary.json +684 -0
  11. package/benchmarks/issue290-pilot/evidence/inventory.json +3728 -0
  12. package/benchmarks/issue290-pilot/evidence/ledger.json +4644 -0
  13. package/benchmarks/issue290-pilot/evidence/replay/pairs.json +482 -0
  14. package/benchmarks/issue290-pilot/evidence/replay/provenance.json +24 -0
  15. package/benchmarks/issue290-pilot/evidence/replay/tables.md +37 -0
  16. package/benchmarks/issue290-pilot/evidence.tar.gz +0 -0
  17. package/benchmarks/issue290-pilot/export.py +110 -0
  18. package/benchmarks/issue290-pilot/export.test.py +65 -0
  19. package/benchmarks/issue290-pilot/fable-supplement.py +55 -0
  20. package/benchmarks/issue290-pilot/fixture.test.py +28 -0
  21. package/benchmarks/issue290-pilot/fixtures/polyglot/instructions.md +19 -0
  22. package/benchmarks/issue290-pilot/fixtures/polyglot/package.json +29 -0
  23. package/benchmarks/issue290-pilot/fixtures/polyglot/simple-linked-list.js +44 -0
  24. package/benchmarks/issue290-pilot/fixtures/polyglot/simple-linked-list.spec.js +131 -0
  25. package/benchmarks/issue290-pilot/fixtures/quixbugs/LICENSE +7 -0
  26. package/benchmarks/issue290-pilot/fixtures/quixbugs/cases.json +7 -0
  27. package/benchmarks/issue290-pilot/fixtures/quixbugs/find_in_sorted.py +31 -0
  28. package/benchmarks/issue290-pilot/fixtures/quixbugs/test_find_in_sorted.py +15 -0
  29. package/benchmarks/issue290-pilot/frozen-documents.json +41 -0
  30. package/benchmarks/issue290-pilot/grader.cjs +43 -0
  31. package/benchmarks/issue290-pilot/grader.test.cjs +10 -0
  32. package/benchmarks/issue290-pilot/hook.test.cjs +27 -0
  33. package/benchmarks/issue290-pilot/host-hook.cjs +35 -0
  34. package/benchmarks/issue290-pilot/metrics.test.py +131 -0
  35. package/benchmarks/issue290-pilot/preflight/amendment.md +32 -0
  36. package/benchmarks/issue290-pilot/preflight/environment.json +15 -0
  37. package/benchmarks/issue290-pilot/preflight/fable-amendment.md +20 -0
  38. package/benchmarks/issue290-pilot/preflight/fable-frozen-files.json +4 -0
  39. package/benchmarks/issue290-pilot/preflight/fable-infrastructure-amendment.md +27 -0
  40. package/benchmarks/issue290-pilot/preflight/fable-retry-frozen-files.json +4 -0
  41. package/benchmarks/issue290-pilot/preflight/fable-supplement-v1.py +47 -0
  42. package/benchmarks/issue290-pilot/preflight/frozen-files.json +18 -0
  43. package/benchmarks/issue290-pilot/preflight/graders.json +67 -0
  44. package/benchmarks/issue290-pilot/pricing-assumptions.json +29 -0
  45. package/benchmarks/issue290-pilot/protocol.json +32 -0
  46. package/benchmarks/issue290-pilot/read_metrics.py +166 -0
  47. package/benchmarks/issue290-pilot/replay.py +167 -0
  48. package/benchmarks/issue290-pilot/reporting.py +82 -0
  49. package/benchmarks/issue290-pilot/run.py +262 -0
  50. package/benchmarks/issue290-pilot/sources.json +10 -0
  51. package/benchmarks/issue290-pilot/verification/analyzer-tests.log +5 -0
  52. package/benchmarks/issue290-pilot/verification/final-gates.json +58 -0
  53. package/benchmarks/issue290-pilot/verification/fixture-tests.log +5 -0
  54. package/benchmarks/issue290-pilot/verification/gates.json +58 -0
  55. package/benchmarks/issue290-pilot/verification/npm-audit.json +84 -0
  56. package/benchmarks/issue290-pilot/verification/offline-correction.json +59 -0
  57. package/benchmarks/issue290-pilot/verification/post-report/helper-tests.log +22 -0
  58. package/benchmarks/issue290-pilot/verification/post-report/test-consistency.log +626 -0
  59. package/benchmarks/issue290-pilot/verification/post-report/test-references.log +6 -0
  60. package/benchmarks/issue290-pilot/verification/post-report/waza-tokens.log +710 -0
  61. package/benchmarks/issue290-pilot/verification/test-collision.log +28 -0
  62. package/benchmarks/issue290-pilot/verification/test-consistency.log +28 -0
  63. package/benchmarks/issue290-pilot/verification/test-docs-capabilities.log +131 -0
  64. package/benchmarks/issue290-pilot/verification/test-mechanism.log +1829 -0
  65. package/benchmarks/issue290-pilot/verification/test-mutations.log +16 -0
  66. package/benchmarks/issue290-pilot/verification/test-platform-compatibility.log +9 -0
  67. package/benchmarks/issue290-pilot/verification/test-plugin-openai.log +6 -0
  68. package/benchmarks/issue290-pilot/verification/test-plugin-submission.log +5 -0
  69. package/benchmarks/issue290-pilot/verification/test-references.log +6 -0
  70. package/benchmarks/issue290-pilot/verification/test-release.log +59 -0
  71. package/benchmarks/issue290-pilot/verification/test-repo-contract.log +5 -0
  72. package/benchmarks/issue290-pilot/verification/test-routing-invariants.log +785 -0
  73. package/benchmarks/issue290-pilot/verification/test-routing-skills.log +28 -0
  74. package/benchmarks/issue290-pilot/verification/test.log +3373 -0
  75. package/benchmarks/issue290-pilot/verification/verification-report.md +76 -0
  76. package/benchmarks/issue290-pilot/verification/waza-tokens.log +710 -0
  77. package/benchmarks/issue290-pilot/verification/with-dependencies/gates.json +26 -0
  78. package/benchmarks/issue290-pilot/verification/with-dependencies/test-collision.log +8 -0
  79. package/benchmarks/issue290-pilot/verification/with-dependencies/test-consistency.log +626 -0
  80. package/benchmarks/issue290-pilot/verification/with-dependencies/test-mechanism.log +1693 -0
  81. package/benchmarks/issue290-pilot/verification/with-dependencies/test-release.log +38 -0
  82. package/benchmarks/issue290-pilot/verification/with-dependencies/test-routing-skills.log +44 -0
  83. package/benchmarks/issue290-pilot/verification/with-dependencies/test.log +3253 -0
  84. package/ci/mechanism-379-self-evolve-workspace.test.js +151 -0
  85. package/ci/mechanism-383-doc-glob-line-terminators.test.js +131 -0
  86. package/docs/document-lifecycle.md +1 -1
  87. package/docs/platform-capabilities.md +4 -0
  88. package/harness-everything/SKILL.md +1 -1
  89. package/harness-everything/scripts/doc-check.js +1 -1
  90. package/harness-everything/scripts/doc-lifecycle.js +2 -2
  91. package/harness-everything/scripts/doc-obligations.js +2 -2
  92. package/hooks/scripts/lib/doc-reconciliation-core.js +2 -2
  93. package/hooks/scripts/lib/doc-reconciliation-provider.js +1 -1
  94. package/opencode-plugin/plugin.json +1 -1
  95. package/package.json +1 -1
  96. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  97. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-core.js +2 -2
  98. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +1 -1
  99. package/plugins/harness-everything/plugin.json +1 -1
  100. package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
  101. package/plugins/harness-everything/skills/harness-everything/scripts/doc-check.js +1 -1
  102. package/plugins/harness-everything/skills/harness-everything/scripts/doc-lifecycle.js +2 -2
  103. package/plugins/harness-everything/skills/harness-everything/scripts/doc-obligations.js +2 -2
  104. package/plugins/harness-everything/skills/self-evolve/SKILL.md +1 -1
  105. package/plugins/harness-everything/skills/self-evolve/references/memory-resolution.md +11 -0
  106. package/plugins/harness-everything/skills/self-evolve/scripts/lesson-candidate.js +9 -12
  107. package/plugins/harness-everything/skills/self-evolve/scripts/persist-memory.js +1 -14
  108. package/plugins/harness-everything/skills/self-evolve/scripts/register-dynamic-skill.js +5 -9
  109. package/plugins/harness-everything/skills/self-evolve/scripts/workspace-helper.js +98 -0
  110. package/sbom.cdx.json +7 -7
  111. package/self-evolve/SKILL.md +1 -1
  112. package/self-evolve/references/memory-resolution.md +11 -0
  113. package/self-evolve/scripts/lesson-candidate.js +9 -12
  114. package/self-evolve/scripts/persist-memory.js +1 -14
  115. package/self-evolve/scripts/register-dynamic-skill.js +5 -9
  116. package/self-evolve/scripts/workspace-helper.js +98 -0
@@ -0,0 +1,146 @@
1
+ """Protect the central evidence distinction: inventory is not an observed read."""
2
+ import importlib.util
3
+ from pathlib import Path
4
+ import unittest
5
+ import json
6
+ import tempfile
7
+ import tarfile
8
+
9
+ spec=importlib.util.spec_from_file_location('audit',Path(__file__).with_name('analyze.py'))
10
+ audit=importlib.util.module_from_spec(spec);spec.loader.exec_module(audit)
11
+
12
+ class AttributionTest(unittest.TestCase):
13
+ def test_tdd_gate_requires_an_invocation(self):
14
+ negatives = [
15
+ 'node workflow-disposition.js stage-binding --evidence "npm tdd:quality gate N/A (no package.json in workspace)"',
16
+ 'echo "npm run tdd:quality"',
17
+ 'printf "%s" "node ./tdd/scripts/quality-gate.js"',
18
+ '# npm run tdd:quality',
19
+ 'cat tdd/scripts/quality-gate.js',
20
+ 'node other.js --evidence "npm run tdd:quality"',
21
+ 'npm run other -- tdd:quality',
22
+ 'node -e "console.log(\'quality-gate.js\')"',
23
+ 'bash -lc \'echo "npm run tdd:quality"\'',
24
+ 'npm run tdd:quality-extra',
25
+ 'npm run tdd:quality --help',
26
+ 'npm run tdd:quality --dry-run',
27
+ 'node ./quality-gate.js.backup',
28
+ 'node ./fixtures/quality-gate.js',
29
+ 'node /tmp/unrelated/quality-gate.js',
30
+ 'npm --prefix /tmp/other-project run tdd:quality',
31
+ 'npm --prefix=/tmp/other-project run tdd:quality',
32
+ 'npm --workspace unrelated run tdd:quality',
33
+ 'npm run tdd:quality --prefix /tmp/other-project',
34
+ 'npm run tdd:quality --workspace unrelated',
35
+ '', 'npm run "unterminated',
36
+ ]
37
+ positives = [
38
+ 'npm run tdd:quality -- evidence.json',
39
+ 'npm run test:tdd-quality',
40
+ ' npm\t run tdd:quality ',
41
+ 'node ./tdd/scripts/quality-gate.js evidence.json',
42
+ 'node .harness/tdd/scripts/quality-gate.js evidence.json',
43
+ 'HARNESS_STATE_HOME=/tmp/state npm run tdd:quality',
44
+ 'env HARNESS_STATE_HOME=/tmp/state npm run tdd:quality',
45
+ 'command npm run tdd:quality',
46
+ 'bash -lc \'npm run tdd:quality -- evidence.json\'',
47
+ '/usr/bin/node --no-warnings ./tdd/scripts/quality-gate.js evidence.json',
48
+
49
+ ]
50
+ for command in negatives:
51
+ with self.subTest(command=command):
52
+ self.assertFalse(audit.is_tdd_quality_command(command))
53
+ for command in positives:
54
+ with self.subTest(command=command):
55
+ self.assertTrue(audit.is_tdd_quality_command(command))
56
+ for command in [None, 17, [], b'npm run tdd:quality']:
57
+ self.assertIs(audit.is_tdd_quality_command(command), False)
58
+ self.assertIs(audit.is_tdd_quality_command('npm run tdd:quality', depth=5), False)
59
+
60
+ def test_binding_evidence_is_not_gate_execution(self):
61
+ with tempfile.TemporaryDirectory() as directory:
62
+ episode=Path(directory)
63
+ (episode/'analysis.json').write_text(json.dumps({'model':{'engine':'codex'},
64
+ 'workload':'profile-lookup','grader':{'pass':False},'usage':None}))
65
+ (episode/'manifest.json').write_text('{}')
66
+ transcript=episode/'transcript.jsonl'
67
+ def inspect(command):
68
+ transcript.write_text(json.dumps({'type':'item.completed','item':{
69
+ 'type':'command_execution','command':command,
70
+ 'aggregated_output':'','exit_code':0}})+'\n')
71
+ return audit.inspect_episode(episode)['tdd_quality_gate_name_matched_invocation']
72
+ self.assertFalse(inspect('node workflow-disposition.js stage-binding --evidence "npm tdd:quality gate N/A (no package.json in workspace)"'))
73
+ self.assertTrue(inspect('npm run tdd:quality -- evidence.json'))
74
+
75
+ def test_retained_ledger_tdd_flags(self):
76
+ """Recompute only this flag from all 40 immutable exported transcripts."""
77
+ root=Path(__file__).parent
78
+ rows=json.loads((root/'evidence/ledger.json').read_text())
79
+ actual={}
80
+ with tarfile.open(root/'evidence.tar.gz') as archive:
81
+ for member in archive.getmembers():
82
+ if not member.name.endswith('/transcript.jsonl'):
83
+ continue
84
+ parent=member.name.rsplit('/',1)[0]
85
+ row=json.load(archive.extractfile(parent+'/analysis.json'))
86
+ events=[json.loads(line) for line in archive.extractfile(member) if line.strip()]
87
+ tool_commands={tool['id']:tool.get('input',{}).get('command','')
88
+ for event in events for tool in event.get('message',{}).get('content',[])
89
+ if tool.get('type')=='tool_use' and tool.get('id')}
90
+ commands=[]
91
+ for event in events:
92
+ item=event.get('item',{})
93
+ if event.get('type')=='item.completed' and item.get('type')=='command_execution':
94
+ commands.append(item.get('command',''))
95
+ result=event.get('tool_use_result')
96
+ if isinstance(result,dict) and 'stdout' in result:
97
+ commands.extend(tool_commands.get(tool.get('tool_use_id'),'')
98
+ for tool in event.get('message',{}).get('content',[])
99
+ if tool.get('type')=='tool_result')
100
+ key=(parent.split('/')[1],row['model']['engine'],row['workload'],row['arm'],row['repeat'])
101
+ self.assertNotIn(key,actual)
102
+ actual[key]=any(audit.is_tdd_quality_command(command) for command in commands)
103
+ self.assertEqual(len(actual),40)
104
+ self.assertEqual(len(rows),40)
105
+ for row in rows:
106
+ key=(row['series'],row['model']['engine'],row['workload'],row['arm'],row['repeat'])
107
+ self.assertEqual(row.get('tdd_quality_gate_name_matched_invocation', row.get('tdd_quality_gate_executed')),actual[key],key)
108
+
109
+ def test_inventory_not_content(self):
110
+ for command in ['rg --files .harness','find .harness -name SKILL.md','ls .harness','wc -c .harness/fable-mode/SKILL.md']:
111
+ self.assertFalse(audit.is_content_command(command),command)
112
+
113
+ def test_completed_content_commands(self):
114
+ for command in ['cat .harness/fable-mode/SKILL.md',"sed -n '1,20p' .harness/tdd/SKILL.md",'rg core .harness/tdd/SKILL.md']:
115
+ self.assertTrue(audit.is_content_command(command),command)
116
+
117
+ def test_scalar_controller_output_is_not_a_contract(self):
118
+ with tempfile.TemporaryDirectory() as directory:
119
+ episode=Path(directory)
120
+ (episode/'analysis.json').write_text(json.dumps({'model':{'engine':'codex'},
121
+ 'workload':'profile-lookup','grader':{'pass':False},'usage':None}))
122
+ (episode/'manifest.json').write_text('{}')
123
+ (episode/'transcript.jsonl').write_text(json.dumps({'type':'item.completed','item':{
124
+ 'type':'command_execution','command':'node workflow-disposition.js --help',
125
+ 'aggregated_output':'2\nUsage: command syntax','exit_code':2}})+'\n')
126
+ row=audit.inspect_episode(episode)
127
+ self.assertEqual(len(row['observed_errors']),1)
128
+ self.assertEqual(row['steps'],[])
129
+
130
+ def test_batched_dictionary_preserves_active_step(self):
131
+ with tempfile.TemporaryDirectory() as directory:
132
+ episode=Path(directory)
133
+ (episode/'analysis.json').write_text(json.dumps({'model':{'engine':'codex'},
134
+ 'workload':'profile-lookup','grader':{'pass':False},'usage':None}))
135
+ (episode/'manifest.json').write_text('{}')
136
+ events=[{'type':'item.completed','item':{'type':'command_execution',
137
+ 'command':'node workflow-disposition.js start',
138
+ 'aggregated_output':'{"activeStep":{"id":"verify"}}\n{"other":true}',
139
+ 'exit_code':0}}, {'type':'item.completed','item':{'type':'command_execution',
140
+ 'command':'cat .harness/verification-loop/SKILL.md',
141
+ 'aggregated_output':'observed reference content','exit_code':0}}]
142
+ (episode/'transcript.jsonl').write_text('\n'.join(map(json.dumps,events))+'\n')
143
+ row=audit.inspect_episode(episode, documents={'verification-loop/SKILL.md':'observed reference content'})
144
+ self.assertEqual(row['observed_reference_reads'][0]['active_step'],'verify')
145
+
146
+ if __name__=='__main__':unittest.main()
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env python3
2
+ """No model calls: the same offline helper gate used locally and by CI."""
3
+ from pathlib import Path
4
+ import subprocess
5
+ import sys
6
+
7
+ HERE = Path(__file__).resolve().parent
8
+ for file in sorted(HERE.glob('*.py')):
9
+ compile(file.read_text(), str(file), 'exec')
10
+ for file in sorted(HERE.glob('*.test.py')):
11
+ subprocess.run([sys.executable, str(file)], check=True)
12
+ for name in ('host-hook.cjs', 'hook.test.cjs', 'grader.cjs', 'grader.test.cjs'):
13
+ subprocess.run(['node', '--check', str(HERE/name)], check=True)
14
+ for name in ('hook.test.cjs', 'grader.test.cjs'):
15
+ subprocess.run(['node', str(HERE/name)], check=True)
16
+ subprocess.run([sys.executable, str(HERE/'replay.py'), '--check'], check=True)
17
+ subprocess.run([sys.executable, str(HERE/'export.py'), '--scan-only',
18
+ *[str(HERE/name) for name in ('evidence.tar.gz', 'evidence', 'verification', 'preflight')]], check=True)
19
+ print('pilot offline helper gate PASS')
@@ -0,0 +1,7 @@
1
+ {
2
+ "path": "evidence.tar.gz",
3
+ "sha256": "93bcb349c6ebbdcd3673641f3dc23148e73e87a0ec975d31bf31d2731d828723",
4
+ "bytes": 1824930,
5
+ "files": 622,
6
+ "inventory_entries": 621
7
+ }