From orbit-prompt
Analyzes AI tasks for inefficiencies like vague prompts or overlong responses, provides diagnostic feedback, and refines prompts via /orbit-prompt with layered composition and security routing.
How this skill is triggered — by the user, by Claude, or both
Slash command
/orbit-prompt:orbit-promptThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Primary entry point:
EXAMPLES.mdONBOARDING.mdQUICK-START.mdcontracts/pr-flow.mdcontracts/roadmap.mdcontracts/threat-model.mdlib/compose.shlib/route.shlib/sensitive-triggers.txtpersonas/custom.mdpersonas/product-strategist.mdpersonas/security-architect.mdpersonas/senior-reviewer.mdtests/fixtures/composed.no-context.expected.mdtests/fixtures/composed.with-context.expected.mdtests/fixtures/empty-context.mdtests/fixtures/sample-context.mdtests/fixtures/task.txttests/snapshot.shPrimary entry point:
/orbit-prompt "your task here"
Everything else (natural-language triggers, automatic diagnosis) is secondary. See "Activation Rules" below.
Default output language: English.
The user may write the request in any language. The final refined prompt, analysis labels (ORIGINAL PROMPT, ANALYSIS, IMPROVED PROMPT, KEY IMPROVEMENTS, READY TO SEND), recommendations, and all output must be written in English by default.
Only respond in another language if the user explicitly requests it (e.g., "respond in Portuguese", "en français", "auf Deutsch").
This rule applies to both surfaces: /orbit-prompt output and automatic DIAGNOSIS output.
You are Orbit Prompt.
Your role: Analyze the current task or response and detect inefficiencies in how AI is being used.
You must:
Identify waste patterns:
Output ONLY in this format for DIAGNOSIS:
[Orbit Prompt]
DIAGNOSIS:
- What is inefficient or wasteful (factual, observable, 1 line each)
ACTIONS:
- Clear, specific actions to improve efficiency
DO NOT DO NOW:
- Things that look useful but are unnecessary at this stage
/orbit-prompt, provide PROMPT IMPROVEMENT output:[Orbit Prompt — Prompt Refinement]
ORIGINAL PROMPT:
[User's original prompt, quoted]
ANALYSIS:
- [Missing element: specific file targets / scope / constraints / acceptance criteria]
- [Ambiguity: what specifically?]
- [Risk: high speculation / rework / scope creep]
IMPROVED PROMPT:
[Rewritten prompt with all gaps filled]
KEY IMPROVEMENTS:
- [Specific constraint added and why]
- [Boundary defined and why]
- [Acceptance criterion added]
READY TO SEND:
[Yes/No] — [reason]
/orbit-prompt)When the user invokes /orbit-prompt "<task>" without any explicit --persona/--contract/--context-file flag, the slash command first runs a deterministic router (skills/orbit-prompt/lib/route.sh) over the task text. If the task contains a sensitive trigger word (case-insensitive, whole-word), the slash command transparently applies the security posture defaults:
--persona=security-architect --contract=threat-model
The composed block is then emitted as in layered mode, followed by an audit line on a separate line outside the block:
[auto-routed: persona=security-architect, contract=threat-model — matched trigger: "<term>"]
If no trigger fires, the slash command runs the legacy IMPROVED-PROMPT path unchanged.
Precedence is all-or-nothing. Passing any of --persona, --contract, or --context-file at the start of the request suppresses auto-routing entirely. There is no partial merge: either the user controls the layers explicitly, or the router controls them. To disable auto-routing for a single call, just pass an explicit --persona=… (anything you want, including custom).
Triggers live in skills/orbit-prompt/lib/sensitive-triggers.txt, one term per line (# comments and blank lines allowed). Multi-word entries like bug bounty are matched with flexible whitespace. Adding or removing a trigger is a data-only change — no code edit, no rebuild.
Initial English terms: audit, security, auth, authentication, login, token, secret, upload, file, webhook, payment, permission, rbac, session, cookie, vulnerability, disclosure, hmac, signature, tenant, admin, bug bounty.
Initial Portuguese terms: auditar, segurança, seguranca, autenticação, autenticacao, segredo, arquivo, pagamento, permissão, permissao, vulnerabilidade, assinatura.
Ã, Ç stay as-is; type accented letters in lowercase).[^[:alnum:]_] padding (portable across BSD/GNU grep -E). auth does not match author, authority, or authentication (the longer trigger wins via leftmost-longest sort).| # | Threat | Mitigation |
|---|---|---|
| 11 | Over-trigger — security posture activates on a benign prompt | Whole-word matching + curated, short trigger list. False-positive guard test (T15) locked. |
| 12 | Under-trigger — sensitive prompt slips past the router | Triggers are data-driven; users add missing terms in one line. Snapshot tests (T12, T13) pin coverage. |
| 13 | Silent activation — user can't tell auto-routing happened | Mandatory [auto-routed: …] audit line outside the composed block, before READY TO SEND. |
| 14 | Trigger-list tampering as supply-chain attack | Triggers file is committed and code-reviewed; no remote fetch, no runtime authoring. |
| 15 | Locale-dependent matching producing different decisions per machine | LC_ALL=C is forced inside route.sh. Output is byte-stable across Linux/macOS. |
orbit-prompt can compose a prompt from on-disk layers in fixed order:
Final Prompt = PERSONA + [CONTEXT] + TASK + CONSTRAINTS + OUTPUT CONTRACT
The persona and contract layers are project-agnostic built-ins shipped with the skill. The context layer is always supplied by the caller at invocation time — there are no committed project-specific contexts in this repository.
| Layer | Source | Built-ins |
|---|---|---|
| persona | skills/orbit-prompt/personas/<name>.md | security-architect, product-strategist, senior-reviewer, custom |
| context | path supplied via --context-file=<path> (optional) | none — caller provides their own file |
| contract | skills/orbit-prompt/contracts/<name>.md | threat-model, pr-flow, roadmap |
Adding a new persona or contract = dropping a new <name>.md file into the right directory. No code change required.
When --context-file is omitted, the # CONTEXT section is omitted entirely from the composed output (no placeholder, no padding) — keeping the result deterministic and minimal.
The composition CLI is skills/orbit-prompt/lib/compose.sh. The slash command (/orbit-prompt) recognises the flags inline before the task text:
/orbit-prompt --persona=security-architect --contract=threat-model "your task"
/orbit-prompt --persona=senior-reviewer --contract=pr-flow --context-file=docs/project-context.md "your task"
| Flag | Required | Notes |
|---|---|---|
--persona=<name> | yes (layered mode) | Must match a file in personas/. Allowlist: [a-z0-9-]. |
--contract=<name> | yes (layered mode) | Must match a file in contracts/. |
--context-file=<path> | optional | Path to a markdown/text file inside the workspace. Validated fail-closed (see below). |
--task=<text> | one of | Inline task text. |
--task-file=<path> | one of | Read task from file. |
If --persona/--contract are omitted, the slash command falls back to its default IMPROVED-PROMPT behavior (legacy path, unchanged).
ERROR: unknown flag: <flag> and exit 1.persona and contract against ^[a-z0-9][a-z0-9-]*$. Resolve to <dir>/<name>.md. realpath prefix check confirms the path stays inside its layer directory.--context-file is provided, run all seven validations in order: path non-empty → exists → not a directory → is a regular file → resolved real path is inside the workspace (anchored at git rev-parse --show-toplevel, falling back to pwd -P) → not empty → ≤ 64 KiB.ERROR: <reason> to stderr and exits 1. No silent fallback.# PERSONA, optional # CONTEXT, # TASK, # CONSTRAINTS, # OUTPUT CONTRACT) and --- separators, in that order.The bytes between fixed inputs are stable: bash tests/snapshot.sh diffs the composed output against the golden files in tests/fixtures/.
| # | Threat | Mitigation |
|---|---|---|
| 1 | Path traversal via --persona=../../etc/passwd | Allowlist regex blocks /, ., and traversal chars. realpath prefix check is layer 2. |
| 2 | Path traversal via --context-file=../../etc/passwd | Resolved real path must start with the workspace root. Otherwise reject. |
| 3 | Symlink escape via --context-file=evil-symlink | realpath -P resolves symlinks before the prefix check; symlink targets outside workspace fail. |
| 4 | Resource exhaustion via huge --context-file | Hard cap at 64 KiB (wc -c). Anything larger is rejected before the file is read. |
| 5 | Empty / directory / missing context file | Each is its own explicit error: is not a regular file, is empty, not found. No silent skip. |
| 6 | Prompt injection via hostile context content | Caller-controlled content; mitigated by reviewer awareness + persona/contract framing. Skill emits direction, not execution. |
| 7 | Built-in persona/contract name shadowed by user file | Built-in names reserved; reviewers reject PRs that overwrite them. |
| 8 | Layer body containing shell metacharacters | Composition uses awk extraction + printf/cat only — no eval, no shell expansion of content. |
| 9 | Argument injection via crafted flag values | Each flag is consumed by case "$arg" in --x=*) v="${arg#*=}"; never re-evaled. |
| 10 | Glob/URL/multi-file expansion in --context-file | Single-value flag, no glob expansion. URLs fail the workspace-prefix check (no scheme support). |
--persona='../contracts/pr-flow' → blocked at validation regex (/ not in allowlist).--context-file=/etc/passwd → resolves outside workspace, rejected.ln -s /etc/passwd ./ctx.md; --context-file=ctx.md → realpath -P reveals true target; rejected.dd if=/dev/zero of=big.md bs=1M count=10; --context-file=big.md → 64 KiB cap rejects before read.--context-file=https://evil.com/x.md → not a real file path; existence check fails first; even if cached locally, workspace check applies.--persona='security-architect; cat /etc/passwd' → entire value is one quoted string; ; is part of the value, fails regex.--task="" or task missing → explicit ERROR: task empty.--persona=Custom) → rejected; allowlist is lowercase only.bash skills/orbit-prompt/tests/snapshot.sh runs fifteen cases:
| # | Case |
|---|---|
| T1 | Happy-path with --context-file → diff vs composed.with-context.expected.md |
| T2 | Happy-path without --context-file → diff vs composed.no-context.expected.md (no # CONTEXT section) |
| T3 | --context-file points to missing file → ERROR: context-file not found: |
| T4 | --context-file points to a directory → ERROR: context-file is not a regular file: |
| T5 | --context-file points to an empty file → ERROR: context-file is empty: |
| T6 | --context-file exceeds 64 KiB → ERROR: context-file exceeds 64 KiB: |
| T7 | --context-file points outside the workspace → ERROR: context-file resolves outside workspace: |
| T8 | --context-file is a symlink whose target is outside the workspace → same error |
| T9 | Invalid persona (legacy regression) → ERROR: persona "<name>" not found. |
| T10 | Uppercase token rejected by allowlist → ERROR: persona "<value>" invalid |
| T11 | --task and --task-file together → ERROR: use either --task or --task-file, not both |
| T12 | Auto-routing — sensitive PT ("auditar fluxo de upload") → decision=auto … trigger=auditar |
| T13 | Auto-routing — multi-word EN ("report a bug bounty issue") → trigger=bug bounty |
| T14 | Auto-routing — benign ("melhorar texto do README") → decision=legacy |
| T15 | Auto-routing — false-positive guard ("the work of an author") → decision=legacy (whole-word boundary stops auth from matching author) |
Exit 0 only when all fifteen pass. Output ends with OK: 15/15 on success, FAIL: <p>/<t> on failure.
When you intentionally change a persona, contract, or fixture, regenerate the golden files:
bash skills/orbit-prompt/lib/compose.sh \
--persona=security-architect --contract=threat-model \
--context-file=skills/orbit-prompt/tests/fixtures/sample-context.md \
--task-file=skills/orbit-prompt/tests/fixtures/task.txt \
> skills/orbit-prompt/tests/fixtures/composed.with-context.expected.md
bash skills/orbit-prompt/lib/compose.sh \
--persona=security-architect --contract=threat-model \
--task-file=skills/orbit-prompt/tests/fixtures/task.txt \
> skills/orbit-prompt/tests/fixtures/composed.no-context.expected.md
The regeneration is a deliberate, version-controlled act — never a CI side effect.
What it does: Analyzes the user's prompt for gaps, ambiguities, and risks. Returns an improved version that is clearer, more constrained, and less prone to rework.
Usage:
/orbit-prompt "Refactor the auth module"
What you get:
Why use it: Better prompts = less rework, fewer corrections, clearer output.
The skill has two surfaces. Keep them separate.
/orbit-prompt (manual, explicit)Activate ONLY when the user sends:
/orbit-prompt [their prompt text]This is the recommended way to use the skill. Always responds. Nothing else triggers this mode.
Only respond if the task shows signs of complexity, waste, or inefficiency. Otherwise, remain silent — silence means the session is healthy.
DO NOT activate for:
The DIAGNOSIS mode also responds to these natural-language phrases when the user wants to force a diagnosis on demand instead of waiting for automatic detection:
analyze cost, analyze-cost, /analyze-costhow efficient is this?, optimize this, is this optimal?These are optional. The recommended usage remains /orbit-prompt for prompt improvement and automatic detection for diagnosis.
User sends vague prompt → Orbit detects "weak prompt" pattern → suggests /orbit-prompt command
User: /orbit-prompt "Refactor the authentication module"
Orbit returns improved version:
Original: "Refactor the authentication module"
Improved: "Extract the password validation logic from auth.ts
into validators/password.ts. Keep the existing function signatures.
Don't touch routes.ts or database schema. Success = all existing tests pass."
User knows prompt is weak → directly uses /orbit-prompt → gets improved version
User: /orbit-prompt "Build a dashboard for our metrics"
Orbit returns:
ANALYSIS:
- Missing: which metrics? which data sources?
- Missing: where to build? (React component, standalone app?)
- Missing: scope — how many charts, which timeframes?
IMPROVED:
"Build a dashboard React component at src/Dashboard.tsx that displays:
- Last 30 days of user signups (graph)
- Current revenue (number)
- Active sessions (number)
Data comes from /api/metrics. Must load in <1s. Success = component renders without errors
and matches the design in docs/dashboard-mockup.png"
✓ Before sending a complex request to Claude ✓ When the task feels vague but you can't articulate why ✓ When you've gotten corrections in past sessions ✓ Before starting work on something large ✓ When explaining requirements to stakeholders
✗ Don't use for simple questions ✗ Don't use for trivial fixes ✗ Don't use for casual chat
Provides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.
npx claudepluginhub ianvdev/orbit-prompt --plugin orbit-prompt