feat(skills): ctl workflow skills foundation (grill/PRD/tasks/TDD/handoff + architecture-review) - #4
Merged
Merged
Conversation
ctl-native agent workflow layer (workflow-skills-foundation-v1), adapting the useful disciplines from Matt Pocock's engineering skill workflow and the First Principles / Bayesian placement from Trellis PR #335 — without vendoring either. Skills/agents manage semantic workflow; ctl keeps managing facts, scope, evidence, gates, ledgers and honest disclosure. Added: - .agent/protocols/workflow-skills.md — canonical managed workflow-core (WORKFLOW_PROTOCOL_VERSION = 1): phase map (grill -> PRD -> tasks -> TDD -> diagnose -> architecture -> handoff), First Principles placed in grill, Bayesian in diagnose, cross-cutting invariants, L0 provenance. - Five skills x OMP + OpenCode (10 SKILL.md), each embedding the core verbatim: ctl-grill-with-spec, ctl-to-prd, ctl-to-tasks, ctl-tdd-loop, ctl-handoff. Bodies reference the real shipped CLI (ctl prd init, ctl handoff export, ctl task create --tdd / tdd-red-green interlock, ctl task create --dry-run). - infrastructure/skills.rs: embed the OMP skills in all_embedded_files (ship via ctl init), generalize the control-guard block extractor, add a workflow_skills registry + workflow_protocol_sync drift tests (core identical across canonical/OMP/OpenCode, version match, marker-corruption + platform-leak detection, OMP/OpenCode phase-body parity, no third-party vendoring, L0 docs). - NOTICE.md provenance (Matt Pocock skills, Trellis PR #335 as L0 references); control-guard routing updated (outside the managed core, both platforms); AGENTS.md + README.md honest framing (disciplines, not proofs). These are agent workflow disciplines. They do not prove correctness, do not replace gates/audits/evidence, do not create authenticated reviewer independence, and do not create L3 tamper evidence. External skills are treated as L0 reference material; ctl does not vendor them as an active control plane. Deferred follow-ups: ctl-architecture-review skill (CLI already exists), ctl-diagnose v2. Pre-existing, unrelated: `architecture check` command-surface guard is stale vs shipped prd/ralph/handoff — fixed separately. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…uard `ctl architecture check` locks the top-level CLI surface, but the expected list was never updated when `handoff`, `prd`, and `ralph` shipped — so the guard was red on HEAD. Add the three already-shipped commands to the expected set; no CLI behavior change. `ctl architecture check` now passes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…se into the workflow Follow-ups to the workflow skills foundation (workflow-skills-followups-v1). - ctl-architecture-review (OMP + OpenCode): a new workflow-foundation skill embedding the managed workflow-core verbatim. Read-only by default — it starts from `ctl architecture review` (mechanical structural checks) and adds the qualitative deepening review (shallow modules, poor locality, hypothetical adapter boundaries, duplicated task/run/lease logic, mega-module risk, ungloassaried domain terms), outputting a candidate report with no code changes. A chosen candidate becomes a NEW governed task. Registered in workflow_skills() + shipped via all_embedded_files; auto-covered by the workflow_protocol_sync drift + phase-body-parity tests. - ctl-diagnose: added a "Workflow placement" cross-link tying it to the foundation's diagnose phase (Bayesian placed here, not floating). Kept on its standalone yao-bayesian lineage and OMP-specific failure-diagnosis.md guide — deliberately NOT embedded in the shared workflow-core and NOT mirrored to OpenCode (its guide dep is OMP-only and the repo keeps OpenCode minimal). Dogfooded the TDD red->green interlock: the registry entry was added first (cargo_test FAIL: missing skill files), then the files (cargo_test PASS). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tch routing
Bring the omp subagent roster into opencode under opencode-native names and
let the primary agent self-dispatch by phase (host-side orchestration; ctl only
governs the spawns — Division of labor preserved).
- .opencode/agent/{designer,oracle}.md: two new writable subagent roles
(explore/build are opencode built-ins). designer = design/ADR/spec authoring;
oracle = falsifiable diagnosis (no fix before a red-capable loop). Each carries
a phase-tied `description` for autonomous dispatch and a behavioral prompt.
- control-guard SKILL: phase->role routing table; explore is the only read-only
role, build/designer/oracle are writable and need an active in_progress task.
- six workflow skills: per-phase "Recommended role" annotations (platform
section only — managed cores untouched).
explore stays the only read-only role, matching omp's gate classification
(verified: omp oracle is writable). Reviewed by an independent high-effort
code-review pass; 2 findings fixed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…floor Add Step 1.5 to the ctl-spec-bootstrap skill: during project analysis, derive the project-wide default gate floor and record it in .ctl/config.toml under [project].default_gates. This is the floor ctl task create applies when a task omits --gates (wired separately in task-create-gates). Selection is by what gates catch, not a fixed per-language list: - always include correctness gates (compile + test) - include real-problem lint gates (clippy) when the project already uses them - exclude auto-fixable formatting (cargo fmt --check) from the blocking floor - no applicable ctl gate templates (Node/Python/Go/Java) -> leave it empty; never invent gate IDs. A later bootstrap fills these in. For a Rust repo that lints with clippy the floor is check + test + clippy. Writing is idempotent and asks before overwriting a user-tuned floor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ctl task create no longer requires --gates. When omitted, gates are derived from [project].default_gates in .ctl/config.toml (recorded by /ctl-spec-bootstrap, the bootstrap-project-gates half of this chain). ctl task quick uses the same resolution instead of its hardcoded ["cargo_check","cargo_test"] default — there is no hardcoded floor anywhere now. When neither explicit --gates nor a project floor is present, both commands error clearly (the application layer still enforces a non-empty gate set, so a floorless project must pass --gates). Config has no general TOML reader; add a minimal, targeted parser for the [project].default_gates string array (single- and multi-line, comment-tolerant) plus unit tests. Parsed gates are still validated against the gate-template list by create_task, so a malformed entry surfaces as "unknown gate", never silent misbehavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The blanket `.ctl` write protection blocked agents from writing .ctl/config.toml, but /ctl-spec-bootstrap is supposed to record the project default gate floor there ([project].default_gates). Without a carve-out the bootstrap skill could never write the floor under governance in a self-governed repo. Add `.ctl/config.toml` alongside the existing `.ctl/workflow.md` / `.ctl/scripts` carve-outs (AI-writable control-plane config). The canonical ledger `.ctl/tasks` stays protected — guarded by the existing ctl_tasks_still_protected_after_carveout test. The live gate already allows a write when the path is in the active task's write_allow and does not re-check is_protected, so this carve-out is sufficient: a task can now scope .ctl/config.toml and write the floor. Red->green: added accept_carveout_ctl_config_toml (failed while the path was protected), then the carve-out (passes). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Policy change: the gate floor mirrors what the project already enforces, so formatting checks (cargo_fmt_check) belong in it when the project enforces formatting (CI runs fmt --check, or a fmt config ships) — they were previously excluded as auto-fixable. Update ctl-spec-bootstrap Step 1.5: the selection principle now includes formatting gates under that condition, the template table marks cargo_fmt_check "yes if the project enforces formatting", and the example floor is all four cargo gates. This repo's own floor (.ctl/config.toml, gitignored) is updated to match: check + test + clippy + fmt_check, which mirrors its CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reformat the project_gates_single_line test string that exceeded the line width — pre-existing drift committed in ebf3153 before cargo_fmt_check was a floor gate. Authorized out-of-scope edit under task floor-add-fmt-gate (ctl apply/grant) since the new fmt gate cannot pass until the tree is fmt-clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Answers the claude-subagent-dispatch research task: writing stays in the main agent because (1) .claude defines no subagent roles to route to, and (2) ctl binds a write to its task via CTL_TASK_ID, which subagents don't inherit — and it's undocumented whether subagent tool calls even reach the PreToolUse gate. Inline writes are the safe default, mirroring the Codex dispatch_mode: inline decision already recorded in .ctl/config.yaml. Recommendation: adopt read-only research dispatch now (safe); keep writes inline by default; gate any writable .claude subagent on first verifying — in a sandbox — whether subagent tool calls fire the gate. Basis is split into observed / confirmed (docs, via claude-code-guide) / open uncertainty; the blocking unknown is named, not hidden. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Agents were probing the ctl surface with --help command by command. Add a ctl-cli-reference skill: the governed task lifecycle (create → ready → start → submit → commit → gate → review → finish → archive) plus the commands and key flags for gates, reviews, apply/approval exceptions, evidence/provenance (research/uncertainty/brainstorm), inspection, and recovery — the ~80% used daily, with `ctl <cmd> --help` as the fallback for exhaustive flags. Includes the governance rules agents must know (protected paths + carve-outs, commit window, independent-actor audit, multiple_active binding, fail-closed gate). Embedded via all_embedded_files so `ctl init` ships it (OMP-canonical, like ctl-spec-bootstrap). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ctl init previously only ever set up .omp/; the .claude/ and .opencode/ integrations were hand-authored and never embedded for injection. Add platform selection: - Embed the Claude Code integration (hooks/ctl-context.py, hooks/ctl-gate.py, settings.json) and the opencode integration (ctl-gate.ts plugin, designer + oracle agent roles, README, 7-skill mirror) as compiled-in files; opencode also gets a generated package.json. The research note subagent-dispatch.md and the plugin's .test.ts are excluded (task output / dev tests). - inject_claude / inject_opencode write-if-absent (never clobber user files); inject_all (.omp) unchanged. - `ctl init --platform <claude|opencode|omp|all>` dispatches to the chosen injector(s). With no flag: prompt interactively when attached to a TTY; in a non-interactive shell the flag is required (clear error). --dry-run reports the target without writing. Tests: inject_claude/inject_opencode assert the shipped file set, the exclusions, and idempotency. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude Code had governance hooks but no ctl workflow skills. Mirror the core subset to .claude/skills/ in Claude Code format: 6 workflow-core skills (grill, to-prd, to-tasks, tdd-loop, handoff, architecture-review) + cli-reference. The managed workflow-core and the shared phase body are copied byte-identical from the OMP versions; only the integration section differs (## Claude Code Integration: PreToolUse ctl gate, CTL_TASK_ID binding, read-only subagent dispatch). Drift wiring (the .claude copies are now first-class, not silently rotting): - workflow_skills() gains 6 claude rows (marker "Claude Code Integration") - workflow_phase_body() cuts at the Claude integration heading - phase_body_is_identical_across_platforms asserts claude == omp too - claude_embedded_files() ships the 7 skills; inject_claude test → 10 files control-guard is split out (claude-control-guard-mirror) — it is coupled to the adapter registry / adapter doctor and needs its own reconciliation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the read-only subagent dispatch routing (the claude-readonly-dispatch -routing follow-up from the subagent-dispatch research) to the ctl-managed CLAUDE.md block: - dispatch read-only work (investigation, search, research, codebase Q&A) to read-only subagents (Explore, claude-code-guide) — they preserve context and cannot break scope; - keep writes inline in the main agent, which alone carries CTL_TASK_ID and routes Write/Edit/Bash through the gate. Do not dispatch edits to subagents (isolated context, no CTL_TASK_ID, gate-reachability unverified). Wired in two places, kept byte-identical so a bootstrap refresh is a no-op: - ctl-spec-bootstrap M2 (the canonical managed-block content future runs emit) - a CLAUDE.md at repo root (this repo's instance, previously absent) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the first .claude/agents/ role: ctl-oracle, a READ-ONLY diagnostician (Bayesian root-causing — falsifiable hypotheses, discriminating evidence, "where is the evidence", observed/confirmed/uncertain split). tools: Read, Grep, Glob, WebFetch — no Write/Edit/Bash. It returns a ranked diagnosis + a recommended repro/fix for the MAIN agent to apply inline. Read-only is the only safe dispatch today: a read-only role never writes, so it sidesteps the unresolved question of whether subagent tool calls reach the gate and the fact that subagents do not inherit CTL_TASK_ID. Writable roles stay deferred until sandbox-verify-subagent-gate resolves U-001. Embedded + shipped by inject_claude (now 11 files); the inject test asserts the agent is present AND that its tools line grants no Write/Edit/Bash. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…m adapter Add the control-guard entry/router skill to .claude/skills/control-guard: control-guard-core copied byte-identical from OMP (drift-checked), with a Claude-specific integration section that states the actual posture — the .claude/hooks/ctl-gate.py PreToolUse enforcement, and READ-ONLY subagent dispatch only (Explore / claude-code-guide / ctl-oracle), writes inline. Writable roles stay deferred (host gate-reachability unverified). Decouple "platform" from "adapter" so Claude can host a drift-checked control-guard without being a (non-existent) executor adapter: - PlatformSkill.adapter becomes Option<&str>; the claude row is None. - platform_skill_for matches Some(adapter), so adapter_doctor (which only iterates SUPPORTED_ADAPTERS = omp, opencode) never looks claude up, while the control-guard drift tests iterate every row and now cover claude. SUPPORTED_ADAPTERS is unchanged (its tripwire test stays green); adapter doctor output is unchanged (verified: still omp + opencode only). Embedded + shipped by inject_claude (now 12 files); .claude/hooks added to the control-guard PLATFORM_TOKENS leak-check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stop hand-mirroring the 6 workflow skills across 3 platforms. Each now has ONE source at .agent/skills/<skill>/source.md (frontmatter + shared phase body + per-platform integration sections). `ctl skills sync` composes every platform's SKILL.md from: frontmatter + a generated preamble + the canonical managed core (.agent/protocols/workflow-skills.md, wrapped) + the shared body + the platform integration. `ctl skills sync --check` re-derives and fails on any on-disk drift; the every_workflow_skill_is_in_sync_on_disk test runs it under cargo test, so CI catches a stale generated file. The core stays byte-identical to canonical and the body identical across platforms BY CONSTRUCTION (one source), so the manual copy + drift-authoring is gone (the existing drift tests remain as belt-and-suspenders and still pass). Fixes a real bug the hand-copy introduced: the .claude workflow skills' preamble said "# <skill> (OMP)" / "OMP-specific mechanics" (I had copied the .omp prefix verbatim, and the drift tests only check the core + body, not the preamble). Generation emits the correct per-platform preamble. control-guard is intentionally NOT generated here — its frontmatter is per-platform and it has no phase body; it stays hand-authored under control_guard_protocol_sync. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
neostfox
added a commit
that referenced
this pull request
Jul 26, 2026
Fold the accumulated gate-lifecycle doc drift in AGENTS.md + README.md into one refresh pass (all gate-related, same two files): - AGENTS Key Conventions #4 (gate allowlist): built-in templates are EXTENDED by project-defined [[gate]] templates in .ctl/config.toml (gh5 / issue #5); built-in ids reserved, collisions rejected at load. - AGENTS #7 (gate observe mode): out-of-scope bash file-mutating commands with statically-identifiable targets are now DENIED, not observed (best-effort classifier, gh7 / issue #7); obfuscated commands still fall through. - AGENTS + README command lists: add 'approve' (human-only ready, gh6 proposal-mode Design A). AGENTS edits are inside the TRELLIS-managed block - re-apply after trellis update. Doc-only; ctl Rust unchanged. Resolves gh5-doc-gate-list-refresh (and folds the gh6/gh7 doc drift).
neostfox
added a commit
that referenced
this pull request
Jul 26, 2026
…cript Updates the V1 cognitive-layer bullet (ctl spec fact ✅ -> 'knowledge/memory layer externalized'), the memory-carrier table (atomic facts writer is now scripts/knowledge.py fact add), marks #1/S + #2/S done, and reframes the remaining memory-system backlog (#3/#4/#5/#6) to target scripts/knowledge.py instead of the removed ctl memory / ctl spec fact commands — consistent with the decision that ctl Rust stays governance-only and the knowledge layer is workflow-side.
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
A ctl-native agent workflow skill layer on top of the existing control plane. Skills/agents manage semantic workflow; ctl keeps managing facts, scope, evidence, gates, ledgers and honest disclosure.
Three commits:
feat(skills)— workflow skills foundationfix(cli)— includehandoff/prd/ralphin thearchitecture checkcommand-surface guard (pre-existing stale list on master too)feat(skills)—ctl-architecture-reviewskill + wirectl-diagnoseinto the workflowAdded
.agent/protocols/workflow-skills.md— canonical managed workflow-core (WORKFLOW_PROTOCOL_VERSION = 1): phase map (grill → PRD → tasks → TDD → diagnose → architecture → handoff), First Principles placed in grill, Bayesian in diagnose, cross-cutting invariants, L0 provenance.ctl-grill-with-spec,ctl-to-prd,ctl-to-tasks,ctl-tdd-loop,ctl-handoff,ctl-architecture-review. Bodies reference the real shipped CLI (ctl prd init,ctl handoff export,ctl architecture review,--tdd/tdd-red-greeninterlock,--dry-run).infrastructure/skills.rs— embed OMP skills (ctl init), generalize the control-guard block extractor, add aworkflow_skills()registry +workflow_protocol_syncdrift tests: core identical across canonical/OMP/OpenCode, version match, marker-corruption + platform-leak detection, OMP/OpenCode phase-body parity, no third-party vendoring, L0 docs.NOTICE.md), control-guard routing (outside the managed core),AGENTS.md+README.mdhonest framing.ctl-diagnosegets a workflow cross-link (kept on its standalone yao-bayesian lineage, OMP-only by design).Inspiration (L0 references — adapted, not vendored)
External skill text is treated as L0 reference material; ctl does not vendor third-party skills as an active control plane.
Honesty
These are agent workflow disciplines. They do not prove correctness, do not replace gates/audits/evidence, do not create authenticated reviewer independence, and do not create L3 tamper evidence.
Deliberately not implemented
Third adapter, Web UI, authenticated principals, cryptographic signing, hash-chain ledger, Ralph/overnight loop, cross-ledger WAL/2PC, perf benchmarking, new ontology/confidence scoring. No new ctl core governance semantics.
Verification
cargo fmt --check✓,cargo clippy --all-targets -D warnings✓,cargo test425 passed,cargo run -- architecture check✓. Developed under governed ctl tasks (workflow-skills-foundation-v1,workflow-skills-followups-v1) with reviewer-labelled audits (actor=ctl-review, distinct from the implementer) and a genuinely-exercised TDD red→green interlock. (Audits are reviewer role labels, not proven independent principals.)🤖 Generated with Claude Code