Skip to content

chore(release): prepare v0.2.0 - #31

Merged
This-Is-NPC merged 3 commits into
masterfrom
test
Jul 1, 2026
Merged

chore(release): prepare v0.2.0#31
This-Is-NPC merged 3 commits into
masterfrom
test

Conversation

@This-Is-NPC

@This-Is-NPC This-Is-NPC commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Before

  • Environment files only prefilled TUI schema defaults and did not reliably reach spawned script processes.
  • Per-run env overrides were not available from omakure run.
  • Injected PATH values could fail to select the intended interpreter, such as a virtualenv Python.
  • Helpers, fixtures, generated files, and nested workspaces could still appear in script scanning surfaces without .omakureignore support.
  • Release automation could not publish the next release without a version bump and matching release notes.

After

  • Active environment files inject runtime variables into scripts across the TUI, omakure run, and queue workers.
  • omakure run --env-file supports per-run environment overrides with explicit precedence.
  • Interpreters resolve against the injected PATH, making virtualenv and shim-based toolchains predictable.
  • .omakureignore rules exclude files and directories from the TUI, omakure scripts, search index, and scheduler.
  • The package is prepared for the v0.2.0 release with complete release notes.

Summary of changes

Aspect Change
Runtime env injection Active .omaken/envs/<name>.conf values are injected into spawned scripts.
Per-run env overrides Added omakure run --env-file <path>.
Env precedence Documented parent shell env < active env < --env-file < Omakure-reserved variables.
Env expansion Added single-pass $VAR and ${VAR} expansion using the inherited/merged environment.
Interpreter resolution Resolved script interpreters against injected PATH.
Diagnostics omakure config reports masked active-env keys and the interpreter path.
Ignore scanning Added .omakureignore support, including nested ignore files.
Release prep Bumped package version to 0.2.0 and added release-notes/v0.2.0.md.

Files updated

  • Cargo.toml
  • Cargo.lock
  • release-notes/v0.2.0.md
  • .docs/env-injection-spec.md
  • .docs/environments.md
  • .docs/scripts-path.md
  • .docs/usage.md
  • src/adapters/environments.rs
  • src/adapters/workspace_repository.rs
  • src/cli/run.rs
  • src/cli/config.rs
  • src/runtime.rs
  • src/run_executor.rs
  • tests/spike_command_path_resolution.rs

Validation

Scenario Outcome
Test suite Passed.
Formatting check Passed.
Clippy warning gate Passed.
Linux release build Passed.
Package extraction/version check Passed.
Release readiness v0.2.0 release notes are present and the package version is bumped.

Deviations

None

Risks / follow-ups

  • Cross-platform release artifacts still depend on the GitHub Actions macOS and Windows runners.
  • .omakureignore intentionally supports a documented subset of gitignore syntax; unsupported patterns remain out of scope.

References

  • Commits: 66b7295, 078bc5c, b2ff963

* 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 This-Is-NPC changed the title Release v0.2.0 chore(release): prepare v0.2.0 Jul 1, 2026
@This-Is-NPC
This-Is-NPC merged commit 512412f into master Jul 1, 2026
3 checks passed
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant