Retract documents a source took off a meeting - #329
Conversation
An import only ever added: a document the supplier stopped listing stayed in search, storage and the export feed until someone removed it by hand, even when the meeting it belonged to was fetched again the next night. Each run now compares a meeting's attachment list with the one in the export log. A dropped document is retracted (delete marker, one batched Quickwit delete task, object storage, export tombstone; no blocklist, so a republished document comes back) only when: - the meeting still lists at least one of its earlier documents, - the document was not emitted elsewhere in the run and no other live meeting or motion of the source lists it, - the run has at most WOOZI_SOURCE_REMOVALS_MAX_PER_RUN (25) candidates, - the supplier confirms it is gone with the revalidation sweep's calibrated responses, after a still-listed document answered "live". iBabs and Notubiz only; WOOZI_SOURCE_REMOVALS=0 turns it off.
|
Kleine aanvulling qua auditability / herleidbaarheid en controleerbaarheid. Als documenten ingetrokken worden, dan is dat niet erg. Ik lees echter niks over een audit trail die dit beschrijft. Ik zal een analyse toevoegen, want het raakt de rechtszekerheid als openbesluitvorming.nl ook dient als middel om aan wettelijke eisen te voldoen. |
Intrekken bij de bron: wel doen, maar met een controleerbaar spoorDat een document verdwijnt als de bron het intrekt, is juist. Deze reactie gaat over wat er daarna overblijft. Na een intrekking moet nog vast te stellen zijn dat het document bestaan heeft, in welke periode, bij welke vergadering en waarom het verdween. Dat lukt nu maar gedeeltelijk. Deze PR voegt een pad toe dat documenten verwijdert zonder reden en zonder bewijs. Alle verwijzingen gaan naar commit Waarom dit nodig is
Wat na een intrekking nog vast te stellen isWel:
Niet:
Technische discrepanties
Voorgestelde aanpakVóór de merge:
Daarna:
|
Review of #329: a retraction removed documents without a recorded reason or evidence, and a failure halfway could hide a document from search while the export feed still served it as an upsert, with no later run to notice. - Each document is finished before the next: delete marker, tombstone, then object storage. A failure stops that document at the step it reached and the outcome says which; one delete task covers every tombstoned document. - Delete records carry `reason` ("takedown", "removed_at_source", "source_purged") and, for a source removal, `meeting_id`. Additive. - Every retracted, kept or half-finished document becomes a run issue (step source_removals, new severity "info", or "warning" when unfinished) with the supplier's answer, the control document's answer and the step reached as details. - The revalidation sweep uses src/documents/source_presence.ts, so there is one calibration (and one timeout, 30 s) instead of two. - AGENTS.md says the automatic path is a deliberate policy change and how it relates to the sweep; API.md documents `reason` and `meeting_id`. - Tests for the retraction itself, including a storage failure halfway and a failure before the marker.
Requested by Joep · project thread
Before: when a griffie deleted a document at the source, it stayed in search, in object storage and in the export feed until someone removed it by hand. That held even though the nightly import fetched its meeting again.
After: if the nightly import finds a document taken off a meeting and the supplier confirms the file is gone, the document disappears from search, its stored files are deleted, and the export feed gets a tombstone. Nothing is blocklisted, so if the source publishes the document again it comes back.
How:
SourceRemovalTracker(src/pipeline/source_removals.ts) compares each meeting'sattachmentlist with the copy in the export log, just before the new version is committed. After extraction, the dropped documents go through these guards in order:findReferencedEntityIds).WOOZI_SOURCE_REMOVALS_MAX_PER_RUNcandidates (default 25). Above that, nothing is removed and a run warning is logged.<error_code>(src/documents/source_presence.ts). Before any candidate is checked, a document the meeting still lists must answer "live". That way an outage or an iBabs block cannot pass for a removal. A document that was only unlinked from the agenda but still downloads is kept.Retraction reuses the takedown steps in
src/ops/delete_document.tsexcept the blocklist. It ingests delete markers with aremoved_at_sourcekind and creates one batched Quickwit delete task per run, since a marker alone does not hide full-text hits. It then deletes the S3 prefixes and records the tombstone before the run's export flush.Scope and limits:
WOOZI_SOURCE_REMOVALS=0turns it off.ibabsDownloadRateLimiter, at most 26 per run.Checks:
deno test --no-run -Ais clean,deno test -A tests/gives 371 passed,oxlintadds no warnings andoxfmt --checkis clean on the changed files. The new test file istests/source_removals.test.tswith 11 cases.Generated by Claude Code