Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f1fe380
docs: design for standards, the rules every change is held to
jflavan Oct 28, 2026
b2af45b
docs(standards): call a rule's id its rule label
jflavan Oct 28, 2026
b95944e
docs(standards): versioned record, exceptions, tool checks, plan-only…
jflavan Oct 28, 2026
af9db2e
docs(standards): console workflow, per-change scope, setup section
jflavan Oct 28, 2026
e17be90
docs(standards): onboarding agent step, LOOPSTRA_BASE for tool checks…
jflavan Oct 28, 2026
cbd030b
docs: implementation plan for standards, with review fixes
jflavan Oct 28, 2026
0331437
feat(standards): parse standard files
jflavan Oct 28, 2026
cd0f448
feat(standards): read from main's commit, applicability, section reader
jflavan Oct 28, 2026
b930f7f
fix(standards): git failures reading standards throw instead of dropp…
jflavan Oct 28, 2026
08956fb
feat(standards): the loop does nothing while a standard cannot be read
jflavan Oct 28, 2026
ea8b86c
test: golden prompts before standards
jflavan Oct 28, 2026
7157f15
feat(standards): the spec gate checks the Standards section
jflavan Oct 28, 2026
29ec7fa
feat(standards): the plan gate covers every rule that applies
jflavan Oct 28, 2026
8a2041b
feat(standards): exceptions wait for a person and are recorded
jflavan Oct 28, 2026
951e124
fix(standards): undo takes back recorded exceptions; record reads safely
jflavan Oct 28, 2026
81538a0
feat(standards): build, resolve and review are held to the standards
jflavan Oct 28, 2026
0280d78
feat(standards): the merge gate protects standards and asks a person …
jflavan Oct 28, 2026
96b1cc9
feat(standards): tool checks run in the merge checks
jflavan Oct 28, 2026
af76279
feat(standards): the done-check judges each rule; outcome.md records …
jflavan Oct 28, 2026
0bd0e30
fix(standards): done-check standards is optional in the schema; no ro…
jflavan Oct 28, 2026
c3bbc0b
feat(standards): no session of the loop edits loopstra/standards/
jflavan Oct 28, 2026
0fbddba
feat(standards): add or remove a standard for one change
jflavan Oct 28, 2026
6543b85
feat(standards): loopstra standards, and tool checks tried on main
jflavan Oct 28, 2026
561b228
feat(console): standard files through agent-files requests
jflavan Oct 28, 2026
ba7ce67
feat(console): standards routes
jflavan Oct 28, 2026
2528651
fix(console): standards routes review round 1
jflavan Oct 28, 2026
fdff701
feat(console): Settings › Standards and Exceptions granted
jflavan Oct 28, 2026
d05611e
feat(setup): loopstra setup standards
jflavan Oct 28, 2026
d93946b
fix(console): Settings › Standards review round 1
jflavan Oct 28, 2026
4068aba
fix(setup): standards section review round 1
jflavan Oct 28, 2026
e85fe80
feat(console): the change's Standards panel
jflavan Oct 28, 2026
0fdcc39
feat(skill): onboarding step for standards
jflavan Oct 28, 2026
f7cafdb
docs: standards
jflavan Oct 28, 2026
ddb2b1d
fix(standards): review fixes — merge gate
jflavan Oct 28, 2026
7309fdc
fix(standards): review fixes — setup
jflavan Oct 28, 2026
cdefb2d
fix(standards): review fixes — start warns about unreadable standards
jflavan Oct 28, 2026
55535d4
fix(standards): review fixes — outcome lines read back
jflavan Oct 28, 2026
3eeade4
fix(standards): review fixes — console names uncommitted files as git…
jflavan Oct 28, 2026
08e4c40
fix(standards): review fixes — reading the standards
jflavan Oct 28, 2026
f3e86f2
fix(standards): review fixes — one helper each, main resolved once
jflavan Oct 28, 2026
df19438
fix(standards): review fixes — review lines and the order of checks
jflavan Oct 28, 2026
d49b401
fix(standards): review fixes — console dialog, parsing and the hook
jflavan Oct 28, 2026
444ba06
docs(standards): review fixes — start warns, added needs_person, setu…
jflavan Oct 28, 2026
c1e1ed8
test: make the standards tests pass on Windows
jflavan Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 216 additions & 15 deletions README.md

Large diffs are not rendered by default.

21 changes: 13 additions & 8 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ Loopstra is an unattended development loop on top of the Claude Code CLI. Code o

## Layers

About 165 modules under `src/`, in eight layers. A module imports only from its own layer or the ones below it. There is no runtime import cycle, and every exported name is imported somewhere: `bun run deadcode` fails otherwise.
About 190 modules under `src/`, in eight layers. A module imports only from its own layer or the ones below it. There is no runtime import cycle, and every exported name is imported somewhere: `bun run deadcode` fails otherwise.

1. **Foundations**, which import no other Loopstra module.
- `text.ts`, `ids.ts`, `paths.ts` and `fsutil.ts` hold small helpers: `writeFileAtomic`, and `readJsonAs`, which reads a file through a zod schema.
- `stop.ts` holds the stop request and the errors that end a step without being its fault (`notTheStepsFault`).
- `lanes.ts` holds the in-process locks, which are keyed, re-entrant and checked for order, and the claims on changes.
- `envelopes.ts` holds the zod schemas of what each agent phase answers.
- `standard-examples.ts` holds the two example standards that `loopstra setup standards` and the console's New standard start from, as plain strings, so the page can import them.
2. **Processes and git.**
- `shell.ts`: `spawnBounded` gives every child a deadline, kills its whole tree, and cleans its environment of a git hook's repository variables.
- `shell.ts`: `spawnBounded` gives every child a deadline, kills its whole tree, and cleans its environment of a git hook's repository variables. `programsIn` and `missingProgram` name the programs a command line runs and the one the shell could not find.
- `git.ts`: `Git`, with every call bounded and taking the checkout or remote lock its subcommand needs, plus the plumbing records use (`commitFiles`, `moveRef`).
- `github.ts`: the `gh` CLI.
3. **State on disk**, each read through a schema.
Expand All @@ -24,12 +25,16 @@ About 165 modules under `src/`, in eight layers. A module imports only from its
- `stamp.ts` holds what an upgrade knows.
- `risk.ts` scores a change's diff against `gates.merge.risky` (`scoreRisk`), for the merge gate.
- `agents.ts` resolves a step's agent setup from the config (`resolveSetup`) and holds its rules: which steps are read-only, which git a step may never get, and which steps run as the build's agent.
- `standards.ts` reads the standard files in `loopstra/standards/` from a commit of main (`readStandards`, every problem with its file and line), works out which apply to a change's files (`applying`), renders them for the prompts (`renderStandards`), reads and checks a spec's or plan's Standards section (`readStandardsSection`, `checkStandardsSection`), and reads an outcome's back (`readOutcomeStandards`).
- `standards-record.ts` reads and writes a change's `intent/<slug>/standards.md` (standards added and removed, exceptions approved), and finds the exceptions a spec or plan asks for that nobody has allowed yet (`exceptionsToApprove`).
- `standards-check.ts` runs a command once in a throwaway checkout of main's last commit (`runOnMain`, which setup's `commands.test` check uses too), and a standard's tool check that way with `LOOPSTRA_BASE` set (`checkOnMain`).
4. **Records.**
- `record-draft.ts` holds `RecordDraft`.
- `context.ts` holds `StepContext` and `commitRecord`, the one way anything is written to main, with `settleRecord` and `landed` (see Records).
- `context.ts` holds `StepContext` and `commitRecord`, the one way anything is written to main, with `settleRecord` and `landed` (see Records). A step reads the standards once, at its commit of main (`StepContext.standards`), and throws `StandardsUnreadable` when one cannot be read.
5. **Sessions.**
- `claude.ts` runs one CLI session: `runSession`, and `classify`, which reads how it ended.
- `prompts.ts` renders the prompts.
- `standards-prompt.ts` holds what each phase is told to do with the standards (`STANDARDS_INSTRUCTIONS`), which `phasePrompt` adds only when the change has standards to show.
- `sessions.ts` traces each session.
- `phases.ts` holds `agentPhase` and `codePhase`, plus `alongside`, for work that runs beside another phase.
- `judges.ts` holds the cheaper first-pass judges.
Expand All @@ -44,11 +49,11 @@ About 165 modules under `src/`, in eight layers. A module imports only from its
- `signals.ts` checks main's health.
- `remote.ts` syncs main and moves it in one step.
8. **Surfaces.**
- `cli.ts` and `commands/*` are the command line.
- `console/*` is the local server, with JSON and SSE.
- `ui/*` is the Preact page.
- `cli.ts` and `commands/*` are the command line; `commands/standards.ts` is `loopstra standards`.
- `console/*` is the local server, with JSON and SSE. `console/standards.ts` serves Settings › Standards, a draft's check, Try it on main, the exceptions granted, a change's Standards panel, and the `standards-scope` request.
- `ui/*` is the Preact page. `ui/views/StandardSettings.tsx`, `ui/views/Exceptions.tsx` and `ui/parts/StandardsPanel.tsx` are the standards' views, and `ui/standards.ts` what they say and check as a person types.
- `chat/*` is the orchestrator, its writer, and the terminal, console, Slack and Discord transports.
- `setup/*` is `loopstra setup`.
- `setup/*` is `loopstra setup`; `setup/sections/standards.ts` is its standards section, and `setup/standards-checks.ts` the standards' checks, which `--check` runs with the rest.
- `upgrade/*` is `loopstra upgrade`.

Good places to start reading are `scheduler.ts`'s `tick` for the loop, and `context.ts`'s `commitRecord` for how anything reaches main.
Expand Down Expand Up @@ -90,7 +95,7 @@ These came out of the hardening pass (#47 and the reviews after it). The reasons

`bun run check` runs the typecheck, the lint, the dead-code gate and the suite, in that order. CI runs it on Ubuntu, macOS and three Windows jobs, and adds a coverage gate of at least 80% and the security scans.

- **About 100 test files.** Unit tests sit in `tests/unit/`; `tests/integration/` runs whole ticks in throwaway git repositories.
- **About 130 test files.** Unit tests sit in `tests/unit/`; `tests/integration/` runs whole ticks in throwaway git repositories.
- **No real Claude or GitHub.**
- A fake `claude` (`tests/fake-claude/`) answers each phase from fixtures, and can be slow, hang or fail on cue.
- A fake `gh` (`tests/fake-gh/`) uses a bare repository as the remote.
Expand Down
Loading
Loading