harness-everything 0.40.0 → 0.41.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/.agents/harness-everything/project-docs.json +9 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +43 -0
- package/benchmarks/results/f1-doc-path-baseline/1-source-clean.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/1-source-clean.stdout.json +20 -0
- package/benchmarks/results/f1-doc-path-baseline/2-injected-architecture.md +229 -0
- package/benchmarks/results/f1-doc-path-baseline/2-source-injected.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/2-source-injected.stdout.json +33 -0
- package/benchmarks/results/f1-doc-path-baseline/3-source-reverted.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/3-source-reverted.stdout.json +20 -0
- package/benchmarks/results/f1-doc-path-baseline/4a-packaged-clean.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/4a-packaged-clean.stdout.json +20 -0
- package/benchmarks/results/f1-doc-path-baseline/4b-packaged-injected.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/4b-packaged-injected.stdout.json +33 -0
- package/benchmarks/results/f1-doc-path-baseline/5-source-missing-config.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/5-source-missing-config.stdout.json +15 -0
- package/benchmarks/results/f1-doc-path-baseline/5b-packaged-missing-config.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/5b-packaged-missing-config.stdout.json +15 -0
- package/benchmarks/results/f1-doc-path-baseline/README.md +54 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/1-source-clean.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/1-source-clean.stdout.json +115 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/2-injected-document.md +328 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/2-source-injected.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/2-source-injected.stdout.json +127 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/3-source-reverted.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/3-source-reverted.stdout.json +115 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/4a-packaged-clean.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/4a-packaged-clean.stdout.json +115 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/4b-packaged-injected.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/4b-packaged-injected.stdout.json +127 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/5-source-missing-config.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/5-source-missing-config.stdout.json +15 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/5b-packaged-missing-config.stderr.txt +0 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/5b-packaged-missing-config.stdout.json +15 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/6-supplementary-fixture-ok.input.md +8 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/6-supplementary-fixture-ok.stdout.json +16 -0
- package/benchmarks/results/f1-doc-path-baseline/before-fix/README.md +34 -0
- package/benchmarks/results/f1-doc-path-baseline/probe-31-docs/after.json +248 -0
- package/benchmarks/results/f1-doc-path-baseline/probe-31-docs/before.json +254 -0
- package/benchmarks/results/f1-doc-path-baseline/probe-31-docs/probe.js +26 -0
- package/benchmarks/results/f2-doc-craft-baseline/README.md +32 -0
- package/benchmarks/results/f2-doc-craft-baseline/arm-f1-report.md +84 -0
- package/benchmarks/results/f2-doc-craft-baseline/arm-f1-task.md +21 -0
- package/benchmarks/results/f2-doc-craft-baseline/arm-f1.diff +19 -0
- package/benchmarks/results/f2-doc-craft-baseline/arm-f2-report.md +110 -0
- package/benchmarks/results/f2-doc-craft-baseline/arm-f2-task.md +21 -0
- package/benchmarks/results/f2-doc-craft-baseline/arm-f2.diff +19 -0
- package/benchmarks/results/f3-derived-views-baseline/README.md +34 -0
- package/benchmarks/results/f3-derived-views-baseline/arm-f2-report.md +43 -0
- package/benchmarks/results/f3-derived-views-baseline/arm-f2-task.md +21 -0
- package/benchmarks/results/f3-derived-views-baseline/arm-f2.diff +21 -0
- package/benchmarks/results/f3-derived-views-baseline/arm-f3-report.md +57 -0
- package/benchmarks/results/f3-derived-views-baseline/arm-f3-task.md +21 -0
- package/benchmarks/results/f3-derived-views-baseline/arm-f3.diff +21 -0
- package/benchmarks/results/live-host/claude-325-3b-s2b/README.md +99 -0
- package/benchmarks/results/live-host/claude-325-3b-s2b/capture.sanitized.jsonl +26 -0
- package/ci/archive/325-prep/README.md +71 -0
- package/ci/{prep → archive/325-prep}/doc-reconciliation-red.js +9 -7
- package/ci/archive/325-prep/f4-expected-red.json +34 -0
- package/ci/archive/325-prep/historical-qualification.test.js +143 -0
- package/ci/fixtures/doc-obligations/reconciliation-prep/cases.json +17 -4
- package/ci/fixtures/doc-obligations/reconciliation-prep/pending-red.json +8 -56
- package/ci/fixtures/doc-obligations/reconciliation-prep/trust-contract.json +2 -2
- package/ci/fixtures/doc-obligations/reconciliation-s1/cases.json +17 -5
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/harness.js +415 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/off-handoff-golden.json +16 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-post-tool-use-failure.json +11 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-post-tool-use-success-minimal.json +9 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-post-tool-use-success.json +13 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-subagent-start.json +7 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-subagent-stop-freetext-reject.json +11 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-subagent-stop-reject.json +11 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-subagent-stop.json +11 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/capture/payload-task-result.json +19 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/off-capture-only.json +99 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/off-legacy.json +67 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/on-concurrent-writers.json +62 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/on-lookalikes-runtime-mutations.json +67 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/on-malformed.json +85 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/on-normal-session.json +74 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/on-runtime-drift-later-npm-test.json +58 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/corpus/on-valid-direct-quoted-review.json +85 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/f4/cases.json +2267 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/wiring/cases.json +1110 -0
- package/ci/fixtures/doc-obligations/reconciliation-s2b/wiring/legacy-off-golden.json +674 -0
- package/ci/lib/doc-reconciliation-file-spy.js +23 -0
- package/ci/lib/doc-reconciliation-prep-fixtures.js +136 -10
- package/ci/lib/doc-reconciliation-qualification-preload.js +37 -0
- package/ci/lib/doc-reconciliation-replay.js +104 -0
- package/ci/lib/doc-reconciliation-staged-tree.js +102 -0
- package/ci/mechanism-2p-opencode-v2-entrypoint.test.js +179 -0
- package/ci/mechanism-325-3b-preparation.test.js +27 -101
- package/ci/mechanism-325-3b-s2b-capture.test.js +561 -0
- package/ci/mechanism-325-3b-s2b-wiring.test.js +668 -0
- package/ci/mechanism-325-f1-doc-check.test.js +674 -0
- package/ci/mechanism-325-f2-doc-craft.test.js +597 -0
- package/ci/mechanism-325-f3-derived-views.test.js +798 -0
- package/ci/mechanism-325-f4-invariants.test.js +606 -0
- package/ci/mechanism-325-f4-projections.test.js +382 -0
- package/ci/mechanism-325-f4-qualification.test.js +228 -0
- package/ci/mechanism-325-f4-trust-boundary.test.js +880 -0
- package/ci/mutation-check.js +26 -3
- package/docs/architecture.md +5 -0
- package/docs/doc-workflow-reconciliation.md +331 -4
- package/docs/document-lifecycle.md +11 -0
- package/docs/governed-index.md +20 -0
- package/docs/platform-capabilities.md +22 -2
- package/grill-with-docs/SKILL.md +1 -1
- package/grill-with-docs/references/session-playbook.md +4 -0
- package/harness-everything/SKILL.md +1 -1
- package/harness-everything/references/doc-check.md +186 -0
- package/harness-everything/references/documentation/_shared/maintenance.md +41 -0
- package/harness-everything/references/documentation/_shared/writing-craft.md +59 -0
- package/harness-everything/references/triage-and-tiers.md +4 -0
- package/harness-everything/scripts/doc-check.js +442 -0
- package/harness-everything/scripts/doc-lifecycle.js +3 -0
- package/hooks/hooks.json +46 -0
- package/hooks/scripts/lib/doc-reconciliation-capture.sanitized.jsonl +26 -0
- package/hooks/scripts/lib/doc-reconciliation-pilot.js +171 -2
- package/hooks/scripts/lib/doc-reconciliation-provider.js +1059 -0
- package/hooks/scripts/lib/doc-reconciliation-qualification.json +34 -0
- package/hooks/scripts/lib/workflow-obligations.js +7 -0
- package/hooks/scripts/state-persist.js +78 -2
- package/hooks/scripts/workflow-stop-gate.js +7 -2
- package/opencode-plugin/README.md +15 -0
- package/opencode-plugin/index.mjs +77 -0
- 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-capture.sanitized.jsonl +26 -0
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-pilot.js +171 -2
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-provider.js +1059 -0
- package/plugins/harness-everything/hooks/scripts/lib/doc-reconciliation-qualification.json +34 -0
- package/plugins/harness-everything/hooks/scripts/lib/workflow-obligations.js +7 -0
- package/plugins/harness-everything/hooks/scripts/state-persist.js +78 -2
- package/plugins/harness-everything/hooks/scripts/workflow-stop-gate.js +7 -2
- package/plugins/harness-everything/plugin.json +1 -1
- package/plugins/harness-everything/skills/grill-with-docs/SKILL.md +1 -1
- package/plugins/harness-everything/skills/grill-with-docs/references/session-playbook.md +4 -0
- package/plugins/harness-everything/skills/harness-everything/SKILL.md +1 -1
- package/plugins/harness-everything/skills/harness-everything/references/doc-check.md +186 -0
- package/plugins/harness-everything/skills/harness-everything/references/documentation/_shared/maintenance.md +41 -0
- package/plugins/harness-everything/skills/harness-everything/references/documentation/_shared/writing-craft.md +59 -0
- package/plugins/harness-everything/skills/harness-everything/references/triage-and-tiers.md +4 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/doc-check.js +442 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/doc-lifecycle.js +3 -0
- package/plugins/harness-everything/skills/repo-docs/SKILL.md +1 -1
- package/plugins/harness-everything/skills/repo-docs/references/process-guide.md +4 -0
- package/plugins/harness-everything/skills/to-spec/SKILL.md +1 -1
- package/plugins/harness-everything/skills/to-spec/references/process.md +4 -0
- package/plugins/harness-everything/skills/to-tickets/SKILL.md +1 -1
- package/plugins/harness-everything/skills/to-tickets/references/publishing-and-templates.md +4 -0
- package/repo-docs/SKILL.md +1 -1
- package/repo-docs/references/process-guide.md +4 -0
- package/sbom.cdx.json +7 -7
- package/to-spec/SKILL.md +1 -1
- package/to-spec/references/process.md +4 -0
- package/to-tickets/SKILL.md +1 -1
- package/to-tickets/references/publishing-and-templates.md +4 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Doc Check (editorial lane)
|
|
2
|
+
|
|
3
|
+
One command for an edited governed document: lifecycle lint plus local Markdown link targets. Use it to find and fix defects, then record the real output.
|
|
4
|
+
|
|
5
|
+
## When to run
|
|
6
|
+
|
|
7
|
+
| Trigger | Run |
|
|
8
|
+
|---|---|
|
|
9
|
+
| Active `doc-change` step (instruction-led: no step binding exists; `SKILL.md` deep dive → `triage-and-tiers.md` leads here) | Yes, after each edit and before claiming the doc is done |
|
|
10
|
+
| Any edit to a file governed by `.agents/harness-everything/project-docs.json` | Yes |
|
|
11
|
+
| Ungoverned file | No. It appears in `coverage.unsupported`; this is not a doc check |
|
|
12
|
+
|
|
13
|
+
## Command
|
|
14
|
+
|
|
15
|
+
Replace `<this-skill-dir>` with the directory of the loaded skill. Use an absolute workspace path.
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
node "<this-skill-dir>/scripts/doc-check.js" check \
|
|
19
|
+
--workspace "<absolute-project-root>" \
|
|
20
|
+
--config .agents/harness-everything/project-docs.json \
|
|
21
|
+
--changed-path "docs/document-lifecycle.md" \
|
|
22
|
+
--base <recorded-base-commit>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- `--changed-path` is repeatable. Quote paths with spaces. Pass deleted and old rename paths too.
|
|
26
|
+
- `--base` is the commit the change is measured against. Omit it and the output shows `evidence.immutability: not-observed`.
|
|
27
|
+
|
|
28
|
+
## Hook invocation grammar
|
|
29
|
+
|
|
30
|
+
Only a direct `node <installed-doc-check.js> check` command earns credit. The installed script path must resolve through native `realpath` to this plugin's runtime, and its CRLF-normalized SHA-256 must match the shipped pin. Case variants are accepted when the host filesystem resolves them to that same file.
|
|
31
|
+
|
|
32
|
+
Candidate detection follows command roles across unquoted newline-separated command segments. A direct `doc-check`/`doc-check.js` target, a checker script operand to a recognized runtime, or a checker command inside a recognized shell `-c` string is a candidate even if its launcher, subcommand, flags or shell composition are unsupported. A command segment that explicitly targets the checker followed by unsupported operators, expansion or malformed trailing quoting remains a candidate and is refused by the strict grammar below; candidate status never authorizes a wrapper. A workflow command whose JSON acceptance text merely mentions `doc-check`, or an unrelated command that prints the name, is not a candidate.
|
|
33
|
+
|
|
34
|
+
The bounded candidate scan treats quoted or escaped newlines as text. Simple here-docs with a same-line delimiter after `<<` or `<<-` are also recognized: their body through the exact closing-delimiter line is data, with leading tabs ignored for `<<-`. Dynamic or continued delimiters and shell-dialect extensions are outside this scan; they do not establish an accepted invocation.
|
|
35
|
+
|
|
36
|
+
- `--workspace`, `--config`, and at least one `--changed-path` are required. `--workspace`, `--config`, and optional `--base` occur once; `--changed-path` may repeat. Every flag takes one value.
|
|
37
|
+
- The strict invocation tokenizer supports single and double quotes, adjacent quoted/unquoted text, and backslash escapes. This lets quoted or escaped paths contain spaces.
|
|
38
|
+
- An explicit checker target using a wrapper such as `sh -c`, `env`, or `npx` is refused. The tokenizer rejects unquoted shell operators and line breaks, escaped line continuations, comment markers at a word boundary, active `$`/backtick substitution syntax (including inside double quotes), and unquoted glob, brace, or tilde expansion. Quoting or escaping makes supported metacharacters literal.
|
|
39
|
+
- A refused explicit candidate gets a reason and cannot fall through to generic shell verification or set `lastVerifyAt`.
|
|
40
|
+
- The hook sees the command text supplied by the host. An opaque alias such as `dc` cannot be resolved as doc-check without host-provided argv or alias expansion, so it remains unrecognized.
|
|
41
|
+
|
|
42
|
+
| Layout | `<this-skill-dir>` |
|
|
43
|
+
|---|---|
|
|
44
|
+
| Source checkout | `<checkout>/harness-everything` |
|
|
45
|
+
| Packaged plugin | `<plugin-root>/skills/harness-everything` |
|
|
46
|
+
|
|
47
|
+
Run it from any cwd. The script finds its sibling `doc-lifecycle.js` from its own location.
|
|
48
|
+
|
|
49
|
+
## Output and exit codes
|
|
50
|
+
|
|
51
|
+
Stdout is always one JSON object. Successful checks use this shape:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
{ lint: {exit, evidence, diagnostics}, links: {checked, broken: [{path, line, target}]}, coverage: {unsupported: [...]} }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Usage or config errors use this reduced shape:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
{ lint: {exit: 2, error}, links: {checked: 0, broken: [], skipped: "lint-usage-error"}, coverage: {unsupported: []} }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| Exit | Meaning |
|
|
64
|
+
|---|---|
|
|
65
|
+
| 0 | Lint passed and every checked link resolves |
|
|
66
|
+
| 1 | A defect: a lint error, a broken link, or an unreadable changed path (`links.broken` with `reason: "unreadable"`). Fix it and rerun |
|
|
67
|
+
| 2 | Usage or config error. Nothing was checked; `links.skipped` says so |
|
|
68
|
+
|
|
69
|
+
A top-level `reminders` array carries advisory prose-share items, `strength: "SHOULD"`. One item is emitted for each changed, readable, non-legacy governed `reference` doc whose body has more than 50% prose lines (`2 * proseLines > eligibleLines`). Reminders never change an exit code and are never diagnostics. The array is absent on the exit-2 lanes. A doc with malformed frontmatter gets no reminder, because lint already reports the frontmatter error.
|
|
70
|
+
|
|
71
|
+
## Shared craft and maintenance
|
|
72
|
+
|
|
73
|
+
Read these before drafting or editing a governed document:
|
|
74
|
+
|
|
75
|
+
- [writing-craft.md](documentation/_shared/writing-craft.md): writing principles and the prose-share reminder rules (D6.7)
|
|
76
|
+
- [maintenance.md](documentation/_shared/maintenance.md): the event table for D6.5 and D6.6
|
|
77
|
+
|
|
78
|
+
These links resolve from this `references/` directory. A copy of the skill without `references/documentation/` must report the shared reference as unavailable.
|
|
79
|
+
|
|
80
|
+
## Derived views
|
|
81
|
+
|
|
82
|
+
**Applicability** (`conservative-all-governed`, not exact dependency inference):
|
|
83
|
+
|
|
84
|
+
| Change | Affected views |
|
|
85
|
+
|---|---|
|
|
86
|
+
| Any governed or legacy source path | Every declared `derived` view |
|
|
87
|
+
| A declared derived output | Every declared view (the check does not narrow to the changed output) |
|
|
88
|
+
| The config (candidate declarations) | Every candidate declaration; removed or changed declarations are reported, never taken as proof of completion |
|
|
89
|
+
|
|
90
|
+
- Include deleted and old rename paths.
|
|
91
|
+
- If the baseline is unavailable, applicability stays unknown and pending.
|
|
92
|
+
- `check` lists each affected view in `coverage.unsupported` as unverified (`applicability: conservative-all-governed`). It never runs a generator. Partial coverage is still exit 0 when lint and links pass.
|
|
93
|
+
- With `--base <rev>`, `check` reads the base config through `git show` and names each declaration that is gone or changed: `applicability: declaration-removed` or `declaration-changed`, still unverified. A base revision that cannot be read is reported, not skipped.
|
|
94
|
+
- Without `--base`, a changed config adds a warning: removed or renamed declarations cannot be detected.
|
|
95
|
+
- A declared glob is reported as `applicability: glob-unsupported`, not as a concrete unverified view.
|
|
96
|
+
- A declared view that also matches a `governed` or `legacy` pattern is reported as `applicability: self-governed`. A derived view must not be governed or indexed by its own generator.
|
|
97
|
+
|
|
98
|
+
**Authorized generation** (host-run, per view):
|
|
99
|
+
|
|
100
|
+
1. Show the complete command, the working directory, and the expected writes.
|
|
101
|
+
2. Get authorization from current host policy. A non-empty `generator` string in config is not authorization.
|
|
102
|
+
3. Run it through the host tool. Do not wrap it to hide expansion from permission review.
|
|
103
|
+
4. Capture stdout bytes to a scratch file outside the source globs. stdout must hold only the artifact; logs go to stderr. Prefer `process.execPath` with an argument array over shell splitting.
|
|
104
|
+
|
|
105
|
+
**`compare-derived`** (pure; executes nothing):
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
node "<this-skill-dir>/scripts/doc-check.js" compare-derived \
|
|
109
|
+
--workspace "<project-root>" --config .agents/harness-everything/project-docs.json \
|
|
110
|
+
--view docs/governed-index.md --candidate "<scratch-file>" --generation-status ok
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
| Case | Exit | Result |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| Fresh stdout, target bytes equal | 0 | `equal` |
|
|
116
|
+
| Target differs, or declared target missing | 1 | `stale` or `missing-view`; keep the target intact |
|
|
117
|
+
| Generator exit non-zero (caller-reported) | 1 | `generator-failed`; no equality claim, even on partial stdout |
|
|
118
|
+
| Host timeout or termination | 2 | `generation-timeout`; partial stdout is not compared |
|
|
119
|
+
| Executable missing or permission unavailable | 2 | `generator-unavailable`; no fallback command |
|
|
120
|
+
| Candidate missing or unreadable; config invalid; absent or invalid status; undeclared or ambiguous view; candidate aliases the target | 2 | `comparison-unavailable`; never PASS |
|
|
121
|
+
| Generator reported `unsupported` (write-in-place or glob output), or a glob or traversal or absolute `--view` | 2 | `unsupported`; the JSON result names the case |
|
|
122
|
+
| Missing required flag, `--flag=value` form, repeated flag, or odd argument count | 2 | `usage-error`; the JSON result names the problem |
|
|
123
|
+
|
|
124
|
+
- `--generation-status` is required: `ok`, `failed`, `timeout`, `unavailable` or `unsupported`. It is caller-reported ordinary evidence, not host attestation. For any non-`ok` value, the candidate is not read.
|
|
125
|
+
- `--view` must match exactly one literal declared `derived.path`. Wildcards are reported as unsupported. Traversal, absolute targets and symlink escape are rejected. A near-miss (leading `./`, a trailing `/`, a case-only difference, or backslashes) is rejected with exit 2, and the reason names the closest declared path.
|
|
126
|
+
- The candidate must be a regular file. A FIFO, a device or a directory gives exit 2 `comparison-unavailable`, and the call never blocks.
|
|
127
|
+
- The declared generator runs from the project root (cwd = the workspace). A relative path such as `node harness-everything/scripts/...` is project-relative. In an installed plugin, name the installed skill path instead.
|
|
128
|
+
- Byte equality only. No trimming, line-ending conversion, encoding repair, or hash-only comparison. CRLF output is stale until regenerated with the project's output convention.
|
|
129
|
+
- Stdout-only generators are supported. Write-in-place and glob outputs are unsupported.
|
|
130
|
+
- Freshness: regenerate after any source or config edit, and compare before further source edits.
|
|
131
|
+
- Record one comparison per affected view in the task report: the command, cwd, exit, the stdout artifact, stderr, and the `compare-derived` result.
|
|
132
|
+
|
|
133
|
+
**Windows:** use host-appropriate `npm.cmd` or PowerShell execution for authorized npm commands. Harness adds no cross-platform shell runner.
|
|
134
|
+
|
|
135
|
+
**Boundary:** generators run with the user's privileges. Neither sandboxing nor trusted provenance is provided. If the host cannot bound or terminate a run, report it unavailable instead of inventing a completed run.
|
|
136
|
+
|
|
137
|
+
## What it does not prove
|
|
138
|
+
|
|
139
|
+
- No normative review, quality review or conflict review. Normative changes still need their own review.
|
|
140
|
+
- No trusted reconciliation credit. Exit 0 is ordinary command evidence, not a documentation-obligation PASS.
|
|
141
|
+
- Link checks cover inline `[text](target)` links to local files, including nested or escaped brackets in labels and balanced parentheses in destinations. Any inline-link form the scanner cannot parse appears in `coverage.unsupported`:
|
|
142
|
+
|
|
143
|
+
| Syntax | Result |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `http:`, `https:`, `mailto:`, `#fragment` | Skipped on purpose |
|
|
146
|
+
| `<angle>` destinations, `?query` suffixes, nested/escaped label brackets, balanced destination parentheses | Checked as their plain target |
|
|
147
|
+
| Other schemes, root-relative `/path`, scheme-less `www.` targets, reference-style links | Listed as unsupported, not checked |
|
|
148
|
+
| Malformed inline-link syntax | Listed as `inline-link-unparsed` in `coverage.unsupported` |
|
|
149
|
+
| Changed path not on disk (`reason: "not on disk"`) | Listed as unsupported, not checked |
|
|
150
|
+
| Changed path not governed (`reason: "not governed"`) | Listed as unsupported, not checked |
|
|
151
|
+
| Changed path on disk but unreadable | `links.broken` with `reason: "unreadable"`; exit 1 |
|
|
152
|
+
|
|
153
|
+
A non-empty `coverage.unsupported` means the check is partial. Say so when you report.
|
|
154
|
+
|
|
155
|
+
Bare `<DOMAIN>-NNN` tokens (no `REQ-`, `PRD-` or `legacy:` prefix) are references only for a declared domain or an exact known ID, alias or legacy ID. When no `domains` are declared, `coverage.unsupported` says so once per run.
|
|
156
|
+
|
|
157
|
+
## Repair a config error
|
|
158
|
+
|
|
159
|
+
| Symptom | Repair |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `cannot read config` (exit 2) | Create `.agents/harness-everything/project-docs.json` with `governed` entries such as `{"path": "docs/x.md", "role": "reference"}` |
|
|
162
|
+
| `invalid project-docs config` (exit 2) | Fix the reported key. Roles: `prd`, `adr`, `ticket`, `reference`, `log`, `report` |
|
|
163
|
+
| Host `projectDocs` differs | A project file wholly overrides differing host values. Keep the fields you still need |
|
|
164
|
+
| `no domains declared; bare <DOMAIN>-NNN references are not checked` in `coverage.unsupported` | Declare `domains` to have bare ADR-style refs checked. An undeclared-domain token is never a valid ADR ID (contract D6.8) |
|
|
165
|
+
|
|
166
|
+
Do not silence a missing config. A missing config is a visible gap.
|
|
167
|
+
|
|
168
|
+
## Credit (F4)
|
|
169
|
+
|
|
170
|
+
The JSON carries a logical command ID (`harness.doc-check.check.v1` or `harness.doc-check.compare-derived.v1`) and per-capability `capabilities` with checked paths, coverage and skipped reasons. Credit is granted only for a registered run of this install's own script, identified by its resolved path and digest.
|
|
171
|
+
|
|
172
|
+
- This JSON is **never self-credited**. Stdout that repeats an ID or a status is not evidence of credit.
|
|
173
|
+
- Credit needs the host-captured raw output, checked against the producer's independently derived expected set. See `docs/doc-workflow-reconciliation.md`, section "F4: credited reconciliation".
|
|
174
|
+
- Reminders never earn credit.
|
|
175
|
+
- Trust is conservative. A compound shell command (newline, heredoc, `$()`, operators, malformed quoting) or any command that names doc-check gets no generic verification and does not make a reviewer independent. Run the checker as a plain command. A benign compound such as `npm test && echo ok` must run as its own command to count as generic verification.
|
|
176
|
+
|
|
177
|
+
For an independent review in the L3 path, the parent computes the post-edit candidate digest with the one read-only command `shasum -a 256 docs/a.md`, then gives the reviewer the relative path and actual digest. The reviewer reads the file and returns a plain `Review verdict: approve` or `Review verdict: reject` line, `Reviewed artifact: docs/a.md sha256:<digest>`, and a non-empty `Summary:` line. Do not edit between hashing and review or pre-fill the verdict. Assessment still checks the correlated host review and the candidate digest; supplying a digest is not proof of reading.
|
|
178
|
+
|
|
179
|
+
## Record evidence
|
|
180
|
+
|
|
181
|
+
Keep these in the task's verification record:
|
|
182
|
+
|
|
183
|
+
- The full command, the workspace, the `--base` SHA and the changed paths
|
|
184
|
+
- Exit code and the single JSON object on stdout (`lint.error` explains exit 2)
|
|
185
|
+
- Whether `coverage.unsupported` is empty
|
|
186
|
+
- Label the claim as command evidence, not as document-obligation credit
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Shared Maintenance (D6.5, D6.6)
|
|
2
|
+
|
|
3
|
+
Shared by the doc-producing skills and the editorial doc check. Read this when a change touches a governed document, a requirement, a ticket or an ADR. The command for the mechanical checks is in [doc-check.md](../../doc-check.md).
|
|
4
|
+
|
|
5
|
+
## Event table
|
|
6
|
+
|
|
7
|
+
Origins cite D-numbers and section names in `docs/document-lifecycle.md` (the repository source; it is not in the packaged skill). Strength and Enforced by are copied from that source. `—` means the source gives no strength or enforcement for the row. It does not mean the row is optional.
|
|
8
|
+
|
|
9
|
+
| Origin | Event | Obligation | Strength | Enforced by |
|
|
10
|
+
|---|---|---|---|---|
|
|
11
|
+
| D6.5 — `doc-change` applicability by diff facts | Any governed file touched | Lint (role, status, ID, alias) and in-repo link check (`doc-check.md`) | — | — |
|
|
12
|
+
| D6.5 — `doc-change` applicability by diff facts | New governed file | Update-over-create check | — | — |
|
|
13
|
+
| D6.5 — `doc-change` applicability by diff facts | New PRD or ADR outline | Outline confirmation | MUST | — |
|
|
14
|
+
| D6.5 — `doc-change` applicability by diff facts | New other governed outline | Outline confirmation | SHOULD | — |
|
|
15
|
+
| D6.5 — `doc-change` applicability by diff facts | Declared derived source affected | Regenerate and regenerate-equals (generators are not automated; see below); the command-lane procedure is in `doc-check.md` § Derived views | — | — |
|
|
16
|
+
| D6.5 — `doc-change` applicability by diff facts | Normative field: frontmatter `status` or `supersedes`, PRD REQ block or acceptance, ADR *Decision* section | Quality review; D6.4 conflict check | MUST | — |
|
|
17
|
+
| D6.5 — `doc-change` applicability by diff facts | Governed reference or guide content | Prose > 50% reminder (see `writing-craft.md`) | SHOULD | — |
|
|
18
|
+
| D6.6 — Event-driven maintenance | A test citing `REQ-X` is added or its assertions change | Update or supersede `REQ-X` in the same change, or record `no-req-change` with reason and cited evidence | MUST | New rule |
|
|
19
|
+
| D6.6 — Event-driven maintenance | An existing test's cited REQ identity set is added, removed, or retargeted, or the changed call cannot be associated with its prior identity | Applicability/scope `unknown`, never N/A; retain candidate REQ identities and the test path. If removal leaves no candidate identity, retain the prior REQ ID as a removed identity. A citation-only change is not by itself a `new-test` or `assertion-change` trigger | — | — |
|
|
20
|
+
| D6.6 — Event-driven maintenance | A legacy file-level REQ tag is added, removed, or retargeted on a modified test file | Applicability/scope `unknown`, never N/A; retain the changed identity and test path, even when stripped comments leave assertion tokens unchanged | — | — |
|
|
21
|
+
| D6.6 — Event-driven maintenance | `no-req-change` without adequate evidence | Recorded as `not-observed`; never an automatic pass | — | — |
|
|
22
|
+
| D6.6 — Event-driven maintenance | Code changed, no REQ-citing test touched | `not-observed`, not a failure; a diff alone does not prove behaviour unchanged | — | — |
|
|
23
|
+
| D6.6 — Event-driven maintenance | Agent claims `REQ-X` affected, no supporting evidence | Claim and evidence contradict; reminder, no lock | — | — |
|
|
24
|
+
| D6.6 — Event-driven maintenance | `describes:` fingerprint drift | Reminder | SHOULD | D5 #4 |
|
|
25
|
+
| D6.6 — Event-driven maintenance | Ticket closed | In-repo tickets: `status: done`; regenerate index. `tickets: "tracker"`: no in-repo ticket status is generated or inferred offline | MUST | D5 #1 + D6.3 lint |
|
|
26
|
+
| D6.6 — Event-driven maintenance | ADR superseded | Old ADR `status: superseded` | MUST | D6.3 lint |
|
|
27
|
+
| D6.6 — Event-driven maintenance | New defect | Goes to tracker or the declared `tickets` path | MUST | Lint reminder when a ticket is added under a `done` phase |
|
|
28
|
+
| D6.6 — Event-driven maintenance | Report finished | `final`; `archived` once its work closes | SHOULD | Reminder |
|
|
29
|
+
|
|
30
|
+
For PRDs (D6.9, “Contract-style PRD revisions”), the update-over-create check applies when adding a governed file. An existing draft revision can be edited in place and is never authoritative. An approved revision may only be activated (`status` and `effective_at`, at the same path); any other edit requires returning it to `draft` and re-approving. An effective revision is frozen; a change creates a new complete revision copied from the current effective revision.
|
|
31
|
+
|
|
32
|
+
## Not automated
|
|
33
|
+
|
|
34
|
+
- Derived-view generator execution. It stays host-authorized: discovery of affected views and the `compare-derived` comparison execute nothing. See `doc-check.md` § Derived views.
|
|
35
|
+
- Trusted reconciliation credit. The lint and link check is ordinary command evidence only.
|
|
36
|
+
- Code-to-doc dependency edges (#350).
|
|
37
|
+
- Forcing or selecting a provider. Advisory provider suggestions do exist (`doc-providers.js`, `suggestDocProviders`, S3); they are never forced or auto-selected.
|
|
38
|
+
- Auto-publish, auto-commit, or automatic locks.
|
|
39
|
+
- Changes to the S1 default-OFF pilot.
|
|
40
|
+
|
|
41
|
+
Each skill's own approval and authority contract still applies. This table adds obligations; it does not replace them.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Shared Writing Craft (D6.7)
|
|
2
|
+
|
|
3
|
+
Shared by the doc-producing skills (`to-spec`, `to-tickets`, `repo-docs`, `grill-with-docs`) and by the editorial doc check. Read this before drafting a governed or shared Markdown document.
|
|
4
|
+
|
|
5
|
+
Attribution: ideas adapted from mattpocock-skills and ECC (both MIT-licensed). The wording here is original; no code is imported.
|
|
6
|
+
|
|
7
|
+
## Principles
|
|
8
|
+
|
|
9
|
+
| Content | Form |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Flow or relations | Mermaid, ideally ≤ ~15 nodes per diagram |
|
|
12
|
+
| Comparisons or fields | Tables, one fact per cell |
|
|
13
|
+
| Ordered steps or rules | Bullets |
|
|
14
|
+
| Rationale | Prose, normally ≤ 3 sentences per paragraph, one idea per sentence |
|
|
15
|
+
| Long elaboration | Outside tables, in prose or a linked section |
|
|
16
|
+
|
|
17
|
+
These are not a claim that brevity proves quality.
|
|
18
|
+
|
|
19
|
+
## Prose-share SHOULD reminder
|
|
20
|
+
|
|
21
|
+
- Threshold: a non-blank, non-code prose-line share above 50% triggers a reminder.
|
|
22
|
+
- Strength: **SHOULD**. It is advisory, never a quality gate, a lock, or a cognitive lock (#190).
|
|
23
|
+
- It does not change exit codes, lint, links, or coverage. Dismiss a reminder by reading it; no waiver or exemption exists.
|
|
24
|
+
|
|
25
|
+
## Line classification
|
|
26
|
+
|
|
27
|
+
Counted on the body only, after removing leading frontmatter and splitting CRLF and LF.
|
|
28
|
+
|
|
29
|
+
| Physical line | Denominator | Prose numerator |
|
|
30
|
+
|---|---|---|
|
|
31
|
+
| Blank or whitespace only | Exclude | Exclude |
|
|
32
|
+
| Fenced code, including the fence markers | Exclude | Exclude |
|
|
33
|
+
| Four-space or tab-indented line outside fences | Exclude | Exclude |
|
|
34
|
+
| ATX heading; `-`, `+` or `*` bullet; ordered marker (digits, then `.` or `)`); pipe-leading table row | Include | Exclude |
|
|
35
|
+
| Thematic separator (three or more identical `-`, `*` or `_`) | Include | Exclude |
|
|
36
|
+
| Everything else (blockquotes, `**Label:** text`, CJK, inline-code sentences, HTML or comments, unmarked continuations) | Include | Include |
|
|
37
|
+
|
|
38
|
+
- Fence rules: an opening fence is 0–3 spaces, then three or more backticks or tildes. The closing fence is the same character, at least the opening length, with trailing whitespace only. An unclosed fence runs to end of file. Mermaid counts as code.
|
|
39
|
+
- Trigger: zero eligible lines gives `share = 0`, no reminder. Otherwise `share = proseLines / eligibleLines`, and the reminder fires when `2 × proseLines > eligibleLines` (strictly greater, so exactly 50% does not fire).
|
|
40
|
+
|
|
41
|
+
## Limitations (documented false positives and negatives)
|
|
42
|
+
|
|
43
|
+
- Counts quoted prose, generated text and continuation lines as prose.
|
|
44
|
+
- Treats deeply indented list content as code.
|
|
45
|
+
- Recognises only pipe-leading tables and ATX headings.
|
|
46
|
+
- A UTF-8 BOM before the opening `---` stops frontmatter detection (the parser needs the exact first line `---`), so frontmatter lines are then counted. No code change; the case is documented here.
|
|
47
|
+
- No reflow normalisation, NLP, label exemption or quality score. Do not grow a Markdown parser to tune one result.
|
|
48
|
+
|
|
49
|
+
## Example fixtures
|
|
50
|
+
|
|
51
|
+
These are the expected counts for the classifier above. They are design expectations, pinned by tests in a later packet.
|
|
52
|
+
|
|
53
|
+
| Body | Prose / eligible | Reminder |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| Heading, then one prose line | 1 / 2 | No (exactly 50%) |
|
|
56
|
+
| Heading, prose line, `**Problem:** More` | 2 / 3 | Yes (label line counts) |
|
|
57
|
+
| Heading, blank line, fenced code | 0 / 1 | No |
|
|
58
|
+
| Blockquote CJK line, CJK prose line, pipe-table row | 2 / 3 | Yes |
|
|
59
|
+
| Code fence only | 0 / 0 | No |
|
|
@@ -56,6 +56,10 @@ The model remains free to choose tools, implementation technique, decomposition
|
|
|
56
56
|
|
|
57
57
|
Keyword/domain matches are normalized planning signals, not document selectors. Each ordered step declares its required and optional skill/reference bindings; only the active step or dependency-ready Fable stage exposes those paths. Read a required skill's complete entry and follow its applicable core contract before the step passes. Required bindings without a known path remain visible and unresolved. Optional bindings resolve as loaded or not-needed. Hooks may remind, but missing bindings do not hard-block ordinary tools or Stop.
|
|
58
58
|
|
|
59
|
+
### Governed-doc check
|
|
60
|
+
|
|
61
|
+
An active `doc-change` step, or any edit to a file governed by `.agents/harness-everything/project-docs.json`, runs the editorial check in [doc-check.md](doc-check.md): lifecycle lint plus local link targets. Its exit code is ordinary command evidence, not trusted document credit.
|
|
62
|
+
|
|
59
63
|
## 2. Routing Mechanism
|
|
60
64
|
|
|
61
65
|
Use the public kernel entry point:
|