| name | om-implement-spec |
| description | Implement a specification (or specific phases) using coordinated subagents with unit tests, integration tests, docs, and code-review compliance. Tracks progress by updating the spec. Triggers on "implement spec", "implement phases", "build from spec", "code the spec". |
Implement Spec Skill
Implements a specification (or selected phases) end-to-end using a team of coordinated subagents. Every code change MUST pass the code-review checklist before the phase is considered done.
Pre-Flight
- Identify the spec: Locate the target spec file(s) in
.ai/specs/ or .ai/specs/enterprise/.
- Load context: Read spec fully. Read all AGENTS.md files listed in the Task Router that match the affected modules/packages.
- Load code-review checklist: Read
.ai/skills/om-code-review/references/review-checklist.md — this is the acceptance gate for every phase.
- Load lessons: Read
.ai/lessons.md for known pitfalls.
- Scope phases: If the user specifies phases (e.g. "phases e-h"), filter to only those. Otherwise implement all phases sequentially.
Extension Mode Decision (Mandatory First Step)
Before writing any code, ask the user:
Where should this feature live?
- External extension (npm package / standalone repo) — uses UMES extension points (widgets, events, enrichers, API interceptors) to add functionality without modifying Open Mercato core. Best for: custom business logic, vertical features, third-party integrations. Preserves upgrade path.
- Core modification (inside
packages/ or apps/mercato/) — directly modifies the platform. Best for: foundational platform capabilities that all users need.
If user chooses External Extension
- Determine if the user is working inside a
create-mercato-app scaffolded repo or wants a standalone npm package in packages/.
- Standalone npm package: Create package under
packages/<extension-name>/ with proper @open-mercato/<extension-name> naming and package.json.
- App-level module: Place code in
apps/mercato/src/modules/<module>/ (or the user's app repo).
- Maximize UMES features: Use widget injection, event subscribers, response enrichers, API interceptors, custom fields/entities, and menu injection to achieve the goal without touching core code.
- Never modify files in
packages/core/, packages/ui/, packages/shared/ etc. unless absolutely necessary for a missing extension point — and if so, the missing extension point itself becomes a prerequisite spec.
If user chooses Core Modification
Ask a confirmation:
Are you sure? Modifying core means:
- Third-party modules depending on changed surfaces may break
- Backward compatibility contract applies (13 frozen/stable categories)
- Users who forked or extended these files will have merge conflicts on upgrade
- Changes require deprecation protocol if touching any contract surface
Proceed with core modification?
Only continue with core changes after explicit confirmation.
Implementation Workflow
For each phase in the spec, execute these steps:
Step 1 — Plan the Phase
Read the phase from the spec. For each step within the phase:
- Identify files to create or modify
- Identify which AGENTS.md guides apply (use Task Router)
- Identify backward compatibility concerns (check
BACKWARD_COMPATIBILITY.md contract surfaces)
- List required exports, conventions, and patterns from the relevant AGENTS.md
- Note any cross-module impacts (events, extensions, widgets, enrichers)
Present a brief plan to the user before coding.
Step 2 — Implement
Use subagents liberally to parallelize independent work:
- One subagent per independent file/component when files don't depend on each other
- Sequential execution when there are dependencies (e.g., entity before API route before backend page)
For every piece of code, enforce these code-review rules inline:
| Area | Rule |
|---|
| Types | No any — use zod + z.infer |
| API routes | Export openApi and per-method metadata with requireAuth / requireFeatures (no top-level export const requireAuth) |
| CRUD APIs | Use makeCrudRoute({ entity, entityId, operations, schema, indexer: { entityType } }) from @open-mercato/shared/lib/crud/factory. Custom (non-makeCrudRoute) write routes MUST call validateCrudMutationGuard before the mutation and runCrudMutationGuardAfterSuccess after success. See packages/core/AGENTS.md → API Routes / CRUD Factory. |
| Entities | Standard columns, snake_case, UUID PKs, indexed organization_id + tenant_id |
| Security | findWithDecryption, tenant scoping, zod validation |
| Encryption maps | For every PII / GDPR-relevant column the phase touches, declare in <module>/encryption.ts exporting defaultEncryptionMaps (type from @open-mercato/shared/modules/encryption). Reads via findWithDecryption / findOneWithDecryption (5-arg (em, entity, where, options?, scope?)). Equality-lookup columns declare a sibling hashField. NEVER hand-rolled AES/KMS, crypto.subtle, or "encrypt later" stubs. See packages/core/AGENTS.md → Encryption + apps/docs/docs/user-guide/encryption.mdx. |
| UI | CrudForm/DataTable (with stable entityId + extensionTableId), apiCall (never raw fetch), flash(), LoadingMessage/ErrorMessage |
| Frontend performance boundaries | Implement the spec's Frontend Architecture Contract. Generated Next.js page.tsx/layout.tsx roots default to server components. Every "use client" needs a ledger justification. Split large client blobs into local leaves, lazy-scope provider/bootstrap registries, dynamically/local-import heavy browser libraries, and capture hydration/interactivity + performance evidence before merge. Run yarn check:client-boundaries for generated frontend/app shell changes. |
| Design System | Semantic status tokens (no text-red-* / bg-green-*); Tailwind text scale (no text-[13px] / text-[11px]); shared primitives StatusBadge / Alert / FormField / SectionHeader / CollapsibleSection / LoadingMessage / Spinner / DataLoader / EmptyState; lucide-react icons in PAGE BODY (never inline <svg>); aria-label on every icon-only button; Boy Scout rule on touched lines. See root AGENTS.md → Design System Rules + .ai/ds-rules.md + .ai/ui-components.md. |
| Cache | Resolve via DI (container.resolve('cache')); tag with tenant:<id> / org:<id>; declare invalidation per write path. NEVER new Redis(...) or raw SQLite. See packages/cache/AGENTS.md. |
| Transaction safety | Multi-phase scalar + relation mutations use withAtomicFlush(em, phases, { transaction: true }) from @open-mercato/shared/lib/commands/flush; never run em.find/em.findOne between a scalar mutation and em.flush(). Side effects + cache invalidation fire AFTER commit, outside withAtomicFlush. See packages/core/AGENTS.md → Entity Update Safety. |
| Commands | registerCommand, undoable, extractUndoPayload() |
| Events | createModuleEvents() with as const; subscribers export metadata; cross-module side effects via subscribers, never direct imports |
| i18n | useT() client, resolveTranslations() server, no hardcoded strings |
| Imports | Package-level @open-mercato/<pkg>/... for cross-module |
| Mutations | useGuardedMutation when not using CrudForm; pass retryLastMutation in injection context |
| Keyboard | Cmd/Ctrl+Enter submit, Escape cancel on dialogs |
| Naming | Modules plural snake_case, events module.entity.past_tense, features module.action |
Step 3 — Unit Tests
For every new feature/function implemented in the phase:
- Create unit tests colocated with the source (e.g.,
*.test.ts or __tests__/)
- Test happy path + key edge cases
- Test error paths for validation and authorization
- Mock external dependencies (DI services, data engine)
- Verify tests pass:
yarn test --filter <module>
Step 4 — Integration Tests
If the spec defines integration test scenarios (or the phase adds API endpoints / UI flows):
- Follow the
om-integration-tests skill workflow (.ai/skills/om-integration-tests/SKILL.md)
- Place tests in
<module>/__integration__/TC-{CATEGORY}-{XXX}.spec.ts
- Tests MUST be self-contained: create fixtures in setup, clean up in teardown
- Tests MUST NOT rely on seeded/demo data
- Run and verify:
npx playwright test --config .ai/qa/tests/playwright.config.ts <path> --retries=0
If the spec does not explicitly list integration scenarios but the phase adds significant API or UI behavior, propose test scenarios to the user before writing them.
Step 5 — Documentation
For each new feature:
- Add/update locale files for new i18n keys
- If new entities with user-facing text: create
translations.ts
- If new convention files: run
yarn generate
- Update relevant AGENTS.md if the feature introduces new patterns developers should follow
Step 6 — Self-Review (Code-Review Gate)
Before marking a phase complete, run a self-review against the full checklist:
- Architecture & Module Independence (checklist section 1)
- Security & Authentication (section 2)
- Data Integrity & ORM (section 3)
- API Routes (section 4) — if applicable
- Events (section 5) — if applicable
- Commands & Undo/Redo (section 6) — if applicable
- Search (section 7) — if applicable
- Cache (section 8) — if applicable
- Queue & Workers (section 9) — if applicable
- Module Setup (section 10) — if applicable
- Custom Fields (section 11) — if applicable
- UI & Backend Pages (section 12) — if applicable
- For generated/frontend pages, confirm the Frontend Architecture Contract was implemented: page roots stay server-first, every
"use client" is justified, no large client-side blob was introduced, provider/bootstrap registries are scoped, hydration/interactivity tests cover changed routes, performance evidence is attached, and yarn check:client-boundaries was run or explicitly waived.
- i18n (section 13)
- Naming (section 14)
- Code Quality (section 15)
- Notifications (section 16) — if applicable
- Widget Injection (section 17) — if applicable
- Testing Coverage (section 20)
- Backward Compatibility (section 21) — always
Fix any violations before proceeding to the next phase.
Step 7 — Update Spec with Progress
After completing each phase, update the spec file:
- Add an
## Implementation Status section at the bottom (or update it if it exists)
- Use this format:
## Implementation Status
| Phase | Status | Date | Notes |
|-------|--------|------|-------|
| Phase A — Foundation | Done | 2026-02-20 | All steps implemented, tests passing |
| Phase B — Menu Injection | Done | 2026-02-21 | 3/3 steps complete |
| Phase C — Events Bridge | In Progress | 2026-02-22 | Step 1-2 done, step 3 pending |
| Phase D — Enrichers | Not Started | — | — |
- For the current phase, mark individual steps:
### Phase C — Detailed Progress
- [x] Step 1: Create event definitions
- [x] Step 2: Implement SSE bridge
- [ ] Step 3: Add client-side hooks
Step 8 — Verification
After all targeted phases are complete:
- Build check:
yarn build:packages — must pass
- Lint check:
yarn lint — must pass
- Unit test check:
yarn test — must pass
- Integration test check: run any new integration tests — must pass
- Module prepare:
yarn generate — if any convention files changed
- Migration check:
yarn db:generate — if any entities changed (verify generated migration is scoped correctly)
Report results to the user. If any check fails, fix and re-verify.
Subagent Strategy
| Task | Agent Type | When |
|---|
| Research existing patterns | Explore | Before implementing unfamiliar patterns |
| Implement independent files | Bash/general-purpose | When files have no dependencies on each other |
| Run tests | Bash | After each phase |
| Self-review | general-purpose | After each phase, against checklist |
| Integration tests | general-purpose | After phases with API/UI changes |
Concurrency rule: Launch parallel subagents only for truly independent work. Sequential for dependent files.
Component Replaceability
When implementing component replacement features (as in SPEC-041h pattern):
- Every page-level component gets a unique replacement handle (auto-generated from module + path)
- Every
DataTable instance gets a replacement handle: data-table:<module>.<entity>
- Every
CrudForm instance gets a replacement handle: crud-form:<module>.<entity>
- Every named section (e.g.,
NotesSection, ActivitySection) gets a replacement handle: section:<module>.<sectionName>
- Document all handles in the module's AGENTS.md or a dedicated reference
Rules
- MUST read the full spec before starting implementation
- MUST read all relevant AGENTS.md files before coding
- MUST ask the Extension Mode Decision question before writing any code
- MUST prefer UMES extension points over core modifications when extension mode is chosen
- MUST pass every applicable code-review checklist item before marking a phase done
- MUST update the spec with implementation progress after each phase
- MUST run
yarn build:packages after final phase to verify no build breaks
- MUST create unit tests for all new behavioral code
- MUST create or propose integration tests for phases with API endpoints or UI flows
- MUST NOT skip the self-review step — it is the quality gate
- MUST NOT introduce
any types, hardcoded strings, raw fetch, or other anti-patterns
- MUST follow backward compatibility rules — no breaking changes without deprecation protocol
- MUST keep subagents focused — one task per subagent, clear boundaries
- MUST report blockers to the user immediately rather than working around them silently