DataTalksClub / DataTalksClub/website

Establish canonical Person short source and relationship resolution

Open
#40 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

content data-migration enhancement foundation integration needs grooming P0 security seo testing
Dominant language
Python
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Parent epic: #4

Normative authority:

Current PM disposition — returned to grooming / do not dispatch

The stable Person identity decision is accepted: one editorial Person is keyed only by the exact existing short, with canonical /people/<short>.html. Names, email, social fields, account identity, employment, course activity, or fuzzy/case-insensitive matching never creates or resolves a Person.

The implementation and relationship contract is not accepted or engineer-ready. The prior body incorrectly declared Depends on #37–#39, while #39 says its Person resolution depends on #40. That cycle is removed below. The prior body also combined a feasible source/resolver foundation with future Event/Course/account/Studio work whose models and authority belong to other issues.

Current origin/main face8e4808d65afbf0374d1ced7a88079950d663 contains a baked rendering projection and callback seam, not an accepted #40 delivery. Its checked content/public_projection/people.json has 438 unique short records and SHA-256 46ca78bad0821cf825b5cdca3ea8d9fcb62490ae26b37864e5de30fe98e07c85, but #253 proves that this artifact is not reproducible from the declared sources with the current generator: the regenerated Person relationship set has one extra podcast-event speaker relation. That checked digest and its current 188 author / 207 guest / 250 speaker relationship census are evidence only, not forward acceptance bindings.

needs grooming remains until accepted/integrated #253 supplies the final reproducible people.json, manifest/tree, exact relationship census, and source provenance. PM must then replace the provisional envelope below with exact final digests/counts before assigning engineering.

Accepted source identity envelope

The Person source itself remains explicit and separate from the currently disputed derived relationship artifact:

  • repository/revision: DataTalksClub/datatalksclub.github.io@ee43d3fa0929faf691178d79f19528e6f15a83e5;
  • selected source: 439 _people/*.md files, exactly 438 public profiles and _people/_template.md as the sole excluded file;
  • identity: frontmatter short must exactly equal the source filename stem and satisfy the accepted safe-key grammar;
  • canonical: exactly /people/<short>.html; clean and trailing-slash compatibility aliases are direct redirects owned by the public route layer;
  • public profile values: allowlisted name, biography, portrait, and public social links only, with immutable source path/checksum provenance;
  • all 438 current identities are active; the checked inventory contains no explicit Person-key alias.

Any difference in that source SHA, selected-file count, excluded-file set, key/path pairing, or source-owned profile inventory returns the issue to PM. A moving branch, production database, provider lookup, account record, or hand-edited generated JSON is never source authority.

Bounded source/resolver lane to finalize after #253

The independently closable #40 implementation should contain only:

  1. a dedicated, deterministic, network-free Person source adapter extracted from the supported checked-projection path;
  2. a versioned canonical identity manifest (or equivalently strict checked artifact) containing the exact 438 active short identities, canonical paths, immutable source provenance, and an explicit alias/replacement section that is empty for the accepted source;
  3. one pure canonical resolver used by content preparation and future domain services, resolving only an exact active short or an explicitly reviewed alias to its one active canonical short and path;
  4. required/optional relationship diagnostics: an unknown required key fails the complete candidate before writes; an optional unresolved key produces one bounded explicit warning and no link;
  5. a deterministic transition/removal validator that receives the exact referenced-short census from a caller and rejects removal or rename of a referenced identity unless a reviewed one-hop alias/replacement targets an active canonical identity; and
  6. the exact post-#253 current editorial relationship projection for article author, book author, podcast guest, and Event speaker, preserving source order and the specification's podcast-event duplicate suppression.

The final grooming pass must bind exact artifact/tree/source digests and exact role/relation counts. book_author remains a distinct normative relationship kind even if an existing presentation groups it under an “author” label. Host, instructor, and maintainer are supported role vocabulary only after their owning domains supply explicit ordered source relations; this issue must not infer them from names, biographies, email addresses, account/course records, or prose.

Identity, alias, and safety contract

  • Exact short is case-sensitive and immutable. Filename/short mismatch, unsafe character, duplicate key/path, empty key, alternate case, normalization collision, or unrecorded rename fails the complete candidate.
  • Alias/replacement entries are reviewed migration data, never inferred. They form a finite one-hop old-key → active canonical-key mapping with unique old keys and targets. Self-aliases, loops, chains, alias/canonical collisions, missing/inactive targets, ambiguous targets, and alternate public paths fail before output or writes.
  • An accepted rename preserves the old established .html path as one permanent direct redirect to the replacement canonical. This source-only lane records the mapping but does not activate a route or public-reader cutover.
  • Profile field edits retain identity. A changed portrait must stay within the adopted source-owned image allowlist and bind exact bytes/checksum. Unsafe/protocol-relative/non-public social links fail safely.
  • Relationship resolution uses only the explicit source key. A Person may have multiple ordered roles without duplicate identity; exact duplicate source relations and the reviewed podcast/event lineage duplicate are suppressed only by their explicit identity rule.
  • accounts.CustomUser and accounts.MemberProfile are separate private identities. This lane must not query, create, link, synchronize, publish, infer, grant, or revoke any account/staff/permission state.
  • Diagnostics contain bounded code and safe source-relative pointer only. They do not expose source body, raw biography, private/account values, token, credential, provider payload, arbitrary exception text, or production data.

Provisional acceptance criteria — final digests/counts still required

  • The final post-#253 body records exact source, Person artifact, manifest, tree, and relationship counts/digests; two clean supported generations match each other and the checked output byte-for-byte.
  • All 438 accepted profiles import once from the exact legacy-main pin, _template is the sole exclusion, every short equals its filename stem, and every canonical is exactly /people/<short>.html.
  • Allowlisted profile fields, source-owned portraits, safe social links, source path/checksum provenance, deterministic ordering, and bounded malformed-input diagnostics pass.
  • The versioned identity/alias manifest is deterministic and complete; the accepted initial alias set is empty, while synthetic rename/removal/alias tests prove the exact fail-closed rules above.
  • Exact required and optional resolver behavior passes for accepted and malformed keys with no fuzzy, case-folded, name, email, account, course, or database guessing.
  • Final current article-author, book-author, podcast-guest, and Event-speaker relations resolve one canonical identity, preserve explicit order, and match #253's accepted duplicate-suppression census; unsupported host/instructor/maintainer relations are not invented.
  • Source-only transition validation blocks a referenced removal/rename without an explicit accepted replacement and accepts only a safe one-hop replacement. Later database consumers must pass their own exact persisted-reference census through their owning service.
  • Existing public Person output and route inventory are byte/semantically identical unless the final #253 census explicitly approves a derived correction; no new People catalogue, reader cutover, Studio/API route, or public alias activation is introduced.
  • A current versioned verification plan, uv-backed lint/format/type checks, focused adapter/resolver/manifest/security tests, graph-selected Django/Playwright/container evidence, independent tester PASS, and PM acceptance exist before commit.

Required test scenarios

  1. Parse the exact 439-file source inventory twice; prove 438 unique active identities, one excluded template, exact provenance/path/checksum binding, deterministic bytes, and complete checked-output equality.
  2. Reject missing/blank/unsafe/duplicate/case-colliding short, filename mismatch, unknown field, unsafe portrait/social URL, symlink/traversal, changed source pin, missing/extra profile, and unexpected template/private file.
  3. Resolve known required/optional keys; reject or warn exactly for unknown keys; prove name/email/case/account data never resolves; prove one Person can hold ordered author/book-author/guest/speaker roles without duplicate identity.
  4. Exercise unchanged profile, field edit, unreferenced removal, referenced removal, rename without alias, valid replacement, self/loop/chain/collision/missing-target alias, and idempotent replay. All failure cases produce no partial output or mutation.
  5. Reproduce the accepted post-#253 article/book/podcast/Event relation census, including the exact podcast-event lineage suppression and unrelated speaker/guest preservation.
  6. Prove zero database migration/model write, account/MemberProfile/user query or mutation, network/provider call, GitHub write, direct-sync activation, public-reader cutover, Studio/admin API route, job, email, or production access.

Verification and screenshots

This bounded lane is source/parser/resolver work. Screenshots are not_applicable only if the final change-selective graph proves public artifacts and render behavior are byte/semantically unchanged. If #253 or the final #40 implementation changes any rendered Person field, relationship, route, or asset, the independent tester must capture and inspect representative Person detail and relationship navigation at desktop/mobile and JavaScript-on/off as selected by the graph.

Dependencies and sequencing

  • Satisfied inputs: #12, #37, #105, and #226.
  • Hard prerequisite before final grooming or engineering: accepted/integrated #253 with a clean reproducible projection/source envelope and green baseline gates.
  • No dependency on #38 or #39. #38 later consumes this adapter/resolver in its source-specific direct-sync slice; a Person-free #39 phase may carry opaque keys, while #39's resolved Person behavior consumes accepted #40.
  • No dependency on #45 or #289. #289 deliberately contains no Person relation. Full #45 consumes accepted #40 to create Event-owned ordered speaker/host references and their database guards.
  • Course/Cohort teaching relations, account-to-Person linking, public reader/direct-sync cutover, and Studio/admin API adapters remain downstream in their owning issues.
  • Engineering starts only from a clean current origin/main whose required release/source provenance and baseline CI gates are green. Any source, artifact, count, digest, relation, or architecture drift returns the issue to PM.

Explicit non-goals

No broad remaining-main-site adapter; direct-sync schema/runner/webhook/reconciliation; staged ContentRelease activation or rollback; Django Person model or migration; Event/Course relation model; account/member/staff link; permission behavior; inferred host/instructor/maintainer; Studio/admin API delivery; public-reader cutover; new People hub; provider or production access; source edit; GitHub write; hand-edited generated artifact; unrelated redesign; commit; push; merge; or deployment during grooming.

Lifecycle

The earlier broad acceptance checkboxes remain unimplemented and are superseded by this returned-to-grooming contract. No #40 engineer handoff, independent tester PASS, screenshots, PM acceptance, focused commit, merge, deployment, or on-call green evidence exists. After #253 is accepted/integrated, PM must bind the exact final artifact and relation envelope, remove needs grooming, and only then dispatch engineering through the normal lifecycle.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with #253 and the cited Person identity, architecture, URL, security, migration, and verification specifications; the source inventory is the 439 files under _people/*.md. Wait for final digests, counts, and the accepted relationship projection before implementation. Done means deterministic source and manifest validation, exact resolver diagnostics, transition checks, and the required focused and graph-selected tests pass without account or public-reader changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, playwright, python
Domain
backend, content
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.