LazyZCode Documentation

English · 简体中文

The complete guide to the discipline layer for ZCode: plan → execute → take evidence → never stop half-done.

Install Installation · Recommended environment
Getting started Overview · Your first goal loop · FAQ
Triggers & protocol Trigger words · The zw protocol · Goal loop commands
Concepts The plan gate · Evidence discipline · The continuation budget · Discipline agents · Hooks & lifecycle · Rate-limit discipline
Reference CLI reference · Diagnostics · State & configuration · Compatibility & limitations

Installation

One package installs both halves of LazyZCode: the lazyzcode:zw plugin (skills, hooks, agents) and the lzy CLI (the goal-loop state machine).

Prerequisites

Install

npm i -g lazyzcode
lzy install

lzy install does three things: deploys the plugin payload to the engine's plugin cache, writes LazyZCode's own registry entry, and enables the plugin through the engine's official plugins enable command. It never writes your config.json — enabling flows only through the engine's own CLI (ADR-0001).

Verify it worked

lzy status   # quick check; exit code 0 = no fail-level findings
lzy doctor   # deep local diagnostics (zero telemetry)

Inside a fresh ZCode session, type zw at the start of a prompt — the orchestration bootstrap should arrive, and the model's first line should read **ZW** engaged — LIGHT tier (or HEAVY).

Uninstall

lzy uninstall

Removes the deployed cache and the registry entry, preferring the engine's official plugins uninstall path.

Item Recommendation Notes
Operating system macOS, Windows, or Linux Engine layout detection covers all three (ADR-0011).
ZCode app Desktop, logged in Hooks and the plugin load through the desktop engine.
Node.js ≥ 22, via nvm or Homebrew The hook-node doctor check reports exactly which resolution path your hooks will use.
Project A git repository Evidence binding requires commits to exist; F-item evidence is captured after a commit.
Launch style Either Launching ZCode from the terminal or the Dock both work; the Dock case is handled by the run-hook launcher.

Overview

LazyZCode installs four things:

  1. One plugin (lazyzcode:zw) whose skill text carries the full orchestration protocol — triage, tier selection, planning, execution, and evidence rules.
  2. Six hooks wired to the engine's lifecycle: SessionStart (re-inject loop state), UserPromptSubmit (trigger words), PreToolUse (command-layer H3R gate — dormant prototype), PostToolUse (comment advisory), PostToolUseFailure (same-tool failure tripwire), Stop (bounded continuation).
  3. Three read-only agents: lazyzcode:explorer, lazyzcode:plan-reviewer, lazyzcode:qa-executor.
  4. One CLI (lzy) implementing the goal loop as a state machine that survives session restarts: register → plan gate → execute → evidence → finish gate.

The mental model: a plan checkbox is a claim; only real-surface evidence is a fact. LazyZCode's job is to make the agent convert claims into facts — and to pull it back when it tries to stop before that conversion is complete.

Your first goal loop

Open a fresh ZCode session in your project and type:

zw implement a CSV export endpoint with tests

What happens:

  1. The UserPromptSubmit hook matches the sentence-initial zw and injects the orchestration bootstrap.
  2. The model announces **ZW** engaged — <tier> tier and triages the task (see The zw protocol).
  3. It registers a goal with the CLI (lzy loop register …) and writes a plan file into .lazyzcode/plans/.
  4. The plan is adopted through the plan gate — HEAVY plans must first pass the lazyzcode:plan-reviewer agent.
  5. The model executes step by step, calling lzy step done <ID> as steps complete. F items require --evidence bound to the current tree hash.
  6. lzy loop finish runs the final gate: all steps done, all evidence fresh. Only then is the goal complete.

If the model stops while the loop is open, the Stop hook pulls it back — at most 2 continuations per session. To resume after an interruption (including a rate-limit kill), just send zw continue (zw 继续); the loop state in .lazyzcode/ is untouched.

To free the slot after a finished loop, run lzy loop reset.

FAQ

Where does LazyZCode keep its state? In .lazyzcode/ inside your project (loop state, plans, archived evidence). It is deliberately separate from ZCode's own .zcode/. Add it to your .gitignore if you do not want to commit it.

Does it phone home? No. Zero telemetry. Everything lzy doctor reports is computed locally from your own files and engine logs.

Does it write my config.json? Never. Enabling goes through the engine's official plugins enable; the installer only deploys files and writes LazyZCode's own registry.

Why didn't my zw trigger? Matching is stratified: a bare zw fires only at the start of the prompt. Mid-sentence zw is ignored (that is intentional — "check the zw hooks" is a question, not an invocation). Use the explicit lazyzcode:zw anywhere, or ulw/ultrawork anywhere word-bounded.

Why did lzy loop finish reject my evidence? Evidence is bound to the tree hash of the commit that was current when it was captured. If you changed code after capturing, the evidence is stale by construction — commit, then re-capture with lzy step done <ID> --evidence ….

I hit [1302] rate limit. Is LazyZCode broken? No — that is the GLM plan's account-level concurrency limit. lzy doctor's rate-limit line reports your measured pressure and a suggested session budget. See Rate-limit discipline.

My hooks do nothing at all. Your engine was probably launched without node on its PATH (common when ZCode.app starts from the Dock). The bundled run-hook launcher resolves node automatically — nvm/Homebrew on POSIX, nvm-windows/Program Files on Windows; lzy doctor's hook-node line tells you what it found. Details in docs/diagnostics/2026-09-07-hook-spawn-env.md.

Can I run two goal loops at once? One loop per project directory. A finished loop still occupies the slot until lzy loop reset clears it.

Can I use the CLI without the plugin (or vice versa)? Yes. The CLI works anywhere; the plugin needs the engine. The workflow works best with both — the hooks and skill text drive the discipline that the CLI enforces.

Trigger words

Trigger Fires Example
zw Start of the prompt only (leading whitespace allowed) zw fix the flaky test
lazyzcode:zw Anywhere; full-width colon accepted explain what lazyzcode:zw does*
ulw / ultrawork Anywhere, word-bounded ultrawork this refactor
/zw or the Skill tool Explicit invocation

* that example does not engage the loop — it is a mention. Injection is conditional: an invocation engages the protocol; a mere mention is ignored and answered directly ("Mention ≠ invocation"). zwift, azw, and mid-sentence zw never fire.

The zw protocol

The injected skill text (plugin/skills/zw/SKILL.md) defines the contract the model follows:

  1. Open with exactly **ZW** engaged — <LIGHT|HEAVY> tier.
  2. Triage the tier. LIGHT for small, contained, low-risk work (a 1–2 item plan, one F item). HEAVY for multi-file features, architecture, or anything risky or vague — explore first, plan every step. Escalating LIGHT → HEAVY is always allowed — and persisted: register with --tier heavy or run lzy loop tier heavy before adopting (the HEAVY review gate is enforced by the machine off the persisted tier). Downgrading is never allowed.
  3. Register the goal with the CLI.
  4. Plan with an N/F checklist (see The plan gate).
  5. Execute step by step, committing work and calling lzy step done <ID> with notes — and evidence for F items.
  6. Capture evidence on real surfaces (see Evidence discipline).
  7. Finish through the CLI gate (see Goal loop commands).

The protocol also carries behavioral red lines (no fake evidence, no silent scope abandonment) and the rate-limit rules below.

Since 0.1.0 the protocol text also annotates enforcement levels — L0 protocol convention, L1 CLI machine gate, L2 trusted host event, L3 external effect — so a reader always knows whether a rule is kept by promise or by machine, and carries a second axis next to tier: risk_class (LOW / MED / HIGH / RESTRICTED, upgrade-only), with HIGH+ barred from unattended lanes and RESTRICTED a hard block. Approvals bind immutable hashes (INV-05): plan adoption binds planHash at L1; a conversational nod stays L0 until the exact-hash human gate lands.

Since 0.1.1 pull-back is claim-gated: only a session that claimed the goal (an invocational trigger like zw 继续) is subject to Stop pull-backs; an empty claim set means nobody is pullable, so bystander sessions are structurally exempt. A session can opt out explicitly with zw standdown — a standdown flag makes the Stop hook release that session read-only until a claiming trigger clears it or the goal is reset. And the host workspace must be a git repository: lzy loop register hard-rejects a non-git host with git init guidance, because evidence binds git trees and a non-git host cannot pass finish (ADR-0019).

Goal loop commands

lzy loop register <slug> --title "…" [--tier heavy]   # planning state; tier defaults to light
lzy loop plan <file> [--review "…"] [--force]
lzy loop start                          # records the base tree hash + prints the measured 并发纪律 advisory
lzy loop subject add <path>             # declare a sibling repo root (executing-only; validated: git repo, no containment)
lzy loop subject remove <path>          # remove a subject (missing-deadlock escape; evidence invalidation semantics apply)
lzy loop subject list                   # list the subject set (empty = host-only)
lzy loop tier heavy                     # tier upgrade, one-way (machine gate is adoption-time)
lzy loop claim [<id>] [--release]        # per-step claim (anonymous, 48h mutex); bare lists claimable steps
lzy step done <ID> [--note "…"] [--evidence "…"] [--evidence-file <file>]…
lzy loop status                         # progress, next step, evidence freshness, tier/subjects/snapshot
lzy loop verify                         # evidence freshness audit (exit 1 = stale/unbound); prints per-tree head/dirty lines
lzy evidence red <Fid> --evidence "…"   # red half on its own surface (waive-red --reason = machine exemption)
lzy dag dependents <id|surface>         # "what depends on X" (central ledger, read-only)
lzy dag stale                           # invalidation preview vs current fingerprint (display-only)
lzy attest comparator --file <json>     # comparator verdicts as attestation (HEAVY finish enforces MATCH)
lzy loop finish                         # the final gate: all done + fresh evidence + all trees clean (+ HEAVY: MATCH attestation); writes the final attestation and auto-archives
lzy loop export                         # re-export the evidence bundle
lzy loop handoff --snapshot <file>      # register a clean handoff; next Stop releases once
lzy loop cost                           # points report (standing coefficients + promo overlay, read-only)
lzy loop list [--root <dir>]            # read-only sweep of sibling repos' goal loops
lzy loop history                        # goal lineage (evidence ∪ stubs ∪ trailers, read-only)
lzy loop abandon | lzy loop reset       # give up / clear state

The plan gate

Plans are markdown checklists with two item kinds:

- [N1] Implement the export endpoint in src/api/export.ts
- [N2] Add CSV serialization with quoting rules
deps: N1
- [F1] `curl localhost:3000/export` returns 200 and parses as CSV (qa-executor)

Known unknowns

Decision-complete means no undecided choices — not no unverified premises. A HEAVY plan therefore ends with an explicit known-unknowns section: 1–3 assumptions the plan silently rests on, each with a falsification path (the signal that would prove it wrong, and how to check). Writing "none" is allowed, but must say in one line where you looked.

The section complements the plan gate rather than softening it: it states unverified premises, not postponed decisions — and the gate still scans every line of it, so an actual TBD inside the section is rejected like anywhere else. The plan-reviewer audits it against hidden risks: is every entry falsifiable, and is a "none" credible?

Evidence discipline

The continuation budget

ZCode grants each session a shared pool of 3 stop-continuations, which background task notifications also draw from. LazyZCode's Stop hook spends at most 2 per session, deliberately reserving 1. Counters are isolated per sessionId (a probe that counted globally once hijacked an unrelated session — that constraint is now structural). Any hook error fails open: the loop never traps a session it does not own, and the user's explicit stop always wins once the budget is spent.

SessionStart re-injects the loop state, so a fresh session continues where the previous one stopped.

Project memory

Planning heavily against a codebase nobody has mapped wastes the plan gate. lazyzcode:init-deep, the plugin's second skill, builds layered project memory: a root AGENTS.md map plus maps for qualifying subdirectories (build entry points, directories with 40+ files, directories the root already mentions). ZCode reads AGENTS.md natively, so the map rides into every future session — no hook required.

The skill is conservative by contract: it drafts first and writes only after your approval; existing files receive patch suggestions, never overwrites; secrets and machine-local paths stay out. It touches only the AGENTS.md layer — personal lessons go to the host's native memory at a zw finish.

lzy agents-md lists qualifying directories and coverage gaps; lzy doctor's agents-md line audits adoption (warn-only: a repo without a root map is skipped, not nagged). HEAVY planning consults the map when one exists.

Unattended

Unattended mode is the same goal loop on a schedule. The engine's built-in automation wakes a fresh session with zw continue (unattended: …); the wake cadence is off-peak by design — lzy doctor's schedule line derives an 8-hour window opposite your measured rate-limit concentration hours, then cross-checks it against known platform pricing peaks (GLM / DeepSeek, a static UTC+8 table maintained by hand) and always states the pricing-safe nightly window. The table can go stale — treat the line as measured rate-limit data plus declared pricing, not a guarantee.

The guardrail is structural, not a promise: an unattended session continues the open goal only — it never registers a new goal and never writes or adopts a plan, because the decision-complete gate needs a human. With nothing to continue it exits cleanly, and the wake-up itself is bounded by the continuation budget, fatal-429 handling, serial subagents, and ≥1-hour spacing between runs.

Since 0.2.0 a wake-up also has an in-wake execution channel: lzy loop drive spawns headless engine segments inside one wake and pushes the executing goal segment by segment. Between segments it checks the gates — the run holds a minutes-scale lease (one runtime holder at a time, renewed by heartbeat), each run gets a fresh wall-clock + points budget, and HIGH+ risk goals are machine-rejected before anything spawns. Every segment's lzy writes carry the run's fence token, so a taken-over run fails closed on write instead of corrupting loop state. Wind-down is clean and enumerated: done, budget exhausted, segments exhausted, two zero-progress segments (stuck) — plus two wind-down causes that exist only in the dormant H3R prototype's lane (they never fire with the prototype asleep): the step gate stopping at a high-risk step (h3r), or a high-risk command denied at the tool boundary (PreToolUse) — every non-done wind-down writes the 7-field handoff snapshot itself and registers the marker for the next session. lzy doctor's drive line reports the channel's availability on your machine:

lzy loop drive [--wall-ms N] [--max-segments N] [--mode m] [--workers N | --fast]

Workers (0.2.4). lzy loop drive --workers N (or the --fast sugar, N=2) runs N worker chains per wave on sibling worktrees: steps are split by the claim gate, each worker commits inside its own worktree, and the wave ends with a merge back plus a barrier re-anchor of all evidenced F items. A merge conflict winds down cleanly and leaves the branches for a human. Entry requires env-auth and the H3R wake switches to be off; the measured cost is turns ≈2× with small tasks possibly slowing down — read the experiment report (docs/reviews/2026-fast-exp-report.md §1.3) before enabling.

The host automation stays the only scheduled wake face — drive is what runs once awake (and what you can run yourself in an unattended window).

No need to wait for your laptop for the overnight digest: push the results to your own IM bot webhook (zero servers — lzy ships no notification channel of its own). Recipe: unattended notify.

Discipline agents

Three read-only roles ship in the plugin's agents/ directory and are auto-discovered by the engine. Spawn them via the Agent tool with the role as subagent_type:

Role Use it for
lazyzcode:explorer Pre-plan reconnaissance: map the relevant code area, answer the planner's questions with file:line evidence. Can use a codegraph index on large repos.
lazyzcode:plan-reviewer The plan review gate: audits decision-completeness, N/F well-formedness, real F-item surfaces, hidden risks. Returns VERDICT: PASS or VERDICT: REVISE.
lazyzcode:qa-executor Evidence execution: run one F-item verification on the real surface and report exactly what it observed — commands and raw output. It fights evidence fabrication.

All three are read-only: they never edit code, and their value is that their findings come from the repository, not from the main agent's assumptions.

Hooks & lifecycle

Hook Event Does
session-start.js SessionStart Re-injects goal-loop state so a new session picks up where the last stopped.
trigger.js UserPromptSubmit Stratified trigger matching; injects the zw bootstrap on invocation.
comment-checker.js PostToolUse (Edit/Write) Advisory detection of TODO/FIXME/XXX/HACK markers and debug residue (console.log, console.debug, debugger) in new content. Capped at 5 hits, 300 characters, inject-only — and only active in workspaces with an open goal loop.
stop.js Stop Requests continuation (max 2/session) with the remaining-steps context while a loop is open; consumes a registered handoff marker once and releases without spending the budget.
tripwire.js PostToolUseFailure Same-tool failure-streak tripwire: warns once when a tool keeps failing or firing off-target (the misfire-attractor escape hatch); inject-only.
h3r-pretool.js PreToolUse (Bash) The command-layer H3R gate, dormant by default: inside an unattended lzy loop drive segment (the drive-injected LZY_SEGMENT_ID is present) and awake only when LZY_ABLATE_H3R_PRETOOL is 1 — the inverse of the LZY_ABLATE_* family — it denies Bash commands whose text matches the H3R word list and writes the hit marker drive consumes for a clean wind-down (7-field snapshot, exit 0). Interactive sessions carry no drive-injected segment id — exempt given env hygiene (the gate validates the <int>:seg-<int> shape, so a stray export degrades to no gate), and they are the recovery path (ADR-0022).

All six commands route through plugin/hooks/run-hook: the engine spawns hooks with its own environment, and a GUI-launched ZCode may have no node on PATH. One manifest line serves both platform families — POSIX shells execute the extensionless run-hook script, while on Windows cmd.exe resolves the same name to the run-hook.cmd twin via PATHEXT. The launcher falls back to nvm (highest version) and Homebrew locations on POSIX (nvm-windows and Program Files on Windows), logs to /tmp/lzy-hook-launcher.log (%TEMP%\lzy-hook-launcher.log on Windows), and exits 0 (fail-open) if everything is missing. lzy doctor's hook-node check reports the resolved path.

Rate-limit discipline

GLM plans enforce an account-level concurrency limit ([1302] / 429). There is no fixed threshold you can configure around: measured headroom varies by plan tier, time of day, and account state — lzy doctor measures it from your engine logs (last 2 days) and reports deduplicated 429 turns, fatal turns, the longest sustained run, and — when the data is coherent — an empirical concurrency band ("N sessions clean / M sessions collide"). Warn only; it never flips the exit code.

Behavioral rules the zw skill carries:

Unattended (host automation): scheduling and the continue-only protocol live in Unattended; the window comes from lzy doctor's schedule line — your own measured concentration hours cross-checked against declared pricing peaks, not a guess.

CLI reference

Project memory: the lazyzcode:init-deep skill generates a layered AGENTS.md map (root + qualifying subdirectories), drafts first — nothing is written without your approval; lzy doctor patrols coverage on every run.

lzy install                     deploy plugin + registry + official enable
lzy sync [--watch]              re-deploy payload (hot reload; --watch keeps watching)
lzy status                      quick health check (exit 0 = no fail-level findings)
lzy doctor                      deep local diagnostics (zero telemetry)
lzy uninstall                   remove cache + registry entry
lzy loop register <slug> --title <t> [--tier heavy]   create the goal (planning; HEAVY adoption without PASS review is machine-rejected)
lzy loop plan <file> [--review <v>] [--force]   adopt the N/F checklist (snapshots plan + binds planHash)
lzy loop supersede <file> [--review <v>]   forward-only plan change mid-execution (supersedes the attempt, opens attempt+1, gates re-run)
lzy loop start                  planning → executing; records base tree hash + 并发纪律 advisory
lzy loop subject add <path>     declare sibling repo root (executing-only; validated, dedup'd)
lzy loop subject remove <path>  remove a subject (missing-deadlock escape)
lzy loop subject list           list the subject set
lzy loop tier heavy             tier upgrade, one-way (adoption-time machine gate)
lzy loop claim [<id>] [--release]  per-step claim (multi-worker; blocked-step checks; 48h mutex)
lzy loop risk <level>              risk_class upgrade (low|med|high|restricted; one-way; ADR-0020)
lzy loop lease acquire|heartbeat|release|reclaim  run-level lease (minutes-scale mutex; fence token;
                                  reclaim = zombie-lease exit; ADR-0020)
lzy loop budget init|spend|remaining  drive budget (wall-clock + points double cap; ADR-0020)
lzy loop status                 progress, next step, evidence freshness, tier/subjects/snapshot
lzy loop verify                 evidence freshness audit (exit 1 = stale/unbound/no goal); per-tree head/dirty lines
lzy step done <ID> [--note <t>] [--evidence <t>] [--evidence-file <f>]…
lzy loop finish                 final gate: all done + fresh composite fingerprint + all {host}∪subjects trees clean; atomic archive
lzy loop export                 re-export the evidence bundle (<slug>.report.md)
lzy loop cost                   points report (coefficients + promo overlay, read-only)
lzy loop list [--root <dir>]    cross-repo goal-loop sweep (read-only)
lzy loop history                goal lineage (evidence ∪ stubs ∪ trailers, read-only)
lzy loop attempts               attempt lineage (attempt.json ∪ central ledger derivation, read-only)
lzy loop abandon                give up, keep the record
lzy loop reset                  clear loop state (incl. session counters, orphan tmp)
lzy agents-md                   layered AGENTS.md audit (exit 1 = gaps/overcaps)
lzy version                     print version

Flags: --note is capped at 300 chars, --evidence at 4000, --evidence-file is repeatable (≤4 per F item, each ≤20 MB); --force=true and --force are equivalent; --watch=<value> warns (it takes no value).

Diagnostics

lzy status runs the base checks; lzy doctor runs those plus the deeper ones. Exit code: fail findings flip it to 1; warn and skip never do.

Check Meaning
payload Repo plugin manifest readable
install Registry entry present and healthy
files Deployed cache matches the repo payload, file by file
enabled The engine lists the plugin as enabled
codegraph Codegraph MCP/CLI availability (absence = skip)
loop Goal-loop progress in this directory (skip when none; warns while a loop is open)
hooks Hook syntax self-check (vm-parsed in a worker) + hooks.json registry validation
node Node version floor (≥ 22)
hook-node Which path the hook launcher resolves node from
lzy-path Whether lzy resolves on PATH
state .lazyzcode/ hygiene (orphan temp files, goal state)
claims Claim patrol: who claimed the open goal loop, stuck markers; zero claims = nobody is pullable under claim-gated pull-back (warn, never flips the exit code)
host-git Host workspace is a git repository (warn with git init guidance when not — evidence binds git trees, ADR-0019)
handoff Handoff marker present (the next Stop consumes it and releases)
handoff-usage Anonymous release counters, registered/consumed (survive reset)
ledger Commit-ledger patrol: share of goal-era commits missing the Goal: trailer (warn, never flips the exit code)
waterline Rolling 5-hour point burn vs the self-calibrated nudge threshold (degraded note when sqlite3 is absent)
orphan-wake Idle-burn patrol for unbound wake automations anchored here (skip when none mounted)
h3r-words The H3R word-list payload: present, schema-valid, and the same order the CLI's reader yields. Missing = warn — awake-time behavior splits by reader: the drive-side gate hard-rejects (throws); the command-layer hook fails open (ADR-0022's failure semantics)
lock Lock-contention window: acquisitions / how many had to wait / total and max wait / wait timeouts (measured against LOCK_WAIT_MS; skip with no samples; timeouts > 0 means §⑩-4's pre-registered trigger fired — warn). Readings are lower bounds: the counters ride a lock-free read-merge-write, and the moment a delta is most likely to be lost is the moment contention is heaviest
platform Engine-candidate notice per platform (ok + path when the desktop engine is found)
agents-md Layered AGENTS.md coverage audit + staleness hint (≥50 covered-dir commits since the map's last commit; skip when no root file; lzy agents-md for details)
rate-limit GLM plan 429 pressure from the last 2 days of engine logs
transport Transport deaths (request-never-reached-server failures, e.g. ENETDOWN): counted as a separate family, never fed into the concurrency math
content Content-moderation kills (provider content-filter mid-stream kills, e.g. 1301): counted as a separate family; an in-place retry reproduces, never fed into the concurrency math
band-by-provider Per-provider empirical band (completed-side clean × 429 dirty buckets); emitted only when the window has ≥1 429 and ≥2 providers — providers without 429s of their own are honestly labeled "no dirty-face sample"
cost Model-tier advisory ("success → try lighter tier"): a zero-429 window with a low rolling waterline suggests a lighter tier for routine goals; advisory text only
schedule Off-peak advisory: automation window from the measured concentration, cross-checked against declared pricing peaks with a safe-window note; hand-maintained UTC+8 pricing table (skip without evidence)

State & configuration

LazyZCode has no configuration file. Everything is derived:

Path Contents
.lazyzcode/loop/goal.json Current goal: steps, statuses, evidence bindings
.lazyzcode/loop/sessions/<sessionId>.json Per-session Stop-hook counters
.lazyzcode/loop/salvage/<slug>.md Salvageable-artifact stubs written when a loop is reset/abandoned (uncommitted changes, footnoted commits, asset pointers); lzy loop status surfaces them in both the no-goal and goal-present views
.lazyzcode/plans/<slug>.md Plan documents
.lazyzcode/evidence/ Archived evidence material
engine plugin cache Deployed payload (managed by lzy install/sync)
LazyZCode registry Install records (managed by the installer)

Environment: LZY_ZCODE_ENGINE replaces the default engine candidate list (default: /Applications/ZCode.app/Contents/Resources/glm/zcode.cjs). That is the entire configuration surface.

Privacy: zero telemetry; diagnostics are computed locally and printed locally.

Compatibility & limitations

Security & trust surface

What LazyZCode runs on your machine, where it installs, and what it deliberately does not defend against:


LazyZCode is MIT-licensed. The workflow is inspired by lazycodex (MIT); oh-my-openagent (OmO, SUL-1.0) contributed ideas only. Documentation structure follows the lazycodex docs with credit.