@event4u/agent-config 2.24.0 → 2.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent-src/commands/bug-fix.md +1 -0
- package/.agent-src/commands/create-pr/description-only.md +39 -11
- package/.agent-src/commands/create-pr.md +59 -5
- package/.agent-src/commands/feature/roadmap.md +2 -2
- package/.agent-src/commands/fix/seeder.md +3 -2
- package/.agent-src/commands/memory/add.md +3 -3
- package/.agent-src/commands/module/create.md +1 -0
- package/.agent-src/commands/module/explore.md +10 -6
- package/.agent-src/commands/onboard.md +9 -1
- package/.agent-src/commands/optimize/augmentignore.md +52 -20
- package/.agent-src/commands/optimize/rtk.md +56 -30
- package/.agent-src/commands/package-test.md +86 -10
- package/.agent-src/commands/quality-fix.md +49 -27
- package/.agent-src/commands/update-form-request-messages.md +2 -1
- package/.agent-src/commands/video/from-script.md +5 -5
- package/.agent-src/commands/video/storyboard.md +1 -1
- package/.agent-src/contexts/augment-infrastructure.md +4 -7
- package/.agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -1
- package/.agent-src/contexts/contracts/research-schema.md +1 -1
- package/.agent-src/contexts/execution/interrupt-examples.md +34 -0
- package/.agent-src/contexts/execution/roadmap-process-loop.md +69 -14
- package/.agent-src/contexts/skills-and-commands.md +2 -2
- package/.agent-src/personas/README.md +3 -2
- package/.agent-src/personas/ai-video-technical-director.md +2 -2
- package/.agent-src/personas/hollywood-director.md +3 -3
- package/.agent-src/profiles/content_creator.yml +5 -0
- package/.agent-src/rules/architecture.md +24 -10
- package/.agent-src/rules/artifact-drafting-protocol.md +6 -0
- package/.agent-src/rules/augment-edit-discipline.md +28 -0
- package/.agent-src/rules/augment-source-of-truth.md +2 -2
- package/.agent-src/rules/autonomous-execution.md +31 -0
- package/.agent-src/rules/context-hygiene.md +1 -1
- package/.agent-src/rules/domain-adoption-policy.md +4 -5
- package/.agent-src/rules/domain-safety-disclaimer.md +114 -0
- package/.agent-src/rules/domain-safety-pii.md +142 -0
- package/.agent-src/rules/domain-safety-retention.md +86 -0
- package/.agent-src/rules/downstream-changes.md +4 -4
- package/.agent-src/rules/framework-neutrality-in-generic-skills.md +130 -0
- package/.agent-src/rules/git-history-discipline.md +99 -0
- package/.agent-src/rules/media-governance-routing.md +82 -0
- package/.agent-src/rules/minimal-safe-diff.md +6 -0
- package/.agent-src/rules/no-roadmap-references.md +4 -2
- package/.agent-src/rules/persona-governance.md +90 -0
- package/.agent-src/rules/provider-lifecycle-discipline.md +75 -0
- package/.agent-src/rules/roadmap-ci-steps-policy.md +145 -0
- package/.agent-src/rules/roadmap-progress-sync.md +11 -5
- package/.agent-src/rules/user-interrupt-priority.md +46 -0
- package/.agent-src/rules/verify-before-complete.md +11 -2
- package/.agent-src/skills/adversarial-review/SKILL.md +1 -1
- package/.agent-src/skills/ai-council/SKILL.md +1 -0
- package/.agent-src/skills/api-endpoint/SKILL.md +58 -154
- package/.agent-src/skills/api-testing/SKILL.md +11 -0
- package/.agent-src/skills/character-consistency/SKILL.md +12 -1
- package/.agent-src/skills/code-refactoring/SKILL.md +36 -30
- package/.agent-src/skills/code-review/SKILL.md +41 -36
- package/.agent-src/skills/context-authoring/SKILL.md +1 -1
- package/.agent-src/skills/dashboard-design/SKILL.md +1 -2
- package/.agent-src/skills/database/SKILL.md +8 -3
- package/.agent-src/skills/dependency-upgrade/SKILL.md +65 -19
- package/.agent-src/skills/developer-like-execution/SKILL.md +25 -14
- package/.agent-src/skills/eloquent/SKILL.md +1 -1
- package/.agent-src/skills/feature-planning/SKILL.md +1 -1
- package/.agent-src/skills/file-editor/SKILL.md +45 -19
- package/.agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
- package/.agent-src/skills/git-workflow/SKILL.md +135 -2
- package/.agent-src/skills/laravel-api-endpoint/SKILL.md +187 -0
- package/.agent-src/skills/{dto-creator → laravel-dto}/SKILL.md +5 -4
- package/.agent-src/skills/{migration-creator → laravel-migration}/SKILL.md +11 -10
- package/.agent-src/skills/laravel-reverb/SKILL.md +3 -3
- package/.agent-src/skills/{websocket → laravel-websocket}/SKILL.md +4 -3
- package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +1 -1
- package/.agent-src/skills/merge-conflicts/SKILL.md +49 -17
- package/.agent-src/skills/migration-architect/SKILL.md +6 -6
- package/.agent-src/skills/module-management/SKILL.md +1 -0
- package/.agent-src/skills/motion-choreographer/SKILL.md +12 -0
- package/.agent-src/skills/multi-tenancy/SKILL.md +15 -8
- package/.agent-src/skills/pest-testing/SKILL.md +18 -0
- package/.agent-src/skills/php-debugging/SKILL.md +28 -0
- package/.agent-src/skills/php-service/SKILL.md +3 -3
- package/.agent-src/skills/pixar-storyteller/SKILL.md +19 -6
- package/.agent-src/skills/playwright-testing/SKILL.md +16 -1
- package/.agent-src/skills/project-analyzer/SKILL.md +68 -42
- package/.agent-src/skills/readme-writing-package/SKILL.md +94 -23
- package/.agent-src/skills/roadmap-management/SKILL.md +1 -1
- package/.agent-src/skills/roadmap-writing/SKILL.md +10 -0
- package/.agent-src/skills/rtk-output-filtering/SKILL.md +23 -8
- package/.agent-src/skills/rule-refactor/SKILL.md +145 -0
- package/.agent-src/skills/rule-writing/SKILL.md +34 -8
- package/.agent-src/skills/scene-expander/SKILL.md +22 -7
- package/.agent-src/skills/security/SKILL.md +38 -29
- package/.agent-src/skills/skill-reviewer/SKILL.md +1 -1
- package/.agent-src/skills/test-driven-development/SKILL.md +4 -4
- package/.agent-src/skills/test-performance/SKILL.md +6 -5
- package/.agent-src/skills/verify-completion-evidence/SKILL.md +24 -27
- package/.agent-src/skills/video-director/SKILL.md +13 -0
- package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/.agent-src/templates/copilot-instructions.md +2 -2
- package/.agent-src/templates/roadmaps.md +16 -0
- package/.agent-src/templates/rule.md +2 -2
- package/.claude-plugin/marketplace.json +6 -4
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +80 -133
- package/README.md +6 -4
- package/config/agent-settings.template.yml +26 -0
- package/docs/architecture.md +2 -2
- package/docs/archive/CHANGELOG-pre-2.25.0.md +191 -0
- package/docs/catalog.md +20 -12
- package/docs/contracts/file-ownership-matrix.json +588 -90
- package/docs/contracts/kernel-membership.md +17 -0
- package/docs/contracts/provider-lifecycle.md +122 -0
- package/docs/contracts/smoke-contracts.md +8 -8
- package/docs/decisions/ADR-011-domain-pack-readiness.md +213 -0
- package/docs/decisions/INDEX.md +1 -0
- package/docs/getting-started-by-role.md +10 -0
- package/docs/getting-started.md +1 -1
- package/docs/guidelines/php/api-design.md +1 -1
- package/docs/guidelines/php/controllers.md +1 -1
- package/docs/guidelines/php/resources.md +1 -1
- package/docs/guidelines/php/validations.md +1 -1
- package/docs/personas.md +73 -26
- package/docs/profiles.md +9 -4
- package/package.json +1 -1
- package/scripts/_tmp_scan_framework_leakage.py +119 -0
- package/scripts/ai-video/adapters/gemini-veo.sh +5 -0
- package/scripts/ai-video/adapters/higgsfield.sh +6 -0
- package/scripts/ai-video/adapters/kling.sh +5 -0
- package/scripts/ai-video/adapters/openai-images.sh +5 -0
- package/scripts/ai-video/adapters/sora.sh +6 -0
- package/scripts/build_linear_digest.py +0 -1
- package/scripts/check_portability.py +6 -0
- package/scripts/lint_framework_leakage.py +348 -0
- package/scripts/lint_framework_leakage_allowlist.json +476 -0
- package/scripts/lint_media_policy_linkage.py +140 -0
- package/scripts/lint_persona_governance.py +164 -0
- package/scripts/lint_roadmap_ci_steps.py +182 -0
- package/scripts/measure_augment_budget.py +6 -0
- package/scripts/schemas/command.schema.json +5 -0
- package/scripts/schemas/skill.schema.json +5 -0
- package/scripts/skill_linter.py +60 -7
- package/scripts/smoke/kernel.sh +4 -4
- package/scripts/smoke/router.sh +2 -2
- package/scripts/smoke/schema.sh +1 -1
- package/.agent-src/personas/pixar-storyboard-artist.md +0 -98
- package/.agent-src/rules/agent-docs.md +0 -20
- package/.agent-src/rules/augment-portability.md +0 -23
- package/.agent-src/rules/capture-learnings.md +0 -19
- package/.agent-src/rules/docs-sync.md +0 -20
- package/.agent-src/rules/domain-safety-disclaimer-consulting.md +0 -52
- package/.agent-src/rules/domain-safety-disclaimer-financial.md +0 -54
- package/.agent-src/rules/domain-safety-disclaimer-legal.md +0 -49
- package/.agent-src/rules/domain-safety-disclaimer-medical.md +0 -56
- package/.agent-src/rules/domain-safety-export-redact.md +0 -65
- package/.agent-src/rules/domain-safety-logging-pii-floor.md +0 -55
- package/.agent-src/rules/domain-safety-pii-finance.md +0 -57
- package/.agent-src/rules/domain-safety-pii-marketing.md +0 -60
- package/.agent-src/rules/domain-safety-pii-recruiting.md +0 -56
- package/.agent-src/rules/domain-safety-pii-support.md +0 -57
- package/.agent-src/rules/domain-safety-retention-finance.md +0 -48
- package/.agent-src/rules/domain-safety-retention-support.md +0 -55
- package/.agent-src/rules/e2e-testing.md +0 -19
- package/.agent-src/rules/no-unsolicited-rebase.md +0 -107
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Lint persona governance — per-domain cap (hard) + citation floor (warn).
|
|
3
|
+
|
|
4
|
+
Enforces the mechanical checks in
|
|
5
|
+
`.agent-src.uncompressed/rules/persona-governance.md`:
|
|
6
|
+
|
|
7
|
+
1. **Per-domain cap (HARD)** — ≤ 2 active specialist personas per
|
|
8
|
+
content domain. Core-tier personas are exempt. `status:
|
|
9
|
+
deprecated` rows (if any survive a transition window) are
|
|
10
|
+
excluded from the count; the canonical path is in-commit
|
|
11
|
+
deletion, no soak window.
|
|
12
|
+
2. **Skill citation floor (WARN)** — every active specialist
|
|
13
|
+
persona SHOULD be cited by `personas: [<id>]` in at least one
|
|
14
|
+
skill SKILL.md under `.agent-src.uncompressed/skills/` or
|
|
15
|
+
`.claude/skills/`. Surfaced as a warning, never blocks CI:
|
|
16
|
+
the citation floor is enforced at PR time per the rule (a new
|
|
17
|
+
specialist MUST land with a cite); pre-existing wiring debt is
|
|
18
|
+
tracked as `--citation-debt` for the maintainer dashboard.
|
|
19
|
+
|
|
20
|
+
Schema conformance (check 4) is delegated to `lint-skills`.
|
|
21
|
+
Deprecation path (check 3) is reviewed at PR time via the table in
|
|
22
|
+
`docs/personas.md`.
|
|
23
|
+
|
|
24
|
+
Domain inference: persona ids → content domain via `DOMAIN_MAP`,
|
|
25
|
+
mirroring `persona-governance.md § Per-domain cap`. Personas absent
|
|
26
|
+
from the map are cross-cutting (uncapped).
|
|
27
|
+
|
|
28
|
+
Exit codes:
|
|
29
|
+
0 per-domain cap clean (citation warnings non-blocking)
|
|
30
|
+
1 per-domain cap violated
|
|
31
|
+
"""
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
import re
|
|
35
|
+
import sys
|
|
36
|
+
from collections import defaultdict
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
|
|
39
|
+
QUIET = "--quiet" in sys.argv
|
|
40
|
+
|
|
41
|
+
REPO = Path(__file__).resolve().parents[1]
|
|
42
|
+
PERSONA_DIR = REPO / ".agent-src.uncompressed" / "personas"
|
|
43
|
+
SKILL_ROOTS: tuple[Path, ...] = (
|
|
44
|
+
REPO / ".agent-src.uncompressed" / "skills",
|
|
45
|
+
REPO / ".claude" / "skills",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Per-domain cap — mirrors persona-governance.md § Per-domain cap.
|
|
49
|
+
# Maps persona id → content-domain bucket. Personas absent from this
|
|
50
|
+
# map are cross-cutting (uncapped) — typically singleton specialists
|
|
51
|
+
# without a domain peer (e.g. `qa`, `tech-writer`).
|
|
52
|
+
DOMAIN_MAP: dict[str, str] = {
|
|
53
|
+
"hollywood-director": "ai-video",
|
|
54
|
+
"ai-video-technical-director": "ai-video",
|
|
55
|
+
"backend-architect": "backend",
|
|
56
|
+
"eloquent-tamer": "backend",
|
|
57
|
+
"cmo": "gtm",
|
|
58
|
+
"revops": "gtm",
|
|
59
|
+
"growth-pm": "growth",
|
|
60
|
+
"customer-success-lead": "customer",
|
|
61
|
+
"discovery-lead": "customer",
|
|
62
|
+
"engineering-manager": "people",
|
|
63
|
+
"people-strategist": "people",
|
|
64
|
+
"finance-partner": "money",
|
|
65
|
+
"strategist": "money",
|
|
66
|
+
}
|
|
67
|
+
PER_DOMAIN_CAP = 2
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def emit(msg: str) -> None:
|
|
71
|
+
if not QUIET:
|
|
72
|
+
print(msg)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def parse_frontmatter(path: Path) -> dict[str, str]:
|
|
76
|
+
text = path.read_text(encoding="utf-8", errors="replace")
|
|
77
|
+
if not text.startswith("---"):
|
|
78
|
+
return {}
|
|
79
|
+
end = text.find("\n---", 3)
|
|
80
|
+
if end == -1:
|
|
81
|
+
return {}
|
|
82
|
+
out: dict[str, str] = {}
|
|
83
|
+
for line in text[3:end].splitlines():
|
|
84
|
+
m = re.match(r"^([a-zA-Z_][\w-]*):\s*(.*)$", line)
|
|
85
|
+
if m:
|
|
86
|
+
out[m.group(1)] = m.group(2).strip().strip('"').strip("'")
|
|
87
|
+
return out
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def collect_personas() -> list[tuple[str, str, str, Path]]:
|
|
91
|
+
"""Return (id, tier, status, path) for every persona file."""
|
|
92
|
+
out: list[tuple[str, str, str, Path]] = []
|
|
93
|
+
if not PERSONA_DIR.exists():
|
|
94
|
+
return out
|
|
95
|
+
for path in sorted(PERSONA_DIR.glob("*.md")):
|
|
96
|
+
if path.stem == "README":
|
|
97
|
+
continue
|
|
98
|
+
fm = parse_frontmatter(path)
|
|
99
|
+
pid = fm.get("id") or path.stem
|
|
100
|
+
tier = fm.get("tier", "")
|
|
101
|
+
status = fm.get("status", "active") or "active"
|
|
102
|
+
out.append((pid, tier, status, path))
|
|
103
|
+
return out
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def citations_for(persona_id: str) -> list[Path]:
|
|
107
|
+
pattern = re.compile(rf"(^|[\s,\[]){re.escape(persona_id)}([\s,\]]|$)")
|
|
108
|
+
hits: list[Path] = []
|
|
109
|
+
for root in SKILL_ROOTS:
|
|
110
|
+
if not root.exists():
|
|
111
|
+
continue
|
|
112
|
+
for skill in root.rglob("SKILL.md"):
|
|
113
|
+
text = skill.read_text(encoding="utf-8", errors="replace")
|
|
114
|
+
if text.startswith("---"):
|
|
115
|
+
end = text.find("\n---", 3)
|
|
116
|
+
fm_block = text[3:end] if end != -1 else ""
|
|
117
|
+
else:
|
|
118
|
+
fm_block = ""
|
|
119
|
+
if "personas:" not in fm_block:
|
|
120
|
+
continue
|
|
121
|
+
if pattern.search(fm_block):
|
|
122
|
+
hits.append(skill)
|
|
123
|
+
return hits
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def main() -> int:
|
|
127
|
+
personas = collect_personas()
|
|
128
|
+
if not personas:
|
|
129
|
+
emit("persona-governance: no persona files found — nothing to lint.")
|
|
130
|
+
return 0
|
|
131
|
+
|
|
132
|
+
by_domain: dict[str, list[str]] = defaultdict(list)
|
|
133
|
+
missing_citations: list[str] = []
|
|
134
|
+
|
|
135
|
+
for pid, tier, status, _ in personas:
|
|
136
|
+
if status == "deprecated" or tier != "specialist":
|
|
137
|
+
continue
|
|
138
|
+
domain = DOMAIN_MAP.get(pid)
|
|
139
|
+
if domain:
|
|
140
|
+
by_domain[domain].append(pid)
|
|
141
|
+
if not citations_for(pid):
|
|
142
|
+
missing_citations.append(pid)
|
|
143
|
+
|
|
144
|
+
overflows = {d: ids for d, ids in by_domain.items() if len(ids) > PER_DOMAIN_CAP}
|
|
145
|
+
for d, ids in sorted(by_domain.items()):
|
|
146
|
+
marker = "❌" if d in overflows else "✅"
|
|
147
|
+
emit(f"{marker} domain={d} {len(ids)}/{PER_DOMAIN_CAP} {', '.join(sorted(ids))}")
|
|
148
|
+
for pid in sorted(missing_citations):
|
|
149
|
+
emit(f"⚠️ no-skill-citation {pid} (warn — see PR-time gate)")
|
|
150
|
+
|
|
151
|
+
if overflows:
|
|
152
|
+
print("\npersona-governance: per-domain cap violated.", file=sys.stderr)
|
|
153
|
+
for d, ids in sorted(overflows.items()):
|
|
154
|
+
print(f" - domain '{d}' has {len(ids)} specialists (cap {PER_DOMAIN_CAP}): {', '.join(sorted(ids))}", file=sys.stderr)
|
|
155
|
+
return 1
|
|
156
|
+
|
|
157
|
+
active = sum(1 for _, t, s, _ in personas if s != "deprecated" and t == "specialist")
|
|
158
|
+
cited = active - len(missing_citations)
|
|
159
|
+
emit(f"persona-governance: {active} active specialist persona(s) — all domains within cap; {cited}/{active} cited by ≥ 1 skill.")
|
|
160
|
+
return 0
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if __name__ == "__main__":
|
|
164
|
+
sys.exit(main())
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Hard-Gate linter for the ``roadmap-ci-steps-policy`` rule.
|
|
3
|
+
|
|
4
|
+
Forbids full-pipeline CI literals (``task ci``, ``make test``,
|
|
5
|
+
``npm run check`` etc.) inside ``agents/roadmaps/*.md`` checkbox steps
|
|
6
|
+
or fenced bash blocks **when** ``quality.local_auto_run`` in
|
|
7
|
+
``.agent-settings.yml`` is ``false``.
|
|
8
|
+
|
|
9
|
+
Carve-outs:
|
|
10
|
+
* Setting is ``true`` → linter no-ops (exit 0).
|
|
11
|
+
* Step line carries ``<!-- carve-out: new-gate-verification -->`` →
|
|
12
|
+
allowed (new gate added by the same roadmap).
|
|
13
|
+
* ``## Acceptance criteria`` section → documentation, not steps.
|
|
14
|
+
* ``agents/roadmaps/archive/`` and ``agents/roadmaps/skipped/`` → out
|
|
15
|
+
of scope; they record history.
|
|
16
|
+
|
|
17
|
+
Cap: ≤ 150 LOC, stdlib only. Hooked into ``task ci-fast`` via
|
|
18
|
+
``task lint-roadmap-ci-steps``.
|
|
19
|
+
"""
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import re
|
|
23
|
+
import sys
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
QUIET = "--quiet" in sys.argv
|
|
27
|
+
|
|
28
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
29
|
+
ROADMAP_GLOB = "agents/roadmaps/*.md"
|
|
30
|
+
SETTINGS_FILE = REPO_ROOT / ".agent-settings.yml"
|
|
31
|
+
LOCAL_AUTO_RUN_PAT = re.compile(
|
|
32
|
+
r"^\s*local_auto_run:\s*(true|false)\s*(?:#.*)?$", re.MULTILINE
|
|
33
|
+
)
|
|
34
|
+
CARVE_OUT_MARKER = "carve-out: new-gate-verification"
|
|
35
|
+
|
|
36
|
+
# CI-shaped literals — case-insensitive whole-word(-ish) matches.
|
|
37
|
+
CI_PATTERNS: tuple[tuple[re.Pattern[str], str], ...] = (
|
|
38
|
+
(re.compile(r"\btask\s+ci-strict\b", re.IGNORECASE), "task ci-strict"),
|
|
39
|
+
(re.compile(r"\btask\s+ci-fast\b", re.IGNORECASE), "task ci-fast"),
|
|
40
|
+
(re.compile(r"\btask\s+ci\b(?!-)", re.IGNORECASE), "task ci"),
|
|
41
|
+
(re.compile(r"\bmake\s+ci\b", re.IGNORECASE), "make ci"),
|
|
42
|
+
(re.compile(r"\bmake\s+test\b", re.IGNORECASE), "make test"),
|
|
43
|
+
(re.compile(r"\bnpm\s+run\s+check\b", re.IGNORECASE), "npm run check"),
|
|
44
|
+
(re.compile(r"\bpnpm\s+run\s+check\b", re.IGNORECASE), "pnpm run check"),
|
|
45
|
+
(re.compile(r"\byarn\s+check\b", re.IGNORECASE), "yarn check"),
|
|
46
|
+
(re.compile(r"\bcomposer\s+test\b", re.IGNORECASE), "composer test"),
|
|
47
|
+
# Whole-suite = bare command, or command followed only by prose
|
|
48
|
+
# ("before the boundary"). A real shell argument starts with ``-``
|
|
49
|
+
# (flag) or contains ``/`` or ``.`` (path / .php file) — that
|
|
50
|
+
# signals a targeted run and is allowed.
|
|
51
|
+
(re.compile(r"\bvendor/bin/phpunit\b(?!\s+(?:-|\S*[/.]))", re.IGNORECASE),
|
|
52
|
+
"vendor/bin/phpunit (whole suite)"),
|
|
53
|
+
(re.compile(r"\bphp\s+artisan\s+test\b(?!\s+(?:-|\S*[/.]))", re.IGNORECASE),
|
|
54
|
+
"php artisan test (whole suite)"),
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
CHECKBOX_PAT = re.compile(r"^\s*-\s*\[[ x~/-]\]\s")
|
|
58
|
+
FENCE_PAT = re.compile(r"^\s*```")
|
|
59
|
+
HEADING_PAT = re.compile(r"^(#{1,6})\s+(.*?)\s*$")
|
|
60
|
+
ACCEPTANCE_HEADING_PAT = re.compile(
|
|
61
|
+
r"^acceptance criteria\b", re.IGNORECASE
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _read_local_auto_run() -> bool:
|
|
66
|
+
"""Return ``quality.local_auto_run`` from ``.agent-settings.yml``.
|
|
67
|
+
|
|
68
|
+
Default ``True`` (= no-op) when file or key is missing. The Hard
|
|
69
|
+
Gate only fires when the setting is explicitly ``false``.
|
|
70
|
+
"""
|
|
71
|
+
if not SETTINGS_FILE.is_file():
|
|
72
|
+
return True
|
|
73
|
+
try:
|
|
74
|
+
text = SETTINGS_FILE.read_text(encoding="utf-8")
|
|
75
|
+
except OSError:
|
|
76
|
+
return True
|
|
77
|
+
in_quality = False
|
|
78
|
+
for raw in text.splitlines():
|
|
79
|
+
if not raw.strip() or raw.lstrip().startswith("#"):
|
|
80
|
+
continue
|
|
81
|
+
if raw.startswith("quality:"):
|
|
82
|
+
in_quality = True
|
|
83
|
+
continue
|
|
84
|
+
if in_quality and raw and not raw.startswith((" ", "\t")):
|
|
85
|
+
in_quality = False
|
|
86
|
+
continue
|
|
87
|
+
if in_quality:
|
|
88
|
+
m = LOCAL_AUTO_RUN_PAT.match(raw)
|
|
89
|
+
if m:
|
|
90
|
+
return m.group(1).lower() == "true"
|
|
91
|
+
return True
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def _scan(text: str) -> list[tuple[int, str, str]]:
|
|
95
|
+
"""Return ``(line_no, matched_literal, line_text)`` for every hit.
|
|
96
|
+
|
|
97
|
+
Only scans:
|
|
98
|
+
* checkbox-step lines (``- [ ] …``)
|
|
99
|
+
* lines inside fenced code blocks (```` ``` ````)
|
|
100
|
+
Skips lines under an ``## Acceptance criteria`` heading.
|
|
101
|
+
Skips lines carrying the carve-out marker.
|
|
102
|
+
"""
|
|
103
|
+
hits: list[tuple[int, str, str]] = []
|
|
104
|
+
in_fence = False
|
|
105
|
+
in_acceptance = False
|
|
106
|
+
for idx, line in enumerate(text.splitlines(), start=1):
|
|
107
|
+
if FENCE_PAT.match(line):
|
|
108
|
+
in_fence = not in_fence
|
|
109
|
+
continue
|
|
110
|
+
if not in_fence:
|
|
111
|
+
heading = HEADING_PAT.match(line)
|
|
112
|
+
if heading:
|
|
113
|
+
in_acceptance = bool(
|
|
114
|
+
ACCEPTANCE_HEADING_PAT.match(heading.group(2))
|
|
115
|
+
)
|
|
116
|
+
continue
|
|
117
|
+
if in_acceptance:
|
|
118
|
+
continue
|
|
119
|
+
is_checkbox = CHECKBOX_PAT.match(line) is not None
|
|
120
|
+
if not (is_checkbox or in_fence):
|
|
121
|
+
continue
|
|
122
|
+
if CARVE_OUT_MARKER in line:
|
|
123
|
+
continue
|
|
124
|
+
for pat, label in CI_PATTERNS:
|
|
125
|
+
if pat.search(line):
|
|
126
|
+
hits.append((idx, label, line.strip()))
|
|
127
|
+
break
|
|
128
|
+
return hits
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def main() -> int:
|
|
132
|
+
if _read_local_auto_run():
|
|
133
|
+
if not QUIET:
|
|
134
|
+
print(
|
|
135
|
+
"✅ quality.local_auto_run=true (or unset) — "
|
|
136
|
+
"CI-step gate disabled"
|
|
137
|
+
)
|
|
138
|
+
return 0
|
|
139
|
+
roadmaps = sorted(REPO_ROOT.glob(ROADMAP_GLOB))
|
|
140
|
+
if not roadmaps:
|
|
141
|
+
if not QUIET:
|
|
142
|
+
print(f"✅ no active roadmaps under {ROADMAP_GLOB}")
|
|
143
|
+
return 0
|
|
144
|
+
failed = 0
|
|
145
|
+
for roadmap in roadmaps:
|
|
146
|
+
rel = roadmap.relative_to(REPO_ROOT)
|
|
147
|
+
text = roadmap.read_text(encoding="utf-8")
|
|
148
|
+
hits = _scan(text)
|
|
149
|
+
if hits:
|
|
150
|
+
failed += 1
|
|
151
|
+
print(f"❌ {rel}", file=sys.stderr)
|
|
152
|
+
for line_no, label, line_text in hits:
|
|
153
|
+
print(
|
|
154
|
+
f" line {line_no}: '{label}' in: {line_text}",
|
|
155
|
+
file=sys.stderr,
|
|
156
|
+
)
|
|
157
|
+
print(
|
|
158
|
+
" → reword as a narrow command "
|
|
159
|
+
"(e.g. 'vendor/bin/phpstan analyse app/Modules/X'), or "
|
|
160
|
+
"mark with '<!-- carve-out: new-gate-verification -->' "
|
|
161
|
+
"when the step verifies a NEW gate introduced by this "
|
|
162
|
+
"roadmap.",
|
|
163
|
+
file=sys.stderr,
|
|
164
|
+
)
|
|
165
|
+
else:
|
|
166
|
+
if not QUIET:
|
|
167
|
+
print(f"✅ {rel}")
|
|
168
|
+
if failed:
|
|
169
|
+
print(
|
|
170
|
+
f"\n❌ {failed} roadmap(s) schedule full-pipeline CI steps "
|
|
171
|
+
f"while quality.local_auto_run=false — "
|
|
172
|
+
f"see .augment/rules/roadmap-ci-steps-policy.md",
|
|
173
|
+
file=sys.stderr,
|
|
174
|
+
)
|
|
175
|
+
return 1
|
|
176
|
+
if not QUIET:
|
|
177
|
+
print(f"\n✅ {len(roadmaps)} roadmap(s) CI-step-clean")
|
|
178
|
+
return 0
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
if __name__ == "__main__":
|
|
182
|
+
sys.exit(main())
|
|
@@ -42,6 +42,12 @@ RULES_DIR = REPO_ROOT / ".augment" / "rules"
|
|
|
42
42
|
TREND_FILE = REPO_ROOT / "agents" / ".augment-budget-history.jsonl"
|
|
43
43
|
|
|
44
44
|
# Augment workspace-guidelines ceiling — empirical 2026-05-08.
|
|
45
|
+
# TOTAL_CAP is the hard ceiling Augment itself enforces. FAIL_THRESHOLD is the
|
|
46
|
+
# soft safety-margin gate (0.95). When a branch breaches it, the discipline
|
|
47
|
+
# is: DO NOT loosen the threshold — invoke the `rule-refactor` skill, which
|
|
48
|
+
# audits all rules for merge / delete / move-to-context / promote-to-skill
|
|
49
|
+
# candidates. Threshold-lift is explicitly rejected as a tool-shape anti-
|
|
50
|
+
# pattern (see the validation-budget rule). Only an ADR may grow the cap.
|
|
45
51
|
TOTAL_CAP = 49_512
|
|
46
52
|
WARN_THRESHOLD = 0.85
|
|
47
53
|
FAIL_THRESHOLD = 0.95
|
|
@@ -67,6 +67,11 @@
|
|
|
67
67
|
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
|
|
68
68
|
"description": "Semver release in which this command became a shim (e.g. '1.15.0')."
|
|
69
69
|
},
|
|
70
|
+
"framework": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
73
|
+
"description": "Framework carve-out marker. Set on commands that are 100% coupled to one stack (e.g. `framework: laravel` on update-form-request-messages). Generic, multi-stack commands MUST omit this key. Routed by .agent-src.uncompressed/rules/framework-neutrality-in-generic-skills.md (Tier 2)."
|
|
74
|
+
},
|
|
70
75
|
"council_depth": {
|
|
71
76
|
"type": "string",
|
|
72
77
|
"enum": ["deep"],
|
|
@@ -35,6 +35,11 @@
|
|
|
35
35
|
"type": "string",
|
|
36
36
|
"pattern": "^[a-z][a-z0-9-]*$"
|
|
37
37
|
},
|
|
38
|
+
"framework": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
41
|
+
"description": "Framework carve-out marker. Set on skills that are 100% coupled to one stack (e.g. `framework: laravel` on laravel-* skills). Generic, multi-stack skills MUST omit this key. Routed by .agent-src.uncompressed/rules/framework-neutrality-in-generic-skills.md (Tier 2)."
|
|
42
|
+
},
|
|
38
43
|
"personas": {
|
|
39
44
|
"type": "array",
|
|
40
45
|
"items": {
|
package/scripts/skill_linter.py
CHANGED
|
@@ -472,6 +472,21 @@ def _command_delegation_signal(text: str, frontmatter: Optional[str]) -> bool:
|
|
|
472
472
|
return False
|
|
473
473
|
|
|
474
474
|
|
|
475
|
+
def _strip_markdown_for_check(text: str) -> str:
|
|
476
|
+
"""Strip fenced code, inline code spans, and markdown links so heuristic
|
|
477
|
+
regex matches operate on prose only.
|
|
478
|
+
|
|
479
|
+
Used by rule-body heuristics whose targets (e.g. ``procedural_rule``)
|
|
480
|
+
must not flip on legitimate skill pointers like ``[git-workflow](…)``
|
|
481
|
+
or ``` `skill:symfony-workflow` ```. Frontmatter is handled by the
|
|
482
|
+
caller via ``text.split("---", 2)[-1]``.
|
|
483
|
+
"""
|
|
484
|
+
text = re.sub(r"```[^\n]*\n.*?```", "", text, flags=re.DOTALL)
|
|
485
|
+
text = re.sub(r"`[^`\n]+`", "", text)
|
|
486
|
+
text = re.sub(r"\[[^\]]*\]\([^)]*\)", "", text)
|
|
487
|
+
return text
|
|
488
|
+
|
|
489
|
+
|
|
475
490
|
def _iron_law_blocks(text: str) -> int:
|
|
476
491
|
"""Count fenced blocks that look like verbatim Iron-Law imperatives.
|
|
477
492
|
|
|
@@ -575,10 +590,36 @@ def has_validation_step(procedure_block: str) -> bool:
|
|
|
575
590
|
return any(signal in lowered for signal in good_signals)
|
|
576
591
|
|
|
577
592
|
|
|
593
|
+
_INSPECT_VERB_PATTERN = re.compile(
|
|
594
|
+
r"\b(?:"
|
|
595
|
+
# Direct inspection
|
|
596
|
+
r"inspect|examine|audit|survey"
|
|
597
|
+
# Read / look
|
|
598
|
+
r"|read|look\s+at"
|
|
599
|
+
# Check (word-boundary — matches "check that", "check current", "check what")
|
|
600
|
+
r"|check"
|
|
601
|
+
# Review (broad — matches "review existing", "review the failures")
|
|
602
|
+
r"|review"
|
|
603
|
+
# Comprehension / orientation
|
|
604
|
+
r"|understand|identify|analyze|analyse"
|
|
605
|
+
# Discovery
|
|
606
|
+
r"|detect|gather|discover"
|
|
607
|
+
r")\b",
|
|
608
|
+
re.IGNORECASE,
|
|
609
|
+
)
|
|
610
|
+
|
|
611
|
+
|
|
578
612
|
def has_inspect_step(procedure_block: str) -> bool:
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
613
|
+
"""Return True if the procedure block opens with an inspect / read step.
|
|
614
|
+
|
|
615
|
+
Corpus-driven verb list (see docs/contracts/linter-structural-model.md):
|
|
616
|
+
the first ordered step in a skill procedure should orient the agent in
|
|
617
|
+
the live system — read existing code, examine current state, detect
|
|
618
|
+
stack — before mutating anything. Regex uses word boundaries to avoid
|
|
619
|
+
substring matches inside unrelated words (e.g. ``read`` inside
|
|
620
|
+
``already``).
|
|
621
|
+
"""
|
|
622
|
+
return bool(_INSPECT_VERB_PATTERN.search(procedure_block))
|
|
582
623
|
|
|
583
624
|
|
|
584
625
|
def find_vague_validation(text: str) -> list[str]:
|
|
@@ -678,8 +719,9 @@ def lint_skill(path: Path, text: str) -> LintResult:
|
|
|
678
719
|
if skill_name and "-" not in skill_name and len(skill_name) >= 3:
|
|
679
720
|
# Single word without qualifier — likely too generic
|
|
680
721
|
ALLOWED_BARE_NOUNS = {"database", "devcontainer", "docker", "eloquent", "flux", "forecasting",
|
|
681
|
-
"grafana", "laravel", "livewire", "
|
|
682
|
-
"security", "terraform", "terragrunt", "traefik",
|
|
722
|
+
"grafana", "laravel", "livewire", "markitdown", "mcp", "openapi",
|
|
723
|
+
"performance", "security", "terraform", "terragrunt", "traefik",
|
|
724
|
+
"websocket"}
|
|
683
725
|
if skill_name.lower() not in ALLOWED_BARE_NOUNS:
|
|
684
726
|
issues.append(Issue("warning", "bare_noun_name",
|
|
685
727
|
f"Bare-noun skill name `{skill_name}` — consider adding a qualifier (e.g., `{skill_name}-management`)"))
|
|
@@ -1504,9 +1546,20 @@ def lint_rule(path: Path, text: str) -> LintResult:
|
|
|
1504
1546
|
if bad_sign in text:
|
|
1505
1547
|
issues.append(Issue("error", "rule_looks_like_skill", f"Rule contains skill-like section: {bad_sign}"))
|
|
1506
1548
|
|
|
1507
|
-
#
|
|
1549
|
+
# Procedural-rule heuristic: a rule "looks procedural" only when its own
|
|
1550
|
+
# prose AND its own structure both signal a procedure. We:
|
|
1551
|
+
# 1. Exclude frontmatter (may contain "type", path strings, etc.).
|
|
1552
|
+
# 2. Strip code spans, fenced blocks, and markdown links — so legitimate
|
|
1553
|
+
# pointers to procedural skills (e.g. `skill:git-workflow`,
|
|
1554
|
+
# [symfony-workflow](…)) do not flip the keyword count.
|
|
1555
|
+
# 3. Require ≥ 2 keyword occurrences in stripped prose AND ≥ 3 ordered
|
|
1556
|
+
# steps AND no Iron-Law block — that combination distinguishes a
|
|
1557
|
+
# mis-classified procedure from a rule that merely references one.
|
|
1508
1558
|
body = text.split("---", 2)[-1] if frontmatter else text
|
|
1509
|
-
|
|
1559
|
+
stripped_body = _strip_markdown_for_check(body)
|
|
1560
|
+
kw_count = len(re.findall(r"\b(procedure|workflow)\b", stripped_body, re.IGNORECASE))
|
|
1561
|
+
ordered_steps = len(re.findall(r"^\s*\d+\.\s+", body, re.MULTILINE))
|
|
1562
|
+
if kw_count >= 2 and ordered_steps >= 3 and _iron_law_blocks(text) == 0:
|
|
1510
1563
|
issues.append(Issue("warning", "procedural_rule", "Rule looks procedural; consider a skill instead"))
|
|
1511
1564
|
|
|
1512
1565
|
return LintResult(
|
package/scripts/smoke/kernel.sh
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
# scripts/smoke/kernel.sh — kernel-tier smoke (step-11 Phase 3 Step 2).
|
|
3
3
|
#
|
|
4
4
|
# Asserts:
|
|
5
|
-
# 1. router.json lists exactly
|
|
5
|
+
# 1. router.json lists exactly 10 kernel rules.
|
|
6
6
|
# 2. Every kernel rule file exists at .agent-src/rules/<id>.md.
|
|
7
|
-
# 3.
|
|
7
|
+
# 3. 9 of 10 carry at least one Iron-Law fenced block.
|
|
8
8
|
# agent-authority is the dispatch index, exempt from the fence
|
|
9
9
|
# requirement (docs/contracts/smoke-contracts.md § 3.1).
|
|
10
10
|
# 4. Kernel-bucket char budget breaches ≤ EXPECTED_BREACHES.
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
set -euo pipefail
|
|
18
18
|
|
|
19
|
-
EXPECTED_KERNEL_COUNT=
|
|
20
|
-
EXPECTED_FENCE_CARRIERS=
|
|
19
|
+
EXPECTED_KERNEL_COUNT=10
|
|
20
|
+
EXPECTED_FENCE_CARRIERS=9
|
|
21
21
|
EXPECTED_BREACHES=2
|
|
22
22
|
EXEMPT_FROM_FENCE="agent-authority"
|
|
23
23
|
|
package/scripts/smoke/router.sh
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# scripts/smoke/router.sh — router-tier smoke (step-11 Phase 3 Step 3).
|
|
3
3
|
#
|
|
4
4
|
# Asserts router.json structural integrity:
|
|
5
|
-
# 1.
|
|
5
|
+
# 1. 68 ids = 10 kernel + 23 tier_1 + 35 tier_2 (locked count).
|
|
6
6
|
# 2. Every id resolves to .agent-src/rules/<id>.md (0 broken).
|
|
7
7
|
# 3. Every routes_to ref resolves through its prefix
|
|
8
8
|
# (skill:, command:, guideline:, contract:); missing-contract
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
set -euo pipefail
|
|
17
17
|
|
|
18
|
-
EXPECTED_TOTAL_IDS=
|
|
18
|
+
EXPECTED_TOTAL_IDS=68
|
|
19
19
|
EXPECTED_MISSING_CONTRACTS=2
|
|
20
20
|
|
|
21
21
|
quiet="${SMOKE_QUIET:-0}"
|
package/scripts/smoke/schema.sh
CHANGED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: pixar-storyboard-artist
|
|
3
|
-
role: Pixar Storyboard Artist
|
|
4
|
-
description: "Senior animation storyboard artist — names the emotional beat, the acting choice, the environment that reacts, and refuses flat reads."
|
|
5
|
-
tier: specialist
|
|
6
|
-
mode: developer
|
|
7
|
-
version: "1.0"
|
|
8
|
-
source: package
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Pixar Storyboard Artist
|
|
12
|
-
|
|
13
|
-
## Focus
|
|
14
|
-
|
|
15
|
-
The acting read of a scene. A prompt is done when the character
|
|
16
|
-
*wants* something, the environment *responds* to them, and one
|
|
17
|
-
emotional beat is unambiguous in the frame. Refuses flat reads —
|
|
18
|
-
eyes-open, mouth-shut, hands-at-sides — and demands acting choices
|
|
19
|
-
the camera can pick up. Not responsible for live-action lensing
|
|
20
|
-
(`hollywood-director`) or provider grammar (`ai-video-technical-director`).
|
|
21
|
-
|
|
22
|
-
## Mindset
|
|
23
|
-
|
|
24
|
-
- A scene without a want is a still life. The character is reaching
|
|
25
|
-
for something — name it.
|
|
26
|
-
- Eyes carry the read. Eye line, blink rhythm, micro-glance — these
|
|
27
|
-
are the acting, not the body pose.
|
|
28
|
-
- The environment is a co-star. Leaves move because the wind moves;
|
|
29
|
-
the wind moves because the moment shifts.
|
|
30
|
-
- Anticipation → action → reaction is a unit. Skip anticipation and
|
|
31
|
-
the action looks teleported.
|
|
32
|
-
- Stylization is a choice, not a default. "Pixar-style" without a
|
|
33
|
-
specific film reference is a wishlist, not a brief.
|
|
34
|
-
|
|
35
|
-
## Unique Questions
|
|
36
|
-
|
|
37
|
-
- What does the character want in this beat, and what is in their way?
|
|
38
|
-
- Where are the eyes pointing, and what does the eye line tell us
|
|
39
|
-
about the want?
|
|
40
|
-
- What does the environment do *because of* the character's action —
|
|
41
|
-
not just around them?
|
|
42
|
-
- Which secondary motion (hair, cloth, dust, leaves) reacts on the
|
|
43
|
-
same beat as the primary action?
|
|
44
|
-
- Which stylistic anchor (specific film, year, palette) grounds the
|
|
45
|
-
look, instead of a generic "animated"?
|
|
46
|
-
|
|
47
|
-
## Output Expectations
|
|
48
|
-
|
|
49
|
-
Four-block output, in this order: CHARACTER SHEET · SCENE PROMPT ·
|
|
50
|
-
IMAGE PROMPT · VIDEO PROMPT. Each block is self-contained and can
|
|
51
|
-
be handed to its downstream skill (image render vs. motion prompt)
|
|
52
|
-
without rewriting.
|
|
53
|
-
|
|
54
|
-
- CHARACTER SHEET names silhouette, palette, wardrobe, signature prop, posture default, eye behavior.
|
|
55
|
-
- SCENE PROMPT names emotional beat, want, obstacle, stylistic anchor (film + year), environment reaction.
|
|
56
|
-
- IMAGE PROMPT is a single still — peak moment, composition + palette explicit.
|
|
57
|
-
- VIDEO PROMPT names anticipation → action → reaction with a beat count per phase.
|
|
58
|
-
- Severity vocabulary on review: `must-fix · should-fix · nit`.
|
|
59
|
-
|
|
60
|
-
## Anti-Patterns
|
|
61
|
-
|
|
62
|
-
- Do NOT default to neutral expressions. Every beat names a feeling the face is doing.
|
|
63
|
-
- Do NOT describe the environment as backdrop. It reacts, or it is not in the prompt.
|
|
64
|
-
- Do NOT cite "Pixar-style" without naming a specific film and year as the stylistic anchor.
|
|
65
|
-
- Do NOT collapse anticipation and action into one motion — both phases named, or fail.
|
|
66
|
-
- Do NOT prescribe lenses — that is the Hollywood director's block.
|
|
67
|
-
|
|
68
|
-
## Critical Rules
|
|
69
|
-
|
|
70
|
-
- CHARACTER SHEET is reused verbatim across every scene in a run.
|
|
71
|
-
Edits to identity tokens require an explicit revision note.
|
|
72
|
-
- SCENE PROMPT names exactly one emotional beat. Compound beats
|
|
73
|
-
("sad but hopeful and tired") fail review.
|
|
74
|
-
- VIDEO PROMPT names a beat count per phase (e.g., "anticipation 0.5s,
|
|
75
|
-
action 1.2s, reaction 0.8s"). No vague pacing.
|
|
76
|
-
- Stylistic anchor cites a specific film + year. Generic style words
|
|
77
|
-
fail.
|
|
78
|
-
- Eye line is named in every IMAGE PROMPT.
|
|
79
|
-
|
|
80
|
-
## Workflows
|
|
81
|
-
|
|
82
|
-
1. Read the scene idea once. Name the want and the obstacle in one
|
|
83
|
-
sentence each.
|
|
84
|
-
2. Choose the stylistic anchor — specific film + year. Justify in
|
|
85
|
-
one sentence what it brings.
|
|
86
|
-
3. Draft the CHARACTER SHEET; lock identity tokens.
|
|
87
|
-
4. Write the SCENE PROMPT with want, obstacle, beat, anchor,
|
|
88
|
-
environment reaction.
|
|
89
|
-
5. Freeze the peak moment into the IMAGE PROMPT — composition, eye
|
|
90
|
-
line, palette.
|
|
91
|
-
6. Decompose the moment into anticipation → action → reaction in the
|
|
92
|
-
VIDEO PROMPT, each with a beat count.
|
|
93
|
-
|
|
94
|
-
## Composes well with
|
|
95
|
-
|
|
96
|
-
- `hollywood-director` — storyboard artist names the acting, the director frames it.
|
|
97
|
-
- `ai-video-technical-director` — folds the four blocks into provider grammar.
|
|
98
|
-
- `character-consistency` skill — consumes the CHARACTER SHEET as identity-token source.
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "auto"
|
|
3
|
-
tier: "2a"
|
|
4
|
-
description: "Reading, creating, or updating agent documentation, module docs, roadmaps, or AGENTS.md"
|
|
5
|
-
source: package
|
|
6
|
-
triggers:
|
|
7
|
-
- path_prefix: "agents/"
|
|
8
|
-
- path_prefix: ".github/copilot-instructions"
|
|
9
|
-
- keyword: "AGENTS.md"
|
|
10
|
-
- keyword: "roadmap"
|
|
11
|
-
routes_to:
|
|
12
|
-
- "skill:agent-docs-writing"
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
# Agent Docs
|
|
16
|
-
|
|
17
|
-
**Iron Law.** Read agent docs (`AGENTS.md`, `agents/`, module `agents/`) before work; update them after structural changes.
|
|
18
|
-
|
|
19
|
-
Body migrated to `skill:agent-docs-writing` (per P4 of `road-to-kernel-and-router.md`).
|
|
20
|
-
Trigger-set above activates this routing under the `balanced` and `full` profiles.
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: "auto"
|
|
3
|
-
tier: "mechanical-already"
|
|
4
|
-
description: "Editing or creating files inside .augment/ directory — skills, rules, commands, templates, contexts must be project-agnostic"
|
|
5
|
-
source: package
|
|
6
|
-
triggers:
|
|
7
|
-
- path_prefix: ".augment/"
|
|
8
|
-
- path_prefix: ".agent-src.uncompressed/"
|
|
9
|
-
- keyword: "portable"
|
|
10
|
-
routes_to:
|
|
11
|
-
- "guideline:augment-portability-patterns"
|
|
12
|
-
validator_ignore:
|
|
13
|
-
- type: "substring"
|
|
14
|
-
pattern: ".agent-src.uncompressed/"
|
|
15
|
-
reason: "Rule scopes the portability gate to the uncompressed authoring tree."
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
# Augment Portability
|
|
19
|
-
|
|
20
|
-
**Iron Law.** Files inside `.augment/` and `.agent-src.uncompressed/` MUST stay project-agnostic — no project names, domains, stacks.
|
|
21
|
-
|
|
22
|
-
Body migrated to `guideline:augment-portability-patterns` (per P4 of `road-to-kernel-and-router.md`).
|
|
23
|
-
Trigger-set above activates this routing under the `balanced` and `full` profiles.
|