[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M755C7M8DPC83CWDK4ECPDF4":3,"skill-same:01M755C7M8DPC83CWDK4ECPDF4":59},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":30,"commitSha":31,"skillDirectory":32,"forksCount":33,"repositoryHtmlUrl":34,"repositoryHomepageUrl":6,"ownerHtmlUrl":35,"ownerBlogUrl":36,"ownerDescription":37,"updatedAt":38,"install":39,"resources":52},"01M755C7M8DPC83CWDK4ECPDF4","x-internal-write-report",null,"Renders _TEMPLATE-*.md templates by substituting {{KEY}} placeholders (simple and nested, dot-path) and resolving {{#each}} loops against a structured JSON data payload, then writes the result atomically to an output path. Supports an --append mode with per-section deduplication keyed by `## ID: \u003Cvalue>` markers. Centralises phase reports, epic execution reports and planning reports so orchestrators (x-implement-epic, x-orchestrate-epic, x-implement-story) stop duplicating `Read template + inline Edit\u002FWrite` logic. Second skill in the x-internal-* convention (after x-internal-update-status pilot): internal visibility, non-user-invocable, subdir scoping under internal\u002Fops\u002F.","review-bench\u002Federcnj_ia-dev-environment","review-bench","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F286778065?v=4","01M7517F9NTEPDZDAXJBR30FWT","ReviewBench","01M7517FAC9F4P7TGWCNJ8VYVW",0,"MIT","https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring-hexagonal\u002F.claude\u002Fskills\u002Fx-internal-write-report\u002FSKILL.md",[],[],"2026-11-12 13:55:43",false,"---\nname: x-internal-write-report\ndescription: \"Renders _TEMPLATE-*.md templates by substituting {{KEY}} placeholders (simple and nested, dot-path) and resolving {{#each}} loops against a structured JSON data payload, then writes the result atomically to an output path. Supports an --append mode with per-section deduplication keyed by `## ID: \u003Cvalue>` markers. Centralises phase reports, epic execution reports and planning reports so orchestrators (x-implement-epic, x-orchestrate-epic, x-implement-story) stop duplicating `Read template + inline Edit\u002FWrite` logic. Second skill in the x-internal-* convention (after x-internal-update-status pilot): internal visibility, non-user-invocable, subdir scoping under internal\u002Fops\u002F.\"\nvisibility: internal\nuser-invocable: false\nallowed-tools: Bash\nargument-hint: \"--template \u003Cname> --output \u003Cpath> --data \u003Cjson-or-@path> [--append]\"\ncategory: internal-ops\ncontext-budget: heavy\nrequires-capabilities: []\n---\n\n## Global Output Policy\n\n- **Language**: English ONLY.\n- **Tone**: Technical, Direct, and Concise.\n- **Efficiency**: Remove all conversational fillers and greetings to save tokens.\n\n> 🔒 **INTERNAL SKILL**\n> Esta skill é invocada apenas por outras skills (orquestradores).\n> NÃO é destinada a invocação direta pelo usuário.\n> Caller principal: x-implement-epic, x-orchestrate-epic, x-implement-story.\n> Segunda skill da convenção `x-internal-*` (após x-internal-update-status,\n> a story PILOTO 0049-0005): frontmatter `visibility: internal`, subdir\n> `internal\u002Fops\u002F`, marker 🔒 e filtragem do menu `\u002Fhelp` via generator.\n\n# Skill: x-internal-write-report\n\n## Purpose\n\nRender a template file under `.claude\u002Ftemplates\u002F` (or an explicit path) by:\n\n1. Reading the template body from disk.\n2. Parsing a structured JSON payload (inline or `@path\u002Fto\u002Fdata.json`).\n3. Substituting `{{KEY}}` placeholders, including nested dot-paths\n   (`{{stories.story-0049-0001.status}}`).\n4. Expanding `{{#each \u003Ccollection>}}…{{\u002Feach}}` blocks with block-local\n   placeholder resolution against each array element.\n5. Writing the rendered output to a target path — either overwriting,\n   or appending with per-ID deduplication when `--append=true`.\n\nThis replaces the ad-hoc `Read template + Write output` pattern currently\ninlined in `x-implement-epic`, `x-orchestrate-epic`, and `x-implement-story`\n(documented in EPIC-0049 S9, S10, S15 analyses), centralising report\nrendering so templates can evolve without editing N orchestrator skills.\n\n## Convention Anchors (x-internal-*)\n\n| Aspect | Value | Rationale |\n| :--- | :--- | :--- |\n| Path | `internal\u002Fops\u002Fx-internal-write-report\u002F` | `internal\u002F` prefix scopes visibility; `ops\u002F` aligns with sibling runtime-ops skills |\n| Frontmatter `visibility` | `internal` | Generator filters these from `\u002Fhelp` menu |\n| Frontmatter `user-invocable` | `false` | Declarative complement to `visibility: internal` |\n| Body marker | `> 🔒 **INTERNAL SKILL**` block as first non-frontmatter content | Visible to humans browsing the repo; no parsing required |\n| Allowed tools | `Bash` only | Minimal surface; renderer is a single shell pipeline built on `jq` |\n| Naming | `x-internal-{subject}-{action}` | Mirrors Rule 04 skill taxonomy; `report-write` = subject+action |\n\nAudit rule: Rule 22 (Lifecycle Integrity) validates every skill under\n`internal\u002F**` satisfies all 6 anchors above. Violations fail the\n`LifecycleIntegrityAuditTest`.\n\n## Triggers\n\nBare-slash form is intentionally omitted — this skill is never invoked\nby a human typing `\u002Fx-internal-write-report` in chat. All invocations\nfollow Rule 13 INLINE-SKILL pattern from a calling orchestrator:\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-EPIC-EXECUTION-PLAN.md \\\n             --output ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fexec-plan.md \\\n             --data @ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fexec-plan.data.json\")\n```\n\n## Parameters\n\n| Parameter | Required | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `--template \u003Cname>` | M | — | Template file name resolved under `.claude\u002Ftemplates\u002F\u003Cname>`. An absolute path is accepted verbatim |\n| `--output \u003Cpath>` | M | — | Target path for the rendered file. Created with parent directories |\n| `--data \u003Cjson-or-@path>` | M | — | Structured payload: inline JSON string, or `@path\u002Fto\u002Fdata.json` to read from disk |\n| `--append` | O | `false` | When `true`, merge the rendered output into an existing file using `## ID: \u003Cvalue>` section markers for deduplication (see Step 6) |\n\n## Response Contract\n\nWhen successful, the skill writes a single-line JSON object to stdout:\n\n| Field | Type | Always Present | Description |\n| :--- | :--- | :--- | :--- |\n| `outputPath` | `String` | yes | Absolute path of the written file |\n| `bytesWritten` | `Integer` | yes | Final size of the output file in bytes |\n| `placeholdersReplaced` | `Integer` | yes | Total count of `{{KEY}}` substitutions (loop expansions count each inner substitution once) |\n| `entriesAppended` | `Integer\\|Null` | only on `--append=true` | Number of new `## ID:` sections appended (existing sections updated in place do not increment this count) |\n\n## Exit Codes\n\n| Code | Name | Condition | Message Format |\n| :--- | :--- | :--- | :--- |\n| 0 | SUCCESS | Render and write completed | — |\n| 1 | TEMPLATE_NOT_FOUND | Template file cannot be read | `Template '\u003Cname>' not found in .claude\u002Ftemplates\u002F` |\n| 2 | INVALID_JSON | `--data` payload fails to parse | `Invalid JSON in --data` |\n| 3 | UNRESOLVED_PLACEHOLDER | Strict-mode placeholder has no value in data | `Placeholder '{{KEY}}' has no value (strict mode)` |\n| 4 | WRITE_FAILED | Atomic `mv` of tmp file failed | `Failed to write \u003Cpath>` |\n\n## Placeholder Grammar\n\n### Simple and nested\n\n- `{{key}}` — top-level scalar lookup against the data object.\n- `{{a.b.c}}` — dot-path into nested objects. Arrays are indexable via\n  `{{stories.0.id}}` but this form is discouraged outside tests; use\n  `{{#each}}` for list rendering.\n- Missing keys in strict mode (default) trigger `UNRESOLVED_PLACEHOLDER`\n  (exit 3). The error message includes the exact placeholder token.\n\n### `{{#each \u003Ccollection>}} … {{\u002Feach}}`\n\n- The collection selector is a dot-path resolving to an array of objects\n  (`stories`, `findings`, `tasks.pending`).\n- Inside the block, placeholders are resolved against the current array\n  element first; a miss falls back to the root data object. This lets\n  templates interleave per-item fields (`{{id}}`, `{{status}}`) with\n  outer context (`{{epicId}}`).\n- Blocks MUST balance: every `{{#each}}` needs exactly one matching\n  `{{\u002Feach}}` at the same nesting depth. Nested loops are allowed up to\n  depth 3 (templates-in-the-wild never exceed depth 2).\n- An empty collection renders the block body zero times — no error.\n\n## Workflow\n\n### Step 1 — Argument parsing and validation\n\nParse flags; reject unknown flags. Reject duplicate flags. Enforce:\n\n- `--template`, `--output`, `--data` all mandatory.\n- `--append` is boolean; absence defaults to `false`.\n\nWhen `--template` is a bare name (no `\u002F`), resolve against\n`\u003CCLAUDE_PROJECT_DIR>\u002F.claude\u002Ftemplates\u002F\u003Cname>`; an absolute or\nrelative path containing `\u002F` is used verbatim (subject to traversal\nguard against `..` above the project root per Rule 06).\n\n### Step 2 — Template read\n\n```bash\nif [[ ! -r \"${template_path}\" ]]; then\n  echo \"Template '${template_name}' not found in .claude\u002Ftemplates\u002F\" >&2\n  exit 1\nfi\ntemplate_body=$(cat \"${template_path}\")\n```\n\n### Step 3 — Data payload parse\n\n```bash\nif [[ \"${data_arg}\" == @* ]]; then\n  data_path=\"${data_arg#@}\"\n  [[ -r \"${data_path}\" ]] || { echo \"Invalid JSON in --data\" >&2; exit 2; }\n  data_json=$(cat \"${data_path}\")\nelse\n  data_json=\"${data_arg}\"\nfi\nif ! echo \"${data_json}\" | jq -e '.' >\u002Fdev\u002Fnull 2>&1; then\n  echo \"Invalid JSON in --data\" >&2\n  exit 2\nfi\n```\n\n### Step 4 — `{{#each}}` expansion (inside-out)\n\nExpand the deepest `{{#each}}` block first, substituting per-element\nplaceholders against the current array element (with fallback to root\ndata). Repeat until no `{{#each}}` tokens remain. A simple regex-based\nstate machine is sufficient because blocks are well-bracketed and\nnever straddle line continuations.\n\nImplementation contract:\n\n```bash\nwhile echo \"${body}\" | grep -q '{{#each '; do\n  body=$(expand_innermost_each \"${body}\" \"${data_json}\")\ndone\n```\n\nThe helper `expand_innermost_each`:\n\n1. Locates the innermost `{{#each \u003Cexpr>}} … {{\u002Feach}}` match.\n2. Resolves `\u003Cexpr>` via `jq` against `${data_json}`; if the result is\n   not an array, exit with a clear error (non-zero, message includes\n   the expression).\n3. For each element, substitutes block-local placeholders (`{{field}}`\n   or `{{field.nested}}`), falling back to the root data.\n4. Concatenates rendered elements in array order, replacing the whole\n   `{{#each}}…{{\u002Feach}}` span in the body.\n\n### Step 5 — Simple placeholder substitution (strict)\n\nAfter all `{{#each}}` blocks are resolved, walk remaining\n`{{\u003Cdot-path>}}` tokens and substitute each via `jq -r`. When the\nlookup yields `null` or the path is absent, exit 3 with\n`UNRESOLVED_PLACEHOLDER` and the exact token in the message. Count\nevery successful substitution into `placeholdersReplaced`.\n\n### Step 6 — Atomic write (overwrite or --append merge)\n\n**Overwrite mode (default):**\n\n```bash\nmkdir -p \"$(dirname \"${output_path}\")\"\ntmp=\"${output_path}.tmp.$$\"\nprintf '%s' \"${rendered}\" > \"${tmp}\"\nif ! mv \"${tmp}\" \"${output_path}\"; then\n  rm -f \"${tmp}\"\n  echo \"Failed to write ${output_path}\" >&2\n  exit 4\nfi\n```\n\n**Append mode (`--append=true`):** the rendered body is interpreted as\na sequence of one or more sections, each beginning with a line of the\nform `## ID: \u003Cvalue>` (leading `##` required; value is the trimmed\nremainder). For every such section in the rendered body:\n\n1. Scan the existing output file for an identical `## ID: \u003Cvalue>`\n   marker.\n2. If found, replace the existing section (up to the next `## ID:`\n   marker or EOF) with the new section body. Do not increment\n   `entriesAppended`.\n3. If not found, append the new section at the end. Increment\n   `entriesAppended`.\n4. When the existing output file does not exist, behave as overwrite\n   mode and count every rendered section as appended.\n\nBoth branches end with the same atomic `mv` tmp → final contract as\noverwrite mode. The append merge is performed in-memory (a single\nawk\u002Fjq pipeline), never line-by-line via interleaved writes.\n\n### Step 7 — Emit response\n\n```bash\nbytes=$(wc -c \u003C \"${output_path}\" | tr -d ' ')\nif [[ \"${append_mode}\" == true ]]; then\n  printf '{\"outputPath\":\"%s\",\"bytesWritten\":%s,\"placeholdersReplaced\":%s,\"entriesAppended\":%s}\\n' \\\n    \"${output_path}\" \"${bytes}\" \"${replaced}\" \"${appended}\"\nelse\n  printf '{\"outputPath\":\"%s\",\"bytesWritten\":%s,\"placeholdersReplaced\":%s,\"entriesAppended\":null}\\n' \\\n    \"${output_path}\" \"${bytes}\" \"${replaced}\"\nfi\n```\n\nExit 0.\n\n## Examples\n\n### Example 1 — Simple render without loops\n\nTemplate `.claude\u002Ftemplates\u002F_TEMPLATE-EPIC-HEADER.md`:\n\n```markdown\n# Epic {{epicId}} — {{title}}\n\nStatus: {{status}}\n```\n\nInvocation:\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-EPIC-HEADER.md \\\n             --output ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fheader.md \\\n             --data '{\\\"epicId\\\":\\\"XXXX\\\",\\\"title\\\":\\\"Skill hygiene\\\",\\\"status\\\":\\\"IN_PROGRESS\\\"}'\")\n```\n\nOutput file contains `Epic XXXX — Skill hygiene` and `Status: IN_PROGRESS`.\nStdout:\n\n```json\n{\"outputPath\":\"ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fheader.md\",\"bytesWritten\":52,\"placeholdersReplaced\":3,\"entriesAppended\":null}\n```\n\nExit: 0.\n\n### Example 2 — `{{#each}}` loop with per-item fields\n\nTemplate fragment:\n\n```markdown\n{{#each stories}}\n- {{id}} ({{status}})\n{{\u002Feach}}\n```\n\nData:\n\n```json\n{\"stories\":[{\"id\":\"story-0049-0001\",\"status\":\"DONE\"},\n            {\"id\":\"story-0049-0002\",\"status\":\"DONE\"},\n            {\"id\":\"story-0049-0006\",\"status\":\"IN_PROGRESS\"}]}\n```\n\nRendered body:\n\n```markdown\n- story-0049-0001 (DONE)\n- story-0049-0002 (DONE)\n- story-0049-0006 (IN_PROGRESS)\n```\n\n`placeholdersReplaced` = 6 (two per iteration).\n\n### Example 3 — `--append` with update in place (no duplication)\n\nExisting `ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fstatus.md`:\n\n```markdown\n## ID: story-XXXX-0001\nstatus: PENDING\n\n## ID: story-XXXX-0002\nstatus: PENDING\n```\n\nInvocation with data `{\"id\":\"story-XXXX-0001\",\"status\":\"DONE\"}` and a\ntemplate producing the two-line `## ID: ... \u002F status: ...` block:\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-STATUS-ENTRY.md \\\n             --output ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fstatus.md \\\n             --data '{\\\"id\\\":\\\"story-XXXX-0001\\\",\\\"status\\\":\\\"DONE\\\"}' \\\n             --append true\")\n```\n\nFinal file:\n\n```markdown\n## ID: story-XXXX-0001\nstatus: DONE\n\n## ID: story-XXXX-0002\nstatus: PENDING\n```\n\nStdout:\n\n```json\n{\"outputPath\":\"ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fstatus.md\",\"bytesWritten\":74,\"placeholdersReplaced\":2,\"entriesAppended\":0}\n```\n\nExit: 0. Note `entriesAppended=0` because the rendered ID already\nexisted and was updated in place.\n\n### Example 4 — `--append` with new entries\n\nSame output file as Example 3; data now introduces an unseen ID:\n\n```json\n{\"id\":\"story-0049-0006\",\"status\":\"IN_PROGRESS\"}\n```\n\nFinal file gains a third section at the end:\n\n```markdown\n## ID: story-0049-0001\nstatus: DONE\n\n## ID: story-0049-0002\nstatus: PENDING\n\n## ID: story-0049-0006\nstatus: IN_PROGRESS\n```\n\nStdout: `\"entriesAppended\":1`.\n\n### Example 5 — Error: template not found\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-NONEXISTENT.md \\\n             --output \u002Ftmp\u002Fout.md \\\n             --data '{}'\")\n```\n\nStderr:\n\n```\nTemplate '_TEMPLATE-NONEXISTENT.md' not found in .claude\u002Ftemplates\u002F\n```\n\nExit: 1.\n\n### Example 6 — Error: unresolved placeholder (strict mode)\n\nTemplate contains `{{undefined_key}}`; data is `{\"epicId\":\"0049\"}`.\n\nStderr:\n\n```\nPlaceholder '{{undefined_key}}' has no value (strict mode)\n```\n\nExit: 3.\n\n### Example 7 — Error: invalid JSON\n\n`--data '{epicId:0049}'` (unquoted keys).\n\nStderr:\n\n```\nInvalid JSON in --data\n```\n\nExit: 2.\n\n## Outputs\n\n| Artifact | Path | Description |\n| :--- | :--- | :--- |\n| Rendered report | `\u003C--output>` | Markdown file written via tmp+rename; overwrite or merged-append |\n| Response envelope | stdout | Single-line JSON (`outputPath` \u002F `bytesWritten` \u002F `placeholdersReplaced` \u002F `entriesAppended`) |\n| Temp file | `\u003C--output>.tmp.$$` | Removed on successful rename; removed on failure |\n\n## Error Handling\n\n| Scenario | Action |\n| :--- | :--- |\n| Missing required flag | Print `usage:` banner to stderr; exit 64 (sysexits EX_USAGE) |\n| `jq` absent on PATH | Exit 127 with `jq is required`; abort before any write |\n| `--data @path` points to unreadable file | Exit 2 (`INVALID_JSON`) with the path echoed |\n| `{{#each expr}}` resolves to non-array | Exit non-zero; message includes the expression and the resolved type |\n| Unbalanced `{{#each}}` \u002F `{{\u002Feach}}` | Exit non-zero; message identifies the dangling token |\n| Strict-mode miss on any placeholder | Exit 3 (`UNRESOLVED_PLACEHOLDER`) with the full token text |\n| `mv` fails mid-write | Delete tmp file; exit 4 (`WRITE_FAILED`); existing output file is left untouched |\n| Output parent directory not writable | Exit 4 after cleaning up the tmp file |\n| Path traversal attempt (`..` above project root) | Exit non-zero; message names the offending path (Rule 06) |\n\n## Performance Contract\n\n- Render \u003C 200 ms for templates \u003C 50 KB with ≤ 3 nested `{{#each}}`\n  levels (DoD-local target of story-0049-0006).\n- Memory usage bounded by template size + 2× data-payload size; the\n  renderer streams rendered body to tmp file and never holds the final\n  output file in memory.\n- Idempotent under repeated invocations with identical template, data,\n  and output path (same bytes, same sha256).\n\n## Testing\n\nStory-0049-0006 ships acceptance test scenarios that every future\n`x-internal-write-report` consumer MUST be able to rely on:\n\n1. **Simple render** — `{{epicId}}` substituted; `placeholdersReplaced=1`.\n2. **Nested placeholder** — `{{stories.story-0049-0001.status}}` resolves.\n3. **`{{#each}}` happy path** — array of three stories renders three lines.\n4. **`{{#each}}` empty collection** — zero iterations, no error.\n5. **`--append` update in place** — existing `## ID:` section replaced;\n   `entriesAppended=0`; file sha256 changes; no duplicate section.\n6. **`--append` new entry** — unseen ID appended at EOF;\n   `entriesAppended=1`.\n7. **TEMPLATE_NOT_FOUND** — absent template; exit 1; stderr matches.\n8. **INVALID_JSON** — malformed `--data`; exit 2.\n9. **UNRESOLVED_PLACEHOLDER** — strict miss; exit 3 with exact token.\n10. **WRITE_FAILED** — output directory read-only; exit 4; tmp cleaned up.\n\nGoldens under\n`src\u002Ftest\u002Fresources\u002Fgolden\u002Finternal\u002Fops\u002Fx-internal-write-report\u002F` lock\nthe SKILL.md rendering. Coverage requirement: ≥ 95% line \u002F ≥ 90%\nbranch across the invoking Bash codepaths.\n\n## Generator Filter Contract\n\nThe `ia-dev-env` generator MUST exclude skills with\n`visibility: internal` from:\n\n1. The `.claude\u002FREADME.md` skill-inventory table.\n2. The `\u002Fhelp` menu listing surfaced by Claude Code.\n3. User-facing autocomplete in the chat input.\n\nInternal skills are still copied into `.claude\u002Fskills\u002F` (flat layout)\nso `Skill(skill: \"x-internal-write-report\")` invocations from other\nskills resolve correctly. The invariant — set by the pilot story\n(0049-0005) — holds here: **user cannot see it; orchestrators can\ninvoke it.**\n\n## Telemetry\n\nInternal skills DO NOT emit `phase.start` \u002F `phase.end` markers —\ntelemetry is produced by the invoking orchestrator (the `phase` wrapping\nthe orchestrator's own step is the correct aggregation boundary).\nPassive hooks still capture `tool.call` for the underlying `Bash`\ninvocation.\n\nReference: Rule 13 (Skill Invocation Protocol), Rule 22 (Lifecycle\nIntegrity Audit), ADR-0010 (Interactive Gates Convention — exempts\ninternal skills from the 3-option menu contract).\n\n## Integration Notes\n\n| Skill | Relationship | Context |\n| :--- | :--- | :--- |\n| `x-implement-epic` | caller | Phase-completion reports, epic execution plan rendering |\n| `x-orchestrate-epic` | caller | Per-story planning report rendering |\n| `x-implement-story` | caller | Story-level remediation \u002F review dashboard rendering |\n| `x-internal-update-status` | peer | Sibling `x-internal-*` skill; both scoped under `internal\u002Fops\u002F`; no shared runtime state |\n| `x-reconcile-status` | consumer | Downstream reader of reports produced here; never mutates concurrently (Rule 22) |\n\nDownstream stories that depend on this skill: story-0049-0009\n(x-implement-epic consumes it), story-0049-0010 (x-orchestrate-epic\nconsumes it), story-0049-0015 (x-implement-story consumes it).\n","## Global Output Policy\n\n- **Language**: English ONLY.\n- **Tone**: Technical, Direct, and Concise.\n- **Efficiency**: Remove all conversational fillers and greetings to save tokens.\n\n> 🔒 **INTERNAL SKILL**\n> Esta skill é invocada apenas por outras skills (orquestradores).\n> NÃO é destinada a invocação direta pelo usuário.\n> Caller principal: x-implement-epic, x-orchestrate-epic, x-implement-story.\n> Segunda skill da convenção `x-internal-*` (após x-internal-update-status,\n> a story PILOTO 0049-0005): frontmatter `visibility: internal`, subdir\n> `internal\u002Fops\u002F`, marker 🔒 e filtragem do menu `\u002Fhelp` via generator.\n\n# Skill: x-internal-write-report\n\n## Purpose\n\nRender a template file under `.claude\u002Ftemplates\u002F` (or an explicit path) by:\n\n1. Reading the template body from disk.\n2. Parsing a structured JSON payload (inline or `@path\u002Fto\u002Fdata.json`).\n3. Substituting `{{KEY}}` placeholders, including nested dot-paths\n   (`{{stories.story-0049-0001.status}}`).\n4. Expanding `{{#each \u003Ccollection>}}…{{\u002Feach}}` blocks with block-local\n   placeholder resolution against each array element.\n5. Writing the rendered output to a target path — either overwriting,\n   or appending with per-ID deduplication when `--append=true`.\n\nThis replaces the ad-hoc `Read template + Write output` pattern currently\ninlined in `x-implement-epic`, `x-orchestrate-epic`, and `x-implement-story`\n(documented in EPIC-0049 S9, S10, S15 analyses), centralising report\nrendering so templates can evolve without editing N orchestrator skills.\n\n## Convention Anchors (x-internal-*)\n\n| Aspect | Value | Rationale |\n| :--- | :--- | :--- |\n| Path | `internal\u002Fops\u002Fx-internal-write-report\u002F` | `internal\u002F` prefix scopes visibility; `ops\u002F` aligns with sibling runtime-ops skills |\n| Frontmatter `visibility` | `internal` | Generator filters these from `\u002Fhelp` menu |\n| Frontmatter `user-invocable` | `false` | Declarative complement to `visibility: internal` |\n| Body marker | `> 🔒 **INTERNAL SKILL**` block as first non-frontmatter content | Visible to humans browsing the repo; no parsing required |\n| Allowed tools | `Bash` only | Minimal surface; renderer is a single shell pipeline built on `jq` |\n| Naming | `x-internal-{subject}-{action}` | Mirrors Rule 04 skill taxonomy; `report-write` = subject+action |\n\nAudit rule: Rule 22 (Lifecycle Integrity) validates every skill under\n`internal\u002F**` satisfies all 6 anchors above. Violations fail the\n`LifecycleIntegrityAuditTest`.\n\n## Triggers\n\nBare-slash form is intentionally omitted — this skill is never invoked\nby a human typing `\u002Fx-internal-write-report` in chat. All invocations\nfollow Rule 13 INLINE-SKILL pattern from a calling orchestrator:\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-EPIC-EXECUTION-PLAN.md \\\n             --output ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fexec-plan.md \\\n             --data @ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fexec-plan.data.json\")\n```\n\n## Parameters\n\n| Parameter | Required | Default | Description |\n| :--- | :--- | :--- | :--- |\n| `--template \u003Cname>` | M | — | Template file name resolved under `.claude\u002Ftemplates\u002F\u003Cname>`. An absolute path is accepted verbatim |\n| `--output \u003Cpath>` | M | — | Target path for the rendered file. Created with parent directories |\n| `--data \u003Cjson-or-@path>` | M | — | Structured payload: inline JSON string, or `@path\u002Fto\u002Fdata.json` to read from disk |\n| `--append` | O | `false` | When `true`, merge the rendered output into an existing file using `## ID: \u003Cvalue>` section markers for deduplication (see Step 6) |\n\n## Response Contract\n\nWhen successful, the skill writes a single-line JSON object to stdout:\n\n| Field | Type | Always Present | Description |\n| :--- | :--- | :--- | :--- |\n| `outputPath` | `String` | yes | Absolute path of the written file |\n| `bytesWritten` | `Integer` | yes | Final size of the output file in bytes |\n| `placeholdersReplaced` | `Integer` | yes | Total count of `{{KEY}}` substitutions (loop expansions count each inner substitution once) |\n| `entriesAppended` | `Integer\\|Null` | only on `--append=true` | Number of new `## ID:` sections appended (existing sections updated in place do not increment this count) |\n\n## Exit Codes\n\n| Code | Name | Condition | Message Format |\n| :--- | :--- | :--- | :--- |\n| 0 | SUCCESS | Render and write completed | — |\n| 1 | TEMPLATE_NOT_FOUND | Template file cannot be read | `Template '\u003Cname>' not found in .claude\u002Ftemplates\u002F` |\n| 2 | INVALID_JSON | `--data` payload fails to parse | `Invalid JSON in --data` |\n| 3 | UNRESOLVED_PLACEHOLDER | Strict-mode placeholder has no value in data | `Placeholder '{{KEY}}' has no value (strict mode)` |\n| 4 | WRITE_FAILED | Atomic `mv` of tmp file failed | `Failed to write \u003Cpath>` |\n\n## Placeholder Grammar\n\n### Simple and nested\n\n- `{{key}}` — top-level scalar lookup against the data object.\n- `{{a.b.c}}` — dot-path into nested objects. Arrays are indexable via\n  `{{stories.0.id}}` but this form is discouraged outside tests; use\n  `{{#each}}` for list rendering.\n- Missing keys in strict mode (default) trigger `UNRESOLVED_PLACEHOLDER`\n  (exit 3). The error message includes the exact placeholder token.\n\n### `{{#each \u003Ccollection>}} … {{\u002Feach}}`\n\n- The collection selector is a dot-path resolving to an array of objects\n  (`stories`, `findings`, `tasks.pending`).\n- Inside the block, placeholders are resolved against the current array\n  element first; a miss falls back to the root data object. This lets\n  templates interleave per-item fields (`{{id}}`, `{{status}}`) with\n  outer context (`{{epicId}}`).\n- Blocks MUST balance: every `{{#each}}` needs exactly one matching\n  `{{\u002Feach}}` at the same nesting depth. Nested loops are allowed up to\n  depth 3 (templates-in-the-wild never exceed depth 2).\n- An empty collection renders the block body zero times — no error.\n\n## Workflow\n\n### Step 1 — Argument parsing and validation\n\nParse flags; reject unknown flags. Reject duplicate flags. Enforce:\n\n- `--template`, `--output`, `--data` all mandatory.\n- `--append` is boolean; absence defaults to `false`.\n\nWhen `--template` is a bare name (no `\u002F`), resolve against\n`\u003CCLAUDE_PROJECT_DIR>\u002F.claude\u002Ftemplates\u002F\u003Cname>`; an absolute or\nrelative path containing `\u002F` is used verbatim (subject to traversal\nguard against `..` above the project root per Rule 06).\n\n### Step 2 — Template read\n\n```bash\nif [[ ! -r \"${template_path}\" ]]; then\n  echo \"Template '${template_name}' not found in .claude\u002Ftemplates\u002F\" >&2\n  exit 1\nfi\ntemplate_body=$(cat \"${template_path}\")\n```\n\n### Step 3 — Data payload parse\n\n```bash\nif [[ \"${data_arg}\" == @* ]]; then\n  data_path=\"${data_arg#@}\"\n  [[ -r \"${data_path}\" ]] || { echo \"Invalid JSON in --data\" >&2; exit 2; }\n  data_json=$(cat \"${data_path}\")\nelse\n  data_json=\"${data_arg}\"\nfi\nif ! echo \"${data_json}\" | jq -e '.' >\u002Fdev\u002Fnull 2>&1; then\n  echo \"Invalid JSON in --data\" >&2\n  exit 2\nfi\n```\n\n### Step 4 — `{{#each}}` expansion (inside-out)\n\nExpand the deepest `{{#each}}` block first, substituting per-element\nplaceholders against the current array element (with fallback to root\ndata). Repeat until no `{{#each}}` tokens remain. A simple regex-based\nstate machine is sufficient because blocks are well-bracketed and\nnever straddle line continuations.\n\nImplementation contract:\n\n```bash\nwhile echo \"${body}\" | grep -q '{{#each '; do\n  body=$(expand_innermost_each \"${body}\" \"${data_json}\")\ndone\n```\n\nThe helper `expand_innermost_each`:\n\n1. Locates the innermost `{{#each \u003Cexpr>}} … {{\u002Feach}}` match.\n2. Resolves `\u003Cexpr>` via `jq` against `${data_json}`; if the result is\n   not an array, exit with a clear error (non-zero, message includes\n   the expression).\n3. For each element, substitutes block-local placeholders (`{{field}}`\n   or `{{field.nested}}`), falling back to the root data.\n4. Concatenates rendered elements in array order, replacing the whole\n   `{{#each}}…{{\u002Feach}}` span in the body.\n\n### Step 5 — Simple placeholder substitution (strict)\n\nAfter all `{{#each}}` blocks are resolved, walk remaining\n`{{\u003Cdot-path>}}` tokens and substitute each via `jq -r`. When the\nlookup yields `null` or the path is absent, exit 3 with\n`UNRESOLVED_PLACEHOLDER` and the exact token in the message. Count\nevery successful substitution into `placeholdersReplaced`.\n\n### Step 6 — Atomic write (overwrite or --append merge)\n\n**Overwrite mode (default):**\n\n```bash\nmkdir -p \"$(dirname \"${output_path}\")\"\ntmp=\"${output_path}.tmp.$$\"\nprintf '%s' \"${rendered}\" > \"${tmp}\"\nif ! mv \"${tmp}\" \"${output_path}\"; then\n  rm -f \"${tmp}\"\n  echo \"Failed to write ${output_path}\" >&2\n  exit 4\nfi\n```\n\n**Append mode (`--append=true`):** the rendered body is interpreted as\na sequence of one or more sections, each beginning with a line of the\nform `## ID: \u003Cvalue>` (leading `##` required; value is the trimmed\nremainder). For every such section in the rendered body:\n\n1. Scan the existing output file for an identical `## ID: \u003Cvalue>`\n   marker.\n2. If found, replace the existing section (up to the next `## ID:`\n   marker or EOF) with the new section body. Do not increment\n   `entriesAppended`.\n3. If not found, append the new section at the end. Increment\n   `entriesAppended`.\n4. When the existing output file does not exist, behave as overwrite\n   mode and count every rendered section as appended.\n\nBoth branches end with the same atomic `mv` tmp → final contract as\noverwrite mode. The append merge is performed in-memory (a single\nawk\u002Fjq pipeline), never line-by-line via interleaved writes.\n\n### Step 7 — Emit response\n\n```bash\nbytes=$(wc -c \u003C \"${output_path}\" | tr -d ' ')\nif [[ \"${append_mode}\" == true ]]; then\n  printf '{\"outputPath\":\"%s\",\"bytesWritten\":%s,\"placeholdersReplaced\":%s,\"entriesAppended\":%s}\\n' \\\n    \"${output_path}\" \"${bytes}\" \"${replaced}\" \"${appended}\"\nelse\n  printf '{\"outputPath\":\"%s\",\"bytesWritten\":%s,\"placeholdersReplaced\":%s,\"entriesAppended\":null}\\n' \\\n    \"${output_path}\" \"${bytes}\" \"${replaced}\"\nfi\n```\n\nExit 0.\n\n## Examples\n\n### Example 1 — Simple render without loops\n\nTemplate `.claude\u002Ftemplates\u002F_TEMPLATE-EPIC-HEADER.md`:\n\n```markdown\n# Epic {{epicId}} — {{title}}\n\nStatus: {{status}}\n```\n\nInvocation:\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-EPIC-HEADER.md \\\n             --output ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fheader.md \\\n             --data '{\\\"epicId\\\":\\\"XXXX\\\",\\\"title\\\":\\\"Skill hygiene\\\",\\\"status\\\":\\\"IN_PROGRESS\\\"}'\")\n```\n\nOutput file contains `Epic XXXX — Skill hygiene` and `Status: IN_PROGRESS`.\nStdout:\n\n```json\n{\"outputPath\":\"ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fheader.md\",\"bytesWritten\":52,\"placeholdersReplaced\":3,\"entriesAppended\":null}\n```\n\nExit: 0.\n\n### Example 2 — `{{#each}}` loop with per-item fields\n\nTemplate fragment:\n\n```markdown\n{{#each stories}}\n- {{id}} ({{status}})\n{{\u002Feach}}\n```\n\nData:\n\n```json\n{\"stories\":[{\"id\":\"story-0049-0001\",\"status\":\"DONE\"},\n            {\"id\":\"story-0049-0002\",\"status\":\"DONE\"},\n            {\"id\":\"story-0049-0006\",\"status\":\"IN_PROGRESS\"}]}\n```\n\nRendered body:\n\n```markdown\n- story-0049-0001 (DONE)\n- story-0049-0002 (DONE)\n- story-0049-0006 (IN_PROGRESS)\n```\n\n`placeholdersReplaced` = 6 (two per iteration).\n\n### Example 3 — `--append` with update in place (no duplication)\n\nExisting `ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fstatus.md`:\n\n```markdown\n## ID: story-XXXX-0001\nstatus: PENDING\n\n## ID: story-XXXX-0002\nstatus: PENDING\n```\n\nInvocation with data `{\"id\":\"story-XXXX-0001\",\"status\":\"DONE\"}` and a\ntemplate producing the two-line `## ID: ... \u002F status: ...` block:\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-STATUS-ENTRY.md \\\n             --output ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fstatus.md \\\n             --data '{\\\"id\\\":\\\"story-XXXX-0001\\\",\\\"status\\\":\\\"DONE\\\"}' \\\n             --append true\")\n```\n\nFinal file:\n\n```markdown\n## ID: story-XXXX-0001\nstatus: DONE\n\n## ID: story-XXXX-0002\nstatus: PENDING\n```\n\nStdout:\n\n```json\n{\"outputPath\":\"ai\u002Fepics\u002Fepic-XXXX\u002Freports\u002Fstatus.md\",\"bytesWritten\":74,\"placeholdersReplaced\":2,\"entriesAppended\":0}\n```\n\nExit: 0. Note `entriesAppended=0` because the rendered ID already\nexisted and was updated in place.\n\n### Example 4 — `--append` with new entries\n\nSame output file as Example 3; data now introduces an unseen ID:\n\n```json\n{\"id\":\"story-0049-0006\",\"status\":\"IN_PROGRESS\"}\n```\n\nFinal file gains a third section at the end:\n\n```markdown\n## ID: story-0049-0001\nstatus: DONE\n\n## ID: story-0049-0002\nstatus: PENDING\n\n## ID: story-0049-0006\nstatus: IN_PROGRESS\n```\n\nStdout: `\"entriesAppended\":1`.\n\n### Example 5 — Error: template not found\n\n```markdown\nSkill(skill: \"x-internal-write-report\",\n      args: \"--template _TEMPLATE-NONEXISTENT.md \\\n             --output \u002Ftmp\u002Fout.md \\\n             --data '{}'\")\n```\n\nStderr:\n\n```\nTemplate '_TEMPLATE-NONEXISTENT.md' not found in .claude\u002Ftemplates\u002F\n```\n\nExit: 1.\n\n### Example 6 — Error: unresolved placeholder (strict mode)\n\nTemplate contains `{{undefined_key}}`; data is `{\"epicId\":\"0049\"}`.\n\nStderr:\n\n```\nPlaceholder '{{undefined_key}}' has no value (strict mode)\n```\n\nExit: 3.\n\n### Example 7 — Error: invalid JSON\n\n`--data '{epicId:0049}'` (unquoted keys).\n\nStderr:\n\n```\nInvalid JSON in --data\n```\n\nExit: 2.\n\n## Outputs\n\n| Artifact | Path | Description |\n| :--- | :--- | :--- |\n| Rendered report | `\u003C--output>` | Markdown file written via tmp+rename; overwrite or merged-append |\n| Response envelope | stdout | Single-line JSON (`outputPath` \u002F `bytesWritten` \u002F `placeholdersReplaced` \u002F `entriesAppended`) |\n| Temp file | `\u003C--output>.tmp.$$` | Removed on successful rename; removed on failure |\n\n## Error Handling\n\n| Scenario | Action |\n| :--- | :--- |\n| Missing required flag | Print `usage:` banner to stderr; exit 64 (sysexits EX_USAGE) |\n| `jq` absent on PATH | Exit 127 with `jq is required`; abort before any write |\n| `--data @path` points to unreadable file | Exit 2 (`INVALID_JSON`) with the path echoed |\n| `{{#each expr}}` resolves to non-array | Exit non-zero; message includes the expression and the resolved type |\n| Unbalanced `{{#each}}` \u002F `{{\u002Feach}}` | Exit non-zero; message identifies the dangling token |\n| Strict-mode miss on any placeholder | Exit 3 (`UNRESOLVED_PLACEHOLDER`) with the full token text |\n| `mv` fails mid-write | Delete tmp file; exit 4 (`WRITE_FAILED`); existing output file is left untouched |\n| Output parent directory not writable | Exit 4 after cleaning up the tmp file |\n| Path traversal attempt (`..` above project root) | Exit non-zero; message names the offending path (Rule 06) |\n\n## Performance Contract\n\n- Render \u003C 200 ms for templates \u003C 50 KB with ≤ 3 nested `{{#each}}`\n  levels (DoD-local target of story-0049-0006).\n- Memory usage bounded by template size + 2× data-payload size; the\n  renderer streams rendered body to tmp file and never holds the final\n  output file in memory.\n- Idempotent under repeated invocations with identical template, data,\n  and output path (same bytes, same sha256).\n\n## Testing\n\nStory-0049-0006 ships acceptance test scenarios that every future\n`x-internal-write-report` consumer MUST be able to rely on:\n\n1. **Simple render** — `{{epicId}}` substituted; `placeholdersReplaced=1`.\n2. **Nested placeholder** — `{{stories.story-0049-0001.status}}` resolves.\n3. **`{{#each}}` happy path** — array of three stories renders three lines.\n4. **`{{#each}}` empty collection** — zero iterations, no error.\n5. **`--append` update in place** — existing `## ID:` section replaced;\n   `entriesAppended=0`; file sha256 changes; no duplicate section.\n6. **`--append` new entry** — unseen ID appended at EOF;\n   `entriesAppended=1`.\n7. **TEMPLATE_NOT_FOUND** — absent template; exit 1; stderr matches.\n8. **INVALID_JSON** — malformed `--data`; exit 2.\n9. **UNRESOLVED_PLACEHOLDER** — strict miss; exit 3 with exact token.\n10. **WRITE_FAILED** — output directory read-only; exit 4; tmp cleaned up.\n\nGoldens under\n`src\u002Ftest\u002Fresources\u002Fgolden\u002Finternal\u002Fops\u002Fx-internal-write-report\u002F` lock\nthe SKILL.md rendering. Coverage requirement: ≥ 95% line \u002F ≥ 90%\nbranch across the invoking Bash codepaths.\n\n## Generator Filter Contract\n\nThe `ia-dev-env` generator MUST exclude skills with\n`visibility: internal` from:\n\n1. The `.claude\u002FREADME.md` skill-inventory table.\n2. The `\u002Fhelp` menu listing surfaced by Claude Code.\n3. User-facing autocomplete in the chat input.\n\nInternal skills are still copied into `.claude\u002Fskills\u002F` (flat layout)\nso `Skill(skill: \"x-internal-write-report\")` invocations from other\nskills resolve correctly. The invariant — set by the pilot story\n(0049-0005) — holds here: **user cannot see it; orchestrators can\ninvoke it.**\n\n## Telemetry\n\nInternal skills DO NOT emit `phase.start` \u002F `phase.end` markers —\ntelemetry is produced by the invoking orchestrator (the `phase` wrapping\nthe orchestrator's own step is the correct aggregation boundary).\nPassive hooks still capture `tool.call` for the underlying `Bash`\ninvocation.\n\nReference: Rule 13 (Skill Invocation Protocol), Rule 22 (Lifecycle\nIntegrity Audit), ADR-0010 (Interactive Gates Convention — exempts\ninternal skills from the 3-option menu contract).\n\n## Integration Notes\n\n| Skill | Relationship | Context |\n| :--- | :--- | :--- |\n| `x-implement-epic` | caller | Phase-completion reports, epic execution plan rendering |\n| `x-orchestrate-epic` | caller | Per-story planning report rendering |\n| `x-implement-story` | caller | Story-level remediation \u002F review dashboard rendering |\n| `x-internal-update-status` | peer | Sibling `x-internal-*` skill; both scoped under `internal\u002Fops\u002F`; no shared runtime state |\n| `x-reconcile-status` | consumer | Downstream reader of reports produced here; never mutates concurrently (Rule 22) |\n\nDownstream stories that depend on this skill: story-0049-0009\n(x-implement-epic consumes it), story-0049-0010 (x-orchestrate-epic\nconsumes it), story-0049-0015 (x-implement-story consumes it).\n",{"name":5,"category":24,"visibility":25,"description":7,"allowed-tools":26,"argument-hint":27,"context-budget":28,"user-invocable":20,"requires-capabilities":29},"internal-ops","internal","Bash","--template \u003Cname> --output \u003Cpath> --data \u003Cjson-or-@path> [--append]","heavy",[],"main","952a630c6f38d193a349d86fa18db1de8843e837","src\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring-hexagonal\u002F.claude\u002Fskills\u002Fx-internal-write-report",1,"https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment","https:\u002F\u002Fgithub.com\u002Freview-bench","https:\u002F\u002Freview-bench.ai","An open benchmark for AI code review.","2026-10-27 06:56:37",{"source":8,"skillName":5,"commands":40,"prompt":50,"zipAvailable":51},[41,44,47],{"tool":42,"command":43},"npx","npx skills add review-bench\u002Federcnj_ia-dev-environment --skill x-internal-write-report",{"tool":45,"command":46},"bunx","bunx skills add review-bench\u002Federcnj_ia-dev-environment --skill x-internal-write-report",{"tool":48,"command":49},"pnpm","pnpm dlx skills add review-bench\u002Federcnj_ia-dev-environment --skill x-internal-write-report","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring-hexagonal\u002F.claude\u002Fskills\u002Fx-internal-write-report\u002FSKILL.md",true,[53],{"path":54,"resourceType":55,"resourceTypeDesc":56,"sizeBytes":57,"sourceHtmlUrl":58},"references\u002Ffull-protocol.md","REFERENCE","参考文档",2101,"https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring-hexagonal\u002F.claude\u002Fskills\u002Fx-internal-write-report\u002Freferences\u002Ffull-protocol.md",[60,67,74,81,88,95],{"skillNo":61,"name":62,"nameZh":6,"description":63,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":64,"categories":65,"keywords":66,"publishedAt":19},"01M757M8J48TQ1Y3X25GSJBXAS","x-parallel-eval","Detects and classifies file-collision risks between work units (tasks, stories, or epic phases) before parallel execution. Reads ## File Footprint blocks produced by x-task-plan \u002F x-story-plan, applies the parallelism-heuristics knowledge pack (hard \u002F regen \u002F soft categories + hotspot overrides), and emits a collision matrix + serialization recommendation in Markdown (default) or JSON.","https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fx-parallel-eval\u002FSKILL.md",[],[],{"skillNo":68,"name":69,"nameZh":6,"description":70,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":71,"categories":72,"keywords":73,"publishedAt":19},"01M757M57XMR9546S69466HDWT","parallelism-heuristics","Canonical catalog of file-collision heuristics for parallel task, story, and epic execution. Defines the File Footprint block format, the three Conflict Categories (hard \u002F regen \u002F soft), a hotspot list of high-contention paths, and the degrade-with-warning policy. Consumed by x-task-plan, x-story-plan, x-epic-map, x-parallel-eval, and x-dev-*-implement.","https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fparallelism-heuristics\u002FSKILL.md",[],[],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":78,"categories":79,"keywords":80,"publishedAt":19},"01M757M11SZ8P1VCQABT08QVYA","x-watch-pr-ci","Polls a PR's CI checks and Copilot review status, blocking until checks complete or timeout. Returns one of 8 stable exit codes (SUCCESS=0, CI_PENDING_PROCEED=10, CI_FAILED=20, TIMEOUT=30, PR_ALREADY_MERGED=40, NO_CI_CONFIGURED=50, PR_CLOSED=60, PR_NOT_FOUND=70). Writes a versioned state-file for session resume.","https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring\u002Fplatform-claude-code\u002F.claude\u002Fskills\u002Fx-watch-pr-ci\u002FSKILL.md",[],[],{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":87,"publishedAt":19},"01M757KW53K8KFPGADFB4PH949","x-validate-docs","Documentation freshness gate: validates 6 dimensions (readme, api-specs, grpc-proto, adr, skill-docs, system-architecture) against code changes in a PR. Stack-aware — only validates targets declared\u002Fauto-detected from ProjectConfig.documentation.targets. Returns exit non-zero on staleness; produces structured report.","https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring\u002Fplatform-claude-code\u002F.claude\u002Fskills\u002Fx-validate-docs\u002FSKILL.md",[],[],{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":19},"01M757KQZHSA10MKC0CR571D60","x-update-system-architecture","Incrementally updates docs\u002Farchitecture\u002Fsystem.md after an epic completes. Appends new entries to the Decision Log (§11) using x-internal-write-report --append (dedup by ## ID: marker) and surgically inserts component\u002Fintegration changes into sections 1-10 via Edit. Idempotent: re-running with the same epic produces a byte-identical system.md.","https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring\u002Fplatform-claude-code\u002F.claude\u002Fskills\u002Fx-update-system-architecture\u002FSKILL.md",[],[],{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":19},"01M757KKBT5Q1SVF8DMJBVF46M","x-update-architecture","Incrementally updates the service architecture document with changes from architecture plans. Adds new components, integrations, flows, and ADR references without rewriting existing content. Use after implementation to keep architecture documentation current.","https:\u002F\u002Fgithub.com\u002Freview-bench\u002Federcnj_ia-dev-environment\u002Fblob\u002Fmain\u002Fsrc\u002Ftest\u002Fresources\u002Fgolden\u002Fjava-spring\u002Fplatform-claude-code\u002F.claude\u002Fskills\u002Fx-update-architecture\u002FSKILL.md",[],[]]