Skip to content

refactor(release-lines)!: make main the sole authored content source #166

Description

@zoeyrose

Parent: atrinik/atrinik#357

Completed migration evidence: #113, #137, #139, #154

Downstream order: atrinik/atrinik#358 → atrinik/classic#170 and atrinik/playtester#2 → atrinik/github-settings#64

Outcome

Make atrinik/content@main the sole mutable authored source. Reconcile the final Classic behavior onto main, publish a deterministic explicit Classic target from main, and retire branch-specific authoring/release machinery only after every consumer has cut over. Preserve all historical tags, releases, assets, checksums, licenses, attribution, and reachable history.

The completed #137 ledger and #139 semantic audit are bounded migration evidence, not a permanent dual-line workflow and not a substitute for the exact equality gates below.

Frozen migration baseline — 2026-08-12

Coordinate Revision Tree
Fork (v1.8.1) 01b1fdb65c2243df4bafe9c8109fc93229df0121 —
main (v2.13.1) 3beec723be15d9f58d6321f728f5d73d33a00013 ecbb60b15202300421f93af76ce46e357281dcdc
1.x (v1.8.18) 0032e319dde316c2076832066fb5381177b34f42 30e4ef7218c97b8bcd4d11f8a8e76820234bda48

These are the certified #154 migration inputs. Independent 1.x feature delivery is frozen. Any authorized reconciliation change that moves an input requires a newly recorded exact coordinate and rerun comparison before cutover.

The lines contain 31 main-only and 34 1.x-only commits and 43 direct tip-tree differences. The completed audit classifies all 43 with zero pending outcomes, but classification does not satisfy this issue's exact authored-tree or Classic-payload gate.

The authored reconciliation roots contain 11 changed paths:

  • two semantically equal forcefield files whose fields differ only in order;
  • nine map-domain paths containing the complete Incuna apartment behavior/tests and maps/light-source-review.json.

Media plus editor/, contracts/, schemas/, and prototypes/ are identical. No open PR targets 1.x.

Exact-head runtime builds currently differ in 12 paths. main still emits a generic schema-1 manifest with no Classic target; 1.x emits the schema-2 Classic compatibility contract and retains the working Incuna apartment adapters. Pointing Classic directly at main is therefore unsupported until this issue is delivered.

Scope

1. Reconcile authored and Classic behavior

  • Port the complete Classic Incuna apartment adapter, event bindings, and tests to main: idempotent/retry-safe grant, owner gating, private-map persistence/reload, portal return, save-bed behavior, and ordered one-time quest completion.
  • Retain typed property intent and replacement-consumer boundaries. Co-location does not authorize a replacement implementation to execute or copy Classic-only GPL Python.
  • Normalize the two forcefield files and select one canonical maps/light-source-review.json result so the final authored trees compare exactly.
  • Preserve provenance and authorship commit-by-commit. Do not merge branch histories wholesale or copy generated runtime output.
  • Never restore maps/light-source-evidence/**, its manifest, proof scene, capture tooling/tests, or capture-bound views/evidence_focus fields.

2. Publish an explicit Classic target from main

Generalize the content-owned publisher with a target contract equivalent to:

python3 tools/build_runtime.py \
  --target classic \
  --source-commit SHA \
  --output DIRECTORY

The Classic target must:

  • identify atrinik/content, source.branch == "main", and the exact clean commit;
  • preserve classic-ads-v1 and the current Classic runtime artifact contract while ADS remains canonical;
  • identify supported Classic consumers and version range;
  • emit deterministic schema-2 compatibility metadata accepted by the wrapper;
  • bind every payload and applicable license/attribution file by size and SHA-256;
  • remain replacement_ready: false and unambiguous from replacement artifacts;
  • fail closed on dirty/mismatched coordinates, unsafe output, incomplete licenses, or nondeterminism.

Future whole-corpus format translation remains content #8/#11 and content-toolkit #6/#9; it is not required merely to unify the current ADS source.

3. Hand off consumer cutover and branch retirement

After the reviewed Classic target is published through normal Semantic Release:

Never create, move, replace, or delete a tag/release manually.

Acceptance criteria

  • git diff --exit-code FINAL_1X FINAL_MAIN -- arch maps editor contracts schemas prototypes is empty at recorded cutover candidates.
  • Stable catalog definitions and normalized references are identical with zero diagnostics.
  • Both candidate refs pass python3 tools/validate.py and git diff --check.
  • Classic-target builds from both candidates have identical lib/, maps/, and attribution/ path sets and SHA-256 values, excluding only enumerated source-coordinate manifest fields.
  • There is no behavioral exception list; final Classic payload parity is exact.
  • Incuna tests cover every behavior named above.
  • The main Classic target is deterministic, schema-2, checksum/license bound, consumer-compatible, and explicitly not replacement-ready.
  • A released Classic target built from main reproduces from its recorded tag/commit and SHA256SUMS.
  • Main/replacement validation remains green without executing or copying Classic-only Python into replacement implementations.
  • No open PR targets 1.x before retirement.

Integration gate

Validation

python3 tools/validate.py
python3 tools/build_runtime.py --target classic --source-commit SHA --output build/classic-runtime
git diff --check

Also run the direct final tree/catalog comparison, both exact-head Classic target builds, package checksum verification, the wrapper Classic build, the isolated content-main-cutover scenario, and current GitHub checks at every recorded coordinate.

Rollback and non-goals

The immutable rollback anchor is v1.8.18@0032e319dde316c2076832066fb5381177b34f42 with its published archives and SHA256SUMS. Until consumer cutover, a reviewed rollback may repin that artifact. Never rewrite a tag, release asset, branch history, or mutable server state.

This issue does not implement the future whole-corpus format migration, retire Classic support, relicense content, delete historical releases, or preserve 1.x as a second authoring source.

Activity

  1. added theissue type on Aug 11, 2026
  2. self-assigned this
    on Aug 12, 2026
  3. moved this from Inbox to Ready in Atrinik workon Aug 12, 2026
  4. moved this from Ready to In progress in Atrinik workon Aug 12, 2026
  5. moved this from In progress to Done in Atrinik workon Aug 13, 2026
  6. github-actions commented on Aug 13, 2026

    @github-actions

    🎉 This issue has been resolved in version 3.0.0 🎉

    The release is available on:

    Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Fields

Priority

None yet

Effort

None yet

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions