cs-feat-ff

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

cs-feat-ff

cs-feat-ff

用户说"帮我做个 xxx"而且需求小的时候,本来 AI 就会直接动手写——这个技能不改变这件事。它只做一件事:在 AI 动手之前,把项目里已经沉淀的 CodeStable 知识指给它,让它按需去搜,写出来的代码就能比裸写多一层保护。
所以这个技能非常轻。没有 design doc、没有 checklist、没有验收清单、不需要用户确认。看完这份指引,该读代码读代码,该写代码写代码。

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.

codestable/compound/
— 经验沉淀

codestable/compound/
— Experience Accumulation

放 learning(踩过的坑)/ trick(好用的做法)/ decision(拍板的技术决定)/ explore(定向调研结论)四类文档。文件名带
doc_type
,可以按 type 和标签过滤。
bash
undefined
Stores four types of documents: learning (pitfalls encountered), trick (useful practices), decision (finalized technical decisions), explore (targeted research conclusions). File names include
doc_type
, which can be filtered by type and tags.
bash
undefined

当前任务相关的踩坑记录

Pitfall records related to the current task

python codestable/tools/search-yaml.py --dir codestable/compound --filter doc_type=learning --query "关键词"
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 "关键词"
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 "关键词"
undefined
python codestable/tools/search-yaml.py --dir codestable/compound --filter doc_type=trick --query "keywords"
undefined

codestable/architecture/
— 架构全景

codestable/architecture/
— Architecture Overview

DESIGN.md
是总入口,子系统拆到同目录下的其他 md 文件里。改到跨模块的东西前先看一眼相关子系统文档,避免违反既定边界。直接
Read
就行。
DESIGN.md
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
Read
it.

codestable/tools/
— 共享脚本

codestable/tools/
— Shared Scripts

  • search-yaml.py
    — YAML frontmatter 搜索(上面示范过),支持
    --filter
    --query
    --sort-by
  • validate-yaml.py
    — YAML 语法校验,如果写了带 frontmatter 的文件就跑一下
用法细节在
codestable/reference/tools.md
  • search-yaml.py
    — YAML frontmatter search (demonstrated above), supports
    --filter
    ,
    --query
    ,
    --sort-by
  • validate-yaml.py
    — YAML syntax validation; run this if you write files with frontmatter
Usage details are in
codestable/reference/tools.md
.

codestable/reference/
— 共享口径

codestable/reference/
— Shared Standards

  • shared-conventions.md
    — feature / issue / compound 的目录结构、命名、元数据字段约定
  • tools.md
    — 上面两个脚本的完整用法
  • maintainer-notes.md
    — 维护侧的约定(这个任务用不上一般不用看)

  • shared-conventions.md
    — Directory structure, naming, and metadata field conventions for feature / issue / compound
  • tools.md
    — Complete usage of the two scripts above
  • maintainer-notes.md
    — Maintenance-side conventions (usually not needed for this task)

怎么用这些知识

How to Use This Knowledge

动手前问自己 2 个问题:
  1. 这块代码以前有人栽过跟头吗? → 搜
    compound/
    的 learning
  2. 这块代码有没有已经拍板的写法约束? → 搜
    compound/
    的 decision + 看
    architecture/
    相关子系统文档
命中就把相关结论融进实现(别抄,是按约束来写)。没命中就按自己判断写,这很正常——不是每个任务都有前人铺好的路。
搜不到不等于没有——换几个关键词再试。
search-yaml.py
支持
--query
做全文搜,词命中范围宽。

Ask yourself 2 questions before starting:
  1. Has anyone encountered pitfalls in this part of the code before? → Search
    compound/
    for learning entries
  2. Are there any finalized writing constraints for this part of the code? → Search
    compound/
    for decision entries + check relevant subsystem docs in
    architecture/
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.
search-yaml.py
supports full-text search with
--query
, which has a wide hit range.

写代码时守住这几条

Stick to These Rules When Writing Code

这些是 design / implement 里的硬约束提炼到 fastforward 来的版本。没有 design doc 不代表可以不讲这几条——这些是让你在"直接动手写"时不偏向 AI 默认会踩的坑。
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"

动手前花 30 秒想一个问题:这次要加的东西,在项目结构里属于哪儿?
  • 这件事是某个现有模块本该承担的吗?是的话在那个模块里扩展,别在外面另起
  • 这件事横跨多个模块?考虑抽一层公共的,或者让某一方主导
  • 已经有模块在做类似的事但名字不一样、你没注意到?
    grep
    一下再决定
  • 和现有任何模块都不太像?可能要新建独立模块——这种情况多半该切回完整 design 流程
默认踩的坑是不思考就往眼前最顺手的文件里加——加完那个文件就变成"什么都装的筐"。
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
    grep
    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

找到落点后,开写之前再看一眼要改的文件:
  • 这个文件现在多长?承担了几件事?新加的是已有职责的延伸,还是第 N+1 件事?
  • 这个类有多少方法?加这个方法是自然扩展,还是把类推向"什么都能干"?
状态健康就直接加。要先收拾一下(拆长文件 / 抽重函数)的话先收拾再加,但范围锁死为"只搬不改行为"。结构性问题(职责要重划 / 模块要拆合)就停下来告诉用户这个比想的复杂、建议回 design 流程。
硬塞功能进一个已经不干净的文件,得到的是一个更长更不干净的文件——这是 AI 的默认偏好,要明着抵抗。
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

只写用户当前明确要的那点东西。不顺手加:
  • "以后可能要用"的配置项 / 参数开关
  • 没人要的防御性兜底 / try-catch
  • 预留的抽象层 / 接口 / 工厂
  • 用户没提的边界处理
写完一段觉得"是不是还得加点 X 才完整"——先问 X 是不是用户能感知到的,不是就别加。多出来的代码不是中性的,是后人维护时要读懂、要怀疑、要担心漏了哪条不变量的负担。
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

写到一半冒出
if (特殊情况) { 特殊处理 }
这种结构,
这种分支冒出来基本只有一个原因:思路没覆盖到这种情况。继续硬写得到的是"为了让代码能跑而加的特殊逻辑",下次别人改这块时根本不知道这个分支为什么存在。正确做法是把这个情况想清楚再继续——要么改数据结构让它不需要特殊处理,要么明确承认它是边界情况并加注释说明为什么特殊。
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

下面几种信号一出现就要停下来重新评估,不是硬着头皮写下去:
  • 往一个已经 > 300 行的文件继续追加
  • 往一个已经 > 10 个方法的类里再加方法
  • 一个函数做的事越来越多,超过一屏
  • 要写第二段"跟上面那段基本一样但改了两个变量"的代码
  • 函数参数加到第 4 个
  • utils.ts
    /
    helpers.ts
    这种万能 util 里继续堆东西
  • 要新起一个概念名(类型 / 函数 / 关键变量)时,先
    grep
    看有没有同名或近义的命名
完整清单看
codestable/reference/shared-conventions.md
第 7 节(代码质量反射检查)。

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
    utils.ts
    /
    helpers.ts
  • When creating a new concept name (type / function / key variable), first
    grep
    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

  • 不写 design doc——这是 fastforward 的整个意义所在。要 design 就去
    cs-feat-design
  • 不写 checklist / acceptance——同上
  • 不跟用户确认方案——用户让你做小功能就是不想等你开会
  • 不在
    codestable/
    里留下新文件
    ——除非写代码过程中发现了值得沉淀的坑或技巧,那另起一次对话用
    cs-learn
    /
    cs-trick
    去写

  • Don't write design docs — this is the whole point of fastforward. If you need design, use
    cs-feat-design
  • 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
    codestable/
    — unless you find a pitfall or trick worth documenting during coding, start a new conversation with
    cs-learn
    /
    cs-trick
    to write it

什么时候跳出 fastforward

When to Exit fastforward

干到一半发现下面任一情况,停下来告诉用户"这个比想象的复杂,建议切回完整 feature 流程"
  • 改动涉及 3 个以上子系统
  • 发现需要引入新术语或和现有术语冲突
  • 要动
    codestable/architecture/
    里既定的模块边界
  • 用户追加的要求让范围翻倍
切回完整流程的方式:触发
cs-feat-design
技能,从 design 阶段重新走。已经写了一部分代码没关系,在 design 里标注"已部分实现"即可。

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
    codestable/architecture/
  • The user's additional requests double the scope
To switch back to the full process: Trigger the
cs-feat-design
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

  • 完全跳过知识检索就写——这个技能存在的唯一理由就是让你搜一下再写,不搜就等于没加载这个技能
  • 把搜到的 learning/decision 当"参考资料"而不是"约束"——decision 是拍过板的,违反它要么重新 decision 要么别做
  • 开始写 design doc——fastforward 就是不写 design,想写就去 design 技能
  • 发现任务变复杂还硬在 fastforward 里推——切回完整流程成本远低于带着错误方案改到底
  • 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