@event4u/agent-config 1.17.0 → 1.19.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 (158) hide show
  1. package/.agent-src/commands/council/default.md +74 -76
  2. package/.agent-src/commands/feature/roadmap.md +22 -0
  3. package/.agent-src/commands/roadmap/create.md +38 -6
  4. package/.agent-src/commands/roadmap/execute.md +36 -9
  5. package/.agent-src/rules/agent-authority.md +1 -0
  6. package/.agent-src/rules/agent-docs.md +1 -0
  7. package/.agent-src/rules/analysis-skill-routing.md +1 -0
  8. package/.agent-src/rules/architecture.md +1 -0
  9. package/.agent-src/rules/artifact-drafting-protocol.md +1 -0
  10. package/.agent-src/rules/artifact-engagement-recording.md +1 -0
  11. package/.agent-src/rules/ask-when-uncertain.md +1 -0
  12. package/.agent-src/rules/augment-portability.md +1 -0
  13. package/.agent-src/rules/augment-source-of-truth.md +1 -0
  14. package/.agent-src/rules/autonomous-execution.md +1 -0
  15. package/.agent-src/rules/capture-learnings.md +1 -0
  16. package/.agent-src/rules/chat-history-cadence.md +34 -0
  17. package/.agent-src/rules/chat-history-ownership.md +1 -0
  18. package/.agent-src/rules/chat-history-visibility.md +1 -0
  19. package/.agent-src/rules/cli-output-handling.md +2 -2
  20. package/.agent-src/rules/command-suggestion-policy.md +1 -0
  21. package/.agent-src/rules/commit-conventions.md +1 -0
  22. package/.agent-src/rules/commit-policy.md +1 -0
  23. package/.agent-src/rules/context-hygiene.md +28 -0
  24. package/.agent-src/rules/direct-answers.md +18 -26
  25. package/.agent-src/rules/docker-commands.md +1 -0
  26. package/.agent-src/rules/docs-sync.md +1 -0
  27. package/.agent-src/rules/downstream-changes.md +1 -0
  28. package/.agent-src/rules/e2e-testing.md +1 -0
  29. package/.agent-src/rules/guidelines.md +1 -0
  30. package/.agent-src/rules/improve-before-implement.md +1 -0
  31. package/.agent-src/rules/language-and-tone.md +1 -0
  32. package/.agent-src/rules/laravel-translations.md +1 -0
  33. package/.agent-src/rules/markdown-safe-codeblocks.md +1 -0
  34. package/.agent-src/rules/minimal-safe-diff.md +1 -0
  35. package/.agent-src/rules/missing-tool-handling.md +1 -0
  36. package/.agent-src/rules/model-recommendation.md +1 -0
  37. package/.agent-src/rules/no-cheap-questions.md +15 -21
  38. package/.agent-src/rules/no-roadmap-references.md +1 -0
  39. package/.agent-src/rules/non-destructive-by-default.md +1 -0
  40. package/.agent-src/rules/onboarding-gate.md +33 -0
  41. package/.agent-src/rules/package-ci-checks.md +1 -0
  42. package/.agent-src/rules/php-coding.md +1 -0
  43. package/.agent-src/rules/preservation-guard.md +1 -0
  44. package/.agent-src/rules/review-routing-awareness.md +1 -0
  45. package/.agent-src/rules/reviewer-awareness.md +1 -0
  46. package/.agent-src/rules/roadmap-progress-sync.md +49 -0
  47. package/.agent-src/rules/role-mode-adherence.md +2 -2
  48. package/.agent-src/rules/rule-type-governance.md +29 -0
  49. package/.agent-src/rules/runtime-safety.md +1 -0
  50. package/.agent-src/rules/scope-control.md +1 -0
  51. package/.agent-src/rules/security-sensitive-stop.md +1 -0
  52. package/.agent-src/rules/size-enforcement.md +1 -0
  53. package/.agent-src/rules/skill-improvement-trigger.md +1 -0
  54. package/.agent-src/rules/skill-quality.md +1 -0
  55. package/.agent-src/rules/slash-command-routing-policy.md +39 -0
  56. package/.agent-src/rules/think-before-action.md +1 -0
  57. package/.agent-src/rules/token-efficiency.md +1 -0
  58. package/.agent-src/rules/tool-safety.md +1 -0
  59. package/.agent-src/rules/ui-audit-gate.md +1 -0
  60. package/.agent-src/rules/upstream-proposal.md +1 -0
  61. package/.agent-src/rules/user-interaction.md +1 -0
  62. package/.agent-src/rules/verify-before-complete.md +1 -0
  63. package/.agent-src/skills/roadmap-management/SKILL.md +29 -4
  64. package/.agent-src/skills/verify-completion-evidence/SKILL.md +8 -1
  65. package/.agent-src/templates/agent-settings.md +16 -0
  66. package/.agent-src/templates/roadmaps.md +12 -3
  67. package/.agent-src/templates/scripts/work_engine/hook_bootstrap.py +9 -0
  68. package/.agent-src/templates/scripts/work_engine/hooks/__init__.py +4 -0
  69. package/.agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +4 -0
  70. package/.agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.py +163 -0
  71. package/.agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.py +111 -0
  72. package/.agent-src/templates/scripts/work_engine/hooks/settings.py +36 -0
  73. package/.agent-src/templates/scripts/work_engine/scoring/decision_trace.py +141 -0
  74. package/.agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +125 -0
  75. package/.claude-plugin/marketplace.json +1 -1
  76. package/CHANGELOG.md +97 -0
  77. package/README.md +20 -20
  78. package/config/agent-settings.template.yml +23 -0
  79. package/docs/architecture.md +1 -1
  80. package/docs/catalog.md +5 -2
  81. package/docs/contracts/adr-settings-sync-engine.md +127 -0
  82. package/docs/contracts/decision-trace-v1.md +146 -0
  83. package/docs/contracts/file-ownership-matrix.json +7 -0
  84. package/docs/contracts/hook-architecture-v1.md +213 -0
  85. package/docs/contracts/load-context-budget-model.md +80 -0
  86. package/docs/contracts/load-context-schema.md +20 -0
  87. package/docs/contracts/memory-visibility-v1.md +138 -0
  88. package/docs/contracts/one-off-script-lifecycle.md +109 -0
  89. package/docs/contracts/roadmap-complexity-standard.md +137 -0
  90. package/docs/contracts/rule-interactions.yml +22 -0
  91. package/docs/customization.md +1 -0
  92. package/docs/development.md +4 -1
  93. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
  94. package/docs/guidelines/agent-infra/direct-answers-demos.md +145 -0
  95. package/docs/guidelines/agent-infra/layered-settings.md +32 -13
  96. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
  97. package/package.json +1 -1
  98. package/scripts/agent-config +64 -0
  99. package/scripts/ai_council/bundler.py +3 -3
  100. package/scripts/ai_council/clients.py +24 -8
  101. package/scripts/ai_council/one_off_archive/2026-05/README.md +67 -0
  102. package/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +206 -0
  103. package/scripts/ai_council/{_one_off_roundtrip.py → one_off_archive/2026-05/_one_off_roundtrip.py} +13 -8
  104. package/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +180 -0
  105. package/scripts/ai_council/session.py +92 -0
  106. package/scripts/build_rule_trigger_matrix.py +360 -0
  107. package/scripts/capture_showcase_session.py +361 -0
  108. package/scripts/chat_history.py +11 -1
  109. package/scripts/check_always_budget.py +46 -2
  110. package/scripts/check_one_off_location.py +81 -0
  111. package/scripts/check_references.py +6 -0
  112. package/scripts/compress.py +5 -2
  113. package/scripts/context_hygiene_hook.py +181 -0
  114. package/scripts/council_cli.py +357 -0
  115. package/scripts/hook_manifest.yaml +184 -0
  116. package/scripts/hooks/__init__.py +1 -0
  117. package/scripts/hooks/augment-context-hygiene.sh +55 -0
  118. package/scripts/hooks/augment-dispatcher.sh +72 -0
  119. package/scripts/hooks/augment-onboarding-gate.sh +55 -0
  120. package/scripts/hooks/cline-dispatcher.sh +86 -0
  121. package/scripts/hooks/cursor-dispatcher.sh +76 -0
  122. package/scripts/hooks/dispatch_hook.py +348 -0
  123. package/scripts/hooks/envelope.py +98 -0
  124. package/scripts/hooks/gemini-dispatcher.sh +117 -0
  125. package/scripts/hooks/state_io.py +122 -0
  126. package/scripts/hooks/windsurf-dispatcher.sh +123 -0
  127. package/scripts/hooks_status.py +146 -0
  128. package/scripts/install.py +728 -51
  129. package/scripts/install.sh +1 -1
  130. package/scripts/lint_examples.py +98 -0
  131. package/scripts/lint_hook_manifest.py +216 -0
  132. package/scripts/lint_one_off_age.py +184 -0
  133. package/scripts/lint_roadmap_complexity.py +127 -0
  134. package/scripts/lint_rule_tiers.py +78 -0
  135. package/scripts/lint_showcase_sessions.py +148 -0
  136. package/scripts/minimal_safe_diff_hook.py +245 -0
  137. package/scripts/onboarding_gate_hook.py +142 -0
  138. package/scripts/readme_linter.py +12 -3
  139. package/scripts/roadmap_progress_hook.py +5 -0
  140. package/scripts/schemas/rule.schema.json +5 -0
  141. package/scripts/sync_agent_settings.py +32 -129
  142. package/scripts/sync_yaml_rt.py +734 -0
  143. package/scripts/verify_before_complete_hook.py +216 -0
  144. /package/scripts/ai_council/{_one_off_2a4_acceptance.py → one_off_archive/2026-05/_one_off_2a4_acceptance.py} +0 -0
  145. /package/scripts/ai_council/{_one_off_context_layer_v1_estimate.py → one_off_archive/2026-05/_one_off_context_layer_v1_estimate.py} +0 -0
  146. /package/scripts/ai_council/{_one_off_context_layer_v1_review.py → one_off_archive/2026-05/_one_off_context_layer_v1_review.py} +0 -0
  147. /package/scripts/ai_council/{_one_off_followups_review.py → one_off_archive/2026-05/_one_off_followups_review.py} +0 -0
  148. /package/scripts/ai_council/{_one_off_nondestructive_inline_audit.py → one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py} +0 -0
  149. /package/scripts/{_one_off_phase4_dispatch_latency.py → ai_council/one_off_archive/2026-05/_one_off_phase4_dispatch_latency.py} +0 -0
  150. /package/scripts/{_one_off_phase6_trigger_jaccard.py → ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py} +0 -0
  151. /package/scripts/ai_council/{_one_off_phase_2a_budget_rebalance.py → one_off_archive/2026-05/_one_off_phase_2a_budget_rebalance.py} +0 -0
  152. /package/scripts/ai_council/{_one_off_phase_2a_post_revert.py → one_off_archive/2026-05/_one_off_phase_2a_post_revert.py} +0 -0
  153. /package/scripts/ai_council/{_one_off_rebalancing_audit.py → one_off_archive/2026-05/_one_off_rebalancing_audit.py} +0 -0
  154. /package/scripts/ai_council/{_one_off_rule_hardening_v1.py → one_off_archive/2026-05/_one_off_rule_hardening_v1.py} +0 -0
  155. /package/scripts/ai_council/{_one_off_structural_open_questions.py → one_off_archive/2026-05/_one_off_structural_open_questions.py} +0 -0
  156. /package/scripts/ai_council/{_one_off_structural_optimization.py → one_off_archive/2026-05/_one_off_structural_optimization.py} +0 -0
  157. /package/scripts/ai_council/{_one_off_structural_v3_gaps.py → one_off_archive/2026-05/_one_off_structural_v3_gaps.py} +0 -0
  158. /package/scripts/ai_council/{_one_off_structural_v3_review.py → one_off_archive/2026-05/_one_off_structural_v3_review.py} +0 -0
@@ -0,0 +1,109 @@
1
+ ---
2
+ stability: beta
3
+ ---
4
+
5
+ # One-off-script lifecycle
6
+
7
+ **Purpose.** Pin the naming, location, age, and purge policy for
8
+ **one-off scripts** so the package does not accumulate a graveyard
9
+ under `scripts/`. One-off here means: a script written for a
10
+ specific migration, retrofit, audit, or council run, with no ongoing
11
+ caller and no place in the durable Taskfile.
12
+
13
+ **Scope.** Defines the file pattern, the directory, the maximum age,
14
+ the TTL extension mechanism, and the CI purge gate. Does **not**
15
+ specify the content of any specific one-off — that belongs to the
16
+ script itself or the cleanup-mechanics context.
17
+
18
+ Last refreshed: 2026-05-04.
19
+
20
+ ## Naming
21
+
22
+ One-off scripts MUST match this regex:
23
+
24
+ ```
25
+ ^_one_off_[a-z0-9-]+\.py$
26
+ ```
27
+
28
+ The `_one_off_` prefix is the load-bearing signal. Files outside
29
+ this prefix are treated as durable scripts and MUST be referenced by
30
+ the Taskfile or by another script.
31
+
32
+ ## Location
33
+
34
+ ```
35
+ scripts/_one_off/<YYYY-MM>/_one_off_<slug>.py
36
+ ```
37
+
38
+ `<YYYY-MM>` is the UTC month the script was first committed. The
39
+ month directory groups one-offs for archival sweeps. Scripts MUST
40
+ NOT live at `scripts/_one_off/_one_off_*.py` (no month) or under
41
+ `scripts/` directly (no `_one_off/`).
42
+
43
+ ## TTL
44
+
45
+ | State | Action |
46
+ |---|---|
47
+ | Age ≤ 60 days from month-directory date | active, no warning |
48
+ | 60 < Age ≤ 90 days | warning emitted by `lint_one_off_age.py`, no failure |
49
+ | Age > 90 days | `lint_one_off_age.py` fails CI; the script is purged in the next housekeeping pass |
50
+
51
+ Age = `today − first-of-month(<YYYY-MM>)` in UTC days. The 60-day
52
+ soft floor and 30-day grace window are intentional — they cover one
53
+ release cycle plus a sprint of grace.
54
+
55
+ ## TTL extension
56
+
57
+ A one-off MAY extend its TTL exactly once, by adding a frontmatter
58
+ block at the top of the script:
59
+
60
+ ```python
61
+ """
62
+ ---
63
+ ttl_extended_until: 2026-08-31
64
+ ttl_reason: blocked on PROJ-123 — re-runs after cutover
65
+ ---
66
+ """
67
+ ```
68
+
69
+ The linter respects `ttl_extended_until` if it is ≤ 180 days from
70
+ the file's `<YYYY-MM>` directory date. Beyond 180 days, the linter
71
+ hard-fails — no second extension. The intent is: if a "one-off" is
72
+ still live at six months, it is a durable concern and belongs in
73
+ `scripts/` or a Taskfile group.
74
+
75
+ ## Purge mechanism
76
+
77
+ `lint_one_off_age.py` runs in `task ci`. On a clean working tree, it
78
+ prints purge candidates as a list. Purge itself is a separate human-
79
+ or-CI action — `task purge-one-offs` removes flagged files. The
80
+ linter does not auto-delete.
81
+
82
+ ## Allowed exceptions
83
+
84
+ Two patterns are exempt from the prefix requirement:
85
+
86
+ - **Bundler / orchestrator helpers** under `scripts/ai_council/`
87
+ that exist to support the council CLI — they are not one-offs even
88
+ though council *runs* are one-offs.
89
+ - **`scripts/_one_off/<YYYY-MM>/README.md`** — a free-form readme is
90
+ allowed in each month directory documenting why the scripts exist.
91
+
92
+ Council run scripts that wrap a question and write the response file
93
+ DO live under `scripts/_one_off/<YYYY-MM>/` and DO follow the prefix
94
+ rule.
95
+
96
+ ## Cross-references
97
+
98
+ - The contract that defines council CLI surface (and so what gets
99
+ archived as a one-off): the council CLI section of the package's
100
+ command catalog.
101
+ - The cleanup-mechanics context for housekeeping passes:
102
+ `agents/contexts/cleanup-mechanics.md`.
103
+ - Linter implementation: `scripts/lint_one_off_age.py`.
104
+
105
+ ## Stability
106
+
107
+ Beta. Breaking changes (e.g. raising the age cap, changing the
108
+ prefix, or removing TTL extensions) require a minor-version bump and
109
+ a `### Breaking` entry in `CHANGELOG.md`.
@@ -0,0 +1,137 @@
1
+ ---
2
+ stability: beta
3
+ ---
4
+
5
+ # Roadmap Complexity Standard
6
+
7
+ > **Audience:** roadmap authors and reviewers in `agents/roadmaps/`.
8
+ > **Linter:** `scripts/lint_roadmap_complexity.py` (run via
9
+ > `task lint-roadmap-complexity`).
10
+ > **Source:** Phase 5 of the `road-to-context-layer-maturity` work
11
+ > (now archived); reviewer-flagged drift after the
12
+ > structural-optimization roadmap proved that "heavy" is correct for
13
+ > structural work but wrong for normal feature work.
14
+
15
+ Roadmaps drift toward heavyweight whenever the previous one was
16
+ heavyweight. This contract pins **two tiers**, names exemplars, and
17
+ hard-fails the lint on tier mismatch.
18
+
19
+ ## Tiers
20
+
21
+ ### Lightweight (default)
22
+
23
+ Almost every roadmap is lightweight. The shape:
24
+
25
+ - **≤ 6 phases** total
26
+ - **≤ 1 page per phase** (≈ 60 source lines including header + steps
27
+ + exit gate; the linter doesn't enforce per-phase line budgets, but
28
+ reviewers do)
29
+ - **No nested council debates** inside the roadmap (no
30
+ `## Council Round 1`, `## Council Round 2`, `### Verdict` sections)
31
+ - **No 178-step backlogs** — phases are delivery-shaped, not
32
+ task-shaped
33
+ - **≤ 600 lines total** (frontmatter + body, blank lines counted)
34
+ - Frontmatter declares `complexity: lightweight`
35
+
36
+ **Exemplars:**
37
+
38
+ - `road-to-context-layer-maturity.md` (archived) — six phases,
39
+ ~376 lines, no nested council; the seed roadmap that triggered this
40
+ standard. Self-tagged as `lightweight`.
41
+ - `road-to-rule-hardening.md` (archived) — five phases, ~263 lines;
42
+ mechanized the rule layer; sibling of the seed, also lightweight.
43
+
44
+ **Typical use:** feature work, follow-ups, bounded refactors,
45
+ mechanization passes, telemetry plumbing.
46
+
47
+ ### Structural (rare)
48
+
49
+ Triggered only when the work changes a contract layer or a budget
50
+ invariant. The shape:
51
+
52
+ - Multi-round council, locked decisions, file-ownership matrix,
53
+ gating contracts on phase boundaries
54
+ - **> 600 lines** total (typical: 800 – 1500)
55
+ - May include `## Council Round N` / `### Verdict` blocks, ADR
56
+ cross-links, decision matrices
57
+ - Frontmatter declares `complexity: structural`
58
+
59
+ **Exemplars:**
60
+
61
+ - Archived `agents/roadmaps/_archived/road-to-structural-optimization.md`
62
+ (closed 2026-05-03 after 6 phases of council-driven budget work).
63
+ ~1.5k lines, multi-round council, file-ownership matrix.
64
+
65
+ **Triggered by:** changes to a public contract surface in
66
+ `docs/contracts/`, a budget invariant in
67
+ [`load-context-budget-model.md`](load-context-budget-model.md), or a
68
+ priority hierarchy in
69
+ [`rule-priority-hierarchy.md`](rule-priority-hierarchy.md).
70
+ **Requires:** explicit user opt-in on creation. The agent must not
71
+ upgrade a lightweight roadmap to structural mid-flight without that
72
+ opt-in.
73
+
74
+ ## Anti-game clause
75
+
76
+ The trigger is **contract-layer change**, not line count alone. A
77
+ heavy roadmap split into two lightweights to dodge the gate is a
78
+ linter-defeat — reviewers flag it on PR review. Conversely, a
79
+ roadmap that legitimately needs the structural shape but tries to
80
+ hide as `lightweight` to skip council overhead is the same defeat in
81
+ the other direction.
82
+
83
+ ## Frontmatter
84
+
85
+ Every roadmap in `agents/roadmaps/` (including draft and archived
86
+ ones) declares its tier:
87
+
88
+ ```yaml
89
+ ---
90
+ complexity: lightweight
91
+ ---
92
+ ```
93
+
94
+ or
95
+
96
+ ```yaml
97
+ ---
98
+ complexity: structural
99
+ status: draft
100
+ ---
101
+ ```
102
+
103
+ Other frontmatter keys (`status:`, `owner:`, `target_release:`) are
104
+ permitted alongside but not required by this contract.
105
+
106
+ ## Linter contract
107
+
108
+ `scripts/lint_roadmap_complexity.py` (≤ 150 LOC, stdlib only)
109
+ enforces the **measurable** subset of this standard:
110
+
111
+ | Check | Lightweight | Structural |
112
+ |---|---|---|
113
+ | `complexity:` frontmatter declared | required | required |
114
+ | Total line count | ≤ 600 | > 0 (no upper cap) |
115
+ | `## Phase N` heading count | ≤ 6 | no cap |
116
+ | `## Council Round N` / `### Verdict` blocks | forbidden | allowed |
117
+ | Council session cross-links (`agents/sessions/.../council-…`) | warn | allowed |
118
+
119
+ The linter runs on every roadmap file under `agents/roadmaps/` and
120
+ exits non-zero on any violation. Hooked into `task ci` via
121
+ `task lint-roadmap-complexity`.
122
+
123
+ **Out of scope for the linter** (reviewer judgment only): step count,
124
+ per-phase length, the contract-layer-change trigger for the
125
+ structural tier.
126
+
127
+ ## Migration
128
+
129
+ Phase 5.3 of `road-to-context-layer-maturity` applies the standard
130
+ retroactively to all open roadmaps in `agents/roadmaps/`: each gets
131
+ a `complexity:` tag based on the rules above. No content rewrites
132
+ land in that step — only the tag.
133
+
134
+ Roadmaps that exceed the lightweight cap but plausibly should be
135
+ lightweight (e.g. they accumulated drift) are tagged `structural`
136
+ for now and may be split or trimmed in a follow-up. The migration
137
+ records existing reality, not aspirational reality.
@@ -221,6 +221,28 @@ pairs:
221
221
  - .agent-src.uncompressed/rules/ask-when-uncertain.md#iron-law--one-question-per-turn-always
222
222
  - .agent-src.uncompressed/rules/direct-answers.md#iron-law-3--brevity-by-default
223
223
 
224
+ - id: scope-x-verify-before-complete
225
+ rules: [verify-before-complete, scope-control]
226
+ relation: complements
227
+ conflict: >-
228
+ Agent has just finished a change that touches user-permission-gated
229
+ operations (push, branch, PR, tag) and is preparing to claim "done"
230
+ in the same turn. Both rules can fire: `verify-before-complete`
231
+ gates the completion claim on fresh evidence; `scope-control`
232
+ gates the git operation on explicit permission this turn.
233
+ resolution: >-
234
+ Both rules apply independently and compose. The
235
+ `verify-before-complete` Iron Law still requires fresh
236
+ verification output in this message before any "done" claim,
237
+ regardless of whether the user has authorised the next git op.
238
+ Conversely, verification passing does not authorise pushing or
239
+ merging — those stay behind the `scope-control` permission gate.
240
+ Skipping either is a rule violation; satisfying one does not
241
+ satisfy the other.
242
+ evidence:
243
+ - .agent-src.uncompressed/rules/verify-before-complete.md#the-iron-law
244
+ - .agent-src.uncompressed/rules/scope-control.md#git-operations--permission-gated
245
+
224
246
  - id: language-x-direct-answers
225
247
  rules: [language-and-tone, direct-answers]
226
248
  relation: complements
@@ -66,6 +66,7 @@ those sections.
66
66
  | `ai_council.cost_budget.max_calls` | `10` | Maximum council members per invocation. |
67
67
  | `ai_council.cost_budget.max_total_usd` | `0.0` | Per-invocation USD ceiling. `0` disables (token caps still apply). |
68
68
  | `ai_council.cost_budget.daily_limit_usd` | `0.0` | Rolling 24h USD ceiling across all `/council` calls. `0` disables. Ledger lives at `~/.config/agent-config/council-spend.jsonl` (mode 0600). |
69
+ | `ai_council.session_retention_days` | `14` | Auto-prune for `agents/council-sessions/` audit folders. Older session directories are removed on the next `save()`. `0` disables (keep forever). |
69
70
 
70
71
  > **Experimental.** AI Council is not yet validated by external users. API costs apply per consultation.
71
72
 
@@ -17,7 +17,10 @@
17
17
 
18
18
  ## Task Commands
19
19
 
20
- All commands use [Task](https://taskfile.dev/). See `Taskfile.yml` for the full list.
20
+ All commands use [Task](https://taskfile.dev/). The root `Taskfile.yml` orchestrates
21
+ `ci`/`_ci-*` and includes the four task groups under `taskfiles/`
22
+ (`ci-fast.yml`, `content.yml`, `engine.yml`, `release.yml`) with `flatten: true`,
23
+ so every task stays in the root namespace. Run `task --list` for the full list.
21
24
 
22
25
  ### CI & Verification
23
26
 
@@ -0,0 +1,134 @@
1
+ ---
2
+ demo_for: ask-when-uncertain
3
+ layer: pattern-memory
4
+ prose_delta:
5
+ rule_chars_before: 3893
6
+ rule_chars_after: 4267
7
+ measured_at: phase-3.3-cross-link-landing
8
+ note: "+374 chars from the Examples cross-link block; future prose-pruning rounds (out of scope for Phase 3) will pull pattern prose from the rule into this demo and drive the after-count below the before-count."
9
+ ---
10
+
11
+ # ask-when-uncertain — Pattern Memory
12
+
13
+ > Wrong / right / why demos for the `ask-when-uncertain` Iron Law
14
+ > (one question per turn, vague-request must ask). Linked from
15
+ > [`ask-when-uncertain`](../../.agent-src.uncompressed/rules/ask-when-uncertain.md)
16
+ > § Examples. Outcome baseline at
17
+ > [`tests/golden/outcomes/ask_when_uncertain.json`](../../tests/golden/outcomes/ask_when_uncertain.json).
18
+
19
+ ## Demo 1 — Vague request, multi-question stack
20
+
21
+ ### Wrong shape
22
+
23
+ ```
24
+ User: improve this
25
+
26
+ Agent:
27
+ 1. Should I optimize for readability or speed?
28
+ 2. Refactor the function signature?
29
+ 3. Add tests too?
30
+ 4. Run PHPStan after?
31
+
32
+ Reply with a, b, c, d so I can pick.
33
+ ```
34
+
35
+ **Failure mode:** four `?` aimed at the user, structured-answer
36
+ demand (`a, b, c, d`), no triage. Iron Law breach: a turn with a
37
+ question has *exactly one*. Compound thinking load — answer to Q1
38
+ reframes Q2.
39
+
40
+ ### Right shape
41
+
42
+ ```
43
+ User: improve this
44
+
45
+ Agent: Welche Achse soll "improve" treffen?
46
+
47
+ 1. Lesbarkeit (Naming, Funktions-Splits)
48
+ 2. Performance (Allokationen, N+1)
49
+ 3. Robustheit (Error-Handling, Edge Cases)
50
+
51
+ Dann lege ich los.
52
+ ```
53
+
54
+ ### Why it works
55
+
56
+ Single `?`, numbered options without compound asks, picks the
57
+ question whose answer reframes everything downstream. The follow-up
58
+ ("tests? PHPStan?") rides on the next turn — its framing depends on
59
+ the answer here.
60
+
61
+ ## Demo 2 — Drive-by execution on a vague trigger
62
+
63
+ ### Wrong shape
64
+
65
+ ```
66
+ User: clean up this file
67
+
68
+ Agent: [edits 12 files, removes 200 lines, reformats imports,
69
+ extracts 3 helpers, renames 5 variables]
70
+ Done.
71
+ ```
72
+
73
+ **Failure mode:** "clean up" is a vague-request trigger
74
+ (`ask-when-uncertain` § Vague-request triggers). MUST-ask before
75
+ touching code. Without scope, the diff is a guess at the user's
76
+ intent.
77
+
78
+ ### Right shape
79
+
80
+ ```
81
+ User: clean up this file
82
+
83
+ Agent: Was bedeutet "clean up" hier?
84
+
85
+ 1. Toten Code raus
86
+ 2. Format / Imports sortieren
87
+ 3. Refactor (Funktionen splitten)
88
+
89
+ Pick one — sonst ist der Diff Raten.
90
+ ```
91
+
92
+ ### Why it works
93
+
94
+ Names the trigger explicitly ("vague-request"), surfaces the three
95
+ canonical interpretations from the rule's trigger table, and
96
+ declines to act without scope. The cost of asking once << cost of
97
+ ripping through 12 files in the wrong direction.
98
+
99
+ ## Demo 3 — Stacked questions inside a handoff
100
+
101
+ ### Wrong shape
102
+
103
+ ```
104
+ Agent: Bevor ich die Roadmap übergebe:
105
+
106
+ - Welcher Branch?
107
+ - Soll ich PRs erwähnen?
108
+ - Welches Modell für die Fortsetzung?
109
+ - Soll ich .agent-chat-history zitieren?
110
+
111
+ Antworte als 1, 2, 3, 4.
112
+ ```
113
+
114
+ **Failure mode:** four-question handoff block. Per § Ordering &
115
+ handoff: handoff questions ride LAST, after domain clarifications,
116
+ folded into the handoff prompt itself — not as a parallel quiz.
117
+
118
+ ### Right shape
119
+
120
+ ```
121
+ Agent: [delivers the handoff prompt with sensible defaults filled
122
+ in: current branch, PR link present if open, model
123
+ recommendation per `model-recommendation`, history reference
124
+ auto-included]
125
+
126
+ Welche der vier Defaults soll ich vor dem Übergeben anpassen?
127
+ ```
128
+
129
+ ### Why it works
130
+
131
+ Defaults absorb three of the four "questions"; the remaining
132
+ question is the only one that genuinely needs user input — and it's
133
+ phrased so a one-word answer ("PR link" / "model" / "passt") closes
134
+ the loop.
@@ -0,0 +1,145 @@
1
+ ---
2
+ demo_for: direct-answers
3
+ layer: pattern-memory
4
+ prose_delta:
5
+ rule_chars_before: 4098
6
+ rule_chars_after: 4514
7
+ measured_at: phase-3.3-cross-link-landing
8
+ note: "+416 chars from the Examples cross-link block; future prose-pruning rounds (out of scope for Phase 3) will pull pattern prose from the rule into this demo and drive the after-count below the before-count."
9
+ ---
10
+
11
+ # direct-answers — Pattern Memory
12
+
13
+ > Wrong / right / why demos for the three Iron Laws of
14
+ > `direct-answers` (no flattery, no invented facts, brevity by
15
+ > default). Linked from
16
+ > [`direct-answers`](../../.agent-src.uncompressed/rules/direct-answers.md)
17
+ > § Examples. Outcome baseline at
18
+ > [`tests/golden/outcomes/direct_answers.json`](../../tests/golden/outcomes/direct_answers.json).
19
+
20
+ ## Demo 1 — Flattery opener (Iron Law 1)
21
+
22
+ ### Wrong shape
23
+
24
+ ```
25
+ User: Wie viele Always-Rules gibt es aktuell?
26
+
27
+ Agent: Sehr gute Frage! Das ist tatsächlich eine spannende
28
+ Eigenschaft des Systems. Lass mich das für dich aufschlüsseln —
29
+ aktuell sind es 38 Always-Rules.
30
+ ```
31
+
32
+ **Failure mode:** flattery opener ("Sehr gute Frage!"), action
33
+ announcement ("Lass mich…"), then 30 Wörter Anlauf für eine
34
+ Ein-Wort-Antwort. Iron Law 1 + Iron Law 3 zusammen verletzt.
35
+
36
+ ### Right shape
37
+
38
+ ```
39
+ User: Wie viele Always-Rules gibt es aktuell?
40
+
41
+ Agent: 38.
42
+ ```
43
+
44
+ ### Why it works
45
+
46
+ Eine Frage mit einer wahren Antwort = ein Satz. Kein Anlauf, kein
47
+ Kissen, kein "let me…". Die Zahl ist die ganze Antwort.
48
+
49
+ ## Demo 2 — Hedged claim without verification (Iron Law 2)
50
+
51
+ ### Wrong shape
52
+
53
+ ```
54
+ User: Hat verify-before-complete ein "load_context"-Feld?
55
+
56
+ Agent: Ja, ich glaube schon — die meisten Always-Rules haben das
57
+ inzwischen. Sollte in der Frontmatter stehen.
58
+ ```
59
+
60
+ **Failure mode:** load-bearing project-shape claim ohne Verify, mit
61
+ zwei Hedges ("ich glaube", "sollte"). Iron Law 2 § Severity-tiered:
62
+ project-shape claims müssen mit einem Tool-Call belegt werden, wenn
63
+ einer reicht — und hier reicht ein `view`/`grep` locker.
64
+
65
+ ### Right shape
66
+
67
+ ```
68
+ User: Hat verify-before-complete ein "load_context"-Feld?
69
+
70
+ Agent: [grept frontmatter]
71
+ Nein. `verify-before-complete.md` deklariert keinen load_context-
72
+ Eintrag (nur die anderen vier Safety-Floor-Rules tun das).
73
+ ```
74
+
75
+ ### Why it works
76
+
77
+ Tool-Call vor Antwort, dann konkrete Aussage mit Begründung. Wenn
78
+ der Verify-Aufwand zu groß wäre → fragen, nicht raten. Hier kostet
79
+ ein `grep` zwei Sekunden, also Tool-Call ist Pflicht.
80
+
81
+ ## Demo 3 — Post-hoc summary creep (Iron Law 3)
82
+
83
+ ### Wrong shape
84
+
85
+ ```
86
+ User: Wie öffne ich die VBC-Demos?
87
+
88
+ Agent: Hier der Pfad zur Datei:
89
+
90
+ `docs/guidelines/agent-infra/verify-before-complete-demos.md`
91
+
92
+ Zusammenfassend: das ist die Demo-Datei für die Iron Law des
93
+ verify-before-complete-Rule. Sie folgt dem wrong/right/why-Schema
94
+ und ist Teil der Phase 3 von road-to-context-layer-maturity.
95
+ Lass mich wissen, falls du Fragen dazu hast.
96
+ ```
97
+
98
+ **Failure mode:** Nutzlose Zusammenfassung nach der Antwort, dann
99
+ Service-Floskel ("Lass mich wissen…"). Iron Law 3: kürzeste
100
+ vollständige Antwort gewinnt; Restaurierung von Kontext und
101
+ Closing-Floskel sind beide Failure-Modes.
102
+
103
+ ### Right shape
104
+
105
+ ```
106
+ User: Wie öffne ich die VBC-Demos?
107
+
108
+ Agent: `docs/guidelines/agent-infra/verify-before-complete-demos.md`
109
+ ```
110
+
111
+ ### Why it works
112
+
113
+ Pfad ist die ganze Antwort. Kein Re-Frame der Frage, kein
114
+ "Zusammenfassend", kein angebotenes Follow-up. Wenn Matze mehr
115
+ will, fragt er.
116
+
117
+ ## Demo 4 — Functional emoji vs prose flair
118
+
119
+ ### Wrong shape
120
+
121
+ ```
122
+ Agent: 🚀 Tests sind durch! ✨ Alle 47 grün 🎉 Bereit für den nächsten Schritt 💪
123
+ ```
124
+
125
+ **Failure mode:** Emoji als Stil-Element, nicht als funktionaler
126
+ Marker. § Emoji Scope erlaubt nur die Whitelist (`📒` Heartbeat,
127
+ mode marker, `❌` `✅` `⚠️` mit Two-Space-Regel, Roadmap-`[x]/[~]/[-]`).
128
+ Alles andere ist Rauschen.
129
+
130
+ ### Right shape
131
+
132
+ ```
133
+ Agent: Tests durch:
134
+
135
+ $ vendor/bin/pest -q
136
+ ............................................... 47 passed
137
+
138
+ ✅ 47/47 grün, Exit 0.
139
+ ```
140
+
141
+ ### Why it works
142
+
143
+ Genau ein Emoji aus der Whitelist (`✅` mit Two-Space), funktional
144
+ verwendet als Status-Marker neben dem CLI-Output. Keine Deko, keine
145
+ Reaktions-Emojis.
@@ -152,27 +152,46 @@ MUST follow these rules. Initial file creation and legacy migration
152
152
  are owned by `scripts/install.py`; these rules govern every edit
153
153
  after that.
154
154
 
155
+ The contract is **additive merge with user-line preservation** —
156
+ the user's file is the ground truth, the template only contributes
157
+ keys the user is missing. Round-trip parser and merger live in
158
+ [`scripts/sync_yaml_rt.py`](../../scripts/sync_yaml_rt.py); the
159
+ supported YAML subset (block-mappings, scalars, lists, comments,
160
+ CRLF/LF) is documented in its module docstring. The stdlib-only
161
+ choice (vs. `ruamel.yaml`) and its revisit triggers are recorded in
162
+ [`docs/contracts/adr-settings-sync-engine.md`](../../contracts/adr-settings-sync-engine.md).
163
+
155
164
  For each section in the template
156
- ([`agent-settings.md`](../../templates/agent-settings.md)), walked in
157
- template order:
165
+ ([`agent-settings.md`](../../templates/agent-settings.md)):
158
166
 
159
- - Keep the section header and its comments verbatim from the template.
160
167
  - For each key under the section:
161
- - **Key exists in user's file** → use the user's current value.
162
- - **Key missing** use the template default.
163
- - **Unknown sections/keys** the user has added preserve at the end
164
- of the section (or in a trailing `_user:` block if no matching
165
- section exists).
168
+ - **Key exists in user's file** → keep the user's line **verbatim**
169
+ (value, quoting, inline comment, indent all preserved).
170
+ - **Key missing** insert the template's line at the position
171
+ after the user's last preceding sibling that is also in the
172
+ template (max-index insertion).
173
+ - **Unknown sections/keys** the user has added → preserved verbatim
174
+ at their existing position. They are not moved to a trailing
175
+ `_user:` block, not re-prefixed, not flattened.
166
176
 
167
177
  Invariants:
168
178
 
169
- - Template section **order** always wins reorder existing keys to
170
- match.
179
+ - **User order wins.** Template order is only consulted to decide
180
+ where to insert missing keys; existing user keys are never
181
+ reordered.
171
182
  - Existing scalar values are **never overwritten** unless the user
172
183
  asked for that specific change.
173
- - New keys added to the template land with their default value.
174
- - Comments from the template replace user comments in the same
175
- position comments are documentation, not user data.
184
+ - New keys added to the template land with their default value and
185
+ the template's leading comments.
186
+ - **User comments are preserved verbatim** on every existing key.
187
+ Template comments only land with keys the merger inserts; once a
188
+ key is in the user's file, its surrounding comments are owned by
189
+ the user.
190
+ - Legacy `_user._user.foo` corruption (accumulated by older buggy
191
+ syncs) heals on the next sync — the leading `_user.` chain is
192
+ stripped and the leaf is re-homed at its template path, or kept
193
+ as a single-level orphan under `_user:` if no template home
194
+ exists.
176
195
  - Write with 2-space indent, no tabs, no trailing whitespace.
177
196
  - Never commit — `.agent-settings.yml` is git-ignored.
178
197
  - If a legacy flat `.agent-settings` (key=value) is still present,