cs-feat-ff
When users say "help me make xxx" and the requirement is small, AI would normally start writing code directly anyway — this skill does not change that. It only does one thing: before AI starts writing, it points AI to the CodeStable knowledge accumulated in the project, letting AI search it as needed. This adds an extra layer of protection to the code compared to writing from scratch.
So this skill is extremely lightweight. No design docs, no checklists, no acceptance criteria, no need for user confirmation. After reading this guide, just read the code and write the code as needed.
Check These Spots Before You Start Coding
The project may already have experience, decisions, and exploration results accumulated by predecessors. Search for relevant content before writing code, and you'll avoid a lot of pitfalls if you find matching entries.
— Experience Accumulation
Stores four types of documents: learning (pitfalls encountered), trick (useful practices), decision (finalized technical decisions), explore (targeted research conclusions). File names include
, which can be filtered by type and tags.
bash
# Pitfall records related to the current task
python codestable/tools/search-yaml.py --dir codestable/compound --filter doc_type=learning --query "keywords"
# Check if there are relevant technical decisions constraining how this should be written
python codestable/tools/search-yaml.py --dir codestable/compound --filter doc_type=decision --query "keywords"
# Check if there are existing practices to reference
python codestable/tools/search-yaml.py --dir codestable/compound --filter doc_type=trick --query "keywords"
— Architecture Overview
is the main entry point, with subsystems split into other md files in the same directory. Before modifying cross-module content, check the relevant subsystem documentation to avoid violating established boundaries. Just
it.
— Shared Scripts
- — YAML frontmatter search (demonstrated above), supports , ,
- — YAML syntax validation; run this if you write files with frontmatter
Usage details are in
codestable/reference/tools.md
.
— Shared Standards
- — Directory structure, naming, and metadata field conventions for feature / issue / compound
- — Complete usage of the two scripts above
- — Maintenance-side conventions (usually not needed for this task)
How to Use This Knowledge
Ask yourself 2 questions before starting:
- Has anyone encountered pitfalls in this part of the code before? → Search for learning entries
- Are there any finalized writing constraints for this part of the code? → Search for decision entries + check relevant subsystem docs in
If you find matching entries, integrate the relevant conclusions into your implementation (don't copy, follow the constraints). If not, write according to your own judgment — this is normal, not every task has a path paved by predecessors.
Not finding results doesn't mean there's nothing — try different keywords.
supports full-text search with
, which has a wide hit range.
Stick to These Rules When Writing Code
These are condensed hard constraints from design / implement processes adapted for fastforward. No design doc doesn't mean you can ignore these — they prevent you from falling into the pitfalls AI would normally default to.
First Think "Where to Put It", Then "How to Write It"
Spend 30 seconds before starting to ask: Where does the thing I'm adding belong in the project structure?
- Is this something an existing module should be responsible for? If yes, extend that module instead of creating a new one outside
- Does this span multiple modules? Consider extracting a common layer or letting one party take the lead
- Is there already a module doing something similar but with a different name you didn't notice? Run a before deciding
- Doesn't fit with any existing module? You may need to create an independent module — in most cases, you should switch back to the full design process
The default pitfall is adding it to the most convenient file in front of you without thinking — after adding, that file becomes a "catch-all basket".
Check the Current State of the File You're Going to Modify
After finding the right spot, before starting to write, check the file you're going to modify:
- How long is this file now? How many responsibilities does it take on? Is the new addition an extension of existing responsibilities, or the N+1th thing?
- How many methods does this class have? Is adding this method a natural extension, or pushing the class towards "can do everything"?
If the state is healthy, add directly. If you need to clean it up first (split long files / extract duplicate functions), clean up first then add, but limit the scope to "only move, don't change behavior". If there are structural issues (responsibilities need to be redefined / modules need to be split or merged), stop and tell the user this is more complex than expected, suggesting switching back to the design process.
Forcing functionality into an already messy file results in an even longer, messier file — this is AI's default preference, and you should actively resist it.
Write the Minimal Amount of Code by Default
Only write exactly what the user explicitly asked for now. Don't add:
- Configuration items / parameter switches "that might be needed later"
- Defensive fallbacks / try-catch blocks no one asked for
- Reserved abstraction layers / interfaces / factories
- Boundary handling not mentioned by the user
If after writing a section you think "should I add X to make it complete?" — first ask if X is something the user can perceive. If not, don't add it. Extra code isn't neutral; it's a burden for future maintainers to understand, question, and worry about missing invariants.
Only Modify What Needs to Be Modified, Don't "Improve" Neighboring Code Casually
When opening a file to modify a function, only modify that function. If other functions in the same file have ugly styles, weird naming, or outdated comments — don't touch them unless they directly conflict with this change. The style of new code should match the existing style in the current file, even if you don't usually write that way.
If you find something worth modifying elsewhere, note it down and tell the user "Found incidentally: {file:line number} {issue}, not in this scope", letting the user decide if it should be done separately.
Put New Logic in New Files by Default
By default, create independent files for new cohesive logic units instead of appending to existing files. Judgment criteria: Will this new logic be referenced elsewhere in the future? If yes, put it in a new file; small utility functions only used in one place can be placed nearby.
Don't Write Patch Branches
When you start writing
if (special case) { special handling }
structures,
stop.
This kind of branch almost always means your thinking didn't cover this case. Continuing to write will result in "special logic added just to make the code run", and the next person modifying this part won't know why this branch exists. The correct approach is to figure out this case before continuing — either modify the data structure so it doesn't need special handling, or explicitly acknowledge it as a boundary case and add comments explaining why it's special.
Stop When Triggering Reflection Signals
Stop and re-evaluate immediately if any of the following signals appear, don't force it:
- Appending to a file that's already > 300 lines
- Adding another method to a class that already has > 10 methods
- A function is doing more and more things, exceeding one screen
- Writing a second section of code "basically the same as the above but with two variables changed"
- Adding the 4th parameter to a function
- Continuing to pile code into universal utils like /
- When creating a new concept name (type / function / key variable), first to see if there are identical or similar names
The full list is in Section 7 (Code Quality Reflection Checks) of
codestable/reference/shared-conventions.md
.
What Not to Do
- Don't write design docs — this is the whole point of fastforward. If you need design, use
- Don't write checklists / acceptance criteria — same as above
- Don't confirm the plan with the user — users ask for small features because they don't want to wait for meetings
- Don't leave new files in — unless you find a pitfall or trick worth documenting during coding, start a new conversation with / to write it
When to Exit fastforward
Stop and tell the user "This is more complex than expected, suggest switching back to the full feature process" if you encounter any of the following during development:
- Changes involve 3 or more subsystems
- You find that you need to introduce new terminology or it conflicts with existing terminology
- You need to modify the established module boundaries in
- The user's additional requests double the scope
To switch back to the full process: Trigger the
skill and restart from the design phase. It's okay if you've already written some code; mark "partially implemented" in the design doc.
Common Pitfalls
- Skipping knowledge retrieval entirely before writing — the only reason this skill exists is to let you search first; not searching means you didn't use this skill
- Treating found learning/decision entries as "reference materials" instead of "constraints" — decisions are finalized; violating them requires re-deciding or abandoning the task
- Starting to write design docs — fastforward means no design docs; if you want to write, use the design skill
- Forcing the task in fastforward after finding it's more complex — switching back to the full process costs far less than modifying with a wrong plan to the end