@event4u/agent-config 1.34.0 → 1.36.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 (47) hide show
  1. package/.agent-src/commands/memory/load.md +69 -0
  2. package/.agent-src/commands/memory/mine-session.md +151 -0
  3. package/.agent-src/commands/memory/promote.md +35 -0
  4. package/.agent-src/commands/memory/propose.md +10 -1
  5. package/.agent-src/commands/memory.md +5 -3
  6. package/.agent-src/commands/roadmap/process-full.md +20 -15
  7. package/.agent-src/contexts/authority/scope-mechanics.md +36 -0
  8. package/.agent-src/contexts/execution/autonomy-detection.md +7 -7
  9. package/.agent-src/contexts/execution/roadmap-process-loop.md +16 -10
  10. package/.agent-src/personas/discovery-lead.md +99 -0
  11. package/.agent-src/personas/product-owner.md +71 -52
  12. package/.agent-src/personas/revops-maintainer.md +100 -0
  13. package/.agent-src/personas/tech-writer.md +99 -0
  14. package/.agent-src/rules/autonomous-execution.md +25 -0
  15. package/.agent-src/rules/scope-control.md +12 -5
  16. package/.agent-src/skills/competitive-positioning/SKILL.md +152 -0
  17. package/.agent-src/skills/customer-research/SKILL.md +116 -0
  18. package/.agent-src/skills/decision-record/SKILL.md +78 -3
  19. package/.agent-src/skills/discovery-interview/SKILL.md +152 -0
  20. package/.agent-src/skills/launch-readiness/SKILL.md +156 -0
  21. package/.agent-src/skills/memory-consolidation/SKILL.md +216 -0
  22. package/.agent-src/skills/release-comms/SKILL.md +123 -0
  23. package/.agent-src/skills/roadmap-writing/SKILL.md +1 -1
  24. package/.agent-src/skills/stakeholder-tradeoff/SKILL.md +91 -3
  25. package/.agent-src/skills/voc-extract/SKILL.md +164 -0
  26. package/.agent-src/templates/roadmaps.md +14 -0
  27. package/.claude-plugin/marketplace.json +9 -1
  28. package/CHANGELOG.md +64 -0
  29. package/README.md +3 -3
  30. package/config/agent-settings.template.yml +35 -0
  31. package/docs/architecture.md +3 -3
  32. package/docs/catalog.md +14 -5
  33. package/docs/contracts/agent-memory-contract.md +15 -1
  34. package/docs/contracts/command-clusters.md +1 -1
  35. package/docs/contracts/context-spine.md +133 -0
  36. package/docs/contracts/file-ownership-matrix.json +388 -0
  37. package/docs/contracts/mental-models.md +336 -0
  38. package/docs/getting-started.md +1 -1
  39. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +52 -0
  40. package/docs/guidelines/cross-role-handoff.md +127 -0
  41. package/package.json +1 -1
  42. package/scripts/check_memory.py +106 -4
  43. package/scripts/check_references.py +1 -0
  44. package/scripts/lint_context_spine_usage.py +133 -0
  45. package/scripts/lint_roadmap_complexity.py +87 -3
  46. package/scripts/mine_session.py +279 -0
  47. package/scripts/schemas/skill.schema.json +9 -0
@@ -0,0 +1,216 @@
1
+ ---
2
+ name: memory-consolidation
3
+ description: "Use when consolidating session signals into curated memory — four-phase loop ORIENT → GATHER → CONSOLIDATE → PRUNE. Triggers on 'mine my sessions', 'consolidate memory', 'review intake signals'."
4
+ status: active
5
+ tier: senior
6
+ source: package
7
+ domain: engineering
8
+ context_spine: [repo]
9
+ ---
10
+
11
+ # memory-consolidation
12
+
13
+ ## When to use
14
+
15
+ - Intake JSONL has accumulated unreviewed signals and `/memory:load` shows the inline-review block.
16
+ - A pattern recurred across recent sessions (correction, preference, decision, repeat-bug) and is at risk of being forgotten by the next fresh chat.
17
+ - Before closing out a multi-day implementation, capture project-scoped facts so the next agent does not re-discover them.
18
+
19
+ Do NOT use for one-off code review notes (those belong in PR comments,
20
+ not memory), for user-attribute facts like name or IDE preference (the
21
+ `onboard` flow owns those), or for transient TODOs (use the task list).
22
+
23
+ ## Cognition cluster
24
+
25
+ - **Mental model 5 — Signal vs. noise.** A consolidation pass that
26
+ promotes 30 entries from a 50-message session is noise; the Pareto
27
+ cut is roughly 3–5 promote-worthy signals per cycle. See
28
+ [`docs/contracts/mental-models.md`](../../../docs/contracts/mental-models.md) § 5.
29
+ - **Mental model 12 — Defense in depth.** Date-discipline, tag
30
+ intersection, and per-invocation transcript-access confirmation are
31
+ three independent guards; any one alone fails open. See § 12.
32
+
33
+ ## Procedure
34
+
35
+ The loop is four sequential phases. Each phase has one exit gate; do
36
+ not advance until the gate is green.
37
+
38
+ ### Phase 1 — ORIENT (review scope and assess adapter)
39
+
40
+ 1. Confirm scope: which project, which time window, which transcript
41
+ source. Default window: last 14 days. The agent must read the
42
+ user's last chat message for an explicit `--since` override before
43
+ defaulting.
44
+ 2. Inspect the current curated state: list files under
45
+ `agents/memory/` and check the most recent `last_validated`
46
+ timestamps. Identify which schemas are stale before mining adds
47
+ noise.
48
+ 3. Review the **repo** slot of the [context-spine](../../../docs/contracts/context-spine.md)
49
+ for project boundaries (modules, owners, sensitive paths). If empty,
50
+ note the gap in the consolidation report; do not invent.
51
+ 4. Resolve the `TranscriptAdapter` for the current host (see Adapter
52
+ contract below). If no adapter matches, stop and route the user to
53
+ `/memory:propose` for manual signal entry. Do **not** synthesize.
54
+
55
+ **Exit gate:** scope, window, adapter all named. If any one is
56
+ missing, stop.
57
+
58
+ ### Phase 2 — GATHER SIGNAL
59
+
60
+ 1. Stream transcript turns through the four signal regex families:
61
+ - **Correction:** `actually|wrong|stop doing|don't do|that's not what|nicht so`.
62
+ - **Preference:** `prefer|always|never|standard|i want|ich will`.
63
+ - **Decision:** `let's go with|decided|we'll use|entschieden`.
64
+ - **Pattern (recurring):** the same file path or symbol appears in
65
+ ≥ 3 turns within 24 hours.
66
+ 2. For each match, extract a **normalised fact** — strip personal
67
+ pronouns, IDE chrome, timestamps, and turn-id. The fact must be
68
+ project-scoped (refers to a file, module, command, or invariant)
69
+ not user-scoped (refers to *me*, *Matze*, *my IDE*).
70
+ 3. Drop user-attribute matches. If the fact cannot survive the
71
+ normalisation, discard it. The miner is a strict gate.
72
+
73
+ **Exit gate:** ≤ 5 normalised facts per cycle. More than 5 means the
74
+ miner is too loose; tighten patterns and re-run before promoting.
75
+
76
+ ### Phase 3 — CONSOLIDATE
77
+
78
+ 1. Tag each fact via the schema-routing table:
79
+
80
+ | Tag | Schema |
81
+ |---|---|
82
+ | `convention` | `agents/memory/conventions.yml` |
83
+ | `invariant` | `agents/memory/domain-invariants.yml` |
84
+ | `gotcha` | `agents/memory/operational-gotchas.yml` |
85
+ | `pattern` | `agents/memory/recurring-patterns.yml` |
86
+
87
+ A fact may carry **two** tags; the promoter resolves via tag
88
+ intersection, not by file extension. See
89
+ [`docs/contracts/agent-memory-contract.md`](../../../docs/contracts/agent-memory-contract.md)
90
+ for the curated YAML schemas.
91
+
92
+ 2. Append each fact as one JSONL line to
93
+ `agents/memory/intake/<primary-tag>.jsonl` with required fields
94
+ per the contract: `ts`, `type`, `key`, `observation`, `source:
95
+ agent`, `session_id`, plus the new optional `tags: [<one>, <two>]`.
96
+ 3. Default to `--preview` mode: render the JSONL block to stdout and
97
+ stop. Only `--commit-intake` writes the file.
98
+
99
+ **Exit gate:** every fact carries ≥ 1 tag and a JSONL-shape that
100
+ validates against the contract.
101
+
102
+ ### Phase 4 — PRUNE & INDEX
103
+
104
+ 1. After promotion (handled by `/memory:promote`, not this skill),
105
+ archive the consumed JSONL lines into
106
+ `agents/memory/intake/.archive/YYYY-Www.jsonl` — week-bucketed,
107
+ not day-bucketed (defeats session-context inference attacks).
108
+ 2. If a curated entry's `last_validated` field is older than 90 days
109
+ AND no signal in the last 30 days touched its `key`, mark it
110
+ stale in the consolidation report — but do **not** auto-delete.
111
+ Pruning is a human-confirmed action.
112
+
113
+ **Exit gate:** report cites ≥ 0 promotions, ≥ 0 stale flags, 0
114
+ auto-deletes.
115
+
116
+ ## TranscriptAdapter contract
117
+
118
+ The miner is host-agnostic by design. A `TranscriptAdapter` for host
119
+ `X` ships:
120
+
121
+ - **Discover:** function returning the absolute path(s) of session
122
+ transcripts for the active project, scoped to the `--since` window.
123
+ Phase 1 ships the Claude-Code adapter only; absent adapter →
124
+ `not-supported-on-this-host`.
125
+ - **Iterate:** generator yielding turn objects with `{role, ts,
126
+ text}`. Adapter strips IDE chrome and tool-call boilerplate before
127
+ yielding.
128
+ - **Redact:** function applied to every yielded text — drops user
129
+ names, file paths outside the repo root, and any personal
130
+ identifier the consumer project lists in
131
+ `.agent-settings.yml` under `memory.redact_patterns`.
132
+
133
+ Phase 1 implementation lives in
134
+ `/memory:mine-session` (single host: Claude Code,
135
+ `~/.claude/projects/*/sessions/*.jsonl`). Phase 3 of the
136
+ adoption roadmap adds a second host adapter; the contract above is
137
+ documented now so the second implementation is not a vacuum design.
138
+
139
+ ## Related Skills
140
+
141
+ **WHEN to use this**
142
+
143
+ - Intake JSONL has > 10 unreviewed signals.
144
+ - A correction / preference recurred across ≥ 3 sessions.
145
+ - Closing out a multi-day implementation.
146
+
147
+ **WHEN NOT to use this**
148
+
149
+ - One-off PR review notes — comment on the PR.
150
+ - User-attribute facts (name, IDE) — those belong to the
151
+ [`onboard`](../../commands/onboard.md) flow, not curated memory.
152
+ - Transient TODOs — use the task-list tools.
153
+ - A single bug fix that does not generalise — fix the bug, do not
154
+ memorise it.
155
+
156
+ ## When the agent should load this
157
+
158
+ - "Mine my recent sessions for memory signals."
159
+ - "Consolidate the intake stream into curated entries."
160
+ - "What did we decide about X across the last week?"
161
+ - "Review unreviewed memory signals before I switch projects."
162
+ - "Run a memory consolidation cycle."
163
+
164
+ ## Output
165
+
166
+ 1. **Consolidation report** — Markdown block printed to stdout: scope
167
+ (project, window, host), signal counts per class, list of
168
+ normalised facts with tag and target schema, stale-flag list. No
169
+ side effects in `--preview` mode.
170
+ 2. **Intake JSONL appendix** — only with `--commit-intake`: appended
171
+ lines to `agents/memory/intake/<tag>.jsonl`. Lines validate
172
+ against the contract.
173
+ 3. **Archive bucket** — only after `/memory:promote` runs and lifts
174
+ the lines into curated YAML: appends to
175
+ `agents/memory/intake/.archive/YYYY-Www.jsonl`. Week-bucketed.
176
+
177
+ ## Gotcha
178
+
179
+ - Mining without `--confirm-transcript-access` reads zero turns and
180
+ prints an opt-in hint. The flag is per-invocation, not persistent.
181
+ - The miner is a strict gate. > 5 normalised facts per cycle means
182
+ the regex set is too loose, not that the session was rich.
183
+ - A fact tagged `gotcha + invariant` lands in the `gotcha` JSONL
184
+ (primary tag); the promoter reads tag intersection to decide the
185
+ curated YAML target.
186
+ - Date-discipline: the `check_memory.py` linter rejects
187
+ `yesterday|today|tomorrow|last/next/this week|month|year` in curated
188
+ YAML without an `YYYY-MM-DD` anchor within ±20 chars. Re-anchor
189
+ before commit.
190
+
191
+ ## Do NOT
192
+
193
+ - Do NOT auto-trigger this skill on session end. The flow is manual,
194
+ per-invocation, and confirmed.
195
+ - Do NOT vendor patterns or text from `grandamenium/dream-skill` —
196
+ the upstream lacks a `LICENSE`. Concept and procedure structure are
197
+ the only adoption surface.
198
+ - Do NOT promote a normalised fact whose `key` falls outside the
199
+ repo root or names another consumer project.
200
+ - Do NOT delete a stale curated entry without explicit user
201
+ confirmation. Stale-flag is the most this skill emits.
202
+
203
+ ## Runnable example
204
+
205
+ After a 4-day refactor of `app/Services/PaymentGateway`, run a
206
+ consolidation cycle:
207
+
208
+ - `/memory:mine-session --since 2026-05-06 --confirm-transcript-access --preview`.
209
+ - Miner surfaces 4 facts: 1 correction (`PaymentGateway::charge` must
210
+ not throw on idempotency replays — `convention`), 1 decision
211
+ (`Stripe webhook signing key lives in `config/services.php` only —
212
+ `gotcha`), 2 patterns (`PaymentGatewayTest` flakes when seeded data
213
+ carries timestamps in microseconds — `pattern + gotcha`).
214
+ - Report cites 0 stale flags. Re-run with `--commit-intake` after
215
+ spot-checking the 4 facts.
216
+ - Hand off to `/memory:promote` for the curated-YAML write.
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: release-comms
3
+ description: "Use when turning a shipped changelog into a release narrative — value-not-feature framing, audience-segmented surfaces, one source of truth. Triggers on 'announce the release', 'write changelog post'."
4
+ status: active
5
+ tier: senior
6
+ source: package
7
+ domain: product
8
+ context_spine: [product, team]
9
+ ---
10
+
11
+ # release-comms
12
+
13
+ ## When to use
14
+
15
+ - Release shipping with user-facing change, team about to send feature-list email.
16
+ - Changelog draft reads like commit log — engineering-honest, unparseable for user.
17
+ - Multiple comms surfaces (in-app, email, social, docs) about to be written by different people from same release.
18
+
19
+ Do NOT use for incident comms (see `incident-commander`),
20
+ deprecation announcements needing legal sign-off, or pre-release
21
+ discovery — this skill assumes change is **shipped**.
22
+
23
+ ## Cognition cluster
24
+
25
+ - **Mental model 16 — Leading vs. lagging indicators.** Release note
26
+ is lagging artifact; leading version = in-app prompt that fired
27
+ before user found change-log. See
28
+ [`docs/contracts/mental-models.md`](../../../docs/contracts/mental-models.md) § 16.
29
+ - **Value-not-feature heuristic.** Every paragraph passes *"so the
30
+ user can ___"* completion. Failing rows go back for re-write.
31
+
32
+ ## Procedure
33
+
34
+ ### Step 0: Ground the release
35
+
36
+ 1. Read merged PR list / changelog block / release branch diff. Release = **what**; comms = **so what**. Conflate the two → ship marketing.
37
+ 2. Read **product** and **team** slots of [context-spine](../../../docs/contracts/context-spine.md) (if consumer filled them) for bounded scope and cadence — surface choice depends on cadence (weekly: in-app + log; quarterly: email + post; major: all four).
38
+ 3. Identify **single dominant change** the release ships. Three "headliners" reads as three half-announcements.
39
+
40
+ ### Step 1: Audience-segment
41
+
42
+ 1. Three audiences max: **active user**, **at-risk / lapsed user**, **prospect**. More fragments message; fewer hides routing.
43
+ 2. Per audience, write one sentence: *"After this release, you can …"* completing with user-side verb, not product-side feature.
44
+ 3. If two audiences end up with same sentence, collapse — segmentation that does not change message = theatre.
45
+
46
+ ### Step 2: Map surfaces to audiences
47
+
48
+ 1. **Changelog** (always) — engineers + power users; truthful, dense, link-heavy. Source of truth — every other surface points back here.
49
+ 2. **In-app prompt** — active users; ≤ 1 sentence + 1 CTA; fires for users whose past behaviour predicts they'll touch the new path.
50
+ 3. **Email** — at-risk / lapsed; one headline value, one CTA, one paragraph of context. No feature lists.
51
+ 4. **Social / blog** — prospect; the **why**, not the **what** — frame against user job (cite [`customer-research`](../customer-research/SKILL.md) if switch-event surfaced).
52
+
53
+ Cut surfaces aggressively. Weekly release does not need blog post.
54
+
55
+ ### Step 3: Draft each surface from the changelog
56
+
57
+ 1. Open changelog. Per surface, copy dominant change line, then **rewrite verb subject** from "we" to "you".
58
+ 2. Strip qualifiers ("now", "even better", "lightning-fast"). Noise, not signal.
59
+ 3. Run *"so the user can ___"* completion on every paragraph. Failing paragraphs cut, not edited.
60
+
61
+ ### Step 4: Truth-check
62
+
63
+ 1. Every claim links back to changelog row or doc URL. Unsourced claim → cut.
64
+ 2. No tense games — past for shipped, future for coming-soon (and only if date is committed). "Roadmap" lives outside this skill.
65
+ 3. Names match product surface. In-app says "Reports" and email says "Insights" → user fires lookup tax.
66
+
67
+ ### Step 5: Hand off
68
+
69
+ 1. Produce four artifacts (see `## Output`).
70
+ 2. Hand to whoever owns send. Do not embed scheduling or A/B test plans here — that is RevOps.
71
+
72
+ ## Related Skills
73
+
74
+ **WHEN to use this**
75
+
76
+ - Change is **shipped** and needs to reach existing users.
77
+ - Multiple comms surfaces written by different people from same source.
78
+ - Team about to default to feature-list email.
79
+
80
+ **WHEN NOT to use this**
81
+
82
+ - Production incident comms → [`incident-commander`](../incident-commander/SKILL.md).
83
+ - Pre-release discovery / validation → [`customer-research`](../customer-research/SKILL.md).
84
+ - Funnel-stage diagnostics post-release → [`funnel-analysis`](../funnel-analysis/SKILL.md).
85
+ - Ranking which release to comms next → [`rice-prioritization`](../rice-prioritization/SKILL.md).
86
+
87
+ ## When the agent should load this
88
+
89
+ - "Write the release notes for sprint 47."
90
+ - "We're shipping the new export — how do we announce it?"
91
+ - "Draft the changelog email for last week's batch."
92
+ - "What's the in-app prompt copy for the redesign?"
93
+ - "Turn the merged PR list into something users can read."
94
+
95
+ ## Output
96
+
97
+ 1. **`release-narrative.md`** — single source of truth: dominant change, audiences (1–3), per-audience *"After this release, you can …"* sentence, links to source changelog rows.
98
+ 2. **`changelog-entry.md`** — engineer-honest, dense, link-heavy block ready to paste into project's changelog.
99
+ 3. **`comms-pack.md`** — per-surface drafts (in-app prompt, email, optional social/blog), each ≤ surface's hard cap, each pointing back to `changelog-entry.md`.
100
+ 4. **`comms-checklist.md`** — pre-send checks: every claim sourced, names consistent across surfaces, audience match, "so the user can …" completion passing on every paragraph. Hand-off artifact for senior PO ([`product-owner`](../../personas/product-owner.md)).
101
+
102
+ ## Gotcha
103
+
104
+ - Default failure mode = feature-list email — written to make engineering feel seen, not to help user.
105
+ - Marketing puffery ("revolutionary", "delightful") fails source check; cut on sight.
106
+ - Two surfaces using different names for same thing = highest-frequency support-ticket trigger after release.
107
+ - Hidden coming-soon claims in past-tense paragraphs erode trust faster than missing the comms entirely.
108
+
109
+ ## Do NOT
110
+
111
+ - Do NOT promote coming-soon item alongside shipped items — user cannot tell which is which and stops trusting next note.
112
+ - Do NOT let long-tail change steal the headline — dominant change earns headline, long tail goes in changelog.
113
+ - Do NOT ship surfaces without truth-check pass; unsourced claim survives in social longer than release does.
114
+
115
+ ## Runnable example
116
+
117
+ Sprint 47 ships a one-click monthly export and three small bug fixes:
118
+
119
+ - Dominant change: one-click export. Bug fixes go in changelog only.
120
+ - Audiences: active user (will use it), at-risk (export friction was churn trigger per [`customer-research`](../customer-research/SKILL.md) evidence-log).
121
+ - "After this release, you can pull a board-ready monthly report in one click." (active, at-risk — same sentence ⇒ collapse to one).
122
+ - Surfaces: changelog (full), in-app prompt to active users on next month-end, email to at-risk cohort with same sentence and one CTA. No social.
123
+ - Truth-check: claim links to export PR; "one click" is literal — verified against shipped UI.
@@ -162,6 +162,6 @@ to every roadmap you author.
162
162
 
163
163
  ## Examples
164
164
 
165
- Browse `agents/roadmaps/` (active plate) and `agents/roadmaps/archive/`
165
+ Browse `agents/roadmaps/` (active set) and `agents/roadmaps/archive/`
166
166
  (closed work) for canonical structural / tactical / structural-with-council
167
167
  examples.
@@ -1,12 +1,15 @@
1
1
  ---
2
2
  name: stakeholder-tradeoff
3
3
  description: "Use when stakeholders pull a decision in different directions — frames each lens, builds a trade-off matrix, surfaces the cost of every choice — even if the user just says 'PO and ops disagree'."
4
+ status: active
5
+ tier: senior
6
+ source: package
7
+ domain: product
8
+ context_spine: [team, product]
4
9
  personas:
5
10
  - product-owner
6
11
  - stakeholder
7
12
  - critical-challenger
8
- source: package
9
- domain: product
10
13
  ---
11
14
 
12
15
  # stakeholder-tradeoff
@@ -38,6 +41,26 @@ Do NOT use when:
38
41
  - The trade-off is risk-only — route to
39
42
  [`risk-officer`](../risk-officer/SKILL.md).
40
43
 
44
+ ## Cognition cluster
45
+
46
+ - **Mental model 5 — Opportunity cost.** Every `+` on the matrix is
47
+ also an opportunity cost on the stakeholders not getting that
48
+ benefit; the matrix only earns its keep when it surfaces who pays
49
+ for the chosen `+`. See
50
+ [`docs/contracts/mental-models.md`](../../../docs/contracts/mental-models.md) § 5.
51
+ - **Mental model 27 — Outcome over output.** Picking the option with
52
+ the most checkmarks is output theatre; pick the option whose `–`
53
+ cells land on stakeholders who can execute mitigations. See
54
+ `mental-models.md` § 27.
55
+ - **Mental model 29 — Pre-mortems.** For the recommended option,
56
+ state the failure mode each `–`-bearing stakeholder will name in
57
+ six months. If you cannot, the lens is incomplete — re-interview.
58
+ See `mental-models.md` § 29.
59
+ - **Team + product context-spine slots.** Read **team** for the
60
+ silent-stakeholders inventory (on-call, support, finance) and
61
+ **product** for end-user / segment lenses (free vs paid, region,
62
+ cohort). See [`context-spine`](../../../docs/contracts/context-spine.md).
63
+
41
64
  ## Procedure
42
65
 
43
66
  ### 1. Identify the stakeholders
@@ -98,7 +121,40 @@ everywhere, the trade-off paragraph names a concrete cost (not just
98
121
  cells the named owner can execute. Ensure no silent stakeholder
99
122
  column is missing.
100
123
 
101
- ## Output format
124
+ ## Related Skills
125
+
126
+ **WHEN to use this**
127
+
128
+ - A request crosses two stakeholder lenses (eng ↔ PO, PO ↔ ops, ops
129
+ ↔ infra) and the trade-off is **not yet code**.
130
+ - The room agrees on the goal but disagrees on who absorbs the cost.
131
+ - A roadmap step has *un*declared trade-offs that need surfacing
132
+ before commit.
133
+
134
+ **WHEN NOT to use this**
135
+
136
+ - The conflict surfaces **inside an open PR** (test-coverage fails
137
+ but PO wants to ship) — start with `code-review-multi-lens`
138
+ (sibling C8); a C8 verdict that surfaces stakeholder conflict
139
+ becomes input to this skill for escalation. Boundary prose lives
140
+ in [`docs/guidelines/cross-role-handoff.md`](../../../docs/guidelines/cross-role-handoff.md).
141
+ - The trade-off is purely technical (perf vs storage, sync vs async)
142
+ — route to [`decision-record`](../decision-record/SKILL.md).
143
+ - The dominant axis is risk, not stakeholder cost — route to
144
+ [`risk-officer`](../risk-officer/SKILL.md).
145
+ - The output is the locked decision artifact — hand off to
146
+ [`decision-record`](../decision-record/SKILL.md) once the matrix
147
+ is built.
148
+
149
+ ## When the agent should load this
150
+
151
+ - "Wer zahlt was bei dieser Entscheidung?"
152
+ - "PO und Ops sind sich uneinig — wir brauchen Klarheit."
153
+ - "Was ist der Trade-off zwischen X und Y für die einzelnen Lenses?"
154
+ - "Stakeholder-Konflikt vor dem Commit auflösen."
155
+ - "Diese Roadmap-Phase hat undeclared trade-offs."
156
+
157
+ ## Output
102
158
 
103
159
  The trade-off report is a single block with these ordered fields:
104
160
 
@@ -147,3 +203,35 @@ Next: /decision-record to lock the choice
147
203
  if it exists, the trade-off was imaginary; surface that.
148
204
  - Do NOT lock the choice in this skill; hand off to
149
205
  `decision-record`.
206
+
207
+ ## Runnable example
208
+
209
+ A pricing-page rewrite that ships faster vs gives ops more lead time:
210
+
211
+ - Decision: *"Should the pricing-page rewrite ship in 2 weeks
212
+ (option A) or 4 weeks with a managed rollout (option B)?"*
213
+ - Stakeholders:
214
+ - **PO** wants: revenue lift on Q-end · fears: churn signal in
215
+ the noise · trades: copy polish for time-to-ship.
216
+ - **On-call eng** wants: change window outside Friday · fears:
217
+ Saturday paging on a marketing rollout · trades: shippable A/B
218
+ framework for a deploy gate.
219
+ - **Support lead** wants: scripted answers for the new tier ·
220
+ fears: ticket-volume spike unprepared · trades: depth of
221
+ answers for breadth.
222
+ - **End-user (free tier)** wants: clear "what stays free" line ·
223
+ fears: silent paywall on a feature they rely on · trades:
224
+ nothing — silent stakeholder.
225
+ - Matrix splits hardest on **operational load** (option A: `–` for
226
+ on-call + support, `+` for PO) and **clarity for end-users**
227
+ (option B: `+` for support + end-user, `–` for PO timing).
228
+ - Trade-off in plain language: *"Option A means PO hits Q-end, but
229
+ on-call carries a marketing-rollout pager and support eats ticket
230
+ spikes blind. Option B means support and end-users land softly,
231
+ but PO slips two weeks past Q-end."*
232
+ - Recommendation: option B. Rationale: the `–` cells in option A
233
+ land on stakeholders who **cannot** mitigate from inside the
234
+ rollout (free-tier user has no voice in the room).
235
+ - Next: `/decision-record` to lock option B; the supersession chain
236
+ cites the original "ship by Q-end" mandate as the constraint that
237
+ changed.
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: voc-extract
3
+ description: "Use when extracting Voice-of-Customer themes from existing artefacts — GH issues, PR threads, Sentry patterns. Triggers on 'what are users saying', 'recurring complaints', 'top themes'."
4
+ status: active
5
+ tier: senior
6
+ source: package
7
+ domain: product
8
+ context_spine: [product]
9
+ ---
10
+
11
+ # voc-extract
12
+
13
+ ## When to use
14
+
15
+ - A backlog or planning round needs grounded user-voice signal, not anecdotes.
16
+ - A round of bug reports / feature requests / Sentry events has accumulated and the team needs themes with citation per theme.
17
+ - A roadmap proposal needs a "what users keep telling us" backing section.
18
+
19
+ Do NOT use this skill for live interviews
20
+ ([`discovery-interview`](../discovery-interview/SKILL.md)) or for
21
+ quantitative funnel diagnosis ([`funnel-analysis`](../funnel-analysis/SKILL.md)).
22
+
23
+ ## Bounded scope
24
+
25
+ - **Read-only on artefacts the host already has** — local repo issues
26
+ (`gh issue list`), PR discussions (`gh pr view`), Sentry projects
27
+ the team owns. No external scrape, no SaaS API calls.
28
+ - **Chat-export sourcing (Discord, Slack) is deferred** pending
29
+ privacy review (council Q5, SHIP-WITHOUT). If a request asks for
30
+ chat-derived VoC, refuse and route the user to a privacy review.
31
+ - **No PII surfacing** — quotes are paraphrased to remove names,
32
+ emails, tenant identifiers; verbatim is reserved for product-team
33
+ artefacts inside the repo.
34
+
35
+ ## Cognition cluster
36
+
37
+ - **Mental model 15 — Signal vs noise.** A loud single reporter
38
+ swamps quiet recurring patterns; rank by **distinct authors**, not
39
+ comment count. See
40
+ [`docs/contracts/mental-models.md`](../../../docs/contracts/mental-models.md) § 15.
41
+ - **Mental model 14 — Pareto.** Roughly 20% of themes carry 80% of
42
+ the contact volume; cut the long tail explicitly so the team acts
43
+ on the head. See `mental-models.md` § 14.
44
+ - **Mental model 22 — Data-informed, not data-driven.** Issue counts
45
+ are evidence, not voting; weight by recency, severity, and segment
46
+ before recommending. See `mental-models.md` § 22.
47
+ - **Product context-spine slot.** Read **product** for segments,
48
+ non-goals, and focal jobs; do not surface themes that fall outside
49
+ the declared scope without a scope-violation flag. See
50
+ [`context-spine`](../../../docs/contracts/context-spine.md).
51
+
52
+ ## Procedure
53
+
54
+ ### 1. Inventory the source artefacts
55
+
56
+ Identify what is in scope **for this run**:
57
+
58
+ - `gh issue list --state all --limit N` per repo.
59
+ - `gh pr list --state all --limit N` per repo.
60
+ - Sentry project names + date window.
61
+
62
+ Capture counts and date window in the output header so the verdict
63
+ is reproducible.
64
+
65
+ ### 2. Inspect each artefact and tag
66
+
67
+ Per artefact, capture:
68
+
69
+ - **Theme tag** (free-text, normalised in step 3).
70
+ - **Author** (distinct identity).
71
+ - **Severity** — blocking / friction / wish / praise.
72
+ - **Segment** — derived from the **product** spine slot.
73
+ - **Citation** — `repo#123`, PR URL, Sentry issue ID.
74
+
75
+ ### 3. Normalise and rank
76
+
77
+ Cluster theme tags into 5–12 themes max. For each:
78
+
79
+ - **Distinct-author count** (the rank key).
80
+ - **Severity mix** (blocking-share matters more than wish-share).
81
+ - **Recency** — last 90 days vs older; weight 2× recent.
82
+ - **Segment skew** — does the theme cluster in one segment?
83
+
84
+ Drop themes with `< 3` distinct authors **unless** severity is
85
+ blocking or the theme is brand-new in the recency window.
86
+
87
+ ### 4. Build the theme report and validate
88
+
89
+ One row per theme. Columns: **theme · distinct authors · severity
90
+ mix · recency · segment skew · representative citations (≤ 3) ·
91
+ proposed next step (refine / probe / defer)**.
92
+
93
+ Validate the report before handing back: verify each row cites
94
+ ≥ 1 artefact, check that distinct-author counts match the source
95
+ inventory from step 1, confirm no PII leaked into the citations,
96
+ and ensure no theme rated `defer` lacks a written rationale.
97
+
98
+ ### 5. Surface scope violations
99
+
100
+ Themes that fall outside the **product** spine slot's declared scope
101
+ go into a `scope-violation.md` block, never silently into the main
102
+ report. The team decides whether to expand scope or close the door.
103
+
104
+ ### 6. Hand back
105
+
106
+ Route refine candidates to [`refine-ticket`](../refine-ticket/SKILL.md);
107
+ route probe candidates (need live interview) to
108
+ [`discovery-interview`](../discovery-interview/SKILL.md); defer the
109
+ rest with explicit rationale.
110
+
111
+ ## Related Skills
112
+
113
+ **WHEN to use this**
114
+
115
+ - The signal needs to come from existing repo / Sentry artefacts.
116
+ - The output is a theme list with citation, not narrative summary.
117
+ - A roadmap proposal needs grounded VoC backing.
118
+
119
+ **WHEN NOT to use this**
120
+
121
+ - The signal needs a live conversation — route to
122
+ [`discovery-interview`](../discovery-interview/SKILL.md).
123
+ - The artefacts are chat-export sourced (Discord, Slack) — refuse
124
+ and route to a privacy review (deferred per bounded scope).
125
+ - The output is a quantitative funnel — route to
126
+ [`funnel-analysis`](../funnel-analysis/SKILL.md).
127
+ - A theme is already a ticket candidate — route directly to
128
+ [`refine-ticket`](../refine-ticket/SKILL.md).
129
+
130
+ ## When the agent should load this
131
+
132
+ - "Was sagen die User wirklich?"
133
+ - "Top-Themen aus den letzten 90 Tagen Issues."
134
+ - "Welche Sentry-Patterns sind recurring?"
135
+ - "Backe der Roadmap-Phase ein VoC-Block dazu."
136
+ - "Gibt es ein Segment, das uns überproportional pingt?"
137
+
138
+ ## Output
139
+
140
+ 1. **Header** — sources scanned, counts, date window, scope notes.
141
+ 2. **Theme report table** — themes, distinct authors, severity mix,
142
+ recency, segment skew, citations, next step.
143
+ 3. **Scope-violation block** — themes outside the product spine
144
+ slot, explicit, never collapsed into the main table.
145
+ 4. **Routing list** — refine / probe / defer rows with the named
146
+ downstream skill per theme.
147
+
148
+ ## Gotcha
149
+
150
+ - One articulate user can own three themes; rank by distinct authors
151
+ or you ship their backlog.
152
+ - A theme with no recency (all > 90 days) is archaeology, not VoC;
153
+ flag it explicitly.
154
+ - Chat-export requests are tempting (Discord copy-paste); refuse
155
+ per bounded scope until the privacy review lands.
156
+
157
+ ## Do NOT
158
+
159
+ - Do NOT scrape external sources or hit SaaS APIs the team does not
160
+ already own.
161
+ - Do NOT surface PII; paraphrase before quoting.
162
+ - Do NOT collapse scope-violations into the main table.
163
+ - Do NOT lock decisions inside this skill — hand off to
164
+ `refine-ticket` or `decision-record`.
@@ -43,6 +43,20 @@ Templates for roadmap files stored in `agents/roadmaps/` or `app/Modules/{Module
43
43
  or budget-invariant changes; multi-round council, file-ownership
44
44
  matrices, > 600 lines. Enforced by `task lint-roadmap-complexity`.
45
45
  Standard: [`docs/contracts/roadmap-complexity-standard.md`](../docs/contracts/roadmap-complexity-standard.md).
46
+ 16. **Time-boxed plates / visible-horizon sections — opt-in via
47
+ `roadmap.horizon_weeks` in `.agent-settings.yml`.** Default is `0`
48
+ (off): roadmaps describe scope and phase ordering, not week-by-week
49
+ commitments. With the default, do **not** add `## Horizon (N-week
50
+ visible plate)` sections, "Inside / outside the plate" framings,
51
+ `In-plate?` columns in decision tables, or `**Out-of-plate.**` /
52
+ `**Out-of-horizon.**` / `(out-of-horizon, gated on Phase N)`
53
+ suffixes on steps or phase headers. AI execution does not operate
54
+ on calendar plates by default; scope ordering and dependency gates
55
+ are sufficient. Pacing is the user's call, decided per turn —
56
+ never encoded into the plan unless they have explicitly set
57
+ `horizon_weeks` to a positive integer. Enforced by
58
+ `task lint-roadmap-complexity` (plate-token detection skipped when
59
+ `horizon_weeks > 0`).
46
60
 
47
61
  ---
48
62