Skip to content

STARTER_GUIDE.md step 3 claims dedup works, but dedup is M5 scope (not shipped) #165

Closed as not planned

Description

@amar-python

Context

Found during PR #63 review on 3 Nov 2026.

docs/STARTER_GUIDE.md (added by PR #63) includes a "Your first change: a guided walkthrough" section with 5 steps. Step 3 is actively wrong:

  1. Re-upload the same file. Confirm duplicate detection kicks in (content-hash based, not filename based).

The current app does not have content-hash dedup. That capability is scoped to ART Milestone 5 (#109: "dedup and naming — per-tenant file dedup, record dedup, versioned datasets, BR-28..31"), which has not been started.

A new reader following step 3 will see no "duplicate detected" response. They'll either think they did something wrong, or that the walkthrough is wrong.

Options

(a) Remove step 3 entirely until M5 ships. The remaining 4 steps still exercise both modes and the test suite — still a useful ten-minute walkthrough.
(b) Mark step 3 as "when M5 ships". Leaves readers knowing dedup is coming, but doesn't invite them to try something that won't work.
(c) Both — remove it from the main numbered sequence, add a short "coming in M5" note in the surrounding prose.

Done when

  • Decision taken on (a)/(b)/(c)
  • docs/STARTER_GUIDE.md edited accordingly, one small PR
  • When M5 ships, the step comes back (if removed) or the "coming" note goes away

Related

Activity

  1. amar-python commented on Nov 8, 2026

    @amar-python
    OwnerAuthor

    Closing: dedup is shipped for dynamic mode — the step was ambiguous, not wrong

    Checked against main at 74c248f. The issue's premise ("the current app does not have content-hash dedup") is incorrect. Dynamic mode has both checks, in this order:

    • api/services/dynamic_loader.py:149 — filename check: SELECT ... FROM {schema}.csv_files WHERE file_name = %s
    • api/services/dynamic_loader.py:188 — content hash check: SELECT ... WHERE file_hash = %s

    Either match returns {"status": "duplicate_file", "reason": "content" | "name", ...} when overwrite is false. The frontend renders it: csv-table-hub-main/src/lib/job-outcome.ts:69 ("Duplicate detected"), src/routes/_authenticated/index.tsx:104 (duplicate: "Duplicate file"), and it is covered by src/__tests__/uploader-state-machine.test.ts:102,163.

    So a reader following step 3 in dynamic mode does see duplicate detection. Removing the step (option a) or deferring it to M5 (option b) would both have deleted a working, demonstrable feature from the walkthrough.

    The real defect

    Step 3 said "re-upload the same file" and came straight after step 2, which is the T&E upload. T&E mode does not refuse duplicates — te_loader._cleanup_prior_registry_entries (api/services/te_loader.py:87) deletes any row matching file_name OR file_hash and re-inserts. A reader who re-uploaded the T&E file saw a successful import and concluded the walkthrough was broken, which is probably how this issue got filed.

    Two further imprecisions in the old wording: "content-hash based, not filename based" — it is both, filename first; and the step did not say which mode the claim applies to.

    Fixed in #206

    Step 4 (after renumbering for #166) now names the dynamic-mode file, states that either a filename or a content-hash match triggers the rejection, and scopes the claim to dynamic mode with #109 cited for the per-tenant/per-record dedup still to come. Closing as not applicable — none of options (a)/(b)/(c) was the right change.

    #109 is unaffected. BR-28..31 (per-tenant file dedup, record-level dedup, versioned datasets) remain M5 scope. What exists today is global, per-file dedup within a schema — not the per-tenant or per-record dedup M5 will add.


    Verified by Claude Code against main at 74c248f


    Generated by Claude Code

  2. added 2 commits that reference this issue on Nov 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions