chore(release): prepare v0.2.0 - #31
Merged
Merged
Conversation
* chore: remove workflow scaffolding, ignore .temp/
Drop the assisted-workflow directories (.workflow, .docs/templates)
and their .gitignore block; add .temp/ to .gitignore.
* docs: replace assisted-workflow with omakiten in agent docs
Point AGENTS.md and CONTRIBUTING.md at the Omakiten MCP for shaping,
planning, and task tracking. Drop the assisted-workflow template table,
knowledge-base, and upstream-update sections. GitHub Projects tracking
is kept.
* test(runtime): spike Command PATH resolution, lock absolute-path interpreter strategy
* docs: spec env injection precedence, var-expansion grammar, secret non-persistence
* feat(config): case-preserving env parser with single-pass var expansion
Add parse_env_injectable, a separate parse path from parse_env_defaults
that preserves original key case verbatim (PATH/VIRTUAL_ENV are
case-sensitive on Linux) and applies single-pass $VAR/${VAR} expansion
per .docs/env-injection-spec.md section 2: no recursion, no command
substitution, undefined refs -> empty string, and \$ as the only
escape. Returns ordered Vec<(String, String)> for later extra_env
injection.
The existing lowercasing parse_env_defaults (TUI schema-field prefill)
is left untouched and is now pinned by a characterization test.
* feat(runtime): inject active env into script process at all 3 call sites
The active managed environment (.omaken/envs/<name>.conf, selected by the
`active` pointer) previously only prefilled TUI schema-field defaults and
never reached the spawned script process. Add a single shared resolver,
`resolve_active_env`, that reads the active env via the case-preserving
`parse_env_injectable` parser and returns layer-2 `extra_env` pairs per the
precedence table in .docs/env-injection-spec.md §1.
Wire it as the `extra_env` argument at all three run call sites (CLI run,
queue worker, TUI inline run) so there is one composition root, not three
implementations. The reserved vars OMAKURE_RUN_ID / OMAKURE_SCRIPTS_DIR
(layer 4) are still pushed after extra_env in execute_with_heartbeat and
remain non-overridable.
Behavior change: env files now inject into the child's os.environ (was
prefill-only). There is no CHANGELOG in this repo; the change is documented
on the resolver doc-comment. Secrets reach only the spawned process env and
are never persisted (spec §3), covered by a redaction test.
* feat(runtime): resolve interpreter to absolute path against injected PATH
When an injected PATH is present in the child environment (e.g. a
venv-prepended PATH from env injection), resolve the interpreter binary
to an absolute path via a which-style lookup against that PATH, then
Command::new(abs_path). This removes the silent wrong-interpreter footgun
where a system python3 could run despite injection, since name resolution
honoring the child PATH is a non-portable std implementation detail.
The resolver is language-agnostic: it resolves any program against the
(possibly prepended) PATH, so the same path serves python .venv, node
nvm/node_modules/.bin, ruby rbenv, etc. Falls back to the original
name-based behavior when no PATH is injected or the interpreter is not
found on it, preserving existing behavior.
* feat(cli): omakure run --env-file for per-run env injection
Add --env-file <path> to `omakure run`, folding the file's KEY=value
pairs on top of the managed active env (layer 3 over layer 2 per
.docs/env-injection-spec.md §1). Env-file values override active-env
values for the same case-sensitive key; omakure-reserved vars remain
non-overridable via the existing reserved-last ordering in
execute_with_heartbeat.
The layer-2 + layer-3 merge lives in a single composition root,
environments::resolve_run_env, rather than inline at the call site. A
missing or unreadable --env-file path is a hard error (invalid_argument)
instead of a silent skip, so typos and stale references surface.
* feat(cli): surface resolved env + interpreter in config
Extend `omakure config` (the diagnostics command) to surface the resolved
active-env KEY=value pairs and the interpreter that would actually run
.py scripts, so env/interpreter collisions become debuggable.
- Active-env keys are listed in injection order; sensitive values are
masked with **** via is_sensitive_key (raw secrets never printed).
- The python interpreter is resolved against the active env's PATH via
resolve_interpreter; falls back to name-based lookup with a note.
- Both human output and the --json ConfigPayload gain the new fields.
* docs: document env injection, --env-file, and venv-via-PATH in user docs
* fix(config): expand env-file $VAR against merged env incl. parent shell
Env-file value expansion sourced `$VAR` only from the current file's own
parsed keys, so a self-referencing value like `PATH=/x/bin:$PATH` expanded
`$PATH` against the file's own raw PATH (still containing `$PATH`). This
produced a doubled prefix, a leftover literal `$PATH` (single-pass, no
recursion), and dropped the parent shell PATH entirely — the spawned child
lost system bins (git/jq/bash).
Split parsing from expansion: `parse_env_pairs_raw` returns unexpanded,
case-preserving pairs; `merge_env_layers` folds raw layers (active env,
then --env-file) on top of a base map seeded with the parent shell env,
expanding each value against the growing accumulator *before* writing the
key back. A self-reference now prepends to the inherited value; a higher
layer sees the lower layer's already-expanded value. The base (parent env)
is an expansion source only — it is never emitted into `extra_env`, so the
child keeps inheriting it and no parent keys leak into the injected pairs.
The now-unused `parse_env_injectable` wrapper is removed; its tests are
retargeted to `parse_env_pairs_raw` / `merge_env_layers`.
Spec §2.1/§2.6 updated to state the expansion source precisely (merged env
including parent shell layer 1) with a worked self-reference example.
Refs: task 1758.
* fix(config): harden env secret diagnostics
* feat(workspace): support omakureignore scanning
* fix(workspace): honor nested omakureignore files * fix(workspace): tighten nested ignore traversal
This-Is-NPC
added a commit
that referenced
this pull request
Jul 7, 2026
* chore(release): prepare v0.2.0 (#31) * feat: harden env injection and add omakureignore (#28) * chore: remove workflow scaffolding, ignore .temp/ Drop the assisted-workflow directories (.workflow, .docs/templates) and their .gitignore block; add .temp/ to .gitignore. * docs: replace assisted-workflow with omakiten in agent docs Point AGENTS.md and CONTRIBUTING.md at the Omakiten MCP for shaping, planning, and task tracking. Drop the assisted-workflow template table, knowledge-base, and upstream-update sections. GitHub Projects tracking is kept. * test(runtime): spike Command PATH resolution, lock absolute-path interpreter strategy * docs: spec env injection precedence, var-expansion grammar, secret non-persistence * feat(config): case-preserving env parser with single-pass var expansion Add parse_env_injectable, a separate parse path from parse_env_defaults that preserves original key case verbatim (PATH/VIRTUAL_ENV are case-sensitive on Linux) and applies single-pass $VAR/${VAR} expansion per .docs/env-injection-spec.md section 2: no recursion, no command substitution, undefined refs -> empty string, and \$ as the only escape. Returns ordered Vec<(String, String)> for later extra_env injection. The existing lowercasing parse_env_defaults (TUI schema-field prefill) is left untouched and is now pinned by a characterization test. * feat(runtime): inject active env into script process at all 3 call sites The active managed environment (.omaken/envs/<name>.conf, selected by the `active` pointer) previously only prefilled TUI schema-field defaults and never reached the spawned script process. Add a single shared resolver, `resolve_active_env`, that reads the active env via the case-preserving `parse_env_injectable` parser and returns layer-2 `extra_env` pairs per the precedence table in .docs/env-injection-spec.md §1. Wire it as the `extra_env` argument at all three run call sites (CLI run, queue worker, TUI inline run) so there is one composition root, not three implementations. The reserved vars OMAKURE_RUN_ID / OMAKURE_SCRIPTS_DIR (layer 4) are still pushed after extra_env in execute_with_heartbeat and remain non-overridable. Behavior change: env files now inject into the child's os.environ (was prefill-only). There is no CHANGELOG in this repo; the change is documented on the resolver doc-comment. Secrets reach only the spawned process env and are never persisted (spec §3), covered by a redaction test. * feat(runtime): resolve interpreter to absolute path against injected PATH When an injected PATH is present in the child environment (e.g. a venv-prepended PATH from env injection), resolve the interpreter binary to an absolute path via a which-style lookup against that PATH, then Command::new(abs_path). This removes the silent wrong-interpreter footgun where a system python3 could run despite injection, since name resolution honoring the child PATH is a non-portable std implementation detail. The resolver is language-agnostic: it resolves any program against the (possibly prepended) PATH, so the same path serves python .venv, node nvm/node_modules/.bin, ruby rbenv, etc. Falls back to the original name-based behavior when no PATH is injected or the interpreter is not found on it, preserving existing behavior. * feat(cli): omakure run --env-file for per-run env injection Add --env-file <path> to `omakure run`, folding the file's KEY=value pairs on top of the managed active env (layer 3 over layer 2 per .docs/env-injection-spec.md §1). Env-file values override active-env values for the same case-sensitive key; omakure-reserved vars remain non-overridable via the existing reserved-last ordering in execute_with_heartbeat. The layer-2 + layer-3 merge lives in a single composition root, environments::resolve_run_env, rather than inline at the call site. A missing or unreadable --env-file path is a hard error (invalid_argument) instead of a silent skip, so typos and stale references surface. * feat(cli): surface resolved env + interpreter in config Extend `omakure config` (the diagnostics command) to surface the resolved active-env KEY=value pairs and the interpreter that would actually run .py scripts, so env/interpreter collisions become debuggable. - Active-env keys are listed in injection order; sensitive values are masked with **** via is_sensitive_key (raw secrets never printed). - The python interpreter is resolved against the active env's PATH via resolve_interpreter; falls back to name-based lookup with a note. - Both human output and the --json ConfigPayload gain the new fields. * docs: document env injection, --env-file, and venv-via-PATH in user docs * fix(config): expand env-file $VAR against merged env incl. parent shell Env-file value expansion sourced `$VAR` only from the current file's own parsed keys, so a self-referencing value like `PATH=/x/bin:$PATH` expanded `$PATH` against the file's own raw PATH (still containing `$PATH`). This produced a doubled prefix, a leftover literal `$PATH` (single-pass, no recursion), and dropped the parent shell PATH entirely — the spawned child lost system bins (git/jq/bash). Split parsing from expansion: `parse_env_pairs_raw` returns unexpanded, case-preserving pairs; `merge_env_layers` folds raw layers (active env, then --env-file) on top of a base map seeded with the parent shell env, expanding each value against the growing accumulator *before* writing the key back. A self-reference now prepends to the inherited value; a higher layer sees the lower layer's already-expanded value. The base (parent env) is an expansion source only — it is never emitted into `extra_env`, so the child keeps inheriting it and no parent keys leak into the injected pairs. The now-unused `parse_env_injectable` wrapper is removed; its tests are retargeted to `parse_env_pairs_raw` / `merge_env_layers`. Spec §2.1/§2.6 updated to state the expansion source precisely (merged env including parent shell layer 1) with a worked self-reference example. Refs: task 1758. * fix(config): harden env secret diagnostics * feat(workspace): support omakureignore scanning * fix: honor nested omakureignore files (#29) * fix(workspace): honor nested omakureignore files * fix(workspace): tighten nested ignore traversal * chore(release): prepare v0.2.0 (#30) * feat(workspace)!: remove omaken concept Move Omakure-owned runtime metadata to .omakure, remove the legacy Omaken CLI surface, and update scanner/docs/tests so .omaken has no active behavior. BREAKING CHANGE: .omaken is no longer created, read, migrated, or supported. Refs: task #1895 (#tests-passing, #documentation) Refs: task #1896 (#tests-passing, #documentation) Refs: task #1897 (#tests-passing, #documentation) Refs: task #1898 (#tests-passing, #documentation) Refs: task #1899 (#tests-passing, #documentation)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Before
omakure run.PATHvalues could fail to select the intended interpreter, such as a virtualenv Python..omakureignoresupport.After
omakure run, and queue workers.omakure run --env-filesupports per-run environment overrides with explicit precedence.PATH, making virtualenv and shim-based toolchains predictable..omakureignorerules exclude files and directories from the TUI,omakure scripts, search index, and scheduler.Summary of changes
.omaken/envs/<name>.confvalues are injected into spawned scripts.omakure run --env-file <path>.--env-file< Omakure-reserved variables.$VARand${VAR}expansion using the inherited/merged environment.PATH.omakure configreports masked active-env keys and the interpreter path..omakureignoresupport, including nested ignore files.0.2.0and addedrelease-notes/v0.2.0.md.Files updated
Cargo.tomlCargo.lockrelease-notes/v0.2.0.md.docs/env-injection-spec.md.docs/environments.md.docs/scripts-path.md.docs/usage.mdsrc/adapters/environments.rssrc/adapters/workspace_repository.rssrc/cli/run.rssrc/cli/config.rssrc/runtime.rssrc/run_executor.rstests/spike_command_path_resolution.rsValidation
v0.2.0release notes are present and the package version is bumped.Deviations
None
Risks / follow-ups
.omakureignoreintentionally supports a documented subset of gitignore syntax; unsupported patterns remain out of scope.References
66b7295,078bc5c,b2ff963