harness-everything 0.45.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 (38) 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 +17 -0
  5. package/ci/fixtures/doc-obligations/read-boundary/boundary-policy.json +2 -2
  6. package/ci/mechanism-2ax-doc-lifecycle.test.js +2 -1
  7. package/ci/mechanism-325-3b-s2b-capture.test.js +6 -1
  8. package/ci/mechanism-325-f4-projections.test.js +11 -1
  9. package/ci/mechanism-prb-outline-review.test.js +1265 -0
  10. package/docs/adr/DOCS-001-project-docs-config.md +32 -0
  11. package/docs/adr/DOCS-002-adr-identity-supersession-index.md +34 -0
  12. package/docs/adr/DOCS-003-prd-revision-contract.md +29 -0
  13. package/docs/adr/DOCS-004-doc-change-step-type.md +28 -0
  14. package/docs/adr/DOCS-005-doc-obligations-evidence-producer.md +29 -0
  15. package/docs/adr/DOCS-006-reconciliation-pilot.md +50 -0
  16. package/docs/adr/DOCS-007-shared-doc-craft-derived-views.md +31 -0
  17. package/docs/adr/DOCS-008-obligation-abstraction-bounded-consumer.md +30 -0
  18. package/docs/doc-workflow-reconciliation.md +30 -0
  19. package/docs/governed-index.md +8 -0
  20. package/docs/platform-capabilities.md +2 -0
  21. package/harness-everything/SKILL.md +1 -1
  22. package/harness-everything/scripts/doc-evidence.js +55 -0
  23. package/hooks/hooks.json +1 -1
  24. package/hooks/scripts/lib/doc-reconciliation-events.js +121 -9
  25. package/hooks/scripts/lib/doc-reconciliation-pilot.js +128 -15
  26. package/hooks/scripts/lib/doc-reconciliation-provider.js +861 -6
  27. package/hooks/scripts/state-persist.js +10 -0
  28. package/opencode-plugin/plugin.json +1 -1
  29. package/package.json +1 -1
  30. package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
  31. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-events.js +121 -9
  32. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-pilot.js +128 -15
  33. package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +861 -6
  34. package/plugins/harness-everything/hooks/scripts/state-persist.js +10 -0
  35. package/plugins/harness-everything/plugin.json +1 -1
  36. package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
  37. package/plugins/harness-everything/skills/harness-everything/scripts/doc-evidence.js +55 -0
  38. package/sbom.cdx.json +7 -7
@@ -148,6 +148,16 @@ function persistPilotCapture(payload, eventName, sessionId, root) {
148
148
  // Observation-time identity: the workflow and pin in force when the host event was captured.
149
149
  const observed = provider.observedIdentityFor(sessionDir);
150
150
  if (observed) entry.observedIdentity = observed;
151
+ if (eventName === 'PreToolUse' && (entry.tool_name === 'Agent' || entry.tool_name === 'Task')) {
152
+ try {
153
+ const existing = provider.readCaptureView(sessionDir);
154
+ entry.outlineDispatch = existing.tampered
155
+ ? { schema: 'harness.outline-dispatch.v1', state: 'unresolved', reasons: ['capture-view-tampered'] }
156
+ : provider.captureOutlineDispatch({ payload, capture: entry, sessionDir, workspaceRoot: root, captures: existing.records });
157
+ } catch {
158
+ entry.outlineDispatch = { schema: 'harness.outline-dispatch.v1', state: 'unresolved', reasons: ['dispatch-capture-failed'] };
159
+ }
160
+ }
151
161
  // Each capture is one exclusively created event file; the compatibility journal is rebuilt from them (not tamper-proof).
152
162
  provider.writeImmutableEvent(sessionDir, entry);
153
163
  provider.rebuildJournalView(sessionDir);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "harness-everything",
4
- "version": "0.45.0",
4
+ "version": "0.46.0",
5
5
  "description": "Invariant-first engineering harness for routing, verification, and failure recovery while preserving agent autonomy.",
6
6
  "author": {
7
7
  "name": "Miya Daniel",
@@ -4,7 +4,7 @@ description: "Route software/project work through Harness: classify tier/topolog
4
4
  license: Apache-2.0
5
5
  metadata:
6
6
  author: Miya Daniel
7
- version: 0.45.0
7
+ version: 0.46.0
8
8
  ---
9
9
 
10
10
  # Harness Everything
@@ -433,6 +433,61 @@ function evaluateObligation(obligation, context) {
433
433
  return entry ? baselineBound(item, entry) : candidateBound(item, path);
434
434
  };
435
435
 
436
+ if (capability === 'outline-confirmation') {
437
+ const candidates = matching.filter(item => reviewList.includes(item) && item.kind === 'outline-confirmation');
438
+ if (candidates.length !== 1) {
439
+ return result('unresolved', 'none',
440
+ 'outline-confirmation requires one validated pre-draft O/review/handoff/dispatch record and a final D; generic execution and waivers do not qualify',
441
+ candidates.map(item => item.id));
442
+ }
443
+ const item = candidates[0];
444
+ const evidence = isPlainObject(item.outlineEvidence) ? item.outlineEvidence : null;
445
+ const sha = value => isSha256(value);
446
+ const digestsMatch = map => isPlainObject(map)
447
+ && Object.keys(map).sort(compareText).join('\0') === scopePaths.slice().sort(compareText).join('\0')
448
+ && scopePaths.every(path => sha(map[path]));
449
+ const identityValid = Boolean(evidence)
450
+ && evidence.schema === 'harness.outline-confirmation.v1' && evidence.state === 'validated'
451
+ && nonEmptyString(evidence.taskId) && nonEmptyString(evidence.attemptId)
452
+ && /^\d{1,2}$/.test(String(evidence.inventoryRowId || ''))
453
+ && /^[A-Z][A-Z0-9]{1,9}$/.test(String(evidence.domain || ''))
454
+ && sha(evidence.inventoryPinDigest) && sha(evidence.inventoryArtifactDigest)
455
+ && /^[0-9a-f]{40,64}$/.test(String(evidence.baselineCommit || ''))
456
+ && /^[0-9a-f]{40,64}$/.test(String(evidence.outlineCommit || ''))
457
+ && /^[0-9a-f]{40,64}$/.test(String(evidence.draftCommit || ''))
458
+ && /^[0-9a-f]{40,64}$/.test(String(evidence.mergedCommit || ''))
459
+ && evidence.outlineCommit !== evidence.draftCommit
460
+ && evidence.ancestry === 'strict-descendant'
461
+ && sha(evidence.handoffDigest) && sha(evidence.reviewCaptureDigest) && sha(evidence.reviewDigest)
462
+ && sha(evidence.seamDigest) && sha(evidence.dispatchInputDigest) && sha(evidence.writerLeaseDigest)
463
+ && nonEmptyString(evidence.dispatchToolUseId) && nonEmptyString(evidence.coordinatorPrincipal)
464
+ && nonEmptyString(evidence.reviewerPrincipal) && nonEmptyString(evidence.workerPrincipal)
465
+ && evidence.reviewerPrincipal !== evidence.coordinatorPrincipal
466
+ && evidence.reviewerPrincipal !== evidence.workerPrincipal
467
+ && Array.isArray(evidence.targetPaths)
468
+ && evidence.targetPaths.slice().sort(compareText).join('\0') === scopePaths.slice().sort(compareText).join('\0')
469
+ && digestsMatch(evidence.outlineArtifactDigests) && digestsMatch(evidence.draftArtifactDigests)
470
+ && digestsMatch(item.artifactDigests)
471
+ && scopePaths.every(path => evidence.draftArtifactDigests[path] === item.artifactDigests[path]
472
+ && candidateBound(item, path));
473
+ const mergeValid = evidence && (evidence.mergeCorrespondence === null
474
+ || (isPlainObject(evidence.mergeCorrespondence)
475
+ && ['accepted', 'changed'].includes(evidence.mergeCorrespondence.state)
476
+ && Array.isArray(evidence.mergeCorrespondence.targetPaths)
477
+ && evidence.mergeCorrespondence.targetPaths.slice().sort(compareText).join('\0')
478
+ === scopePaths.slice().sort(compareText).join('\0')));
479
+ const outlineProblems = [];
480
+ if (!identityValid) outlineProblems.push('envelope-or-current-D-binding');
481
+ if (!mergeValid) outlineProblems.push('merge-correspondence');
482
+ if (item.baseDigest !== baselineDigest) outlineProblems.push('original-B-digest');
483
+ if (outlineProblems.length) {
484
+ diagnostics.push({ code: 'outline-evidence-unresolved', obligationId,
485
+ message: `the outline evidence is incomplete or inconsistent: ${outlineProblems.join(', ')}` });
486
+ return result('unresolved', 'none', 'outline evidence is incomplete or unbound to the original B and final D', [item.id]);
487
+ }
488
+ return result('observed', 'pass', 'validated independent review of exact O, coordinator handoff, clean one-use dispatch, pinned inventory, and strict O-to-D evidence', [item.id]);
489
+ }
490
+
436
491
  for (const item of matching) {
437
492
  if (executionList.includes(item) && !completeExecution(item)) {
438
493
  diagnostics.push({
package/sbom.cdx.json CHANGED
@@ -2,23 +2,23 @@
2
2
  "$schema": "https://cyclonedx.org/schema/bom-1.7.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.7",
5
- "serialNumber": "urn:uuid:16eef945-b68a-5405-9f2c-9d18949bad33",
5
+ "serialNumber": "urn:uuid:4e82c3bc-ded1-5f78-8aa6-6dd26488f41f",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-10-27T11:52:14.799Z",
8
+ "timestamp": "2026-10-28T00:05:02.172Z",
9
9
  "tools": [
10
10
  {
11
11
  "vendor": "Harness Everything",
12
12
  "name": "generate-sbom.js",
13
- "version": "0.45.0"
13
+ "version": "0.46.0"
14
14
  }
15
15
  ],
16
16
  "component": {
17
17
  "type": "application",
18
- "bom-ref": "pkg:npm/harness-everything@0.45.0",
18
+ "bom-ref": "pkg:npm/harness-everything@0.46.0",
19
19
  "name": "harness-everything",
20
- "version": "0.45.0",
21
- "purl": "pkg:npm/harness-everything@0.45.0"
20
+ "version": "0.46.0",
21
+ "purl": "pkg:npm/harness-everything@0.46.0"
22
22
  }
23
23
  },
24
24
  "components": [
@@ -2033,7 +2033,7 @@
2033
2033
  ]
2034
2034
  },
2035
2035
  {
2036
- "ref": "pkg:npm/harness-everything@0.45.0",
2036
+ "ref": "pkg:npm/harness-everything@0.46.0",
2037
2037
  "dependsOn": [
2038
2038
  "pkg:npm/%40commitlint/cli@19.8.1",
2039
2039
  "pkg:npm/%40commitlint/config-conventional@19.8.1",