Verifiedon 2026.7.1
Action boundary
Before you act
- Expected result
- A reviewer can validate requests without running the capability and can tell every failure from a successful empty result.
- Failure mode
- Free-form input, ambiguous output, or silent fallback makes a side effect or unsupported claim appear successful.
- Rollback
- Disable the capability and return a typed validation error until the contract and fixtures are corrected.
A description is not a contract
“Research the web” is a goal, not an interface. It says nothing about source scope, maximum work, evidence quality, or whether the caller can ask the capability to send, publish, or delete. A safe extension starts with a contract that can reject a request before it invokes a tool.
The reviewed OpenClaw MCP documentation is the primary receipt for the integration boundary. Pair it with the skills documentation when the contract is being packaged as reusable instructions. Those sources tell you what OpenClaw exposes at the pinned revision; your contract must still define what this particular capability accepts and refuses.
The contract has four gates: input validation, allowlist and policy, bounded invocation, and evidence output. Every gate must have an observable result. A caller should never need to inspect a log and infer whether a malformed request was rejected or whether a remote source simply had no matching findings.
- Input validationReject missing fields, overlong queries, invalid URLs, unknown modes, and credentials.
- Allowlist and policyCheck approved sources, side-effect intent, timeout, cost, and human-gate requirements.
- InvocationCall only the bounded tool or fixture after the previous gates pass.
- Evidence resultReturn status, findings, URLs, timestamps, run ID, and sideEffects explicitly.
Define the request before the implementation
For the course capstone, use a request shape like this:
{
"query": "OpenClaw 2026.7.1 release notes",
"sources": ["https://github.com/openclaw/openclaw/releases"],
"maxFindings": 3,
"mode": "dry-run"
}
A useful schema decision table looks like this:
| Field | Rule | Reason for the bound |
|---|---|---|
query |
required string, 1–160 characters | prevents unbounded prompt and retrieval cost |
sources |
one to three exact HTTPS origins or paths | prevents arbitrary discovery and exfiltration |
maxFindings |
integer from 1 to 3 | keeps review effort predictable |
mode |
dry-run by default; no live-write mode in this course |
makes safe behavior the default |
| credentials | forbidden | the public research job does not need them |
| local paths | forbidden | prevents accidental filesystem expansion |
Do not allow the model to rewrite these policy fields. If a caller includes mode: "publish", the contract should return side_effect_blocked; it should not ask the model whether publishing “seems safe.” Policy is code or a reviewed configuration boundary, not a suggestion in natural language.
Define results so absence is not success
A good result distinguishes status from findings:
{
"status": "ok",
"findings": [
{
"claim": "Release note found",
"url": "https://github.com/openclaw/openclaw/releases",
"retrievedAt": "2026-07-30T00:00:00Z",
"sourceId": "openclaw-releases"
}
],
"sideEffects": [],
"runId": "fixture-001"
}
An empty findings array can be valid when the source was reached and no matching evidence exists. It is not valid to use an empty result to hide a 403, timeout, parse error, or policy denial. Use a small, stable status vocabulary:
ok: the allowlisted source was reached and the result is evidence-backed, even when findings are empty;invalid_request: the request failed validation and invocation did not occur;source_unavailable: the allowlisted source could not be reached or verified; include the source and retry guidance;side_effect_blocked: the request asked for a write or irreversible action and was stopped before invocation;unknown_after_timeout: a timeout occurred after a state-changing boundary may have been crossed; stop and require inspection.
The sideEffects field should be present in every result and equal [] for this capstone. That invariant makes an accidental write visible in a test diff rather than relying on a reviewer to interpret prose.
const input = { query, sources, maxFindings, mode };
if (!Number.isInteger(maxFindings) || maxFindings < 1 || maxFindings > 3)
return { status: 'invalid_request', reason: 'maxFindings must be 1..3', sideEffects: [] };
if (sources.some((source) => !ALLOWED_SOURCES.has(source)))
return { status: 'invalid_request', reason: 'source is not allowlisted', sideEffects: [] };
if (mode !== 'dry-run')
return { status: 'side_effect_blocked', reason: 'dry-run is the only allowed mode', sideEffects: [] };
return invokeFixture(input);Expected output: invalid_request and side_effect_blocked complete with zero invocation count
Worked example — classify three failures
Imagine three requests arrive. First, maxFindings: 99: return invalid_request, with the field-level reason and no network call. Second, the approved releases URL returns HTTP 403: return source_unavailable and preserve the URL; do not silently switch to a mirror. Third, the caller asks to send the summary to a channel: return side_effect_blocked before invoking retrieval or messaging. The status tells the operator what happened and where to look next.
A common anti-pattern is “helpful fallback”: if the approved source fails, the capability searches the entire web, finds a similar page, and returns ok. That changes both authority and evidence. Another is “best effort” parsing that converts an invalid payload into a default query. Defaults are safe only when they are explicit, documented, and testable. A default must never broaden the source or action boundary.
Hands-on lab — write the negative cases first
Create four fixture files or structured test objects: valid request, overlong query, source outside the allowlist, and a request that asks to send, publish, or delete. For each, record expected status, invocation count, and sideEffects. The last three must finish without network or browser activity. Add a fifth case for an allowlisted source that returns no matching evidence; it should be ok with findings: [], not a failure.
Expected output is a table like this:
| Fixture | Status | Invocation | Side effects |
|---|---|---|---|
| valid | ok |
1 fixture call | [] |
| overlong | invalid_request |
0 | [] |
| outside allowlist | invalid_request |
0 | [] |
| publish request | side_effect_blocked |
0 | [] |
| no matching evidence | ok |
1 fixture call | [] |
Failure cases include a validator that calls the tool before checking sources, a parser that loses the source URL, a retry that repeats a write request, or a test that checks only status while ignoring sideEffects. Roll back by disabling the capability and returning invalid_request for every input until the contract and fixtures agree. Do not “fix” a failing safety test by weakening the expected denial.
Local practice
Contract review
Every step remains visible without JavaScript. When enabled, this browser stores checks on this device only.
0 of 5 checked
Checkpoint
A source returns HTTP 403. Which result is truthful?
A. ok with an empty list
B. source_unavailable plus the source URL and retry guidance
C. Retry against an arbitrary mirror
D. Ask the model to infer the missing content
Answer: B. The learner needs a distinguishable, reproducible failure. A status code does not license a substitute source or invented evidence.
Learner artifact and evidence receipt
Submit the request and result schemas, the five fixture cases, and a contract-flow diagram. Annotate which gate produces each failure and prove that the blocked-side-effect path terminates before invocation. Include the pinned OpenClaw revision 2d2ddc43d0dcf71f31283d780f9fe9ff4cc04fe4 and links to the MCP source and skills source. A reviewer should be able to run the fixtures without secrets, accounts, or live writes. Re-check the pinned references when the implementation surface changes; they bound platform concepts, while the worksheet remains the evidence for this decision.
Source provenanceVerification and sources
Review receipt rr_skills_contracts
- Outcome
- approved
- Method
- source-review
- Reviewer
- academy-editorial
- Reviewed
Evidence
- openclaw-docs-mcp — cc570a7-docs-tools-mcp; snapshot
37fc1164d79d… - openclaw-docs-skills — cc570a7-docs-tools-skills; snapshot
5a734c2f8488…
Limitations
- Approval covers the bounded instructional claims, pinned primary sources, and disposable fixture evidence; no personal profile, production account, or external write was used.
Lesson checkpoint
Ready to move on?
Mark this lesson complete when you can apply its outcome without relying on the examples above.