[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71932254PTQ3E88FAMTTA40":3,"skill-same:01M71932254PTQ3E88FAMTTA40":145},{"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":28,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":87,"commitSha":88,"skillDirectory":89,"forksCount":90,"repositoryHtmlUrl":91,"repositoryHomepageUrl":6,"ownerHtmlUrl":92,"ownerBlogUrl":93,"ownerDescription":6,"updatedAt":94,"install":95,"resources":108},"01M71932254PTQ3E88FAMTTA40","slopgate-code-hygiene-refactor",null,"Recovery playbook for Slopgate and project quality failures. Load after hook\u002Flint denials such as PY-CODE-017 flat sibling modules, PY-CODE-018 oversized modules, QUALITY-LINT-001 post-edit quality backstops, PY-QUALITY-010 magic numbers \u002F repeated literals, PY-CODE-012\u002FPY-CODE-013 smell findings, type-suppression bans, duplicate helpers, or repeated hygiene retry loops. Also load when asked to \"refactor this module\", \"split this file\", \"extract a class\", \"reduce complexity\", \"fix god class\", \"flatten module hierarchy\", \"move code to a package\", \"extract helpers\", \"consolidate duplicates\", \"replace magic numbers with constants\", or when a hook blocks an edit with structural complaints. Focuses on preserving public APIs while refactoring toward packages, cohesive modules, typed seams, and focused tests.","vasceannie\u002Fslopgate","vasceannie","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20271133?v=4","01M718RGA8VV2EF22XJEMXVQ0Q","Travis Vasceannie","01M718RGB0GWSXBBZBN67Q6NHQ",1,"MIT","https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000007","代码审查","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"slopgate code hygiene refactor","code","refactor","hygiene","code hygiene","consolidate","coordination","reduce","when","utility","only","fix","structural","inventory","move","project","retry","duplicates","complexity","modules","2026-11-10 10:12:30",false,"---\nname: slopgate-code-hygiene-refactor\ndescription: |\n  Recovery playbook for Slopgate and project quality failures. Load after hook\u002Flint denials such as PY-CODE-017 flat sibling modules, PY-CODE-018 oversized modules, QUALITY-LINT-001 post-edit quality backstops, PY-QUALITY-010 magic numbers \u002F repeated literals, PY-CODE-012\u002FPY-CODE-013 smell findings, type-suppression bans, duplicate helpers, or repeated hygiene retry loops. Also load when asked to \"refactor this module\", \"split this file\", \"extract a class\", \"reduce complexity\", \"fix god class\", \"flatten module hierarchy\", \"move code to a package\", \"extract helpers\", \"consolidate duplicates\", \"replace magic numbers with constants\", or when a hook blocks an edit with structural complaints. Focuses on preserving public APIs while refactoring toward packages, cohesive modules, typed seams, and focused tests.\nversion: 1.0.0\nauthor: Slopgate\nlicense: MIT\ncompatibility: claude-code, opencode, codex, hermes, slopgate\nmetadata:\n  hermes:\n    tags: [slopgate,refactor,module-size,complexity,quality-gates]\n    related_skills: [slopgate-hygiene-orchestrator,slopgate-code-smell-utility-locator,slopgate-intelligent-coding-patterns]\n  slopgate:\n    rule_ids: [PY-CODE-017,PY-CODE-018,PY-CODE-014,PY-CODE-008,PY-CODE-009,PY-CODE-015,QUALITY-LINT-001]\n    activation:\n      primary: [oversized modules\u002Ffunctions,flat sibling packages,god classes,post-edit quality failures]\n      avoid: [repo-wide coordination,helper inventory before ownership is known,test-only expansion]\n---\n\n# Code Hygiene Refactor\n\nUse this skill when a hook, linter, review, or CI gate says the code shape is wrong and the next move should be a refactor rather than another local patch. The goal is to fix the design signal without weakening the guardrail that caught it.\n\n## When to Use\n\nUse for a local structural repair after a hook, lint, CI, or review says the code shape is wrong.\n\n- Rule IDs include `PY-CODE-017`, `PY-CODE-018`, `PY-CODE-014`, complexity\u002Fparameter\u002Ffunction-size findings, or touched-file `QUALITY-LINT-001`.\n- The likely fix is splitting modules, extracting cohesive helpers\u002Fclasses, preserving public imports, or repairing a post-edit quality backstop.\n- Use after `slopgate-code-smell-utility-locator` if the first question is whether an existing helper\u002Fconstant already owns the behavior.\n\n## When Not to Use\n\nDo not use as the first skill for broad repo-wide cleanup; use `slopgate-hygiene-orchestrator` to group and dispatch.\n\nDo not use for simple helper discovery, magic-number ownership, or duplicate utility inventory before code ownership is known; use `slopgate-code-smell-utility-locator`.\n\nDo not use for test-only coverage gaps unless production structure must change first.\n\n## Non-negotiables\n\n1. **Do not weaken gates**: do not edit quality tests, rule configs, baselines, allowlists, thresholds, suppressions, or hook settings just to pass.\n2. **No scoped fake-success lint**: public `slopgate lint check` is repo-root\u002Ffull-scope only. Run it from the repo root; do not pass a file\u002Fpath argument.\n3. **No type suppression escapes**: avoid `# type: ignore`, `# pyright: ignore`, `# ty: ignore`, broad `Any`, and casts unless the project explicitly documents the exception.\n4. **Repair before continuing**: if a PostToolUse\u002Fafter-edit backstop blocked, assume the bad mutation has landed. Fix it before unrelated edits.\n5. **Preserve public API**: package splits should keep import compatibility with `__init__.py` re-exports or explicit migration edits plus tests.\n6. **Smallest coherent diff**: split by responsibility, not by line-count shuffling.\n7. **No detector camouflage**: never split strings\u002Fnumbers (`\"pri\" + \"mary\"`), stitch constants (`PK_PRI + \"mary\"`), tuple-pack values, or add aliases just to dodge duplicate-literal\u002Fconstant rules.\n\n## Preemptive triggers — refactor *before* the hook denies\n\nThe cheapest refactor is the one done before any hook fires. Any of these conditions means split the module **now**, even if the current edit alone would not breach a threshold:\n\n- **Line count is at ~250 and your edit adds code.** Do not wait for ~600 \u002F `PY-CODE-018`. The split is cheaper before the function under edit grows further.\n- **Function approaching budget.** A function at ~40 lines, ~9 cyclomatic complexity, or 4 params with a 5th obviously coming next iteration → extract the seam now, before `PY-CODE-008` \u002F `PY-CODE-015` \u002F `PY-CODE-009` denies the next write.\n- **Class approaching method-count budget.** A class at 8 non-dunder methods and the current change adds the 9th or 10th → extract a collaborator before you hit 11 and `PY-CODE-014` denies the write. Group methods by the data they mutate or the collaborator they call; that grouping *is* the new class. Do not wait for the hook — by then you are refactoring under denial pressure with the new method already half-written.\n- **Class crossed ~250 lines or has multiple distinct responsibilities visible.** Class-line and method-count budgets converge fast. If you can name two distinct domain concerns the class owns (\"manages buffer state\" + \"writes archive to disk\"), do the split now even if methods are at 7 — the next two edits will push it over and the second responsibility extracts cleanly today, painfully tomorrow.\n- **God-class signal in tests.** If the class under edit needs 6+ fixtures, multiple `monkeypatch` setups per test, or test classes named after subsets of its methods (`TestUserAuth` + `TestUserProfile` + `TestUserBilling` for one `User` class), the production class is already a god-class waiting for `PY-CODE-014`. Extract collaborators now; the test split will follow naturally.\n- **Shared-prefix sibling cluster forming.** Two files share a `\u003Cprefix>_` stem (`result_models.py`, `result_runner.py`) and the new code wants a `result_reconciliation.py`. **Stop.** Promote `result\u002F` to a package before adding the third sibling. Three siblings is the antipattern, not the warning shot.\n- **Touched-file lint not yet flagged but trending.** If `slopgate lint check` from repo root reports a new collector hit on the touched file (length \u002F complexity \u002F duplication \u002F nesting), repair before unrelated edits, even if no PreToolUse hook denied the write.\n- **Comment \u002F docstring stripping urge.** If the only way a refactor \"fits\" is by removing module docstrings, removing inline `# Why this exists` comments, collapsing multi-line `try\u002Fexcept` into one-liners, or removing blank lines between logical groups, the refactor shape is wrong — split into a package and keep the explanatory text in the moved files.\n\nWhen you make a preemptive split, the rules of the rule-specific recovery map below still apply: package directory over flat siblings, `__init__.py` re-exports for the public API, no facade-rebuild of the oversized module.\n\n## First 90 seconds after a denial\n\n1. Read the rule ID, path, and metadata\u002Fhits in the hook response.\n2. Identify the current phase:\n   - **PreToolUse \u002F PermissionRequest**: proposed edit was blocked before landing; redesign the edit.\n   - **PostToolUse \u002F after-edit**: edit likely landed; inspect the touched file(s), repair, then verify.\n3. Write a tiny repair plan in your own scratch context:\n   - target files;\n   - refactor shape;\n   - public imports to preserve;\n   - focused tests\u002Fcompile command.\n4. Search for existing helpers\u002Fconstants\u002Fownership before creating new abstractions. If the hook\u002Flint response names an existing constant, import that exact symbol from the cited `path:line` instead of creating a duplicate.\n5. Patch the design, not the guardrail.\n\n## Rule-specific recovery map\n\n### `PY-CODE-017` — flat sibling module cluster\n\nSignal: files like `result_models.py`, `result_runner.py`, `result_reconciliation.py` are accumulating beside each other, or a new `prefix_*.py` appears beside an existing `prefix\u002F` package. **Two `\u003Cprefix>_` siblings is the trigger to plan the package; the third sibling is too late** — if you find yourself about to write a third, do the package split instead. Do not rationalize \"just one more flat file.\"\n\nPreferred repair:\n\n```text\n# Before\nsrc\u002Fagents\u002Fresult_models.py\nsrc\u002Fagents\u002Fresult_runner.py\nsrc\u002Fagents\u002Fresult_reconciliation.py\n\n# After\nsrc\u002Fagents\u002Fresult\u002F\n  __init__.py          # facade\u002Fre-exports stable API\n  models.py\n  runner.py\n  reconciliation.py\n```\n\nSteps:\n\n1. Create the package directory and an `__init__.py` facade.\n2. Move cohesive pieces into package siblings; avoid another flat `prefix_*.py` file.\n3. Preserve public imports with re-exports where safe:\n   ```python\n   from .models import ResultModel\n   from .runner import ResultRunner\n\n   __all__ = [\"ResultModel\", \"ResultRunner\"]\n   ```\n4. Update internal imports from `prefix_foo` to `prefix.foo` or package-relative imports.\n5. Delete or move the old flat siblings in the same coherent patch when possible.\n6. Verify compile\u002Fimports and focused tests before continuing.\n\nImportant nuance: mechanical filesystem moves may be the correct recovery step. Do not replace them with more flat files. After moves, make sure stale path mentions are not treated as still-existing modules.\n\n### `PY-CODE-018` and oversized-module collectors\n\nSignal: a proposed or existing Python module crosses the size threshold; `QUALITY-LINT-001` may surface the same condition after a write.\n\nPreferred repair:\n\n1. Identify natural seams: domain model, parser, renderer, adapter, CLI, tests, fixtures, constants, IO, validation, orchestration.\n2. Convert `module.py` to `module\u002F` package when callers import the module as an API surface.\n3. Keep `__init__.py` thin: re-export public names only; do not rebuild the oversized module in the facade.\n4. Move tests with the behavior or add focused tests around the seam being extracted.\n5. For `conftest.py`: keep area-level `conftest.py` thin and import fixture implementations from `tests\u002F\u003Carea>\u002F_fixtures\u002F` or `tests\u002F\u003Carea>\u002Fsupport\u002F` when the project allows that shape.\n6. For generated\u002Fstatic literals: move to resources, fixtures, builders, or data files when appropriate.\n\nAvoid these fake fixes:\n\n- splitting by arbitrary line ranges;\n- creating `utils.py` dumping grounds;\n- moving code without updating import ownership;\n- adding broad allowlists\u002Fbaselines;\n- making `__init__.py` as large as the old module.\n\n### `PY-CODE-014` — god class\n\nSignal: a class crossed >10 non-dunder methods, or `QUALITY-LINT-001` flagged class-body-size after a write.\n\nThreshold reminder: the hook denies at >10 non-dunder methods. **The preemptive trigger is 8 methods with growth obvious in this PR**, not 11 with the hook in your face. Class-line budget (~250 lines) converges on the same bound; whichever budget you approach first is the trigger.\n\nRecovery:\n\n1. Identify the seam by **data + collaborators**, not by alphabetizing methods. A clean seam is a set of methods that share state with each other and barely touch the rest of the class. If the methods you would move all read\u002Fwrite the same three attributes that no other method touches, those attributes plus those methods are the new collaborator.\n2. Name the collaborator after the responsibility (`RunArchiveStore`, `SnapshotPersister`), not after its parent (`EventBufferHelper`, `UserManager`). Inability to name the responsibility means the seam is wrong — re-plan.\n3. Use constructor injection. The new collaborator gets its dependencies through `__init__` parameters. The parent class instantiates it once.\n4. Move tests with the methods. If `TestUserAuth` covered the extracted methods, it follows them to a new test module — do not leave orphaned tests referencing methods that no longer exist on the parent.\n5. After extraction, audit the parent. If it now consists of `__init__` plus four one-line delegating methods, that is `PY-CODE-013` waiting to fire. Either inline the parent's remaining behavior into the call site, or rename the collaborator to take the parent's place.\n\nAnti-patterns to refuse:\n\n- **Random method shuffling to get under 10.** Splitting by alphabetical order is hiding the smell, not fixing it.\n- **`Helper` \u002F `Manager` \u002F `Service` suffix on the new class with no domain noun.** Re-plan the seam.\n- **One-line wrapper methods on the parent that call into the new collaborator.** Move the callers, do not add wrappers.\n- **Bidirectional dependency** (collaborator needs parent passed into `__init__`). The seam was wrong; the responsibility you extracted still depends on parent state.\n\nSee `references\u002Frefactoring_patterns.md` § \"God class extraction\" for the worked positive example (`cloud\u002Fservices\u002Fevent_buffer\u002F`).\n\n### `QUALITY-LINT-001` — post-edit lint backstop\n\nSignal: a mutation landed and the touched file now has a quality violation.\n\nRecovery:\n\n1. Inspect the hook details for collector names and touched paths\u002Fhits.\n2. Repair the landed change before any unrelated work.\n3. If the finding is oversized-module\u002Fgod-class\u002Flong-method\u002Fduplicate-helper, use the structural strategies in this skill.\n4. If the finding is type-safety, load `type-strictness` too.\n5. Run focused verification, then repo-root lint.\n\n### Repeated literal \u002F existing constant findings\n\nSignal: `PY-QUALITY-010`, `PY-DUP-004`, `repeated-string-literal`, or a `QUALITY-LINT-001` detail says a literal is repeated, magic, or already defined as a constant.\n\nResolution strategy:\n\n1. Use the cited existing constant location first. Good hook output should name the symbol and the owner, e.g. `PRIMARY_TIMEOUT_MS = 500 (src\u002Fconstants.py:12)` or `import existing constant PRIMARY_TIMEOUT_MS from src\u002Fconstants.py:12`.\n2. Read that owner file before editing. Confirm the constant is semantically the same value\u002Fpolicy, not just coincidentally equal.\n3. Import and reuse the existing symbol at call sites; preserve the owner module as the single source of truth.\n4. If no existing constant is cited, create one near the owning domain (`constants.py`, `_constants.py`, config\u002Fdefaults module, or a domain package constant), then replace all semantic duplicates intentionally.\n5. Verify with the focused test\u002Fcompile command and repo-root `slopgate lint check`.\n\nDirty fixes to reject:\n\n- splitting a literal into fragments such as `\"pri\" + \"mary\"`;\n- composing a duplicate from partial constants such as `PK_PRI + \"mary\"`;\n- aliasing an existing constant under a new name without adding domain meaning;\n- tuple\u002Flist packing or generated indirection whose only purpose is to change detector hashes;\n- moving the value to `utils.py` or a random config file unrelated to the owning policy.\n\n### `PY-QUALITY-010` — magic numbers \u002F repeated literals\n\nSignal: a literal value appears in code outside a constants\u002Fconfig module, or the same literal is repeated across call sites.\n\nRecovery:\n\n1. Check the hook\u002Flint output for the cited existing constant first. Good output names the symbol and owner, e.g. `PRIMARY_TIMEOUT_MS = 500 (src\u002Fconstants.py:12)`.\n2. Read that owner file before editing. Confirm the constant is semantically the same value\u002Fpolicy, not just coincidentally equal.\n3. Import and reuse the existing symbol at call sites; preserve the owner module as the single source of truth.\n4. If no existing constant is cited, create one near the owning domain (`constants.py`, `_constants.py`, config\u002Fdefaults module, or a domain package constant), then replace all semantic duplicates intentionally.\n5. For magic numbers in algorithmic\u002Fmath code, prefer named constants that explain the policy, not just the value: `MAX_RETRIES = 3` not `THREE = 3`.\n6. Verify with the focused test\u002Fcompile command and repo-root `slopgate lint check`.\n\nDirty fixes to reject:\n\n- splitting a literal into fragments such as `\"pri\" + \"mary\"`;\n- composing a duplicate from partial constants such as `PK_PRI + \"mary\"`;\n- aliasing an existing constant under a new name without adding domain meaning;\n- tuple\u002Flist packing or generated indirection whose only purpose is to change detector hashes;\n- moving the value to `utils.py` or a random config file unrelated to the owning policy.\n\n### `PY-AST-001` — parse\u002Fread failure\n\nRecovery:\n\n1. Re-read the file and restore parseability first.\n2. Run `python3 -m py_compile \u003Cfile>` or the project equivalent.\n3. Only resume refactoring after syntax is clean.\n\n### `PY-CODE-012`, `PY-CODE-013`, duplicate helpers, feature envy\n\nRecovery:\n\n- Thin wrapper: inline it or add meaningful validation, normalization, caching, error translation, or policy.\n- Feature envy: move behavior to the object being inspected or introduce a domain method.\n- Duplicate helper: search existing helpers\u002Fconstants first; consolidate into the existing owner or a cohesive new module.\n- Scattered utility: prefer a domain-owned module over `utils.py`.\n\n## Blast-radius measurement (GitNexus-first, deterministic fallbacks)\n\nBefore any module-to-package split — preemptive or denial-driven — measure who imports the module and which symbols escape so the split preserves the public API.\n\n**Preferred (when GitNexus is available and the index is fresh):**\n\n```text\ngitnexus_impact({target: \"\u003Csymbol_or_module>\", direction: \"upstream\"})\ngitnexus_context({name: \"\u003Csymbol>\"})\ngitnexus_detect_changes()   # before commit, after refactor\n```\n\nIf any GitNexus tool reports the index is stale, run `npx gitnexus analyze` first; do not proceed on stale graph data.\n\n**Fallback recipe when GitNexus is unavailable, stale, or not configured for this repo.** Each command is deterministic, fast, and avoids global filesystem scans. Replace `\u003CMODULE>` with the dotted import path (e.g. `cloud.services.event_buffer._buffer`) and `\u003CSYMBOL>` with the class\u002Ffunction name.\n\n```bash\n# 1. Direct importers — who would break if the module path changes\nrg -n --pcre2 \"^\\s*(from\\s+\u003CMODULE>\\s+import|import\\s+\u003CMODULE>)\" -t py\n\n# 2. Symbol callers \u002F mentions — approximate when GitNexus is absent\nrg -nw \"\u003CSYMBOL>\" -t py\n\n# 3. Public surface of the file under split — names callers can be reaching\nrg -n \"^(def|class|async def)\\s+\\w+\" path\u002Fto\u002Fmodule.py\nrg -n \"^__all__\\s*=\" path\u002Fto\u002Fmodule.py\n\n# 4. Module size + function-size signal\nwc -l path\u002Fto\u002Fmodule.py\nrg -n \"^(def|class|async def) \" path\u002Fto\u002Fmodule.py | wc -l\n\n# 5. Cyclomatic \u002F function-length spot check (radon if installed)\nradon cc -s -a path\u002Fto\u002Fmodule.py\nradon mi -s path\u002Fto\u002Fmodule.py\n\n# 6. Co-change history — files that change together belong together\ngit log --pretty=format: --name-only --diff-filter=AM -- path\u002Fto\u002Fmodule.py \\\n  | grep -v '^$' | sort | uniq -c | sort -rn | head -20\n\n# 7. Test files referencing the symbol (check coverage before moving)\nrg -l \"\u003CSYMBOL>\" tests\u002F\n\n# 8. Find similar-prefix siblings already accumulating in the same dir\nls path\u002Fto\u002Fdir\u002F | grep '^\u003Cprefix>_'\n```\n\nTreat the result of (1) and (7) as the authoritative caller list when no graph index is available. Anything imported only from inside the same package is safe to move freely; anything imported from elsewhere must keep its name reachable through the new `__init__.py` facade or get an explicit migration edit in the same PR.\n\nIf (6) consistently shows two files co-changing on every PR, that is the package boundary asking to exist — group them.\n\n## Verification commands\n\nPick the smallest commands that prove the repair. Common Python\u002FSlopgate sequence:\n\n```bash\n# Syntax for changed Python files\npython3 -m py_compile path\u002Fto\u002Fchanged.py\n\n# Focused tests for touched behavior\npython3 -m pytest tests\u002Fpath\u002Fto\u002Ffocused_test.py -q\n\n# Slopgate quality gate from repo root; no path args\ncd \u002Fpath\u002Fto\u002Frepo && HOME=\u002Fhome\u002Ftrav \u002Fhome\u002Ftrav\u002F.local\u002Fbin\u002Fslopgate lint check\n```\n\nWhen changing Slopgate itself:\n\n```bash\n# From the repository root\n.venv\u002Fbin\u002Fpython -m py_compile src\u002Fslopgate\u002Fengine.py src\u002Fslopgate\u002Frules\u002Fpython_ast\u002F_rules.py\n.venv\u002Fbin\u002Fpython -m pytest tests\u002Ftest_flat_file_sibling_packages.py tests\u002Ftest_size_guard_hook_behavior.py -q\nHOME=\u002Fhome\u002Ftrav .venv\u002Fbin\u002Fslopgate test\ngit diff --check\n```\n\n## When to escalate to `hygiene-orchestrator`\n\nLoad `hygiene-orchestrator` instead of doing a single local refactor when:\n\n- multiple files or packages need coordinated hygiene repairs;\n- many findings share an import graph or public API surface;\n- parallel agents are useful but require file ownership boundaries;\n- a repo-wide quality gate is failing after several local fixes.\n\n## Reference docs\n\n- `references\u002Fquality_rules.md` — current rule IDs and recovery strategies.\n- `references\u002Frefactoring_patterns.md` — package split and smell-specific examples.\n","# Code Hygiene Refactor\n\nUse this skill when a hook, linter, review, or CI gate says the code shape is wrong and the next move should be a refactor rather than another local patch. The goal is to fix the design signal without weakening the guardrail that caught it.\n\n## When to Use\n\nUse for a local structural repair after a hook, lint, CI, or review says the code shape is wrong.\n\n- Rule IDs include `PY-CODE-017`, `PY-CODE-018`, `PY-CODE-014`, complexity\u002Fparameter\u002Ffunction-size findings, or touched-file `QUALITY-LINT-001`.\n- The likely fix is splitting modules, extracting cohesive helpers\u002Fclasses, preserving public imports, or repairing a post-edit quality backstop.\n- Use after `slopgate-code-smell-utility-locator` if the first question is whether an existing helper\u002Fconstant already owns the behavior.\n\n## When Not to Use\n\nDo not use as the first skill for broad repo-wide cleanup; use `slopgate-hygiene-orchestrator` to group and dispatch.\n\nDo not use for simple helper discovery, magic-number ownership, or duplicate utility inventory before code ownership is known; use `slopgate-code-smell-utility-locator`.\n\nDo not use for test-only coverage gaps unless production structure must change first.\n\n## Non-negotiables\n\n1. **Do not weaken gates**: do not edit quality tests, rule configs, baselines, allowlists, thresholds, suppressions, or hook settings just to pass.\n2. **No scoped fake-success lint**: public `slopgate lint check` is repo-root\u002Ffull-scope only. Run it from the repo root; do not pass a file\u002Fpath argument.\n3. **No type suppression escapes**: avoid `# type: ignore`, `# pyright: ignore`, `# ty: ignore`, broad `Any`, and casts unless the project explicitly documents the exception.\n4. **Repair before continuing**: if a PostToolUse\u002Fafter-edit backstop blocked, assume the bad mutation has landed. Fix it before unrelated edits.\n5. **Preserve public API**: package splits should keep import compatibility with `__init__.py` re-exports or explicit migration edits plus tests.\n6. **Smallest coherent diff**: split by responsibility, not by line-count shuffling.\n7. **No detector camouflage**: never split strings\u002Fnumbers (`\"pri\" + \"mary\"`), stitch constants (`PK_PRI + \"mary\"`), tuple-pack values, or add aliases just to dodge duplicate-literal\u002Fconstant rules.\n\n## Preemptive triggers — refactor *before* the hook denies\n\nThe cheapest refactor is the one done before any hook fires. Any of these conditions means split the module **now**, even if the current edit alone would not breach a threshold:\n\n- **Line count is at ~250 and your edit adds code.** Do not wait for ~600 \u002F `PY-CODE-018`. The split is cheaper before the function under edit grows further.\n- **Function approaching budget.** A function at ~40 lines, ~9 cyclomatic complexity, or 4 params with a 5th obviously coming next iteration → extract the seam now, before `PY-CODE-008` \u002F `PY-CODE-015` \u002F `PY-CODE-009` denies the next write.\n- **Class approaching method-count budget.** A class at 8 non-dunder methods and the current change adds the 9th or 10th → extract a collaborator before you hit 11 and `PY-CODE-014` denies the write. Group methods by the data they mutate or the collaborator they call; that grouping *is* the new class. Do not wait for the hook — by then you are refactoring under denial pressure with the new method already half-written.\n- **Class crossed ~250 lines or has multiple distinct responsibilities visible.** Class-line and method-count budgets converge fast. If you can name two distinct domain concerns the class owns (\"manages buffer state\" + \"writes archive to disk\"), do the split now even if methods are at 7 — the next two edits will push it over and the second responsibility extracts cleanly today, painfully tomorrow.\n- **God-class signal in tests.** If the class under edit needs 6+ fixtures, multiple `monkeypatch` setups per test, or test classes named after subsets of its methods (`TestUserAuth` + `TestUserProfile` + `TestUserBilling` for one `User` class), the production class is already a god-class waiting for `PY-CODE-014`. Extract collaborators now; the test split will follow naturally.\n- **Shared-prefix sibling cluster forming.** Two files share a `\u003Cprefix>_` stem (`result_models.py`, `result_runner.py`) and the new code wants a `result_reconciliation.py`. **Stop.** Promote `result\u002F` to a package before adding the third sibling. Three siblings is the antipattern, not the warning shot.\n- **Touched-file lint not yet flagged but trending.** If `slopgate lint check` from repo root reports a new collector hit on the touched file (length \u002F complexity \u002F duplication \u002F nesting), repair before unrelated edits, even if no PreToolUse hook denied the write.\n- **Comment \u002F docstring stripping urge.** If the only way a refactor \"fits\" is by removing module docstrings, removing inline `# Why this exists` comments, collapsing multi-line `try\u002Fexcept` into one-liners, or removing blank lines between logical groups, the refactor shape is wrong — split into a package and keep the explanatory text in the moved files.\n\nWhen you make a preemptive split, the rules of the rule-specific recovery map below still apply: package directory over flat siblings, `__init__.py` re-exports for the public API, no facade-rebuild of the oversized module.\n\n## First 90 seconds after a denial\n\n1. Read the rule ID, path, and metadata\u002Fhits in the hook response.\n2. Identify the current phase:\n   - **PreToolUse \u002F PermissionRequest**: proposed edit was blocked before landing; redesign the edit.\n   - **PostToolUse \u002F after-edit**: edit likely landed; inspect the touched file(s), repair, then verify.\n3. Write a tiny repair plan in your own scratch context:\n   - target files;\n   - refactor shape;\n   - public imports to preserve;\n   - focused tests\u002Fcompile command.\n4. Search for existing helpers\u002Fconstants\u002Fownership before creating new abstractions. If the hook\u002Flint response names an existing constant, import that exact symbol from the cited `path:line` instead of creating a duplicate.\n5. Patch the design, not the guardrail.\n\n## Rule-specific recovery map\n\n### `PY-CODE-017` — flat sibling module cluster\n\nSignal: files like `result_models.py`, `result_runner.py`, `result_reconciliation.py` are accumulating beside each other, or a new `prefix_*.py` appears beside an existing `prefix\u002F` package. **Two `\u003Cprefix>_` siblings is the trigger to plan the package; the third sibling is too late** — if you find yourself about to write a third, do the package split instead. Do not rationalize \"just one more flat file.\"\n\nPreferred repair:\n\n```text\n# Before\nsrc\u002Fagents\u002Fresult_models.py\nsrc\u002Fagents\u002Fresult_runner.py\nsrc\u002Fagents\u002Fresult_reconciliation.py\n\n# After\nsrc\u002Fagents\u002Fresult\u002F\n  __init__.py          # facade\u002Fre-exports stable API\n  models.py\n  runner.py\n  reconciliation.py\n```\n\nSteps:\n\n1. Create the package directory and an `__init__.py` facade.\n2. Move cohesive pieces into package siblings; avoid another flat `prefix_*.py` file.\n3. Preserve public imports with re-exports where safe:\n   ```python\n   from .models import ResultModel\n   from .runner import ResultRunner\n\n   __all__ = [\"ResultModel\", \"ResultRunner\"]\n   ```\n4. Update internal imports from `prefix_foo` to `prefix.foo` or package-relative imports.\n5. Delete or move the old flat siblings in the same coherent patch when possible.\n6. Verify compile\u002Fimports and focused tests before continuing.\n\nImportant nuance: mechanical filesystem moves may be the correct recovery step. Do not replace them with more flat files. After moves, make sure stale path mentions are not treated as still-existing modules.\n\n### `PY-CODE-018` and oversized-module collectors\n\nSignal: a proposed or existing Python module crosses the size threshold; `QUALITY-LINT-001` may surface the same condition after a write.\n\nPreferred repair:\n\n1. Identify natural seams: domain model, parser, renderer, adapter, CLI, tests, fixtures, constants, IO, validation, orchestration.\n2. Convert `module.py` to `module\u002F` package when callers import the module as an API surface.\n3. Keep `__init__.py` thin: re-export public names only; do not rebuild the oversized module in the facade.\n4. Move tests with the behavior or add focused tests around the seam being extracted.\n5. For `conftest.py`: keep area-level `conftest.py` thin and import fixture implementations from `tests\u002F\u003Carea>\u002F_fixtures\u002F` or `tests\u002F\u003Carea>\u002Fsupport\u002F` when the project allows that shape.\n6. For generated\u002Fstatic literals: move to resources, fixtures, builders, or data files when appropriate.\n\nAvoid these fake fixes:\n\n- splitting by arbitrary line ranges;\n- creating `utils.py` dumping grounds;\n- moving code without updating import ownership;\n- adding broad allowlists\u002Fbaselines;\n- making `__init__.py` as large as the old module.\n\n### `PY-CODE-014` — god class\n\nSignal: a class crossed >10 non-dunder methods, or `QUALITY-LINT-001` flagged class-body-size after a write.\n\nThreshold reminder: the hook denies at >10 non-dunder methods. **The preemptive trigger is 8 methods with growth obvious in this PR**, not 11 with the hook in your face. Class-line budget (~250 lines) converges on the same bound; whichever budget you approach first is the trigger.\n\nRecovery:\n\n1. Identify the seam by **data + collaborators**, not by alphabetizing methods. A clean seam is a set of methods that share state with each other and barely touch the rest of the class. If the methods you would move all read\u002Fwrite the same three attributes that no other method touches, those attributes plus those methods are the new collaborator.\n2. Name the collaborator after the responsibility (`RunArchiveStore`, `SnapshotPersister`), not after its parent (`EventBufferHelper`, `UserManager`). Inability to name the responsibility means the seam is wrong — re-plan.\n3. Use constructor injection. The new collaborator gets its dependencies through `__init__` parameters. The parent class instantiates it once.\n4. Move tests with the methods. If `TestUserAuth` covered the extracted methods, it follows them to a new test module — do not leave orphaned tests referencing methods that no longer exist on the parent.\n5. After extraction, audit the parent. If it now consists of `__init__` plus four one-line delegating methods, that is `PY-CODE-013` waiting to fire. Either inline the parent's remaining behavior into the call site, or rename the collaborator to take the parent's place.\n\nAnti-patterns to refuse:\n\n- **Random method shuffling to get under 10.** Splitting by alphabetical order is hiding the smell, not fixing it.\n- **`Helper` \u002F `Manager` \u002F `Service` suffix on the new class with no domain noun.** Re-plan the seam.\n- **One-line wrapper methods on the parent that call into the new collaborator.** Move the callers, do not add wrappers.\n- **Bidirectional dependency** (collaborator needs parent passed into `__init__`). The seam was wrong; the responsibility you extracted still depends on parent state.\n\nSee `references\u002Frefactoring_patterns.md` § \"God class extraction\" for the worked positive example (`cloud\u002Fservices\u002Fevent_buffer\u002F`).\n\n### `QUALITY-LINT-001` — post-edit lint backstop\n\nSignal: a mutation landed and the touched file now has a quality violation.\n\nRecovery:\n\n1. Inspect the hook details for collector names and touched paths\u002Fhits.\n2. Repair the landed change before any unrelated work.\n3. If the finding is oversized-module\u002Fgod-class\u002Flong-method\u002Fduplicate-helper, use the structural strategies in this skill.\n4. If the finding is type-safety, load `type-strictness` too.\n5. Run focused verification, then repo-root lint.\n\n### Repeated literal \u002F existing constant findings\n\nSignal: `PY-QUALITY-010`, `PY-DUP-004`, `repeated-string-literal`, or a `QUALITY-LINT-001` detail says a literal is repeated, magic, or already defined as a constant.\n\nResolution strategy:\n\n1. Use the cited existing constant location first. Good hook output should name the symbol and the owner, e.g. `PRIMARY_TIMEOUT_MS = 500 (src\u002Fconstants.py:12)` or `import existing constant PRIMARY_TIMEOUT_MS from src\u002Fconstants.py:12`.\n2. Read that owner file before editing. Confirm the constant is semantically the same value\u002Fpolicy, not just coincidentally equal.\n3. Import and reuse the existing symbol at call sites; preserve the owner module as the single source of truth.\n4. If no existing constant is cited, create one near the owning domain (`constants.py`, `_constants.py`, config\u002Fdefaults module, or a domain package constant), then replace all semantic duplicates intentionally.\n5. Verify with the focused test\u002Fcompile command and repo-root `slopgate lint check`.\n\nDirty fixes to reject:\n\n- splitting a literal into fragments such as `\"pri\" + \"mary\"`;\n- composing a duplicate from partial constants such as `PK_PRI + \"mary\"`;\n- aliasing an existing constant under a new name without adding domain meaning;\n- tuple\u002Flist packing or generated indirection whose only purpose is to change detector hashes;\n- moving the value to `utils.py` or a random config file unrelated to the owning policy.\n\n### `PY-QUALITY-010` — magic numbers \u002F repeated literals\n\nSignal: a literal value appears in code outside a constants\u002Fconfig module, or the same literal is repeated across call sites.\n\nRecovery:\n\n1. Check the hook\u002Flint output for the cited existing constant first. Good output names the symbol and owner, e.g. `PRIMARY_TIMEOUT_MS = 500 (src\u002Fconstants.py:12)`.\n2. Read that owner file before editing. Confirm the constant is semantically the same value\u002Fpolicy, not just coincidentally equal.\n3. Import and reuse the existing symbol at call sites; preserve the owner module as the single source of truth.\n4. If no existing constant is cited, create one near the owning domain (`constants.py`, `_constants.py`, config\u002Fdefaults module, or a domain package constant), then replace all semantic duplicates intentionally.\n5. For magic numbers in algorithmic\u002Fmath code, prefer named constants that explain the policy, not just the value: `MAX_RETRIES = 3` not `THREE = 3`.\n6. Verify with the focused test\u002Fcompile command and repo-root `slopgate lint check`.\n\nDirty fixes to reject:\n\n- splitting a literal into fragments such as `\"pri\" + \"mary\"`;\n- composing a duplicate from partial constants such as `PK_PRI + \"mary\"`;\n- aliasing an existing constant under a new name without adding domain meaning;\n- tuple\u002Flist packing or generated indirection whose only purpose is to change detector hashes;\n- moving the value to `utils.py` or a random config file unrelated to the owning policy.\n\n### `PY-AST-001` — parse\u002Fread failure\n\nRecovery:\n\n1. Re-read the file and restore parseability first.\n2. Run `python3 -m py_compile \u003Cfile>` or the project equivalent.\n3. Only resume refactoring after syntax is clean.\n\n### `PY-CODE-012`, `PY-CODE-013`, duplicate helpers, feature envy\n\nRecovery:\n\n- Thin wrapper: inline it or add meaningful validation, normalization, caching, error translation, or policy.\n- Feature envy: move behavior to the object being inspected or introduce a domain method.\n- Duplicate helper: search existing helpers\u002Fconstants first; consolidate into the existing owner or a cohesive new module.\n- Scattered utility: prefer a domain-owned module over `utils.py`.\n\n## Blast-radius measurement (GitNexus-first, deterministic fallbacks)\n\nBefore any module-to-package split — preemptive or denial-driven — measure who imports the module and which symbols escape so the split preserves the public API.\n\n**Preferred (when GitNexus is available and the index is fresh):**\n\n```text\ngitnexus_impact({target: \"\u003Csymbol_or_module>\", direction: \"upstream\"})\ngitnexus_context({name: \"\u003Csymbol>\"})\ngitnexus_detect_changes()   # before commit, after refactor\n```\n\nIf any GitNexus tool reports the index is stale, run `npx gitnexus analyze` first; do not proceed on stale graph data.\n\n**Fallback recipe when GitNexus is unavailable, stale, or not configured for this repo.** Each command is deterministic, fast, and avoids global filesystem scans. Replace `\u003CMODULE>` with the dotted import path (e.g. `cloud.services.event_buffer._buffer`) and `\u003CSYMBOL>` with the class\u002Ffunction name.\n\n```bash\n# 1. Direct importers — who would break if the module path changes\nrg -n --pcre2 \"^\\s*(from\\s+\u003CMODULE>\\s+import|import\\s+\u003CMODULE>)\" -t py\n\n# 2. Symbol callers \u002F mentions — approximate when GitNexus is absent\nrg -nw \"\u003CSYMBOL>\" -t py\n\n# 3. Public surface of the file under split — names callers can be reaching\nrg -n \"^(def|class|async def)\\s+\\w+\" path\u002Fto\u002Fmodule.py\nrg -n \"^__all__\\s*=\" path\u002Fto\u002Fmodule.py\n\n# 4. Module size + function-size signal\nwc -l path\u002Fto\u002Fmodule.py\nrg -n \"^(def|class|async def) \" path\u002Fto\u002Fmodule.py | wc -l\n\n# 5. Cyclomatic \u002F function-length spot check (radon if installed)\nradon cc -s -a path\u002Fto\u002Fmodule.py\nradon mi -s path\u002Fto\u002Fmodule.py\n\n# 6. Co-change history — files that change together belong together\ngit log --pretty=format: --name-only --diff-filter=AM -- path\u002Fto\u002Fmodule.py \\\n  | grep -v '^$' | sort | uniq -c | sort -rn | head -20\n\n# 7. Test files referencing the symbol (check coverage before moving)\nrg -l \"\u003CSYMBOL>\" tests\u002F\n\n# 8. Find similar-prefix siblings already accumulating in the same dir\nls path\u002Fto\u002Fdir\u002F | grep '^\u003Cprefix>_'\n```\n\nTreat the result of (1) and (7) as the authoritative caller list when no graph index is available. Anything imported only from inside the same package is safe to move freely; anything imported from elsewhere must keep its name reachable through the new `__init__.py` facade or get an explicit migration edit in the same PR.\n\nIf (6) consistently shows two files co-changing on every PR, that is the package boundary asking to exist — group them.\n\n## Verification commands\n\nPick the smallest commands that prove the repair. Common Python\u002FSlopgate sequence:\n\n```bash\n# Syntax for changed Python files\npython3 -m py_compile path\u002Fto\u002Fchanged.py\n\n# Focused tests for touched behavior\npython3 -m pytest tests\u002Fpath\u002Fto\u002Ffocused_test.py -q\n\n# Slopgate quality gate from repo root; no path args\ncd \u002Fpath\u002Fto\u002Frepo && HOME=\u002Fhome\u002Ftrav \u002Fhome\u002Ftrav\u002F.local\u002Fbin\u002Fslopgate lint check\n```\n\nWhen changing Slopgate itself:\n\n```bash\n# From the repository root\n.venv\u002Fbin\u002Fpython -m py_compile src\u002Fslopgate\u002Fengine.py src\u002Fslopgate\u002Frules\u002Fpython_ast\u002F_rules.py\n.venv\u002Fbin\u002Fpython -m pytest tests\u002Ftest_flat_file_sibling_packages.py tests\u002Ftest_size_guard_hook_behavior.py -q\nHOME=\u002Fhome\u002Ftrav .venv\u002Fbin\u002Fslopgate test\ngit diff --check\n```\n\n## When to escalate to `hygiene-orchestrator`\n\nLoad `hygiene-orchestrator` instead of doing a single local refactor when:\n\n- multiple files or packages need coordinated hygiene repairs;\n- many findings share an import graph or public API surface;\n- parallel agents are useful but require file ownership boundaries;\n- a repo-wide quality gate is failing after several local fixes.\n\n## Reference docs\n\n- `references\u002Fquality_rules.md` — current rule IDs and recovery strategies.\n- `references\u002Frefactoring_patterns.md` — package split and smell-specific examples.\n",{"name":5,"author":54,"license":15,"version":55,"metadata":56,"description":85,"compatibility":86},"Slopgate","1.0.0",{"hermes":57,"slopgate":66},{"tags":58,"related_skills":62},[59,31,60,47,61],"slopgate","module-size","quality-gates",[63,64,65],"slopgate-hygiene-orchestrator","slopgate-code-smell-utility-locator","slopgate-intelligent-coding-patterns",{"rule_ids":67,"activation":75},[68,69,70,71,72,73,74],"PY-CODE-017","PY-CODE-018","PY-CODE-014","PY-CODE-008","PY-CODE-009","PY-CODE-015","QUALITY-LINT-001",{"avoid":76,"primary":80},[77,78,79],"repo-wide coordination","helper inventory before ownership is known","test-only expansion",[81,82,83,84],"oversized modules\u002Ffunctions","flat sibling packages","god classes","post-edit quality failures","Recovery playbook for Slopgate and project quality failures. Load after hook\u002Flint denials such as PY-CODE-017 flat sibling modules, PY-CODE-018 oversized modules, QUALITY-LINT-001 post-edit quality backstops, PY-QUALITY-010 magic numbers \u002F repeated literals, PY-CODE-012\u002FPY-CODE-013 smell findings, type-suppression bans, duplicate helpers, or repeated hygiene retry loops. Also load when asked to \"refactor this module\", \"split this file\", \"extract a class\", \"reduce complexity\", \"fix god class\", \"flatten module hierarchy\", \"move code to a package\", \"extract helpers\", \"consolidate duplicates\", \"replace magic numbers with constants\", or when a hook blocks an edit with structural complaints. Focuses on preserving public APIs while refactoring toward packages, cohesive modules, typed seams, and focused tests.\n","claude-code, opencode, codex, hermes, slopgate","master","5fab8004af1390aa17b3447f2780766c8bf2482c",".opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor",0,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate","https:\u002F\u002Fgithub.com\u002Fvasceannie","thingswithstuff.io","2026-11-12 20:22:46",{"source":8,"skillName":5,"commands":96,"prompt":106,"zipAvailable":107},[97,100,103],{"tool":98,"command":99},"npx","npx skills add vasceannie\u002Fslopgate --skill slopgate-code-hygiene-refactor",{"tool":101,"command":102},"bunx","bunx skills add vasceannie\u002Fslopgate --skill slopgate-code-hygiene-refactor",{"tool":104,"command":105},"pnpm","pnpm dlx skills add vasceannie\u002Fslopgate --skill slopgate-code-hygiene-refactor","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002FSKILL.md",true,[109,115,119,125,129,133,137,141],{"path":110,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":113,"sourceHtmlUrl":114},"references\u002Fquality_rules.md","REFERENCE","参考文档",3304,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Freferences\u002Fquality_rules.md",{"path":116,"resourceType":111,"resourceTypeDesc":112,"sizeBytes":117,"sourceHtmlUrl":118},"references\u002Frefactoring_patterns.md",9568,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Freferences\u002Frefactoring_patterns.md",{"path":120,"resourceType":121,"resourceTypeDesc":122,"sizeBytes":123,"sourceHtmlUrl":124},"scripts\u002Fanalyze_long_functions.py","SCRIPT","脚本",6307,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Fscripts\u002Fanalyze_long_functions.py",{"path":126,"resourceType":121,"resourceTypeDesc":122,"sizeBytes":127,"sourceHtmlUrl":128},"scripts\u002Fanalyze_violations.py",6806,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Fscripts\u002Fanalyze_violations.py",{"path":130,"resourceType":121,"resourceTypeDesc":122,"sizeBytes":131,"sourceHtmlUrl":132},"scripts\u002Ffind_constants.py",6693,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Fscripts\u002Ffind_constants.py",{"path":134,"resourceType":121,"resourceTypeDesc":122,"sizeBytes":135,"sourceHtmlUrl":136},"scripts\u002Ffind_similar_functions.py",7501,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Fscripts\u002Ffind_similar_functions.py",{"path":138,"resourceType":121,"resourceTypeDesc":122,"sizeBytes":139,"sourceHtmlUrl":140},"scripts\u002Ffix_assertion_messages.py",6446,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Fscripts\u002Ffix_assertion_messages.py",{"path":142,"resourceType":121,"resourceTypeDesc":122,"sizeBytes":143,"sourceHtmlUrl":144},"scripts\u002Fsuggest_test_renames.py",4123,"https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002F.opencode\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002Fscripts\u002Fsuggest_test_renames.py",[146,171,196,225,246,264],{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":153,"publishedAt":49},"01M71951JDWCYMS8GDC2C7395D","type-strictness","Enforce strict type compliance by eliminating `Any` types and `# type: ignore` comments. Use when:\n(1) Editing code that contains `Any` as a type annotation\n(2) Code has `# type: ignore` or `# pyright: ignore` comments\n(3) User requests type fixes or type strictness enforcement\n(4) Importing from untyped third-party libraries\n(5) User asks to \"fix types\", \"remove Any\", or \"add proper typing\"\n(6) Pyrefly or mypy reports type errors that need resolution\n(7) Code review reveals weak typing patterns\nFollows hierarchical resolution: codebase inference → type stubs → library inspection → type guards → casting (last resort).","https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002Fbundle\u002Fshared\u002Fskills\u002Ftype-strictness\u002FSKILL.md",[152],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[154,155,156,157,158,159,40,160,161,37,30,162,163,164,165,166,167,168,169,170],"type","type strictness","typing","types","remove","code review","errors","inspection","review","reports","libraries","casting","pyrefly","mypy","pyright","library","patterns",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":175,"categories":176,"keywords":181,"publishedAt":49},"01M7194XGBQXSE7Y5BZ4K5CSTK","slopgate-test-extender","Extend Python test suites with parametrization, fixture reuse, and quality enforcement. Use when asked to add tests, extend existing tests, improve test coverage, consolidate duplicate tests, fix test quality issues, or when Slopgate reports untested-production-code, missing test references, or coverage gaps. Triggers on requests like \"add tests for X\", \"extend these tests\", \"parametrize tests\", \"consolidate tests\", \"fix test quality\", \"improve test coverage\", \"write tests for this function\", \"test this module\", \"behavior tests\", \"integration tests\", \"missing tests\", \"coverage holes\", \"untested code\", or when a hook denies with test-related findings.","https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002Fbundle\u002Fshared\u002Fskills\u002Fslopgate-test-extender\u002FSKILL.md",[177,178],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":179,"categoryName":180,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量",[182,183,184,185,186,40,187,188,189,39,190,191,37,30,192,34,163,193,194,195],"slopgate test extender","test","coverage","fixture","testing","issues","write tests","improve","cleanup","loop","candidate","references","opencode","orchestrator",{"skillNo":197,"name":65,"nameZh":6,"description":198,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":199,"categories":200,"keywords":212,"publishedAt":49},"01M7194RMVQS5YJJ4ZEFXX20VS","Pattern-selection playbook for agents editing code with complex branching, stateful parsers\u002Fworkflows, duplicated skeletons, policy checks, or ordered transforms. Load before refactoring if\u002Felif dispatch chains, boolean-flag state machines, repeated validation predicates, parallel provider\u002Flanguage implementations, or regex\u002Fcontent transformation pipelines. Also load when asked to \"apply a design pattern\", \"which pattern should I use here\", \"refactor this switch statement\", \"replace if-elif chain\", \"state machine pattern\", \"strategy pattern\", \"template method\", \"pipeline pattern\", \"specification pattern\", \"dispatch table\", \"guard clause refactor\", \"reduce cyclomatic complexity\", or when Slopgate fires PY-CODE-014, PY-CODE-017, PY-CODE-018, QUALITY-LINT-001, or PY-QUALITY-010. Use with behavior-locking tests and avoid pattern theater for simple one-off code.","https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002Fbundle\u002Fshared\u002Fskills\u002Fslopgate-intelligent-coding-patterns\u002FSKILL.md",[201,202,205,208,209],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":203,"categoryName":204,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":206,"categoryName":207,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},{"categoryNo":210,"categoryName":211,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000032","设计师",[213,214,170,215,216,47,217,218,219,220,221,222,223,39,190,38,224,37,36,30],"coding patterns","slopgate intelligent coding patterns","coding","stateful","branch","which","chain","parsers","pipeline","selection","design","workflows",{"skillNo":226,"name":63,"nameZh":6,"description":227,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":228,"categories":229,"keywords":232,"publishedAt":49},"01M7194KTXBM85GB0W7JKFQD55","Orchestrate systematic elimination of linter warnings and errors across Python, TypeScript, and Rust codebases. Use when asked to \"clean up lints\", \"fix all warnings\", \"run hygiene\", \"eliminate type errors\", \"orchestrate code quality fixes\", \"fix lint errors\", \"resolve quality gate failures\", \"pass CI checks\", \"reduce tech debt\", \"refactor to pass hooks\", or when a Slopgate hook denies with QUALITY-LINT-001, PY-CODE-017, PY-CODE-018, or any collector finding. This skill coordinates multiple code-hygiene-enforcer agents working in parallel on non-conflicting file groupings, tracks progress persistently via JSON exports, and loops until all issues are resolved. CRITICAL: Never run linters directly—always use `slopgate lint check` as the primary gate, discover project-specific tools from config files, and export findings to JSON for tracking.","https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002Fbundle\u002Fshared\u002Fskills\u002Fslopgate-hygiene-orchestrator\u002FSKILL.md",[230,231],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":206,"categoryName":207,"taxonomyType":21,"taxonomyTypeDesc":22},[233,32,195,44,40,234,235,236,237,238,190,36,239,240,241,242,243,244,61,245],"slopgate hygiene orchestrator","ci","local","clean","never run","files","run","lint check","systematic","config","typescript","debt","hook",{"skillNo":247,"name":64,"nameZh":6,"description":248,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":249,"categories":250,"keywords":253,"publishedAt":49},"01M7194G50FZYXXT8VNK360RPA","Autoactivate when code-smell hooks or reviews mention feature envy, thin wrappers, duplicate helpers, duplicate code,\nscattered helpers, builders\u002Ffactories\u002Fconfig\u002Fconstants\u002Fdataclass reuse, PY-CODE-012, PY-CODE-013, QUALITY-LINT-001,\nor repeated slopgate code-quality denials. Also load when asked to \"find existing helpers\", \"consolidate utilities\",\n\"search for duplicate code\", \"where is this already implemented\", \"reuse existing logic\", \"don't duplicate this\",\n\"find similar functions\", \"utility inventory\", \"code smell radar\", or before adding new helpers\u002Fwrappers so agents can\nfind existing shared utilities and consolidate instead of duplicating.","https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002Fbundle\u002Fshared\u002Fskills\u002Fslopgate-code-smell-utility-locator\u002FSKILL.md",[251,252],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},[38,254,30,255,184,256,42,257,258,39,259,37,35,34,194,260,261,242,262,263],"slopgate code smell utility locator","shared","reviews","search","hooks","new","radar","code-quality","Utilities","dataclass",{"skillNo":265,"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":266,"categories":267,"keywords":270,"publishedAt":49},"01M7194AWG1Q37F9756H4SFDH9","https:\u002F\u002Fgithub.com\u002Fvasceannie\u002Fslopgate\u002Fblob\u002Fmaster\u002Fbundle\u002Fshared\u002Fskills\u002Fslopgate-code-hygiene-refactor\u002FSKILL.md",[268,269],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},[33,29,30,31,32,48,47,46,45,44,43,42,41,40,39,38,37,36,35,34]]