agentsclimarketplace

Ooda config

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

View, modify, and validate config.json settings via slash commands.From its SKILL.md

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.

2 things 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.
  • runs commandsInstructs the agent to run 1 command, including `git revert {sha}..HEAD`.

SKILL.md

18.0 KB, ~4.7k tokens by cl100k_base, 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

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most project setup skills give in ~4.7k tokens

Counted across 1,553 of the 3,091 authors here whose files we hold, read 2026-09-06

  • Write the configuration filein 36 of 1553
  • Create the directory structurein 35 of 1553, across 33 files
  • Verify the setupin 31 of 1553, across 28 files
  • Run the setup scriptin 30 of 1553, across 29 files
  • Pre-determine the required sample sizein 29 of 1553, across 12 files
  • Check if the configuration already existsin 29 of 1553
  • Document every testin 26 of 1553, across 10 files
  • Start with a hypothesisin 26 of 1553, across 11 files
  • Ask one question at a timein 22 of 1553
  • Test a single variable per testin 21 of 1553, across 9 files
  • Read product marketing context before asking questionsin 19 of 1553, across 8 files
  • Do not peek and stop earlyin 18 of 1553, across 7 files

Said here and by no other author read

  • Validate JSON after writing
  • Stop if the HALT file exists
  • Fail fast if level is invalid
  • Require typed confirmation for level 3
  • Create empty state file if absent
  • Back up lens file before overwriting

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. 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.