DataTalksClub / DataTalksClub/website

Define direct-sync active-content validation receipt and side-effect-free evaluator

Open
#272 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

content decision enhancement foundation human integration needs grooming operations P0 security testing
Dominant language
Python
Stars
0
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Product outcome

Define the content-owned, immutable validation evidence that a future restore/startup controller can consume to decide whether one exact direct-sync content state is internally complete, source-derived, projection-consistent, current enough under an approved policy, and compatible with the exact runtime and database schema.

The validation path is observation and proof only. It performs no sync, repair, row transition, projection build, cache/search/graph mutation, activation, consumer release, provider operation, or network access.

PM status — BLOCKED / retain needs grooming

This issue is not engineer-ready. The receipt envelope and fail-closed evaluator shape are derivable, but their authoritative producer inputs and policy values are not:

  • #38 still describes the rejected staged lifecycle and has not defined or delivered direct-sync SyncLog, source-status, completion, transaction, collision, draft-transition, or partial-recovery semantics.
  • #253 has no accepted reproducible projection manifest/tree/artifact baseline and is blocked on an immutable content-source correction.
  • #264 has specified, but not yet supplied as an accepted dependency, the canonical runtime and database-schema identity types this issue must reuse.
  • the authoritative source set, freshness and receipt-age bounds, recovery treatment of a failed/partial latest sync, restore-generation/checkpoint authority, retained-artifact authority, and live evidence/activation authority require explicit HUMAN decisions.

Engineering must not invent provisional SyncLog states, treat current ContentRelease rows as direct-sync evidence, pin invalid face8e4 projection hashes, or infer live policy from settings/current rows. Re-groom only after the prerequisites and decision packet below are complete.

Normative authority and vocabulary correction

  • _docs/PROCESS.md: dependency ordering, role separation, versioned verification, and sensitive-artifact rules.
  • _docs/specs/open-decisions.md, decision 1 as resolved by #226: source lock → immutable checkout → parse/dispatch → direct upsert → source-scoped soft-delete or draft transition → SyncLog and source status. Draft/unpublished rows are excluded from public queries. Ordinary sync has no site-wide candidate/activation/rollback graph.
  • _docs/specs/01-platform-architecture.md, _docs/architecture/app-boundaries.md, and _docs/specs/07-security-privacy-operations.md: one Django deployment, owner-service boundaries, safe restore holds, exact runtime/schema identity, redacted evidence, and fail-closed recovery.
  • _docs/specs/03-github-content-and-people.md, _docs/specs/06-studio-and-admin-api.md, _docs/specs/08-aws-development-terraform.md, and _docs/specs/09-migration-rollout-roadmap.md still contain staged ContentRelease, candidate, pointer, activation, and rollback vocabulary. For this issue those passages are stale where they conflict with the later explicit #226 owner decision. They remain useful only for unchanged source security, parsing, provenance, route, search/graph, audit, and bounded-freshness requirements.
  • #38 owns the direct-sync persistence/status contract and its migration from the current staged implementation.
  • #219 owns preservation/repair of historical ContentRelease migration data. Historical rows remain readable migration provenance; they are not active-content authority for this receipt.
  • #253 owns deterministic source-to-public-projection generation and the accepted manifest/tree/artifact identities.
  • #264 owns canonical schema-2 runtime identity and database-migration identity. This issue reuses those DTOs and validators rather than creating another grammar.
  • #267 is the one-way downstream restore/startup consumer; #269 is the later HUMAN rehearsal. Neither supplies content truth or policy to this issue.

“Active content” here means the exact direct-sync database state selected by the accepted public query contract, together with its accepted retained generated projection. It does not mean a ContentRelease, candidate, active-release foreign key, pointer swap, path-claim activation, or rollback target.

One-way ownership boundary

#38 direct-sync source status + SyncLog evidence ---\
#253 accepted retained projection evidence ---------> content observation/evaluator -> immutable content receipt -> #267
#264 exact runtime + database-schema identities ----/
restore generation/checkpoint + policy requirements /

The implementation belongs in content/content_sync behind a dependency-light immutable DTO seam. #267 may import only the safe receipt/evaluator interface. Content code must not import #267, recovery orchestration, privacy, delivery, AWS/provider SDKs, Terraform, Studio/API presentation, or deployment mutation code.

Derivable execution-disabled contract

The following is the minimum contract PM can freeze now. It remains execution-disabled until the named inputs and HUMAN values are pinned.

1. ActiveContentValidationRequirements schema 1

One immutable requirements object contains exactly:

  • schema_version = 1 and validator_contract_version = 1;
  • environment_class: exact allowlisted enum shared with #264;
  • opaque lowercase RFC 4122 restore_generation_id and evaluation_checkpoint_id, supplied by the future accepted restore boundary, never generated or selected here;
  • direct_sync_contract_digest: digest of the exact accepted #38 status/transaction/visibility contract;
  • authoritative_source_policy_digest: digest of the exact ordered source requirement manifest approved below;
  • projection_requirements_digest: digest of the exact accepted #253 projection identity requirements;
  • exact nested #264 RuntimeReleaseIdentity and DatabaseSchemaIdentity;
  • explicit positive bounded maximum_source_observation_age_seconds, maximum_successful_sync_age_seconds, and maximum_receipt_age_seconds supplied by the approved policy, with no default or environment fallback;
  • requirements_digest: schema/domain-separated SHA-256 of every preceding field except itself.

The source-policy manifest bound by the requirements must enumerate each authoritative source exactly once using only a code-owned source_key, enabled/required disposition, source/adapter contract versions, accepted branch policy digest, required remote-observation type, and its allowed normalized source-status set. Repository URLs, credentials, webhook secrets, mutable “current” aliases, or database IDs are not receipt fields.

2. #38-owned DirectSyncSourceEvidence prerequisite

#38 must publish one immutable safe evidence record per required source. #272 consumes it but does not define a competing SyncLog model or status machine. The accepted #38 record must expose at least:

  • evidence schema and source/adapter/status contract versions;
  • exact code-owned source_key;
  • immutable lowercase full source commit SHA and, when the source contract supplies it, tree SHA-1 plus source-attestation/CI digest;
  • exact source-status revision and one normalized state mapping accepted by #38;
  • exact successful SyncLog opaque UUID, canonical log/result digest, start/completion UTC seconds, and observed-remote UTC second/commit binding;
  • aggregate bounded selected/created/updated/unchanged/drafted-or-soft-deleted/rejected counts with arithmetic defined by #38;
  • source-owned visible-state digest, draft/unpublished-state digest, ownership/index digest, and evidence-record digest;
  • a durable completion marker that proves the evidence was created only after the accepted transaction/partial-recovery boundary.

The normalized state reaching #272 must be exactly one of complete, in_progress, failed, partial, unavailable, or conflicting. Only complete is eligible. #38 must define the exhaustive mapping from its native states and whether a later failed/partial attempt invalidates an earlier success; #272 may not guess it.

The complete source-evidence manifest is canonically sorted by source_key, rejects duplicate or unknown sources, and has source_count, complete_source_count, and source_evidence_set_digest. A count mismatch or a required source outside complete blocks.

3. RetainedProjectionIdentity schema 1

This immutable observation binds the final accepted #253 output without copying source content:

  • schema_version = 1 and exact projection-generator contract version;
  • projection manifest SHA-256 and complete tree SHA-256;
  • canonical source-set digest and source count;
  • canonical artifact-map digest and artifact count;
  • exact route-migration, search, graph, media/assets, and public-record-count digests derived from the manifest;
  • supported manifest schema/selection/runtime-contract digests;
  • completion UTC second and projection_identity_digest.

The projection artifact map remains the detailed authority. The receipt stores its digest/count and the named security-critical subset above. Missing, extra, duplicate, changed, unreadable, symlinked, oversized, noncanonical, or digest-mismatched retained files block. Current face8e4 values and stale-source regeneration values are evidence only and must not be pinned here.

4. ActiveContentObservation schema 1

A side-effect-free collector reads one transactionally consistent database snapshot plus already-retained local projection artifacts and produces an untrusted immutable observation:

  • schema/collector contract versions;
  • exact environment, restore generation, and evaluation checkpoint;
  • exact nested current runtime and database-schema identities;
  • exact direct-sync contract, source-policy, and projection-requirements digests;
  • exact source evidence manifest/count/digest;
  • exact retained projection identity;
  • public-selection contract digest plus bounded visible/draft/unpublished/source-owned counts and canonical state digests;
  • observed_at, state, allowlisted code, and domain-separated observation_digest.

Observation state is exactly complete, in_progress, failed, partial, unavailable, or conflicting. complete/ok is the sole valid pair. The collector performs no hidden clock read—the caller supplies one aware UTC second—and no network, sync, row mutation, lock takeover, repair, rebuild, cache access, or provider call.

Because #226 accepts no atomic cross-content publication snapshot, “complete” proves only that all required per-source facts and the retained projection agreed at this fenced checkpoint and stayed unchanged through the final read. It must not claim that direct sync provides a historical atomic release.

5. ActiveContentValidationReceipt and outcome schema 1

A receipt is emitted only for a valid complete observation and contains exactly:

  • schema_version = 1, validator_contract_version = 1, and exact requirements_digest;
  • exact environment, restore generation, and evaluation checkpoint;
  • exact direct_sync_contract_digest, authoritative_source_policy_digest, and projection_requirements_digest;
  • exact source evidence set digest/count and retained projection identity;
  • exact public-selection contract/state digests and bounded visible/draft/unpublished/source-owned counts;
  • exact nested runtime and database-schema identities;
  • exact observed_at and validated_at UTC seconds;
  • state = valid, code = ok;
  • receipt_digest: schema/domain-separated SHA-256 of the canonical receipt payload excluding itself.

The validator/evaluator returns only valid or blocked plus one allowlisted code. A blocked outcome has no partial, provisional, or fabricated receipt.

Initial blocked-code families are exact and content-free:

  • missing_evidence, unsafe_evidence, noncanonical_evidence, unsupported_contract;
  • generation_mismatch, checkpoint_mismatch, environment_mismatch;
  • runtime_identity_mismatch, schema_identity_mismatch, pending_migrations;
  • source_policy_mismatch, source_set_mismatch, source_status_unsafe, source_evidence_conflict;
  • source_observation_future, source_observation_stale, successful_sync_stale;
  • draft_visibility_leak, ownership_mismatch, selection_contract_mismatch;
  • projection_requirements_mismatch, projection_source_mismatch, projection_artifact_mismatch, projection_route_mismatch, projection_search_mismatch, projection_graph_mismatch, projection_asset_mismatch, projection_count_mismatch;
  • observation_changed, receipt_stale, digest_mismatch.

Unknown schemas, states, codes, fields, values, or inconsistent state/code combinations normalize to blocked/unsafe_evidence; unsafe input is never echoed.

Canonical encoding and digest rules

All schema-1 DTOs use the strict canonical JSON contract already established by #264: UTF-8/ASCII-safe objects, exact lexicographically ordered keys, compact separators, exact key sets, no duplicate keys/whitespace/BOM/trailing data, no null/bool-as-int/float/NaN, bounded integers and structures, lowercase fixed-width digests, lowercase full Git SHAs, and UTC calendar seconds exactly YYYY-MM-DDTHH:MM:SSZ with no offset/fraction/leap-second inference.

Each requirements, source manifest/evidence, projection identity, observation, and receipt digest uses a distinct schema-specific ASCII domain separator followed by NUL and the canonical payload without its own digest. Cross-kind/version digest substitution, semantically equivalent but bytewise noncanonical input, unknown-field preservation, downgrade, default version, nullable field, or best-effort parsing blocks.

Pure evaluation, freshness, and drift

evaluate_active_content_receipt(receipt, requirements, current_observation, current_runtime, current_schema, evaluated_at) is deterministic and side-effect-free. It validates every nested digest and identity and succeeds only when:

  1. schemas/contracts and canonical encoding are exact;
  2. environment, restore generation, checkpoint, requirements, source policy, direct-sync contract, runtime, and pending-zero schema all match;
  3. every required source is present exactly once in complete, its evidence arithmetic/digest is valid, and no later or concurrent in-progress/failed/partial/conflicting attempt invalidates it under #38's accepted policy;
  4. source commits/evidence agree with the retained projection's authoritative source identities under the approved source policy;
  5. public selection contains no draft/unpublished leak and its counts/digests/ownership agree with the accepted direct-sync query contract;
  6. the complete retained projection matches the accepted #253 manifest/tree/artifact/route/search/graph/assets/count identities;
  7. source_observed_at <= sync_completed_at <= projection_completed_at <= observed_at <= validated_at <= evaluated_at wherever those events are required by the final policy; and
  8. every explicit source-observation, successful-sync, and receipt age is non-negative and within its exact approved boundary.

Before-boundary and exact-boundary behavior, plus one-second-over behavior, must be pinned in the final grooming after the owner selects inclusive/exclusive rules. Any database/source/projection/runtime/schema/policy/generation change before or after receipt creation blocks current evaluation. An old successful receipt never masks new work or drift.

A valid receipt proves content consistency at one checkpoint only. It grants no sync, repair, activation, workload start, deploy, restore, retention, RPO/RTO, or operator authorization.

Security and fail-closed evidence

  • DTOs, outcomes, logs, audits, exceptions, and fixtures may contain only contract versions, code-owned source keys, opaque UUIDs, full source/runtime SHA values, fixed digests, allowlisted states/codes, UTC seconds, and bounded aggregate counts.
  • Exclude raw content/frontmatter/HTML/search text, source paths/edit URLs, repository/provider URLs, branch names unless represented by an approved digest, database IDs/names/hosts, user/profile/course/event/email/message data, low-entropy or reversible subject hashes, IP/header/query/body, SQL, ARNs, provider payloads, credentials/tokens/secrets, environment values, exception text, and stack traces.
  • Sensitive canaries in any input position, excessive count/size/depth, symlink/path escape, clock regression, concurrent drift, decoder/log/evidence failure, or an unavailable retained artifact blocks without exposing the unsafe value.
  • Receipt validation never trusts model clean(), mutable “latest” rows, auto-increment order, filesystem mtime, Git checkout state, wall-clock discovery, settings/env overrides, or a ContentRelease status/pointer.

HUMAN/owner decision packet required before re-grooming

  1. Authoritative sources: exhaustive ordered direct-sync source keys; required/optional/disabled behavior; accepted branch/commit/remote-observation authority; whether all five specification-03 repositories participate or some remain baked-only.
  2. Public authority and projection relationship: which direct-sync database query is public authority at restore time, which content remains checked/baked, and exactly how its source commits must relate to #253's manifest. A database sync and a retained projection at different commits cannot both be called active without an explicit policy.
  3. Freshness: exact source-observation, successful-sync, projection, and receipt age bounds by environment; event definitions; inclusive/exclusive boundary; outage/maintenance treatment; and whether “below 15 minutes” in specification 07 means a hard ceiling, alert target, or activation gate.
  4. Partial/failure recovery: whether any failed or partial latest attempt invalidates the preceding success; accepted per-source transaction boundary; cross-source mixed-version treatment; quarantine/repair authority; and what evidence returns a source from blocked to complete.
  5. Generation/checkpoint: authoritative opaque restore-generation and checkpoint producer; durable storage outside/through the restored database; monotonicity/supersession; source snapshot binding; and behavior when that authority is missing or restored from itself.
  6. Artifact authority and custody: exact retained #253 manifest location/reader, immutable custody, availability during restore, projection completion evidence, and which party may attest its bytes.
  7. Receipt and live authority: who may request observation, issue/store a receipt, define its retention, and supply it to #267; operator/go-no-go/abort roles; evidence destination/audience; and explicit statement that valid content evidence alone cannot release consumers.

Public issue text records only stable keys, versions, digests, bounds, states, and approval evidence. Protected environment/resource/contact values remain in the approved confidential channel.

Required verification after final re-grooming

  • strict codec/digest round trips, ordering independence at builder input, canonical wire rejection, cross-kind/version substitution, corrupt/duplicate/unknown/excessive input, and deterministic replay;
  • every source state and transition from #38; absent/duplicate/unknown sources; count arithmetic; later failed/partial/in-progress attempt; commit/tree/status/log/ownership/visible/draft digest drift; concurrent sync before/during/after observation;
  • draft/unpublished leak and source-scoped soft-delete/draft behavior across public query, route, search, graph, sitemap, and retained projection comparisons;
  • #253 source/manifest/tree/artifact/route/search/graph/media/count tamper, missing/extra files, symlink/path escape, stale source, and complete two-generation mismatch;
  • wrong environment/generation/checkpoint/runtime/image/schema/migration graph/applied set/pending migration/policy/requirements and cross-generation receipt mixing;
  • freshness/future/clock-regression cases at before, exact, and one-second-over boundaries for every approved clock;
  • SQLite and PostgreSQL consistent-read/concurrency tests, including sync committing between first and final observation reads, transaction rollback, retry, and no lock/mutation/network side effect;
  • network/socket/subprocess/provider/AWS/secret/settings/env guards; sensitive canaries in all string inputs and error paths; no free-form diagnostics;
  • import/ownership tests proving one-way #272 → #267 DTO consumption and no reverse/circular domain or provider dependency;
  • versioned focused and graph-selected full quality/type/Django/container verification. Browser/render/screenshots are not_applicable because this issue adds no HTTP route, template, copy, or operator surface. Any such surface requires re-grooming.

Explicit non-goals

  • No ContentRelease resurrection, candidate, preview, ready/active/superseded state, pointer/path-claim activation, rollback, or release manifest terminology in the new contract.
  • No redefinition or migration of #38 SyncLog/source-status/direct-upsert behavior; no repair of #219 historical migrations; no generation or blessing of #253 projection bytes.
  • No sync/webhook/reconciliation, immutable checkout, parser/render execution, direct upsert, draft/soft-delete transition, collision resolution, or public-reader cutover.
  • No projection/search/graph/media/route/cache rebuild, swap, invalidation, repair, or network/source/provider read.
  • No restore, backup, privacy replay, delivery reconciliation, startup/consumer gate, job/scheduler, deploy, AWS/Terraform, production data, Studio/admin/API/command/route, or operator override.
  • No mutable latest selection, stale-success grace, partial-valid result, guessed source set, hidden default, environment/settings bypass, --force, hand-edited evidence, provider payload, or ContentRelease-to-direct-sync compatibility fiction.

Dependency and re-grooming exit

Blocking order:

  1. complete/accept #219's historical migration repair or explicitly supersede it in #38's reviewed migration plan;
  2. re-groom, implement, independently verify, and accept #38's direct-sync models/services/status evidence and partial-recovery semantics;
  3. complete and accept #253's source-first deterministic projection baseline;
  4. accept #264's runtime/database-schema identity seam;
  5. resolve and record all seven HUMAN decision groups above; then
  6. PM replaces placeholders with exact accepted type/state names, source manifest, policy values/digests, #253 identities, and producer interfaces before removing needs grooming.

#267 and #269 are downstream and remain blocked on the resulting accepted receipt. They must update their stale “active release/pointer” wording to this direct-sync receipt when they are next re-groomed; they are not dependencies that authorize implementation here.

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 _docs/PROCESS.md, the listed architecture and decision documents, and the dependency issues #38, #253, and #264; confirm their contracts and the required HUMAN policy decisions before examining content/content_sync. This issue is done only when those prerequisites are accepted and the immutable requirements, observation, receipt, and fail-closed evaluator contracts can be implemented without inventing missing semantics.

Written by the indexing model from the issue text.

Assessment

Tech stack
django, python
Domain
backend-api-design, 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.