harness-everything 0.44.0 → 0.46.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 (46) hide show
  1. package/.agents/harness-everything/project-docs.json +3 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/CHANGELOG.md +27 -0
  5. package/ci/fixtures/doc-obligations/read-boundary/boundary-policy.json +2 -2
  6. package/ci/fixtures/doc-obligations/reconciliation-s2a/harness.js +19 -1
  7. package/ci/mechanism-2ax-doc-lifecycle.test.js +2 -1
  8. package/ci/mechanism-325-3b-s2b-capture.test.js +6 -1
  9. package/ci/mechanism-325-f2-doc-craft.test.js +2 -2
  10. package/ci/mechanism-325-f3-derived-views.test.js +5 -2
  11. package/ci/mechanism-325-f4-projections.test.js +11 -1
  12. package/ci/mechanism-pr-a-conflict-check.test.js +507 -0
  13. package/ci/mechanism-prb-outline-review.test.js +1265 -0
  14. package/docs/adr/DOCS-001-project-docs-config.md +32 -0
  15. package/docs/adr/DOCS-002-adr-identity-supersession-index.md +34 -0
  16. package/docs/adr/DOCS-003-prd-revision-contract.md +29 -0
  17. package/docs/adr/DOCS-004-doc-change-step-type.md +28 -0
  18. package/docs/adr/DOCS-005-doc-obligations-evidence-producer.md +29 -0
  19. package/docs/adr/DOCS-006-reconciliation-pilot.md +50 -0
  20. package/docs/adr/DOCS-007-shared-doc-craft-derived-views.md +31 -0
  21. package/docs/adr/DOCS-008-obligation-abstraction-bounded-consumer.md +30 -0
  22. package/docs/doc-workflow-reconciliation.md +32 -1
  23. package/docs/governed-index.md +8 -0
  24. package/docs/platform-capabilities.md +6 -0
  25. package/harness-everything/SKILL.md +1 -1
  26. package/harness-everything/scripts/doc-check.js +84 -6
  27. package/harness-everything/scripts/doc-evidence.js +55 -0
  28. package/harness-everything/scripts/doc-lifecycle.js +51 -6
  29. package/hooks/hooks.json +1 -1
  30. package/hooks/scripts/lib/doc-reconciliation-events.js +138 -9
  31. package/hooks/scripts/lib/doc-reconciliation-pilot.js +131 -15
  32. package/hooks/scripts/lib/doc-reconciliation-provider.js +941 -13
  33. package/hooks/scripts/state-persist.js +10 -0
  34. package/opencode-plugin/plugin.json +1 -1
  35. package/package.json +1 -1
  36. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  37. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-events.js +138 -9
  38. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-pilot.js +131 -15
  39. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +941 -13
  40. package/plugins/harness-everything/hooks/scripts/state-persist.js +10 -0
  41. package/plugins/harness-everything/plugin.json +1 -1
  42. package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
  43. package/plugins/harness-everything/skills/harness-everything/scripts/doc-check.js +84 -6
  44. package/plugins/harness-everything/skills/harness-everything/scripts/doc-evidence.js +55 -0
  45. package/plugins/harness-everything/skills/harness-everything/scripts/doc-lifecycle.js +51 -6
  46. package/sbom.cdx.json +7 -7
@@ -1,8 +1,10 @@
1
1
  {
2
2
  "governed": [
3
3
  { "path": "docs/architecture.md", "role": "reference" },
4
- { "path": "docs/doc-workflow-reconciliation.md", "role": "reference" }
4
+ { "path": "docs/doc-workflow-reconciliation.md", "role": "reference" },
5
+ { "path": "docs/adr/*.md", "role": "adr" }
5
6
  ],
7
+ "domains": ["ROUTE", "GATE", "EVID", "SONE", "DOCS", "DIST"],
6
8
  "derived": [
7
9
  { "path": "docs/governed-index.md", "generator": "node harness-everything/scripts/doc-lifecycle.js index --workspace . --config .agents/harness-everything/project-docs.json --all" }
8
10
  ]
@@ -10,7 +10,7 @@
10
10
  "name": "harness-everything",
11
11
  "source": "./",
12
12
  "description": "Harness OS: an orchestrated agent operating system — tier routing, circuit breaker guardrails, verification gates, WAL session memory, and self-evolving workspace rules.",
13
- "version": "0.44.0",
13
+ "version": "0.46.0",
14
14
  "author": {
15
15
  "name": "Miya Daniel"
16
16
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "harness-everything",
3
3
  "description": "Harness OS: an orchestrated agent operating system — tier routing, circuit breaker guardrails, verification gates, WAL session memory, and self-evolving workspace rules.",
4
- "version": "0.44.0",
4
+ "version": "0.46.0",
5
5
  "author": {
6
6
  "name": "Miya Daniel"
7
7
  },
package/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## [0.46.0](https://github.com/dyphn1/Harness-everything/compare/v0.45.0...v0.46.0) (2026-10-28)
6
+
7
+ ### Features
8
+
9
+ * **doc-reconciliation:** add pre-draft outline review evidence lane ([ac41562](https://github.com/dyphn1/Harness-everything/commit/ac415627369fa0ecadcb19c265d7fe1052d291e1)), closes [#325](https://github.com/dyphn1/Harness-everything/issues/325)
10
+
11
+ ### Bug Fixes
12
+
13
+ * **doc-reconciliation:** canonicalize outline roots for windows short paths ([c508e43](https://github.com/dyphn1/Harness-everything/commit/c508e43141c684e70ee94f4c359e427706a85320))
14
+ * **doc-reconciliation:** keep legacy session-dir keying on the raw workspace root ([f39f533](https://github.com/dyphn1/Harness-everything/commit/f39f53332435e58beb2bb5b01fff3e1707dd18a2))
15
+ * **doc-reconciliation:** observe file-tool writers and deny seal-only retries ([9cbe0ea](https://github.com/dyphn1/Harness-everything/commit/9cbe0ea6b1af7bfadc2be954a6f8337be11eac0c)), closes [#325](https://github.com/dyphn1/Harness-everything/issues/325)
16
+
17
+ ## [0.45.0](https://github.com/dyphn1/Harness-everything/compare/v0.44.0...v0.45.0) (2026-10-27)
18
+
19
+ ### Features
20
+
21
+ * **doc-lifecycle:** produce conflict-check from a full-corpus assessment ([ec596e0](https://github.com/dyphn1/Harness-everything/commit/ec596e02de554f14778f7790551b6990a50dd0b6)), closes [#325](https://github.com/dyphn1/Harness-everything/issues/325)
22
+
5
23
  ## [0.44.0](https://github.com/dyphn1/Harness-everything/compare/v0.43.1...v0.44.0) (2026-10-27)
6
24
 
7
25
  ### Features
@@ -16,6 +34,15 @@ All notable changes to this project are documented in this file.
16
34
 
17
35
  ## [Unreleased]
18
36
 
37
+ ### Added
38
+
39
+ - **doc-governance:** declare six ADR domains (ROUTE, GATE, EVID, SONE, DOCS, DIST) and record the eight DOCS ADRs (DOCS-001 to DOCS-008) for already-in-effect document-lifecycle mechanisms.
40
+
41
+ ### Features
42
+
43
+ * **doc-lifecycle:** add complete full-corpus conflict-check evidence with snapshot-bound scope and corpus identity.
44
+ * **doc-reconciliation:** add a dedicated pre-draft outline review lane bound to the pinned inventory and exact O→D Git cycle; positive live-host credit remains gated.
45
+
19
46
  ### Fixed
20
47
 
21
48
  - **doc-governance:** allow regular governed-content revisions and expand base-owned governed/derived globs against Git trees, while retaining review for membership, structural, policy, trust-surface, fixture, and derived-output changes; run the guard in its own CI job.
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "canonicalization": "estree-alpha-target-v2",
13
13
  "moduleFingerprints": {
14
- "evaluator": "21e5922f94a0ffd6a2fa4c6c14becfd6680854df342d31c7e0dfd74d776feb6d",
14
+ "evaluator": "d2097839b602b1266f02f31168e1f72e6dab2d88f796d1dc64df21e2cf3afded",
15
15
  "capture": "95d0ca61505914e6c7cfc4603556f028208bd44203167397896ce0bf4ec58ef7"
16
16
  },
17
17
  "targets": [
@@ -25,7 +25,7 @@
25
25
  "module": "evaluator",
26
26
  "name": "evaluateObligation",
27
27
  "ruleIds": ["CAPTURE_CALL_SITES"],
28
- "fingerprint": "fdeabb3d9ddebec17cef5c0eb2fe6ff846af5c0b29eb2a701e3aea566276f82e"
28
+ "fingerprint": "643127bd802817a0236b753516641de062b5af995969895cfca909a387dfd2b4"
29
29
  },
30
30
  {
31
31
  "module": "evaluator",
@@ -400,7 +400,7 @@ function buildEvents(snapshot, repo, vec) {
400
400
  originRef: `fake-origin:event:${ref}`
401
401
  };
402
402
  if (kind === 'execution') {
403
- events[ref] = {
403
+ const event = {
404
404
  ...common,
405
405
  kind: 'execution',
406
406
  principalId: PRINCIPALS.executor,
@@ -415,6 +415,24 @@ function buildEvents(snapshot, repo, vec) {
415
415
  resultRef: `result-${capability}`,
416
416
  artifactDigests: clone(artifactDigests)
417
417
  };
418
+ if (capability === 'conflict-check') {
419
+ const { documentCorpusPaths } = require(path.join(ROOT, 'harness-everything', 'scripts', 'doc-lifecycle.js'));
420
+ const configSource = snapshot.config.capture.sources.find(item => item.path === CONFIG_REL && item.presence === 'present');
421
+ const configBytes = Buffer.isBuffer(configSource?.bytes) ? configSource.bytes : Buffer.from(configSource?.bytes?.data || []);
422
+ const corpusPaths = documentCorpusPaths(snapshot.candidate.records, snapshot.config.resolution.config);
423
+ event.corpusBinding = {
424
+ complete: true,
425
+ paths: corpusPaths,
426
+ digests: Object.fromEntries(corpusPaths.map(relative => [relative,
427
+ snapshot.candidate.records.find(item => item.path === relative && item.presence === 'present')?.digest])),
428
+ config: { path: CONFIG_REL, digest: sha256(configBytes) },
429
+ baseCommit: snapshot.originContext.baseline.commit,
430
+ baselineDigest: snapshot.identity.baselineDigest,
431
+ candidateDigest: snapshot.identity.candidateDigest,
432
+ configIdentityDigest: snapshot.identity.configDigest,
433
+ };
434
+ }
435
+ events[ref] = event;
418
436
  } else {
419
437
  events[ref] = {
420
438
  ...common,
@@ -1694,7 +1694,8 @@ checkCase('2ax. frozen Git-object guard with bootstrap and tamper controls', ()
1694
1694
  path.join(root, 'ci/fixtures/doc-lifecycle/scenarios')
1695
1695
  );
1696
1696
  const policy = JSON.parse(fs.readFileSync(path.join(REPOSITORY_ROOT, '.agents/harness-everything/project-docs.json'), 'utf8'));
1697
- for (const record of [...policy.governed, ...policy.derived]) writeRelative(root, record.path, `baseline ${record.path}\n`);
1697
+ // glob records (e.g. docs/adr/*.md) are policy patterns, not files; '*' is not a valid Windows filename
1698
+ for (const record of [...policy.governed, ...policy.derived]) if (!record.path.includes('*')) writeRelative(root, record.path, `baseline ${record.path}\n`);
1698
1699
  writeRelative(root, 'docs/ordinary.md', 'baseline ordinary document\n');
1699
1700
  return { root, base: commitFixture(root, 'fixture baseline') };
1700
1701
  }
@@ -282,6 +282,11 @@ function isolatedRunProvider(leg, input, reference) {
282
282
  const lib = path.join(dir, 'hooks', 'scripts', 'lib');
283
283
  fs.mkdirSync(lib, { recursive: true });
284
284
  fs.copyFileSync(path.join(leg.lib, 'doc-reconciliation-provider.js'), path.join(lib, 'doc-reconciliation-provider.js'));
285
+ fs.copyFileSync(path.join(leg.lib, 'workflow-isolation.js'), path.join(lib, 'workflow-isolation.js'));
286
+ const sharedScriptsLib = path.join(dir, 'scripts', 'lib');
287
+ fs.mkdirSync(sharedScriptsLib, { recursive: true });
288
+ fs.copyFileSync(path.resolve(leg.lib, '../../../scripts/lib/verification-contract.js'),
289
+ path.join(sharedScriptsLib, 'verification-contract.js'));
285
290
  const provider = require(path.join(lib, 'doc-reconciliation-provider.js')).createClaudeOriginProvider(H.providerInput(input));
286
291
  const response = provider.resolveEvent({ reference, identity: H.providerIdentity() });
287
292
  const context = provider.resolveContext({ workspaceRoot: H.FIXED.workspaceRoot, workflowId: H.FIXED.workflowId, sessionId: H.FIXED.sessionId });
@@ -523,7 +528,7 @@ runner.run('R2C1-MANIFEST-SUBAGENT-HOOKS', [], (_mods, leg) => {
523
528
  const hasStatePersist = group => ((group && group.hooks) || []).some(handler =>
524
529
  handler.type === 'command' && /state-persist\.js/.test(handler.command || ''));
525
530
  for (const route of [
526
- { event: 'PreToolUse', matcher: 'Bash|PowerShell|Task|Agent' },
531
+ { event: 'PreToolUse', matcher: 'Bash|PowerShell|Task|Agent|Write|Edit|apply_patch' },
527
532
  { event: 'PostToolUse', matcher: 'Task|Agent' },
528
533
  { event: 'SubagentStart' },
529
534
  { event: 'SubagentStop' },
@@ -502,8 +502,8 @@ function mp2Apply() {
502
502
  const dir = scriptCopy('f2 doc craft mp2 ');
503
503
  const file = path.join(dir, MODULE);
504
504
  const original = fs.readFileSync(file, 'utf8');
505
- const emitMatches = [...original.matchAll(/return emit\(result[^;]*\);/g)];
506
- if (emitMatches.length !== 1) throw new ProbeApplyError(`could not uniquely locate the final emit (${emitMatches.length} candidates); update this probe for the green shape`);
505
+ const emitMatches = [...original.matchAll(/return emit\(result, lintExit === 1 \|\| broken\.length \? 1 : 0\);/g)];
506
+ if (emitMatches.length !== 1) throw new ProbeApplyError(`could not uniquely locate the plain-check exit mapping (${emitMatches.length} candidates); update this probe for the green shape`);
507
507
  const injected = `if (result.reminders && result.reminders.length) return emit(result, 1);\n ${emitMatches[0][0]}`;
508
508
  fs.writeFileSync(file, original.replace(emitMatches[0][0], injected));
509
509
  return dir;
@@ -356,8 +356,11 @@ function caseD13(leg) {
356
356
  const candidate = path.join(dir, 'candidate.md');
357
357
  fs.writeFileSync(candidate, Buffer.from(TARGET_BYTES.toString('utf8').replace(/\n/g, '\r\n'), 'utf8'));
358
358
  const result = runCompare(leg.dir, { workspace: ws, config: CONFIG, view: 'docs/index.md', candidate, status: 'ok' });
359
- same(result.status, 1, 'exit');
360
- if (!JSON.stringify(jsonOut(result)).includes('stale')) throw new Error(`CRLF candidate accepted: ${truncate(result.stdout)}`);
359
+ let comparison;
360
+ try { comparison = JSON.parse(result.stdout); } catch { comparison = null; }
361
+ const detail = `compare-derived JSON: ${JSON.stringify(comparison)}; stdout: ${truncate(result.stdout)}; stderr: ${truncate(result.stderr)}`;
362
+ same(result.status, 1, `exit; ${detail}`);
363
+ if (!comparison || !JSON.stringify(comparison).includes('stale')) throw new Error(`CRLF candidate accepted; ${detail}`);
361
364
  }
362
365
  assertPerLeg('case-d13:crlf-candidate-not-normalized', leg => caseD13(leg));
363
366
 
@@ -267,6 +267,11 @@ function partB() {
267
267
  const copy = path.join(tmp, 'hooks', 'scripts', 'lib');
268
268
  fs.mkdirSync(copy, { recursive: true });
269
269
  fs.copyFileSync(path.join(leg.lib, 'doc-reconciliation-provider.js'), path.join(copy, 'doc-reconciliation-provider.js'));
270
+ fs.copyFileSync(path.join(leg.lib, 'workflow-isolation.js'), path.join(copy, 'workflow-isolation.js'));
271
+ const sharedScriptsLib = path.join(tmp, 'scripts', 'lib');
272
+ fs.mkdirSync(sharedScriptsLib, { recursive: true });
273
+ fs.copyFileSync(path.resolve(leg.lib, '../../../scripts/lib/verification-contract.js'),
274
+ path.join(sharedScriptsLib, 'verification-contract.js'));
270
275
  const live = path.join(tmp, LIVE_REL);
271
276
  fs.mkdirSync(live, { recursive: true });
272
277
  fs.writeFileSync(path.join(live, 'README.md'), 'garbage\n');
@@ -301,9 +306,14 @@ const RED_LIVE_GATE = 'missing-implementation: the retained live gate accepts an
301
306
  function partBPreloadBoundary(leg) {
302
307
  const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'f4-preload-'));
303
308
  try {
304
- const entry = path.join(tmp, 'entry');
309
+ const entry = path.join(tmp, 'hooks', 'scripts');
305
310
  fs.mkdirSync(path.join(entry, 'lib'), { recursive: true });
306
311
  fs.copyFileSync(path.join(leg.lib, 'doc-reconciliation-provider.js'), path.join(entry, 'lib', 'doc-reconciliation-provider.js'));
312
+ fs.copyFileSync(path.join(leg.lib, 'workflow-isolation.js'), path.join(entry, 'lib', 'workflow-isolation.js'));
313
+ const sharedScriptsLib = path.join(tmp, 'scripts', 'lib');
314
+ fs.mkdirSync(sharedScriptsLib, { recursive: true });
315
+ fs.copyFileSync(path.resolve(leg.lib, '../../../scripts/lib/verification-contract.js'),
316
+ path.join(sharedScriptsLib, 'verification-contract.js'));
307
317
  const probe = path.join(entry, 'probe.js');
308
318
  fs.writeFileSync(probe, [
309
319
  "const provider = require('./lib/doc-reconciliation-provider.js');",