Skip to content

Releases: jhfnetboy/DevLoop

0.6.11

Choose a tag to compare

@jhfnetboy jhfnetboy released this 17 Sep 04:14
e7f4652

Release 0.6.11

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.11 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.11. This document is the release note, not a second semver.

New in 0.6.11

The DevLoop view closes the loop on everything it needs a second window
for: answering a blocked halt, registering a project, and cleaning up
branches and worktrees all moved in, and the "Open dashboard" button
that used to stand in for them is gone.

  • Answer a blocked halt from the view (#158).
    The question, its evidence, and the same retry/review/accept/stop
    options the standalone page offers, read straight off the Gate
    object — now sent on the project list itself, not just the detail
    fetch, since it was already computed on every read.
  • Register a project from the view (#159).
    Browse one directory level at a time, pick a repository, add it —
    the same GET /api/browse / POST /api/projects the standalone
    page's own picker uses, now inline.
  • Clean up branches and worktrees from the view (#160).
    The same scan-and-plan the standalone page's repository panel reads,
    with a checkbox per offered branch; the host rebuilds the plan fresh
    at the moment of deleting regardless of what was shown.
  • The "Open dashboard" button is gone. With all three of the gaps it
    stood in for closed, the view links out to the standalone page
    nowhere. The sidebar launcher's own page fallback — for a profile
    with no DevLoop tab to press at all — is unchanged.

New in 0.6.10

A native DevLoop view in the app itself, and elapsed time on whatever task
is running right now.

  • A DevLoop tab beside Chat and Trajectory (#154).
    The sidebar button only ever opened /devloop/ in a window — DevLoop lived
    beside the app, never in it. This renders the whole main view area instead:
    every project with its lane, today's spend, task counts and halt reasons in
    the loop's own words, Pause/Resume, and arming an unarmed root with a typed
    goal. Same routes, same auth, same revision-guarded writes as the standalone
    page; no new endpoint. The page itself remains, reachable from the sidebar
    button, for what the view does not cover (goal gates, registering a
    repository, cleanup).
  • Elapsed time on the task in progress (#155, #156).
    Until now the dashboard only showed the last completed transition;
    nothing said how long the current one had been running. Each ProjectLoop
    now tracks what it is dispatching, in memory, while a backend call is in
    flight, and both surfaces (the standalone page and the new DevLoop tab) show
    it as a "running Xm" chip, on the same 5-second refresh they already had.

New in 0.6.9

A native sidebar entry for DSH Desktop and the browser, and the loop writing
its own planning documents instead of pointing at a skill it cannot invoke.

  • A sidebar button, composed from this one package (#149).
    On a profile with a Harness chrome (a browser tab or DSH Desktop), an icon
    in the sidebar footer opens /devloop/ in a new window — no second package
    to install, no decision to make. A headless profile never composes a client
    bundle at all. Ported from jhfnetboy/dsh-devloop-ui, the standalone
    package that verified this was feasible before folding it in.
  • Writing the planning documents is the goal's first reviewed task (#150, #152).
    The readiness panel used to point at pilot plan for missing planning
    documents — a skill this loop's headless CLI-spawn architecture cannot
    invoke. When docs/agent/ (or .pilot.yml's configured directory) is
    empty, the host now prepends a real task — "write the planning documents",
    reviewed and merged through the normal worktree pipeline like any other —
    before the planner's own tasks. Nothing writes docs unreviewed.

New in 0.6.8

A one-click fix for the readiness panel's most common block, and a worked
install example for people who aren't building from source.

  • Create and switch to a work branch from the page (#146).
    When the readiness panel blocks on trunk.onTrunk or branch.detached, it
    now shows a name field and a button next to the failing check. It runs the
    same git switch -c the check already names, refuses once the project is
    armed (pausing the loop is what that's for), and refuses an unusable name,
    the trunk itself, or a name already taken. New route:
    POST /devloop/api/projects/<id>/branch.
  • npm install and a worked example in the README (#147).
    A one-line dsh plugin --profile web add @jhfnetboy/dsh-devloop@0.6.8
    install, and a full cordis.patch.yml for the common setup this project
    runs in production: Codex plans, DeepSeek Flash implements, Claude Opus
    reviews locally, forge opens a PR per task.

New in 0.6.7

DeepSeek work defaults to DeepSeek V4.1 Flash, by the API id DeepSeek
published for it (notice of 2026-09-10) and DeepSeek Harness 0.1.5's own
default agent model: deepseek-flash.

  • Default routes (#144).
    routing.T1 and routing.T2 default to deepseek-flash instead of
    deepseek-v4-flash (deprecated, routed to V4.1 Flash for now) and
    deepseek-v4-pro (served by V4.1 Flash from 2026-09-14 12:00 Beijing
    time). A profile that names its routes is unchanged.
  • Prices (#143).
    deepseek-flash is priced from the V4.1 Flash card; deepseek-v4-flash
    and deepseek-v4-pro at the same card, each with a note saying why; all
    are billed as deepseek-flash. docs/Pricing.md lists the ids.

The model id passes through to DeepSeek's API, so dsh builds before 0.1.5
use deepseek-flash too (as a text-only route); dsh 0.1.5 adds its image
input and in-history system prompt updates.

New in 0.6.6

One repository, worked on goal after goal, every change reviewed. Found by
running 0.6.5 end to end on a live dashboard and a sandbox forge repository,
and shaped after LoopX, where a goal is long-lived and
finished work stays with it.

  • The next goal on the same repository (#128#131).
    A finished project's page shows a "Next goal" box. The finished goal is
    archived under .devloop/archive/NNNN/ (GOAL, STATE, PLAN, REVIEW,
    PROGRESS) under the state lock, and the next is planned on the same work
    branch; spend carries over, per-task counters restart. Where the forge
    merges, the next goal waits for the finished one's release to merge, its
    task ids get a g<N>- prefix so its branches never meet an earlier goal's,
    and its release is matched by number, never by an earlier goal's merge.
  • Each project pushes to its own forge repository (#132, #135, #136).
    Before a registered project first starts on the forge route, the page shows
    its checkout's origin (read without insteadOf) for the operator to
    confirm; it is kept in the project registry, never re-read from the
    checkout, and the project's loop runs with it. Also fixes the forge route
    failing to start when a profile never named forge.localReview.
  • Mechanical checks fix before review (#133).
    A commit the pre-PR checker blocks on a rule, or whose acceptance command
    fails, goes back to the worker with what the check said, bounded by the
    task's attempts; only size alone (split the task) or no verdict still asks
    the operator. The PR record shows how many tasks passed their first review
    (#139).
  • Safer with a repository that is already in use (#127, #137, #140).
    A branch named for a task that holds other work is never reset: the task
    holds and asks (task_branch_taken). A forge merge removes the task's
    worktree. .devloop/ is added to the local info/exclude. Ahead/behind
    is counted against the remote's trunk.
  • Say what the task is (#134, #138).
    Task commits are <task id>: <title>; the task pull request lists the
    contract's acceptance and allowed paths; the release links each task's
    pull request.

New: .devloop/archive/, STATE goal and Task.pullRequest, registry
pushUrl, hold reason task_branch_taken, POST /api/projects/<id>/next.
Checked before release by a forge E2E in the sandbox: two goals in a row on
one work branch, four pull requests reviewed and merged by DevLoop.

New in 0.6.5

Hardening and polish of 0.6.4's per-task pull requests, from PR-daemon's
reviews of it. No new mode; local mode gains the git and credential fixes too.

  • Models run without the host's credentials (#111).
    Every worker, reviewer and planner (dsh, claude, codex) starts without any
    inherited GIT_*, GH_*, GITHUB_* or ...
Read more

0.6.10

Choose a tag to compare

@jhfnetboy jhfnetboy released this 17 Sep 02:38
4de3ed6

Release 0.6.10

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.10 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.10. This document is the release note, not a second semver.

New in 0.6.10

A native DevLoop view in the app itself, and elapsed time on whatever task
is running right now.

  • A DevLoop tab beside Chat and Trajectory (#154).
    The sidebar button only ever opened /devloop/ in a window — DevLoop lived
    beside the app, never in it. This renders the whole main view area instead:
    every project with its lane, today's spend, task counts and halt reasons in
    the loop's own words, Pause/Resume, and arming an unarmed root with a typed
    goal. Same routes, same auth, same revision-guarded writes as the standalone
    page; no new endpoint. The page itself remains, reachable from the sidebar
    button, for what the view does not cover (goal gates, registering a
    repository, cleanup).
  • Elapsed time on the task in progress (#155, #156).
    Until now the dashboard only showed the last completed transition;
    nothing said how long the current one had been running. Each ProjectLoop
    now tracks what it is dispatching, in memory, while a backend call is in
    flight, and both surfaces (the standalone page and the new DevLoop tab) show
    it as a "running Xm" chip, on the same 5-second refresh they already had.

New in 0.6.9

A native sidebar entry for DSH Desktop and the browser, and the loop writing
its own planning documents instead of pointing at a skill it cannot invoke.

  • A sidebar button, composed from this one package (#149).
    On a profile with a Harness chrome (a browser tab or DSH Desktop), an icon
    in the sidebar footer opens /devloop/ in a new window — no second package
    to install, no decision to make. A headless profile never composes a client
    bundle at all. Ported from jhfnetboy/dsh-devloop-ui, the standalone
    package that verified this was feasible before folding it in.
  • Writing the planning documents is the goal's first reviewed task (#150, #152).
    The readiness panel used to point at pilot plan for missing planning
    documents — a skill this loop's headless CLI-spawn architecture cannot
    invoke. When docs/agent/ (or .pilot.yml's configured directory) is
    empty, the host now prepends a real task — "write the planning documents",
    reviewed and merged through the normal worktree pipeline like any other —
    before the planner's own tasks. Nothing writes docs unreviewed.

New in 0.6.8

A one-click fix for the readiness panel's most common block, and a worked
install example for people who aren't building from source.

  • Create and switch to a work branch from the page (#146).
    When the readiness panel blocks on trunk.onTrunk or branch.detached, it
    now shows a name field and a button next to the failing check. It runs the
    same git switch -c the check already names, refuses once the project is
    armed (pausing the loop is what that's for), and refuses an unusable name,
    the trunk itself, or a name already taken. New route:
    POST /devloop/api/projects/<id>/branch.
  • npm install and a worked example in the README (#147).
    A one-line dsh plugin --profile web add @jhfnetboy/dsh-devloop@0.6.8
    install, and a full cordis.patch.yml for the common setup this project
    runs in production: Codex plans, DeepSeek Flash implements, Claude Opus
    reviews locally, forge opens a PR per task.

New in 0.6.7

DeepSeek work defaults to DeepSeek V4.1 Flash, by the API id DeepSeek
published for it (notice of 2026-09-10) and DeepSeek Harness 0.1.5's own
default agent model: deepseek-flash.

  • Default routes (#144).
    routing.T1 and routing.T2 default to deepseek-flash instead of
    deepseek-v4-flash (deprecated, routed to V4.1 Flash for now) and
    deepseek-v4-pro (served by V4.1 Flash from 2026-09-14 12:00 Beijing
    time). A profile that names its routes is unchanged.
  • Prices (#143).
    deepseek-flash is priced from the V4.1 Flash card; deepseek-v4-flash
    and deepseek-v4-pro at the same card, each with a note saying why; all
    are billed as deepseek-flash. docs/Pricing.md lists the ids.

The model id passes through to DeepSeek's API, so dsh builds before 0.1.5
use deepseek-flash too (as a text-only route); dsh 0.1.5 adds its image
input and in-history system prompt updates.

New in 0.6.6

One repository, worked on goal after goal, every change reviewed. Found by
running 0.6.5 end to end on a live dashboard and a sandbox forge repository,
and shaped after LoopX, where a goal is long-lived and
finished work stays with it.

  • The next goal on the same repository (#128#131).
    A finished project's page shows a "Next goal" box. The finished goal is
    archived under .devloop/archive/NNNN/ (GOAL, STATE, PLAN, REVIEW,
    PROGRESS) under the state lock, and the next is planned on the same work
    branch; spend carries over, per-task counters restart. Where the forge
    merges, the next goal waits for the finished one's release to merge, its
    task ids get a g<N>- prefix so its branches never meet an earlier goal's,
    and its release is matched by number, never by an earlier goal's merge.
  • Each project pushes to its own forge repository (#132, #135, #136).
    Before a registered project first starts on the forge route, the page shows
    its checkout's origin (read without insteadOf) for the operator to
    confirm; it is kept in the project registry, never re-read from the
    checkout, and the project's loop runs with it. Also fixes the forge route
    failing to start when a profile never named forge.localReview.
  • Mechanical checks fix before review (#133).
    A commit the pre-PR checker blocks on a rule, or whose acceptance command
    fails, goes back to the worker with what the check said, bounded by the
    task's attempts; only size alone (split the task) or no verdict still asks
    the operator. The PR record shows how many tasks passed their first review
    (#139).
  • Safer with a repository that is already in use (#127, #137, #140).
    A branch named for a task that holds other work is never reset: the task
    holds and asks (task_branch_taken). A forge merge removes the task's
    worktree. .devloop/ is added to the local info/exclude. Ahead/behind
    is counted against the remote's trunk.
  • Say what the task is (#134, #138).
    Task commits are <task id>: <title>; the task pull request lists the
    contract's acceptance and allowed paths; the release links each task's
    pull request.

New: .devloop/archive/, STATE goal and Task.pullRequest, registry
pushUrl, hold reason task_branch_taken, POST /api/projects/<id>/next.
Checked before release by a forge E2E in the sandbox: two goals in a row on
one work branch, four pull requests reviewed and merged by DevLoop.

New in 0.6.5

Hardening and polish of 0.6.4's per-task pull requests, from PR-daemon's
reviews of it. No new mode; local mode gains the git and credential fixes too.

  • Models run without the host's credentials (#111).
    Every worker, reviewer and planner (dsh, claude, codex) starts without any
    inherited GIT_*, GH_*, GITHUB_* or SSH_* variable — git's numbered
    GIT_CONFIG_KEY_n/VALUE_n included — with gh pointed at an empty config
    and git at no global or system config. dsh is pinned to workspace-write.
    A model's own sandbox is still what stops it reading credential files on disk.
  • Every host git through one hardened helper (#113, #114).
    Inherited GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE/GIT_COMMON_DIR no
    longer redirect it, fsmonitor and hooks are off; project registration and
    the pre-PR checker included.
  • Checks you can require (#112, #123).
    forge.requireChecks: true makes a commit with no checks wait instead of
    counting as green. Checks are read in the same call as the pull request's
    head, so a later push cannot lend the reviewed commit its checks.
  • A forge refusal is its own question (#119, #124, #125).
    Branch protection, an expired gh login or empty forge settings hold as
    forge_merge_refused: fix it outside DevLoop and resume; the worker is not
    run again. The checkout failing to follow the merge stays merge_wedged;
    a pull request pushed to or retargeted since revie...
Read more

0.6.9

Choose a tag to compare

@jhfnetboy jhfnetboy released this 16 Sep 15:33
fea3d4d

Release 0.6.9

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.9 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.9. This document is the release note, not a second semver.

New in 0.6.9

A native sidebar entry for DSH Desktop and the browser, and the loop writing
its own planning documents instead of pointing at a skill it cannot invoke.

  • A sidebar button, composed from this one package (#149).
    On a profile with a Harness chrome (a browser tab or DSH Desktop), an icon
    in the sidebar footer opens /devloop/ in a new window — no second package
    to install, no decision to make. A headless profile never composes a client
    bundle at all. Ported from jhfnetboy/dsh-devloop-ui, the standalone
    package that verified this was feasible before folding it in.
  • Writing the planning documents is the goal's first reviewed task (#150, #152).
    The readiness panel used to point at pilot plan for missing planning
    documents — a skill this loop's headless CLI-spawn architecture cannot
    invoke. When docs/agent/ (or .pilot.yml's configured directory) is
    empty, the host now prepends a real task — "write the planning documents",
    reviewed and merged through the normal worktree pipeline like any other —
    before the planner's own tasks. Nothing writes docs unreviewed.

New in 0.6.8

A one-click fix for the readiness panel's most common block, and a worked
install example for people who aren't building from source.

  • Create and switch to a work branch from the page (#146).
    When the readiness panel blocks on trunk.onTrunk or branch.detached, it
    now shows a name field and a button next to the failing check. It runs the
    same git switch -c the check already names, refuses once the project is
    armed (pausing the loop is what that's for), and refuses an unusable name,
    the trunk itself, or a name already taken. New route:
    POST /devloop/api/projects/<id>/branch.
  • npm install and a worked example in the README (#147).
    A one-line dsh plugin --profile web add @jhfnetboy/dsh-devloop@0.6.8
    install, and a full cordis.patch.yml for the common setup this project
    runs in production: Codex plans, DeepSeek Flash implements, Claude Opus
    reviews locally, forge opens a PR per task.

New in 0.6.7

DeepSeek work defaults to DeepSeek V4.1 Flash, by the API id DeepSeek
published for it (notice of 2026-09-10) and DeepSeek Harness 0.1.5's own
default agent model: deepseek-flash.

  • Default routes (#144).
    routing.T1 and routing.T2 default to deepseek-flash instead of
    deepseek-v4-flash (deprecated, routed to V4.1 Flash for now) and
    deepseek-v4-pro (served by V4.1 Flash from 2026-09-14 12:00 Beijing
    time). A profile that names its routes is unchanged.
  • Prices (#143).
    deepseek-flash is priced from the V4.1 Flash card; deepseek-v4-flash
    and deepseek-v4-pro at the same card, each with a note saying why; all
    are billed as deepseek-flash. docs/Pricing.md lists the ids.

The model id passes through to DeepSeek's API, so dsh builds before 0.1.5
use deepseek-flash too (as a text-only route); dsh 0.1.5 adds its image
input and in-history system prompt updates.

New in 0.6.6

One repository, worked on goal after goal, every change reviewed. Found by
running 0.6.5 end to end on a live dashboard and a sandbox forge repository,
and shaped after LoopX, where a goal is long-lived and
finished work stays with it.

  • The next goal on the same repository (#128#131).
    A finished project's page shows a "Next goal" box. The finished goal is
    archived under .devloop/archive/NNNN/ (GOAL, STATE, PLAN, REVIEW,
    PROGRESS) under the state lock, and the next is planned on the same work
    branch; spend carries over, per-task counters restart. Where the forge
    merges, the next goal waits for the finished one's release to merge, its
    task ids get a g<N>- prefix so its branches never meet an earlier goal's,
    and its release is matched by number, never by an earlier goal's merge.
  • Each project pushes to its own forge repository (#132, #135, #136).
    Before a registered project first starts on the forge route, the page shows
    its checkout's origin (read without insteadOf) for the operator to
    confirm; it is kept in the project registry, never re-read from the
    checkout, and the project's loop runs with it. Also fixes the forge route
    failing to start when a profile never named forge.localReview.
  • Mechanical checks fix before review (#133).
    A commit the pre-PR checker blocks on a rule, or whose acceptance command
    fails, goes back to the worker with what the check said, bounded by the
    task's attempts; only size alone (split the task) or no verdict still asks
    the operator. The PR record shows how many tasks passed their first review
    (#139).
  • Safer with a repository that is already in use (#127, #137, #140).
    A branch named for a task that holds other work is never reset: the task
    holds and asks (task_branch_taken). A forge merge removes the task's
    worktree. .devloop/ is added to the local info/exclude. Ahead/behind
    is counted against the remote's trunk.
  • Say what the task is (#134, #138).
    Task commits are <task id>: <title>; the task pull request lists the
    contract's acceptance and allowed paths; the release links each task's
    pull request.

New: .devloop/archive/, STATE goal and Task.pullRequest, registry
pushUrl, hold reason task_branch_taken, POST /api/projects/<id>/next.
Checked before release by a forge E2E in the sandbox: two goals in a row on
one work branch, four pull requests reviewed and merged by DevLoop.

New in 0.6.5

Hardening and polish of 0.6.4's per-task pull requests, from PR-daemon's
reviews of it. No new mode; local mode gains the git and credential fixes too.

  • Models run without the host's credentials (#111).
    Every worker, reviewer and planner (dsh, claude, codex) starts without any
    inherited GIT_*, GH_*, GITHUB_* or SSH_* variable — git's numbered
    GIT_CONFIG_KEY_n/VALUE_n included — with gh pointed at an empty config
    and git at no global or system config. dsh is pinned to workspace-write.
    A model's own sandbox is still what stops it reading credential files on disk.
  • Every host git through one hardened helper (#113, #114).
    Inherited GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE/GIT_COMMON_DIR no
    longer redirect it, fsmonitor and hooks are off; project registration and
    the pre-PR checker included.
  • Checks you can require (#112, #123).
    forge.requireChecks: true makes a commit with no checks wait instead of
    counting as green. Checks are read in the same call as the pull request's
    head, so a later push cannot lend the reviewed commit its checks.
  • A forge refusal is its own question (#119, #124, #125).
    Branch protection, an expired gh login or empty forge settings hold as
    forge_merge_refused: fix it outside DevLoop and resume; the worker is not
    run again. The checkout failing to follow the merge stays merge_wedged;
    a pull request pushed to or retargeted since review holds as
    no_review_pass, to be reviewed again.
  • Gates and bodies that say what happens (#114, #117, #120, #121, #122).
    The release body says how it is decided (a GitHub review, always) and marks
    tasks accepted without a change; a trunk or detached checkout held before
    review no longer says the task "passed review"; a superseded trunk pull
    request is closed; a task merged by someone else is logged as a warning.
  • Review notes (#115, #116, #118).
    A local reviewer's long notes are cut at 8192 characters instead of stopping
    the loop; the PR log names the local reviewer.

New config: forge.requireChecks (default false). New hold reason:
forge_merge_refused (the only new value STATE can hold). New PR-LOG field:
localReviewer.
Not in 0.6.5: automatic retry of transient forge merge errors (gh gives no
signal to tell them from refusals).

New in 0.6.4

One GitHub pull request per task,...

Read more

0.6.8

Choose a tag to compare

@jhfnetboy jhfnetboy released this 16 Sep 14:16
1e7fc26

Release 0.6.8

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.8 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.8. This document is the release note, not a second semver.

New in 0.6.8

A one-click fix for the readiness panel's most common block, and a worked
install example for people who aren't building from source.

  • Create and switch to a work branch from the page (#146).
    When the readiness panel blocks on trunk.onTrunk or branch.detached, it
    now shows a name field and a button next to the failing check. It runs the
    same git switch -c the check already names, refuses once the project is
    armed (pausing the loop is what that's for), and refuses an unusable name,
    the trunk itself, or a name already taken. New route:
    POST /devloop/api/projects/<id>/branch.
  • npm install and a worked example in the README (#147).
    A one-line dsh plugin --profile web add @jhfnetboy/dsh-devloop@0.6.8
    install, and a full cordis.patch.yml for the common setup this project
    runs in production: Codex plans, DeepSeek Flash implements, Claude Opus
    reviews locally, forge opens a PR per task.

New in 0.6.7

DeepSeek work defaults to DeepSeek V4.1 Flash, by the API id DeepSeek
published for it (notice of 2026-09-10) and DeepSeek Harness 0.1.5's own
default agent model: deepseek-flash.

  • Default routes (#144).
    routing.T1 and routing.T2 default to deepseek-flash instead of
    deepseek-v4-flash (deprecated, routed to V4.1 Flash for now) and
    deepseek-v4-pro (served by V4.1 Flash from 2026-09-14 12:00 Beijing
    time). A profile that names its routes is unchanged.
  • Prices (#143).
    deepseek-flash is priced from the V4.1 Flash card; deepseek-v4-flash
    and deepseek-v4-pro at the same card, each with a note saying why; all
    are billed as deepseek-flash. docs/Pricing.md lists the ids.

The model id passes through to DeepSeek's API, so dsh builds before 0.1.5
use deepseek-flash too (as a text-only route); dsh 0.1.5 adds its image
input and in-history system prompt updates.

New in 0.6.6

One repository, worked on goal after goal, every change reviewed. Found by
running 0.6.5 end to end on a live dashboard and a sandbox forge repository,
and shaped after LoopX, where a goal is long-lived and
finished work stays with it.

  • The next goal on the same repository (#128#131).
    A finished project's page shows a "Next goal" box. The finished goal is
    archived under .devloop/archive/NNNN/ (GOAL, STATE, PLAN, REVIEW,
    PROGRESS) under the state lock, and the next is planned on the same work
    branch; spend carries over, per-task counters restart. Where the forge
    merges, the next goal waits for the finished one's release to merge, its
    task ids get a g<N>- prefix so its branches never meet an earlier goal's,
    and its release is matched by number, never by an earlier goal's merge.
  • Each project pushes to its own forge repository (#132, #135, #136).
    Before a registered project first starts on the forge route, the page shows
    its checkout's origin (read without insteadOf) for the operator to
    confirm; it is kept in the project registry, never re-read from the
    checkout, and the project's loop runs with it. Also fixes the forge route
    failing to start when a profile never named forge.localReview.
  • Mechanical checks fix before review (#133).
    A commit the pre-PR checker blocks on a rule, or whose acceptance command
    fails, goes back to the worker with what the check said, bounded by the
    task's attempts; only size alone (split the task) or no verdict still asks
    the operator. The PR record shows how many tasks passed their first review
    (#139).
  • Safer with a repository that is already in use (#127, #137, #140).
    A branch named for a task that holds other work is never reset: the task
    holds and asks (task_branch_taken). A forge merge removes the task's
    worktree. .devloop/ is added to the local info/exclude. Ahead/behind
    is counted against the remote's trunk.
  • Say what the task is (#134, #138).
    Task commits are <task id>: <title>; the task pull request lists the
    contract's acceptance and allowed paths; the release links each task's
    pull request.

New: .devloop/archive/, STATE goal and Task.pullRequest, registry
pushUrl, hold reason task_branch_taken, POST /api/projects/<id>/next.
Checked before release by a forge E2E in the sandbox: two goals in a row on
one work branch, four pull requests reviewed and merged by DevLoop.

New in 0.6.5

Hardening and polish of 0.6.4's per-task pull requests, from PR-daemon's
reviews of it. No new mode; local mode gains the git and credential fixes too.

  • Models run without the host's credentials (#111).
    Every worker, reviewer and planner (dsh, claude, codex) starts without any
    inherited GIT_*, GH_*, GITHUB_* or SSH_* variable — git's numbered
    GIT_CONFIG_KEY_n/VALUE_n included — with gh pointed at an empty config
    and git at no global or system config. dsh is pinned to workspace-write.
    A model's own sandbox is still what stops it reading credential files on disk.
  • Every host git through one hardened helper (#113, #114).
    Inherited GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE/GIT_COMMON_DIR no
    longer redirect it, fsmonitor and hooks are off; project registration and
    the pre-PR checker included.
  • Checks you can require (#112, #123).
    forge.requireChecks: true makes a commit with no checks wait instead of
    counting as green. Checks are read in the same call as the pull request's
    head, so a later push cannot lend the reviewed commit its checks.
  • A forge refusal is its own question (#119, #124, #125).
    Branch protection, an expired gh login or empty forge settings hold as
    forge_merge_refused: fix it outside DevLoop and resume; the worker is not
    run again. The checkout failing to follow the merge stays merge_wedged;
    a pull request pushed to or retargeted since review holds as
    no_review_pass, to be reviewed again.
  • Gates and bodies that say what happens (#114, #117, #120, #121, #122).
    The release body says how it is decided (a GitHub review, always) and marks
    tasks accepted without a change; a trunk or detached checkout held before
    review no longer says the task "passed review"; a superseded trunk pull
    request is closed; a task merged by someone else is logged as a warning.
  • Review notes (#115, #116, #118).
    A local reviewer's long notes are cut at 8192 characters instead of stopping
    the loop; the PR log names the local reviewer.

New config: forge.requireChecks (default false). New hold reason:
forge_merge_refused (the only new value STATE can hold). New PR-LOG field:
localReviewer.
Not in 0.6.5: automatic retry of transient forge merge errors (gh gives no
signal to tell them from refusals).

New in 0.6.4

One GitHub pull request per task, reviewed there and merged by DevLoop, then
one release pull request to trunk: the per-task review the 0.6 design set
out, run end to end in a sandbox repository before release. Off unless
reviewerRoute names the forge backend; without it tasks merge locally as
before. How to turn it on: README, "One pull request per task".

  • Verdicts from GitHub reviews (#93, #98).
    Only allowlisted reviewers who are not this host, only reviews of exactly the
    reviewed commit, each reviewer's latest word; any request for changes
    outranks every approval and is rework. An approval passes only once the
    commit's checks are green. forge.verdictSource: comments keeps the old
    envelope path; exactly one source is read.
  • Rework carries the review (#95, #96, #105, #106).
    A request for changes' body — PR-daemon's, or the local reviewer's — reaches
    the worker's next attempt, as one quoted string, and survives a failed or
    blocked attempt; it is dropped once an attempt ...
Read more

0.6.7

Choose a tag to compare

@jhfnetboy jhfnetboy released this 13 Sep 06:44
6e7bbad

Release 0.6.7

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.7 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.7. This document is the release note, not a second semver.

New in 0.6.7

DeepSeek work defaults to DeepSeek V4.1 Flash, by the API id DeepSeek
published for it (notice of 2026-09-10) and DeepSeek Harness 0.1.5's own
default agent model: deepseek-flash.

  • Default routes (#144).
    routing.T1 and routing.T2 default to deepseek-flash instead of
    deepseek-v4-flash (deprecated, routed to V4.1 Flash for now) and
    deepseek-v4-pro (served by V4.1 Flash from 2026-09-14 12:00 Beijing
    time). A profile that names its routes is unchanged.
  • Prices (#143).
    deepseek-flash is priced from the V4.1 Flash card; deepseek-v4-flash
    and deepseek-v4-pro at the same card, each with a note saying why; all
    are billed as deepseek-flash. docs/Pricing.md lists the ids.

The model id passes through to DeepSeek's API, so dsh builds before 0.1.5
use deepseek-flash too (as a text-only route); dsh 0.1.5 adds its image
input and in-history system prompt updates.

New in 0.6.6

One repository, worked on goal after goal, every change reviewed. Found by
running 0.6.5 end to end on a live dashboard and a sandbox forge repository,
and shaped after LoopX, where a goal is long-lived and
finished work stays with it.

  • The next goal on the same repository (#128#131).
    A finished project's page shows a "Next goal" box. The finished goal is
    archived under .devloop/archive/NNNN/ (GOAL, STATE, PLAN, REVIEW,
    PROGRESS) under the state lock, and the next is planned on the same work
    branch; spend carries over, per-task counters restart. Where the forge
    merges, the next goal waits for the finished one's release to merge, its
    task ids get a g<N>- prefix so its branches never meet an earlier goal's,
    and its release is matched by number, never by an earlier goal's merge.
  • Each project pushes to its own forge repository (#132, #135, #136).
    Before a registered project first starts on the forge route, the page shows
    its checkout's origin (read without insteadOf) for the operator to
    confirm; it is kept in the project registry, never re-read from the
    checkout, and the project's loop runs with it. Also fixes the forge route
    failing to start when a profile never named forge.localReview.
  • Mechanical checks fix before review (#133).
    A commit the pre-PR checker blocks on a rule, or whose acceptance command
    fails, goes back to the worker with what the check said, bounded by the
    task's attempts; only size alone (split the task) or no verdict still asks
    the operator. The PR record shows how many tasks passed their first review
    (#139).
  • Safer with a repository that is already in use (#127, #137, #140).
    A branch named for a task that holds other work is never reset: the task
    holds and asks (task_branch_taken). A forge merge removes the task's
    worktree. .devloop/ is added to the local info/exclude. Ahead/behind
    is counted against the remote's trunk.
  • Say what the task is (#134, #138).
    Task commits are <task id>: <title>; the task pull request lists the
    contract's acceptance and allowed paths; the release links each task's
    pull request.

New: .devloop/archive/, STATE goal and Task.pullRequest, registry
pushUrl, hold reason task_branch_taken, POST /api/projects/<id>/next.
Checked before release by a forge E2E in the sandbox: two goals in a row on
one work branch, four pull requests reviewed and merged by DevLoop.

New in 0.6.5

Hardening and polish of 0.6.4's per-task pull requests, from PR-daemon's
reviews of it. No new mode; local mode gains the git and credential fixes too.

  • Models run without the host's credentials (#111).
    Every worker, reviewer and planner (dsh, claude, codex) starts without any
    inherited GIT_*, GH_*, GITHUB_* or SSH_* variable — git's numbered
    GIT_CONFIG_KEY_n/VALUE_n included — with gh pointed at an empty config
    and git at no global or system config. dsh is pinned to workspace-write.
    A model's own sandbox is still what stops it reading credential files on disk.
  • Every host git through one hardened helper (#113, #114).
    Inherited GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE/GIT_COMMON_DIR no
    longer redirect it, fsmonitor and hooks are off; project registration and
    the pre-PR checker included.
  • Checks you can require (#112, #123).
    forge.requireChecks: true makes a commit with no checks wait instead of
    counting as green. Checks are read in the same call as the pull request's
    head, so a later push cannot lend the reviewed commit its checks.
  • A forge refusal is its own question (#119, #124, #125).
    Branch protection, an expired gh login or empty forge settings hold as
    forge_merge_refused: fix it outside DevLoop and resume; the worker is not
    run again. The checkout failing to follow the merge stays merge_wedged;
    a pull request pushed to or retargeted since review holds as
    no_review_pass, to be reviewed again.
  • Gates and bodies that say what happens (#114, #117, #120, #121, #122).
    The release body says how it is decided (a GitHub review, always) and marks
    tasks accepted without a change; a trunk or detached checkout held before
    review no longer says the task "passed review"; a superseded trunk pull
    request is closed; a task merged by someone else is logged as a warning.
  • Review notes (#115, #116, #118).
    A local reviewer's long notes are cut at 8192 characters instead of stopping
    the loop; the PR log names the local reviewer.

New config: forge.requireChecks (default false). New hold reason:
forge_merge_refused (the only new value STATE can hold). New PR-LOG field:
localReviewer.
Not in 0.6.5: automatic retry of transient forge merge errors (gh gives no
signal to tell them from refusals).

New in 0.6.4

One GitHub pull request per task, reviewed there and merged by DevLoop, then
one release pull request to trunk: the per-task review the 0.6 design set
out, run end to end in a sandbox repository before release. Off unless
reviewerRoute names the forge backend; without it tasks merge locally as
before. How to turn it on: README, "One pull request per task".

  • Verdicts from GitHub reviews (#93, #98).
    Only allowlisted reviewers who are not this host, only reviews of exactly the
    reviewed commit, each reviewer's latest word; any request for changes
    outranks every approval and is rework. An approval passes only once the
    commit's checks are green. forge.verdictSource: comments keeps the old
    envelope path; exactly one source is read.
  • Rework carries the review (#95, #96, #105, #106).
    A request for changes' body — PR-daemon's, or the local reviewer's — reaches
    the worker's next attempt, as one quoted string, and survives a failed or
    blocked attempt; it is dropped once an attempt is handed in or the task is
    accepted.
  • The work branch (#94, #97, #107).
    Recorded at the first delegate; task pull requests target it, labelled
    devloop, never trunk. It is created on the forge at the task's base,
    fast-forwarded when behind, left alone when ahead, refused when moved away;
    a review with no work branch holds on trunk or detached instead of opening a
    pull request.
  • A local review first (#99).
    forge.localReview runs a local reviewer before the pull request opens, and
    its usage counts toward the caps.
  • DevLoop merges (#100#102).
    The verdict and checks are read again, then gh pr merge --match-head-commit
    from an empty directory; the checkout fetches the merge commit by id and
    fast-forwards to it b...
Read more

0.6.6

Choose a tag to compare

@jhfnetboy jhfnetboy released this 13 Sep 06:35
494eee2

Release 0.6.6

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.6 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.6. This document is the release note, not a second semver.

New in 0.6.6

One repository, worked on goal after goal, every change reviewed. Found by
running 0.6.5 end to end on a live dashboard and a sandbox forge repository,
and shaped after LoopX, where a goal is long-lived and
finished work stays with it.

  • The next goal on the same repository (#128#131).
    A finished project's page shows a "Next goal" box. The finished goal is
    archived under .devloop/archive/NNNN/ (GOAL, STATE, PLAN, REVIEW,
    PROGRESS) under the state lock, and the next is planned on the same work
    branch; spend carries over, per-task counters restart. Where the forge
    merges, the next goal waits for the finished one's release to merge, its
    task ids get a g<N>- prefix so its branches never meet an earlier goal's,
    and its release is matched by number, never by an earlier goal's merge.
  • Each project pushes to its own forge repository (#132, #135, #136).
    Before a registered project first starts on the forge route, the page shows
    its checkout's origin (read without insteadOf) for the operator to
    confirm; it is kept in the project registry, never re-read from the
    checkout, and the project's loop runs with it. Also fixes the forge route
    failing to start when a profile never named forge.localReview.
  • Mechanical checks fix before review (#133).
    A commit the pre-PR checker blocks on a rule, or whose acceptance command
    fails, goes back to the worker with what the check said, bounded by the
    task's attempts; only size alone (split the task) or no verdict still asks
    the operator. The PR record shows how many tasks passed their first review
    (#139).
  • Safer with a repository that is already in use (#127, #137, #140).
    A branch named for a task that holds other work is never reset: the task
    holds and asks (task_branch_taken). A forge merge removes the task's
    worktree. .devloop/ is added to the local info/exclude. Ahead/behind
    is counted against the remote's trunk.
  • Say what the task is (#134, #138).
    Task commits are <task id>: <title>; the task pull request lists the
    contract's acceptance and allowed paths; the release links each task's
    pull request.

New: .devloop/archive/, STATE goal and Task.pullRequest, registry
pushUrl, hold reason task_branch_taken, POST /api/projects/<id>/next.
Checked before release by a forge E2E in the sandbox: two goals in a row on
one work branch, four pull requests reviewed and merged by DevLoop.

New in 0.6.5

Hardening and polish of 0.6.4's per-task pull requests, from PR-daemon's
reviews of it. No new mode; local mode gains the git and credential fixes too.

  • Models run without the host's credentials (#111).
    Every worker, reviewer and planner (dsh, claude, codex) starts without any
    inherited GIT_*, GH_*, GITHUB_* or SSH_* variable — git's numbered
    GIT_CONFIG_KEY_n/VALUE_n included — with gh pointed at an empty config
    and git at no global or system config. dsh is pinned to workspace-write.
    A model's own sandbox is still what stops it reading credential files on disk.
  • Every host git through one hardened helper (#113, #114).
    Inherited GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE/GIT_COMMON_DIR no
    longer redirect it, fsmonitor and hooks are off; project registration and
    the pre-PR checker included.
  • Checks you can require (#112, #123).
    forge.requireChecks: true makes a commit with no checks wait instead of
    counting as green. Checks are read in the same call as the pull request's
    head, so a later push cannot lend the reviewed commit its checks.
  • A forge refusal is its own question (#119, #124, #125).
    Branch protection, an expired gh login or empty forge settings hold as
    forge_merge_refused: fix it outside DevLoop and resume; the worker is not
    run again. The checkout failing to follow the merge stays merge_wedged;
    a pull request pushed to or retargeted since review holds as
    no_review_pass, to be reviewed again.
  • Gates and bodies that say what happens (#114, #117, #120, #121, #122).
    The release body says how it is decided (a GitHub review, always) and marks
    tasks accepted without a change; a trunk or detached checkout held before
    review no longer says the task "passed review"; a superseded trunk pull
    request is closed; a task merged by someone else is logged as a warning.
  • Review notes (#115, #116, #118).
    A local reviewer's long notes are cut at 8192 characters instead of stopping
    the loop; the PR log names the local reviewer.

New config: forge.requireChecks (default false). New hold reason:
forge_merge_refused (the only new value STATE can hold). New PR-LOG field:
localReviewer.
Not in 0.6.5: automatic retry of transient forge merge errors (gh gives no
signal to tell them from refusals).

New in 0.6.4

One GitHub pull request per task, reviewed there and merged by DevLoop, then
one release pull request to trunk: the per-task review the 0.6 design set
out, run end to end in a sandbox repository before release. Off unless
reviewerRoute names the forge backend; without it tasks merge locally as
before. How to turn it on: README, "One pull request per task".

  • Verdicts from GitHub reviews (#93, #98).
    Only allowlisted reviewers who are not this host, only reviews of exactly the
    reviewed commit, each reviewer's latest word; any request for changes
    outranks every approval and is rework. An approval passes only once the
    commit's checks are green. forge.verdictSource: comments keeps the old
    envelope path; exactly one source is read.
  • Rework carries the review (#95, #96, #105, #106).
    A request for changes' body — PR-daemon's, or the local reviewer's — reaches
    the worker's next attempt, as one quoted string, and survives a failed or
    blocked attempt; it is dropped once an attempt is handed in or the task is
    accepted.
  • The work branch (#94, #97, #107).
    Recorded at the first delegate; task pull requests target it, labelled
    devloop, never trunk. It is created on the forge at the task's base,
    fast-forwarded when behind, left alone when ahead, refused when moved away;
    a review with no work branch holds on trunk or detached instead of opening a
    pull request.
  • A local review first (#99).
    forge.localReview runs a local reviewer before the pull request opens, and
    its usage counts toward the caps.
  • DevLoop merges (#100#102).
    The verdict and checks are read again, then gh pr merge --match-head-commit
    from an empty directory; the checkout fetches the merge commit by id and
    fast-forwards to it before the task is done. Already merged is not merged
    twice; anything that cannot be completed holds.
  • The release pull request (#103, #104).
    Opened once every task is done, looked at each tick outside the state lock,
    merged once approved with green checks, on the forge only.
  • Security fix: a worker could run a program as the host through git
    (#108). Found by PR-daemon's
    review. The Codex delegate was granted its worktree's gitdir, and any worker
    could rewrite its worktree's .git pointer; either could point the host's
    next git call — committing the task, the pre-PR checker, the repository
    status scan — at a repository whose config runs a program. Codex no longer
    gets the gitdir, and every host git call in a task worktree pins its git
    directories to the host's own paths with fsmonitor and hooks off. This
    predates 0.6.4 and affects local ...
Read more

0.6.5

Choose a tag to compare

@jhfnetboy jhfnetboy released this 13 Sep 03:21
1f96ebb

Release 0.6.5

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.5 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.5. This document is the release note, not a second semver.

New in 0.6.5

Hardening and polish of 0.6.4's per-task pull requests, from PR-daemon's
reviews of it. No new mode; local mode gains the git and credential fixes too.

  • Models run without the host's credentials (#111).
    Every worker, reviewer and planner (dsh, claude, codex) starts without any
    inherited GIT_*, GH_*, GITHUB_* or SSH_* variable — git's numbered
    GIT_CONFIG_KEY_n/VALUE_n included — with gh pointed at an empty config
    and git at no global or system config. dsh is pinned to workspace-write.
    A model's own sandbox is still what stops it reading credential files on disk.
  • Every host git through one hardened helper (#113, #114).
    Inherited GIT_DIR/GIT_WORK_TREE/GIT_INDEX_FILE/GIT_COMMON_DIR no
    longer redirect it, fsmonitor and hooks are off; project registration and
    the pre-PR checker included.
  • Checks you can require (#112, #123).
    forge.requireChecks: true makes a commit with no checks wait instead of
    counting as green. Checks are read in the same call as the pull request's
    head, so a later push cannot lend the reviewed commit its checks.
  • A forge refusal is its own question (#119, #124, #125).
    Branch protection, an expired gh login or empty forge settings hold as
    forge_merge_refused: fix it outside DevLoop and resume; the worker is not
    run again. The checkout failing to follow the merge stays merge_wedged;
    a pull request pushed to or retargeted since review holds as
    no_review_pass, to be reviewed again.
  • Gates and bodies that say what happens (#114, #117, #120, #121, #122).
    The release body says how it is decided (a GitHub review, always) and marks
    tasks accepted without a change; a trunk or detached checkout held before
    review no longer says the task "passed review"; a superseded trunk pull
    request is closed; a task merged by someone else is logged as a warning.
  • Review notes (#115, #116, #118).
    A local reviewer's long notes are cut at 8192 characters instead of stopping
    the loop; the PR log names the local reviewer.

New config: forge.requireChecks (default false). New hold reason:
forge_merge_refused (the only new value STATE can hold). New PR-LOG field:
localReviewer.
Not in 0.6.5: automatic retry of transient forge merge errors (gh gives no
signal to tell them from refusals).

New in 0.6.4

One GitHub pull request per task, reviewed there and merged by DevLoop, then
one release pull request to trunk: the per-task review the 0.6 design set
out, run end to end in a sandbox repository before release. Off unless
reviewerRoute names the forge backend; without it tasks merge locally as
before. How to turn it on: README, "One pull request per task".

  • Verdicts from GitHub reviews (#93, #98).
    Only allowlisted reviewers who are not this host, only reviews of exactly the
    reviewed commit, each reviewer's latest word; any request for changes
    outranks every approval and is rework. An approval passes only once the
    commit's checks are green. forge.verdictSource: comments keeps the old
    envelope path; exactly one source is read.
  • Rework carries the review (#95, #96, #105, #106).
    A request for changes' body — PR-daemon's, or the local reviewer's — reaches
    the worker's next attempt, as one quoted string, and survives a failed or
    blocked attempt; it is dropped once an attempt is handed in or the task is
    accepted.
  • The work branch (#94, #97, #107).
    Recorded at the first delegate; task pull requests target it, labelled
    devloop, never trunk. It is created on the forge at the task's base,
    fast-forwarded when behind, left alone when ahead, refused when moved away;
    a review with no work branch holds on trunk or detached instead of opening a
    pull request.
  • A local review first (#99).
    forge.localReview runs a local reviewer before the pull request opens, and
    its usage counts toward the caps.
  • DevLoop merges (#100#102).
    The verdict and checks are read again, then gh pr merge --match-head-commit
    from an empty directory; the checkout fetches the merge commit by id and
    fast-forwards to it before the task is done. Already merged is not merged
    twice; anything that cannot be completed holds.
  • The release pull request (#103, #104).
    Opened once every task is done, looked at each tick outside the state lock,
    merged once approved with green checks, on the forge only.
  • Security fix: a worker could run a program as the host through git
    (#108). Found by PR-daemon's
    review. The Codex delegate was granted its worktree's gitdir, and any worker
    could rewrite its worktree's .git pointer; either could point the host's
    next git call — committing the task, the pre-PR checker, the repository
    status scan — at a repository whose config runs a program. Codex no longer
    gets the gitdir, and every host git call in a task worktree pins its git
    directories to the host's own paths with fsmonitor and hooks off. This
    predates 0.6.4 and affects local mode too.

Carried to 0.6.5 (from the reviews), and closed there: workers inherited this
host's gh login; an empty set of checks counted as green; a few messages and
gate texts to tighten. 0.6.x numbers follow the release plan rather than strict semver.

New in 0.6.3

The page speaks English, Chinese and Thai. A switch at the top right
(EN · 中 · ไทย) changes every word the page draws, in place, and is
remembered on that browser; English is the default.

  • The page's own words (#77#82).
    dashboard/i18n.js holds each string as [English, 中文, ไทย], served at
    /devloop/i18n.js behind the page's authentication. Headers, the home
    lanes, cards, the start panel, the gate and halt panels, tasks, budget,
    events, documents, the guide, repository status and the PR record all go
    through it; times use the reader's locale (Thai dates show the Buddhist
    year). A missing translation falls back to English and an unknown key
    shows as itself.
  • What the server says, by code (#83#90).
    Readiness checks, cleanup reasons, protect_patterns warnings, every gate's
    question, evidence and steps, and the halt reasons now carry a stable code
    and the values their sentence uses; the page says them in the reader's
    language and falls back to the server's own words for a code it does not
    know. The CLI and the server's messages are unchanged.
  • Tests keep it whole. Every key the page asks for, every code the server
    can send and every gate family in gate.ts must have all three languages;
    a key defined twice fails the suite.
  • Fix: a saved language is taken only when it is one of the three by own
    property (a stored constructor used to break every date on the page).

Not translated, on purpose: what models and people wrote (task titles,
GOAL.md, planning documents) and raw identifiers (reason codes, commands,
branch names).

New fields: readiness code/params, cleanup code, ProtectDrop.code,
gate key/vars, halt details (haltDetails on a project). No config or
STATE change. 0.6.x numbers follow the release plan rather than strict
semver.

New in 0.6.2

The page answers "what needs me?" first, and says what an answer costs before
it is given. Both ideas are borrowed from LoopX's control plane.

  • The home page is grouped by attention (#71, #72, #74).
    Four columns, in this order: 等你处理 (a halt asking a question, a project
    the page cannot read, an armed loop whose process has stopped), 进行中, 闲置
    (not started, paused, or a halt answered "leave it" while it is still that
    halt), 已完成. Once there are projects they come before the guide and the
    picker. Each card says in one sentence what happens next or what it waits
    for, and h...
Read more

0.6.4

Choose a tag to compare

@jhfnetboy jhfnetboy released this 12 Sep 19:33
dab8458

Release 0.6.4

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.4 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.4. This document is the release note, not a second semver.

New in 0.6.4

One GitHub pull request per task, reviewed there and merged by DevLoop, then
one release pull request to trunk: the per-task review the 0.6 design set
out, run end to end in a sandbox repository before release. Off unless
reviewerRoute names the forge backend; without it tasks merge locally as
before. How to turn it on: README, "One pull request per task".

  • Verdicts from GitHub reviews (#93, #98).
    Only allowlisted reviewers who are not this host, only reviews of exactly the
    reviewed commit, each reviewer's latest word; any request for changes
    outranks every approval and is rework. An approval passes only once the
    commit's checks are green. forge.verdictSource: comments keeps the old
    envelope path; exactly one source is read.
  • Rework carries the review (#95, #96, #105, #106).
    A request for changes' body — PR-daemon's, or the local reviewer's — reaches
    the worker's next attempt, as one quoted string, and survives a failed or
    blocked attempt; it is dropped once an attempt is handed in or the task is
    accepted.
  • The work branch (#94, #97, #107).
    Recorded at the first delegate; task pull requests target it, labelled
    devloop, never trunk. It is created on the forge at the task's base,
    fast-forwarded when behind, left alone when ahead, refused when moved away;
    a review with no work branch holds on trunk or detached instead of opening a
    pull request.
  • A local review first (#99).
    forge.localReview runs a local reviewer before the pull request opens, and
    its usage counts toward the caps.
  • DevLoop merges (#100#102).
    The verdict and checks are read again, then gh pr merge --match-head-commit
    from an empty directory; the checkout fetches the merge commit by id and
    fast-forwards to it before the task is done. Already merged is not merged
    twice; anything that cannot be completed holds.
  • The release pull request (#103, #104).
    Opened once every task is done, looked at each tick outside the state lock,
    merged once approved with green checks, on the forge only.
  • Security fix: a worker could run a program as the host through git
    (#108). Found by PR-daemon's
    review. The Codex delegate was granted its worktree's gitdir, and any worker
    could rewrite its worktree's .git pointer; either could point the host's
    next git call — committing the task, the pre-PR checker, the repository
    status scan — at a repository whose config runs a program. Codex no longer
    gets the gitdir, and every host git call in a task worktree pins its git
    directories to the host's own paths with fsmonitor and hooks off. This
    predates 0.6.4 and affects local mode too.

Carried to 0.6.5 (from the reviews): workers still inherit this host's gh
login; an empty set of checks counts as green; a few messages and gate texts
to tighten. 0.6.x numbers follow the release plan rather than strict semver.

New in 0.6.3

The page speaks English, Chinese and Thai. A switch at the top right
(EN · 中 · ไทย) changes every word the page draws, in place, and is
remembered on that browser; English is the default.

  • The page's own words (#77#82).
    dashboard/i18n.js holds each string as [English, 中文, ไทย], served at
    /devloop/i18n.js behind the page's authentication. Headers, the home
    lanes, cards, the start panel, the gate and halt panels, tasks, budget,
    events, documents, the guide, repository status and the PR record all go
    through it; times use the reader's locale (Thai dates show the Buddhist
    year). A missing translation falls back to English and an unknown key
    shows as itself.
  • What the server says, by code (#83#90).
    Readiness checks, cleanup reasons, protect_patterns warnings, every gate's
    question, evidence and steps, and the halt reasons now carry a stable code
    and the values their sentence uses; the page says them in the reader's
    language and falls back to the server's own words for a code it does not
    know. The CLI and the server's messages are unchanged.
  • Tests keep it whole. Every key the page asks for, every code the server
    can send and every gate family in gate.ts must have all three languages;
    a key defined twice fails the suite.
  • Fix: a saved language is taken only when it is one of the three by own
    property (a stored constructor used to break every date on the page).

Not translated, on purpose: what models and people wrote (task titles,
GOAL.md, planning documents) and raw identifiers (reason codes, commands,
branch names).

New fields: readiness code/params, cleanup code, ProtectDrop.code,
gate key/vars, halt details (haltDetails on a project). No config or
STATE change. 0.6.x numbers follow the release plan rather than strict
semver.

New in 0.6.2

The page answers "what needs me?" first, and says what an answer costs before
it is given. Both ideas are borrowed from LoopX's control plane.

  • The home page is grouped by attention (#71, #72, #74).
    Four columns, in this order: 等你处理 (a halt asking a question, a project
    the page cannot read, an armed loop whose process has stopped), 进行中, 闲置
    (not started, paused, or a halt answered "leave it" while it is still that
    halt), 已完成. Once there are projects they come before the guide and the
    picker. Each card says in one sentence what happens next or what it waits
    for, and how long it has waited. Each project's summary carries its lane
    and since.
  • A halt offers one answer, with its cost (#73, #75).
    Every answer now says whether a model is paid again and whether existing work
    is thrown away. The gate names a recommended answer, which is the page's one
    primary button; the others are folded under 其他选项. A gate whose only
    answer is to leave it leads with 要你做的事, the steps for the person.
  • Fix: retry said "from a clean worktree"; it is not. A retry runs the
    worker again in the task's existing worktree and base. The summary, the docs
    and the new impact say so. A redo from a clean base is still the manual
    command in the over-budget and replan gates.

A patch: new summary fields (lane, since) and gate fields (recommended,
impact), no config change and no STATE change.

New in 0.6.1

The per-PR budget, enforced by PR-daemon's own rules and recorded so it can
be judged on data. Each task's change goes through PR-daemon's mechanical
pre-PR checker before any reviewer is paid; the rules live in the PR-daemon
repository and are only called from here, so a rule change there reaches the
loop with a git pull, without a DevLoop release.

  • The checker gates the review (#55#57, #65).
    Off by default; set prePrCheck to the checker's argv
    (['bash', '~/Dev/tools/PR-daemon/scripts/pre-pr-check.sh']), with
    prePrProfile (devloop) and prePrTimeoutMinutes (5). DevLoop knows only
    the checker's contract — argv, exit codes, JSON — and never a rule. Exit 0
    passes; exit 1 with a blocking finding holds the task, as
    task_over_budget when only size rules blocked (redo it smaller) or
    prepr_blocked otherwise (SZ-4, high-risk content mixed in, is not a size); anything else, a timeout, or a result that
    disagrees with itself holds as prepr_unavailable, never a pass.
  • The budget has an elastic band (#64#69). Up to 200 lines, 5 files and
    2 counted top-level directories is normal; up to 260 / 6 / 3 is elastic —
    reviewed, with the size put in front of the reviewer, who is asked to judge
    whether it should have been split (REWORK or REPLAN); beyond that the task
    is refused as over budget. The thresholds are PR-daemon's (size.band,
    size.limits, rules 1.2.0); an older checker's result is read as normal or
    over from its blocks.
  • The planner is told the budget and estimates each task's size
    (#59, #66, #67). The estimate is
    never enforced — a malformed one is dropped, not the plan — and is logged
    beside the checker's count, the data the estimate rules will be tuned on.
  • .devloop/PR-LOG.jsonl and the PR 记录 panel
    ([#58...
Read more

0.6.3

Choose a tag to compare

@jhfnetboy jhfnetboy released this 12 Sep 13:58
6ec5d00

Release 0.6.3

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.3 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.3. This document is the release note, not a second semver.

New in 0.6.3

The page speaks English, Chinese and Thai. A switch at the top right
(EN · 中 · ไทย) changes every word the page draws, in place, and is
remembered on that browser; English is the default.

  • The page's own words (#77#82).
    dashboard/i18n.js holds each string as [English, 中文, ไทย], served at
    /devloop/i18n.js behind the page's authentication. Headers, the home
    lanes, cards, the start panel, the gate and halt panels, tasks, budget,
    events, documents, the guide, repository status and the PR record all go
    through it; times use the reader's locale (Thai dates show the Buddhist
    year). A missing translation falls back to English and an unknown key
    shows as itself.
  • What the server says, by code (#83#90).
    Readiness checks, cleanup reasons, protect_patterns warnings, every gate's
    question, evidence and steps, and the halt reasons now carry a stable code
    and the values their sentence uses; the page says them in the reader's
    language and falls back to the server's own words for a code it does not
    know. The CLI and the server's messages are unchanged.
  • Tests keep it whole. Every key the page asks for, every code the server
    can send and every gate family in gate.ts must have all three languages;
    a key defined twice fails the suite.
  • Fix: a saved language is taken only when it is one of the three by own
    property (a stored constructor used to break every date on the page).

Not translated, on purpose: what models and people wrote (task titles,
GOAL.md, planning documents) and raw identifiers (reason codes, commands,
branch names).

New fields: readiness code/params, cleanup code, ProtectDrop.code,
gate key/vars, halt details (haltDetails on a project). No config or
STATE change. 0.6.x numbers follow the release plan rather than strict
semver.

New in 0.6.2

The page answers "what needs me?" first, and says what an answer costs before
it is given. Both ideas are borrowed from LoopX's control plane.

  • The home page is grouped by attention (#71, #72, #74).
    Four columns, in this order: 等你处理 (a halt asking a question, a project
    the page cannot read, an armed loop whose process has stopped), 进行中, 闲置
    (not started, paused, or a halt answered "leave it" while it is still that
    halt), 已完成. Once there are projects they come before the guide and the
    picker. Each card says in one sentence what happens next or what it waits
    for, and how long it has waited. Each project's summary carries its lane
    and since.
  • A halt offers one answer, with its cost (#73, #75).
    Every answer now says whether a model is paid again and whether existing work
    is thrown away. The gate names a recommended answer, which is the page's one
    primary button; the others are folded under 其他选项. A gate whose only
    answer is to leave it leads with 要你做的事, the steps for the person.
  • Fix: retry said "from a clean worktree"; it is not. A retry runs the
    worker again in the task's existing worktree and base. The summary, the docs
    and the new impact say so. A redo from a clean base is still the manual
    command in the over-budget and replan gates.

A patch: new summary fields (lane, since) and gate fields (recommended,
impact), no config change and no STATE change.

New in 0.6.1

The per-PR budget, enforced by PR-daemon's own rules and recorded so it can
be judged on data. Each task's change goes through PR-daemon's mechanical
pre-PR checker before any reviewer is paid; the rules live in the PR-daemon
repository and are only called from here, so a rule change there reaches the
loop with a git pull, without a DevLoop release.

  • The checker gates the review (#55#57, #65).
    Off by default; set prePrCheck to the checker's argv
    (['bash', '~/Dev/tools/PR-daemon/scripts/pre-pr-check.sh']), with
    prePrProfile (devloop) and prePrTimeoutMinutes (5). DevLoop knows only
    the checker's contract — argv, exit codes, JSON — and never a rule. Exit 0
    passes; exit 1 with a blocking finding holds the task, as
    task_over_budget when only size rules blocked (redo it smaller) or
    prepr_blocked otherwise (SZ-4, high-risk content mixed in, is not a size); anything else, a timeout, or a result that
    disagrees with itself holds as prepr_unavailable, never a pass.
  • The budget has an elastic band (#64#69). Up to 200 lines, 5 files and
    2 counted top-level directories is normal; up to 260 / 6 / 3 is elastic —
    reviewed, with the size put in front of the reviewer, who is asked to judge
    whether it should have been split (REWORK or REPLAN); beyond that the task
    is refused as over budget. The thresholds are PR-daemon's (size.band,
    size.limits, rules 1.2.0); an older checker's result is read as normal or
    over from its blocks.
  • The planner is told the budget and estimates each task's size
    (#59, #66, #67). The estimate is
    never enforced — a malformed one is dropped, not the plan — and is logged
    beside the checker's count, the data the estimate rules will be tuned on.
  • .devloop/PR-LOG.jsonl and the PR 记录 panel
    (#58, #61#63, #65).
    One line per check — size, band, estimate, rules hit, rules version — and
    per review verdict. Best-effort (a lost line costs only that line), never
    through a symlink, and a malformed line is dropped rather than taking the
    page down. The project page shows the latest 50, marking 弹性 and 超限.
  • Redoing a task smaller is real (#60).
    The over-budget and replan gates used to suggest editing PLAN.md, which the
    loop never reads back; they now give the commands that redo the task from
    its base, and the worker's prompt states the budget.
  • A pending hold that cannot be read says so on every tick
    (#59). One kept through a
    read error (EACCES and the like) used to wait in silence until it read.

A minor: three new optional config keys, new optional task fields
(overBudget, estimate), a new file under .devloop/, no change to
existing behaviour while prePrCheck is unset.

New in 0.6.0

The first step of the 0.6 plan (design: draft PR #42): DevLoop does
the status half of pilot's work itself — see a repository's branches and
worktrees, and clean up merged branches — from the page, without a skill.
Shipped as eleven reviewed PRs, each inside the per-PR budget and each through
PR-daemon's mechanical pre-PR rules, a local review and PR-daemon's review.

  • 仓库状态 panel (#43#47, #49, #50).
    On every project page, before and after a start: current branch, trunk,
    ahead/behind, uncommitted changes; the merged branches that can go, as ticked
    checkboxes; every kept branch with its reason; the steps left to a person
    with their commands. 删除选中的分支 runs git branch -d for the ticked
    branches the plan still offers at that moment, and says which were deleted
    and why any were not. The rules it keeps are in
    Dashboard.md ("Branch cleanup deletes only what git itself calls safe").
  • .pilot.yml protect_patterns are honoured, read as a superset of pilot's
    own ref hook (both list forms, CRLF, blank and comment lines, non-ASCII
    names) and never below release/hotfix/deploy; entries that protect nothing,
    such as globs, are shown as a warning.
  • A finished dispatch waits for the state lock to save its result
    (#51) instead of dropping it
    after one try, and a hold that cannot get the lock is kept in
    .devloop/PENDING_HOLD for the next tick.
  • Fix: a tag named like the trunk no longer hides it
    (#48). With a tag main, git
    shortened the branch to heads/main and the start check let a loop start on
    main; branches are now read by full ref.

A minor: new operator surface and a new endpoint pair
(GET …/projects/<id>/status, POST …/projects/<id>/cleanup), no config
change and no new STATE field.

New in 0.5.6

The last loose ends before 0.6, and the first release made the new way: split
into PRs inside the per-PR budget (≤200 lines, ≤5 files, ≤2 counted top-level
directories), each passing PR-daemon's mechanical pre-PR rules and a local
review before PR-daemon reviewed it.

  • **Each task reco...
Read more

0.6.2

Choose a tag to compare

@jhfnetboy jhfnetboy released this 12 Sep 12:20
be5ccfb

Release 0.6.2

Bounded autonomous engineering loop: structured model results, deterministic state transitions, host-enforced write scope, SHA-bound independent review, durable recovery, and role/tier routing. Tag v0.6.2 and the GitHub Release are created after this commit is on main; steps: Deploy.md.

Package version: 0.6.2. This document is the release note, not a second semver.

New in 0.6.2

The page answers "what needs me?" first, and says what an answer costs before
it is given. Both ideas are borrowed from LoopX's control plane.

  • The home page is grouped by attention (#71, #72, #74).
    Four columns, in this order: 等你处理 (a halt asking a question, a project
    the page cannot read, an armed loop whose process has stopped), 进行中, 闲置
    (not started, paused, or a halt answered "leave it" while it is still that
    halt), 已完成. Once there are projects they come before the guide and the
    picker. Each card says in one sentence what happens next or what it waits
    for, and how long it has waited. Each project's summary carries its lane
    and since.
  • A halt offers one answer, with its cost (#73, #75).
    Every answer now says whether a model is paid again and whether existing work
    is thrown away. The gate names a recommended answer, which is the page's one
    primary button; the others are folded under 其他选项. A gate whose only
    answer is to leave it leads with 要你做的事, the steps for the person.
  • Fix: retry said "from a clean worktree"; it is not. A retry runs the
    worker again in the task's existing worktree and base. The summary, the docs
    and the new impact say so. A redo from a clean base is still the manual
    command in the over-budget and replan gates.

A patch: new summary fields (lane, since) and gate fields (recommended,
impact), no config change and no STATE change.

New in 0.6.1

The per-PR budget, enforced by PR-daemon's own rules and recorded so it can
be judged on data. Each task's change goes through PR-daemon's mechanical
pre-PR checker before any reviewer is paid; the rules live in the PR-daemon
repository and are only called from here, so a rule change there reaches the
loop with a git pull, without a DevLoop release.

  • The checker gates the review (#55#57, #65).
    Off by default; set prePrCheck to the checker's argv
    (['bash', '~/Dev/tools/PR-daemon/scripts/pre-pr-check.sh']), with
    prePrProfile (devloop) and prePrTimeoutMinutes (5). DevLoop knows only
    the checker's contract — argv, exit codes, JSON — and never a rule. Exit 0
    passes; exit 1 with a blocking finding holds the task, as
    task_over_budget when only size rules blocked (redo it smaller) or
    prepr_blocked otherwise (SZ-4, high-risk content mixed in, is not a size); anything else, a timeout, or a result that
    disagrees with itself holds as prepr_unavailable, never a pass.
  • The budget has an elastic band (#64#69). Up to 200 lines, 5 files and
    2 counted top-level directories is normal; up to 260 / 6 / 3 is elastic —
    reviewed, with the size put in front of the reviewer, who is asked to judge
    whether it should have been split (REWORK or REPLAN); beyond that the task
    is refused as over budget. The thresholds are PR-daemon's (size.band,
    size.limits, rules 1.2.0); an older checker's result is read as normal or
    over from its blocks.
  • The planner is told the budget and estimates each task's size
    (#59, #66, #67). The estimate is
    never enforced — a malformed one is dropped, not the plan — and is logged
    beside the checker's count, the data the estimate rules will be tuned on.
  • .devloop/PR-LOG.jsonl and the PR 记录 panel
    (#58, #61#63, #65).
    One line per check — size, band, estimate, rules hit, rules version — and
    per review verdict. Best-effort (a lost line costs only that line), never
    through a symlink, and a malformed line is dropped rather than taking the
    page down. The project page shows the latest 50, marking 弹性 and 超限.
  • Redoing a task smaller is real (#60).
    The over-budget and replan gates used to suggest editing PLAN.md, which the
    loop never reads back; they now give the commands that redo the task from
    its base, and the worker's prompt states the budget.
  • A pending hold that cannot be read says so on every tick
    (#59). One kept through a
    read error (EACCES and the like) used to wait in silence until it read.

A minor: three new optional config keys, new optional task fields
(overBudget, estimate), a new file under .devloop/, no change to
existing behaviour while prePrCheck is unset.

New in 0.6.0

The first step of the 0.6 plan (design: draft PR #42): DevLoop does
the status half of pilot's work itself — see a repository's branches and
worktrees, and clean up merged branches — from the page, without a skill.
Shipped as eleven reviewed PRs, each inside the per-PR budget and each through
PR-daemon's mechanical pre-PR rules, a local review and PR-daemon's review.

  • 仓库状态 panel (#43#47, #49, #50).
    On every project page, before and after a start: current branch, trunk,
    ahead/behind, uncommitted changes; the merged branches that can go, as ticked
    checkboxes; every kept branch with its reason; the steps left to a person
    with their commands. 删除选中的分支 runs git branch -d for the ticked
    branches the plan still offers at that moment, and says which were deleted
    and why any were not. The rules it keeps are in
    Dashboard.md ("Branch cleanup deletes only what git itself calls safe").
  • .pilot.yml protect_patterns are honoured, read as a superset of pilot's
    own ref hook (both list forms, CRLF, blank and comment lines, non-ASCII
    names) and never below release/hotfix/deploy; entries that protect nothing,
    such as globs, are shown as a warning.
  • A finished dispatch waits for the state lock to save its result
    (#51) instead of dropping it
    after one try, and a hold that cannot get the lock is kept in
    .devloop/PENDING_HOLD for the next tick.
  • Fix: a tag named like the trunk no longer hides it
    (#48). With a tag main, git
    shortened the branch to heads/main and the start check let a loop start on
    main; branches are now read by full ref.

A minor: new operator surface and a new endpoint pair
(GET …/projects/<id>/status, POST …/projects/<id>/cleanup), no config
change and no new STATE field.

New in 0.5.6

The last loose ends before 0.6, and the first release made the new way: split
into PRs inside the per-PR budget (≤200 lines, ≤5 files, ≤2 counted top-level
directories), each passing PR-daemon's mechanical pre-PR rules and a local
review before PR-daemon reviewed it.

  • Each task records who planned it (#38).
    STATE named the implementer and reviewer but not the planner, so after the
    switch to three-way routing only Codex's own logs showed who planned. Every
    task a plan creates now carries planner (the route identity), validated on
    load like the other two; STATE files without it load unchanged.
  • The page shows all three roles, and a selection no longer freezes it
    (#40). Each task row reads
    规划 … · 实现 … · 评审 …. The refresh used to pause for any text selection
    until the reader clicked elsewhere, so a task id selected to copy froze the
    gate and budget; it now pauses only for a selection inside a document, and
    for at most 60 seconds.

A patch: a new optional task field, no config change.

New in 0.5.5

The loop can be watched and understood from the page, and the trunk rule now
holds for the whole run, not only at start.

  • Every merge refuses the trunk. 0.5.4 checked the branch when a loop
    started. Now the merge asks the same question each time, so a checkout
    switched back to main/master/the configured base mid-loop, or a project
    armed by writing GOAL.md by hand, halts with a new merge_onto_trunk hold
    (and a detached HEAD with merge_detached_head, which used to retry silently).
    The reviewed task stays merge_ready; the page says to move the checkout back
    and resume, and it merges on the next tick without being redone or paid for
    again.
  • A root that is not its own git toplevel is refused. A plain directory
    inside another repository used to pass the start check with the outer
    repository's branch.
  • The planning documents are on the page. The project page has a 文档 panel,
    before and after a start. It previews pilot's roadmap, tasks, progress,
    acceptance, architecture, spec and research from docs_dir, and DevLoop's own
    GOAL, PLAN, REVIEW and PROGRESS, rendered as markdown built from text nodes.
    Each task in the table now l...
Read more