harness-everything 0.46.2 → 0.46.3
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +7 -0
- package/ci/mechanism-prb-outline-review.test.js +40 -0
- package/docs/doc-workflow-reconciliation.md +1 -1
- package/hooks/scripts/lib/doc-reconciliation-provider.js +18 -2
- package/opencode-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/plugins/harness-everything/.codex-plugin/plugin.json +1 -1
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +18 -2
- package/plugins/harness-everything/plugin.json +1 -1
- package/sbom.cdx.json +7 -7
|
@@ -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.46.
|
|
13
|
+
"version": "0.46.3",
|
|
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.46.
|
|
4
|
+
"version": "0.46.3",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Miya Daniel"
|
|
7
7
|
},
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.46.3](https://github.com/dyphn1/Harness-everything/compare/v0.46.2...v0.46.3) (2026-10-28)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
* **doc-reconciliation:** clear outline reviewers that stopped before dispatch ([d62bdb8](https://github.com/dyphn1/Harness-everything/commit/d62bdb870523e39a19f63a117557794c21387e3c))
|
|
10
|
+
* **doc-reconciliation:** require a unique reviewer start before clearing it ([99527f6](https://github.com/dyphn1/Harness-everything/commit/99527f6df6729ae8a5db331fc39bed5359797f17))
|
|
11
|
+
|
|
5
12
|
## [0.46.2](https://github.com/dyphn1/Harness-everything/compare/v0.46.1...v0.46.2) (2026-10-28)
|
|
6
13
|
|
|
7
14
|
### Bug Fixes
|
|
@@ -911,6 +911,46 @@ test('outline evidence binds exact task, B, O blobs, independent review, worker
|
|
|
911
911
|
'a delayed write/edit callback from the coordinator remains visible and blocks ambiguous writer history');
|
|
912
912
|
} finally { delayedWriter.cleanup(); }
|
|
913
913
|
|
|
914
|
+
// Live run 2026-10-28: a non-isolated reviewer starts in O; only a stop journaled before the dispatch clears it.
|
|
915
|
+
const reviewerStart = fixture => provider.buildCaptureRecord({ session_id: fixture.sessionId, cwd: fixture.root,
|
|
916
|
+
hook_event_name: 'SubagentStart', agent_id: 'outline-reviewer', agent_type: 'reviewer' }, 'SubagentStart', fixture.root);
|
|
917
|
+
const stoppedReviewer = createOutlineFixture();
|
|
918
|
+
try {
|
|
919
|
+
stoppedReviewer.reviewCaptures.unshift(reviewerStart(stoppedReviewer));
|
|
920
|
+
const completed = stoppedReviewer.finishDraft();
|
|
921
|
+
assert.strictEqual(completed.result.status, 'accepted',
|
|
922
|
+
`a reviewer that started and stopped in O before the dispatch is not a competing writer: ${JSON.stringify(completed.result)}`);
|
|
923
|
+
} finally { stoppedReviewer.cleanup(); }
|
|
924
|
+
for (const [name, arrange] of [
|
|
925
|
+
['reviewer stop after the dispatch', fixture => {
|
|
926
|
+
const stop = fixture.reviewCaptures.findIndex(item => item.event === 'SubagentStop');
|
|
927
|
+
fixture.extraCaptures.push(...fixture.reviewCaptures.splice(stop, 1));
|
|
928
|
+
fixture.reviewCaptures.unshift(reviewerStart(fixture));
|
|
929
|
+
}],
|
|
930
|
+
['reviewer start without a stop', fixture => {
|
|
931
|
+
fixture.reviewCaptures.unshift(provider.buildCaptureRecord({ session_id: fixture.sessionId, cwd: fixture.root,
|
|
932
|
+
hook_event_name: 'SubagentStart', agent_id: 'other-agent', agent_type: 'reviewer' }, 'SubagentStart', fixture.root));
|
|
933
|
+
}],
|
|
934
|
+
['reviewer start after its stop', fixture => { fixture.reviewCaptures.push(reviewerStart(fixture)); }],
|
|
935
|
+
['duplicate reviewer start with one stop before the dispatch', fixture => {
|
|
936
|
+
fixture.reviewCaptures.unshift(reviewerStart(fixture), reviewerStart(fixture));
|
|
937
|
+
}],
|
|
938
|
+
['reviewer start with duplicate stops before the dispatch', fixture => {
|
|
939
|
+
const stop = fixture.reviewCaptures.find(item => item.event === 'SubagentStop');
|
|
940
|
+
fixture.reviewCaptures.unshift(reviewerStart(fixture));
|
|
941
|
+
fixture.reviewCaptures.push({ ...stop, ref: `${stop.ref}:dup`, captureId: `${stop.captureId}:dup` });
|
|
942
|
+
}],
|
|
943
|
+
['reviewer start after the dispatch', fixture => { fixture.extraCaptures.push(reviewerStart(fixture)); }],
|
|
944
|
+
]) {
|
|
945
|
+
const fixture = createOutlineFixture();
|
|
946
|
+
try {
|
|
947
|
+
arrange(fixture);
|
|
948
|
+
const completed = fixture.finishDraft();
|
|
949
|
+
assert.ok(completed.result.diagnostics?.some(item => item.code === 'outline-competing-writer-start'),
|
|
950
|
+
`${name} stays a competing writer start: ${JSON.stringify(completed.result)}`);
|
|
951
|
+
} finally { fixture.cleanup(); }
|
|
952
|
+
}
|
|
953
|
+
|
|
914
954
|
const unqualified = createOutlineFixture();
|
|
915
955
|
try {
|
|
916
956
|
const completed = unqualified.finishDraft();
|
|
@@ -1256,6 +1256,6 @@ flowchart LR
|
|
|
1256
1256
|
| Worker and D | The dispatch key is `(session_id, tool_use_id)`. Exactly one matching Task/Agent result must carry `tool_response.status === 'completed'`; its observed `tool_response.agentId` must map to exactly one `SubagentStart` and one `SubagentStop` with the same `session_id` and `agent_id`. Require PreToolUse < SubagentStart < SubagentStop in journal order, but do not order the completed result against Stop. Both worker events need exact canonical `cwd === workerRoot`. `prompt_id` and `parent_tool_use_id` are not correlation keys; `interrupted` is not completion proof. Async launches, failures, cancellation, missing/duplicate events, replayed IDs, worktree isolation and root mismatch stay unresolved. D is checked against the current candidate separately from O. O must be a strict ancestor of D. A squash may retain the cycle only when a coordinator correspondence record proves identical target blobs between retained pre-merge D and the merged tree; changed bytes need fresh final quality review. |
|
|
1257
1257
|
| Checker outcome | `outline-confirmation` has its own pass/unresolved lane. Generic command success and waivers never satisfy it. No D is incomplete/unresolved. Its result is separate from the aggregate result over every MUST derived from original B→D; an outline pass never waives lint, conflict, quality review, requirement-sync or other MUSTs. |
|
|
1258
1258
|
|
|
1259
|
-
Capture and validation failures stay fail-open to host tools and withhold evidence credit. Unclassified shell commands and writes outside the correlated worker/root remain unresolved. Retries use a fresh attempt, token, clean worktree and immutable handoff; only one non-superseded leaf is current. An identical same-tool-ID/input callback may reuse its stored seam, but repeated PreToolUse records remain ambiguous for evidence credit; changed input or token reuse is unresolved. OpenCode and Codex remain unsupported for positive outline credit.
|
|
1259
|
+
Capture and validation failures stay fail-open to host tools and withhold evidence credit. Unclassified shell commands and writes outside the correlated worker/root remain unresolved. Any other subagent start in the worker root rejects the outline as a competing writer, unless that start and its unique stop are both journaled before the dispatch PreToolUse (for example, a non-isolated outline reviewer). Retries use a fresh attempt, token, clean worktree and immutable handoff; only one non-superseded leaf is current. An identical same-tool-ID/input callback may reuse its stored seam, but repeated PreToolUse records remain ambiguous for evidence credit; changed input or token reuse is unresolved. OpenCode and Codex remain unsupported for positive outline credit.
|
|
1260
1260
|
|
|
1261
1261
|
The current retained Claude qualification does not establish the versioned `claude-outline-dispatch-mapping/2` contract. The outline provider therefore grants no positive live-host credit until a retained Claude capture validates the prompt, coordinator, result status/agent ID, explicit non-background boundary, isolation absence and exact worker-root mapping. Deterministic fixtures exercise the real hook/provider/adapter/checker/pilot path with a synthetic inventory pin; they are mechanism evidence, not live-host behavior or E1 readiness.
|
|
@@ -1452,8 +1452,24 @@ function resolveOutlineEvidence({ safeInput, capture, captures, request, originR
|
|
|
1452
1452
|
if (review.reviewerPrincipal === worker.agent_id) return fail('outline-reviewer-is-draft-worker');
|
|
1453
1453
|
const principals = { author: safeInput.sessionId, executors: journalExecutors(captures, safeInput.sessionId) };
|
|
1454
1454
|
if (!reviewRecordIndependent(review.review, captures, principals)) return fail('outline-review-not-independent');
|
|
1455
|
-
|
|
1456
|
-
|
|
1455
|
+
// An agent whose start and unique stop both precede the dispatch cannot write after the seam; earlier writes
|
|
1456
|
+
// are covered by the clean-O seam check and by unattributedWriters below.
|
|
1457
|
+
const journal = Array.isArray(captures) ? captures : [];
|
|
1458
|
+
const dispatchIndex = journal.indexOf(correlation.pre);
|
|
1459
|
+
const stoppedBeforeDispatch = start => {
|
|
1460
|
+
const lifecycle = event => journal.filter(item => recordOf(item) && item.event === event
|
|
1461
|
+
&& item.session_id === start.session_id && textOf(start.agent_id) && item.agent_id === start.agent_id);
|
|
1462
|
+
// Exactly one Start and one Stop per (session_id, agent_id); a duplicate either way stays ambiguous.
|
|
1463
|
+
const starts = lifecycle('SubagentStart');
|
|
1464
|
+
const stops = lifecycle('SubagentStop');
|
|
1465
|
+
if (starts.length !== 1 || starts[0] !== start || stops.length !== 1) return false;
|
|
1466
|
+
const startIndex = journal.indexOf(start);
|
|
1467
|
+
const stopIndex = journal.indexOf(stops[0]);
|
|
1468
|
+
return dispatchIndex >= 0 && startIndex >= 0 && startIndex < stopIndex && stopIndex < dispatchIndex;
|
|
1469
|
+
};
|
|
1470
|
+
const competingStarts = journal.filter(item => recordOf(item)
|
|
1471
|
+
&& item.event === 'SubagentStart' && item.ref !== worker.ref && sameCanonicalPath(item.cwd, workerRoot)
|
|
1472
|
+
&& !stoppedBeforeDispatch(item));
|
|
1457
1473
|
if (competingStarts.length) return fail('outline-competing-writer-start');
|
|
1458
1474
|
const unattributedWriters = (Array.isArray(captures) ? captures : []).filter(item => possibleWriterCapture(item)
|
|
1459
1475
|
&& (item.agent_id !== worker.agent_id || !sameCanonicalPath(item.cwd, workerRoot)));
|
package/package.json
CHANGED
|
@@ -1452,8 +1452,24 @@ function resolveOutlineEvidence({ safeInput, capture, captures, request, originR
|
|
|
1452
1452
|
if (review.reviewerPrincipal === worker.agent_id) return fail('outline-reviewer-is-draft-worker');
|
|
1453
1453
|
const principals = { author: safeInput.sessionId, executors: journalExecutors(captures, safeInput.sessionId) };
|
|
1454
1454
|
if (!reviewRecordIndependent(review.review, captures, principals)) return fail('outline-review-not-independent');
|
|
1455
|
-
|
|
1456
|
-
|
|
1455
|
+
// An agent whose start and unique stop both precede the dispatch cannot write after the seam; earlier writes
|
|
1456
|
+
// are covered by the clean-O seam check and by unattributedWriters below.
|
|
1457
|
+
const journal = Array.isArray(captures) ? captures : [];
|
|
1458
|
+
const dispatchIndex = journal.indexOf(correlation.pre);
|
|
1459
|
+
const stoppedBeforeDispatch = start => {
|
|
1460
|
+
const lifecycle = event => journal.filter(item => recordOf(item) && item.event === event
|
|
1461
|
+
&& item.session_id === start.session_id && textOf(start.agent_id) && item.agent_id === start.agent_id);
|
|
1462
|
+
// Exactly one Start and one Stop per (session_id, agent_id); a duplicate either way stays ambiguous.
|
|
1463
|
+
const starts = lifecycle('SubagentStart');
|
|
1464
|
+
const stops = lifecycle('SubagentStop');
|
|
1465
|
+
if (starts.length !== 1 || starts[0] !== start || stops.length !== 1) return false;
|
|
1466
|
+
const startIndex = journal.indexOf(start);
|
|
1467
|
+
const stopIndex = journal.indexOf(stops[0]);
|
|
1468
|
+
return dispatchIndex >= 0 && startIndex >= 0 && startIndex < stopIndex && stopIndex < dispatchIndex;
|
|
1469
|
+
};
|
|
1470
|
+
const competingStarts = journal.filter(item => recordOf(item)
|
|
1471
|
+
&& item.event === 'SubagentStart' && item.ref !== worker.ref && sameCanonicalPath(item.cwd, workerRoot)
|
|
1472
|
+
&& !stoppedBeforeDispatch(item));
|
|
1457
1473
|
if (competingStarts.length) return fail('outline-competing-writer-start');
|
|
1458
1474
|
const unattributedWriters = (Array.isArray(captures) ? captures : []).filter(item => possibleWriterCapture(item)
|
|
1459
1475
|
&& (item.agent_id !== worker.agent_id || !sameCanonicalPath(item.cwd, workerRoot)));
|
|
@@ -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.46.
|
|
4
|
+
"version": "0.46.3",
|
|
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",
|
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:
|
|
5
|
+
"serialNumber": "urn:uuid:194f592d-6226-519c-a5b8-9f6750fb3c19",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-10-
|
|
8
|
+
"timestamp": "2026-10-28T05:22:07.321Z",
|
|
9
9
|
"tools": [
|
|
10
10
|
{
|
|
11
11
|
"vendor": "Harness Everything",
|
|
12
12
|
"name": "generate-sbom.js",
|
|
13
|
-
"version": "0.46.
|
|
13
|
+
"version": "0.46.3"
|
|
14
14
|
}
|
|
15
15
|
],
|
|
16
16
|
"component": {
|
|
17
17
|
"type": "application",
|
|
18
|
-
"bom-ref": "pkg:npm/harness-everything@0.46.
|
|
18
|
+
"bom-ref": "pkg:npm/harness-everything@0.46.3",
|
|
19
19
|
"name": "harness-everything",
|
|
20
|
-
"version": "0.46.
|
|
21
|
-
"purl": "pkg:npm/harness-everything@0.46.
|
|
20
|
+
"version": "0.46.3",
|
|
21
|
+
"purl": "pkg:npm/harness-everything@0.46.3"
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
"components": [
|
|
@@ -2033,7 +2033,7 @@
|
|
|
2033
2033
|
]
|
|
2034
2034
|
},
|
|
2035
2035
|
{
|
|
2036
|
-
"ref": "pkg:npm/harness-everything@0.46.
|
|
2036
|
+
"ref": "pkg:npm/harness-everything@0.46.3",
|
|
2037
2037
|
"dependsOn": [
|
|
2038
2038
|
"pkg:npm/%40commitlint/cli@19.8.1",
|
|
2039
2039
|
"pkg:npm/%40commitlint/config-conventional@19.8.1",
|