@event4u/agent-config 14.17.0 → 14.19.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +207 -77
- package/README.md +72 -150
- package/dist/agent-src/README.md +1 -1
- package/dist/agent-src/commands/agent-handoff.md +2 -2
- package/dist/agent-src/commands/pr/merge.md +35 -44
- package/dist/agent-src/commands/review/changes.md +19 -19
- package/dist/agent-src/commands/review.md +2 -2
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +30 -3
- package/dist/agent-src/rules/autonomous-execution.md +1 -1
- package/dist/agent-src/rules/git-history-discipline.md +2 -2
- package/dist/agent-src/rules/guidelines.md +1 -1
- package/dist/agent-src/rules/session-canary.md +2 -2
- package/dist/agent-src/rules/token-efficiency.md +1 -1
- package/dist/agent-src/skills/accessibility-auditor/SKILL.md +2 -0
- package/dist/agent-src/skills/adversarial-review/SKILL.md +0 -8
- package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +27 -1
- package/dist/agent-src/skills/canvas-design/SKILL.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +60 -12
- package/dist/agent-src/skills/complexity-first-planning/SKILL.md +27 -0
- package/dist/agent-src/skills/design-intelligence/SKILL.md +1 -1
- package/dist/agent-src/skills/design-intelligence/data/app-interface.csv +1 -1
- package/dist/agent-src/skills/design-intelligence/data/motion.csv +17 -17
- package/dist/agent-src/skills/design-intelligence/data/ux-guidelines.csv +2 -2
- package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +17 -0
- package/dist/agent-src/skills/design-intelligence/references/design-rules-checklist.md +4 -4
- package/dist/agent-src/skills/design-review/SKILL.md +3 -1
- package/dist/agent-src/skills/design-variations/SKILL.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +1 -1
- package/dist/agent-src/skills/fe-design/SKILL.md +32 -5
- package/dist/agent-src/skills/fe-design/references/craft-floor.md +7 -0
- package/dist/agent-src/skills/fe-design/references/design-patterns.md +47 -2
- package/dist/agent-src/skills/feature-planning/SKILL.md +34 -0
- package/dist/agent-src/skills/git-workflow/SKILL.md +37 -12
- package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +176 -0
- package/dist/agent-src/skills/laravel-mail/SKILL.md +44 -0
- package/dist/agent-src/skills/laravel-scheduling/SKILL.md +3 -1
- package/dist/agent-src/skills/project-analyzer/SKILL.md +0 -6
- package/dist/agent-src/skills/react-native-setup/SKILL.md +3 -3
- package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
- package/dist/agent-src/skills/sequential-thinking/SKILL.md +18 -8
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
- package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +40 -0
- package/dist/agent-src/skills/ui-apply-generic/SKILL.md +1 -1
- package/dist/agent-src/skills/ui-component-architect/SKILL.md +1 -1
- package/dist/agent-src/skills/using-git-worktrees/SKILL.md +29 -2
- package/dist/agent-src/skills/verify-repair-loop/SKILL.md +53 -8
- package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -1
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/commands/recordTriggerEval.js +2 -2
- package/dist/cli/main.js +1 -1
- package/dist/cli-delegate/{chunk-AKJGUQNO.js → chunk-GZTMRYCN.js} +405 -341
- package/dist/cli-delegate/{chunk-7RXIKF62.js → chunk-IDHUQIXP.js} +283 -132
- package/dist/cli-delegate/cmd_adr_effective.js +318 -81
- package/dist/cli-delegate/cmd_conformance.js +749 -669
- package/dist/cli-delegate/cmd_doctor.js +1 -1
- package/dist/cli-delegate/cmd_export.js +1 -1
- package/dist/cli-delegate/cmd_handoff.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +1 -1
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +1 -1
- package/dist/cli-delegate/cmd_uninstall.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +39 -38
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +2764 -2439
- package/dist/install/install.mjs +588 -527
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1381 -1138
- package/dist/scripts/_lib/model_tier.js +1 -1
- package/dist/shared/settingsConsent.js +1 -1
- package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +1 -1
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
- package/docs/guidelines/design-antipatterns.md +87 -64
- package/package.json +1 -1
- package/src/agent-src/README.md +1 -1
- package/src/config/ci-local-parity.yml +6 -0
- package/src/config/conformance-claim-baseline.json +9 -0
- package/src/config/gate-coverage.yml +170 -0
- package/src/config/gate-violation-baselines.json +4 -4
- package/src/config/release-gate-locality.yml +141 -0
- package/src/scripts/_cli/cmd_doctor.ts +2 -2
- package/src/scripts/_cli/cmd_handoff.ts +1 -1
- package/src/scripts/_cli/cmd_update.ts +1 -1
- package/src/scripts/_cli/cmd_versions.ts +1 -1
- package/src/scripts/_lib/adr_frontmatter.ts +44 -0
- package/src/scripts/_lib/consequence_objects.ts +152 -0
- package/src/scripts/_lib/exec_evidence.ts +7 -0
- package/src/scripts/_lib/global_deploy_inventory.ts +2 -2
- package/src/scripts/_lib/host_permission_checks.ts +251 -0
- package/src/scripts/_lib/model_tier.ts +1 -1
- package/src/scripts/_lib/obligation_frequency.ts +2 -2
- package/src/scripts/_lib/release_highlights.ts +265 -1
- package/src/scripts/_lib/release_material.ts +129 -0
- package/src/scripts/_lib/repeated_run.ts +77 -0
- package/src/scripts/_lib/runtime_journal.ts +26 -3
- package/src/scripts/_lib/runtime_wiring_checks.ts +12 -1
- package/src/scripts/_lib/session_register.ts +11 -6
- package/src/scripts/_lib/sqlite_schema.ts +22 -0
- package/src/scripts/_lib/surface.ts +86 -0
- package/src/scripts/_lib/tamper_vocabulary.ts +242 -0
- package/src/scripts/_lib/ui_authority.ts +116 -0
- package/src/scripts/_lib/unified_diff.ts +121 -0
- package/src/scripts/adr/regenerate_index.ts +54 -1
- package/src/scripts/adr_cite_check.ts +71 -15
- package/src/scripts/ai_council/clients.ts +1 -1
- package/src/scripts/autonomy_friction_corpus.ts +229 -0
- package/src/scripts/build_proof.ts +15 -2
- package/src/scripts/check_beta_review_markers.ts +141 -17
- package/src/scripts/check_enforcement_coverage.ts +1 -1
- package/src/scripts/check_enforcement_denominator.ts +121 -11
- package/src/scripts/check_finding_dispositions.ts +239 -6
- package/src/scripts/check_gate_coverage.ts +96 -0
- package/src/scripts/check_installed_hooks_fresh.ts +381 -0
- package/src/scripts/check_release_highlights.ts +99 -14
- package/src/scripts/check_skill_activation_claim.ts +179 -0
- package/src/scripts/check_suppression_hygiene.ts +11 -0
- package/src/scripts/check_trigger_evals.ts +1 -1
- package/src/scripts/code_graph/build.ts +230 -33
- package/src/scripts/code_graph/extract.ts +168 -33
- package/src/scripts/code_graph/types.ts +37 -2
- package/src/scripts/code_graph/validate.ts +12 -1
- package/src/scripts/conformance_scan.ts +45 -4
- package/src/scripts/detect_silent_catch.ts +403 -0
- package/src/scripts/detect_verification_tampering.ts +538 -0
- package/src/scripts/explain_run.ts +1 -1
- package/src/scripts/generate_capability_matrix.ts +1 -1
- package/src/scripts/git_authorization_hook.ts +228 -18
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +47 -30
- package/src/scripts/hooks/augment-dispatcher.sh +1 -1
- package/src/scripts/hooks/block_no_verify.ts +3 -3
- package/src/scripts/hooks/category_a.ts +291 -0
- package/src/scripts/hooks/cline-dispatcher.sh +1 -1
- package/src/scripts/hooks/concern_registry.ts +2 -2
- package/src/scripts/hooks/cursor-dispatcher.sh +11 -5
- package/src/scripts/hooks/dispatch_hook.ts +17 -22
- package/src/scripts/hooks/evidence_independence.ts +21 -2
- package/src/scripts/hooks/{block_unauthorized_git.ts → git_command_classifier.ts} +175 -364
- package/src/scripts/hooks/host_lowering.ts +215 -0
- package/src/scripts/hooks/host_lowering.yaml +185 -0
- package/src/scripts/hooks/host_semantics.ts +105 -37
- package/src/scripts/hooks/journal_record_hook.ts +10 -0
- package/src/scripts/hooks/permission_gate.ts +117 -0
- package/src/scripts/hooks/push_settle_hook.ts +250 -0
- package/src/scripts/hooks/ship_diff_volume_hook.ts +1 -1
- package/src/scripts/hooks_status.ts +12 -10
- package/src/scripts/install-hooks.sh +134 -1
- package/src/scripts/install.ts +53 -82
- package/src/scripts/install_anthropic_key.sh +2 -2
- package/src/scripts/language_mirror_hook.ts +27 -5
- package/src/scripts/lint_design_antipattern_parity.ts +80 -0
- package/src/scripts/lint_evidence_artifacts.ts +45 -1
- package/src/scripts/lint_hook_manifest.ts +87 -3
- package/src/scripts/lint_motion_authority_drift.ts +731 -0
- package/src/scripts/lint_readme_size.ts +158 -12
- package/src/scripts/lint_reasoning_fixtures.ts +216 -0
- package/src/scripts/lint_skill_trigger_contradiction.ts +161 -0
- package/src/scripts/measure_sibling_naming.ts +150 -0
- package/src/scripts/redact_hook_capture.ts +1 -1
- package/src/scripts/release.ts +31 -143
- package/src/scripts/release_drill.ts +71 -1
- package/src/scripts/release_publication.ts +243 -3
- package/src/scripts/release_verify.ts +220 -0
- package/src/scripts/report_skill_activation.ts +319 -7
- package/src/scripts/schemas/review-findings.schema.json +6 -1
- package/src/scripts/schemas/skill.schema.json +12 -2
- package/src/scripts/self_review_gate.ts +10 -1
- package/src/scripts/session_canary_hook.ts +1 -1
- package/src/scripts/session_register_hook.ts +4 -3
- package/src/scripts/trigger_eval_grandfather.json +5 -1
- package/src/scripts/validate_agent_settings.ts +1 -1
- package/src/shared/settingsConsent.ts +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: fe-design
|
|
4
|
-
description: "Frontend design heuristics
|
|
4
|
+
description: "Frontend design heuristics and the loop applying them: existing-ui-audit, brief, inventory, build, review. Use when building or changing any UI, not only when planning one."
|
|
5
5
|
personas:
|
|
6
6
|
- frontend-engineer
|
|
7
7
|
domain: engineering
|
|
@@ -46,10 +46,37 @@ else runs the loop.
|
|
|
46
46
|
1. **Audit first** — run [`existing-ui-audit`](../existing-ui-audit/SKILL.md).
|
|
47
47
|
What already exists (components, tokens, layout conventions) outranks every
|
|
48
48
|
heuristic below. Reinventing an existing component is the #1 failure mode.
|
|
49
|
-
2. **Brief** —
|
|
50
|
-
`layout`, `components`, `states`, `microcopy`,
|
|
51
|
-
five of `empty`, `loading`, `error`, `success`,
|
|
52
|
-
one is unfinished, not concise.
|
|
49
|
+
2. **Brief** — seven keys before any code. Five are the ones the engine gates
|
|
50
|
+
(`REQUIRED_BRIEF_KEYS`): `layout`, `components`, `states`, `microcopy`,
|
|
51
|
+
`a11y`. `states` means all five of `empty`, `loading`, `error`, `success`,
|
|
52
|
+
`disabled` — a brief missing one is unfinished, not concise.
|
|
53
|
+
|
|
54
|
+
Two more are **declared, not gated**: `frequency` and `initiation`. The
|
|
55
|
+
engine does not halt on them, and that is stated rather than left to be
|
|
56
|
+
discovered — adding a required key would halt every brief already written
|
|
57
|
+
against the five.
|
|
58
|
+
|
|
59
|
+
| Key | Values | Why it is declared and never inferred |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `frequency` | `one-time` · `low` · `medium` · `high` (100+ per day) | How often a surface is used decides whether motion on it reads as polish or as a toll. Nothing in a diff reveals it. |
|
|
62
|
+
| `initiation` | `keyboard` · `pointer` · `system` | A keyboard-initiated surface is reached by someone who already knows where they are going; an animation there is pure latency. |
|
|
63
|
+
|
|
64
|
+
Both are prefilled from the surface's role and overridden only on evidence.
|
|
65
|
+
There is no resolver and no inference from handlers: a `mousemove` listener
|
|
66
|
+
is not proof of pointer initiation, and a keyboard shortcut in the code is
|
|
67
|
+
not proof anyone uses it.
|
|
68
|
+
|
|
69
|
+
| Surface role | `frequency` | `initiation` |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| Command palette | `high` | `keyboard` |
|
|
72
|
+
| Tooltip | `high` | `pointer` |
|
|
73
|
+
| Modal / sheet | `medium` | `pointer` |
|
|
74
|
+
| Onboarding flow | `one-time` | `pointer` |
|
|
75
|
+
| Toast / notification | `medium` | `system` |
|
|
76
|
+
| Table row action | `high` | `pointer` |
|
|
77
|
+
|
|
78
|
+
The default for a role not listed is `medium` / `pointer`, stated in the
|
|
79
|
+
brief as a default rather than left blank.
|
|
53
80
|
3. **Inventory — only when an artifact was provided, and before you build.**
|
|
54
81
|
List the artifact's **interactions, keyframes, and script includes** from its
|
|
55
82
|
source (`design-fidelity-mechanics` § Data-basis ladder — read it, do not
|
|
@@ -43,6 +43,13 @@ the moment the floor has to be present. Same content, later delivery.
|
|
|
43
43
|
An undeclared pick is an undeclared choice (T7).
|
|
44
44
|
12. **Zero silent drops.** A mechanic present in a supplied source and absent
|
|
45
45
|
from the output, with no `flagged` entry, is a silent drop.
|
|
46
|
+
13. **Shipped motion carries a `feel` line naming its method.** Duration and
|
|
47
|
+
easing being inside the bands in
|
|
48
|
+
[`design-patterns.md`](design-patterns.md) § Motion is a static check, and
|
|
49
|
+
motion that passes it can still be wrong to watch. The line names one of
|
|
50
|
+
`slow-motion` · `frame-step` · `device` · `next-day` and its outcome; an
|
|
51
|
+
outcome of `unbacked` is legal, an absent method is not
|
|
52
|
+
(`docs/contracts/evidence-artifact-types.md` § `feel`).
|
|
46
53
|
|
|
47
54
|
## What is NOT on this page
|
|
48
55
|
|
|
@@ -152,6 +152,16 @@ Step indicator (1 — 2 — 3)
|
|
|
152
152
|
|
|
153
153
|
## Motion — decision-tree and rationale
|
|
154
154
|
|
|
155
|
+
This section is the **sole carrier** of motion duration bands, easing choice and
|
|
156
|
+
the bounce prohibition; the five files that restate any of them are bound to the
|
|
157
|
+
values below and are checked against them by
|
|
158
|
+
`src/scripts/lint_motion_authority_drift.ts`:
|
|
159
|
+
`src/skills/design-intelligence/references/design-rules-checklist.md`,
|
|
160
|
+
`src/skills/design-intelligence/data/ux-guidelines.csv`,
|
|
161
|
+
`src/skills/design-intelligence/data/app-interface.csv`,
|
|
162
|
+
`src/skills/design-intelligence/data/styles.csv`,
|
|
163
|
+
`src/skills/design-intelligence/data/motion.csv`.
|
|
164
|
+
|
|
155
165
|
Before adding any animation to a UI element, run through this decision tree:
|
|
156
166
|
|
|
157
167
|
**1. Should this animate at all?**
|
|
@@ -162,8 +172,8 @@ Before adding any animation to a UI element, run through this decision tree:
|
|
|
162
172
|
|
|
163
173
|
**2. Which easing?**
|
|
164
174
|
- Entering (element appearing)? **ease-out** (starts fast, slows to rest). Why: the element arriving quickly signals responsiveness; the deceleration feels natural as it settles.
|
|
165
|
-
- Exiting (element disappearing)? **ease-
|
|
166
|
-
- **Never ease-in
|
|
175
|
+
- Exiting (element disappearing)? **ease-out** as well. Why: one curve in both directions is the value a reader can hold and a gate can check; the field has no settled answer on exit easing, so a single shared curve removes the contradiction between carriers instead of propagating it. This line settles the **curve** only — how long an exit runs relative to its enter is a separate question it does not answer.
|
|
176
|
+
- **Never ease-in, in either direction.** Why: ease-in delays the initial movement — the exact moment the user is watching most closely — making it feel slow even at the same total duration.
|
|
167
177
|
- **Never bounce or elastic easing in UI.** Why: bounce draws attention to the animation itself, not the content; it feels dated.
|
|
168
178
|
|
|
169
179
|
**3. How long?**
|
|
@@ -199,6 +209,41 @@ The six interaction states every interactive element must assert are
|
|
|
199
209
|
[`design-review`](../../design-review/SKILL.md)'s; this entry is the motion half
|
|
200
210
|
of the hover one.
|
|
201
211
|
|
|
212
|
+
**6. Which mechanism carries it?**
|
|
213
|
+
|
|
214
|
+
Steps 1-5 decide *whether* and *how much*. This step decides *with what*, and it
|
|
215
|
+
is the step the tree used to skip: a CSS `transition` was the implicit answer to
|
|
216
|
+
everything, which is why an entry animation on a `<dialog>` or a popover
|
|
217
|
+
silently does nothing and a shared-element route change gets hand-rolled.
|
|
218
|
+
|
|
219
|
+
- **A CSS `transition` on `transform` and `opacity`** is the default and covers
|
|
220
|
+
most of steps 1-5. Reach past it only for the cases below.
|
|
221
|
+
- **An element entering or leaving the DOM, or the top layer** (`<dialog>`,
|
|
222
|
+
`popover`) has no "before" state to transition from and is gone before an exit
|
|
223
|
+
could run. That is what `@starting-style` is for — it supplies the entry's
|
|
224
|
+
starting values — together with `transition-behavior: allow-discrete` so
|
|
225
|
+
`display` and `overlay` participate instead of snapping. Without both, the
|
|
226
|
+
animation is not slow or wrong; it does not happen.
|
|
227
|
+
- **The Web Animations API** (`Element.animate()`) is the mechanism when the
|
|
228
|
+
values are computed at runtime, when the animation must be interruptible
|
|
229
|
+
(`Animation.cancel()`, `.reverse()`, `.finished`), or when several elements
|
|
230
|
+
share one timeline. A keyframe set known at author time does not need it.
|
|
231
|
+
- **A view transition** (`document.startViewTransition()`) is the mechanism for
|
|
232
|
+
a state or route change where an element persists across the change. It is the
|
|
233
|
+
first-party form of what a hand-built shared-element transition approximates,
|
|
234
|
+
and it is the case the 300-500ms page-transition band is for.
|
|
235
|
+
- **`transform-origin`** decides where a `scale()` grows from. A menu or popover
|
|
236
|
+
scaling in should originate at its trigger, not at its own centre, or it reads
|
|
237
|
+
as arriving from nowhere. Scale in from ~0.96, never from `scale(0)`: growing
|
|
238
|
+
from nothing is an entrance, and steps 1-2 asked for feedback.
|
|
239
|
+
- **`@media (hover: hover)`** gates any hover-carried motion. Without it a touch
|
|
240
|
+
device fires the hover treatment on tap and leaves it stuck, because there is
|
|
241
|
+
no pointer to leave.
|
|
242
|
+
|
|
243
|
+
All six still obey step 3's bands, step 2's single `ease-out` curve, and the
|
|
244
|
+
`@media (prefers-reduced-motion: reduce)` requirement above — a newer mechanism
|
|
245
|
+
is not an exemption from the authority, it is another way of spending it.
|
|
246
|
+
|
|
202
247
|
**4. What to animate?**
|
|
203
248
|
Animate `transform` and `opacity` only. Why: these run on the GPU compositor thread, not the main thread; they never trigger layout or paint.
|
|
204
249
|
`scale(0)` → `scale(1)` is wrong. Why: nothing in the real world appears from nothing. Use `scale(0.95)` + `opacity: 0` → `scale(1)` + `opacity: 1` instead.
|
|
@@ -176,6 +176,40 @@ complexity: lightweight # default — skips bite-sized granularity
|
|
|
176
176
|
|
|
177
177
|
Source: adapted from an external reference; complexity-gating is our addition (Council Round 1, Q4 — mitigates UX pushback for senior engineers on well-scoped work).
|
|
178
178
|
|
|
179
|
+
## The four plan criteria — what a reviewer fails a plan on
|
|
180
|
+
|
|
181
|
+
The 3-scan self-review below catches mechanical gaps. These four catch the plan
|
|
182
|
+
itself. Each is written so a reviewer can **fail** on it: the criterion states
|
|
183
|
+
what failing looks like, not what passing feels like. A plan that cannot be
|
|
184
|
+
failed on any of the four has not been reviewed, it has been read.
|
|
185
|
+
|
|
186
|
+
1. **Necessity** — every phase, step and artifact in the plan is traceable to a
|
|
187
|
+
stated problem or acceptance criterion. **Fails when** the plan contains work
|
|
188
|
+
no requirement asked for: a new abstraction with one caller, a migration for a
|
|
189
|
+
field nothing reads, a "while we're in there" refactor, a config surface
|
|
190
|
+
nobody requested. Name the orphan step and the requirement it does not map to.
|
|
191
|
+
2. **Sufficiency** — every stated requirement and acceptance criterion is
|
|
192
|
+
discharged by at least one step. **Fails when** a requirement has no owning
|
|
193
|
+
step, or when the only step that claims it is a heading with no verifiable
|
|
194
|
+
outcome under it. This is the mirror of Necessity and is checked in the
|
|
195
|
+
opposite direction: walk the requirements, not the steps.
|
|
196
|
+
3. **Ordering** — no step depends on the outcome of a step that comes after it,
|
|
197
|
+
and the load-bearing unknown is resolved before the work that assumes it (see
|
|
198
|
+
[`complexity-first-planning`](../complexity-first-planning/SKILL.md)).
|
|
199
|
+
**Fails when** step N consumes something step N+2 creates, or when the plan
|
|
200
|
+
builds three cheap phases on an integration nobody has proven yet.
|
|
201
|
+
4. **Groundedness** — every command, skill, command-verb and tool the plan tells
|
|
202
|
+
someone to run **exists**. **Fails when** the plan names a verb, skill or
|
|
203
|
+
command that is not in the index. Check it against
|
|
204
|
+
[`CAPABILITIES.yaml`](../../../CAPABILITIES.yaml) at the repository root — the
|
|
205
|
+
generated capability index listing every shipped skill and command per
|
|
206
|
+
capability area — plus the project's own script/task entry points for anything
|
|
207
|
+
the index does not cover. This is the one of the four that is decidable
|
|
208
|
+
without judgement, so it is the one that should never be waved through.
|
|
209
|
+
|
|
210
|
+
A failure on any of the four is a blocker, not a note: fix the plan and re-run
|
|
211
|
+
the criterion, or move the item to *Open questions* with the reason.
|
|
212
|
+
|
|
179
213
|
## Self-review (3-scan checklist)
|
|
180
214
|
|
|
181
215
|
Before presenting any plan, run these three scans in order. Each is a fast pass — not a deep review. Failures block presentation; fix and re-scan.
|
|
@@ -100,21 +100,46 @@ Work complete. What would you like to do?
|
|
|
100
100
|
### Option 1: Push and create PR
|
|
101
101
|
|
|
102
102
|
1. Run quality pipeline + tests (only when `quality.local_auto_run: true`; default `false` → skip, remote CI is the gate).
|
|
103
|
-
2.
|
|
104
|
-
|
|
103
|
+
2. **The push-ready sequence** — fetch → integrate the base SET → regenerate →
|
|
104
|
+
verify → re-check freshness (this repo wires it as a `push-ready` task target;
|
|
105
|
+
a consumer wires its own). Not optional housekeeping: see § A push closes its
|
|
106
|
+
own loop. A stale push is refused, so skipping this buys the refusal.
|
|
107
|
+
3. `git push -u origin <branch>`.
|
|
108
|
+
4. `gh pr create` using PR template.
|
|
109
|
+
5. **Settle it** — the turn is not over at step 4:
|
|
110
|
+
`npx tsx node_modules/@event4u/agent-config/src/scripts/ci_settle.ts <pr>`
|
|
105
111
|
|
|
106
|
-
|
|
112
|
+
## A push closes its own loop
|
|
107
113
|
|
|
108
|
-
Report: "Branch `<name>` preserved locally." — do nothing.
|
|
109
|
-
|
|
110
|
-
### Option 3: Discard
|
|
111
|
-
|
|
112
|
-
**Confirm first** — list branch name and commit count.
|
|
113
|
-
Wait for explicit confirmation. Then:
|
|
114
|
-
```bash
|
|
115
|
-
git checkout main
|
|
116
|
-
git branch -D <feature-branch>
|
|
117
114
|
```
|
|
115
|
+
A PUSH IS NOT A DELIVERY. THE EVIDENCE FOR A PUSH IS THE CI VERDICT,
|
|
116
|
+
NEVER THE PUSH'S OWN EXIT CODE.
|
|
117
|
+
BEHIND THE BASE → INTEGRATE BEFORE PUSHING, NEVER AFTER THE PR IS RED.
|
|
118
|
+
RED AFTER PUSHING → FIX IT IN THE SAME TURN, OR SAY PLAINLY THAT YOU DID NOT.
|
|
119
|
+
NEVER HAND THE USER A RED PR WITH ITS CAUSE NAMED AND UNFIXED.
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Two halves, failing differently, over the 30 sessions and 50 PRs before
|
|
123
|
+
2026-09-04. **Stale base**: 25 of 50 PRs carried a `Merge branch 'main' into …`
|
|
124
|
+
commit (52 in total), and the three most-failing workflows are the base-relative
|
|
125
|
+
ones — a branch pushed behind its base was verified against a base it no longer
|
|
126
|
+
merges into. **Unsettled push**: 22 of 30 sessions ran `gh run view
|
|
127
|
+
--log-failed`, and 20 of 50 PRs carried a follow-up `fix(ci|gates|budget)`
|
|
128
|
+
commit. Only 19 of 50 landed with neither. Each half now has a deterministic
|
|
129
|
+
carrier — the pre-push hook refuses a verified-behind branch and points at the
|
|
130
|
+
push-ready sequence; the `push-settle` PostToolUse concern fires the moment git
|
|
131
|
+
reports a ref advanced. Neither replaces the discipline: the hook is skippable
|
|
132
|
+
with `AGENT_CONFIG_SKIP_PREPUSH_FRESHNESS=1` for a genuine WIP push, and the
|
|
133
|
+
settle reminder is advisory, because leaving a push deliberately unsettled is
|
|
134
|
+
legitimate — **ending the turn silently on one is not**.
|
|
135
|
+
|
|
136
|
+
`ci_settle` non-zero → read only the failing part
|
|
137
|
+
(`gh run view --job <id> --log-failed | grep -E '×|FAIL|Error'`), fix, push
|
|
138
|
+
again; the author of the red is irrelevant (`fix-what-you-see`). Three failed
|
|
139
|
+
attempts on one target → stop and surface them (`autonomous-execution` N=3).
|
|
140
|
+
Exit `2` is **not** a verdict — the wait timed out or the API could not be read.
|
|
141
|
+
Counts, carrier limits and the honest cost:
|
|
142
|
+
[`references/push-closes-its-loop.md`](references/push-closes-its-loop.md).
|
|
118
143
|
|
|
119
144
|
## PR template
|
|
120
145
|
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# A push closes its own loop — the measurement
|
|
2
|
+
|
|
3
|
+
Reference for [`git-workflow`](../SKILL.md) § A push closes its own loop. The
|
|
4
|
+
obligation lives in the skill; this file carries the evidence behind it and the
|
|
5
|
+
two deterministic carriers that now exist, so neither has to be re-derived and
|
|
6
|
+
neither inflates the skill body.
|
|
7
|
+
|
|
8
|
+
## What was measured
|
|
9
|
+
|
|
10
|
+
Corpus: the 30 most recent local session transcripts and the 50 most recent
|
|
11
|
+
pull requests on this repository, read on 2026-09-04. Session events are counted
|
|
12
|
+
from git's and `gh`'s own literal output in the transcripts, never from prose
|
|
13
|
+
about them; PR workflow runs come from `actions/runs?event=pull_request`, which
|
|
14
|
+
paginates out at 1,000 runs and therefore covers **36** of the 50 PRs — the
|
|
15
|
+
older 14 are unmeasured, not clean, and are excluded from that row rather than
|
|
16
|
+
counted as green.
|
|
17
|
+
|
|
18
|
+
### Half one — the stale base
|
|
19
|
+
|
|
20
|
+
| Signal | Count |
|
|
21
|
+
|---|---|
|
|
22
|
+
| PRs carrying ≥ 1 `Merge branch 'main' into <branch>` commit | **25 / 50** |
|
|
23
|
+
| Such merge commits in total | **52** |
|
|
24
|
+
| Sessions hitting a literal `CONFLICT (content)` / `Automatic merge failed` | **10 / 30** |
|
|
25
|
+
| Sessions hitting a rejected push (`Updates were rejected` / non-fast-forward) | **20 / 30** |
|
|
26
|
+
|
|
27
|
+
The worst single PRs needed four and five separate base merges. What that
|
|
28
|
+
buys is not only conflict work: the three workflows that failed most —
|
|
29
|
+
**Tests (18), Consistency (16), Rule Backstops (13)** — are the base-relative
|
|
30
|
+
ones. Ratchets, budgets and generated counts are green against the base a branch
|
|
31
|
+
forked from and red against the base it merges into, so a branch pushed behind
|
|
32
|
+
its base was verified against a question nobody asked.
|
|
33
|
+
|
|
34
|
+
### Half two — the unsettled push
|
|
35
|
+
|
|
36
|
+
| Signal | Count |
|
|
37
|
+
|---|---|
|
|
38
|
+
| Sessions running `gh run view --log-failed` (a red job was investigated) | **22 / 30** |
|
|
39
|
+
| PRs with ≥ 1 FAILED workflow run (of the 36 readable) | **17** |
|
|
40
|
+
| Failed runs in total | **56** |
|
|
41
|
+
| PRs carrying a follow-up `fix(ci\|gates\|budget\|deps\|tests)` commit | **20 / 50** |
|
|
42
|
+
| Such repair commits in total | **41** |
|
|
43
|
+
|
|
44
|
+
Every one of those pushes SUCCEEDED. What failed was the ending: the push
|
|
45
|
+
returned 0, the turn closed, and the red arrived where the user found it.
|
|
46
|
+
|
|
47
|
+
**Only 19 of 50 PRs landed with neither half.**
|
|
48
|
+
|
|
49
|
+
## The two carriers
|
|
50
|
+
|
|
51
|
+
| Half | Carrier | Behavior |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| Stale base | `check_branch_freshness` in the pre-push hook (`src/scripts/install-hooks.sh`) | Asks the REMOTE, one `ls-remote`, ~4.5 s. Refuses only on a VERIFIED behind state and names the push-ready sequence. Never merges. |
|
|
54
|
+
| Unsettled push | the `push-settle` PostToolUse concern (`src/scripts/hooks/push_settle_hook.ts`) | Fires on git's own ref-advance report, resolves the PR number, and names the literal `ci_settle` command. Warn only. |
|
|
55
|
+
|
|
56
|
+
### What each one does NOT do
|
|
57
|
+
|
|
58
|
+
- **The hook never merges.** Resolution belongs to a step run with the result in
|
|
59
|
+
front of you; a hook that rewrites the tree at the moment the contributor
|
|
60
|
+
believes their work is finished turns one refused push into an unreviewed
|
|
61
|
+
commit. It refuses and names the push-ready sequence instead.
|
|
62
|
+
- **The hook cannot see an unverifiable base.** Offline, in CI, on a detached
|
|
63
|
+
HEAD, or standing on the base itself, `check_branch_freshness` exits 0 and
|
|
64
|
+
says which — so an unreachable network never blocks a push, and a green there
|
|
65
|
+
means "did not refuse", not "current".
|
|
66
|
+
- **The concern cannot block.** It is `severity: advisory`,
|
|
67
|
+
`fail_closed: false`. Leaving a push deliberately unsettled is legitimate;
|
|
68
|
+
ending the turn silently on one is what the reminder exists to stop. Whether
|
|
69
|
+
the reminder changes behavior is unmeasured — it ships as a carrier, not as a
|
|
70
|
+
claim.
|
|
71
|
+
- **Neither reaches a host without the slot.** `agent-config hooks:status`
|
|
72
|
+
answers which slots are bound where you actually are; `post_tool_use` is
|
|
73
|
+
unbound on windsurf and copilot, and there the settle obligation is
|
|
74
|
+
model-carried by the skill alone.
|
|
75
|
+
|
|
76
|
+
## Cost, stated rather than implied
|
|
77
|
+
|
|
78
|
+
The pre-push gate set was already measured at 36.05 s against the 25 s
|
|
79
|
+
`pre_push_budget_seconds` ceiling in `src/config/ci-local-parity.yml`, and the
|
|
80
|
+
freshness gate adds ~4.5 s on the green path. That is a real cost on an already
|
|
81
|
+
over-budget hook, and it is recorded here rather than hidden: the trade is 4.5 s
|
|
82
|
+
per push against 52 base merges and 56 failed runs across 50 PRs. On the RED
|
|
83
|
+
path the hook gets *cheaper*, not dearer — the refusal exits before the ~10 s
|
|
84
|
+
regeneration and the preflight set, because everything after it would be
|
|
85
|
+
answered against a base that is about to move.
|
|
86
|
+
|
|
87
|
+
## The gap this change does NOT close
|
|
88
|
+
|
|
89
|
+
**The pre-push hook is INSTALLED, not read from source.** `install-hooks.sh`
|
|
90
|
+
writes `.git/hooks/pre-push`, and afterwards it is rewritten only by the
|
|
91
|
+
package manager's post-install lifecycle step or by running the installer
|
|
92
|
+
again. Measured in this repository on 2026-09-04, before this change: the
|
|
93
|
+
installed hook was
|
|
94
|
+
**113 lines** against a source body of ~146 — it was missing header revisions
|
|
95
|
+
merged on 2026-08-30, so it had been stale for days with no signal anywhere.
|
|
96
|
+
|
|
97
|
+
The freshness gate therefore does nothing on a checkout whose hook predates it,
|
|
98
|
+
and the contributor is not told. That is a real hole in a change whose whole
|
|
99
|
+
subject is "the agent should not leave work for the user to discover", and it is
|
|
100
|
+
recorded rather than papered over:
|
|
101
|
+
|
|
102
|
+
task install-hooks # rewrites .git/hooks/* from source
|
|
103
|
+
|
|
104
|
+
### Closed 2026-09-05 — the contributor is now told
|
|
105
|
+
|
|
106
|
+
`check_installed_hooks_fresh` renders what `install-hooks.sh` would write into a
|
|
107
|
+
scratch directory and compares content AND the executable bit against
|
|
108
|
+
`.git/hooks`. It runs in the pre-push body — advisory, and after the
|
|
109
|
+
base-freshness gate — and again from the `post-merge` / `post-checkout`
|
|
110
|
+
auto-sync block, at the moment a pull causes the drift.
|
|
111
|
+
|
|
112
|
+
**It reports and never refuses, and the ordering is part of the answer.** The
|
|
113
|
+
predicate is "installed == what THIS checkout renders", and `.git/hooks` is
|
|
114
|
+
shared by every linked worktree, so with two worktrees whose installer bodies
|
|
115
|
+
differ at most one satisfies it at a time — a refusal would fire on ordinary
|
|
116
|
+
parallel work and the skip variable would become routine, which retires the
|
|
117
|
+
check rather than enforcing it. And being behind a base that moved the installer
|
|
118
|
+
is the commonest cause of a mismatch, whose repair is to MERGE: re-installing
|
|
119
|
+
from a behind-base checkout writes the older hook set over the shared directory.
|
|
120
|
+
Base freshness therefore answers first, and the notice never prescribes a
|
|
121
|
+
re-install as universally correct. On the checkout that closed the gap it found `pre-push`, `post-merge` and
|
|
122
|
+
`post-checkout` all stale — the same drift, five days on and one hook wider.
|
|
123
|
+
|
|
124
|
+
It compares rendered output rather than slicing these heredocs, because
|
|
125
|
+
`post-merge` and `post-checkout` are a heredoc PLUS an appended block: no slice
|
|
126
|
+
of the installer equals what it installs, so a slice-based comparison would have
|
|
127
|
+
been wrong for two of six hooks.
|
|
128
|
+
|
|
129
|
+
**What was deliberately NOT built: the repair.** The roadmap asked for
|
|
130
|
+
`post-merge` to re-run the installer so the hooks fixed themselves with no
|
|
131
|
+
command. Two findings stopped it, and both are worth keeping.
|
|
132
|
+
|
|
133
|
+
1. **Measured 2026-09-05:** a bash script that `cat >`-overwrites its own path
|
|
134
|
+
mid-run stops executing at that point and **exits 0**. Every statement after
|
|
135
|
+
it is skipped, silently. A repair placed in `post-merge` would truncate
|
|
136
|
+
`post-merge`'s own remaining body — the projection sync and the CLI rebuild —
|
|
137
|
+
and report success. Any future attempt needs the installer to stage and
|
|
138
|
+
`mv` into place first.
|
|
139
|
+
2. **Linked worktrees share one `.git/hooks`** through the common dir. "The
|
|
140
|
+
installed hooks match the checked-out tree" has no unique referent when eight
|
|
141
|
+
worktrees hold eight versions of the installer: a repair would let whichever
|
|
142
|
+
worktree checked out last redefine the gates all the others run, and a
|
|
143
|
+
checkout of an older branch would reinstall older hooks over newer ones.
|
|
144
|
+
|
|
145
|
+
An AI council (`claude-sonnet-4-5` + `codex-default`, 2026-09-05, two rounds,
|
|
146
|
+
2 of 2 seats present in both) reached the same verdict independently in both
|
|
147
|
+
seats: report, do not repair. *Reopen* on either per-worktree hook isolation
|
|
148
|
+
(`core.hooksPath`) or a branch-independent dispatcher installed once in the
|
|
149
|
+
common dir — both make "which version is authoritative" answerable, which is the
|
|
150
|
+
question the repair cannot currently answer.
|
|
151
|
+
|
|
152
|
+
### Answered 2026-09-05 — consumers get no git hooks, by decision
|
|
153
|
+
|
|
154
|
+
A consumer install writes **no git hooks at all** (`src/install/` references
|
|
155
|
+
`.git/hooks` nowhere, and the package manager's post-install lifecycle step does
|
|
156
|
+
not run for a registry dependency), so the pre-push gate is a maintainer-only
|
|
157
|
+
mechanism. The same council, unanimously, made that the decision rather than the
|
|
158
|
+
status quo: the pre-push chain runs this repository's own consistency and
|
|
159
|
+
preflight gate chains, which depend on its Taskfile, its `./scripts-run` shim
|
|
160
|
+
and its generated trees — none of which exist in a consumer project — and a
|
|
161
|
+
dependency install should not establish persistent repository execution. *Revisit-if* a
|
|
162
|
+
consumer-native gate set is designed with its own opt-in command and consent
|
|
163
|
+
step; that is a product feature, not an extension of this installer. Stated for
|
|
164
|
+
consumers in `docs/development.md` § "Git hooks are maintainer-only". Named
|
|
165
|
+
rather than linked: this file is projected byte-identically into
|
|
166
|
+
`dist/agent-src/`, which sits one level deeper, so a repo-root-relative link
|
|
167
|
+
resolves in one copy and not in the other.
|
|
168
|
+
|
|
169
|
+
## Revisit-if
|
|
170
|
+
|
|
171
|
+
- A later corpus shows base merges and post-push repair commits at a rate the
|
|
172
|
+
carriers cannot explain — then the carriers are firing and not landing, and
|
|
173
|
+
the next lever is delivery, not another reminder.
|
|
174
|
+
- `pre_push_budget_seconds` is enforced by something. Today nothing measures the
|
|
175
|
+
hook, which is how the set grew past its own ceiling with no signal; once it
|
|
176
|
+
is measured, this gate is one of the entries that has to justify its slice.
|
|
@@ -167,6 +167,50 @@ Route::get('/mail-preview', function () {
|
|
|
167
167
|
});
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
+
## Surviving the mail client
|
|
171
|
+
|
|
172
|
+
An email is not a web page. Mail clients strip, rewrite, and ignore CSS that
|
|
173
|
+
every browser honors, so a template that renders correctly in
|
|
174
|
+
`/mail-preview` tells you nothing about the inbox. Markdown templates (above)
|
|
175
|
+
give you a tested baseline for free — this section is what to hold to when a
|
|
176
|
+
design forces you off them.
|
|
177
|
+
|
|
178
|
+
**Four requirements, in order of what breaks first:**
|
|
179
|
+
|
|
180
|
+
1. **Table-based layout, not flexbox or grid.** Use nested `<table>` elements
|
|
181
|
+
with `role="presentation"`, a fixed outer width of 600px, and `cellpadding`
|
|
182
|
+
/ `cellspacing` / `border` set to `0`. `display: flex` and
|
|
183
|
+
`display: grid` are unsupported or partially supported in the Windows
|
|
184
|
+
Outlook family and collapse to a single stacked column.
|
|
185
|
+
2. **Inline styles, not a `<style>` block.** Write `style="…"` on the element.
|
|
186
|
+
A `<head><style>` block is stripped outright by some webmail clients, and
|
|
187
|
+
class selectors then match nothing. Use a CSS inliner at build time if the
|
|
188
|
+
template is authored with classes — never ship the classes unresolved. Keep
|
|
189
|
+
a `<style>` block only for what cannot be inlined (media queries), and treat
|
|
190
|
+
everything in it as optional.
|
|
191
|
+
3. **No web fonts, no background images, no external JS.** Declare a font stack
|
|
192
|
+
ending in a system fallback; a remote font silently degrades. Background
|
|
193
|
+
images require the `v:fill` VML fallback in Outlook, so put the color on
|
|
194
|
+
`bgcolor` and treat the image as decoration.
|
|
195
|
+
4. **Explicit width and alt text on every image, and no image-only content.**
|
|
196
|
+
Images are blocked by default in several clients, so an email whose call to
|
|
197
|
+
action is an image is an email with no call to action.
|
|
198
|
+
|
|
199
|
+
**The client list worth testing, and what breaks in each:**
|
|
200
|
+
|
|
201
|
+
| Client | What breaks |
|
|
202
|
+
|---|---|
|
|
203
|
+
| **Outlook 2016-2019 / Windows (Word engine)** | `flex`, `grid`, `float`, `max-width`, `border-radius`, background images, `padding` on `<div>`; the strictest target — if it renders, most others do |
|
|
204
|
+
| **Outlook.com / Outlook 365 web** | strips `<style>` blocks in some views; rewrites `class` attributes; ignores `margin` on several elements |
|
|
205
|
+
| **Gmail web** | clips the message past ~102 KB of HTML with a "view entire message" link — anything below the clip, including the unsubscribe link, is not seen; strips `<style>` when the message is clipped |
|
|
206
|
+
| **Gmail app (iOS / Android)** | no support for embedded `<style>` on non-Gmail accounts; media queries ignored there, so the mobile layout must be the fluid default |
|
|
207
|
+
| **Apple Mail / iOS Mail** | the most permissive; auto-scales small text and auto-links dates and addresses unless suppressed — a false green if it is the only client you check |
|
|
208
|
+
| **Dark mode (Apple Mail, Outlook, Gmail)** | colors are force-inverted; a logo on a hardcoded white background becomes a white box on dark, and `#000` text on a transparent background becomes invisible |
|
|
209
|
+
|
|
210
|
+
**Verify against a real client, not a preview route.** `/mail-preview` renders in
|
|
211
|
+
a browser and proves none of the above. Send to real accounts, or use a
|
|
212
|
+
rendering service, before the template ships.
|
|
213
|
+
|
|
170
214
|
## Core rules
|
|
171
215
|
|
|
172
216
|
- **Always queue emails** — implement `ShouldQueue` to avoid blocking requests.
|
|
@@ -118,7 +118,9 @@ Schedule::command('queue:work')->everyMinute()->evenInMaintenanceMode();
|
|
|
118
118
|
## Running the scheduler
|
|
119
119
|
|
|
120
120
|
```bash
|
|
121
|
-
# The scheduler itself runs every minute via system cron
|
|
121
|
+
# The scheduler itself runs every minute via system cron.
|
|
122
|
+
# cron has no working directory to inherit, and artisan takes no directory
|
|
123
|
+
# flag, so the `cd` is the shape here rather than a habit worth replacing.
|
|
122
124
|
* * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1
|
|
123
125
|
|
|
124
126
|
# Test locally
|
|
@@ -350,12 +350,6 @@ After detecting **any** match, record the stack in the analysis output and selec
|
|
|
350
350
|
2. Tech stack inventory with versions and dependencies
|
|
351
351
|
3. Architecture diagram or module map
|
|
352
352
|
|
|
353
|
-
## Auto-trigger keywords
|
|
354
|
-
|
|
355
|
-
- project analysis
|
|
356
|
-
- codebase analysis
|
|
357
|
-
- architecture analysis
|
|
358
|
-
|
|
359
353
|
## Gotcha
|
|
360
354
|
|
|
361
355
|
- Full project analysis can take several minutes — warn the user about the time investment.
|
|
@@ -113,8 +113,8 @@ Before installing or upgrading anything, inspect what's already there — modify
|
|
|
113
113
|
- Stuck pods: `pod deintegrate && pod install`.
|
|
114
114
|
|
|
115
115
|
**Build failures**
|
|
116
|
-
- Clean iOS: `
|
|
117
|
-
- Clean Android:
|
|
116
|
+
- Clean iOS: `rm -rf ios/build ios/Pods ios/Podfile.lock` then `pod install --project-directory=ios`.
|
|
117
|
+
- Clean Android: `./gradlew -p android clean`.
|
|
118
118
|
- Clear Xcode derived data when stale build artefacts persist.
|
|
119
119
|
|
|
120
120
|
**New Architecture issues**
|
|
@@ -142,7 +142,7 @@ echo $ANDROID_HOME # non-empty
|
|
|
142
142
|
```bash
|
|
143
143
|
npx @react-native-community/cli init MyProject
|
|
144
144
|
cd MyProject
|
|
145
|
-
|
|
145
|
+
RCT_NEW_ARCH_ENABLED=1 pod install --project-directory=ios
|
|
146
146
|
npm start # Metro
|
|
147
147
|
npm run ios # in a second terminal
|
|
148
148
|
npm run android # in a third terminal
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: react-shadcn-ui
|
|
4
|
-
description: "
|
|
4
|
+
description: "Building React UI on shadcn/ui primitives + Tailwind — the apply/review/polish skill dispatched by `directives/ui/*` for the `react-shadcn` stack; idiom from tailwind-engineer."
|
|
5
5
|
domain: engineering
|
|
6
6
|
workspaces:
|
|
7
7
|
- engineering
|
|
@@ -129,12 +129,22 @@ Explore alternatives when:
|
|
|
129
129
|
1. Numbered reasoning steps with conclusions
|
|
130
130
|
2. Final answer or recommendation with confidence level
|
|
131
131
|
|
|
132
|
-
##
|
|
132
|
+
## Tool availability — this is a procedure, not a tool call
|
|
133
133
|
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
134
|
+
Everything above runs **in-session**: it is a way of structuring reasoning, and
|
|
135
|
+
it needs nothing installed.
|
|
136
|
+
|
|
137
|
+
The wider MCP ecosystem carries a `sequentialthinking` server exposing a tool of
|
|
138
|
+
that name. **This package registers no MCP server** — `mcp.json` ships
|
|
139
|
+
`{"servers": {}}` — so on a default install that tool is not present, and
|
|
140
|
+
nothing here tries to call it. Registering one is a consumer-side install
|
|
141
|
+
decision this package deliberately does not make for you.
|
|
142
|
+
|
|
143
|
+
So a reader on a default install can answer the question directly: the tool is
|
|
144
|
+
not available to you, and none of this skill depends on it. If you have
|
|
145
|
+
registered such a server yourself, the once-per-task limit below governs that
|
|
146
|
+
call too — the limit is about looping, not about which mechanism does the
|
|
147
|
+
thinking.
|
|
138
148
|
|
|
139
149
|
## Gotcha
|
|
140
150
|
|
|
@@ -145,9 +155,9 @@ Explore alternatives when:
|
|
|
145
155
|
## Do NOT
|
|
146
156
|
|
|
147
157
|
- Do NOT use this for simple, well-understood tasks — it adds unnecessary overhead.
|
|
148
|
-
- Do NOT
|
|
149
|
-
you
|
|
150
|
-
- Do NOT use
|
|
158
|
+
- Do NOT run this procedure more than **once per task**. If you are reaching for it
|
|
159
|
+
repeatedly, you are looping — stop and act directly instead.
|
|
160
|
+
- Do NOT use it as a "thinking proxy" — if the task is "view a file" or
|
|
151
161
|
"run a command", just do it. No thinking step needed.
|
|
152
162
|
- Do NOT skip the validation step — always check the solution against the original problem.
|
|
153
163
|
- Do NOT ignore contradictions — they are signals, not noise.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: tailwind-engineer
|
|
4
|
-
description: "
|
|
4
|
+
description: "Writing or reviewing Tailwind CSS — utility-first, design tokens, no inline-style drift, responsive variants, dark mode — 'style this' or 'mach das hübsch'. Pairs with react-shadcn-ui."
|
|
5
5
|
personas:
|
|
6
6
|
- frontend-engineer
|
|
7
7
|
domain: engineering
|
|
@@ -208,6 +208,46 @@ rg -n '\b(it|test|describe)\.skip\b|\.only\b|xit\(|xdescribe\(|@pytest\.mark\.(s
|
|
|
208
208
|
|
|
209
209
|
This is the test-surface instance of the `autonomous-execution` N=3 / allowlist-growth antipattern (bulk `skip`/`xfail` to force green counts as the tool being wrong, not the content) and the `verify-before-complete` floor (green must be *earned*, not manufactured).
|
|
210
210
|
|
|
211
|
+
### The named smells — canonical vocabulary, and what it does NOT cover
|
|
212
|
+
|
|
213
|
+
The behaviors above are described; two of them also have field names a
|
|
214
|
+
reviewer can cite, and this table is where the name meets the behavior. The
|
|
215
|
+
grep column follows the shape [`ai-code-blindspots`](../ai-code-blindspots/SKILL.md)
|
|
216
|
+
uses: an authoring-time backstop, zero results is the pass, a hit is a prompt
|
|
217
|
+
to read that line — never an auto-fix.
|
|
218
|
+
|
|
219
|
+
| Canonical name | The behavior, as already described above | Backstop grep |
|
|
220
|
+
|---|---|---|
|
|
221
|
+
| **Magic-number test** | Anti-Pattern 6 — "a hardcoded expected value the code will always emit". The expectation is a literal rather than something derived from the input, so the test cannot disagree with the code. | `rg -n '\b(toBe\|toEqual\|assertEquals\|assertSame)\(\s*-?[0-9]{2,}' tests/` |
|
|
222
|
+
| **Assertion roulette** | The multi-case stack Anti-Pattern 6 *requires* (boundary, error, abuse in one test), written without per-assertion messages — so a failure names a line number and not a reason. The stack is right; the silence is the smell. | `rg -c '\b(expect\|assert\w*\|self\.assert\w*\|\$this->assert\w*)\(' tests/ \| awk -F: '$2 >= 8'` |
|
|
223
|
+
|
|
224
|
+
Both greps are scoped to **the test file you just wrote**, not to a tree —
|
|
225
|
+
`tests/` above is a placeholder for that path. Run over a whole repository
|
|
226
|
+
they are useless as verdicts: measured on this repository on 2026-09-04 the
|
|
227
|
+
first returns 585 lines and the second 1189 files, because an exact assertion
|
|
228
|
+
against a two-digit literal and a file with eight assertions are both ordinary.
|
|
229
|
+
They are authoring-time prompts to reread one file, exactly as
|
|
230
|
+
`ai-code-blindspots` states, and neither is a gate.
|
|
231
|
+
|
|
232
|
+
The second grep counts per **file**, not per test — no regex sees a test
|
|
233
|
+
boundary.
|
|
234
|
+
|
|
235
|
+
**Three further names are deliberately NOT in the table**, recorded here so a
|
|
236
|
+
later round meets a record rather than a fresh argument. Measured 2026-09-04
|
|
237
|
+
over both files of this skill: `roulette`, `eager`, `lazy` and `duplicate` each
|
|
238
|
+
return **0** occurrences, and `hardcoded` returns **6**.
|
|
239
|
+
|
|
240
|
+
- **Eager test** (one test exercising several behaviors) would carry the same
|
|
241
|
+
behavior and the same grep as assertion roulette above, and Anti-Pattern 6
|
|
242
|
+
*prescribes* the shape on purpose. A row for it would be one entry under two
|
|
243
|
+
names, which is the drift this table exists to prevent.
|
|
244
|
+
- **Lazy test** (several tests over one fixture, differing only in name) is
|
|
245
|
+
described nowhere above. A row would be new guidance wearing a naming step's
|
|
246
|
+
clothes.
|
|
247
|
+
- **Duplicate assert** (the same condition asserted twice in one test) is
|
|
248
|
+
likewise undescribed, and is not greppable without parsing test boundaries —
|
|
249
|
+
so it could not carry the backstop column even if it were.
|
|
250
|
+
|
|
211
251
|
## Output format
|
|
212
252
|
|
|
213
253
|
1. The mocking decision recorded as a one-line comment in the test file (`// mock at <seam>: <reason>`).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: medium
|
|
3
3
|
name: ui-apply-generic
|
|
4
|
-
description: "Use when implementing a UI brief on a stack with no framework executor — Svelte, Astro, Angular, plain HTML.
|
|
4
|
+
description: "Use when implementing a UI brief on a stack with no framework executor — Svelte, Astro, Angular, plain HTML. Stack-independent sibling of react-shadcn-ui; idiom from the stack corpus."
|
|
5
5
|
personas:
|
|
6
6
|
- frontend-engineer
|
|
7
7
|
domain: engineering
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
model_tier: high
|
|
3
3
|
name: ui-component-architect
|
|
4
|
-
description: "
|
|
4
|
+
description: "Shaping a UI component tree — composition vs inheritance, slot patterns, prop API design, controlled vs uncontrolled, polymorphic — on 'split this component'. Feeds react-shadcn-ui."
|
|
5
5
|
personas:
|
|
6
6
|
- frontend-engineer
|
|
7
7
|
domain: engineering
|