Summary
Spec v0.1.2 (attachment-guide.md) defines basic_clean as a distinct scan_status value in §5, but the §3 payload schema and the §3 routability constraint were not updated alongside that introduction. Two conflicting normative statements result; strict-validating consumers reject basic_clean while §5 explicitly permits it.
The three lines in conflict
§3 Attachment Object Schema, line ~220 — payload schema enum (excludes basic_clean):
scan_status | enum | Yes | Security scan result: pending, clean, suspicious, or rejected.
§3 Constraints, line ~224 — routability constraint (excludes basic_clean):
scan_status in routed message payloads MUST be clean or suspicious — never pending or rejected.
§5 scan_status Values, line ~429 — table introduces basic_clean and marks it routable:
| Value |
Meaning |
Can route? |
pending |
Upload in progress or scan not yet started |
No |
clean |
Passed all scanning checks |
Yes |
basic_clean |
Passed required checks only (no AV/injection scan) |
Yes |
suspicious |
Passed but flagged with injection patterns |
Yes (with warning) |
rejected |
Failed one or more required checks |
No — file deleted |
Failure mode for strict validators
The §3 line ~220 enum is the harder failure: a peer that schema-validates incoming payload.attachments[*].scan_status against the §3 enum will reject any message carrying basic_clean before it ever evaluates the §3 routability rule. This is silently incompatible with §5's stated intent that providers without AV/injection scanning emit basic_clean.
Our interpretation (looking for confirmation)
We're treating the §5 table as authoritative because:
- §5 is the section that introduces
basic_clean as a distinct state with explicit semantics ("Passed required checks only").
- §5 carves out the exact case (
MUSTs passed, no SHOULDs) that an AV-less provider sits in, including the §5 pipeline diagram which shows clean | basic_clean | suspicious | rejected as the four terminal states.
- The §3 enum and the §3 "MUST be clean or suspicious" constraint read as pre-
basic_clean text that was not updated when the four-state model landed.
If that reading is wrong, please correct — happy to revisit our impl.
Suggested v0.1.3 reconciliation
Update both §3 lines in lockstep so all three normative statements agree:
- §3 line ~220 — extend the schema enum to
pending, clean, basic_clean, suspicious, or rejected.
- §3 line ~224 — rewrite the routability constraint to
MUST be \clean`, `basic_clean`, or `suspicious` — never `pending` or `rejected`.`
The §5 table already states the intended semantics; the change is just propagating it to §3.
Reference implementation
We hit this while closing out our internal scanner audit against v0.1.2: swickson/ai-maestro#145 (merged). Our /v1/attachments/[id]/confirm route emits basic_clean on the MUSTs-passed success path; downstream /download, /status, and GET /v1/attachments/[id] accept both clean and basic_clean per the §5 table.
— filed by an AMP-protocol reference-impl consumer; happy to PR the spec edit if useful.
Summary
Spec v0.1.2 (attachment-guide.md) defines
basic_cleanas a distinctscan_statusvalue in §5, but the §3 payload schema and the §3 routability constraint were not updated alongside that introduction. Two conflicting normative statements result; strict-validating consumers rejectbasic_cleanwhile §5 explicitly permits it.The three lines in conflict
§3 Attachment Object Schema, line ~220 — payload schema enum (excludes
basic_clean):§3 Constraints, line ~224 — routability constraint (excludes
basic_clean):§5 scan_status Values, line ~429 — table introduces
basic_cleanand marks it routable:pendingcleanbasic_cleansuspiciousrejectedFailure mode for strict validators
The §3 line ~220 enum is the harder failure: a peer that schema-validates incoming
payload.attachments[*].scan_statusagainst the §3 enum will reject any message carryingbasic_cleanbefore it ever evaluates the §3 routability rule. This is silently incompatible with §5's stated intent that providers without AV/injection scanning emitbasic_clean.Our interpretation (looking for confirmation)
We're treating the §5 table as authoritative because:
basic_cleanas a distinct state with explicit semantics ("Passed required checks only").MUSTs passed, no SHOULDs) that an AV-less provider sits in, including the §5 pipeline diagram which showsclean | basic_clean | suspicious | rejectedas the four terminal states.basic_cleantext that was not updated when the four-state model landed.If that reading is wrong, please correct — happy to revisit our impl.
Suggested v0.1.3 reconciliation
Update both §3 lines in lockstep so all three normative statements agree:
pending,clean,basic_clean,suspicious, orrejected.MUST be \clean`, `basic_clean`, or `suspicious` — never `pending` or `rejected`.`The §5 table already states the intended semantics; the change is just propagating it to §3.
Reference implementation
We hit this while closing out our internal scanner audit against v0.1.2: swickson/ai-maestro#145 (merged). Our
/v1/attachments/[id]/confirmroute emitsbasic_cleanon the MUSTs-passed success path; downstream/download,/status, andGET /v1/attachments/[id]accept bothcleanandbasic_cleanper the §5 table.— filed by an AMP-protocol reference-impl consumer; happy to PR the spec edit if useful.