@event4u/agent-config 2.8.0 → 2.9.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 (49) hide show
  1. package/.agent-src/personas/engineering-manager.md +133 -0
  2. package/.agent-src/personas/finance-partner.md +129 -0
  3. package/.agent-src/personas/people-strategist.md +126 -0
  4. package/.agent-src/personas/strategist.md +129 -0
  5. package/.agent-src/skills/build-buy-partner/SKILL.md +145 -0
  6. package/.agent-src/skills/comp-banding/SKILL.md +160 -0
  7. package/.agent-src/skills/competitive-moat-analysis/SKILL.md +152 -0
  8. package/.agent-src/skills/contracts-cognition/SKILL.md +147 -0
  9. package/.agent-src/skills/data-handling-judgment/SKILL.md +155 -0
  10. package/.agent-src/skills/forecasting/SKILL.md +164 -0
  11. package/.agent-src/skills/hiring-loop-design/SKILL.md +167 -0
  12. package/.agent-src/skills/market-entry-analysis/SKILL.md +144 -0
  13. package/.agent-src/skills/onboarding-program/SKILL.md +157 -0
  14. package/.agent-src/skills/one-on-one-cadence/SKILL.md +161 -0
  15. package/.agent-src/skills/org-design/SKILL.md +158 -0
  16. package/.agent-src/skills/perf-feedback-craft/SKILL.md +157 -0
  17. package/.agent-src/skills/privacy-review/SKILL.md +160 -0
  18. package/.agent-src/skills/runway-cognition/SKILL.md +136 -0
  19. package/.agent-src/skills/scenario-modeling/SKILL.md +139 -0
  20. package/.agent-src/skills/throughput-vs-morale-tradeoff/SKILL.md +165 -0
  21. package/.agent-src/skills/unit-economics-modeling/SKILL.md +54 -7
  22. package/.agent-src/skills/vision-articulation/SKILL.md +146 -0
  23. package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  24. package/.agent-src/templates/scripts/telemetry/settings.py +65 -0
  25. package/.agent-src/templates/scripts/tier_usage_report.py +183 -0
  26. package/.claude-plugin/marketplace.json +18 -1
  27. package/AGENTS.md +1 -1
  28. package/CHANGELOG.md +106 -0
  29. package/README.md +3 -3
  30. package/docs/architecture.md +37 -11
  31. package/docs/catalog.md +22 -4
  32. package/docs/contracts/adr-forecast-construction-shape.md +89 -0
  33. package/docs/contracts/adr-wing4-context-spine.md +125 -0
  34. package/docs/contracts/command-clusters.md +41 -0
  35. package/docs/contracts/command-surface-tiers.md +25 -9
  36. package/docs/contracts/context-spine.md +8 -0
  37. package/docs/contracts/mcp-beta-criteria.md +129 -0
  38. package/docs/guidelines/wing4-handoff.md +127 -0
  39. package/docs/mcp-server.md +1 -1
  40. package/package.json +1 -1
  41. package/scripts/_cli/cmd_doctor.py +527 -14
  42. package/scripts/_cli/cmd_validate.py +10 -0
  43. package/scripts/agent-config +19 -18
  44. package/scripts/install.py +5 -0
  45. package/scripts/lint_context_spine_usage.py +1 -0
  46. package/scripts/mcp_server/__init__.py +1 -0
  47. package/scripts/mcp_server/server.py +4 -3
  48. package/scripts/schemas/skill.schema.json +2 -2
  49. package/scripts/skill_linter.py +107 -3
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: vision-articulation
3
+ description: "Use when articulating internal vision — where we're going / why now / why us, founder-mode anchor, distinct from fundraising pitch. Triggers on 'what's our vision', 'why are we doing this'."
4
+ status: active
5
+ tier: senior
6
+ source: package
7
+ domain: process
8
+ context_spine: [org-stage, product, customer-segment]
9
+ ---
10
+
11
+ # vision-articulation
12
+
13
+ ## When to use
14
+
15
+ - An internal anchor is needed — board off-site, all-hands, strategy doc — and the question is *where are we going, why now, why us*. The audience is the team, not investors.
16
+ - A founder or strategist is sense-checking whether the current direction still holds, or whether reality has diverged from the stated vision.
17
+ - A new hire / new exec needs the founder-mode read of the company — not the fundraise pitch, the durable internal frame.
18
+
19
+ Do NOT use for outward-facing fundraise pitch (route to Wing-3 `fundraising-narrative` (H7); vision is internal-anchor, fundraising is external-pitch — different audiences, different proof bars), positioning copy / launch narrative (route to Wing-3 `positioning-strategy` / `messaging-architecture`), or roadmap construction (route to `feature-roadmap` workflows; vision constrains roadmaps, doesn't replace them).
20
+
21
+ ## Cognition cluster
22
+
23
+ - **Mental model 27 — Why now.** Vision without a *why now* is a wishlist. The market shift, technology wave, regulatory change, or demographic inflection that makes the vision *achievable in this window* is the load-bearing claim. See [`mental-models.md`](../../../docs/contracts/mental-models.md) § 27.
24
+ - **Mental model 1 — First principles.** Strip the vision to outcomes for a named cohort, not feature lists or company milestones. *"Be the X for Y"* is shape; *"customer C does outcome O 10× faster"* is substance. See `mental-models.md` § 1.
25
+ - **Mental model 21 — Second-order thinking.** *"If this vision is realised, what does the world look like in 5 years?"* If the answer is just *"we got bigger"*, the vision isn't load-bearing; if the answer is structural change (workflow shift, market re-shape), it is. See `mental-models.md` § 21.
26
+ - **Context-spine — org-stage + product + customer-segment.** Read **org-stage** for vision-horizon (pre-seed = 3-year survival vision; growth = 5–7-year market-shape vision; mature = 10-year). Read **product** for the realistic shipping shape. Read **customer-segment** for the cohort whose outcome anchors the vision.
27
+
28
+ ## Procedure
29
+
30
+ ### Step 0: Identify stance — founder vs operator
31
+
32
+ Vision-articulation is a founder-mode act, not an operator-mode act (per council Q6). Before starting:
33
+
34
+ 1. Confirm the requester is in founder-stance — they are setting the durable frame, not optimising within an existing frame.
35
+ 2. If the requester is in operator-stance (planning, executing, refining within a fixed frame), this skill is wrong; route to roadmap / planning skills.
36
+
37
+ Founder-stance is the precondition; without it the output is mis-shaped.
38
+
39
+ ### Step 1: Frame "where we're going" — cohort + outcome + horizon
40
+
41
+ One sentence: *"In [horizon], [customer-segment] [does outcome O] [because of structural change S]."*
42
+
43
+ Anti-patterns to reject:
44
+
45
+ 1. *"We're the [Big Company] of [Vertical]"* — feature-comparison, not cohort outcome. Reject.
46
+ 2. *"We're building the future of X"* — generic, no cohort named. Reject.
47
+ 3. *"We're growing to $100M ARR"* — milestone, not vision. Reject.
48
+
49
+ The sentence must name *who*, *what they do that they can't do today*, *why it matters in [horizon]*.
50
+
51
+ ### Step 2: Construct "why now"
52
+
53
+ Name 2–3 inflections that make this vision achievable in this window — not next decade, not last decade:
54
+
55
+ 1. **Technology inflection** — capability newly cheap / newly possible (AI, edge compute, new platform).
56
+ 2. **Market inflection** — buyer behaviour shift, segment opening, incumbent vulnerability (M&A churn, regulatory burden, talent loss).
57
+ 3. **Demographic / regulatory inflection** — workforce shift, policy change, generational handover.
58
+
59
+ Each inflection must be *recent* (last 24–36 months) or *imminent* (next 24 months). Inflections from 10 years ago are settled; inflections 10 years out are speculative. The *why now* window is narrow.
60
+
61
+ ### Step 3: Construct "why us"
62
+
63
+ Name 2–3 reasons this team, not another, can execute the vision. Honesty test:
64
+
65
+ 1. **Unique capability** — composes `competitive-moat-analysis` (P3); cite the moat dimensions where we score strong with evidence.
66
+ 2. **Unique distribution** — channel, community, partnership we have and competitors structurally can't replicate.
67
+ 3. **Unique insight** — founder / team origin gives us a read on the cohort that competitors don't have.
68
+
69
+ If the answer is *"we're hardworking"* or *"we move fast"*, the answer is none. Most teams are. Re-run.
70
+
71
+ ### Step 4: Inversion — what would falsify the vision?
72
+
73
+ For each load-bearing claim (cohort outcome, why-now inflection, why-us reason), write:
74
+
75
+ 1. *"What evidence in the next 12 months would falsify this?"* — leading signal that the vision is wrong-shaped.
76
+ 2. *"What change in the world would make this vision obsolete?"* — exogenous shift we're betting against.
77
+
78
+ A vision that can't be falsified is a slogan. Concrete falsifiers = real vision.
79
+
80
+ ### Step 5: Validate the vision before emitting
81
+
82
+ Before producing the artifact, verify three things:
83
+
84
+ 1. **Cohort-outcome specificity** — confirm the Step-1 sentence names a specific cohort + specific outcome + specific horizon; generic phrasing fails and must be re-run.
85
+ 2. **Why-now timestamp** — assert each Step-2 inflection is dated within the recent-24-36-months or imminent-24-months window; un-timestamped inflections are claims, not inflections.
86
+ 3. **Why-us falsifiability** — check that each Step-3 reason has a named Step-4 falsifier; un-falsifiable reasons are slogans and must be demoted.
87
+
88
+ All three must pass. If any fails, return to the failing step.
89
+
90
+ ### Step 6: Emit the vision frame
91
+
92
+ Produce the vision-frame artifact for internal use (board, all-hands, exec onboarding). Hand off to Wing-3 `fundraising-narrative` (H7) if an external pitch derivative is needed — that's a translation, not a copy.
93
+
94
+ ## Related Skills
95
+
96
+ **WHEN to use this**
97
+
98
+ - Internal vision articulation for board off-site, all-hands, strategy doc.
99
+ - Founder / exec sense-check on vision-vs-reality divergence.
100
+ - New-hire / new-exec onboarding to founder-mode read.
101
+
102
+ **WHEN NOT to use this**
103
+
104
+ - Outward-facing fundraise pitch — route to Wing-3 [`fundraising-narrative`](../fundraising-narrative/SKILL.md) (H7); vision is internal anchor, fundraising is external pitch.
105
+ - Positioning / messaging copy — route to Wing-3 [`positioning-strategy`](../positioning-strategy/SKILL.md) and [`messaging-architecture`](../messaging-architecture/SKILL.md).
106
+ - Moat reading — route to [`competitive-moat-analysis`](../competitive-moat-analysis/SKILL.md) (P3); this skill composes P3 for the "why us" frame.
107
+ - Roadmap / phase planning — route to roadmap workflows; vision constrains roadmaps, doesn't replace them.
108
+
109
+ ## When the agent should load this
110
+
111
+ - "What's our vision?"
112
+ - "Sense-check our direction — does this still hold?"
113
+ - "Draft the vision section for the board off-site."
114
+ - "Why now / why us frame for the strategy doc."
115
+ - "Wo wollen wir hin und warum jetzt?"
116
+
117
+ ## Output
118
+
119
+ 1. **`vision-frame.md`** — one-sentence vision (cohort + outcome + horizon), three "why now" inflections, three "why us" reasons.
120
+ 2. **`falsifiers.md`** — leading signals + exogenous shifts that would falsify each load-bearing claim.
121
+ 3. **`vision-vs-reality.md`** *(optional)* — when used as a sense-check, the delta between stated vision and current trajectory; named divergence points.
122
+
123
+ ## Gotcha
124
+
125
+ - "Be the X for Y" frames are positioning slogans, not vision. Reject; force cohort-outcome-horizon.
126
+ - "Why now" with no timestamp is a claim, not an inflection. Force a date.
127
+ - "Why us" answers like *"we're a great team"* mean none. Force unique capability / distribution / insight cited with evidence.
128
+ - Vision artifacts that survive zero change in the world over 5 years are slogans. Real visions have falsifiers.
129
+
130
+ ## Do NOT
131
+
132
+ - Do NOT collapse vision into fundraise pitch — different audiences, different proof bars.
133
+ - Do NOT skip the inversion / falsifier step — un-stressed visions are unfalsifiable.
134
+ - Do NOT bolt vision onto roadmap milestones — milestones are downstream of vision, not the same thing.
135
+
136
+ ## Runnable example
137
+
138
+ Series-A vertical SaaS, founder requests vision sense-check for board off-site.
139
+
140
+ - Step 0 — Stance: founder-mode confirmed (off-site context, setting durable frame).
141
+ - Step 1 — Vision: *"In 5 years, mid-size healthcare specialty groups (50–200 providers) deliver patient scheduling with 80 % less administrative load because the workflow is regulation-aware and self-adapting per state."*
142
+ - Step 2 — Why now: (a) state-licensure data became machine-readable in the last 24 months (tech inflection); (b) incumbent hospital-focused vendors hit their growth ceiling and are starting to mis-fit specialty groups (market inflection); (c) post-COVID, specialty-group practice owners control admin spend directly (buyer-behaviour shift, last 36 months).
143
+ - Step 3 — Why us: (a) founder's clinical-ops background + customer-segment access (unique insight, cited with 12 customer interviews); (b) switching-cost moat from 24-month deployment depth (composes P3, cited evidence); (c) HIPAA + 50-state licensure capability stack (unique capability).
144
+ - Step 4 — Falsifiers: (a) incumbent ships specialty-group focused migration tooling = unique-capability claim erodes; (b) state-licensure data becomes opaque again (regulatory rollback) = tech inflection inverts; (c) specialty-group consolidation accelerates so 50–200 cohort shrinks = cohort scope shrinks.
145
+ - Step 5 — Validate: cohort + outcome + horizon present; why-now inflections all dated within 24–36 months; why-us reasons each have falsifier. Pass.
146
+ - Step 6 — Emit vision-frame for board off-site; flag potential H7 derivative needed for the upcoming Series-B narrative.
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.py (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "2.7.0"
42
+ agent_config_version: "2.8.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -18,6 +18,12 @@ DEFAULT_LOG_PATH = Path(".agent-engagement.jsonl")
18
18
  DEFAULT_GRANULARITY = "task"
19
19
  ALLOWED_GRANULARITIES = ("task", "phase-step", "tool-call")
20
20
 
21
+ #: Defaults for the tier-usage signal (Phase 5 of road-to-surface-discipline).
22
+ #: Separate file, separate opt-in, same default-off posture. Contract:
23
+ #: ``docs/contracts/command-clusters.md#tier-usage-signal-contract``.
24
+ DEFAULT_TIER_USAGE_LOG_PATH = Path(".agent-tier-usage.jsonl")
25
+ DEFAULT_TIER_USAGE_RETIER = {"window_days": 30, "min_invocations": 20, "min_distinct_users": 3}
26
+
21
27
 
22
28
  @dataclass(frozen=True)
23
29
  class TelemetrySettings:
@@ -104,9 +110,68 @@ def read_settings(path: Path) -> TelemetrySettings:
104
110
  return settings
105
111
 
106
112
 
113
+ @dataclass(frozen=True)
114
+ class TierUsageSettings:
115
+ enabled: bool
116
+ log_path: Path
117
+ window_days: int
118
+ min_invocations: int
119
+ min_distinct_users: int
120
+
121
+
122
+ def read_tier_usage_settings(path: Path) -> TierUsageSettings:
123
+ """Return parsed tier-usage settings — never raises on missing data.
124
+
125
+ Sibling of :func:`read_settings`; reads the
126
+ ``telemetry.tier_usage`` namespace from ``.agent-settings.yml``.
127
+ Default-off, same parse-tolerant shape — a missing file, a missing
128
+ section, or PyYAML being absent all collapse to ``enabled=False``.
129
+ """
130
+ section: dict[str, Any] = {}
131
+ if path.is_file():
132
+ try:
133
+ import yaml # type: ignore[import-not-found]
134
+ except ImportError:
135
+ yaml = None # type: ignore[assignment]
136
+ if yaml is not None:
137
+ try:
138
+ raw = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
139
+ except Exception:
140
+ raw = {}
141
+ if isinstance(raw, dict):
142
+ tele = raw.get("telemetry")
143
+ if isinstance(tele, dict):
144
+ tu = tele.get("tier_usage")
145
+ if isinstance(tu, dict):
146
+ section = tu
147
+
148
+ output = section.get("output") if isinstance(section.get("output"), dict) else {}
149
+ retier = section.get("retier") if isinstance(section.get("retier"), dict) else {}
150
+ defaults = DEFAULT_TIER_USAGE_RETIER
151
+
152
+ def _coerce_int(value: Any, default: int) -> int:
153
+ if isinstance(value, bool):
154
+ return default
155
+ if isinstance(value, int) and value >= 0:
156
+ return value
157
+ return default
158
+
159
+ return TierUsageSettings(
160
+ enabled=_coerce_bool(section.get("enabled"), default=False),
161
+ log_path=_coerce_path(output.get("path"), DEFAULT_TIER_USAGE_LOG_PATH),
162
+ window_days=_coerce_int(retier.get("window_days"), defaults["window_days"]),
163
+ min_invocations=_coerce_int(retier.get("min_invocations"), defaults["min_invocations"]),
164
+ min_distinct_users=_coerce_int(retier.get("min_distinct_users"), defaults["min_distinct_users"]),
165
+ )
166
+
167
+
107
168
  __all__ = [
108
169
  "DEFAULT_GRANULARITY",
109
170
  "DEFAULT_LOG_PATH",
171
+ "DEFAULT_TIER_USAGE_LOG_PATH",
172
+ "DEFAULT_TIER_USAGE_RETIER",
110
173
  "TelemetrySettings",
174
+ "TierUsageSettings",
111
175
  "read_settings",
176
+ "read_tier_usage_settings",
112
177
  ]
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env python3
2
+ """Tier-usage report — aggregate the local tier-usage log into a frequency table.
3
+
4
+ Phase 5 Step 3 of road-to-surface-discipline. Reads the JSONL log
5
+ written by the dispatcher (default ``.agent-tier-usage.jsonl``; override
6
+ via ``telemetry.tier_usage.output.path``) and emits a per-command
7
+ frequency table grouped by tier, plus distinct ``user_hash`` counts.
8
+ Run-local-only; no upload, no remote aggregation.
9
+
10
+ Privacy floor mirrors the contract in
11
+ ``docs/contracts/command-clusters.md#tier-usage-signal-contract`` and
12
+ the four-layer enforcement model used by artefact-engagement telemetry.
13
+ Records that carry any field outside the contract whitelist are dropped
14
+ at the read gate — the report refuses to render leaked shapes rather
15
+ than re-emit them.
16
+
17
+ Usage:
18
+ python3 tier_usage_report.py # last 30d, table
19
+ python3 tier_usage_report.py --window-days 7 # last 7d
20
+ python3 tier_usage_report.py --window-days 0 # full log
21
+ python3 tier_usage_report.py --json # JSON for tooling
22
+ python3 tier_usage_report.py --log-path X.jsonl # archived snapshot
23
+
24
+ Exit codes:
25
+ 0 success or telemetry disabled (single header line)
26
+ 1 no records survived the privacy floor on a non-empty file
27
+ 2 IO error (permission denied; passed path missing)
28
+ """
29
+ from __future__ import annotations
30
+
31
+ import argparse
32
+ import json
33
+ import sys
34
+ from collections import defaultdict
35
+ from datetime import datetime, timedelta, timezone
36
+ from pathlib import Path
37
+ from typing import Any
38
+
39
+ from telemetry.settings import DEFAULT_TIER_USAGE_LOG_PATH, read_tier_usage_settings
40
+
41
+ #: Contract whitelist (see ``docs/contracts/command-clusters.md``).
42
+ ALLOWED_FIELDS = frozenset({"ts_bucket", "command", "tier", "outcome", "user_hash"})
43
+ ALLOWED_OUTCOMES = frozenset({"success", "error", "blocked"})
44
+
45
+
46
+ def _parse_record(raw: str) -> dict[str, Any] | None:
47
+ """Return a sanitized record or ``None`` when the line violates the floor."""
48
+ try:
49
+ obj = json.loads(raw)
50
+ except json.JSONDecodeError:
51
+ return None
52
+ if not isinstance(obj, dict):
53
+ return None
54
+ if not set(obj.keys()).issubset(ALLOWED_FIELDS):
55
+ return None
56
+ cmd = obj.get("command")
57
+ if not isinstance(cmd, str) or not cmd or "/" in cmd or "\\" in cmd:
58
+ return None
59
+ if not isinstance(obj.get("tier"), int) or obj["tier"] not in (0, 1, 2, 3):
60
+ return None
61
+ if obj.get("outcome") not in ALLOWED_OUTCOMES:
62
+ return None
63
+ uh = obj.get("user_hash")
64
+ if not isinstance(uh, str) or len(uh) != 16:
65
+ return None
66
+ if not isinstance(obj.get("ts_bucket"), str):
67
+ return None
68
+ return obj
69
+
70
+
71
+ def _within_window(ts_bucket: str, window_days: int | None) -> bool:
72
+ if window_days is None or window_days == 0:
73
+ return True
74
+ try:
75
+ ts = datetime.fromisoformat(ts_bucket.replace("Z", "+00:00"))
76
+ except ValueError:
77
+ return False
78
+ if ts.tzinfo is None:
79
+ ts = ts.replace(tzinfo=timezone.utc)
80
+ return ts >= datetime.now(timezone.utc) - timedelta(days=window_days)
81
+
82
+
83
+ def aggregate(
84
+ log_path: Path, window_days: int,
85
+ ) -> tuple[dict[tuple[int, str], dict[str, Any]], int, int]:
86
+ """Return ``((tier, command) -> stats, total_lines, kept)`` over the window."""
87
+ buckets: dict[tuple[int, str], dict[str, Any]] = defaultdict(
88
+ lambda: {"count": 0, "users": set()},
89
+ )
90
+ total = 0
91
+ kept = 0
92
+ if not log_path.exists():
93
+ return {}, 0, 0
94
+ with log_path.open("r", encoding="utf-8") as fh:
95
+ for line in fh:
96
+ line = line.strip()
97
+ if not line:
98
+ continue
99
+ total += 1
100
+ rec = _parse_record(line)
101
+ if rec is None:
102
+ continue
103
+ if not _within_window(rec["ts_bucket"], window_days):
104
+ continue
105
+ kept += 1
106
+ key = (int(rec["tier"]), rec["command"])
107
+ buckets[key]["count"] += 1
108
+ buckets[key]["users"].add(rec["user_hash"])
109
+ out = {k: {"count": v["count"], "distinct_users": len(v["users"])}
110
+ for k, v in buckets.items()}
111
+ return out, total, kept
112
+
113
+
114
+ def render(
115
+ table: dict[tuple[int, str], dict[str, Any]],
116
+ window_days: int,
117
+ ) -> str:
118
+ suffix = f" (last {window_days}d)" if window_days else " (full log)"
119
+ if not table:
120
+ return f"(no tier-usage records{suffix})\n"
121
+ rows = sorted(table.items(), key=lambda kv: (kv[0][0], -kv[1]["count"], kv[0][1]))
122
+ header = f"{'Tier':<6}{'Command':<32}{'Calls':>8}{'Users':>8}"
123
+ lines = [header, "-" * len(header)]
124
+ for (tier, command), stats in rows:
125
+ lines.append(
126
+ f"{tier:<6}{command:<32}{stats['count']:>8}{stats['distinct_users']:>8}",
127
+ )
128
+ lines.append(f"\n(window:{suffix.strip()})")
129
+ return "\n".join(lines) + "\n"
130
+
131
+
132
+ def main(argv: list[str] | None = None) -> int:
133
+ parser = argparse.ArgumentParser(description="Tier-usage frequency report.")
134
+ parser.add_argument("--window-days", type=int, default=30,
135
+ help="trailing window in days (0 = full log)")
136
+ parser.add_argument("--json", action="store_true",
137
+ help="emit JSON instead of the table")
138
+ parser.add_argument("--log-path", type=Path, default=None,
139
+ help="override settings; read an archived log")
140
+ parser.add_argument("--settings-file", type=Path, default=Path(".agent-settings.yml"))
141
+ args = parser.parse_args(argv)
142
+
143
+ settings = read_tier_usage_settings(args.settings_file)
144
+ log_path = args.log_path or settings.log_path or DEFAULT_TIER_USAGE_LOG_PATH
145
+
146
+ if args.log_path is None and not settings.enabled:
147
+ sys.stdout.write(
148
+ "(tier-usage telemetry disabled; set "
149
+ "`telemetry.tier_usage.enabled: true` in .agent-settings.yml)\n",
150
+ )
151
+ return 0
152
+
153
+ try:
154
+ table, total, kept = aggregate(log_path, args.window_days)
155
+ except OSError as exc:
156
+ print(f"❌ {exc}", file=sys.stderr)
157
+ return 2
158
+
159
+ if total > 0 and kept == 0:
160
+ print(f"❌ {total} record(s) read; 0 survived the privacy floor — "
161
+ "report refused", file=sys.stderr)
162
+ return 1
163
+
164
+ if args.json:
165
+ payload = {
166
+ "window_days": args.window_days,
167
+ "log_path": str(log_path),
168
+ "records_total": total,
169
+ "records_kept": kept,
170
+ "rows": [
171
+ {"tier": t, "command": c, "count": v["count"],
172
+ "distinct_users": v["distinct_users"]}
173
+ for (t, c), v in sorted(table.items(), key=lambda kv: (kv[0][0], kv[0][1]))
174
+ ],
175
+ }
176
+ sys.stdout.write(json.dumps(payload, indent=2) + "\n")
177
+ else:
178
+ sys.stdout.write(render(table, args.window_days))
179
+ return 0
180
+
181
+
182
+ if __name__ == "__main__":
183
+ sys.exit(main())
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Shared agent configuration \u2014 skills for AI coding tools (Claude Code, Augment, Cursor, Cline, Windsurf, Gemini CLI).",
9
- "version": "2.8.0",
9
+ "version": "2.9.0",
10
10
  "keywords": [
11
11
  "agent-config",
12
12
  "skills",
@@ -70,6 +70,7 @@
70
70
  "./.claude/skills/bug-analyzer",
71
71
  "./.claude/skills/bug-fix",
72
72
  "./.claude/skills/bug-investigate",
73
+ "./.claude/skills/build-buy-partner",
73
74
  "./.claude/skills/challenge-me",
74
75
  "./.claude/skills/challenge-me-vision",
75
76
  "./.claude/skills/challenge-me-with-docs",
@@ -86,6 +87,8 @@
86
87
  "./.claude/skills/command-writing",
87
88
  "./.claude/skills/commit",
88
89
  "./.claude/skills/commit-in-chunks",
90
+ "./.claude/skills/comp-banding",
91
+ "./.claude/skills/competitive-moat-analysis",
89
92
  "./.claude/skills/competitive-positioning",
90
93
  "./.claude/skills/composer-packages",
91
94
  "./.claude/skills/compress",
@@ -95,6 +98,7 @@
95
98
  "./.claude/skills/context-create",
96
99
  "./.claude/skills/context-document",
97
100
  "./.claude/skills/context-refactor",
101
+ "./.claude/skills/contracts-cognition",
98
102
  "./.claude/skills/conventional-commits-writing",
99
103
  "./.claude/skills/copilot-agents-optimization",
100
104
  "./.claude/skills/copilot-config",
@@ -109,6 +113,7 @@
109
113
  "./.claude/skills/customer-research",
110
114
  "./.claude/skills/dashboard-design",
111
115
  "./.claude/skills/data-flow-mapper",
116
+ "./.claude/skills/data-handling-judgment",
112
117
  "./.claude/skills/database",
113
118
  "./.claude/skills/dcf-modeling",
114
119
  "./.claude/skills/deal-qualification-meddic",
@@ -151,6 +156,7 @@
151
156
  "./.claude/skills/fix-seeder",
152
157
  "./.claude/skills/flux",
153
158
  "./.claude/skills/forecast-accuracy",
159
+ "./.claude/skills/forecasting",
154
160
  "./.claude/skills/form-handler",
155
161
  "./.claude/skills/fundraising-narrative",
156
162
  "./.claude/skills/funnel-analysis",
@@ -160,6 +166,7 @@
160
166
  "./.claude/skills/grill-me",
161
167
  "./.claude/skills/gtm-launch",
162
168
  "./.claude/skills/guideline-writing",
169
+ "./.claude/skills/hiring-loop-design",
163
170
  "./.claude/skills/implement-ticket",
164
171
  "./.claude/skills/incident-commander",
165
172
  "./.claude/skills/jira-integration",
@@ -189,6 +196,7 @@
189
196
  "./.claude/skills/livewire",
190
197
  "./.claude/skills/livewire-architect",
191
198
  "./.claude/skills/logging-monitoring",
199
+ "./.claude/skills/market-entry-analysis",
192
200
  "./.claude/skills/markitdown",
193
201
  "./.claude/skills/mcp",
194
202
  "./.claude/skills/mcp-builder",
@@ -214,6 +222,8 @@
214
222
  "./.claude/skills/okr-tree-modeling",
215
223
  "./.claude/skills/onboard",
216
224
  "./.claude/skills/onboarding-design",
225
+ "./.claude/skills/onboarding-program",
226
+ "./.claude/skills/one-on-one-cadence",
217
227
  "./.claude/skills/openapi",
218
228
  "./.claude/skills/optimize",
219
229
  "./.claude/skills/optimize-agents-dir",
@@ -222,12 +232,14 @@
222
232
  "./.claude/skills/optimize-rtk",
223
233
  "./.claude/skills/optimize-skills",
224
234
  "./.claude/skills/orchestrate",
235
+ "./.claude/skills/org-design",
225
236
  "./.claude/skills/override",
226
237
  "./.claude/skills/override-create",
227
238
  "./.claude/skills/override-manage",
228
239
  "./.claude/skills/override-management",
229
240
  "./.claude/skills/package-reset",
230
241
  "./.claude/skills/package-test",
242
+ "./.claude/skills/perf-feedback-craft",
231
243
  "./.claude/skills/performance",
232
244
  "./.claude/skills/performance-analysis",
233
245
  "./.claude/skills/persona-writing",
@@ -241,6 +253,7 @@
241
253
  "./.claude/skills/po-discovery",
242
254
  "./.claude/skills/positioning-strategy",
243
255
  "./.claude/skills/prepare-for-review",
256
+ "./.claude/skills/privacy-review",
244
257
  "./.claude/skills/project-analysis-core",
245
258
  "./.claude/skills/project-analysis-hypothesis-driven",
246
259
  "./.claude/skills/project-analysis-laravel",
@@ -287,6 +300,8 @@
287
300
  "./.claude/skills/rtk-output-filtering",
288
301
  "./.claude/skills/rule-compliance-audit",
289
302
  "./.claude/skills/rule-writing",
303
+ "./.claude/skills/runway-cognition",
304
+ "./.claude/skills/scenario-modeling",
290
305
  "./.claude/skills/script-writing",
291
306
  "./.claude/skills/secrets-management",
292
307
  "./.claude/skills/security",
@@ -318,6 +333,7 @@
318
333
  "./.claude/skills/tests-execute",
319
334
  "./.claude/skills/threat-model",
320
335
  "./.claude/skills/threat-modeling",
336
+ "./.claude/skills/throughput-vs-morale-tradeoff",
321
337
  "./.claude/skills/token-optimizer",
322
338
  "./.claude/skills/traefik",
323
339
  "./.claude/skills/ui-component-architect",
@@ -328,6 +344,7 @@
328
344
  "./.claude/skills/using-git-worktrees",
329
345
  "./.claude/skills/validate-feature-fit",
330
346
  "./.claude/skills/verify-completion-evidence",
347
+ "./.claude/skills/vision-articulation",
331
348
  "./.claude/skills/voc-extract",
332
349
  "./.claude/skills/voice-and-tone-design",
333
350
  "./.claude/skills/websocket",
package/AGENTS.md CHANGED
@@ -20,7 +20,7 @@ task ci # full pipeline — green before PR
20
20
  - **Kernel + Router** (beta) — 9 always-loaded Iron-Law rules, tier-1 / tier-2 routing, cost profiles, per-rule char caps enforced by `task lint-rule-budget`: [`kernel-membership`](docs/contracts/kernel-membership.md) + [`rule-router`](docs/contracts/rule-router.md).
21
21
  - **Content pipelines** — A [compression](docs/architecture/compression.md), B [Augment projection](docs/architecture/augment-projection.md), C [multi-tool projection](docs/architecture/multi-tool-projection.md), D [Claude.ai bundle](docs/architecture/claude-bundle.md). Index: [`docs/architecture.md`](docs/architecture.md).
22
22
  - **Editing this repo** — Iron-Law rules (portability, source-of-truth, skill-quality) + Thin-Root contract: [`augment-portability`](.agent-src/rules/augment-portability.md), [`augment-source-of-truth`](.agent-src/rules/augment-source-of-truth.md), [`skill-quality`](.agent-src/rules/skill-quality.md), [`agents-md-thin-root`](.agent-src/skills/agents-md-thin-root/SKILL.md).
23
- - **Consumer story** — `npm install` + `scripts/install.sh` + `.agent-settings.yml` opt-in flags, sandbox/offline install paths, verified-offline manifest: [`README.md`](README.md).
23
+ - **Consumer story** — `npx` + `scripts/install.sh` + `.agent-settings.yml` opt-in flags, sandbox/offline install paths, verified-offline manifest: [`README.md`](README.md).
24
24
  - **Personas** — 11 review-lens cast (6 core · 5 specialist), `personas:` vs `/mode` axes, citation map, override pattern: [`docs/personas.md`](docs/personas.md), schema [`docs/contracts/persona-schema.md`](docs/contracts/persona-schema.md) (beta).
25
25
 
26
26
  ## Emergency triage — read this when nothing else is reachable