April 6, 2026
4 pull requests merged across 2 repos
bahdotsh/indxr
- Add
wiki_compoundMCP tool — single-call knowledge compounding that auto-routes synthesis text to the best matching wiki page (or creates a new topic page). Uses keyword scoring, no LLM call needed. - Replace
contribute_hintstrings inwiki_search/wiki_readwith structuredcompound_suggestionobjects containing tool name, args template, and source page IDs. - Add
indxr wiki compoundCLI command (reads from file or stdin) for autonomous/scripted compounding. - Extract shared scoring logic from
wiki_suggest_contributioninto reusablescore_synthesis_against_pagesandderive_topic_idhelpers.
Test plan
-
cargo build --features wiki— compiles clean -
cargo build(without wiki) — compiles clean -
cargo clippy --features wiki— no warnings -
cargo fmt --check— formatted -
cargo test --features wiki— all 420 tests pass (413 unit + 7 integration) - Manual: start MCP server, verify
wiki_compoundintools/list - Manual: compound to existing page, verify content appended
- Manual: compound with no match, verify new topic page created
- Manual:
echo "test" | indxr wiki compound - --source-pages architecture
Transforms the wiki from a manually-triggered feature into a self-maintaining knowledge system that compounds automatically.
- Contradiction tracking: Structured
Contradictiontype in page frontmatter, parsed from LLM update responses via<!-- CONTRADICTIONS -->blocks. Surfaced inwiki_status,wiki_read,wiki_search. Resolvable viawiki_contribute. - Auto-contribute hints:
wiki_searchandwiki_readresponses include contribution hints when touching multiple pages. Newwiki_suggest_contributiontool suggests where to file synthesis (keyword matching, no LLM call). - New page detection:
update_affectednow detects uncovered changed files and uses incremental LLM planning to assign them to existing pages or create new ones (capped at 3 per update). - Auto-update on watch:
serve --watch --wiki-auto-updatetriggers background wiki updates after file changes with a separate 30s debounce. UsesAtomicBoolconcurrency guard and a background tokio runtime. NewMcpServerConfigstruct replaces the growing param list.
All changes are backward compatible (serde(default) on new fields), feature-gated behind #[cfg(feature = "wiki")], and pass all 413 tests.
Test plan
-
cargo build --features wikicompiles -
cargo build(no wiki feature) compiles -
cargo test --features wiki— 406 unit + 7 integration tests pass -
cargo test— 358 tests pass (no wiki) -
cargo clippy --features wiki— clean -
cargo clippy— clean -
cargo fmt --check— clean - Backward compat: existing wiki pages without
contradictionsfield deserialize with empty Vec - Manual:
indxr serve --watch --wiki-auto-update --wiki-exec <mock>— verify wiki updates after file change - Manual: generate wiki, add new source file, run
wiki update— verify new page created
bahdotsh/wrkflw
wrkflw validatenow rejectsenv: VAR=value(bare strings) at step, job, and top-level — GitHub Actions only accepts mappings forenv:- Expression strings like
env: ${{ fromJSON(...) }}are still allowed - Adds
validate_env()helper in the validators crate, wired intovalidate_steps,validate_jobs, andevaluate_workflow_file
Closes #89
Test plan
-
cargo fmt --all— clean -
cargo clippy --all-targets --all-features— clean -
cargo test -p wrkflw-validators— 30 tests pass (6 new) -
cargo test -p wrkflw-evaluator— passes - Full
cargo test— all green - End-to-end:
wrkflw validaterejectsenv: VAR=valueat step, job, and top level - End-to-end:
wrkflw validateaccepts properenv:mappings
Adds the missing subsystems needed to emulate real-world GitHub Actions workflows locally: artifact storage, persistent caching, secret expression resolution, inter-job output chaining, and workflow command parsing.
New capabilities
- Artifact upload/download — Local
ArtifactStoreemulatesactions/upload-artifactandactions/download-artifact. Files are copied under a per-run temp directory, preserving relative paths. Path traversal and symlink attacks are blocked.
- Persistent cache — Local
CacheStoreat~/.wrkflw/cache/emulatesactions/cachewith SHA-256 keyed entries, prefix-basedrestore-keysmatching, LRU eviction at 1 GiB, and atomic save via tmp+rename. Cache persists across workflow runs.
- **
secrets.*expressions** — Secrets referenced in job steps are pre-resolved at job start and available via${{ secrets.NAME }}. The evaluator stays synchronous; async resolution happens once per job.
- **
needs.*/jobs.*context** —needs.<job>.outputs.<key>andneeds.<job>.resultresolve from upstream job results. Outputs are accumulated across dependency batches and filtered to declaredneeds:dependencies. Matrix jobs warn on non-deterministic output overwrites.
- Step outcome/conclusion —
steps.<id>.outcome(raw) andsteps.<id>.conclusion(aftercontinue-on-error) track real values.success()/failure()/cancelled()builtins consult actual job state instead of returning hardcoded values.
- Workflow commands — New parser for
::set-output::,::add-mask::,::error::,::warning::,::notice::,::debug::,::group::/::endgroup::,::save-state::, and::stop-commands::from step stdout.::add-mask::dynamically registers secrets with the masker.
Correctness and security fixes
- Expression tokenizer operates on
&strinstead of&[u8], fixing UTF-8 corruption in string literals format()uses single-pass replacement to prevent arg content from being consumed by later placeholderstoJSON()usesserde_jsonfor proper escaping of control charactersSecretMaskeruses fixed***replacement (matching GHA) instead of leaking first/last charactersSecretMaskerusesRwLockinterior mutability so::add-mask::can add secrets through shared refs- Path traversal checks on artifact names, cache paths, download targets, reusable workflow paths, and
hashFilesglobs - Symlinks are skipped in artifact/cache directory walks
INPUT_*env vars are masked in step output logs- Unparseable
if:conditions now evaluate tofalse(matching GHA) instead oftrue - Workflow command
decode_valuehandles%2C(comma) and%3B(semicolon) in addition to the existing encodings
Architecture improvements
JobServicesstruct groups secret manager, masker, stores, and resolved context to reduce parameter countsStepLoopStatededuplicates the step-outcome processing logic betweenexecute_jobandexecute_matrix_jobhandle_upload_artifact,handle_download_artifact,handle_cache_actionextracted from theexecute_stepmonolithpreprocess_expressionstakes a singleExpressionContextinstead of 5 separate parameters- Reusable workflow execution shares parent's secret manager, masker, and artifact/cache stores
secrets: inheritpropagates parent secrets to called workflows
Test plan
-
cargo build— compiles clean -
cargo test— all tests pass, 0 failures -
cargo clippy— no warnings -
cargo fmt -- --check— no formatting issues - New unit tests for
workflow_commands,artifacts,cache,format()edge cases, condition parse-error behavior, andprocess_workflow_commandsintegration