diff --git a/AGENTS.md b/AGENTS.md index 2c1ae2d..2f37e07 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,52 +1 @@ -# Lorah - -## Project Overview - -Lorah is a simple infinite-loop harness for long-running autonomous coding agents. It runs Claude Code CLI in a continuous loop, parsing stream-JSON output and formatting it nicely. Includes a task management system for structured agent workflow coordination. The agent manages its own workflow — Lorah just provides the loop, error recovery, output formatting, and task tracking. Follows the Ralph pattern. Distributed as a single self-contained binary with no external runtime dependencies. - -## Commands - -```bash -make build # Build binary -go run . run PROMPT.md # Development run -lorah run PROMPT.md [flags...] # Run loop (all flags after prompt passed to claude CLI) -lorah task [args...] # Task management -``` - -Use TDD — write tests before implementation. Use `make fmt` and `make lint`. - -## Architecture - -``` -main.go CLI router: subcommand dispatch, help text, version -internal/loop/ - loop.go Run() entry point, signal handling, infinite loop - claude.go Subprocess execution - output.go Stream-JSON parsing and formatted output - constants.go ANSI colors, buffer size, retry delay -internal/task/ - task.go Core types: Phase, Section, Task, TaskStatus, TaskList, Filter - storage.go Storage interface - json_storage.go JSONStorage implementation (.lorah/tasks.json) - format.go Output formatters: json, markdown - cmd.go CLI subcommand handlers -docs/design/ Design specifications (authoritative reference) -``` - -## Design Principles - -**Ralph Philosophy**: The agent is smart enough to manage its own workflow. Don't orchestrate — provide a simple loop and trust the model. - -**Radical Simplicity**: Every line of code is overhead. The simplest solution that works is the best solution. Prefer deleting code over adding it. - -**Agent is in Control**: The harness provides the loop and nice output. The agent reads the codebase, decides what to do, and makes progress. No phase management needed. - -**No Ceremony**: No config files, session state, lock files, or scaffolding commands. Just a prompt file and a loop. - -**Filesystem as State**: No session files. Git commits show progress. Agent reads files to understand context. - -**Design Specifications**: Authoritative design docs live in `docs/design/`. When in doubt about intended behavior, consult the specs: `cli.md`, `run.md`, `output.md`, `task.md`. - -## Dependencies - -No external runtime dependencies. All functionality uses the Go standard library. The `claude` CLI (separate install) is the only runtime requirement. +If you discover something non-obvious about this project, ask if it should be noted in CLAUDE.md. diff --git a/docs/guide/README.md b/docs/guide/README.md new file mode 100644 index 0000000..96e92ea --- /dev/null +++ b/docs/guide/README.md @@ -0,0 +1,13 @@ +# Lorah Guides + +Practical guides for using Lorah effectively. These cover _how to use_ Lorah — for _how Lorah is built_, see the [design specifications](../design/README.md). + +## Index + +| Guide | Description | +| ------------------------------------ | ---------------------------------------------------------- | +| [workflow.md](workflow.md) | An incremental spec-driven development workflow pattern | +| [design-specs.md](design-specs.md) | How to write design specs that agents can reliably execute | +| [configuration.md](configuration.md) | Setting up a .lorah project directory | +| [prompts.md](prompts.md) | Router and phase prompt templates for the agent loop | +| [tasks.md](tasks.md) | Task file format and status lifecycle | diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md new file mode 100644 index 0000000..4d1dc26 --- /dev/null +++ b/docs/guide/configuration.md @@ -0,0 +1,104 @@ +# Guide: Configuration + +A `.lorah` directory contains the files that define a unit of work for the agent loop. It sits at the project root by default (overridable with Lorah's `--dir` flag). Commit `.lorah/` to git — the workflow depends on git history for state and continuity, and task files are committed as part of the loop. + +``` +.lorah/ +├── plan.md # scope and acceptance criteria +├── prompt.md # orient + route to phase prompt +├── prompts/ +│ ├── plan.md # task selection +│ ├── test.md # write tests for selected task +│ └── implement.md # make tests pass +├── tasks/ +│ ├── 01-.md # one file per task +│ └── ... +└── settings.json # Claude Code CLI settings +``` + +The `lorah` CLI wraps Claude Code to run the agent loop. It accepts a prompt file and forwards additional flags to `claude`. + +## Plan file + +The plan file is the output of the scoping step — [Setup](workflow.md#setup-scope-the-work) in the spec-driven workflow. It defines what is being built and what done looks like. The agent loop uses it as the contract between the human and the agents. + +A plan file contains: + +- **Scope** — what is being built, at the level of a brief description and a list of capabilities. Reference the design specs rather than duplicating them. +- **Boundaries** — constraints and invariants that apply across the work (e.g., "stdlib only", "no external dependencies"). +- **Acceptance criteria** — concrete, verifiable conditions that define when the work is complete. An agent should be able to check each criterion against git state and test results. + +A plan file does not contain individual tasks. Task selection happens inside the loop, where each agent picks the next task based on current state. + +```markdown +# + +## Scope + +What is being built — brief description and list of capabilities. +Reference the design specs rather than duplicating them. + +## Boundaries + +- Constraints and invariants that apply across the work. + +## Acceptance Criteria + +- [ ] Concrete, verifiable conditions. +``` + +## Prompt files + +The prompt structure splits into a router prompt and phase-specific prompts. This keeps each agent's context small and focused. See the [prompt files guide](prompts.md) for templates. + +## Task files + +Each task gets its own file in `.lorah/tasks/`. The planning agent creates one task file per iteration; the testing and implementation agents update it as they work. See the [task files guide](tasks.md) for the template and status values. + +## Settings + +`settings.json` is a standard Claude Code CLI settings file. Pass it via the `--settings` flag: + +```sh +lorah run prompt.md --settings .lorah/settings.json +``` + +Common fields: + +```json +{ + "model": "sonnet", + "permissions": { + "defaultMode": "bypassPermissions" + }, + "sandbox": { + "enabled": true, + "autoAllowBashIfSandboxed": true + }, + "attribution": { "commit": "", "pr": "" } +} +``` + +- **model** — which Claude model to use. +- **permissions** — `bypassPermissions` is typical for autonomous loops where no human is approving each action. +- **sandbox** — enables sandboxed execution. `autoAllowBashIfSandboxed` avoids permission prompts for shell commands when sandboxing is on. +- **attribution** — text added to commit messages (as git trailers) and PR descriptions. Empty strings disable attribution; omitting the field uses Claude Code's defaults. + +See the [Claude Code settings reference](https://code.claude.com/docs/en/settings) for all available settings. + +## Claude flags + +Additional Claude CLI flags can be passed after the prompt file: + +```sh +lorah run prompt.md --settings .lorah/settings.json --model claude-opus-4-6 --max-turns 50 +``` + +Flags are passed through to the `claude` CLI unchanged. Common flags: + +- `--settings ` — path to settings file +- `--model ` — override the model (takes precedence over settings.json) +- `--max-turns ` — limit the number of agent turns per iteration +- `--allowedTools ` — restrict which tools the agent can use + +See the [Claude Code CLI reference](https://code.claude.com/docs/en/cli-reference) for all available flags. diff --git a/docs/guide/design-specs.md b/docs/guide/design-specs.md new file mode 100644 index 0000000..c8d95fe --- /dev/null +++ b/docs/guide/design-specs.md @@ -0,0 +1,136 @@ +# Guide: Writing Design Specs + +A design spec is a behavioral contract — it defines what the system does, not how to code it or how to use it. Specs are the foundation of the [incremental spec-driven workflow](workflow.md) and the single source of truth for their domain. If the spec and the code disagree, one of them has a bug. + +Specs are stable during execution — modifying a spec mid-loop invalidates the plan file, existing tests, and completed work derived from it. Changes happen between units of work, not during them. + +Specs are not tutorials, READMEs, API reference docs, or implementation plans. + +A spec emerges through iteration between an engineer and an agent. The engineer holds the intent; the agent drives the structure. The properties below guide each pass — they are not a checklist to complete once. How the engineer-agent pair reaches a spec that meets these properties is up to them. + +## Spec Structure + +A spec has three invariant parts — Overview, Examples, Related Specifications — and topic-specific behavioral sections in between. The middle sections diverge based on what the component does; their shape is dictated by the content, not a template. + +```markdown +# Specification + +--- + +## 1. Overview + +### Purpose + +What this component does and why it exists — one paragraph. + +### Goals + +- Bulleted list of what this spec defines. + +### Non-Goals + +- Bulleted list of active exclusions. + +--- + +## 2–N. [Topic-specific sections] + +The middle sections define the component's behavior. Their shape +depends on what the component does: + +- If it has a user-facing interface (CLI, API), define it first — + commands, flags, endpoints, parameters. +- If it has distinct behavioral modes or lifecycle phases, give + each its own section. +- If it has data structures or storage, specify the schema. +- If it has internal rules or algorithms, describe them precisely + enough to test against. + +Use tables, code blocks, and subsections as the content demands. + +--- + +## N+1. Examples + +5–15 concrete input/output examples. These become test cases. + +--- + +## N+2. Related Specifications + +- Links to specs that interact with this one. +``` + +**One spec per logical unit.** A logical unit is a behavioral domain that can be tested in isolation. Split specs by what a component _does_ — its observable behavior — not by file or package. If two behaviors can be tested without referencing each other, they belong in separate specs. If testing one requires understanding the other, they either belong together or need an explicit cross-reference. + +**Cross-reference, do not duplicate.** When two specs interact, link between them. Duplicated content diverges over time, and agents cannot know which copy is authoritative. + +**Self-contained sections.** An agent working on output formatting should be able to read the relevant section of the output spec without reading every section that precedes it. Each section should establish its own context. + +## Properties of a Good Spec + +These properties define what makes a spec effective. When properties conflict, prioritize testability and boundary-completeness over scannability. + +### Behavioral, not implementational + +Specs define what a component does as observed from the outside — its inputs, outputs, error cases, and side effects. They do not prescribe internal implementation. The exception is cross-boundary contracts: shared data formats, storage schemas, or contracts that multiple components depend on. A useful test: if a test in a _different_ spec would assert on this detail, it is a cross-boundary contract and belongs in the spec. + +- Cross-boundary: "Tasks are persisted as a `TaskList` JSON object in `tasks.json` with the schema defined in §3." — Multiple specs depend on this format. +- Not cross-boundary: "The router uses a switch statement to dispatch subcommands." — Only this spec's implementation cares. +- Borderline: "The `Storage` interface defines `Load`, `Save`, `Get`, `List`, `Create`, `Update`, `Delete`." — Specify it now if the intent is to stabilize it for multiple consumers; leave it as an implementation detail if the interface is still in flux. + +### Prescriptive tone + +Use present-tense declarative statements. "The CLI exits 1 on unknown command" — not "should exit" or "ideally exits." + +### Testable + +The difference between a testable spec and a vague one is concrete, observable values: + +- Vague: "The program handles Ctrl+C gracefully." + Precise: "First SIGINT sets a stopping flag and lets the current iteration complete. Second SIGINT calls os.Exit(0) immediately." +- Vague: "Long tool inputs are truncated." + Precise: "Tool inputs with more than one line display the first line followed by `... +N lines` where N is the remaining line count." +- Vague: "The system creates a default file if none exists." + Precise: "If tasks.json does not exist on Load, return an empty TaskList with Version 1.0. Do not create the file on disk until the first Save." +- Vague: "The system writes results to an output file." + Precise: "On successful completion, the command writes the result JSON to `{dir}/output.json` with 0644 permissions. If the file exists, it is overwritten atomically via write-to-temp-then-rename. If the directory does not exist, the command returns an error — it does not create parent directories." + +If a claim is hard to make precise, the behavior is underspecified — return to it and tighten it before moving on. + +### Boundary-complete + +Every input has defined behavior for empty, missing, and invalid cases. Every output has a defined format and error representation. + +### Explicitly scoped + +Every spec needs Goals and Non-Goals. Non-Goals are active exclusions, not a "future work" list. + +### Decision rationale + +Record why, not just what. Apply to non-obvious constraints and rejected alternatives — self-evident decisions don't need rationale. Keep rationale inline, close to the decision it explains. + +### Defined vocabulary + +Define terms once in a central glossary — a shared file (e.g., `glossary.md`) or a section in the specs directory README — and use them consistently. Agents treat synonyms as distinct concepts. + +### Scannable structure + +Each spec uses numbered top-level sections with horizontal rule dividers. Use tables for reference data, code blocks for formats, and subsection headings for distinct behavioral areas. + +## Readiness Checklist + +A spec is ready for implementation when all of these hold: + +- [ ] Does the spec define observable behavior without prescribing internal implementation? +- [ ] Can you write a test assertion for every behavioral claim? +- [ ] Are all inputs covered for empty, missing, and invalid cases? +- [ ] Does every output have a defined format and error representation? +- [ ] Are cross-boundary contracts identified and specified? +- [ ] Do Non-Goals actively exclude the most likely scope creep? +- [ ] Do 5–15 concrete examples exist and were they easy to write? +- [ ] Does the spec use present-tense declarative statements without hedging? +- [ ] Do non-obvious decisions include inline rationale? +- [ ] Are terms defined in the glossary and used consistently? + +If any criterion fails, the spec needs more work. This is expected — specs tighten through iteration. diff --git a/docs/guide/prompts.md b/docs/guide/prompts.md new file mode 100644 index 0000000..16f236d --- /dev/null +++ b/docs/guide/prompts.md @@ -0,0 +1,128 @@ +# Guide: Prompt Files + +The prompt file is a markdown file piped to Claude Code on each loop iteration. Rather than a single monolithic prompt, the structure splits into a router prompt and phase-specific prompts. This keeps each agent's context small and focused. + +## Router prompt + +The main `prompt.md` orients the agent and routes it to the correct phase prompt. It is the only file piped to Claude Code — phase prompts are read by the agent during execution. + +```markdown +# <Project Name> + +Complete exactly one task per invocation. + +--- + +## Workflow + +1. **Orient** — Run `git log --oneline -10` to understand what was + done in prior iterations. + +2. **Route** — Scan `.lorah/tasks/` for task files. At most one + task is non-completed at any time. + - If a task has `status: blocked`, read its Log to understand the + issue, then read and follow `.lorah/prompts/plan.md`. + - If a task has `status: in_progress` and no tests exist for it, + read and follow `.lorah/prompts/test.md`. + - If a task has `status: in_progress` and tests exist, read and + follow `.lorah/prompts/implement.md`. + - Otherwise, read and follow `.lorah/prompts/plan.md`. + +3. **Exit** — Stop. Do not proceed to the next task. + +--- + +## Rules + +- One task per invocation: complete one task, commit, exit. +- Design specs are authoritative: `docs/design/` defines the target + behavior. +``` + +## Phase prompts + +Each phase prompt lives in `.lorah/prompts/` and defines the workflow for a single phase. The agent reads exactly one per iteration. + +**`prompts/plan.md`** — Select the next task from the design specs and current state, then create a task file. + +```markdown +# Planning Phase + +## Workflow + +1. Read `.lorah/plan.md` for scope and acceptance criteria. +2. Read the design specs in `docs/design/` for behavioral details. +3. Review git history and completed tasks in `.lorah/tasks/` to + understand what has been built. +4. Check for a blocked task in `.lorah/tasks/`. If one exists, read + its Log and revise the task to address the issue. Set status to + `in_progress`, add notes to the Log, and skip to step 8. +5. Check the plan file's acceptance criteria against current git + state and test results. If all criteria are met, exit — the work + is complete. +6. Identify the single next task — the smallest unit of work that + moves toward acceptance criteria. +7. Create a new task file in `.lorah/tasks/` using the task file + format. Set status to `in_progress`. Add planning notes to the + Log. +8. Commit. +``` + +**`prompts/test.md`** — Write tests for the in-progress task. + +```markdown +# Testing Phase + +## Workflow + +1. Read the in-progress task file in `.lorah/tasks/`. +2. Read the relevant design spec section(s) referenced in the task. +3. Write tests that verify the behavior described in the task's + acceptance criteria. Do not write any production code. Add stubs + or interface definitions only if required to make tests + compilable. +4. Verify: run the test suite. Failures are expected (no + implementation yet), but panics and compilation errors must be + fixed. +5. Update the Testing section of the task file's Log with files + created and edge cases covered. +6. Commit. + +## Blocked workflow + +If the design spec is ambiguous or contradicts the task file, add a +note to the task file explaining the issue, set status to `blocked`, +and exit without committing test code. +``` + +**`prompts/implement.md`** — Make the tests pass. + +```markdown +# Implementation Phase + +## Workflow + +1. Read the in-progress task file in `.lorah/tasks/`. +2. Read the tests written in the testing phase. +3. Read the relevant design spec section(s) referenced in the task. +4. Write production code to make the tests pass. Do not write new + tests. +5. Verify: run the full test suite. All tests must pass. +6. Update the task file: set status to `completed`, add + implementation notes to the Log. +7. Commit. + +## Blocked workflow + +If the existing tests conflict with the design spec: + +1. Discard uncommitted changes. +2. Set the task status to `blocked` with notes explaining the + conflict. +3. Exit without committing. + +The next iteration will route to the planning phase to reassess the +task. +``` + +The prompts above are starting points. Adapt the rules and workflow steps to match your project. Focus on boundaries and invariants rather than detailed instructions for every scenario. diff --git a/docs/guide/tasks.md b/docs/guide/tasks.md new file mode 100644 index 0000000..4b2d63d --- /dev/null +++ b/docs/guide/tasks.md @@ -0,0 +1,50 @@ +# Guide: Task Files + +Each task gets its own file in `.lorah/tasks/`. The planning agent creates one task file per iteration; the testing and implementation agents update it as they work. This keeps context small — an agent only reads the task it is working on. At most one task is non-completed at any time. + +Task files use sequential numbering as a prefix (e.g., `01-parse-cli-args.md`) to preserve ordering. + +```markdown +--- +status: in_progress +--- + +# Task: <title> + +## Behavior + +What this task implements — reference the relevant spec section(s). + +## Acceptance Criteria + +- Concrete, testable conditions. + +## Context + +Relevant files, prior task decisions, or anything the next agent +needs. + +## Log + +### Planning + +- ... + +### Testing + +- ... + +### Implementation + +- ... +``` + +## Status values + +- `in_progress` — actively being worked by the current or most recent iteration. +- `completed` — done. Tests pass, code is committed. +- `blocked` — cannot proceed. See notes in Log for details. + +## Blocked task handling + +When the planning agent encounters a blocked task, it revises the existing task file — updating the Behavior, Acceptance Criteria, or Context as needed to address the issue noted in the Log. It sets status back to `in_progress` and adds notes to the Planning log explaining the revision. No new task file is created. diff --git a/docs/guide/workflow.md b/docs/guide/workflow.md new file mode 100644 index 0000000..d7cb733 --- /dev/null +++ b/docs/guide/workflow.md @@ -0,0 +1,83 @@ +# Guide: Incremental Spec-Driven Development + +Lorah provides the loop. How you structure the work inside that loop is up to you. There are many valid approaches — this document presents one pattern that works well for spec-driven development. + +## Overview + +This is a spec-driven development (SDD) workflow. Unlike test-driven development where tests drive the design, here the spec drives the design — tests verify the spec, and code satisfies the tests. + +The workflow has two parts: a one-time scoping step, then a repeating loop of task selection, testing, and implementation. + +``` +Scope the work + └─► Loop + ├─ Select next task + ├─ Write tests + ├─ Implement + └─ Repeat until done +``` + +Each step is handled by a fresh agent. Agents maintain continuity through git history, the plan file, and task files — not shared memory. + +## Setup: Scope the work + +Before the loop begins, an agent reviews the design specs and produces a plan file. This is not a full task breakdown. It defines: + +- **What is being built** — the boundaries of this unit of work. +- **Constraints** — invariants and boundaries that apply across the work. +- **What done looks like** — concrete, verifiable acceptance criteria. + +The plan file is the contract between the human and the agent loop. It should be specific enough that an agent can determine whether the work is complete by checking git state and test results. Avoid subjective criteria. + +This step runs once. The loop handles everything else. + +## Loop step 1: Select the next task + +Each iteration begins with an agent checking the plan file's definition of done against current state. If all acceptance criteria are met, the work is complete and the loop ends. Otherwise, the agent reviews: + +- The design specs (authoritative source of truth). +- The plan file (boundaries and definition of done). +- Current git state (what has already been built). + +Based on this, the agent identifies and documents the single next task to work on. It does not plan beyond the immediate next step. If a prior task was marked `blocked`, the planning agent reassesses it first — revising the task to address the issue before moving on. + +This is where the workflow diverges from upfront planning. Instead of decomposing all work at the start, each task is chosen with full knowledge of what exists now. This means: + +- **Ordering adapts** to what was actually built, not what was predicted. +- **No plan drift** — there is no detailed plan to become stale. +- **The agent naturally sequences** foundational work before dependent work, because it can see what is missing. + +The quality of task selection depends on the quality of the design specs. If the specs clearly define boundaries and behavior, the agent has a deterministic contract to work against. Ambiguity in specs propagates into ambiguity in task selection. + +## Loop step 2: Write tests + +An agent writes tests for the selected task based on the design spec. The spec defines the intended behavior; the tests encode it as a verifiable contract between this agent and the implementation agent that follows. A passing test suite means the task is complete. + +Test quality is the bottleneck of the entire workflow. If the tests are shallow or misinterpret the spec, the implementation agent will write code that passes bad tests. + +## Loop step 3: Implement + +An agent writes code to pass the tests. It can see the tests, the specs, and the full git history. When the tests pass, it exits. + +If the implementation agent encounters an issue — an ambiguous spec, a flawed test, or a dependency it cannot resolve — it sets the task status to `blocked` with notes in the task's Log before exiting. The next iteration routes to the planning phase to reassess. + +## Key properties + +**Agent isolation with continuity.** Each agent starts fresh, but git history and the plan file provide full context. This prevents context pollution while maintaining coherence across iterations. + +**Tests as contract.** Tests are the handoff mechanism between agents. They encode the spec as verifiable assertions, removing ambiguity about what "done" means for each task. + +**Specs are the quality ceiling.** The entire workflow is only as good as the design specs. Clear boundaries and unambiguous behavior definitions produce reliable agent output. Vague specs produce drift. + +**Incremental over upfront.** Planning the next task is a simpler, more reliable problem than planning all tasks. Each decision is made with maximum information. + +## Alternatives + +This is one workflow among many. Other valid patterns include: + +- **Upfront task planning** — decompose all work before the loop begins. Simpler coordination, but plans can drift as implementation diverges from predictions. +- **No formal testing phase** — the implementation agent writes its own tests. Faster iteration, but loses the contract between test and implementation agents. +- **Parallel execution** — run independent tasks concurrently. Higher throughput when tasks are truly independent. +- **Single-agent iterations** — one agent handles task selection, testing, and implementation in a single loop iteration. Less overhead, but larger context per agent. + +The right workflow depends on the nature of the work, the specificity of the specs, and how much you trust a single agent context to handle. diff --git a/examples/latest/.lorah/prompt.md b/examples/latest/.lorah/prompt.md new file mode 100644 index 0000000..4041b7a --- /dev/null +++ b/examples/latest/.lorah/prompt.md @@ -0,0 +1,34 @@ +# Planning API — Local Dev Scaffold + +Complete exactly one task per invocation. + +--- + +## Workflow + +1. **Orient** — Run `git log --oneline -10` to understand what was + done in prior iterations. + +2. **Route** — Scan `.lorah/tasks/` for task files. At most one + task is non-completed at any time. + - If a task has `status: blocked`, read its Log to understand the + issue, then read and follow `.lorah/prompts/plan.md`. + - Else if a task has `status: test`, read and follow + `.lorah/prompts/test.md`. + - Else if a task has `status: implement`, read and follow + `.lorah/prompts/implement.md`. + - Else, read and follow `.lorah/prompts/plan.md`. + +3. **Exit** — Stop. Do not proceed to the next task. + +--- + +## Rules + +- One task per invocation: complete one task, commit, exit. +- Design specs are authoritative: `docs/design/` defines the target + behavior. +- Task files use incrementing numeric prefix with kebab-case name + (e.g., `01-docker-compose.md`, `02-knexfile.md`). +- Each invocation must start in a clean git state. If uncommitted + changes exist, discard them before proceeding. diff --git a/examples/latest/.lorah/prompts/implement.md b/examples/latest/.lorah/prompts/implement.md new file mode 100644 index 0000000..52122ba --- /dev/null +++ b/examples/latest/.lorah/prompts/implement.md @@ -0,0 +1,32 @@ +# Implementation Phase + +## Workflow + +1. Read `.lorah/plan.md` for scope and acceptance criteria. +2. Read the relevant design specs indexed in `docs/design/README.md` + for behavioral details. +3. Review git history and current task file in `.lorah/tasks/`. +4. If tests were written in the testing phase, read them. Otherwise + skip to step 6. +5. Read the relevant design spec section(s) referenced in the task. +6. Write production code to satisfy the acceptance criteria (and make + tests pass, if they exist). Do not write new tests. +7. Verify: if tests exist, run the full test suite — all tests must + pass. Otherwise, verify acceptance criteria directly (e.g., run + commands, check file contents). +8. Update the task file: set status to `completed`, add + implementation notes to the Log. +9. If acceptance criteria has been met, update `.lorah/plan.md`. +10. Commit. + +## Blocked workflow + +If the existing tests conflict with the design spec: + +1. Discard uncommitted changes. +2. Set the task status to `blocked` with notes explaining the + conflict. +3. Exit without committing. + +The next iteration will route to the planning phase to reassess the +task. diff --git a/examples/latest/.lorah/prompts/plan.md b/examples/latest/.lorah/prompts/plan.md new file mode 100644 index 0000000..681f992 --- /dev/null +++ b/examples/latest/.lorah/prompts/plan.md @@ -0,0 +1,28 @@ +# Planning Phase + +## Workflow + +1. Read `.lorah/plan.md` for scope and acceptance criteria. +2. Read the relevant design specs indexed in `docs/design/README.md` + for behavioral details. +3. Review git history and completed tasks in `.lorah/tasks/` to + understand what has been built. +4. Check for a blocked task in `.lorah/tasks/`. If one exists, read + its Log and revise the task to address the issue. Set status to + `test` or `implement` (same criteria as step 7), add notes to the + Log, and skip to step 8. +5. Check the plan file's acceptance criteria against current git + state and test results. If all criteria are met, exit — the work + is complete. +6. Identify the single next task — the smallest unit of work that + moves toward acceptance criteria. +7. Create a new task file in `.lorah/tasks/` using the task file + format. Set the task status based on whether it has testable + behavior: + - `test` — the task implements logic, endpoints, or behavior that + benefits from test-first development. + - `implement` — the task is pure configuration, scaffolding, or + boilerplate with no behavioral logic to test. Note the rationale + in the task file's Log > Planning section. + Add planning notes to the Log. +8. Commit. diff --git a/examples/latest/.lorah/prompts/test.md b/examples/latest/.lorah/prompts/test.md new file mode 100644 index 0000000..0bb3416 --- /dev/null +++ b/examples/latest/.lorah/prompts/test.md @@ -0,0 +1,26 @@ +# Testing Phase + +## Workflow + +1. Read `.lorah/plan.md` for scope and acceptance criteria. +2. Read the relevant design specs indexed in `docs/design/README.md` + for behavioral details. +3. Read the current task file in `.lorah/tasks/`. +4. Read the relevant design spec section(s) referenced in the task. +5. Write tests that verify the behavior described in the task's + acceptance criteria. Do not write any production code. Add stubs + or interface definitions only if required to make tests + compilable. +6. Verify: run the test suite. Failures are expected (no + implementation yet), but panics and compilation errors must be + fixed. +7. Update the Testing section of the task file's Log with files + created and edge cases covered. +8. Update the task status from `test` to `implement`. +9. Commit. + +## Blocked workflow + +If the design spec is ambiguous or contradicts the task file, add a +note to the task file explaining the issue, set status to `blocked`, +and exit without committing test code. diff --git a/examples/latest/.lorah/settings.json b/examples/latest/.lorah/settings.json new file mode 100644 index 0000000..d988115 --- /dev/null +++ b/examples/latest/.lorah/settings.json @@ -0,0 +1,14 @@ +{ + "model": "opus", + "permissions": { + "defaultMode": "bypassPermissions" + }, + "sandbox": { + "enabled": true, + "autoAllowBashIfSandboxed": true, + "network": { + "allowedDomains": ["registry.npmjs.org"] + } + }, + "attribution": { "commit": "", "pr": "" } +} diff --git a/examples/latest/.lorah/tasks/00-task-template.md b/examples/latest/.lorah/tasks/00-task-template.md new file mode 100644 index 0000000..cb9e703 --- /dev/null +++ b/examples/latest/.lorah/tasks/00-task-template.md @@ -0,0 +1,33 @@ +--- +status: test +--- + +<!-- Valid statuses: test | implement | blocked | completed --> + +# Task: <title> + +## Behavior + +What this task implements — reference the relevant spec section(s). + +## Acceptance Criteria + +- Concrete, testable conditions. + +## Context + +Relevant files, prior task decisions, or anything the next agent needs. + +## Log + +### Planning + +- ... + +### Testing + +- ... + +### Implementation + +- ...