AGENT.md: REQUIRED T2 frontmatter per §2.1. manifest.yaml: REQUIRED governance: block per §2.2. Register new toolkit skills. install.sh: chmod +x. skills/cto-python-toolkit/SKILL.md (v0.1): closes Python stack gap inline. References real workspace projects as exemplars: scripts/sot-precommit.py (single-file CLI), bte-mcp/server.py + bte_core.py (FastMCP server), svrnty-hermes-webui-plugin (PEP 621 + pytest.ini_options), curator/sweep.py (mode flags + dry-run + stdlib-heavy). Sandcastle prompt template + post- run quality-gate routing via PG-svrnty.lib-quality-gates. skills/cto-angular-toolkit/SKILL.md (v0.1): closes Angular stack gap inline. Anchored to adwright/adwright-console as canonical Plan B Angular reference (Angular 21.2 + signals + standalone components + inject() + gRPC-web via @protobuf-ts/grpcweb-transport + L6-svrnty.lib-cqrs-datasource). Sandcastle prompt template + DESIGN.md compliance check for UI work. CONTRACT.md §6: Python+Angular promoted from ⚪ generic → 🟡 skill-only (no more "gap" marker). Documents path to ✅ deep when cortex/ libs extract. skills/cto-agent/SKILL.md: routing table updated — Python/Angular rows now route to the toolkit skills instead of falling through to generic. CLAUDE.md: site-map footer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
186 lines
10 KiB
Markdown
186 lines
10 KiB
Markdown
---
|
|
name: cto-python-toolkit
|
|
description: "Use when the user mentions 'Python code task', 'fix bug in Python repo', 'implement feature in Python', 'refactor Python', 'pytest', 'ruff', 'mypy', 'uv', 'python-task', or the target stack identified by cto-agent is Python. Encodes Python best-practice patterns for sandcastle invocations: tooling (ruff/pytest/mypy/uv), project layout, post-run quality-gate routing. Closes the Python stack gap in cto-planb (no dedicated cortex/ Python framework lib yet — this skill provides the patterns inline, anchored to real workspace Python projects)."
|
|
metadata:
|
|
version: 0.1.0
|
|
model: qwen-local/qwen3.6-35b-a3b
|
|
hermes:
|
|
requires_toolsets: [terminal, memory_tool]
|
|
tier: T2
|
|
status: active
|
|
owner: jp
|
|
source: hand
|
|
last_reviewed: 2026-05-24
|
|
---
|
|
|
|
# CTO Python Toolkit — Sandcastle Prompt + Quality Patterns
|
|
|
|
> **Scope:** routed-to by `cto-agent` when the target repo stack is Python. Closes the Python stack gap documented in `CONTRACT.md §6` (no cortex/ Python framework lib exists; this skill provides the patterns inline). All patterns anchored to **real Python projects in this workspace** — no hypothetical examples.
|
|
|
|
## When CTO routes here
|
|
|
|
Per `skills/cto-agent/SKILL.md` per-stack routing table — Python row. Triggers:
|
|
- Target repo contains `pyproject.toml`, `setup.py`, `requirements*.txt`, or `*.py` files at root
|
|
- Task description mentions Python explicitly
|
|
- `cto-agent` analyze step detects Python as primary stack
|
|
|
|
## Reference Python projects in this workspace (study these patterns)
|
|
|
|
| Repo | Pattern shown | What to copy |
|
|
|---|---|---|
|
|
| [`scripts/sot-precommit.py`](../../../scripts/sot-precommit.py) | Single-file CLI w/ stdlib + 1 dep (pyyaml); `pathlib`-first; `subprocess.check_output` for git; `re` for parsing; type hints (`Optional[str]`); function-level docstrings | Single-file tools, git-integration scripts, validators |
|
|
| [`bte-mcp/server.py`](../../../bte-mcp/server.py) + [`bte-mcp/bte_core.py`](../../../bte-mcp/bte_core.py) | FastMCP server (`mcp.server.fastmcp`); decorator-based tool registration (`@mcp.tool()`); thin transport (server.py) + business logic (bte_core.py) split; env-driven config | New MCP servers, thin stateless proxies |
|
|
| [`svrnty-hermes-webui-plugin/`](../../../svrnty-hermes-webui-plugin/) | Modern PEP 621 pyproject; `[tool.pytest.ini_options]` w/ testpaths + python_files; setuptools packages.find; Flask-style routes (`routes/*.py`); README + CHANGELOG + CLAUDE.md per repo | Packaged libraries, web plugins, multi-route Python apps |
|
|
| [`curator/sweep.py`](../../../curator/sweep.py) | Long-running script w/ mode flags (`--validate-only`/`--index-only`/`--dry-run`); `from __future__ import annotations`; stdlib-heavy (no extra deps); subprocess to other Python scripts | Long-running tasks, idempotent sweeps, dry-run patterns |
|
|
| [`hermes-agent/`](../../../hermes-agent/) | **READ-ONLY** upstream — DO NOT modify or use as edit target. Study only as constraint reference (Hermes core API surfaces) | Reference only — never modify |
|
|
| [`cortex/L3-svrnty.agents-voice`](../../../../cortex/L3-svrnty.agents-voice), `agents-training`, `agents-trust` | Multi-package L3 agents w/ pyproject; Python-side svrnty stack reference | Agent libs, ML-adjacent agents |
|
|
|
|
When the sandcastle agent needs an exemplar, point it at the closest match above. Example sandcastle prompt fragment:
|
|
|
|
> "For project layout + pyproject + pytest config, follow `svrnty-hermes-webui-plugin/pyproject.toml` as the canonical Plan B Python pattern. For single-file CLI scripts, follow `scripts/sot-precommit.py`."
|
|
|
|
## Tooling baseline (always include in sandcastle prompt)
|
|
|
|
| Tool | Purpose | Invocation | Required? | Real example |
|
|
|---|---|---|---|---|
|
|
| **uv** | Package + venv manager | `uv sync` / `uv pip install` | Preferred (faster than pip) | bte-mcp uses pip + requirements.txt (legacy); migrate new projects to uv + pyproject |
|
|
| **ruff** | Linter + formatter | `ruff check .` / `ruff format .` | YES — fail PR if violations | Add to svrnty-hermes-webui-plugin's pyproject (currently uses default ruff config) |
|
|
| **pytest** | Test runner | `pytest` / `pytest -x` (fail-fast) | YES if tests exist | svrnty-hermes-webui-plugin has `[tool.pytest.ini_options]` block — use that shape |
|
|
| **mypy** | Static type checker | `mypy <pkg>` | If `mypy` configured in pyproject.toml | scripts/sot-precommit.py uses `Optional[str]` hints throughout — type-hint public APIs |
|
|
| **pip-audit** | Vuln scan | `pip-audit` | Recommended for dep changes | not yet in any workspace project — first task to add can be the reference |
|
|
|
|
## Project layout patterns (encode in prompt)
|
|
|
|
Two valid Plan B layouts (match the existing repo style — don't migrate without explicit task):
|
|
|
|
**Layout A — single-file CLI** (per `scripts/sot-precommit.py`):
|
|
```
|
|
<repo>/
|
|
├── tool-name.py # entry point, stdlib + ≤1 dep
|
|
├── pyproject.toml # PEP 621 if shipping; omit if just a script
|
|
└── README.md
|
|
```
|
|
|
|
**Layout B — packaged lib + routes** (per `svrnty-hermes-webui-plugin/`):
|
|
```
|
|
<repo>/
|
|
├── pyproject.toml # PEP 621 / setuptools; [tool.pytest.ini_options]
|
|
├── <pkg_name>/__init__.py # main package (flat-layout used here)
|
|
├── routes/ # if web/plugin: sub-modules per route group
|
|
│ └── *.py
|
|
├── tests/test_*.py # pytest discovery
|
|
├── CHANGELOG.md
|
|
├── CLAUDE.md # repo-local Claude context (Hermes convention)
|
|
└── README.md
|
|
```
|
|
|
|
**Layout C — modular service** (per `bte-mcp/`):
|
|
```
|
|
<repo>/
|
|
├── server.py # thin transport (FastMCP / FastAPI / Flask)
|
|
├── <name>_core.py # business logic (importable, testable)
|
|
├── requirements.txt OR pyproject.toml
|
|
├── .env.example
|
|
└── README.md
|
|
```
|
|
|
|
Sandcastle prompt MUST tell the agent:
|
|
- **Match existing layout** — do NOT migrate src-layout↔flat-layout mid-task
|
|
- Type-hint public APIs (mypy will gate)
|
|
- Use **pytest fixtures**, not unittest-style setUp/tearDown
|
|
- Async code: prefer `asyncio` stdlib + `pytest-asyncio` for tests
|
|
- No `print()` debugging in committed code — use `logging` module (or stderr for CLI tools — see `sot-precommit.py` for `print(..., file=sys.stderr)` pattern)
|
|
|
|
## Sandcastle invocation template (Python)
|
|
|
|
```bash
|
|
SANDCASTLE_REPO="${SANDCASTLE_REPO:-$HOME/workspaces/hermes/sandcastle}"
|
|
cd "$SANDCASTLE_REPO"
|
|
npx tsx -e "
|
|
import { run, claudeCode } from '@ai-hero/sandcastle';
|
|
import { docker } from '@ai-hero/sandcastle/sandboxes/docker';
|
|
const result = await run({
|
|
agent: claudeCode('claude-opus-4-7'),
|
|
sandbox: docker({
|
|
image: 'python:3.12-slim',
|
|
setup: [
|
|
'pip install uv',
|
|
'cd /workspace && (uv sync 2>/dev/null || pip install -e \".[dev]\" 2>/dev/null || pip install -r requirements-dev.txt 2>/dev/null || pip install -r requirements.txt)'
|
|
]
|
|
}),
|
|
promptFile: '${CTO_HOME}/work/${WORK_ID}/prompt.md',
|
|
cwd: '${TARGET_REPO}',
|
|
branchStrategy: { type: 'branch', branch: 'cto/${WORK_ID}' },
|
|
maxIterations: 5,
|
|
});
|
|
console.log(JSON.stringify({ commits: result.commits, branch: result.branch }, null, 2));
|
|
"
|
|
```
|
|
|
|
Prompt file (`prompt.md`) MUST instruct the sandboxed agent to:
|
|
1. Read `pyproject.toml` (or fall back to `setup.py` / `requirements*.txt`) — identify dependency manager
|
|
2. Identify layout (A/B/C above) — match it
|
|
3. Make code changes per the brief
|
|
4. Run `ruff check . && ruff format --check .` — must pass
|
|
5. Run `pytest` — must pass (if tests exist; check `[tool.pytest.ini_options].testpaths`)
|
|
6. Run `mypy <pkg>` — must pass (if mypy configured)
|
|
7. Commit + report
|
|
|
|
## Post-run quality gates (mount `PG-svrnty.lib-quality-gates` if available)
|
|
|
|
After sandcastle completes, run quality gates against the diff:
|
|
|
|
```bash
|
|
QG=/home/svrnty/workspaces/cortex/PG-svrnty.lib-quality-gates
|
|
[ -d "$QG" ] && "$QG/bin/run-gates" --stack python --repo "${TARGET_REPO}" --branch "cto/${WORK_ID}"
|
|
```
|
|
|
|
The lib-quality-gates Python suite covers (per `CORTEX-TOOLING.md`):
|
|
- import order (isort-compatible)
|
|
- docstring coverage (interrogate)
|
|
- complexity (radon CC ≤ 10)
|
|
- security (bandit)
|
|
- dependency vulns (safety / pip-audit)
|
|
|
|
If gates fail: re-prompt sandcastle with the gate violations, max 3 iterations, then escalate to JP.
|
|
|
|
## Worked example — add a route to svrnty-hermes-webui-plugin
|
|
|
|
Task: "Add a route `/api/profile-catalog` that returns parsed PROFILE-CATALOG.md as JSON."
|
|
|
|
Sandcastle prompt would:
|
|
1. Mount `/home/svrnty/workspaces/hermes/svrnty-hermes-webui-plugin/` as cwd
|
|
2. Reference existing `routes/transcribe.py` and `routes/vault_status.py` as the route pattern
|
|
3. Add `routes/profile_catalog.py` with FastAPI/Flask handler (match existing style — inspect first)
|
|
4. Wire into `routes/__init__.py`
|
|
5. Add `tests/test_profile_catalog.py`
|
|
6. Run `pytest tests/test_profile_catalog.py` to verify
|
|
7. Run `ruff check routes/profile_catalog.py tests/test_profile_catalog.py`
|
|
8. Commit on branch `cto/<work-id>`, open PR
|
|
|
|
## Anti-patterns (sandcastle prompt MUST forbid)
|
|
|
|
- `pip install` without pinning (use `uv pip install <pkg>==<version>` or update lockfile)
|
|
- Bare `except:` clauses — must specify exception class (see `sot-precommit.py:git_read_staged` for correct catch)
|
|
- Mutable default arguments (`def f(x=[]):`) — use `None` sentinel + check
|
|
- `time.sleep()` in tests (use `pytest-asyncio` + `asyncio.sleep` or `freezegun`)
|
|
- Editing `.python-version` without JP approval (project Python upgrade = JP decision)
|
|
- Adding ML/AI deps (torch, transformers, etc.) without explicit task scope — they are heavy
|
|
- Modifying `hermes-agent/*.py` — workspace hard rule (read-only upstream)
|
|
|
|
## Stack gap roadmap
|
|
|
|
This skill closes the Python gap inline. The future path (per workspace CLAUDE.md):
|
|
1. v0.x: this inline-pattern skill (CURRENT)
|
|
2. v1.x: extract canonical patterns into `cortex/L6-svrnty.lib-python-framework` (deferred — not yet justified by usage)
|
|
3. When extracted: replace this skill body with `mount cortex/L6-svrnty.lib-python-framework` + the routing table moves there
|
|
|
|
Until v1.x, this file IS the framework reference.
|
|
|
|
## Related
|
|
|
|
- [`../cto-agent/SKILL.md`](../cto-agent/SKILL.md) — orchestrator that routes here
|
|
- [`../../CONTRACT.md`](../../CONTRACT.md) §6 — Python stack disclosure (gap status)
|
|
- [`../../../sot/06-REGISTRY/CORTEX-TOOLING.md`](../../../sot/06-REGISTRY/CORTEX-TOOLING.md) — confirms Python has no dedicated cortex/ lib (yet)
|
|
- [`../cto-angular-toolkit/SKILL.md`](../cto-angular-toolkit/SKILL.md) — sibling skill closing Angular gap
|