Skip to the content.

LDL — LLM Delivery Loop

A delivery methodology for AI agents: contract first, gated delivery loop, compounding second brain.

LDL (LLM Delivery Loop) is a pattern for delivering real results with AI agents. In one sentence — humans govern through contracts and gates, agents execute through loops, and every project compounds into a second brain. Three elements: (1) contract & gates (governance) (2) loop execution (delivery) (3) compounding assets. If the LLM Wiki compounds knowledge, LDL compounds delivery.

Versions. The published stable release is v0.7.0, the tag v0.7.0 in this repository — that is what “LDL does X” refers to anywhere in this document unless a line says otherwise. It adds the profile-aware launch policy, the opt-in approved-job interface, atomic invocation reservation, expected-output reconciliation, and the read-only status report on top of v0.6.1. For the exact commit, resolve the tag or open its GitHub Release; do not trust a hash transcribed into a document. One authority: AUTHORITY.md. Prevention rules: REVIEW_LOG.md.

Quick start — paste this document into your agent and ask: “Install this into my workspace.” Works with Claude Code, Codex, Cursor, Gemini CLI, or any agent that can read and write files. Nothing to install, no dependencies — in LDL the methodology is the folder structure.

What’s inside: the double loop (inner delivery loop + outer knowledge loop) · seven phases from contract to verification · four evidence-backed approval gates · the v0.3.0 Evidence & Safety Model · the v0.4.0 Ship-First MVP Loop · the v0.4.1 Safe Pre-Engineering Harness · the v0.4.2 Independent Promotion Boundary · the v0.5.0 Evaluator-First Portfolio Loop · the v0.6.0 Enforced Evaluation · the v0.6.1 Gated Invocation · the v0.7.0 Approved execution, reconciliation, status · the Ingest / Query / Lint protocol for a compounding wiki · a folder tree you can install today.

If you are looking for an AI agent workflow that survives real projects, a way to stop re-explaining context to your agent every session, contract-first prompting, human-in-the-loop quality gates, or a second brain that agents actually maintain — that is what LDL is for.

Core

Agree the goal and criteria first, as a contract → enforce them through structure → delegate → humans verify at the gates → feed the results back into criteria and rules.

Contract = Phase 0–1 (goal, requirements) / structure = Phase 2 / delegation = Phase 3–5 (research, scoping, execution) / verification = the four gates + the Phase 6 loop / feedback = at Phase 6 completion → the outer loop.

Structure — double loop

┌─ Outer loop: compounding assets ──────────────────┐
│  Ingest · Query · Lint — wiki · rules · templates    │
│  ┌─ Inner loop: delivery ──────────────────┐       │
│  │ Phase 0  goal setting (the contract)     │       │
│  │ Phase 1  requirements definition         │       │
│  │ Phase 2  scaffolding structure design    │       │
│  │ Phase 3  problem research                │       │
│  │ Phase 4  solution scoping & priorities   │       │
│  │ Phase 5  engineering execution           │       │
│  │ Phase 6  the loop (verify·iterate·feed back) │   │
│  └─────────────────────────────────────────┘       │
│  at project end, promote lessons/rules/templates out │
└─────────────────────────────────────────────────────┘

v0.3.0 — Evidence & Safety Model

v0.2 made the contract structurally testable. v0.3.0 closes the next failure mode: a workspace can be structurally green while its gates, evidence, calculations, or execution readiness are not. It strengthens the existing documents rather than adding another phase.

  1. Gates are a state machine, not prose. PROGRESS.md carries G1–G4 with one verdict from PENDING | HOLD | PASS | FAIL | SUPERSEDED. A PASS names the contract version, approval mode, approver, non-future UTC time, and a unique substantive approval artifact under project raw/ that identifies that gate and contract version. The matching phase rows must be done and the append-only log must contain GATE-PASS: G<n> contract=<version>. A later gate cannot pass while an earlier gate is not PASS. A new contract version requires new gate evidence; old decisions remain history. One utterance can approve several gates: a contract version bump invalidates every earlier gate, so the owner usually re-approves them together. Keep that verbatim utterance once, in a new create-only file under project raw/ (existing raw files, including the Phase 0 interview record, are immutable); each gate’s approval cites that file and names only its own gate. A legacy Markdown approval artifact that quotes a multi-gate approval verbatim mentions the other gates and is refused, correctly, because an artifact naming three gates cannot prove which one it approves. A typed gate decision (v0.4.1 and later) names its gate in a field and lists the utterance file as hashed evidence.
  2. Evidence is a chain. Every [measured] or [proven] claim has a unique Claim ID, substantive claim, ACTIVE | DISPUTED | SUPERSEDED status, source artifact captured under project raw/, real capture date, scope/window, and transform or reproducer. A hand-copied summary or live external URL is not immutable primary evidence. The lint checks the chain exists; a separated verifier judges whether it is true.
  3. Safety propagates by impact, not by document section. 04_SCOPE.md maps each ready action to one or more uniquely identified impact dimensions, preconditions, an approval tier, canary, rollback, and readiness. If any linked dimension is HOLD, FAIL, or NOT_RUN, that action cannot be ready — an empty map, duplicate ID, or changed group name does not create an escape hatch.
  4. Quantitative work is reproducible. The contract declares whether quantitative claims exist. If yes, the scope records baseline/candidate windows and units, assumptions, formula or executable reproducer, and reconciliation. Conditional outcomes stay as scenarios; “asked”, “confirmed”, and “succeeded” are different states.
  5. Four verdicts stay separate. Harness, Product, Execution readiness, and Method conformance are reported independently. NOT_RUN never rolls up to PASS. A historical gate-order violation can coexist with a repaired Product PASS, but Method conformance for that run remains FAIL.
  6. Verification is read-only by default. The verifier works in an external review/scratch workspace, reconstructs the verdict from contract and primary evidence, and reports target mutation. A checker that rewrites target logs has contaminated its own audit.

The reference lint implements only deterministic boundaries (schema, links, vocabulary, ordering, propagation). Structural headings, tables, and verdicts inside fenced code or HTML comments are examples/hidden content and do not count. Each required scalar appears exactly once. The lint does not pretend to decide whether evidence supports a claim or whether a solution is good. That remains a separated semantic gate.

New v0.3 workspaces carry a root .ldl-version marker. Removing a project’s Governance profile does not downgrade it into a permissive legacy project. Marker-free pre-v0.3 workspaces remain readable; init refuses to mark a nonempty legacy workspace unless the operator explicitly passes --migrate-v03.

v0.4.0 — Ship-First MVP Loop

v0.3 prevented structurally green work from laundering bad evidence. A field run then exposed a second failure: the method could spend more time proving a product than getting a reversible MVP in front of users. v0.4 optimizes time to first live artifact, first completed user journey, and first real feedback.

  1. Choose the delivery mode. startup-reversible is the default for low-risk experiments; gated-high-risk retains the full pre-release gate path for legal, payment, personal-data, medical, or irreversible systems.
  2. Write one Launch brief. It fixes the target user, painful problem, smallest value journey, launch metric, feedback channel, kill criteria, timebox, risk, and rollback. Startup release still requires G1 and the P0/P1/P2/P4 launch documents, but not G2–G4.
  3. Ship MVP-1, not a core library. MVP-1 needs one real end-to-end journey plus deterministic, rendered/browser, and separated evidence. A typed ldl-mvp-evidence-v1 manifest binds distinct primary artifacts by path+SHA; empty files, maker self-attestation, and final-report self-citation fail.
  4. Use the Release ledger as the Launch Gate. A low-risk release PASS requires MVP-1 PASS, instrumentation, feedback, rollback, an HTTPS live artifact, human approval, and a typed ldl-release-evidence-v1 manifest with live smoke, telemetry, rollback, and feedback evidence. High-risk mode additionally requires G4 PASS.
  5. Build–Measure–Learn after launch. The Experiment ledger records one hypothesis, one change, one metric, a typed path+SHA evidence manifest, and one decision from ITERATE | EXPAND | PIVOT | STOP. Any post-MVP feature increment requires MVP-1 Release PASS, a measured experiment signal consumed once, and its own primary artifact; unrequested features cannot quietly become PASS.
  6. Context travels as handles. A phase packet is at most 8KB and carries requirement IDs, bounded commands/blockers, and artifact path + SHA-256; full reports stay on disk. tools/lean.py verify rejects stale hashes, path escapes, hidden/nested payloads, and split verbatim reports.
  7. Execution economy is contractual. Each project caps relay/checker summaries and checker/rerun counts, and records model/token/call/checker/wall-time telemetry. Malformed, outside, or self-referential cost evidence does not count.
  8. One batch, one rerun; delta gates, deterministic first. Tests, hashes, generated sweeps, and browser traces run before an LLM. Unchanged evidence is not replayed. A failed consolidated checker opens one root-class correction batch and one rerun, then HOLD.
  9. Owner/maker writes are physically separated. Owner uses owner/inbox.md and owner/outbox.md; maker preserves one canonical decision under project raw/ and reviews point to it.
  10. Verdicts stay separate. Release PASS, Product PASS, Harness, Readiness, Method, and Final delivery are different claims. Shipping an experiment is not claiming final product completeness.

The reference v0.4 suite proves the launch path and the refusal path: startup release can pass with G2–G4 pending after G1+MVP-1, high-risk release cannot; missing launch controls fail; post-MVP increments without measured user signal fail; packet, evidence, telemetry, recursive-raw, archive, and symlink bypasses fail deterministically.

v0.4.1 — Safe Pre-Engineering Harness

The first v0.4 field evaluation stopped a weak user-problem claim, but also exposed harness defects: failed agents could partially write the target, whole-workspace lint reported future-phase placeholders, a decision-only project had to explain MVP/Release fields, and free-form gate evidence was brittle. v0.4.1 promotes those failures into enforcement.

  1. Scratch is the default write boundary. workflow.py scratch-init TARGET SCRATCH creates a baseline-bound copy. workflow.py promote SCRATCH TARGET --through P<n> refuses target drift, existing-raw mutation, log rewrites, deleted files, and lint failures before staging changed files for promotion.
  2. Raw capture is create-only. workflow.py raw-put PROJECT relative/path SOURCE uses exclusive creation and rejects path escape, symlink traversal, and overwrite.
  3. Lint is phase-aware. Run lint.py --through P0, --through P3, --through P4, or --final for the whole-workspace verdict. Omitting both also defaults to final. Future-phase placeholders no longer force fake rows before their owning phase.
  4. P0 is mechanically lean. A v0.4.1 00_CONTRACT.md over 8,192 bytes fails L4. Detail belongs in linked evidence/reviews, not the governing surface.
  5. Decision-only work has its own profile. scaffold.py new NAME --profile pre-engineering-decision ends at G3, uses a Decision brief, and creates no Increment/Release/Experiment ledgers. startup-reversible remains the default; gated-high-risk remains available.
  6. Evidence semantics are explicit. Evidence level is [hypothesis] | [measured] | [proven]; Claim lifecycle is ACTIVE | DISPUTED | SUPERSEDED; Evidence domain is SUPPLY | DEMAND | BEHAVIOR | CAUSAL | LEGAL | OPERATIONAL. A fenced example ships in the scaffold without becoming live evidence.
  7. P1→P6 IDs synchronize deterministically. workflow.py sync-verdicts PROJECT adds missing requirement verdict rows as NOT_RUN, preserves existing rows, and rejects missing/duplicate/invalid IDs.
  8. Gate decisions are typed. workflow.py gate-validate and gate-apply verify an ldl-gate-decision-v1 JSON manifest, content-addressed evidence, gate/version/mode/timestamp, phase/prior-gate preconditions, create-only raw preservation, the Gate ledger, and the append-only event. Legacy Markdown approvals remain readable for v0.3/v0.4.

v0.4.2 — Independent Promotion Boundary

An adversarial review proved that a v0.4.1 maker could replace the scratch-side lint with exit(0), promote an invalid contract, and permanently install the disabled checker. It also found phase false-greens, a rewritable cost ledger, and no typed recovery from Gate FAIL. v0.4.2 closes those classes.

  1. The checker is outside the maker boundary. Promotion always executes TARGET/tools/lint.py against the scratch root. The scratch copy never grades itself.
  2. Installed tools are immutable during maker promotion. Any added or changed root tools/** file refuses promotion. Tool upgrades use explicit scaffold migration, never the maker scratch.
  3. Phase ownership is native. Validators receive the requested phase before entering a check block. P0 rejects populated future-phase ledgers; P3 skips Scope checks; P4 skips final Experiment/Increment/Release checks. The old global error-code whitelist is a compatibility no-op.
  4. Promotion enforces phase and control-plane ownership. P0 cannot change P1/P3/P4/final documents; P3 cannot change Scope or engineering outputs; P4 cannot change engineering outputs. PROGRESS.md never moves through maker promotion—typed workflow operations own Gate and phase state.
  5. Cost telemetry is append-only twice. Promotion and persistent lint-state both preserve the byte prefix of logs/**/cost-ledger.csv, just like event logs. Corrections are new rows, not history rewrites.
  6. Gate FAIL is contract-version terminal, not project terminal. A typed REOPEN decision may move FAIL to PENDING only on a higher contract version. Its two hashed inputs are exactly the new 00_CONTRACT.md and the prior immutable typed FAIL decision; the validator parses that prior decision and reconciles it with the failed Gate row before resetting the full Gate ledger.

REOPEN is one atomic control-plane operation—the revised contract never bypasses promotion by being edited in place:

python3 tools/workflow.py gate-reopen \
  projects/YYYY-MM-DD_name \
  /tmp/00_CONTRACT-v2.md \
  /tmp/gate-reopen-v2.json

The command validates the candidate contract and both hashes, then writes the revised contract, immutable REOPEN artifact, Gate ledger reset, and append-only event together. Any intermediate failure restores all four targets.

The default safe sequence is:

python3 tools/workflow.py scratch-init . /tmp/my-ldl-run
# run the maker only inside /tmp/my-ldl-run
# optional preflight; the target-owned checker inspects scratch
python3 tools/lint.py --through P0 /tmp/my-ldl-run
# promotion repeats the same target-owned check and refuses tool/future-phase drift
python3 tools/workflow.py promote /tmp/my-ldl-run . --through P0

v0.5.0 — Evaluator-First Portfolio Loop

v0.5.0 adds an optional breadth-first profile for competitive or ambiguous work. It does not force every bug fix to invent alternatives. Use scaffold.py new NAME --profile portfolio-competition when several problem candidates must be compared before agents build.

  1. Contract the evaluation environment. 02_EVALUATION.json separates deterministic checkers, AI structural/practitioner simulators, declared human reviewers, and agent consumers. Every evaluator declares its journey, blind inputs, unjudgeable dimensions, disqualification rules, and a 100-point rubric; bounded iteration limits apply globally. A human result requires a distinct ldl-human-review-v1 manifest bound to contract, evaluator, approver, non-future UTC time, and the exact reviewed subject. This is structural attestation, not cryptographic identity authentication.
  2. Select from a comparable portfolio. 03_PORTFOLIO.json requires at least three candidates only in this profile, one selected winner, explicit rejection/reopen conditions, unique IDs, and candidate-specific immutable evidence. Evidence copied between candidates does not become independent support.
  3. Preflight before build. 04_PREFLIGHT.json binds each dependency to a separated runner, executed-at time, expected/actual exit code, nonzero check count, and immutable probe evidence. Boolean zero, self-labeled PASS, failed dependencies, and nonzero blockers do not open P4/final.
  4. Prove promises, not prose. 06_CAPABILITIES.json gives every promise a required evidence level and observed status from NOT_IMPLEMENTED | BOUNDED_FALLBACK | CAPTURED_REAL | LIVE_VERIFIED. An observed level below the promised level fails final validation.
  5. Treat scores as simulations. 06_JUDGE_SCORES.json binds evaluator-profile SHA, exact accepted subject hash, blocking defects, unjudgeable dimensions, and immutable evidence. A rising internal score is not an external outcome and cannot target an unrelated hash.
  6. Gate submission separately. 06_SUBMISSION.json reconciles required/included files, secret scan, link check, original-log integrity, archive structure, and evidence after packaging.
  7. Keep project-local prompt history. Every new project has append-only logs/prompts.jsonl and logs/intervention-ledger.csv. Record prompts from a file so secrets do not enter shell arguments:
python3 tools/workflow.py prompt-log PROJECT SESSION prompt.txt --actor human

The command rejects common key/token/password/private-key shapes before append, records UTC/session/actor/content SHA-256, and never rewrites prior entries. Target-owned lint independently validates JSONL schema, content hashes, secret canaries, and byte-prefix continuity. This is tamper evidence against the constrained scratch maker—not external notarization against an operator who can rewrite the target and its lint state. Secret prevention happens before logging; if a credential enters an immutable original log, rotate it and record failure—redaction does not repair provenance.

Evaluator and downstream typed artifacts bind the active contract version. Judge rounds bind the exact evaluator-profile SHA. Once G1 is no longer PENDING, ordinary maker promotion cannot change 02_EVALUATION.json; a revised evaluator requires a new contract version and typed REOPEN.

  1. Keep checkpoints monotonic. In v0.5 portfolio projects, requesting P0 after portfolio/preflight/final state exists is refused as checkpoint regression; use the current or later --through stage.

Explicit migration from v0.4.2 is limited to empty workspaces:

python3 tools/scaffold.py init WORKSPACE --migrate-v050

v0.6.0 — Enforced Evaluation

v0.5.0 built the evaluation layer; v0.6.0 makes it binding. Every rule below closed a scenario that passed lint under v0.5.0 — the maker could still grade its own work through an unfrozen evaluator, an empty check, a self-set bar, a self-reported number, or a judge wearing the maker’s name.

  1. The freeze needs a gate to hang on. 06_SUBMISSION.json now requires G1 PASS. Under v0.5.0 the portfolio profile never required G1, so “the evaluator profile is frozen after G1” never engaged and a rubric could be rewritten at final and re-hashed.
  2. An empty check is not a passed check. Empty dependencies, required_files, included_files, submission_grammar, and empty evaluator journey / blind_inputs / cannot_judge / disqualification_rules now fail. A blind review that declares nothing blind is not a blind review.
  3. The maker does not set its own bar. Every capability binds a requirement_id that must exist in the 01_REQUIREMENTS.md ledger, and required_level may not fall below CAPTURED_REAL. Declaring a grand promise at NOT_IMPLEMENTED and passing is closed.
  4. Numbers come from execution output. A preflight checks count may not exceed the line count of its own evidence, the exit_code must appear in that evidence, and a judge score must appear in the round’s evidence. Content-addressed evidence proved the file existed; it did not prove the number came from it.
  5. Separation is an identity, not a forbidden word. Any runner_id containing “maker” is refused (maker-agent and maker used to pass), and a typed human review’s approver must match the G1 approver recorded in the gate ledger.
  6. A verdict for every input. Malformed nested fields in typed artifacts now produce an L13 verdict instead of a traceback.

tests/test_v060.py carries the hostile fixtures the earlier releases lacked: the empty-set cases, the maker-shaped identities, and one composed false-green that violates six rules at once — the shape a single-field negative test cannot catch.

Explicit migration from v0.5.0 is limited to empty workspaces:

python3 tools/scaffold.py init WORKSPACE --migrate-v060

v0.6.1 — Gated Invocation

v0.6.0 enforced what the maker writes; both 2026-08-26 field runs died on what the maker executes. One run lost 34 of 36 scoring artifacts to an orchestrator shell bug and no ledger noticed until the completion report; the other launched a runner fan-out behind a pending G1 — the orchestrator stepped over the very gate its own contract declared. The write path was fenced; the execution path was open. v0.6.1 closes that asymmetry.

  1. Runners launch through the wrapper, and the wrapper reads the gate ledger. tools/invoke.py run PROJECT --phase Pn --runner-id ID --session S -- command... refuses the launch unless the phase’s predecessor gate (P1–P3 → G1, P4 → G2, P5/P6 → G3) is PASS with typed evidence: the ledger row must link a raw/gate-decisions/*.json that validates against the v1 gate schema and matches the row’s gate, verdict, contract version, and approver. A textual PASS pasted into PROGRESS.md is not a gate. A refusal launches nothing and ledgers nothing.
  2. Ledgering splits around the process, not after it. The wrapper appends a STARTED row to the append-only logs/runner-ledger.csv before the process exists, and a COMPLETED (with exit code) or ABORTED row after it exits. A started/completed mismatch is not a bookkeeping gap — it is the evidence of interruption, and it survives any termination including kill -9. Batch after-the-fact ledgering cannot produce this property; it disagrees with reality precisely when reality goes wrong.
  3. The maker cannot wear a runner’s coat at launch time. A maker-shaped --runner-id is refused before the gate is even consulted — the same identity rule v0.6.0 applies to preflight manifests, moved to the moment of execution.
  4. The ledger is a log like every other log. runner-ledger.csv joins the L6 append-only set: it may only grow, its header and event vocabulary are validated, and a COMPLETED/ABORTED row without a prior STARTED row fails lint — a forged completion cannot repair a sequence the wrapper never started.

tests/test_v061.py proves the owner-specified negatives without a single model call: a pending G1 blocks a dummy runner without launching it, a typed G1 PASS permits exactly one harmless local invocation with a split ledger, and an interrupted invocation leaves STARTED=1, COMPLETED=0, ABORTED=1.

Migration from v0.6.0 is explicit but — unlike every earlier migration — does not require an empty workspace: v0.6.1 changes no project file schema, and the harness fix must be installable under the sealed failed runs it exists to prevent. Existing projects gain logs/runner-ledger.csv lazily on first invocation.

python3 tools/scaffold.py init WORKSPACE --migrate-v061

v0.7.0 — Approved execution, reconciliation, status

The current release, on top of v0.6.1. None of it is an OS sandbox or human authentication: the checks bind declarations to records written outside the maker’s tree.

# workspace (opt-in migration; without the flag a v0.6.1 workspace stays v0.6.1)
python3 tools/scaffold.py init WORKSPACE --migrate-v070

# what may launch, per delivery profile
python3 tools/policy.py show startup-reversible
python3 tools/policy.py check PROJECT --phase P4

# launch a runner: legacy (gate policy only, labelled limited)
python3 tools/invoke.py run PROJECT --phase P4 --runner-id steve --session S-1 -- python3 build.py

# launch under an approved job the maker did not write, with declared outputs
python3 tools/execution.py job-validate PROJECT job.json --phase P4 --runner-id steve \
    --runner-role runner --cwd "$PWD" --approvals-root /outside/owner-approvals -- python3 build.py
python3 tools/invoke.py run PROJECT --phase P4 --runner-id steve --session S-1 \
    --job job.json --approvals-root /outside/owner-approvals --expect expected-outputs.json \
    -- python3 build.py

# artifacts, status relay, frozen evaluator template, measurement
python3 tools/execution.py reconcile PROJECT expected-outputs.json --not-before "$START_EPOCH"
python3 tools/execution.py status PROJECT --format md
python3 tools/execution.py evaluator-validate evaluator.json --expected-sha256 <pinned digest>
python3 tools/execution.py measure-collect PROJECT --deliverable "one real deliverable" --output m.json
python3 tools/execution.py measure-validate m.json

The runner command always follows a literal --. --expect is frozen before launch and the declared output paths are reserved against other live invocations, so a child cannot rewrite its own success criteria or silently share another run’s output. status is derived read-only: it writes no gate, verdict or history, and missing or unverifiable evidence reports UNKNOWN/NOT_RUN/HOLD — never PASS. evaluator-validate without --expected-sha256 reports UNBOUND, because a self-recomputed hash proves only that the file hashed itself. Improvement targets stay targets: a gain claim is refused unless a measured baseline and its unit, window and source exist, and human acceptance recorded as a string is reported CLAIMED_UNVERIFIED.

Phase 0 — Goal setting (the contract)

This phase’s deliverable is a contract between the user and the AI. Agree on what problem to solve, why, how, and how the whole flow will run; every later phase is execution of the contract. Scope changes are handled as contract changes. Keep the contract as a separate file from the constitution (00_CONTRACT.md) — the constitution holds immutable principles; the contract is a project document updated through contract changes.

Deliverable: 00_CONTRACT.md — preceded by the interview record in raw/.

The interview comes first

The contract is not what the agent inferred — it is what the human said. Before writing the contract, interview the user and preserve the answers verbatim in the project’s raw/ (one file, IDs IV-01, IV-02, …). The contract then cites those IDs, and any field with no citation is agent inference and carries a [hypothesis] label. This applies Phase 1’s primary-utterance rule at Phase 0, where it decides everything downstream.

Ask three or four at a time. Offer choices — including your own guess — and allow free text; a wrong guess is itself information.

Question The contract field it fills
What is the real problem behind this request? Why
What exactly is in your hands when this is done? What
How will you check that it was done? How · evaluation criteria
By when, at what cost, with how many people? Constraints
Who decides pass or fail — a person, or code? Criteria judge
Is there work here that cannot be undone? Permission tiers
Do you know this domain? Where are the primary sources? Phase 3 depth · raw/
Verified once at a deadline, or continuously? Scope mode
What would you look at and call this a failure? Failure conditions

A question that fills no field is not asked — it only spends the user’s attention.

Go deeper only on a trigger: a vague word (“fast”, “properly”) → ask for the number and the instrument; Why and What don’t connect → “how does that deliverable remove that problem?”; a criterion can’t decide pass or fail → “what would you look at and call it failure?”; irreversible work exists → approval path and rollback; no domain expertise → who to ask, which document is primary; the constraints make the What impossible → “what do you drop first?”; raw/ is empty → ask for the material before asking more questions — one document can remove five of them.

“I don’t know” is a valid answer. If the unknown does not move the pass line (a tool, a method, a nice-to-have), it enters the contract as [hypothesis] and becomes a Phase 3 research item. If the unknown is the pass line (a missing law, policy, or primary source that decides what counts as done), no contract can honestly form yet — that is what pre-contract research below is for. An interview that stalls on unknowns is a bad interview.

Cost ceiling: three rounds. If the exit tests still fail after three, this is not a problem an interview can solve. Two legal exits — “hand it to Phase 3” is not one of them, because Phase 3 sits behind gate ① and gate ① is exactly what you cannot pass:

The five exit tests — the interview ends when all five pass

Each failed test is the next question. The interview is a loop, not a form — so give it what every loop needs: a verifier (the tests), a cost ceiling (three rounds), and a termination condition (all five pass).

Phase 1 — Requirements definition

Deliverable: 01_REQUIREMENTS.md

Phase 2 — Scaffolding structure design

The workspace harness (constitution, rules, wiki, templates) was installed once; the project skeleton (the project part of the default tree) was created at project start. Phase 2 designs not folders but this project’s enforcement devices. Build the harness before delegating research and execution — delegating without structure scatters evidence and outputs.

Deliverable: the project constitution + the delegation and permission structure

Phase 3 — Problem research

Deliverable: 03_EVIDENCE.md (the evidence ledger)

Phase 4 — Solution scoping & priorities

Deliverable: 04_SCOPE.md

Phase 5 — Engineering execution

Deliverable: the results accumulating in 05_engineering/ (delivered versions point-in-time frozen)

Phase 6 — The loop (verify · iterate · feed back)

Deliverable: 06_VERIFICATION.md (the verification report — updated cumulatively per increment)

Four human gates

Contract approval (Phase 0) / problem finalized (Phase 3) / solution finalized (Phase 4) / final delivery (Phase 6). At each gate, the head of the phase document carries a four-line review summary (what was done / key conclusion / the judgment being requested / where the detailed evidence lives), so the human opens one file and judges in minutes. Everything else belongs to the loop. Record every gate pass in the append-only event log and the PROGRESS.md Gate ledger; a generic “go ahead” is not silently promoted into approval unless it explicitly identifies the gate decision.

Outer loop — Ingest · Query · Lint

The operation of the workspace root (raw/ · wiki/ · index.md · RULES.md · templates/ · logs/). As the wiki accumulates, it becomes a second brain.

Logs and progress

The three-sentence pattern — the basic language of delegation

① “Don’t do X — go only as far as Y” (scope first) ② “Attach a source to every claim” (demand evidence) ③ Instead of “do it again”: “from now on, judge by this criterion and do it again” (feedback via criteria)

Installation procedure — executed by the agent

Install only what is listed below. Add further devices only when the need is proven.

Step 0 — Preflight, then the global constitution. First, probe the host: can the agent write agent-instruction files (CLAUDE.md and its kin) unattended? Some hosts protect them behind per-file live approval, and an unattended install will stall there. If they are protected, either present the human one approval packet up front listing every instruction file the install will write, or fall back to plain filenames (CONSTITUTION.md, PROJECT_PROTOCOL.md) — and state explicitly that fallback files are not auto-loaded: the agent must be told to read them at each session start.

Then the global constitution (first-time users): if there is no user-level global config file (~/.claude/CLAUDE.md or your tool’s equivalent), create it first. Five base principles:

Add your own situational rules on top (response language, frequently used commands, recurring-task rules). The constitution has four layers: global → workspace constitution (outer-loop protocol) → shared project protocol projects/CLAUDE.md (inner-loop protocol) → the individual project constitution (Phase 2). Each layer stacks on the one above it, and in tools that load nested CLAUDE.md files hierarchically, this structure enforces itself. Step 1 — Scaffold first, then interview. The interview record has to land somewhere immutable, so the folders come first. Ask the user where to install (default: a folder in the current directory), create the workspace once, then create the first project skeleton under projects/. Afterwards every new project gets the same skeleton and starts from Phase 0. The default tree — these are the names the scaffolder writes; rename them if you like, but rename them in the script, not per project:

   llm-delivery-loop/             ← workspace = outer loop (installed once)
   ├── .ldl-version               # schema marker; prevents silent legacy downgrade
   ├── CLAUDE.md                  # workspace constitution — identity/principles + outer-loop (wiki) protocol
   ├── RULES.md                   # prevention rules (the ratchet) — each with its origin
   ├── index.md                   # workspace index — link-closed catalog (query entry point)
   ├── raw/                       # second-brain source layer — project-independent collections (read-only)
   ├── wiki/                      # knowledge layer — the cross-project second brain
   ├── templates/                 # task prompt & document templates
   ├── logs/                      # outer-loop log — collection purposes, ingest verdicts, lint (log.md)
   ├── owner/                     # owner inbox/outbox — owner never writes project evidence directly
   ├── tools/                     # scaffold.py + lint.py + integrity.py + lean.py + workflow.py + policy.py + invoke.py + execution.py
   └── projects/                  ← inner loop = one folder per project
       ├── CLAUDE.md              # shared project protocol — Phase 0–6 gates, naming, document & log standards
       └── YYYY-MM-DD_<name>/     ← start date, never renamed
           ├── 00_CONTRACT.md     # Phase 0 · gate ①
           ├── 01_REQUIREMENTS.md # Phase 1
           ├── 03_EVIDENCE.md     # Phase 3 · gate ②
           ├── 04_SCOPE.md        # Phase 4 · gate ③
           ├── 05_engineering/    # Phase 5 deliverables (delivered versions frozen)
           ├── 06_VERIFICATION.md # Phase 6 · gate ④
           ├── CLAUDE.md          # project constitution (Phase 2 — scope constraint, project-specific rules)
           ├── PROGRESS.md        # progress — the review hub
           ├── raw/               # this project's sources + the interview record (immutable)
           └── logs/              # log.md + cost-ledger.csv + prompts.jsonl + intervention ledger + sessions/

Generate this with a script, not by hand. The reference toolset is tools/scaffold.py, tools/lint.py, tools/integrity.py, tools/lean.py, tools/workflow.py, tools/invoke.py, and — added in v0.7.0 — tools/policy.py and tools/execution.py: eight tools in total. scaffold.py init creates a v0.7.0 workspace; it refuses a nonempty marker-free workspace unless --migrate-v03 is explicit. Migration is sequential and explicit: v0.3 → v0.4.0 with --migrate-v04, empty v0.4.0 → v0.4.1 with --migrate-v041, empty v0.4.1 → v0.4.2 with --migrate-v042, empty v0.4.2 → v0.5.0 with --migrate-v050, empty v0.5.0 → v0.6.0 with --migrate-v060, v0.6.0 → v0.6.1 with --migrate-v061 (projects may stay in place; no project schema changes), and v0.6.1 → v0.7.0 with --migrate-v070. Every migration is opt-in: without the explicit flag an existing v0.6.1 workspace stays v0.6.1 and no file is rewritten. Active projects are never silently rewritten. scaffold.py new registers the project in index.md; add --profile pre-engineering-decision for a G3 decision endpoint, --profile gated-high-risk for the full risk path, or --profile portfolio-competition for the v0.5 evaluator-first portfolio path. A rewrite must keep the same verdicts: lint.py --selftest plus tests/test_v030.py, tests/test_v040.py, tests/test_v041.py, tests/test_v042.py, tests/test_v050.py, tests/test_v060.py, tests/test_v061.py, tests/test_v070.py, tests/test_v070_correction.py, and tests/test_v070_review2.py cover legacy, evidence/safety, Ship-First, safe pre-engineering, independent promotion, evaluator-first portfolio, enforced-evaluation, and gated-invocation boundaries. Two installers that disagree on what passes are two different methodologies wearing one version number.

The scaffolder pre-creates every numbered document as a headed skeleton — an empty 03_EVIDENCE.md in a fresh project is a to-do, not litter, and link-closure still applies to it: every phase document is reachable from the project’s PROGRESS.md.

Step 2 — Interview → contract. See Phase 0 above for the full question set, the triggers, and the five exit tests. Preserve the answers verbatim with IDs in the new project’s raw/, then organize them into the contract and confirm with the user. Do not skip this and write the contract from inference — that is the single most expensive shortcut in this document.

Additionally: set the three permission tiers (unattended = read-only, always; reversible = backup first; irreversible = explicit re-confirmation) and a measurement baseline (measure the current value once, now).

Step 3 — Engrave the constitutions. In the workspace constitution (skeleton of six parts — identity in one sentence / principles / how we work / permissions and limits / scope constraints / center), write the outer-loop protocol (Ingest·Query·Lint, wiki standards). In the shared project protocol (projects/CLAUDE.md), write the Phase 0–6 gate, document, and log standards, plus the instruction: “Read the active project’s contract (00_CONTRACT.md) before starting any work. Work outside the contract only after contract-change approval.” Transfer only the rules needed, rewritten in the user’s own language — never copy this document wholesale. Purpose: a future session’s agent behaves by the methodology without ever seeing this file. The reference lint fails while either installation sentinel remains; deleting the sentence without replacing the protocol is not engraving. Step 4 — Verify the installation. Confirm all eight tools execute (policy.py and execution.py arrived in v0.7.0). Run python3 tools/lint.py --selftest; validate one phase packet; create the first project and complete Phase 0; run python3 tools/lint.py --through P0 .; then prove workflow.py scratch-init and promote --through P0 on a disposable copy. Demonstrate rejection of target drift, existing-raw mutation, an oversized contract, a stale artifact hash, a stale typed Gate evidence hash, and a missing requirement verdict. Report executed verdicts, not intentions.

Principles


About LDL

LDL — LLM Delivery Loop. Maintained by @daniel-kjseo. MIT licensed — use it, fork it, rename it to fit your team.

Found this useful, or ran it on a real project? Open an issue with what broke — every failure becomes a rule in RULES.md, which is the whole point.