Repository navigation
v0.25.0
Features
- build, doctor: build internal skills as real flattened local-only packages under gitignored repo-root
internal-skills/, isolated from publicskills/, everydist/output, plugins and public installs. Verify both staged inventories before canonical promotion; custom/no-promote builds leave both trees unchanged. Correct the doctor's rebuild/load hint and measure Gate 2 on the actual emitted artifact rather than a synthesized rename. (#434) - lint, doctor, agents: turn recurring corrections into enforcement guards. A new
idd-lint correctionssubcommand detects corrections the pipeline keeps re-learning — review-feedback fix cycles (fix(<scope>): address review feedbackcommits, scanned across all refs because squash merges keep them off main) and repeatedskipped_reasonvalues inruns.jsonl— and records one deduplicated, approval-gated improvement proposal per recurring key in.gitissue/improvement-proposals.jsonl(append-onlyproposed → approved → landed/rejectedevents). Approval is a human act; agents and auto-mode skills only ever propose, and landing an approved proposal requires a reproducing negative test plus the guard itself. The normative gate lives in a new Correction-to-enforcement section ofdocs/shared-agent-conventions.md, the procedure and ledger schema indocs/correction-guards.md, and/idd-doctor's run-log summary now surfaces pending proposals. (#524) - resolver, pr-review: add opt-in project-local verification recipes. A repository may commit
.gitissue-recipe.jsondescribing how to launch its app, when it is ready, which capabilities to drive for which changed paths, and what cleanup to run. The new sharedgi-recipe.pyreads the recipe from the base ref only, so a branch never supplies the recipe it is verified by. It launches the app in its own process group, drives only the capabilities the diff maps, tears down only that owned group (on readiness failure and SIGTERM too), and keepslaunch.log, eachdrive.log, the drive outputs andverdict.jsonunder<git common dir>/idd/evidence/<sha>/, where they survive teardown and never dirty the tree./issue-resolverruns it in every Step 4 cycle and passes the clean cycle's evidence to the revision receipt asartifacts./issue-pr-reviewruns it in Step 4, even under a trusted QA handoff. A failing drive is a fixable finding. Interactive runs ask first, and auto mode runs only when the recipe'sautolist namesresolveorreview. Repos without the file see no change. This repo ships a pilot recipe for its static site with no auto opt-in. (#523) - resolver: add caller-first design sketches to Step 2 planning. When a change adds or reshapes a domain type, state or transition and the repo already has a static checker (
tsc --noEmit,mypy,pyright,go vet), the synthesizer's options differ in structure rather than scope. Each option carries adesign_sketch: its types, valid callers, and callers that attempt a forbidden transition. The orchestrator type-checks every caller in a gitignored.gitissue/sketch-<N>/scratch directory, never runs the sketch, and deletes the directory afterwards. The new sharedgi-sketch.pyfails a design whose checker accepts an invalid transition or rejects a valid caller, flags designs that are not structurally distinct, and decidesproceed,switch(select the passing design instead of the recommendation) orunproven(marked(needs review), never a stop). The selected sketch reaches Step 3 as the target shape, with one negative test per rejected transition. The light profile and reused analyses skip the check and say so. (#520) - resolver: add sensitivity and equivalence checks to the behavior-test contract. The implementer now mutates the hunk behind each acceptance-criterion test by hand, confirms that one focused test fails for the stated reason, then restores it. This stays manual: no mutation framework and no full-suite run. For a plan that declares no behavior change, it runs the tests that pin the touched outputs, negative and error-path tests included, green before editing, and they must still pass unedited afterwards. A test may be deleted or weakened only when an acceptance criterion or plan item removes the behavior it pins. The implementer and the fixer record that reason, and the code reviewer flags any unjustified removal as
action: fixin both/issue-resolverand/issue-pr-review. The PR body cites the mutation as sensitivity evidence. A check that cannot run is recordednot_verifiedand never blocks auto mode. (#521) - resolver: add a sensitive-change gate to Step 2. It runs on every profile, the light XS/S path included, and in auto mode. The new shared
gi-sensitive.py --classifytriggers it from the issue's labels or the planned paths (CI workflows, secrets, auth/session/permission/security code, access policy, security config), never from size. The plan then needs at least one falsifiable load-bearing probe that has run, plus a fresh code-reviewer challenge in the new{review_mode}=challengemode. Challenge-mode blockers are exempt from the confidence floor, and--adjudicatecloses a blocker only by an amendment that a re-challenge clears or by a rebuttal whosepath:lineor held-probe citation it verifies. One open blocker at any confidence stops the plan, and in auto mode that stop is a safety stop: the run endsfailed. (#518) - resolver: add a premise-reset gate to Step 4 QA. The fixer now returns the
premiseits fix acts on, and the orchestrator records a premise identity for each failed fix. The new sharedgi-premise.pyblocks the next fix once two failures share a premise. The block lifts only when diagnostics the orchestrator reruns to their recorded result support a revised premise, and neither the cycle cap nor the interactive continue gets past it. (#519) - evals: add an opt-in, blinded real-agent promotion lane.
evals/harness/agent_eval.pyruns a real agent CLI against a baseline and a candidateskills/revision on held-out tasks whose task and private-rubric digests are committed inevals/promotion/lock.json. It checks for leaks before and after the runs (canary and 8-word-shingle checks over the skills trees, the staged inputs and the transcripts), shuffles runs under opaque ids, hands graders scrubbed packets while the arm key stays sealed, and decidespromote,hold,reject,insufficientorinvalid. Each run records the model, CLI version, tools, harness digests, both arms' SHAs and skills trees, the executor and every artifact's digest inprovenance.json, andverifyre-checks them. The lane refuses to run in CI, and the hermetic suite stays the CI gate. (#517) - plugin: prepare the same eight IDD skills for Codex with a generated manifest and release-pinned marketplace, deterministic submission ZIP tooling, and a local preview/submission guide. This is the first tag that carries the Codex package; submission to the Codex plugin directory remains a separate owner step. (#489)
Fixes
- state, pr-review: validate run-state transitions and scope the pre-pass to approved paths.
gi-state.py --updatenow holds a transition table for the top-levelphase,current.phaseandlanes[].phase, built from/auto-pilot's documented checkpoints and resume back-edges. It also requires evidence for each phase: an integerprfor returned/review/fix/merge and for a merged cleanup, abranchfor a planned or resolving lane, andtelemetry.run_logfor log_pending/logged/completed. An unknown phase, an illegal edge (for examplefix/mergewithoutreview, orcompletedbeforelogged) or a missing piece of evidence exits 3 before anything is written, under--dry-runtoo./issue-pr-review's Step 2 pre-pass now formats only the PR's files that were clean before it ran. It stages with explicit NUL-delimited pathspecs instead ofgit add -A, scans the staged set withgi-secscan.py --staged, and commits only that list withgit commit --only. Unrelated dirty, untracked and pre-staged files are left untouched, and formatter spill-over is reported, never staged. (#522) - merge: every automated merge now checks that the commit and base its CI verdict covered are still the ones being merged. A new Step 5.1c — Merge identity gate in
/auto-pilot, a matching check before/issue-pr-review --auto's merge, and the partial and critical-issue merges all re-read the head and compare it with the live base branch (gh api …/compare/<base>...<head> --jq .behind_bymust be0). They never usebaseRefOid, which records the base at the PR's last sync. Every merge passes--match-head-commit. A moved head or a moved base leaves the PR open, and patch-id equality never replaces fresh integration checks. (#516) - qa-handoff:
/issue-pr-reviewused to trust a QA handoff marker that anyone who can edit a PR body can write. It now also requires a revision receipt for the PR's head./issue-resolverwrites that receipt at clean-QA exit with the new sharedgi-receipt.py, which records the full SHA, a clean tree, the executor's identity, the suite's count, SHA and command, and artifact digests, and stores it under the git common dir, outside every branch and PR body. A forged marker plus unrelated green CI now skips nothing. (#515)
Changed
- brand: the product is now called IDD Stack everywhere it is named: the website, the plugin listing (
displayName"IDD Stack: Issue-Driven Development"), the marketplace descriptions,llms.txt, the logo kit's accessible names, the README and docs, and the comments/issue-creatorposts on issues. The old product name "gitissue" is gone from prose. "IDD" still names the methodology (Issue-Driven Development and the IDD Spec), and identifiers are unchanged: theiddplugin id, the/idd:namespace,IDD_*variables,.gitissue.ymland thegitissue:markers. (#512)
Contributions by @luongnv89.
Full Changelog: v0.24.0...v0.25.0