Imported from Tom-Wang898/memory-runtime (
AGENTS.md). Install upstream withnpx skills add Tom-Wang898/memory-runtime. Copyright stays with the author.
Managed Project Rules Overlay
- Host:
codex - Profile:
monorepo-lite - Project root:
<repo-root> - Languages:
typescript - Frameworks:
none - Sources:
upstream:base/core.mdupstream:base/git.mdupstream:languages/typescript.mdlocal:local-rules/base/codex-workflow.mdlocal:local-rules/base/verification-discipline.mdlocal:local-rules/profiles/monorepo-lite.md
Core Development Principles
Attitude Toward Legacy Code
This is the most important rule: Do not mimic the style and patterns of existing code in the project. Always follow this specification.
- When modifying old code, refactor the parts you touch according to this specification. Do not perpetuate bad habits for the sake of "consistency"
- If old code has obvious design problems (God Class, deep nesting, hardcoding, excessive coupling), fix them while making changes
- Do not be afraid to change the structure of old code, as long as behavior remains unchanged
- If the refactoring scope is too large (cascading changes across more than 3 files), explain the plan before proceeding
Hard Requirements for Code Quality
- A single function must not exceed 30 lines (excluding blank lines and comments); split if it does
- A single file must not exceed 300 lines; split by responsibility if it does
- Nesting depth must not exceed 3 levels (if/for/callback); reduce with early returns, extracted functions, etc.
- Function parameters must not exceed 4; use an object parameter if more are needed
- No commented-out code allowed; delete unused code instead of commenting it out
- No magic numbers or magic strings; extract them into named constants
Naming
- Names must be semantic; the purpose should be clear from the name alone
- No meaningless names:
data1,temp,info,obj,result,item(except loop variables) - Boolean values use
is/has/can/shouldprefixes:isLoading,hasPermission - Function names start with a verb:
fetchUser,validateInput,calculateTotal - Constants in ALL_CAPS_SNAKE_CASE:
MAX_RETRY_COUNT,API_BASE_URL - Event handler functions use
handleprefix:handleClick,handleSubmit
Architecture Principles
- Single Responsibility: One function does one thing, one file owns one domain
- Separation of Concerns: UI contains no business logic, business logic contains no UI code, data access is a separate layer
- Unidirectional Dependencies: Upper layers depend on lower layers, never the reverse. UI -> Business Logic -> Data Layer
- Program to Interfaces: Modules communicate through interfaces/protocols, not concrete implementations
- Composition Over Inheritance: Use composition unless there is a clear is-a relationship
Error Handling
- Perform defensive validation only at system boundaries (user input, external API responses, file I/O)
- Internal function calls trust parameter types; no redundant validation
- Error messages should be human-friendly and include context (which operation failed, what values were passed)
- Async operations must have error handling; no bare Promises or unhandled async calls
- Do not wrap the entire function body in try-catch; only wrap the specific operations that may fail
Avoid Over-Engineering
- Solve only the current problem; do not add abstractions for hypothetical future requirements
- Three lines of duplicated code are better than a premature abstraction
- Do not create utility functions for logic that is used only once
- Do not add unnecessary intermediate layers, wrappers, or adapters
- Add configuration and options only when flexibility is genuinely needed
Git Conventions
Commit Rules
- Do not commit code automatically unless explicitly requested
- Ensure the code runs correctly before committing
Commit Message Format
<type>(<scope>): <subject>
A space follows the colon. Type values:
| type | Purpose |
|---|---|
| feat | New feature |
| fix | Bug fix |
| docs | Documentation or comments |
| style | Code formatting (no runtime impact) |
| refactor | Refactoring (not a new feature or bug fix) |
| perf | Performance optimization |
| test | Adding tests |
| chore | Build process or tooling changes |
Use a list when there are more than two key points:
feat(web): implement email verification workflow
- Add email verification token generation service
- Create verification email template with dynamic links
- Add API endpoint for token validation
TypeScript Guidelines
Type System
- No
any. Useunknownwhen the type is uncertain, then narrow with type guards - Use
interfacefor object shapes; usetypefor unions / intersections / mapped types - Public functions must have explicit return types; internal functions may rely on inference
- Mark properties and parameters that won't be mutated with
readonly - Leverage built-in utility types:
Partial<T>,Pick<T, K>,Omit<T, K>,Record<K, V> - Generic parameter names should be meaningful:
TItemrather than bareT(single generic parameter excepted)
// 禁止
function parse(data: any): any { ... }
// 正确
function parse(data: unknown): ParseResult { ... }
Naming
- Types and interfaces:
PascalCase(UserProfile,ApiResponse) - Variables and functions:
camelCase(getUserById,isValid) - Constants:
UPPER_CASE(MAX_RETRY_COUNT) - Enum members:
PascalCase(Status.Active) - Generic parameters: single uppercase letter or
Tprefix (T,TKey,TValue)
Module Organization
- One primary export per file (a component, a class, or a group of closely related functions)
- Place type definitions at the top of the file that uses them; shared cross-file types go in a
types/directory - Do not use
index.tsbarrel exports -- they cause circular dependencies and tree-shaking issues; import directly from source files - Separate
import typefrom value imports
import type { UserProfile } from './types/user'
import { formatDate } from './utils/date'
Functions
- Prefer arrow functions; use
functiononly whenthisbinding is needed - Prefer
async/await; do not chain more than 2 levels of.then() - Handle errors with specific types; do not
catch(e: any)
// 禁止
fetchData().then(res => process(res)).then(data => save(data)).catch(e => console.log(e))
// 正确
try {
const res = await fetchData()
const data = process(res)
await save(data)
} catch (error) {
if (error instanceof NetworkError) {
showNetworkError(error.message)
}
throw error
}
Prohibited Patterns
- No
// @ts-ignoreor// @ts-expect-error(unless accompanied by a comment explaining why) - No
astype assertions (unless narrowing fromunknownwith good reason) - No
!non-null assertions (use optional chaining?.or early null checks instead) - No
enum(useas constobjects or union types instead to avoid runtime overhead)
// 禁止
enum Status { Active, Inactive }
// 正确
const Status = { Active: 'active', Inactive: 'inactive' } as const
type Status = typeof Status[keyof typeof Status]
Codex Workflow Overlay
Context First
- Read the current repository structure, config, and existing patterns before editing
- Reuse local implementations when they are good enough; do not create a second pattern for the same job
- Search with fast local tools first (
rg, targeted scripts, existing tests) before reaching for external docs
Host Compatibility
- Do not assume Claude-specific plugin commands, environment variables, or marketplace features exist
- Do not reference host-only tools such as
TodoWrite,Skill tool,Read,Glob,Grep, orWebFetch - Use the current host's native file, shell, browser, and search tools instead of inventing abstract pseudo-tools
Project Discipline
- Prefer small, reversible changes over broad rewrites
- If a rule conflicts with the project's real stack, follow the stack and remove the conflicting rule in the next refresh
- Keep project instructions specific to the detected stack; avoid generic boilerplate that does not change behavior
Verification Discipline Overlay
Proof Before Claim
- Run the smallest meaningful verification after changes: targeted tests, lint, typecheck, build, or a focused smoke command
- If verification cannot be run, say exactly what is missing instead of claiming success
- Do not say a fix is complete until there is fresh evidence from the current project state
Failure Handling
- Surface exact failing commands, logs, or pages instead of vague summaries
- If the stack detection is ambiguous, present the ambiguity and ask for confirmation before writing project rules
- When updating an existing instruction file, replace only the managed overlay block and preserve all manual sections
Monorepo Lite Profile Overlay
Boundary Discipline
- Be explicit about package boundaries and ownership; do not hide cross-package coupling behind convenience imports
- Shared code should stay genuinely shared; app-specific logic belongs in the app package that owns it
- When touching multiple packages, verify the contract at the boundary instead of assuming workspace-wide consistency