feat!: Kivax owns the workflow, and models are selected from config - #9
Merged
Conversation
The flow was configurable in ways that cost users decisions without
buying them anything. A project could reorder the pipeline, add its own
phases, retarget every path, and flip approval gates — so "Kivax" meant
something different in each repo, and the docs, skills, and error
messages could only describe the default. This makes the workflow the
tool's, and leaves config.yml holding only what a project genuinely
decides.
BREAKING CHANGE: config.yml keys `pipeline`, `gates`, `git.branch_prefix`,
every `paths.*` except `features`, and `stack.*.cmd_lint` are ignored;
`kivax promote` and `.kivax/sync.json` are gone. Old configs keep
working — `kivax doctor` names each dead key and what replaced it.
The flow is now code:
- PIPELINE is fixed at spec → compile → plan → tdd → it → audit → retro,
with GATES alongside it. Both live in kivax_lib, not in any config.
- Users can no longer add agents, skills, or phases to the flow. The
worked example under share/examples/ and the extension paths in the
orchestrator and skills are removed.
- paths_of() derives every path from paths.features, the one a project
still chooses (an existing repo may have docs/spec/ spoken for).
principles and architecture leave the pipeline entirely:
They describe the project, not this week's feature, so asking "does the
file exist yet?" at the head of every feature answered a question about
the repository in the wrong place — two steps in each feature's history
that did nothing. They become one-time setup behind the new kivax-setup
skill, gated by `kivax feature new`, which refuses while either document
is missing. Completion is the file existing on disk; deliberately no
flag in state.yml, which could disagree with it. ARCHITECTURE.md upkeep
already lived in the plan phase, so nothing moves there.
upgrade replaces the three-way sync:
The manifest, hash comparison, conflict reporting, and .upstream sidecar
files existed only to protect local edits to files that are generated
from the store plus config.yml. With nothing left to customize in them,
upgrade overwrites what it manages and prunes what the store no longer
ships, so a renamed skill can't linger as a phase driver the flow never
references. `kivax promote`, which pushed those edits back upstream, has
no purpose left.
Per-agent model selection lands where the choice belongs:
agents:
default: {model: sonnet}
orchestrator: {model: opus}
The value is rendered into each agent file's frontmatter at init/upgrade
in the runtime's own spelling, and doctor rejects an unknown agent name,
which is otherwise silent. It reaches claude, cursor, and opencode;
copilot-cli, vscode-copilot, and codex have no model field to write to.
Co-Authored-By: Claude <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
Kivax no longer lets a project reshape the SDD flow. The phase pipeline, the approval gates, and the specialist agents become code;
.kivax/config.ymlkeeps only what a project genuinely decides — and gains a way to pick the model each agent runs on.principlesandarchitecturealso leave the pipeline: they become one-time project setup, run once per repository instead of being checked at the head of every feature.Why
The configurability cost users decisions without buying them anything. A project could reorder the pipeline, insert its own phases, retarget every path, and flip gates — so "Kivax" meant something different in each repo, while the docs, skills, and error messages could only ever describe the default. Worse, a project that dropped
auditor movedtddbeforeplanwas still called Kivax while making none of the promises Kivax exists to make.Two things fell out of that once the flow was Kivax's:
sync.json, the hash comparison, conflict reporting, and.upstreamsidecars existed solely to protect local edits to files that are generated from the store plusconfig.yml. With nothing left to customize in them,upgradejust overwrites.kivax promote, whose whole job was pushing those edits back upstream, went with it. This is the single largest reduction in the diff, and it wasn't obvious going in.principles/architecturewere in the wrong place, not merely optional. Making them mandatory didn't fix that they self-skipped: asking "doesPRINCIPLES.mdexist yet?" at the head of every feature answers a question about the repository in the wrong place — two steps in each feature's history that did nothing, and a pipeline that looked like nine phases when seven are the work. Notably,ARCHITECTURE.mdupkeep already lived in theplanphase andtech-planner.mdalready said "initial creation only", so being in the pipeline had never bought anything.What a reviewer should know
The flow is now code.
PIPELINE(spec → compile → plan → tdd → it → audit → retro) andGATESlive inkivax_lib.paths_of()derives every path frompaths.features, the one a project still chooses — an existing repo may already havedocs/spec/spoken for.Setup is enforced once, at
kivax feature new, which refuses whilePRINCIPLES.mdorARCHITECTURE.mdis missing and points at the newkivax-setupskill. Completion is the file existing on disk — deliberately no flag instate.yml, which could disagree with the filesystem.kivax doctortreats it as a next step on a fresh project (exit 0, nothing is broken) and as a real problem once features exist without them.upgradeprunes. It deletes files under the managed dirs that the store no longer ships, so a renamed skill can't linger as a phase driver the flow never references. Pruning is scoped to those dirs only —.github/workflowsand project source are never touched, and there's a test pinning that.Model selection is per-agent, rendered at install time:
doctorrejects an unknown agent name, which is otherwise silent (the agent just renders with no model). Known gap worth a decision: this reachesclaude,cursor, andopencode;copilot-cli,vscode-copilot, andcodexhave no model field in their agent files, so the setting silently does nothing there. Documented, but it's config that no-ops on half the supported runtimes.Migration is non-breaking for existing projects. Old configs keep working; the dead keys are ignored.
doctorandupgradename each one and what replaced it, then ask forversion: 3.The CI smoke job now asserts the refusal. It called
kivax feature newright afterinit, which fails by design now — so it checks the error and then stands in for the assistant by writing the two documents, rather than routing around the precondition.Checklist
pytest testspasses — 472 passedruff check . bin/kivaxpassespending_setup, thefeature newrefusal,upgradeoverwrite/prune, and model rendering;test_cli_promote.pydeleted with the feature)share/updated — newkivax-setup, rewrittenkivax-principles/kivax-architecture/kivax-new, orchestrator flow and gates sections, and the extension paths removed fromkivax-run/kivax-audit🤖 Generated with Claude Code