AUR-021: Fixar MCP conformance e segurança
Documento histórico do board. Pode descrever componentes removidos; para uso atual, consulte o guia do produto.
This is a research/decision card. It does not ship an executable feature or
start any MCP server; it fixes a design contract a later O11-mcp card
implements against. The observable behavior is the acceptance lint itself:
tests/acceptance/AUR-021.sh deterministically resolves the artifacts below
and either passes or names exactly which one is incomplete.
Behavior
tests/acceptance/AUR-021.sh (selector AC-001) reads six artifacts this
card owns and checks that they resolve to one consistent, testable pin,
without making any network request:
.board/research/mcp.md— contains, case-insensitive, every term listed intests/specs/AUR-021/required-terms.txt(stdio,read-only,OAuth,injection,capabilityat time of writing), and a## Sources matrixtable with at least 5 data rows, each citing a[label](url)source whose host is allowlisted (tests/specs/AUR-021/allowed-source-domains.txt), a parseable version, an ISO-8601 date, and a non-empty "what it fixes" cell.standards/mcp/protocol.yaml— declaresprotocol.versionas an ISO-8601 date andgo_sdk.module/go_sdk.versionas a semantic version; both version strings must also appear verbatim in.board/research/mcp.md, so the pinned standard cannot silently diverge from the source that justifies it.standards/mcp/tools.yaml— every declared tool hasclass: read_onlyorclass: mutable; everymutabletool setsrequires_explicit_consent: trueand noread_onlytool sets it; every tool named intests/specs/AUR-021/required-mutable-tools.txt(review.publishat time of writing) is present, classifiedmutable, and requires explicit consent.
Contract
tests/specs/AUR-021/required-terms.txt,tests/specs/AUR-021/allowed-source-domains.txt, andtests/specs/AUR-021/required-mutable-tools.txtare the single source of truth for, respectively, the literal terms the research document must contain, the hostnames aSources matrixlink may cite, and the tools that must be classifiedmutablewith explicit consent. The shell acceptance test reads all three instead of duplicating the lists.- A
Sources matrixrow'sVersioncell must match a semantic-version-like pattern (v1.6.1) or an ISO-8601 date, optionally followed by free text (2026-07-28 (RC locked 2026-05-21)); itsDatecell must be a plain ISO-8601 date. standards/mcp/tools.yaml's tool classification does not trust any MCP server's own self-reportedreadOnlyHint/destructiveHintannotations (the MCP specification itself treats those as untrusted unless the server is already trusted); it is this project's own, independently fixed policy.- This card produces no executable MCP server, transport, or tool registry.
The protocol/SDK pin and tool classification it fixes here are consumed
by a dependent
O11-mcpcard, not built here.
Limits
standards/mcp/protocol.yaml fixes the two pins this baseline requires:
protocol.version: the adopted MCP specification revision (2025-11-25);protocol.transports: the transports this baseline recognizes (stdio,streamable-http).go_sdk.module/go_sdk.version: the adopted Go SDK (github.com/modelcontextprotocol/go-sdkv1.6.1).
standards/mcp/tools.yaml fixes, per tool, a class of read_only or
mutable, and for every mutable tool a requires_explicit_consent: true
flag that a future server implementation must enforce before invocation.
Example (no secret)
Running the acceptance test directly, with no network access and no secret material of any kind:
$ ./.board/bin/oci-run --profile bootstrap-readonly-v1 --card AUR-021
{"card":"AUR-021","scenario":"AC-001","selector":"AC-001","required_terms":5,"source_rows":7,"result":"pass"}
A failing example — review.publish reclassified read_only in
standards/mcp/tools.yaml:
$ tests/acceptance/AUR-021.sh
AUR-021/AC-001/tool-misclassified: required tool review.publish must be class: mutable with requires_explicit_consent: true, got class=read_only requires_explicit_consent=
Diagnosis
AUR-021/AC-001/behavior-missing: required artifact absent: <path>— one of.board/research/mcp.md,standards/mcp/protocol.yaml,standards/mcp/tools.yaml, or atests/specs/AUR-021/*fixture is missing or empty. Restore it from the card's owned paths.AUR-021/AC-001/behavior-missing: required term missing from .board/research/mcp.md: <term>— one of the five required terms was removed or renamed; restore it, case-insensitively.AUR-021/AC-001/source-not-versioned: ...— aSources matrixrow is missing, cites a non-allowlisted host, has no versionedVersioncell, has a non-ISODatecell, or a pin's version string instandards/mcp/protocol.yamlno longer appears in the research document. Fix the offending cell or restore the citation.AUR-021/AC-001/tool-misclassified: ...— a tool instandards/mcp/tools.yamlhas an invalidclass, amutabletool is missingrequires_explicit_consent: true, aread_onlytool wrongly sets it, or a required mutable tool (review.publish) is missing or reclassified. Fix the tool'sclass/requires_explicit_consentfields.AUR-021/AC-001/infrastructure: ...— a required host tool is missing or the repository root could not be resolved; this is never a behavioral result and never counts as RED evidence for this card.
History: Integration proof path was escalated and resolved at v2
At version: 1, this card's declared paths entry and TDD-proof
"Integration" line named tests/integration/AUR-021.go::IntegrationAUR021.
A .go file without the _test.go suffix is invisible to go test's
scanner by definition of the Go toolchain, and IntegrationAUR021 was not
Test-prefixed either, so that path could never carry a real, discoverable
Integration proof — the same defect AUR-020's card carried at version: 1
(tests/integration/AUR-020.go::IntegrationAUR020), which round 1 vetoed
as dead code and round 2 vetoed as a working test delivered outside the
card's declared paths, resolved only by a governance version bump
(.board/cards/ready/AUR-020.md v2) retargeting the path to
tests/integration/AUR-020_test.go::TestAUR020Boundary.
Because .board/cards is this card's own forbidden_paths entry, the
builder could not make that same correction from inside the card. Per the
board's rule that an unimplementable spec is escalated rather than
silently worked around, no file was written at either the declared
dead-code path or an undeclared _test.go path in that round.
Governance resolved the escalation the same way it resolved AUR-020's: a
version bump to version: 2 (.board/cards/doing/AUR-021.md) retargeted
the TDD-proof "Integration" line to
tests/integration/AUR-021_test.go::TestAUR021Boundary. That file is now
part of this card's delivered paths, is discovered by go test ./...
with no external dispatcher, and is the Integration evidence this document
and the acceptance test currently rely on.