jackin'
Behind jackin' — InternalsGetting Oriented

Workspace Automation (xtasks)

Every cargo xtask subcommand, what it does, and when a contributor reaches for it

jackin' keeps its workspace automation in a single Rust binary, crates/jackin-xtask/src/main.rs, following the cargo-xtask pattern: all task logic is Rust, subprocesses (docker, git) are driven through std::process::Command, and the project carries no shell task scripts. The cargo alias in .cargo/config.toml makes cargo xtask <command> the direct entrypoint, and the construct-* tasks in mise.toml delegate to the same binary so CI and local runs share one implementation.

This page is the canonical inventory of xtask commands. A PR that adds, removes, or reshapes a subcommand updates this page in the same PR. The declarative image build graph stays in docker-bake.hcl — the xtask invokes it rather than reimplementing it in flag assembly.

Construct image tasks

The construct family (source: crates/jackin-xtask/src/construct.rs) builds and publishes the construct base image. Each has a matching mise task; the role-author-facing build walkthrough lives on Construct image.

Commandmise taskWhat it does
cargo xtask construct init-buildxconstruct-init-buildxCreate and bootstrap the named Buildx builder.
cargo xtask construct doctor-buildxconstruct-doctor-buildxInspect the configured Buildx builder and list available builders.
cargo xtask construct reset-buildxconstruct-reset-buildxRecreate the configured Buildx builder from scratch — the fix when builds fail with a corrupted builder.
cargo xtask construct build-localconstruct-build-localBuild the construct image for the host platform and load it into the local Docker daemon.
cargo xtask construct build-platform <amd64|arm64>construct-build-platform <platform>Build for one specific platform and load it locally.
cargo xtask construct push-platform <amd64|arm64>construct-push-platform <platform>Push a single-platform image by digest. CI-only for the canonical registry.
cargo xtask construct assert-version-unpublishedconstruct-assert-version-unpublishedFail when the version in docker/construct/versions.env already exists in the registry — the publish-gate guard.
cargo xtask construct publish-manifestconstruct-publish-manifestCombine per-platform digest pushes into one multi-platform manifest. CI publish step.
cargo xtask construct inspectconstruct-inspectPrint the resolved Bake configuration without building — dry-run inspection.

Pull request verification helpers

jackin-dev pr sync <PR_NUMBER> (source: crates/jackin-dev/src/main.rs) owns the checkout and isolation setup for local PR verification. It asks GitHub for the PR head, refreshes $HOME/Projects/jackin-project/test/pr-<PR_NUMBER>/jackin, checks out the PR's real head branch while keeping the bundle directory keyed by PR number, trusts and installs mise, builds the local jackin binary, copies live config into $HOME/Projects/jackin-project/test/pr-<PR_NUMBER>/state/config, creates empty runtime state under $HOME/Projects/jackin-project/test/pr-<PR_NUMBER>/state/home, and writes $HOME/Projects/jackin-project/test/pr-<PR_NUMBER>/env.sh.

Source the generated env file before smoke testing the PR. jackin-dev runs as a child process, so it cannot export into the parent shell directly. The env file prepends the checkout's target/debug directory to PATH, sets JACKIN_CONFIG_DIR to the PR bundle's copied config, sets JACKIN_HOME_DIR to the PR bundle's empty state home, and includes JACKIN_CAPSULE_BIN or JACKIN_CONSTRUCT_IMAGE only when the PR diff requires local capsule or construct preparation.

CommandWhat it does
jackin-dev pr sync <PR_NUMBER>Clone or refresh the PR checkout on the PR's real branch, prepare isolated config/state, build local jackin, auto-build capsule/construct inputs from the diff, and write env.sh.
jackin-dev pr clean <PR_NUMBER>Remove the full PR verification bundle.
jackin-dev pr env <PR_NUMBER>Print the cd, source, and which jackin commands for entering the bundle.
jackin-dev pr path <PR_NUMBER>Print the PR bundle root.
jackin-dev pr status <PR_NUMBER>Show local checkout freshness, branch/head SHAs, and env/state existence.

sync takes optional overrides: --config blank starts from an empty config directory for clean-room verification (default copy mirrors the operator's live config), --test-dir <path> relocates the bundle root, and --repo <owner/name> targets a different repository.

cargo xtask pr body --base <ref> assembles a PR body from the diff. It prints a classified change digest (rust / docs / capsule / schema, plus the changed-file list) to stderr, and the body skeleton — .github/PULL_REQUEST_TEMPLATE.md with the verify-locally ### blocks that do not apply to the diff removed — to stdout. The split lets you redirect the body to a file (cargo xtask pr body > body.md) while reading the digest in the terminal. Block selection: Checkout always; Static checks / Rust tests / User smoke on a Rust change; Schema migration smoke on a versioned-schema touch; Docs checks / Documentation on a docs/** change; jackin-capsule smoke on a crates/jackin-capsule/ change. The prose sections stay as template placeholders for the author to fill.

PTY fixture extraction

cargo xtask pty-fixture <run.jsonl> <session-label> <out.bin> (source: crates/jackin-xtask/src/pty_fixture.rs) turns a --debug run log into a replayable terminal-fixture file. It scans the log for the capsule's session feed_pty bytes: debug lines, filters them to one session label (the label= field, e.g. Codex), decodes the hex byte dumps, and concatenates them in order into a binary fixture for the render-conformance harness in crates/jackin-capsule/src/daemon/tests.rs.

Both log shapes work as input: the host diagnostics run JSONL (capsule lines embedded inside JSON string fields) and a raw in-container multiplexer.log. Fixtures land under crates/jackin-capsule/tests/fixtures/pty/README.md by convention, and the full recording flow — reproducing with --debug, locating the run id, extracting, and wiring the fixture into the harness — is documented in TESTING.md.

Reach for it when an operator-reported rendering bug needs the agent's exact byte stream as a regression test: one command replaces hand-extracting hex from logs.

Documentation sidebar tasks

The change, research, and roadmap families (source: crates/jackin-xtask/src/docs.rs) scaffold and validate the Fumadocs meta.json sidebars under docs/content/docs/, so contributors never hand-edit the sidebar JSON or leave a new page unreachable. They locate the repo root by walking up for docs/content/docs, so they run from anywhere in the tree.

CommandWhat it does
cargo xtask change new <slug> --group <group>Scaffold a roadmap item at reference/roadmap/<slug>.mdx (frontmatter, **Status**: Open, Problem/Why It Matters/Design/Tasks/Related Files) and register it as ../<slug> in the named group's meta.json. --title overrides the title-cased default.
cargo xtask research scaffold <slug>Scaffold a research dossier at research/<slug>/ with index.mdx, a prompt.mdx brief, a meta.json (pages: ["index", "prompt"]), and register the dossier in the parent research/meta.json. --title overrides the default.
cargo xtask research checkValidate every research meta.json: each pages entry resolves to a file/dir on disk, and no .mdx is orphaned. Non-zero exit on any problem.
cargo xtask roadmap auditSame validation for the roadmap subtree, including (group) folders and ../<slug> cross-references. Non-zero exit on any problem.
cargo xtask roadmap retire <slug>Retire a shipped roadmap item. --plan (default) prints a read-only worklist — page content, inbound links, and the sidebar entry. --apply drops the ../<slug> group entry, deletes the .mdx, runs the audit, and fails if any inbound link still resolves to it. --partial sets **Status**: Partially implemented and keeps the page.

research check is read-only and deterministic. Roadmap sidebar parity is already gated in CI by bun run check:roadmap-sidebar (in the docs workflow), so roadmap audit is the local equivalent rather than a second CI gate.

Schema migration gate

cargo xtask schema-check --base <ref> (source: crates/jackin-xtask/src/schema.rs) enforces the five-artifact rule for versioned schemas described in PRERELEASE.md. It reads each CURRENT_{CONFIG,WORKSPACE,MANIFEST}_VERSION on the working tree and at the base ref; when one is bumped it asserts the new from-<predecessor>/ fixture directory exists (meta.toml / before.toml / after.toml, with the right target_version) and that schema-versions.mdx carries a Timeline entry for the new version. The migration step and the existing-fixture re-bake are already enforced by tests/migration_fixtures.rs, so this gate covers only the two artifacts those tests cannot see. The CI workflow runs it on every Rust change so a partial schema bump fails before merge.

Adding a new xtask

Repo-internal automation belongs in this binary, not in shell scripts or one-off justfile recipes: add a module under crates/jackin-xtask/src/main.rs, register the subcommand in the Command enum, and — when CI or contributors will invoke it routinely — add a delegating mise task. Host-side developer workflows that must be available before a checkout exists belong in jackin-dev instead. Update this page in the same PR.

On this page