Retraction sweep evidence diagnostics report

Date: 2026-10-24. Status: findings and suggested follow-up only; no implementation or production repair performed. This is a source review report, not a new Railspike implementation cycle or an approval of changes.

Production observation

text
./v3 retraction-sweep preview
Retraction sweep failed: Retraction evidence unavailable; repair canonical state before cleanup.

The message establishes that ExchangeRetractionState::read() returned null. It does not identify the failing record or prove corrupt canonical data. preview() throws before artifact scanning or exchange-store inspection; this invocation performed no cleanup. Production filesystem, configuration, permissions, Git history and deployed revision have not been inspected directly.

The absent-target condition is a plausible explanation given the separately documented production incident involving retained retractions for deleted replies. It is not a confirmed diagnosis of this command. The high-traffic publication assessment is related context, not evidence that fixing publication also fixes this sweep.

Sources: CLI (source unavailable), sweep (source unavailable), evidence reader (source unavailable), removal evidence (source unavailable), record loader (source unavailable), signature and operator authority (source unavailable), operational reference, related publication assessment (source unavailable).

Failure inventory and suggested responses

Proposed codes below are suggestions, not currently supported CLI output. Report repository-relative paths and identifiers in operator diagnostics, without post bodies, credentials or raw subprocess output containing secrets.

Condition in current evidence scanSuggested diagnosticSuggested recovery or engineering response
Selected root has no readable records/ directoryrepository_records_missing or repository_records_unreadable, selected root and selection sourceShow precedence: explicit --repository-root, then FORUM_REPOSITORY_ROOT, then application state/local_repository. Confirm intended instance and mount before changing records; report missing versus inaccessible separately.
Git metadata exists, but git ls-tree ... HEAD failscanonical_git_failed, operation, exit status and sanitized causeDistinguish unavailable Git, ownership/safe-directory rejection, unreadable metadata, invalid HEAD, damaged history and other command failures. Correct the specific environment/history problem; do not broadly disable Git ownership protections.
Git tracks a retraction .txt file that is missing or unreadabletracked_retraction_missing or tracked_retraction_unreadable, pathInspect checkout/sparse-checkout, filesystem and access rights. Restore only reviewed trusted evidence where appropriate; do not discard unrelated changes.
Removal evidence tracked in HEAD is absenttracked_removal_missing, pathInspect checkout completeness and trusted history. Keep cleanup blocked until required evidence is recovered.
Removal JSON is unreadable, unsafe, too large, invalid JSON or structurally invalidSeparate removal_unreadable, unsafe_evidence_path, removal_too_large, removal_parse_invalid, removal_structure_invalidIdentify the file and violated constraint; preserve original bytes and recover trusted evidence rather than manufacturing acceptance. Cover invalid source/thread IDs, hashes, operation and label bindings.
Removal record lacks exact-byte trusted local acceptance, or Git lookup failsremoval_acceptance_missing versus canonical_git_failed, pathDetermine whether trusted acceptance history is missing, shallow or unavailable. Imported files alone do not establish authority. Restore trusted history or use the existing reviewed acceptance process with sufficient source evidence.
Retraction directory is a symlink, wrong file type, unreadable, or cannot be listedunsafe_evidence_path, evidence_not_directory, evidence_directory_unreadable, evidence_listing_failedShow the specific directory and reason. Verify intended layout and permissions. Preserve symlink rejection; do not automatically follow arbitrary links.
Individual retraction is a symlink, unreadable, cannot be hashed, or changes/disappears during scanningunsafe_evidence_path, retraction_unreadable, evidence_hash_failed, evidence_changed_during_scanReject unsafe paths; recover permissions or a stable checkout. Use bounded retries only for demonstrated transient changes, followed by an explicit retryable failure. Bind validation and hashing to consistent bytes.
Retraction headers/body, identifiers, timestamp, operation, classification or filename are invalidretraction_parse_invalid or retraction_path_mismatch, path and safe parser reasonReport the exact failed rule. Preserve invalid evidence for investigation; recover an authentic valid record through the existing process.
Signature is invalid, or an operator retraction lacks a verified signatureretraction_signature_invalid or operator_signature_unverifiedPreserve current acceptance rules. Distinguish bad signature from missing key, unavailable verifier or other verification failure where the verifier can establish that distinction. Do not assume every unverified author record currently fails: loader policy treats author/operator cases differently.
Operator retraction lacks content-bound local acceptanceoperator_acceptance_missing, record path and required evidence categorySeparate missing acceptance from failed Git lookup in the authority helper. Restore trusted history/authority evidence or perform an explicitly reviewed existing acceptance procedure; never synthesize an acceptance commit just to pass validation.
Referenced post exists but cannot be read or parsed, or its path does not match its IDtarget_post_unreadable, target_post_parse_invalid, target_post_path_mismatchIdentify retraction path, post ID and attempted target paths; retain nested safe parser cause. Include legacy timestamp recovery failures as a distinct reason when known.
Referenced post is absent from both resolver candidates and no accepted delete removal supplies authorityretraction_target_absent, post ID, retraction path, attempted paths and removal-evidence statusDescribe an absent target, not generic corruption. Inspect whether deletion was intentional and whether trusted removal evidence exists. Do not restore deleted prose or delete retained retractions merely to satisfy the sweep. Separately assess safe absent-target cleanup semantics before relaxing the current guard.
Unexpected exception in removal or retraction processingevidence_scan_internal_error, phase and correlation IDPreserve the exception chain privately; expose a concise operator message. Keep unknown failures blocking and never convert them into an empty retraction list.

Important distinctions: an absent records/post-retractions/ directory is currently allowed if no tracked evidence is missing and removal scanning succeeds. A parsed retraction that does not apply to an existing post is not itself this failure: RetractedPosts::applies() returns false for author mismatch, protected authority posts and other inapplicable cases. Report those as separate scan outcomes where useful, without granting suppression authority. The strict sweep reader and absent-tolerant snapshot reader have different contracts; do not substitute one for the other globally.

Suggested error-reporting contract

  1. Replace the information-losing null boundary internally with a typed result carrying success/blocked state, effective IDs, scan completeness and structured issues. Preserve compatibility for callers that require null on any failure until deliberately migrated. Never use partial IDs to authorize destructive cleanup.

  2. Each issue should contain a stable code, phase, safe relative path, applicable post/record ID, cause category, retryability and concrete next action. Record selected repository and configuration source once. Retain a sanitized exception chain in private diagnostics, with a correlation ID for unexpected failures.

  3. Human output should lead with the actual blocker and explicitly state that preview cleanup did not occur. For example: Retraction preview blocked [retraction_target_absent]: <post-id>; evidence: records/post-retractions/<record>.txt. Neither expected post path exists and no accepted deletion evidence was found. No cleanup performed. Show safe inspected paths and the relevant recovery action next.

  4. Make --json failures structured on a documented stream, with nonzero exit status and stable fields such as status, code, issues, scan_complete, repository_root, configuration_source, retryable and cleanup_performed. Currently exceptions always produce plain text on stderr even with --json.

  5. A read-only evidence diagnostic command/mode should collect a bounded number of independent issues, report truncation and scan completeness, and permit continuation past a bad record for diagnosis only. Bound expensive Git/history work as well as issue count; the existing sweep row limit does not cap canonical validation.

  6. Carry the same issue codes through manual run, persisted sweep status, task-queue failures and private logs. Currently run saves only failure: cleanup_failed, the worker reduces errors to a generic cleanup message, and preview does not save its failure. Preserve preview's read-only behavior rather than writing a status file as an incidental diagnostic side effect.

  7. Keep public/browser output concise and omit private paths and evidence details; place detailed reporting in operator CLI/private diagnostics. Do not expose removed prose, signatures, key material or entire records in errors.

Suggestions for absent-target cleanup

Treat this as a separate behavior decision from better messages. An intentionally absent post can still have surviving derived HTML or exchange payloads. Simply ignoring its retraction can therefore leave content behind. Conversely, treating every parsed record as effective removal can grant unsupported authority.

Compare retaining strict cleanup with actionable evidence repair against a narrowly authorized absent-target cleanup design. The latter must establish which evidence is sufficient, prove dependency/exclusion behavior for generated artifacts and exchanges, retain malformed/untrusted evidence failures, and fence concurrent deletion, reappearance and evidence changes. Existing snapshot handling is useful precedent, not automatic authorization or proof of sweep correctness. Keep published replies, canonical history and other excluded stores outside cleanup scope.

Suggested verification and delivery sequence

  • First add source-level reason preservation and read-only diagnostics, then propagate those reasons through CLI, JSON, status and worker reporting. Preserve current cleanup authority while making production diagnosis actionable.

  • Cover every inventory row with existing-style fixtures, including missing/unreadable directories and files, broken Git/HEAD, missing tracked files, unsafe paths, malformed records/JSON, signature and acceptance failures, invalid posts/legacy timestamps, and absent targets with and without accepted deletion evidence. Verify permission cases under a user for whom access restrictions actually apply.

  • Verify success controls: no retractions, accepted deletion of an absent target, valid author/operator records, nonapplicable retractions and normal bounded cleanup. Check that a late scan failure never permits partial destructive cleanup.

  • Assert human messages, structured JSON errors and nonzero exit codes; verify private persisted/worker causes and redaction. Confirm preview/diagnostics create no databases, progress files or canonical changes. Add concurrency/retry checks for file replacement and target reappearance before considering changed absent-target semantics.

  • In production, first collect the deployed revision, selected repository/configuration source and read-only evidence diagnosis under the actual CLI and worker users. Select recovery only after the blocker is known; rerun preview before any cleanup. A clean local source review does not establish production recovery.

Dependency delta for this report: zero. No runtime code, production state, task queue, UI, existing effort-study records or todo.txt changed. Implementation proposals require the normal project planning and approval process.