You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
STARTER_GUIDE.md step 3 claims dedup works, but dedup is M5 scope (not shipped) #165
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:
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
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
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.
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.
Activity
docs: supersede API_INTEGRATION.md, fix starter/quickstart refs (#164 #…
amar-python commentedon Nov 8, 2026
Closing: dedup is shipped for dynamic mode — the step was ambiguous, not wrong
Checked against
mainat74c248f. 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 = %sapi/services/dynamic_loader.py:188— content hash check:SELECT ... WHERE file_hash = %sEither match returns
{"status": "duplicate_file", "reason": "content" | "name", ...}whenoverwriteis 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 bysrc/__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 matchingfile_name OR file_hashand 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
mainat74c248fGenerated by Claude Code
docs: drop STARTER_GUIDE/QUICKSTART/API_INTEGRATION/README edits; #206 …
Merge pull request #206 from amar-python/docs/starter-guide-walkthrou…