Deferred from #455 (item 5). cfl attachment list --unused has three compounding defects that make its output unreliable:
- Representation-blind: it re-fetches the page requesting only the
storage body (tools/cfl/internal/cmd/attachment/list.go:69-83) and treats missing/empty storage as an empty page body. ADF-native pages therefore classify every attachment as unused (false positives).
- Pagination-incomplete: the unused filter runs only over the single fetched attachment page (capped by
--limit, default 25). Attachments beyond the first page are never examined, so results can be incomplete or misleading. HasMore() is only surfaced in the footer, not used to complete the scan.
- Naive reference detection: usage is
strings.Contains(body, filename) (list.go:117), so an attachment counts as "used" if its filename appears anywhere in the page text, including prose (false negatives).
A correct implementation must:
- Inspect attachment references in both ADF and storage XHTML representations, using structural references (e.g. ADF media nodes,
ri:attachment elements) rather than substring matching.
- Paginate through attachments until it has enough unused results or exhausts the attachment list.
- Keep stdout data-only and route any advisory prose to stderr, per the repo output contract.
Until then, --unused remains as-is (per #455's breaking-change batch, which deliberately did not touch it).
Deferred from #455 (item 5).
cfl attachment list --unusedhas three compounding defects that make its output unreliable:storagebody (tools/cfl/internal/cmd/attachment/list.go:69-83) and treats missing/empty storage as an empty page body. ADF-native pages therefore classify every attachment as unused (false positives).--limit, default 25). Attachments beyond the first page are never examined, so results can be incomplete or misleading.HasMore()is only surfaced in the footer, not used to complete the scan.strings.Contains(body, filename)(list.go:117), so an attachment counts as "used" if its filename appears anywhere in the page text, including prose (false negatives).A correct implementation must:
ri:attachmentelements) rather than substring matching.Until then,
--unusedremains as-is (per #455's breaking-change batch, which deliberately did not touch it).