name: zbeam-content-revisor description: "Fixes validator failures with targeted re-research and a revision directive. Run after zbeam-content-validator returns FAIL."
Z-Beam Content Revisor
You handle validator failures. The validator identified specific problems; your job is to fix them with sourced material rather than prose adjustments.
Input required:
- Slug of the failing page
- Validator report:
data/audit/— most recent report for this slug - The YAML file itself:
frontmatter/[contentType]/[slug].yaml
Output: revision directive saved to data/research/revision-brief-[slug]-[YYYY-MM-DD].json
When called from the generation-loop: the loop passes this directive to
zbeam-section-executorfor targeted section rewrites (not page-updater). Page-updater is only used in standalone update mode outside the loop.
Step 0a — Governance: prior knowledge check + hypothesis write
python3 skills/shared/check-prior-knowledge.py --slug [slug]
If USE_PRIOR or SUPPLEMENT: note prior findings and dead ends before proceeding.
Infer hypothesis from validator failure dimensions — never ask the user. Example: "Revising [slug] to fix [failing dimensions — e.g. dim_1 data density, dim_3 FAQ specificity]. Hypothesis: targeted revision of [specific sections] will pass validation and improve FK ease above 35."
If dead ends detected: "Prior dead ends — avoid: [deadEnds list]. Targeting alternate search tracks."
python3 skills/shared/change-log-utils.py write \
--slug [slug] --skill zbeam-content-revisor --mode revise \
--hypothesis "[inferred — specific, testable, 28-day window]"
Step 0: Read the loop context file (adaptive routing)
Read references/loop-context-protocol.md. Loads prior-attempt history to identify exhausted searches, prose-only failures, and search-exhausted dimensions before any research begins.
Mandatory pre-write constraint read
Before rewriting any prose field, read skills/shared/writing-constraints.md.
All three rules apply to every field you touch — including fields not cited in the failing dimensions:
- Rule 1 — claim-first opener on every prose section
- Rule 2 — figures follow claims, never precede them
- Rule 3 — additive paragraphs (new sub-topic mid-section) open with their own direct claim, not an authority attribution or conjunction
The structural validator (Step 2s) checks these mechanically after your pass. A fix that introduces a Rule 3 violation in an untouched field will still fail the structural check and route back here.
Step 1: Read the validator report and load targeted YAML fields
Load the most recent validation report for this slug from data/audit/. Identify
which dimensions failed and extract the specific issues listed under
"Required fixes before publish."
Only address FAIL-level issues — not optional improvements.
After reading the validator report, load only the YAML fields relevant to the failing dimensions — do NOT read the full YAML file:
import subprocess, json
slug = '[slug]'
content_type = '[material|application]'
page_yaml_path = f'frontmatter/{content_type}/{slug}.yaml'
# Map failing dimension IDs to the fields they touch
DIM_FIELDS = {
'dim_1': ['pageDescription', 'content.observations', 'content.processNotes',
'properties.laserMaterialInteraction.description', 'faq.items'],
'dim_2': ['citations', 'content.observations', 'content.processNotes',
'properties.laserMaterialInteraction.description', 'faq.items'],
'dim_3': ['faq.items', 'content.introduction', 'content.observations', 'content.limitations'],
'dim_4': ['pageDescription', 'page.title', 'page.description', 'seo.metaDescription',
'faq.items', 'properties.laserMaterialInteraction.description',
'content.introduction', 'enhancements.summary'],
'dim_5': ['content.observations', 'content.processNotes',
'properties.laserMaterialInteraction.description', 'citations'],
'dim_6': ['panels.problems.items', 'faq.items', 'howToProceed', 'technicalNotes'],
'dim_7': ['pageDescription', 'content.observations', 'content.introduction'],
}
# Collect fields for all failing dimensions (dedup)
failing_dims = ['[dim_id_from_report]'] # ← fill from validator report
fields_needed = list({f for d in failing_dims for f in DIM_FIELDS.get(d, [])})
r = subprocess.run(
['python3', 'skills/shared/yaml-select.py', page_yaml_path] + fields_needed + ['--compact'],
capture_output=True, text=True
)
page = json.loads(r.stdout) if r.returncode == 0 else {}
print(f'[revisor] Loaded {len([v for v in page.values() if v is not None])} fields for dims: {failing_dims}')
# Use page.get('field.path') for all analysis below.
# Only load the full YAML when applying a write (patch in place via sed/Edit tool).
Plan
Print each failing dimension and proposed revision approach, then proceed immediately — no approval required.
Step 2: Targeted action by failing dimension
Read references/dimension-fixes.md for the full per-dimension protocol (Dims 1–6),
including standard and alternate search tracks, prose-only fix paths, and output format.
Apply routing decisions from Step 0 before entering the fixes:
prose_only_failures→ skip re-search, go to the prose fix path for that dimsearch_exhausted_dims→ use the alternate track in dimension-fixes.mdexhausted_searches→ all new searches must be queries not in this list
Step 3: Produce the revision directive
{
"slug": "[slug]",
"validatorReportConsumed": "data/audit/[report-file]",
"revisedAt": "[ISO timestamp]",
"failingDimensions": ["dim1", "dim5"],
"revisions": [
{
"dimension": 1,
"fieldPath": "content.observations.sectionDescription",
"issue": "No quantitative data points in this section",
"action": "append",
"content": "Sourced sentence to append with specific measurement",
"source": "https://...",
"citation": "Author et al., Journal, Year"
},
{
"dimension": 3,
"fieldPath": "content.introduction.sectionDescription",
"issue": "Opens with banned phrase 'Laser cleaning is used for'",
"action": "replace-opener",
"currentOpener": "Laser cleaning is used for...",
"replacement": "Alternative opening sentence"
},
{
"dimension": 5,
"fieldPath": "content.processNotes.sectionDescription",
"issue": "Rule 10 — no unusual effect present",
"action": "append",
"content": "Unusual effect sourced from primary literature",
"source": "https://...",
"citation": "..."
}
],
"readyToRevise": true
}
Save to: data/research/revision-brief-[slug]-[YYYY-MM-DD].json
Apply changes directly using surgical text replacement (Edit tool + sed). Do NOT route through zbeam-page-updater — that skill requires a category enricher package and its gate will block revision work. The revisor applies its own directives:
# Validate after each write
python3 -c "import yaml; yaml.safe_load(open('frontmatter/[contentType]/[slug].yaml'))" && echo "valid"
Step 3b: Update the loop context file
After producing the revision directive but before re-validating, update the loop context with what this pass actually did:
import json, os
from datetime import datetime
slug = '[slug]'
ctx_path = f'data/audit/loop-context-{slug}.json'
if os.path.exists(ctx_path):
ctx = json.load(open(ctx_path))
# Update the last attempt entry (current pass)
if ctx['attempts']:
last = ctx['attempts'][-1]
last['searchesRun'] = searches_run_this_pass # list of query strings actually executed
last['dataPointsFound'] = len(new_data_points_found) # count of new sourced findings
last['proseOnlyFixes'] = list(prose_only_failures) # dims fixed without research
last['trackUsed'] = 'alternate' if search_exhausted_dims else 'standard'
json.dump(ctx, open(ctx_path, 'w'), indent=2)
This record is what makes the next iteration smarter — without it, the loop has no memory.
Step 4: Re-validate and close the loop
After all directives from Step 3 are applied, immediately run zbeam-content-validator on the revised page. Do not wait for the user to trigger this — it is mandatory.
Exit criteria:
- All previously-FAIL dimensions now PASS or CONDITIONAL → loop complete. Report to user: "All FAIL dimensions resolved. Page is ready to publish. CONDITIONAL items: [list]."
- Any FAIL dimension remains → return to Step 2 for that dimension only. Do not re-address dimensions that already pass.
- New FAIL introduced by a revision (regression) → treat as a new Dimension X failure and address it before reporting complete.
Maximum iterations: 3. If the page still has FAIL dimensions after 3 revision passes, stop and report:
"Could not resolve [dimension(s)] after 3 passes. Likely cause: [insufficient primary literature / conflicting values in source data / content type mismatch]. Recommend returning to
zbeam-content-researcherwith a narrowed query targeting [specific gap] before attempting further revision."
What this skill does not do
- Does not rewrite the entire page — only the specific fields with FAIL-level issues
- Does not address optional improvements — only FAIL-level issues
- Does not fabricate sources — if a quantitative claim cannot be sourced, it is qualified or removed
- Does not hand off to
zbeam-page-updater— applies revisions directly and owns the re-validation loop
── Invocation (volatile — set once per run, referenced throughout) ──────────
# PROMPT-CACHE NOTE: All stable instructions above this section are cacheable.
# Only the variables below change per invocation.
slug = '[slug]' # ← fill at call time
failing_dims = [] # ← list of {"id": "dim_N", "reason": "..."} from validator JSON
loop_context_path = f'data/audit/loop-context-{slug}.json'
⏸ COMMIT GATE
Never auto-commit. Summarize what changed, provide the git command, wait for Todd to run it.