Scenario-driven answers to common questions practitioners have when adopting and using Lattice. Each answer is self-contained and brief.
- Getting Started
- Requirements
- Architecture
- Language
- Customization
- Workflow
- Codebase Transformation
- Domain-Driven Design
- Team Usage
- The Learning Flywheel
- Troubleshooting
Run /lattice-init. It scans your project, creates .lattice/config.yaml, and tells you which refiners to run based on what it finds. After that, run the suggested refiners (starting with /knowledge-priming-refiner, then /language-idioms-refiner) to give Lattice context about your project and language. Once done, you're ready to use any molecule.
No. Lattice works for brownfield codebases too. Run /lattice-init to scan the repo and set up .lattice/ around what you already have. Use /refactor-safely, /bug-fix, and /review for incremental improvement without rewriting everything. Run /architecture-refiner to give Lattice explicit ground rules for whatever architecture you actually follow — it writes .lattice/standards/architecture.md so the architecture atom enforces your structure, not a generic default.
Molecules work, but results will be generic. Without /knowledge-priming-refiner, Lattice has no awareness of your project — it can't tailor generated code to your stack or conventions. Without /language-idioms-refiner, atoms use pseudocode defaults which assume OOP + exceptions — problematic for Go, Rust, or functional languages. The other refiners (architecture, clean code, DDD, review) have solid embedded defaults, so skipping those is fine initially. But /knowledge-priming-refiner and /language-idioms-refiner are strongly recommended.
The .lattice/ folder is Lattice's living context layer. It holds config.yaml (your settings), standards/ (refiner outputs like architecture and coding rules), requirements/ (epic and feature specs produced by requirement-forge), context/ (per-feature living documents capturing decisions and blueprints), reviews/ (review log), and learnings/ (operational learnings accumulated across design, implementation, review, and bug-fix sessions). Commit it — it's the shared source of truth for your team's standards and accumulates value over time. requirements/ is the one exception worth calling out: it's optional and pluggable — teams that already track requirements in an external system (Jira, Linear, etc.) can skip it entirely and point design-blueprint at an external reference instead. Commit it only if you're using it.
Use /requirement-forge when the feature scope, problem statement, or acceptance criteria are not yet clearly defined — it acts as a senior PM + BA pair that challenges assumptions, structures epics and features, and produces specs complete enough for design-blueprint to consume without further interviews. Go straight to /design-blueprint when the feature is already well-understood and you only need to make technical design decisions. When in doubt, run requirement-forge first — a well-specced feature produces a sharper blueprint.
Three artifacts in .lattice/requirements/: a thin index.md apex file (definitions, glossary, and a generated list of epics), one epics/{epic-slug}.md per epic (hand-authored header plus a generated feature table listing name and summary), and per-feature files in features/ — each carrying its own status, priority, and depends_on frontmatter, which is never mirrored into the rollups. Each feature file contains a problem statement, user/personas, scope (in-scope and out-of-scope), boundary conditions, assumptions, ordered scenarios (each with acceptance criteria), implementation notes, and open questions. If source documents were provided during intake, the relevant epic file also includes a Source Materials table (tracing which documents produced which features) and a Deferred Items section (content intentionally excluded from the current feature set). The feature file is the direct input to design-blueprint.
A scenario is a bounded situation the feature must handle — not a user story, not an acceptance criterion. A feature is broken into 2–5 scenarios; each scenario has 3–6 Given/When/Then acceptance criteria. Scenarios are ordered chronologically — the natural implementation sequence. This two-level structure prevents both scenario sprawl (too many ACs on a flat feature) and story fragmentation (too many fine-grained stories disconnected from the feature).
No — requirement-forge works with built-in defaults out of the box. When no standards document is found, the molecule tells you the active defaults (Given/When/Then ACs, P0/P1/P2 priority, max 5 scenarios per feature, max 6 ACs per scenario, standard status workflow) so you know what will govern the session. Run /requirement-forge-refiner when you want to tailor these to your team — custom AC format, alternative nomenclature (e.g., "use case" instead of "scenario"), different priority notation, or an extended status workflow. It is a one-time setup.
The molecule opens by asking whether you have existing material before assuming a blank slate. Provide file paths, paste text, or describe where documents live. It reads everything silently and runs a structured triage: classifies each document by type (product requirements, technical design, stakeholder wishlist, marketing — only product requirements and wishlists feed the pipeline), identifies overlaps between documents (same capability described differently), surfaces contradictions for your resolution, checks granularity (ACs mistaken for features, or broad epics mistaken for features), identifies gaps (implied behaviors never explicitly stated), and flags orphaned content (material that doesn't map to any feature — collected for the relevant epic's Deferred Items section). It then presents a structured hypothesis with proposed epics and features. You confirm or correct before anything is written.
The molecule's first action is always to scan .lattice/requirements/ for existing work. It classifies each feature file as complete, structurally incomplete (missing sections), or quality-suspect (present but with a spec quality issue flagged by the requirement-quality atom). It surfaces each issue one by one and asks whether to finish it, move on, or skip — no blanket restart. When you're done resolving incomplete features, it offers explicit re-entry points: add features to an existing epic, create a new epic, or update a specific spec.
I only want to spec one feature, not design a whole product. Does requirement-forge force me through a full epic structure?
No. If your description or documents reveal only 1–3 features, the molecule offers a single-feature fast path: spec the feature directly, then create a placeholder epics/{epic-slug}.md plus a thin index.md pointing to it, so the structure is in place for later expansion. You are not forced to define a complete epic before speccing a single feature.
Each feature file has a Links: Design field that design-blueprint writes the first time it resolves that feature's requirement doc in Step 1 — on either a new design session or a resumed one. The design-blueprint molecule's context-anchoring step accepts a "requirement doc link" pointing to the feature file — it loads the problem statement and scope as starting context for the design session. The two molecules complement each other: requirement-forge defines WHAT and WHY; design-blueprint defines HOW.
Collaborative mode (default) pauses for confirmation at every phase — epic list, feature list per epic, feature frame, and each scenario. The molecule proposes and you approve or correct before advancing. Autonomous mode runs all phases silently, drafts everything, then presents the complete output for review. Use collaborative when you want to shape the spec interactively; use autonomous when you want a draft quickly and prefer to review and edit in one pass. Autonomous mode pauses only for genuine blockers — contradictions with no reasonable resolution, missing domain knowledge, or scope so ambiguous that two valid structures exist.
"Users" is too vague for good specs. Different user types produce different acceptance criteria — what an admin sees on login is not what a buyer sees. The molecule pushes for specific roles (buyer, seller, admin, guest) so each scenario's ACs are verifiable for a concrete user type. If a feature genuinely serves all user types identically, state that explicitly — the persona section still forces you to confirm it rather than silently assume.
Feature files include an explicit Assumptions section — statements the team proceeds with as true without full validation. The requirement-quality atom checks for hidden assumptions (preconditions buried in ACs without being documented) and treats them as an anti-pattern. When an assumption reads like it could be a requirement ("users will have verified emails" — is that an assumption or a feature to build?), the atom flags it as an ambiguity signal for you to decide.
It goes into the relevant epic's Deferred Items section — intentionally excluded content with reasons for deferral. Nothing disappears silently. Marketing copy, competitive positioning, out-of-scope ideas, and deferred feature suggestions are all tracked so stakeholders can verify that everything from the source material was either mapped to a feature or consciously set aside.
Yes. The atom works standalone — it does not require the molecule. Point it at any feature spec file and it runs the 11-item self-validation checklist (problem statement, scope, personas, assumptions, scenarios, ACs, independence, etc.) and the 15-item anti-pattern scan. It will flag issues like vague problem statements, missing failure scenarios, persona-less specs, hidden assumptions, and wrong granularity. Use it as a quality gate before handing any spec to design-blueprint.
No. Clean architecture is the default — atoms enforce it out of the box with no config needed. Optionally run /architecture-refiner to customize specific rules (e.g., disable the Provider pattern, adjust layer naming) and write them to .lattice/standards/architecture.md.
I use clean architecture but want to customize a few rules (e.g., we don't use the Provider pattern).
Run /architecture-refiner. It interviews you about your specific rules and writes .lattice/standards/architecture.md in overlay mode by default — your customizations apply on top of clean architecture defaults, so you only need to document what differs.
Run /architecture-refiner and select hexagonal / ports & adapters when prompted. It sets architecture_mode: custom in .lattice/config.yaml and writes .lattice/standards/architecture.md — an enriched document where you capture port/adapter boundaries, inbound/outbound rules, allowed dependency directions, anti-patterns, naming conventions, and any other constraints your team follows. The richer the document, the more precisely the architecture atom enforces your structure.
Yes. Run /architecture-refiner and describe your modular monolith structure. It sets architecture_mode: custom and produces .lattice/standards/architecture.md where you document your slice boundaries, module contracts, shared kernel rules, and any cross-slice constraints. The architecture atom enforces exactly what you define.
We don't follow any named architecture pattern — we have our own layer structure. Can Lattice enforce it?
Yes. Run /architecture-refiner and describe your layers, their responsibilities, and the rules between them. It sets architecture_mode: custom and writes .lattice/standards/architecture.md — Lattice has no requirement for a named pattern. The more precisely you describe your rules, the more precisely the atom enforces them.
architecture_mode tells the architecture atom which rulebook to use: clean (default) uses embedded clean architecture enforcement; custom uses only your .lattice/standards/architecture.md. You only need to set it when you're not using clean architecture — /architecture-refiner sets it automatically when you select a non-clean style.
Re-run /architecture-refiner and select hexagonal when prompted. It updates architecture_mode: custom in .lattice/config.yaml and rewrites .lattice/standards/architecture.md with your new structure. Your old clean architecture document is replaced.
Run /language-idioms-refiner. It detects your language, proposes idiomatic patterns (error handling, type system, naming, testing, DI), and asks you to confirm or adjust. The output goes to .lattice/standards/language-idioms.md and is consumed by multiple atoms — clean-code, test-quality, secure-coding, DDD, and architecture all reference specific sections to adapt their pseudocode defaults to your language. /lattice-init auto-suggests this as priority #2 after knowledge-priming.
We use Java/TypeScript. The defaults already seem fine. Do we still need the language-idioms document?
Recommended but not critical. The embedded defaults have an OOP + exception-based style that aligns well with Java, Kotlin, TypeScript, and C#. The language-idioms document still adds value — it captures your specific conventions (test framework, DI approach, naming patterns) — but the gap is smaller than for Go or Rust where the defaults actively conflict.
Knowledge-priming answers "what is this project?" — tech stack, directory layout, trusted docs, conventions. Language idioms answers "how does this language express patterns?" — error handling philosophy, type system, naming rules, testing idioms, DI approach. Knowledge-priming says "we use Go 1.22 with Chi router." Language idioms says "Go uses error returns not exceptions, interfaces at consumer not provider, table-driven tests."
Language idioms describes how the language works — language-level facts. A clean-code overlay describes how your team works within the language — team-level preferences. Language idioms: "Go uses error returns." Clean-code overlay: "We use fmt.Errorf('context: %w', err) for wrapping and custom error types for domain errors." They're complementary, not overlapping.
One language-idioms document per project, covering the primary language. /lattice-init detects multiple languages and asks which is primary. If both languages are equally important, create the document for whichever language you use Lattice with most (typically the backend). The other language still gets reasonable behavior from the pseudocode defaults.
You're missing the language-idioms document. Run /language-idioms-refiner — it proposes Go-idiomatic patterns including error returns, if err != nil, and error wrapping. The clean-code atom reads the "Error Handling" section and adapts §8 accordingly. Without it, atoms fall back to pseudocode defaults which assume exceptions.
Run the corresponding refiner (e.g., /clean-code-refiner, /architecture-refiner) — it interviews you and writes a standards document to .lattice/standards/ that the atom picks up. If no refiner exists for what you need, add your rules directly to .lattice/standards/knowledge-base.md; the knowledge-priming atom loads it into every workflow.
Overlay (default) applies your standards document on top of embedded defaults — only sections you define replace the corresponding defaults; everything else stays. Override fully replaces the defaults with your document — atoms enforce only what you wrote. Use overlay when you want to tweak a few rules; use override when you manage the full standard yourself.
No. Edit .lattice/standards/architecture.md directly — it's a plain markdown file. Update the section you want to change and save. The atom picks it up on the next invocation. Re-run /architecture-refiner only if you want a guided interview to rebuild the document from scratch.
Yes. Create the file directly under .lattice/standards/ (e.g., architecture.md) and point to it in .lattice/config.yaml via the relevant paths key. The refiner is just a guided way to produce the same file — the atom only cares about the document, not how it was created.
Add them to .lattice/standards/knowledge-base.md. The knowledge-priming atom loads this document into every workflow, so any rule, convention, or constraint you put there is available to all atoms and molecules. You can edit it directly or use /knowledge-priming-refiner to build it via a guided interview.
Use /design-blueprint when the feature involves real design decisions — new components, cross-layer interactions, API contracts, or anything where getting the structure wrong is costly to fix. Go straight to /code-forge for small, well-understood changes where the design is already clear. When in doubt, blueprint first — it takes minutes and prevents larger refactors later. If the feature itself is not yet well-defined, start with /requirement-forge before /design-blueprint.
/refactor-safely requires agreement on the target structure before touching code, then uses characterization tests as a safety net to ensure externally observable behavior doesn't change. Refactoring directly skips both — no upfront structural agreement and no enforced regression protection. Use /refactor-safely when the change is non-trivial or the code lacks test coverage.
/bug-fix enforces the right thought process: RCA first, reproduce with a failing test, then fix. It prevents jumping straight to a patch without understanding the cause. That said, it's a judgment call — for obvious, contained bugs you're confident about, fixing directly is fine. /bug-fix adds the most value when the root cause is unclear or the fix touches critical paths.
/review is delta-scoped and structured — it only reviews what changed, applies all relevant atoms (architecture, clean code, security, test quality) as enforcement lenses, and produces severity-ordered findings. A normal code review depends on the reviewer's knowledge and attention. /review ensures no atom's rules are silently skipped and captures recurring patterns as learnings to improve future code generation.
Inside-out means code-forge implements from the innermost layer outward: domain/core entities first, then use cases, then adapters/infrastructure, then the entry points (controllers, handlers). This order ensures outer layers always depend on already-implemented inner layers — matching the dependency direction defined in your architecture rules and preventing placeholder stubs from leaking into the final code.
Run /architecture-compass. It scans the repository, conducts a short targeted interview, then leads a collaborative session to agree on the current architectural state and a recommended direction. The output is .lattice/insights/architecture.md — an insights document capturing what was found, what was agreed, and what to do first. The first moves in the document guide which existing molecules to use next: /refactor-safely for moving existing code, /design-blueprint + /code-forge for introducing new structures.
A single document at .lattice/insights/architecture.md with: repository identity, why the team is doing this (from the interview), archaeology findings (dead code, duplicates, hidden coupling), domain map, current architecture with Mermaid diagram, recommended direction with diagram and annotated folder tree, gap assessment, and first moves (2–3 structural decisions with molecule guidance). Not a full execution plan — an orientation document.
Plan for one focused session of 2–3 hours. The scan and interview are fast. The two agreement rounds — current architecture and recommended direction — take longer than most teams expect. The current state agreement in particular surfaces things the team assumed were intentional but are actually drift, and vice versa. The gap assessment and first moves can be built in a follow-up session — reaching current + direction agreement is itself a complete and valuable output.
Only if you have a specific reason. The molecule is designed to propose the minimum viable direction — the simplest structure that resolves the stated pain. The test: can the team take the first move this week? A direction that only pays off after six months of work is wrong. Push for more complexity only when you have a concrete reason tied to the actual pain, not because simplicity feels unsatisfying.
The interview explicitly asks about previous failed attempts. That is the most important question in the session — previous failures reveal specific blockers (technical, organisational, or political) that will stall this attempt too unless the insights document accounts for them. Whatever stopped the last attempt needs to be named and addressed in the recommended direction before any work begins.
/refactor-safely operates at a bounded, specific scope — one module, one known structural problem. It assumes you already know what needs to change and why. /architecture-compass operates at the repository level — it helps the team agree on where the architecture is and what direction it should move. Use /architecture-compass when the team needs shared orientation. Use /refactor-safely when you have a specific, bounded improvement to make — including the first moves from an architecture-compass session.
Yes — and it will produce sharper output. If .lattice/standards/architecture.md exists (from /architecture-refiner), the molecule uses it as the audit lens and as input to the recommended direction. If .lattice/standards/knowledge-base.md exists, it loads it for codebase identity. If neither exists, it infers defaults from the scan and offers to run /lattice-init first.
The insights document says the recommended direction is the best current understanding. Does that mean it will change?
Yes, and that is expected. The direction is a hypothesis based on what is known at the time of the session. As first moves complete, the team learns things that refine the direction. Update the document when that happens — the session status table tracks what is agreed and when. A document framed as a living hypothesis gets updated and trusted. One framed as authoritative gets abandoned when reality diverges.
No. The molecule uses a strategic scanning protocol: directory tree, dependency manifests, architecture documents, import patterns via grep, entry points, interface files, and one representative file per top-level module — roughly 15–25 targeted reads total. Full method implementations, test files, generated code, and vendor directories are skipped. The scan extracts architectural signal, not completeness.
Yes. Run /ddd-refiner — it interviews you about your DDD usage and writes .lattice/standards/ddd-principles.md. You can limit enforcement to only the patterns your team uses (e.g., aggregates and value objects but not bounded contexts) and add project-specific rules on top of the defaults. For example: "all domain objects must be constructed via the builder pattern", "aggregates must never expose mutable collections", "value objects must be immutable and self-validating". The DDD atom enforces whatever you define alongside the embedded defaults.
Commit .lattice/ to version control. All standards documents, config, blueprints, and review insights live there — everyone on the team shares the same rules automatically. Refiners are run once (or as a team decision) and the outputs become the shared source of truth. Individual developers pull the latest .lattice/ and Lattice enforces the team's agreed standards, not personal defaults.
As a team, at least for the first time. Refiner outputs define what Lattice enforces for everyone — architecture rules, coding standards, DDD patterns. These are team decisions, not individual preferences. One person running a refiner and committing the output is fine mechanically, but the decisions inside should reflect team consensus. Re-runs to tweak rules follow the same principle.
Treat .lattice/standards/architecture.md like any other source file — resolve the conflict in version control. Review both versions as a team, agree on the rules, and merge into one canonical document. Going forward, architecture changes should go through the same review process as code changes to prevent divergence.
They pull the repo — .lattice/ is already there with all the team's standards, config, and review history. No refiner runs needed. They install Lattice into their AI tool, and it immediately enforces the team's agreed rules. The .lattice/ folder is the onboarding artifact.
/review captures two things: a review log (.lattice/reviews/review-log.md) for health tracking and trends, and operational learnings (.lattice/learnings/operational-learnings.md) for recurring cross-cutting patterns worth remembering. Operational learnings feed back into all molecules — when /code-forge, /design-blueprint, /bug-fix, or /refactor-safely runs next, it loads these patterns and uses them to avoid repeating past mistakes (e.g., if learnings flag "anemic domain models keep appearing," code-forge actively pushes behavior into entities from the start). All molecules both consume and contribute to operational learnings via the learning-harvest atom.
Check .lattice/reviews/review-log.md — it tracks findings per review (critical, warning, suggestion counts) and key patterns over time. If the same issues keep appearing, they'll surface in .lattice/learnings/operational-learnings.md as recurring patterns. Improvement shows up as fewer critical and warning findings per review cycle and fewer recurring entries in learnings.
/review handles this automatically — once the log exceeds ~20 entries, it moves the oldest entries into a one-line ## History summary section at the top of .lattice/reviews/review-log.md. For .lattice/learnings/operational-learnings.md, the learning-harvest atom self-assesses document health and proposes tightening when entries grow dense or overlap — consolidating duplicates, flagging noise, and suggesting promotion to standards. You can also edit the file manually.
Yes. Edit .lattice/learnings/operational-learnings.md directly and add a bullet under the appropriate category in the same format: - YYYY-MM-DD [context] Pattern — actionable takeaway. Keep it concise and actionable — the goal is a signal that helps future sessions avoid the same mistake, not a detailed incident report.
Run the corresponding refiner to produce a standards document for that atom — it replaces or overlays the embedded defaults. If no refiner exists for the atom, add your rules to .lattice/standards/knowledge-base.md. If you disagree with a specific check entirely, use override mode to take full control of what the atom enforces.
Check three things: first, that .lattice/standards/knowledge-base.md exists and describes your project's tech stack, conventions, and coding style — run /knowledge-priming-refiner if it doesn't. Second, check .lattice/standards/language-idioms.md — if it's missing and you use Go, Rust, Python, or another non-OOP language, atoms will use pseudocode defaults that assume exceptions and classes. Run /language-idioms-refiner to fix this. Third, check .lattice/standards/clean-code.md — if it's missing or generic, run /clean-code-refiner to capture your project-specific style.
Check three things: (1) .lattice/config.yaml has paths.architecture pointing to the correct file path; (2) the file actually exists at that path; (3) architecture_mode: custom is set — without it, the atom uses clean architecture defaults and ignores the custom document. If all three are correct, check that the document has a valid markdown structure with headings the atom can parse.