Skip to content

feat!: Kivax owns the workflow, and models are selected from config - #9

Merged
null-result merged 1 commit into
developfrom
feature/kivax-owns-the-flow
Aug 1, 2026
Merged

feat!: Kivax owns the workflow, and models are selected from config#9
null-result merged 1 commit into
developfrom
feature/kivax-owns-the-flow

Conversation

@null-result

Copy link
Copy Markdown
Owner

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.yml keeps only what a project genuinely decides — and gains a way to pick the model each agent runs on.

principles and architecture also 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 audit or moved tdd before plan was 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:

  • The three-way sync had no reason to exist. sync.json, the hash comparison, conflict reporting, and .upstream sidecars existed solely to protect local edits to files that are generated from the store plus config.yml. With nothing left to customize in them, upgrade just 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/architecture were in the wrong place, not merely optional. Making them mandatory didn't fix that they self-skipped: asking "does PRINCIPLES.md exist 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.md upkeep already lived in the plan phase and tech-planner.md already 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) and GATES live in kivax_lib. paths_of() derives every path from paths.features, the one a project still chooses — an existing repo may already have docs/spec/ spoken for.

Setup is enforced once, at kivax feature new, which refuses while PRINCIPLES.md or ARCHITECTURE.md is missing and points at the new kivax-setup skill. Completion is the file existing on disk — deliberately no flag in state.yml, which could disagree with the filesystem. kivax doctor treats it as a next step on a fresh project (exit 0, nothing is broken) and as a real problem once features exist without them.

upgrade prunes. 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/workflows and project source are never touched, and there's a test pinning that.

Model selection is per-agent, rendered at install time:

agents:
  default:      {model: sonnet}
  orchestrator: {model: opus}

doctor rejects an unknown agent name, which is otherwise silent (the agent just renders with no model). Known gap worth a decision: this reaches claude, cursor, and opencode; copilot-cli, vscode-copilot, and codex have 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. doctor and upgrade name each one and what replaced it, then ask for version: 3.

The CI smoke job now asserts the refusal. It called kivax feature new right after init, 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 tests passes — 472 passed
  • Coverage stays above the 90% gate — 97.23%
  • ruff check . bin/kivax passes
  • Behavior changes are covered by tests that fail without the fix (new tests for pending_setup, the feature new refusal, upgrade overwrite/prune, and model rendering; test_cli_promote.py deleted with the feature)
  • Agents and skills under share/ updated — new kivax-setup, rewritten kivax-principles/kivax-architecture/kivax-new, orchestrator flow and gates sections, and the extension paths removed from kivax-run/kivax-audit
  • README updated — pipeline table, new "Project setup" section, wizard steps, migration note

🤖 Generated with Claude Code

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>
@null-result
null-result merged commit 39fdbd2 into develop Aug 1, 2026
13 checks passed
@null-result
null-result deleted the feature/kivax-owns-the-flow branch August 1, 2026 09:16
@null-result null-result mentioned this pull request Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant