agentsclimarketplace

Ooda config

Skill mataeil/OODA-loop/skills/ooda-config

Autonomous operations layer for Claude Code — opens small reviewable PRs for your live side project and re-orients from which ones you merge or reject. HALT file + hard cost cap; you stay in command.

Install
npx -y skills add mataeil/OODA-loop --skill ooda-config

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

View, modify, and validate config.json settings via slash commands.

SKILL.md

18.0 KB, as published. Nobody here has run it

ooda-config: Configuration Management CLI

View, modify, and validate config.json without editing JSON by hand. All writes: back up to config.json.bak, then re-parse to confirm valid JSON.


Step 0: HALT + Preflight

Read config.safety.halt_file (default agent/safety/HALT). If that path exists: HALT: <reason>. ooda-config aborted. — stop.

If config.json is missing and subcommand is not validate: config.json not found. Run /ooda-setup to create one. — stop.

Parse the user's invocation to one of: show | level | domain add | domain remove | domain list | safety | validate | lens review | lens reset | action {list|approve|defer|reject|prioritize} | mode/season | rotation {show|reset} | context show | rollback {cycle} | auto-merge {on|off}. Unknown subcommand → print the Usage block and exit.


Step A — show

Print a compact summary: schema_version, project fields, domain list with weight/skill/enabled status, current progressive_complexity level and name, and key safety values (halt_file presence, confidence_threshold, max_prs_per_cycle).


Step B — level {N}

  1. Validate N is 0–3; fail fast otherwise.
  2. If N == 3, print explicit warning and require a typed confirmation phrase:
    [DANGER] Level 3 enables AUTONOMOUS mode:
      - The agent autonomously writes code and opens PRs (no prompt).
      - By DEFAULT those are DRAFT PRs you review and merge — nothing reaches
        main without your click. (You stay in command.)
      - Auto-merge is a SEPARATE opt-in: only if you ALSO run
        `/ooda-config auto-merge on` (safety.enable_auto_merge=true) will it merge
        LOW-RISK PRs by itself — non-protected paths, <= auto_merge_max_files /
        auto_merge_max_lines, tests green — with a post-merge health check that
        auto-reverts + HALTs on failure. It stays OFF until you flip it.
      - Only the HALT file or the daily cost cap can stop a running cycle.
    Type "enable autonomous" to confirm (anything else cancels):
    
    Only accept the exact phrase enable autonomous. Any other response: Cancelled.
  3. Back up config.json.
  4. Set progressive_complexity.current_level = N and implementation.enabled = (N == 3).
  5. Write + validate JSON. Print: Level changed: <old> → <N> ("<name>").

Step C — domain add {name}

Ask the user in sequence for: weight (float, default 1.0), primary_skill (must start with "/"), state_file path (default agent/state/<name>.json).

Back up config.json. Insert into config.domains:

{ "weight": <w>, "state_file": "<path>", "primary_skill": "<skill>",
  "chain": [], "branch_prefix": "auto/<name>/", "fallback": true,
  "enabled": true, "status": "active" }

(status is the field evolve's filters treat as authoritative — a domain without it would never be selected. enabled is kept for back-compat; evolve treats a domain with enabled: true and NO status field as "active".) Create empty state file if absent ({ "schema_version": "1.0.0", "domain": "<name>", "last_run": null }). Append primary_skill to safety.skill_allowlist if not already present. Write + validate. Print confirmation showing state file status and allowlist change.


Step D — domain remove {name}

Look up config.domains.<name>. Not found or already disabled → print message and exit. Back up. Set enabled: false (soft-delete — data retained). Write + validate. Print: Domain disabled: <name> (re-enable by setting enabled: true)


Step E — domain list

Print a table: name, status (enabled/disabled), weight, primary_skill, state_file. Footer: Total: <N> domains, <enabled_count> enabled. If config.domains is empty: No domains configured.


Step F — safety

Print the full safety section as a labeled key-value block: halt_file (with presence indicator), confidence_threshold, min_cycle_interval_minutes, max_prs_per_cycle, max_files_per_pr, max_lines_per_pr, first_cycle_observe_only, protected_paths list, and skill_allowlist.


Step G — validate

The full check list (1–27) is defined ONCE in "Step G — validate (extended)" below — that section is canonical. (An earlier 17-check copy of this list lived here and drifted from the extended one; never maintain two lists.)


Lens Management

Step H — lens review {domain}

Show the lens snapshot for the named domain.

  1. Look up the domain in config.domains. Not found → Domain not found: <name> and exit.
  2. Derive the lens path: agent/state/<name>/lens.json (or lens_file field if present in config).
  3. If lens.json does not exist → No lens data for <name>. Run a cycle first. and exit.
  4. Print the full contents of lens.json as a labeled key-value block, including all evidence trail entries (timestamps, sources, confidence deltas).

Step I — lens reset {domain}

Wipe the lens snapshot for the named domain, forcing a fresh start on the next cycle.

  1. Look up the domain in config.domains. Not found → Domain not found: <name> and exit.
  2. Derive the lens path the same way as Step H.
  3. If lens.json does not exist → No lens file found for <name>. Nothing to reset. and exit.
  4. Ask for confirmation: Reset lens for <name>? This clears all accumulated evidence. (yes/no) Any answer other than "yes" → Cancelled. and exit.
  5. Back up the existing lens file to lens.json.bak in the same directory before overwriting. Print: Backed up: <lens_path>.bak
  6. Overwrite lens.json with the FULL empty schema (every array evolve 5-E reads must exist — a reset file missing focus_items/learned_thresholds/ discovered_signals breaks the next lens update): { "schema_version": "1.0.0", "domain": "<name>", "reset_at": "<ISO timestamp>", "focus_items": [], "learned_thresholds": [], "discovered_signals": [], "deprecated_items": [], "evidence": [] }
  7. Print: Lens reset: <name> (evidence cleared, backup saved, next cycle starts fresh)

Action Queue Management

Step J — action list

Print pending actions from agent/state/evolve/action_queue.json:

[Action Queue] {pending_count} pending, {completed_count} completed

| # | ID     | Title                        | RICE  | Age  | Status  |
|---|--------|------------------------------|-------|------|---------|
| 1 | a15-1  | Update context.json names    | 50400 | 3.2d | pending |
| 2 | a17-1  | Pipeline FTS index           | 25200 | 3.0d | approved |

Show effective_rice (with decay applied) and age since extracted_at.


Step K — action approve {id}

Set action status to "approved". Approved items are prioritized over pending items in dev-cycle selection regardless of RICE score.

1. Find action by id in action_queue.pending
2. If not found: "Action not found: {id}" — exit
3. Set status = "approved", approved_at = now
4. Boost effective_rice by 20% (item.effective_rice *= 1.2)
5. Print "Approved: {title} (effective RICE: {new_rice})"

Step L — action defer {id} [days]

Defer an action for N days (default 7). Deferred items are excluded from dev-cycle selection until their defer period expires.

1. Find action by id
2. Set status = "deferred", deferred_until = now + N days
3. Print "Deferred: {title} until {date} ({N} days)"

Step M — action reject {id} [reason]

Move action to completed with status "rejected_by_human".

1. Find action by id
2. Move to completed array with status = "rejected_by_human", reason = reason
3. Print "Rejected: {title} — {reason or 'no reason given'}"

Step N — action prioritize {id}

Move action to top of queue by setting effective_rice above current highest.

1. Find action by id
2. Set effective_rice = max(all pending effective_rice) + 1.0
3. Re-sort pending by effective_rice descending
4. Print "Prioritized: {title} → top of queue (RICE: {new_rice})"

Step O — mode {name} (alias: season {name})

Switch season/phase mode. Mode overrides domain weights, disables selected domains for the season, and may bump signal bonuses. Changes take effect on the NEXT cycle (they are read in-memory at Step 1-A; disk config.json is updated so /ooda-status shows the current mode).

1. Read config.season_modes.modes
2. If modes not configured: "No season modes defined. Add season_modes to config.json." — exit
3. If {name} not in modes: "Unknown mode: {name}. Available: {list}" — exit
4. Back up config.json
5. Set config.season_modes.current_mode = {name}
6. Set config.season_modes.enabled = true (in case it was false)
7. Print applied overrides:
   - weight_overrides: {domain: multiplier}
   - disabled_domains: [...]
   - signal_bonuses: {signal: value}
8. Write + validate JSON
9. Print "Season mode changed: {old} → {name}"

Step O1 — season list

List all defined modes with a one-line summary.

1. Read config.season_modes.modes
2. For each mode: print "- {name}: {len(weight_overrides)} weights, {len(disabled_domains)} disabled, {len(signal_bonuses)} signal bonuses"
3. Print: "Current: {current_mode}" (or "(season_modes disabled)" if enabled=false)

Step O2 — season show

Print the full active-mode overrides applied to the current scoring table.

1. Read config.season_modes
2. If not enabled: print "Season modes disabled." — exit
3. For the current_mode:
   - Print "Mode: {current_mode}"
   - Print weight_overrides with the previous weights for comparison:
     "  service_health: config=2.0 -> mode=1.0 (effective)"
   - Print disabled_domains: "  disabled: [competitors]"
   - Print signal_bonuses: "  signal bonuses: {health_alert_bonus: +5.0}"

Step P — rotation show {domain}

Show the rotation list and current cursor for a domain.

1. Look up domain in config.domains
2. If no `rotation` field: "Domain '{name}' has no rotation list." — exit
3. Read cursor from agent/state/{domain}/rotation_cursor.json (missing = cursor 0)
4. Print the rotation list with an arrow at the current cursor position:
     [thumbnail-editor, dashboard -> stats, billing]
5. Print: "Next focus_item: {list[cursor]}"

Step P1 — rotation reset {domain}

Reset the rotation cursor to 0 for a domain.

1. Look up domain in config.domains
2. If no `rotation` field: "Domain '{name}' has no rotation list." — exit
3. Back up agent/state/{domain}/rotation_cursor.json to .bak (if present)
4. Write {"cursor": 0, "last_updated": now, "focus_item": rotation_list[0]}
5. Print: "Rotation cursor reset: {domain} -> 0 ({first_focus_item})"

Step Q — context show

Print the current active_context config + the loaded blob contents.

1. Read config.active_context
2. If no active_context.path: "No active_context configured." — exit
3. Try to read the file at that path:
   - If missing: "active_context file missing: {path}"
   - If malformed JSON: "active_context file is not valid JSON"
   - If OK: print path, mtime age, refresh_skill (if any), refresh_interval_hours,
            and the blob contents (pretty-printed, cap at 80 lines)

Step R — rollback {cycle}

Revert the repo + state to a recorded checkpoint. Checkpoints are written by evolve 4-C2 when safety.enable_rollback (or safety.enable_auto_merge) is on.

1. Read agent/state/evolve/checkpoints.json. If missing/empty:
   "No checkpoints recorded. Set safety.enable_rollback=true to enable." — exit.
2. Find the checkpoint where checkpoint.cycle == {cycle}.
   If not found: "No checkpoint for cycle {cycle}. Available: {cycles}" — exit.
3. Confirm (typed phrase): print
   "Roll back to cycle {cycle} (commit {sha})? This reverts every commit since
    then and restores state. Type 'rollback {cycle}' to confirm:"
   Accept ONLY the exact phrase; anything else: "Cancelled." — exit.
4. Re-check the HALT file.
5. Revert the repo. CAUTION: `git revert {sha}..HEAD` reverts each commit in the
   range and **fails on any merge commit in that range** (it needs `-m`, and a
   mixed range can't take a single `-m`) — leaving main HALF-reverted. This is
   safe only on a linear history; auto-merge uses `--squash` precisely to keep it
   linear. If the range may contain `--merge` merge commits, prefer `--hard`.
     # default (linear history, e.g. squash-merged auto-merges):
     git revert --no-edit {checkpoint.commit_sha}..HEAD
     git push origin HEAD
     # robust fallback / operator `--hard` (destructive — warn first):
     git reset --hard {checkpoint.commit_sha} && git push --force origin HEAD
6. Restore confidence.json and action_queue.json pending items from
   checkpoint.state_snapshot.
7. Create the HALT file: "Manual rollback to cycle {cycle} ({sha}). Delete to resume."
8. Print "Rolled back to cycle {cycle} ({sha}). HALT created — review, then
   delete the HALT file to resume."

Step S — auto-merge {on|off}

Toggle the autonomous low-risk auto-merge opt-in (config.safety.enable_auto_merge, default off). This is the SINGLE switch that lets evolve merge PRs on its own.

1. Parse on|off. Unknown → print Usage and exit.
2. Turning ON:
   - Require progressive_complexity.current_level == 3, else:
     "Auto-merge needs Level 3. Run /ooda-config level 3 first." — exit.
   - Print the gates and require a typed phrase:
     "[DANGER] Auto-merge will let the agent merge LOW-RISK PRs without your click:
        non-protected paths, <= {auto_merge_max_files} files / {auto_merge_max_lines}
        lines, tests green. A post-merge health check auto-reverts + HALTs on
        failure. Larger/protected changes still wait for you.
      Type 'enable auto-merge' to confirm:"  (accept only the exact phrase)
3. Back up config.json. Set safety.enable_auto_merge = (on ? true : false).
   Write + validate JSON.
4. Print "Auto-merge: {enabled|disabled}."  When enabled, also print the active
   low-risk thresholds so the operator sees the blast-radius bound.

Step G — validate (extended)

Run checks in order; print [PASS] or [FAIL] <reason> for each:

  1. config.json exists and is readable
  2. Parses as valid JSON
  3. schema_version field present
  4. project.name, project.locale, project.timezone all present
  5. safety.halt_file, safety.confidence_threshold, safety.max_prs_per_cycle present
  6. Value ranges: confidence_threshold in [0.0, 1.0]; max_prs_per_cycle >= 1; min_cycle_interval_minutes >= 1
  7. If present, health_check_timeout_seconds is a number in [2, 30]
  8. If present, test_timeout_seconds is a number >= 10
  9. If present, deploy_monitor_timeout_seconds is a number >= 60
  10. If present, deploy_health_wait_seconds is a number >= 5
  11. If present, deploy_workflow_inputs is a plain object (not array, not null)
  12. If present, safety.lock_timeout_minutes is a number >= 1
  13. At least one domain defined
  14. Each domain has weight, primary_skill, state_file, and status (or legacy enabled — warn [WARN] domain {name}: no status field; evolve treats enabled:true as status:"active" instead of failing)
  15. Every active domain's (status == "active", or legacy enabled: true) primary_skill is in safety.skill_allowlist
  16. progressive_complexity.current_level is 0–3
  17. No sensitive field holds a raw token (must use $ENV_VAR form)
  18. At least one domain has fallback: true (confidence gate escape)
  19. No duplicate branch_prefix values across domains
  20. signals.health_alert_bonus should be <= 2× max domain weight (monopoly risk)
  21. memory.contrarian_check_interval is in range [1, 100]
  22. memory.action_queue_decay_days > 0 and action_queue_decay_amount in (0, 1]
  23. If implementation.enabled, progressive_complexity.current_level must be 3
  24. memory.working_memory_size >= 5 (minimum for pattern detection)
  25. If saturation block present, warn_threshold < boost_threshold < halt_threshold
  26. If safety.enable_auto_merge is true, progressive_complexity.current_level must be 3
  27. If present, safety.auto_merge_max_files <= safety.max_files_per_pr and safety.auto_merge_max_lines <= safety.max_lines_per_pr (the low-risk bar must be tighter than the hard PR cap)
  28. If eval.enabled is true, eval.model is a non-empty string and eval.grade_on is a non-empty list containing none of futile/error/observe (never spend an eval call on a no-value cycle)

Final: Validation: <N> passed, <M> failed On any failure append: Run /ooda-config show to review your settings.


Usage

/ooda-config show                  Print current config summary
/ooda-config level {0-3}           Change progressive complexity level
/ooda-config domain add {name}     Add a new domain (interactive)
/ooda-config domain remove {name}  Disable a domain (soft-delete)
/ooda-config domain list           List all domains with status
/ooda-config safety                Show full safety settings
/ooda-config validate              Validate config.json structure and values
/ooda-config lens review {domain}  Show lens.json for a domain with evidence trails
/ooda-config lens reset {domain}   Wipe lens.json for a domain (start fresh)
/ooda-config action list           List pending actions with RICE and age
/ooda-config action approve {id}   Approve action for priority execution
/ooda-config action defer {id} [N] Defer action for N days (default 7)
/ooda-config action reject {id}    Reject action with optional reason
/ooda-config action prioritize {id} Move action to top of queue
/ooda-config mode {name}           Switch season/phase mode (alias: `season {name}`)
/ooda-config season list           List available season modes
/ooda-config season show           Show current mode overrides in detail
/ooda-config rotation show {d}     Show rotation list + cursor for a domain
/ooda-config rotation reset {d}    Reset rotation cursor to 0
/ooda-config context show          Show active_context path + blob contents
/ooda-config auto-merge {on|off}   Toggle low-risk autonomous merge (Level 3, opt-in)
/ooda-config rollback {cycle}      Revert repo + state to a recorded checkpoint

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.