Skip to content
PakhomLeoPublic

About

Plan-first workflow for AI coding agents: the agent writes a short plan, stops for your approval, builds, then checks once. Ships a SKILL.md skill (Qoder and other clients) and a DSH quick dev mode, with one safe installer for bash and PowerShell.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

plan-gate

English | 简体中文

A plan-first workflow for AI coding agents. It does not change how the agent writes code. It controls when the agent may start: the agent writes a short plan, stops, waits for your approval, builds, and runs its checks once at the end.

The project ships two components from one repository and one installer:

Component For What you get
skill Qoder, and any agent client that reads the SKILL.md format The workflow skill: SKILL.md plus four document templates
dsh DSH (DeepSeek Harness) A "quick dev" agent mode next to the built-in standard mode: the same skill, a small plugin that opens plan mode when a plan is due, and the mode declaration

This project merges two earlier repositories, dsh-quick-dev and code-project-flow. See History and Migrating from dsh-quick-dev or code-project-flow.

The project is called plan-gate; the skill it installs is still called code-project-flow. See Skill name.


Contents


Why

AI-assisted coding tends to fail in four ways:

Failure What it looks like
Writes before agreeing Requirements are still fuzzy, twenty files already changed
Drifts further each round The same spot breaks again, so it grows another branch, wrapper or flag
Context blowup Every new session re-reads the whole repository, mostly detail this task never touches
Fake green Tests mock around the real path; it passes locally and breaks when it ships

The workflow answers them with four documents, five phases and four overriding principles, and turns "may I start?" into an explicit approval step instead of a vague "go ahead" in the chat.


How it works

Five phases

Five phases: read, write brief, confirm, build, close out

  1. Read – the rules and design documents first. If the design document does not exist, the agent drafts it from the actual shape of the code, not an ideal one, and leaves the structure and the two flows for you to review.
  2. Write the brief – TASK.md, in plain language (the ASD-STE100 simplified-technical style: short sentences, one word for one thing, active voice), with exactly seven sections: why; how, down to functions and paths (files not listed must not be touched); what it touches; what not to do on the side; conflicts with the design document; details that need your sign-off; acceptance boundary. Then it stops.
  3. Confirm – until you explicitly say go, nothing changes. "Keep refining" sends your feedback back to the brief.
  4. Build – if the brief lists a conflict with the design document, that sentence goes into the design document first. No tests and no harness runs while building.
  5. Close out – one run only: check the round against the brief's acceptance boundary, then run every registered harness with real data, no fake mocks. A failure is fixed in the code; registered checks are never loosened or deleted to get a green result. The agent then proposes write-backs to the design and harness documents, with before and after sentences. They are written only if you agree, and a "no" is never asked twice. Finally TASK.md is deleted.

Four documents

The four documents and where they live

File Who writes it What it owns
Doc 1 AGENTS.md You only Agent rules, the four overriding principles, who owns what
Doc 2 MAP.md Agent proposes, you approve Design: feature choices, project structure, user flow, data flow (eight fixed sections)
Doc 3 HARNESS.md Agent proposes, you approve Registered regression loops ("harnesses"); their code lives in harness/
Doc 4 TASK.md Agent writes, you confirm, deleted at close-out This round only, down to functions and paths (seven fixed sections)

Where the documents live depends on the component:

  • skill: AGENTS.md in the project root, the other three under docs/ (docs/MAP.md, docs/HARNESS.md, docs/TASK.md).
  • dsh: all four in the project root. DSH auto-loads instruction files by bare file name while walking up from the working directory, so a file in a subfolder would never load. The installer renders the skill for this layout; the source is the same.

The documents are also the workflow's state. A new session reads Docs 1–3 and knows which step it is on, without chat memory. Templates: references/.

Four overriding principles

They live in Doc 1 and win over any other instruction:

  • No patches – fix the place that produced the error; no extra branch, wrapper, compatibility layer, flag or special case next to it.
  • Self-explanatory code – names and structure say what the code does; comments only hold what a reader would guess wrong (why, who calls it, what it guarantees).
  • No residue – unused functions, files, flags, commented-out code, stale harnesses and the task brief are removed at close-out.
  • Deployment parity – the path that works locally is the path that ships; no per-machine special cases, no fake data.

Language

SKILL.md, the four templates and the DSH mode's built-in guidance are Chinese. This README explains them in English. The agent reads Chinese rules and fills Chinese templates; your code and comments stay in your project's language. Pull requests adding English templates are welcome (see CONTRIBUTING.md).


Install

Components and install targets

Requirements: bash (macOS, Linux, WSL, Git Bash) or PowerShell 5.1+ on Windows, and git to clone. For the dsh component, DSH must have been started at least once, so that profiles/ exists.

Recommended: clone, then run

git clone https://github.com/PakhomLeo/plan-gate.git
cd plan-gate
./install.sh --dry-run      # see what would change
./install.sh                # install the auto-detected components
git clone https://github.com/PakhomLeo/plan-gate.git
cd plan-gate
powershell -ExecutionPolicy Bypass -File .\install.ps1 -DryRun
powershell -ExecutionPolicy Bypass -File .\install.ps1

-ExecutionPolicy Bypass applies to this one process only; it does not change your machine's policy.

What it looks like: the real output of ./install.sh from v1.0.0, run with no options in a temporary HOME (/tmp/demo), followed by a listing of the installed files.

Terminal: ./install.sh auto-detects the skill component and installs code-project-flow into ~/.qoder-cn/skills; the listing shows SKILL.md, LICENSE, .plan-gate-manifest and the four templates under references/

Options

install.sh install.ps1 Meaning
--components skill,dsh -Components skill,dsh What to install: skill, dsh or all. Default: auto-detect (see below)
--skills-dir DIR -SkillsDir DIR (alias -SkillsRoot) Skills folder for skill. Default: ~/.qoder-cn/skills, or ~/.qoder/skills
--dsh-home DIR -DshHome DIR DSH home for dsh. Default: $DSH_HOME, then ~/.dsh
--uninstall -Uninstall Remove what the installer installed
--migrate-legacy -MigrateLegacy Move installs made by the earlier installers to a backup folder, then continue
--dry-run -DryRun Print planned changes, change nothing

Auto-detect picks skill when a Qoder skills folder exists or --skills-dir is given, and dsh when $DSH_HOME/profiles exists or --dsh-home is given. With neither, it installs skill into ~/.qoder-cn/skills. If the skill is already installed under ~/.qoder/skills, updates go there.

Exit codes: 0 done, 1 error, 2 bad arguments, 3 finished but skipped a step (for example an earlier install that needs --migrate-legacy).

Other agent clients

Any client that loads SKILL.md skills from a folder can use the skill component:

./install.sh --components skill --skills-dir /path/to/your/client/skills

Start a new agent session afterwards; skills load at session start.

Alternative: one-line install from a release (download, verify, run)

Every release has these assets, built by .github/workflows/release.yml with scripts/make-release.sh:

Asset What
plan-gate-vX.Y.Z.tar.gz, plan-gate-vX.Y.Z.zip The tagged source tree, including both installers
install.sh, install.ps1 The same installers as separate files
SHA256SUMS sha256 of the four files above

The checksums are a release asset. They are not a file committed to the repository, and they verify the downloaded release assets only. They protect against a broken or altered download. They do not protect against a compromised GitHub account, because the checksums come from the same place. The commands below download the archive, check it, and only then run the installer from the extracted folder, so nothing else is fetched.

macOS / Linux (use shasum -a 256 -c - instead of sha256sum -c - on macOS without coreutils):

V=v1.0.0; B=https://github.com/PakhomLeo/plan-gate/releases/download/$V
mkdir -p plan-gate-dl && cd plan-gate-dl \
  && curl -fsSLO "$B/plan-gate-$V.tar.gz" && curl -fsSLO "$B/SHA256SUMS" \
  && grep " plan-gate-$V.tar.gz\$" SHA256SUMS | sha256sum -c - \
  && tar xzf "plan-gate-$V.tar.gz" && bash "plan-gate-$V/install.sh"

Windows (PowerShell):

$V = 'v1.0.0'; $B = "https://github.com/PakhomLeo/plan-gate/releases/download/$V"; $f = "plan-gate-$V.zip"
Invoke-WebRequest "$B/$f" -OutFile $f; Invoke-WebRequest "$B/SHA256SUMS" -OutFile SHA256SUMS
$want = (((Get-Content SHA256SUMS) -match "  $([regex]::Escape($f))$") -split '\s+')[0]
if ((Get-FileHash $f -Algorithm SHA256).Hash -ne $want) { throw 'SHA256 mismatch: do not run it' }
Expand-Archive $f -DestinationPath .
powershell -ExecutionPolicy Bypass -File ".\plan-gate-$V\install.ps1"

Add installer options at the end of the last line, for example --components dsh or -Components dsh. To check a file you already downloaded: sha256sum -c --ignore-missing SHA256SUMS (Linux), shasum -a 256 -c --ignore-missing SHA256SUMS (recent macOS), or Get-FileHash FILE -Algorithm SHA256 and compare with the line in SHA256SUMS (Windows).

Make it the default (Qoder)

Installing only makes the skill available. To route every coding task through it, add this to your global ~/.qoder-cn/AGENTS.md (or a project's AGENTS.md). Keep it verbatim; it matches the skill's Chinese trigger description:

凡写代码、改代码、把功能落到仓库的任务,默认使用 skill code-project-flow。
开工先写 docs/TASK.md 并停下等确认。

Without that line, the skill fires on words such as 开工 (start work), 收工 (close out), MAP, 当次说明 (task brief) or harness, or when you ask for it by name. The installer never edits your AGENTS.md.

Update and uninstall

Update: pull the checkout and run the installer again. It rewrites only the files listed in its .plan-gate-manifest and removes files that an earlier version shipped and this one does not.

./install.sh --uninstall                  # or: --components dsh --uninstall
.\install.ps1 -Uninstall

Uninstall removes the files in the manifest, the plugin if its content matches a shipped version, and the preset block. A patch layer is then byte-for-byte what it was before. Files you added to the skill folder stay, and so does the folder.


Skill name

The repository and project are called plan-gate. The skill it installs keeps its old name, code-project-flow: the folder is skills/code-project-flow/ and SKILL.md says name: code-project-flow. The reasons:

  • The Qoder default line above says 默认使用 skill code-project-flow. Users have it in their AGENTS.md, and the installer never edits that file. A new name would silently turn that line off.
  • Existing installs live in skills/code-project-flow/. With the same name, an upgrade replaces the old skill in place, so the agent never sees two copies of the same workflow.
  • The trigger words and the DSH mode's guidance refer to the skill by this name.

For the same reason, the DSH preset id (preset-quick-dev), the plugin file (quick-dev-plan-arm.mjs) and the mode name stay as they were. Only names that never left the installer changed: the manifest is .plan-gate-manifest, backups go to ~/.plan-gate-backups/, and the piped-mode variables are PLAN_GATE_REF and PLAN_GATE_REPO_URL.


Migrating from dsh-quick-dev or code-project-flow

The installer recognises what the two former installers wrote, in the places they wrote it. This was checked against their source. The tests run the former installers, unmodified, to make real old installs and migrate them (see Development and tests).

What it recognises

Former installer What it wrote How the new installer recognises it
code-project-flow install.sh / install.ps1 A git clone --depth 1 of github.com/PakhomLeo/code-project-flow into <skills>/code-project-flow. <skills> was the first argument (-SkillsRoot), else ~/.qoder-cn/skills or ~/.qoder/skills. Updates ran git pull --ff-only. A skill folder (SKILL.md with name: code-project-flow) without .plan-gate-manifest, whose .git/config has that origin. Reported as code-project-flow git checkout.
dsh-quick-dev install.sh / install.ps1 $DSH_HOME/skills/code-project-flow/ (SKILL.md and references/, no marker file); $DSH_HOME/plugins/quick-dev-plan-arm.mjs; one - insert: block with id: preset-quick-dev in every profiles/*/cordis.patch.yml. An interrupted run could leave cordis.patch.yml.dsh-quick-dev.tmp. The skill folder without manifest under $DSH_HOME/skills/ (dsh-quick-dev copy). The plugin by its sha256: plan-gate ships the same file. The preset block by its id. The leftover by its name.
Copy by hand, or another git checkout A skill folder without manifest Reported as manual copy or git checkout of unknown origin.

$DSH_HOME defaults to ~/.dsh, as before. For each old skill folder, the installer also lists the files that the former installer did not write (your notes, for example). They are never removed: they stay in the folder, or move with it into the backup.

What it does

Item Without --migrate-legacy With --migrate-legacy (or "y" at the prompt)
Old skill folder Left untouched. Warning, exit code 3. For dsh, the plugin and preset are then not touched either. The whole folder, including .git and your files, moves to ~/.plan-gate-backups/<time>/. A fresh copy with a manifest is installed in the same place.
Plugin with the shipped content Replaced in place (same file). Same.
Plugin you edited Kept. Warning, exit code 3. Moved to the backup, then replaced.
preset-quick-dev block Replaced in place: one block per layer, the rest of the layer unchanged. Same.
cordis.patch.yml.dsh-quick-dev.tmp Reported only. Moved to the backup.

Nothing is ever deleted. Delete the backup folder yourself when you no longer need it. The installer also prints a note when it sees an old install in a place this run does not manage.

Commands

git clone https://github.com/PakhomLeo/plan-gate.git && cd plan-gate
./install.sh --dry-run                          # what it found and what would change
./install.sh --migrate-legacy                   # skill and dsh, as auto-detected
./install.sh --components dsh --migrate-legacy  # dsh-quick-dev only
./install.sh --components skill --skills-dir /path/to/skills --migrate-legacy  # a former first argument
git clone https://github.com/PakhomLeo/plan-gate.git; cd plan-gate
powershell -ExecutionPolicy Bypass -File .\install.ps1 -DryRun
powershell -ExecutionPolicy Bypass -File .\install.ps1 -MigrateLegacy
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Components dsh -MigrateLegacy
powershell -ExecutionPolicy Bypass -File .\install.ps1 -Components skill -SkillsDir C:\path\to\skills -MigrateLegacy

After migrating, ./install.sh --uninstall removes the new install, and every patch layer is again byte-for-byte what it was before dsh-quick-dev changed it.

What changed for existing users:

  • The skill is now copied, not cloned. git pull inside the skills folder is no longer the update path; pull this repository and run the installer again.
  • The dsh skill copy now uses the newest workflow text (plain-language replies in the ASD-STE100 style), which dsh-quick-dev already used in its mode guidance.
  • Positional ./install.sh /path/to/skills still works and prints a deprecation note; use --skills-dir.

The DSH quick dev mode

The dsh component adds a mode named 快速开发模式 ("quick dev"), shown second in the new-session picker. After installing, restart DSH and start a blank session; DSH only switches modes on a session without history.

What the installer writes into $DSH_HOME:

Where What
skills/code-project-flow/ The workflow skill, rendered for the project-root document layout
plugins/quick-dev-plan-arm.mjs Opens plan mode when a plan is due
profiles/*/cordis.patch.yml One top-level - insert: entry with id preset-quick-dev, in every existing profile

The mode declaration (dsh/preset/quick-dev.patch.yml) is a copy of DSH's standard mode plugin list with four changes: a persona suffix asking for plain-language replies, auto-loaded instruction files widened to AGENTS.md, CLAUDE.md, MAP.md, HARNESS.md, TASK.md with a 200 KB budget, a plan-mode prompt that explains the workflow and then restates every rule of DSH's standard plan-mode prompt (for example: agreement in the chat is not approval; no edits except the plan file, no commits, no formatters while planning; exit_plan_mode is the only way to submit; stay in plan mode if review is unavailable), and one extra plugin row. The other rows were copied unchanged from standard mode when the preset was written, so the tool list is the same.

When the plugin opens plan mode

The plugin (dsh/plugin/quick-dev-plan-arm.mjs) exists because a new DSH session starts outside plan mode and the model has no tool to enter it. It turns plan mode on for root agents when the working directory has AGENTS.md and no TASK.md, and again after a round's TASK.md disappears. It skips subagents, adds no tools, blocks no tool call, and only logs a warning if anything fails.

Known boundaries (by design):

  • Only blank sessions can switch modes (a DSH rule).
  • DSH lists the mode under "custom" in settings; the picker order comes from order: 1.5.
  • Modes do not inherit. When DSH updates its standard mode, this copy does not follow; re-check dsh/preset/quick-dev.patch.yml against new DSH releases.
  • The workflow is guidance, not a fence. It never removes tools per phase, because changing the tool table would invalidate the prompt cache.
  • DSH source code is not modified.

Security and permissions

Installers (install.sh, install.ps1):

  • Never use sudo or elevation. They write only to the chosen skills folder, the DSH home, and the backup folder (only with --migrate-legacy).
  • Overwrite or remove only what they installed: files listed in .plan-gate-manifest, a plugin whose hash matches a shipped version, and the one preset block. Anything else is reported and skipped.
  • Recommended install: clone and run. The release one-liner verifies the archive against the release's SHA256SUMS before it runs anything. Piping install.sh straight from the network into bash still works (it then clones the repository; PLAN_GATE_REF pins a tag), but nothing is verified, so it is not documented as an install method.

What the agent gets:

  • The skill is text only. Its front matter has name and description; it declares no tools, permissions or auto-approval.
  • The DSH mode uses the same tool rows as DSH's standard mode (shell, file system, web fetch, subagents and so on). It adds no tools, sets no sandbox or approval policy, and keeps DSH's own approval behaviour. In the preset, the plugin-manager tool, the external codex and claude-code subagent rows and tool-ralph are disabled.
  • The plugin only makes the agent more restricted (it turns plan mode on). Approving a plan is always your action.

Report vulnerabilities as described in SECURITY.md.


Customising

references/AGENTS.md is the template meant for you to edit; put your copy in the project root. The agent must not change it.

Note: the template is written for exploratory projects. While a project is in development, it tells the agent not to add extra security layers, retries or caching to temporary components. It also says the agent must not remove or bypass existing authentication, permission checks or input validation, and must still validate external input. For production code, review that paragraph and set your own bar.

SKILL.md is editable too, but it is the workflow itself; changes alter how the five phases run. Edit the source in this repository (with docs/ paths) and reinstall; the installer renders the DSH layout.

Good fit: exploratory projects where blocks may be thrown away; long-lived repositories that suffer from drift; wanting a plan before code. Poor fit: throwaway scripts, and requirements you expect the agent to discover by writing.


Repository layout

.
├── SKILL.md                     # skill entry point: the five-phase rules (Chinese)
├── references/                  # the four document templates (Chinese)
│   ├── AGENTS.md  MAP.md  HARNESS.md  TASK.md
├── dsh/
│   ├── preset/quick-dev.patch.yml   # DSH mode declaration (profile patch layer block)
│   └── plugin/quick-dev-plan-arm.mjs
├── install.sh  install.ps1      # one installer, two platforms, same behaviour
├── tests/
│   ├── install-test.sh          # end-to-end test of install.sh in a temp HOME
│   ├── parity-test.sh           # install.sh vs install.ps1, byte-identical results
│   ├── release-test.sh          # release assets, SHA256SUMS, download-verify-run
│   ├── legacy-test.ps1          # migration from real former installs, PowerShell side
│   ├── legacy-fixtures.sh       # runs the former installers to make real old installs
│   └── fixtures/legacy/         # git bundles of the former repositories (test data)
├── scripts/                     # make-release.sh (assets + SHA256SUMS), diagram generator, PNG export
├── docs/assets/                 # SVG diagrams (light and dark aware), install screenshot
├── VERSION  CHANGELOG.md  LICENSE  CONTRIBUTING.md  SECURITY.md
└── README.md  README.zh-CN.md

SKILL.md and references/ are still at the repository root, so a clone into a skills folder under the skill's name (git clone https://github.com/PakhomLeo/plan-gate.git code-project-flow) still works. The installer is the supported path.


Development and tests

shellcheck install.sh scripts/*.sh tests/*.sh
bash tests/install-test.sh                 # install.sh, every case in a throwaway HOME
bash tests/parity-test.sh                  # needs PowerShell 7 (pwsh)
pwsh -NoProfile -File tests/legacy-test.ps1  # install.ps1 vs the former installers' install.ps1
bash tests/release-test.sh                 # release assets, SHA256SUMS, download-verify-run

Releases: push a tag vX.Y.Z that matches VERSION; .github/workflows/release.yml runs the tests, builds the assets with scripts/make-release.sh and publishes them.

The tests never touch your real home folder or the network. The migration cases run the former installers, unmodified, from git bundles of the former repositories in tests/fixtures/legacy/. See CONTRIBUTING.md.


History

Version 1.0.0 of plan-gate merges two repositories by the same author:

  • code-project-flow (2026-09-28 – 2026-10-03): the workflow skill for Qoder, with docs/ document layout and a git clone installer.
  • dsh-quick-dev (2026-09-29 – 2026-10-21): the DSH quick dev mode, with a copy of the skill in the project-root layout, the plan-arm plugin and the preset.

The two skill copies are now one source. See CHANGELOG.md.

Contributing

See CONTRIBUTING.md.

License

MIT © 2026 PakhomLeo

About

Plan-first workflow for AI coding agents: the agent writes a short plan, stops for your approval, builds, then checks once. Ships a SKILL.md skill (Qoder and other clients) and a DSH quick dev mode, with one safe installer for bash and PowerShell.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages