Changelog
All notable changes to Praxis are documented in this file.
The format is based on Keep a Changelog,
and this project adheres, loosely, to Semantic Versioning —
loosely because the library is pre-1.0; some interfaces may still shift between
minor versions until it stabilizes.
Unreleased
Fixed
- Governance gate count corrected across current-state docs. README (counts table + "What's inside" + architecture diagram + project tree),
INSTALLATION.md,PLAYBOOK.md, anddocs/{operating-model,quickstart,getting-started,claude-code-setup}.mdsaid "17 gates (6 core + 11 conditional)", butgovernance/governance.yamldefines 18 — theideation_refinement_approvalconditional gate (end ofideation-refinement-loop.yaml) was never counted, whileplugin.json/.claude-plugin/marketplace.jsonalready said 18. All current-state docs now read 18 (6 core + 12 conditional). Root cause:build-registry.pysyncs skill/agent/workflow/command counts but not gate counts, so this drift was invisible to CI; the durable fix (teaching the registry to own the gate count) is noted for a follow-up. - Full-platform prod-readiness audit (3 parallel reviews: docs currency, ADLC coverage, harness parity). P0s fixed:
commands/slice.mdcontradicted the two-tier delegation canon (told delivery-lead to spawn specialists directly; agents/delivery-lead.md and the Codex praxis-slice both say Lead Developer dispatches, delivery-lead only as fallback) AND never had lead-developer produce the task ledger — breaking the/slice→/drivehandoff on Claude; the Codexadaptive-model-routingoverlay was stale (delivery-lead still listed deep/high vs the canonical standard/medium rebalance; false "identical to every harness" claim; unclosed code fence swallowing two sections; missing routing-examples reference). Parity: addedpraxis-factory-record(the one missing Codex command; validator now requires it); Codex delivery-lead + lead-developer TOML developer_instructions now carry the core constraints (two-tier delegation, single-writer, drive-mode runner/in-session split, ledger-at-slice-open); the mirror's hooks.json plugin-root var gets a${CLAUDE_PLUGIN_ROOT:-${CODEX_PLUGIN_ROOT:-}}fallback chain;using-praxisnow states the per-spawnmodel:mechanic is Claude-only (Codex applies routing via regenerated profiles) and names the Codex command surface. Docs: counts corrected everywhere (91 skills / 12 commands / 5-11-1 tiers) across README/INSTALLATION/PLAYBOOK/quickstart/getting-started + 4 harness docs; PLAYBOOK §2.3 no longer calls the plugin "future" (plugin-first install, both harnesses); getting-started leads with plugin install; CONTRIBUTING documents resolve-model/test-routing-parity/governance-overrides/setup-claude-agents; autonomous-drive doc states in-session drive loops continuously; telemetry doc covers the Codex Stop upsert; plugin-builds documents the fail-on-orphan build. Coverage verdict recorded: strong across methodology/brownfield/incidents/UX/routing/data-ML; named gaps (product experimentation + outcome analytics, dynamic security validation/DAST-pentest, evaluative usability testing) deferred as candidate new skills. - Drive no longer stops after one task in-session on EITHER harness (root cause, shared agent).
agents/delivery-lead.md's Drive mode said "when invoked via/driveorscripts/praxis-drive.sh, execute exactly ONE iteration and exit — the harness re-invokes you." That contract only holds for the unattended runner; under in-session/drivenothing re-invokes it, so the run died after a single task (observed on both Codex and Claude Code). Drive mode now splits the two invocation paths explicitly — runner: one iteration then exit; in-session: complete an iteration then immediately begin the next (or return so the orchestrator can), continuing through the slice drain and into the next ledger — and adds a hard rule: ending a drive run after one completed task with no non-negotiable stop and nostop_afterboundary reached is a protocol violation, not "correct one-iteration behavior."commands/drive.mdnow tells the in-session orchestrator it is the loop and must not report-and-wait. - Codex in-session
$praxis-drivenow loops like Claude's/driveinstead of stopping after one task. The Codex skill's header said "You do NOT loop internally" over the whole skill and its in-session step said "one iteration at a time … reporting the outcome each time", so the orchestrator did a single delivery-lead iteration and paused — even understop_after: gate, where it should continue through the slice drain (code/security/QA review + closure) to the next real stop. "One iteration then exit, no internal loop" is correct ONLY for a delivery-lead invoked by the unattended runner (which re-invokes per iteration); it must not apply to the in-session orchestrator. The skill now scopes that discipline to the runner path and instructs the in-session path to iterate continuously within the session until a non-negotiable stop or thestop_afterboundary, explicitly noting per-slice reviews are drain, not governance gates. Matchescommands/drive.md(Claude) andskills/autonomous-drive§"stop_after semantics". The unattended runner (praxis-drive.sh --harness codex) already looped deterministically and is the reliable path for whole-slice/workflow drive. - workflow-drive no longer crashes on machine-checkable
decision_nodesteps (external review, P1). A decision_node runs no agent, so it left theUSAGE_*vars unset — but the telemetry append reads them bare (not${x:-null}), so underset -uthe runner aborted withUSAGE_INPUT_TOKENS: unbound variableright after evaluating the step (exactly on the newstatus_fieldideation path). The decision_node branch (and the sub_ledger parse-fail branch) now initialize allUSAGE_*+ITER_EFFORTtonull, matching the sub_ledger success branch. Verified: astatus_fielddecision_node reachesdone(pass) / writes anoutcome: failedrecord withroute_back(fail), no unbound-variable abort in either case. - Pre-commit now rebuilds the Codex mirror on hook-only changes (external review, P2).
hooks/is packaged bybuild-codex-plugin.shbut was absent from.githooks/pre-commitTRIGGERS, so a change to onlyhooks/tap.shorhooks/hooks.jsoncould commit without regeneratingplugins/praxis-codex/hooks/. Addedhooks/toTRIGGERS. - Codex drive routing is now actually enforced (external review, P1). The drive runner resolved routing per harness by assuming
mapwas always the model map — but for Codexmapismodel_reasoning_effort, so Codex iterations recordediteration_model: "low"(mislabeled effort) and applied nothing (model_flag: null). The runner now resolves the two axes by FIELD NAME (model→ model axis,*effort*→ effort axis) generically for every harness, skipsautovalues, and Codex effort is applied ascodex exec -c model_reasoning_effort=<level>(model as-m, omitted while the model map isauto). Verified: Codex deep-tier iteration emits-c model_reasoning_effort=highas clean argv, telemetryiteration_effort: high/iteration_model: null; Claude unchanged (--model opus --effort high). autonomy.yaml codex harness gainsmodel_flag: -m,effort_flag: -c,effort_arg_prefix. - Codex end-of-session token capture is now wired to the right event (external review, P1). Codex has no
SessionEnd(its turn-scopedStopis the analog, verified against the Codex hooks reference); the packaged plugin registered onlySessionEnd, so Codex captured nothing.tap.shnow handlesSessionEnd|Stopthrough one handler; the mirror's hooks.json drops the unsupportedSessionEndand addsStop; theStoppath emits a valid{}on stdout (Codex requires JSON output for Stop and would treat plain text as invalid — and a bare{}avoids an accidentaldecision: blockcontinuation). Token capture is now an UPSERT keyed by session id, so a turn-scopedStopfiring more than once refreshes the running total in place instead of double-counting.validate-codex-plugin.shnow rejects any Codex-unsupported hook event name and requiresStop. - Generated Codex mirror no longer silently retains stale files (external review, P2).
build-codex-plugin.shreplaced the "orphans may linger" fallback: it refreshes every file in place, then reconciles OUT against the exact set it produced and REMOVES anything left over; if a stale file cannot be removed it FAILS (exit 4) rather than publish a dirty public package.validate-codex-plugin.shalready fails on mirror drift. - Fallback gates reconciled with governance (external review, P2). A
fallback_gateis a human review BOUNDARY (predicate not machine-checkable at runtime), distinct from a governance-matrix gate;validate-workflows.pyno longer warns that fallback_gate names are "missing from governance.yaml" (onlykind: gatenames are cross-checked), andreferences/phase-gates.md§2 states the distinction. Check-kind regexes are now inline-comment tolerant (matching the runner, which strips comments). - Ideation convergence is now genuinely machine-checked (external review, P2).
convergence_checkpersists a deterministic verdict (recommended_disposition, computed from "no findings ≥ major AND next-pass value cosmetic/low") to.project/working/ideation-convergence.yaml, andloop_decisionreads it viacheck: status_fieldinstead of afallback_gate— sogovernance.yaml's "machine-checked" description is now true rather than aspirational.
Added
-
/intake($praxis-intake) — a single steady-state front door for new requirements, so you never pick a workflow by hand. Therequirements-intakediscipline (triage size + blast radius + owner, sequence, route) already existed as a skill but had no command, which forced manual routing per story/epic./intakefronts it: drop any new story/ticket/change and it logs to.project/working/inbox.md, right-sizes, and routes to the lightest safe path (small ready story → slice +/drive; touches existing behavior → impact-analysis first; epic/cross-cutting → discover + architect + project-phasing; unproven → spike; P0/P1 → expedited-change), preventing FIFO churn and impulse coding. Wired for all harnesses (Claude/Gemini command files + Codex command skill), registry counts auto-updated (11→12 commands), and theusing-praxisrouter +docs/drive-first-playbook.mdsteady-state section now point at it. -
Drive and no-drive now route identically (single source of truth). Previously a spawn's model came from the drive runner (which read the effective table) in drive, but from the baked agent profile (plugin default) in no-drive — so a project override only affected drive. Now one rule governs every spawn:
resolve(tier, harness)against the effective table (.project/governance/model-routing.yamlfirst, plugin default fallback), withforce_tierapplied. Newscripts/resolve-model.pyis the shared resolver;adaptive-model-routing/delivery-lead/using-praxisnow resolve through it and pass the model at spawn (Claude Code's per-invocationmodel:beats frontmatter);scripts/setup-claude-agents.sh(+apply-model-routing.py --claude-out) materializes project-local.claude/agents/*.mdthat shadow the plugin so the static fallback is override-correct too.scripts/test-routing-parity.shasserts the resolver and the drive runner agree for every tier on both harnesses and that an override moves both together. Fixed a latent bug the parity test caught: the drive runner ignoredoverrides.force_tier— it now honors it, matching the resolver and the governance intent ("force every agent to that tier"). -
Project routing overrides now reach the Codex subagent profiles. Previously the
.codex/agents/*.tomlwere generated from the PLUGIN'smodel-routing.yamlat build time, so a project-level.project/governance/model-routing.yamloverride (which the drive loop already honors at runtime) never affected the static subagent profiles — you'd have had to hardcode models in the plugin defaults. Nowapply-model-routing.pytakes--routing/--project-dir(read the project override, falling back to the plugin default) and--codex-out DIR(write the resolvedmodel/model_reasoning_effortinto a target.codex/agents/, leaving the plugin's own files untouched), and$praxis-setup-subagentsruns it on install/refresh. Setmodel_map(pin models) ormap(effort) in your project override and re-run setup-subagents to propagate — no plugin edits. Defaultmodel_map: autostill writes nomodelline (subagents inherit the Codex session model). Re-running also refreshes stale effort values (the reason astandard-tier agent could still showhighafter a tier rebalance). -
Governance-override drift detection + non-destructive refresh.
.project/governance/{model-routing,autonomy}.yamlare seeded once and win over the plugin's copies (so per-engagement tuning survives updates) — which meant new default keys from a plugin update (e.g. the codexeffort_flag/effort_arg_prefixthat enable per-iteration reasoning-effort routing) never reached an existing project. Now: the SessionStart hook detects the drift (plugin has keys your copy lacks) and prints a warning with the exact fix command;scripts/refresh-governance-overrides.sh [--apply]reports the drift and, on--apply, merges the new keys in while KEEPING your tuned values (backs up first; changed defaults are surfaced for review, never silently overwritten);scripts/governance-overrides.pyis the zero-dep diff/merge engine.governance.yamlstays plugin-owned (read from the plugin, not a project override) so gate-topology changes propagate automatically. Docs:docs/codex-setup.mdrefresh checklist +INSTALLATION.md§6. -
triageskill (experimental): on-demand discovery scan (git activity, failing tests/CI, tech-debt register, TODO drift, dependency alerts, doc-vs-code drift) that writes a classified inbox (.project/operational/triage/.md) splitting findings into auto-fixable-with-machine-verify vs needs-human vs informational. Zero standing cost — invoked, never scheduled; the scheduled heartbeat stays roadmap-only. Optionally seeds a slice ledger for /drive on explicit ask. -
Routing v2 (simplified, single tier axis — lane axis deliberately rejected as redundant): each capability tier now resolves to model AND reasoning effort, not just model. Claude gets per-iteration
--effort(verified flag: low|medium|high|xhigh|max) alongside--model, andeffort:in agent frontmatter — enabling the cheaper cost lever (deep thinking on a standard model instead of a model-family jump). Codex agent TOMLs gain optionalmodelalongsidemodel_reasoning_effort, and drive telemetry captures Codexreasoning_output_tokensseparately (verified end-to-end: input=50/cache_read=30/reasoning=42).model: auto/model_map: autosupported = omit the flag/key and use harness default; concrete models stay the library default so per-iteration cost tiering does not regress; project overrides pin per engagement. drive.jsonl gains iteration_effort + reasoning_output_tokens; routing-decision template gains resolved_effort + decision_source. Docs updated (model-routing, adaptive-model-routing, llm-cost-optimization, telemetry, factory-metrics-schema). -
Workflow-drive — the top-level loop over workflow steps.
scripts/praxis-drive.sh --workflow(opt-in, default off) loops a workflow's steps rather than a slice's tasks, reading.project/working/workflow-state.yaml; each step runs on its own phase-tier model — universal per-step model routing that now covers the orchestrator itself, not just specialists. Autonomy zone is C -> D only (implementation through release); discovery/architecture (A/B) stay human-gated, andkind: gatesteps plus any non-machine-checkable boundary always stop for a human regardless of the autonomy dial. Schema and step kinds:references/phase-gates.md; protocol:skills/autonomous-drive's "Workflow-drive" section; operator docs:docs/autonomous-drive.md,docs/operating-model.md. -
Phase-exit predicate hardening. Every workflow
decision_node/ phase-exit boundary must now resolve to a machine-checkablecheck(command | artifact_exists | artifact_contains | verdict_file) or declare an explicitfallback_gatefor judgment-call boundaries;scripts/validate-workflows.pyfails any decision node that does neither — closing the "LLM silently asserts a phase exit" gap. Seereferences/phase-gates.md§2. -
delivery-plannernow emits the workflow-step ledger (.project/working/workflow-state.yaml, one entry per phase/gate/decision-node) alongside the workflow instance it already produced — this is the artifact workflow-drive consumes. -
Added the
ideation_refinement_approvalgovernance gate, closing a pre-existing dangling reference (workflows/ideation-refinement-loop.yamlnamed the gate beforegovernance/governance.yamldefined it). -
Routed the router: drive iterations now run on the model the TASK's tier resolves to (new per-harness model_flag in autonomy.yaml: --model for claude, -m for gemini, TOML-profile for codex; recorded as iteration_model in drive.jsonl) — a light-tier task's whole iteration, including delivery-lead protocol execution, runs on the light model. delivery-lead's static tier corrected deep -> standard (measured evidence: routing sessions were the largest deep-tier cost center); deep is now an escalation for re-plans/ambiguous decision nodes/judgment-heavy gates, never a resting state — routing table, per-agent assignments (5 deep / 11 standard / 1 light), and docs/model-routing.md updated.
-
Session discipline codified in PLAYBOOK (7.0): one slice, one session — clear after the slice-close checkpoint (never mid-slice; /compact at task boundaries for long slices); rationale: chosen compaction points beat lossy auto-compaction, fresh context beats quality dilution, and session-per-slice makes tokens.jsonl read directly as cost-per-slice.
-
Artifact-class token hygiene named per surface (generic AOP rule made rationalization-proof): qa-engineer suite-run hygiene (quiet reporters, log capture, summary + failing extracts; coverage summaries only), platform-sre pipeline/deploy/IaC-plan log hygiene, static analysis to file with top-N consumption in /audit (all copies), code-reviewer exclusion of generated/lock artifacts from ingestion (consistency-check instead), and testing-strategy now mandates quiet reporters as the test-plan default with verbose re-runs on demand.
-
Live per-invocation token capture: SubagentStop hook computes the transcript usage DELTA since the last cursor position and writes it to agent-spawns.jsonl attributed to the finishing agent (event: invocation_usage; concurrent spawns honestly share a delta); factory-routing-report.py renders a 'Real tokens per agent' table; cursor cleaned at SessionEnd. Cost is now visible DURING runs, not only at session end.
-
Evidence-first token optimizations with explicit quality guards: hand-off reply contract (<=15-line structured replies, artifacts on disk — blockers/deviations/uncertainty are MANDATORY fields, never compressed away), read discipline (grep-to-locate before Read; reviewers work diff+context; reading deeper is always permitted when judgment requires — only mechanical over-reading is targeted), cache-aware spawn-prompt ordering (stable prefix first, volatile state last; drive's constant prompt documented as deliberate cache design), and diff-scoped review guard in code-reviewer with 'review depth is never budget-capped' stated verbatim.
-
Token attribution ladder completed: sidechain-aware per-agent-invocation attribution in factory-token-report.py (main-vs-sidechain split, invocation segments with best-effort agent identity), task started_at/completed_at timestamps in the ledger (stamped on status change, drive and interactive alike) enabling window-attributed per-task tokens in interactive sessions — clearly labeled approximation vs drive.jsonl's exact per-task measurement; attribution ladder documented (session exact > drive task exact > sidechain measured > interactive window approximation).
-
Token telemetry made universal: SessionEnd hook now sums each session's own Claude Code transcript into .project/telemetry/tokens.jsonl (deterministic, every session — interactive or driven); factory-token-report.py treats hook records as authoritative with transcript mining as gap-fill; ceremony honored at pre-merge review in ANY mode (delivery-lead general discipline, not drive-only); tool-output hygiene promoted to a universal AOP rule in using-praxis.
-
Real token telemetry: praxis-drive.sh captures actual usage + total_cost_usd from headless JSON output into drive.jsonl; new scripts/factory-token-report.py mines Claude Code session transcripts for per-session/model/day/slice token totals with a proxy-calibration table; factory-routing-report.py surfaces real tokens/USD per drive run and its prose-dispatch parser now counts routing-frontmatter files (PortiQ validation: 0 -> 13 dispatches).
-
Verify-output hygiene: verify commands authored quiet, full output captured to .project/working/verify-.log, model consumes exit code + failure extract only (loop-contracts, autonomous-drive, lead-developer) — tool-result token sink closed.
-
Adaptive ceremony: task ledgers carry ceremony: full|expedited|spike scored at slice open (reversibility x blast radius x production exposure; security-bearing surfaces force full), drive drains gates accordingly (expedited = single blocker-only review + mandatory retro; spike = report artifact, never merges); engagement switches in governance/autonomy.yaml; governance gates unaffected.
-
Honest harness test-status published everywhere support is claimed: tested end-to-end on real engagements = Claude Code + Codex; adapters shipped and structurally validated but under test = Gemini CLI, Cursor, OpenCode, Copilot, Kiro, Antigravity. Publishing-readiness sweep synced all counts (90/17/9/11/17) and telemetry descriptions across README, INSTALLATION, PLAYBOOK, and every docs page.
-
Telemetry redesigned around checkpoint records — the universal aggregation point at EVERY closure boundary (gate, phase end, slice close, loop convergence, disposition, workflow end), covering discovery/architecture/ideation/release phases that have no slice: structured episodic entries (agents_dispatched, skills_consumed, artifacts, cost_proxy, human touchpoints) written by delivery-lead at the AOP Document step; new scripts/factory-usage-report.py mines checkpoints + packets/ledgers/routing/commands/sessions into per-skill/agent/workflow usage analytics; hooks/tap.sh slimmed (retired the ~5%-capture per-Read and preload stub files and per-session stub files — sessions now one JSONL line each); factory-frequency/aging marked legacy; factory-evaluation and docs/telemetry.md updated to the mined-artifacts model. Zero incremental token cost: analytics ride on artifacts the workflow already produces.
-
Brownfield parity for governance seeding: /audit (all copies + Codex praxis-audit) gains a Day-0 setup step — initialize the .project tree, seed .project/governance/ overrides, and ask the same routing/autonomy tuning question as /start, with a brownfield-specific suggestion of stop_after: slice until characterization-test coverage is trusted.
-
Governance overrides now seed automatically: the SessionStart hook copies model-routing.yaml + autonomy.yaml into
.project/governance/on first session (project copies win, survive plugin updates), and/start(all harnesses incl. Codex praxis-start) asks the user once whether to keep default adaptive routing/autonomy or tune force_tier / cost_weights / stop_after / run_budget for the engagement — answers applied to project copies only. build-registry.py now also maintains the /start count line. -
Per-project governance overrides:
.project/governance/model-routing.yamland.project/governance/autonomy.yamlnow win over the plugin-shipped copies (consumed by praxis-drive.sh, factory-routing-report.py, and delivery-lead's runtime routing) — engagements can tune force_tier / cost_weights / stop_after / budgets without editing the installed plugin; documented in docs/model-routing.md. -
UI-quality enforcement wired end-to-end:
visual_reviewbranch in the pre-merge gate ofimplementation-slice.yaml(ux-designer reviews implementation screenshots against the design plan/tokens/frontend-design calibration; fires only on UI-bearing slices; blockers feed the same fix loop), UX hand-off now emitsdesign_tokens+design_plan, FE/mobile branches captureui_screenshotsas evidence, task ledgers gain avisual_reviewgate key and token-lint in FE taskverify, ux-designer produces.project/semantic/design-brief.mdat first engagement, and delivery-planner gains adesign_fidelityflag. -
frontend-designskill (experimental): harness-portable visual-design craft adapted from Anthropic's open frontend-design skill — subject-grounded direction, two-pass plan-then-critique process, anti-generic calibration (the three AI-default looks), interface-copy rules, and a free-first design-tooling fallback chain (Figma MCP -> community/Penpot -> Stitch/v0 free tiers -> token-themed shadcn baseline -> text-only floor). Consumed by frontend-developer, mobile-developer, and ux-designer. -
Three new workflows + six conditional governance gates.
workflows/expedited-change.yaml
(P0/P1 incident or critical-security-patch fast path: compressed gates now —
scope containment, blocker-only combined review, rollback readiness —
gated byexpedited_change_approval, repaid by a MANDATORY retroactive
full review + blameless postmortem + tech-debt entries, gated by
expedited_change_retro);workflows/spike.yaml(time-boxed feasibility
exploration; a bounded build-to-learn loop with no review gate on the
throwaway code, gated only at disposition —spike_disposition—
archive or promote the report into discovery; spike code never merges);
workflows/modernization.yaml(strangler-fig legacy replacement: deep
comprehension + seam identification, target architecture + migration
strategy sign-off atmodernization_strategy_sign_off, a per-seam
increment loop with characterization tests +implementation-slice
sub-workflow + parallel-run comparison telemetry gated at
parallel_run_verification, then a gated legacy decommission phase at
legacy_decommission_approval). Total: 9 workflows, 17 gates (6 core +
11 conditional). Plus a "Workflow composition policy" section in
skills/using-praxis/SKILL.mdand a workflow-selection table in
skills/delivery-planner/SKILL.md: a scenario earns a new workflow file
only when its gate topology differs, otherwise it's planner
parameterization of an existing template — the anti-sprawl rule that
keeps workflow-count creep afactory-evaluationdecay signal alongside
skill-count creep. -
Autonomous drive mode.
scripts/praxis-drive.sh— a Ralph-style outer
runner that re-invokes a fresh-context harness against the task ledger
until a stop condition fires (exit codes:0natural,3stalled,4
budget,5blocked); the autonomy dial (stop_afterin
governance/autonomy.yaml, the three non-negotiable stops, the
first-slice-of-phase rule) plus run budgets and stall detection; loop
contracts and the task ledger schema (references/loop-contracts.md,
.project/working/slice-<id>-tasks.yaml); theskills/autonomous-drive
delivery-lead protocol; the/drivecommand; drive telemetry at
.project/telemetry/drive.jsonlplus a drive section in
scripts/factory-routing-report.py; slice-close async summaries at
.project/telemetry/summaries/; new operator docs
docs/autonomous-drive.mdanddocs/operating-model.md. -
Cost/routing telemetry completed:
hooks/tap.shnow writes deterministic spawn/completion events (with model and token fields when available) to.project/telemetry/agent-spawns.jsonl;scripts/factory-routing-report.pyaggregates structured telemetry, prose routing logs, and usage records into a per-slice routing/cost report (cost proxy viacost_weightsingovernance/model-routing.yaml); JSONL schemas documented inreferences/factory-metrics-schema.md. -
Documentation overhaul: new
docs/quickstart.md(5-minute path),docs/telemetry.md,docs/model-routing.md; README docs index; per-tool verify-your-install checklists; CONTRIBUTING validator/generated-surfaces/skill-authoring guides. -
Pre-commit hook now reminds the committer to double-check documentation when core artifacts change without any doc change (non-blocking).
-
Four new skills (state: experimental):
feature-flags-progressive-delivery,schema-migration,caching-strategy,developer-experience. -
Abstract capability tiers. Agents now declare a harness-agnostic
capability_tier
(deep | standard | light) in frontmatter instead of a concrete model name.
governance/model-routing.yamlis the single file that maps tiers to concrete
models per harness (Claude Code, Codex, Gemini CLI);scripts/apply-model-routing.py
applies the mapping and rewritesagents/*.mdfrontmatter and
codex-plugin-assets/codex-agents/*.tomlaccordingly (--checkmode for CI). -
Runtime ±1-tier adaptive routing.
delivery-leadscores each sub-agent spawn
against theadaptive-model-routingrubric and may shift the agent's default tier
up or down by one step; on gate failure it promotes one tier and retries once before
escalating to the human. Every routing decision is logged to
.project/telemetry/model-routing.jsonlfor cost/quality analysis. -
definition-of-doneskill — a shared, explicit checklist agents apply before
declaring a slice, phase, or release complete. -
mobile-developeragent — a new specialist role for mobile-stack implementation
work, following the existing Tier-2 specialist pattern (backend/frontend/data/ml). -
Registry + validator scripts and CI — scripts that build and check the
agent/skill/workflow registry (scripts/build-registry.py --check), wired into CI
so skill/agent/workflow counts and cross-references stay accurate without manual
bookkeeping. -
10 new reference files — filled in from the highest-priority items tracked in
references/MISSING-INVENTORY.md. -
Repo governance docs —
CHANGELOG.md(this file),SECURITY.md,ROADMAP.md.
Fixed
-
External-review blockers (workflow-drive, all 4 + validator gaps): nested block-form exit.args now parse (parse_steps_block rewritten); new status_field check kind reads a dotted field from a file and compares to expect (phase-gates §2); failed workflow exits now stamp status=failed + completed_at + raise stop_flags instead of leaving steps stuck in_progress; decision_node steps with a machine check are evaluated (not auto-stopped); 12 decision_nodes that used check:command with no runnable cmd (silent false-pass) converted to fallback_gate with the expr kept for interactive evaluation; validate-workflows now fails any check:command lacking a cmd/command arg (the false-pass class) and accepts status_field; build-codex-plugin falls back to overwrite-in-place when deletes are blocked (fixes stale mirror); validate-codex-plugin fails on missing phase-gates.md or a praxis-drive.sh/autonomous-drive/loop-contracts mirror drift.
-
validate-codex-plugin.sh now respects TMPDIR (falls back to a repo-local scratch file) instead of hardcoding /tmp — the validator no longer fails on sandboxes where /tmp is locked; CI unaffected.
-
Ledger status vocabulary enforced end-to-end (real defect: LD authored
status: pending, runner silently drained): the runner now hard-stops (exit 5) on unknown status tokens naming them with the fix; interactive-only tasks (verify: null) are skipped by the runner but surfaced at drain instead of ignored; vocabulary declared CLOSED in loop-contracts and lead-developer with the pending trap called out; tier-assignment ownership clarified (LD proposes per-task tier at authoring from agent defaults + fast-paths; dispatcher applies final +-1 at spawn and logs). Also fixed the residual--model-reasoning-effortflag-override mention in the Codex routing overlay. -
Codex telemetry parity (external review, all 7 findings verified true): pre-commit now runs apply-model-routing --check before the codex build; hooks/ packaged into the Codex plugin with a hooks manifest key (generated, not hand-edited); tap.sh is harness-aware (generic PLUGIN_ROOT, TAP_TOOL detection incl. codex, dual transcript stores ~/.claude/projects + ~/.codex/sessions, tolerant usage shapes incl. turn.completed with cached_input_tokens mapping); drive runner gains a codex-json usage parser (codex exec --json event stream) with json_output_flag/usage_parse wired in the codex harness config; fabricated
codex --agentCLI syntax replaced with documented .codex/agents/ profile behavior; validate-codex-plugin.sh enforces all of the above; codex-setup.md gains the post-update refresh checklist (reinstall, setup-subagents with overwrite, hook trust, drive token verification). -
Routing-log schema drift: resolved_model is now a REQUIRED field in the routing decision template (deterministic — chosen_tier mapped through the governance harness map, never guessed); reports key on tiers so older records stay valid. Token-capture failures are now observable: the SessionEnd hook writes a token_capture_skipped breadcrumb to sessions.jsonl (transcript not found / jq missing / no transcript store) instead of silently producing nothing.
-
Drive runner discoverability: /drive (all copies) and the drive docs now explain that praxis-drive.sh ships inside the PLUGIN, with concrete resolution per install type (find ~/.claude/plugins for marketplace installs, ./scripts/ for install.sh, clone path for --plugin-dir) and a clear 'not found = plugin predates drive mode, update it' hint — previously all references used a bare relative path that only worked for file installs.
-
tap.sh no longer requires jq for SessionStart/SessionEnd: governance seeding and session logging now run without jq (degraded session id), and only tool-event parsing bails when jq is absent — a missing jq previously killed the entire hook layer silently.
-
Routing-decision logging made resilient: delivery-lead now embeds the tier decision (agent/default_tier/chosen_tier/score/reason) in every routing-*.md frontmatter as part of the routing-transparency discipline it demonstrably follows, with the model-routing.jsonl append folded into the same step; factory-routing-report.py recovers frontmatter decisions as decided records when the JSONL is missing; session-start hook pre-creates .project/telemetry/ so appends cannot fail on a missing directory.
-
Visual review propagated to ALL harness surfaces after double-check: greenfield-saas's inline review cluster (visual_review step + FE branch screenshots + frontend-design skill), Codex praxis-slice command skill, /slice command in all four copies, autonomous-drive drain step, definition-of-done (now nine gates incl. visual review), using-praxis slice chain, output-skill-map telemetry patterns, and screenshot-capture duty in frontend/mobile developer agents. Found and fixed real drift: .claude/commands/{slice,release}.md had fallen behind the canonical commands/ copies — now synced, and CI gains a command-copy drift check so it cannot recur. Brownfield-enhancement and modernization inherit visual review via the implementation-slice sub-workflow.
-
Cleared remaining line-budget warnings: Codex adaptive-model-routing overlay slimmed 369 -> 298 (examples/tables to references/), using-praxis 330 -> 299 (gate-topology and agent-mapping tables to references/); validate-skills.sh now counts
capability: commandadapter skills separately from the 70-90 knowledge-skill health band. -
Delegation-chain contradiction resolved: canonical two-tier model is now unambiguous — Lead Developer (not Delivery Lead) dispatches specialists per the ledger DAG and validates integration; Delivery Lead resumes at review gates. Harness fallback documented for environments that cannot nest agent spawns. Parallelism rule made explicit everywhere (delivery-lead, lead-developer, implementation-slice.yaml, loop-contracts, Codex praxis-slice): dependencies are on contract artifacts, not on sibling implementations — FE/test start when the contract lands.
-
Drive runner stop summary no longer over-counts iterations by one; scenario operational playbook added at docs/scenarios.md; README value prop, badges, and counts brought fully current; PLAYBOOK/quickstart counts and command lists synced (11 commands incl. /drive).
-
Second external review (8 findings): restored executable bits on all scripts/hooks (now CI-checked); unified the last stale routing-log path in
using-praxis; fixedinstall.shCursor rule filename; added the 3 missing Gemini command TOMLs (review,refine-idea,factory-record— Gemini now has all 10);using-praxisrouting tree/table now covers/refine-idea,/review,/factory-recordand describes Markdown commands;/startcounts corrected and now auto-routes to the next phase instead of prompting; CI now rebuilds and freshness-checks the Codex package, verifies exec bits, telemetry-path consistency, and installer path references; gate count (11) now derived fromgovernance.yamlbybuild-registry.pyand corrected in both manifests.
Changed
-
External-review fixes:
.claude/commands/now carries all 10 Markdown commands andinstall.sh/INSTALLATION.mddescribe the.mdcommand format; routing telemetry unified on.project/telemetry/model-routing.jsonl;ideation-refinement-loopartifact state made explicit (loop_state.current_artifact/previous_artifactwith astate_updatestep); Codexadaptive-model-routingoverlay aligned with capability tiers (6 high / 10 medium / 1 low, generated — not hand-edited); added Codexpraxis-refine-ideacommand skill;validate-codex-plugin.shnow requiresmobile-developer;build-registry.pyalso maintains slash-command counts and README/install.sh count phrases; trailing whitespace cleaned. -
Library-wide progressive-disclosure pass: every SKILL.md now <=300 lines; embedded templates, worked examples, and long code blocks moved to per-skill
references/files (19 skills slimmed this round). -
Reliability-cluster ownership boundaries clarified:
resilience-patterns(in-process fault handling),distributed-systems-patterns(cross-service coordination; now owns outbox/saga),reliability-dr(availability architecture),chaos-engineering(verification practice). -
Skill slimming — trimmed several SKILL.md bundles to reduce redundancy and
keep the library under its own bloat thresholds (see PLAYBOOK.md §10,
"library is starting to feel bloated"). -
README.mdandPLAYBOOK.mdupdated to describe capability-tier routing in place
of the previous Opus/Sonnet-hardcoded language, and to be explicit that YAML
workflows are declarative specs interpreted bydelivery-lead, not a deterministic
execution engine. -
scripts/build-codex-plugin.sh— generated Codex package README now warns
explicitly that the generated output is not the place to make edits.
0.1.0 — initial library
The first public release of Praxis: a tool-portable AI-delivery platform — skills,
role agents, workflows, and governance gates for end-to-end software delivery with
AI coding agents.
Added
- Role-agent library covering delivery lead, product/discovery, architecture
(+ architecture challenger), UX, backend/frontend/data/ML specialists, code
review, security review, QA, tech writing, platform/SRE, and system-steward
roles. - SKILL.md library spanning foundation, lifecycle, discovery, architecture, UX,
stack packs, quality + security, build + deploy, ops, data, ML, agentic-AI,
and maintenance disciplines — each with an anti-rationalization table and a
verification checklist. - Named workflow compositions:
greenfield-api-service,greenfield-saas,
brownfield-enhancement,implementation-slice,production-release. - Governance gate set (
governance/governance.yaml) with evidence packs and an
approver matrix, includingrequirements_freeze,architecture_sign_off,
production_go_live,responsible_ai_review, andsteward_promotion. - Adaptive model-routing skill (5-signal scoring rubric).
- Telemetry stack:
hooks/tap.shPostToolUse tap +factory-record.sh+
factory-aging.sh+factory-frequency.sh. - Multi-tool install paths: Claude Code plugin-dir, Codex plugin marketplace,
file-based install for 8 supported AI coding tools. - Six-type project memory taxonomy under
.project/. - Cross-cutting reference library plus
references/MISSING-INVENTORY.mdtracking
the remaining backlog.