Skip to content

Releases: The01Geek/prflow

v2.30.0

Choose a tag to compare

@prflow-implementer prflow-implementer released this 31 Jul 20:30

[2.30.0] — 2026-07-31

Changed

Changed

  • PRFlow rename Tier 2 (issue #1003) — the three consumer-visible brand identifiers move,
    and every reader of a pre-rename artifact keeps resolving it.
    • The provenance label new runs stamp is now PRFlow. Every selector accepts both
      PRFlow and the superseded DevFlow (lib/scan.sh, lib/classify-pr-kind.jq,
      lib/fetch-pr-context.sh), so no retrospective history is dropped. The API-side filter
      now uses a single --search "… label:PRFlow,DevFlow" qualifier — gh pr list --label A --label B is an AND and would have returned zero candidates silently.
    • The telemetry branch default is now prflow-telemetry. Records already published on
      devflow-telemetry are not migrated automatically; the unmigrated state is detected
      with a breadcrumb naming the one-line git push origin devflow-telemetry:prflow-telemetry
      migration (see docs/efficiency-trace.md).
    • Comment markers newly written carry <!-- prflow:… -->. No existing issue or PR body
      is rewritten. Readers of persisted GitHub artifacts accept both spellings per record,
      so a workpad mutated in place across the rename boundary still discharges its pre-rename
      deferred-filed records and binds its pre-rename scope-decision pr=pending ones.
      In-tree reference boundaries (*-ref) and the in-run dispatch-scope file-format marker
      are renamed in place with no dual form.
    • deferred.labels defaults to PRFlow,Deferred.

Fixed

  • scripts/match-lint-adjudications.py's adjudication-sentinel tamper guard now counts the
    union of both marker spellings. Counting each spelling independently would have let one
    genuine new-form section sit beside one attacker-quoted old-form section, read as 1 and
    1, raise no tamper flag, and honor the forged window. The review engine's producer-side
    neutralization list names both spellings to match.
  • Every fail-open marker reader is fixed rather than documented: both trigger resolvers, the
    #989 review-backstop dedupe override, the stall-backstop lifetime attempt counter and the
    review-backstop per-head attempt counter now match or count both spellings — a marker miss
    in any of them was a duplicate-run or suppressed-resume bug, not a cosmetic gap.
  • .prflow/config.schema.json's docs.labels default was DevFlow, disagreeing with the
    shipped example config, the live config and the resolver default; it is now Documented.

Added

  • lib/rename-map.json gains a top-level identifiers rename channel with per-entry match
    semantics (token / prefix), and lib/test/pin-corpus-lint.py compiles it. The alternation
    is ordered longest-literal-first with frozen entries winning ties, and the builder now refuses
    a name that is both frozen and mapped, an unrecognised top-level block, and an identifier
    entry with no declared match — three edits that were previously silent no-ops.

v2.29.0

Choose a tag to compare

@prflow-implementer prflow-implementer released this 31 Jul 18:23

[2.29.0] — 2026-07-31

Changed

Rename everything PRFlow ships into a consumer repository from devflow to prflow, and make /prflow:init migrate an existing repository as a single atomic unit (#1002).

The plugin has been prflow for several releases, but everything it shipped into a consumer repository still carried the old brand at the structural layer. That is now migrated: the .devflow/ state directory becomes .prflow/, the vendored plugin path .devflow/vendor/devflow/ becomes .prflow/vendor/prflow/, the seven brand-named top-level config keys (devflow, devflow_implement, devflow_runner, devflow_review, devflow_review_and_fix, devflow_retrospective, devflow_version) become their prflow_* equivalents, the shipped workflow bodies name the new paths and keys, and the .gitignore rules follow the directory.

The migration is all-or-nothing. The shipped workflows invoke bundled helpers at the vendored path as repo-relative leading tokens and the cloud allowlist grants are per-literal-path, so a half-moved tree is not merely broken — it is silently denied, and the run ends with no verdict. scripts/migrate-consumer-tier1.sh therefore plans, validates every precondition for all four members, stages every new byte, and only then commits behind a rollback journal. A single unsatisfiable member refuses the whole set and leaves the repository byte-identical. /prflow:init runs it before the scaffolder, and install.sh runs it first inside its one apply path, where the shipped-workflow copy loop now shares its fate.

Detection where a migration has not happened yet. scripts/config-get.sh gained a superseded-key probe that distinguishes a genuinely absent key from one a consumer deliberately set to "", false, 0 or null — a distinction the resolver structurally could not make before — and breadcrumbs only on the first. The two shipped workflow config jobs gained a per-family fail-loud guard, because the trigger-time channel reads config through inline jq and never through the resolver, so no breadcrumb could reach it. scripts/scaffold-config.sh migrates the config keys behind a fail-closed shipped-workflow freshness gate, reports the version pin without gating on it, names any retained workflow no installer run can refresh, and its deep-merge backfill will not graft a prflow_* key while its devflow_* counterpart is still present.

The state directory has a transitional read-through, and the config keys deliberately do not. /prflow:init registers the marketplace with autoUpdate: true, so a consumer's plugin can update ahead of any migration run; without a fallback the next update would resolve an absent config and silently revert every defaulted read. Readers therefore resolve .prflow/ first and fall back to .devflow/ only when it alone is present, breadcrumbing the remedy every time. The key-level rule from #988 is unchanged — no read-through there, because a silent key fallback makes the migration unobservable and therefore permanent.

Unchanged, and deliberately so: devflow-marketplace, the workflows.devflow / workflows.devflow-review config sub-keys, every .github/workflows/ filename, the DevFlow provenance label, the devflow-telemetry branch, the <!-- devflow:* --> comment markers, the DEVFLOW_* environment variables, the devflow_module_pin_* harness functions, and the byte-contents of learnings/*.jsonl and logs/*.tsv — those files move with the directory but are never rewritten. The label, branch and marker rulings are tracked in #1003; the environment-variable advisory report in #1004.

v2.28.5

Choose a tag to compare

@prflow-implementer prflow-implementer released this 31 Jul 02:13

[2.28.5] — 2026-07-31

Fixed

  • Renamed the PR-authoring GitHub App reference to its current slug. The App
    was renamed devflow-autopilotprflow-implementer (PRFlow (Implementer);
    the app id is unchanged at 3102164) and the old slug now 404s, so every
    workflow comment, setup instruction, and architecture note naming it pointed at
    an identity a reader could not look up. The DEVFLOW_APP_ID variable and
    secret names are deliberately unchanged — they are configuration identifiers,
    not App identity — as are the workspace-path grants in .devflow/config.json
    (repo-name, re-anchored onto the live $GITHUB_WORKSPACE) and the dated
    CHANGELOG.md records.

v2.28.4

Choose a tag to compare

@prflow-implementer prflow-implementer released this 31 Jul 01:26

[2.28.4] — 2026-07-31

Fixed

  • The frozen pin-corpus census can no longer silently disagree with its own adjudication
    table.
    lib/test/pin-corpus-classifier.py resolves lib/test/pin-corpus-adjudications.tsv
    at the census's recorded revision, so the existing frozen-revision regeneration
    re-derived whatever rationales the census already carried and could never notice a
    working-tree table that had moved on — a table-only edit shipped a superseded rationale
    behind a green suite, the #810 gate and green CI. The frozen-revision test now repeats its
    byte-comparison with the working tree's adjudications reconciled into the recorded
    revision's table, so changing an adjudicated cell for a key the census already carries is RED,
    with the drifting row and column named instead of a whole-file diff; a companion mutation
    control drives the same reconcile-then-regenerate path with one working-tree rationale changed
    each run, so the comparison cannot be satisfied vacuously. Only keys the two files share are
    compared: a site that resolves a literal is keyed by a hash of that literal, so rewording a
    pinned literal re-keys the same adjudication, and the census — a frozen snapshot whose lag is
    fail-closed by design — is not thereby stale. The two-commit inventory-free protocol itself is unchanged.
    (#967)

v2.28.3

Choose a tag to compare

@prflow-implementer prflow-implementer released this 30 Jul 23:50

[2.28.3] — 2026-07-30

Changed

Fixed

  • Cloud setup docs no longer describe devflow-review.yml, a workflow that is not in the
    tree. docs/cloud-setup.md had named it among "the five consumer-shipped workflows" and
    its workflow inventory gave an install instruction ("edit that list when installing") for
    a file that does not exist. The true shipped set is two workflows — devflow.yml and
    devflow-implement.yml — and the inventory now states which entries install.sh copies,
    which belong to this repository only, and which are the retained withheld-tier files.
    docs/DEVFLOW_SYSTEM_OVERVIEW.md carried the same stale count and is reconciled.
  • README requirements no longer overstate the PyYAML dependency. It is a lazy import in a
    single helper, reached only when a pull-request body already carries a deferred-findings
    block, and the review engine logs and steps over its absence with all findings intact.
  • The withheld auto-review tier disclosure is reworded to state its actual disposition —
    the feature was withdrawn rather than abandoned, and a fresh install is unaffected — and
    moved below the fold, with the removal procedure spelled out.

Changed

  • Skill descriptions shown in the skill picker use the current product name: init,
    receiving-code-review and requesting-code-review. The /devflow:implement alias in
    the implement skill's description is retained deliberately — it is still a live trigger.
  • docs/DEVFLOW_SYSTEM_OVERVIEW.md no longer carries a hand-maintained version literal
    (it read 2.4.3 against a shipped 2.28.1); it points at plugin.json instead.
  • CHANGELOG.md's live header uses the current product name. Dated entries are unchanged.
  • The README gained an install anchor so the published one-pager's call-to-action lands
    on the install instructions rather than the top of the page.

v2.28.2

Choose a tag to compare

@prflow-implementer prflow-implementer released this 30 Jul 23:03

[2.28.2] — 2026-07-30

Fixed

  • A new user's first command works again: the documented install identifier is now
    prflow@devflow-marketplace.
    The plugin was renamed devflowprflow and the rename
    swept every executable surface, but the human-facing surfaces were left behind — README.md
    and docs/ still told a reader to run claude plugin install devflow@devflow-marketplace,
    which fails on a clean install with Plugin "devflow" not found in marketplace "devflow-marketplace". The marketplace renames map migrates an already-installed plugin;
    it is not an install-time alias. All nine documented install sites across README.md,
    docs/install.md, docs/cloud-setup.md and docs/DEVFLOW_SYSTEM_OVERVIEW.md now name
    prflow@devflow-marketplace, and both README.md and docs/install.md explain why the
    marketplace keeps the devflow-marketplace name (the renames map is scoped per
    marketplace, so renaming it would strand every existing install).
  • Every documented command is now /prflow:. README's quick start, the skills table, the
    end-to-end workflow diagram and all of docs/ used the retired /devflow: local-command
    namespace. The README's namespacing note previously gave inverted advice — "always use the
    /devflow:-prefixed form"
    — and now states the split correctly: local slash commands are
    /prflow: only, because a skill's namespace is the plugin name, while cloud comment
    triggers accept both
    namespaces during the alias window. docs/workflow-triggers.md states
    that dual acceptance where the trigger surface is documented.
  • Two dead documentation links are repointed. docs/external/release-notes.md cited
    issues #930 and #920 at the pre-rename The01Geek/devflow-autopilot path, which now returns
    404; both point at The01Geek/prflow and were re-verified live.
  • Product naming and scaffolded config. README.md, CITATION.cff, CONTRIBUTING.md,
    SECURITY.md, LICENSES/README.md, the docs/ corpus and the vendored agent descriptions
    now say PRFlow. .devflow/config.example.json — what /prflow:init scaffolds into a new
    repository — and the config.schema.json descriptions an editor surfaces no longer seed the
    stale devflow: agent namespace or document /devflow: commands.
  • Deliberately unchanged: the devflow-marketplace marketplace name, the .devflow/
    directory, DEVFLOW_* environment variables, devflow_* config keys, the <!-- devflow:* -->
    markers, the reserved DevFlow provenance label, the Devflow Reflection / Devflow Review
    markers, the workflow filenames, the lib + python tests check name, and the
    devflow-autopilot GitHub App, which is a separate identity that has not been renamed.
    CHANGELOG.md and .devflow/learnings/** are dated historical records and keep the old name.

v2.28.1

Choose a tag to compare

@prflow-implementer prflow-implementer released this 30 Jul 21:14

[2.28.1] — 2026-07-30

Changed

  • Repository references now point at The01Geek/prflow, the repository's new name. The
    GitHub repository was renamed from devflow-autopilot to prflow; this updates every live
    reference that names it — the installer's DEVFLOW_REPO default, the vendor-plugin
    composite action's DEVFLOW_REPO default, the claude plugin marketplace add instructions,
    the raw.githubusercontent.com installer pins, the plugin and marketplace manifests'
    homepage/repository metadata, the config schema's $id and its devflow_version
    description, the citation metadata, and the marketplace registration
    scripts/provision-local-settings.sh writes into .claude/settings.json. GitHub redirects
    the old repository path for git and API traffic, so existing installations keep working and
    no consumer action is required; GitHub Pages does not redirect, which is why the
    README's one-pager links had to move to https://the01geek.github.io/prflow/. Dated
    historical records — the changelog, the external release notes, and the retrospective
    learnings corpus — deliberately keep the old name, because rewriting them would falsify a
    record of runs that happened under it. The plugin's own identity is untouched: the plugin is
    still named prflow with the devflow alias, and the devflow-autopilot GitHub App keeps
    its name, which is a separate thing from the repository. (#972)

v2.28.0

Choose a tag to compare

@prflow-implementer prflow-implementer released this 30 Jul 20:32

[2.28.0] — 2026-07-30

Changed

Changed

  • The plugin identifier is now prflow (displayName: PRFlow). The former
    devflow identifier is declared as a permanent alias in
    lib/plugin-identity.json and as a renames entry in the marketplace
    manifest. The marketplace name itself (devflow-marketplace) is deliberately
    unchanged: the renames map is per-marketplace, so renaming the marketplace
    would put the migration map somewhere existing installs do not look.
  • Comment triggers accept both the /prflow: and the transitional /devflow:
    command namespaces. The detected command token is always emitted in the
    canonical /prflow: form, because the consumers that compare it need one
    spelling. A consumer that parses the token must accept every declared
    namespace instead — scripts/prepare-harness-floor.sh now derives that set
    rather than stripping a hardcoded prefix, and announces a token it cannot
    classify instead of silently recording an empty command class.

Upgrading

renames is a real, documented platform mechanism, but it is not universal,
and the fallback is a one-time manual reinstall:

  • It requires Claude Code v2.1.193 or later (the marketplace-manifest schema
    documents the floor). Earlier versions ignore renames entirely and report
    plugin-not-found for the old name.
  • DevFlow installs from a remote source, and the documented behaviour there
    is plugin-cache-miss after the rename, so even a supported version needs one
    /plugin install to fetch the plugin under its new name.
  • Third-party marketplaces have auto-update disabled by default, so the
    renames map may not be fetched at all until /plugin marketplace update is
    run. (Installs provisioned by init set autoUpdate: true and are unaffected.)
  • Managed/policy settings scopes are read-only and never auto-rewrite.

Fallback, sufficient in every case above: run /plugin marketplace update
followed by /plugin install prflow@devflow-marketplace. Local /devflow:*
slash commands do not survive the rename in any case — a skill's namespace is the
plugin name — so update local muscle memory to /prflow:*. The cloud
comment-trigger path and the agent_overrides config keys do keep accepting
the old namespace during the alias window.

v2.27.1

Choose a tag to compare

@prflow-implementer prflow-implementer released this 30 Jul 15:42

[2.27.1] — 2026-07-30

Changed

Changed

  • Retire the throwaway devflow-alias-probe plugin alias. lib/plugin-identity.json's
    plugin_aliases returns to [] and every dependent region is regenerated, so the four
    baked copies (.github/actions/vendor-plugin/vendor-slice.sh,
    .github/workflows/devflow-runner.yml, install.sh, scripts/resolve-extra-plugins.sh)
    accept the canonical devflow only. The probe had already established what it was declared
    for — that a second accepted identifier propagates to every baked region, that the
    agent-namespace roster guards must be alias-agnostic, and that the canonical discriminator
    still resolves with an alias declared — and its removal was a stated condition of the change
    that introduced it: leaving it in ships a trust-discriminator widening for an identifier
    nobody owns. The name-agnostic mechanism itself is untouched, as is the alias-agnostic
    hardening of the roster guards.
  • Two comments that were corrected because an alias was declared —
    lib/generate-plugin-identity.py's payload_install docstring and install.sh's
    superseded-identifier gate comment — are reconciled with the tree they now ship in: each
    states the conditional the code implements, names the current (empty) state as a property
    of the manifest rather than of the function, and tells the reader to re-read the manifest
    before asserting which way the gate falls.

v2.27.0

Choose a tag to compare

@prflow-implementer prflow-implementer released this 30 Jul 15:13

[2.27.0] — 2026-07-30

Changed

Added

  • install.sh now has a real consumer upgrade path. Re-running it in a repository that
    already carries a DevFlow installation is dry-run by default: it prints the plan and a
    unified diff of every byte it would change and writes nothing until you re-run with
    --apply. A first-time install still applies immediately, so the documented one-liner is
    unchanged; --dry-run forces the preview there too, and DEVFLOW_DRY_RUN=1 /
    DEVFLOW_APPLY=1 select the same modes for a curl | bash invocation that cannot pass a
    flag. The preview is not a second implementation of the plan — it runs the real install
    into a sandbox copy of the consumer's own tree and diffs it.

  • Installed artifacts now carry provenance in .devflow/install-manifest.json (a sha256 per
    artifact). An upgrade updates an artifact whose bytes match the recorded digest, leaves an
    already-identical one alone, recreates a deleted one, and preserves one that was
    hand-edited — writing the new version to <path>.devflow-new for a human merge instead of
    overwriting. An installation with no manifest (predating it, or a skipped-version jump) is
    treated as unverified rather than pristine: unknown is never collapsed onto "unmodified".

  • The provenance layer fails safe whenever a digest cannot be established, and the blast
    radius matches the cause:

    • No working python3 — stock Windows / Git-Bash before the shim provisioner has run.
      Nothing can be digested, so the upgrade preserves every artifact it finds, offers each
      new version as a <path>.devflow-new sidecar, and writes no manifest.
    • A read error on one artifact while python3 works — an unreadable file, or one
      unreadable file inside a composite-action directory. Only that artifact is preserved
      and offered as a sidecar; every other artifact is classified and written as usual, and the
      manifest is still recorded — the preserved one simply keeps its previous entry rather than
      being re-recorded against bytes nothing could read.

    Each case reports the cause that actually applied and the remedy that matches it, rather
    than naming a missing interpreter on a host whose interpreter works.

    Whether an artifact exists is decided without python3 in both cases, so a genuinely absent
    artifact is still created and a first-time install on such a host is unaffected; what an
    unreadable digest costs is the comparison, never the consumer's bytes. Both report distinctly
    from "no recorded digest" (provenance UNESTABLISHED), and each names its own remedy.

  • The upgrade path surfaces the withheld automatic-review tier (issue #936) when a
    repository still carries it, naming the #930/#920 exposure, and offers removal behind the
    explicit --remove-withheld-review-tier opt-in. The opt-in sets workflows["devflow-review"]
    to false and then deletes the three workflow files, and states that the branch-protection
    context is a step no installer can perform. Deletion is guarded by a per-file signature
    each withheld workflow actually carries — not by the mere presence of the string devflow,
    which a consumer's own telemetry-push.yml may legitimately contain (a .devflow/** path
    filter, a comment) and which would otherwise have deleted their file. The config key is
    turned off before the files are removed: that is the only order whose interrupted state
    is self-healing, since once the files are gone no later run reaches the config edit.

  • The dry-run diff covers .claude/plugins/ as well, so the recursive removal of a stale
    pre-relocation .claude/plugins/devflow tree is shown rather than performed unpreviewed.
    The consumer's wider .claude/ is still neither written nor diffed.

  • An artifact the installer replaces is staged beside its target and swapped into place, so a
    failure mid-copy can no longer leave a half-written file or composite action behind. That
    mattered more than a partial write usually does here: the aborted run never reaches the
    manifest write, so the next upgrade would compare the half-copied bytes against the old
    digest, call them a local edit, and preserve the corruption on every subsequent run.

  • The upgrade path reports a .claude/settings.json still registering a superseded
    plugin/marketplace identifier and routes the consumer to /devflow:init, which already owns
    that migration through scripts/provision-local-settings.sh. install.sh still writes no
    .claude/settings.json.

  • DEVFLOW_SRC skips the clone and installs from an already-materialized source tree — the
    offline seam the test suite drives real end-to-end fixture upgrades through.

Changed

  • The local marketplace.json install.sh writes is now composed from the generated plugin
    identity region
    rather than hand-spelled literals, and the region carries the canonical
    plugin/marketplace pair plus the superseded identifier sets alongside the existing
    discriminator ERE. Declaring an alias in lib/plugin-identity.json and regenerating is the
    only edit an identifier change needs in the installer.