Instruction file imported from equinor/ai-platform-actions (
.github/instructions/inner-loop.instructions.md). Copyright stays with the author.
Inner-loop action contract
Keep the GitHub Action transport, adapter matrix, Docker entrypoint, and Typer command tree synchronized.
Ownership
action.yamldeclares the public GitHub Action inputs and exposes every input asINPUT_<UPPER_SNAKE_NAME>underruns.env.src/aip/inner/action_entrypoint.pyowns action-mode adaptation, command applicability, required inputs, aliases, legacy action invocation compatibility, and deferred CLI import.src/aip/inner/main.pyand the verb modules own the direct Typer CLI and command behavior.Dockerfilemust enter throughpython -m aip.inner.action_entrypoint. Direct users must still be able to invokepython -m aip.inner.main.test_action_contract.pyenforces synchronization between all of these surfaces.
Required synchronization
When adding, removing, renaming, requiring, or changing the default of an input or command, update all applicable surfaces in the same change:
- The input declaration and
INPUT_*exposure inaction.yaml. ACTION_INPUTS,CLI_OPTIONS, and the relevantCOMMAND_SPECSentry inaction_entrypoint.py.- The corresponding Typer registration and command signature.
- The command examples and input documentation when the public contract changes.
- Contract-test expectations, including command counts when a command pair changes.
The adapter matrix and Typer tree must expose exactly the same command pairs, options, required options, and positional argument for each command. Every declared action input must be classified as applicable to at least one command or explicitly unsupported.
Invariants
- Do not restore a universal
runs.argslist inaction.yaml; action mode must omit blank and inapplicable options. - Do not point the Dockerfile directly at
aip.inner.main. - Keep
action_entrypoint.pyimportable without importingaip.inner.main, Azure SDK modules, or command modules. Validate before the deferred CLI import. Errors may name a recognized verb-subject pair, but must not echo raw unsupported selectors or any other input values. - Preserve direct CLI passthrough and historical full-argument action compatibility unless an explicit migration removes them.
- Keep command-specific defaults in Typer or adapter logic rather than as global action defaults when a default would make an input appear nonblank for unrelated commands.
- Reject nonblank inapplicable, conflicting, and unsupported inputs. Do not enable Click/Typer unknown-option passthrough to conceal contract drift.
- Preserve environment-only mappings and cleanup for values that cannot be represented safely or compatibly as CLI options.
Validation
Run the focused contract suite after every contract change:
Set-Location inner-loop
uv run pytest test_action_contract.py -q
The change is incomplete if the action metadata, command matrix, and Typer-tree synchronization assertions do not pass.