Capstone extension design review
Exercise objective
Given a real extension requirement, complete a source-evidence-driven design review before deciding whether to implement it. The central task is to prove “why this belongs at this boundary” and “what the minimum modification surface is.”
Prerequisites
- Complete the read-only Tool plugin exercise.
- Read every extension-development chapter.
- Be able to separate confirmed facts, inferences, and unknowns using source and test evidence.
Choose one scenario
Pick one of these three:
A. Internal enterprise knowledge lookup
Requirement: query internal documents through an existing HTTP service.
Decide:
- native Tool or MCP;
- private-network SSRF allowlist;
- token configuration;
- read-only behavior and rate limiting;
- result truncation and citations.
B. New OpenAI-compatible model platform
Requirement: integrate a Provider that is not registered but claims OpenAI compatibility.
Decide:
- whether
customis already sufficient; - whether a
ProviderSpecis needed; - real compatibility of Tool Calls, streaming, and reasoning;
- retry metadata;
- registry order.
C. Webhook chat platform
Requirement: receive an HTTP POST and send the result to an external callback.
Decide:
- Channel plugin;
- sender, chat, and Session identity;
- authentication, pairing, and replay;
- start/stop lifecycle;
- delivery retry and idempotency;
- SSRF and callback allowlist.
Required source reading
Select the row for your scenario:
| Scenario | Core source | Comparison tests |
|---|---|---|
| A | agent/tools/web.py, agent/tools/mcp.py, security/network.py | tests/tools/test_web_fetch_security.py, test_mcp_tool.py |
| B | providers/registry.py, openai_compat_provider.py, factory.py | one simple Provider test + test_provider_retry.py |
| C | channels/base.py, registry.py, manager.py | test_base_channel.py, test_channel_plugins.py |
Expected observations
After reading, you should usually find that:
- most extensions first belong in an edge adapter, registry, or plugin contract—not AgentLoop;
- “it connects” proves only transport; schema, lifecycle, cancellation, retry, and security remain separate contracts;
- configuration, discovery, execution, and presentation may belong to different modules, so the change matrix rarely contains one file;
- a requirement may depend on external protocol facts the source cannot prove; preserve those as to be confirmed;
- a dependable design can test most behavior with pure-function and contract tests, reserving a real service for the final smoke test.
Deliverable 1: boundary decision
Complete this table:
| Question | Decision | Source or documentation evidence | Unknown |
|---|---|---|---|
| Extension type | |||
| Who discovers it? | |||
| Input contract | |||
| Output contract | |||
| Configuration location | |||
| Lifecycle | |||
| Security boundary |
Include at least one rejected alternative and a concrete reason for rejecting it.
Deliverable 2: call chain
Draw a Mermaid diagram that includes at least:
- the external entry point;
- the adapter;
- the nanobot core boundary;
- state or message changes;
- result delivery;
- the error path.
Do not draw services that do not exist. Label any node the source cannot establish as “to be confirmed.”
Deliverable 3: minimum change matrix
| File or package | Purpose of change | Required or optional | Corresponding test |
|---|---|---|---|
Requirements:
- if core
loop.pyorrunner.pymust change, explain why an edge adapter cannot solve the problem; - configuration, registration, tests, and documentation must remain paired;
- do not add abstraction layers for hypothetical future use.
Deliverable 4: failure modes
Analyze at least:
- invalid arguments;
- authentication failure;
- timeout or cancellation;
- duplicate requests;
- failure after partial output;
- process shutdown;
- secret leakage;
- unauthorized access or SSRF;
- version or protocol incompatibility.
For each item, state:
- observable symptom;
- handling layer;
- whether to retry;
- whether it is idempotent;
- how to test it.
Deliverable 5: test pyramid
flowchart BT A["Pure-function and schema tests"] --> B["Adapter contract tests"] B --> C["AgentLoop or Registry integration"] C --> D["One real smoke test"]
Keep the real service at the top. Do not let network tests replace deterministic lower layers.
Completion criteria
- All five deliverables are complete.
- Every implementation fact cites source, a test, or official documentation.
- Unknowns are stated explicitly.
- The implementation scope fits in one small pull request.
- Security and rollback plans are actionable.
- A peer can reconstruct the complete call chain from the design alone.
Verification
Use these questions for self-review:
- If one proposed new file is removed, does the design still work?
- Is there an edge implementation that avoids changing AgentLoop?
- Does the design confuse real-service failures with model failures?
- Does it account for existing streaming, cancellation, and fallback behavior?
- Could a test contact a network or real account accidentally?
- Does the documentation explain what a user must configure instead of merely listing class names?
Review questions
- Did your initial extension type change? What evidence changed it?
- Which unknown would materially change the design?
- Which test would expose a contract error earliest?
- Which proposed change is most likely to couple core and runtime surfaces?
After completion, continue to Quick reference and turn the common entry points into your own source index.