Environment Adoption — Centralized Capability Registry
Overview
Single source of truth for tool detection, version tracking, and capability routing. Two-tier state model: persistent inventory (what is installed) and volatile session state (runtime connectivity, auth). Replaces scattered inline probing across forge, codex-orchestration, and other skills.
When to Use
- Session start — probe environment, report tier
- Before delegating to Codex/agy — check
tools.codex.installed / capabilities.agy_analyst
- When a skill needs to branch on tool availability — use
get subcommand
- After installing a new tool — run
probe.sh check --force to update inventory
When NOT to Use
- Do not re-probe on every skill invocation (read the manifest instead)
- Do not use for Codex session management (use
codex-orchestration)
Operations
| Operation |
Command |
Purpose |
| check |
bash ~/.claude/skills/env-adoption/scripts/probe.sh check |
Probe tools, write inventory + session state |
| get |
bash ~/.claude/skills/env-adoption/scripts/probe.sh get <path> |
Read a value from inventory or session state |
| context |
bash ~/.claude/skills/env-adoption/scripts/probe.sh context |
Live Q3 — main-loop | child-session | non-claude-host[:<id>]. Pure env eval, NEVER cached. See references/context-detection.md |
| setup |
bash ~/.claude/skills/env-adoption/scripts/probe.sh setup |
Interactive guided install for missing tools |
check flags
| Flag |
Effect |
--inventory-only |
Skip session state (connectivity checks) |
--force |
Re-probe even if inventory is fresh (<24h) |
--silent |
No stdout, just write state files |
--json |
Output combined inventory + session state as JSON |
get paths
# Inventory (persistent)
probe.sh get tools.codex.installed # true/false
probe.sh get tools.codex.version # "0.120.0" or null
probe.sh get tier # 0, 1, or 2
probe.sh get tier_label # minimal, standard, full
# Session state (volatile)
probe.sh get capabilities.triple_model # true/false
probe.sh get capabilities.codex_challenger # true/false
probe.sh get capabilities.agy_analyst # true/false
# Orchestration capabilities (S055 — workflow-adoption keystone)
probe.sh get capabilities.workflow_tool # true/false (Workflow tool surface, Q2)
probe.sh get capabilities.native_teams # true/false (experimental, env-gated)
probe.sh get capabilities.agent_spawn # true/false (Agent/subagent surface)
probe.sh get harness.workflow_tool # true/false (Q1 host capability, inventory)
Orchestration decision rule (restate verbatim in every consumer):
can_orchestrate = capabilities.<surface> AND context == main-loop.
capabilities.* alone NEVER authorizes orchestration — session files are
shared with subagents (children inherit CLAUDE_CODE_SESSION_ID), so the
probe.sh context conjunct is mandatory. probe.sh get capabilities.<name>
is the ONLY capability read API — no raw jq on inventory.json, no inline
claude --version. See references/context-detection.md.
Tier Model
| Tier |
Label |
Requirements |
What works |
| 0 |
minimal |
git + python3 |
All skills as reference, wiki agent |
| 1 |
standard |
+ gh + codex + agy |
forge/bob/alf with multi-model reviews |
| 2 |
full |
+ copilot + docker |
Everything incl. containers |
State Files
| File |
Lifecycle |
Content |
~/.claude/state/inventory.json |
Persistent, re-probed if >24h old |
Tools, versions, tier |
$XDG_RUNTIME_DIR/env-adoption/session-<id>.json |
Volatile, per-session |
Auth, MCP, capabilities |
Integration
Other skills consume the manifest instead of inline probing:
# Shell: via get subcommand
CODEX_OK=$(bash ~/.claude/skills/env-adoption/scripts/probe.sh get tools.codex.installed)
# Shell: via direct jq (faster, for hot paths)
CODEX_OK=$(jq -r '.tools.codex.installed' ~/.claude/state/inventory.json 2>/dev/null || echo false)
# Skill YAML/markdown: read ~/.claude/state/inventory.json
# Session routing: read $XDG_RUNTIME_DIR/env-adoption/session-*.json
See references/integration.md for full patterns.
Anti-Patterns
| Don't |
Why |
Do Instead |
| Make state bash-sourceable |
Shell-specific, security risk |
JSON canonical, get helper for shell |
| Single file for inventory + session |
Different lifecycles, session interference |
Two-tier: persistent + volatile |
| Probe on every skill invocation |
Performance death by 1000 probes |
Probe once, read many |
| Hard-fail when manifest missing |
Breaks fresh installs |
Auto-probe on first read, degrade gracefully |
Bypass get with hardcoded paths |
Breaks if state location changes |
Use get or read documented paths |
1---2name: env-adoption3description: Use when checking tool availability (Codex, Antigravity CLI (agy), Copilot, gh, Docker), determining environment tier, reading cached inventory or session state, setting up missing tools, or when any skill needs to know what capabilities are available in the current environment.4---56# Environment Adoption — Centralized Capability Registry78## Overview910Single source of truth for tool detection, version tracking, and capability routing. Two-tier state model: persistent inventory (what is installed) and volatile session state (runtime connectivity, auth). Replaces scattered inline probing across forge, codex-orchestration, and other skills.1112## When to Use1314- Session start — probe environment, report tier15- Before delegating to Codex/agy — check `tools.codex.installed` / `capabilities.agy_analyst`16- When a skill needs to branch on tool availability — use `get` subcommand17- After installing a new tool — run `probe.sh check --force` to update inventory1819## When NOT to Use2021- Do not re-probe on every skill invocation (read the manifest instead)22- Do not use for Codex session management (use `codex-orchestration`)2324## Operations2526| Operation | Command | Purpose |27|-----------|---------|---------|28| **check** | `bash ~/.claude/skills/env-adoption/scripts/probe.sh check` | Probe tools, write inventory + session state |29| **get** | `bash ~/.claude/skills/env-adoption/scripts/probe.sh get <path>` | Read a value from inventory or session state |30| **context** | `bash ~/.claude/skills/env-adoption/scripts/probe.sh context` | **Live Q3** — `main-loop` \| `child-session` \| `non-claude-host[:<id>]`. Pure env eval, NEVER cached. See `references/context-detection.md` |31| **setup** | `bash ~/.claude/skills/env-adoption/scripts/probe.sh setup` | Interactive guided install for missing tools |3233### check flags3435| Flag | Effect |36|------|--------|37| `--inventory-only` | Skip session state (connectivity checks) |38| `--force` | Re-probe even if inventory is fresh (<24h) |39| `--silent` | No stdout, just write state files |40| `--json` | Output combined inventory + session state as JSON |4142### get paths4344```bash45# Inventory (persistent)46probe.sh get tools.codex.installed # true/false47probe.sh get tools.codex.version # "0.120.0" or null48probe.sh get tier # 0, 1, or 249probe.sh get tier_label # minimal, standard, full5051# Session state (volatile)52probe.sh get capabilities.triple_model # true/false53probe.sh get capabilities.codex_challenger # true/false54probe.sh get capabilities.agy_analyst # true/false5556# Orchestration capabilities (S055 — workflow-adoption keystone)57probe.sh get capabilities.workflow_tool # true/false (Workflow tool surface, Q2)58probe.sh get capabilities.native_teams # true/false (experimental, env-gated)59probe.sh get capabilities.agent_spawn # true/false (Agent/subagent surface)60probe.sh get harness.workflow_tool # true/false (Q1 host capability, inventory)61```6263> **Orchestration decision rule (restate verbatim in every consumer):**64> `can_orchestrate = capabilities.<surface> AND context == main-loop`.65> `capabilities.*` alone NEVER authorizes orchestration — session files are66> shared with subagents (children inherit `CLAUDE_CODE_SESSION_ID`), so the67> `probe.sh context` conjunct is mandatory. `probe.sh get capabilities.<name>`68> is the ONLY capability read API — no raw `jq` on `inventory.json`, no inline69> `claude --version`. See `references/context-detection.md`.7071## Tier Model7273| Tier | Label | Requirements | What works |74|------|-------|-------------|------------|75| 0 | **minimal** | git + python3 | All skills as reference, wiki agent |76| 1 | **standard** | + gh + codex + agy | forge/bob/alf with multi-model reviews |77| 2 | **full** | + copilot + docker | Everything incl. containers |7879## State Files8081| File | Lifecycle | Content |82|------|-----------|---------|83| `~/.claude/state/inventory.json` | Persistent, re-probed if >24h old | Tools, versions, tier |84| `$XDG_RUNTIME_DIR/env-adoption/session-<id>.json` | Volatile, per-session | Auth, MCP, capabilities |8586## Integration8788Other skills consume the manifest instead of inline probing:8990```bash91# Shell: via get subcommand92CODEX_OK=$(bash ~/.claude/skills/env-adoption/scripts/probe.sh get tools.codex.installed)9394# Shell: via direct jq (faster, for hot paths)95CODEX_OK=$(jq -r '.tools.codex.installed' ~/.claude/state/inventory.json 2>/dev/null || echo false)9697# Skill YAML/markdown: read ~/.claude/state/inventory.json98# Session routing: read $XDG_RUNTIME_DIR/env-adoption/session-*.json99```100101See `references/integration.md` for full patterns.102103## Anti-Patterns104105| Don't | Why | Do Instead |106|-------|-----|------------|107| Make state bash-sourceable | Shell-specific, security risk | JSON canonical, `get` helper for shell |108| Single file for inventory + session | Different lifecycles, session interference | Two-tier: persistent + volatile |109| Probe on every skill invocation | Performance death by 1000 probes | Probe once, read many |110| Hard-fail when manifest missing | Breaks fresh installs | Auto-probe on first read, degrade gracefully |111| Bypass `get` with hardcoded paths | Breaks if state location changes | Use `get` or read documented paths |