| name | ralplan |
| description | Consensus planning entrypoint that auto-gates vague ultragoal requests before execution |
| argument-hint | [--interactive] [--deliberate] [--architect openai-code] [--critic openai-code] <task description> |
| level | 4 |
| source | forked from upstream ralplan skill and rebranded for GJC |
Ralplan (Consensus Planning Alias)
Ralplan is the consensus planning workflow. It triggers iterative planning with Planner, Architect, and Critic agents until consensus is reached, with RALPLAN-DR structured deliberation (short mode by default, deliberate mode for high-risk work).
Usage
/skill:ralplan "task description"
Flags
--interactive: Adds draft-review prompts and one-at-a-time reconciliation. When the final receipt resolves auto_handoff.effectiveTarget to off without degradationReason: "planning_stuck", final approval uses an ask workflow gate; a configured automatic admission is handled by step 8.
--deliberate: Forces high-risk deliberation: pre-mortem plus expanded test planning. It may also auto-enable for explicit auth/security, migration, destructive, incident, compliance/PII, or public-API-breakage risk.
--architect openai-code / --critic openai-code: Use OpenAI code for that review pass when available; otherwise note the fallback and use default GJC review.
gjc.ralplan.autoHandoff: Selects final-plan admission: off (default), ultragoal, or autoresearch. An autoresearch target admits /skill:autoresearch to continue research from the approved plan rather than implement it; it needs no availability probe. PLANNING-STUCK also resolves every target to off. Invalid settings reject the final write before any final artifact is persisted. The final receipt's ledger-backed runtime-owned auto_handoff.effectiveTarget is authoritative across state loss and run switching.
--write --stage <type> --stage_n <N> --artifact <markdown file path or markdown string>: Native writer for Planner/Architect/Critic/revision/ADR/final pending-approval markdown under .gjc/_session-{sessionid}/plans/ralplan/<run-id>/; do not edit .gjc/ directly.
Corrupt current-session state recovery
For corrupt, tampered, unreadable, or stale current-session ralplan state, run gjc state clear --force --mode ralplan scoped by --session-id, command payload, or GJC_SESSION_ID; it clears only ralplan state for that session.
Behavior
Planning/Execution Boundary
Ralplan is planning only. It may inspect context and draft plan/spec/proposal artifacts, but those remain pending approval until explicit current-turn or structured-UI execution approval, or a valid non-off final receipt's runtime-owned auto_handoff.effectiveTarget admits the existing handoff chain. Before either admission, do not mutate product source, run mutation-oriented shell, commit, push, open PRs, invoke execution skills, or delegate implementation.
Except for a terminal planning_stuck final receipt, explicitly naming ultragoal (including /skill: and gjc forms) counts as opting into execution for that skill — do not re-ask for the same consent.
Persist planning artifacts and handoffs through the ralplan CLI writer, never direct .gjc/ edits:
Direct write, edit, or ast_edit calls against .gjc/_session-{sessionid}/specs, .gjc/_session-{sessionid}/plans, .gjc/_session-{sessionid}/state, or any other .gjc/ path are forbidden unless an explicit force override is active.
gjc ralplan --write --worktree-root <repository_binding.worktreeRoot> --session-id <owner-session-id> --run-id <run-id> --stage <type> --stage_n <N> --artifact "markdown file path or markdown string"
gjc ralplan --write --worktree-root <repository_binding.worktreeRoot> --session-id <owner-session-id> --run-id <run-id> --stage <type> --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT
Use stages planner, intent, architect, critic, disposition, revision, post-interview, adr, or final; increment --stage_n each consensus pass. The writer accepts inline markdown (or JSON for disposition), an artifact path prepared outside .gjc/, or --artifact-env GJC_RALPLAN_ARTIFACT, persists stage-<NN>-<stage>.md plus index.jsonl under .gjc/_session-{sessionid}/plans/ralplan/<run-id>/, and copies final to pending-approval.md. Ralplan mutation blocking is enforced in code; use temp directories (os.tmpdir()/$TMPDIR, /tmp, /var/tmp) only for oversized scratch artifacts, never the repo or .gjc/. Staging via the write tool or a quoted-delimiter bash heredoc (cat > /tmp/plan.md <<'EOF' … EOF) into those temp roots is tolerated by the planning-phase guard.
Restricted read-only role agents (planner, architect, critic) must pass markdown through GJC_RALPLAN_ARTIFACT with --artifact-env GJC_RALPLAN_ARTIFACT; their restricted bash environment disables artifact file-path ingestion.
RECEIPT-ONLY guideline: role agents (planner, architect, and critic) persist durable outputs via gjc ralplan --write and return ONLY the receipt fields (session_id, run_id, path, sha256) plus verdict/status routing fields; include stage and stage_n when available, and never return the full persisted body.
The ralplan seed/write receipt's session_id is the immutable workflow owner session and run_id is the run identity. Include both in every Planner/Architect/Critic assignment and every parent-side revision/post-interview/ADR/final write. A role subagent's own session id is transcript/resume identity only and MUST NOT own ralplan state or artifacts.
The seed/write receipt's repository_binding.worktreeRoot is the canonical artifact root for the run. Whenever a writer's cwd can differ from that root — a dispatcher directory, a linked branch worktree, or a role subagent runtime cwd — propagate the seed receipt's repository_binding.worktreeRoot as --worktree-root <repository_binding.worktreeRoot> on every gjc ralplan seed/write (Planner, Architect, Critic, revision, disposition, post-interview, ADR, and final). Explicit-target mode routes all run state, stage artifacts, index.jsonl, HUD state, stuck markers, and review-budget accounting to that exact worktree regardless of the writer's cwd; it fails before any write when the target is missing, not a directory, not a git worktree root, when no seeded run state exists there, or when the target is not exactly the run's bound worktreeRoot (a linked worktree that merely shares commonDir is rejected). A relative --artifact file is still resolved from the invoking cwd. Without --worktree-root, legacy cwd-based behavior is unchanged. Never scan the filesystem for runs or merge artifact trees by hand.
This skill runs GJC planning in consensus mode for the provided arguments.
The consensus workflow:
-
Planner creates the initial plan and a compact RALPLAN-DR summary before review. Launch the Planner ONCE per run as a detached, resumable subagent (await it before the Architect) and record its returned subagent id as the run's persisted Planner id; persist the stage with gjc ralplan --write --worktree-root <repository_binding.worktreeRoot> --stage planner --stage_n 1 --artifact-env GJC_RALPLAN_ARTIFACT --planner-id <id> --planner-resumable <true|false> (see Persisted role agents below):
- After persistence, return only the receipt/path plus compact planning status; do not paste the full plan markdown back to the caller unless explicitly requested.
- Principles (3-5)
- Decision Drivers (top 3)
- Viable Options (>=2) with bounded pros/cons
- If only one viable option remains, explicit invalidation rationale for alternatives
- Deliberate mode only: pre-mortem (3 scenarios) + expanded test plan (unit/integration/e2e/observability)
-
Pre-consensus material-intent reconciliation (always before Architect/Critic): Reconcile material scope and intent before paying for consensus review. This is a bounded contract check, not a second planning loop.
a. Read the persisted Planner artifact plus relevant .gjc/_session-{sessionid}/specs/deep-interview-*.md, prior plans, and current user constraints. Extract only material unresolved decisions, assumptions that could change architecture/scope/acceptance criteria, and conflicts with an explicit prior non-goal. Cosmetic wording and implementation details that do not alter the contract are not material.
b. When material open items exist, use the ask tool one at a time, highest-impact first, with concrete options. When none exist, proceed without an empty ceremony or user prompt.
c. Persist the check with gjc ralplan --write --worktree-root <repository_binding.worktreeRoot> --stage intent --stage_n <N> --artifact-env GJC_RALPLAN_ARTIFACT --json. The artifact must list evidence inspected, resolved material decisions, retained non-goals, and either material-open-items: none or the still-open items.
d. If reconciliation changes objective, scope, non-goals, acceptance criteria, or verification obligations, resume the persisted Planner and persist a revision before review. Architect and Critic receive the reconciled Planner/revision receipt plus the intent receipt; they never review the superseded pre-reconciliation draft.
e. With --interactive, also present the reconciled draft plus Principles / Drivers / Options summary (Proceed to review / Request changes / Skip review). Without --interactive, proceed automatically once material intent is resolved.
Important: Architect and Critic MAY run in the same parallel batch only for the plan-only Critic lane after Planner persistence (review pass 1). Pass 2+ re-reviews MUST run sequentially Architect -> Critic: await Architect before issuing Critic, pass the current-pass Architect receipt/path to Critic for the rule-5 counter-review, then apply the same review join gate before consensus.
Consensus iteration cap (operator contract)
-
Default max consensus iterations: 5 (gjc.ralplan.maxIterations).
-
On cap: exit code 3, marker PLANNING-STUCK (stdout), no silent re-loop, no automatic or explicit ultragoal dispatch. Opener budget is max(index.jsonl openers, on-disk stage-*-{planner,revision}.md count) so a missing/empty/malformed ledger cannot fail open after prior openers.
-
Headless/CI: treat PLANNING-STUCK / exit 3 as terminal planning failure for orchestration/watchdogs.
-
Interactive: retain the best existing plan as a terminal planning result; residual critic findings stay as caveats.
-
Workflow settings precedence — ralplan reads all of its settings
(gjc.ralplan.maxIterations, gjc.ralplan.maxReviewPassesPerLane,
gjc.ralplan.autoHandoff) through one shared resolver in this exact order
(first valid value wins):
- project
.gjc/config.yml
- user
<agentDir>/config.yml (normally ~/.gjc/agent/config.yml, honoring
GJC_CODING_AGENT_DIR/PI_CODING_AGENT_DIR; XDG applies only to categorized data/state/cache subdirs, never the workflow config path)
- built-in default
config.yml uses the nested (schema) form — gjc: { ralplan: { maxIterations } }.
Project configuration beats user configuration. The reported source is the
canonical path of the winning file, or default. config.yml is the ONLY
settings surface: the legacy settings.json files (project and config-root)
are retired: the config-root ~/.gjc/settings.json is migrated once into the
default global agent config.yml and its source removed, while the project
.gjc/settings.json is retained for non-workflow settings (only its workflow
keys are migrated into project .gjc/config.yml and no longer read unless a migration target is absent - a migration that could not publish (e.g. a read-only .gjc) leaves the retained legacy value effective as the previously configured override until it can publish). Malformed or
invalid explicit settings in any layer exit 2
(invalid ralplan settings at <path>: <reason>) — including
, whose former silent fallback to the default is
removed.
gjc:
ralplan:
maxIterations: 3
Per-lane review budget (operator contract)
- Default: 1 Architect pass and 1 Critic pass per opener iteration.
- Override via
gjc.ralplan.maxReviewPassesPerLane (integer 1..10, registered in the public settings schema) using the workflow-settings precedence above; project overrides user.
- On overflow: exit code 3 with the
PLANNING-STUCK marker and lane-specific JSON/stderr detail.
post-interview, adr, and final are always allowed.
- Identical re-writes dedupe without stuck-signaling — including after a crash between artifact write and ledger append: the identical retry repairs the missing ledger row and returns the dedupe receipt.
- A new
--run-id starts a fresh budget.
- A rule-2-justified blocker routes through a Planner
revision opener (new iteration, fresh lane budget), never a second same-iteration review pass.
- Override example (project
.gjc/config.yml):
gjc:
ralplan:
maxIterations: 3
maxReviewPassesPerLane: 2
Follow this ralplan-internal consensus workflow for consensus mode details.
Persisted role agents (consensus loop)
The Planner, Architect, and Critic are same-session persisted subagents. Launch the Planner detached once and await it before review fan-out; Architect and Critic are also launched once per run as detached, resumable subagents in the pass-1 fan-out (parallel only for the plan-only Critic lane tied to the same Planner receipt/path/sha/stage_n). On pass 2+, resume the SAME persisted Planner with consolidated feedback and resume the SAME persisted Architect and Critic lane subagents with the mandatory re-review context bundle instead of fresh-spawning. Do NOT modify the subagent control surface; use existing subagent resume/steer controls only.
Persistence boundary: same-parent, active-session continuity only. Resumability requires retained subagent resume metadata and a persistent parent session (in-memory parent yields resumable:false), not just .gjc run-state. A terminal subagent can still resume when its retained descriptor points at a saved subagent session; after process restart, missing metadata, or failed/unavailable resume, use the fresh role/lane fallback.
Resume routing table (for every persisted role: Planner, Architect, and Critic) (per re-review pass, when resuming that role's persisted id):
| Resume outcome | Action |
|---|
running | steer/inject that role's follow-up context to the same id, then await — do NOT fresh-spawn |
queued | retain/update the queued message or await the same id — do NOT fresh-spawn just because it is queued |
context_unavailable, not_found, no_runner, resume_failed | fresh-spawn fallback for that role/lane on that pass; record the fallback metadata. not_found should only mean same-session resume metadata is unavailable, not merely that a terminal live job was evicted. |
terminal (completed/failed/cancelled) + follow-up message | resume the same id when context is available; otherwise use the fresh-spawn fallback above |
Ratchet synergy: a resumed Architect or Critic natively retains prior-pass context, but the re-review context bundle remains mandatory regardless so the fresh-spawn fallback remains fully functional and applies all five rules.
Recording persisted-role-agent metadata (audit/routing only — never claim subagent list proves resumability, since the snapshot does not expose resumable). Ride the matching optional flags on the role's normal --write for the pass:
| Role | Normal write stage | Metadata flags |
|---|
| Planner | planner or revision | `--planner-id --planner-resumable <true |
| Architect | architect | `--architect-id --architect-resumable <true |
| Critic | critic | `--critic-id --critic-resumable <true |
The existing fallback flags ride the same role's normal write: --fallback-reason <context_unavailable|not_found|no_runner|resume_failed|process_restart|missing_record>, --fallback-attempted-id <id>, --fallback-stage-n <N>, and optional --fallback-receipt-path <fresh-role-stage-artifact-path>. A planner/revision write records Planner fallback metadata, an Architect write records Architect fallback metadata, and a Critic write records Critic fallback metadata. Set the matching --*-resumable flag to true only when the parent session is provably persistent; set/record false after an observed context_unavailable; otherwise omit it (unknown). Fallback flags are recorded only when a fresh-spawn fallback actually occurs: a fallback record requires --fallback-reason together with --fallback-attempted-id and --fallback-stage-n (the failed id and the pass it failed on), while --fallback-receipt-path is optional.
Pre-Execution Gate
Execution skills (ultragoal) implement bounded work; they are not scope-discovery lanes. Vague execution requests are routed through ralplan so scope, acceptance criteria, consensus, and verification exist before code changes.
Passes the gate (specific enough for direct execution): file paths, issue/PR numbers, named symbols, explicit tests, numbered steps, acceptance criteria, error references, code blocks, or escape prefixes (force: / !). Examples: fix src/hooks/bridge.ts, implement #42, add validation to processKeywordDetector, do:\n1. Add input validation\n2. Write tests.
Gated — redirected to ralplan: fix this, build the app, improve performance, add authentication, make it better.
Gate auto-pass signals: file path, issue/PR number, camelCase/PascalCase/snake_case symbol, test runner, numbered steps, acceptance criteria, error reference, code block, or escape prefix. If it fires on a well-specified prompt, add one concrete anchor; if you intentionally bypass, prefix force: or !.
On consensus approval, choose:
- ultragoal: goal-tracked autonomous execution with verification (recommended default)
A redirected request proceeds only through the structured approval option or an explicit execution-skill choice; just do it / skip planning alone leaves the plan pending approval.