From a8d5ae8cd33b8028a995ee8decfa0b70b20a782d Mon Sep 17 00:00:00 2001 From: anusbutt Date: Fri, 14 Aug 2026 21:32:12 +0500 Subject: [PATCH] docs: align documentation with current features --- README.md | 4 + benchmarks/graphkeeper-memory-bench-v0.1.md | 4 +- docs/contributor-issues.md | 21 +---- docs/diagnostics.md | 91 +++++++++++++++++++++ examples/worked-example/README.md | 11 +++ tests/integration/contributor-docs.test.ts | 31 ++++++- 6 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 docs/diagnostics.md diff --git a/README.md b/README.md index 6896c75..132a40a 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,8 @@ The older claim remains in history and is marked as superseded. Reviewers can fo | `graphkeeper query ` | Resolve an exact ID or unique alias and print active claims with provenance. It does not read evidence contents. | | `graphkeeper doctor` | Run fast validation plus file existence, containment, line-range, dangling-reference, and unused-entity checks. | | `graphkeeper update` | Check npm's stable `latest` release and globally install one exact newer version. Repository files are never changed. | +| `graphkeeper --help` | Print the supported command grammar and options. | +| `graphkeeper --version` (`-v`) | Print the installed GraphKeeper version. | Exit codes are stable: `0` success, `1` validation failure, `2` usage error, `3` missing prerequisite, `4` operational failure, and `5` unexpected internal failure. Diagnostics begin with a searchable `GKnnn` code. @@ -164,6 +166,8 @@ prompt. ## Recovery and adoption - Re-running `init` is safe: existing graph data is skipped. Use `--force` only to refresh `graph/SCHEMA.md` and `.agents/skills/graphkeeper/SKILL.md`. +- For a `GKnnn` failure, use the [diagnostic reference](docs/diagnostics.md) to identify + the emitting command, exit class, and safe recovery before changing graph data. - A root `SKILL.md` created by an older GraphKeeper version is legacy user content. It is reported and preserved; migrate by committing the generated `.agents/skills/graphkeeper/SKILL.md`. - `--integrate codex` manages the Codex skill plus one marked block in `AGENTS.md`; `--integrate claude` does the same for the Claude skill and `CLAUDE.md`. Multiple diff --git a/benchmarks/graphkeeper-memory-bench-v0.1.md b/benchmarks/graphkeeper-memory-bench-v0.1.md index 1ea13c4..02161db 100644 --- a/benchmarks/graphkeeper-memory-bench-v0.1.md +++ b/benchmarks/graphkeeper-memory-bench-v0.1.md @@ -2,7 +2,7 @@ This document defines the first four scenarios for evaluating durable project memory in coding agents. -At this stage, the goal is only to define the tests. Scoring methodology and benchmark implementation will come later. +The benchmark defines the scenarios. Test A also has manually recorded pre-fix and post-fix executions; reusable scoring methodology, automated evaluation, and datasets remain future work. ## Test A — Repeated Investigation @@ -71,4 +71,4 @@ GraphKeeper Memory Bench v0.1 currently defines only these four scenarios: 3. Provenance 4. Correction history -Scoring methodology, automated evaluation, datasets, and benchmark execution are intentionally left for later versions. +Test A has recorded [pre-fix FAIL](results/repeated-investigation-pre-fix-2026-08-14/README.md) and [post-fix PASS](results/repeated-investigation-post-fix-pass-2026-08-14/README.md) results. These are manual evidence records, not an automated benchmark harness. Tests B-D, reusable scoring methodology, automated evaluation, and datasets remain future work. diff --git a/docs/contributor-issues.md b/docs/contributor-issues.md index 187e74e..edf15bd 100644 --- a/docs/contributor-issues.md +++ b/docs/contributor-issues.md @@ -4,25 +4,6 @@ These are launch-ready drafts, not committed roadmap promises. A maintainer shou confirm priority and create the GitHub issue before work starts. Each task stays inside GraphKeeper's v1 boundaries. -## Document every public `GKnnn` diagnostic - -**Suggested labels:** `good first issue`, `type:docs`, `area:cli` - -**Context:** Diagnostics are stable and searchable, but users currently have to read -source and tests to learn which command emits each code and what recovery is safe. - -**Scope:** Add a concise diagnostic reference derived from `src/lib/errors.ts`, CLI -call sites, and validator output. Link it from README recovery guidance. Do not change -codes or exit behavior. - -**Acceptance criteria:** - -- Every public code family and stable exit code has a plain-language meaning. -- Each entry names the emitting command or validator and a safe next step. -- The reference distinguishes validation, prerequisite, operational, and internal - failures. -- A documentation test fails if the reference or README link is removed. - ## Add a second worked example for a durable architecture constraint **Suggested labels:** `good first issue`, `type:docs`, `area:testing` @@ -97,7 +78,7 @@ POSIX paths. Keep evidence contents inert. - Each hostile shape has a rejecting test with the expected stable diagnostic. - Valid nested repository-relative evidence remains accepted. -- Tests run in the existing Linux and Windows/Git Bash CI jobs. +- Tests run in the existing Linux, macOS, Windows/Git Bash, and native Windows PowerShell CI jobs as applicable. - No test executes stored commands or follows an escaping symlink. ## Document and test a shared-hook chaining recipe diff --git a/docs/diagnostics.md b/docs/diagnostics.md new file mode 100644 index 0000000..406b9e0 --- /dev/null +++ b/docs/diagnostics.md @@ -0,0 +1,91 @@ +# Diagnostic reference + +GraphKeeper diagnostics use `GKnnn` codes so failures remain searchable across the CLI, +repository validator, Git hook, and `doctor`. The text in brackets identifies the +record, file, alias, or evidence reference that needs attention. + +`src/lib/errors.ts` defines the stable exit codes. `src/lib/validation.ts` is the +canonical fast-validator source, and the generated `scripts/validate.mjs` mirrors it. +The legacy `scripts/validate.sh` is a compatibility fallback. + +Before repairing a validation failure, preserve GraphKeeper's append-only rules. Restore +changed committed claims or evidence, then append a superseding claim or new evidence +instead of rewriting history. Run `graphkeeper check` after a repair and +`graphkeeper doctor` when evidence or cross-record relationships are involved. + +## Exit codes + +| Exit | Class | Meaning | +|---|---|---| +| `0` | Success | The command completed. `doctor` also uses `0` when it reports warnings but no errors. | +| `1` | Validation | Graph data, provenance, evidence, or query resolution is invalid. | +| `2` | Usage | Command grammar, arguments, validator mode, or required confirmation is invalid. | +| `3` | Prerequisite | A required executable such as Git, Node.js, npm, or legacy `sh`/jq is unavailable. | +| `4` | Operational | GraphKeeper could not safely read, write, compare, spawn, integrate, or contact a required service. | +| `5` | Internal | A child validator returned an exit code outside GraphKeeper's public range. | + +## CLI and runtime diagnostics + +| Code | Emitted by | Meaning and safe recovery | +|---|---|---| +| `GK002` | CLI and standalone validator | Invalid command arguments, validator mode, or non-interactive confirmation. Run `graphkeeper --help`, correct the arguments, and use `--yes` or `--dry-run` when confirmation cannot be interactive. | +| `GK003` | `init`, `check`, `update`, and standalone validator | A named prerequisite is missing. Install or restore the named tool, confirm it is on `PATH`, and retry. A customized legacy validator may require POSIX `sh` and jq 1.6 or newer. | +| `GK004` | All repository-mutating commands, `check`, `query`, `doctor`, `update`, and validator loading | An operation could not be completed safely. Follow the specific message: restore access or a missing generated validator, repair malformed integration markers, retry a timed-out process or registry request, and rerun without bypassing ownership checks. | +| `GK005` | `check` | The repository validator returned an unexpected exit code. Preserve its preceding output, rerun once, and report a reproducible failure if it persists. | + +`GK002`, `GK003`, `GK004`, and `GK005` map to exit codes `2`, `3`, `4`, and `5` +respectively. + +## Fast validation diagnostics + +These codes are emitted by the Node validator used by `graphkeeper check`, `query`, +`doctor`, and the installed pre-commit hook. Each is a validation failure with exit +code `1`. + +| Code | Meaning | Safe recovery | +|---|---|---| +| `GK101` | A required graph JSON file is missing from the worktree or staged snapshot. | Restore the named file, run `graphkeeper init` for a missing scaffold, or add and stage the required file. | +| `GK102` | A graph document is not valid JSON. | Restore a valid JSON array and rerun validation. | +| `GK110` | Entity schema or entity-ID uniqueness is invalid. | Correct the named records, keep IDs unique, and preserve committed identity fields; aliases and `source_docs` may only grow. | +| `GK120` | Claim schema, claim-ID uniqueness, or source shape is invalid. | Correct uncommitted records. For a committed conclusion, restore it and append a valid superseding claim. | +| `GK130` | Run schema, run-ID uniqueness, or lifecycle is invalid. | Correct uncommitted records; only grow an open run, close it once, and never mutate a committed closed run. | +| `GK140` | References, bidirectional provenance, or the supersession graph is invalid. | Repair missing links in both directions and keep supersession to one acyclic successor. Restore committed records before appending a correction. | +| `GK150` | The committed `HEAD` graph cannot be parsed as JSON. | Inspect the committed baseline, restore valid graph JSON through a reviewed history repair, then validate new work against that baseline. | +| `GK151` | A committed claim changed or was removed. | Restore the claim byte-for-byte at the data-model level and append a new claim with `supersedes`. | +| `GK152` | Committed entity identity changed, or an alias/source-document value was removed. | Restore identity and removed accumulated values; only append aliases or `source_docs`. | +| `GK153` | An open run made a non-growth transition, or a committed closed run changed. | Restore the run; grow only allowed open-run fields and close the run exactly once. | +| `GK154` | Committed evidence changed, was deleted, or was renamed. | Restore the original evidence path and contents, then capture new output in a new evidence file. | + +## Query diagnostics + +Both query codes use exit code `1` after fast validation succeeds. + +| Code | Emitted by | Meaning and safe recovery | +|---|---|---| +| `GK201` | `query` | An alias resolves to more than one entity. Query one of the listed canonical IDs; do not remove a committed alias to force uniqueness. | +| `GK202` | `query` | No entity matches the exact ID or alias. Check the spelling, use a known canonical ID, or add a valid entity before querying it. | + +## Doctor diagnostics + +`doctor` includes all fast-validator diagnostics, then performs duplicate-key, evidence, +and graph-reference checks. Codes `GK300` through `GK325` are errors and produce exit +code `1`. `GK390` is a warning and does not fail an otherwise healthy doctor run. + +| Code | Meaning | Safe recovery | +|---|---|---| +| `GK300` | A graph document became unreadable after fast validation. | Restore file access and rerun; if another process is changing the graph, stop it before retrying. | +| `GK301` | A graph document contains a duplicate JSON key. | Keep one intended key/value in the uncommitted record and rerun both check and doctor. | +| `GK310` | An evidence reference has the wrong shape, is unsafe, or resolves outside `evidence/`. | Use `evidence/#L-L` with a contained repository-relative path. | +| `GK311` | Referenced evidence does not exist. | Restore the referenced file or, for new work, capture it and update the uncommitted reference. | +| `GK312` | Evidence cannot be read. | Restore read permission and ensure the path is an accessible regular file. | +| `GK313` | Evidence is not a regular UTF-8 text file or contains binary control bytes. | Capture inert UTF-8 text in a regular file and reference that file instead. | +| `GK314` | An evidence line range starts below line 1. | Change the uncommitted range so its start is at least 1. | +| `GK315` | An evidence range starts after it ends. | Put the inclusive start before or at the inclusive end. | +| `GK316` | An evidence range ends past the file's logical line count. | Recount the file and use an in-bounds inclusive range. | +| `GK320` | A claim subject does not resolve to an entity. | Add the missing entity or correct the uncommitted subject ID. | +| `GK321` | A claim's `produced_by` run does not exist. | Add the producing run or correct the uncommitted run ID. | +| `GK322` | A claim's `supersedes` target does not exist. | Point to the actual predecessor claim and preserve an acyclic correction chain. | +| `GK323` | A run's `claims_written` entry names no claim. | Add the claim or remove the invalid uncommitted run entry. | +| `GK324` | A run lists a claim whose `produced_by` names another run. | Make the uncommitted claim and run agree on one producer. | +| `GK325` | A claim names a producing run that does not list the claim. | Add the claim ID to the matching open run's `claims_written` list before it is committed closed. | +| `GK390` | An entity is not referenced by any claim. | No action is required if intentional; otherwise record a grounded claim through a run. Do not delete a committed entity merely to silence the warning. | diff --git a/examples/worked-example/README.md b/examples/worked-example/README.md index f45e866..8eb28d9 100644 --- a/examples/worked-example/README.md +++ b/examples/worked-example/README.md @@ -17,6 +17,17 @@ WSL: node dist/src/cli.js check node dist/src/cli.js doctor +From native Windows PowerShell: + +```powershell +npm run build +New-Item -ItemType Directory -Force graph, evidence | Out-Null +Copy-Item -Path examples/worked-example/graph/* -Destination graph/ -Recurse -Force +Copy-Item -Path examples/worked-example/evidence/* -Destination evidence/ -Recurse -Force +node dist/src/cli.js check +node dist/src/cli.js doctor +``` + Installed-package users can run `npx graphkeeper check` and `npx graphkeeper doctor` instead. Both commands should succeed, and doctor should report zero errors and zero warnings. diff --git a/tests/integration/contributor-docs.test.ts b/tests/integration/contributor-docs.test.ts index c405cf6..61df3b4 100644 --- a/tests/integration/contributor-docs.test.ts +++ b/tests/integration/contributor-docs.test.ts @@ -131,6 +131,33 @@ test('contribution guide documents recovery and known scale limits', async () => assert.match(guide, /(?:20 percent.*regression|regression.*20 percent)/is); }); +test('diagnostic reference covers every public code and stable exit class', async () => { + const readme = await read('README.md'); + const reference = await read('docs/diagnostics.md'); + + assert.match(readme, /\[diagnostic reference\]\(docs\/diagnostics\.md\)/i); + assert.match(reference, /src\/lib\/validation\.ts.*canonical/is); + assert.match(reference, /restore.*committed claims.*append.*superseding/is); + + const publicCodes = [ + 'GK002', 'GK003', 'GK004', 'GK005', + 'GK101', 'GK102', 'GK110', 'GK120', 'GK130', 'GK140', + 'GK150', 'GK151', 'GK152', 'GK153', 'GK154', + 'GK201', 'GK202', + 'GK300', 'GK301', 'GK310', 'GK311', 'GK312', 'GK313', 'GK314', 'GK315', 'GK316', + 'GK320', 'GK321', 'GK322', 'GK323', 'GK324', 'GK325', 'GK390', + ] as const; + for (const code of publicCodes) { + assert.ok(reference.includes('| `' + code + '` |'), 'Missing diagnostic reference for ' + code); + } + + for (const exitCode of ['0', '1', '2', '3', '4', '5']) { + assert.ok(reference.includes('| `' + exitCode + '` |'), 'Missing exit code ' + exitCode); + } + assert.match(reference, /doctor.*uses `0`.*warnings/is); + assert.match(reference, /`GK390` is a warning.*does not fail/is); +}); + test('SQLite and PostgreSQL remain a future good-first-issue design exploration', async () => { const guide = await read('CONTRIBUTING.md'); assert.match(guide, /good first issue/i); @@ -175,9 +202,9 @@ test('issue and pull-request templates require actionable engineering context', assert.match(conduct, /report.*privately/is); const issueDrafts = await read('docs/contributor-issues.md'); - assert.equal((issueDrafts.match(/^## /gm) ?? []).length, 7); + assert.equal((issueDrafts.match(/^## /gm) ?? []).length, 6); for (const field of ['Suggested labels', 'Context', 'Scope', 'Acceptance criteria']) { - assert.equal((issueDrafts.match(new RegExp('\\*\\*' + field, 'g')) ?? []).length, 7); + assert.equal((issueDrafts.match(new RegExp('\\*\\*' + field, 'g')) ?? []).length, 6); } const guide = await read('CONTRIBUTING.md');