From 6d1413cd5c357b4c25166d6a5ec917f422ae38d9 Mon Sep 17 00:00:00 2001 From: AIOSAI Date: Thu, 18 Jun 2026 18:01:56 -0700 Subject: [PATCH] feat(hooks): seed fresh-clone tier wiring across all 3 layers (FPLAN-0284 P5) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the deployment gap — cadence_config.json + the settings.json bridge are machine-local (gitignored), so fresh clones needed the tiered wiring seeded from committed sources: - cadence.py DEFAULTS (keystone): adds tier0(period 1) + navmap(period 5) to the code fallback, so a fresh clone with no cadence_config.json gets tiered cadence automatically (was defaulting tier0 to period 5). - setup.sh: fresh-install bridge seed now emits tier0_kernel + navmap, drops global_prompt. - provider_manifest.json: doctor update path adds the tiered entries on existing machines, drops global_prompt. Convergence: the committed hooks.json (global_prompt enabled:false) means even a stale settings.json with a global bridge is skipped by the engine. 615/615 tests (1 new: test_defaults_include_tiered_loaders), seedgo 100%. --- .claude/provider_manifest.json | 3 ++- setup.sh | 3 ++- src/aipass/hooks/apps/modules/cadence.py | 2 ++ src/aipass/hooks/tests/test_cadence.py | 11 +++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/.claude/provider_manifest.json b/.claude/provider_manifest.json index c81be7a6..49a72ec4 100644 --- a/.claude/provider_manifest.json +++ b/.claude/provider_manifest.json @@ -4,7 +4,8 @@ "cli": { "claude": { "hooks": [ - {"command": "$AIPASS_HOME/.venv/bin/python3 $AIPASS_HOME/src/aipass/hooks/apps/handlers/bridges/claude.py UserPromptSubmit:global_prompt", "event": "UserPromptSubmit"}, + {"command": "$AIPASS_HOME/.venv/bin/python3 $AIPASS_HOME/src/aipass/hooks/apps/handlers/bridges/claude.py UserPromptSubmit:tier0_kernel", "event": "UserPromptSubmit"}, + {"command": "$AIPASS_HOME/.venv/bin/python3 $AIPASS_HOME/src/aipass/hooks/apps/handlers/bridges/claude.py UserPromptSubmit:navmap", "event": "UserPromptSubmit"}, {"command": "$AIPASS_HOME/.venv/bin/python3 $AIPASS_HOME/src/aipass/hooks/apps/handlers/bridges/claude.py UserPromptSubmit:branch_prompt", "event": "UserPromptSubmit"}, {"command": "$AIPASS_HOME/.venv/bin/python3 $AIPASS_HOME/src/aipass/hooks/apps/handlers/bridges/claude.py UserPromptSubmit:identity_injector", "event": "UserPromptSubmit"}, {"command": "$AIPASS_HOME/.venv/bin/python3 $AIPASS_HOME/src/aipass/hooks/apps/handlers/bridges/claude.py UserPromptSubmit:email_notification", "event": "UserPromptSubmit"}, diff --git a/setup.sh b/setup.sh index 6678ac01..83afe50d 100755 --- a/setup.sh +++ b/setup.sh @@ -631,7 +631,8 @@ else: # PreCompact: 3 hooks x 2 matchers (manual + auto) = 6 entries settings["hooks"] = { "UserPromptSubmit": [ - {"hooks": [{"type": "command", "command": f"{bridge} UserPromptSubmit:global_prompt"}]}, + {"hooks": [{"type": "command", "command": f"{bridge} UserPromptSubmit:tier0_kernel"}]}, + {"hooks": [{"type": "command", "command": f"{bridge} UserPromptSubmit:navmap"}]}, {"hooks": [{"type": "command", "command": f"{bridge} UserPromptSubmit:branch_prompt"}]}, {"hooks": [{"type": "command", "command": f"{bridge} UserPromptSubmit:identity_injector"}]}, {"hooks": [{"type": "command", "command": f"{bridge} UserPromptSubmit:email_notification"}]}, diff --git a/src/aipass/hooks/apps/modules/cadence.py b/src/aipass/hooks/apps/modules/cadence.py index 6d610b44..4e97b4ae 100644 --- a/src/aipass/hooks/apps/modules/cadence.py +++ b/src/aipass/hooks/apps/modules/cadence.py @@ -44,6 +44,8 @@ DEFAULTS = { "enabled": True, "period": 5, "loaders": { + "tier0": {"period": 1}, + "navmap": {"period": 5, "offset": 0}, "global": {"offset": 0}, "branch": {"offset": 0}, }, diff --git a/src/aipass/hooks/tests/test_cadence.py b/src/aipass/hooks/tests/test_cadence.py index 96f3a0cc..6b56b5b1 100644 --- a/src/aipass/hooks/tests/test_cadence.py +++ b/src/aipass/hooks/tests/test_cadence.py @@ -325,6 +325,17 @@ class TestConfig: assert config["loaders"]["global"]["offset"] == 0 assert config["loaders"]["branch"]["offset"] == 0 + def test_defaults_include_tiered_loaders(self, tmp_path): + """Fresh clone with no cadence_config.json gets tiered cadence out of the box.""" + from aipass.hooks.apps.modules.cadence import _load_config + + with patch(f"{MODULE}._CONFIG_PATH", tmp_path / "nonexistent.json"): + config = _load_config() + + assert config["loaders"]["tier0"]["period"] == 1 + assert config["loaders"]["navmap"]["period"] == 5 + assert config["loaders"]["navmap"]["offset"] == 0 + def test_config_deep_merges_over_defaults(self, tmp_path): from aipass.hooks.apps.modules.cadence import _load_config