Skip to content

fix(si): harden evidence, proposal ids, eval mode, registry, and eval gate - #232

Merged
anvil008 merged 1 commit into
mainfrom
fix/si-hardening
Sep 14, 2026
Merged

anvil008 merged 1 commit into
mainfrom
fix/si-hardening

Conversation

@anvil008

Copy link
Copy Markdown
Owner

Fixes the bugs found by an end-to-end run of the installed si-project / si-global CLIs, plus follow-ups from two independent review passes.

Fixes

  1. record refuses duplicate evidence basenames instead of silently overwriting (which left check failing).
  2. Proposal ids never overwrite: automatic ids get -2, -3 suffixes via exclusive create; an existing explicit --id is refused.
  3. Eval mode: register refuses; the marker is honoured from any subdirectory of a jj workspace or git worktree (including nested git repos inside a jj workspace); si-global skips eval-mode projects and flags them in projects.
  4. agents-md rule text and titles are folded to one line (no markdown injection into AGENTS.md); skill proposal text stays verbatim.
  5. Invalid registries fail loudly in both si.py (no silent rewrite) and si_global.py; a missing registry is still empty.
  6. The eval gate pointed at the deleted evals/run_evals.py; it now names the CI checks (unittest discover, update-guide.py --check, package.py), with a test that the paths exist and appear in ci.yml.
  7. Proposal --id and --skill-name / stored skillName are validated before filesystem access (no traversal, no control characters); legacy ids still apply; corrupt proposal JSON gives si error: exit 1.

Verification

  • Regression tests for each fix (confirmed failing on the previous code)
  • python3 -m unittest discover -s tests: 157 tests OK; update-guide.py --check OK; package.py OK
  • Two independent review passes; all findings resolved

🤖 Generated with Claude Code

https://claude.ai/code/session_01VnZxcmzmwzvXQXfwFk6vXW

… gate

- record refuses duplicate evidence basenames before writing, so a
  successful record always leaves check passing.
- propose allocates unique proposal ids (-2, -3 suffix, exclusive
  create) and refuses an explicit --id that already exists.
- register refuses eval-mode repositories, and the eval-mode check
  covers subdirectories of a workspace or worktree (up to the same
  jj-first boundary resolve_toplevel uses, so nested .git repos do not
  escape it); si_global skips eval-mode projects in
  scan/cluster/propose and flags them in projects.
- propose folds --title, and the rule text of agents-md proposals
  (also on apply), so they cannot inject markdown into AGENTS.md; skill
  proposal text stays verbatim as the whole SKILL.md.
- si_global fails on an invalid or wrongly shaped registry; a missing
  registry is still empty.
- Replace the deleted evals/run_evals.py gate with Nova's CI checks in
  propose output, si-global SKILL.md, and ADR 0035.
- si.py init/register refuse an invalid or wrongly shaped registry
  instead of treating it as empty, leaving the file untouched.
- propose validates ids and skill names before any filesystem access:
  new ids must match the raw trace id pattern, --apply accepts an
  existing proposal named by any single safe path component, and
  --skill-name or a stored skillName must be a safe component (no
  separators, leading dot, or control characters). A corrupt
  proposal file on --apply is a controlled si error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VnZxcmzmwzvXQXfwFk6vXW
@anvil008
anvil008 merged commit 5f09da4 into main Sep 14, 2026
1 check passed
@anvil008
anvil008 deleted the fix/si-hardening branch September 14, 2026 17:07
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