Skip to content

v26.11.3

Choose a tag to compare

@ancongui ancongui released this 07 Nov 09:48
· 403 commits to main since this release
73086f9

This release installs devkit with one command, runs its
hooks from a pinned copy, gives you a live dashboard, puts the crew under one enforced RACI (who is Responsible,
Accountable, Consulted, and Informed for each kind of work), holds irreversible actions until you grant them, protects
devkit's own state from agents, carries a session's work through compaction, backs up branches that exist only on
this Mac when that starts no CI run, explains what fills your disk and frees it item by item, and makes the audit trail
verifiable and exportable.

What changes for you

devkit refuses more in this release. Each refusal says why and names the command to use instead.

  • You run dev install, dev update, and install.sh yourself, in a terminal. Agents are refused them.
    dev install refuses a checkout with uncommitted tracked changes or code that does not compile, and pins only a
    published release or a commit whose bin/dev ci --run passed; --unverified --why "…" overrides that, and the
    override is audited.
  • Agents cannot change devkit's state, configuration, or install. Writes to ~/.local/state/devkit,
    ~/.config/devkit/config.json, and ~/.local/share/devkit, dev config set safeguards.* or audit.*, and
    dev config edit are refused to every agent. You change safeguards in a terminal. A DEVKIT_* variable added to
    the env block of a Claude Code settings file (user, project, or local) is refused and removed.
  • devkit cannot be pointed elsewhere by an agent. The guard refuses HOME, DEVKIT_CONFIG, DEV_ROOT, or
    DEVKIT_SESSION set for dev, and a swapped dev link or another dev earlier on the PATH. devkit reads a
    non-standard DEVKIT_CONFIG or DEV_ROOT only from a command you run in a terminal with no agent among its parent processes.
  • Four escape hatches moved. dev commit, dev push, dev pr create, and dev release no longer read
    DEVKIT_SKIP_SECRET_SCAN or DEVKIT_LOCAL_CI_PASSED from their environment. Pass --ci-passed (recorded as
    attested), or let a real dev ci --run lift the push budget. dev git and dev gh no longer read
    DEVKIT_FLAKY or DEVKIT_CROSS_PROJECT from theirs; rerun a flaky CI run with
    dev run rerun <id> --flaky "<reason>". In the main session, a hatch still works as a prefix of the command
    itself, such as DEVKIT_SKIP_SECRET_SCAN=1 git commit, where the guard sees it and records it as guard.bypass;
    the next prompt names it, and DEVKIT_GUARD=off is recorded once per session and shown when a session starts.
  • Irreversible actions wait for your grant. In the main session, these need a line you type on its own,
    grant <action> <target>: merging a pull request (grant merge 142), releasing a version, also by pushing its tag
    (grant release v26.11.3), a force push or a push to the default branch, a comment, review, or edit on a pull
    request or an issue, publishing a package, a deploy, a write through an API, and an MCP tool that sends, creates,
    or deletes something outside this Mac. The refusal names the exact line. A grant is used once, holds only in the
    repository of the session you typed it in, and expires after 30 minutes. A push of another branch and a new pull
    request are recorded, not held. For its first week on a Mac the gate only records what it would refuse, then it enforces;
    safeguards.irreversible_main sets it.
  • Some actions are yours alone, in every setting. Lifting an embargo (dev branch embargo --lift),
    dev backup --public, and a change to a project's backup policy wait for a line you type: grant embargo <branch>
    or grant backup <project> (grant developer-only <target> works too). The gate's first audit week does not let
    them through, and crew members never run them.
  • An agent's push or pull request of an embargoed branch needs your grant embargo <branch>. A push or pull
    request from a folder the guard can only learn when it runs (cd "$X" && git push, GIT_DIR=$G git push) is
    refused while any project on this Mac has an embargo; the agent writes the folder out instead.
  • A decision is yours only in your own words. It counts when you answer the question dialog, or type a line of
    your own: approve D3, approve D3: B, or grant push feat/invoice-export. Without that, an answer the tech lead
    records is marked unverified, and an irreversible decision stays pending. dev crew mode auto --approve takes one
    target per action (push feat/*) and never pre-approves publish, deploy, a developer-only action, or a command the
    guard cannot name.
  • Crew members are named by role. devkit's output, briefs, and refusals write a member as Backend engineer
    (Tank)
    and the main session as the tech lead. A final message or a member's report whose prose names a member
    without the role is sent back once; the role alone is fine, in any language (canary.roles).
  • dev options are read exactly. Every dev command refuses an abbreviated option (--sched for
    --scheduled), and a word after -- is an argument, as the guard reads it.
  • dev pr ready needs local CI evidence for HEAD, because marking a draft ready starts its one CI run. When every
    check of a pull request was skipped, dev pr checks reports no checks yet (exit code 8) and dev pr merge waits for
    the real run.
  • Only the tech lead plans and decides. dev progress start, assign, begin, reopen, skip, and done, and
    dev crew decide and mode, are refused from a crew member and from a script. A second dev progress start on a
    live run needs --replace --why "…".
  • The RACI is enforced. dev progress assign refuses a member who is not Responsible for the step's kind of work,
    and dev progress done refuses to end a run before each Accountable member approved; --why "…" overrides both
    and is recorded. dev progress start and add refuse unknown, ambiguous, or duplicate step names and dependency
    cycles, and no step starts before its dependencies are done.
  • Crew members are held tighter. They are refused every escape hatch (DEVKIT_* variables, env -i,
    --ci-passed, --no-verify, dev config set, new secret-scan exceptions). A review or read-only member's shell
    runs only a read-only allowlist; add your project's own checks with safeguards.readonly_commands. Members never
    merge, release, tag, publish, deploy, write through an API, or force-push. A member pushes a branch, backs one up,
    or opens a pull request only in a step allowed it (dev progress assign --allow push,pr), and only with your grant
    for that action or a decision of yours that names it; the step keeps the target and the repository that evidence
    covers, and opens nothing else. When a review or read-only member's shell call writes files, the tech lead gets a
    message, which names the working member whose scope holds a file, and the member's step ends unverified until the
    tech lead checks the diff. In the session scratchpad, each member writes only in its own scratchpad/<member>/
    folder.
  • A member's step ends done only on evidence. That is a Check ✓ in its report, or its own
    dev progress step --check. Otherwise the step shows as unverified, for the tech lead to close with evidence or
    reopen (dev progress reopen <step> --why "…").
  • Approvals are explicit. Each finished step owes a verdict from the Accountable member of its kind of work,
    given after the work, for example by the Check ✓ of a review step that follows it. Nobody approves their own work:
    when the approver did it, the Code reviewer (Seraph) approves code and configuration, and the tech lead the rest. An
    approval needs the ✓ itself, so "tests not run" approves nothing, and a step with no approver cannot be approved
    until its kind of work is declared (dev progress assign … --activity <id>).
    dev progress step --approves "<steps>" and dev crew ask --decision --approves "<steps>" name the work a Check or
    your answer approves.
  • Running a devkit hook by hand is refused in every session, because a hook event typed through a shell could
    forge your prompt or answer.
  • Audit records are kept 13 months, on this Mac and in the handoff copy; this Mac used to keep two years.
    dev config validate refuses an audit.retention.floor_months under 3.
  • dev ls, dev du, and dev status show what is on this Mac. A footer counts the other projects of the
    portfolio, and dev ls --all lists them with the dev clone command for each.
  • dev gc is the old name of dev free. Without arguments it prints the plan to free space instead of a
    cleanup dry run, and dev gc 3 frees item 3 of that plan. dev gc --apply still runs the unattended cleanup.
  • dev dashboard starts a local server and opens a one-time sign-in link instead of writing a file.
    dev dashboard --export <file> writes the static page.

Added

Install and update

  • A one-line install: curl -fsSL https://raw.githubusercontent.com/fireflysoftwaresolutions/devkit/main/install.sh | bash
    installs Homebrew, git, Python, and the GitHub CLI when they are missing, clones the newest devkit release into
    ~/Development/fireflysoftwaresolutions/devkit, signs you in to GitHub, and starts the setup wizard. Its questions
    come from the terminal even through the pipe; without a terminal (CI), it runs without questions and says how to
    finish. It says first that devkit is for macOS (Apple Silicon and Intel) and stops on any other system. New:
    --no-setup, --help, and the DEVKIT_HOME, DEVKIT_REPO, and DEVKIT_REF variables. Each step says in one
    plain sentence what it does and why; a failed step is named, with the command to run again; and the run ends with
    what you have now and what to do first.
  • A first install for people who are not developers: a step-by-step guide in Getting started, with what you
    see at each step. Pressing Return at every question gives a working setup: the GitHub sign-in uses HTTPS and the
    browser, so it asks no questions about protocols or tokens, and the wizard's first screen says what devkit and the
    handoff repository are.
  • A pinned, read-only copy runs the hooks and the guard. dev install copies the checkout's commit to
    ~/.local/share/devkit/releases/<version>-<sha>, read-only and with a SHA-256 manifest. The hooks, the status line,
    ~/.local/bin/dev, the scheduled jobs, and the Desktop launcher run that copy, so an edit to the checkout, broken
    or malicious, no longer changes the guard of every session at once. dev doctor fails on a changed copy or a hook
    that runs elsewhere, dev install --version <version> rolls back, and the newest three copies and any in use are
    kept. dev update pins the new release.
  • First-task tutorials for every surface: Claude Code (Terminal and the IDEs), Claude Desktop's Code tab, Codex
    CLI, and Codex in the ChatGPT app, plus a page on Claude Desktop chat and Cowork. Each shows what you see on the way:
    the status block, progress updates, approvals, the crew graph, and the dashboard. Where to use devkit compares the
    surfaces. Codex is not verified live yet.

The live dashboard

  • dev dashboard is a live, read-only app on this Mac. It starts a local server (or reuses one of the same
    version), opens a one-time sign-in link, and pushes each change to the open page, which updates in place: the
    route, the filters, the scroll position, and an open drawer stay. --no-open prints the link, --status and
    --stop manage the server, and --export <file> and --path write the static page. The server stops after 30
    minutes with no open page (dashboard.idle_minutes). It answers only GET and HEAD on 127.0.0.1, with a token or a
    same-site cookie, under a content security policy that allows only its own scripts.
  • Background work: decisions waiting for you first, every run with its steps and owners, CI results with the
    first error and the next action, and scheduled jobs with their failed, overdue, and not-scheduled states.
  • One drawer for every detail, the connected task (who has it, what blocks it, what is next), the crew with
    role-first names, and a live indicator with reconnecting and offline banners. No data is never "on track," every
    count names its window, and a contradiction shows where it occurs, with its fix. The navigation never scrolls
    sideways, from 320 to 1,600 pixels wide.

The crew

  • A RACI for every kind of work, led by the tech lead. Each of 34 kinds of work has one Responsible member, one
    Accountable member, and the members Consulted and Informed (dev crew raci). The tech lead (Morpheus) routes every
    development request by it. Nobody approves their own kind of work: the Security engineer approves CI/CD, the Code
    reviewer approves security code, the Product owner approves UX, the Security engineer approves compliance, and the
    tech lead approves incidents.
  • Roles first, everywhere. The crew views, the progress update and its Crew line, messages, decisions,
    delegation, dispatch, scope and slot refusals, the continuity texts, and every brief's report header write a member
    as Backend engineer (Tank). The guard's refusals call the main session the tech lead. Stored names and the ids in
    commands (--to tank) do not change. The end-of-turn role check holds the prose to it (see What changes for you).
  • A procedure for every member: phases, the skills and devkit commands to use, a gate, and a proof that devkit
    checks. Each brief carries the knowledge of its kind of work (skills and devkit guides), the stack skills of its
    files, and the known pitfalls for the task.
  • Kinds of work in any language. A step's kind of work comes from what you declare (--activity on
    dev progress assign, [id] in a plan spec), then from the member's role, then from its files. Words are only the
    last guess and never refuse work. Lessons work the same way: they carry anchors (files, commands, kinds of work,
    error signatures, stack), set with dev lesson add --file, --command, and --error, or dev lesson anchor.
  • The crew gates. When a member stops, devkit reads its transcript and sends it back once for a missing proof, a
    skill it did not load, unfinished work, a test that cannot fail, or a missing lesson after repeated refusals.
    crew.gates.enforce: false only records them.
  • Lanes and helpers. Each member's lane binds to its own launch, so members launched together never take each
    other's name or step, and a step binds to a working lane only when that lane's launch names it. A member may launch
    narrow helpers, which get its tools and files, take a slot, and stop at progress.max_depth (2).
  • Crew slots. progress.max_parallel (4) sets how many members work at once, and your recorded usage lowers it:
    progress.quota_steps keeps a share of the slots from 50, 70, and 85 % usage, the 5-hour and the weekly windows
    both count and the lower limit wins, and one member works at a time from progress.quota_percent (90). A
    review-only or read-only member costs half a slot and the Lookup scout (Sparks) nothing (progress.slot_weights).
    progress.reserve (1) keeps a slot for what you ask while the crew works. dev crew next ranks the ready steps by
    critical path, then your latest request, then age, and records that order; a launch out of it needs
    dev crew next --first <step> --why "…". The slots in use and why the limit is lower show in dev crew,
    dev crew next, and the status block's Crew line, and each change of the limit is audited (crew.limit). A member
    stopped with TaskStop frees its slot at once. A team's policy/progress.json can set a ceiling, and you change the
    keys with dev config set, in a terminal.
  • Who is calling. A call ledger records which agent made each shell call, so a dev command knows whether the
    tech lead or a member ran it, and two sessions in one repository each update their own run.
  • New commands: dev crew graph (the live session as one graph; --mermaid, --json), dev crew rules (every
    crew rule and the check that enforces it), dev crew raci --set, dev crew set, and dev crew history (the team's
    changes, kept in the handoff repository with who and why), dev crew decisions --ask, dev task reopen --why, and
    dev agents rules [--section].
  • The status block gains optional Crew and You bullets, and dev status shows each on its own rows.
  • Claude Desktop chat and Cowork get the full global rules through the extension's new devkit_rules tool.

Continuity

  • A session keeps its work through compaction, resume, and /clear, on Claude Code and Codex. Before a
    compaction, devkit writes a checkpoint: the run and its current step, the crew working now, the decisions and
    messages waiting, your last 5 requests, and git. In Claude Code's main session it also tells the summarizer what to
    keep. After the compaction or a resume, the session gets the continuity brief first (at most 4 KB), and in Claude
    Code the next hook names what the summary left out ("Not in the summary"). A member whose own context was compacted
    gets a reminder of its role, step, scope, and report format. After /clear, the new session hears of the old
    session's open run and gets dev session carry. See Continuity.
  • Your requests stay private to the session. They are kept redacted, cut to 1,000 characters, only for turns of
    development work, for 7 days at most, and only the session's own provider sees their text. The summary itself is
    never stored. dev session forget deletes the records.
  • devkit_resume, a read-only tool of the devkit extension, gives Claude Desktop chat and Cowork the same brief for
    a project's latest session, with your request text only when the app is that session's provider.
  • The global instructions tell the agent that devkit's record wins over a summary, and what to keep when it writes
    one.

Branches, backups, and pull requests

  • The branch map: one row per local branch with its upstream, how far it is ahead of and behind the upstream and
    the default branch, the commits that exist only on this Mac and the branch that carries them, its last backup, an
    embargo, its worktree, its pull request, its linked task, and whether its work is safe off this Mac, with the
    reason. dev branch ls prints it (--json), dev status has a Branches section, dev overview counts the
    branches not backed up and embargoed, the handoff note's generated block lists the branches, the session-start
    context names the branches only on this Mac, and the dashboard has a Branches tab on each project page.
  • dev backup [<branch>…] [--all] copies the commits that exist only on this Mac to the remote, under the same
    branch name, when that push starts no CI run. It reads the CI configuration of the commit it sends (GitHub
    Actions, GitLab, Bitbucket, and Azure) to tell. It never pushes the default branch, a long-lived branch (main,
    master, develop, trunk, gh-pages), or a branch a workflow deploys from, never forces, and stops at a
    diverged remote branch with the commands to resolve it. Its WIP, embargo, security-fix, and secret checks read
    exactly the commits the push target lacks, also when another remote has them, and it reads visibility and pull
    requests on the repository the branch's remote names. --accept-ci pushes anyway and counts against the push
    budget. dev sync backs up the branches
    that need it every hour and at the end of a session, for commits older than backup.after_minutes (30);
    backup.auto: false turns that off.
  • A backup policy per project: dev backup policy on|off|ask --why "…" records it in the project's handoff note,
    for every machine and the team. Without one, a private repository is on and a public one is ask: dev backup
    asks you once, in your own terminal, and records the answer. dev sync and agents are never asked and never
    publish.
  • Embargoes: dev branch embargo <branch> --why "…" [--until …] holds the pushes of a branch, and of the commits
    it held after a merge, until you lift it (--lift): from its project, its git folders and worktrees, temporary
    clones, and folders that are no project (see Known limits). An embargo is kept in the handoff note's metadata, so every
    machine sees it, and a note devkit cannot read stops every backup. On a public repository, a branch whose commits
    read as a security fix is not backed up: devkit suggests an embargo, and dev backup --public pushes it anyway.
  • Draft pull requests early, CI once. With delivery.draft_pr on, dev pr create opens a draft unless
    --ready, and a draft needs no local CI evidence where the workflows skip drafts. dev pr ready checks the
    evidence for HEAD, then marks the draft ready, which starts its one CI run. dev ci audit flags workflows that run
    every job on drafts or skip drafts without ready_for_review, and --fix and dev ci init write the draft gate.
  • The push budget counts only pushes that start CI. devkit reads whether a push starts a run, and counts it on
    any doubt.
  • dev task start links the task to the branch it runs on, in the private handoff, so task ids stay out of branch
    names.

Commit messages

  • One template for every commit: config/git/commit-template.txt, with the header, why, what changed, and how it
    was verified, then the Refs: and BREAKING CHANGE: trailers. dev commit --why "…" --verified "…" writes it,
    --body (repeatable) adds what changed, --refs and --breaking add the trailers, and Refs: comes from the
    ticket of the task started on the branch. A message that names a devkit task id is refused.
  • The template in your editor: dev setup asks whether new commit messages open with it, the git step of
    dev install sets commit.template in each repository that has none of its own, and dev setup commit-template
    asks again (--remove takes it out). See Git and GitHub › Commits.

The terminal

  • Project aliases: dev alias <alias> [project], dev alias rm <alias>, and dev alias to list them, shared
    with the team through the handoff repository. Names match by exact id or alias, then repository name, then start,
    then any part; a tie lists every match with its command instead of guessing. dev status, go, open,
    wt new --repo, claude, and codex accept them, so dev status devkit works from any folder.
  • A new dev status: it shows Needs you first, then Right now, the last update in full, details, and the footer. It wraps
    at 100 columns, fits 80, and reads the same with NO_COLOR; --json returns the same data.
  • dev config is a report: each difference says whether it is new in this devkit version, changed outside
    devkit, or removed outside devkit, and names the fix. dev config --check prints one line and exits 1 on a
    difference.
  • A devkit helper in your shell prompt, if you want it: dev setup prompt asks first, in your own terminal only
    (an agent's call changes nothing), and dev install asks once. Inside a devkit project it shows the project's
    alias, how many crew members are working, your branch's checks, and a question that waits for you; outside, nothing.
    Nothing runs when the prompt is drawn: the hooks (a tool call at most every 5 seconds; a prompt, the end of a turn,
    and a member that starts or stops at once), dev status, dev alias, dev prompt refresh, and CI watch results
    write its facts to a cache, which a zsh function reads (0.13 ms per prompt, measured). The function reads the cache
    only when it is a regular file of yours that nobody else can write, and takes only digits from it as numbers.
    Members count while their heartbeat is under 15 minutes old, the checks hide when you leave their branch, and after
    24 hours without a refresh only the alias stays. Starship gets a marked block in starship.toml, saved first; plain
    zsh gets devkit's own block, so ~/.zshrc is not edited; oh-my-posh and Powerlevel10k get snippets.
    dev setup prompt --remove takes it out, and dev prompt shows what it shows here. See
    The prompt helper.
  • dev config set <key> <value> changes one key in a terminal: it validates the value, writes the file
    atomically, prints the old and the new value, and records dev.config.set in the audit trail. Agents are refused.
  • devkit keeps the whole status block of a final message (up to 8,000 characters), not its first 700.
  • Shell completion covers every command and the verbs of dev task, progress, crew, and agents.
  • dev doctor checks that the skills the crew names are installed for each agent. The setup wizard offers optional
    skill groups for the tools you pick, such as iac for Terraform.
  • dev session shows and manages what devkit keeps of a session through compaction, /clear, and resume:
    brief prints it (--latest for the project's newest session with an open run), carry moves the run into this
    session after /clear, compactions <transcript> counts a Claude Code transcript's compactions, and forget
    deletes the records. brief, carry, and forget are the tech lead's. See Continuity for the hooks that fill
    these records.

Disk

  • dev du explains what fills your disk. For each project on this Mac: the main checkout, managed worktrees,
    Claude Code and Codex worktrees, and copies outside the layout, each with its largest ignored folders. Then
    Colima's disk and the space macOS has not got back, agent data and caches with whether each is safe to clear, and a
    plan to free space, ranked by size, with each item's safety, risk, and command. It deletes nothing, and answers in
    under 2 seconds from its cache (--refresh, --plan, --json, or one project by name). See
    Disk use.
  • dev free <n> frees items of that plan by number, or every safe one with --safe. It lists what it deletes,
    asks once, checks again at that moment for changed files, unpushed commits, and programs working in the folder,
    and deletes nothing when a newer measurement changed the plan you saw. It keeps a build folder that holds files git
    tracks, never prunes Docker volumes, and records every deletion in the audit trail.
  • dev docker trim gives Colima's free space back to macOS without deleting anything.

The audit trail

  • Schema v2: every record has a sortable id, who acted (and the crew member, lane, and launch), the project,
    branch, run, and step, a category and severity, the reason for an override, and its evidence. Older records still
    read. See The audit trail.
  • A hash chain: each record is linked to the one before it, and dev audit verify reports the first edited,
    removed, or inserted record, using the published copy as the anchor.
  • Retention you set: audit.retention.local_months, team_months, and floor_months, audit.hold for a legal
    hold, and audit.level (security, changes, or all). A team policy in the handoff repository can only raise
    them.
  • Queries and exports: dev audit show, stats, and config, filters by date, project, member, category,
    severity, outcome, and text, dev audit export as JSONL, CSV, OCSF, or CEF, and audit.forward to a file or
    syslog.
  • Personal data: the audit trail page says what is recorded and never recorded, who receives it, how long it is
    kept, and how the people recorded use their GDPR rights.

Changed

  • A first dev setup on a Mac with no projects asks which languages to set up, with Python and Node preselected,
    instead of installing Java, PHP, Node, and Python without asking.
  • Claude Code: attribution.sessionUrl is false, so cloud and Remote Control sessions add no Claude-Session
    trailer either; the deprecated includeCoAuthoredBy key is removed; and BASH_DEFAULT_TIMEOUT_MS is 5 minutes,
    so a test suite or a build in the foreground is not cut off at 2.
  • Codex: analytics.enabled is false. dev doctor also reads whether your Codex account adds commit and PR
    attribution (an account setting, not a config.toml key) from your newest session.
  • dev doctor reads Claude Desktop's own switch for bypass mode in the Code tab (Settings → Code → Allow bypass
    permissions mode) and says whether it is allowed, off, or not offered for the signed-in account.
  • dev update follows releases: a checkout at a release tag moves to the newest vYY.MM.PATCH tag (compared as
    numbers, so 26.11.10 is newer than 26.11.2) and then runs dev install; at the newest release already, it says so
    and changes nothing. A checkout on a branch still gets git pull --ff-only. It refuses, with nothing changed, while
    tracked files have local changes or when the checkout is at a commit that is neither a release nor a branch.
  • The wizard's line prompts say so when no terminal can answer and every question takes its default. Without a
    GitHub sign-in, the wizard says why it needs one and prints the exact command.
  • The PostToolUse hook shows the status block right after a call that usually ends a turn (a subagent launch, a
    monitor, a background command, or a closing dev command), with the project and branch filled in. A note
    written after the last tool call no longer lands before the block, so the Stop hook does not have to send
    the turn back.
  • Lessons are recalled by what a call does. A session gets the catalog of kinds of work, skills, and lesson
    anchors at its start. A tool call is reminded of the lessons anchored on its command or file, and its output of
    those whose error signature it shows, each at most once an hour; every refusal names the lessons of the call it
    refuses. dev sleep merges lessons that share anchors, and with background AI on (ai.*, opt-in, with a daily
    budget), a small model also merges lessons written in different languages.
  • Skill rules trigger on files, commands, and declared kinds of work, and a turn counts as development work from
    what it did, never from your words.
  • The dashboard counts a run as working while the run or any of its crew lanes reported in the last 30 minutes,
    "of about" is the plan's current total (active time plus the time left), lists show a step's title without codes
    such as F4, and a member's step that stopped without evidence shows as unverified, for the tech lead to check, never
    under Needs you.
  • Fewer turns sent back. Before the end of a turn, and after every commit, devkit lists the end-of-turn items
    still open (the handoff note, required skills, tests that cannot fail, untracked stubs), each once per turn, so the
    agent settles them before the Stop hook would. The handoff gate sends a turn back only at
    handoff.block_after_commits (5) commits newer than the note, when the oldest is handoff.block_after_minutes (60)
    old, or after a milestone: the end of a run, a work item closed, a push, a pull request, or a release. An
    intermediate step is not a milestone, a milestone counts only the commits made before it, and while crew members
    work the main session gets the reminder only. Each send-back is audited as stop.block and each item settled after
    a reminder as stop.prevented; dev canary opens with the turns sent back per day and rule. Codex gets the same
    reminder after a shell call, not verified live yet.
  • devkit's own test suite is hermetic. Run it as a package, python3 -m unittest discover -s tests -t .:
    tests/__init__.py gives the run a temporary home and refuses, and records, any access to your real devkit state,
    configuration, install, handoff repository, or agent homes. CI, the contributing guide, and the docs use that
    command, and the consistency checks keep them on it.
  • Estimates are rounded to 5 minutes, and to the minute under 10 minutes, on the dashboard and in dev progress:
    of about 2h00m, not 1h59m. Measured times stay exact.
  • Each hook reconciles its session's own run: a member that stopped without saying so, a lost launch, or a run whose
    session ended is marked as such, so the run, its slots, and the dashboard stay true.
  • dev doctor's fix for a full disk names dev free.

Fixed

  • The audit trail's copy in the handoff repository never grows past 45 MB in one file: a month that would pass it is
    held, with a warning in the trail and in dev doctor, instead of growing toward GitHub's 100 MB limit and stopping
    every handoff push. Daily, compressed audit files replace the monthly ones in 26.11.5.
  • dev install no longer stops at the skills step on a fresh clone or a release archive: git keeps no empty folder, so
    devkit's own agents/skills folder is missing there, and the step now links the third-party skills without it.
  • install.sh works on Intel Macs: it finds Homebrew in /usr/local as well as /opt/homebrew, and runs the wizard
    with Homebrew's Python from brew --prefix instead of a fixed /opt/homebrew/bin/python3. On Apple Silicon, it adds
    Homebrew to ~/.zprofile when Homebrew was not on the PATH, so new terminals find brew, gh, and the toolchain.
    The shell profile and dev setup also find Java and Docker's CLI plugins under Homebrew's real prefix.
  • Hooks and dev commands no longer lose each other's changes: one lock per session covers its session and run
    records, so of 8 crew questions asked at once, all 8 are kept (it was 1), and an ended session no longer comes back.
  • Crew members launched together no longer swap names, lanes, or steps.
  • A step assigned to a member who is already working waits for its dependencies instead of starting.
  • The Stop hook waits while crew members are still working on a plan, instead of sending the tech lead back each
    turn.
  • Crew message and decision ids stay unique past 200, so an answer no longer reaches the wrong member.
  • A crew member working in a worktree of the same repository can edit the files of its scope.
  • Read-only crew commands (graph, show, raci), commit messages, and heredocs that only mention a lane command
    are no longer refused to members.
  • The prompt hook no longer logs an error on every prompt and loses the turn's class.
  • A reply with no tool calls (a status question, "continue") counts as the previous turn's kind, so a missing status
    block there is scored.
  • dev doctor informs, instead of failing, about a crew skill from an optional group you have not turned on.
  • The devkit_audit tool shows who acted again, and devkit_task_update says that it changes tasks and that only
    the audit trail, not the guard, covers it.
  • dev status shows a saved status block's Crew and You lines on their own rows and wraps long values.
  • The irreversible-action gate's audit record failed on every write, so a crew member got the gate's error text
    instead of its refusal. Records are written now, and a record that fails cannot change the gate's decision.
  • Review and read-only members can run dev test prove, which works in a temporary copy of the checkout.
  • The Accountable or a Consulted member of a kind of work could take it without --why and then approve it. Only
    the Responsible member takes it now; the others need --why, which is recorded.
  • dev gc <n> is recorded in the audit trail as a deletion, while listing aliases and printing the plan to free
    space are not recorded, because they only read.
  • Review readiness. A review step waited forever behind a member's unverified step, which only that review could
    approve. A review step now starts on unverified work, and its Check ✓ ends done the steps it follows that its
    member approves; every other step still waits for done or skipped. One rule tells a review step everywhere: its
    kind of work is review, or its member works review-only.
  • Step binding. A step assigned to a member whose lane was still running could close done when that lane ended,
    with none of its work. A lane's ending now closes only the steps its evidence is about: the step its launch names,
    a step its dev progress step --step "<name>" names, or one its report names. Its other steps go back to pending.
  • A file that a working member changed during a review member's shell call no longer counts against the reviewer:
    it is flagged as possible, and the message names the member whose scope holds it.
  • grant unknown cmd-<hash>, which a refusal of a command the guard cannot name asks for, recorded nothing, so the
    command could never run. The grant opens that one command, once.
  • A decision's options reached no audit record, so every answer read as free text. Records now keep the option an
    answer names.
  • dev test, dev test prove, and dev ci --run --resume run a test folder that is a Python package from the
    repository root, so its __init__.py setup runs.
  • dev stubs needs the stub word and its time word in one clause, so a comment that says nothing is stubbed is not a
    finding.
  • The status block that dev progress step prints rounds estimates like the dashboard.
  • A member's dev crew ask or dev progress step whose message comes from a quoted heredoc reaches its lane
    instead of being refused.

Security

  • devkit trusts only its own Codex hooks. Before, it told Codex to trust every new hook in ~/.codex/hooks.json at
    each session start and every 6 hours, so a hook an agent wrote there would later run outside the guard. Now a hook
    counts as devkit's only when it matches exactly what devkit renders (event, matcher, command, timeout); any other
    hook stays untrusted, and dev doctor lists it among the hooks devkit did not write.
  • The guard sees what a command really runs: through wrapper flags that take a value (nice -n 5, env -u X,
    sudo -u me, exec -a x), interpreter flags (python3 -u bin/dev), arithmetic shifts that looked like heredocs,
    git and gh aliases, shell scripts run by their path, and git push --repo=<url>. env -S is refused, because the
    guard cannot see the command it runs.
  • Writes with a relative path from devkit's state or configuration folder, or from a folder that holds them, are
    refused.
  • A WebFetch URL that carries a secret is refused.
  • Your approvals cannot be forged. devkit reads your answers and grants only from the session's own transcript,
    where Claude Code writes it; an event that names another file records nothing and is audited as
    crew.evidence-refused, and a prompt or answer replayed through a hook counts once. Agents cannot write, move,
    or delete Claude Code transcripts or Codex sessions. A program an agent runs that loads devkit's code to reach these
    functions or devkit's state is refused, also when it loads them through the agent's own files (three levels deep)
    or through code decoded at run time. On Codex, devkit reads no transcript yet, so a grant or an answer you type
    there opens nothing: run irreversible actions on Codex yourself, in a terminal.
  • A "no" never opens an irreversible action. A decision that leads to a release, merge, push, or deploy opens it
    only when your answer chooses the option that performs it (--performs, else the one option that reads yes or
    approve, else the recommended one); before, any verified answer opened it, approve D1: no included. Any other
    answer opens nothing and is audited as crew.grant-refused, with the decision and the option, never your text.
    dev crew ask refuses a --performs that names an option reading as not doing it (B: no), and the question
    you are asked names the choice that runs the action and its target: D1 · Release now? (choosing “A: release” runs release v26.11.4).
  • The irreversible-action gate sees more: the repository that gh -R, --repo, or GH_REPO names (so a grant for
    one repository never covers another), commands run through script, watch, GNU parallel, sem, arch,
    flock, unbuffer, chronic, or yarn workspace, targets that xargs appends, curl methods inside short-flag
    clusters (-sXPOST), and npm -w <pkg> publish.
  • A forged hook event can no longer end a working member's lane and free its slot.
  • The audit redactor closes the 14 gaps a probe of 32 fake secrets found (among them names like
    AWS_SECRET_ACCESS_KEY, quoted values, --password flags, PGP private keys, and Stripe, GitLab, Hugging Face,
    Google OAuth, Docker, Slack, and Azure tokens), and also knows Bearer tokens, JWTs, npm and PyPI tokens, Google API
    keys, and URL credentials. It also redacts curl -u, sshpass -p, mysql -p, docker login -p,
    gh secret set --body, Authorization: token, passphrase=, credentials:, and a value piped by echo or
    printf into --password-stdin or --with-token. The redactor knows these shapes and no others: a secret in a
    shape it does not know can still reach a record, so keep secrets out of commands.
  • Records hold less about people. Crew message text, decision questions, and the user name in home folders are left
    out; a decision's answer is kept only when it names one of the options (otherwise its length), and your approval
    lines only by their length. Records written before are cleaned the same way when read, and dev audit verify still
    checks them as stored.
  • The dashboard server checks the Host header, sends base-uri and form-action rules in its content security
    policy, keeps its token out of process arguments, and reads files only inside the handoff repository. Search
    results and the command palette open a link only after the page's URL check, so a javascript: or data: link in
    the data cannot run, in the static export either.
  • The guard was hardened over three red-team rounds. Each way around it that a round found is closed, and a test
    in tests/test_red_team.py or tests/test_red_team_2.py keeps it closed. The classes closed:
    • A command whose program or subcommand is known only when it runs is the unknown action: a crew member never
      runs it, and the main session runs it once with grant unknown cmd-<hash>, which the refusal names.
    • A command that git or gh hands to a pager is judged as the command it is, and agents may not write a pager or
      any other git setting that runs a command (in any scope, from the environment, or in a repository's own .git
      folder, whose config and hooks agents can no longer write).
    • A nested agent session that would run without devkit's hooks or sandbox is refused, also when a package runner
      or a program's own code starts it, and agents may not pass a Codex profile.
    • Running one of devkit's hooks by hand, and dev config lock and unlock, are refused from every tool call.
    • An MCP tool that merges, pushes, or approves counts as an external action, like one that creates or sends.
    • dev flags are read the way devkit's parser reads them, so an abbreviation or a word after -- hides nothing.
    • A heredoc that macOS's bash ends earlier than zsh fails closed, and text inside an interpreter's string literals
      is no longer read as program names.
    • A backup is a push to the guard, granted per branch, and the push budget counts only pushes that start CI.
  • devkit runs isolated. bin/dev runs python3 -I -S, and so does every devkit process it starts (hooks in
    the background, the MCP server's calls, scheduled jobs, the wizard, the CI watcher, the dashboard server, the
    Desktop launcher), so a PYTHONPATH, a planted module, a user site folder, or a .pth file cannot load code into
    it. The guard refuses Python's code-loading variables on a devkit call and on a nested agent session.
  • The gates fail closed. When the irreversible-action gate itself fails while it enforces, a command that names an
    irreversible action is refused (guard.irreversible with a gate error), and so is an MCP call. A crew member's
    shell command that devkit cannot check against its lane is refused instead of run unchecked. Other handlers still
    fail open, with a guard.failopen record.
  • A grant a step uses for a push or a pull request covers only its own target pattern in its own repository.
  • The dashboard server reads a project's branch map at most every 5 seconds and two at once, answering more with
    429, so a client cannot start unbounded git reads.
  • An agent's push from a folder that is no project (a temporary clone, a folder made in the same command, one a
    sourced file picks) is refused while any project has an embargo, and a push from inside a git folder, or through
    env -C or sudo -D, is judged as that folder's project, so its embargo holds.

Known limits

  • The guard is a seatbelt, not a sandbox. It catches an agent's mistakes and the common forms of prompt
    injection, but a determined program can still find a form it does not recognize. Keep your own review; see
    Guard rules › What the guard is and is not.
  • Developer grants on Codex are not confirmed yet. devkit reads no Codex transcript, so a grant or an answer you
    type in Codex opens nothing: run irreversible actions there yourself, in a terminal.
  • Agents use your credentials. devkit works with the GitHub account you are signed in to with gh and your own
    tokens and keys; there is no separate identity for agents, by design. The guard and your grants hold the
    irreversible actions.
  • An embargo holds pushes from its own project only. It holds pushes from the embargoed project, its git folders
    and worktrees, temporary clones, and unknown folders; a copy of its commits in another project's folder is not
    held yet (26.11.4).

Removed

  • The word lists: skill rules no longer match your prompt (15 patterns removed), the prompt hook no longer looks for
    corrections in it, and dev lesson scan no longer lists corrections.
  • The static-file-only dev dashboard: the static page is dev dashboard --export <file>.