Skip to content

THOTH-CHAPTER-01: Enforce a single parent for chapter works #803

Description

@ja573

Status

APPROVED FOR DESIGN/IMPLEMENTATION SPECIFICATION - CTO DECISION RECORDED

Programme

Thoth core data integrity

Repository

thoth-pub/thoth

Base branch / PR target

Classification: HIGH-RISK HOTFIX

  • Base branch: master
  • PR target: master
  • Reason: develop contains unrelated, unreleased development which must not be released as a side effect of this hotfix; the change must therefore be cut from, and merged to, origin/master.
  • Post-release reconciliation: after the hotfix lands on master and production is verified, merge master forward into develop (a separate, controlled step).
  • Explicit prohibition: do not merge develop into master as part of THOTH-CHAPTER-01: Enforce a single parent for chapter works #803, and do not import unreleased develop implementation into the hotfix.

Supersedes the original instruction (develop -> develop), updated per the CTO HIGH-RISK HOTFIX decision. The approved domain decision, scope, invariants, existing-data audit requirements, acceptance criteria, rollout gate, rollback requirements and risk classification are unchanged.

Risk

HIGH - database/domain integrity rule affecting write acceptance and potentially existing data.

Dependencies

  • CTO/domain decision: a chapter Work must have at most one parent Work.
  • Existing-data audit must complete before any enforcing migration or production activation.

Decision

Although reuse of an unchanged chapter across editions is theoretically possible, current product practice does not rely on it. Thoth will therefore enforce that a chapter Work has at most one parent relation.

This rule is an integrity guard, not a way for the API to infer user intent. If the first relation submitted for a newly created chapter points at the wrong book, the API cannot independently know which book the user intended. The thoth-app regression task remains necessary.

Explicit scope

  1. Determine the narrowest authoritative enforcement point for 'chapter has at most one parent'. Prefer database/domain enforcement over UI-only checks.
  2. Audit existing production-compatible data for chapter Works with more than one parent before adding enforcement.
  3. Define the exact relation/work-type semantics being constrained: BOOK_CHAPTER child relation(s) representing parent book membership.
  4. Add tests proving a second parent assignment for the same chapter is rejected.
  5. Preserve normal creation of a chapter under its first parent.
  6. Ensure the error returned through the API is deterministic and safe for clients.
  7. Add migration(s) only if required for authoritative enforcement.
  8. Record rollout, rollback, and existing-data evidence in the implementation report.

Non-goals

  • Do not add a transactional 'create chapter under book' endpoint in this task.
  • Do not change chapter deletion semantics.
  • Do not attempt to determine whether the first supplied parent is the user's intended book.
  • Do not modify bulk import behavior except where necessary to comply with the same invariant.
  • Do not broaden this into general WorkRelation semantic validation.

Invariants

  • A chapter Work may have zero or one parent while intermediate/orphan records remain technically possible under the current two-step creation flow.
  • A chapter Work may never persist two distinct parent-book relationships after enforcement is active.
  • Existing valid chapter relationships must remain unchanged.
  • No migration may silently choose a surviving parent for already-corrupt multi-parent data; any such rows must be reported and explicitly resolved before enforcement.
  • Authorization behavior must not be weakened.

Existing-data audit gate

Before migration/activation, produce evidence identifying:

  • count of chapter Works with 0 parents;
  • count with exactly 1 parent;
  • count with >1 parents;
  • identifiers/details for every >1-parent case sufficient for CTO/data-owner resolution.

If >1-parent records exist, return BLOCKED for activation until they are explicitly resolved. Do not auto-delete or auto-reparent them.

Acceptance criteria

  • A first valid parent relation for a chapter succeeds.
  • A second distinct parent relation for the same chapter is rejected at the authoritative write boundary even if both Works are authorized for the caller.
  • Repeated/idempotent behavior, if supported by current relation semantics, is explicitly tested and documented.
  • Non-chapter WorkRelation types are unaffected unless the implementation necessarily shares a generic constraint; any broader effect requires separate approval.
  • Existing-data audit evidence is attached to the PR/implementation report.
  • Populated and empty database migration tests pass if a migration is introduced.
  • API/client-facing failure behavior is covered by tests.
  • Changelog updated under Unreleased.

Required verification

  • make check-all or the exact equivalent repository checks.
  • Migration verification against both empty and representative populated databases if schema changes are made.
  • Targeted WorkRelation/domain tests for first-parent success and second-parent rejection.
  • Authorization regression tests around the affected mutation path.
  • git diff --check.
  • Independent final-diff review at the exact PR head.

Rollout

Initially inactive until:

  1. existing-data audit is complete;
  2. any corrupt multi-parent data is explicitly resolved;
  3. CI and migration evidence are green;
  4. independent review returns APPROVED;
  5. CTO explicitly approves merge/production activation.

Rollback

Must be specified by implementation according to the chosen enforcement mechanism. A migration-based constraint must have a tested rollback path that does not delete or rewrite chapter data.

Relationship to incident

This guard reduces the space of possible chapter-parent corruption and prevents one chapter from becoming attached to multiple books. It does not explain or prevent a wrong first parent UUID; that is covered by the separate thoth-app investigation/regression task.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions