Skip to content

Instance and Resource Naming

All naming logic lives in src/instance/naming.rs (container names, instance IDs, role-family matching) and src/runtime/naming.rs (image tags, derived resource names, display formatting).

Every fresh launch claims a unique, DNS-safe container name:

jk-{instance_id}-{workspace_compact}-{role_compact} ← saved workspace
jk-{instance_id}-{role_compact} ← ad-hoc launch (no workspace)

Components:

ComponentValueRules
jk-Fixed prefixIdentifies all jackin-managed Docker resources
instance_id8 charsCrockford base32, cryptographically random, collision-resistant
workspace_compactVariableOriginal workspace name with non-alphanumeric characters stripped, lowercased
role_compactVariableRole name with non-alphanumeric characters stripped, lowercased

Budget: The total base name must fit within 58 characters so that {base}-dind stays within Docker’s 63-character DNS label limit. The budget for workspace and role combined is 58 - 2 (jk) - 8 (id) - 3 (separators) = 45 characters. If the two compact components together exceed 45 characters they are split evenly and each is truncated with a 4-character SHA-256 suffix to keep the result deterministic.

Examples:

jk-1vft0hkh-chainargosblockchainnodes-agentbrown
└─ workspace: chainargos-blockchain-nodes
└─ role: agent-brown
jk-1vft0hkh-agentbrown
└─ ad-hoc launch, no workspace
jk-1vft0hkh-scentbird-thearchitect
└─ workspace: scentbird
└─ role: the-architect

Every container launch also creates three Docker resources derived by appending a suffix to the base name:

Role container: {base}
DinD sidecar: {base}-dind
Docker network: {base}-net
TLS certs vol: {base}-dind-certs

Example:

jk-1vft0hkh-chainargosblockchainnodes-agentbrown
jk-1vft0hkh-chainargosblockchainnodes-agentbrown-dind
jk-1vft0hkh-chainargosblockchainnodes-agentbrown-net
jk-1vft0hkh-chainargosblockchainnodes-agentbrown-dind-certs

DNS-sensitive environment variables (DOCKER_HOST, JACKIN_DIND_HOSTNAME, DOCKER_TLS_SAN, NO_PROXY, no_proxy, TESTCONTAINERS_HOST_OVERRIDE) use the DinD name as the hostname.

The Docker image is built once per role and rebuilt only when the role changes. It is stable across sessions.

Namespaced role: jk_{namespace}_{role-name}
Flat role: jk_{role-name}

All structural separators in image names are _. Role segment names are validated to [a-z0-9-] only, so _ never appears in a role or namespace name — _ always marks a structural boundary, never a word break inside a component.

Examples:

jk_chainargos_agent-brown ← chainargos/agent-brown
jk_agent-smith ← agent-smith (no namespace)
jk_scentbird_the-architect ← scentbird/the-architect

Collision safety: chainargos/agent-brown produces jk_chainargos_agent-brown while a flat role literally named chainargos-agent-brown produces jk_chainargos-agent-brown. The underscore vs hyphen difference makes them distinct.

Image vs container names: Container names use jk-{id}-… with - separators (required for DNS label validity). Image names use jk_… with _ separators. Both start with jk but use a different delimiter, so they are visually distinct in docker ps and docker images output.

When a role is built from a specific branch (jackin load --branch), the image tag adds the branch slug after a _ separator:

Namespaced role: jk_{namespace}_{role-name}_{branch-slug}
Flat role: jk_{role-name}_{branch-slug}

Branch slashes become dashes in the slug. All separators are _ — unambiguous because branch slugs contain only [a-z0-9-].

Examples:

jk_the-architect_feat-my-pr ← the-architect, branch feat/my-pr
jk_chainargos_agent-brown_feat-my-pr ← chainargos/agent-brown, branch feat/my-pr

Branch-specific images do not replace the stable image — they coexist with jk_the-architect under a distinct tag.

The per-instance state directory on the host always has the same name as the container:

~/.jackin/data/{container_name}/

Example:

~/.jackin/data/jk-1vft0hkh-chainargosblockchainnodes-agentbrown/

Set once at launch time, never renamed. The Docker container name and the state directory name are always identical — they are derived from the same string in src/instance/mod.rs.

The repo cache uses a stable per-role lock file to serialize concurrent git clone/fetch operations for the same role:

~/.jackin/data/{role-name}.repo.lock ← flat role
~/.jackin/data/{namespace}_{role-name}.repo.lock ← namespaced role
~/.jackin/data/{role-name}.locks/
~/.jackin/data/{namespace}_{role-name}.locks/

Example:

~/.jackin/data/agent-smith.repo.lock
~/.jackin/data/chainargos_agent-brown.repo.lock

The same _ separator as image names makes these stable across sessions and collision-safe between namespaced and flat selectors.

Cloned role repos are cached under ~/.jackin/roles/ using the selector’s namespace and name directly:

~/.jackin/roles/{role-name}/ ← flat role
~/.jackin/roles/{namespace}/{role-name}/ ← namespaced role

Example:

~/.jackin/roles/agent-smith/
~/.jackin/roles/chainargos/agent-brown/

By convention, role repos on GitHub are named jackin-{role-name}. This is a GitHub naming convention only — it has no effect on Docker container names or image tags.

https://github.com/ChainArgos/jackin-agent-brown
https://github.com/jackin-project/jackin-the-architect
https://github.com/jackin-project/jackin-agent-smith

When jackin role new scaffolds a new role repo, it creates the directory at:

{projects_dir}/{namespace}/jackin-{role-name} ← namespaced
{projects_dir}/jackin-{role-name} ← flat

jackin hardline, jackin eject, and jackin purge accept three forms:

chainargos/agent-brown ← role selector: finds running containers for this role
jk-1vft0hkh-agentbrown ← full container name: exact match
1vft0hkh ← instance ID: resolved via the instance index

When a role selector matches exactly one running container, the command proceeds directly. When it matches multiple containers, the command fails with an error that lists the matching container names and asks the operator to pass a specific container name or instance ID instead.