| name | doc-feedback |
| user-invocable | true |
| description | Process review feedback on any Green Goods Google Doc downloaded as `.docx` — `docs/` drafts, research notes, grant proposals, product feedback. Parses comments and tracked-changes into a triage-able markdown record, then walks through addressing each item with a scope-lock gate between phases and an in-repo or out-of-repo address mode (auto-inferred from doc title/filename). Use when the team has finished reviewing a doc and you have (or can produce) a `.docx` export. |
| argument-hint | [<docx-path>] [--mode in-repo|out-of-repo] [--parse-only|--triage|--address] |
Doc Feedback Skill
External-review intake for any Green Goods Google Doc — docs/ drafts, research notes, grant proposals (NLnet, Octant, Mirror), product-feedback intake, ADR drafts, strategy memos.
The recurring pattern: a doc gets shared in Google Docs, the team leaves comments and tracked-change suggestions, and the writer needs to walk back through and address each item. The .docx export is the only feedback channel that survives offline — Google's connector tools don't expose comments.
The address phase splits into two modes because the destination of addressed work varies — sometimes edits land in repo files (docs/, .plans/), sometimes they're replies/edits to be pasted back into the original Google Doc or an external portal. The skill infers the mode from the doc and confirms with you before editing.
Activation
Use when:
- the team has finished commenting on a Google Doc and you have a
.docx export
- you say "address the doc comments", "process the docx feedback", "apply the team's review on X"
- a
.docx shows up under ~/Downloads/ after a review pass
Skip when:
- review feedback lives in a GitHub PR (use
/review instead)
- review is verbal or in chat (capture as ADR or session note instead)
- the doc has zero open comments and zero tracked changes (parse confirms — then stop)
Invocation
/doc-feedback # locate a .docx, parse, triage gate, address
/doc-feedback <path> # explicit input path
/doc-feedback --parse-only # phase 1 only — write feedback.md and stop
/doc-feedback --triage # resume at triage gate (already parsed)
/doc-feedback --address # resume at address phase (triage approved)
/doc-feedback --mode in-repo # force in-repo address mode (skip inference)
/doc-feedback --mode out-of-repo # force out-of-repo address mode (skip inference)
The path may be absolute, relative, or a ~/Downloads/... reference. If omitted, hunt the newest .docx in ~/Downloads/ whose name plausibly matches recent work and confirm before parsing.
Execution Model
- Phased with a scope-lock gate: parse → user-approved triage → address. Never edit files in phase 1 or 2.
- Working source-of-truth is the parsed
feedback.md under ignored tmp/doc-feedback/<slug>/, not the .docx. The .docx lives where it was downloaded (usually ~/Downloads/); do not copy it into the repo.
- One comment at a time in phase 3 — read the target file, edit, tick the checklist, move on. No batch sweeps.
- Do not auto-commit. Surface a suggested commit grouping at the end; let the user run
/ship.
Phases
Phase 1 — Parse
-
Resolve the .docx path. If ambiguous, list candidates and ask.
-
Pick <slug> = lowercase-hyphenated doc title (or .docx filename stem if title is generic). Preserve hyphens, drop punctuation.
-
Run the parser:
bun scripts/harness/parse-docx-feedback.ts <docx-path> \
--out tmp/doc-feedback/<slug>/feedback.md
-
Read feedback.md and surface a one-line summary: doc title (or filename), comment count, inserted-run count, deleted-run count.
If --parse-only, stop here and report the path.
Phase 2 — Triage gate
Two steps. Surface both before letting the user answer.
Step 1 — Infer address mode
Address mode determines where edits land in Phase 3:
- in-repo — edits go into repo files (
docs/, a current package guide, or an existing .plans/{ideas,backlog,active}/<feature>/ hub)
- out-of-repo — produce
tmp/doc-feedback/<slug>/responses.md with copy-pasteable replies/edits for the original Google Doc, Mirror, NLnet portal, etc. No tracked repo files are touched.
Inference rules, applied in order — first match wins:
- CLI
--mode in-repo or --mode out-of-repo → that mode, skip the rest
- Doc title or filename contains a
docs/ path component, or ADR, or matches an existing .plans/<feature>/ slug → in-repo
- Filename matches
*proposal*, *grant*, *nlnet*, *octant*, *mirror*, *feedback*, *research*, *memo* → out-of-repo
- Otherwise: ask once.
Surface the inferred mode (e.g. "Inferring out-of-repo mode from filename nlnet-evidence-commons.docx") and let the user override before continuing. Don't silent-default.
Step 2 — Triage list
Produce a numbered list, one row per open comment plus one block summarising tracked-change suggestions. For each comment:
N. [^cid] — comment id from feedback.md
- 1-line distillation of the comment body
- Anchor: the quoted text being commented on (truncated)
- Suspected target (in-repo mode only): best-guess file path under
docs/ or other repo location, or ? if not inferable. Skip this column in out-of-repo mode.
Then ask: "Which numbers to address, defer, or decline?" Wait for explicit selection. Do not edit anything until the user answers.
Write the user's selection into tmp/doc-feedback/<slug>/checklist.md as:
- [ ] [^cid] one-line title — `target/file.mdx` — accept|defer|decline # in-repo
- [ ] [^cid] one-line title — gdoc reply — accept|defer|decline # out-of-repo
Phase 3 — Address
Behavior branches on the address mode locked in Phase 2.
in-repo mode
For each accepted item, in order:
- Read the target file.
- Make the smallest edit that resolves the comment. If the comment is a question, answer it inline or in the linked context — don't add a comment to the file.
- For tracked-change suggestions in the body (
{++inserted++} / {--deleted--}), treat each segment as a proposal: apply if the user accepted that range during triage, otherwise leave alone.
- Tick the matching
checklist.md line.
- Move to the next item.
When all accepted items are addressed:
- Run touched-package verification:
bun lint && bun run test scoped to whichever packages were edited.
- Surface a suggested commit grouping (e.g. "all
docs/concepts/* edits → docs(concepts): apply review").
- Do not run
/ship yourself — let the user.
out-of-repo mode
The output is a single markdown file the user copies from. No repo files are edited.
Append one entry per accepted item to tmp/doc-feedback/<slug>/responses.md:
## [^cid] — to <author>
> <quoted anchor text from the original comment>
**Reply / proposed edit:**
<the response or edited paragraph, in plain markdown that pastes cleanly into a Google Doc reply or a Mirror/portal text field>
**Apply notes:** <where in the doc to paste it, or "reply to comment thread", or "replace anchor text with the edit above">
---
Then tick the matching checklist.md line and move on.
When all accepted items are addressed:
- Surface "ready to paste from
responses.md" with the file path.
- For grant portals (NLnet, Octant): note that comment replies usually go in the GDoc, but proposed-edit blocks may need to be pasted into the portal's revision field separately. Don't assume a single destination.
- Delete
tmp/doc-feedback/<slug>/ after the user confirms they have pasted the responses. If a durable decision belongs in the repo, record only the compact outcome in the edited document or an existing formal feature hub.
Output Contract
| Phase | Output |
|---|
| 1 | One-line summary + path to feedback.md |
| 2 | Inferred address mode (with reason) + numbered triage list, ending with the accept/defer/decline question. No edits. |
| 3 (in-repo) | Per-item: file edited + brief change summary + checklist tick. End with totals + touched-package verification + suggested commit grouping. |
| 3 (out-of-repo) | Per-item: appended block in responses.md + checklist tick. End with totals + path to responses.md + paste-destination notes. |
Conventions
- Workspace: ignored
tmp/doc-feedback/<slug>/ — contains feedback.md, checklist.md, and optionally responses.md. It is transient working state and must not create a new .plans/ root entry.
- Slug collisions: same slug on a re-review → suffix with
-yyyy-mm-dd (the date of the .docx, not today).
- Resolved comments: Google Docs drops resolved comments on
.docx export — what you parse is the open set, by definition. Don't waste cycles inferring resolved-status.
- Reply threads: Word's flat format means replies appear as separate
<w:comment> entries in arrival order, sharing no thread id. Treat each as standalone unless the body clearly references another.
- Multi-paragraph anchors: a
[^N: and its closing ] may span paragraphs. Read the whole quoted-anchor block in feedback.md for context.
- Don't commit the
.docx or parser output: keep the export where it landed and the parsed files under ignored tmp/. Durable outcomes belong in the edited document or an existing formal feature hub, not a parallel feedback archive.
Failure Modes
.docx not a real docx → unzip -p fails on word/document.xml. Confirm the file is the Word export, not PDF or .gdoc shortcut.
- No
word/comments.xml → no comments existed, only tracked changes. Parser handles this; surface "no comments, N tracked-change runs" and pivot to suggestion-only triage.
- Comment anchor text doesn't match
docs/ content → the doc has drifted from the repo. Flag as a research item; don't guess at a target file.
- Parser regex breaks on unusual XML → Word XML for headings/runs is stable but new constructs (e.g.
<w:sdt> content controls) may show up. If a paragraph renders empty in feedback.md, escalate the parser fix rather than working around it.
Anti-Patterns
| Don't | Why |
|---|
| Start addressing comments before parse output and triage are locked | The parsed feedback and user-approved checklist are the source of truth |
Commit the downloaded .docx into the repo | The export stays external; feedback.md is the durable repo record |
| Guess at repo targets when anchors do not match current files | Drift should be flagged instead of patched into the wrong surface |
| Batch unrelated comments into a broad rewrite | One-comment-at-a-time edits keep review and rollback possible |
Auto-commit or run /ship from this skill | The skill ends with verification and suggested grouping; the user controls shipping |
Related Skills
/review — for in-repo PR diffs (different surface)
/ship — pre-merge gate to run after addressing
plan — if the feedback expands into multi-package work, hand off to a feature plan