refactor(skills): clean up bundled skill set + add environments: relevance gate (#39028)
* refactor(skills): clean up bundled skill set + add environments: relevance gate Bundled skills cleanup pass plus a new offer-time relevance gate. Removals (redundant / dead): - spotify (covered by the spotify plugin's 7 native tools) - linear (covered by `hermes mcp install linear`) - kanban-codex-lane, debugging-hermes-tui-commands - empty category markers: diagramming, gifs, inference-sh, mlops/training, mlops/vector-databases - domain (stale orphan dup of optional/research/domain-intel) Bundled -> optional: - baoyu-article-illustrator, baoyu-comic, creative-ideation, pixel-art - dspy, subagent-driven-development - minecraft-modpack-server, pokemon-player - hermes-s6-container-supervision (-> optional/devops) Consolidation: - webhook-subscriptions + native-mcp folded into the hermes-agent skill as references/webhooks.md + references/native-mcp.md with SKILL.md pointers - writing-plans merged into plan (v2.0.0); related_skills + prose refs updated New: environments: frontmatter gate (agent/skill_utils.skill_matches_environment) - Offer-time relevance filter (kanban / docker / s6), parallel to platforms:. - Wired into the 3 OFFER surfaces only (prompt_builder skills index, skills_tool.list_skills, skill_commands slash discovery). - Explicit loads (skill_view, --skills preload) intentionally BYPASS it, so load-bearing force-loads like the kanban dispatcher's `--skills kanban-worker` always resolve. Verified via E2E. - kanban-orchestrator/kanban-worker tagged environments: [kanban]; hermes-s6-container-supervision tagged environments: [s6] + platforms: [linux]. Validation: 8/8 E2E gating assertions (incl force-load invariant); 442 targeted tests green (agent, skills_tool, skill_commands, kanban worker). * docs: regenerate skill catalogs + pages for the bundled cleanup Regenerated per-skill doc pages, catalogs, and sidebar to match the skill moves/removals in the parent commit. Moved skills' pages relocate bundled -> optional (history preserved); removed skills' pages deleted; edited skills' pages refreshed (hermes-agent now embeds the webhook + native-mcp reference pointers). zh-Hans i18n mirror: stale bundled pages and catalog rows for moved/removed skills pruned (new optional translations land via the translation pipeline). * test: drop regression test for removed kanban-codex-lane skill The kanban-codex-lane skill was removed in the bundled-skills cleanup; its dedicated regression test read the now-deleted SKILL.md and failed with FileNotFoundError on CI shard 6.
This commit is contained in:
@ -22,6 +22,7 @@ from agent.skill_utils import (
|
|||||||
get_disabled_skill_names,
|
get_disabled_skill_names,
|
||||||
iter_skill_index_files,
|
iter_skill_index_files,
|
||||||
parse_frontmatter,
|
parse_frontmatter,
|
||||||
|
skill_matches_environment,
|
||||||
skill_matches_platform,
|
skill_matches_platform,
|
||||||
)
|
)
|
||||||
from utils import atomic_json_write
|
from utils import atomic_json_write
|
||||||
@ -1005,6 +1006,13 @@ def _parse_skill_file(skill_file: Path) -> tuple[bool, dict, str]:
|
|||||||
if not skill_matches_platform(frontmatter):
|
if not skill_matches_platform(frontmatter):
|
||||||
return False, frontmatter, ""
|
return False, frontmatter, ""
|
||||||
|
|
||||||
|
# Environment relevance gate (offer-time only): hide skills tagged for
|
||||||
|
# a runtime environment that isn't active (e.g. kanban-only skills for
|
||||||
|
# non-kanban users, s6-only skills outside the container). Explicit
|
||||||
|
# loads (skill_view / --skills) bypass this — see skill_matches_environment.
|
||||||
|
if not skill_matches_environment(frontmatter):
|
||||||
|
return False, frontmatter, ""
|
||||||
|
|
||||||
return True, frontmatter, extract_skill_description(frontmatter)
|
return True, frontmatter, extract_skill_description(frontmatter)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning("Failed to parse skill file %s: %s", skill_file, e)
|
logger.warning("Failed to parse skill file %s: %s", skill_file, e)
|
||||||
|
|||||||
@ -270,7 +270,7 @@ def scan_skill_commands() -> Dict[str, Dict[str, Any]]:
|
|||||||
_skill_commands_platform = _resolve_skill_commands_platform()
|
_skill_commands_platform = _resolve_skill_commands_platform()
|
||||||
_skill_commands = {}
|
_skill_commands = {}
|
||||||
try:
|
try:
|
||||||
from tools.skills_tool import SKILLS_DIR, _parse_frontmatter, skill_matches_platform, _get_disabled_skill_names
|
from tools.skills_tool import SKILLS_DIR, _parse_frontmatter, skill_matches_platform, skill_matches_environment, _get_disabled_skill_names
|
||||||
from agent.skill_utils import get_external_skills_dirs, iter_skill_index_files
|
from agent.skill_utils import get_external_skills_dirs, iter_skill_index_files
|
||||||
disabled = _get_disabled_skill_names()
|
disabled = _get_disabled_skill_names()
|
||||||
seen_names: set = set()
|
seen_names: set = set()
|
||||||
@ -291,6 +291,10 @@ def scan_skill_commands() -> Dict[str, Dict[str, Any]]:
|
|||||||
# Skip skills incompatible with the current OS platform
|
# Skip skills incompatible with the current OS platform
|
||||||
if not skill_matches_platform(frontmatter):
|
if not skill_matches_platform(frontmatter):
|
||||||
continue
|
continue
|
||||||
|
# Skip skills not relevant to the current runtime env
|
||||||
|
# (kanban/docker/s6). Offer-time only; explicit load bypasses.
|
||||||
|
if not skill_matches_environment(frontmatter):
|
||||||
|
continue
|
||||||
name = frontmatter.get('name', skill_md.parent.name)
|
name = frontmatter.get('name', skill_md.parent.name)
|
||||||
if name in seen_names:
|
if name in seen_names:
|
||||||
continue
|
continue
|
||||||
|
|||||||
@ -169,6 +169,106 @@ def skill_matches_platform(frontmatter: Dict[str, Any]) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# ── Environment matching ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
# Recognized environment tags and how each is detected. An environment tag is
|
||||||
|
# a *relevance* gate, not a hard-compatibility gate (that is what ``platforms:``
|
||||||
|
# is for). A skill tagged for an environment it isn't relevant to is hidden from
|
||||||
|
# the skills index / offer surfaces so it does not add noise for users who will
|
||||||
|
# never need it — but it can ALWAYS still be loaded explicitly (``skill_view``,
|
||||||
|
# ``--skills``), because an explicit request is explicit consent.
|
||||||
|
#
|
||||||
|
# Detection is cached for the process lifetime via ``_ENV_DETECT_CACHE``.
|
||||||
|
_KNOWN_ENVIRONMENTS = frozenset({"kanban", "docker", "s6"})
|
||||||
|
|
||||||
|
_ENV_DETECT_CACHE: Dict[str, bool] = {}
|
||||||
|
|
||||||
|
|
||||||
|
def _detect_environment(env: str) -> bool:
|
||||||
|
"""Return True when the named runtime environment is currently active.
|
||||||
|
|
||||||
|
Cached per process. Unknown env names return True (fail-open: never hide a
|
||||||
|
skill because of a tag we don't understand).
|
||||||
|
"""
|
||||||
|
if env in _ENV_DETECT_CACHE:
|
||||||
|
return _ENV_DETECT_CACHE[env]
|
||||||
|
|
||||||
|
result = True
|
||||||
|
if env == "kanban":
|
||||||
|
# Kanban is "active" either as a dispatcher-spawned worker (the
|
||||||
|
# dispatcher sets ``HERMES_KANBAN_TASK`` / ``HERMES_KANBAN_BOARD`` in the
|
||||||
|
# worker env) or as an orchestrator profile that has opted into the
|
||||||
|
# kanban toolset. Mirror the same signals the kanban tools themselves
|
||||||
|
# gate on (``tools/kanban_tools.py``) so the offer filter agrees with
|
||||||
|
# tool availability.
|
||||||
|
if os.getenv("HERMES_KANBAN_TASK") or os.getenv("HERMES_KANBAN_BOARD"):
|
||||||
|
result = True
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
from tools.kanban_tools import _profile_has_kanban_toolset
|
||||||
|
|
||||||
|
result = bool(_profile_has_kanban_toolset())
|
||||||
|
except Exception:
|
||||||
|
result = False
|
||||||
|
elif env == "docker":
|
||||||
|
try:
|
||||||
|
from hermes_constants import is_container
|
||||||
|
|
||||||
|
result = is_container()
|
||||||
|
except Exception:
|
||||||
|
result = False
|
||||||
|
elif env == "s6":
|
||||||
|
# The Hermes Docker image runs s6-overlay as PID 1 (/init). s6 plants
|
||||||
|
# its runtime scaffolding under /run/s6 and ships its admin tree under
|
||||||
|
# /package/admin/s6-overlay. Either marker means we're inside an
|
||||||
|
# s6-supervised container.
|
||||||
|
result = os.path.isdir("/run/s6") or os.path.isdir(
|
||||||
|
"/package/admin/s6-overlay"
|
||||||
|
)
|
||||||
|
|
||||||
|
_ENV_DETECT_CACHE[env] = result
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def skill_matches_environment(frontmatter: Dict[str, Any]) -> bool:
|
||||||
|
"""Return True when the skill is relevant to the current runtime environment.
|
||||||
|
|
||||||
|
Skills may declare an ``environments`` list in their YAML frontmatter::
|
||||||
|
|
||||||
|
environments: [kanban] # only relevant when kanban is active
|
||||||
|
environments: [s6] # only relevant inside the s6 Docker image
|
||||||
|
environments: [docker] # only relevant inside any container
|
||||||
|
|
||||||
|
If the field is absent or empty the skill is relevant in **all**
|
||||||
|
environments (backward-compatible default).
|
||||||
|
|
||||||
|
This is an OFFER-time filter: it controls whether a skill shows up in the
|
||||||
|
skills index / autocomplete / slash-command list. It is intentionally NOT
|
||||||
|
enforced by ``skill_view`` or ``--skills`` preloading — an explicit load is
|
||||||
|
explicit consent, and load-bearing force-loads (e.g. the kanban dispatcher
|
||||||
|
injecting ``--skills kanban-worker``) must always succeed regardless of how
|
||||||
|
the offer surfaces filter the skill.
|
||||||
|
|
||||||
|
A skill matches when ANY of its declared environments is currently active
|
||||||
|
(OR semantics, mirroring ``platforms``). Unknown env tags fail open.
|
||||||
|
"""
|
||||||
|
environments = frontmatter.get("environments")
|
||||||
|
if not environments:
|
||||||
|
return True
|
||||||
|
if not isinstance(environments, list):
|
||||||
|
environments = [environments]
|
||||||
|
for env in environments:
|
||||||
|
normalized = str(env).lower().strip()
|
||||||
|
if not normalized:
|
||||||
|
continue
|
||||||
|
if normalized not in _KNOWN_ENVIRONMENTS:
|
||||||
|
# Tag we don't understand — don't hide the skill over it.
|
||||||
|
return True
|
||||||
|
if _detect_environment(normalized):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
# ── Disabled skills ───────────────────────────────────────────────────────
|
# ── Disabled skills ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,8 @@ description: Modify, debug, or extend the s6-overlay supervision tree inside the
|
|||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
author: Hermes Agent
|
author: Hermes Agent
|
||||||
license: MIT
|
license: MIT
|
||||||
|
platforms: [linux]
|
||||||
|
environments: [s6]
|
||||||
metadata:
|
metadata:
|
||||||
hermes:
|
hermes:
|
||||||
tags: [docker, s6, supervision, gateway, profiles]
|
tags: [docker, s6, supervision, gateway, profiles]
|
||||||
@ -8,7 +8,7 @@ platforms: [linux, macos, windows]
|
|||||||
metadata:
|
metadata:
|
||||||
hermes:
|
hermes:
|
||||||
tags: [delegation, subagent, implementation, workflow, parallel]
|
tags: [delegation, subagent, implementation, workflow, parallel]
|
||||||
related_skills: [writing-plans, requesting-code-review, test-driven-development]
|
related_skills: [plan, requesting-code-review, test-driven-development]
|
||||||
---
|
---
|
||||||
|
|
||||||
# Subagent-Driven Development
|
# Subagent-Driven Development
|
||||||
@ -22,7 +22,7 @@ Execute implementation plans by dispatching fresh subagents per task with system
|
|||||||
## When to Use
|
## When to Use
|
||||||
|
|
||||||
Use this skill when:
|
Use this skill when:
|
||||||
- You have an implementation plan (from writing-plans skill or user requirements)
|
- You have an implementation plan (from the `plan` skill or user requirements)
|
||||||
- Tasks are mostly independent
|
- Tasks are mostly independent
|
||||||
- Quality and spec compliance are important
|
- Quality and spec compliance are important
|
||||||
- You want automated review between tasks
|
- You want automated review between tasks
|
||||||
@ -254,10 +254,10 @@ git add -A && git commit -m "feat: complete [feature name] implementation"
|
|||||||
|
|
||||||
## Integration with Other Skills
|
## Integration with Other Skills
|
||||||
|
|
||||||
### With writing-plans
|
### With plan
|
||||||
|
|
||||||
This skill EXECUTES plans created by the writing-plans skill:
|
This skill EXECUTES plans created by the `plan` skill:
|
||||||
1. User requirements → writing-plans → implementation plan
|
1. User requirements → plan → implementation plan
|
||||||
2. Implementation plan → subagent-driven-development → working code
|
2. Implementation plan → subagent-driven-development → working code
|
||||||
|
|
||||||
### With test-driven-development
|
### With test-driven-development
|
||||||
@ -140,6 +140,10 @@ hermes mcp test NAME Test connection
|
|||||||
hermes mcp configure NAME Toggle tool selection
|
hermes mcp configure NAME Toggle tool selection
|
||||||
```
|
```
|
||||||
|
|
||||||
|
How the built-in MCP client connects servers (stdio/HTTP), auto-discovers
|
||||||
|
their tools, and exposes them as first-class tools, plus catalog install
|
||||||
|
(`hermes mcp install <name>`): `skill_view(name="hermes-agent", file_path="references/native-mcp.md")`.
|
||||||
|
|
||||||
### Gateway (Messaging Platforms)
|
### Gateway (Messaging Platforms)
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -188,6 +192,9 @@ hermes webhook remove NAME Remove a subscription
|
|||||||
hermes webhook test NAME Send a test POST
|
hermes webhook test NAME Send a test POST
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Full setup, route config, payload templating, and event-driven agent-run
|
||||||
|
patterns: `skill_view(name="hermes-agent", file_path="references/webhooks.md")`.
|
||||||
|
|
||||||
### Profiles
|
### Profiles
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@ -1,16 +1,3 @@
|
|||||||
---
|
|
||||||
name: native-mcp
|
|
||||||
description: "MCP client: connect servers, register tools (stdio/HTTP)."
|
|
||||||
version: 1.0.0
|
|
||||||
author: Hermes Agent
|
|
||||||
license: MIT
|
|
||||||
platforms: [linux, macos, windows]
|
|
||||||
metadata:
|
|
||||||
hermes:
|
|
||||||
tags: [MCP, Tools, Integrations]
|
|
||||||
related_skills: [mcporter]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Native MCP Client
|
# Native MCP Client
|
||||||
|
|
||||||
Hermes Agent has a built-in MCP client that connects to MCP servers at startup, discovers their tools, and makes them available as first-class tools the agent can call directly. No bridge CLI needed -- tools from MCP servers appear alongside built-in tools like `terminal`, `read_file`, etc.
|
Hermes Agent has a built-in MCP client that connects to MCP servers at startup, discovers their tools, and makes them available as first-class tools the agent can call directly. No bridge CLI needed -- tools from MCP servers appear alongside built-in tools like `terminal`, `read_file`, etc.
|
||||||
@ -1,13 +1,3 @@
|
|||||||
---
|
|
||||||
name: webhook-subscriptions
|
|
||||||
description: "Webhook subscriptions: event-driven agent runs."
|
|
||||||
version: 1.1.0
|
|
||||||
platforms: [linux, macos, windows]
|
|
||||||
metadata:
|
|
||||||
hermes:
|
|
||||||
tags: [webhook, events, automation, integrations, notifications, push]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Webhook Subscriptions
|
# Webhook Subscriptions
|
||||||
|
|
||||||
Create dynamic webhook subscriptions so external services (GitHub, GitLab, Stripe, CI/CD, IoT sensors, monitoring tools) can trigger Hermes agent runs by POSTing events to a URL.
|
Create dynamic webhook subscriptions so external services (GitHub, GitLab, Stripe, CI/CD, IoT sensors, monitoring tools) can trigger Hermes agent runs by POSTing events to a URL.
|
||||||
@ -1,277 +0,0 @@
|
|||||||
---
|
|
||||||
name: kanban-codex-lane
|
|
||||||
description: Use when a Hermes Kanban worker wants to run Codex CLI as an isolated implementation lane while Hermes keeps ownership of task lifecycle, reconciliation, testing, and handoff.
|
|
||||||
version: 1.0.0
|
|
||||||
author: Hermes Agent
|
|
||||||
license: MIT
|
|
||||||
metadata:
|
|
||||||
hermes:
|
|
||||||
tags: [kanban, codex, worktrees, autonomous-agents, prediction-market-bot]
|
|
||||||
related_skills: [kanban-worker, codex, hermes-agent]
|
|
||||||
---
|
|
||||||
|
|
||||||
# Kanban Codex Lane
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This skill defines the lightweight Hermes+Codex dual-lane convention for Kanban workers. Hermes is always the task owner: it calls `kanban_show`, decides whether Codex is appropriate, creates or selects an isolated workspace, starts and monitors Codex, reconciles any diff, runs verification, and writes the final `kanban_complete` or `kanban_block` handoff. Codex is an input lane only. Codex output is not a task completion signal, not a trusted reviewer, and not allowed to write durable Kanban state directly.
|
|
||||||
|
|
||||||
The convention exists so a Hermes worker can use Codex for bounded implementation help without changing the dispatcher. The dispatcher must still spawn Hermes workers. A worker may optionally spawn Codex inside its own run, then accept, partially accept, or reject the lane after independent review and tests.
|
|
||||||
|
|
||||||
## When to Use
|
|
||||||
|
|
||||||
Use the Codex lane when all of these are true:
|
|
||||||
|
|
||||||
- The Kanban task is a coding, refactor, documentation, test, or mechanical migration task with clear acceptance criteria.
|
|
||||||
- A bounded diff can be evaluated by Hermes in one run.
|
|
||||||
- The repo can be copied or checked out in an isolated git worktree/branch.
|
|
||||||
- Hermes can run the relevant tests itself after Codex exits.
|
|
||||||
- The prompt can state all safety constraints and files that must not change.
|
|
||||||
|
|
||||||
Do not use the Codex lane when any of these are true:
|
|
||||||
|
|
||||||
- The task requires human judgment that is not already captured in the Kanban body.
|
|
||||||
- The worker lacks repo access, Codex auth, or time to reconcile the result.
|
|
||||||
- The change touches secrets, credential stores, private user data, or production order-entry systems.
|
|
||||||
- A small direct edit is faster and safer than spawning another agent.
|
|
||||||
- The task is research-only and should produce a written handoff rather than a diff.
|
|
||||||
- The worker would be tempted to mark Done based only on Codex self-report.
|
|
||||||
|
|
||||||
## Ownership Rules
|
|
||||||
|
|
||||||
1. Hermes owns the Kanban lifecycle. Codex must never call `kanban_complete`, `kanban_block`, `kanban_create`, gateway messaging, or any Hermes board CLI as a substitute for the worker.
|
|
||||||
2. Hermes owns final acceptance. Treat Codex commits/diffs as untrusted patches until reviewed and verified.
|
|
||||||
3. Hermes owns test execution. Codex may run tests, but those runs are advisory; repeat required verification from Hermes with the repo's canonical wrapper.
|
|
||||||
4. Hermes owns safety. If Codex changes safety boundaries, risk gates, live trading behavior, or secrets handling, reject the lane even if tests pass.
|
|
||||||
5. Hermes owns cleanup. Kill stuck Codex processes and remove temporary worktrees when they are no longer needed.
|
|
||||||
|
|
||||||
## Required Worktree and Branch Pattern
|
|
||||||
|
|
||||||
Never run Codex directly in a shared dirty checkout. Use a branch/worktree name that ties the lane to the Kanban task and keeps untrusted edits isolated.
|
|
||||||
|
|
||||||
Recommended variables:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
TASK_ID="${HERMES_KANBAN_TASK:-t_manual}"
|
|
||||||
REPO="/path/to/repo"
|
|
||||||
BASE="$(git -C "$REPO" rev-parse --abbrev-ref HEAD)"
|
|
||||||
SAFE_TASK="$(printf '%s' "$TASK_ID" | tr -cd '[:alnum:]_-')"
|
|
||||||
BRANCH="codex/${SAFE_TASK}/$(date -u +%Y%m%d%H%M%S)"
|
|
||||||
WORKTREE="/tmp/${SAFE_TASK}-codex-lane"
|
|
||||||
```
|
|
||||||
|
|
||||||
Create the isolated lane:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git -C "$REPO" fetch --all --prune
|
|
||||||
git -C "$REPO" worktree add -b "$BRANCH" "$WORKTREE" "$BASE"
|
|
||||||
git -C "$WORKTREE" status --short --branch
|
|
||||||
```
|
|
||||||
|
|
||||||
If the current Kanban workspace is already an isolated git worktree created for this task, you may create a sibling Codex branch inside it only if `git status --short` is clean except for intentional Hermes edits. Otherwise create a separate temporary worktree and cherry-pick or copy accepted commits back after reconciliation.
|
|
||||||
|
|
||||||
Cleanup after reconciliation:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git -C "$REPO" worktree remove "$WORKTREE"
|
|
||||||
git -C "$REPO" branch -D "$BRANCH" # only after accepted commits were copied/cherry-picked or intentionally rejected
|
|
||||||
```
|
|
||||||
|
|
||||||
Keep the worktree if it is needed as an artifact for review; record it in `codex_lane.artifacts` and mention it in the handoff.
|
|
||||||
|
|
||||||
## Codex Capability Checks
|
|
||||||
|
|
||||||
Run these before spawning Codex. Missing Codex is a normal reason to skip the lane, not a task blocker if Hermes can do the task directly.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
command -v codex
|
|
||||||
codex --version
|
|
||||||
codex features list | grep -i goals || true
|
|
||||||
```
|
|
||||||
|
|
||||||
If `/goal` support is required, enable or launch with the feature flag only after checking availability:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
codex features enable goals || true
|
|
||||||
codex --enable goals --version
|
|
||||||
```
|
|
||||||
|
|
||||||
Authentication can be via `OPENAI_API_KEY` or the Codex CLI OAuth state (often `~/.codex/auth.json`). Do not print token files. A missing `OPENAI_API_KEY` is not proof that auth is unavailable.
|
|
||||||
|
|
||||||
## Mode Selection
|
|
||||||
|
|
||||||
Use `codex exec` for bounded one-shot edits where Codex should exit on its own:
|
|
||||||
|
|
||||||
```python
|
|
||||||
terminal(
|
|
||||||
command="codex exec --full-auto '$(cat /tmp/codex_prompt.md)'",
|
|
||||||
workdir=WORKTREE,
|
|
||||||
background=True,
|
|
||||||
pty=True,
|
|
||||||
notify_on_complete=True,
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Use Codex `/goal` only for broader multi-step work that benefits from durable objective tracking. Launch interactively in a PTY/tmux session or with `codex --enable goals` if the feature is disabled by default. Keep the goal objective self-contained: repo path, task id, safety constraints, allowed scope, acceptance criteria, tests, and commit expectations.
|
|
||||||
|
|
||||||
Example `/goal` objective text to paste into Codex:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/goal Work in this repository only: <WORKTREE>. Task: <TASK_ID> <TITLE>.
|
|
||||||
Hermes owns the Kanban lifecycle; do not call Hermes kanban tools or messaging.
|
|
||||||
Create small commits on branch <BRANCH>. Follow the PMB safety constraints in the prompt.
|
|
||||||
Run the requested verification commands and report exact outputs. Stop after producing a diff and summary.
|
|
||||||
```
|
|
||||||
|
|
||||||
Do not use `--yolo` for prediction-market-bot or safety-sensitive repos. Prefer `--full-auto` inside the isolated worktree, then rely on Hermes reconciliation.
|
|
||||||
|
|
||||||
## Prompt Construction
|
|
||||||
|
|
||||||
Use the linked template at `templates/pmb-codex-lane-prompt.md` for prediction-market-bot work. For other repos, keep the same structure and replace the PMB-specific safety block with repo-specific invariants.
|
|
||||||
|
|
||||||
Every Codex prompt must include:
|
|
||||||
|
|
||||||
- `task_id`, title, and full Kanban acceptance criteria.
|
|
||||||
- Repo path, worktree path, branch name, and allowed file scope.
|
|
||||||
- Explicit statement: Hermes owns Kanban lifecycle; Codex is an input lane only.
|
|
||||||
- Required output: concise summary, files changed, commits, tests run, and known risks.
|
|
||||||
- Prohibited actions: secrets access, external messaging, board mutation, unrelated refactors, dependency upgrades unless required.
|
|
||||||
- Verification commands Codex may run and commands Hermes will run afterward.
|
|
||||||
|
|
||||||
For PMB, include these mandatory safety constraints verbatim:
|
|
||||||
|
|
||||||
```text
|
|
||||||
PMB safety constraints:
|
|
||||||
- live-SIM is paper-only; do not add or enable live REST order entry.
|
|
||||||
- Never use market orders.
|
|
||||||
- Do not add execution crossing or bypass price/risk checks.
|
|
||||||
- Do not fake passive fills, fills, PnL, order states, or reconciliation evidence.
|
|
||||||
- Do not weaken risk gates, limits, kill switches, or fail-closed behavior.
|
|
||||||
- Keep research/selection outside the C++ hot path unless explicitly requested.
|
|
||||||
- Do not read, print, write, or require secrets/tokens/credentials.
|
|
||||||
```
|
|
||||||
|
|
||||||
## Monitoring, Timeout, and Kill Behavior
|
|
||||||
|
|
||||||
Start long Codex lanes in the background with PTY and completion notification:
|
|
||||||
|
|
||||||
```python
|
|
||||||
result = terminal(
|
|
||||||
command="codex exec --full-auto '$(cat /tmp/codex_prompt.md)'",
|
|
||||||
workdir=WORKTREE,
|
|
||||||
background=True,
|
|
||||||
pty=True,
|
|
||||||
notify_on_complete=True,
|
|
||||||
)
|
|
||||||
session_id = result["session_id"]
|
|
||||||
```
|
|
||||||
|
|
||||||
Monitor without interfering:
|
|
||||||
|
|
||||||
```python
|
|
||||||
process(action="poll", session_id=session_id)
|
|
||||||
process(action="log", session_id=session_id, limit=200)
|
|
||||||
process(action="wait", session_id=session_id, timeout=300)
|
|
||||||
```
|
|
||||||
|
|
||||||
Send a Kanban heartbeat every few minutes for lanes longer than two minutes, e.g. `kanban_heartbeat(note="Codex lane running in <WORKTREE>; waiting for tests/diff")`.
|
|
||||||
|
|
||||||
Kill conditions:
|
|
||||||
|
|
||||||
- No useful output for the task's remaining runtime budget.
|
|
||||||
- Codex requests secrets, production credentials, or external permissions.
|
|
||||||
- Codex attempts to modify files outside the worktree.
|
|
||||||
- Codex starts unrelated rewrites or dependency churn.
|
|
||||||
- Codex is still running near the worker timeout and no safe partial artifact exists.
|
|
||||||
|
|
||||||
Kill command:
|
|
||||||
|
|
||||||
```python
|
|
||||||
process(action="kill", session_id=session_id)
|
|
||||||
```
|
|
||||||
|
|
||||||
After kill, inspect `git status --short`, preserve useful patches only if safe, and record `codex_lane.result: timed_out` or `rejected` with a concrete `rejected_reason`.
|
|
||||||
|
|
||||||
## Reconciliation Checklist
|
|
||||||
|
|
||||||
Hermes must perform this checklist before accepting any Codex lane result:
|
|
||||||
|
|
||||||
- [ ] `git -C <WORKTREE> status --short --branch` shows only expected files.
|
|
||||||
- [ ] `git -C <WORKTREE> diff --stat` and `git diff` were reviewed by Hermes.
|
|
||||||
- [ ] No secrets, credentials, generated caches, unrelated data, or local artifacts are included.
|
|
||||||
- [ ] PMB safety constraints were preserved: no live REST order entry, no market orders, no execution crossing, no fake passive fills/PnL, no risk-gate weakening, no secrets.
|
|
||||||
- [ ] Codex commits are small enough to cherry-pick or squash cleanly.
|
|
||||||
- [ ] Hermes ran the canonical tests itself, using `scripts/run_tests.sh` for Hermes Agent or the repo's documented wrapper for other repos.
|
|
||||||
- [ ] Any Codex-run tests are listed separately from Hermes-run tests.
|
|
||||||
- [ ] Accepted commits/diffs were applied to the Hermes-owned workspace/branch.
|
|
||||||
- [ ] Rejected or partial work has a concrete reason and artifact path if useful.
|
|
||||||
|
|
||||||
Acceptance outcomes:
|
|
||||||
|
|
||||||
- `accepted`: Codex diff/commits were reviewed, applied, and verified.
|
|
||||||
- `partial`: Some Codex work was accepted after edits or cherry-picks; rejected parts are documented.
|
|
||||||
- `rejected`: No Codex changes were accepted; reason is documented.
|
|
||||||
- `timed_out`: Codex exceeded the lane budget; useful artifacts may or may not exist.
|
|
||||||
|
|
||||||
## kanban_complete Metadata Schema
|
|
||||||
|
|
||||||
Include this object under `metadata.codex_lane` for every task where the lane was considered. If Codex was not used, set `used: false` and explain why in `rejected_reason` or a sibling `notes` field.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"codex_lane": {
|
|
||||||
"used": true,
|
|
||||||
"mode": "exec | goal | skipped",
|
|
||||||
"worktree": "/absolute/path/to/codex/worktree",
|
|
||||||
"branch": "codex/t_caa69668/20260508100000",
|
|
||||||
"command": "codex exec --full-auto ...",
|
|
||||||
"result": "accepted | rejected | partial | timed_out",
|
|
||||||
"accepted_commits": ["<sha1>", "<sha2>"],
|
|
||||||
"rejected_reason": "empty when fully accepted; otherwise concrete reason",
|
|
||||||
"tests_run": [
|
|
||||||
{"command": "scripts/run_tests.sh tests/tools/test_x.py", "exit_code": 0, "owner": "hermes"},
|
|
||||||
{"command": "codex-reported: npm test", "exit_code": 0, "owner": "codex"}
|
|
||||||
],
|
|
||||||
"artifacts": ["/absolute/path/to/log-or-patch"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For tasks that intentionally skip Codex:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"codex_lane": {
|
|
||||||
"used": false,
|
|
||||||
"mode": "skipped",
|
|
||||||
"worktree": null,
|
|
||||||
"branch": null,
|
|
||||||
"command": null,
|
|
||||||
"result": "rejected",
|
|
||||||
"accepted_commits": [],
|
|
||||||
"rejected_reason": "Direct Hermes edit was smaller and safer than spawning Codex.",
|
|
||||||
"tests_run": [],
|
|
||||||
"artifacts": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Common Pitfalls
|
|
||||||
|
|
||||||
1. Treating Codex self-report as verification. Always inspect the diff and rerun tests from Hermes.
|
|
||||||
2. Running Codex in the user's dirty main checkout. Always isolate in a worktree/branch.
|
|
||||||
3. Letting Codex own Kanban. Codex may summarize progress, but Hermes writes board state.
|
|
||||||
4. Forgetting PMB safety invariants in the prompt. Missing safety text is a lane setup failure.
|
|
||||||
5. Using `/goal` for quick edits. Prefer `codex exec` unless durable multi-step continuation is needed.
|
|
||||||
6. Killing a stuck lane without recording why. `rejected_reason` must explain the decision.
|
|
||||||
7. Accepting broad unrelated cleanup because tests pass. Reject or cherry-pick only the scoped changes.
|
|
||||||
|
|
||||||
## Verification Checklist
|
|
||||||
|
|
||||||
- [ ] Codex was skipped or started only after `command -v codex`, `codex --version`, and optional goals feature checks.
|
|
||||||
- [ ] Codex ran only in an isolated worktree/branch.
|
|
||||||
- [ ] Prompt included task scope, ownership rules, PMB safety constraints when applicable, and verification commands.
|
|
||||||
- [ ] Hermes reviewed `git diff` and safety-sensitive files.
|
|
||||||
- [ ] Hermes ran canonical tests independently.
|
|
||||||
- [ ] `kanban_complete.metadata.codex_lane` follows the schema above.
|
|
||||||
- [ ] Temporary processes and unnecessary worktrees were cleaned up.
|
|
||||||
@ -1,57 +0,0 @@
|
|||||||
# PMB Codex Lane Prompt Template
|
|
||||||
|
|
||||||
Use this template when a Hermes Kanban worker chooses to run Codex as an implementation lane for prediction-market-bot. Fill every bracketed field before launching Codex. Do not include secrets.
|
|
||||||
|
|
||||||
```text
|
|
||||||
You are Codex CLI running as an input lane for a Hermes Kanban worker.
|
|
||||||
|
|
||||||
Ownership:
|
|
||||||
- Hermes owns the Kanban task lifecycle, final review, test verification, and handoff.
|
|
||||||
- You are an implementation lane only. Do not call Hermes kanban tools, Hermes CLI board commands, messaging gateways, or external notification tools.
|
|
||||||
- Produce a scoped diff/commits and a concise report; do not mark any task complete.
|
|
||||||
|
|
||||||
Task:
|
|
||||||
- task_id: [KANBAN_TASK_ID]
|
|
||||||
- title: [KANBAN_TITLE]
|
|
||||||
- acceptance criteria:
|
|
||||||
[PASTE_ACCEPTANCE_CRITERIA]
|
|
||||||
|
|
||||||
Repository and isolation:
|
|
||||||
- repo: [REPO_PATH]
|
|
||||||
- worktree: [CODEX_WORKTREE_PATH]
|
|
||||||
- branch: [CODEX_BRANCH]
|
|
||||||
- allowed files/scope: [ALLOWED_FILES_OR_DIRECTORIES]
|
|
||||||
- forbidden files/scope: [FORBIDDEN_FILES_OR_DIRECTORIES]
|
|
||||||
|
|
||||||
PMB safety constraints:
|
|
||||||
- live-SIM is paper-only; do not add or enable live REST order entry.
|
|
||||||
- Never use market orders.
|
|
||||||
- Do not add execution crossing or bypass price/risk checks.
|
|
||||||
- Do not fake passive fills, fills, PnL, order states, or reconciliation evidence.
|
|
||||||
- Do not weaken risk gates, limits, kill switches, or fail-closed behavior.
|
|
||||||
- Keep research/selection outside the C++ hot path unless explicitly requested.
|
|
||||||
- Do not read, print, write, or require secrets/tokens/credentials.
|
|
||||||
|
|
||||||
Implementation constraints:
|
|
||||||
- Follow existing project conventions and style.
|
|
||||||
- Keep diffs small and reviewable.
|
|
||||||
- Do not perform unrelated refactors, dependency upgrades, formatting sweeps, or generated-file churn.
|
|
||||||
- If a requirement is unsafe or ambiguous, stop and report the blocker instead of guessing.
|
|
||||||
- Commit only if asked by the Hermes worker; if committing, use small commits with clear subjects.
|
|
||||||
|
|
||||||
Verification you may run:
|
|
||||||
- [COMMAND_1]
|
|
||||||
- [COMMAND_2]
|
|
||||||
|
|
||||||
Verification Hermes will rerun independently:
|
|
||||||
- [HERMES_COMMAND_1]
|
|
||||||
- [HERMES_COMMAND_2]
|
|
||||||
|
|
||||||
Required final report:
|
|
||||||
- Summary of changes.
|
|
||||||
- Files changed.
|
|
||||||
- Commit SHAs, if any.
|
|
||||||
- Tests/commands run with exit codes.
|
|
||||||
- Safety constraints checked.
|
|
||||||
- Known risks or incomplete items.
|
|
||||||
```
|
|
||||||
@ -3,6 +3,7 @@ name: kanban-orchestrator
|
|||||||
description: Decomposition playbook + anti-temptation rules for an orchestrator profile routing work through Kanban. The "don't do the work yourself" rule and the basic lifecycle are auto-injected into every kanban worker's system prompt; this skill is the deeper playbook when you're specifically playing the orchestrator role.
|
description: Decomposition playbook + anti-temptation rules for an orchestrator profile routing work through Kanban. The "don't do the work yourself" rule and the basic lifecycle are auto-injected into every kanban worker's system prompt; this skill is the deeper playbook when you're specifically playing the orchestrator role.
|
||||||
version: 3.0.0
|
version: 3.0.0
|
||||||
platforms: [linux, macos, windows]
|
platforms: [linux, macos, windows]
|
||||||
|
environments: [kanban]
|
||||||
metadata:
|
metadata:
|
||||||
hermes:
|
hermes:
|
||||||
tags: [kanban, multi-agent, orchestration, routing]
|
tags: [kanban, multi-agent, orchestration, routing]
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user