arch-drift-guard
When to use
Use this skill when any of the following appears:
- giant
main.rs / god file keeps regrowing
- repeated API drift after partial refactors
- struct initializer drift after adding fields
- cross-layer edits keep breaking compile/tests
- module boundaries are unclear or routinely violated
- agent edits cause repo erosion over time
- user says things like: “漂移”, “越改越乱”, “边界不稳”, “模块化不够”
Do not use when
- simple isolated bug with clear local fix -> use
systmt-dbggng
- brand-new system design -> use
ddd-project-grdrls
- only one extraction move with known order in ict-engine main.rs -> consider
ict-engi-stag-main-extr
Core rule
Do not start with code changes.
First classify the drift, define the allowed change surface, and write the governing artifacts.
Drift classes
Classify the problem before touching code:
file-truncation-drift
- file content is cut, reverted, or structurally broken
api-signature-drift
- function signatures changed, call sites stale
struct-initializer-drift
- new fields added, builders/defaults/tests stale
boundary-erosion
- logic leaks across application/domain/reporting/orchestration layers
workflow-surface-drift
- output/report/workflow snapshots evolve without synchronized adapters
dependency-drift
- imports/dependencies move without declared layering rules
Mandatory artifact-first flow
Before significant edits, create or update repo artifacts:
DEBUG.md for reproduction and evidence
docs/architecture-boundaries.md for durable module/layer boundaries
docs/change-surface.md for this task's allowed edit surface
docs/drift-ledger.md for repeated erosion patterns and fixes
If the repo already has equivalent artifacts, update them instead of creating duplicates.
Allowed change surface
Define explicitly:
- files allowed to change
- files forbidden to change
- public interfaces allowed to move
- invariants that must remain stable
- tests/checks that must pass before expanding scope
If a fix requires touching files outside the declared surface, stop and revise the artifact first.
Required checks
Always prefer mechanical enforcement over prose.
For each drift task, choose at least 2:
- compile/build check
- targeted test
- full test suite if surface is broad
- search for stale symbols/imports/call sites
- graph/dependency inspection
- diff audit on boundary-sensitive files
Anti-drift implementation order
- restore file integrity first
- restore type/build consistency
- restore adapter/wrapper surfaces
- restore module boundaries
- only then add new feature work
Contract-first growth under external unknowns
Use this pattern when the target depends on real websites, browsers, callbacks, payment flows, or APIs whose runtime truth is not yet verified, and the user asks for “禁污染/禁负债” style progress:
- Re-open
docs/change-surface.md for each increment; make the current task, allowed files, forbidden files, completion criteria, and rollback trigger explicit.
- Prefer pure contracts first: dataclasses, state machines, repository methods, schema tables, serializer helpers, and tests.
- Keep unverified URL/DOM/network/API assumptions out of production services; place them only in
probes/ or adapters/experimental/ after evidence exists.
- Do not widen into pipeline, browser workers, or old giant scripts unless the change surface explicitly permits it.
- Verify with targeted tests plus full suite/compile check when the surface touches models or storage; remove generated caches before finalizing.
Architecture guardrails
- One new field -> update struct, default, builders, tests, fixtures in one pass
- One new function signature -> patch all call sites immediately
- New reporting/output surface -> add adapter/helper first, do not inline giant logic into
main.rs
- Repeated similar output blocks -> extract helper, do not wide-replace text
- If touching a god file, prefer unique helper insertion over direct large rewrites
- For Rust
main.rs signature migrations, do not run broad textual close-paren replacements ()? vs })?) across the file. Use unique, per-callsite edits or AST-aware/manual patches; wide replacements can silently corrupt unrelated append_* / save_* calls.
- When modularizing a god-file CLI/workflow surface, extract pure value/surface builders first, then command functions later. Command handlers often depend on local loaders, refresh helpers, and private bootstrap glue; moving them first creates unresolved-boundary churn.
- Before moving a function out of a monolith, list its private dependencies explicitly: data loaders, snapshot refreshers, local helper views, and crate-path assumptions (
crate::... vs binary-side ict_engine::...). If those are not portable yet, narrow the extraction surface.
Recommended repo artifacts
docs/architecture-boundaries.md
Include:
- layer list
- ownership of each layer
- forbidden dependency directions
- allowed adapter bridges
- “what does not belong here” examples
docs/change-surface.md
Include:
- task objective
- drift class
- editable paths
- non-editable paths
- verification commands
- rollback trigger
docs/drift-ledger.md
Append entries like:
- symptom
- root cause
- repair order that worked
- new permanent guardrail added
Validation standard
Minimum before claiming done:
- target compile/build passes
- no stale references in touched surfaces
- declared tests pass
- artifacts updated
- diff is scoped to declared surface or the surface artifact was revised
Escalation rule
If the same area has drifted 3+ times, stop treating it as a one-off bug.
Create or update a durable architecture boundary artifact or a repo-specific skill.
Good outputs from this skill
- compact drift classification
- repo artifact updates
- small repair sequence
- boundary/ownership clarification
- mechanical checks listed and executed
Bad outputs
- vague “we should modularize more” with no artifact
- giant refactor started before classifying drift
- code changes without declared change surface
- relying on memory instead of repo truth
Suggested commands/checks
Use Hermes tools first, but typical shell verification may include:
cargo fmt --all
cargo check
cargo test
- targeted test names
- targeted symbol searches for stale paths/signatures
Relationship to other skills
- use with
systmt-dbggng when root cause still unknown
- use with
ict-engi-stag-main-extr for large main.rs extraction in ict-engine
- use with
ict-engi-safe-main-outp when drift is concentrated in output/reporting wiring
- use with
ddd-project-grdrls if drift reveals missing strategic boundaries
1---2name: arch-drift-guard3description: Use when a repo is suffering architecture drift, API drift, main-file bloat, boundary erosion, or repeated breakage from cross-layer edits. Enforces artifact-first anti-drift governance: classify drift type, declare allowed change surface, write durable repo artifacts, require mechanical checks, and only then modify code.4---56# arch-drift-guard78## When to use9Use this skill when any of the following appears:10- giant `main.rs` / god file keeps regrowing11- repeated API drift after partial refactors12- struct initializer drift after adding fields13- cross-layer edits keep breaking compile/tests14- module boundaries are unclear or routinely violated15- agent edits cause repo erosion over time16- user says things like: “漂移”, “越改越乱”, “边界不稳”, “模块化不够”1718## Do not use when19- simple isolated bug with clear local fix -> use `systmt-dbggng`20- brand-new system design -> use `ddd-project-grdrls`21- only one extraction move with known order in ict-engine main.rs -> consider `ict-engi-stag-main-extr`2223## Core rule24Do not start with code changes.25First classify the drift, define the allowed change surface, and write the governing artifacts.2627## Drift classes28Classify the problem before touching code:291. `file-truncation-drift`30 - file content is cut, reverted, or structurally broken312. `api-signature-drift`32 - function signatures changed, call sites stale333. `struct-initializer-drift`34 - new fields added, builders/defaults/tests stale354. `boundary-erosion`36 - logic leaks across application/domain/reporting/orchestration layers375. `workflow-surface-drift`38 - output/report/workflow snapshots evolve without synchronized adapters396. `dependency-drift`40 - imports/dependencies move without declared layering rules4142## Mandatory artifact-first flow43Before significant edits, create or update repo artifacts:44- `DEBUG.md` for reproduction and evidence45- `docs/architecture-boundaries.md` for durable module/layer boundaries46- `docs/change-surface.md` for this task's allowed edit surface47- `docs/drift-ledger.md` for repeated erosion patterns and fixes4849If the repo already has equivalent artifacts, update them instead of creating duplicates.5051## Allowed change surface52Define explicitly:53- files allowed to change54- files forbidden to change55- public interfaces allowed to move56- invariants that must remain stable57- tests/checks that must pass before expanding scope5859If a fix requires touching files outside the declared surface, stop and revise the artifact first.6061## Required checks62Always prefer mechanical enforcement over prose.63For each drift task, choose at least 2:64- compile/build check65- targeted test66- full test suite if surface is broad67- search for stale symbols/imports/call sites68- graph/dependency inspection69- diff audit on boundary-sensitive files7071## Anti-drift implementation order721. restore file integrity first732. restore type/build consistency743. restore adapter/wrapper surfaces754. restore module boundaries765. only then add new feature work7778## Contract-first growth under external unknowns79Use this pattern when the target depends on real websites, browsers, callbacks, payment flows, or APIs whose runtime truth is not yet verified, and the user asks for “禁污染/禁负债” style progress:801. Re-open `docs/change-surface.md` for each increment; make the current task, allowed files, forbidden files, completion criteria, and rollback trigger explicit.812. Prefer pure contracts first: dataclasses, state machines, repository methods, schema tables, serializer helpers, and tests.823. Keep unverified URL/DOM/network/API assumptions out of production services; place them only in `probes/` or `adapters/experimental/` after evidence exists.834. Do not widen into pipeline, browser workers, or old giant scripts unless the change surface explicitly permits it.845. Verify with targeted tests plus full suite/compile check when the surface touches models or storage; remove generated caches before finalizing.858687## Architecture guardrails88- One new field -> update struct, default, builders, tests, fixtures in one pass89- One new function signature -> patch all call sites immediately90- New reporting/output surface -> add adapter/helper first, do not inline giant logic into `main.rs`91- Repeated similar output blocks -> extract helper, do not wide-replace text92- If touching a god file, prefer unique helper insertion over direct large rewrites93- For Rust `main.rs` signature migrations, do not run broad textual close-paren replacements (`)?` vs `})?`) across the file. Use unique, per-callsite edits or AST-aware/manual patches; wide replacements can silently corrupt unrelated `append_*` / `save_*` calls.94- When modularizing a god-file CLI/workflow surface, extract pure value/surface builders first, then command functions later. Command handlers often depend on local loaders, refresh helpers, and private bootstrap glue; moving them first creates unresolved-boundary churn.95- Before moving a function out of a monolith, list its private dependencies explicitly: data loaders, snapshot refreshers, local helper views, and crate-path assumptions (`crate::...` vs binary-side `ict_engine::...`). If those are not portable yet, narrow the extraction surface.9697## Recommended repo artifacts9899### docs/architecture-boundaries.md100Include:101- layer list102- ownership of each layer103- forbidden dependency directions104- allowed adapter bridges105- “what does not belong here” examples106107### docs/change-surface.md108Include:109- task objective110- drift class111- editable paths112- non-editable paths113- verification commands114- rollback trigger115116### docs/drift-ledger.md117Append entries like:118- symptom119- root cause120- repair order that worked121- new permanent guardrail added122123## Validation standard124Minimum before claiming done:125- target compile/build passes126- no stale references in touched surfaces127- declared tests pass128- artifacts updated129- diff is scoped to declared surface or the surface artifact was revised130131## Escalation rule132If the same area has drifted 3+ times, stop treating it as a one-off bug.133Create or update a durable architecture boundary artifact or a repo-specific skill.134135## Good outputs from this skill136- compact drift classification137- repo artifact updates138- small repair sequence139- boundary/ownership clarification140- mechanical checks listed and executed141142## Bad outputs143- vague “we should modularize more” with no artifact144- giant refactor started before classifying drift145- code changes without declared change surface146- relying on memory instead of repo truth147148## Suggested commands/checks149Use Hermes tools first, but typical shell verification may include:150- `cargo fmt --all`151- `cargo check`152- `cargo test`153- targeted test names154- targeted symbol searches for stale paths/signatures155156## Relationship to other skills157- use with `systmt-dbggng` when root cause still unknown158- use with `ict-engi-stag-main-extr` for large `main.rs` extraction in ict-engine159- use with `ict-engi-safe-main-outp` when drift is concentrated in output/reporting wiring160- use with `ddd-project-grdrls` if drift reveals missing strategic boundaries