Skip to content

v2.7.0: routing, concurrency and cost - #11

Merged
Param-Harrison merged 1 commit into
mainfrom
release/v2.7.0
Sep 27, 2026
Merged

Param-Harrison merged 1 commit into
mainfrom
release/v2.7.0

Conversation

@Param-Harrison

Copy link
Copy Markdown
Contributor

Summary

  • routes in .factory/config.json picks an agent per (type, stage), resolved by resolveRoute
    (routes[type].stages[stage] → stages[stage] → stages.default → "claude"); triage always
    uses stages.triage, since the type isn't known yet. template/.factory/config.example.json
    ships the recommended default (triage/PR on Haiku, plan on Opus, build/verify on Sonnet, docs
    builds on Haiku).
  • src/context.ts: buildContextPack assembles AGENTS.md, a route's skills, ARCHITECTURE.md and
    the plan's named files into one pack per stage, capped at 64 KiB, dropped whole (never
    truncated) in priority order. Claude gets it on the same --append-system-prompt as
    STAGE_GUIDANCE; every other agent gets it inlined ahead of the artifact contract.
  • Pricing for claude-sonnet-5 and claude-opus-5-5, captured in research/pricing/anthropic.md.
  • src/machine.ts: machine-wide concurrency (FACTORY_SLOTS or machine.json), leased in
    machine.db and reclaimed on a dead pid, so two watchers on one machine share one pool. A
    repo's own concurrency becomes a cap on top, and factory doctor advises a slot count.
  • Continuous dispatch in watch.ts: the poll loop no longer waits for the whole batch to drain
    before starting new work off a freed slot.
  • Spend caps: spend.perIssueUsd and dailyUsd (repo and machine), checked before every stage
    against stage_runs.cost_usd; over a cap parks the issue with a "budget" inbox item.
  • proof: "test" | "check" on the plan artifact: check runs named commands instead of a
    failing test, so Markdown-only work (a blog post, a docs page) can ship without one. The type
    list is config-driven everywhere now; TYPE_LABELS is the default, not the only list.

Structural tests (all revert-and-fail proven)

  • every (type, stage) pair in routes/TYPE_LABELS resolves to a defined agent
  • loadConfig refuses at boot when a routed skill has no SKILL.md on disk, instead of a silent
    mid-run no-op in the context pack (tests/routes.test.ts)
  • a proof: check plan (Markdown files, a prose-lint gate, no test file) ships exactly like a
    proof: test plan (tests/scenarios.test.ts, scenario 23)
  • the app-agnostic grep now covers every file under template/.claude/skills and
    template/.claude/agents for a named stack tool
  • a property test holds running jobs to the machine's slots across two watcher processes and
    confirms a freed slot is picked up within one poll

Test plan

  • bunx tsc --noEmit clean
  • bun test: 739 pass, 0 fail, 2384 expect() calls, 74 files
  • make check: ok (typecheck + test + skills-ref validate)
  • Two genuine revert-and-fail proofs shown this release (routed-skill-exists check in
    src/config.ts, and the proof: "check" schema entry in src/schemas.ts)
  • Live run on splitbill-demo exercising the new routes and concurrency — pending your reset OK

🤖 Generated with Claude Code

Model routing per issue type and stage, a per-stage context pack, current
Anthropic model pricing, machine-wide concurrency slots and spend caps, and
proof:check so Markdown-only work never needs a failing test. Closes out
the remaining v2.7.0 structural tests: every routed skill is checked at
boot, and a Markdown-only proof:check plan ships with no test file, both
proven by revert-and-fail.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Param-Harrison
Param-Harrison merged commit dada6de into main Sep 27, 2026
2 checks passed
@Param-Harrison
Param-Harrison deleted the release/v2.7.0 branch September 27, 2026 13:30
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