Skip to content

feat(laws): add always-injected one-liner tier for permanent instincts#9

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

feat(laws): add always-injected one-liner tier for permanent instincts#9
NestorPVsf wants to merge 1 commit into
Luispitik:mainfrom
NestorPVsf:cortex-fusion-laws

Conversation

@NestorPVsf

Copy link
Copy Markdown
Contributor

Summary

Introduces a Laws tier: always-injected one-liner projections of permanent instincts (or fs-cortex stand-alone seeds), injected at SessionStart with rotation by last_injected ASC. Cap: 10 laws / ~300 tokens per session. Purely additive — no existing command or schema changes.

Model

permanent instinct   (full entry in _instincts-index.json)
    |
    v   optionally distilled via /promote --law
Law                  (one-liner in _laws/<id>.txt, injected at SessionStart)

source_instinct: null means the law is a stand-alone seed (e.g. fs-cortex import). When /promote --law distills a permanent instinct, source_instinct points to that instinct id.

Changes

  • core/_laws-injector.sh (new, 70 LOC): SessionStart hook with YAML-frontmatter parser, MAX_LAWS=10 / TOKEN_BUDGET=300 caps, atomic tmp → rename write for last_injected update (survives concurrent sessions).
  • seeds/laws/*.txt (5 new): ported from fermontero/fs-cortex (MIT © Fernando Montero): read-first, grep-read-verify, git-triple-check, never-hardcode-secrets, three-layer-security.
  • core/settings.template.json: adds SessionStart block (_hooks_total: 6 → 7, _hooks_breakdown: SessionStart(1) + PreToolUse(4) + PostToolUse(1) + Stop(1)).
  • install.sh: copies injector + seed laws into ~/.claude/skills/_laws/. Idempotent — existing files preserve their last_injected on upgrade.
  • commands/promote.md: new Step 4 offers Law distillation when an instinct is promoted to permanent.
  • tests/test-laws.sh (new, 10 TDD tests): presence, seed count, empty-dir silent exit, emission format, MAX_LAWS cap, last_injected atomic update, rotation ordering, malformed-file resilience, whitespace normalization. 10/10 GREEN. Suite: 116 → 126.
  • docs/FEATURES.md: Laws tier section.
  • CHANGELOG.md: v4.5.0 entry with rationale.

Rationale

Sinapsis already projected patterns as instincts (regex-gated, per-tool-use injection). What was missing: a thin tier of always-on crystallized wisdom — the 5-10 principles the user never wants to risk forgetting, no matter the context. Matches fs-cortex's `laws` concept without replacing instincts: laws are a projection of permanents, not a parallel registry.

Test plan

  • `bash tests/test-laws.sh` → 10/10 GREEN
  • Full suite (`bash tests/test-*.sh`) → 126/126 GREEN, 0 regressions
  • JSON validity on `settings.template.json`
  • `bash -n` syntax check on all shell scripts (16 total)
  • Live hook with `SINAPSIS_DEBUG=1` → zero stderr
  • End-to-end `install.sh` in sandbox → laws installed, injector executable, idempotent re-install preserves `last_injected`
  • Token count measured: 128 tokens for 5 seed laws (cap 300)
  • Reviewer: sanity check on Linux/macOS fresh install (developed on Windows Git Bash)

Independence

Branches from `main` (45949ed `chore: bump version to v4.4.1 (#5)`). No dependency on PR #8 (seeds/instincts) or PR #7 (dashboard fix). Can merge in any order.

Credit

`seeds/laws/*.txt` — MIT © 2026 Fernando Montero, ported from fermontero/fs-cortex. Attribution preserved in each file's frontmatter.

Introduces a Laws tier: always-injected one-liner projections of permanent
instincts (or fs-cortex stand-alone seeds), injected at SessionStart with
rotation by last_injected ASC, cap 10 laws / ~300 tokens per session.

- core/_laws-injector.sh (70 LOC): SessionStart hook with YAML-frontmatter
  parser, MAX_LAWS=10 and TOKEN_BUDGET=300 caps, atomic tmp+rename write for
  last_injected update.
- seeds/laws/: 5 seeds ported from fermontero/fs-cortex (MIT):
  read-first, grep-read-verify, git-triple-check, never-hardcode-secrets,
  three-layer-security.
- core/settings.template.json: adds SessionStart hook block
  (hooks total 6 to 7).
- install.sh: copies injector + seed laws into ~/.claude/skills/_laws/
  (idempotent, preserves existing last_injected on upgrade).
- commands/promote.md: new Step 4 distills a Law when an instinct is
  promoted to permanent.
- tests/test-laws.sh: 10 TDD tests, 10/10 GREEN. Suite 116 to 126.
- docs/FEATURES.md: Laws tier section.

Credit: Fernando Montero (github.com/fermonterom/fs-cortex, MIT).
NestorPVsf pushed a commit to NestorPVsf/sinapsis that referenced this pull request Apr 18, 2026
Addresses 3 bugs flagged by Codex CLI during PR Luispitik#9 review. All 3 are
pre-existing in the feat(seeds) commit of PR Luispitik#8.

P1: install.sh hardcoded `python` instead of `$PYTHON_CMD` detected in
Step 1. On systems with only python3 in PATH, seed import failed and was
silently swallowed by `|| true`. Uses `$PYTHON_CMD` now with a warning
fallback when Python is unavailable.

P2: parse_yaml_simple stripped quotes but did not decode backslash
escapes. Seeds with `"spec\.ts"` were stored with literal backslashes,
producing invalid regex. Added _decode_yaml_double_quoted (handles
\ \" \n \t \r) and _decode_yaml_single_quoted (`''` → `'`). Fixes 3
broken seeds: e2e-playwright-selectors, security-headers-vercel,
supabase-rls-auth-uid.

P2: _instinct-activator.sh pre-filters by ALWAYS_DOMAINS + stack-detected
domains when context.md exists. Seed domains workflow-general, testing,
web-development, saas-development are outside both sets so those seeds
never reached regex evaluation. Added DOMAIN_MAP in importer:
workflow-general → operations, testing → quality, web-development →
frontend, saas-development → stripe. original_domain preserved for
traceability.

Tests: 3 new in test-seeds.sh (9-11). Suite 8/8 → 11/11 GREEN.

Credit: bugs identified by Codex CLI (cross-model review).

@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.

The idea fits the scope (laws as a projection of permanent instincts — the activate layer of the observe→learn→index→activate pipeline), and the base code is solid: node is already a hard prerequisite, no eval, quoted paths, per-file try/catch, sandboxed tests. So this is not a close — but it can't merge as-is:

  1. Doesn't apply on v4.6.1git apply --check fails on 4 of the 6 modified files (CHANGELOG.md, core/settings.template.json, docs/FEATURES.md, install.sh). The branch predates v4.5; please rebase.
  2. Version collision: v4.5.0 was released in main (Opus 4.7 + PreCompact hook). Renumber to the next free version, and after the rebase settings.template.json must declare _hooks_total: 8 with PreCompact included — your diff proposes 6→7 omitting PreCompact, which a careless conflict resolution would drop from everyone's settings.
  3. install.bat parity is missing — it copies each hook explicitly (lines 147-153) and would receive neither _laws-injector.sh nor the seeds nor the SessionStart block. Windows users would get a SessionStart hook pointing at a script that doesn't exist (silent no-op): the population that already reports the most bugs would be the one silently excluded from the feature.

Injector tweaks for the new revision:

  • Pass the laws dir from bash into node via env (LAWS_DIR="$LAWS_DIR" node -e '…' reading process.env.LAWS_DIR) instead of reconstructing it from process.env.HOME — MSYS path conversion makes the reconstructed path a silent-no-op risk on Git Bash.
  • The trailing 2>/dev/null on the node block defeats SINAPSIS_DEBUG's exec 2>> — make the redirect conditional on SINAPSIS_DEBUG != 1.
  • Use continue, not break, when a law exceeds the token budget — as written, one long law at the head of the rotation starves all the short ones behind it.
  • Reconsider shipping three-layer-security as a default seed — "middleware → API validation → Supabase RLS" is stack-specific and doesn't generalize in a public MIT repo. Make seeds opt-in (e.g. --with-seed-laws) or keep only the generic four.
  • /promote --law is mentioned in the body/CHANGELOG but commands/promote.md doesn't define that flag — align the docs with the interactive Step 4 you actually implemented.
  • After the rebase: re-run the full suite and refresh the test badge (main has grown since your base), add an assertion to tests/test-install-upgrade.sh that both installers leave _laws/ populated and that a re-install preserves last_injected, and add a note to FEATURES.md recording the (accepted) tension between last_injected rotation and the v4.5 byte-stable-ordering philosophy — one injection per session makes it fine, but it should be a documented decision, not an accident.

The unconditional context cost (~128-300 tokens per session for every user, with seeds not opt-in) is the part I most want to see addressed in the next revision. Looking forward to the rebase.

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