harness-everything 0.37.0 → 0.39.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/AGENTS.md +79 -63
- package/CHANGELOG.md +41 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/README.md +76 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/a-reviews-b.md +191 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/b-reviews-a.md +100 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/baseline-probes.log +47 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/bom-red.log +85 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/bom-transition.txt +25 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/coordinator-probes.txt +84 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/cross-suite.txt +18 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/final-bom.log +3 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/final-consistency.log.gz +0 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/final-core.log +198 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/final-probes.log +27 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/final-producer.log +83 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/final-review.md +89 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/final-transitions.log +5 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/implementation-a.md +166 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/implementation-b.md +264 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/logs.sha256 +15 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/peer-a-probe.log +62 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/peer-a-probe.txt +313 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/peer-b-probe.log +51 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/peer-b-probe.txt +94 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/semantic-transitions.txt +25 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/source.sha256 +9 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/tests-a-on-b-core.log +201 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/tests-a-on-b-producer.log +82 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/tests-b-on-a-core.log +197 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/tests-b-on-a-producer.log +82 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/verify-all.log.gz +0 -0
- package/benchmarks/results/reviews/pr353-r6-2026-10-22/verify-gate-summary.json +22 -0
- package/ci/fixtures/doc-obligations/reconciliation-prep/cases.json +70 -11
- package/ci/fixtures/doc-obligations/reconciliation-prep/pending-red.json +24 -556
- package/ci/fixtures/doc-obligations/reconciliation-s1/cases.json +6842 -0
- package/ci/fixtures/doc-obligations/reconciliation-s1/fail-session-writes.js +116 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2a/harness.js +489 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2a/vectors.json +617 -0
- package/ci/lib/doc-reconciliation-prep-fixtures.js +116 -10
- package/ci/mechanism-325-3b-preparation.test.js +8 -8
- package/ci/mechanism-325-3b-s1-review.test.js +831 -0
- package/ci/mechanism-325-3b-s1.test.js +188 -0
- package/ci/mechanism-325-3b-s2a-core.test.js +840 -0
- package/ci/mechanism-325-3b-s2a-producer.test.js +564 -0
- package/ci/prep/doc-reconciliation-red.js +2 -1
- package/docs/doc-workflow-reconciliation.md +574 -26
- package/docs/document-lifecycle.md +4 -4
- package/harness-everything/SKILL.md +1 -1
- package/harness-everything/scripts/doc-lifecycle.js +1 -1
- package/harness-everything/scripts/project-docs-resolver.js +42 -8
- package/hooks/scripts/lib/doc-reconciliation-core.js +280 -0
- package/hooks/scripts/lib/doc-reconciliation-events.js +141 -0
- package/hooks/scripts/lib/doc-reconciliation-pilot.js +152 -0
- package/hooks/scripts/lib/doc-reconciliation-producer.js +206 -0
- package/hooks/scripts/lib/workflow-obligations.js +44 -0
- package/hooks/scripts/workflow-disposition.js +2 -0
- package/hooks/scripts/workflow-stop-gate.js +24 -1
- package/multi-agent-workspace/SKILL.md +1 -1
- package/multi-agent-workspace/scripts/project-docs-resolver.js +42 -8
- 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-core.js +280 -0
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-events.js +141 -0
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-pilot.js +152 -0
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-producer.js +206 -0
- package/plugins/harness-everything/hooks/scripts/lib/workflow-obligations.js +44 -0
- package/plugins/harness-everything/hooks/scripts/workflow-disposition.js +2 -0
- package/plugins/harness-everything/hooks/scripts/workflow-stop-gate.js +24 -1
- package/plugins/harness-everything/plugin.json +1 -1
- package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
- package/plugins/harness-everything/skills/harness-everything/scripts/doc-lifecycle.js +1 -1
- package/plugins/harness-everything/skills/harness-everything/scripts/project-docs-resolver.js +42 -8
- package/plugins/harness-everything/skills/multi-agent-workspace/SKILL.md +1 -1
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/project-docs-resolver.js +42 -8
- package/plugins/harness-everything/skills/to-spec/SKILL.md +1 -1
- package/plugins/harness-everything/skills/to-spec/scripts/project-docs-resolver.js +42 -8
- package/sbom.cdx.json +7 -7
- package/to-spec/SKILL.md +1 -1
- package/to-spec/scripts/project-docs-resolver.js +42 -8
|
@@ -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.
|
|
13
|
+
"version": "0.39.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.
|
|
4
|
+
"version": "0.39.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Miya Daniel"
|
|
7
7
|
},
|
package/AGENTS.md
CHANGED
|
@@ -1,93 +1,109 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Operating guide for AI agents working inside the Harness-everything repository — layout, change rules, quality gates, and release policy.
|
|
2
|
+
description: Operating guide for AI agents working inside the Harness-everything repository — how we work, layout, change rules, quality gates, and release policy.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# AGENTS.md — Working in This Repository
|
|
6
6
|
|
|
7
|
-
You are modifying **Harness**: an orchestrated agent operating system (skills + hooks/plugins + routing) for AI coding agents. Changes here ship to real agent sessions
|
|
7
|
+
You are modifying **Harness**: an orchestrated agent operating system (skills + hooks/plugins + routing) for AI coding agents. Changes here ship to real agent sessions. A vague `SKILL.md`, a stale manifest, a contradictory platform claim or a bypassable selected workflow can misroute other people's agents. Precision is the product.
|
|
8
|
+
|
|
9
|
+
## How We Work
|
|
10
|
+
|
|
11
|
+
Harness exists to put agents on the **fastest path to a working result**, not to fence them in. Prefer mechanisms that make the right action the easy one over written demands that agents talk themselves out of.
|
|
12
|
+
|
|
13
|
+
```mermaid
|
|
14
|
+
flowchart LR
|
|
15
|
+
A["1. Wire the whole path<br/>(smallest end-to-end version)"] --> B["2. Record a baseline<br/>on that path"]
|
|
16
|
+
B --> C["3. Improve one thing per stage,<br/>compare to the baseline"]
|
|
17
|
+
C --> D["4. Lock behaviour<br/>with tests against drift"]
|
|
18
|
+
C -. "effect not measurable<br/>on the full path" .-> A
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
- **Whole path first.** Do not polish details or add tests for parts that are not connected yet.
|
|
22
|
+
- **Stages follow the full path.** A stage whose effect cannot be measured end to end is split wrongly.
|
|
23
|
+
- **Mechanisms over mandates.** Put recurring rules in CI, hooks, mods or templates so actions match them naturally. A new prose MUST is the last resort.
|
|
24
|
+
- **Dogfood the rules.** Docs, packets and reports written here follow the same doc rules Harness ships.
|
|
25
|
+
- **Coordinator role.** In multi-agent work the coordinator dispatches and analyses. Agents and the reviewer check each step; the coordinator re-verifies everything at the final stage.
|
|
26
|
+
|
|
27
|
+
### Writing docs (this file included)
|
|
28
|
+
|
|
29
|
+
1. **Mermaid** for anything that can be drawn: flows, stages, dependencies, state.
|
|
30
|
+
2. **Short bullets or tables** for rules and facts.
|
|
31
|
+
3. **Prose** only for detail that needs it; link it rather than inline it.
|
|
8
32
|
|
|
9
33
|
## Repository Layout
|
|
10
34
|
|
|
11
35
|
| Path | What it is |
|
|
12
36
|
|---|---|
|
|
13
37
|
| `<skill-name>/SKILL.md` | One canonical skill per top-level directory. Frontmatter: `name`, `description`, `metadata.author`, `metadata.version`. |
|
|
14
|
-
| `hooks/` | Claude Code lifecycle
|
|
38
|
+
| `hooks/` | Claude Code lifecycle hooks and shared mechanisms (circuit breaker, workflow/action/scope guards, stop gates). Not every host packages every hook. |
|
|
15
39
|
| `harness-everything/scripts/` | Runtime: kernel/tier routing, workflow contract, verification, bootstrap, self-heal. |
|
|
16
|
-
| `opencode-plugin/` | OpenCode native plugin
|
|
40
|
+
| `opencode-plugin/` | OpenCode native plugin. Mechanism-tested, with partial live-host evidence (see the boundary below). |
|
|
17
41
|
| `.agents/plugins/` + `plugins/harness-everything/` | Local OpenAI/Codex marketplace + `.codex-plugin` package with canonical skill copies and packaged session/prompt hooks. |
|
|
18
42
|
| `submission/openai/` | Public OpenAI Skills-only listing/test inputs. The public artifact does not include local `.codex-plugin` lifecycle hooks. |
|
|
19
43
|
| `evals/<skill>/` | Trigger/routing eval per skill (waza format). Required for every canonical routed skill. |
|
|
20
|
-
| `behavioral-evals/` | LLM-behavior cases run via headless CLI sessions
|
|
44
|
+
| `behavioral-evals/` | LLM-behavior cases run via headless CLI sessions, structurally validated by CI. |
|
|
21
45
|
| `benchmarks/` | BENCHMARK_SOP fixtures and recorded results. Evidence lives here or nowhere. |
|
|
22
|
-
| `.claude-plugin/` | Claude Code plugin
|
|
23
|
-
| `docs/platform-capabilities.md` | Canonical
|
|
24
|
-
| `docs/repository-contract.md` | Generated
|
|
25
|
-
| `.nvmrc` | Primary
|
|
26
|
-
| `docs/`, `references/` | Philosophy, architecture, workflow
|
|
46
|
+
| `.claude-plugin/` | Claude Code plugin manifests. Must list exactly the on-disk canonical skills. |
|
|
47
|
+
| `docs/platform-capabilities.md` | Canonical platform/install/enforcement/evidence matrix. |
|
|
48
|
+
| `docs/repository-contract.md` | Generated Node/workflow/action/gate contract. Regenerate with `npm run docs:sync`; never hand-edit. |
|
|
49
|
+
| `.nvmrc` | Primary dev/CI Node runtime. `package.json#engines.node` stays the supported minimum. |
|
|
50
|
+
| `docs/`, `references/` | Philosophy, architecture, workflow docs, shared checklists. |
|
|
27
51
|
|
|
28
52
|
## OpenCode evidence boundary
|
|
29
53
|
|
|
30
|
-
The retained [OpenCode evidence](benchmarks/results/live-host/opencode-2026-09-16/README.md) supports project-scope `.js` loading and edit/verification state on OpenCode 1.18.31 (macOS).
|
|
31
|
-
|
|
32
|
-
## Non-Negotiable Change Rules
|
|
33
|
-
|
|
34
|
-
1. **Every canonical SKILL.md keeps ≤ 500 tokens** (hard CI gate) and must contain `## USE FOR:` and `## DO NOT USE FOR:`. Deep detail goes in references/guides.
|
|
35
|
-
2. **Descriptions are routing surfaces.** Differentiate neighboring skills deliberately; `test:collision` guards overlap.
|
|
36
|
-
3. **A new canonical skill ships with a routing eval.** Positive task `description:` must exactly match the skill frontmatter description.
|
|
37
|
-
4. **Release version policy:** normal PRs do not manually bump package/plugin versions. `semantic-release` owns stable SemVer and `scripts/sync-release-version.js` owns distribution synchronization. Nested sub-skills inherit their parent skill version.
|
|
38
|
-
5. **Distribution manifests are generated facts:** add/remove/rename changes must sync every copied/listed distribution. Run `npm run plugin:sync`, `npm run test:consistency`, and `npm run test:plugin:openai`.
|
|
39
|
-
6. **Platform capability claims are tested contracts.** Update `docs/platform-capabilities.md` with integration behavior changes. Package/mechanism evidence is not live-host evidence, and public Skills-only behavior does not include local lifecycle hooks.
|
|
40
|
-
7. **Runtime/workflow claims are generated facts.** `package.json`, `.nvmrc`, Dockerfile, and active workflows feed `scripts/repository-contract.js`; run `npm run docs:sync` after relevant changes.
|
|
41
|
-
8. **CHANGELOG.md keeps pending human-authored notes under `[Unreleased]`.** Semantic-release owns stable headings/tags/release notes.
|
|
42
|
-
9. **Conventional Commit type is release input.** Breaking→major; `feat`→minor; `fix`/`perf`/`refactor`/`build`/`revert`→patch; docs/test/ci/style/chore do not release by themselves.
|
|
43
|
-
10. **Selected workflow is a semantic contract; tactics remain flexible.** Compose ordered requirement steps with declared required/optional skill or reference bindings. Load/resolve bindings only when their step (or dependency-ready Fable stage) is active; required bindings MUST resolve before that step passes, and applicable skill core contracts MUST be followed. Unknown/unavailable bindings stay visible and unresolved. Selected-topology obligations MUST resolve; missing host evidence may produce reminders, not a persistent Harness lock.
|
|
44
|
-
11. **User-visible Harness Status is mandatory for non-trivial work.** Render one readable Markdown block headed `### 🚦 Harness Status`, with bullet-aligned bold `Current`, `Read / Evidence`, `Next`, plus optional `Risk / Blocked`; use nested evidence bullets when useful. Emit it before substantive execution, after major phases, on direction changes, during long work at meaningful boundaries, and before final completion. The routing checkpoint is internal source state, not a second user-facing block. This semantic MUST does not create a hard lock.
|
|
45
|
-
12. **Tier-3/Fable isolation disposition is mandatory before broad mutation.** Use/reuse a verified linked Git worktree, or record an explicit degraded fallback when isolation is unavailable or the user explicitly chooses to stay in place. Ordinary isolation SHOULD be used when it materially reduces collision/risk. Failure to isolate is a visible semantic gap, not a Harness-owned deadlock. See [workflow-runtime.md](docs/workflow-runtime.md).
|
|
46
|
-
13. **Use contract strength deliberately.** MUST = required semantic obligation; SHOULD = expected default with an evidence-based exception; MAY = optional optimization. Do not use recommend/prefer/advisory/guidance to weaken a MUST. See [philosophy.md](docs/philosophy.md#contract-strength-must--should--may).
|
|
47
|
-
14. **The turn label line is mandatory on every turn, trivial ones included.** End the final message of every turn — short answers, lookups, questions back to the user — with one hidden `<!-- harness-label {...} -->` line: your own post-work judgement of validity, context dependence, tier, intents, workflow and skills used ([docs/routing.md](docs/routing.md#turn-label-line)). It records data and never gates routing.
|
|
54
|
+
The retained [OpenCode evidence](benchmarks/results/live-host/opencode-2026-09-16/README.md) supports project-scope `.js` loading and edit/verification state on OpenCode 1.18.31 (macOS).
|
|
48
55
|
|
|
49
|
-
|
|
56
|
+
- The final snapshot is post-reset (`hardLock: false`, `count: 1`).
|
|
57
|
+
- Hard lock is only an interactive observation with no retained blocked-tool trace.
|
|
58
|
+
- Reflection was operator-seeded, then agent-rewritten. Agent-controlled state deletion resets the breaker.
|
|
59
|
+
- Global scope, npm-package installation, and other OpenCode versions remain unverified.
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
npm test
|
|
55
|
-
npm run test:mutations
|
|
56
|
-
npm run test:mechanism
|
|
57
|
-
npm run test:consistency
|
|
58
|
-
npm run test:repo-contract
|
|
59
|
-
npm run test:docs:capabilities
|
|
60
|
-
npm run test:references
|
|
61
|
-
npm run test:release
|
|
62
|
-
npm run test:collision
|
|
63
|
-
npm run test:routing:skills
|
|
64
|
-
npm run test:routing:invariants
|
|
65
|
-
npm run test:plugin:openai
|
|
66
|
-
npm run test:plugin:submission
|
|
67
|
-
npm run test:platform:compatibility
|
|
68
|
-
npm run test:portability
|
|
69
|
-
```
|
|
61
|
+
## Change Rules
|
|
70
62
|
|
|
71
|
-
|
|
63
|
+
**Skills and routing**
|
|
72
64
|
|
|
73
|
-
|
|
65
|
+
1. **Every canonical SKILL.md keeps ≤ 500 tokens** (CI gate) and contains `## USE FOR:` and `## DO NOT USE FOR:`. Detail goes in references/guides.
|
|
66
|
+
2. **Descriptions are routing surfaces.** Differentiate neighbouring skills deliberately; `test:collision` guards overlap.
|
|
67
|
+
3. **A new canonical skill ships with a routing eval.** The positive task `description:` exactly matches the skill frontmatter description.
|
|
74
68
|
|
|
75
|
-
|
|
76
|
-
waza check <skill-dir>
|
|
77
|
-
waza spec verify <skill> evals/<skill>/eval.yaml --fail --threshold 1
|
|
78
|
-
waza tokens check
|
|
79
|
-
```
|
|
69
|
+
**Release and distribution**
|
|
80
70
|
|
|
81
|
-
|
|
71
|
+
4. **Versions:** normal PRs never bump versions. `semantic-release` owns SemVer; `scripts/sync-release-version.js` syncs distributions. Nested sub-skills inherit their parent's version.
|
|
72
|
+
5. **Distribution manifests are generated facts.** After add/remove/rename run `npm run plugin:sync`, `npm run test:consistency` and `npm run test:plugin:openai`.
|
|
73
|
+
6. **Platform capability claims are tested contracts.** Update `docs/platform-capabilities.md` with integration changes. Package/mechanism evidence is not live-host evidence; public Skills-only behavior has no local lifecycle hooks.
|
|
74
|
+
7. **Runtime/workflow claims are generated facts.** `package.json`, `.nvmrc`, Dockerfile and active workflows feed `scripts/repository-contract.js`; run `npm run docs:sync` after relevant changes.
|
|
75
|
+
8. **CHANGELOG.md:** human notes go under `[Unreleased]`; semantic-release owns stable headings, tags and release notes.
|
|
76
|
+
9. **Conventional Commit type is release input:** breaking→major, `feat`→minor, `fix`/`perf`/`refactor`/`build`/`revert`→patch; docs/test/ci/style/chore do not release alone.
|
|
82
77
|
|
|
83
|
-
|
|
78
|
+
**Workflow behaviour**
|
|
84
79
|
|
|
85
|
-
|
|
80
|
+
10. **Selected workflow is a semantic contract; tactics remain flexible.** Compose ordered requirement steps with declared required/optional skill or reference bindings. Resolve a binding only when its step (or dependency-ready Fable stage) is active; required bindings MUST resolve before that step passes, and applicable skill core contracts MUST be followed. Unknown/unavailable bindings stay visible. Selected-topology obligations MUST resolve; missing host evidence yields reminders, not a persistent Harness lock.
|
|
81
|
+
11. **User-visible Harness Status is mandatory for non-trivial work.** One Markdown block headed `### 🚦 Harness Status` with bold `Current`, `Read / Evidence`, `Next`, optional `Risk / Blocked`; use nested evidence bullets when useful. Emit it before substantive execution, after major phases, on direction changes, at long-run boundaries and before completion. The routing checkpoint is internal state, not a second block. Not a hard lock.
|
|
82
|
+
12. **Tier-3/Fable isolation disposition is mandatory before broad mutation.** Use a verified linked Git worktree, or record an explicit degraded fallback when isolation is unavailable or the user chooses to stay in place. Ordinary isolation SHOULD be used when it materially reduces collision risk. Failure to isolate is a visible gap, not a Harness deadlock. See [workflow-runtime.md](docs/workflow-runtime.md).
|
|
83
|
+
13. **Use contract strength deliberately** ([philosophy.md](docs/philosophy.md#contract-strength-must--should--may)): MUST = required semantic obligation, SHOULD = default with an evidence-based exception, MAY = optional. Do not use recommend/prefer/advisory/guidance to weaken a MUST.
|
|
84
|
+
14. **The turn label line is mandatory on every turn, trivial ones included.** End each turn's final message with one hidden `<!-- harness-label {...} -->` line giving your post-work judgement ([docs/routing.md](docs/routing.md#turn-label-line)). It records data and never gates routing.
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
## Verification Before You Claim Done
|
|
87
|
+
|
|
88
|
+
```mermaid
|
|
89
|
+
flowchart LR
|
|
90
|
+
F["npm run verify:all -- --fast<br/>(pre-push subset)"] --> V["npm run verify:all<br/>(CI order, PASS/FAIL/UNCHECKED report)"]
|
|
91
|
+
V -. optional .-> C["-- --clean<br/>(fresh worktree of HEAD)"]
|
|
92
|
+
V -. optional .-> N["-- --node22<br/>(Node 22 smoke lane)"]
|
|
93
|
+
```
|
|
88
94
|
|
|
89
|
-
- `
|
|
90
|
-
-
|
|
91
|
-
-
|
|
95
|
+
- `npm run verify:all` runs every CI gate category and prints paste-ready evidence. Individual gates: `npm test`, `npm run test:mutations`, `test:mechanism`, `test:consistency`, `test:repo-contract`, `test:docs:capabilities`, `test:references`, `test:release`, `test:collision`, `test:routing:skills`, `test:routing:invariants`, `test:plugin:openai`, `test:plugin:submission`, `test:platform:compatibility`, `test:portability`.
|
|
96
|
+
- With waza (`~/bin/waza`): `waza check <skill-dir>`, `waza spec verify <skill> evals/<skill>/eval.yaml --fail --threshold 1`, `waza tokens check`.
|
|
97
|
+
- CI runs Node.js 24 on Ubuntu/Windows/macOS plus a Node.js 22 floor lane ([repository-contract.md](docs/repository-contract.md)). Node 22 install compatibility stays UNCHECKED locally.
|
|
98
|
+
- Never report "it works" from code reading. Name the evidence layer: package, deterministic mechanism, live host or behavior.
|
|
99
|
+
|
|
100
|
+
## Behavioral & Benchmark Evidence
|
|
101
|
+
|
|
102
|
+
| Claim | Evidence required |
|
|
103
|
+
|---|---|
|
|
104
|
+
| Hook/plugin contract holds | Deterministic mechanism test |
|
|
105
|
+
| A real host loaded and fired it | Preserved host/session artifact |
|
|
106
|
+
| Behavior improved | Paired evidence per #71 (baseline vs treatment) |
|
|
92
107
|
|
|
93
|
-
|
|
108
|
+
- Behavior runs: `node behavioral-evals/run.js run --engine opencode` (or `--engine claude`). On demand; costs tokens. The weekly workflow validates structure and runs live cases only where the CLI exists.
|
|
109
|
+
- Benchmarks: `node benchmarks/run.js scaffold <scenario>`, run both variants, then `record` with evidence logs.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.39.0](https://github.com/dyphn1/Harness-everything/compare/v0.38.0...v0.39.0) (2026-10-21)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* **doc-lifecycle:** add s2a document evidence producer and reconciliation core ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([7d54802](https://github.com/dyphn1/Harness-everything/commit/7d5480292891f4cbac126bfa4ed6dc43be9173f2))
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **doc-lifecycle:** bind captured origin pin to the s2a baseline ([#353](https://github.com/dyphn1/Harness-everything/issues/353)) ([59421f4](https://github.com/dyphn1/Harness-everything/commit/59421f41a8ce2b00250c96634a4a43ae0ba782bf))
|
|
14
|
+
* **doc-lifecycle:** bind s2a start pin, scope progress keys, stop should/n/a gating ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([5e48a91](https://github.com/dyphn1/Harness-everything/commit/5e48a9119b511d60c23cccdbd06ca3f865d82d83))
|
|
15
|
+
* **doc-lifecycle:** make the s2a producer inventory portable to windows ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([f1a9fb5](https://github.com/dyphn1/Harness-everything/commit/f1a9fb50e055e9ce21782d1ede96b926f08ff486))
|
|
16
|
+
* **doc-lifecycle:** reconcile s2a origin identity and binary records ([#353](https://github.com/dyphn1/Harness-everything/issues/353)) ([475fcfc](https://github.com/dyphn1/Harness-everything/commit/475fcfc26cf4c16a6ed5af40bc55c09281fe98c0))
|
|
17
|
+
* **doc-lifecycle:** reject prototype-sensitive s2a inventory ([#353](https://github.com/dyphn1/Harness-everything/issues/353)) ([b2b93ea](https://github.com/dyphn1/Harness-everything/commit/b2b93ea3d52ab9316d679b323343b5abe0525ccd))
|
|
18
|
+
* **doc-lifecycle:** resolve s2a workspace identity with native realpath on windows ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([c663fd8](https://github.com/dyphn1/Harness-everything/commit/c663fd8479869d6a3c7930bd47a067d4323cb6c9)), closes [#353](https://github.com/dyphn1/Harness-everything/issues/353)
|
|
19
|
+
* **doc-lifecycle:** revalidate the s2a start pin at event acceptance ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([2cf466d](https://github.com/dyphn1/Harness-everything/commit/2cf466d04e52dd92f8df2b7263348287f9eef2da))
|
|
20
|
+
|
|
21
|
+
## [0.38.0](https://github.com/dyphn1/Harness-everything/compare/v0.37.0...v0.38.0) (2026-10-21)
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* **doc-lifecycle:** add default-off s1 document reconciliation gate ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([8903435](https://github.com/dyphn1/Harness-everything/commit/8903435efa04e0e142a70d26caa9c0c4b78a7834)), closes [#341](https://github.com/dyphn1/Harness-everything/issues/341)
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* **doc-lifecycle:** keep the stop decision when the session store is unwritable ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([8c8d6fa](https://github.com/dyphn1/Harness-everything/commit/8c8d6faa7a3fc9b239dbe520981b69f99d0b6c90))
|
|
30
|
+
* **doc-lifecycle:** scope stop persistence recovery to an actual withheld pilot run ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([0f766ef](https://github.com/dyphn1/Harness-everything/commit/0f766efe67a76606144ae97ad703e0789ab4bce8))
|
|
31
|
+
* **doc-lifecycle:** withhold on config scope change and failed withholding writes ([#325](https://github.com/dyphn1/Harness-everything/issues/325)) ([dc04db8](https://github.com/dyphn1/Harness-everything/commit/dc04db8d573339604f32a28ec1a8a65fcffe10a1))
|
|
32
|
+
|
|
33
|
+
## [Unreleased]
|
|
34
|
+
|
|
35
|
+
- Reject root-level `__proto__` files in S2a snapshot capture and validation instead of silently dropping their document obligations (#353).
|
|
36
|
+
|
|
37
|
+
- Bind the S2a captured origin identity to the snapshot identity (workspace, session, workflow, revision, task), the captured plan and the selected active host, so a jointly substituted origin context and provider context cannot earn credit in either reconciliation mode; bind the captured config bytes to the captured inventory (#353).
|
|
38
|
+
|
|
39
|
+
- Keep a whole-project S2a inventory usable when it contains binary records: every stored byte stays in the candidate digest, records the derive contract cannot observe are omitted from semantic derivation, and governed/derived/code/test records that cannot be decoded fail closed as inventory-unsupported (#353).
|
|
40
|
+
|
|
41
|
+
- Reject S2a document evidence when the captured origin commit disagrees with the hashed baseline, including joint provider/context commit replacement; also reject inconsistent roots within the snapshot (#353).
|
|
42
|
+
|
|
43
|
+
- Ship the unwired S2a document evidence producer and reconciliation core (snapshot capture, captured config, accepted-origin adapter, expected-set reconciliation); S1 stays no-credit until S2b host integration.
|
|
44
|
+
- Ship default-OFF Phase 3b S1 scope assessment and no-credit runtime gate (opt in with `HARNESS_DOC_RECONCILIATION_PILOT=1`); S2 pending (S3 shipped in 0.37.0), E1 not started.
|
|
45
|
+
|
|
5
46
|
## [0.37.0](https://github.com/dyphn1/Harness-everything/compare/v0.36.4...v0.37.0) (2026-10-21)
|
|
6
47
|
|
|
7
48
|
### Features
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# PR #353 — two independent implementations and cross-validation
|
|
2
|
+
|
|
3
|
+
- Base: `59421f41a8ce2b00250c96634a4a43ae0ba782bf`.
|
|
4
|
+
- Environment: macOS, Node 24.14.1; per-worktree temporary directories.
|
|
5
|
+
- Selected: **A plus the coordinator's BOM fix**. Both OpenCode reviewers accept A; B accepts the final delta.
|
|
6
|
+
- Scope: S2a only. No runtime wiring, public derive/checker API, digest schema, version or dependency change.
|
|
7
|
+
- Evidence layer: **deterministic mechanism**, with fake origin providers; no host provenance or live-host claim.
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart LR
|
|
11
|
+
Base["59421f4"] --> A["OpenCode A: independent implementation"]
|
|
12
|
+
Base --> B["OpenCode B: independent implementation"]
|
|
13
|
+
A --> X["Swap tests + independent probes + peer reviews"]
|
|
14
|
+
B --> X
|
|
15
|
+
X --> S["Select A; add BOM regression and fix"]
|
|
16
|
+
S --> V["Full gates + final OpenCode review"]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Requirements addressed
|
|
20
|
+
|
|
21
|
+
| Comment | Final behavior |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| P1: disconnected origin and event identity halves | Match all five origin-correlated identity fields, captured plan fields and selected active host; reject partial substitutions in verification, review and cached evidence. |
|
|
24
|
+
| P1 same-class config link | Captured config source bytes must match the captured candidate inventory. |
|
|
25
|
+
| P2: ordinary binary assets reject a complete capture | Keep all captured bytes in baseline/candidate hashes; omit undecodable data only outside the conservative document/code/test/derived/frontmatter relevance surface. Producer and core use one helper. |
|
|
26
|
+
| Coordinator's BOM defect | A leading UTF-8 BOM cannot conceal undecodable frontmatter from the relevance check. |
|
|
27
|
+
|
|
28
|
+
## Comparison and selection (executed unless marked)
|
|
29
|
+
|
|
30
|
+
| Check | A | Revised B |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| Own core / producer suites | 195/0; 76/0 | 193/0; 78/0 |
|
|
33
|
+
| Common coordinator probes | 26/0 | 26/0 |
|
|
34
|
+
| Candidate-content transition probes | 4/0 | 4/0 (initial B was 0/4; fixed before comparison) |
|
|
35
|
+
| BOM frontmatter probe | 0/2 | 0/2 |
|
|
36
|
+
| B's tests against A | 193/0 core; 78/0 producer | — |
|
|
37
|
+
| A's tests against B | — | 193/2 core; 74/2 producer |
|
|
38
|
+
| Peer assessment | accepted by B | A found plan/config links and masked-frontmatter gaps; not accepted as-is |
|
|
39
|
+
|
|
40
|
+
A closes more represented identity links and fails closed on ambiguous semantic inputs. Its relevance rule avoids extra derivation passes but mirrors existing path rules; this maintenance cost is stated in code with a `shortcut:` comment. The BOM gap was independently reproduced for both candidates, then fixed in the selected tree.
|
|
41
|
+
|
|
42
|
+
Peer reviews are [A reviews B](a-reviews-b.md) and [B reviews A](b-reviews-a.md). [Final integration review](final-review.md): **ACCEPT**, source-traced (no tests rerun by the reviewer).
|
|
43
|
+
|
|
44
|
+
## Final evidence
|
|
45
|
+
|
|
46
|
+
| Check | Result |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Baseline coordinator probes | 10 PASS / 16 FAIL |
|
|
49
|
+
| BOM regression before fix | 78 PASS / 2 FAIL / 0 INFRA |
|
|
50
|
+
| Final core | **195 PASS / 0 FAIL / 0 INFRA** |
|
|
51
|
+
| Final producer | **80 PASS / 0 FAIL / 0 INFRA** |
|
|
52
|
+
| Final independent probes | **26 + 4 + 2 = 32 PASS / 0 FAIL** |
|
|
53
|
+
| `npm run verify:all` | **13 PASS / 0 FAIL / 3 UNCHECKED** |
|
|
54
|
+
| `verify-gate.js --json` after cleanup | Discovered `package-test` ran with exit **0**; gate status `UNCHECKED_DISCOVERED` because no declared project verification contract exists (not a contract PASS). |
|
|
55
|
+
| Post-review comment/wording-only cleanup | consistency and diff whitespace PASS; no functional delta after full gates |
|
|
56
|
+
|
|
57
|
+
The three UNCHECKED entries are Node 22 execution/install lanes. CI owns the cross-platform and runtime-floor evidence. Focused stdout, swapped-suite logs, losslessly compressed full-gate logs and source hashes are retained beside this README. Probe scripts are retained as `.txt` evidence; they were run outside the repository and are not installed runtime code. Full OpenCode JSON streams remain local rather than being shipped.
|
|
58
|
+
|
|
59
|
+
## Limits and follow-ups
|
|
60
|
+
|
|
61
|
+
- Undecodable files under code/test/governed/derived paths remain **unavailable by design**, including harmless binary test fixtures or diagrams under governed globs. This conservative acceptance boundary is explicit in the S2a contract; exploratory probes confirm B accepts a no-REQ test fixture while A refuses it. No claim that every binary file in every path is accepted.
|
|
62
|
+
- A mirrors the derive contract's code/test/glob rules. Keep them synchronized until a shared classifier is exposed.
|
|
63
|
+
- Malformed byte records may now report `inventory-unsupported` rather than the old `invalid-input`; both withhold credit. This is a non-blocking diagnostic drift noted by B.
|
|
64
|
+
- Fully self-consistent restatement of all detached metadata and cached accepted structures is outside S2a attestation: external origin authentication remains S2b. Both independent implementations share this boundary.
|
|
65
|
+
- The owner decides PR readiness, merge and release.
|
|
66
|
+
|
|
67
|
+
## Trust-boundary review
|
|
68
|
+
|
|
69
|
+
| Threat | Check |
|
|
70
|
+
| --- | --- |
|
|
71
|
+
| Context spoofing / metadata tampering | Five tuple fields, plan/config/host and config bytes linked before credit. |
|
|
72
|
+
| Binary omission | Relevant undecodable inputs fail closed; byte hashes retain every captured file. |
|
|
73
|
+
| Invalid snapshot | No event adaptation or eligibility. |
|
|
74
|
+
| Secrets / injected execution | Targeted changed-source scan found no added secret literal or dynamic execution; no endpoint/auth/dependency added. |
|
|
75
|
+
|
|
76
|
+
STATUS: DONE
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# PR #353 — Cross-review of peer leg B (reviewer: leg A)
|
|
2
|
+
|
|
3
|
+
Reviewed: peer worktree `/Users/daniel.chang/Desktop/Skills/Harness-everything/.worktrees/353-r6-b`
|
|
4
|
+
(base `59421f41a8ce2b00250c96634a4a43ae0ba782bf`), report `/tmp/harness-353-r6-b/REPORT.md`, and B's
|
|
5
|
+
working-tree diff against `59421f4`.
|
|
6
|
+
Method: read B's current source, its test and doc diffs; ran **one** independent probe
|
|
7
|
+
(`/tmp/harness-353-r6-a/probe/cross-review-probe.js`, scratch, outside both repositories) against **both**
|
|
8
|
+
worktrees; no suite was re-run, no implementation was edited, no git/gh write was issued, no full gate
|
|
9
|
+
was run. The probe builds its own Git fixture repositories, its own fake origin provider and its own
|
|
10
|
+
event builder; it depends on neither leg's fixture harness.
|
|
11
|
+
|
|
12
|
+
## Verdict
|
|
13
|
+
|
|
14
|
+
| | Peer B | Leg A |
|
|
15
|
+
| --- | --- | --- |
|
|
16
|
+
| P1 origin tuple (`workspaceId`, `sessionId`, `workflowId`, `workflowRevision`, `taskId`) | closed | closed |
|
|
17
|
+
| P1 `activeHost` ↔ captured selected config | closed | closed |
|
|
18
|
+
| P1 captured plan ↔ identity | **open** (F1) | closed |
|
|
19
|
+
| P1 captured config bytes ↔ captured inventory | **open** (F2) | closed |
|
|
20
|
+
| P2 binary bytes stay in both digests | closed | closed |
|
|
21
|
+
| P2 irrelevant binary asset does not break the capture | closed | closed |
|
|
22
|
+
| P2 baseline/candidate/new/deleted relevance class | closed | closed |
|
|
23
|
+
| P2 relevance decided by the unchanged derivation (no rule duplication) | **yes** | no (F5) |
|
|
24
|
+
| P2 a record that opens a frontmatter block cannot vanish | not guaranteed (F4) | closed |
|
|
25
|
+
|
|
26
|
+
**Peer B is not accepted as-is.** One blocker-class finding (F1) and two recommended additions (F2, F4),
|
|
27
|
+
all in the packet's own P1/P2 scope and all reproducible with the probe. With the minimal delta
|
|
28
|
+
described below, I accept B. **Leg A has no blocker-class finding** in this review; its only weakness is
|
|
29
|
+
a maintenance coupling (F5), not a present trust gap.
|
|
30
|
+
|
|
31
|
+
## Probe results (one probe, both worktrees)
|
|
32
|
+
|
|
33
|
+
| Probe case | Expected | A | B |
|
|
34
|
+
| --- | --- | --- | --- |
|
|
35
|
+
| `p1-control-eligible` | eligible | eligible | eligible |
|
|
36
|
+
| `p1-joint-origin-task-substitution` (the packet's named attack) | rejected | rejected | rejected |
|
|
37
|
+
| `p1-plan-only-substitution` | rejected | rejected (`identity-mismatch`) | **accepted (eligible)** |
|
|
38
|
+
| `p1-config-bytes-substitution` | rejected | rejected (`config-capture-mismatch`) | **accepted (eligible)** |
|
|
39
|
+
| `p1-fully-joint-self-consistent-substitution` | rejected | accepted (eligible) | accepted (eligible) |
|
|
40
|
+
| `p2-asset-irrelevant` | ready | ready | ready |
|
|
41
|
+
| `p2-governed-path-unchanged` | unavailable | unavailable | unavailable |
|
|
42
|
+
| `p2-role-frontmatter-asset` | unavailable | unavailable | unavailable |
|
|
43
|
+
| `p2-masked-frontmatter-asset` | unavailable | unavailable | **ready** |
|
|
44
|
+
| `p2-new-binary-governed-record` | unavailable | unavailable | unavailable |
|
|
45
|
+
| `p2-deleted-binary-governed-record` | unavailable | unavailable | unavailable |
|
|
46
|
+
| `p2-binary-bytes-covered-by-both-digests` | differ | differ | differ |
|
|
47
|
+
| `p2-producer-core-parity` | no errors | no errors | no errors |
|
|
48
|
+
| `p2-malformed-record-rejected` | `invalid-input` | `invalid-input` | `invalid-input` |
|
|
49
|
+
|
|
50
|
+
Probe definitions: *plan-only* = the captured plan names another workflow and `taskScopeDigest` is
|
|
51
|
+
recomputed correctly, the identity and the captured origin context keep the original tuple; *config-bytes* =
|
|
52
|
+
the captured config source bytes are replaced and every digest that names them is recomputed, and the
|
|
53
|
+
cached acceptance is restated; *fully joint* = the captured origin context, the identity, the captured plan,
|
|
54
|
+
the digests and the cached acceptance are restated together; *masked frontmatter* = the record's bytes open
|
|
55
|
+
a `---` block whose closing delimiter is separated from it by one invalid UTF-8 byte.
|
|
56
|
+
|
|
57
|
+
## Findings
|
|
58
|
+
|
|
59
|
+
**F1 — executed — peer B — blocker-class (P1 scope): the captured plan is not bound to the identity.**
|
|
60
|
+
`validateSnapshot` checks `originContext` against `identity` and `activeHost` against the config capture,
|
|
61
|
+
but nothing compares the captured plan with the identity. `taskScopeDigest` binds the plan *content* to the
|
|
62
|
+
identity's digest field; it does not bind the plan's workflow triple / task id to the identity's. A
|
|
63
|
+
snapshot whose plan describes another workflow, with the digest correctly recomputed, verifies as
|
|
64
|
+
`eligible` (probe `p1-plan-only-substitution`). The packet asks to "inspect all represented tuple links,
|
|
65
|
+
not only two examples" and to check the plan "where represented"; the plan represents `workflowId`,
|
|
66
|
+
`workflowRevision`, `sessionId` and `taskId`, which the identity also represents. B's shipped doc text
|
|
67
|
+
("The plan stays bound through `taskScopeDigest`") states more than the code enforces. Fix: compare
|
|
68
|
+
`taskSemantics.workflow.{workflowId,workflowRevision,sessionId}`, `taskSemantics.task.taskId`,
|
|
69
|
+
`taskSemantics.prdRoot` and `taskSemantics.configDigest` with the identity inside the existing
|
|
70
|
+
`validateSnapshot` (A: `originBound`, ~6 lines, pure, no I/O).
|
|
71
|
+
|
|
72
|
+
**F2 — executed — peer B — recommended (same class): the captured config bytes are not bound to the
|
|
73
|
+
captured inventory.** Replacing the captured config source bytes and recomputing every digest that names
|
|
74
|
+
them (`configDigest`, `identity.configDigest`, the plan's `configDigest`, `taskScopeDigest`) plus
|
|
75
|
+
restating the cached acceptance verifies as `eligible` (probe `p1-config-bytes-substitution`). The
|
|
76
|
+
producer already enforces exactly this rule at capture (its config-source loop compares the captured
|
|
77
|
+
source bytes with the candidate records); the core re-checks nothing, so the two halves of the capture
|
|
78
|
+
can describe different files. Fix: the producer's rule as a core check → `config-capture-mismatch`
|
|
79
|
+
(A: `configBytesBound`, ~8 lines).
|
|
80
|
+
|
|
81
|
+
**F3 — executed — shared by both legs — contract-bounded, not a defect of either: a fully joint,
|
|
82
|
+
self-consistent restatement is accepted.** Restating the captured origin context, the identity, the
|
|
83
|
+
captured plan, the digests and the cached acceptance together yields `eligible` under A and B
|
|
84
|
+
(probe `p1-fully-joint-self-consistent-substitution`). The snapshot is detached and self-authenticating;
|
|
85
|
+
the only external anchor is the origin provider, which `acceptDocEvents` consults on a fresh acceptance
|
|
86
|
+
and the pure core never re-reads. This matches the S2a contract's own boundary ("external worktree
|
|
87
|
+
authentication remains outside this S2a guarantee"; S2b recollects every tuple and accepted binding before
|
|
88
|
+
credit). Consequence for the selection: F1 and F2 are *partial* defenses — they reject partial
|
|
89
|
+
substitutions, not a full restatement. Both legs share that boundary, so it is not a differentiator.
|
|
90
|
+
|
|
91
|
+
**F4 — executed — divergence — peer B: a record that opens a frontmatter block can still be omitted.**
|
|
92
|
+
The lifecycle decides "is this a frontmatter document" by the first line being exactly `---`
|
|
93
|
+
(`harness-everything/scripts/doc-lifecycle.js`, `parseFrontmatter`). B's relevance decision is the
|
|
94
|
+
unchanged derivation applied to the *lossy* reading of the record; when the invalid byte sits inside the
|
|
95
|
+
frontmatter block, the lossy reading is unterminated, carries no role, and the record is omitted
|
|
96
|
+
(probe `p2-masked-frontmatter-asset`: B → ready, A → unavailable). A governed document with one stray
|
|
97
|
+
invalid byte in its frontmatter can therefore be dropped from the derivation, so `doc-lint` / `link-check`
|
|
98
|
+
would not fire where a tolerant reader would see a governed PRD. Exotic, but it is the one probed case
|
|
99
|
+
where the two legs differ on a trust-relevant outcome. Fix on B: fail closed when a record's first line is
|
|
100
|
+
exactly `---` — the lifecycle's own test, independent of the witnesses (~3 lines).
|
|
101
|
+
|
|
102
|
+
**F5 — source-traced — leg A (for balance): A mirrors the derive contract's path rules inside the
|
|
103
|
+
reconciliation module.** Because `doc-obligations.js` is outside the write-set, A duplicates
|
|
104
|
+
`CODE_EXTENSION`, `TEST_PATH` and the contract's glob semantics to decide relevance. The duplication is
|
|
105
|
+
currently exact (the probe shows A and B agreeing on 8 of 9 P2 cases), but a later change to the derive
|
|
106
|
+
contract's code/test/glob rules would silently make A *omit* a record the contract treats as relevant —
|
|
107
|
+
the dangerous direction — with no test failure. B has no such surface: its relevance decision is the
|
|
108
|
+
derivation's own. Removing A's coupling needs either a public export of the contract's classification
|
|
109
|
+
(out of this packet's scope) or B's witness approach.
|
|
110
|
+
|
|
111
|
+
**F6 — executed — shared residual: a binary record at a governed path makes the capture unavailable even
|
|
112
|
+
when unchanged.** Both legs fail closed for `docs/prd/diagram.png` (probe `p2-governed-path-unchanged`;
|
|
113
|
+
B via the addition witness, A via the path rule). This matches the S2a contract ("Unsupported
|
|
114
|
+
encodings ... that prevent faithful identity yield unavailable") and is conservative in both, but it means
|
|
115
|
+
a repository holding a binary diagram under `docs/prd/` can never be captured. Availability cost, not a
|
|
116
|
+
trust gap; identical in both legs.
|
|
117
|
+
|
|
118
|
+
**F7 — executed — shared: the new/deleted record identity class is closed in both.** A binary record that
|
|
119
|
+
exists on only one side of the capture fails closed in both legs (probes `p2-new-binary-governed-record`,
|
|
120
|
+
`p2-deleted-binary-governed-record`), and both agree with the coordinator's transition probe. B's
|
|
121
|
+
round-2 witnesses (actual / addition / deletion) close the candidate-only omission the coordinator found
|
|
122
|
+
in B's first implementation; A's path rules cover the same paths. Neither leg depends on a newline-only
|
|
123
|
+
modification to detect the transition.
|
|
124
|
+
|
|
125
|
+
**F8 — executed — shared: byte integrity, parity and malformed inputs.** Both legs keep the binary bytes
|
|
126
|
+
in `candidateDigest` *and* `baselineDigest` (probe `p2-binary-bytes-covered-by-both-digests`), the core's
|
|
127
|
+
re-derivation accepts the producer's snapshot with a binary asset in both (probe
|
|
128
|
+
`p2-producer-core-parity`), and a record whose stored bytes do not match its digest is refused with
|
|
129
|
+
`invalid-input` in both (probe `p2-malformed-record-rejected`).
|
|
130
|
+
|
|
131
|
+
**F9 — source-traced — scope, API and parity between the legs.** Both legs touch the same nine files
|
|
132
|
+
inside the packet's write-set, change no public derive/checker API, no identity/digest schema, no S1
|
|
133
|
+
runtime and no workflow wiring, add no new `.js` file to the repository, and leave
|
|
134
|
+
`doc-reconciliation-events.js` untouched — correct, because that module already compares the provider
|
|
135
|
+
context with the captured origin context and calls `validateSnapshot`, so it inherits the P1 binding. Both
|
|
136
|
+
cores stay pure (no file, process or network activity); B's extra derivation calls are pure computations.
|
|
137
|
+
B's packaged copies are byte-identical to its canonical files (sha256 verified); A's parity is asserted
|
|
138
|
+
by its own suite. B's doc text and CHANGELOG entries accurately describe B's behaviour except for the
|
|
139
|
+
plan-binding claim noted in F1.
|
|
140
|
+
|
|
141
|
+
**F10 — inconclusive.** The completeness of B's relevance witnesses is not provable for every byte
|
|
142
|
+
sequence (B's own report says so; F4 is the demonstrated instance). Live-host provenance is out of reach
|
|
143
|
+
in both legs (the origin provider is an explicit fake). Platform coverage is macOS-only in both; the
|
|
144
|
+
Windows lane and the Node 22 floor remain CI's.
|
|
145
|
+
|
|
146
|
+
## Comparison of the two approaches
|
|
147
|
+
|
|
148
|
+
**Peer B — strengths.** The relevance decision is the *unchanged derivation's own*, so there is no
|
|
149
|
+
extension allowlist and no duplicated path rules to drift (the packet's "inspect existing derive/lifecycle
|
|
150
|
+
semantics to justify relevance" in its strongest form). The three witnesses (actual transition, addition,
|
|
151
|
+
deletion) directly answer the coordinator's class requirement, and B's round-2 fix is a real improvement
|
|
152
|
+
over a naive path-rule approach. Its P1 origin binding is exactly equivalent to A's for the five tuple
|
|
153
|
+
fields and the host. Its test set is larger and pins the semantic-binary regressions.
|
|
154
|
+
|
|
155
|
+
**Peer B — defects.** F1 (blocker-class, P1 scope), F2 (same class), F4 (one probed omission case). Its
|
|
156
|
+
report's plan-binding claim is stronger than its code.
|
|
157
|
+
|
|
158
|
+
**Leg A — strengths.** Strictly more of the P1 class is closed (F1, F2), the derivation-relevant omission
|
|
159
|
+
cannot happen for a frontmatter-opening record (F4), the implementation is cheaper (no extra derivation
|
|
160
|
+
calls) and the reason codes are explicit.
|
|
161
|
+
|
|
162
|
+
**Leg A — defects.** F5: the relevance rule is a mirror of the derive contract rather than the contract
|
|
163
|
+
itself, so it can drift silently; and it fails closed on any record whose first line is `---`, which is
|
|
164
|
+
stricter than the derivation requires (an availability cost, the mirror image of B's F4).
|
|
165
|
+
|
|
166
|
+
**Shared.** F3 (no external anchor in the cached path), F6 (a binary under a governed path is
|
|
167
|
+
unavailable), F10 (residual limits). Neither leg's extra checks change F3.
|
|
168
|
+
|
|
169
|
+
## Recommendation
|
|
170
|
+
|
|
171
|
+
**Minimal combination, base B**: keep B's derivation-grounded relevance (no duplicated rules, no drift
|
|
172
|
+
surface, and it already answers the baseline/candidate/new/deleted class), and add A's three small
|
|
173
|
+
additions to B's core — the plan↔identity comparison (F1), the config-bytes↔inventory check (F2) and the
|
|
174
|
+
frontmatter-opener guard (F4). Cost: ≈17 lines in `hooks/scripts/lib/doc-reconciliation-core.js` plus the
|
|
175
|
+
three corresponding test cases; no public API, digest schema, event module or producer change; the
|
|
176
|
+
packaged copy is regenerated with `npm run plugin:sync`.
|
|
177
|
+
|
|
178
|
+
**If the owner selects one leg without merging**: take **A**. The P1 gaps in B are current and
|
|
179
|
+
demonstrated, and this PR exists to close that class; A's weakness is a maintenance coupling that can be
|
|
180
|
+
removed later (exporting the derive contract's classification, or porting B's witness approach) without
|
|
181
|
+
changing any trust guarantee. B's grounding is the better long-term shape for the P2 rule, so it is worth
|
|
182
|
+
recording as the follow-up. B should not be selected unmodified: F1 alone is inside the packet's stated
|
|
183
|
+
P1 scope, and B's documentation currently claims that scope is closed.
|
|
184
|
+
|
|
185
|
+
**Acceptance.** Leg A: accepted (no blocker-class finding; F5 is a recorded residual). Peer B: not
|
|
186
|
+
accepted as-is (F1); accepted once F1, F2 and F4 are applied and pinned by the three probe cases above.
|
|
187
|
+
|
|
188
|
+
This review does not certify PR readiness and does not judge the live-host provenance of either leg; the
|
|
189
|
+
owner decides.
|
|
190
|
+
|
|
191
|
+
STATUS: DONE
|