ResearchShared TUI Extraction

04 - Extraction And Migration Plan

04 - Extraction And Migration Plan

This is a two-repository program delivered through one future jackin❯ feature branch and one pull request. The PR remains open through Stages 0-5; stage boundaries are signed checkpoint commits, not independently merged PRs. During bootstrap, TermRock is created empty if absent. Filtered history and new TermRock commits are prepared in a dedicated clone; only a neutral, scanned, standalone head is first pushed directly to main, without a TermRock PR. Every later bootstrap head follows the same direct-main rule. This approved exception and the exact-revision integration protocol are defined in Decision 18.

Only tailrocks/termrock and jackin❯ participate. Other Tailrocks products explain why the API must be neutral, but this program does not check out, modify, build, validate, migrate, or release any of them.

Stage 0: Freeze and prepare execution

  • record the closed Decision Record as the implementation baseline;
  • create the single jackin❯ implementation branch and open its one PR; no later stage opens another jackin❯ PR;
  • surface in the implementation launch summary that the approved program creates tailrocks/termrock if absent and pushes bootstrap commits directly to its main;
  • revalidate the time-sensitive GitHub repository and crates.io package namespaces and record the intended owners immediately before creation/publication;
  • record the operator's trademark disposition before public launch; no dedicated domain is required because the initial catalog is hosted with the repository;
  • record the donor origin/main revision and the Stage 0 re-freeze/merge-sync protocol from Decision 20;
  • verify the history-preserving extraction tool and attribution procedure;
  • freeze the lookbook CLI, Fumadocs component-page contract, and extract/parameterize/remain ledger;
  • generate the public API, consumer map, story/render manifest, dependency tree, compatibility matrix, and provenance record defined in 08 - Migration evidence and gates;
  • wire the lookbook SVG drift check (tui-lookbook --check) into jackin❯ CI and re-verify the committed fixtures before freezing them as parity evidence;
  • record the bug-compatible quality backlog (character-count width defects, color-only panel focus cue) with post-parity fix notes;
  • fix the stale donor docs: COMPONENTS.md lookbook pointers and the crate-root reference to a nonexistent Theme type;
  • capture current jackin❯ component tests, lookbook renders, key behavior, and terminal cleanup as parity evidence;
  • identify every consumer of jackin-tui and jackin-core compatibility helpers.

Exit gate: no ownership ambiguity remains; the single PR is open; freeze evidence is reproducible; and the external repository name, owners, and direct main write scope are recorded before the first external push.

Stage 1: Prepare the external donor history

  • create an empty public tailrocks/termrock without a generated README/license commit, secondary branch, or tag; prepare its source in a dedicated local extraction clone;
  • use git filter-repo or equivalent to retain the complete two-donor-path history plus exact, path-complete neutral component pages, preview assets, relevant TUI design files, and the root LICENSE/NOTICE history;
  • preserve authorship, timestamps where possible, SPDX headers, copyright, Apache license text, and all applicable donor NOTICE attribution; create a TermRock-specific REUSE.toml rather than carrying the donor's repository-wide annotation unchanged;
  • record the source repository, extraction revision, retained paths, filter command, and imported-history boundary;
  • do not filter mixed jackin-core files for individual helpers; move/reimplement their neutral code in later signed commits and record source-file/revision lineage;
  • scan the filtered history for secrets, incompatible licenses, oversized binaries, and source from reference projects; do not push donor branches or tags;
  • prepare the path/reorganization map without committing a partial new TermRock bootstrap;
  • keep the prepared history local through Stage 2: an inherited filtered tip may not build outside the monorepo and must never be advertised as a TermRock checkpoint.

Exit gate: provenance can trace extracted code to donor commits, the pre-publish history/license/secret review passes, and the dedicated clone is ready for neutralization without any raw donor tip having been published.

Stage 2: Break product coupling and publish

  • move neutral text, scrolling, dialog, and bottom-chrome ownership from jackin-core to the shared crate in foundation-first order;
  • establish the Rust workspace, Fumadocs application, governance, CI, dependency/license gates, cache policy, and release automation specified in 07 - Repository engineering;
  • move the interactive terminal lookbook, SVG generation/check behavior, and neutral story registry into the external lookbook package;
  • keep environment-aware path-display policy such as shorten_home in jackin-core and remove its jackin-tui re-export; TermRock text APIs do not read $HOME or own path presentation;
  • remove agent/container/brand-specific exports and stories;
  • introduce the private/builder-based semantic theme and consumer brand/header input;
  • depend on ratatui-core in the base crate and put Crossterm session/event integration behind one optional feature;
  • extract the executor-neutral runtime contracts and pure Ratatui drive_frame/drive_render drivers into the base runtime module, optional by use and referenced by no widget; keep Tokio spawning/receiver integration (via the module's closure adapter) and product-global terminal ownership consumer-owned;
  • replace raw hyperlink/pointer/clipboard overlay bytes with typed osc requests and pure encoders, leaving emission policy in consumers;
  • derive lookbook SVG colors from the shared theme values, asserting the committed SVGs stay byte-identical;
  • carry every quality-backlog defect through unchanged: no width or non-color fix rides along with the ownership move;
  • convert public rendering to the stable Widget for &T / StatefulWidget for &T convention, with borrowed render data and stable consumer IDs;
  • ensure public APIs contain no consumer model;
  • resolve the frozen component dispositions exactly: filter behavior is a TextInput composition rather than a public FilterField; TermRock has backdrop/dialog/hit primitives but no modal stack/router; scroll state uses usize logical units, clips in logical space, and uses one centralized saturating u16 conversion only at the Ratatui edge;
  • make every new TermRock-authored change after the provenance boundary a DCO-signed, buildable commit; inherited donor commits are not retroactively signed or required to build standalone;
  • after the neutral standalone head passes local source, build, render, provenance, license, and secret checks, push only main to the empty public repository and run the available push gates; record that immutable commit in the jackin❯ implementation PR.

Exit gate: cargo tree and source audit show no Tailrocks product dependency; neutral tests/render fixtures pass; the first published TermRock main head is buildable and green; and no donor branch or tag was published.

Stage 3: Establish revision-consumable quality

  • document components, state ownership, key/focus behavior, theming, and integration examples;
  • add neutral interactive stories for every public component/state;
  • add deterministic minimum/normal/wide render gates and terminal restoration tests;
  • build the Fumadocs component catalog from committed CLI-generated SVGs and a generated coverage manifest;
  • document and test terminal, list, render, and check CLI operations;
  • test the supported Rust/Ratatui/Crossterm matrix on macOS and Linux;
  • run formatting, lint, unit, docs, dependency, license, and supply-chain checks;
  • run default/no-default, all-feature, feature-powerset, MSRV, rustdoc, package, public-API-report, catalog-coverage, deterministic-render, and declared-platform checks; commit the reviewed public API report, while the first tag later establishes the automated semver comparison baseline;
  • publish an immutable Git revision and migration guide; publishing a crates.io preview remains optional.

Exit gate: an external minimal consumer can pin one full commit SHA, build and render without jackin❯ code, open the Fumadocs catalog, and reproduce the committed previews.

Stage 4: Migrate the first consumer

  • depend on the tested full TermRock main commit through Cargo's rev form and commit Cargo.lock; do not switch this migration to a preview release or tag;
  • replace imports incrementally without product redesign or a broad compatibility re-export facade;
  • retain product components/stories locally;
  • move generic component documentation, neutral SVG previews, and the neutral interaction conventions (tab pattern, focusability, hover-scroll, dialog/backdrop layering without a shared modal stack, hint discipline) to the external Fumadocs site as debranded pages, while retaining jackin❯ composition and design-decision docs that link out;
  • remove the local generic lookbook CLI only after equivalent external terminal/render/check workflows pass;
  • migrate every jackin-core compatibility caller before deleting duplicates;
  • re-home the Tokio subscription spawn helpers into jackin-console;
  • keep Capsule's locally painted status bar and hint rows; converging them on the shared Tabs/HintBar is a post-parity follow-up, not a migration requirement;
  • compare console, Capsule, launch, input, mouse, modal, terminal-restoration, lookbook, and SVG fixtures;
  • update canonical TUI docs to identify shared versus jackin❯ ownership;
  • compare the frozen donor revision with current origin/main; before donor deletion, merge current origin/main by the normal merge-sync policy and regenerate affected inventory/parity evidence for any upstream TUI change;
  • delete in-tree donor crates only after parity and dependency audits pass.

All migration slices are commits on the one implementation branch. Each slice pins a full TermRock main commit through Cargo rev, commits the lockfile, and reruns the complete workspace; none merges independently.

Exit gate: no visible/key behavior regression, no duplicate shared implementation, and the active jackin❯ branch is green.

Rollback: until final donor deletion, the unmerged implementation branch can repin the last known-good TermRock commit or retain not-yet-migrated donor modules. Direct TermRock main commits are never rewritten or force-pushed; fixes land as new commits. Do not duplicate a type under both owners and do not publish compatibility shims.

Stage 5: Stabilize TermRock

  • land every quality-backlog fix (display width, non-color cues) with regenerated fixtures and migration notes before the first tag;
  • publish the first annotated Git tag after jackin❯ runs the final pinned revision successfully; the tag establishes the future semver-check baseline, while jackin❯ remains pinned to the full commit and crates.io publication remains a separate operator decision;
  • follow the shared-project-first Ratatui/Crossterm upgrade policy: the library upgrades first and jackin❯ repins as the compatibility oracle, with one supported pair per revision line;
  • maintain compatibility and migration notes for the TermRock/jackin❯ revision pair;
  • keep branch/fork iteration available while requiring exact commit pins for durable consumer changes;
  • defer every other product adoption and every component beyond the donor set to separately scoped future work;
  • split termrock-testing only after repeated cross-consumer test-helper demand;
  • measure API churn, dependency weight, render performance, and maintenance load before broadening scope;
  • enable protected-branch/pull-request governance for TermRock after the final tag/checkpoint and before the roadmap closes;
  • merge current origin/main into the jackin❯ implementation branch again before final merge, rerunning any evidence affected by upstream changes.

The final jackin❯ PR commit retires this roadmap item only after the TermRock tag, donor deletion, documentation transfer, and all completion gates are present. Partial completion is not merged.

Program risks and controls

RiskRequired control
premature generalizationclassify every item as extract, parameterize, remain, or remove; reject components beyond the existing donor set
visual or interaction regressionfreeze verified fixtures, migrate jackin❯ before redesign, and require the parity matrix before donor deletion
silent quality fixes during migrationrecord every known defect in quality-backlog.md; reject any unrecorded render change until parity completes
newly discovered blocking donor defectreturn the same branch to Stage 0, fix the donor, regenerate evidence, and re-freeze before continuing
dependency inversion or framework capturereject consumer imports and executor-specific public types; keep widgets independent from runtime and keep Crossterm additive
cross-repository deadlockpublish an immutable TermRock revision first, migrate one consumer slice at a time, and retain only not-yet-migrated donor modules
oversized single PRstructure the one branch as stage/slice checkpoint commits, maintain an evidence index, and keep every checkpoint independently reviewable and green
incomplete public TermRock mainprepare filtered history locally, first publish only a neutral buildable head, require every new TermRock commit after the provenance boundary to be signed/buildable, and repair forward rather than rewriting history
brand or domain leakagerequire semantic/data-driven APIs and keep product fixtures, wording, effects, and policy in each consumer
history or license lossuse history-preserving extraction, record the exact source/filter command, and require independent provenance/REUSE review
mutable dependency driftallow trusted branches only for iteration; require a full revision or immutable release plus the committed lockfile for durable changes

These controls are completion gates, not suggestions. A stage does not advance when its applicable control lacks evidence.

Acceptance checklist

  • No Tailrocks product crate is a dependency of the shared component crate.
  • No public shared type contains a product domain model.
  • Donor history and license attribution are independently reviewed.
  • Only TermRock main was published; inherited donor commits are clearly separated from new signed/buildable commits, and no donor branch/tag or raw filtered tip was advertised.
  • All public components have docs, tests, and neutral lookbook states.
  • The extracted CLI can interactively preview, list, render, and verify every neutral story.
  • The standalone Fumadocs site renders generated SVG states and fails verification when component docs, stories, or previews drift.
  • Keyboard, focus, non-color, Unicode, and terminal-size contracts pass.
  • Terminal mode restoration passes supported failure paths.
  • The quality backlog was carried bug-compatible through extraction and migration; every fix landed post-parity with regenerated fixtures.
  • Base termrock builds without Tokio or Crossterm; every component remains available there, while the optional Crossterm integration passes additivity, partial-initialization, and PTY restoration tests.
  • Public API and package diffs pass the documented semver/package policy.
  • The first tag is the recorded initial API baseline; cargo-semver-checks comparisons start with subsequent candidates rather than a nonexistent prior release.
  • jackin❯ parity passes before local donor deletion.
  • The post-bootstrap repository policy permits trusted branch/fork iteration but requires immutable commits or releases for durable builds.
  • No other Tailrocks product repository was checked out, changed, or used as a completion gate.
  • Roadmap and canonical docs name one owner for each component/policy.

On this page