@event4u/agent-config 2.18.0 → 2.20.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 (108) hide show
  1. package/.agent-src/commands/agent-status.md +29 -0
  2. package/.agent-src/commands/onboard.md +221 -81
  3. package/.agent-src/commands/refine-ticket.md +3 -0
  4. package/.agent-src/packs/README.md +49 -0
  5. package/.agent-src/packs/agency-delivery.yml +63 -0
  6. package/.agent-src/packs/content-engine.yml +53 -0
  7. package/.agent-src/packs/founder-mvp.yml +51 -0
  8. package/.agent-src/personas/README.md +8 -0
  9. package/.agent-src/presets/README.md +26 -0
  10. package/.agent-src/presets/balanced.yml +34 -0
  11. package/.agent-src/presets/fast.yml +31 -0
  12. package/.agent-src/presets/strict.yml +38 -0
  13. package/.agent-src/profiles/README.md +29 -0
  14. package/.agent-src/profiles/agency.yml +27 -0
  15. package/.agent-src/profiles/content_creator.yml +25 -0
  16. package/.agent-src/profiles/developer.yml +26 -0
  17. package/.agent-src/profiles/finance.yml +24 -0
  18. package/.agent-src/profiles/founder.yml +25 -0
  19. package/.agent-src/profiles/ops.yml +25 -0
  20. package/.agent-src/rules/no-cheap-questions.md +25 -17
  21. package/.agent-src/skills/adr-create/SKILL.md +78 -68
  22. package/.agent-src/skills/refine-ticket/SKILL.md +3 -0
  23. package/.agent-src/skills/subagent-orchestration/SKILL.md +33 -0
  24. package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  25. package/.agent-src/templates/skill-archive-note.md +101 -0
  26. package/.agent-src/user-types/README.md +124 -0
  27. package/.agent-src/user-types/_template/user-type.md +95 -0
  28. package/.agent-src/user-types/galabau-field-crew.md +100 -0
  29. package/.agent-src/user-types/metalworking-shop.md +105 -0
  30. package/.agent-src/user-types/truck-driver.md +113 -0
  31. package/.claude-plugin/marketplace.json +1 -1
  32. package/CHANGELOG.md +91 -30
  33. package/README.md +68 -72
  34. package/config/agent-settings.template.yml +22 -0
  35. package/docs/adrs/caveman/0001-default-off-until-bench.md +93 -0
  36. package/docs/adrs/caveman/README.md +9 -0
  37. package/docs/adrs/cost/0001-hard-stop-hook.md +114 -0
  38. package/docs/adrs/cost/README.md +9 -0
  39. package/docs/adrs/memory/0001-consumer-side-snapshot.md +111 -0
  40. package/docs/adrs/memory/README.md +9 -0
  41. package/docs/adrs/router/0001-three-tier-routing.md +119 -0
  42. package/docs/adrs/router/README.md +9 -0
  43. package/docs/adrs/schema/0001-json-schema-frontmatter.md +102 -0
  44. package/docs/adrs/schema/README.md +9 -0
  45. package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +99 -0
  46. package/docs/adrs/smoke/README.md +9 -0
  47. package/docs/architecture/current-onboard-baseline.md +126 -0
  48. package/docs/architecture/current-safety-behavior.md +137 -0
  49. package/docs/archive/CHANGELOG-pre-2.16.0.md +48 -0
  50. package/docs/contracts/adr-layout.md +108 -0
  51. package/docs/contracts/adr-mcp-runtime.md +128 -0
  52. package/docs/contracts/adr-user-types-axis.md +127 -0
  53. package/docs/contracts/benchmark-corpus-spec.md +97 -0
  54. package/docs/contracts/benchmark-report-schema.md +111 -0
  55. package/docs/contracts/command-clusters.md +1 -0
  56. package/docs/contracts/command-taxonomy.md +137 -0
  57. package/docs/contracts/compression-default-kill-criterion.md +69 -0
  58. package/docs/contracts/config-presets.md +144 -0
  59. package/docs/contracts/cost-dashboard.md +143 -0
  60. package/docs/contracts/cost-enforcement.md +134 -0
  61. package/docs/contracts/file-ownership-matrix.json +0 -7
  62. package/docs/contracts/mcp-tool-inventory.md +53 -0
  63. package/docs/contracts/measurement-baseline.md +102 -0
  64. package/docs/contracts/namespace.md +125 -0
  65. package/docs/contracts/profile-system.md +142 -0
  66. package/docs/contracts/safety-model.md +129 -0
  67. package/docs/contracts/smoke-contracts.md +144 -0
  68. package/docs/contracts/user-type-schema.md +146 -0
  69. package/docs/contracts/workflow-packs.md +121 -0
  70. package/docs/decisions/ADR-010-profile-pack-preset-boundary.md +132 -0
  71. package/docs/decisions/INDEX.md +1 -0
  72. package/docs/featured-commands.md +27 -0
  73. package/docs/parity/bench-ruflo.json +58 -0
  74. package/docs/parity/bench.json +41 -0
  75. package/docs/parity/ruflo.md +46 -0
  76. package/docs/profiles.md +91 -0
  77. package/docs/recruits/_template.md +81 -0
  78. package/package.json +1 -1
  79. package/scripts/_cli/cmd_explain.py +250 -0
  80. package/scripts/_lib/bench_cost.py +138 -0
  81. package/scripts/_lib/bench_quality.py +118 -0
  82. package/scripts/_lib/bench_report.py +150 -0
  83. package/scripts/agent-config +13 -0
  84. package/scripts/audit_adr_coverage.py +175 -0
  85. package/scripts/audit_mcp_tools.py +146 -0
  86. package/scripts/bench_baseline_ready.py +108 -0
  87. package/scripts/bench_drift_check.py +151 -0
  88. package/scripts/bench_per_tool.py +216 -0
  89. package/scripts/bench_run.py +155 -0
  90. package/scripts/compress.py +48 -2
  91. package/scripts/config/__init__.py +9 -0
  92. package/scripts/config/presets.py +206 -0
  93. package/scripts/config/profiles.py +173 -0
  94. package/scripts/cost/budget.mjs +73 -12
  95. package/scripts/cost/preflight.mjs +89 -0
  96. package/scripts/lint_archived_skills.py +143 -0
  97. package/scripts/lint_bench_corpus.py +161 -0
  98. package/scripts/lint_namespace.py +135 -0
  99. package/scripts/schemas/user-type.schema.json +35 -0
  100. package/scripts/skill_linter.py +139 -4
  101. package/scripts/skill_overlap.py +204 -0
  102. package/scripts/skill_tools/audit_user_type_coverage.py +148 -0
  103. package/scripts/skill_usage_collect.py +191 -0
  104. package/scripts/skill_usage_report.py +162 -0
  105. package/scripts/smoke/kernel.sh +101 -0
  106. package/scripts/smoke/router.sh +129 -0
  107. package/scripts/smoke/schema.sh +71 -0
  108. package/scripts/smoke/skills.sh +101 -0
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env bash
2
+ # scripts/smoke/router.sh — router-tier smoke (step-11 Phase 3 Step 3).
3
+ #
4
+ # Asserts router.json structural integrity:
5
+ # 1. 75 ids = 9 kernel + 24 tier_1 + 42 tier_2 (locked count).
6
+ # 2. Every id resolves to .agent-src/rules/<id>.md (0 broken).
7
+ # 3. Every routes_to ref resolves through its prefix
8
+ # (skill:, command:, guideline:, contract:); missing-contract
9
+ # count locked at ≤ EXPECTED_MISSING_CONTRACTS.
10
+ #
11
+ # Runtime ceiling: 30 s.
12
+ # Output: table by default, baseline line on stdout last; SMOKE_QUIET=1
13
+ # suppresses the table.
14
+ # Contract: docs/contracts/smoke-contracts.md § 3.2
15
+
16
+ set -euo pipefail
17
+
18
+ EXPECTED_TOTAL_IDS=75
19
+ EXPECTED_MISSING_CONTRACTS=2
20
+
21
+ quiet="${SMOKE_QUIET:-0}"
22
+ log() { [ "$quiet" = "1" ] || printf '%s\n' "$*"; }
23
+
24
+ result=$(python3 <<'PY'
25
+ import json, os, sys, pathlib
26
+
27
+ d = json.load(open("router.json"))
28
+ kernel = d.get("kernel", [])
29
+ tier1 = d.get("tier_1", [])
30
+ tier2 = d.get("tier_2", [])
31
+ ids = list(kernel) + [r["id"] for r in tier1] + [r["id"] for r in tier2]
32
+ total = len(ids)
33
+
34
+ # Rule-file resolution
35
+ missing_rules = [i for i in ids if not os.path.exists(f".agent-src/rules/{i}.md")]
36
+
37
+ # routes_to resolution
38
+ def resolve(ref):
39
+ if ":" not in ref:
40
+ return f".agent-src.uncompressed/skills/{ref}/SKILL.md", "skill"
41
+ kind, rest = ref.split(":", 1)
42
+ if kind == "skill":
43
+ return f".agent-src.uncompressed/skills/{rest}/SKILL.md", "skill"
44
+ if kind == "command":
45
+ for p in (
46
+ f".agent-src.uncompressed/commands/{rest}.md",
47
+ f".agent-src.uncompressed/commands/{rest}/INDEX.md",
48
+ ):
49
+ if os.path.exists(p):
50
+ return p, "command"
51
+ return f".agent-src.uncompressed/commands/{rest}.md", "command"
52
+ if kind == "guideline":
53
+ return f"docs/guidelines/{rest}.md", "guideline"
54
+ if kind == "contract":
55
+ return f"docs/contracts/{rest}.md", "contract"
56
+ return None, kind
57
+
58
+ refs = set()
59
+ for r in tier1 + tier2:
60
+ for ref in r.get("routes_to", []):
61
+ refs.add(ref)
62
+
63
+ missing_by_kind = {"skill": [], "command": [], "guideline": [], "contract": []}
64
+ for ref in refs:
65
+ path, kind = resolve(ref)
66
+ if path is None or not os.path.exists(path):
67
+ missing_by_kind.setdefault(kind, []).append(ref)
68
+
69
+ print(f"TOTAL_IDS={total}")
70
+ print(f"KERNEL={len(kernel)}")
71
+ print(f"TIER1={len(tier1)}")
72
+ print(f"TIER2={len(tier2)}")
73
+ print(f"MISSING_RULES={len(missing_rules)}")
74
+ print(f"ROUTES_TO_REFS={len(refs)}")
75
+ for kind, items in missing_by_kind.items():
76
+ print(f"MISSING_{kind.upper()}={len(items)}")
77
+ for r in items:
78
+ print(f" - {kind}: {r}")
79
+ PY
80
+ )
81
+
82
+ # Parse out the counters
83
+ TOTAL_IDS=$(echo "$result" | grep '^TOTAL_IDS=' | cut -d= -f2)
84
+ KERNEL=$(echo "$result" | grep '^KERNEL=' | cut -d= -f2)
85
+ TIER1=$(echo "$result" | grep '^TIER1=' | cut -d= -f2)
86
+ TIER2=$(echo "$result" | grep '^TIER2=' | cut -d= -f2)
87
+ MISSING_RULES=$(echo "$result" | grep '^MISSING_RULES=' | cut -d= -f2)
88
+ ROUTES_TO_REFS=$(echo "$result" | grep '^ROUTES_TO_REFS=' | cut -d= -f2)
89
+ MISSING_SKILL=$(echo "$result" | grep '^MISSING_SKILL=' | cut -d= -f2)
90
+ MISSING_COMMAND=$(echo "$result" | grep '^MISSING_COMMAND=' | cut -d= -f2)
91
+ MISSING_GUIDELINE=$(echo "$result" | grep '^MISSING_GUIDELINE=' | cut -d= -f2)
92
+ MISSING_CONTRACT=$(echo "$result" | grep '^MISSING_CONTRACT=' | cut -d= -f2)
93
+
94
+ log "## Router smoke"
95
+ log ""
96
+ log "| Check | Value |"
97
+ log "|---|---:|"
98
+ log "| Total router ids | $TOTAL_IDS (kernel $KERNEL · tier_1 $TIER1 · tier_2 $TIER2) |"
99
+ log "| Broken rule pointers | $MISSING_RULES |"
100
+ log "| routes_to refs | $ROUTES_TO_REFS |"
101
+ log "| missing skill targets | $MISSING_SKILL |"
102
+ log "| missing command targets | $MISSING_COMMAND |"
103
+ log "| missing guideline targets | $MISSING_GUIDELINE |"
104
+ log "| missing contract targets | $MISSING_CONTRACT (locked ≤ $EXPECTED_MISSING_CONTRACTS) |"
105
+
106
+ fail=0
107
+ if [ "$TOTAL_IDS" -ne "$EXPECTED_TOTAL_IDS" ]; then
108
+ echo "ℹ️ router id count drifted: $TOTAL_IDS (was $EXPECTED_TOTAL_IDS)"
109
+ fi
110
+ if [ "$MISSING_RULES" -gt 0 ]; then
111
+ echo "❌ broken rule pointers: $MISSING_RULES"
112
+ echo "$result" | grep '^ - skill:\|^ - guideline:' || true
113
+ fail=1
114
+ fi
115
+ if [ "$MISSING_SKILL" -gt 0 ] || [ "$MISSING_COMMAND" -gt 0 ] || [ "$MISSING_GUIDELINE" -gt 0 ]; then
116
+ echo "❌ broken routes_to targets:"
117
+ echo "$result" | grep -E '^ - (skill|command|guideline):' || true
118
+ fail=1
119
+ fi
120
+ if [ "$MISSING_CONTRACT" -gt "$EXPECTED_MISSING_CONTRACTS" ]; then
121
+ echo "❌ missing contracts: $MISSING_CONTRACT > $EXPECTED_MISSING_CONTRACTS (regression)"
122
+ echo "$result" | grep '^ - contract:' || true
123
+ fail=1
124
+ fi
125
+
126
+ log ""
127
+ echo "BASELINE: $TOTAL_IDS router ids · $MISSING_RULES broken rule pointers · $ROUTES_TO_REFS routes_to refs · $MISSING_CONTRACT missing contracts"
128
+
129
+ exit $fail
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+ # scripts/smoke/schema.sh — schema-tier smoke (step-11 Phase 3 Step 4).
3
+ #
4
+ # Runs scripts/skill_linter.py --all over every lintable artefact and
5
+ # asserts:
6
+ # 1. 0 schema FAILs (hard).
7
+ # 2. Warns ≤ EXPECTED_WARNS (regression lock).
8
+ # 3. Total ≥ EXPECTED_MIN_TOTAL (catches accidental skill deletion).
9
+ #
10
+ # v2 schema (step-5) fields are deferred — when step-5 Phase 1 closes,
11
+ # this smoke gains a `model_tier` presence check; Phase 3 adds
12
+ # `schema_version: "2"`. See docs/contracts/smoke-contracts.md § 3.3.
13
+ #
14
+ # Runtime ceiling: 30 s.
15
+ # Output: table by default, baseline line on stdout last; SMOKE_QUIET=1
16
+ # suppresses the table.
17
+ # Contract: docs/contracts/smoke-contracts.md § 3.3
18
+
19
+ set -euo pipefail
20
+
21
+ EXPECTED_WARNS=92
22
+ EXPECTED_MIN_TOTAL=438
23
+
24
+ quiet="${SMOKE_QUIET:-0}"
25
+ log() { [ "$quiet" = "1" ] || printf '%s\n' "$*"; }
26
+
27
+ # Run the linter and capture summary
28
+ out=$(python3 scripts/skill_linter.py --all --quiet 2>&1 || true)
29
+ summary=$(printf '%s\n' "$out" | grep -E '^Summary: ' | tail -1)
30
+
31
+ if [ -z "$summary" ]; then
32
+ echo "❌ skill_linter.py produced no summary line"
33
+ printf '%s\n' "$out" | tail -5
34
+ exit 1
35
+ fi
36
+
37
+ # Parse: "Summary: 346 pass, 92 warn, 0 fail, 438 total"
38
+ pass=$(echo "$summary" | sed -E 's/.*Summary: ([0-9]+) pass.*/\1/')
39
+ warn=$(echo "$summary" | sed -E 's/.*, ([0-9]+) warn.*/\1/')
40
+ fail=$(echo "$summary" | sed -E 's/.*, ([0-9]+) fail.*/\1/')
41
+ total=$(echo "$summary" | sed -E 's/.*, ([0-9]+) total.*/\1/')
42
+
43
+ log "## Schema smoke"
44
+ log ""
45
+ log "| Check | Value |"
46
+ log "|---|---:|"
47
+ log "| Total artefacts | $total (≥ $EXPECTED_MIN_TOTAL) |"
48
+ log "| Pass | $pass |"
49
+ log "| Warn | $warn (locked ≤ $EXPECTED_WARNS) |"
50
+ log "| Fail | $fail (hard 0) |"
51
+ log "| v2 schema enforcement | deferred (see step-5-schema-rigor.md) |"
52
+
53
+ exit_code=0
54
+ if [ "$fail" -gt 0 ]; then
55
+ echo "❌ schema FAILs: $fail (must be 0)"
56
+ printf '%s\n' "$out" | grep -E '^\[FAIL\]' | head -10 || true
57
+ exit_code=1
58
+ fi
59
+ if [ "$warn" -gt "$EXPECTED_WARNS" ]; then
60
+ echo "❌ schema warns: $warn > $EXPECTED_WARNS (regression)"
61
+ exit_code=1
62
+ fi
63
+ if [ "$total" -lt "$EXPECTED_MIN_TOTAL" ]; then
64
+ echo "❌ artefact total $total < $EXPECTED_MIN_TOTAL (unexpected deletion?)"
65
+ exit_code=1
66
+ fi
67
+
68
+ log ""
69
+ echo "BASELINE: $total lintable artefacts · $fail schema FAIL(s) · $warn warn(s)"
70
+
71
+ exit $exit_code
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env bash
2
+ # scripts/smoke/skills.sh — skills-tier smoke (step-11 Phase 3 Step 5).
3
+ #
4
+ # Picks 5 random skills (deterministic seed = epoch day) from
5
+ # .agent-src.uncompressed/skills/*/SKILL.md and asserts:
6
+ # 1. SKILL.md exists.
7
+ # 2. Frontmatter parses + validates against scripts/schemas/skill.schema.json.
8
+ # 3. `name:` field matches the parent directory name.
9
+ # 4. Total skill count ≥ EXPECTED_MIN_SKILLS (regression lock against
10
+ # accidental directory removal).
11
+ #
12
+ # Runtime ceiling: 30 s.
13
+ # Output: table by default, baseline line on stdout last; SMOKE_QUIET=1
14
+ # suppresses the table.
15
+ # Contract: docs/contracts/smoke-contracts.md § 3.4
16
+
17
+ set -euo pipefail
18
+
19
+ EXPECTED_MIN_SKILLS=205
20
+ SAMPLE_SIZE=5
21
+
22
+ quiet="${SMOKE_QUIET:-0}"
23
+ log() { [ "$quiet" = "1" ] || printf '%s\n' "$*"; }
24
+
25
+ result=$(python3 <<'PY'
26
+ import os, sys, time, hashlib, pathlib, glob
27
+ sys.path.insert(0, "scripts")
28
+ from validate_frontmatter import parse_frontmatter, load_schema, validate
29
+
30
+ root = ".agent-src.uncompressed/skills"
31
+ skills = sorted(
32
+ d for d in os.listdir(root)
33
+ if os.path.isdir(os.path.join(root, d))
34
+ and os.path.exists(os.path.join(root, d, "SKILL.md"))
35
+ )
36
+ total = len(skills)
37
+ print(f"TOTAL_SKILLS={total}")
38
+
39
+ # Deterministic seed = epoch day → same sample within 24h, drifts daily.
40
+ seed = int(time.time() // 86400)
41
+ import random
42
+ rng = random.Random(seed)
43
+ sample = rng.sample(skills, min(5, total))
44
+
45
+ schema = load_schema("skill")
46
+
47
+ failures = []
48
+ for name in sample:
49
+ path = os.path.join(root, name, "SKILL.md")
50
+ text = open(path, encoding="utf-8").read()
51
+ fm, _ = parse_frontmatter(text)
52
+ if fm is None:
53
+ failures.append(f"{name}: no frontmatter")
54
+ continue
55
+ errs = validate(fm, schema)
56
+ if errs:
57
+ for e in errs:
58
+ failures.append(f"{name}: {e.format()}")
59
+ continue
60
+ declared = fm.get("name")
61
+ if declared != name:
62
+ failures.append(f"{name}: name field='{declared}' ≠ directory='{name}'")
63
+
64
+ print(f"SAMPLE={','.join(sample)}")
65
+ print(f"SAMPLE_PASS={len(sample) - len([f for f in failures])}")
66
+ print(f"SAMPLE_TOTAL={len(sample)}")
67
+ for f in failures:
68
+ print(f" FAIL: {f}")
69
+ PY
70
+ )
71
+
72
+ TOTAL_SKILLS=$(echo "$result" | grep '^TOTAL_SKILLS=' | cut -d= -f2)
73
+ SAMPLE=$(echo "$result" | grep '^SAMPLE=' | cut -d= -f2)
74
+ SAMPLE_PASS=$(echo "$result" | grep '^SAMPLE_PASS=' | cut -d= -f2)
75
+ SAMPLE_TOTAL=$(echo "$result" | grep '^SAMPLE_TOTAL=' | cut -d= -f2)
76
+ FAILS=$(echo "$result" | grep -c '^ FAIL:' || true)
77
+
78
+ log "## Skills smoke"
79
+ log ""
80
+ log "| Check | Value |"
81
+ log "|---|---:|"
82
+ log "| Total skills | $TOTAL_SKILLS (≥ $EXPECTED_MIN_SKILLS) |"
83
+ log "| Sample size | $SAMPLE_TOTAL |"
84
+ log "| Sample (epoch-day seed) | $SAMPLE |"
85
+ log "| Sample pass | $SAMPLE_PASS/$SAMPLE_TOTAL |"
86
+
87
+ exit_code=0
88
+ if [ "$TOTAL_SKILLS" -lt "$EXPECTED_MIN_SKILLS" ]; then
89
+ echo "❌ skill count $TOTAL_SKILLS < $EXPECTED_MIN_SKILLS (unexpected deletion?)"
90
+ exit_code=1
91
+ fi
92
+ if [ "$FAILS" -gt 0 ]; then
93
+ echo "❌ sample failures:"
94
+ echo "$result" | grep '^ FAIL:'
95
+ exit_code=1
96
+ fi
97
+
98
+ log ""
99
+ echo "BASELINE: $TOTAL_SKILLS skills · $SAMPLE_PASS/$SAMPLE_TOTAL random sample passes (seed=epoch-day)"
100
+
101
+ exit $exit_code