wyrd/tools
esc

    ↑↓ Move ↵ Open intentional results first Search by Pagefind
    Releases

    Initialization

    Initialize once to choose which artifacts Intentional manages and which Git tags define their current versions. A repository that already released a version uses the same discovery workflow as a new repository. Changesets repositories also require the explicit takeover described below.

    Discover the inventory

    Run from the Git repository root:

    intentional init

    Discovery recursively follows Git ignore rules and hard cache exclusions. Package-manager workspace membership informs recommendations, dependency analysis, and Changesets parity; it never limits discovery. Version-control metadata, Intentional state, and ecosystem caches are skipped. Ordinary names such as build, dist, bin, and vendor are scanned unless ignored. A manifest that describes no versioned project is not a candidate: a Cargo manifest without [package], or a package.json without a string name.

    The first run writes .intentional/init-plan.yml when candidates need input and exits with code 2. This is a request for decisions, not an operational failure. inferred-config.release-units: {} is expected before candidates have been resolved. Do not fill that mapping by hand to resolve candidates.

    Resolve every candidate

    Every item under discovery-candidates needs a resolution.kind. The first plan omits resolution; add it inside each candidate, alongside detector, path, projection, and tag. Use kebab-case keys.

    Choose a stable release-unit id, such as sample-application. This is the logical name used in configuration and later add --release-unit commands. It need not match the package name or directory, and choosing it does not rename the native package or module.

    Create a release unit

    For a standalone application or library, append this mapping to its candidate:

    resolution:
      kind: independent
      release-unit: sample-application

    The following excerpt shows the insertion point for a root Go module. Keep the actual generated id, evidence, native identity, and suggestions; the omitted fields here are only to keep the excerpt short:

    discovery-candidates:
      - id: candidate:0000000000000000000000000000000000000000000000000000000000000000
        detector: go-module
        path: go.mod
        # Keep the generated evidence and native-identity fields here.
        projection:
          adapter: go
          path: go.mod
          mode: none
        tag:
          id: primary
          role: primary
          template: '{id}@{version}'
        resolution:
          kind: independent
          release-unit: sample-application

    resolution.kind: independent creates a release unit. projection.mode is a separate field that controls version materialization; it does not resolve the candidate. For Go it is none: go.mod has no application version field, and Git tags supply the release version.

    Attach another manifest to that unit

    Use projection when two manifests represent the same logical release. Both independent and projection require release-unit. If the owning unit is created by another candidate in this plan, copy that creator’s actual id into target-candidate:

    resolution:
      kind: projection
      release-unit: sample-application
      target-candidate: candidate:0000000000000000000000000000000000000000000000000000000000000000

    If the unit already exists in .intentional/config.yml, omit target-candidate. Do not copy the placeholder id from this example.

    Leave an artifact unmanaged

    Use this complete mapping for an artifact outside the managed inventory:

    resolution:
      kind: excluded

    This does not delete the artifact. No release-unit or free-text reason field is accepted for this resolution.

    Resolve every path, including duplicate native identities. Do not merge or delete candidates. Initialization rejects duplicate release-unit creators, absent targets, identity disagreement, and projection cycles. See the configuration reference for candidate evidence, extraction diagnostics, and discovery receipts.

    Apply the initialization plan

    Edit only candidate and diagnostic resolution fields supported by the plan schema; retain generated evidence, fingerprints, suggestions, and state. Rerun the same initialization command after resolving candidates:

    intentional init --dry-run
    intentional init

    Ordinary initialization writes .intentional/config.yml, creates .intentional/intents/, and removes .intentional/init-plan.yml when the complete candidate graph validates. Review the generated configuration, including release-unit ids and tag templates, then commit it through your normal repository workflow. Init does not commit, publish, or create tags.

    A later init scans configured repositories too. Matching receipts make it a no-op; new candidates or changed excluded evidence require explicit input.

    Bootstrap an already released repository

    Suppose the repository has already released 0.1.0. Resolve its candidates and review the generated configuration before committing it. The default primary tag template is {id}@{version}. If existing releases use bare versions, change the resulting .intentional/config.yml to use {version} instead:

    release-units:
      sample-application:
        # Keep the generated path, projections, and discovery receipts.
        tags:
          primary:
            role: primary
            template: '{version}'

    This is a configuration excerpt, not a replacement file. Make this edit after init writes the configuration, rather than changing generated candidate suggestions. Commit the configuration once it matches the existing tag stream. {version} matches 0.1.0; {id}@{version} describes a different stream.

    Ensure the release tags and their history are available in the local checkout, then inspect:

    intentional status
    intentional check

    Matching pre-Intentional lightweight tags and annotated tags without Intentional record fields supply current-version authority. With a matching 0.1.0 tag, the current version is 0.1.0: no new baseline tag or repeat release is needed. Do not recreate or move that tag. tag --baseline also leaves it in place, ignoring an explicit --version for that existing stream. A tag carrying any Intentional record field is validated in full; partial or corrupt records fail validation.

    For Go this works without a manifest version. If the expected tag is present but status reports a missing baseline, inspect the configured template and available history before creating a new tag stream.

    After validation succeeds, author intents for subsequent changes. Adoption itself does not require an intent that re-releases the existing version. Intentional does not replace the repository’s build and publication workflow; that workflow still owns publishing when release tags are pushed.

    Establish a missing baseline

    Use this only when the configured tag stream has no existing matching tag. Commit configuration first. When version-bearing projections all agree, preview and create a baseline from them:

    intentional tag --baseline --dry-run
    intentional tag --baseline

    A tag-only unit, including a Go module, cannot infer a version from its manifest. Supply the intended current version explicitly. For an already released application whose current version is 0.1.0:

    intentional tag --baseline --version sample-application=0.1.0 --dry-run
    intentional tag --baseline --version sample-application=0.1.0

    A new, unreleased repository can use an explicit 0.0.0 baseline. This records a starting version; it does not publish a release. Named workspace tag streams without an existing matching tag also need explicit versions, using --version workspace/release=0.1.0. Repeat --version for multiple streams. Do not combine --baseline with --plan or --channel.

    Baselines create local annotated tags at the current commit. Preview their targets before creating them; the surrounding workflow owns pushing tags and any automation that push triggers. Finish with intentional status and intentional check to verify version authority.

    Adopt a Changesets repository

    When .changeset/config.json exists, ordinary intentional init preserves Changesets authority and writes .intentional/init-plan.yml. The plan contains source fingerprints, inferred configuration, stable diagnostics, exact source evidence, finite choices, recommendations, editable resolution fields, planned operations, pending-intent conversions, and a parity comparison for each release unit.

    intentional init
    # edit only the plan's resolution fields and make the reported repository edits
    intentional init
    intentional init --take-over --dry-run
    intentional init --take-over

    Initialization exits with:

    • 0 for a complete ordinary initialization, a ready adoption or upgrade plan, or a completed takeover.
    • 2 when the plan needs resolutions or verified repository edits.
    • 1 for invalid input or operational failure.

    intentional init --json emits the same plan as stable structured JSON. Reruns preserve resolutions while their evidence remains valid, report stale resolutions, and verify repository-integration edits from actual file state. Initialization never proposes a root projection file, and a rerun keeps the root projections that the configuration already has.

    When an npm manifest is explicitly projected onto a non-npm release unit, initialization may present a retain or remove integration choice. A best-effort removal recommendation uses only manifest structure, workspace and dependency graphs, exact source-tool identity references, and repository use. The diagnostic separates supporting evidence from contradictory evidence and states its uncertainty. Descriptions, comments, prose, semantic keywords, private status, minimal shape, path proximity, and matching versions never establish removability by themselves. The selected resolution is authoritative; takeover deletes the manifest only after an explicit remove resolution and a fresh check that no non-source-tool repository references remain.

    Changesets ignore entries become explicit suspended, excluded, or managed choices. suspended preserves release-unit identity while blocking any release that requires it, so it is the default recommendation unless repository evidence supports another disposition.

    Pending Changesets Markdown bodies are kept, and their package bumps are translated by the plan’s bump-translation field; see Bump translation below. Fixed and linked groups, npm dependency ranges and peer edges, internal dependency policy, and the translated pending bumps participate in the parity comparison. Private-package version and tag settings are recorded explicitly because Intentional separates version management from publication privacy and annotates every managed release. Unsupported or repository-specific behavior remains an explicit diagnostic. Repository release metadata and release scripts are retained as external evidence; Intentional does not interpret their private schemas or infer package, tag, publication, or ordering semantics from them. Cross-projection identity is provided only through explicit discovery-candidate resolutions. When a Changesets ignore entry names a native package that a candidate resolution projects onto another managed release unit, source parity is undefined at the package boundary. The target remains in both inventories and takeover stays blocked until the ignore entry is removed or the candidate resolution is revised. Changesets’ range-conditional peer-dependent option is one such explicit contract choice because Intentional applies configured depends-on edges uniformly; any pending-release difference remains a parity blocker. Internal devDependencies participate in the Changesets source computation but are not authored as durable Intentional depends-on edges; adopting that contract is also explicit, and current divergence remains blocking.

    --take-over is the only authority handoff. It refuses unresolved, stale, or blocked plans, then performs a rollback-capable transaction that writes canonical Intentional state, moves pending intents, removes recognized .changeset/ state, applies explicitly authorized proxy-manifest removals, and consumes the one transient initialization plan. References in workflows, package scripts and dependencies, lockfiles, release scripts, and tests are reported with exact locations; Intentional verifies the edits but does not rewrite those files.

    After committing the takeover changes, inspect version authority and establish any missing baselines:

    intentional status
    intentional tag --baseline --dry-run
    intentional tag --baseline
    intentional check

    Baseline inference succeeds only when every version-bearing projection of a release unit agrees. Tag-only release units and new workspace tag streams require explicit versions:

    intentional tag --baseline \
      --version library=1.2.3 \
      --version workspace/release=1.2.3

    status and check report the missing-baseline diagnostic and command until the configured primary baselines exist.

    Bump translation

    Changesets, and a contract-1 configuration with pre-1-0-bump-mapping: component, read a bump name as the version component to increment. Intentional reads it as the significance of the change. At 0.x, the two readings release different versions, so adoption translates pending bumps one time. The init plan records the choice in its bump-translation field, and init --bump-translation sets it:

    Pending bump at 0.4.1parity (default)significance
    majormajor with graduate: 1.0.0major: 0.5.0
    minormajor: 0.5.0minor: 0.4.2
    patchpatch: 0.4.2patch: 0.4.2
    • parity keeps the versions that the source tool would release. The parity comparison must be equivalent, including releases that dependency propagation causes. A rewrite cannot keep a dependency-derived version, for example from an internal dependency policy of minor at 0.x; such a release blocks the plan. Choose significance or change the pending changes.
    • significance keeps the bump names. Intentional’s result must equal the source tool’s algorithm with bump names read as significance. The parity comparison then shows each version that differs from the source tool with expected-difference: true, and its status is expected-difference. Such a plan can still be ready. Any other difference blocks the plan.

    At and after 1.0.0, and for release units without a version, bumps do not change. The version a bump applies to is the highest current version of the release unit’s fixed or linked group, else its own current version.

    An intent whose bump name changes keeps its body and gets an HTML comment that states the original bump and the version it keeps, for example:

    ---
    sample-library: major
    ---
    
    Add a capability.
    
    <!-- bump translation: Changesets `minor` for `sample-library` at 0.4.1 is `major` here, so that the next version stays 0.5.0. -->

    The comment is visible in review and hidden in the rendered changelog.

    A later init keeps the plan’s bump-translation unless you pass the flag again.

    Upgrade a contract-1 configuration

    intentional init upgrades a contract-1 configuration to contract-2. It keeps the comments in .intentional/config.yml. Release tags created under contract-1 stay valid.

    intentional init

    A configuration without pre-1-0-bump-mapping: component, or without pending intents whose release changes, upgrades at once, even when discovery candidates still need resolutions. A release changes when any next version differs, including versions from dependency propagation. A component configuration with such a release writes a plan with source-kind: contract-1, the default bump-translation, the intents it rewrites, and a parity comparison of the contract-1 and contract-2 versions. The plan is ready unless parity cannot keep a version; then it is needs-input with parity status blocked. Nothing else changes until you run init again:

    intentional init
    # review bump-translation and converted-intents in .intentional/init-plan.yml
    intentional init

    intentional init --bump-translation parity or intentional init --bump-translation significance upgrades in one step. If the configuration or the pending intents change after the plan is written, the next init writes a new plan for review.