DataTalksClub / DataTalksClub/website
Harden historical registration source preparation and publish aggregate event counts
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Outcome
Finish the already-merged aggregate-only historical registration lane by hardening the local protected-source preparation boundary, preserving the authoritative public registration-count contract, and retaining the authorized real-source reconciliation as a separate HUMAN gate. Engineering dispatch is blocked on the explicit owner choice below.
The website persists reviewed aggregate counts and provenance only. It never imports or publishes a legacy attendee row, name, email, attendee/guest identifier or digest, answer, consent, timestamp, filename/path, or provider payload.
The currently authorized public event-detail wording is exact N registered for every event state. This is a registration aggregate, not attendance/check-in evidence. The unapproved past-event copy N came must not be treated as an engineer-ready requirement.
Product and architecture authority
- 02 — URL, SEO, robots, sitemap, and cache compatibility
- 05 — Event/registration ownership and privacy
- 06 — Studio/admin API parity
- 07 — Privacy, security, and protected data
- 09 — Idempotent migration controls
- 10 — Verification strategy
- Migration checklist
Specs 02, 05, and 10 and the explicit owner direction in comment 5231898150 are authoritative: the public label is N registered for every event state, and neither Luma approved nor Eventbrite Attending is attendance/check-in evidence. An issue rewrite cannot silently supersede those authorities.
Owner decision required before engineering
Choose exactly one:
- Keep the authoritative default —
N registered(recommended). Future/current/past canonical event details all use exact0 registered,1 registered, or<plural integer> registeredwhen accepted coverage is complete. Omission and all existing privacy/cache/surface rules remain unchanged. No attendance meaning is introduced and specs 02/05/10 remain aligned. - Explicitly approve time-aware presentation. Future/current details use
N registered; past details useN came. Approval must acknowledge thatcamepresents a registration-only aggregate in language that can imply attendance even though there is no check-in/attendance evidence. Specs 02, 05, and 10 must be amended and accepted before engineering starts; the amendment must continue to prohibit any attendance-state, export, API, audit, or evidence inference.
Until the owner records one choice, #112 is not engineer-ready. Do not implement the wording change or amend normative specs by inference. The otherwise bounded preparation hardening remains documented below but is not dispatched from this mixed issue while the product contract is unresolved.
Current safe source evidence
Committed aggregate/schema evidence from the protected preparation run records:
- Luma: 166 event pairs, 51,924 rows, 51,873
approved, 51declined, andmapping_review_required; - Eventbrite: the already-reviewed whole-source checksum, 209 CSV event files plus one unsupported XLSX, 24,001
Attendingrows, 209 event IDs, andmapping_review_required.
This supersedes the older Luma snapshot cardinalities in this issue. It does not establish the reviewed mapping partition for the refreshed 166-event Luma source. No engineer/tester may infer that the old 64/95 proposal/review split remains correct. The exact map/exclude/source-missing set is an authorized HUMAN result and activation remains closed until it is reviewed.
Only aggregate/schema facts, checksums, policy versions, state totals, and bounded reason codes may appear in source control, tests, logs, screenshots, APIs, or issue reports. Do not copy a protected local path, archive member/filename, provider event ID, attendee row/value, or secret into evidence.
Scope
1. Protected source-preparation boundary
Harden scripts/prepare_event_registration_sources.py and focused synthetic tests. The command may accept explicit source arguments, but the prepared outputs are restricted to the main checkout's gitignored protected migration-data root. It must reject a destination outside that root and reject symlinked/non-directory ancestors; --replace authorizes replacement of only the exact provider output below that root.
Use the same code-owned ceilings as the aggregate adapters unless a stricter preparation ceiling is documented:
- at most 5,000 source/archive entries;
- at most 512 MiB compressed Eventbrite archive input;
- at most 128 MiB per regular file/member;
- at most 2 GiB total expanded bytes;
- maximum 20:1 expansion for each compressed member;
- at most 2,000,000 parsed attendee rows.
Bounds are checked before or while bytes are consumed and before publishing a prepared output. Fail with a bounded code; never include a protected path/member/value in the error or report.
Luma
- The source root and
_jsonchild must be real directories, not symlinks. - Every consumed CSV/JSON must be a direct regular non-symlink file. Reject hidden, nested, special, unexpected, duplicate, case/normalization-colliding, or otherwise ambiguous input/output paths rather than silently ignoring or overwriting them.
- Require a one-to-one CSV/checkpoint pair and cross-check the checkpoint event identifier against the CSV event identifier(s).
- Validate exact required schema/status shape and bounded row/file/total counts before publication.
- Do not copy the checkpoint payload. Emit only the minimized adapter JSON already required by the aggregate importer and the attendee-level CSV copy.
Eventbrite
- Require one regular non-symlink archive within the compressed-size ceiling.
- Reject empty/too-many members, directory/hidden/absolute/traversal/backslash/symlink/special entries, duplicate raw paths, and duplicate or case/normalization-colliding prepared output paths.
- Accept only the exact wrapper CSV contract plus the one expected XLSX path. The XLSX is copied as opaque bounded bytes and is never parsed or converted.
- Validate every CSV header/status and row ceiling. Copy/read archive members through bounded streams; do not materialize an entire archive or attendee CSV in memory and do not retain attendee deduplication state beyond preparation.
- Enforce per-member expanded size, total expanded size, compression ratio, and actual streamed-byte agreement with declared metadata before publication.
Atomic output and permissions
- Build each provider output in a private sibling staging location beneath the protected root, validate it completely, fsync/close it, set modes, and atomically publish it. A failure leaves the prior accepted output byte-for-byte available and removes only task-owned staging artifacts.
- Use a restrictive process umask and explicitly force/verify
0700on protected directories and0600on prepared files/archives, regardless of the caller's umask or a pre-existing permissive target. ZIP member mode metadata is0600but does not replace filesystem-mode enforcement on the output archive. - Never follow a destination symlink and never recursively delete an unresolved/user-controlled path.
- Stdout is one aggregate-only JSON result. Stderr/exceptions/logs contain bounded codes only.
2. Public count representation
- On the canonical event detail only, complete accepted coverage renders an exact unrounded non-negative integer.
- Pending the owner decision above, the authoritative behavior is
N registeredfor future, current, and past events.N cameis not approved for implementation. - Incomplete, review-required, source-missing, quarantined, or uncertain coverage omits the count; it is never shown as zero.
- Hub, sitemap, structured data, search, cache metadata, serializers, and management APIs do not gain the public copy or provider split.
- Existing no-store/zero-TTL, revision, invalidation, redaction, no-double-count, replacement, rollback, Studio/API permission, masking, and audit contracts remain unchanged.
3. Reconciliation profile update boundary
The committed refreshed Luma aggregate facts require a new versioned code-owned reconciliation profile before real staging/activation. The engineering patch may add the profile shape and fail-closed selection, but it must not invent mappings or derive them from titles, slugs, dates, filenames, or similarity. Exact provider identity may create a proposal only; every remaining event requires authorized map/exclude review. The prior profile remains immutable for replay/audit.
No real protected source is opened by engineering or automated testing. The authorized operator supplies the final exact refreshed mapping-set revision and redacted aggregate result during the HUMAN gate.
Dependencies and delivery status
- #64 is a hard dependency for real protected-source handling, retention/disposal, reconciliation, and activation. Automated hardening may proceed with synthetic fixtures while #64 remains open.
- #105's accepted canonical event identity is the overlay key. Full #45 lifecycle is not a prerequisite for this bounded aggregate lane.
- #46/#47 govern future native registration/attendance rows and their no-overlap cutover; they do not block preparation hardening or historical aggregate-only review.
- #109 gates positive anonymous edge caching only. Until it passes, any detail carrying a count remains zero-TTL/no-store.
- The issue remains open with
human. The engineer eventually commits accepted automated work withRefs #112, notCloses #112.
Priority remains P0 because the current preparation command handles attendee-level protected material without the complete bounded/permission/atomic-output contract and the HUMAN migration gate is blocked on it.
Non-goals
- No legacy attendee/registration row, answer, consent, identity, email, name, provider attendee ID/digest, or timestamp import.
- No public attendee card, identity, directory, search, list, export, or provider breakdown.
- No inference that a registration means attendance/check-in; no attendance state/status migration.
- No fuzzy/automatic mapping, silent event creation, inferred zero, unreviewed overlap/addition/replacement, or reuse of the stale Luma 64/95 partition.
- No Luma/Eventbrite API, webhook, write-back, credential handling, ticket/payment/QR/wallet import, newsletter/sponsor/email/consent side effect.
- No arbitrary upload/path support in Studio or admin API.
- No broad #45/#46/#47 implementation, positive-cache rollout, production deployment, or public indexing change.
- No production/protected fixture, archive, row, filename, local path, credential, or mapping value in repository tests or screenshots.
Acceptance criteria — automated implementation
- The owner records choice 1 or choice 2 above. Under choice 1, specs 02/05/10 and tests continue to require
N registeredfor all event states. Under choice 2, the owner first accepts corresponding spec amendments and the non-attendance limitation before engineering starts. - Source preparation enforces the exact destination boundary, regular-file/symlink rules, archive/member/path uniqueness rules, and all 5,000 / 512 MiB / 128 MiB / 2 GiB / 20:1 / 2,000,000 ceilings before publishing output.
- Luma preparation rejects unsafe/extra/ambiguous files, mismatched pairs and cross-file event identity, unsupported schema/status, duplicate registration/event/path cases, and count/size excess with bounded codes.
- Eventbrite preparation rejects unsafe/duplicate/colliding members, unsupported wrapper paths, malformed CSV, declared/actual size mismatch, size/count/ratio excess, and never opens the XLSX as a workbook.
- Preparation is streaming/bounded-memory, fail-closed, atomic, and preserves the prior output on every validation/write/replace failure.
- Protected directories/files are explicitly verified as
0700/0600; permissive caller umask or existing modes cannot weaken them. - Output/report/log/error tests prove no source path, filename/member, provider raw ID, attendee value, email/name, answer, token, or payload is disclosed.
- Synthetic fixtures under project-local
.tmp/cover success plus every security/failure branch; reduced injected limits exercise bounds without large committed fixtures. No protected source is opened. - The refreshed Luma reconciliation profile is versioned and fail-closed; no stale 64/95 assumption or fuzzy mapping can activate the 166-event source.
- Exact 0/1/plural/omitted states render only on canonical event detail using the owner-approved wording; unless choice 2 is explicitly accepted after spec amendment, this is
N registeredfor every event state. Provider/attendee leakage remains absent and no-store/revision behavior remains unchanged. - Focused importer/preparation/service/public/Studio/admin security tests, migration drift, management parity, OpenAPI, quality, container, and the graph-required Django/Playwright verification plan pass through
uv/Make targets. - An independent tester captures and inspects canonical event-detail desktop 1440×900 and mobile 390×844 screenshots for future/current, past, and omitted states; screenshots use synthetic totals only and contain no protected value.
Acceptance criteria — HUMAN (must remain unchecked by engineering/tester)
- [HUMAN] An authorized operator under #64 confirms the real protected inputs/outputs have the reviewed checksums, supported schemas, safe
0700/0600modes, bounded preparation report, retention owner, and disposal plan, without publishing paths/member names/rows. - [HUMAN] The operator reviews every refreshed Luma and retained Eventbrite exact proposal, map, exclusion, source-missing record, and overlap/native boundary; no fuzzy or stale-cardinality decision is accepted.
- [HUMAN] Dry-run/replay/activation/rollback/invalidation completes in development with aggregate-only redacted evidence; mapped canonical pages show the owner-approved registration-count wording and no attendee row/PII is stored or reported.
Browser and failure scenarios
- Synthetic upcoming/current, past, complete-zero, plural, incomplete, quarantined, and source-missing totals prove the owner-approved exact copy (default:
N registeredfor all event states), omission, no leakage, canonical-only output, zero TTL, and revision behavior at desktop/mobile. - Synthetic Luma trees exercise source/root/file symlink, special/hidden/nested/extra file, pair mismatch, duplicate/colliding output, event-ID mismatch, malformed encoding/JSON/CSV, unsupported status, and every count/size limit.
- Synthetic Eventbrite archives exercise raw and normalized duplicate paths, absolute/traversal/backslash/hidden/directory/symlink/special entries, wrapper mismatch, compressed/member/expanded/ratio/row ceilings, malformed metadata/encoding/CSV/header/status, opaque XLSX, and a bounded streaming success.
- Permission tests start from permissive umask and modes and prove final
0700/0600; injected failures before and during publication prove prior output preservation and cleanup of task-owned staging only. - Studio/admin negative authorization, source-token masking, CAS/idempotency, audit redaction, mapping/coverage conflicts, rollback, and no-email/provider side effects remain green without exposing or opening a real source.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with scripts/prepare_event_registration_sources.py and its focused synthetic tests, then read the linked migration and verification specs before changing behavior. Done means the protected destination, file and archive rules, bounded ceilings, permissions, atomic publication, and aggregate-only output are enforced without opening real sources; public wording remains blocked on the owner decision.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data, security, testing
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100