Releases: jeet129/praxis
Releases · jeet129/praxis
Release list
Praxis 0.1.0
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...