femic.instance_context Module
The femic.instance_context module is FEMIC’s source-of-truth seam for
resolving the active deployment instance root. It is small, but it owns one of
the most important path contracts in the entire system: whether runtime paths
should be resolved from an explicit --instance-root, the
FEMIC_INSTANCE_ROOT environment variable, the current working directory, or
the legacy repo-root fallback path used for backward compatibility.
If you are debugging why FEMIC read config or data files from the wrong place, why a command worked from the repo root but not from a deployment instance, or why tests and direct command-function calls behave differently from the CLI, this is the first module to read. In practice it owns:
precedence rules for instance-root resolution
the typed
InstanceContextpayload used by downstream path logiccompatibility fallback to the legacy repository-root layout
normalization of relative paths against the resolved instance root
Start Here If…
Use this page first if you are trying to:
understand the precedence between
--instance-root,FEMIC_INSTANCE_ROOT, and the current working directorydebug why FEMIC unexpectedly fell back to the legacy repository root
inspect how a relative
Pathoption becomes an absolute runtime pathdecide whether an instance-path bug belongs here or in
femic.pipeline.io
Typical maintenance path:
Start with
resolve_instance_context()for any question about which root FEMIC chose.Read
InstanceContext.resolve_pathwhen the issue is about how relative config/data/log paths are normalized.Inspect the legacy workspace marker helpers if behavior differs between deployment-instance and source-checkout workflows.
Typical Usage
The common pattern is to resolve the context once and then normalize all instance-relative paths through it:
from pathlib import Path
from femic.instance_context import resolve_instance_context
context = resolve_instance_context(instance_root=Path("external/femic-k3z-instance"))
run_config_path = context.resolve_path(Path("config/run_profile.k3z.yaml"))
How This Fits Into The Pipeline
This module sits below the CLI and above nearly every runtime path decision:
command-layer inputs decide whether an explicit instance root was supplied
resolve_instance_context()chooses the active root using CLI, env, current working directory, and optional legacy fallback rulesdownstream modules such as
femic.pipeline.iouse that resolved root to derive config, data, output, and log paths
That means this module owns where FEMIC thinks the instance begins. It does not decide which specific artifacts inside that root should be used. Once the root is chosen, artifact selection moves into higher-level modules.
Key Entry Surfaces
The highest-value entrypoints in this module are:
resolve_instance_context()Resolve the active instance root with CLI > env > cwd precedence and optional legacy fallback behavior.InstanceContextSmall typed payload that records the chosen root, its source, and any compatibility warnings.InstanceContext.resolve_path()Normalize a user-facing path relative to the resolved instance root.
Core Contracts
The most important runtime contracts in this module are:
explicit CLI
instance_rootwins over everything elseFEMIC_INSTANCE_ROOTwins when CLI input is absentotherwise FEMIC uses the current working directory
optional legacy fallback is only used when the caller provides a legacy repo root, the current working directory does not already look like an instance root, and the legacy root still matches the older workspace markers
relative paths are always resolved beneath the chosen instance root
Those rules are why this module matters so much for tmp clones, bundled
external/* instances, and tests that call command functions directly.
Failure Seams To Watch
The common failure boundaries in this module are:
wrong precedence assumptions callers sometimes expect current working directory behavior even when
FEMIC_INSTANCE_ROOTis setsilent legacy fallback surprise compatibility fallback can make FEMIC appear to “find” files unexpectedly if the repo root still looks like an old-style workspace
non-
Pathoption objects direct test invocation can surface TyperOptionInfo-like objects, which this module explicitly normalizes away
Cross-References
Guides and references that pair especially closely with this module:
Related API pages:
Instance-root resolution helpers for deployment-scoped FEMIC execution.
- class femic.instance_context.InstanceContext(root, source, warnings=())[source]
Bases:
objectResolved instance-root context used for path derivation.
- Parameters:
root (Path)
source (str)
warnings (tuple[str, ...])
- resolve_path(value)[source]
Resolve user-provided path relative to the instance root.
- Parameters:
value (Path)
- Return type:
Path
- root: Path
- source: str
- warnings: tuple[str, ...] = ()
- femic.instance_context.resolve_instance_context(*, instance_root, env=None, cwd=None, legacy_repo_root=None, allow_legacy_fallback=True)[source]
Resolve active instance root with CLI > env > cwd precedence.
- Parameters:
instance_root (Path | None)
env (Mapping[str, str] | None)
cwd (Path | None)
legacy_repo_root (Path | None)
allow_legacy_fallback (bool)
- Return type:
InstanceContext