@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.
- package/.agent-src/commands/council/default.md +74 -76
- package/.agent-src/commands/feature/roadmap.md +22 -0
- package/.agent-src/commands/roadmap/create.md +38 -6
- package/.agent-src/commands/roadmap/execute.md +36 -9
- package/.agent-src/rules/agent-authority.md +1 -0
- package/.agent-src/rules/agent-docs.md +1 -0
- package/.agent-src/rules/analysis-skill-routing.md +1 -0
- package/.agent-src/rules/architecture.md +1 -0
- package/.agent-src/rules/artifact-drafting-protocol.md +1 -0
- package/.agent-src/rules/artifact-engagement-recording.md +1 -0
- package/.agent-src/rules/ask-when-uncertain.md +1 -0
- package/.agent-src/rules/augment-portability.md +1 -0
- package/.agent-src/rules/augment-source-of-truth.md +1 -0
- package/.agent-src/rules/autonomous-execution.md +1 -0
- package/.agent-src/rules/capture-learnings.md +1 -0
- package/.agent-src/rules/chat-history-cadence.md +34 -0
- package/.agent-src/rules/chat-history-ownership.md +1 -0
- package/.agent-src/rules/chat-history-visibility.md +1 -0
- package/.agent-src/rules/cli-output-handling.md +2 -2
- package/.agent-src/rules/command-suggestion-policy.md +1 -0
- package/.agent-src/rules/commit-conventions.md +1 -0
- package/.agent-src/rules/commit-policy.md +1 -0
- package/.agent-src/rules/context-hygiene.md +28 -0
- package/.agent-src/rules/direct-answers.md +18 -26
- package/.agent-src/rules/docker-commands.md +1 -0
- package/.agent-src/rules/docs-sync.md +1 -0
- package/.agent-src/rules/downstream-changes.md +1 -0
- package/.agent-src/rules/e2e-testing.md +1 -0
- package/.agent-src/rules/guidelines.md +1 -0
- package/.agent-src/rules/improve-before-implement.md +1 -0
- package/.agent-src/rules/language-and-tone.md +1 -0
- package/.agent-src/rules/laravel-translations.md +1 -0
- package/.agent-src/rules/markdown-safe-codeblocks.md +1 -0
- package/.agent-src/rules/minimal-safe-diff.md +1 -0
- package/.agent-src/rules/missing-tool-handling.md +1 -0
- package/.agent-src/rules/model-recommendation.md +1 -0
- package/.agent-src/rules/no-cheap-questions.md +15 -21
- package/.agent-src/rules/no-roadmap-references.md +1 -0
- package/.agent-src/rules/non-destructive-by-default.md +1 -0
- package/.agent-src/rules/onboarding-gate.md +33 -0
- package/.agent-src/rules/package-ci-checks.md +1 -0
- package/.agent-src/rules/php-coding.md +1 -0
- package/.agent-src/rules/preservation-guard.md +1 -0
- package/.agent-src/rules/review-routing-awareness.md +1 -0
- package/.agent-src/rules/reviewer-awareness.md +1 -0
- package/.agent-src/rules/roadmap-progress-sync.md +49 -0
- package/.agent-src/rules/role-mode-adherence.md +2 -2
- package/.agent-src/rules/rule-type-governance.md +29 -0
- package/.agent-src/rules/runtime-safety.md +1 -0
- package/.agent-src/rules/scope-control.md +1 -0
- package/.agent-src/rules/security-sensitive-stop.md +1 -0
- package/.agent-src/rules/size-enforcement.md +1 -0
- package/.agent-src/rules/skill-improvement-trigger.md +1 -0
- package/.agent-src/rules/skill-quality.md +1 -0
- package/.agent-src/rules/slash-command-routing-policy.md +39 -0
- package/.agent-src/rules/think-before-action.md +1 -0
- package/.agent-src/rules/token-efficiency.md +1 -0
- package/.agent-src/rules/tool-safety.md +1 -0
- package/.agent-src/rules/ui-audit-gate.md +1 -0
- package/.agent-src/rules/upstream-proposal.md +1 -0
- package/.agent-src/rules/user-interaction.md +1 -0
- package/.agent-src/rules/verify-before-complete.md +1 -0
- package/.agent-src/skills/roadmap-management/SKILL.md +29 -4
- package/.agent-src/skills/verify-completion-evidence/SKILL.md +8 -1
- package/.agent-src/templates/agent-settings.md +16 -0
- package/.agent-src/templates/roadmaps.md +12 -3
- package/.agent-src/templates/scripts/work_engine/hook_bootstrap.py +9 -0
- package/.agent-src/templates/scripts/work_engine/hooks/__init__.py +4 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/__init__.py +4 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.py +163 -0
- package/.agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.py +111 -0
- package/.agent-src/templates/scripts/work_engine/hooks/settings.py +36 -0
- package/.agent-src/templates/scripts/work_engine/scoring/decision_trace.py +141 -0
- package/.agent-src/templates/scripts/work_engine/scoring/memory_visibility.py +125 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +97 -0
- package/README.md +20 -20
- package/config/agent-settings.template.yml +23 -0
- package/docs/architecture.md +1 -1
- package/docs/catalog.md +5 -2
- package/docs/contracts/adr-settings-sync-engine.md +127 -0
- package/docs/contracts/decision-trace-v1.md +146 -0
- package/docs/contracts/file-ownership-matrix.json +7 -0
- package/docs/contracts/hook-architecture-v1.md +213 -0
- package/docs/contracts/load-context-budget-model.md +80 -0
- package/docs/contracts/load-context-schema.md +20 -0
- package/docs/contracts/memory-visibility-v1.md +138 -0
- package/docs/contracts/one-off-script-lifecycle.md +109 -0
- package/docs/contracts/roadmap-complexity-standard.md +137 -0
- package/docs/contracts/rule-interactions.yml +22 -0
- package/docs/customization.md +1 -0
- package/docs/development.md +4 -1
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
- package/docs/guidelines/agent-infra/direct-answers-demos.md +145 -0
- package/docs/guidelines/agent-infra/layered-settings.md +32 -13
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
- package/package.json +1 -1
- package/scripts/agent-config +64 -0
- package/scripts/ai_council/bundler.py +3 -3
- package/scripts/ai_council/clients.py +24 -8
- package/scripts/ai_council/one_off_archive/2026-05/README.md +67 -0
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +206 -0
- package/scripts/ai_council/{_one_off_roundtrip.py → one_off_archive/2026-05/_one_off_roundtrip.py} +13 -8
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +180 -0
- package/scripts/ai_council/session.py +92 -0
- package/scripts/build_rule_trigger_matrix.py +360 -0
- package/scripts/capture_showcase_session.py +361 -0
- package/scripts/chat_history.py +11 -1
- package/scripts/check_always_budget.py +46 -2
- package/scripts/check_one_off_location.py +81 -0
- package/scripts/check_references.py +6 -0
- package/scripts/compress.py +5 -2
- package/scripts/context_hygiene_hook.py +181 -0
- package/scripts/council_cli.py +357 -0
- package/scripts/hook_manifest.yaml +184 -0
- package/scripts/hooks/__init__.py +1 -0
- package/scripts/hooks/augment-context-hygiene.sh +55 -0
- package/scripts/hooks/augment-dispatcher.sh +72 -0
- package/scripts/hooks/augment-onboarding-gate.sh +55 -0
- package/scripts/hooks/cline-dispatcher.sh +86 -0
- package/scripts/hooks/cursor-dispatcher.sh +76 -0
- package/scripts/hooks/dispatch_hook.py +348 -0
- package/scripts/hooks/envelope.py +98 -0
- package/scripts/hooks/gemini-dispatcher.sh +117 -0
- package/scripts/hooks/state_io.py +122 -0
- package/scripts/hooks/windsurf-dispatcher.sh +123 -0
- package/scripts/hooks_status.py +146 -0
- package/scripts/install.py +728 -51
- package/scripts/install.sh +1 -1
- package/scripts/lint_examples.py +98 -0
- package/scripts/lint_hook_manifest.py +216 -0
- package/scripts/lint_one_off_age.py +184 -0
- package/scripts/lint_roadmap_complexity.py +127 -0
- package/scripts/lint_rule_tiers.py +78 -0
- package/scripts/lint_showcase_sessions.py +148 -0
- package/scripts/minimal_safe_diff_hook.py +245 -0
- package/scripts/onboarding_gate_hook.py +142 -0
- package/scripts/readme_linter.py +12 -3
- package/scripts/roadmap_progress_hook.py +5 -0
- package/scripts/schemas/rule.schema.json +5 -0
- package/scripts/sync_agent_settings.py +32 -129
- package/scripts/sync_yaml_rt.py +734 -0
- package/scripts/verify_before_complete_hook.py +216 -0
- /package/scripts/ai_council/{_one_off_2a4_acceptance.py → one_off_archive/2026-05/_one_off_2a4_acceptance.py} +0 -0
- /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
- /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
- /package/scripts/ai_council/{_one_off_followups_review.py → one_off_archive/2026-05/_one_off_followups_review.py} +0 -0
- /package/scripts/ai_council/{_one_off_nondestructive_inline_audit.py → one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py} +0 -0
- /package/scripts/{_one_off_phase4_dispatch_latency.py → ai_council/one_off_archive/2026-05/_one_off_phase4_dispatch_latency.py} +0 -0
- /package/scripts/{_one_off_phase6_trigger_jaccard.py → ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py} +0 -0
- /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
- /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
- /package/scripts/ai_council/{_one_off_rebalancing_audit.py → one_off_archive/2026-05/_one_off_rebalancing_audit.py} +0 -0
- /package/scripts/ai_council/{_one_off_rule_hardening_v1.py → one_off_archive/2026-05/_one_off_rule_hardening_v1.py} +0 -0
- /package/scripts/ai_council/{_one_off_structural_open_questions.py → one_off_archive/2026-05/_one_off_structural_open_questions.py} +0 -0
- /package/scripts/ai_council/{_one_off_structural_optimization.py → one_off_archive/2026-05/_one_off_structural_optimization.py} +0 -0
- /package/scripts/ai_council/{_one_off_structural_v3_gaps.py → one_off_archive/2026-05/_one_off_structural_v3_gaps.py} +0 -0
- /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
|
package/docs/customization.md
CHANGED
|
@@ -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
|
|
package/docs/development.md
CHANGED
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
|
|
18
18
|
## Task Commands
|
|
19
19
|
|
|
20
|
-
All commands use [Task](https://taskfile.dev/).
|
|
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))
|
|
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** →
|
|
162
|
-
|
|
163
|
-
- **
|
|
164
|
-
|
|
165
|
-
|
|
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
|
-
-
|
|
170
|
-
|
|
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
|
-
|
|
175
|
-
|
|
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,
|