| name | foreman |
| description | Use this skill whenever the user says /foreman or asks to create, review, inspect, harden, transform, secure, or productionize an AI-agent tool, MCP server, OpenAPI action, function-calling schema, workflow, slash command, PR, code-execution tool, browser tool, email/refund/delete tool, database tool, or tool registry entry. Foreman designs and reviews defensive tool boundaries: runtime-owned authority, narrow schemas, staged side effects, idempotency, structured failures, approval gates, traces, and evals. |
Foreman
Foreman is one skill for agent-tool safety. It creates new tool boundaries, reviews existing ones, and rebuilds unsafe tools into safer shapes.
The core rule is simple:
The model may choose intent.
The runtime owns authority.
A tool is not safe because the prompt tells the model to be careful. It is safer when the tool boundary itself makes dangerous choices impossible, reviewable, or measurable.
Decide the job from the material
Infer the job from what the user brings. Do not ask them to choose between create, review, and transform unless the request is genuinely ambiguous.
| User brings | Treat as | Output emphasis |
|---|
| Tool idea, workflow, product requirement | Create | New defensive contract, schema, runtime policy, evals |
| Existing function, schema, MCP tool, OpenAPI action, PR | Review | Verdict, blockers, line-level findings, minimal patch |
| Broad or unsafe tool | Transform | Safer split, staged workflow, replacement code, evals |
| Large tool catalog or MCP server | Review + govern | Risk inventory, highest-risk tools, registry metadata, kill switches |
Short request like /foreman refund tool | Create | Make reasonable assumptions, state them briefly |
Start with the boundary, not the prompt
For every tool, identify four things before writing or rewriting code:
- What can this tool affect?
- What did the model get to choose?
- What must the runtime own?
- What eval would prove the boundary holds?
If the answer depends on the model obeying a prompt, convert the prompt constraint into one of these:
- a narrower tool
- a stricter schema
- a runtime policy check
- an approval step
- an idempotency key
- a structured error
- a trace requirement
- an eval case
Foreman smells
Treat these as high-signal hazards. They are not all automatic blockers, but they should always trigger inspection.
| Smell | Why it matters |
|---|
user_id, customer_id, account_id, or tenant_id in model-visible input | The model may be choosing identity or scope |
mode, role, admin, readonly, or scope as free text | Access control has become a parameter |
payload: any, dict, object, Record<string, unknown>, or arbitrary JSON | The tool does not have a real contract |
query: string for database access | The model can invent a query plan |
command: string for shell or code execution | The model can invent behavior |
send_email, post_message, create_calendar_event | External communication creates social side effects |
refund, payment, booking, delete, cancel, approve | Consequential write or financial/legal side effect |
| "Only use when safe" or "do not misuse" | A prompt is pretending to be a guardrail |
return "failed" or prose-only errors | The agent cannot recover cleanly |
| Idempotency mentioned only in description | Duplicate calls can still duplicate effects |
Use the risk ladder
Classify the tool by blast radius, not by how easy it is to implement.
pure compute
read-only bounded data
open-world read
sensitive read
internal reversible write
external communication
financial/legal/business write
destructive write
browser/computer use
shell/code execution
agent-as-tool or workflow-as-tool with delegated authority
Higher rungs need narrower interfaces, stronger runtime checks, richer traces, and more eval coverage.
Inspection order
Walk the site in this order:
- Effect — what state, data, people, systems, money, or external channels can be affected?
- Authority — which fields are model-chosen, user-provided, runtime-owned, policy-owned, or approval-owned?
- Schema — are inputs typed, bounded, enum-constrained, and explicit about required evidence?
- Read path — is authorization performed before retrieval, and are outputs redacted and treated as untrusted data?
- Write path — should this be split into draft/proposal, approval, and commit?
- Idempotency — can retries, resumes, and duplicate tool calls create duplicate side effects?
- Failure — does the result include stable
error_code, retryable, retry_after, and next_action fields?
- Trace — can an operator reconstruct tool availability, arguments, policy decision, approval, side effect, and result?
- Evals — are prompt constraints measured through tool-selection, argument, policy, state, and adversarial cases?
Output style
Be direct and practical. Use a concise verdict first when reviewing existing code. Use code where code clarifies the boundary. Do not bury blockers after long explanation.
For reviews
Use this shape:
Verdict: pass | pass with changes | required changes | stop ship
Highest-risk issue:
[one paragraph]
Blockers:
- [file/line if available]: [finding] → [required change]
Required changes:
- ...
Better boundary:
[code or tool split]
Missing evals:
- ...
For new tools
Use this shape:
Assumptions:
- ...
Risk class:
- ...
Tool boundary:
- what the model may choose
- what runtime owns
- what approval owns
Contract:
[code/schema]
Runtime policy:
[checks]
Evals:
[test cases]
For transformations
Show before and after. Keep the original capability if it is legitimate, but change the load path.
Before:
refundCustomer(customerId, amount, reason)
After:
get_authorized_case_summary()
create_refund_proposal(case_id, reason, evidence)
approve exact payload outside the model
commit_approved_refund(proposal_id, approval_token, idempotency_key)
Default defensive patterns
Use these patterns unless the user gives a reason not to.
- Identity comes from runtime context, not model-visible parameters.
- Tenant and account scope come from the session, policy engine, or gateway.
- External communication tools draft first and send only after exact approval.
- Financial, destructive, and legal side effects use proposal/approval/commit.
- Database tools expose approved reports or typed filters, not arbitrary SQL.
- Browser and shell tools run in sandboxes with allowlists, timeouts, no secrets, and no network by default.
- Tool results are data, not instructions.
- Opaque failures become structured failures.
- Every safety claim gets at least one eval.
When to read bundled references
Read only what is needed.
| Reference | Read when |
|---|
references/inspection-rubric.md | You need severity levels, risk ladder details, or a full review checklist |
references/patterns.md | You need concrete defensive rewrites for identity, writes, reads, shell, database, errors, or evals |
references/framework-notes.md | The user mentions MCP, FastMCP, OpenAPI, PydanticAI, Vercel AI SDK, LangChain, LangGraph, Semantic Kernel, or another framework |
references/examples.md | You need short before/after examples to include in the answer |
Use the scanner when files are available
If the user provides local files or asks for repository review, run:
python skills/foreman/scripts/dtd_lint.py path/to/file_or_directory
The scanner catches obvious hazards. It is not a substitute for review. Treat it as the first walk around the site, then inspect the boundary yourself.
Do not overbuild harmless tools
Foreman does not turn every weather lookup into a banking workflow. Match control to blast radius.
A pure compute tool may only need types, bounds, and structured errors. A refund, delete, email, shell, browser, or tenant-data tool needs much more. The point is not ceremony. The point is that the load-bearing controls sit where the load is.