@event4u/agent-config 5.0.0 → 5.1.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/contexts/execution/roadmap-process-loop.md +30 -4
- package/.agent-src/rules/linked-projects-onboarding-gate.md +82 -0
- package/.agent-src/rules/roadmap-progress-sync.md +39 -5
- package/.agent-src/scripts/update_roadmap_progress.py +63 -7
- package/.agent-src/skills/roadmap-management/SKILL.md +121 -21
- package/.agent-src/skills/roadmap-writing/SKILL.md +63 -0
- package/.agent-src/templates/agent-settings.md +16 -0
- package/.agent-src/templates/roadmaps.md +22 -1
- package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +20 -3
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +33 -0
- package/README.md +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +33 -11
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +3 -3
- package/dist/discovery/workspaces.json +5 -4
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/router.json +1 -1
- package/docs/architecture.md +1 -1
- package/docs/catalog.md +3 -2
- package/docs/decisions/ADR-032-linked-projects-scope.md +118 -0
- package/docs/decisions/INDEX.md +1 -0
- package/docs/getting-started.md +1 -1
- package/docs/guides/cross-repo-linked-projects.md +86 -0
- package/package.json +1 -1
- package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/scripts/_lib/agent_settings.py +20 -3
- package/scripts/_lib/linked_projects.py +238 -0
- package/scripts/check_no_local_settings_committed.py +51 -0
|
@@ -231,10 +231,36 @@ execution either way.
|
|
|
231
231
|
consultations count (if on), steps remaining, halts.
|
|
232
232
|
- Final dashboard regen.
|
|
233
233
|
- **If the entire roadmap reached `count_open == 0`** → run the full
|
|
234
|
-
project quality pipeline. On
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
project quality pipeline. On red → stop, surface failures, do **not**
|
|
235
|
+
archive. On green → run **deferred-resolution gate** below before
|
|
236
|
+
archival.
|
|
237
|
+
|
|
238
|
+
### 6a. Deferred-resolution gate — Iron Law 3
|
|
239
|
+
|
|
240
|
+
Before any `git mv` to `archive/`, count `[~]` items in closing
|
|
241
|
+
roadmap. If `count_deferred > 0`, archival **blocked** per
|
|
242
|
+
[`roadmap-progress-sync § Iron Law 3`](../../rules/roadmap-progress-sync.md).
|
|
243
|
+
Loop MUST:
|
|
244
|
+
|
|
245
|
+
1. Enumerate every `[~]` step (phase + text + optional
|
|
246
|
+
`<!-- deferred: ... -->` annotation).
|
|
247
|
+
2. Surface numbered-options block from
|
|
248
|
+
[`roadmap-management § 4b`](../../skills/roadmap-management/SKILL.md) —
|
|
249
|
+
five choices: follow-up (draft), follow-up (ready + blocked),
|
|
250
|
+
keep-in-archive (intentional drop), restore to `[ ]`, convert
|
|
251
|
+
to `[-]` cancelled.
|
|
252
|
+
3. Wait for user. Autonomous mandate (`/work`,
|
|
253
|
+
`/roadmap:process-full`, "decide for me") does **not** lift this
|
|
254
|
+
gate — Iron Law 3 calls it "the canonical lost-information failure
|
|
255
|
+
mode this rule exists to prevent."
|
|
256
|
+
4. On picks 1 / 2 → run "Spawn follow-up from deferred items"
|
|
257
|
+
procedure in [`roadmap-management`](../../skills/roadmap-management/SKILL.md).
|
|
258
|
+
On picks 3 / 4 / 5 → apply change, re-evaluate decision table,
|
|
259
|
+
archive when gate clears.
|
|
260
|
+
|
|
261
|
+
`count_deferred == 0` → archive proceeds via
|
|
262
|
+
[`roadmap-management`](../../skills/roadmap-management/SKILL.md) skill
|
|
263
|
+
(`git mv`, regen).
|
|
238
264
|
|
|
239
265
|
## Scope deltas — what each wrapper binds
|
|
240
266
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: "auto"
|
|
3
|
+
tier: "2b"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
description: "IDE-attached sibling repo detected — prompt once to opt it into proactive cross-repo awareness, persist local-only, then surface cross-repo impact on relevant changes"
|
|
6
|
+
source: package
|
|
7
|
+
triggers:
|
|
8
|
+
- intent: "work across two projects"
|
|
9
|
+
- intent: "sibling repository"
|
|
10
|
+
- keyword: "linked project"
|
|
11
|
+
- keyword: "cross-repo"
|
|
12
|
+
- keyword: "sibling repo"
|
|
13
|
+
- path_prefix: ".idea/modules.xml"
|
|
14
|
+
- path_prefix: ".idea/vcs.xml"
|
|
15
|
+
validator_ignore:
|
|
16
|
+
- type: "substring"
|
|
17
|
+
pattern: "scripts/_lib/linked_projects.py"
|
|
18
|
+
reason: "Rule names the detector module as the runtime detection entrypoint."
|
|
19
|
+
workspaces:
|
|
20
|
+
- agent-config-maintainer
|
|
21
|
+
- engineering
|
|
22
|
+
packs:
|
|
23
|
+
- engineering-base
|
|
24
|
+
lifecycle: experimental
|
|
25
|
+
trust:
|
|
26
|
+
level: experimental
|
|
27
|
+
confidence: medium
|
|
28
|
+
human_review_required: false
|
|
29
|
+
install:
|
|
30
|
+
default: true
|
|
31
|
+
removable: true
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
# Linked-Projects Onboarding Gate
|
|
35
|
+
|
|
36
|
+
**Iron Law.** IDE attached a sibling repo and it is not yet in `linked_projects` → prompt developer **once** to opt in, persist local-only, then proactively flag cross-repo impact — never bulk-include the sibling's files.
|
|
37
|
+
|
|
38
|
+
Closes the **proactivity gap**: agent can already read/write a sibling, but does not *consider* one unless told — and the developer who most needs cross-repo awareness won't think to mention the sibling. Detection reads the relationship already encoded by attaching the repo in the IDE (zero-knowledge). See the cross-repo guide (`docs/guides/cross-repo-linked-projects.md`) and ADR-032.
|
|
39
|
+
|
|
40
|
+
## When this fires
|
|
41
|
+
|
|
42
|
+
First substantive turn (and on new IDE attachment), when a detected sibling is absent from `linked_projects` in `.agent-settings.local.yml` (in agents/settings/). Inert when no sibling attached or every detected sibling already decided (opted-in or declined).
|
|
43
|
+
|
|
44
|
+
## Detection
|
|
45
|
+
|
|
46
|
+
Run the detector against project root:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python3 -c "from scripts._lib.linked_projects import detect_linked_projects; \
|
|
50
|
+
import json; print(json.dumps(detect_linked_projects('.')))"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Returns config-attached siblings only (PhpStorm `.idea/modules.xml` + `vcs.xml`, VS Code `*.code-workspace`) resolving outside the project, existing, git repos. A sibling above `linked_projects_max_files` (default 20000) carries `"large": true` — awareness only, never excluded.
|
|
54
|
+
|
|
55
|
+
## Opt-in (one-time per sibling)
|
|
56
|
+
|
|
57
|
+
For each detected sibling **not** already in `linked_projects`, ask once (numbered options per `user-interaction`): include / decline / always / never-ask. Persist to `.agent-settings.local.yml` (in agents/settings/) (gitignored per-machine layer — never committed `.agent-settings.yml`):
|
|
58
|
+
|
|
59
|
+
```yaml
|
|
60
|
+
linked_projects:
|
|
61
|
+
- path: /abs/path/to/sibling
|
|
62
|
+
include: true # false = declined; never re-prompt
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Declined sibling (`include: false`) never prompted again.
|
|
66
|
+
|
|
67
|
+
## Behavioral directive (each `include: true` sibling)
|
|
68
|
+
|
|
69
|
+
- **proactively check cross-repo impact** when a change here may affect it — API-contract changes, shared-type / enum drift, renamed routes the sibling consumes — and **warn** before finishing;
|
|
70
|
+
- **do not bulk-include** the sibling's files (passive awareness, not implicit inclusion — large repos stay cheap);
|
|
71
|
+
- out-of-root edits are normal work, but the host agent's own out-of-root **permission gate still applies** (no silent cross-repo write).
|
|
72
|
+
|
|
73
|
+
## Kill-switch
|
|
74
|
+
|
|
75
|
+
Experimental, removable rule. If opt-in consistently declined or siblings never cited, remove it — no telemetry, signal is local.
|
|
76
|
+
|
|
77
|
+
## Follow-up (not yet shipped)
|
|
78
|
+
|
|
79
|
+
- Consumer-install detector reachability: detector lives in `scripts/_lib/`; exposing it as an `agent-config` CLI subcommand for consumers is a follow-up. Import-reachable in this repo / co-located maintainer setups today.
|
|
80
|
+
- Multi-agent verification: only Claude Code empirically validated (ADR-032). Cursor / Augment / Copilot unverified — manual fallback in the guide covers them until tested.
|
|
81
|
+
|
|
82
|
+
Trigger-set above activates this routing under the `balanced` and `full` profiles.
|
|
@@ -48,11 +48,42 @@ IS A RULE VIOLATION, NOT AN OVERSIGHT.
|
|
|
48
48
|
|
|
49
49
|
`command:` triggers in this rule's frontmatter load it the moment any `/roadmap:process-*` command fires and keep it loaded for the whole run — independent of whether the agent is editing files under `agents/roadmaps/`. The loop carries its own deterministic flip-guard at [`roadmap-process-loop § 5b`](../contexts/execution/roadmap-process-loop.md#5b-flip-guard--deterministic) — defense-in-depth, not a substitute for the inline flip.
|
|
50
50
|
|
|
51
|
-
**Step counts as done** when
|
|
51
|
+
**Step counts as done** when code/doc saved AND verification cited in step passed (fresh output, this reply or earlier).
|
|
52
52
|
|
|
53
|
-
**
|
|
53
|
+
**Glyph semantics** — single source of truth, aligned with `scripts/update_roadmap_progress.py` and [`roadmap-management`](../skills/roadmap-management/SKILL.md):
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
| Glyph | Meaning | Counter |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| `[ ]` | open — planned, not done | `count_open` |
|
|
58
|
+
| `[x]` | done — landed + verified | `count_done` |
|
|
59
|
+
| `[~]` | deferred — planned, not happening **this** run; blocks archive (Iron Law 3) | `count_deferred` |
|
|
60
|
+
| `[-]` | cancelled — scope dropped | `count_cancelled` |
|
|
61
|
+
|
|
62
|
+
`[~]` is **not** "in-progress". Mid-reply work-in-flight has no checkbox change until step lands — normal `[ ] → [x]`.
|
|
63
|
+
|
|
64
|
+
**Dashboard regen cadence — opt-in batching.** Checkbox flip is non-batchable. **Subprocess regen** (`./agent-config roadmap:progress`) is batchable per `roadmap.dashboard_regen_cadence` (`per_step` default · `every_5_steps` · `phase_boundary`). Run end, phase boundary, any file-shape touch (rename / phase add / archive — Iron Law 1) always force immediate regen regardless of cadence.
|
|
65
|
+
|
|
66
|
+
## Iron Law 3 — no silent archive with unresolved deferred items
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
A ROADMAP WITH `[~]` DEFERRED ITEMS NEVER AUTO-ARCHIVES SILENTLY.
|
|
70
|
+
SURFACE EVERY DEFERRED STEP. ASK USER WHAT HAPPENS TO THE PLAN.
|
|
71
|
+
A SILENT ARCHIVE THAT BURIES PLANNED-FOR-LATER WORK
|
|
72
|
+
IS A RULE VIOLATION, NOT A CONVENIENCE.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
When closure check fires (`count_open == 0` and `count_deferred > 0`), agent MUST:
|
|
76
|
+
|
|
77
|
+
1. Enumerate every `[~]` step (phase + step text + any inline `<!-- deferred: ... -->` annotation).
|
|
78
|
+
2. Present numbered options (per [`user-interaction`](user-interaction.md)) — at minimum:
|
|
79
|
+
1. **Follow-up roadmap (draft)** — spawn `agents/roadmaps/road-to-<slug>.md` with `status: draft`, `parent_roadmap: <this-slug>`, deferred steps lifted verbatim into phases. Draft hidden from dashboard until flipped to `ready`.
|
|
80
|
+
2. **Follow-up roadmap (ready, blocked)** — spawn with `status: ready` (default), `parent_roadmap: <this-slug>`, plus body note `> Blocked until <condition>`. Dashboard surfaces it; execution waits.
|
|
81
|
+
3. **Keep in this archive** — confirm deferred items stay searchable in archived file; no follow-up. Records explicit decision-to-drop in same reply.
|
|
82
|
+
4. **Restore selected items to `[ ]`** — finish them in this roadmap before archive.
|
|
83
|
+
5. **Convert selected items to `[-]` cancelled** — drop with rationale recorded inline.
|
|
84
|
+
3. Only after user resolves deferrals does `git mv` to `archive/` run. Dashboard regen happens after resolution.
|
|
85
|
+
|
|
86
|
+
Migration mechanics (file naming, frontmatter, body shape, parent back-link) live in [`roadmap-management § Spawn follow-up from deferred items`](../skills/roadmap-management/SKILL.md). Rule owns obligation; skill owns procedure.
|
|
56
87
|
|
|
57
88
|
## Pre-send self-check — MANDATORY
|
|
58
89
|
|
|
@@ -66,9 +97,12 @@ Before sending any reply that landed roadmap work:
|
|
|
66
97
|
- `phase_boundary` → only when this reply closes the phase or run.
|
|
67
98
|
- Any file-shape touch (rename / phase add / archive) → yes, regardless of cadence.
|
|
68
99
|
If yes and not run yet → run `./agent-config roadmap:progress`, then continue.
|
|
69
|
-
4. Did `count_open` reach 0?
|
|
100
|
+
4. Did `count_open` reach 0?
|
|
101
|
+
- **No** → continue normally.
|
|
102
|
+
- **Yes + `count_deferred == 0`** → `git mv` to `archive/` and regen again — same reply.
|
|
103
|
+
- **Yes + `count_deferred > 0`** → STOP. Run Iron Law 3 deferred-resolution flow (surface items + numbered options + wait). Archive only after resolution.
|
|
70
104
|
|
|
71
|
-
Any "no" at step 2 → reply is incomplete. Do not send.
|
|
105
|
+
Any "no" at step 2 → reply is incomplete. Do not send. Skipped step 3 regen fine when cadence permits — checkbox truth lives in markdown file. Skipping deferred-resolution gate at step 4 is **never** acceptable; it is the canonical "lost-information" failure mode this rule exists to prevent.
|
|
72
106
|
|
|
73
107
|
Long-form mechanics (failure-mode catalog, Copilot fallback, `[~]` vs `[ ]` semantics, hook + CI defence-in-depth) live in `guideline:agent-infra/roadmap-progress-mechanics`.
|
|
74
108
|
Trigger-set above activates this routing under the `balanced` and `full` profiles.
|
|
@@ -16,6 +16,13 @@ Checkbox states:
|
|
|
16
16
|
Percentage = done / (done + open). Deferred and cancelled do not count towards
|
|
17
17
|
"open" (they are explicit decisions).
|
|
18
18
|
|
|
19
|
+
`[~]` deferred items carry plans the user intends to revisit later. They
|
|
20
|
+
block silent auto-archive per `roadmap-progress-sync` Iron Law 3: a
|
|
21
|
+
roadmap with `count_open == 0` and `count_deferred > 0` is reported
|
|
22
|
+
separately (`pending_iron_law_3`) and the user must resolve the
|
|
23
|
+
deferrals (spawn follow-up roadmap, restore, or convert to cancelled)
|
|
24
|
+
before the file moves to `archive/`.
|
|
25
|
+
|
|
19
26
|
Roadmap visibility is binary:
|
|
20
27
|
|
|
21
28
|
- No `status:` frontmatter (or `status: ready`) → executable, listed.
|
|
@@ -245,18 +252,38 @@ def collect(roadmap_root: Path) -> list[RoadmapStats]:
|
|
|
245
252
|
|
|
246
253
|
|
|
247
254
|
def unarchived_complete(roadmaps: list[RoadmapStats]) -> list[RoadmapStats]:
|
|
248
|
-
# A roadmap is complete when every active checkbox is done
|
|
249
|
-
# one active checkbox exists
|
|
250
|
-
#
|
|
251
|
-
#
|
|
252
|
-
#
|
|
253
|
-
|
|
255
|
+
# A roadmap is complete-and-clean when every active checkbox is done,
|
|
256
|
+
# at least one active checkbox exists, AND no `[~]` deferred items
|
|
257
|
+
# remain. The `roadmap-progress-sync` rule mandates that such a
|
|
258
|
+
# roadmap be moved to `agents/roadmaps/archive/` in the same response
|
|
259
|
+
# that closes its last open item; `collect()` already excludes that
|
|
260
|
+
# directory, so anything left here is unarchived.
|
|
261
|
+
#
|
|
262
|
+
# Deferred items are intentionally excluded — they block silent
|
|
263
|
+
# archive per Iron Law 3 (see `pending_iron_law_3` below).
|
|
264
|
+
return [
|
|
265
|
+
r for r in roadmaps
|
|
266
|
+
if r.total_active > 0 and r.open_ == 0 and r.deferred == 0
|
|
267
|
+
]
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def pending_iron_law_3(roadmaps: list[RoadmapStats]) -> list[RoadmapStats]:
|
|
271
|
+
# Roadmaps with no open work but unresolved `[~]` deferred items.
|
|
272
|
+
# Per `roadmap-progress-sync` Iron Law 3 the agent must NOT auto-
|
|
273
|
+
# archive these — surface the deferred items and ask the user
|
|
274
|
+
# (spawn follow-up, restore, or convert). The dashboard merely
|
|
275
|
+
# reports the state; the obligation lives in the rule.
|
|
276
|
+
return [
|
|
277
|
+
r for r in roadmaps
|
|
278
|
+
if r.total_active > 0 and r.open_ == 0 and r.deferred > 0
|
|
279
|
+
]
|
|
254
280
|
|
|
255
281
|
|
|
256
282
|
def render(roadmaps: list[RoadmapStats]) -> str:
|
|
257
283
|
total_done = sum(r.done for r in roadmaps)
|
|
258
284
|
total_active = sum(r.total_active for r in roadmaps)
|
|
259
285
|
overall_pct = round(total_done * 100 / total_active) if total_active else 0
|
|
286
|
+
pending = pending_iron_law_3(roadmaps)
|
|
260
287
|
lines: list[str] = []
|
|
261
288
|
lines.append("# Roadmap Progress\n")
|
|
262
289
|
header_meta = (
|
|
@@ -274,6 +301,21 @@ def render(roadmaps: list[RoadmapStats]) -> str:
|
|
|
274
301
|
lines.append("## Overall\n")
|
|
275
302
|
lines.append(f"**{total_done} / {total_active} steps done · {overall_pct}%**\n")
|
|
276
303
|
lines.append("```text\n" + bar(overall_pct, 40) + f" {overall_pct}%\n```\n")
|
|
304
|
+
if pending:
|
|
305
|
+
lines.append("## ⚠️ Iron Law 3 — unresolved deferred items\n")
|
|
306
|
+
lines.append(
|
|
307
|
+
"These roadmaps have `count_open == 0` but carry `[~]` deferred "
|
|
308
|
+
"items. Per `roadmap-progress-sync` Iron Law 3 they do NOT "
|
|
309
|
+
"auto-archive — the user must resolve the deferrals first "
|
|
310
|
+
"(spawn follow-up, restore, or cancel). See "
|
|
311
|
+
"[`roadmap-management § 4b`](../packages/core/.agent-src.uncondensed/skills/roadmap-management/SKILL.md).\n"
|
|
312
|
+
)
|
|
313
|
+
lines.append("| Roadmap | Done | Deferred | Cancelled |")
|
|
314
|
+
lines.append("|---|---:|---:|---:|")
|
|
315
|
+
for r in pending:
|
|
316
|
+
lines.append(f"| [{r.rel}](roadmaps/{r.rel}) | {r.done} | "
|
|
317
|
+
f"{r.deferred} | {r.cancelled} |")
|
|
318
|
+
lines.append("")
|
|
277
319
|
if not roadmaps:
|
|
278
320
|
lines.append("_No open roadmaps._\n")
|
|
279
321
|
return "\n".join(lines) + "\n"
|
|
@@ -326,6 +368,7 @@ def main() -> int:
|
|
|
326
368
|
new_text = render(roadmaps)
|
|
327
369
|
current = target.read_text(encoding="utf-8") if target.exists() else ""
|
|
328
370
|
complete = unarchived_complete(roadmaps)
|
|
371
|
+
pending = pending_iron_law_3(roadmaps)
|
|
329
372
|
if args.check:
|
|
330
373
|
stale = current != new_text
|
|
331
374
|
if stale:
|
|
@@ -340,7 +383,14 @@ def main() -> int:
|
|
|
340
383
|
for r in complete:
|
|
341
384
|
print(f" - {r.rel} ({r.done}/{r.total_active} done)",
|
|
342
385
|
file=sys.stderr)
|
|
343
|
-
if
|
|
386
|
+
if pending:
|
|
387
|
+
print("❌ Iron Law 3 — roadmaps with unresolved `[~]` deferred "
|
|
388
|
+
"items must NOT auto-archive. Resolve via `roadmap-management § 4b` "
|
|
389
|
+
"(spawn follow-up, restore, or cancel):", file=sys.stderr)
|
|
390
|
+
for r in pending:
|
|
391
|
+
print(f" - {r.rel} ({r.done}/{r.total_active} done · "
|
|
392
|
+
f"{r.deferred} deferred)", file=sys.stderr)
|
|
393
|
+
if stale or complete or pending:
|
|
344
394
|
return 1
|
|
345
395
|
print(f"✅ {target.relative_to(args.repo_root)} is up to date.")
|
|
346
396
|
return 0
|
|
@@ -353,6 +403,12 @@ def main() -> int:
|
|
|
353
403
|
"`agents/roadmaps/archive/`:", file=sys.stderr)
|
|
354
404
|
for r in complete:
|
|
355
405
|
print(f" - {r.rel}", file=sys.stderr)
|
|
406
|
+
if pending:
|
|
407
|
+
print("⚠️ Iron Law 3 — roadmaps with unresolved `[~]` deferred items. "
|
|
408
|
+
"Surface them and ask the user (`roadmap-management § 4b`) "
|
|
409
|
+
"before any archive:", file=sys.stderr)
|
|
410
|
+
for r in pending:
|
|
411
|
+
print(f" - {r.rel} ({r.deferred} deferred)", file=sys.stderr)
|
|
356
412
|
return 0
|
|
357
413
|
|
|
358
414
|
|
|
@@ -238,45 +238,145 @@ After the last step of a roadmap is done, check completion status:
|
|
|
238
238
|
- `[-]` = cancelled (individual item dropped)
|
|
239
239
|
|
|
240
240
|
3. **Decision rule — `count_open == 0` means the roadmap has no active
|
|
241
|
-
work left. `[x]`, `[
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
| ≥ 1 | 0 |
|
|
249
|
-
| 0 | 0 | ≥ 1 | **Auto-
|
|
250
|
-
| ≥ 0 | ≥ 1 | ≥ 0 | **
|
|
241
|
+
work left. `[x]`, `[-]` are final states. `[~]` deferred items
|
|
242
|
+
block silent closure — they carry plans user has not consented to drop
|
|
243
|
+
(enforced by [`roadmap-progress-sync`](../../rules/roadmap-progress-sync.md)
|
|
244
|
+
Iron Law 3).**
|
|
245
|
+
|
|
246
|
+
| count_x | count_open | count_deferred | count_cancelled | Action |
|
|
247
|
+
|---|---|---|---|---|
|
|
248
|
+
| ≥ 1 | 0 | 0 | 0 | **Auto-archive** (silent) — pure completion |
|
|
249
|
+
| ≥ 1 | 0 | 0 | ≥ 1 | **Auto-archive** (silent) — done with explicit drops |
|
|
250
|
+
| ≥ 1 | 0 | ≥ 1 | ≥ 0 | **STOP — Iron Law 3 flow.** Surface deferred items, present follow-up options, wait. Step 4b. |
|
|
251
|
+
| 0 | 0 | ≥ 1 | ≥ 0 | **STOP — Iron Law 3 flow.** Scope-drop or deferred-to-later? Same options as 4b. |
|
|
252
|
+
| 0 | 0 | 0 | ≥ 1 | **Auto-skip** (silent) — no work, all cancelled |
|
|
253
|
+
| ≥ 0 | ≥ 1 | ≥ 0 | ≥ 0 | **Ask the user** — open work remains (step 4a) |
|
|
251
254
|
|
|
252
255
|
Show on auto-move:
|
|
253
256
|
|
|
254
257
|
- Archive: `✅ Roadmap archived → agents/roadmaps/archive/{filename}`
|
|
255
258
|
- Skip: `⏭️ Roadmap skipped → agents/roadmaps/skipped/{filename}`
|
|
256
259
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
+
`[-]` cancelled items remain searchable in archived file — they were
|
|
261
|
+
explicit drops. `[~]` deferred items, by contrast, may not silently
|
|
262
|
+
follow file into archive: they represent work user planned and would
|
|
263
|
+
lose track of. Step 4b is the gate.
|
|
260
264
|
|
|
261
|
-
|
|
265
|
+
4a. **Open items remain (`count_open ≥ 1`)** → **Ask the user.** Show what's incomplete:
|
|
262
266
|
|
|
263
267
|
```
|
|
264
268
|
📋 Roadmap completion check:
|
|
265
269
|
|
|
266
270
|
✅ Completed: {count_x}
|
|
267
271
|
⬜ Open: {count_open} — {list of open items, 1 line each}
|
|
268
|
-
⏭️ Deferred: {
|
|
269
|
-
❌ Cancelled: {
|
|
272
|
+
⏭️ Deferred: {count_deferred} — {list of deferred items, 1 line each}
|
|
273
|
+
❌ Cancelled: {count_cancelled} — {list of cancelled items, 1 line each}
|
|
270
274
|
|
|
271
275
|
> 1. Archive — mark open items as cancelled [-] and archive now
|
|
272
276
|
> 2. Keep active — I want to finish the open items
|
|
273
|
-
> 3. Mark open items as deferred [~] and archive
|
|
277
|
+
> 3. Mark open items as deferred [~] and archive (triggers Iron Law 3 flow)
|
|
274
278
|
> 4. Skip — move to skipped/ (no meaningful work done, not pursuing)
|
|
275
279
|
```
|
|
276
280
|
|
|
277
|
-
Option 4
|
|
278
|
-
trivial (e.g. prerequisites
|
|
279
|
-
|
|
281
|
+
Option 4 only appropriate when `count_x == 0` or completed items were
|
|
282
|
+
trivial (e.g. prerequisites). If user picks 4 despite meaningful work
|
|
283
|
+
done, confirm once — archive usually right. Picking option 3 does
|
|
284
|
+
NOT archive immediately — converts open → deferred, re-enters the
|
|
285
|
+
`count_deferred > 0` branch, which runs step 4b.
|
|
286
|
+
|
|
287
|
+
4b. **Deferred items present (`count_deferred ≥ 1`, `count_open == 0`)** — Iron Law 3 flow.
|
|
288
|
+
Archive **blocked** until user resolves deferrals. Surface plan and ask:
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
📋 Roadmap closure check — deferred items must resolve before archive:
|
|
292
|
+
|
|
293
|
+
✅ Completed: {count_x}
|
|
294
|
+
⏭️ Deferred: {count_deferred}
|
|
295
|
+
{for each deferred item:}
|
|
296
|
+
- Phase {N}: {step text} {<!-- deferred: <annotation> --> if present}
|
|
297
|
+
|
|
298
|
+
These items carry plans you would lose to a silent archive.
|
|
299
|
+
|
|
300
|
+
> 1. Spawn follow-up roadmap as DRAFT
|
|
301
|
+
> → agents/roadmaps/road-to-{auto-slug}.md, status: draft,
|
|
302
|
+
> parent_roadmap: {this-slug}. Hidden from dashboard until you
|
|
303
|
+
> flip status to "ready".
|
|
304
|
+
> 2. Spawn follow-up roadmap as READY (with blocked-until note)
|
|
305
|
+
> → status: ready (default), parent_roadmap: {this-slug}, plus
|
|
306
|
+
> `> Blocked until <condition>` line in body. Visible in
|
|
307
|
+
> dashboard; execution waits on condition.
|
|
308
|
+
> 3. Keep deferred items in this archive — confirm "no follow-up"
|
|
309
|
+
> intentional drop. Items stay searchable in archive/.
|
|
310
|
+
> 4. Restore selected items to [ ] — finish them here before archive.
|
|
311
|
+
> 5. Convert selected items to [-] cancelled — drop with rationale.
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
Picks 1 or 2 → see "Spawn follow-up from deferred items" below.
|
|
315
|
+
Picks 3, 4, or 5 → apply the change in this roadmap; re-evaluate
|
|
316
|
+
the decision table; archive when gate clears.
|
|
317
|
+
|
|
318
|
+
### Spawn follow-up from deferred items (procedure)
|
|
319
|
+
|
|
320
|
+
When user picks option 1 or 2 in step 4b:
|
|
321
|
+
|
|
322
|
+
1. **Derive slug.** Default `<parent-slug>-followup` (e.g. `road-to-x.md`
|
|
323
|
+
→ `road-to-x-followup.md`). User-supplied slug in picker → use that.
|
|
324
|
+
Avoid collisions with `agents/roadmaps/` (active + `archive/` + `skipped/`).
|
|
325
|
+
|
|
326
|
+
2. **Write new file** at `agents/roadmaps/<slug>.md`:
|
|
327
|
+
|
|
328
|
+
```markdown
|
|
329
|
+
---
|
|
330
|
+
complexity: lightweight # bump if parent was structural
|
|
331
|
+
status: draft # option 1; omit for option 2 (= ready)
|
|
332
|
+
parent_roadmap: <parent-slug> # back-link to source
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
# Roadmap: Follow-up to <parent-title>
|
|
336
|
+
|
|
337
|
+
> <One sentence stating carried-over outcome.>
|
|
338
|
+
|
|
339
|
+
## Context
|
|
340
|
+
|
|
341
|
+
This roadmap collects items deferred from
|
|
342
|
+
[`agents/roadmaps/archive/<parent-slug>.md`](archive/<parent-slug>.md).
|
|
343
|
+
See parent's archive entry for original rationale.
|
|
344
|
+
|
|
345
|
+
## Prerequisites
|
|
346
|
+
|
|
347
|
+
- [ ] Read `AGENTS.md` and parent archive entry.
|
|
348
|
+
{parent prerequisites still relevant, copied verbatim}
|
|
349
|
+
|
|
350
|
+
<!-- Option 2 only — body note, NOT a frontmatter key: -->
|
|
351
|
+
> Blocked until <condition>. Execution starts when condition clears.
|
|
352
|
+
|
|
353
|
+
## Phase 1: <name carried from parent>
|
|
354
|
+
|
|
355
|
+
- [ ] {deferred step text, copied verbatim with parent-phase pointer}
|
|
356
|
+
{repeat per deferred item, regrouped by parent phase}
|
|
357
|
+
|
|
358
|
+
## Acceptance Criteria
|
|
359
|
+
|
|
360
|
+
- [ ] {restate or adjust per deferred scope}
|
|
361
|
+
- [ ] All quality gates pass — see `quality-tools`.
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
3. **In parent roadmap** (still in working tree), append a line at
|
|
365
|
+
bottom (above any final `---`):
|
|
366
|
+
|
|
367
|
+
```
|
|
368
|
+
<!-- Deferred items migrated to agents/roadmaps/<followup-slug>.md on YYYY-MM-DD -->
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Do **not** delete `[~]` lines — keep visible in archived parent so
|
|
372
|
+
trail stays grep-able. Follow-up carries forward executable copy.
|
|
373
|
+
|
|
374
|
+
4. **Regenerate dashboard.** Follow-up appears (draft hidden, ready
|
|
375
|
+
visible) and parent — once moved — drops off.
|
|
376
|
+
|
|
377
|
+
5. **Archive parent** (`git mv` → `archive/`) and regen one more time
|
|
378
|
+
per [`roadmap-progress-sync`](../../rules/roadmap-progress-sync.md)
|
|
379
|
+
Iron Laws 1 + 3.
|
|
280
380
|
|
|
281
381
|
5. **Move the file** with `git mv` so history is preserved:
|
|
282
382
|
|
|
@@ -351,7 +451,7 @@ The dashboard is a **read-only snapshot**. Do not edit it by hand — regenerate
|
|
|
351
451
|
- Roadmap files go in `agents/roadmaps/` — don't create them in other directories.
|
|
352
452
|
- Don't mark phases complete without running verification (tests, quality checks) — the verify-before-complete rule applies.
|
|
353
453
|
- The model tends to skip phases it deems "simple" — every phase must be explicitly completed.
|
|
354
|
-
- Auto-archive
|
|
454
|
+
- Auto-archive is allowed when `count_open == 0` AND `count_deferred == 0`. `[-]` cancelled items archive silently (explicit drops). `[~]` deferred items **block** silent archive — they trigger the Iron Law 3 flow (see step 4b).
|
|
355
455
|
- `archive/` and `skipped/` are distinct — `archive/` = work happened, `skipped/` = no meaningful work, not pursuing. Create either directory if it doesn't exist.
|
|
356
456
|
- Use `git mv` (not `mv`) so history follows the file.
|
|
357
457
|
|
|
@@ -99,6 +99,69 @@ phase is done) and **rollback** (what to revert if the phase fails).
|
|
|
99
99
|
A phase without exit criteria is open-ended; a phase without
|
|
100
100
|
rollback assumes success.
|
|
101
101
|
|
|
102
|
+
### 6. Step-marker semantics — pick `[~]` (defer) vs `[-]` (cancel) honestly
|
|
103
|
+
|
|
104
|
+
Difference carries load when authoring (and especially when rewriting
|
|
105
|
+
mid-flight):
|
|
106
|
+
|
|
107
|
+
| Glyph | Semantic | When to use |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `[~]` | **deferred** — planned, will be done, just not in this roadmap | Scope-cut + clear intent to revisit. Triggers Iron Law 3 follow-up flow before archive — info preservation enforced. |
|
|
110
|
+
| `[-]` | **cancelled** — won't be done at all | Scope rejected, design changed, replaced by another roadmap. Decision final; no follow-up implied. |
|
|
111
|
+
|
|
112
|
+
Optional inline annotations on same line:
|
|
113
|
+
|
|
114
|
+
```markdown
|
|
115
|
+
- [~] Migrate bulk-import job to chunked dispatch. <!-- deferred: ops capacity in Q3 -->
|
|
116
|
+
- [-] Wire SQS retry topic. <!-- cancelled: superseded by Lambda DLQ in road-to-event-bridge -->
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Annotation for next human reader (and for migration procedure when
|
|
120
|
+
[`roadmap-management`](../roadmap-management/SKILL.md) spawns a follow-up).
|
|
121
|
+
Bare `[~]` / `[-]` allowed; annotated preferred.
|
|
122
|
+
|
|
123
|
+
### 7. Follow-up roadmaps spawn from deferred items — frontmatter shape
|
|
124
|
+
|
|
125
|
+
When parent roadmap closes with `[~]` items,
|
|
126
|
+
[`roadmap-management`](../roadmap-management/SKILL.md) skill spawns a
|
|
127
|
+
follow-up. Authors and reviewers must recognise the shape:
|
|
128
|
+
|
|
129
|
+
```markdown
|
|
130
|
+
---
|
|
131
|
+
complexity: lightweight
|
|
132
|
+
status: draft # optional — draft hides from dashboard
|
|
133
|
+
parent_roadmap: <parent-slug> # back-link to archived source
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
# Roadmap: Follow-up to <parent-title>
|
|
137
|
+
|
|
138
|
+
> <One sentence: carried-over outcome.>
|
|
139
|
+
|
|
140
|
+
## Context
|
|
141
|
+
|
|
142
|
+
This roadmap collects items deferred from
|
|
143
|
+
[`agents/roadmaps/archive/<parent-slug>.md`](../archive/<parent-slug>.md).
|
|
144
|
+
{ … original phases preserved verbatim … }
|
|
145
|
+
|
|
146
|
+
<!-- For option 2 (ready + blocked), add as body note, NOT in frontmatter: -->
|
|
147
|
+
> Blocked until <condition>. Execution starts when condition clears.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Two states author picks between (mirrors Iron Law 3 numbered-options
|
|
151
|
+
block in [`roadmap-progress-sync`](../../rules/roadmap-progress-sync.md)):
|
|
152
|
+
|
|
153
|
+
- **`status: draft`** → hidden from `agents/roadmaps-progress.md` until
|
|
154
|
+
flipped. Use for items user wants captured but not surfaced to
|
|
155
|
+
active backlog yet.
|
|
156
|
+
- **`status: ready` (default; omit key)** plus body `> Blocked until …`
|
|
157
|
+
note → visible in dashboard, execution gated by documented
|
|
158
|
+
condition. Blocking is body convention, not enforced by dashboard
|
|
159
|
+
generator — readers honor the note.
|
|
160
|
+
|
|
161
|
+
Follow-up is **not** authored from scratch — deferred steps copied
|
|
162
|
+
verbatim (with phase context). Preserves plan exactly as author
|
|
163
|
+
originally wrote it.
|
|
164
|
+
|
|
102
165
|
## Output format
|
|
103
166
|
|
|
104
167
|
A single Markdown file at `agents/roadmaps/{name}.md`:
|
|
@@ -430,6 +430,20 @@ telemetry:
|
|
|
430
430
|
# Append-only JSONL log. Path is relative to the project root.
|
|
431
431
|
# Always gitignored (see config/gitignore-block.txt).
|
|
432
432
|
path: .agent-engagement.jsonl
|
|
433
|
+
|
|
434
|
+
# --- Linked projects (cross-repo awareness, local-only) ---
|
|
435
|
+
# IDE-attached sibling repos in scope for proactive cross-repo awareness.
|
|
436
|
+
# BELONGS IN `.agent-settings.local.yml` (in agents/settings/) (per-machine, gitignored) — sibling
|
|
437
|
+
# paths differ per developer, never commit them. Each entry: path (absolute,
|
|
438
|
+
# auto-filled by detection) + include (true = in scope, false = declined,
|
|
439
|
+
# never re-prompted). Detection skips bloat dirs; a sibling over max_files is
|
|
440
|
+
# flagged `large` (awareness only), never excluded. See ADR-032 +
|
|
441
|
+
# docs/guides/cross-repo-linked-projects.md. Agent never bulk-includes sibling
|
|
442
|
+
# files — passive awareness only.
|
|
443
|
+
linked_projects: []
|
|
444
|
+
# - path: /abs/path/to/sibling-repo
|
|
445
|
+
# include: true
|
|
446
|
+
linked_projects_max_files: 20000 # ceiling for the `large` flag; never excludes
|
|
433
447
|
```
|
|
434
448
|
|
|
435
449
|
## Settings Reference
|
|
@@ -503,6 +517,8 @@ the canonical narrative lives in
|
|
|
503
517
|
| `telemetry.artifact_engagement.record.consulted` | `true`, `false` | `true` | When `true`: record artefacts loaded into context. |
|
|
504
518
|
| `telemetry.artifact_engagement.record.applied` | `true`, `false` | `true` | When `true`: record artefacts cited or driving a decision. |
|
|
505
519
|
| `telemetry.artifact_engagement.output.path` | path | `.agent-engagement.jsonl` | Append-only JSONL log path, relative to the project root. Always gitignored. |
|
|
520
|
+
| `linked_projects` | list of `{path, include}` | `[]` | IDE-attached sibling repos in scope for proactive cross-repo awareness. **Belongs in `.agent-settings.local.yml` (in agents/settings/)** (per-machine, gitignored). See [cross-repo guide](../../docs/guides/cross-repo-linked-projects.md) + ADR-032. |
|
|
521
|
+
| `linked_projects_max_files` | integer | `20000` | File-count ceiling above which a detected sibling is flagged `large` (awareness only). Never excludes. |
|
|
506
522
|
|
|
507
523
|
### Rename-Map (migration)
|
|
508
524
|
|
|
@@ -8,7 +8,8 @@ Templates for roadmap files stored in `agents/roadmaps/` or `{module_root}/{Modu
|
|
|
8
8
|
|
|
9
9
|
1. **Be precise and concise.** Aim for 500–1000 lines max. If larger, split into multiple files.
|
|
10
10
|
2. **Checkboxes are mandatory, not decorative.** Every active roadmap MUST contain at least one `- [ ]` per non-intro phase. Decision tables, ICE matrices, and block-sequencing tables capture the *why*; checkboxes capture the *what to do next*. A roadmap without checkboxes is invisible to `agents/roadmaps-progress.md` — the dashboard cannot count it, the next reader thinks no work is planned. Enforced by [`roadmap-progress-sync`](../rules/roadmap-progress-sync.md) Iron Law #2.
|
|
11
|
-
- **
|
|
11
|
+
- **Glyph semantics:** `[ ]` open · `[x]` done · `[~]` **deferred** (planned for later — blocks silent archive per `roadmap-progress-sync` Iron Law 3) · `[-]` **cancelled** (won't do — explicit drop). Pick `[~]` vs `[-]` honestly; former carries follow-up-roadmap obligations, latter does not. Optional inline annotations: `<!-- deferred: reason -->` / `<!-- cancelled: reason -->` on same line.
|
|
12
|
+
- **Status is binary: `ready` (default) or `draft`.** New roadmaps are created **ready** unless the user explicitly says draft — `ready` is implicit and need not be written. Drafts declare it via frontmatter at the top of the file (`---\nstatus: draft\n---`) and are hidden from the dashboard until the flag is removed or flipped to `ready`. Use `draft` while the roadmap is still being authored, while waiting for upstream decisions, as a capture-only synthesis that has not been promoted to executable phases, or as a follow-up roadmap (see rule 17 below) that is not yet ready to surface. There are no other status values; legacy banners like `**Status: directional**` are removed.
|
|
12
13
|
3. **State the goal first.** One sentence at the top — what is the outcome?
|
|
13
14
|
4. **List prerequisites** — what must exist or be running before starting.
|
|
14
15
|
5. **Reference existing code** — point to files, classes, or modules.
|
|
@@ -57,6 +58,26 @@ Templates for roadmap files stored in `agents/roadmaps/` or `{module_root}/{Modu
|
|
|
57
58
|
`horizon_weeks` to a positive integer. Enforced by
|
|
58
59
|
`task lint-roadmap-complexity` (plate-token detection skipped when
|
|
59
60
|
`horizon_weeks > 0`).
|
|
61
|
+
17. **Follow-up roadmaps from deferred items carry `parent_roadmap`.**
|
|
62
|
+
When a roadmap closes with `[~]` deferred items,
|
|
63
|
+
[`roadmap-management`](../skills/roadmap-management/SKILL.md) skill
|
|
64
|
+
spawns a follow-up under `agents/roadmaps/road-to-<parent>-followup.md`.
|
|
65
|
+
Follow-up's frontmatter declares back-link:
|
|
66
|
+
```yaml
|
|
67
|
+
---
|
|
68
|
+
complexity: lightweight
|
|
69
|
+
status: draft # optional — hides from dashboard
|
|
70
|
+
parent_roadmap: <parent-slug>
|
|
71
|
+
---
|
|
72
|
+
```
|
|
73
|
+
Follow-up's body opens with `## Context` block citing
|
|
74
|
+
`agents/roadmaps/archive/<parent>.md`. Deferred steps copied
|
|
75
|
+
**verbatim** (with original phase context) so plan survives
|
|
76
|
+
migration. If follow-up is "ready but blocked" rather than draft,
|
|
77
|
+
omit `status:` and add body note `> Blocked until <condition>` —
|
|
78
|
+
dashboard surfaces roadmap, readers honor body convention.
|
|
79
|
+
Authoring contract: [`roadmap-writing § 7`](../skills/roadmap-writing/SKILL.md);
|
|
80
|
+
spawn procedure: [`roadmap-management § Spawn follow-up`](../skills/roadmap-management/SKILL.md).
|
|
60
81
|
|
|
61
82
|
---
|
|
62
83
|
|