| name | update-guide |
| description | Modify an existing Pathfinder guide based on a change request. Plans the edit, applies it surgically, runs a review pass against critical rules, and validates with the Pathfinder CLI. Preserves all blocks outside the planned change. Use when the user wants to add, edit, or remove blocks in an existing guide, swap a data source, retrofit lazyRender, or otherwise modify a guide's content.json without rewriting it from scratch. |
Update Existing Guide
Modify an existing content.json based on a change request. The skill plans the edit, applies it, reviews it against the critical rules, and validates the result. Blocks outside the planned change are guaranteed unchanged (byte-level diff at the end).
This skill writes to content.json. It is not read-only — read safety-invariants.md before running.
Do NOT read external reference files upfront. Each phase's sub-agent loads its own references. Everything the orchestrator needs is inline below.
This skill implements the skill-memory convention. See ../skill-memory.md for the shared assets/, manifest, and frontmatter standards.
Workflow Overview
Input (guide directory + change request)
│
├─ Phase 0: Check for Prior Run ── orchestrator
│ Hash = guide content + change request
│
├─ Phase 1: Acquire & Snapshot ── orchestrator (no external reads)
│ Reads: content.json, manifest.json
│ Writes: assets/snapshots/content.json.before
│ assets/guide-structure.json (id → path map)
│
├─ Phase 2: Plan the Change ───── sub-agent loads authoring-guide.mdc
│ │ + best-practices.mdc
│ │ + ../shared/critical-rules.md
│ Writes: assets/change-plan.md
│
├─ Checkpoint: User confirms plan ── orchestrator
│
├─ Phase 3: Apply the Change ──── orchestrator + per-section sub-agents
│ │ (sub-agents load authoring-guide.mdc + best-practices.mdc)
│ Writes: updated content.json
│ assets/change-log.md (before/after per block path)
│
├─ Phase 4: Review & Fix ──────── sub-agent loads review-guide-pr.mdc
│ │ + ../shared/critical-rules.md
│ Writes: fixed content.json + assets/review-report.md
│
└─ Phase 5: Validate ──────────── orchestrator
Byte-level diff vs snapshot for unchanged paths
JSON validity, ID uniqueness, IDREF resolution
Pathfinder CLI: validate --package {guide_dir}
On failure: restore from snapshot, mark run failed
Inputs
- Required:
guide_dir — path to a directory containing content.json.
- Required:
change_request — free-text description of the change ("add a Loki section after the Prometheus one", "swap data source X for Y", "add lazyRender: true to the step at blocks[3].blocks[2]") OR a structured change spec (see change-request-schema.md).
- Optional:
target_path — explicit block path (e.g., blocks[3].blocks[2]) when the change_request is ambiguous about location. Phase 2 will use this if provided.
If the user gives only guide_dir, ask for the change_request. Free-text is acceptable.
Critical Rules
Read ../shared/critical-rules.md for the canonical 21 critical rules. Phase 2, Phase 3, and Phase 4 sub-agents must cite rule numbers when proposing or reviewing changes. The shared file forwards to ../../../AGENTS.md — that is the authoritative list.
Safety Invariants
Read safety-invariants.md — five inviolable rules the orchestrator and Phase 5 enforce. Violating any one fails the run and restores from snapshot.
Generated Files
The deliverable is the updated content.json. Everything in assets/ is skill-internal.
{guide_dir}/
content.json ← UPDATED (was modified by Phase 3)
manifest.json ← UPDATED only if change_request affects manifest fields
assets/
manifest.yaml ← skill memory (input hash, change request, last_update_at)
guide-structure.json ← id → path map (Phase 1)
change-plan.md ← user-approved plan (Phase 2)
change-log.md ← per-block before/after (Phase 3)
review-report.md ← review findings + fixes (Phase 4)
snapshots/
content.json.before ← pre-write snapshot (Phase 1)
Frontmatter disclaimer
Every generated markdown file in assets/ must start with:
---
disclaimer: Auto-generated by update-guide skill. Do not edit manually.
notice: To regenerate, re-run the skill with the same change request.
input_sha256: {hex digest}
guide_id: {id from content.json}
change_request: "{the change request, truncated to 100 chars}"
---
Manifest file
After Phase 5, write {guide_dir}/assets/manifest.yaml:
schema_version: 1
skill_name: "update-guide"
generated_at: "{ISO 8601 timestamp}"
input_sha256: "{hex digest — see below}"
guide:
id: "{guide id from content.json}"
change:
request: "{the full change request}"
paths_added: ["blocks[N]", ...]
paths_edited: ["blocks[M]", ...]
paths_removed: ["blocks[P]", ...]
validation:
cli_validate_passed: {true|false}
byte_level_diff_clean: {true|false}
files:
change_plan: "assets/change-plan.md"
change_log: "assets/change-log.md"
review_report: "assets/review-report.md"
snapshot: "assets/snapshots/content.json.before"
Compute input_sha256 by hashing the pair (content.json contents, change_request):
cat {guide_dir}/content.json <(printf "\n---\n%s" "{change_request}") | shasum -a 256 | awk '{print $1}'
This means re-running the same change against the same starting content.json matches the prior run and triggers warm-start. If either the content or the request differs, a fresh plan is generated.
Phase 0: Check for Prior Run (Orchestrator)
Before starting the update pipeline, check whether this update has already been applied.
- Check whether
{guide_dir}/assets/manifest.yaml exists.
- If it does: read the manifest, extract
input_sha256 and change.request.
- Re-hash the current pair:
cat content.json <(printf "\n---\n%s" "{change_request}") | shasum -a 256 | awk '{print $1}'.
- Compare hashes:
- Match → this exact change was already applied. Tell the user (cite
change.request and generated_at) and offer three options: (a) view the existing change-log.md, (b) re-run the change against the current content.json (treating it as a fresh request — drops the prior manifest), (c) abort.
- Mismatch → this is a different change request or the file has been edited since. Move the prior
manifest.yaml, change-plan.md, change-log.md, review-report.md to assets/history/{prior_generated_at}/. Proceed with the fresh run.
- If
manifest.yaml does not exist: fresh run — proceed to Phase 1.
Phase 1: Acquire & Snapshot (Orchestrator)
-
Verify {guide_dir}/content.json exists and is valid JSON. If not, report the parse error and stop.
-
Create {guide_dir}/assets/snapshots/ and copy content.json to assets/snapshots/content.json.before (raw bytes — no parsing, no re-serialisation).
-
Read manifest.json if present (Phase 2 may reference it for context).
-
Walk the block tree and produce assets/guide-structure.json — a map from every block id (and section id, input variable name) to its path. Shape:
{
"ids": {
"open-dashboards": "blocks[2].blocks[0]",
"configure-prometheus": "blocks[3]"
},
"section_ids": {
"navigation": "blocks[2]"
},
"input_variables": {
"datasourceName": "blocks[1]"
},
"tree_summary": {
"total_blocks": 42,
"total_sections": 5,
"total_interactive_steps": 18
}
}
-
Compute input_sha256 (see above) and stash it for Phase 5.
Phase 2: Plan the Change (Sub-agent)
Dispatch a sub-agent (Plan subagent type) with the following brief:
You are the **Plan the Change** phase of the update-guide skill. Read the following files in order, then produce a change plan.
**Read (in order):**
1. [.cursor/authoring-guide.mdc](../../../.cursor/authoring-guide.mdc) — block types, action types, requirements, best practices
2. [.cursor/best-practices.mdc](../../../.cursor/best-practices.mdc) — decision trees for blocks/actions/requirements/objectives; code smells
3. [../shared/critical-rules.md](../shared/critical-rules.md) — the 21 critical rules (cited by number)
4. [./change-request-schema.md](./change-request-schema.md) — structured change-request shapes (for context, even if the request is free-text)
5. {guide_dir}/assets/guide-structure.json — the id → path map
6. {guide_dir}/content.json — the original guide (for context)
**Resolve the change_request `{change_request}` to a concrete plan.**
For free-text requests, identify:
- **What** is changing (add a block / edit a block / remove a block / replace a section / add a requirement)
- **Where** it goes (use `target_path` if provided; otherwise infer from the request and from `guide-structure.json`)
- **Why** (so Phase 3 can write good prose for any new blocks)
For structured requests, validate against `change-request-schema.md` and surface any malformed fields.
**Output: a structured markdown plan at `{guide_dir}/assets/change-plan.md`** with the standard frontmatter disclaimer and these sections:
```markdown
# Change Plan
## Request
{verbatim change_request}
## Edits
For each edit:
- **Action**: add | edit | remove | replace
- **Path**: blocks[N].blocks[M] (existing path for edit/remove/replace; insertion target + position for add)
- **Block type**: markdown | interactive | section | ...
- **What it does**: one-sentence description
- **Why this location**: one-sentence rationale citing existing structure
## New Selectors To Verify
Any new `reftarget` selectors the user needs to confirm against the live Grafana UI before the change is applied. List one per line with the action context.
## New Requirements / Objectives
If the plan adds requirements or objectives, list them with their rationale. Cite the relevant requirement type from `docs/requirements-reference.md` (mentally — don't open it).
## IDREFs Affected
If any change touches:
- A section that other sections depend on via `section-completed:<id>`
- An `input` block whose variable is referenced by `var-<name>` or `{{<name>}}`
…list every referrer so Phase 3 knows what to revalidate.
## Risks
Anything the plan author is uncertain about. Examples:
- Selector stability ("this `data-testid` may have changed in recent Grafana")
- Section placement ("the new Loki section may be better after step 5 rather than at the end")
- Rule conflicts ("this addition may double the section's step count past 8")
```
**Do not modify content.json.** Stop after writing the plan. The orchestrator will present it to the user for confirmation.
After the sub-agent writes the plan, the orchestrator presents the plan to the user and asks for confirmation before proceeding to Phase 3. If the user requests revisions, re-dispatch Phase 2 with the same brief plus the user's feedback as additional context.
This is a hard checkpoint. Do not run Phase 3 until the user explicitly approves the plan.
Phase 3: Apply the Change (Orchestrator + Sub-agents)
After plan approval:
-
Re-read content.json (in case the user has tweaked since Phase 1 — if so, re-snapshot and warn).
-
For each edit in the plan:
- Add: insert the block at the specified path.
- If the block is a simple structural insertion (
markdown, noop), the orchestrator generates the JSON directly using the plan's "What it does" / "Why this location" prose.
- If the block is interactive content that requires authoring expertise (a full
section, a guided block with multiple steps, a quiz), dispatch a per-section sub-agent (Plan subagent type) with the brief below.
- Edit: apply the field-level changes from the plan.
- Remove: delete the block.
- Replace: do a paired remove + add at the same path.
-
After every edit, write content.json with the same indentation style as the original (detect from assets/snapshots/content.json.before — usually 2-space).
-
Write assets/change-log.md with per-block before/after blocks. Frontmatter as above. Shape:
## Edit 1 — add at `blocks[5]`
**Before**: (none — new block)
**After**:
```json
{ "type": "markdown", "content": "..." }
Edit 2 — edit blocks[3].blocks[2]
Before:
{ "type": "interactive", "action": "highlight", "reftarget": "..." }
After:
{ "type": "interactive", "action": "highlight", "reftarget": "...", "lazyRender": true }
-
If manifest.json is affected by the change request (title, description, targeting, tier, dependencies, milestones), update it. Otherwise leave it untouched.
Per-section sub-agent brief
You are generating one section block for an in-flight update to an existing Pathfinder guide. Read these files, then produce ONE section JSON object.
**Read (in order):**
1. [.cursor/authoring-guide.mdc](../../../.cursor/authoring-guide.mdc)
2. [.cursor/best-practices.mdc](../../../.cursor/best-practices.mdc)
3. [../shared/critical-rules.md](../shared/critical-rules.md)
4. {guide_dir}/assets/change-plan.md — the approved plan (find your section's entry under Edits)
5. {guide_dir}/assets/guide-structure.json — for ID uniqueness checks
**Section brief**: {paste the plan's "Action / Path / Block type / What it does / Why this location" for this section}
**Constraints:**
- Section id MUST be unique (check against `guide-structure.json` `ids` and `section_ids`)
- Follow all 21 critical rules
- Step budget: 3-8 interactive steps for a typical section
- Include section bookends (intro + summary markdown) unless the section has only 1-2 blocks
- Cite the rule numbers you considered in a comment block above the JSON if helpful (the orchestrator will strip the comment)
**Output**: ONE valid JSON object for the section block. No prose. No markdown fences. Just the JSON.
(This sub-agent pattern mirrors autogen-guide/SKILL.md Phase 3.)
Phase 4: Review & Fix (Sub-agent)
Dispatch a sub-agent (Plan subagent type) with the following brief:
You are the **Review & Fix** phase of the update-guide skill. Read these files, then review the changed blocks AND their immediate neighbours.
**Read (in order):**
1. [.cursor/review-guide-pr.mdc](../../../.cursor/review-guide-pr.mdc) — the review protocol
2. [../shared/critical-rules.md](../shared/critical-rules.md) — the 21 critical rules
3. {guide_dir}/assets/change-log.md — what was changed
4. {guide_dir}/content.json — the current state of the guide (post-edit)
**Scope**: every block path listed in `change-log.md` AND its siblings + parent section.
**Apply** every blocking check from review-guide-pr.mdc §1, every structural check from §2.4-2.5, and the §4.6 legacy `?doc=` check. Auto-fix findings in-place (write the updated `content.json`) unless the fix would change the user-facing intent of the change.
**Output**: `{guide_dir}/assets/review-report.md` with the standard frontmatter disclaimer and these sections:
```markdown
# Review Report
## Summary
- Findings: N (auto-fixed: N, requires user attention: N)
- Scope: {list of block paths reviewed}
## Auto-fixed
For each: path, rule number, what changed.
## Requires user attention
For each: path, rule number, why it can't be auto-fixed.
```
**Do not touch blocks outside the scope. Do not regenerate prose — only fix concrete rule violations.**
Phase 5: Validate (Orchestrator)
After Phase 4:
-
Byte-level diff vs snapshot. Parse both content.json and assets/snapshots/content.json.before. For every block path NOT in change-log.md, the block must be byte-identical between the two. If any unchanged path differs, this is a safety invariant violation — restore from snapshot, write assets/review-report.md with a ## CRITICAL: safety invariant violated section, and stop.
-
JSON validity. Parse content.json with strict JSON. On parse error, restore from snapshot and stop.
-
ID uniqueness. Walk the updated tree and confirm every block id is unique. On collision, restore and stop.
-
IDREF resolution. For every section-completed:<id> requirement and every var-<name> requirement, confirm the target still exists. For every {{<name>}} in markdown content, confirm an input block with that variable name exists earlier in the guide. On unresolved reference, restore and stop.
-
Pathfinder CLI validate. Run:
node {pathfinder-app}/dist/cli/cli/index.js validate --package {guide_dir}
If the CLI is not available, surface this as an incomplete-validation warning rather than a failure (skills cannot assume the user has the CLI built). If the CLI returns non-zero, restore from snapshot and stop.
-
If all checks pass: write/update {guide_dir}/assets/manifest.yaml with the schema documented above. Surface a one-paragraph summary to the user with: paths added/edited/removed, validation results, and the path to audit-report.md if the user wants a deeper review afterwards.
If any check fails, the orchestrator MUST:
- Restore
content.json from assets/snapshots/content.json.before (byte-level copy).
- Restore
manifest.json if it was modified.
- Write
assets/review-report.md with a ## CRITICAL: validation failed section explaining which check failed and which snapshot was restored.
- Mark the run as failed in
assets/manifest.yaml (validation.cli_validate_passed: false) and STOP.
When to use vs. skip
Use update-guide when:
- An existing guide needs a non-trivial change that touches multiple blocks or requirements.
- A change request must be reviewed and validated before merging (e.g., adding
lazyRender retrofits).
- You want a paper trail of what changed (
change-plan.md, change-log.md).
Skip update-guide and hand-edit when:
- The change is a 1-line content tweak (typo, prose clarification, tooltip rewording).
- The guide doesn't yet exist — use
autogen-guide instead.
- The change is a full rewrite — re-run
autogen-guide from the latest source.
See Also