Skip to content

Releases: LuisFelipeMoro/Harness-devkit

v2.8.1

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 17 Oct 22:58
6d8fa54

Changed

  • /multi-agent and /task recommend the thin orchestrator. When the session is not running as
    claude --agent orchestrator, they print the exact relaunch commands once and never block:
    /multi-agent always, /task only when the blast radius is big. The main session carried most of
    the delivery's cost (measured on one delivery).

v2.8.0

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 17 Oct 22:34
8894ae5

Go idioms that are checked against the module's own Go version, a latency method that starts with a
trace, a fan-out rule that lets read-only work run wider than writes, and an opt-in stance on agent
teams, plus leaner dispatches. Five stories, each judged on its own.

Added

  • Version-gated Go idioms. references/go-modern-idioms.md tabulates Go 1.18–1.26 idioms. Each
    row carries its minimum Go version and applies only when the module's go directive reaches it.
  • Advisory modernize gate. go fix -diff (Go ≥ 1.26) is a row in both quality-gate references.
    QA and /quality-gate report it as ADVISORY or skipped; it never fails a gate. A wiring check rejects an unpinned fetch.
  • Named contract rows. validate-wiring.py gains contract_check(name, …), so a failing row
    prints FAIL: <name> and can be falsified with break-run.sh.
  • Trace-first latency budget. references/latency-budget.md traces one slow request before it
    picks a fix by layer. /performance-profiling routes to it when latency is spread across services. Fixes chosen from the budget return to steps 4–5, so a characterization test pins current behaviour before the first change.
  • Cross-layer fixes. The performance-profiling fixes table gains five rows: pool sizing, owned
    caches, chained service calls, async off-path work, and payload size. There are no millisecond
    thresholds; targets come from the service's SLO.
  • Architect design fields. The Architect template gains a remote-calls-per-request field and a
    cache-owner field, so latency is decided at design time.
  • Agent teams, documented and off. references/agent-teams.md records what the experimental
    flag does to dispatch and the only way the devkit tolerates it: read-only lanes, with the flag
    never set by the installer. CLAUDE.md points to it.
  • Leaner dispatches. Pipeline agents declare a tools: allowlist: a measured probe fell from
    41.5k to 14.9k tokens of inherited tool definitions. Dispatch rules forbid resuming an agent
    except for a QA re-audit, because a resumed transcript replays in full. Small doc-only manifest
    rows bundle into one row. An opt-in thin orchestrator (claude --agent orchestrator) keeps the
    main session off file reads, and bench-context.py --manifest prints a main-session estimate.

Changed

  • Validators cannot edit. qa, reviewer, stress, verdict and plan-reviewer list no Edit or Write
    tool, and validate-wiring.py (tools_check) fails the build if one gains either. They keep Bash
    for running gates, so this is a tools-list rule, not a sandbox.
  • Read-only fan-out has its own width. Writers stay at three per turn. Read-only subagents (no
    Edit or Write tools, a no-mutation prompt, no mutating shell command) get a separate width in
    thresholds.md. Contracts are frozen before fan-out, read-only dispatches may run in the
    background while the gate chain stays in the foreground, and every dispatch still counts toward
    the session budget. The escalation ladder applies to writers only.
  • Model aliases are named as the source of truth. The model table pins no version: the
    opus, sonnet and haiku aliases resolve to the newest model in each family, and the two skills
    that restate the table defer to it.

Credits

  • Idea sources, paraphrased (no text copied): JetBrains/go-modern-guidelines (Apache-2.0) for the Go idiom table, and danicat/skills (Apache-2.0) for the read-only fan-out, contract-convergence and return-cap rules.

Versions

Plugin Version Why
coding-pipeline 2.7.1 → 2.8.0 Go idioms and advisory modernize gate, latency budget, read-only fan-out width, agent-teams reference. Additive: no rule a consumer relies on is removed.
engineering 1.5.1 → 1.6.0 Advisory modernize row in the gate reference, guarded against an unpinned fetch.

v2.7.1 — Hook installer works from a git worktree

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 25 Sep 18:56
8741a8c

Fixed

  • Installing from inside a git worktree aborted half-way. git-hooks/install.sh copied hooks to
    <toplevel>/.git/hooks/, but in a linked worktree .git is a file, so cp failed with "Not a
    directory" and set -e stopped the whole devkit install at step 3/5. Hooks now go to the repo's
    common git dir (git rev-parse --git-common-dir), which every worktree shares, and the success
    message prints where they actually landed.

Versions

Plugin Version Why
coding-pipeline 2.7.0 → 2.7.1 Hook installer fix.

v2.7.0 — Diff-scoped story loop and harness guards

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 25 Sep 12:45
5321aca

Half the subagent dispatches for the same guarantees, and a set of guards that close the ways a
pipeline run went wrong while it was being built. The first half is a measured change to the story
loop; the second is what running that loop on real work taught.

The study: where does a delivery's cost go?

Question. A delivery spends tokens in two places: the guides each dispatch loads, and the number
of dispatches. v2.6.0 measured the first and cut it 3.5%; the dispatch graph was untouched at 40 per
five-story delivery. Which of the two is worth changing?

Method. scripts/bench-context.py models the dispatch graph and the guide tokens each path
loads, run against the v2.6.0 tree and the new one. Per-agent costs come from real dispatches, not
estimates: every agent run in this release was logged with its token count.

Result.

Per five-story delivery v2.6.0 2.7.0 Change
Subagent dispatches (uniform roster) 40 20 −50%
Subagent dispatches (mixed rosters) — 18
Guide tokens loaded 244,170 216,309 −11.4%

The mechanical sensors read far less than an agent would: a security scan prints 365 tokens where
the changed files are 66k (182×), a tautology scan 65 where a 38-file test suite is 52k (797×), the
duplication gate 91 where raw jscpd output is 6.8k (75×).

Why it moved. Dispatches fell because work that was agent judgment became arithmetic or a
sensor: the verdict is verdict.sh, not an agent; story generation for a one-row manifest is a
template fill; the story-level PR review read the same diff the Reviewer had already read; Stress
runs only when the diff warrants it. Validation reads the story's diff, not the tree.

What the model does not show. Fix rounds. The estimate counts first passes; on stories that ran
the full roster, rework added 40–60% on top. The guide-token saving also shrank from −14.2% to
−11.4% once the rules below were written into every agent's guide — a deliberate trade of tokens
for guarantees, measured rather than assumed.

Added

  • Rosters. Each story declares a roster — cosmetic, light, standard, full — and it
    decides which agents run. Mechanical gates run on every roster without exception.
    classify-diff.sh checks the declaration against the real diff and only ever escalates: a file
    that looks like style but holds code, a rename that disguises code as style, a symlink, or a
    deleted source file cannot lower the roster.
  • One-command mechanical checkpoint. checkpoint-m.sh runs every mechanical check a story must
    pass and reports every failure at once: spec rows by exact name, the exact changed-file set
    (renames count both paths, deletions count), no commits beyond the base, no leftover
    falsification markers, the roster, the repository's gate command and duplication. A sub-check
    that cannot measure fails closed. No agent validates code this checkpoint has failed.
  • Self-restoring falsification. break-run.sh applies one literal mutation — refused unless it
    matches exactly once — requires the named test to fail by its own name, and restores the file
    byte for byte on every exit it can trap, keeping the pristine copy if a restore ever fails. It
    refuses symlinks and paths outside the repository and locks the file against concurrent runs.
  • Release-content guard. Session memory, handoff notes and generated test output are rejected
    from commits and pushes by path, from patterns in a committed .devkit/release-exclude. Every
    published commit is checked, merge commits included; a git failure blocks instead of passing.
  • Execution-options checkpoint. After a plan is approved, bench-context.py --manifest shows
    the operator dispatches and a token range per option — with first-pass and with-rework figures,
    each cost labelled measured or assumed — and no code starts until one is chosen.
  • Oversized-prompt warning. dispatch-budget.sh warns when a single agent prompt is too long or
    names too many files; oversized prompts were the cause of every agent stall observed.

Changed

  • The story loop validates the story's own diff, dispatches by roster, runs the Reviewer and Stress
    in parallel after QA, and re-checks narrowly after a fix. The verdict is verdict.sh.
  • Agent guides carry scope rules: edit only the listed files, never revert work you did not make,
    probe only under $TMPDIR, falsify through break-run.sh, make every error path fail closed and
    test it. An agent's report is a claim; the evidence is what the checkpoint reproduces.
  • PROGRESS.md is local session memory: git-ignored and never committed.

Lessons behind the guards

Each failure class below was observed while building this release; each has a guard or a rule.

Failure Guard
An agent reported work or evidence that did not exist checkpoint-m.sh checks rows by name and the exact file set; the orchestrator reproduces evidence with break-run.sh
A test failed without naming itself, or passed for the wrong reason break-run.sh accepts only a failure that names the row
An agent died mid-test and left code deliberately broken Break markers; the checkpoint fails while one exists
A mutation hit a comment instead of code and proved nothing break-run.sh refuses a pattern that is not unique
An agent committed, reverted or created files outside its scope Exact file-set and commit checks; scope rules in every guide
A check that could not measure reported a pass Every sensor exits 2 (unmeasured) on a failure it cannot see past
A classifier trusted a file's name over its content Content is scanned before a roster is ever lowered
Oversized prompts stalled agents The prompt-size warning; split large dispatches
Estimates ignored rework Rework factors in the execution-options table
A timing bound held only on an idle machine Test waits are sized for a loaded machine
Session notes shipped in a release The release-content guard

Still open: an agent told to work in a worktree can edit the main checkout instead. A guard that
refuses edits outside the active worktree is the next change.

Versions

Plugin Version Why
coding-pipeline 2.6.0 → 2.7.0 Rosters, new verify scripts and guards (features).
devtools 1.3.0 → 1.3.1 handoff docs: PROGRESS.md is git-ignored, never committed.
engineering 1.5.1 Unchanged.
pr-workflow 1.5.1 Unchanged.

v2.6.0

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 22 Sep 20:12
c342347

Token and dispatch cost, cut without weakening a guarantee. Three rules the devkit stated and never
enforced now have sensors, the mechanical half of three agent audits became scripts, and the 80%
context ceiling stopped needing a human to act on it.

Added

  • Context and dispatch sensors. hooks/context-budget.sh reads real context fill from the
    session transcript (prompt + cache + the last turn's output, subagent turns skipped) and warns at
    60% / calls the ceiling at 80%. The model no longer reports a number it cannot measure.
    hooks/dispatch-budget.sh counts subagent dispatches per session and warns once past 14
    (3 per story × 3 + 3 planning + 2 delivery). Neither ever blocks.
  • Autonomous context loop. At 80% the instruction is now checkpoint and continue: update
    PROGRESS.md, commit and push, carry on. The new PreCompact hook precompact-snapshot.sh
    records branch, dirty files, last commits and whether PROGRESS.md went stale; on
    source=compact, session-bootstrap.sh re-injects it for the same session only and re-arms the
    60/80 latches. The window is inferred (usage past 200k means 1M) unless DEVKIT_CONTEXT_WINDOW is
    set. No step waits for a person to open a new session.
  • Mechanical verifiers in scripts/verify/: spec-coverage.sh, falsification.sh,
    tautology-scan.py, security-scan.sh, verdict.sh. Each replaces the lookup half of a QA,
    Reviewer or Verdict pass and prints what it does not cover, so the judgment half stays with the
    agent. Unreadable input exits 2 (UNMEASURED) — never a PASS. Measured read-avoidance: 22× to 797×.
  • git-hooks/dup-gate.sh — the one owner of jscpd's flags and line-level attribution. pre-push
    calls it; --worktree measures uncommitted work in a throwaway worktree, so /quality-gate gives
    pre-push's verdict before anything is committed.
  • references/thresholds.md — every numeric gate in one place. The coverage floor had been
    restated in 18 files and had already drifted in one.
  • scripts/bench-context.py (guide tokens per delivery) and .github/scripts/test-verify.sh,
    wired into CI: the verify scripts replaced model passes, so nothing else checks them.

Changed

  • Seven guides told agents to run raw repo-wide jscpd, which counts markdown and pre-existing
    debt and disagreed with the hook. They now point at dup-gate.sh.
  • qa.md, reviewer.md and verdict.md delegate their mechanical checks to the scripts; the
    security test-case table loads on a scan hit or an I/O/auth surface, and QA states which.
  • verdict.sh enforces the per-story floor (Reviewer and Stress ≥ 7) that the average could hide.

Fixed

  • install-global.sh aborted under set -e when any directory — a gitignored __pycache__ —
    sat in git-hooks/, silently skipping every step after it, settings wiring included. Only files
    are copied now.
  • The git-hook test suite and the duplication report used fixed temp paths; concurrent runs deleted
    each other's files. Both are per-run now.

Full Changelog: v2.5.1...v2.6.0

v2.5.1 — remote tag deletion as its own guard case

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 07 Sep 23:57
74e964f

What's Changed

Fixed

  • destructive-guard treated every remote ref deletion as a branch deletion. Deleting a remote
    tag tripped the branch-deletion block, which surfaced while cutting v2.5.0: the guard refused a
    legitimate tag cleanup, and working around it would have defeated the point of having it. The two
    are different risks — a deleted branch can take unmerged commits with it, while a deleted tag is
    recovered by re-tagging the same SHA.

    Tag deletion is now allowed only when every deleted ref is spelled out as refs/tags/. The
    explicit form is the operator stating intent, so the ambiguous shorthands stay blocked: -d,
    --delete <name> and :<name> all still fail, as does any refspec touching refs/heads/ —
    including a mixed push that would delete a tag and a branch together. Falsified by reverting the
    guard and observing the two allow-cases turn red. Hook tests: 42, up from 37.

Full Changelog: v2.5.0...v2.5.1

v2.5.0 — Go concurrency & testing standards + skill-surface single source of truth

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 07 Sep 23:57
c5e0b45

What's Changed

Two sources: the GopherCon Latam 2026 workshop material (concurrency + modern Go testing) and the
skill-optimizer standard from the skills.danicat.dev catalogue.

Added

  • Go concurrency rules for the defects -race cannot see. Transaction races (check-and-act
    split across two critical sections), lock ordering by stable id, never holding a mutex across
    I/O, cloning before returning references to guarded state, the Locked suffix with
    +checklocks, result channels buffered to sender count, defer placed at acquisition,
    errgroup closures using gctx rather than the outer context, and atomics limited to a single
    read-modify-write. A data race is caught by the race detector; a transaction race has every
    access synchronised and the sequence wrong, so a green -race run is not evidence against it.

  • A Concurrency Tool Fit table naming the right primitive per problem and the
    overengineering signals — an actor where a mutex suffices, a pipeline whose stages relay values,
    errgroup where no goroutine returns an error. This is CD2 expressed in Go primitives, wired to
    one MINOR review flag.

  • Modern Go testing rules: no time.Sleep, test-scoped contexts, cleanup registered at
    acquisition, b.Loop with b.ReportAllocs(), benchstat over -count=10 runs rather than
    eyeballed single runs, fuzz corpus discipline (diverse seeds, t.Skip for out-of-domain input,
    panic-safety separated from property targets, committed crash files), fstest.TestFS and
    iotest.TestReader contract tests, deterministic failure stubs, and goroutine-leak assertions
    around a close-once-plus-drain Stop.

  • A toolchain capability table in go.md, carrying no version numbers. Each rule states its
    invariant; the mechanism is selected by a go doc detection command with a named fallback. Three
    of the five version claims in the source material were wrong — T.Context is Go 1.24 rather than
    1.21, T.ArtifactDir is 1.26 rather than 1.24, and synctest.Run was the 1.24 experimental
    spelling, replaced by synctest.Test at GA in 1.25 and removed in 1.26. A rule naming
    synctest.Run today produces code that does not compile. An exit code does not rot the way a
    version number does.

  • references/prose-standards.md — a nine-row catalogue of AI tells for agent-authored prose,
    run as an editorial pass by /handoff and /release-management and carried as one NIT row in
    the Reviewer. It applies to docs, PR bodies and CHANGELOG entries, never to code comments, which
    the stricter why-not-what rule already governs. It is not a gate: prose quality has no exit code.

  • allowed-tools on the two genuinely read-only skills, checkcomments and quality-gate,
    both scoped to [Bash] since each shells out without mutating state. technical-analysis and
    business-analysis were considered and excluded — both write an HTML file, so annotating them
    read-only would have broken their contracts.

  • Two wiring checks in validate-wiring.py: every skill named in the routing table resolves to
    a real skill, and every skill description carries at least one trigger phrase. Both were verified
    by breaking them, observing the failure, and restoring.

Changed

  • Trigger phrases now live in one place. They were stored twice — the routing table in
    CLAUDE.md and each SKILL.md description — and all 23 pairs disagreed. Nine skills carried
    zero phrases in their own description while the routing table listed 5 to 16 each, so
    security-review was reachable by "threat model", "auth bypass" and "CVE" only through a file
    that skill discovery never reads. Descriptions are now the source of truth and the routing table
    lists task to skill, which removes roughly 940 tokens from every session in every project.

  • Sleep-based tests now block. qa.md stated "no real sleeps" inside a non-blocking test-quality
    section. That clause moved into the blocking audit block as timing-coupled test, so one rule
    owns the defect at one severity. This fails suites that pass today — a test whose correctness
    depends on wall-clock duration proves the machine was fast enough, and that is the flakiness this
    Harness keeps paying for. Probabilistic failure injection joins it as a blocking finding.

  • Every PR opens as a draft and is promoted with gh pr ready once its review returns no
    findings, on both the delivery path and the hotfix path. On the hotfix path promotion is gated on
    the existing single review pass; that pass was not converted into a loop.

Fixed

  • write-a-skill required a tool that cannot run. It made SkillSpec a completion condition and
    allowed skipping it only when "not installed". The binary here is installed and cannot execute —
    an arm64 build on an Intel host. The condition now covers "cannot execute" and names the
    fallback.

  • Nine pointers to files that do not exist. Seven skills advertised skill.spec.yml and
    deps.toml as a machine-checkable contract; two more referenced them from Rules bullets. No such
    file exists in the repo, they are gitignored, and the generator cannot run. The sentence claiming
    Claude never loads them was itself loaded on every invocation of those skills.

  • write-a-skill enforced rules that most skills broke. The "Use when" prefix was required and
    9 of 23 skills did not use it; trigger phrases were capped at 2–5 and 13 of 23 exceeded it, up to
    10. Both rules were retired in favour of the Tier 1 token budget, which is now checkable.
    rote's description also lost the imperative it duplicated from its own body.

Known limitations

  • The fallback named in write-a-skill is shallower than SkillSpec. validate-wiring.py checks
    link resolution and trigger-phrase presence; it does not check behavior contracts, implicit
    dependencies, or prose density. A skill authored after this release clears a weaker bar than the
    skill file promises.

  • business-analysis still hard-codes Brazilian Portuguese output. Parameterising it was planned
    and deliberately not shipped: it is a maintainer question about intended behaviour, and closing it
    by picking a default is the author answering a question that was not theirs.

Full Changelog: v2.4.3...v2.5.0

v2.4.3 — Hook tests isolated from PATH; both install routes documented

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 31 Aug 21:20
a63d607

The test bug, found by fixing something else

run_hook prepended the stub directory to the caller's PATH, leaving the real binaries reachable further down it. Every case asserting a tool is absent was therefore asserting something about the machine, not the hook. The suite was green for two releases — until jscpd was installed here, at which point nine assertions failed for reasons unrelated to the code under test.

Now scoped to <stubs>:/usr/bin:/bin. Verified both ways, which is the point: green with jscpd installed and with it hidden from PATH entirely; falsified by reverting to the caller's PATH, which reproduces the nine failures exactly.

Same defect class the suite's own header warns about — a gate passing for the wrong reason. It just happened to be in the tests rather than the hooks.

The double-loaded standards

install.sh imports ~/.claude/devkit/CLAUDE.md globally, so it applies everywhere. This repo also @-imported its own identical copy — ~6,560 tokens loaded twice per session, but only when working on the devkit itself. The repo file now points at the canonical path and tells an uninstalled contributor how to get it. No other repository was ever affected.

Both install routes, stated honestly

A plugin cannot write to .git/hooks/ and cannot ship a CLAUDE.md. Rather than pretend otherwise: the skills and agents restate inline the rules they depend on, so the plugin route works correctly standalone — verified, not assumed. What it does not carry is the repo-wide contract (Coding Discipline, Proportionality, Security Defaults, and the objectives that break ties), and the README now gives the three lines that add it. Both routes are supported; neither is going away.

Also

  • install.sh --dry-run printed npm install -gjscpd, missing its space — a copy-pasteable command. The real install path was always correct.
  • marketplace.json still advertised an 11-agent pipeline without the Plan Reviewer.

Plugin versions: coding-pipeline 2.4.3

v2.4.2 — Reviewer audited against its own token rule

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 31 Aug 21:12
067565f

reviewer.md grew 2,894 → 5,972 tokens in v2.4.0 and loads on every review — the worst token regression of that release, and the one file not held to the rule the same release added to CLAUDE.md: an addition must earn its tokens against one of the seven objectives.

Now 5,614. 358 tokens removed, zero rules removed.

Verified identical before and after: every PE/RD/CD identifier · all six hard gates · all nine Security Deep-Dive sections · the scoring bands · the output block.

What went — all duplication or prose restating a rule stated elsewhere:

  • Language-Specific Checks restated the specialist mandate and version policy carried by references/languages/<language>.md, the file the Reviewer loads moments later. Now a pointer plus the two severities that file does not assign.
  • Design & Durability's closing paragraph restated the slop/overengineering table twelve lines above it.
  • Reuse & Duplication restated the jscpd command that quality-gate-reference.md owns.
  • Principal Engineer Standard and the Correctness procedure compressed, without losing a property, a step, or a severity.

What stayed on purpose — the three lines in the closing Rules: block repeating the cost test, the linter rule and the idiom rule. Terminal repetition of the governing constraint is load-bearing for adherence in a long agent prompt; trading that for ~90 tokens is the wrong side of quality-over-speed.

Measured context: per-story guidance load is ~27k tokens, QA + Reviewer being 45% of it — the confidence and validation the objectives rank first and second. That share was audited for duplication, not trimmed for size.

Plugin versions: coding-pipeline 2.4.2

v2.4.1 — Duplication scan excludes .git

Choose a tag to compare

@LuisFelipeMoro LuisFelipeMoro released this 31 Aug 21:04
fa701e7

Patch on v2.4.0.

Fixed — jscpd's ignore list omitted .git/, so git's own sample hooks were counted as duplication: noise in the pre-existing debt report, and a polluted denominator under every percentage the gate prints.

How it was found, and why the tests missed it — by running the gate end-to-end against real jscpd output rather than the hand-written report fixtures both suites use. test-dup-attribution.sh feeds the script a report the test file writes, and test-git-hooks.sh stubs jscpd entirely; together they prove the attribution logic and the hook's wiring, but they stub the invocation, so an ignore-list defect is structurally invisible to them. That limitation is now recorded in the suite header rather than left to be rediscovered, and the end-to-end check is the thing to repeat whenever the invocation changes.

Verified after the fix with real jscpd: a pre-existing clone passes and is reported as debt; a clone the delivery copy-pastes blocks and names both locations.

Plugin versions: coding-pipeline 2.4.1