Skip to content
Back to skills

Ceo Loop

ASecurity

CEO Decision Loop — the ORBIT execution protocol (OBSERVE → REASON → BUILD → INSPECT → TURN) for one iteration of NXTG-Forge autonomous product governance. Preloaded into the nxtg-ceo-loop agent and started by the /forge:ceo-loop command; the ceo-loop-stop.sh Stop hook re-invokes it each iteration until the queue empties or limits hit. Use when running or resuming a CEO-LOOP: classify pending decisions by depth, apply the impact×reversibility matrix, write the append-only decision journal + p...

  • 5 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 6, 2026
ai-agentspythonrustgobashsqlgitapi

Works with

  • api

Security analysis

A100/100

Scanned September 6, 2026

npx -y skills add nxtg-ai/forge-plugin --skill ceo-loop --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ceo Loop?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ceo Loop
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nxtg-ai-ceo-loop/badge)](https://www.skillsdirectory.com/skills/nxtg-ai-ceo-loop)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ceo-loop
description: >
  CEO Decision Loop — the ORBIT execution protocol (OBSERVE → REASON → BUILD → INSPECT → TURN) for
  one iteration of NXTG-Forge autonomous product governance. Preloaded into the nxtg-ceo-loop agent and
  started by the /forge:ceo-loop command; the ceo-loop-stop.sh Stop hook re-invokes it each iteration
  until the queue empties or limits hit. Use when running or resuming a CEO-LOOP: classify pending
  decisions by depth, apply the impact×reversibility matrix, write the append-only decision journal +
  progress file, run retrograde verification, update trust calibration, and decide continue-or-stop.
disable-model-invocation: true
allowed-tools: Read, Write, Edit, Grep, Glob, Bash, Task, TodoWrite
---

# CEO Decision Loop — ORBIT Protocol

## Overview

The CEO-LOOP ORBIT model turns the CEO agent from a single-pass decision oracle into a **continuous governance engine**. Each invocation of this skill is one ORBIT iteration. The Stop hook (`ceo-loop-stop.sh`) re-invokes this skill after each iteration until the queue is empty or limits are reached.

**Five contributions ORBIT adds to CEO-LOOP:**
1. **Actual loop mechanism** — Stop hook + state file, not pseudocode
2. **Cross-context continuity** — progress file bridges compaction
3. **Iteration tracking + retrograde** — was the last decision correct?
4. **Adaptive depth** — ESLint fix in 30s, architecture in 15 min with Agent Teams
5. **Trust calibration** — accuracy tracked, demotion alert surfaces to human

---

## State Files (all in `$PROJECT_ROOT/.claude/`)

These are written and read by the loop. **Never modify manually during an active loop.**

### `ceo-loop-state.json` — Hook state
```json
{
  "active": true,
  "iteration": 7,
  "max_iterations": 20,
  "time_limit_minutes": 30,
  "started_at": "2026-03-08T10:00:00Z",
  "trust_level": "standard",
  "depth_escalation_counter": 0,
  "correct_decisions": 47,
  "incorrect_decisions": 2
}
```
- `active`: Stop hook checks this. If false, hook is a no-op.
- `iteration`: Current iteration number. Hook increments this before re-feed.
- `depth_escalation_counter`: How many consecutive trivial-only iterations. At 3, go proactive.
- `trust_level`: `"standard"` | `"elevated"` | `"demoted"`. Demoted = escalate more.

### `ceo-loop-decisions.jsonl` — Decision journal (append-only)
```json
{
  "id": "iter-7-1",
  "iteration": 7,
  "ts": "2026-03-08T10:15:00Z",
  "tier": "auto_approve",
  "depth": "trivial",
  "category": "quality",
  "input": "Add ESLint auto-fix to CI pipeline",
  "decision": "APPROVED",
  "reason": "Code quality improvements are always welcome. Low risk, high alignment.",
  "next_action": "Commit and move to next task.",
  "verification": "PENDING",
  "retrograde": { "previous_id": null, "outcome": "N/A" },
  "confidence": 0.98
}
```
**Tier values**: `auto_approve` | `quick_review` | `deep_think` | `escalate`
**Depth values**: `trivial` | `light` | `medium` | `heavy`
**Category values**: `feature` | `architecture` | `quality` | `scope` | `deploy`
**Decision values**: `APPROVED` | `NEEDS_REVIEW` | `REJECTED`
**Verification values**: `CONFIRMED` | `FAILED` | `PENDING`
**Retrograde outcome values**: `CORRECT` | `INCORRECT` | `PENDING` | `N/A`

### `ceo-loop-progress.md` — Human-readable iteration log
Updated by CEO-LOOP at the end of each INSPECT phase:
```markdown
# CEO-LOOP Progress — Iteration 7 of 20

**Started**: 2026-03-08T10:00:00Z | **Current**: 2026-03-08T10:15:00Z
**Trust level**: standard | **Accuracy**: 47/49 = 95.9%

## Last Iteration Summary
- Processed 3 trivial decisions in batch (all APPROVED)
- Deep focus: ESLint auto-fix architecture (APPROVED, reason: ...)
- Retrograde check: iter-6 decisions all CONFIRMED correct

## Queue Status
- Pending: 2 decisions remaining
- Next depth target: light (1 pending light item)

## Active since: 2026-03-08T10:00:00Z | Iterations: 7/20
```

### `ceo-decisions-pending.json` — Input queue (optional)
Agents write here to submit decisions for review:
```json
[
  {
    "id": "req-001",
    "submitted_at": "2026-03-08T10:01:00Z",
    "requestor": "forge:builder",
    "category": "architecture",
    "title": "WebSocket vs polling for agent communication",
    "description": "Should we implement WebSocket-based real-time agent communication or keep polling?",
    "impact": "medium",
    "reversible": true,
    "context": "Current polling adds 2-3s latency. WebSocket would require server changes."
  }
]
```
If this file is absent, CEO-LOOP does a proactive scan instead (see OBSERVE phase).

---

## Gotchas

Real failure modes of the loop mechanism (`hooks/scripts/ceo-loop-stop.sh` + the `nxtg-ceo-loop` agent). Read before running.

1. **State is keyed to the current working directory, not a fixed project.** The Stop hook sets `PROJECT_ROOT="$(pwd)"` and looks for `.claude/ceo-loop-state.json` under it (Guard 1). If the loop is running from a different CWD than where the state file was written, the hook silently exits 0 — the loop dies with **no error and no re-feed**. Always run from the same project root where `/forge:ceo-loop` wrote the state.

2. **No `jq` → the loop dies silently.** Guard 2 exits 0 if `jq` is not on PATH — no warning. Independently, the time-limit check needs `python3`; if it is missing, `ELAPSED=0` and the **time limit never fires** — only `max_iterations` or a manual `active:false` can stop the loop.

3. **You must set `active:false` yourself to stop cleanly.** The hook only auto-stops on `iteration >= max_iterations` or elapsed time. If the queue empties and TURN forgets to write `active:false`, the hook keeps re-feeding until it burns **all** remaining iterations running proactive scans. Empty queue + nothing to scan ⇒ set `active:false`.

4. **The decision journal is append-only — you cannot edit a past `verification` in place.** Retrograde outcomes (`CONFIRMED`/`FAILED`) are recorded in the **progress file** and folded into `correct_decisions`/`incorrect_decisions` in the state file. New decisions are appended fresh with `verification:"PENDING"`. Never rewrite old JSONL lines to "update" a verification.

5. **Only the top of the progress file survives to the next iteration.** The hook re-feeds `head -30 ceo-loop-progress.md` and only `tail -1` of the journal (for the retrograde line). Put queue status, next-depth target, and retrograde results **near the top** of the progress file, or the next iteration will not see them.

6. **"Budget remaining" is a fabricated estimate, not a real token gauge.** The hook computes `~(100 − iteration×4)%` — a linear guess. Phase-5 check 2 ("last 10% of token budget") is heuristic only; do not treat it as a measured context reading.

7. **Trust calibration only moves if INSPECT updates the counters.** `correct_decisions`/`incorrect_decisions` in the state file are the sole inputs to `trust_level` and the accuracy line the hook injects. If a retrograde check does not increment them, trust never changes and the injected accuracy line stays blank.

8. **Inside the `nxtg-ceo-loop` agent there is no Bash tool.** That agent's allowlist is `Read, Grep, Glob, TodoWrite, Task, Write, Edit` — no Bash. When this skill runs under that agent, the `cat`/`jq`/`git`/`grep -r` snippets below **will not execute**; read state files with `Read` and scan with `Grep`/`Glob` instead. The Bash snippets apply when the loop is driven directly by the `/forge:ceo-loop` command (whose `allowed-tools` does grant Bash).

---

## ORBIT Execution Protocol

### Phase 1 — OBSERVE

**Read in this order:**

1. **State file**: `cat .claude/ceo-loop-state.json`
   - What iteration is this? What limits remain?
   - What is the current trust level?
   - Has depth escalation counter hit 3? (→ proactive mode)

2. **Progress file**: `cat .claude/ceo-loop-progress.md`
   - What was done last iteration?
   - What is the retrograde status of last iteration's decisions?
   - What is the current queue status?

3. **Decision queue**:
   - If `.claude/ceo-decisions-pending.json` exists: load and classify all pending items
   - If absent or empty: **proactive mode** — scan for governance work:
     ```bash
     # Check test coverage drift
     cat .claude/governance.json 2>/dev/null | jq '.quality_gates'
     # Check uncommitted decisions in code (TODO: CEO-APPROVE comments)
     grep -r "CEO-APPROVE\|CEO-REVIEW" src/ --include="*.ts" -l 2>/dev/null | head -10
     # Check git status for pending work
     git status --short | head -20
     ```

4. **Last-iteration retrograde**: Check the last 3 entries in `ceo-loop-decisions.jsonl` where `verification == "PENDING"`. For each, determine if the agent implemented the decision:
   ```bash
   # Check recent commits match expected next_action
   git log --oneline -5
   # Check task state if forge-orchestrator is active
   cat .forge/state.json 2>/dev/null | jq '.tasks[-5:]'
   ```
   Update verification in progress file (don't rewrite the JSONL — note in progress file).

**Classify each pending decision:**
| Depth | Time budget | Criteria |
|-------|------------|---------|
| trivial | < 30s | Linting, docs, test coverage, formatting |
| light | 1-3 min | New feature aligned with vision, API addition |
| medium | 5-15 min | Architecture choice, API contract change |
| heavy | 15-30 min | Major pivot, production gate, feature removal |

---

### Phase 2 — REASON

**Precedent retrieval**: Before deciding, search the decision journal for the 3 most similar past decisions:
```bash
# Find recent decisions in the same category
tail -50 .claude/ceo-loop-decisions.jsonl 2>/dev/null | grep '"category":"architecture"'
```
Apply them as few-shot examples. Avoid repeating decisions that had `retrograde.outcome == "INCORRECT"`.

**Depth selection strategy:**
- Process ALL trivial items in batch (fast path, output decision structs sequentially)
- Select ONE light/medium/heavy item as the "deep focus" for this iteration
- Do NOT attempt all heavy items — the loop will return to them next iteration
- If all items are trivial for 3+ consecutive iterations → activate proactive mode

**Apply the CEO-LOOP decision matrix:**
| Impact | Reversible | → |
|--------|-----------|---|
| Low | Yes | auto_approve |
| Low | No | quick_review |
| Medium | Yes | quick_review |
| Medium | No | deep_think |
| High | Yes | quick_review |
| High | No | deep_think or escalate |

**For medium/heavy items — plan before deciding:**
State the alternatives, risks, reversibility, and vision alignment BEFORE outputting the decision struct. Externalise the reasoning.

---

### Phase 3 — BUILD (Execute decisions, mode-aware)

**Batch mode** (trivial items): Output decision structs in sequence using the CEO-LOOP format:
```
[CEO-LOOP] Decision on: <item title>
├─ Iteration: {N} | Depth: trivial | Category: quality
├─ Impact: Low | Risk: Low | Vision Alignment: 95/100
├─ Decision: APPROVED
├─ Reason: <brief>
└─ Next Action: <what agent should do>
```
Append each to the decision journal (JSONL format, one per line).

**Deep mode** (selected light/medium/heavy item):

- **light**: Decide with full reasoning chain logged. One Agent Team optional.
- **medium**: Research before deciding. Spawn `forge:detective` or `forge:planner` to gather context:
  ```
  Spawn forge:detective: "Gather context on [decision topic]: check codebase state,
  relevant files, test coverage, and technical constraints. Report back in 3 minutes."
  ```
  Then decide with that context.
- **heavy**: Full Agent Team:
  - `forge:detective` → gather context, identify risks
  - `forge:planner` → draft architecture recommendation
  - `forge:guardian` → check vision alignment and quality gates
  - CEO-LOOP synthesises all inputs and issues final decision

---

### Phase 4 — INSPECT

Three checks per iteration:

**1. Action verification** — For the deep-focus decision: did the agent receive and act on it?
- Check git log for expected changes
- Check `.forge/state.json` task updates
- Check if TodoWrite tasks were created
- Record the verification result in the **progress file** (the journal is append-only — do not edit past JSONL lines)

**2. Decision retrograde** — For decisions from 1-2 iterations ago with `verification == "PENDING"`:
- Did the agent's implementation align with what was approved?
- Did it pass tests? (`git log` + CI status if available)
- If INCORRECT: log it, update trust calibration, note what should have been different

**3. Trust calibration update**:
```
accuracy = correct_decisions / (correct_decisions + incorrect_decisions)
```
- accuracy > 90%: trust_level = "elevated" (after 20+ decisions)
- accuracy < 80% (last 20 decisions): trust_level = "demoted" → escalate more items
- accuracy < 60% (last 10 decisions): surface to human NOW — output warning

**4. Write progress file** — Update `.claude/ceo-loop-progress.md` with:
- What decisions were made this iteration
- Retrograde results
- Queue status (remaining items)
- Current accuracy

**5. Write decision journal** — Append each decision as a JSONL line to `.claude/ceo-loop-decisions.jsonl`. One entry per decision. Do NOT overwrite — always append.

---

### Phase 5 — TURN

Evaluate whether to continue. **The Stop hook handles the actual looping mechanism** — this phase updates the state file so the hook can make the right TURN decision.

**Check sequence:**
1. Is the decision queue empty (and proactive scan found nothing)? → Set `active: false` in state file. Write session summary to progress file. Exit.
2. Are we in the last 10% of token budget (estimated)? → Set `active: false`. Batch-only exit.
3. Has `max_iterations` been reached? → Set `active: false`. Write summary.
4. Has `time_limit_minutes` elapsed since `started_at`? → Set `active: false`. Write summary.
5. All clear → Update state file (the Stop hook will increment iteration and re-feed).

**Depth escalation rule**: If `depth_escalation_counter >= 3` and queue is empty → do proactive governance scan before marking done:
- Check vision alignment of last 5 shipped features
- Review test coverage against quality gates
- Check for stale decisions in the journal (`verification == "PENDING"` for > 2 iterations)

**Write state file update** at end of TURN:
```bash
# Update state file — only write if should continue
jq '.depth_escalation_counter += 1' .claude/ceo-loop-state.json > .claude/ceo-loop-state.json.tmp
mv .claude/ceo-loop-state.json.tmp .claude/ceo-loop-state.json
```
If stopping: set `active: false`.

---

## Worked Example — One Iteration

Queue (`ceo-decisions-pending.json`) holds 3 items: two trivial (add an ESLint rule, fix a README typo) and one medium (SQLite vs Postgres for state storage).

- **OBSERVE** — state shows iteration 7/20, trust `standard`, 47/49 correct. Progress file's last entry: iter-6 decisions all `CONFIRMED`. Load the 3 pending items → classify as 2 trivial, 1 medium.
- **REASON** — grep the journal for `"category":"architecture"` precedent → find iter-3 "chose SQLite, CONFIRMED". Batch the 2 trivials (Low impact, reversible → `auto_approve`). Pick the SQLite/Postgres item as the single deep focus.
- **BUILD** — emit two `auto_approve` structs for the trivials; spawn `forge:detective` to report current scale + infra constraints; decide SQLite (reversible, single-user), tier `quick_review`. Append all three as JSONL lines with `verification:"PENDING"`.
- **INSPECT** — verify iter-5's deep decision landed: `git log` shows the expected commit → mark it `CONFIRMED` in the progress file, bump `correct_decisions` to 48 in the state file. Rewrite the progress file with `queue: 0 remaining` **near the top** (gotcha 5).
- **TURN** — queue empty; proactive scan finds no drift → set `active:false`, write the session summary. On the next Stop the hook sees `active:false` (Guard 3) and lets the session end.

---

## Trust Calibration Rules

| Condition | Trust Level | Effect |
|-----------|-------------|--------|
| < 20 decisions | standard | Normal escalation thresholds |
| ≥ 20 decisions, accuracy > 90% | elevated | Fewer escalations, auto-approve more |
| ≥ 20 decisions, accuracy 80-90% | standard | Normal |
| ≥ 20 decisions, accuracy < 80% | demoted | Escalate medium → escalate tier |
| ≥ 10 decisions, accuracy < 60% | **ALERT** | Surface to human immediately |

When trust is demoted, output at start of next REASON phase:
```
⚠️ TRUST CALIBRATION ALERT: Decision accuracy at {X}% (last 20 decisions).
Elevated caution mode active. Escalating medium-tier decisions to human review.
```

---

## Progress File Template

Use this structure when writing `.claude/ceo-loop-progress.md`:

```markdown
# CEO-LOOP Progress — Iteration {N} of {max}

**Started**: {started_at} | **Updated**: {current_time}
**Trust level**: {trust_level} | **Accuracy**: {correct}/{total} = {pct}%
**Depth escalation counter**: {depth_escalation_counter}

## Iteration {N} Summary
- Trivial decisions (batch): {count} — all APPROVED / {N} REJECTED
- Deep focus: {title} ({depth}) — {APPROVED|REJECTED|NEEDS_REVIEW}
  Reason: {reason}
- Retrograde check: {results}

## Queue Status
- Remaining pending decisions: {count}
- Next depth target: {trivial|light|medium|heavy}
- Estimated iterations to completion: {estimate}

## Session Statistics
- Total decisions this session: {total}
- Auto-approved (trivial): {count}
- Deep decisions: {count}
- Escalated to human: {count}
- Incorrect (retrograde): {count}
```

---

## When the Loop Finishes

Output a session summary in the CEO-LOOP decision format, then write it to the progress file:
```
[CEO-LOOP] Session Complete — ORBIT Loop Finished

Iterations: {N} of {max_iterations}
Duration: {elapsed} minutes
Decisions made: {total}
  └─ Auto-approved: {count} | Deep: {count} | Escalated: {count}
Decision accuracy: {pct}% ({correct}/{total with retrograde})
Queue status: EMPTY / {N} remaining (time limit reached)

Vision alignment check: {all decisions aligned | N misaligned — see journal}

Next session: Re-run /forge:ceo-loop when decisions accumulate.
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…