Write Environment Facts into Rules
Model config, tech-stack lock-in, data format taxonomy, and must-know traps like isComposing
THE QUESTION THIS PAGE ANSWERS
ANSWER FIRSTWhat is the key idea behind “Write Environment Facts into Rules”?
Model config, tech-stack lock-in, data format taxonomy, and must-know traps like isComposing
Turn taste into a behavior the product can repeat. The useful outcome is not a nice opinion. It is a visible rule, a small example, and a way to tell when the experience falls below the bar.
Capture one before-and-after example that shows the quality bar without extra explanation.
Polish that improves the surface while leaving the user's uncertainty untouched.
Why Rules: If you put config in .env and let AI read it on its own, it won't always do so proactively. If you write it in the conversation, it gets truncated and forgotten as the conversation grows. Rules are loaded into context before every conversation turn — the most reliable injection method.
When a Chinese IME (input method editor) confirms a candidate word, it triggers Enter. An input field that only checks e.key === 'Enter' will send a half-composed message. Coverage of isComposing in AI training data is low — if you don't write it into a Rule, the AI will definitely forget it. Switch to a Chinese IME and try typing in the box below.
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' && !e.shiftKey
&& !e.nativeEvent.isComposing) {
e.preventDefault()
handleSend()
}
}
isComposingistrue: IME is still composing — Enter only confirms the candidate, it does not trigger sendisComposingisfalse: direct keyboard input — Enter sends normally- Rule text: never check only
e.key === 'Enter'without also checkingisComposing
The data-format tripartite rule: three formats, each ruling its own domain — never mixed. Click a scenario, then pick the format you think is right.
{
"tool": "send_message",
"arguments": "{\"channel\": \"dev\",
\"payload\": \"{\\\"title\\\":
\\\"Release reminder\\\", \\\"body\\\":
\\\"v1.4 is live\\\"}\"}"
}
<tool_call name="send_message">
<channel>dev</channel>
<payload>
<title>Release reminder</title>
<body>v1.4 is live</body>
</payload>
</tool_call>
Every nesting level in JSON doubles the backslashes — when an LLM generates token by token, it is very easy to mismatch brackets and quotes. XML tag closure is intuitive, and models make far fewer errors.
Progress: 0 / 3 scenarios
Image generation needs at least 120–180 s
Image APIs often fail due to the default 30-second timeout, and the AI keeps retrying the same broken config. Write the HTTP client timeout into a Rule — solved once and for all.
On network failure, retry via proxy first
When a network request fails, always retry via proxy (default 127.0.0.1:7890) before reporting failure to the user. Never skip the proxy and error out directly.
All user-visible LLM responses must stream
Every user-visible LLM response must use Streaming. Non-streaming is only permitted for internal backend calls.
Stack selection is a human decision
- Backend: FastAPI; Frontend: React + Tailwind + Vite; Database: SQLite; Vector store: Chroma
- Once decided, stop discussing alternatives — the AI's job is to write good code within the chosen stack
- Avoid port 5000; assign randomly from 8000–9000 so multiple projects don't conflict
Icon and detail standards
- Never use emoji as button icons — icons must be SVG
- Choose icon sets by product tone: SaaS → Lucide; warm/friendly tone → Tabler Icons
- Download icons locally — do not depend on a CDN
Note: Projects that use only GPT-series models can switch tool calls back to JSON — its function calling is natively JSON. "Agents use XML" is the greatest common denominator for multi-model setups; Claude-series models perform more stably with XML format.
Deliverable: the environment configuration section of your Rule. ① List your project's environment facts: model, API provider, timeout, proxy, tech stack, database. ② Write them as a Rule section; put sensitive keys in a separate secrets file and add it to .gitignore. ③ Open a fresh conversation to verify: without any additional context, can the AI immediately state your tech stack and model configuration?
Source material: open-source repo itshen/xs_vibe_rules, rule-opensource.mdc, Chapter 1 "Model Configuration", Chapter 4 "Documentation & Design Standards", Chapter 5 "Data Format Standards", Chapter 6 "Tech Stack & Frameworks".
Turn the feeling in “Interactive Demo 1 · isComposing — Try It with an IME” into a judgment
“Why Rules: If you put config in .env and let AI read it on its own, it won't always do so proactively.” points out that AI has lowered the bar for making something usable. The skill readers need is noticing what is wrong and turning that feeling into an actionable requirement.
Watch the user's next action, not just the surface
Turn “When a Chinese IME (input method editor) confirms a candidate word, it triggers Enter.” into observable questions: does the user know what happened, what to do next, and how to recover from an empty or failed state? Does the hierarchy make the important information visible first?
- isComposing is true : IME is still composing — Enter only confirms the candidate, it does not trigger send
- isComposing is false : direct keyboard input — Enter sends normally
- Rule text: never check only e.key === 'Enter' without also checking isComposing
Pretty is not the same as usable
Apply “Deliverable: the environment configuration section of your Rule.” to a second screen or flow. Record one moment of hesitation and the user action after the change; observable behavior is stronger evidence than polish alone.
From “Interactive Demo 1 · isComposing — Try It with an IME” to “Interactive Exercise 2 · Which Format Fits This Scenario”
“Interactive Demo 1 · isComposing — Try It with an IME” grounds the problem in “When a Chinese IME (input method editor) confirms a candidate word, it triggers Enter. An input field that only checks e.key === 'Enter' will send a half-composed message. Coverage of isComposing in AI training…”. “Interactive Exercise 2 · Which Format Fits This Scenario” then moves it toward “The data-format tripartite rule: three formats, each ruling its own domain — never mixed. Click a scenario, then pick the format you think is right”. Together, they show that the lesson is not just a conclusion to remember, but a claim with conditions.
Carry the judgment into the next situation
For experience work, turn abstract impressions into user actions: did the person understand the state, find the next step, recover from an error, and want to continue?
- “Interactive Demo 1 · isComposing — Try It with an IME”: When a Chinese IME (input method editor) confirms a candidate word, it triggers Enter. An input field that only checks e.key === 'Enter' will send a half-composed message. Coverage of isComposing in AI training…
- “Interactive Exercise 2 · Which Format Fits This Scenario”: The data-format tripartite rule: three formats, each ruling its own domain — never mixed. Click a scenario, then pick the format you think is right
- “The closing point”: Once decided, stop discussing alternatives — the AI's job is to write good code within the chosen stack
The final “The closing point” brings the discussion to “Once decided, stop discussing alternatives — the AI's job is to write good code within the chosen stack”. The useful thing to carry forward is knowing which judgments must be revisited when input, scale, or risk changes.
I turned one judgment from this article into a small experiment I could run today. Knowing what to observe next is more useful than simply remembering the conclusion.
After reading this, I first looked for the conditions behind the idea instead of copying the method into a project. That order made the later trade-offs much clearer.
When this judgment reaches real work, which constraint should be added first? I am curious which step matters most between reading and the first practical attempt.
No discussion on this article yet.