[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6E5RYWM0FJS0TRZW0PWX1KD":3,"skill-same:01M6E5RYWM0FJS0TRZW0PWX1KD":58},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":32,"linkOnly":33,"markdownContent":34,"markdownBody":35,"frontMatter":36,"refName":38,"commitSha":39,"skillDirectory":40,"forksCount":13,"repositoryHtmlUrl":41,"repositoryHomepageUrl":6,"ownerHtmlUrl":42,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":43,"install":44,"resources":57},"01M6E5RYWM0FJS0TRZW0PWX1KD","file-bug",null,"File a GitHub issue with built-in dup-search, drift-evidence-on-existing-issue, and multi-layer-gap discrimination. Consolidates 3 charter-promotion-target memories into a single command.","parametrization\u002F2real-team-framework","parametrization","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1111097?v=4","01M6E5MC117M94CEXKX3C96PPX","01M6E5MC7YWG5N3VV4792VFK85",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Ffile-bug\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31],"file","file bug","bug","github","search","command","dup","evidence","prompts","github issue","issue","drift","memories","gap","2026-11-10 10:12:30",false,"---\nname: file-bug\ndescription: File a GitHub issue with built-in dup-search, drift-evidence-on-existing-issue, and multi-layer-gap discrimination. Consolidates 3 charter-promotion-target memories into a single command.\nargs: optional — keyword(s) describing the bug; if omitted, the skill prompts for them\n---\n\nFiles a GitHub issue against the appropriate repo, but FIRST runs three discriminator passes that catch:\n\n1. **Duplicates** — same root cause, different framing\n2. **Drift evidence** — single-instance drift covered by an open rationalization workstream\n3. **Multi-layer gaps** — distinct layers (detection \u002F strategy \u002F docs) that share a root cause but are NOT duplicates\n\nThis skill consolidates three feedback memories that have hit the charter-promotion threshold but are skill-shaped, not charter-shaped:\n\n- `feedback_search_before_filing.md` — duplicate detection\n- `feedback_drift_evidence_to_existing_rationalization_issue.md` — single-instance-of-pattern detection\n- `feedback_multi_layer_gap_filing.md` — distinct-layer counter-rule\n\n> **Note:** all repo paths in bash blocks below are rooted at `$REPO_ROOT` to avoid cwd drift when the skill is invoked from a worktree or child-repo subdirectory.\n\n## When to use\n\n- The user reports a bug or surfaces a gap in conversation.\n- A code review surfaces a finding that needs tracking.\n- The orchestrator's `\u002Fwave-wrapup` audit identifies a rationalization opportunity.\n\nInvoke as `\u002Ffile-bug \u003Ckeywords>` (e.g., `\u002Ffile-bug CSP theme-flash`) OR with no args (the skill will prompt).\n\n## Instructions\n\n### 1. Gather inputs\n\nIdentify:\n\n- **Symptom keywords** — 2-4 words from the surface symptom (e.g., `theme flash`, `notify-deploy`, `OAuth \u002Ftoken`).\n- **Suspected root cause keywords** — 2-4 words describing the underlying mechanism (e.g., `CSP inline script`, `repository_dispatch event-type`, `URL override prod-gate`).\n- **Layer classification** (preliminary) — is this:\n  - **detection** (CI \u002F hook \u002F validator \u002F monitor)\n  - **strategy \u002F architectural** (ADR, IaC pattern, ownership)\n  - **docs \u002F runbook** (operator procedure, escalation path)\n  - **bug** (single concrete defect at one layer)\n- **Affected repo** — which repo's tracker should the issue land in?\n- **Layer-sibling candidates** — does this incident also surface gaps at OTHER layers? (Pre-flag for the multi-layer-gap pass below.)\n\n### 2. Pass A — search-before-filing (duplicate detection)\n\nSearch the relevant repo for existing issues that may cover the same root cause:\n\n```bash\ngh issue list --repo \"noorinalabs\u002F\u003Crepo>\" --state all --search \"\u003Csymptom keywords>\" --json number,title,state --limit 10\ngh issue list --repo \"noorinalabs\u002F\u003Crepo>\" --state all --search \"\u003Croot-cause keywords>\" --json number,title,state --limit 10\n```\n\nFor cross-repo bugs (deploy chain, CSP, auth, ontology), search BOTH the symptom-side repo AND the cause-side repo. Examples:\n\n- notify-deploy bugs may be filed in `noorinalabs-deploy` OR `noorinalabs-isnad-graph`.\n- CSP issues may be filed in `noorinalabs-isnad-graph` OR `noorinalabs-design-system`.\n- Hook drift may be filed in `noorinalabs-main` OR the affected child repo.\n\nRead the matches.\n\n> **Origin > local clone**: when evaluating file-content claims in a matched issue (e.g., \"file X still exists at path Y\", \"config Z has value W\"), fetch via `gh api repos\u002F\u003Cowner>\u002F\u003Crepo>\u002Fcontents\u002F\u003Cpath>?ref=\u003Chead_sha>` — NOT the local clone. Local main may lag origin, especially during waves where work lands on a wave branch first. Charter `pull-requests.md § Origin > Local Clone for \"Still-Has-X\" File-Content Claims` (promoted from `feedback_origin_over_local_for_still_has_claims.md`, Bereket→Lucas-87\u002FPR #181 2026-04-28).\n\nScore each as:\n\n| Score | Meaning | Action |\n|---|---|---|\n| **STRONG dup** | Same root cause, same proposed fix; titles share core keywords | Comment new diagnosis on existing issue, exit |\n| **WEAK dup** | Adjacent symptom, may share root cause but unclear | Comment on existing AND consider continuing — confirm with user |\n| **No match** | No existing issue covers this | Continue to Pass B |\n\nIf STRONG dup: comment your diagnosis (with `gh api` head_sha verification per `state-claims.md § Refresh State Before Claim`), then EXIT. Do not file a new issue.\n\n### 3. Pass B — drift-evidence-on-existing (single-instance pattern detection)\n\nEven if Pass A found no symptom dup, search for open **rationalization \u002F cleanup** issues whose execution would eliminate this entire class of bug:\n\n```bash\ngh issue list --repo \"noorinalabs\u002F\u003Crepo>\" --state open \\\n  --search \"rationalize OR consolidate OR standardize OR cleanup OR canonical\" \\\n  --json number,title,labels --limit 20\n```\n\nAlso search for issue titles matching `tech-debt:`, `rationalize:`, `consolidate:`, `cleanup:`, `standardize:`.\n\nIf your incident is a **single concrete instance** of a pattern that one of these issues would eliminate (typical examples: copy-resident drift, duplicated config, divergent paths after rename), the right action is to **comment evidence on the existing rationalization issue**, NOT file a new single-instance ticket.\n\nDecision rule:\n\n| Pattern | Open rationalization issue exists? | Action |\n|---|---|---|\n| Single-instance drift | Yes — would eliminate this class | Comment evidence on existing; do NOT file |\n| Single-instance drift | No | Continue to Pass C |\n| Multi-instance \u002F new class | (irrelevant) | Continue to Pass C |\n\nComment shape on the existing rationalization issue:\n\n```markdown\n## Concrete drift example surfaced 2026-MM-DD\n\n**Surface:** \u003Cfile path or component>\n**Drift observed:** \u003Cspecific divergence — sha refs, line numbers>\n**Source:** \u003Cwhere this surfaced — code review of PR #N, \u002Fwave-wrapup audit, etc.>\n\nThis strengthens the case for #\u003Cthis-issue> rationalization (concrete > abstract).\nNot filed as a separate issue per `feedback_drift_evidence_to_existing_rationalization_issue.md`.\n```\n\nSurface the observation in the originating review comment as well (so the author sees it inline). Both, not either.\n\n### 4. Pass C — multi-layer-gap discrimination\n\nIf the incident has surfaced gaps at MORE THAN ONE layer (detection AND strategy, or strategy AND docs, etc.), **file separately at each layer with cross-references** rather than collapsing into one comprehensive issue.\n\nDistinct-layer issues that share a root cause are NOT duplicates. The `search-before-filing` rule (Pass A) catches symptom-dup; this rule catches the inverse — false-collapse of distinct layers.\n\nWorked example (B2 cred rotation, 2026-04-28):\n\n| Layer | Issue | Concern |\n|---|---|---|\n| Detection | `noorinalabs-deploy#158` | CI validate-creds drift check (automation) |\n| Strategy | `noorinalabs-deploy#180` | ADR \u002F bucket IaC management, rotation cadence (architectural decision) |\n| Docs | `noorinalabs-deploy#182` | Operator runbook for rotation loop (documentation) |\n\nEach was filed separately, all three cross-referenced in their bodies. Bereket initially proposed dedup at retro; Lucas-Rev-177's three-layer separation overrode.\n\nFor each distinct-layer issue, draft a body that:\n\n- Names the layer in the title prefix (e.g., `detection:`, `strategy:`, `docs:`)\n- Cross-references all sibling issues in a `## Layer siblings` section\n- Notes the shared root cause but the layer-specific scope\n\n### 5. File the issue (single layer, or one of N)\n\nAfter Passes A + B + C, file the new issue (or batch of layer-issues):\n\n```bash\ngh issue create --repo \"noorinalabs\u002F\u003Crepo>\" \\\n  --title \"\u003Cdiscoverable title — symptom + root-cause guess>\" \\\n  --body-file \u002Ftmp\u002Fissue-body-\u003Cdescriptive-slug>.txt \\\n  --label \"\u003Cbug|tech-debt>\" \\\n  --label \"\u003Cassignee-label, if known>\" \\\n  --label \"\u003Cwave-label, if applicable>\"\n```\n\nTitle discipline (per `feedback_search_before_filing.md`): include both the symptom AND a guess at the root cause. The next person who hits this should find your issue via either keyword.\n\nIssue body skeleton:\n\n```markdown\n## Symptom\n\n\u003Cobservable behavior, with file\u002Fline references where possible>\n\n## Suspected root cause\n\n\u003Cmechanism — what's broken, why>\n\n## Reproduction (if applicable)\n\n\u003Cminimal repro steps>\n\n## Layer siblings (if multi-layer)\n\n- detection: #N\n- strategy: #M\n- docs: #K\n\n## Pre-filing dup-search performed\n\n- `gh issue list --search \"\u003Csymptom>\"` → no matches OR matches considered: #X (different scope), #Y (different scope)\n- `gh issue list --search \"\u003Croot-cause>\"` → no matches OR matches considered: #Z (resolved 2026-MM-DD)\n- Rationalization scan (Pass B) → no eliminating issue found OR found #W (this is multi-instance \u002F new class, not single-instance covered by #W)\n\n## Acceptance Criteria\n\n- [ ] \u003Cspecific, testable>\n- [ ] \u003Cspecific, testable>\n\n## Out of scope\n\n\u003Cwhat this issue does NOT cover, with cross-refs to where it does>\n```\n\nPer `feedback_tmp_msg_file_stale.md`: write the body to `\u002Ftmp\u002Fissue-body-\u003Cdescriptive-slug>.txt` (NOT `\u002Ftmp\u002Fmsg.txt` — the issue#-keyed slug avoids the stale-tmp-file race), then `gh issue create --body-file`. Read-back-verify within 30s of creation per `feedback_gh_pr_edit_silent_noop.md`:\n\n```bash\nNEW_ISSUE_NUM=\u003Cfrom gh issue create output>\ngh issue view \"$NEW_ISSUE_NUM\" --repo \"noorinalabs\u002F\u003Crepo>\" --json number,title,labels --jq '{n:.number, t:.title, l:[.labels[].name]}'\n```\n\n### 6. Post-file follow-up\n\nPer `CLAUDE.md § Bug Report Workflow`:\n\n1. **Label for current wave** — check `cross-repo-status.json` for `wave_\u003CN>_active=true`, apply that wave label.\n2. **Add to project board** — `gh project item-add 2 --owner noorinalabs --url \u003Cissue-url>`.\n3. **If multi-layer:** repeat steps 5-6 for each sibling issue, then update each issue's `## Layer siblings` section with the actual issue numbers (since they only become known after creation).\n\n### 7. Telemetry append (every invocation)\n\nAppend a single JSONL line per `\u002Ffile-bug` invocation to `.claude\u002F.file-bug-log.jsonl` (gitignored). Captures the Pass A\u002FB\u002FC outcome and the disposition (filed-new, commented-existing, etc.) so aggregate signal is queryable without re-deriving from issue-body prose.\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nLOG=\"$REPO_ROOT\u002F.claude\u002F.file-bug-log.jsonl\"\n\n# Build the record from your in-skill state. Pass values come from each Pass's\n# outcome (the prose summary in Step 8 already encodes them).\nTS=$(date -u +%Y-%m-%dT%H:%M:%SZ)\nREPO_FULL=\"noorinalabs\u002F\u003Crepo>\"\nPASS_A=\"\u003CSTRONG_DUP|WEAK_DUP|NO_MATCH>\"       # Step 2 outcome\nPASS_B=\"\u003CCOMMENTED_ON|NO_MATCH|SKIPPED>\"      # Step 3 outcome (SKIPPED if A intercepted)\nPASS_C=\"\u003CSINGLE_LAYER|MULTI_LAYER_N|SKIPPED>\" # Step 4 outcome (SKIPPED if A\u002FB intercepted)\nDISPOSITION=\"\u003CFILED_NEW|FILED_MULTIPLE|COMMENTED_EXISTING|NOT_FILED>\"\n# Issue numbers as a JSON array: the new issue(s) filed, OR the existing issue\n# you commented on, OR empty array if nothing was created\u002Ftouched.\nISSUE_NUMBERS_JSON='[362]'   # or '[]' or '[362,363,364]' for multi-layer\n\njq -c -n \\\n  --arg ts \"$TS\" \\\n  --arg repo \"$REPO_FULL\" \\\n  --arg a \"$PASS_A\" \\\n  --arg b \"$PASS_B\" \\\n  --arg c \"$PASS_C\" \\\n  --arg d \"$DISPOSITION\" \\\n  --argjson nums \"$ISSUE_NUMBERS_JSON\" \\\n  '{ts:$ts, repo:$repo, pass_a:$a, pass_b:$b, pass_c:$c, disposition:$d, issue_numbers:$nums}' \\\n  >> \"$LOG\"\n```\n\nThe record is append-only — no rewrites, no per-issue back-references. Each invocation produces exactly one line, regardless of whether 0 \u002F 1 \u002F N issues were created.\n\nRequired state values (closed enums — keep stable so retro queries don't drift):\n\n| Field | Values |\n|---|---|\n| `pass_a` | `STRONG_DUP`, `WEAK_DUP`, `NO_MATCH` |\n| `pass_b` | `COMMENTED_ON`, `NO_MATCH`, `SKIPPED` |\n| `pass_c` | `SINGLE_LAYER`, `MULTI_LAYER_2`, `MULTI_LAYER_3`, …, `SKIPPED` |\n| `disposition` | `FILED_NEW`, `FILED_MULTIPLE`, `COMMENTED_EXISTING`, `NOT_FILED` |\n\nIf you EXIT at Pass A on STRONG dup: `pass_a=STRONG_DUP`, `pass_b=SKIPPED`, `pass_c=SKIPPED`, `disposition=COMMENTED_EXISTING`, `issue_numbers=[\u003Cthe existing one>]`.\n\nIf you comment evidence on a rationalization issue at Pass B: `pass_a=NO_MATCH`, `pass_b=COMMENTED_ON`, `pass_c=SKIPPED`, `disposition=COMMENTED_EXISTING`.\n\nIf you file N siblings at Pass C: `disposition=FILED_MULTIPLE`, `pass_c=MULTI_LAYER_N`, `issue_numbers=[\u003Call N>]`.\n\n## Output to user\n\nPresent a structured summary:\n\n```\n**File-bug result**\n\n| Pass | Result |\n|---|---|\n| A — search-before-filing | \u003CSTRONG dup #N | WEAK dup #M | no match> |\n| B — drift-evidence-on-existing | \u003Ccommented on #K | no rationalization match> |\n| C — multi-layer | \u003Csingle layer | N siblings: #X #Y #Z> |\n\n**Action taken:** \u003Cfiled #N | commented on #K | filed N siblings: #X #Y #Z>\n**Follow-up:** \u003Cwave-labeled, project-board-added, all sibling cross-refs updated>\n```\n\nIf Pass A or B intercepted the file (no new issue created), state that clearly so the operator knows the bug is tracked even though no new issue exists.\n\n## What remains manual\n\n- **Score interpretation** — STRONG vs WEAK dup is judgment; the skill surfaces matches, the operator decides.\n- **Layer classification at incident time** — the skill prompts for it but does not infer it.\n- **Acceptance criteria authorship** — domain-specific, operator-authored.\n\nThe skill encodes the discipline; it does not replace the judgment.\n\n## Reporting\n\nAggregate signal lives in `.claude\u002F.file-bug-log.jsonl` (gitignored, append-only). Query directly with `jq -s` — no separate reporting skill is required.\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nLOG=\"$REPO_ROOT\u002F.claude\u002F.file-bug-log.jsonl\"\n\n# Total invocations this wave (or all-time if no time filter)\njq -s 'length' \"$LOG\"\n\n# Pass A intercept rate — would-have-duped saves\njq -s '[.[] | select(.pass_a == \"STRONG_DUP\")] | length' \"$LOG\"\n\n# Pass B intercept rate — drift-evidence-on-existing\njq -s '[.[] | select(.pass_b == \"COMMENTED_ON\")] | length' \"$LOG\"\n\n# Pass C multi-layer preservation — issues that would have been collapsed\n# by Pass-A-alone but were correctly split by Pass C\njq -s '[.[] | select(.pass_c | startswith(\"MULTI_LAYER_\"))] | length' \"$LOG\"\n\n# Per-repo dup-attempt rate\njq -s 'group_by(.repo) | map({\n  repo: .[0].repo,\n  total: length,\n  strong_dup: ([.[] | select(.pass_a == \"STRONG_DUP\")] | length),\n  multi_layer: ([.[] | select(.pass_c | startswith(\"MULTI_LAYER_\"))] | length)\n})' \"$LOG\"\n\n# This-wave only (filter by ISO date range)\nWAVE_START=\"2026-05-10T17:55:00Z\"\njq -s --arg s \"$WAVE_START\" '[.[] | select(.ts >= $s)] | {total: length,\n  strong_dup: ([.[] | select(.pass_a == \"STRONG_DUP\")] | length),\n  pass_b_commented: ([.[] | select(.pass_b == \"COMMENTED_ON\")] | length),\n  multi_layer: ([.[] | select(.pass_c | startswith(\"MULTI_LAYER_\"))] | length),\n  filed_new: ([.[] | select(.disposition == \"FILED_NEW\")] | length),\n  filed_multiple: ([.[] | select(.disposition == \"FILED_MULTIPLE\")] | length)\n}' \"$LOG\"\n```\n\n`\u002Fwave-retro` Step 7.7 (memory-to-automation audit) should cite the wave-scoped totals from the last recipe in its skill-effectiveness summary, starting with the first retro after this PR lands.\n","Files a GitHub issue against the appropriate repo, but FIRST runs three discriminator passes that catch:\n\n1. **Duplicates** — same root cause, different framing\n2. **Drift evidence** — single-instance drift covered by an open rationalization workstream\n3. **Multi-layer gaps** — distinct layers (detection \u002F strategy \u002F docs) that share a root cause but are NOT duplicates\n\nThis skill consolidates three feedback memories that have hit the charter-promotion threshold but are skill-shaped, not charter-shaped:\n\n- `feedback_search_before_filing.md` — duplicate detection\n- `feedback_drift_evidence_to_existing_rationalization_issue.md` — single-instance-of-pattern detection\n- `feedback_multi_layer_gap_filing.md` — distinct-layer counter-rule\n\n> **Note:** all repo paths in bash blocks below are rooted at `$REPO_ROOT` to avoid cwd drift when the skill is invoked from a worktree or child-repo subdirectory.\n\n## When to use\n\n- The user reports a bug or surfaces a gap in conversation.\n- A code review surfaces a finding that needs tracking.\n- The orchestrator's `\u002Fwave-wrapup` audit identifies a rationalization opportunity.\n\nInvoke as `\u002Ffile-bug \u003Ckeywords>` (e.g., `\u002Ffile-bug CSP theme-flash`) OR with no args (the skill will prompt).\n\n## Instructions\n\n### 1. Gather inputs\n\nIdentify:\n\n- **Symptom keywords** — 2-4 words from the surface symptom (e.g., `theme flash`, `notify-deploy`, `OAuth \u002Ftoken`).\n- **Suspected root cause keywords** — 2-4 words describing the underlying mechanism (e.g., `CSP inline script`, `repository_dispatch event-type`, `URL override prod-gate`).\n- **Layer classification** (preliminary) — is this:\n  - **detection** (CI \u002F hook \u002F validator \u002F monitor)\n  - **strategy \u002F architectural** (ADR, IaC pattern, ownership)\n  - **docs \u002F runbook** (operator procedure, escalation path)\n  - **bug** (single concrete defect at one layer)\n- **Affected repo** — which repo's tracker should the issue land in?\n- **Layer-sibling candidates** — does this incident also surface gaps at OTHER layers? (Pre-flag for the multi-layer-gap pass below.)\n\n### 2. Pass A — search-before-filing (duplicate detection)\n\nSearch the relevant repo for existing issues that may cover the same root cause:\n\n```bash\ngh issue list --repo \"noorinalabs\u002F\u003Crepo>\" --state all --search \"\u003Csymptom keywords>\" --json number,title,state --limit 10\ngh issue list --repo \"noorinalabs\u002F\u003Crepo>\" --state all --search \"\u003Croot-cause keywords>\" --json number,title,state --limit 10\n```\n\nFor cross-repo bugs (deploy chain, CSP, auth, ontology), search BOTH the symptom-side repo AND the cause-side repo. Examples:\n\n- notify-deploy bugs may be filed in `noorinalabs-deploy` OR `noorinalabs-isnad-graph`.\n- CSP issues may be filed in `noorinalabs-isnad-graph` OR `noorinalabs-design-system`.\n- Hook drift may be filed in `noorinalabs-main` OR the affected child repo.\n\nRead the matches.\n\n> **Origin > local clone**: when evaluating file-content claims in a matched issue (e.g., \"file X still exists at path Y\", \"config Z has value W\"), fetch via `gh api repos\u002F\u003Cowner>\u002F\u003Crepo>\u002Fcontents\u002F\u003Cpath>?ref=\u003Chead_sha>` — NOT the local clone. Local main may lag origin, especially during waves where work lands on a wave branch first. Charter `pull-requests.md § Origin > Local Clone for \"Still-Has-X\" File-Content Claims` (promoted from `feedback_origin_over_local_for_still_has_claims.md`, Bereket→Lucas-87\u002FPR #181 2026-04-28).\n\nScore each as:\n\n| Score | Meaning | Action |\n|---|---|---|\n| **STRONG dup** | Same root cause, same proposed fix; titles share core keywords | Comment new diagnosis on existing issue, exit |\n| **WEAK dup** | Adjacent symptom, may share root cause but unclear | Comment on existing AND consider continuing — confirm with user |\n| **No match** | No existing issue covers this | Continue to Pass B |\n\nIf STRONG dup: comment your diagnosis (with `gh api` head_sha verification per `state-claims.md § Refresh State Before Claim`), then EXIT. Do not file a new issue.\n\n### 3. Pass B — drift-evidence-on-existing (single-instance pattern detection)\n\nEven if Pass A found no symptom dup, search for open **rationalization \u002F cleanup** issues whose execution would eliminate this entire class of bug:\n\n```bash\ngh issue list --repo \"noorinalabs\u002F\u003Crepo>\" --state open \\\n  --search \"rationalize OR consolidate OR standardize OR cleanup OR canonical\" \\\n  --json number,title,labels --limit 20\n```\n\nAlso search for issue titles matching `tech-debt:`, `rationalize:`, `consolidate:`, `cleanup:`, `standardize:`.\n\nIf your incident is a **single concrete instance** of a pattern that one of these issues would eliminate (typical examples: copy-resident drift, duplicated config, divergent paths after rename), the right action is to **comment evidence on the existing rationalization issue**, NOT file a new single-instance ticket.\n\nDecision rule:\n\n| Pattern | Open rationalization issue exists? | Action |\n|---|---|---|\n| Single-instance drift | Yes — would eliminate this class | Comment evidence on existing; do NOT file |\n| Single-instance drift | No | Continue to Pass C |\n| Multi-instance \u002F new class | (irrelevant) | Continue to Pass C |\n\nComment shape on the existing rationalization issue:\n\n```markdown\n## Concrete drift example surfaced 2026-MM-DD\n\n**Surface:** \u003Cfile path or component>\n**Drift observed:** \u003Cspecific divergence — sha refs, line numbers>\n**Source:** \u003Cwhere this surfaced — code review of PR #N, \u002Fwave-wrapup audit, etc.>\n\nThis strengthens the case for #\u003Cthis-issue> rationalization (concrete > abstract).\nNot filed as a separate issue per `feedback_drift_evidence_to_existing_rationalization_issue.md`.\n```\n\nSurface the observation in the originating review comment as well (so the author sees it inline). Both, not either.\n\n### 4. Pass C — multi-layer-gap discrimination\n\nIf the incident has surfaced gaps at MORE THAN ONE layer (detection AND strategy, or strategy AND docs, etc.), **file separately at each layer with cross-references** rather than collapsing into one comprehensive issue.\n\nDistinct-layer issues that share a root cause are NOT duplicates. The `search-before-filing` rule (Pass A) catches symptom-dup; this rule catches the inverse — false-collapse of distinct layers.\n\nWorked example (B2 cred rotation, 2026-04-28):\n\n| Layer | Issue | Concern |\n|---|---|---|\n| Detection | `noorinalabs-deploy#158` | CI validate-creds drift check (automation) |\n| Strategy | `noorinalabs-deploy#180` | ADR \u002F bucket IaC management, rotation cadence (architectural decision) |\n| Docs | `noorinalabs-deploy#182` | Operator runbook for rotation loop (documentation) |\n\nEach was filed separately, all three cross-referenced in their bodies. Bereket initially proposed dedup at retro; Lucas-Rev-177's three-layer separation overrode.\n\nFor each distinct-layer issue, draft a body that:\n\n- Names the layer in the title prefix (e.g., `detection:`, `strategy:`, `docs:`)\n- Cross-references all sibling issues in a `## Layer siblings` section\n- Notes the shared root cause but the layer-specific scope\n\n### 5. File the issue (single layer, or one of N)\n\nAfter Passes A + B + C, file the new issue (or batch of layer-issues):\n\n```bash\ngh issue create --repo \"noorinalabs\u002F\u003Crepo>\" \\\n  --title \"\u003Cdiscoverable title — symptom + root-cause guess>\" \\\n  --body-file \u002Ftmp\u002Fissue-body-\u003Cdescriptive-slug>.txt \\\n  --label \"\u003Cbug|tech-debt>\" \\\n  --label \"\u003Cassignee-label, if known>\" \\\n  --label \"\u003Cwave-label, if applicable>\"\n```\n\nTitle discipline (per `feedback_search_before_filing.md`): include both the symptom AND a guess at the root cause. The next person who hits this should find your issue via either keyword.\n\nIssue body skeleton:\n\n```markdown\n## Symptom\n\n\u003Cobservable behavior, with file\u002Fline references where possible>\n\n## Suspected root cause\n\n\u003Cmechanism — what's broken, why>\n\n## Reproduction (if applicable)\n\n\u003Cminimal repro steps>\n\n## Layer siblings (if multi-layer)\n\n- detection: #N\n- strategy: #M\n- docs: #K\n\n## Pre-filing dup-search performed\n\n- `gh issue list --search \"\u003Csymptom>\"` → no matches OR matches considered: #X (different scope), #Y (different scope)\n- `gh issue list --search \"\u003Croot-cause>\"` → no matches OR matches considered: #Z (resolved 2026-MM-DD)\n- Rationalization scan (Pass B) → no eliminating issue found OR found #W (this is multi-instance \u002F new class, not single-instance covered by #W)\n\n## Acceptance Criteria\n\n- [ ] \u003Cspecific, testable>\n- [ ] \u003Cspecific, testable>\n\n## Out of scope\n\n\u003Cwhat this issue does NOT cover, with cross-refs to where it does>\n```\n\nPer `feedback_tmp_msg_file_stale.md`: write the body to `\u002Ftmp\u002Fissue-body-\u003Cdescriptive-slug>.txt` (NOT `\u002Ftmp\u002Fmsg.txt` — the issue#-keyed slug avoids the stale-tmp-file race), then `gh issue create --body-file`. Read-back-verify within 30s of creation per `feedback_gh_pr_edit_silent_noop.md`:\n\n```bash\nNEW_ISSUE_NUM=\u003Cfrom gh issue create output>\ngh issue view \"$NEW_ISSUE_NUM\" --repo \"noorinalabs\u002F\u003Crepo>\" --json number,title,labels --jq '{n:.number, t:.title, l:[.labels[].name]}'\n```\n\n### 6. Post-file follow-up\n\nPer `CLAUDE.md § Bug Report Workflow`:\n\n1. **Label for current wave** — check `cross-repo-status.json` for `wave_\u003CN>_active=true`, apply that wave label.\n2. **Add to project board** — `gh project item-add 2 --owner noorinalabs --url \u003Cissue-url>`.\n3. **If multi-layer:** repeat steps 5-6 for each sibling issue, then update each issue's `## Layer siblings` section with the actual issue numbers (since they only become known after creation).\n\n### 7. Telemetry append (every invocation)\n\nAppend a single JSONL line per `\u002Ffile-bug` invocation to `.claude\u002F.file-bug-log.jsonl` (gitignored). Captures the Pass A\u002FB\u002FC outcome and the disposition (filed-new, commented-existing, etc.) so aggregate signal is queryable without re-deriving from issue-body prose.\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nLOG=\"$REPO_ROOT\u002F.claude\u002F.file-bug-log.jsonl\"\n\n# Build the record from your in-skill state. Pass values come from each Pass's\n# outcome (the prose summary in Step 8 already encodes them).\nTS=$(date -u +%Y-%m-%dT%H:%M:%SZ)\nREPO_FULL=\"noorinalabs\u002F\u003Crepo>\"\nPASS_A=\"\u003CSTRONG_DUP|WEAK_DUP|NO_MATCH>\"       # Step 2 outcome\nPASS_B=\"\u003CCOMMENTED_ON|NO_MATCH|SKIPPED>\"      # Step 3 outcome (SKIPPED if A intercepted)\nPASS_C=\"\u003CSINGLE_LAYER|MULTI_LAYER_N|SKIPPED>\" # Step 4 outcome (SKIPPED if A\u002FB intercepted)\nDISPOSITION=\"\u003CFILED_NEW|FILED_MULTIPLE|COMMENTED_EXISTING|NOT_FILED>\"\n# Issue numbers as a JSON array: the new issue(s) filed, OR the existing issue\n# you commented on, OR empty array if nothing was created\u002Ftouched.\nISSUE_NUMBERS_JSON='[362]'   # or '[]' or '[362,363,364]' for multi-layer\n\njq -c -n \\\n  --arg ts \"$TS\" \\\n  --arg repo \"$REPO_FULL\" \\\n  --arg a \"$PASS_A\" \\\n  --arg b \"$PASS_B\" \\\n  --arg c \"$PASS_C\" \\\n  --arg d \"$DISPOSITION\" \\\n  --argjson nums \"$ISSUE_NUMBERS_JSON\" \\\n  '{ts:$ts, repo:$repo, pass_a:$a, pass_b:$b, pass_c:$c, disposition:$d, issue_numbers:$nums}' \\\n  >> \"$LOG\"\n```\n\nThe record is append-only — no rewrites, no per-issue back-references. Each invocation produces exactly one line, regardless of whether 0 \u002F 1 \u002F N issues were created.\n\nRequired state values (closed enums — keep stable so retro queries don't drift):\n\n| Field | Values |\n|---|---|\n| `pass_a` | `STRONG_DUP`, `WEAK_DUP`, `NO_MATCH` |\n| `pass_b` | `COMMENTED_ON`, `NO_MATCH`, `SKIPPED` |\n| `pass_c` | `SINGLE_LAYER`, `MULTI_LAYER_2`, `MULTI_LAYER_3`, …, `SKIPPED` |\n| `disposition` | `FILED_NEW`, `FILED_MULTIPLE`, `COMMENTED_EXISTING`, `NOT_FILED` |\n\nIf you EXIT at Pass A on STRONG dup: `pass_a=STRONG_DUP`, `pass_b=SKIPPED`, `pass_c=SKIPPED`, `disposition=COMMENTED_EXISTING`, `issue_numbers=[\u003Cthe existing one>]`.\n\nIf you comment evidence on a rationalization issue at Pass B: `pass_a=NO_MATCH`, `pass_b=COMMENTED_ON`, `pass_c=SKIPPED`, `disposition=COMMENTED_EXISTING`.\n\nIf you file N siblings at Pass C: `disposition=FILED_MULTIPLE`, `pass_c=MULTI_LAYER_N`, `issue_numbers=[\u003Call N>]`.\n\n## Output to user\n\nPresent a structured summary:\n\n```\n**File-bug result**\n\n| Pass | Result |\n|---|---|\n| A — search-before-filing | \u003CSTRONG dup #N | WEAK dup #M | no match> |\n| B — drift-evidence-on-existing | \u003Ccommented on #K | no rationalization match> |\n| C — multi-layer | \u003Csingle layer | N siblings: #X #Y #Z> |\n\n**Action taken:** \u003Cfiled #N | commented on #K | filed N siblings: #X #Y #Z>\n**Follow-up:** \u003Cwave-labeled, project-board-added, all sibling cross-refs updated>\n```\n\nIf Pass A or B intercepted the file (no new issue created), state that clearly so the operator knows the bug is tracked even though no new issue exists.\n\n## What remains manual\n\n- **Score interpretation** — STRONG vs WEAK dup is judgment; the skill surfaces matches, the operator decides.\n- **Layer classification at incident time** — the skill prompts for it but does not infer it.\n- **Acceptance criteria authorship** — domain-specific, operator-authored.\n\nThe skill encodes the discipline; it does not replace the judgment.\n\n## Reporting\n\nAggregate signal lives in `.claude\u002F.file-bug-log.jsonl` (gitignored, append-only). Query directly with `jq -s` — no separate reporting skill is required.\n\n```bash\nREPO_ROOT=\"$(git rev-parse --show-toplevel)\"\nLOG=\"$REPO_ROOT\u002F.claude\u002F.file-bug-log.jsonl\"\n\n# Total invocations this wave (or all-time if no time filter)\njq -s 'length' \"$LOG\"\n\n# Pass A intercept rate — would-have-duped saves\njq -s '[.[] | select(.pass_a == \"STRONG_DUP\")] | length' \"$LOG\"\n\n# Pass B intercept rate — drift-evidence-on-existing\njq -s '[.[] | select(.pass_b == \"COMMENTED_ON\")] | length' \"$LOG\"\n\n# Pass C multi-layer preservation — issues that would have been collapsed\n# by Pass-A-alone but were correctly split by Pass C\njq -s '[.[] | select(.pass_c | startswith(\"MULTI_LAYER_\"))] | length' \"$LOG\"\n\n# Per-repo dup-attempt rate\njq -s 'group_by(.repo) | map({\n  repo: .[0].repo,\n  total: length,\n  strong_dup: ([.[] | select(.pass_a == \"STRONG_DUP\")] | length),\n  multi_layer: ([.[] | select(.pass_c | startswith(\"MULTI_LAYER_\"))] | length)\n})' \"$LOG\"\n\n# This-wave only (filter by ISO date range)\nWAVE_START=\"2026-05-10T17:55:00Z\"\njq -s --arg s \"$WAVE_START\" '[.[] | select(.ts >= $s)] | {total: length,\n  strong_dup: ([.[] | select(.pass_a == \"STRONG_DUP\")] | length),\n  pass_b_commented: ([.[] | select(.pass_b == \"COMMENTED_ON\")] | length),\n  multi_layer: ([.[] | select(.pass_c | startswith(\"MULTI_LAYER_\"))] | length),\n  filed_new: ([.[] | select(.disposition == \"FILED_NEW\")] | length),\n  filed_multiple: ([.[] | select(.disposition == \"FILED_MULTIPLE\")] | length)\n}' \"$LOG\"\n```\n\n`\u002Fwave-retro` Step 7.7 (memory-to-automation audit) should cite the wave-scoped totals from the last recipe in its skill-effectiveness summary, starting with the first retro after this PR lands.\n",{"args":37,"name":5,"description":7},"optional — keyword(s) describing the bug; if omitted, the skill prompts for them","main","53ec1032b93d41533a48603e8fae7a92f56cc66c","intake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Ffile-bug","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework","https:\u002F\u002Fgithub.com\u002Fparametrization","2026-09-21 01:06:30",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add parametrization\u002F2real-team-framework --skill file-bug",{"tool":50,"command":51},"bunx","bunx skills add parametrization\u002F2real-team-framework --skill file-bug",{"tool":53,"command":54},"pnpm","pnpm dlx skills add parametrization\u002F2real-team-framework --skill file-bug","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Ffile-bug\u002FSKILL.md",true,[],[59,80,96,112,127,140],{"skillNo":60,"name":61,"nameZh":6,"description":62,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":65,"publishedAt":32},"01M6E5VG1R7FF1025BZAV6BDTS","wave-wrapup","Finalize a wave — PR review, merge sequencing, issue cleanup, worktree cleanup, and handoff to retro","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Fwave-wrapup\u002FSKILL.md",[],[66,67,68,69,70,71,72,73,74,75,76,28,77,78,79],"wave wrapup","wrapup","review","handoff","merge","pr review","pr","cleanup","worktree","retro","team","worktree cleanup","name","sequencing",{"skillNo":81,"name":82,"nameZh":6,"description":83,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":32},"01M6E5V9GDF75GV4YD2WPSH912","wave-start","Initialize a new wave — worktree cleanup, branch creation, label setup, status file update","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Fwave-start\u002FSKILL.md",[],[87,88,89,73,90,74,18,76,91,92,93,77,94,78,95],"wave start","start","setup","update","branch","file update","initialize","creation","status",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":32},"01M6E5V4VXEJ39V87VHN1A3AW9","wave-scope","Reconcile declared-vs-labeled wave scope between \u002Fwave-retro and \u002Fwave-kickoff — collect dispositions, fold in retro carry-forwards and memory must-includes, and refresh the meta-issue","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Fwave-scope\u002FSKILL.md",[],[103,104,105,106,107,75,108,109,110,28,111],"wave scope","scope","memory","collect","Meta","refresh","reconcile","Fold","kickoff",{"skillNo":113,"name":114,"nameZh":6,"description":115,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":118,"publishedAt":32},"01M6E5TZNPGG5EXZEN1FKJJT6K","wave-retro","Automated wave retrospective — PR analysis, assessments, trust matrix updates, feedback log, charter change proposals","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Fwave-retro\u002FSKILL.md",[],[119,75,120,121,72,122,123,76,124,125,126,78],"wave retro","log","change","retrospective","analysis","feedback","proposals","trust",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":32},"01M6E5TR8XB3Z10A9SD4ZYNV45","wave-kickoff","Automated wave planning — branch creation, label management, issue labeling, kickoff comments, and execution plan","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Fwave-kickoff\u002FSKILL.md",[],[134,111,135,28,94,78,136,76,137,91,138,139],"wave kickoff","management","plan","execution","planning","execution plan",{"skillNo":141,"name":142,"nameZh":6,"description":143,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":144,"categories":145,"keywords":146,"publishedAt":32},"01M6E5TMZAFB6MTVYT750FZDVY","wave-audit","Audit open issues against merged PRs — find and close orphaned issues with proper comments","https:\u002F\u002Fgithub.com\u002Fparametrization\u002F2real-team-framework\u002Fblob\u002Fmain\u002Fintake\u002Fnoorinalabs-2026-06\u002Fcandidates\u002Fskills\u002Fwave-audit\u002FSKILL.md",[],[147,148,149,150,151,152],"audit","wave audit","close","find","open","issues"]