P10
Apply NASA's Power of 10 safety rules as a pre-execution planning contract for any engineering task. Use this skill before writing or modifying code whenever a task has been defined (via gstack, /council ruling, or direct issue). The skill researches the codebase, drafts a P10-compliant implementation plan (full task or named stage), saves it to Obsidian, and provides a decision overview. The saved draft becomes the foundation the execution agent reads before touching any file. Trigger on: "plan this with p10", "p10 draft", "bridge to execution", "safe implementation plan", any task following a /council ruling, or any gstack /plan phase where correctness and safety are non-trivial. This is the bridge between planning and elite execution — always invoke it before implementing complex, stateful, or safety-critical logic.From its SKILL.md
npx -y skills add ray-aqno/Toto-Wolff --skill p10Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 6 stars6 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.
SKILL.md
19.9 KB, as published. Nobody here has run it
P10 Bridge
A pre-execution planning layer grounded in NASA JPL's Power of 10 rules. Given a task, the skill scouts the codebase, analyzes the task against each P10 rule, drafts a compliant implementation plan, passes it to Opus for arbitration, and commits the approved plan to Obsidian. The execution agent reads this draft before writing a single line — ensuring complex architecture is built on a verified, safe foundation.
NASA Power of 10 Rules
| # | Rule | Execution constraint |
|---|---|---|
| 1 | Simple control flow | No recursion. No goto. No setjmp/longjmp. |
| 2 | Fixed loop bounds | Every loop has a provable upper bound. Annotate it. |
| 3 | No dynamic memory post-init | Heap allocation only during initialization phase. |
| 4 | Functions ≤ 60 lines | One screen, one purpose. Split if exceeded. |
| 5 | ≥ 2 assertions per function | Invariants are explicit. Use assert or typed guards. |
| 6 | Minimal variable scope | Declare at narrowest scope. No wide globals. |
| 7 | Check every return value | No silent failures. Every call site handles errors. |
| 8 | Preprocessor / macro use minimal | No function-like macros. Constants over #define. |
| 9 | Restrict pointer use | No function pointers unless unavoidable. Dereference once. |
| 10 | Zero warnings | All compiler/linter warnings treated as errors. |
Rules 3, 8, and 9 adapt for dynamic and modern compiled languages — see Language Adapters section below.
Architecture
Task Input (gstack issue / /council ruling / direct prompt)
│
▼
┌─────────────────┐
│ CODEBASE SCOUT │ Haiku subagents (parallel) — map files, deps, entry points
└─────────────────┘
│
▼
┌─────────────────┐
│ P10 ANALYZER │ Sonnet — maps task against each rule, surfaces risks + constraints
└─────────────────┘
│
▼
┌─────────────────┐
│ DRAFT WRITER │ Sonnet — writes staged, P10-compliant implementation plan
└─────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ P10 ARBITER (Opus) │
│ Reads: P10 analysis + draft only (not raw scouts) │
│ Approve → status: approved │
│ Revise → Sonnet rewrites once, Opus re-reviews │
│ Block → status: blocked, names rule + resolution │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────┐
│ OBSIDIAN WRITE │ Haiku — commits Opus-stamped plan to vault
└─────────────────┘
│
▼
Execution agent reads Obsidian draft — status: approved required to proceed
Step 0 — Config Resolution
Resolve vaultPath and this skill's log/plan directory before doing anything else. Same 4-step order in every skill this plugin bundles (p10, llm-council, the-cabinet) — do not deviate, this consistency is what keeps the lookup unambiguous:
TOTO_VAULT_PATHenv var, if set — always wins.<plugin-root>/settings.local.json, if the plugin was installed viaclaude plugin addand the file exists.- Global
~/.claude/CLAUDE.mdprose (the legacy convention — still honored, not removed). - Hardcoded default (
~/.toto/vault), if nothing above resolved.
Print which source won (e.g. resolved vaultPath from: env TOTO_VAULT_PATH) before proceeding — this line is load-bearing, not cosmetic: without it, an env var silently shadowing a settings.local.json override becomes an invisible footgun.
First-run / no cached resolution beyond the hardcoded default: if there's an interactive session (TTY available), ask the user for vaultPath (and this skill's log/plan dir, if it differs from the default) via AskUserQuestion, then write the answer to <plugin-root>/settings.local.json (source #2 above) so future runs skip the prompt. If writing fails (e.g. read-only plugin dir), use the answered value for this run only and warn that the prompt will repeat next time.
No interactive session available (headless, CI, scripted claude plugin add): do NOT wait on AskUserQuestion — it has no path to a human here. Fall through to source #4 (hardcoded default) and emit a fail-loud stderr warning naming the exact remediation: set TOTO_VAULT_PATH=<path> or create <plugin-root>/settings.local.json before running in a non-interactive environment. Never proceed silently as if a value were confirmed when it wasn't.
Step 1 — Codebase Scout (Haiku, parallel subagents)
Spawn 2–4 scout subagents to map the codebase relevant to the task. Each Agent tool call MUST set these parameters explicitly — do not rely on defaults:
model: 'claude-haiku-4-5-20251001'— inheriting the parent session's model (Sonnet/Opus) here is the single largest cost driver in this skill. Always set it.subagent_type: 'Explore'— scouts only read and map; they never write or edit.general-purpose's default system prompt is far larger than a scout task needs.- Read-scope bound in the prompt itself: "Inspect at most 15 files. Do not read any file end-to-end unless the task specifically requires its full content — prefer targeted symbol/grep lookups and cite line ranges." A word cap on the response (below) does nothing if the scout still burns its budget reading unbounded input.
- Report-length bound in the prompt itself: "Report back in under 400 words, structured, file:line citations only — no full file dumps, no pasted source blocks longer than 5 lines." This is what keeps the P10 Analyzer's incoming context small.
Tool preference: When running inside Claude Code with Serena MCP registered, scouts should default to Serena's symbol-aware tools instead of grep — AST-level scouting catches structural violations (real function boundaries, actual call graphs) that text search misses:
mcp__serena__get_symbols_overview— file-level symbol maps (Scout A, entry points)mcp__serena__find_symbol— locate specific functions/classes by name (Scout A, B)mcp__serena__find_referencing_symbols— call-graph / impact analysis (Scout B, C)
Fall back to grep-based scouting only if Serena MCP is not registered in the session.
Scout A: Find entry points and call sites related to the task scope
(Serena: get_symbols_overview + find_symbol; fallback: grep for function
names, imports, exports)
Scout B: Map data flow — what state is read/written by this task's scope
(Serena: find_symbol + find_referencing_symbols; fallback: grep)
Scout C: Identify existing violations of P10 rules in affected files
(functions > 60 lines, unchecked returns, dynamic alloc patterns —
Serena: get_symbols_overview to get exact function boundaries/line counts;
fallback: grep)
Scout D: Check gstack /freeze registry — flag any locked modules in scope
Scouts output a codebase snapshot: file list, relevant functions, existing violations, freeze flags. Passed to P10 Analyzer — not to the user directly.
Step 2 — P10 Analysis (Sonnet)
Agent tool call: model: 'claude-sonnet-4-6', subagent_type: 'general-purpose'.
This step makes judgment calls across 10 interacting rules, not a search — a scoped
search-only agent type is the wrong fit here. Cap the incoming scout context to what
Step 1 already bounded; do not paste raw scout transcripts if a summary suffices.
For each of the 10 rules, assess impact on the task:
### P10 Analysis
**Rule 1 — Control flow:** [SAFE | RISK | BLOCKED] — [why]
**Rule 2 — Loop bounds:** [SAFE | RISK | BLOCKED] — [why + bound annotation if needed]
**Rule 3 — Memory:** [SAFE | RISK | N/A] — [why]
**Rule 4 — Function size:** [SAFE | RISK] — [functions at risk of exceeding 60 lines]
**Rule 5 — Assertions:** [SAFE | MISSING] — [where assertions must be added]
**Rule 6 — Scope:** [SAFE | RISK] — [variable scope concerns]
**Rule 7 — Return values:** [SAFE | RISK] — [call sites that must handle errors]
**Rule 8 — Macros:** [SAFE | N/A] — [macro usage in scope]
**Rule 9 — Pointers:** [SAFE | RISK | N/A] — [pointer/reference concerns]
**Rule 10 — Warnings:** [CLEAN | FLAGS] — [known lint/type issues in scope]
**Blocking risks:** [rules with BLOCKED status must be resolved before execution]
**Pre-conditions:** [what must be true before execution begins]
Step 3 — Draft Plan (Sonnet)
Agent tool call: model: 'claude-sonnet-4-6', subagent_type: 'general-purpose'.
Drafting a staged plan is synthesis, not search — general-purpose is the right fit.
Write a staged, P10-compliant implementation plan:
## P10 Implementation Draft — [TASK TITLE]
**Task:** [one sentence]
**Stage:** [if partial — which stage of the overall plan]
**gstack phase:** [plan / review / ship]
**Council ruling ref:** [link or slug if triggered by /council]
**Date:** [ISO]
### Pre-conditions
[What must be true before execution. Verified by scout.]
### Implementation Stages
#### Stage N: [name]
- **Scope:** [files and functions touched]
- **P10 constraints active:** [rules 1–10 relevant to this stage]
- **Assertions required:** [explicit invariants to add]
- **Return value handling:** [every call site that needs a handler]
- **Loop bound annotations:** [each loop with its provable upper bound]
- **Function split plan:** [if any function risks exceeding 60 lines]
- **Freeze check:** [any locked modules — do not touch without /council]
### Decision Overview
**Why this approach:** [reasoning grounded in P10 + codebase findings]
**Alternatives rejected:** [what was considered and why discarded]
**Risk surface:** [what could still go wrong and why it's acceptable]
**Execution agent instructions:** [what the agent must read/check before starting]
One draft per task or per named stage. Multi-stage tasks: one draft per stage, linked in the Obsidian index.
Step 4 — P10 Arbiter (Opus)
Agent tool call: model: 'claude-opus-4-8', subagent_type: 'general-purpose'.
Already correctly scoped to receive only the compressed analysis/draft, not raw
scout output — keep it that way, this is the cheapest tier to get wrong.
Opus receives only the P10 analysis and draft plan — not raw scout output. Three valid responses:
A) Approve:
## P10 Arbiter — Approved
**Status:** approved
**Ruling:** [confirmation that plan satisfies all 10 rules]
**Conditions:** [any execution-time conditions the agent must uphold]
**Cross-rule notes:** [interactions between rules Sonnet may have missed]
B) Revision Required (once per draft):
## P10 Arbiter — Revision Required
**Status:** revision-required
**Rule(s):** [specific rules insufficiently addressed]
**Required change:** [exactly what Sonnet must fix in the draft]
After revision: Sonnet updates draft (~400 tok), Opus re-reviews. Maximum one cycle.
C) Blocked:
## P10 Arbiter — Blocked
**Status:** blocked
**Blocking rule:** [rule N — exact violation]
**Resolution required:** [what architectural decision must be made first]
**Escalation:** [/council recommended | task must be redesigned]
Blocked drafts cannot proceed. Resolution typically requires a /council session —
the block reason becomes the council input.
Step 5 — Obsidian Commit (Haiku)
Uses vaultPath and p10.planDir (default P10-Plans) resolved in Step 0.
File: {vaultPath}/{p10.planDir}/YYYY-MM-DD-{task-slug}.md
Frontmatter:
---
date: YYYY-MM-DD
task: [slug]
stage: [N or "full"]
gstack_phase: [phase]
council_ref: [slug or null]
status: draft | revision-required | approved | blocked | executed | revised
arbiter_action: approved | revision-required | blocked
p10_blocking_rules: [list of BLOCKED rules, or none]
tags: [p10, planning, gstack, {domain}]
---
Update P10-Plans/INDEX.md with each new draft (date, task, stage, status).
gstack Integration
| gstack Phase | P10 Bridge role |
|---|---|
/plan | Primary trigger — draft P10 plan before any architecture is locked |
/review | Re-run P10 analysis on PR diff; flag new violations |
/ship | Verify status: approved before execution proceeds |
/retro | Surface P10 violations introduced during execution; update draft status |
/council ruling | Ruling becomes council_ref in the draft frontmatter |
Freeze respect: If scout finds a frozen module in task scope, the draft must include:
⚠️ FROZEN: [module] — /council required before touching.
Execution Agent Handoff
Before writing any code, read:
{vaultPath}/{p10.planDir}/{draft-filename}.md
Verify status is `approved` and arbiter_action is `approved`.
If status is anything other than `approved` — STOP. Do not execute.
If blocked, escalate to /council. If revision-required, return to p10-bridge.
Follow the staged plan exactly. Do not exceed function size limits.
Add all annotated assertions. Handle every return value listed in the draft.
Respect all freeze flags.
Token Budget
| Step | Model | Budget |
|---|---|---|
| Scout ×2–4 | Haiku | ~250 tok each |
| P10 Analyzer | Sonnet | ~800 tok |
| Draft Writer | Sonnet | ~1000 tok |
| P10 Arbiter | Opus | ~800 tok |
| Revision (if needed) | Sonnet + Opus | ~400 + ~500 tok |
| Obsidian Writer | Haiku | ~300 tok |
Target: ~3800–4300 tok per draft. With revision: ~4700–5200 tok.
Language Adapters
Rules 3, 8, and 9 do not map directly to dynamic or modern compiled languages. Scouts load the relevant section below at codebase scan time.
TypeScript / JavaScript
| Rule | Adaptation |
|---|---|
| 1 — Control flow | No recursion. No eval. Flatten promise chains with async/await. |
| 2 — Loop bounds | Every for/while must have a provable bound. Comment the max count. No unbounded while(true). |
| 3 — Memory | No unbounded data structure growth at runtime. Arrays and maps must have max-size guards. |
| 4 — Function size | ≤ 60 lines. ESLint max-lines-per-function enforced. |
| 5 — Assertions | assert from node:assert or typed invariant helper. Min 2 per function. Type guards that throw count. |
| 6 — Scope | const over let. let over var. No var. Module-level state must be justified. |
| 7 — Return values | No ignored Promise rejections. Every await in try/catch or .catch(). ESLint @typescript-eslint/no-floating-promises. |
| 8 — Macros | No eval, no Function() constructor, no dynamic require. |
| 9 — Pointers | No any type. No unchecked type assertions (as Type without guard). |
| 10 — Warnings | tsc --strict --noEmit clean. ESLint zero warnings. "strict": true in tsconfig. |
Python
| Rule | Adaptation |
|---|---|
| 1 — Control flow | No recursion (or explicit sys.setrecursionlimit with documented bound). No exec. No dynamic import at runtime. |
| 2 — Loop bounds | All while loops must document max iteration count. for over iterables preferred — document expected max length. |
| 3 — Memory | No unbounded list/dict growth. Use collections.deque(maxlen=N) for bounded queues. Document max size for all growing structures. |
| 4 — Function size | ≤ 60 lines. flake8 --max-function-length enforced. |
| 5 — Assertions | assert with descriptive messages. Min 2 per function. isinstance checks count. |
| 6 — Scope | No module-level mutable state unless justified. No global without documentation. |
| 7 — Return values | No ignored returns for functions that can fail. Never bare except:. All exceptions caught at appropriate boundary. |
| 8 — Macros | No exec, no eval, no __import__. |
| 9 — Pointers | All parameters and returns must have type annotations. mypy --strict must pass. |
| 10 — Warnings | mypy --strict clean. flake8 zero warnings. pylint score ≥ 9.0. |
Go
| Rule | Adaptation |
|---|---|
| 1 — Control flow | No recursion unless provably bounded and documented. No goto. |
| 2 — Loop bounds | All for loops with a condition (not range) must document max iterations. |
| 3 — Memory | No unbounded goroutine spawning. Channel buffers must be sized. Use sync.Pool for reuse. |
| 4 — Function size | ≤ 60 lines. gocyclo complexity ≤ 10. |
| 5 — Assertions | Explicit error checks as assertions. panic with message for true invariant violations. |
| 6 — Scope | := at narrowest scope. Package-level vars must be justified. |
| 7 — Return values | Every error return checked. errcheck linter enforced. No _ for error values. |
| 8 — Macros | No unsafe package without documented justification. |
| 9 — Pointers | Prefer value receivers. Document every pointer receiver choice. |
| 10 — Warnings | go vet clean. staticcheck clean. golangci-lint zero warnings. |
Rust
| Rule | Adaptation |
|---|---|
| 1 — Control flow | No recursion unless bounded. No unsafe control flow. |
| 2 — Loop bounds | All loop blocks must document exit condition and maximum iteration bound. |
| 3 — Memory | Ownership system enforces structurally. No unsafe allocator use. Box::new only in init paths. |
| 4 — Function size | ≤ 60 lines. clippy::too_many_lines enforced. |
| 5 — Assertions | assert! and debug_assert! min 2 per function. No unwrap() — use expect("invariant reason"). |
| 6 — Scope | Narrowest scope always. No unnecessary mut. |
| 7 — Return values | All Result and Option handled. No unwrap() in production paths. #[must_use] on all Result-returning functions. |
| 8 — Macros | macro_rules! only for well-understood patterns. No proc macros without team review. |
| 9 — Pointers | No raw pointers (*const, *mut) outside unsafe. No unsafe without /council-reviewed justification. |
| 10 — Warnings | cargo clippy -- -D warnings clean. cargo check clean. |
Output to User
- Draft path — confirm file written to vault
- Arbiter ruling — Approved / Revision Required / Blocked (prominent)
- P10 analysis summary — any RISK or BLOCKED rules called out
- Stage overview — what the execution agent will do, in order
- Execution readiness —
READY|BLOCKED: [rule N — reason]
When NOT to use this skill
- Trivial single-line fixes with no architectural surface
- Pure documentation or config changes
- Tasks already covered by an approved, unexecuted P10 draft
- Hotfixes where speed is critical — flag for post-hoc P10 review instead