Skip to content

feat(reflexes): port 5 passive rules from fs-cortex + idempotent merger#12

Open
NestorPVsf wants to merge 1 commit into
Luispitik:mainfrom
NestorPVsf:cortex-fusion-reflexes
Open

feat(reflexes): port 5 passive rules from fs-cortex + idempotent merger#12
NestorPVsf wants to merge 1 commit into
Luispitik:mainfrom
NestorPVsf:cortex-fusion-reflexes

Conversation

@NestorPVsf

Copy link
Copy Markdown
Contributor

Summary

Ports 5 non-duplicate passive rules (reflexes) from fermontero/fs-cortex (MIT) into the Sinapsis passive-rules tier. Adds an idempotent merger so fresh installs and upgrades both receive the new rules while preserving any user customizations.

Ported (5)

ID Trigger Purpose
read-before-edit ^(Edit|Write)\s Reminder to Read a file before editing it
test-after-change ^(Edit|Write)\s.*(\.test\.|...) Run tests after code edits
git-push-safety git push|gh pr create Fetch+rebase before push; --force-with-lease
git-merge-verify gh pr merge|git merge Verify CI + cleanup branch
instinct-downvote /downvote|wrong instinct|... Prompt /downvote on negative feedback (adapted from fs-cortex /cx-downvote to Sinapsis's native /downvote)

Skipped as duplicates (5)

env-never-commit, git-commit-quality, api-auth-check (→ api-auth-reminder), security-headers (→ security-headers-check), capture-decision (→ decision-capture). Sinapsis equivalents kept as-is.

Changes

  • seeds/reflexes.json (new): 5 rules + _credit / _license header.
  • core/_reflex-merge.mjs (new, ~100 LOC Node.js): idempotent merger, user id wins on conflict, atomic tmp → rename write that preserves 0600 file mode (install.sh hardens _passive-rules.json to 0600; the merger must not relax to umask). CLI flags: --seeds-path, --index-path, --dry-run.
  • install.sh + install.bat: new Step 5c runs the merger after hook scripts.
  • tests/test-reflexes.sh (new): 11 TDD tests including activator-integration (rules actually fire) and a regression guard that test-after-change does NOT fire on Read/Grep.

Codex review fixes applied pre-commit

/codex:review --base main flagged 3 issues, all addressed before this PR:

  • P1 install.bat was missing the reflex step → Windows fresh installs would have stayed on the old rule set. Fixed.
  • P2 atomic write replaced 0600-protected file with a new file at umask default (0644 typical) → relaxed permissions on a file documented as personal data. Fixed: merger stats existing file and chmods tmp to same mode (0600 fallback on fresh install).
  • P2 test-after-change fired on Read/Grep because trigger only tested filename. Scoped to ^(Edit|Write)\s.*. Regression test added.

Test plan

  • bash tests/test-reflexes.sh → 11/11 GREEN (including regression guard)
  • Full suite → 127/127 GREEN, 0 regressions
  • JSON validity on seeds/reflexes.json
  • bash -n syntax on install.sh
  • Manual: each new rule fires on its trigger (Edit, git push, gh pr merge, /downvote)
  • Manual: test-after-change does NOT fire on Read/Grep
  • /codex:review second-opinion applied

Independence

Branches from main (45949ed). No dependency on PR #7 (dashboard), PR #8 (seeds), or PR #9 (laws). Can merge in any order.

Credit

5 rules ported from fermontero/fs-cortex — MIT © 2026 Fernando Montero. Attribution preserved as origin: seed:fermontero-fs-cortex in each rule.

Ports 5 non-duplicate reflexes from fermontero/fs-cortex (MIT) into the
Sinapsis passive-rules tier:

- read-before-edit:   verify file was Read before Edit/Write
- test-after-change:  reminder to run tests after code edits
- git-push-safety:    pre-push fetch+rebase, --force-with-lease
- git-merge-verify:   pre-merge CI checks + cleanup
- instinct-downvote:  adapted from /cx-downvote to Sinapsis /downvote

Skipped 5 duplicates (env-never-commit, git-commit-quality,
api-auth-check/reminder, security-headers, capture-decision).

Implementation:
- seeds/reflexes.json: 5 rules + MIT attribution
- core/_reflex-merge.mjs: idempotent merger, user customizations win,
  atomic write preserves 0600 mode
- install.sh / install.bat: Step 5c runs the merger after hook scripts
- tests/test-reflexes.sh: 11 TDD tests (11/11 GREEN) incl. regression
  guard that test-after-change does NOT fire on Read/Grep

Codex review fixes applied pre-commit:
- P1: install.bat now mirrors install.sh reflex step
- P2: merger preserves existing chmod 0600
- P2: test-after-change scoped to ^(Edit|Write) so Read/Grep dont fire

Suite: 116 → 127 GREEN, 0 regressions.
Credit: Fernando Montero (github.com/fermontero/fs-cortex, MIT).

@Luispitik Luispitik left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified empirically and the quality is above the bar: your 11 tests pass 11/11 on Windows Git Bash (Node 24), cygpath/mktemp/USERPROFILE are handled correctly, the merger works against main's real _passive-rules.json (6→11), all 5 rules fire through the v4.6.1 activator (byte-identical to your base — no functional drift), and the atomic write even preserves the file's 0600 mode. Scope is fine too: the passive-rules tier is core product (6 default rules documented in FEATURES.md), not engineering tooling.

The blocker is staleness, not substance — git merge-tree confirms conflicts in 4 files (CHANGELOG.md, docs/FEATURES.md, install.sh, install.bat), and v4.5.0 was meanwhile released in main for the Opus 4.7 integration, so the version number collides semantically as well. Asks:

  1. Rebase onto main (v4.6.1) — when resolving install.sh/install.bat, keep the _precompact-guard.sh copy and the hook-count text that v4.5 introduced.
  2. Renumber to the next free version and update the 'v4.5' references in _reflex-merge.mjs, seeds/reflexes.json, both installers and docs/FEATURES.md. Refresh the '116 → 127 passing' badge — the suite has grown since your base.
  3. Register the tests in CI: add a bash tests/test-reflexes.sh step to .github/workflows/tests.yml (the existing ubuntu/macos/windows matrix is ideal for validating the cygpath handling).
  4. Drop (or justify and downgrade) read-before-edit: Claude Code already enforces Read-before-Edit at the harness level, so the rule injects ~25 redundant tokens on every Edit/Write and occupies 1 of the activator's 3 slots — a single Edit on route.ts already saturates the cap (verified: api-auth-reminder + read-before-edit + test-after-change).
  5. Create the tmp file already protected: fs.writeFileSync(tmp, text, { mode: 0o600 }) instead of write-then-chmod — closes the umask window on a file install.sh documents as personal data.
  6. Minor: unify the Step 5c vs Step 5d comment inconsistency after the rebase, and have install.bat check errorlevel after invoking the merger and WARN on failure (install.sh's || true degrades gracefully, but silently — a one-line warning would help).
  7. Found while testing: instinct-downvote is nearly inert — the activator is PreToolUse and only sees tool_name/tool_input, never the user's chat, so in practice it fires only when the user already ran /downvote (via file_path commands/downvote.md), making the inject redundant. Prune it or rethink the trigger during the rebase. Same spirit for test-after-change: it fires before the edit, so wording like "You are about to modify test/route code — plan to run the suite after" is more honest about the moment of injection.

After the rebase this merges. Thanks for the cross-OS care — it shows.

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.

2 participants