From 088fc204ee7e74fdd8a4281b8ab48e50d5fee508 Mon Sep 17 00:00:00 2001 From: Tom Boucher Date: Fri, 15 May 2026 10:23:55 -0400 Subject: [PATCH] fix(3347): clear CI gates raised by initial commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/CONFIGURATION.md: document graphify.auto_update key (config-schema-docs-parity) - hooks/gsd-check-update-worker.js: add gsd-graphify-update.sh to MANAGED_HOOKS (managed-hooks) - agents/gsd-planner.md + gsd-phase-researcher.md: slim auto-update awareness block to a one-line @-reference; extract full instructions to a new reference file - get-shit-done/references/planner-graphify-auto-update.md: new reference with the status-file schema, the four annotation cases (running/failed/ok-current/ok-stale), and interaction with the existing stale-mtime annotation - docs/INVENTORY.md: References (60 → 61 shipped) + row for new reference; regenerate docs/INVENTORY-MANIFEST.json via gen-inventory-manifest.cjs Co-Authored-By: Claude Opus 4.7 (1M context) --- agents/gsd-phase-researcher.md | 2 +- agents/gsd-planner.md | 16 +---- docs/CONFIGURATION.md | 1 + docs/INVENTORY-MANIFEST.json | 1 + docs/INVENTORY.md | 3 +- .../planner-graphify-auto-update.md | 58 +++++++++++++++++++ hooks/gsd-check-update-worker.js | 1 + 7 files changed, 65 insertions(+), 17 deletions(-) create mode 100644 get-shit-done/references/planner-graphify-auto-update.md diff --git a/agents/gsd-phase-researcher.md b/agents/gsd-phase-researcher.md index da39afaa5..17e6349fd 100644 --- a/agents/gsd-phase-researcher.md +++ b/agents/gsd-phase-researcher.md @@ -637,7 +637,7 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" graphify status If the status response has `stale: true`, note for later: "Graph is {age_hours}h old -- treat semantic relationships as approximate." Include this annotation inline with any graph context injected below. -**Auto-update awareness (issue #3347).** If `.planning/graphs/.last-build-status.json` exists, read it and surface the most recent auto-build state alongside the staleness note. The hook (`hooks/gsd-graphify-update.sh`, opt-in via `graphify.auto_update`) writes this file. Format the surfaced annotation based on `status`: `"running"` → "rebuild in flight (started {ts})"; `"failed"` → "auto-rebuild FAILED at {ts} (exit {exit_code}); context is from the prior build — run `/gsd:graphify build` manually to retry"; `"ok"` with `head_at_build` matching current `HEAD` → silent (graph is current); `"ok"` with `head_at_build` differing → "last rebuilt at {ts} for {head_at_build[:7]}; current HEAD has advanced". File missing → silent. +If `.planning/graphs/.last-build-status.json` exists, also load @get-shit-done/references/planner-graphify-auto-update.md — it covers how to surface the most recent auto-build state (running / failed / stale `head_at_build`). Opt-in via `graphify.auto_update` (default false, #3347); silent if the file is absent. Query the graph for each major capability in the phase scope (2-3 queries per D-05, discovery-focused): diff --git a/agents/gsd-planner.md b/agents/gsd-planner.md index 6a3a3b75b..7a36c4d3d 100644 --- a/agents/gsd-planner.md +++ b/agents/gsd-planner.md @@ -892,21 +892,7 @@ node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" graphify status If the status response has `stale: true`, note for later: "Graph is {age_hours}h old -- treat semantic relationships as approximate." Include this annotation inline with any graph context injected below. -**Auto-update awareness (issue #3347).** If `.planning/graphs/.last-build-status.json` exists, read it and surface the most recent auto-build state alongside the staleness note. The hook (`hooks/gsd-graphify-update.sh`, opt-in via `graphify.auto_update`) writes this file. Format the surfaced annotation based on `status`: - -- `status: "running"` — "Graph auto-rebuild in flight (started {ts}); treat semantic relationships as approximate until rebuild completes." -- `status: "failed"` — "Graph auto-rebuild FAILED at {ts} (exit {exit_code}); the planning context below is from the prior build. Run `/gsd:graphify build` to retry manually." -- `status: "ok"` with `head_at_build` matching the current `HEAD` — silent (graph is current). -- `status: "ok"` with `head_at_build` differing from current `HEAD` — "Graph last rebuilt at {ts} for commit {head_at_build[:7]}; current HEAD has advanced -- treat semantic relationships as approximate." -- File missing — silent; rely on the existing staleness note above. - -Read the status file with: - -```bash -test -f .planning/graphs/.last-build-status.json && cat .planning/graphs/.last-build-status.json -``` - -The auto-update mechanism is opt-in (`graphify.auto_update: false` by default per #3347); users who do not opt in will never see this file and the annotation above is a no-op. +If `.planning/graphs/.last-build-status.json` exists, load @get-shit-done/references/planner-graphify-auto-update.md for auto-build state surfacing (opt-in, #3347). Query the graph for phase-relevant dependency context (single query per D-06): diff --git a/docs/CONFIGURATION.md b/docs/CONFIGURATION.md index 415b05752..73c7d8a0a 100644 --- a/docs/CONFIGURATION.md +++ b/docs/CONFIGURATION.md @@ -464,6 +464,7 @@ Toggle optional capabilities via the `features.*` config namespace. Feature flag |---------|------|---------|-------------| | `graphify.enabled` | boolean | `false` | Enable the project knowledge graph. When `true`, `/gsd-graphify` builds and queries a graph in `.planning/graphs/`. Added in v1.36 | | `graphify.build_timeout` | number (seconds) | `300` | Maximum seconds allowed for a `/gsd-graphify build` run before it aborts. Added in v1.36 | +| `graphify.auto_update` | boolean | `false` | **Opt-in (issue #3347).** When `true` (and `graphify.enabled` is also `true`), the bundled PostToolUse hook `hooks/gsd-graphify-update.sh` auto-rebuilds the project knowledge graph in a detached background process after `git commit/merge/pull/rebase --continue/cherry-pick` on the default branch (`git.base_branch` override, else `main`/`master`/`trunk`). Hook returns instantly; the rebuild updates `.planning/graphs/{graph.json,graph.html,GRAPH_REPORT.md}` and writes `.planning/graphs/.last-build-status.json` (`{ts, status: "running"\|"ok"\|"failed", exit_code, duration_ms, head_at_build}`). PID-locked, CI-aware (`$CI` env suppresses), bails silently if `graphify` is not on `PATH`. Default `false` so existing behaviour is unchanged after upgrade. | #### Multi-developer setup diff --git a/docs/INVENTORY-MANIFEST.json b/docs/INVENTORY-MANIFEST.json index 62c2266ea..317360c7a 100644 --- a/docs/INVENTORY-MANIFEST.json +++ b/docs/INVENTORY-MANIFEST.json @@ -224,6 +224,7 @@ "planner-antipatterns.md", "planner-chunked.md", "planner-gap-closure.md", + "planner-graphify-auto-update.md", "planner-human-verify-mode.md", "planner-mvp-mode.md", "planner-reviews.md", diff --git a/docs/INVENTORY.md b/docs/INVENTORY.md index f8e5a884a..4203c0b59 100644 --- a/docs/INVENTORY.md +++ b/docs/INVENTORY.md @@ -262,7 +262,7 @@ Full roster at `get-shit-done/workflows/*.md`. Workflows are thin orchestrators --- -## References (60 shipped) +## References (61 shipped) Full roster at `get-shit-done/references/*.md`. References are shared knowledge documents that workflows and agents `@-reference`. The groupings below match [`docs/ARCHITECTURE.md`](ARCHITECTURE.md#references-get-shit-donereferencesmd) — core, workflow, thinking-model clusters, and the modular planner decomposition. @@ -352,6 +352,7 @@ The `gsd-planner` agent is decomposed into a core agent plus reference modules t | `planner-source-audit.md` | Planner source-audit and authority-limit rules. | | `planner-mvp-mode.md` | Vertical-slice planning rules for MVP mode. | | `planner-human-verify-mode.md` | Rules for `workflow.human_verify_mode = end-of-phase`: suppress `checkpoint:human-verify` task emission and route deferred items via ``. | +| `planner-graphify-auto-update.md` | How `load_graph_context` surfaces `.last-build-status.json` auto-update state (running / failed / stale head) alongside the existing staleness annotation. Opt-in via `graphify.auto_update` (#3347). | | `skeleton-template.md` | SKELETON.md template emitted for new-project Walking Skeleton (Phase 1 + `--mvp`). | | `user-story-template.md` | User story format for MVP planning — "As a / I want to / So that" structured fields. | | `spidr-splitting.md` | SPIDR splitting decomposition rules for handling large user stories in MVP mode. | diff --git a/get-shit-done/references/planner-graphify-auto-update.md b/get-shit-done/references/planner-graphify-auto-update.md new file mode 100644 index 000000000..e7c3167fc --- /dev/null +++ b/get-shit-done/references/planner-graphify-auto-update.md @@ -0,0 +1,58 @@ +# Planner — Graphify Auto-Update Awareness + +> Loaded by `gsd-planner` and `gsd-phase-researcher` inside the `` block, after the existing `graphify status` staleness check. Surfaces the most recent auto-update state from `.planning/graphs/.last-build-status.json`, the file written by the bundled `hooks/gsd-graphify-update.sh` PostToolUse hook (opt-in via `graphify.auto_update`, default `false` — issue #3347). + +## Why this exists + +The graph at `.planning/graphs/graph.json` is consumed automatically (every `gsd-planner` and `gsd-phase-researcher` step) but produced manually (one `/gsd:graphify build` per session at best). Without auto-update, the producer-consumer gap silently widens with every commit. The existing `stale: true` annotation tells the consumer the mtime is old; it cannot tell the consumer whether the auto-build hook has been running, just failed, or is in flight. + +When `graphify.auto_update: true`, the hook writes a status file synchronously before detaching and rewrites it on completion. This reference instructs the planner to read that file and surface the state inline with the existing staleness note. + +## The status file + +`.planning/graphs/.last-build-status.json`: + +```json +{ + "ts": "2026-05-15T14:02:23Z", + "status": "running" | "ok" | "failed", + "exit_code": null | , + "duration_ms": null | , + "head_at_build": "", + "graphify_version": null | "" +} +``` + +The hook writes `status: "running"` synchronously **before** detach, so the next planner invocation can see the in-flight signal even if `graphify update .` has not finished. The detached `hooks/lib/gsd-graphify-rebuild.sh` rewrites the file to `ok` or `failed` on completion (with `exit_code` and `duration_ms`). + +## Read the file + +```bash +test -f .planning/graphs/.last-build-status.json && cat .planning/graphs/.last-build-status.json +``` + +If the file is absent, the operator either hasn't opted in to `graphify.auto_update` or hasn't yet performed a HEAD-advancing git op since enabling it. The annotation below is a no-op in that case. + +## Format the annotation + +Combine the status with the current `HEAD` sha when relevant. The first matching case wins: + +| Status | `head_at_build` vs current HEAD | Annotation | +|--------|----------------------------------|------------| +| `running` | (any) | "Graph auto-rebuild in flight (started `{ts}`); treat semantic relationships as approximate until rebuild completes." | +| `failed` | (any) | "Graph auto-rebuild FAILED at `{ts}` (exit `{exit_code}`); the planning context below is from the prior build. Run `/gsd:graphify build` to retry manually." | +| `ok` | matches | (silent — graph is current at the current HEAD) | +| `ok` | differs | "Graph last rebuilt at `{ts}` for commit `{head_at_build[:7]}`; current HEAD has advanced — treat semantic relationships as approximate." | +| (file missing) | n/a | (silent — fall back to the existing `stale: true` annotation only) | + +Get the current HEAD with `git rev-parse HEAD`. + +## Interaction with the existing staleness note + +If both the existing `stale: true` mtime check AND the auto-update annotation are non-silent, present them on the same line, ordered: auto-update state first, mtime staleness second. Example: + +> "Graph auto-rebuild FAILED at 2026-05-15T14:02:23Z (exit 1); the planning context below is from the prior build. Run `/gsd:graphify build` to retry manually. (Existing graph is 36h old — treat semantic relationships as approximate.)" + +## Opt-in reminder + +The auto-update mechanism is opt-in (`graphify.auto_update: false` by default per issue #3347). Users who haven't opted in will never produce this file, and every annotation above is a no-op. The existing `stale: true` annotation continues to be the only signal. diff --git a/hooks/gsd-check-update-worker.js b/hooks/gsd-check-update-worker.js index ff5a16f7e..c460878f7 100644 --- a/hooks/gsd-check-update-worker.js +++ b/hooks/gsd-check-update-worker.js @@ -50,6 +50,7 @@ const MANAGED_HOOKS = [ 'gsd-check-update-worker.js', 'gsd-check-update.js', 'gsd-context-monitor.js', + 'gsd-graphify-update.sh', 'gsd-phase-boundary.sh', 'gsd-prompt-guard.js', 'gsd-read-guard.js',