@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
@@ -0,0 +1,109 @@
1
+ # Odds aggregation + bonus-question taxonomy
2
+
3
+ Lookup material for `prediction-pool-optimizer`. Two parts:
4
+
5
+ - **A — Multi-book consensus**: which books to read, how to weight them, how
6
+ to fold them into one calibration probability.
7
+ - **B — Bonus / award / special questions**: a type → method table so every
8
+ open question in the pool reaches an answer.
9
+
10
+ Not betting advice; how to read a public market as a probability prior for a
11
+ fun pool.
12
+
13
+ ---
14
+
15
+ ## A. Multi-book consensus — read several, weight by sharpness
16
+
17
+ ### Why not one book
18
+
19
+ A single bookmaker's line can be stale, regionally shaded, or carry a fat
20
+ margin. A consensus across several books is a far better probability estimate,
21
+ and cross-book agreement tells you the market's confidence. **Never mirror one
22
+ portal.**
23
+
24
+ ### Which books (5–10, publicly viewable)
25
+
26
+ Availability varies by region and over time — this list is **illustrative,
27
+ refresh it at run time** and use whatever is publicly viewable from the current
28
+ locale. Fastest way to see many at once = an **odds-comparison aggregator**:
29
+
30
+ - **Aggregators (many books on one page):** Oddschecker, Oddsportal,
31
+ Betexplorer, OddsAlert.
32
+ - **Sharp / low-margin reference books (weight higher):** Pinnacle, Betfair
33
+ Exchange (an exchange = closest thing to a true market price).
34
+ - **Large recreational books (weight lower):** bet365, Bwin, William Hill,
35
+ Unibet, Betano, Tipico, Interwetten, bet-at-home, 888sport, Winamax.
36
+
37
+ Aim for **5–10** spanning both groups. If only recreational books are viewable,
38
+ say so in the run note — the consensus is then softer.
39
+
40
+ ### The recipe
41
+
42
+ 1. **Per market, per book**: collect decimal odds (1X2, exact-score, each
43
+ outright, each special/award market a bonus question needs).
44
+ 2. **De-vig each book independently.** For 1X2 decimal odds `o_H, o_D, o_A`,
45
+ raw implied probs `1/o` sum to `>1` (overround); normalise:
46
+ `p_i = (1/o_i) / Σ(1/o)`. Per book — never aggregate raw odds.
47
+ 3. **Sharpness-weight and combine.** Sharp books > recreational; **weighted
48
+ mean** — or **trimmed median** when books disagree a lot (robust to one
49
+ outlier). A defensible weighting:
50
+
51
+ - Pinnacle / Betfair Exchange → weight 3
52
+ - large recreational books → weight 1
53
+ - aggregator "average" column → weight 1 (already blends many)
54
+
55
+ `p_consensus = Σ(wᵢ · pᵢ) / Σwᵢ` per outcome, then re-normalise the outcome
56
+ set to sum to 1.
57
+ 4. **Outlier handling.** One book far off the others = **flag, not truth**:
58
+ check for a reason (priced-in injury, stale line) before moving the
59
+ consensus. Cross-book agreement = signal; one disagreeing book = investigate.
60
+ 5. **Healthy weighting overall.** The consensus is a **prior**. Blend it with
61
+ the per-sport model (Poisson / Gaussian) and override only with *current*
62
+ info the market has not absorbed (confirmed lineup, late injury,
63
+ suspension, manager change). The pool answer is EV under the rules on top of
64
+ this blended probability — the market informs, it does not dictate.
65
+
66
+ ### Worked mini-example (1X2)
67
+
68
+ Two books, home/draw/away decimal odds:
69
+
70
+ - Book S (sharp, w=3): 1.80 / 3.60 / 4.50 → raw 0.556/0.278/0.222 (sum 1.056)
71
+ → de-vig 0.526/0.263/0.210
72
+ - Book R (recreational, w=1): 1.75 / 3.50 / 4.20 → raw 0.571/0.286/0.238
73
+ (sum 1.095) → de-vig 0.522/0.261/0.217
74
+
75
+ Weighted mean (3:1), per outcome, then renormalise:
76
+ ≈ **Home 0.525 / Draw 0.262 / Away 0.212**. That is the calibration base for
77
+ the per-match EV grid — not either book's raw number.
78
+
79
+ ---
80
+
81
+ ## B. Bonus / award / special questions — type → method
82
+
83
+ Every entry on the step-1 checklist gets an answer. Match the question to a
84
+ row; real market where one exists, a **labelled** model estimate where none
85
+ does. Optimize each on expected points under its point weight.
86
+
87
+ | Question type | Example | Method |
88
+ |---|---|---|
89
+ | **Outright winner** | "Who wins the tournament?" | Outright "to win" market, consensus per A; or `poisson_sim.py` `title_pct`. EV-max under the question's points. |
90
+ | **Group / stage** | "Who wins group X?", "Who advances?" | "To win group" / "to qualify" markets; or `advance_pct` from the simulator. |
91
+ | **Finalists / matchup** | "Who reaches the final?" | "To reach final" market per team; simulator pairing is approximate — prefer the market. |
92
+ | **Top scorer (player)** | "Tournament top scorer?" | "Top goalscorer" outright market, consensus per A; EV-max player (favourite unless rarity scoring rewards a longer shot). |
93
+ | **Team of the top scorer** | "Which team supplies the top scorer?" | Aggregate per-player top-scorer probabilities **by team** (sum each squad); pick the highest-summed team. |
94
+ | **Most assists / cards / etc.** | "Most yellow cards?" | Matching special market if offered; else a labelled model estimate (discipline/aggression proxy). |
95
+ | **Binary special** | "Will there be a red card in match X?" | De-vig the yes/no line to a probability; EV-max side under the points. No market → labelled base-rate estimate. |
96
+ | **Over / under total** | "Over/under total goals / cards?" | De-vig the totals line at the offered threshold; higher-EV side. |
97
+ | **Exact stat** | "How many goals in the final?" | Market totals distribution if available; else per-match Poisson on consensus xG. State the model. |
98
+
99
+ ### Rules for bonus answers
100
+
101
+ - **Answer all of them.** The output's bonus table must have the same number
102
+ of rows as the step-1 checklist. A missing row = a dropped question.
103
+ - **Market first, labelled model second.** Prefer a real special market; none
104
+ exists → derive from a stated model and mark `Source: model`.
105
+ - **Rarity rules apply here too.** Under quote/rarity scoring, a
106
+ plausible-but-rarer answer can out-score the favourite when
107
+ `payout × probability` is higher — same EV logic as the scores.
108
+ - **No hallucinated numbers.** Outright/award probabilities come from real
109
+ markets or the executed simulator — never a claimed-but-unrun simulation.
@@ -1,5 +1,5 @@
1
1
  ---
2
- model_tier: inherit
2
+ model_tier: medium
3
3
  name: rtk-output-filtering
4
4
  description: "Use when running verbose CLI commands — wraps them with rtk (Rust Token Killer) for 60-90% token savings. Covers installation, configuration, and usage patterns."
5
5
  domain: process
@@ -1,5 +1,5 @@
1
1
  ---
2
- model_tier: inherit
2
+ model_tier: medium
3
3
  name: script-writing
4
4
  description: "Use when adding or editing any script under `scripts/` — `--quiet` flag, `_lib/script_output` helpers, silent Taskfile wiring, Iron-Law carve-outs — even when you just say 'add a check script for X'."
5
5
  domain: process
@@ -1,5 +1,5 @@
1
1
  ---
2
- model_tier: inherit
2
+ model_tier: medium
3
3
  name: token-optimizer
4
4
  description: "Use BEFORE any verbose CLI run, large file read, doc conversion, or near-context handoff — single decision tree keyed by intent that cites the canonical token-saving asset. Consult before the action."
5
5
  domain: process
@@ -1,5 +1,5 @@
1
1
  ---
2
- model_tier: inherit
2
+ model_tier: medium
3
3
  name: using-git-worktrees
4
4
  description: "Use when starting parallel work in isolation from the current branch — spawn a git worktree with ignore-safety checks and a clean test baseline — even when the user says 'try this on the side'."
5
5
  domain: process
@@ -6,7 +6,7 @@ settings.
6
6
 
7
7
  ## File format
8
8
 
9
- **YAML**, with a single top-level scalar (`cost_profile`) plus one level of
9
+ **YAML**, with a single top-level scalar (`rule_loading_tier`) plus one level of
10
10
  grouped sections (`personal`, `project`, `github`, `eloquent`, `pipelines`,
11
11
  `subagents`). Comments with `#`.
12
12
 
@@ -57,7 +57,7 @@ made by the user directly or by the agent on request, following the
57
57
  # highest token cost. Pick this when working on agent-config
58
58
  # itself or when you need every behavioural rule active.
59
59
  # custom = ignore profile — every matrix value must be set explicitly.
60
- cost_profile: balanced
60
+ rule_loading_tier: balanced
61
61
 
62
62
  # --- Personal preferences ---
63
63
  personal:
@@ -132,7 +132,7 @@ eloquent:
132
132
  # agent session can be resumed. See scripts/chat_history.py for the API.
133
133
  #
134
134
  # Defaults below are placeholders — scripts/install.py substitutes them
135
- # per cost_profile (see config/profiles/*.ini).
135
+ # per rule_loading_tier (see config/profiles/*.ini).
136
136
  chat_history:
137
137
  # Log chat events to disk (true, false)
138
138
  enabled: true
@@ -199,7 +199,7 @@ pipelines:
199
199
  # Skill improvement pipeline (true, false)
200
200
  # true = after meaningful tasks, propose learning capture and improvements (default)
201
201
  # false = silent, no post-task analysis
202
- # Included by every cost_profile except `custom`.
202
+ # Included by every rule_loading_tier except `custom`.
203
203
  skill_improvement: true
204
204
 
205
205
  # --- Roadmap execution ---
@@ -460,7 +460,7 @@ the canonical narrative lives in
460
460
 
461
461
  | Key path | Values | Default | Description |
462
462
  |---|---|---|---|
463
- | `cost_profile` | `minimal`, `balanced`, `full`, `custom` | `minimal` | Selects which agent surfaces are active. See [Cost profiles](#cost-profiles). |
463
+ | `rule_loading_tier` | `minimal`, `balanced`, `full`, `custom` | `minimal` | Selects which agent surfaces are active. See [Cost profiles](#cost-profiles). |
464
464
  | `personal.ide` | `code`, `phpstorm`, `cursor` | _(empty)_ | CLI command to open files in the IDE |
465
465
  | `personal.open_edited_files` | `true`, `false` | `false` | Auto-open edited files in the IDE after edits |
466
466
  | `personal.user_name` | first name | _(empty)_ | User's first name, used to address the user personally. Captured by `/onboard`. |
@@ -527,7 +527,7 @@ Applied automatically when `scripts/install` finds a legacy `.agent-settings`
527
527
 
528
528
  | Legacy flat key | New YAML path |
529
529
  |---|---|
530
- | `cost_profile` | `cost_profile` |
530
+ | `rule_loading_tier` | `rule_loading_tier` |
531
531
  | `ide` | `personal.ide` |
532
532
  | `open_edited_files` | `personal.open_edited_files` |
533
533
  | `user_name` | `personal.user_name` |
@@ -550,7 +550,7 @@ so nothing is silently dropped; the migration log points them out.
550
550
 
551
551
  ## Cost profiles
552
552
 
553
- The `cost_profile` setting selects which agent surfaces are active. See
553
+ The `rule_loading_tier` setting selects which agent surfaces are active. See
554
554
  `docs/customization.md` for the authoritative description.
555
555
 
556
556
  | Profile | Description |
@@ -7,7 +7,7 @@
7
7
  # Precedence (lowest → highest):
8
8
  # 1. Package defaults (shipped by event4u/agent-config)
9
9
  # 2. ~/.event4u/agent-config/agent-settings.yml — user-global DX-comfort
10
- # defaults (whitelist: name, ide, cost_profile, personal.bot_icon,
10
+ # defaults (whitelist: name, ide, rule_loading_tier, personal.bot_icon,
11
11
  # personal.autonomy, telegraph.speak_scope). Created on opt-in via
12
12
  # /onboard; project-local files always win. Legacy
13
13
  # ~/.config/agent-config/agent-settings.yml is read as a fallback.
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.py (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "4.3.0"
42
+ agent_config_version: "5.7.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -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(
@@ -64,7 +64,7 @@ def _build_hook_registry(args: argparse.Namespace) -> HookRegistry:
64
64
  gate_hook.register(registry)
65
65
  if settings.memory_visibility:
66
66
  MemoryVisibilityHook(
67
- cost_profile=settings.cost_profile,
67
+ memory_cadence=settings.memory_cadence,
68
68
  visibility_off=settings.memory_visibility_off,
69
69
  ).register(registry)
70
70
  if settings.chat_history_enabled:
@@ -43,10 +43,12 @@ class MemoryVisibilityHook:
43
43
 
44
44
  Parameters
45
45
  ----------
46
- cost_profile:
47
- Cadence profile from ``.agent-settings.yml`` (``lean`` /
48
- ``standard`` / ``verbose``). ``lean`` suppresses the line
49
- unless ``asks ≥ 3`` per the contract's cadence table.
46
+ memory_cadence:
47
+ Cadence from ``memory.cadence`` in ``.agent-settings.yml``
48
+ (``auto`` / ``always`` / ``never``). ``auto`` suppresses the
49
+ line unless ``asks ≥ 3``; ``never`` suppresses it entirely;
50
+ ``always`` (default) emits whenever ``asks ≥ 1`` per the
51
+ contract's cadence table.
50
52
  visibility_off:
51
53
  When ``True``, the hook stays silent — used to mirror
52
54
  ``memory.visibility: off`` in the consumer settings.
@@ -59,11 +61,11 @@ class MemoryVisibilityHook:
59
61
  def __init__(
60
62
  self,
61
63
  *,
62
- cost_profile: str = "standard",
64
+ memory_cadence: str = "always",
63
65
  visibility_off: bool = False,
64
66
  asked_types: Iterable[str] | None = None,
65
67
  ) -> None:
66
- self._cost_profile = cost_profile
68
+ self._memory_cadence = memory_cadence
67
69
  self._visibility_off = visibility_off
68
70
  self._asked_types = (
69
71
  tuple(asked_types) if asked_types is not None else DEFAULT_ASKED_TYPES
@@ -81,7 +83,7 @@ class MemoryVisibilityHook:
81
83
  summary = summarise_visibility(memory, asked_types=self._asked_types)
82
84
  if not should_emit(
83
85
  summary,
84
- cost_profile=self._cost_profile,
86
+ memory_cadence=self._memory_cadence,
85
87
  visibility_off=self._visibility_off,
86
88
  ):
87
89
  return
@@ -16,7 +16,7 @@ settings.py``):
16
16
 
17
17
  Per road-to-portable-dev-preferences P3, the YAML read goes through
18
18
  :func:`work_engine._lib.agent_settings.load_agent_settings`, which
19
- cascades the whitelisted ``cost_profile`` (and other DX-comfort keys)
19
+ cascades the whitelisted ``rule_loading_tier`` (and other DX-comfort keys)
20
20
  from ``~/.event4u/agent-config/agent-settings.yml`` (legacy
21
21
  ``~/.config/agent-config/agent-settings.yml`` read as fallback) when
22
22
  the project file omits them. Project values always win.
@@ -61,7 +61,7 @@ class HookSettings:
61
61
  decision_trace: bool = False
62
62
  memory_visibility: bool = False
63
63
  memory_visibility_off: bool = False
64
- cost_profile: str = "standard"
64
+ memory_cadence: str = "always"
65
65
  chat_history_enabled: bool = False
66
66
  chat_history_script: str = DEFAULT_CHAT_HISTORY_SCRIPT
67
67
  decision_engine: DecisionEngineSettings = DecisionEngineSettings()
@@ -82,8 +82,8 @@ def load_hook_settings(
82
82
  ``~/.event4u/agent-config/agent-settings.yml`` (with a read fallback
83
83
  to the legacy ``~/.config/agent-config/agent-settings.yml``) and
84
84
  only cascades the whitelisted DX-comfort keys (currently
85
- ``cost_profile``) when the project file omits them. See
86
- road-to-portable-dev-preferences P3.
85
+ ``rule_loading_tier`` and ``memory.cadence``) when the project file
86
+ omits them. See road-to-portable-dev-preferences P3.
87
87
  """
88
88
  path = Path(settings_path) if settings_path else Path(DEFAULT_SETTINGS_FILE)
89
89
  raw = load_agent_settings(
@@ -133,12 +133,16 @@ def _settings_from_raw(data: dict[str, Any]) -> HookSettings:
133
133
 
134
134
  memory_section = data.get("memory")
135
135
  visibility_off = False
136
+ memory_cadence = "always"
136
137
  if isinstance(memory_section, dict):
137
138
  raw = memory_section.get("visibility")
138
139
  if isinstance(raw, str) and raw.strip().lower() == "off":
139
140
  visibility_off = True
140
141
  elif isinstance(raw, bool) and raw is False:
141
142
  visibility_off = True
143
+ cadence_raw = memory_section.get("cadence")
144
+ if cadence_raw is not None:
145
+ memory_cadence = str(cadence_raw).strip().lower() or "always"
142
146
 
143
147
  memory_hooks = hooks.get("memory_visibility")
144
148
  if isinstance(memory_hooks, dict):
@@ -148,11 +152,6 @@ def _settings_from_raw(data: dict[str, Any]) -> HookSettings:
148
152
  else:
149
153
  memory_visibility_on = True
150
154
 
151
- cost_profile_raw = data.get("cost_profile") or "standard"
152
- cost_profile = (
153
- str(cost_profile_raw).strip().lower() or "standard"
154
- )
155
-
156
155
  return HookSettings(
157
156
  enabled=True,
158
157
  trace=_coerce_bool(hooks.get("trace"), False),
@@ -168,7 +167,7 @@ def _settings_from_raw(data: dict[str, Any]) -> HookSettings:
168
167
  decision_trace=decision_trace_on,
169
168
  memory_visibility=memory_visibility_on,
170
169
  memory_visibility_off=visibility_off,
171
- cost_profile=cost_profile,
170
+ memory_cadence=memory_cadence,
172
171
  chat_history_enabled=chat_block_enabled and global_chat_on,
173
172
  chat_history_script=chat_script,
174
173
  decision_engine=decision_engine_settings,
@@ -242,17 +242,30 @@ def format_changed_decisions_block(
242
242
  def should_emit(
243
243
  summary: dict[str, Any],
244
244
  *,
245
- cost_profile: str = "standard",
245
+ memory_cadence: str = "always",
246
246
  visibility_off: bool = False,
247
247
  ) -> bool:
248
- """Apply the cadence + opt-out gates from the contract."""
248
+ """Apply the cadence + opt-out gates from the contract.
249
+
250
+ ``memory_cadence`` is the ``memory.cadence`` cadence key:
251
+
252
+ * ``always`` (default) — emit whenever ``asks >= 1``.
253
+ * ``auto`` — emit only when ``asks >= 3`` (reduces noise on
254
+ shallow-retrieval steps).
255
+ * ``never`` — suppress the line entirely.
256
+
257
+ ``visibility_off`` is the legacy ``memory.visibility: off`` master
258
+ switch and still wins over any ``memory_cadence`` value.
259
+ """
249
260
  if visibility_off:
250
261
  return False
251
262
  asks = int(summary.get("asks", 0) or 0)
252
263
  if asks <= 0:
253
264
  return False
254
- profile = (cost_profile or "standard").strip().lower()
255
- if profile == "lean":
265
+ status = (memory_cadence or "always").strip().lower()
266
+ if status == "never":
267
+ return False
268
+ if status == "auto":
256
269
  return asks >= 3
257
270
  return True
258
271