@event4u/agent-config 5.6.1 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/.agent-src/commands/agent-handoff.md +1 -1
  2. package/.agent-src/commands/agent-status.md +1 -1
  3. package/.agent-src/commands/agents/audit.md +1 -1
  4. package/.agent-src/commands/agents/init.md +1 -1
  5. package/.agent-src/commands/agents/user/accept.md +3 -3
  6. package/.agent-src/commands/agents/user/init.md +4 -4
  7. package/.agent-src/commands/agents/user/show.md +3 -3
  8. package/.agent-src/commands/agents/user/update.md +3 -3
  9. package/.agent-src/commands/agents/user.md +1 -1
  10. package/.agent-src/commands/agents.md +1 -1
  11. package/.agent-src/commands/analytics/prune.md +1 -1
  12. package/.agent-src/commands/analytics/show.md +1 -1
  13. package/.agent-src/commands/analytics.md +1 -1
  14. package/.agent-src/commands/bug-fix.md +1 -1
  15. package/.agent-src/commands/challenge-me.md +1 -1
  16. package/.agent-src/commands/chat-history/import.md +1 -1
  17. package/.agent-src/commands/chat-history/learn.md +1 -1
  18. package/.agent-src/commands/chat-history/show.md +1 -1
  19. package/.agent-src/commands/chat-history.md +1 -1
  20. package/.agent-src/commands/check-current-md.md +1 -1
  21. package/.agent-src/commands/condense.md +1 -1
  22. package/.agent-src/commands/context.md +1 -1
  23. package/.agent-src/commands/cost-report.md +13 -8
  24. package/.agent-src/commands/council.md +3 -3
  25. package/.agent-src/commands/create-pr/description-only.md +1 -1
  26. package/.agent-src/commands/create-pr.md +1 -1
  27. package/.agent-src/commands/e2e-heal.md +1 -1
  28. package/.agent-src/commands/e2e-plan.md +1 -1
  29. package/.agent-src/commands/feature.md +1 -1
  30. package/.agent-src/commands/fix/ci.md +1 -1
  31. package/.agent-src/commands/fix/portability.md +1 -1
  32. package/.agent-src/commands/fix/pr-bot-comments.md +1 -1
  33. package/.agent-src/commands/fix/pr-comments.md +1 -1
  34. package/.agent-src/commands/fix/pr-developer-comments.md +1 -1
  35. package/.agent-src/commands/fix/refs.md +1 -1
  36. package/.agent-src/commands/fix/seeder.md +1 -1
  37. package/.agent-src/commands/fix.md +1 -1
  38. package/.agent-src/commands/judge.md +1 -1
  39. package/.agent-src/commands/knowledge/cross-repo.md +1 -1
  40. package/.agent-src/commands/knowledge/forget.md +1 -1
  41. package/.agent-src/commands/knowledge/ingest.md +1 -1
  42. package/.agent-src/commands/knowledge/list.md +1 -1
  43. package/.agent-src/commands/knowledge.md +1 -1
  44. package/.agent-src/commands/memory/add.md +1 -1
  45. package/.agent-src/commands/memory/learn-low-impact.md +1 -1
  46. package/.agent-src/commands/memory/load.md +1 -1
  47. package/.agent-src/commands/memory/mine-session.md +1 -1
  48. package/.agent-src/commands/memory/promote.md +1 -1
  49. package/.agent-src/commands/memory/propose.md +1 -1
  50. package/.agent-src/commands/memory.md +1 -1
  51. package/.agent-src/commands/mode.md +1 -1
  52. package/.agent-src/commands/optimize/agents-dir.md +1 -1
  53. package/.agent-src/commands/optimize/augmentignore.md +1 -1
  54. package/.agent-src/commands/optimize/rtk.md +1 -1
  55. package/.agent-src/commands/optimize/skills.md +1 -1
  56. package/.agent-src/commands/optimize.md +1 -1
  57. package/.agent-src/commands/orchestrate.md +1 -1
  58. package/.agent-src/commands/override/create.md +1 -1
  59. package/.agent-src/commands/override/manage.md +1 -1
  60. package/.agent-src/commands/override.md +1 -1
  61. package/.agent-src/commands/package-reset.md +1 -1
  62. package/.agent-src/commands/prediction-pool.md +234 -0
  63. package/.agent-src/commands/profile/activate.md +81 -0
  64. package/.agent-src/commands/profile/deactivate.md +68 -0
  65. package/.agent-src/commands/profile/show.md +70 -0
  66. package/.agent-src/commands/profile.md +68 -0
  67. package/.agent-src/commands/project-health.md +1 -1
  68. package/.agent-src/commands/quality-fix.md +1 -1
  69. package/.agent-src/commands/roadmap/process-full.md +1 -1
  70. package/.agent-src/commands/roadmap/process-phase.md +1 -1
  71. package/.agent-src/commands/roadmap/process-step.md +1 -1
  72. package/.agent-src/commands/roadmap.md +1 -1
  73. package/.agent-src/commands/set-cost-profile.md +9 -9
  74. package/.agent-src/commands/skill/preview.md +3 -3
  75. package/.agent-src/commands/skill.md +1 -1
  76. package/.agent-src/commands/skills/discover.md +1 -1
  77. package/.agent-src/commands/skills.md +1 -1
  78. package/.agent-src/commands/sync-agent-settings.md +3 -3
  79. package/.agent-src/commands/sync-gitignore/fix.md +1 -1
  80. package/.agent-src/commands/sync-gitignore.md +1 -1
  81. package/.agent-src/commands/update-form-request-messages.md +1 -1
  82. package/.agent-src/presets/README.md +1 -1
  83. package/.agent-src/profiles/README.md +1 -1
  84. package/.agent-src/rules/non-destructive-by-default.md +2 -1
  85. package/.agent-src/skills/check-refs/SKILL.md +1 -1
  86. package/.agent-src/skills/finishing-a-development-branch/SKILL.md +1 -1
  87. package/.agent-src/skills/git-workflow/SKILL.md +1 -1
  88. package/.agent-src/skills/jira-integration/SKILL.md +1 -1
  89. package/.agent-src/skills/markitdown/SKILL.md +1 -1
  90. package/.agent-src/skills/prediction-pool-optimizer/SKILL.md +314 -0
  91. package/.agent-src/skills/prediction-pool-optimizer/evals/triggers.json +20 -0
  92. package/.agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +175 -0
  93. package/.agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +109 -0
  94. package/.agent-src/skills/rtk-output-filtering/SKILL.md +1 -1
  95. package/.agent-src/skills/script-writing/SKILL.md +1 -1
  96. package/.agent-src/skills/token-optimizer/SKILL.md +1 -1
  97. package/.agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  98. package/.agent-src/templates/agent-settings.md +7 -7
  99. package/.agent-src/templates/agents/agent-project-settings.example.yml +2 -2
  100. package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +54 -6
  101. package/.agent-src/templates/scripts/work_engine/hook_bootstrap.py +1 -1
  102. package/.agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.py +9 -7
  103. package/.agent-src/templates/scripts/work_engine/hooks/settings.py +9 -10
  104. package/.agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +17 -4
  105. package/.claude-plugin/marketplace.json +370 -364
  106. package/CHANGELOG.md +108 -0
  107. package/README.md +2 -2
  108. package/config/agent-settings.template.yml +11 -2
  109. package/config/discovery/packs.yml +11 -0
  110. package/config/discovery/session-profiles.yml +37 -0
  111. package/config/discovery/workspaces.yml +1 -1
  112. package/config/profiles/balanced.ini +1 -1
  113. package/config/profiles/full.ini +1 -1
  114. package/config/profiles/minimal.ini +1 -1
  115. package/dist/discovery/deprecation-report.md +1 -1
  116. package/dist/discovery/discovery-manifest.json +254 -100
  117. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  118. package/dist/discovery/discovery-manifest.summary.md +4 -3
  119. package/dist/discovery/orphan-report.md +1 -1
  120. package/dist/discovery/packs.json +41 -6
  121. package/dist/discovery/trust-report.md +3 -3
  122. package/dist/discovery/workspaces.json +19 -6
  123. package/dist/mcp/registry-manifest.json +3 -3
  124. package/dist/server/io/substituteTemplate.js +3 -3
  125. package/dist/server/io/substituteTemplate.js.map +1 -1
  126. package/dist/server/routes/settings.js +2 -2
  127. package/dist/server/routes/settings.js.map +1 -1
  128. package/dist/server/schemas/settings.js +4 -2
  129. package/dist/server/schemas/settings.js.map +1 -1
  130. package/dist/ui/assets/{index-DVsyUMZe.js → index-5lFqAKL0.js} +2 -2
  131. package/dist/ui/assets/index-5lFqAKL0.js.map +1 -0
  132. package/dist/ui/index.html +1 -1
  133. package/docs/architecture/current-onboard-baseline.md +3 -3
  134. package/docs/architecture.md +2 -2
  135. package/docs/catalog.md +11 -5
  136. package/docs/contracts/adr-level-6-productization.md +1 -1
  137. package/docs/contracts/command-clusters.md +2 -0
  138. package/docs/contracts/config-presets.md +2 -2
  139. package/docs/contracts/cost-profile-defaults.md +5 -5
  140. package/docs/contracts/discovery-manifest.schema.json +1 -1
  141. package/docs/contracts/explain-trace.schema.json +3 -3
  142. package/docs/contracts/memory-visibility-v1.md +15 -7
  143. package/docs/contracts/profile-system.md +2 -2
  144. package/docs/contracts/session-profile-overlay.md +120 -0
  145. package/docs/contracts/settings-api.md +3 -3
  146. package/docs/contracts/value-report-schema.md +14 -1
  147. package/docs/customization.md +47 -5
  148. package/docs/decisions/ADR-010-profile-pack-preset-boundary.md +47 -11
  149. package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +16 -2
  150. package/docs/decisions/ADR-034-per-skill-model-recommendation-transport.md +1 -1
  151. package/docs/decisions/ADR-036-global-install-browser-wizard-handoff.md +106 -0
  152. package/docs/decisions/ADR-037-cost-profile-untangle.md +117 -0
  153. package/docs/decisions/ADR-038-canonical-settings-path.md +66 -0
  154. package/docs/decisions/ADR-039-claude-skills-untracked.md +139 -0
  155. package/docs/decisions/ADR-rule-kernel-and-router.md +1 -1
  156. package/docs/decisions/INDEX.md +4 -0
  157. package/docs/development.md +12 -0
  158. package/docs/getting-started.md +2 -2
  159. package/docs/guidelines/agent-infra/layered-settings.md +10 -4
  160. package/docs/installation.md +3 -3
  161. package/docs/setup/mcp-client-config.md +1 -1
  162. package/docs/skills-catalog.md +5 -1
  163. package/docs/value.md +9 -7
  164. package/docs/wizard.md +1 -1
  165. package/llms.txt +4 -0
  166. package/package.json +1 -1
  167. package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
  168. package/scripts/_cli/cmd_doctor.py +3 -2
  169. package/scripts/_cli/cmd_explain.py +1 -1
  170. package/scripts/_cli/cmd_versions.py +2 -2
  171. package/scripts/_cli/explain_last/inputs.py +11 -8
  172. package/scripts/_cli/explain_last/sections/inputs.py +1 -1
  173. package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
  174. package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
  175. package/scripts/_lib/agent_settings.py +54 -6
  176. package/scripts/_lib/agent_src.py +30 -0
  177. package/scripts/_lib/value_ladder.py +99 -2
  178. package/scripts/_lib/value_report.py +30 -16
  179. package/scripts/ai_council/modes.py +1 -1
  180. package/scripts/ai_council/session.py +5 -1
  181. package/scripts/audit_command_surface.py +7 -1
  182. package/scripts/audit_initial_context.py +26 -2
  183. package/scripts/check_gate_paths.py +117 -0
  184. package/scripts/check_references.py +51 -2
  185. package/scripts/check_skill_requires.py +143 -0
  186. package/scripts/check_test_coverage_diff.py +180 -0
  187. package/scripts/compile_router.py +5 -1
  188. package/scripts/condense.py +92 -4
  189. package/scripts/config/session_profiles.py +492 -0
  190. package/scripts/council_cli.py +5 -1
  191. package/scripts/first-run.sh +11 -11
  192. package/scripts/hook_manifest.yaml +15 -7
  193. package/scripts/hooks/dispatch_hook.py +8 -0
  194. package/scripts/install +14 -1
  195. package/scripts/install-hooks.sh +2 -1
  196. package/scripts/install.py +203 -433
  197. package/scripts/install_anthropic_key.sh +1 -1
  198. package/scripts/install_openai_key.sh +1 -1
  199. package/scripts/inventory_abstraction_budget.py +6 -1
  200. package/scripts/lint_agents_md.py +11 -4
  201. package/scripts/lint_discovery_vocabulary.py +5 -5
  202. package/scripts/lint_hook_concern_budget.py +5 -1
  203. package/scripts/lint_marketplace.py +18 -7
  204. package/scripts/lint_roadmap_ci_steps.py +5 -1
  205. package/scripts/lint_roadmap_complexity.py +5 -1
  206. package/scripts/lint_value_dashboard.py +1 -1
  207. package/scripts/mcp_server/prompts.py +5 -1
  208. package/scripts/prediction-pool/adapters/_schema.md +42 -0
  209. package/scripts/prediction-pool/adapters/kicktipp.yml +23 -0
  210. package/scripts/prediction-pool/poisson_sim.py +167 -0
  211. package/scripts/prediction-pool/pool_winsim.py +236 -0
  212. package/scripts/prediction-pool/score_ev.py +188 -0
  213. package/scripts/profile_staleness_hook.py +69 -0
  214. package/scripts/render_value_md.py +1 -0
  215. package/scripts/roadmap_progress_hook.py +56 -6
  216. package/scripts/schemas/agent-settings.schema.json +77 -0
  217. package/scripts/schemas/skill.schema.json +7 -0
  218. package/scripts/smoke_quickstart.py +7 -6
  219. package/scripts/sync_agent_settings.py +12 -5
  220. package/scripts/validate_agent_settings.py +124 -0
  221. package/scripts/validate_decision_engine.py +5 -1
  222. package/templates/minimal/.agent-settings.yml +1 -1
  223. package/dist/ui/assets/index-DVsyUMZe.js.map +0 -1
  224. package/scripts/measure_roadmap_trajectory.py +0 -112
  225. package/scripts/verify_roadmap_closure.py +0 -327
@@ -146,7 +146,7 @@ The system supports four configuration profiles:
146
146
  Set your profile in `.agent-settings.yml`:
147
147
 
148
148
  ```yaml
149
- cost_profile: balanced
149
+ rule_loading_tier: balanced
150
150
  ```
151
151
 
152
152
  `balanced` is the default — kernel + tier-1 auto-rules. Rationale:
@@ -169,7 +169,7 @@ Your agent now understands slash commands:
169
169
  | `/quality-fix` | Run and fix all quality checks |
170
170
  | `/chat-history` | Inspect the persistent chat-history log (read-only `show`) |
171
171
 
172
- → [Browse all 145 active commands](../.agent-src/commands/)
172
+ → [Browse all 150 active commands](../.agent-src/commands/)
173
173
 
174
174
  ---
175
175
 
@@ -18,8 +18,14 @@ on user request.
18
18
  | File | Git | Scope | Owner | Example values |
19
19
  |---|---|---|---|---|
20
20
  | `.agent-project-settings.yml` | **committed** | team / repo | lead maintainer | `project.stack`, `quality.php.tools`, `memory.dogfood` |
21
- | `~/.event4u/agent-config/agent-settings.yml` | **n/a** (outside repo) | individual developer · cross-project | individual | `name`, `ide`, `cost_profile`, `personal.bot_icon`, `personal.autonomy`, `telegraph.speak_scope` (legacy `~/.config/agent-config/agent-settings.yml` read as fallback) |
22
- | `.agent-settings.yml` | **gitignored** | individual developer · this project | individual | `personal.ide`, `personal.user_name`, `subagents.max_parallel`, `onboarding.onboarded` |
21
+ | `~/.event4u/agent-config/agent-settings.yml` | **n/a** (outside repo) | individual developer · cross-project | individual | `name`, `ide`, `rule_loading_tier`, `personal.bot_icon`, `personal.autonomy`, `telegraph.speak_scope` (legacy `~/.config/agent-config/agent-settings.yml` read as fallback) |
22
+ | `agents/settings/.agent-settings.yml` | **gitignored** | individual developer · this project | individual | `personal.ide`, `personal.user_name`, `subagents.max_parallel`, `onboarding.onboarded` |
23
+
24
+ > **Canonical location (ADR-038):** the developer file lives in the settings
25
+ > layer at `agents/settings/.agent-settings.yml` (alongside
26
+ > `.agent-settings.local.yml`, `contexts/`, `policies/`). A repo-root
27
+ > `.agent-settings.yml` is read as a **back-compat fallback** and is migrated
28
+ > into the canonical location by `install` on the next run.
23
29
 
24
30
  All three are YAML. Schemas:
25
31
 
@@ -36,7 +42,7 @@ Lowest priority → highest priority:
36
42
  1. Package defaults (shipped by event4u/agent-config)
37
43
  2. ~/.event4u/agent-config/agent-settings.yml (user-global · whitelist-filtered · legacy ~/.config/agent-config/ read as fallback)
38
44
  3. .agent-project-settings.yml (team file, committed)
39
- 4. .agent-settings.yml (developer file, gitignored)
45
+ 4. agents/settings/.agent-settings.yml (developer file, gitignored; legacy repo-root .agent-settings.yml read as fallback — ADR-038)
40
46
  ```
41
47
 
42
48
  Keys from higher layers win unless a lower layer marks them
@@ -52,7 +58,7 @@ intentionally tiny — adding a key requires an ADR.
52
58
  ```
53
59
  name
54
60
  ide
55
- cost_profile
61
+ rule_loading_tier
56
62
  personal.bot_icon
57
63
  personal.autonomy
58
64
  telegraph.speak_scope
@@ -303,7 +303,7 @@ explicitly by adding `agent_config_version: <semver>` to
303
303
  The orchestrator chains payload sync and bridge generation:
304
304
 
305
305
  ```bash
306
- bash scripts/install # defaults to cost_profile=balanced
306
+ bash scripts/install # defaults to rule_loading_tier=balanced
307
307
  bash scripts/install --profile=minimal
308
308
  bash scripts/install --force # overwrite existing bridges
309
309
  bash scripts/install --skip-bridges # payload only
@@ -359,7 +359,7 @@ regardless of which AI tool they use.** No per-developer plugin installation nee
359
359
  After initial setup, commit these files:
360
360
 
361
361
  ```
362
- .agent-settings.yml ← shared profile (e.g., cost_profile: balanced)
362
+ .agent-settings.yml ← shared profile (e.g., rule_loading_tier: balanced)
363
363
  agents/installed-tools.lock ← AI bill of materials (ADR-008, Phase 3)
364
364
  .augment/ ← rules, skills, commands (symlinks)
365
365
  .cursor/rules/ ← Cursor rules (symlinks)
@@ -589,7 +589,7 @@ The system works immediately with sensible defaults. Optionally, create `.agent-
589
589
  to choose a profile:
590
590
 
591
591
  ```yaml
592
- cost_profile: balanced
592
+ rule_loading_tier: balanced
593
593
  ```
594
594
 
595
595
  | Profile | What's active | For whom |
@@ -33,7 +33,7 @@ look for MCP server config inside `.agent-settings.yml`.
33
33
  | File | Where | Who reads it | Purpose |
34
34
  |---|---|---|---|
35
35
  | MCP client config (this page) | client-specific path per section above | the MCP client at startup | which MCP servers to talk to (name + URL / command) |
36
- | `.agent-settings.yml` | consumer project root (`<repo>/.agent-settings.yml`) | the agent at runtime (Claude / Cursor / …) | per-developer preferences: `name`, `ide`, `cost_profile`, `personal.autonomy`, `pipelines.skill_improvement`, `telegraph.speak_scope`, … |
36
+ | `.agent-settings.yml` | consumer project root (`<repo>/.agent-settings.yml`) | the agent at runtime (Claude / Cursor / …) | per-developer preferences: `name`, `ide`, `rule_loading_tier`, `personal.autonomy`, `pipelines.skill_improvement`, `telegraph.speak_scope`, … |
37
37
 
38
38
  The Worker is **stateless** and **project-agnostic** — it serves the
39
39
  same skill / rule / command catalog to every client. Personalization
@@ -1,6 +1,6 @@
1
1
  # Skills Catalog
2
2
 
3
- All **219 skills** available in this package, in alphabetical order.
3
+ All **223 skills** available in this package, in alphabetical order.
4
4
  Click a skill name to open its SKILL.md and read the full guidance.
5
5
 
6
6
  > **Regenerate:** `python3 scripts/generate_catalog.py`
@@ -89,6 +89,8 @@ Click a skill name to open its SKILL.md and read the full guidance.
89
89
  | [`gtm-launch`](../.agent-src/skills/gtm-launch/SKILL.md) | Use when sequencing a launch — alpha / beta / GA waves, audience-by-wave logic, narrative beats per wave, engineering-readiness gates. Triggers on 'plan the launch', 'sequence GA'. |
90
90
  | [`guideline-writing`](../.agent-src/skills/guideline-writing/SKILL.md) | Use when creating or editing a guideline in docs/guidelines/ — reference material cited by skills, no auto-triggers — even when the user just says 'write up our naming conventions'. |
91
91
  | [`hiring-loop-design`](../.agent-src/skills/hiring-loop-design/SKILL.md) | Use when shaping an engineering hiring loop — stages, take-home vs live, calibration, bar-raiser, signal-vs-noise audit. Triggers on 'design our interview loop', 'audit our hiring bar'. |
92
+ | [`image-analyser`](../.agent-src/skills/image-analyser/SKILL.md) | Use to analyse a character image down to the smallest mole and diff against a canon — per-feature spec, OCR-reads tattoo text, flags drift. Triggers 'analyse this image', 'match the canon'. |
93
+ | [`image-creator`](../.agent-src/skills/image-creator/SKILL.md) | Use to generate a character image to spec — max-fidelity reproducible prompt from a Canon Spec, anchors-first, provider/governance-gated. Triggers 'generate this character', 'render to spec'. |
92
94
  | [`incident-commander`](../.agent-src/skills/incident-commander/SKILL.md) | Use during or right after an incident — frames severity, sets comms cadence, drafts the post-mortem skeleton — even when the user just says 'production is down' or 'wir haben einen Vorfall'. |
93
95
  | [`jira-integration`](../.agent-src/skills/jira-integration/SKILL.md) | Use when the user says "check Jira", "create ticket", "update issue", or needs JQL queries, ticket transitions, or branch-to-ticket linking. |
94
96
  | [`jobs-events`](../.agent-src/skills/jobs-events/SKILL.md) | Use when creating Laravel jobs, queued workflows, events, or listeners. Covers clear responsibilities, safe serialization, and retry/failure handling. |
@@ -152,6 +154,7 @@ Click a skill name to open its SKILL.md and read the full guidance.
152
154
  | [`playwright-testing`](../.agent-src/skills/playwright-testing/SKILL.md) | Use when writing Playwright E2E tests — browser automation, visual regression testing, Page Objects, fixtures, and reliable test patterns. |
153
155
  | [`po-discovery`](../.agent-src/skills/po-discovery/SKILL.md) | Use when shaping a fuzzy product ask into a refined backlog item — problem framing, user-story rewrite, AC tightening — even if the user just says 'help me write this ticket'. |
154
156
  | [`positioning-strategy`](../.agent-src/skills/positioning-strategy/SKILL.md) | Use when locking the market frame — category, segment, alternative, point-of-view — before messaging, launch, or pricing rides on it. Triggers on 'who are we for', 'opposable audit'. |
157
+ | [`prediction-pool-optimizer`](../.agent-src/skills/prediction-pool-optimizer/SKILL.md) | Optimize prediction-pool tips (kicktipp etc.): rules + multi-book consensus odds → expected-points-max answer for every question, scores AND bonus. Triggers 'optimize my pool tips', 'predict'. |
155
158
  | [`privacy-review`](../.agent-src/skills/privacy-review/SKILL.md) | Use when reviewing data flows, support macros, refund templates for GDPR/CCPA/HIPAA fit — regime, consent, PII redaction (email, order-id), breach triage. Triggers 'is this GDPR-safe', 'PII redact'. |
156
159
  | [`project-analysis-core`](../.agent-src/skills/project-analysis-core/SKILL.md) | Raw discovery primitives — project discovery, version resolution, docs loading, architecture mapping, execution flow. Called by `universal-project-analysis`. Single-pass scan → `project-analyzer`. |
157
160
  | [`project-analysis-hypothesis-driven`](../.agent-src/skills/project-analysis-hypothesis-driven/SKILL.md) | Use when a bug has multiple plausible causes across layers — competing hypotheses, validation loops, evidence-based conclusions — even when the user just says 'why is this happening?'. |
@@ -199,6 +202,7 @@ Click a skill name to open its SKILL.md and read the full guidance.
199
202
  | [`skill-management`](../.agent-src/skills/skill-management/SKILL.md) | Use when condensing, decondenseing, refactoring, or improving existing skills. Covers the full skill lifecycle from verbose → sharp → maintained. |
200
203
  | [`skill-reviewer`](../.agent-src/skills/skill-reviewer/SKILL.md) | Use when reviewing, auditing, or optimizing skills — validates against the 7 Skill Killers checklist and produces fix recommendations. |
201
204
  | [`skill-writing`](../.agent-src/skills/skill-writing/SKILL.md) | Use when deciding 'should this be a skill or a rule?', creating/improving/reviewing agent skills, SKILL.md frontmatter, or procedure sections — even without saying 'skill-writing'. |
205
+ | [`song-to-script`](../.agent-src/skills/song-to-script/SKILL.md) | Turn an audio track into a timed `## Scene N` script: song sections → per-scene durations, auto mode adds mood + lip-sync lines. Triggers 'music video', 'from the song', 'cut to the beat'. |
202
206
  | [`sql-writing`](../.agent-src/skills/sql-writing/SKILL.md) | Use when writing raw SQL — MariaDB/MySQL syntax, parameterization, raw migrations, seeders with `DB::statement` — even when the user just pastes a query and asks 'why is this slow' without naming SQL. |
203
207
  | [`stakeholder-tradeoff`](../.agent-src/skills/stakeholder-tradeoff/SKILL.md) | Use when stakeholders pull a decision in different directions — frames each lens, builds a trade-off matrix, surfaces the cost of every choice — even if the user just says 'PO and ops disagree'. |
204
208
  | [`subagent-orchestration`](../.agent-src/skills/subagent-orchestration/SKILL.md) | Use when orchestrating implementer/judge subagents — seven modes (do-and-judge ±two-stage, do-in-steps/parallel/worktrees, do-competitively, judge-with-debate) — models from .agent-settings.yml. |
package/docs/value.md CHANGED
@@ -23,15 +23,17 @@ Liest sich von oben nach unten. Positive Δ-Werte = das Paket *kostet* Tokens (R
23
23
  | Stufe | Was sie tut | Δ Tokens | Kumulativ | Quelle |
24
24
  |---|---|---:|---:|---|
25
25
  | **Ohne Paket / Without package** | Baseline — der nackte Request ohne Paket-Regeln. | +0 | +0.00% | `n/a` · ✅ gemessen |
26
- | Mit Paket (Regeln laden) / With package (rule load) | Die immer-aktiven Regeln landen im Kontext jedes Requests. ⚠️ erst teurer | +8522 | +106.53% | `dist/router.json` · ✅ gemessen |
27
- | | _Fußnote:_ Kernel = 10 rules (30080 chars) + charter (4010 chars); tokens ≈ chars / 4. | | | |
28
- | + condense (Regeln eindampfen) / + condense (rule shrink) | Build-Schritt schrumpft Regel-Dateien vor dem Ausliefern. | -186 | +104.20% | `internal/bench/reports/telegraph-v2.json` · gemessen |
26
+ | Mit Paket (Regeln laden) / With package (rule load) | Die immer-aktiven Regeln landen im Kontext jedes Requests. ⚠️ erst teurer | +59359 | +741.99% | `internal/bench/reports/projection-cost.json` · ✅ gemessen |
27
+ | | _Fußnote:_ Eager-Default: alle 79 Rule-Files always-on im `.claude`-Projektionspfad (0B.6-bestätigt fürs primäre Tool). Nicht nur der Kernel — das ist die ehrliche Up-Front-Last; tokens ≈ chars / 4. | | | |
28
+ | + thin (Regeln als Pointer) / + thin (rules as pointers) | Nicht-Kernel-Regel-Bodies werden zu router-aufgelösten Pointern. | -45 857 | +741.99% | `internal/bench/reports/projection-cost.json` · 🔁 verfügbar (Default aus) |
29
+ | | _Fußnote:_ Verfügbar hinter `lean_projection.mode=thin` (Default `eager-all` — deshalb NICHT im Default-NETTO). Mit Thin aktiv: Rule-Layer 59359 → 13502 GPT tok (−45857, −77.3%). MUST-LOAD-Floor `task trigger-coverage` 26/26 grün; Live-A/B-Validierung ausstehend (Harness abgelehnt). Rollback = ein Flip. | | | |
30
+ | + condense (Regeln eindampfen) / + condense (rule shrink) | Build-Schritt schrumpft Regel-Dateien vor dem Ausliefern. | -186 | +739.66% | `internal/bench/reports/telegraph-v2.json` · ✅ gemessen |
29
31
  | | _Fußnote:_ Aggregate across non-Thin-Root categories; Thin-Root files (AGENTS.md variants) net negative (~−4%) and are excluded from the rung — surfaced separately. | | | |
30
- | + rtk (CLI-Output filtern) / + rtk (filter CLI output) | rtk schneidet verbose CLI-Ausgabe vor dem Modell-Input weg. | -593 | +96.79% | `internal/bench/reports/rtk/latest.json` · ✅ gemessen |
31
- | + terse (Antworten knapper) / + terse (shorter replies) | Telegraph-Stil zielt auf knappere Modell-Antworten. | +56 | +97.49% | `internal/bench/reports/telegraph-v1.json` · ✅ gemessen |
32
+ | + rtk (CLI-Output filtern) / + rtk (filter CLI output) | rtk schneidet verbose CLI-Ausgabe vor dem Modell-Input weg. | -585 | +732.35% | `internal/bench/reports/rtk/latest.json` · ✅ gemessen |
33
+ | + terse (Antworten knapper) / + terse (shorter replies) | Telegraph-Stil zielt auf knappere Modell-Antworten. | +56 | +733.05% | `internal/bench/reports/telegraph-v1.json` · ✅ gemessen |
32
34
  | | _Fußnote:_ Honest: gemessener Median = -9.27% gegen 'sei knapp' — Telegraph liefert hier mehr Tokens, nicht weniger. Wir messen, wir verstecken nicht. | | | |
33
35
 
34
- **NETTO: Mehrkosten** ⚠️ — **+7799 Tokens / Request**, kumulativ **+97.49%** vs. Baseline.
36
+ **NETTO: Mehrkosten** ⚠️ — **+58644 Tokens / Request**, kumulativ **+733.05%** vs. Baseline.
35
37
 
36
38
  ## Panel B — Verhalten (mit vs. ohne)
37
39
 
@@ -81,4 +83,4 @@ Diese Seite ist eine **abgeleitete** Sicht — keine eigene Messung. Sie fasst d
81
83
  - Pending rungs contribute 0 to the cumulative until measured.
82
84
  - Reference scale: 1000 requests × 8000 input / 600 output tokens per request.
83
85
 
84
- _Last rendered: `2026-05-31T14:37:17+00:00`_
86
+ _Last rendered: `2026-06-01T12:10:59+00:00`_
package/docs/wizard.md CHANGED
@@ -33,7 +33,7 @@ selects which surface renders.
33
33
  |---|---|---|
34
34
  | 1 | Identity | `personal.user_name`, `personal.ide` |
35
35
  | 2 | Personality | `personal.minimal_output`, `personal.play_by_play`, `personal.open_edited_files` |
36
- | 3 | Cost profile | `cost_profile` (minimal · balanced · full) |
36
+ | 3 | Cost profile | `rule_loading_tier` (minimal · balanced · full) |
37
37
  | 4 | Roadmap quality | `roadmap.quality_floor`, `roadmap.run_tests_inline` |
38
38
  | 5 | Memory | `memory.enabled`, MCP server presence |
39
39
  | 6 | `.agent-user.md` | Optional long-form persona / preferences |
package/llms.txt CHANGED
@@ -87,6 +87,8 @@ grafana: Use when working with Grafana — dashboards, Loki LogQL queries, alert
87
87
  gtm-launch: Use when sequencing a launch — alpha / beta / GA waves, audience-by-wave logic, narrative beats per wave, engineering-readiness gates. Triggers on 'plan the launch', 'sequence GA'.
88
88
  guideline-writing: Use when creating or editing a guideline in docs/guidelines/ — reference material cited by skills, no auto-triggers — even when the user just says 'write up our naming conventions'.
89
89
  hiring-loop-design: Use when shaping an engineering hiring loop — stages, take-home vs live, calibration, bar-raiser, signal-vs-noise audit. Triggers on 'design our interview loop', 'audit our hiring bar'.
90
+ image-analyser: Use to analyse a character image down to the smallest mole and diff against a canon — per-feature spec, OCR-reads tattoo text, flags drift. Triggers 'analyse this image', 'match the canon'.
91
+ image-creator: Use to generate a character image to spec — max-fidelity reproducible prompt from a Canon Spec, anchors-first, provider/governance-gated. Triggers 'generate this character', 'render to spec'.
90
92
  incident-commander: Use during or right after an incident — frames severity, sets comms cadence, drafts the post-mortem skeleton — even when the user just says 'production is down' or 'wir haben einen Vorfall'.
91
93
  jira-integration: Use when the user says "check Jira", "create ticket", "update issue", or needs JQL queries, ticket transitions, or branch-to-ticket linking.
92
94
  jobs-events: Use when creating Laravel jobs, queued workflows, events, or listeners. Covers clear responsibilities, safe serialization, and retry/failure handling.
@@ -150,6 +152,7 @@ playwright-architect: Use when shaping a Playwright suite — locator strategy,
150
152
  playwright-testing: Use when writing Playwright E2E tests — browser automation, visual regression testing, Page Objects, fixtures, and reliable test patterns.
151
153
  po-discovery: Use when shaping a fuzzy product ask into a refined backlog item — problem framing, user-story rewrite, AC tightening — even if the user just says 'help me write this ticket'.
152
154
  positioning-strategy: Use when locking the market frame — category, segment, alternative, point-of-view — before messaging, launch, or pricing rides on it. Triggers on 'who are we for', 'opposable audit'.
155
+ prediction-pool-optimizer: Optimize prediction-pool tips (kicktipp etc.): rules + multi-book consensus odds → expected-points-max answer for every question, scores AND bonus. Triggers 'optimize my pool tips', 'predict'.
153
156
  privacy-review: Use when reviewing data flows, support macros, refund templates for GDPR/CCPA/HIPAA fit — regime, consent, PII redaction (email, order-id), breach triage. Triggers 'is this GDPR-safe', 'PII redact'.
154
157
  project-analysis-core: Raw discovery primitives — project discovery, version resolution, docs loading, architecture mapping, execution flow. Called by `universal-project-analysis`. Single-pass scan → `project-analyzer`.
155
158
  project-analysis-hypothesis-driven: Use when a bug has multiple plausible causes across layers — competing hypotheses, validation loops, evidence-based conclusions — even when the user just says 'why is this happening?'.
@@ -197,6 +200,7 @@ skill-improvement-pipeline: ONLY when user explicitly requests: run the skill im
197
200
  skill-management: Use when condensing, decondenseing, refactoring, or improving existing skills. Covers the full skill lifecycle from verbose → sharp → maintained.
198
201
  skill-reviewer: Use when reviewing, auditing, or optimizing skills — validates against the 7 Skill Killers checklist and produces fix recommendations.
199
202
  skill-writing: Use when deciding 'should this be a skill or a rule?', creating/improving/reviewing agent skills, SKILL.md frontmatter, or procedure sections — even without saying 'skill-writing'.
203
+ song-to-script: Turn an audio track into a timed `## Scene N` script: song sections → per-scene durations, auto mode adds mood + lip-sync lines. Triggers 'music video', 'from the song', 'cut to the beat'.
200
204
  sql-writing: Use when writing raw SQL — MariaDB/MySQL syntax, parameterization, raw migrations, seeders with `DB::statement` — even when the user just pastes a query and asks 'why is this slow' without naming SQL.
201
205
  stakeholder-tradeoff: Use when stakeholders pull a decision in different directions — frames each lens, builds a trade-off matrix, surfaces the cost of every choice — even if the user just says 'PO and ops disagree'.
202
206
  subagent-orchestration: Use when orchestrating implementer/judge subagents — seven modes (do-and-judge ±two-stage, do-in-steps/parallel/worktrees, do-competitively, judge-with-debate) — models from .agent-settings.yml.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "5.6.1",
3
+ "version": "5.8.0",
4
4
  "description": "Universal AI Agent OS \u2014 audited skills, governance rules, commands, and templates for AI coding tools (Claude Code, Cursor, Windsurf, Copilot).",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -55,6 +55,7 @@ from scripts._lib.agent_settings import (
55
55
  ROOT_OVERRIDE_ENV,
56
56
  ProjectRootError,
57
57
  find_project_root_with_trace,
58
+ project_settings_path,
58
59
  resolve_project_root,
59
60
  )
60
61
 
@@ -131,7 +132,7 @@ def _settings_layer_chain(project_root: Path) -> list[str]:
131
132
  user_global = user_global_paths.resolve_with_fallback("agent-settings.yml")
132
133
  if user_global is not None and user_global.is_file():
133
134
  layers.append(str(user_global))
134
- project_settings = project_root / ".agent-settings.yml"
135
+ project_settings = project_settings_path(project_root)
135
136
  if project_settings.is_file():
136
137
  layers.append(str(project_settings))
137
138
  return layers
@@ -778,7 +779,7 @@ def _check_tier_usage_readiness(project_root: Path) -> dict[str, Any]:
778
779
 
779
780
  Contract: ``docs/contracts/command-clusters.md`` § tier-usage signal.
780
781
  """
781
- settings_file = project_root / ".agent-settings.yml"
782
+ settings_file = project_settings_path(project_root)
782
783
  log_path = project_root / ".agent-tier-usage.jsonl"
783
784
  enabled = False
784
785
  if settings_file.is_file():
@@ -262,7 +262,7 @@ makes network calls. Output is the ExplainTrace v1 contract:
262
262
 
263
263
  why-slots answered (Markdown sections; JSON keys in parens):
264
264
 
265
- inputs — profile / preset / cost_profile with per-knob source
265
+ inputs — profile / preset / rule_loading_tier with per-knob source
266
266
  (pack | profile | preset | user | env | runtime |
267
267
  default)
268
268
  route — matched tier-1 rules · kernel rules · active persona
@@ -18,7 +18,7 @@ import subprocess
18
18
  import sys
19
19
  from pathlib import Path
20
20
 
21
- from scripts._lib.agent_settings import resolve_project_root
21
+ from scripts._lib.agent_settings import project_settings_path, resolve_project_root
22
22
 
23
23
  PACKAGE_NAME = "@event4u/agent-config"
24
24
 
@@ -51,7 +51,7 @@ def _local_package_version() -> str:
51
51
 
52
52
  def _pinned_version() -> str:
53
53
  """Return the ``agent_config_version`` pin from ``.agent-settings.yml``."""
54
- settings = _project_root() / ".agent-settings.yml"
54
+ settings = project_settings_path(_project_root())
55
55
  if not settings.exists():
56
56
  return ""
57
57
  try:
@@ -16,7 +16,7 @@ from scripts._cli.explain_last.scrubber import scrub_string
16
16
  from scripts._lib.agent_settings import DEFAULT_PROJECT_FILE, load_agent_settings
17
17
  from scripts.config import presets, profiles
18
18
 
19
- _DEFAULT_COST_PROFILE = "balanced"
19
+ _DEFAULT_RULE_LOADING_TIER = "balanced"
20
20
  _SILENCED_LOGGERS = ("scripts.config.profiles", "scripts.config.presets")
21
21
 
22
22
 
@@ -65,19 +65,22 @@ def build(project_root: Path) -> dict[str, Any] | None:
65
65
  )
66
66
  except (profiles.ProfileError, presets.PresetError, OSError):
67
67
  return None
68
- cost_profile = settings.get("cost_profile") if isinstance(settings, dict) else None
69
- cost_profile_source = "user" if cost_profile else "default"
70
- if not cost_profile or cost_profile == "__COST_PROFILE__":
71
- cost_profile = _DEFAULT_COST_PROFILE
72
- cost_profile_source = "default"
68
+ rule_loading_tier = (
69
+ (settings.get("rule_loading_tier") or settings.get("cost_profile"))
70
+ if isinstance(settings, dict) else None
71
+ )
72
+ rule_loading_tier_source = "user" if rule_loading_tier else "default"
73
+ if not rule_loading_tier or rule_loading_tier == "__RULE_LOADING_TIER__":
74
+ rule_loading_tier = _DEFAULT_RULE_LOADING_TIER
75
+ rule_loading_tier_source = "default"
73
76
  return {
74
77
  "profile": scrub_string(resolved_profile.id),
75
78
  "preset": scrub_string(resolved_preset.id),
76
- "cost_profile": scrub_string(str(cost_profile)),
79
+ "rule_loading_tier": scrub_string(str(rule_loading_tier)),
77
80
  "source_per_knob": {
78
81
  "profile": resolved_profile.source,
79
82
  "preset": resolved_preset.source,
80
- "cost_profile": cost_profile_source,
83
+ "rule_loading_tier": rule_loading_tier_source,
81
84
  },
82
85
  }
83
86
 
@@ -15,7 +15,7 @@ def render(trace: dict[str, Any]) -> str:
15
15
  rows = [
16
16
  ("profile.id", inputs.get("profile"), sources.get("profile")),
17
17
  ("preset.id", inputs.get("preset"), sources.get("preset")),
18
- ("cost_profile", inputs.get("cost_profile"), sources.get("cost_profile")),
18
+ ("rule_loading_tier", inputs.get("rule_loading_tier"), sources.get("rule_loading_tier")),
19
19
  ]
20
20
  out.append("| knob | value | source |")
21
21
  out.append("|---|---|---|")
@@ -76,6 +76,45 @@ def _local_settings_path(project_root: Path) -> Path:
76
76
  return project_root.joinpath(*LOCAL_PROJECT_SUBDIR, LOCAL_PROJECT_FILE)
77
77
 
78
78
 
79
+ def _canonical_settings_path(project_root: Path) -> Path:
80
+ """Canonical project settings file: ``<root>/agents/settings/.agent-settings.yml``.
81
+
82
+ The project settings file lives in the project's settings layer
83
+ (``agents/settings/``, alongside ``contexts/`` and ``policies/`` and
84
+ the ``.agent-settings.local.yml`` override), NOT at the repo root.
85
+ The repo-root ``.agent-settings.yml`` is a legacy location read only
86
+ as a back-compat fallback (see :func:`project_settings_path`).
87
+ """
88
+ return project_root.joinpath(*LOCAL_PROJECT_SUBDIR, DEFAULT_PROJECT_FILE)
89
+
90
+
91
+ def project_settings_path(project_root: Path) -> Path:
92
+ """Resolve the project settings file for **reading**.
93
+
94
+ Returns the canonical ``agents/settings/.agent-settings.yml`` when it
95
+ exists; otherwise the legacy repo-root ``.agent-settings.yml`` when
96
+ that exists (back-compat for installs predating the relocation);
97
+ otherwise the canonical path (so the caller still names the right
98
+ target on a fresh repo). Existence-checked, never writes.
99
+ """
100
+ canonical = _canonical_settings_path(project_root)
101
+ if canonical.exists():
102
+ return canonical
103
+ legacy = project_root / DEFAULT_PROJECT_FILE
104
+ if legacy.exists():
105
+ return legacy
106
+ return canonical
107
+
108
+
109
+ def canonical_settings_write_path(project_root: Path) -> Path:
110
+ """Always the canonical **write** target: ``agents/settings/.agent-settings.yml``.
111
+
112
+ Writers (install, sync, migrate) target this unconditionally; the
113
+ legacy root file is migrated into it, never written afresh.
114
+ """
115
+ return _canonical_settings_path(project_root)
116
+
117
+
79
118
  DEFAULT_TEAM_FILE = ".agent-project-settings.yml"
80
119
  USER_GLOBAL_FILENAME = "agent-settings.yml"
81
120
 
@@ -100,7 +139,8 @@ def _resolve_user_global_file() -> Path:
100
139
  MERGEABLE_KEYS: tuple[str, ...] = (
101
140
  "name",
102
141
  "ide",
103
- "cost_profile",
142
+ "rule_loading_tier",
143
+ "memory.cadence",
104
144
  "personal.bot_icon",
105
145
  "personal.autonomy",
106
146
  "telegraph.speak_scope",
@@ -430,12 +470,14 @@ def _resolve_cascade_paths(
430
470
  """
431
471
  if cwd is None:
432
472
  legacy = Path(project_path) if project_path else Path(DEFAULT_PROJECT_FILE)
433
- return [legacy, _local_settings_path(legacy.parent)]
473
+ return [legacy, _canonical_settings_path(legacy.parent),
474
+ _local_settings_path(legacy.parent)]
434
475
 
435
476
  root = find_project_root(cwd)
436
477
  if root is None:
437
478
  legacy = Path(project_path) if project_path else Path(DEFAULT_PROJECT_FILE)
438
- return [legacy, _local_settings_path(legacy.parent)]
479
+ return [legacy, _canonical_settings_path(legacy.parent),
480
+ _local_settings_path(legacy.parent)]
439
481
 
440
482
  cwd_resolved = cwd.resolve()
441
483
  # Build the chain root → … → cwd (shallowest first, deepest last).
@@ -450,9 +492,15 @@ def _resolve_cascade_paths(
450
492
  break
451
493
  cursor = parent
452
494
  chain.reverse()
453
- # Committed cascade root → cwd, then the single project-level local override
454
- # under agents/settings/ as the deepest (winning) layer.
455
- return [d / DEFAULT_PROJECT_FILE for d in chain] + [_local_settings_path(root)]
495
+ # Legacy per-dir cascade root → cwd (repo-root .agent-settings.yml is the
496
+ # shallowest, back-compat), then the canonical project settings file under
497
+ # agents/settings/ (wins over the legacy root location), then the
498
+ # per-machine local override under agents/settings/ as the deepest (winning)
499
+ # layer.
500
+ return (
501
+ [d / DEFAULT_PROJECT_FILE for d in chain]
502
+ + [_canonical_settings_path(root), _local_settings_path(root)]
503
+ )
456
504
 
457
505
 
458
506
  def load_agent_settings(
@@ -30,6 +30,7 @@ from typing import Iterator
30
30
  ROOT = Path(__file__).resolve().parents[2]
31
31
  LEGACY_SRC = ROOT / ".agent-src.uncondensed"
32
32
  PACKAGES = ROOT / "packages"
33
+ PACKAGE_CORE = PACKAGES / "core"
33
34
 
34
35
  # Repo-relative POSIX path prefixes that anchor an artefact source tree.
35
36
  # Order: legacy first (kept until the move lands), then packages/*. Each
@@ -155,3 +156,32 @@ def strip_source_prefix(rel: str) -> str | None:
155
156
  def is_artefact_path(rel: str) -> bool:
156
157
  """``True`` if a repo-relative POSIX path sits under any source root."""
157
158
  return strip_source_prefix(rel) is not None
159
+
160
+
161
+ def resolve_package_core_path(relative_target: str) -> Path:
162
+ """Return the canonical ``packages/core/<relative_target>`` path.
163
+
164
+ The single resolution point for every gate that enforces something
165
+ against a fixed ``packages/core/`` target. A future move of the
166
+ ``packages/core/`` tree updates :data:`PACKAGE_CORE` here — one
167
+ resolver — instead of N hard-coded ``REPO_ROOT / "packages" / "core"``
168
+ constants scattered across gate scripts (the ``aab5755`` silent-no-op
169
+ class this eliminates).
170
+
171
+ Pure resolver: deterministic, **no filesystem I/O**. ``agent_src`` is
172
+ imported by scanners that must stay usable in the legacy-only and
173
+ pack-only layouts (see :func:`artefact_roots`), so this MUST NOT
174
+ assert existence at import or call time — a packages/core existence
175
+ check here would break those layouts. Callers that need existence
176
+ check it themselves; ``scripts/check_gate_paths.py`` is the single
177
+ gate that asserts the enforced targets resolve under ``packages/core/``.
178
+
179
+ Examples:
180
+ ``resolve_package_core_path(".agent-src.uncondensed")``
181
+ → ``<repo>/packages/core/.agent-src.uncondensed``
182
+ ``resolve_package_core_path(".agent-src.uncondensed/commands")``
183
+ → ``<repo>/packages/core/.agent-src.uncondensed/commands``
184
+ ``resolve_package_core_path("")`` → ``<repo>/packages/core``
185
+ """
186
+ rel = relative_target.replace("\\", "/").lstrip("/")
187
+ return PACKAGE_CORE / rel if rel else PACKAGE_CORE
@@ -35,6 +35,13 @@ DEFAULT_REFERENCE_SCALE = {
35
35
  "model_tier": "sonnet",
36
36
  }
37
37
 
38
+ # Confidence levels that contribute to the cumulative / NETTO headline.
39
+ # `pending` (not yet measured) and `available` (measured but behind a
40
+ # default-off kill-switch, e.g. the thin projection) are shown with their
41
+ # token_delta but excluded from the default cumulative — the headline must
42
+ # reflect what actually ships by default.
43
+ _COUNTING_CONFIDENCES = ("measured", "estimated", "vendor-claim")
44
+
38
45
  # ── Pricing ─────────────────────────────────────────────────────────────
39
46
 
40
47
 
@@ -228,6 +235,96 @@ def load_rung_from_frugality(
228
235
  }
229
236
 
230
237
 
238
+ def load_rung_from_projection(
239
+ projection: Optional[Dict[str, Any]],
240
+ reference_scale: Dict[str, Any],
241
+ pricing_row: Dict[str, Any],
242
+ tool: str = ".claude",
243
+ ) -> Optional[Dict[str, Any]]:
244
+ """Build the load rung from the REAL eager always-on footprint.
245
+
246
+ Phase 3.1 honesty fix: the older `load_rung_from_router` counts only the
247
+ kernel + charter (~8.5k tok), modelling non-kernel rules as on-demand.
248
+ But 0B.6 confirmed the primary tool **eager-loads every rule body**
249
+ (~59k tok always-on). This rung reads that measured footprint from
250
+ `internal/bench/reports/projection-cost.json::rule_footprint[<tool>]`
251
+ so Panel A reflects what actually lands in context per request.
252
+
253
+ Returns None when the projection report lacks the footprint, so the
254
+ caller can fall back to the router/frugality rung.
255
+ """
256
+ rf = (projection or {}).get("rule_footprint", {})
257
+ entry = rf.get(tool) or next(iter(rf.values()), None)
258
+ if not entry or "tokens_gpt" not in entry:
259
+ return None
260
+ token_delta = int(entry["tokens_gpt"])
261
+ files = int(entry.get("files", 0))
262
+ return {
263
+ "id": "load",
264
+ "label": "Mit Paket (Regeln laden) / With package (rule load)",
265
+ "what_it_does": "Die immer-aktiven Regeln landen im Kontext jedes Requests.",
266
+ "token_delta": token_delta,
267
+ "eur_delta": price_input_delta_eur(token_delta, reference_scale, pricing_row),
268
+ "cumulative_pct": 0.0,
269
+ "confidence": "measured",
270
+ "source_report": "internal/bench/reports/projection-cost.json",
271
+ "footnote": (
272
+ f"Eager-Default: alle {files} Rule-Files always-on im "
273
+ f"`{tool}`-Projektionspfad (0B.6-bestätigt fürs primäre Tool). "
274
+ "Nicht nur der Kernel — das ist die ehrliche Up-Front-Last; "
275
+ "tokens ≈ chars / 4."
276
+ ),
277
+ }
278
+
279
+
280
+ def thin_rung_from_projection(
281
+ projection: Optional[Dict[str, Any]],
282
+ reference_scale: Dict[str, Any],
283
+ pricing_row: Dict[str, Any],
284
+ ) -> Dict[str, Any]:
285
+ """Build the thin-projection rung (Phase 3.1 lever).
286
+
287
+ The thin projection keeps the kernel full-bodied and demotes every
288
+ non-kernel rule body to a router-resolved pointer, measured at
289
+ −`saved_gpt` tokens. It ships **behind a kill-switch**
290
+ (`lean_projection.mode`, default `eager-all`), so this rung is
291
+ `confidence: available` — its measured delta is shown but does NOT
292
+ enter the default cumulative (the default reality is eager). The
293
+ footnote states the would-be always-on total and the validation state.
294
+ """
295
+ tp = (projection or {}).get("thin_projection", {})
296
+ if not tp or "saved_gpt" not in tp:
297
+ return pending_rung(
298
+ "thin",
299
+ "+ thin (Regeln als Pointer) / + thin (rules as pointers)",
300
+ "Nicht-Kernel-Regel-Bodies werden zu router-aufgelösten Pointern.",
301
+ "internal/bench/reports/projection-cost.json",
302
+ footnote="Run scripts/project_thin_rules.py --measure to populate.",
303
+ )
304
+ saved = int(tp["saved_gpt"])
305
+ thin_total = int(tp.get("thin_gpt", 0))
306
+ eager_total = int(tp.get("eager_gpt", 0))
307
+ pct = tp.get("saved_pct", 0)
308
+ return {
309
+ "id": "thin",
310
+ "label": "+ thin (Regeln als Pointer) / + thin (rules as pointers)",
311
+ "what_it_does": "Nicht-Kernel-Regel-Bodies werden zu router-aufgelösten Pointern.",
312
+ "token_delta": -saved,
313
+ "eur_delta": price_input_delta_eur(-saved, reference_scale, pricing_row),
314
+ "cumulative_pct": 0.0,
315
+ "confidence": "available",
316
+ "source_report": "internal/bench/reports/projection-cost.json",
317
+ "footnote": (
318
+ f"Verfügbar hinter `lean_projection.mode=thin` (Default `eager-all` "
319
+ f"— deshalb NICHT im Default-NETTO). Mit Thin aktiv: Rule-Layer "
320
+ f"{eager_total} → {thin_total} GPT tok (−{saved}, −{pct}%). "
321
+ "MUST-LOAD-Floor `task trigger-coverage` 26/26 grün; "
322
+ "Live-A/B-Validierung ausstehend (Harness abgelehnt). "
323
+ "Rollback = ein Flip."
324
+ ),
325
+ }
326
+
327
+
231
328
  def condense_rung_from_telegraph_v2(
232
329
  telegraph_v2: Optional[Dict[str, Any]],
233
330
  baseline_input_tokens: int,
@@ -551,7 +648,7 @@ def assemble_ladder(
551
648
  rung_copy = dict(rung)
552
649
  delta = (
553
650
  int(rung_copy.get("token_delta", 0))
554
- if rung_copy.get("confidence") != "pending"
651
+ if rung_copy.get("confidence") in _COUNTING_CONFIDENCES
555
652
  else 0
556
653
  )
557
654
  running += delta
@@ -575,7 +672,7 @@ def compute_totals(
575
672
  cumulative_token_delta = sum(
576
673
  int(r.get("token_delta", 0))
577
674
  for r in rungs
578
- if r.get("confidence") != "pending"
675
+ if r.get("confidence") in _COUNTING_CONFIDENCES
579
676
  )
580
677
  cumulative_pct = 0.0
581
678
  if baseline_input_tokens > 0: