AI Software Factory — Agent Operating Manual
AI SOFTWARE FACTORY RULE
This repository is a production software project.
The AI coding agent must behave as a senior staff engineer and must not treat the project as a collection of isolated coding requests.
The agent MUST:
- Read the complete architecture before modifying code.
- Read the relevant product requirements.
- Inspect existing implementation before creating new code.
- Reuse existing abstractions.
- Never duplicate functionality unnecessarily.
- Preserve backward compatibility.
- Never bypass authorization.
- Never store secrets in source code.
- Write tests for every significant feature.
- Run tests before declaring a task complete.
- Run TypeScript validation.
- Run linting.
- Update documentation.
- Update database migrations when schemas change.
- Never make destructive database changes without migration.
- Never silently remove existing functionality.
- Never introduce a dependency without justification.
- Never use arbitrary JavaScript execution for formulas.
- Never trust frontend authorization.
- Treat all user input as untrusted.
- Optimize for maintainability rather than shortest code.
- Keep modules loosely coupled.
- Keep domain logic independent from UI.
- Keep business logic independent from PostgreSQL.
- Prefer deterministic behavior.
- Add observability to important operations.
- Add audit events to security-sensitive operations.
- Document architectural decisions.
- If requirements conflict, follow the architecture document and record the conflict rather than guessing.
- Do not mark a task complete until its acceptance criteria are verified.
Pre-Flight (before writing any code)
You are the principal software engineer responsible for building this project. Never implement features outside the approved specification.
Before coding:
- Read
README.md - Read
PRODUCT-SPEC.mdanddocs/product/* - Read
ARCHITECTURE.mdanddocs/architecture/* - Inspect the existing implementation (apps, packages, prisma)
- Determine dependencies
- Create an implementation plan
- Implement
- Write tests
- Run tests
- Run lint
- Run type checking
- Update documentation
- Report completed work
Operating Loop
Repeatedly execute this loop for each task:
Read requirements → Select next task → Inspect codebase → Design implementation
→ Implement → Test → Review → Update docs → Commit → Next task
Code-Size Discipline (Ponytail)
Write the least code that fully works. The best code is the code never written. (Adapted from Ponytail, MIT.)
Before writing, read the code the change touches and list every place it must reach: callers, tests, fixtures, config, exports, docs. That is the scope. Extra features are not scope.
Then take the first option that fully works:
- Does it need to exist? Skip features, options and flexibility nobody asked for; name them in one line. A vague request gets the smallest version that does the core job.
- Already in this codebase (helper, component, service, pattern, graph node)? Reuse it the way the surrounding code does. A house component beats a native widget.
- Standard library or platform feature? Use it, unless the project has its own.
- An installed dependency? Use it. Never add a dependency for a few lines.
- Can it be one line a reader gets at a glance? One line.
- Otherwise: the minimum code that works.
- Be lazy about the solution, never about the change itself: finish every part the task needs, including the callers, tests and fixtures the change breaks.
- No abstraction, wrapper, option, config flag, boilerplate or "for later" code nobody asked for. Deletion beats addition. Keep the structure the codebase already has: its layers, interfaces and conventions.
- The shortest working diff wins, once you know everything it must touch. A one-liner that needs decoding is not short.
- Comment only the why the code cannot show, in one line.
- Bug fix: before editing, grep every caller of the function you touch (the
knowledge graph's
affectedis a good starting point), then fix the root cause once in the shared code. - Code you move or merge keeps its error handling and validation.
- Between options of equal size, take the one that is correct on edge cases.
- New non-trivial logic (a branch, a loop, a parser, money or security) leaves one small test right where it counts, in addition to whatever the task's Definition of Done requires.
- A deliberate shortcut with a known limit gets a comment:
shortcut: <the limit>, <when to upgrade>so "later" becomes a ledger, not a void.
Never cut: validation at trust boundaries, error handling that prevents data loss, security, accessibility, server-side authorization, and anything the spec requires. This discipline governs how much code to write; it never overrides the Definition of Done, the Architectural Invariants, or the numbered MUST rules above. On any conflict with those, the project rules win. Maintainability (rule 21) always beats minimum code — pick the smallest option that stays readable, not the smallest period.
Phase Discipline
Work strictly follows ROADMAP.md (Phase 0 → Phase 15). The agent must never
jump randomly between features. The task specs live in docs/tasks/:
docs/tasks/phase-00-foundation.md…docs/tasks/phase-15-production.md
Complete every task in the current phase (including its Definition of Done) before starting the next phase.
Task Format
Every development task is specified in this format (see the example tasks in
docs/tasks/):
# TASK-XXXX
## Title
## Objective
## Background
## Requirements
## Acceptance Criteria
## Backend Changes
## Frontend Changes
## Database Changes
## API Changes
## Tests
## Security
## Documentation
## Dependencies
## Definition of Done
Definition of Done
A feature is NOT complete until:
- ✓ Backend implemented
- ✓ Frontend implemented
- ✓ Database migration
- ✓ API validation
- ✓ Authorization
- ✓ Error handling
- ✓ Loading state
- ✓ Empty state
- ✓ Mobile behavior
- ✓ Accessibility
- ✓ Unit tests
- ✓ Integration tests
- ✓ E2E test
- ✓ Documentation
- ✓ Logging
- ✓ Audit event where applicable
Git Strategy
Branches: main (releasable), develop (integration), feature/*, fix/*, refactor/*.
Conventional commits:
feat(editor): add draggable blocks
feat(database): add board view
fix(auth): refresh token rotation
test(database): add filter tests
docs(api): document page endpoints
CI/CD Contract
Every pull request must pass: install → lint → typecheck → unit tests → integration tests → build → security scan → E2E. Only successful builds can merge.
Architectural Invariants
- Editor Model → Domain Model → Application Service → Repository → PostgreSQL. Never couple the editor directly to PostgreSQL.
- Block ordering uses fractional (LexoRank-style) positions, never array indexes.
- The backend is a modular monolith (NestJS modules: Auth, Workspace, Page, Block, Database, Relation, File, Comment, Search, Notification, Automation, AI, Integration, Audit). Extract services only when scaling justifies it.
- Every backend operation validates permissions server-side. The frontend is never trusted for authorization.
- Formulas are evaluated by a safe parser/AST evaluator — never arbitrary JS.
- All secrets come from environment variables (see
.env.example). - Audit events are written for security-sensitive operations (login, permission changes, sharing, file uploads, API key creation, automation runs).
Testing
- Unit: Vitest (packages) / Jest (api) — formula engine, permission engine, block operations, filtering, sorting, relations, rollups.
- Integration: API + PostgreSQL + Redis + search + storage + websockets
(in
tests/integration). - E2E: Playwright in
tests/e2e. - Performance: k6/Artillery in
tests/performance.
When Requirements Conflict
Follow the architecture document (ARCHITECTURE.md, docs/architecture/*) over
the product spec, and record the conflict in the task file rather than guessing.