[spark-compete wave 5] security cross-cut (stacked) - #307
Merged
Conversation
registry.py DEFAULT_LAB_PATH hardcoded ~/Desktop/spark-personality-chip-labs/personalities, which breaks installs that don't have the lab checked out on the Desktop. Switch the default to the platform-safe ~/.spark/spark-personality-chip-labs/personalities location, consistent with the search paths already prioritized in chip_loader.DEFAULT_CHIP_LAB_PATHS. Narrowed from PR #28: the chip_loader.py hunk was dropped because HEAD already prioritizes ~/.spark/modules/... and ~/.spark/... ahead of Desktop and uses the stronger guard 'spark-personality-chip-labs' in path.parts (a better impl than the PR's 'in str(path)'). Only the still-unfixed registry.py one-line default is landed here. Co-authored-by: johncrossu <johncrossu@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The secret-exfiltration guard used \b before the alternation, but \b does not match between a non-word char (.) and a word char in '.env', so 'curl ... .env' slipped past. Replace the leading \b with a (?<!\w) look-behind so the dot-prefixed token matches. PR #291 Co-authored-by: ifeoluwaaj@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…t stderr PR #295 (adopt): wrap subprocess.run in try/except so a missing codex binary (FileNotFoundError) or an exceeded budget (TimeoutExpired) surface as an actionable RuntimeError that preserves the operator's next move, instead of a raw stack trace. PR #296 (adjust): redact the raw stderr from the non-zero-exit RuntimeError (keep rc for triage, drop the stderr payload that can carry internal paths or prompt fragments). Per maintainer note, the tautological packet test (re-implemented the message, never imported codex_provider) was discarded; replaced with tests/test_codex_exec_stderr.py exercising the real call_codex redaction path via a monkeypatched subprocess.run. PR #295 PR #296 Co-authored-by: 4gjnbzb4zf-sudo@users.noreply.github.com Co-authored-by: TALLSOME24@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PR #276 (adopt): open state.db via 'file:...?mode=ro' URI so the probe builder can never accidentally mutate SIB's authoritative state (the user_instructions / personality_observations tables). PR #297 (adjust): redact sib_home from the _open_state FileNotFoundError ('State database not found'). Per maintainer note, the tautological packet test (re-implemented the message, never imported memory_grounded) was discarded; replaced with tests/test_memory_grounded_path.py exercising the real _open_state on a directory with no state.db. PR #276 PR #297 Co-authored-by: 4gjnbzb4zf-sudo@users.noreply.github.com Co-authored-by: TALLSOME24@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Consolidated path-redaction across the character runtime's FileNotFoundError / ValueError messages so callers no longer learn the internal directory layout. PR #287 (Esc1200, adopt): drop the full path from critic.load_critic and the base-chip YAML filename from registry.promote_evolved_persona_to_chip_lab. PR #286 (Esc1200, adjust; same-author same-concern as #287 -> one band): drop the search-path list from chip_loader.load_chip_by_id and replace the absolute artifact paths in persona.set_latest_persona_version / load_persona with the bare filename. Per maintainer note, also redact persona.load_persona_from_path (line 203) to the filename for consistency; the chip id / artifact filename are retained because they aid debugging. PR #298 (TALLSOME24, adjust): set_latest_persona_version line redaction. Per maintainer note the tautological packet test (re-implemented the message, never imported persona) was discarded; replaced with tests/test_persona_artifact_path.py exercising the real set_latest_persona_version against a missing artifact. The bundled packet-chip-loader-path-leak.json from #286 was excluded. PR #287 PR #286 PR #298 Co-authored-by: Esc1200@users.noreply.github.com Co-authored-by: TALLSOME24@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…inuous_eval Replace the two traceback.print_exc() calls in the continuous_eval loop with module-logger .exception() calls so failures land in structured logs (with the provider/context) rather than raw stderr dumps. PR #285 Co-authored-by: Esc1200@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
find_lowest_tier seeded weakest at (None, 1.0, 0), so when every eligible axis sits at the 1.0 ceiling the strict '< 1.0' comparison never fired and no tier was returned. Seed at (None, inf, 0) so a perfect-1.0 tier still qualifies as the weakest when all eligible axes tie at the ceiling. PR #267 Co-authored-by: 4gjnbzb4zf-sudo@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…md found When find_latest_persona has no persona.vN.md to load, the bare 'No persona.vN.md artifacts found.' gave the operator nowhere to look. Name the ARTIFACTS_DIR it searched and tell them to seed persona.v1.md there (or override ARTIFACTS_DIR), in both evolve.py and evolve_persona.py. PR #299 Co-authored-by: 4gjnbzb4zf-sudo@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nary PR #290 (adjust). Per maintainer note, landed ONLY the reliability/safety core: - full_pulse.py: wrap score_persona in try/except so a T1 scorer failure records an error row and continues instead of crashing the daemon. - codex_provider._default_codex_binary: when CODEX_PATH / SPARK_CODEX_PATH is set, expanduser + isfile-validate it (raise a clear FileNotFoundError) rather than blindly returning the string for execution. REVERTED (not applied): the two '@master' -> '@11c1d2da...' git-URL pins in evals/auto_loop.py and evals/lowest_tier_watch.py. Hardcoding this PR's own head commit into the self-evolution consumer-refresh loop would freeze auto-update and go stale on the next commit (a regression). Both URLs remain pinned to @master. PR #290 Co-authored-by: ifeoluwaaj@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…n not-found PR #6 (resurrect_adopt): make validate_chip_yaml_spec errors actionable - each type/shape failure now reports the offending type (got X) and a small inline YAML example, plus a pointer to the canonical chip schema doc. Also refines the #286 redaction of load_chip_by_id's FileNotFoundError: the full path-list was stripped, but the existing repo test (test_load_chip_by_id_omits_unavailable_desktop_lab_from_default_paths) asserts the *active* search-lab basenames stay in the message (while the unavailable Desktop lab must not). Restore the active-lab basenames (names only, de-duped/sorted) so the message stays debuggable without leaking the full filesystem layout. PR #6 Co-authored-by: 4gjnbzb4zf-sudo@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… example PR #21 (resurrect_adjust). Per maintainer note the chip_loader.py hunk was a BROKEN DIFF (unresolved <<<<<<< / ======= / >>>>>>> conflict markers; HEAD already uses 'except recoverable_load_errors' which supersedes it) and was discarded. Landed ONLY the memory_grounded.py docstring fix: replace the embedded 'C:/Users/USER/Desktop/.../tmp-home' and the real 'human:telegram:8319079055' id in the usage example with 'Path.home() / ".spark" / "sib-home"' and a '<your-user-id>' placeholder. PR #21 Co-authored-by: johncrossu@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ntion) PR #66 (resurrect_adjust). compare_personas.py returned 1 when the baseline held, conflating a domain verdict with a process failure. Flip to return 0 so a completed comparison always exits success; the verdict stays on stdout (WINS vs holds). Per maintainer note, confirmed no CI / Makefile / docs / wrapper in the repo branches on the old exit-1 signal, and documented the exit-0-always contract inline (option a). PR #66 Co-authored-by: 4gjnbzb4zf-sudo@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…bility) Follow-up to the #287/#286 path-redaction: PR #287 over-redacted promote_evolved_persona_to_chip_lab's ValueError to fully generic, but the repo invariant (test_persona_sidecar_promotion_rejects_malformed_base_yaml) keeps the offending chip *basename* in the message. The basename is not a path leak (no surrounding directory) and aids debugging, matching the #286 maintainer guidance that the filename should be retained. Restore ': {base_yaml_path.name}'. PR #287 Co-authored-by: Esc1200@users.noreply.github.com Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The env-var binary validation from #284 (block arbitrary execution via a malicious/stale CODEX_PATH / SPARK_CODEX_PATH) landed, but it ran inside _default_codex_binary() at module import (DEFAULT_CODEX_PATH = ...), so a stale CODEX_PATH crashed every importer of codex_provider — including eval drivers that never touch the codex backend. Split resolution from validation: - _default_codex_binary() now only resolves (expands ~, picks the platform fallback) and never raises, so import is always safe. - new validate_codex_binary() performs the isfile() check, scoped to an explicit env-supplied path, and is invoked at call time in call_codex() and codex_available(). Bare PATH lookups ("codex") stay a no-op. Preserves the security guarantee of #284 (an explicit, non-regular-file path is still blocked before exec) while removing the import-time crash. Closes the systemic group with #288/#290 (duplicates). Co-authored-by: ifeoluwaaj <ifeoluwaaj@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cherry-picks the two adversarial tests from #24 onto the current test_search_adapter.py. The production sanitizer (prompt_guard + attach_search_context) and a base sanitization test already exist in HEAD; these add coverage for multi-result snippet payloads: - snippets that try to become agent instructions (system-prompt-override + instruction-override categories), asserting the raw text is dropped and the benign summary survives. - snippets that request hidden data (secret-exfiltration + secret-file-request categories). Test-only; rebased onto current line numbers, no production change. Co-authored-by: jumperz11 <jumperz11@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-security-crosscut
vibeforge1111
changed the base branch from
spark-compete/wave4-memory-persona-voice
to
master
June 26, 2026 13:18
vibeforge1111
marked this pull request as ready for review
June 26, 2026 13:20
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.
Spark Compete — Wave 5 (security cross-cut), stacked on
spark-compete/wave4-memory-persona-voiceHighest-value security set. Wave-5 delta only.
Commits
On-merge points
ifeoluwaaj 9 · jumperz11 5
Verified: proportionate diff, no churn, no conflict markers. Compiles / tests green. Draft — gated on CI + approval.
🤖 Generated with Claude Code