@chemx/starter-kit 26.10.4-1258 → 26.10.7-1061
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/AGENTS.md +483 -0
- package/blueprints/molecule-capsule/m-sample-card.svelte +1 -1
- package/blueprints/molecule-capsule/m-sample-card.vue +1 -1
- package/cli/audit/audit-summary.js +30 -0
- package/cli/audit/gate-verdict.js +30 -0
- package/cli/audit/ratchet.js +64 -0
- package/cli/audit-scope.js +44 -0
- package/cli/build/detector.js +0 -2
- package/cli/commands/cmd-audit.js +58 -11
- package/cli/commands/cmd-router.js +3 -1
- package/cli/commands-schema.js +3 -1
- package/cli/errors/catcher.js +11 -1
- package/cli/host-shims.js +74 -0
- package/cli/installer.js +4 -44
- package/cli/mcp/antigravity.js +4 -5
- package/cli/mcp/call-scope.js +93 -0
- package/cli/mcp/index.js +6 -2
- package/cli/mcp/manifests.js +13 -1
- package/cli/mcp/server.js +26 -27
- package/cli/mcp/tools-audit.js +27 -11
- package/cli/mcp/tools-search-util.js +1 -10
- package/cli/mcp/tools-team-tasks.js +6 -4
- package/cli/mcp/tools.js +15 -4
- package/cli/navigator-actions.js +1 -1
- package/cli/navigator-banner-helpers.js +15 -5
- package/cli/navigator-banner.js +2 -9
- package/cli/navigator-guide.js +2 -2
- package/cli/path-scope.js +1 -1
- package/cli/pillars-schema.js +8 -82
- package/cli/pillars-wizard.js +56 -44
- package/cli/pillars-write-guard.js +52 -0
- package/cli/reader-markdown.js +26 -0
- package/cli/reader.js +8 -6
- package/cli/scaffold-frameworks.js +29 -0
- package/cli/scaffold.js +2 -10
- package/cli/team/task-list-view.js +43 -0
- package/cli/team/team-commands.js +11 -6
- package/cli/team/team-flags.js +1 -0
- package/cli/team/team-format.js +4 -2
- package/cli/verify.js +33 -15
- package/package.json +8 -4
- package/cli/audit/autofix.spec.js +0 -85
- package/cli/audit/clone-detector.spec.js +0 -46
- package/cli/audit/csharp-analyzer.spec.js +0 -216
- package/cli/audit/pattern-detector.spec.js +0 -113
- package/cli/audit/prompts.spec.js +0 -367
- package/cli/audit/rules.spec.js +0 -361
- package/cli/audit/slop-string-literal.spec.js +0 -34
- package/cli/audit/social-git.spec.js +0 -71
- package/cli/audit/structural-weight.spec.js +0 -116
- package/cli/audit-preflight.spec.js +0 -115
- package/cli/audit-stages.spec.js +0 -30
- package/cli/blast-radius.spec.js +0 -113
- package/cli/build/detector.spec.js +0 -81
- package/cli/columnar.spec.js +0 -49
- package/cli/config/config.spec.js +0 -51
- package/cli/config.spec.js +0 -1
- package/cli/create.spec.js +0 -291
- package/cli/embeddings.spec.js +0 -92
- package/cli/errors/errors.spec.js +0 -163
- package/cli/exploder.spec.js +0 -99
- package/cli/friction-fixes.spec.js +0 -96
- package/cli/generator-compact.spec.js +0 -104
- package/cli/generator-framework.spec.js +0 -315
- package/cli/generator-jig.spec.js +0 -148
- package/cli/generator-templates/archetypes/vector-matcher.spec.js +0 -25
- package/cli/generator-templates.spec.js +0 -187
- package/cli/generator.spec.js +0 -288
- package/cli/help.spec.js +0 -109
- package/cli/installer.spec.js +0 -72
- package/cli/languages.spec.js +0 -65
- package/cli/mcp/installer.spec.js +0 -118
- package/cli/mcp/server.spec.js +0 -710
- package/cli/mcp/tools-project.spec.js +0 -51
- package/cli/mutators.spec.js +0 -176
- package/cli/navigator-banner.spec.js +0 -68
- package/cli/patcher.spec.js +0 -190
- package/cli/path-traversal.spec.js +0 -242
- package/cli/pillars.spec.js +0 -138
- package/cli/polyglot.spec.js +0 -222
- package/cli/project-detector.spec.js +0 -123
- package/cli/reader-logic.spec.js +0 -160
- package/cli/reader-polyglot.spec.js +0 -47
- package/cli/reader-shorthand.spec.js +0 -60
- package/cli/search-bulletproof.spec.js +0 -104
- package/cli/search-queries-hotspot-graph.spec.js +0 -66
- package/cli/search-queries-similar.spec.js +0 -43
- package/cli/search.spec.js +0 -294
- package/cli/team/team-adversarial-locks.spec.js +0 -176
- package/cli/team/team-adversarial-telemetry.spec.js +0 -93
- package/cli/team/team-concurrency-stress.spec.js +0 -95
- package/cli/team/team-lock-concurrency.spec.js +0 -182
- package/cli/team/team-mailbox-empirical.spec.js +0 -191
- package/cli/team/team-mailbox.spec.js +0 -93
- package/cli/team/team-memory.spec.js +0 -123
- package/cli/team/team-multi-model-telemetry.spec.js +0 -80
- package/cli/team/team-multiprocess-concurrency.spec.js +0 -193
- package/cli/team/team-projects.spec.js +0 -116
- package/cli/team/team-release-train.spec.js +0 -91
- package/cli/team/team-tasks-asana.spec.js +0 -60
- package/cli/team/team-tasks-hierarchy.spec.js +0 -176
- package/cli/team/team-vds.spec.js +0 -125
- package/cli/team/team-verification-gate.spec.js +0 -280
- package/cli/team/team.spec.js +0 -574
- package/cli/tesseract.spec.js +0 -55
- package/cli/trace.spec.js +0 -92
- package/cli/trend.spec.js +0 -51
- package/cli/ui-canonical-routes.spec.js +0 -130
- package/cli/ui-direct-routes.spec.js +0 -55
- package/cli/ui-e2e-verification.spec.js +0 -197
- package/cli/ui-filetree.spec.js +0 -175
- package/cli/ui-kanban.spec.js +0 -217
- package/cli/ui-sse.spec.js +0 -100
- package/cli/ui-vbulletin.spec.js +0 -188
- package/cli/ui-workbench-dbstudio.spec.js +0 -172
- package/cli/ui.spec.js +0 -312
- package/cli/verify-lint.spec.js +0 -44
- package/cli/verify.spec.js +0 -211
package/AGENTS.md
ADDED
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
# Chemical X Molecular Architecture Directives
|
|
2
|
+
|
|
3
|
+
> *"Clean, literate code that reads like poetry to both humans and AI."*
|
|
4
|
+
> Mandatory architectural directives for AI agents operating on this repository. Strictly enforce these standards on every code generation, refactor, and review pass.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. The Molecular Architecture Protocol
|
|
9
|
+
|
|
10
|
+
### A. Structural Weight, Cognitive Cohesion & Profile Architecture
|
|
11
|
+
- **The Pragmatic Staff Engineer Paradigm (Default)**: Chemical X audits **Structural Weight and Responsibility Density**, not arbitrary mechanical line caps. A cohesive 140-line table, modal, or canvas wrapper where state and layout are naturally co-located is far cleaner and more reliable for LLMs to edit than six fractured micro-files connected by prop-drilling. Slicing cohesive logic into artificial files just to appease a counter is an anti-pattern: *indirection masquerading as modularity*.
|
|
12
|
+
- **Structural Weight Limits (Pragmatic Default)**:
|
|
13
|
+
- **Cyclomatic Complexity**: Max 12 decision points per component/hook.
|
|
14
|
+
- **Hook & State Density**: Max 4 independent hooks/state setters before extracting into a domain hook or reducer.
|
|
15
|
+
- **Render Tree Depth**: Max 4 nesting levels in JSX/templates; nested ternaries are strictly banned in favor of computed descriptor objects.
|
|
16
|
+
- **Prop Surface Area**: Max 7 flat props before grouping into a typed domain entity model.
|
|
17
|
+
- **Line Budget**: Soft warning at 250 lines only if cyclomatic complexity is high.
|
|
18
|
+
- **Atomic-Strict Profile (`--profile=atomic-strict`)**: Opt-in strict mode enforcing 100-line capsule caps and mandatory atomization for teams building foundational design system component primitives.
|
|
19
|
+
- **The Rule of Three for Abstractions**: Premature abstraction is worse than duplication. Do NOT extract an atom or molecule until a pattern is reused across 3+ distinct features, or until it encapsulates isolated behavioral/accessibility requirements.
|
|
20
|
+
|
|
21
|
+
### B. Table-of-Contents Views
|
|
22
|
+
- Top-level page views MUST NEVER contain hundreds of lines of nested DOM scaffolding.
|
|
23
|
+
- A view template MUST read like a clean, 10 to 20 line declarative Table of Contents assembling self-contained molecules and organisms via named slot templates (`#header`, `#default`, `#modals`).
|
|
24
|
+
|
|
25
|
+
### C. Crystalline Molecule Capsules
|
|
26
|
+
- Every molecule and organism lives in an isolated, self-contained directory capsule:
|
|
27
|
+
```
|
|
28
|
+
m-<feature>-card/
|
|
29
|
+
├── m-<feature>-card.<ext> (< 100 lines: declarative layout & bindings)
|
|
30
|
+
├── m-<feature>-card.controller.ts (pure reactive state & 2-stage booleans)
|
|
31
|
+
├── _m-<feature>-card.scss (mixin-only glass styling)
|
|
32
|
+
├── types.d.ts (pure Props & Emits declarations)
|
|
33
|
+
└── index.ts (clean public entrypoint)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### D. Anti-Prop-Drilling & Domain State
|
|
37
|
+
- Never pass 10+ props or chained event bubbles across component tiers.
|
|
38
|
+
- Encapsulate shared feature state in dedicated domain composables/hooks, scoped stores, or typed provide/inject.
|
|
39
|
+
- Child components consume state directly from the domain composable and emit minimal, intention-revealing semantic events.
|
|
40
|
+
|
|
41
|
+
### E. Same-Name Prop Shorthand (Vue 3.4+ & Svelte 5)
|
|
42
|
+
- **Vue 3.4+**: Always use same-name `:prop` shorthand instead of redundant `:prop="prop"`:
|
|
43
|
+
`<m-spark-kpi-strip :metrics :records :can-refresh />`
|
|
44
|
+
- **Svelte 5**: Always use same-name `{prop}` shorthand instead of `prop={prop}`:
|
|
45
|
+
`<SparkKpiStrip {metrics} {records} {canRefresh} />`
|
|
46
|
+
- **React 19 (JSX)**: Explicitly bind `prop={prop}`. Never write `<Comp prop />` for variables (JSX evaluates bare attributes to boolean `true`).
|
|
47
|
+
|
|
48
|
+
### F. Pre-Split Pattern Discovery & Harmonization Protocol
|
|
49
|
+
- **Survey Before Slicing**: Before decomposing any monolithic file or collection of files, the AI must first conduct a cross-file pattern discovery audit across all candidate monoliths.
|
|
50
|
+
- **Identify Recurring Structures**: Map shared UI layouts, duplicate controllers, repeated predicates, common state machines, and mirrored type definitions across files before writing any split code.
|
|
51
|
+
- **Map to Existing Foundations**: Check the design system, shared atom catalog (`x-*`), central composables, and core utilities first. Never invent a bespoke one-off atom or utility if an equivalent foundation exists.
|
|
52
|
+
- **Canonical Extraction First**: Consolidate and extract shared atoms, molecules, or composables once into canonical capsules before splitting consumer monoliths.
|
|
53
|
+
- **Zero Bespoke Pattern Proliferation**: Decompose consumer monoliths by binding directly to the extracted canonical capsules, preventing the proliferation of duplicate, slightly divergent patterns across spliced views.
|
|
54
|
+
|
|
55
|
+
### G. Component Encapsulation, Semantic Integrity & The Zero-Raw-DOM Scope
|
|
56
|
+
- **Pragmatic Profile (Default)**: Wrapping every native `<button>`, `<input>`, or `<a>` in a trivial single-line atom creates pointless wrapper boilerplate. In Pragmatic mode, native semantic elements are permitted, provided they maintain:
|
|
57
|
+
1. *Design Token Integrity*: Styled using design tokens, theme utilities, or scoped classes (no hardcoded hex colors or raw style objects).
|
|
58
|
+
2. *Accessibility Standard*: Native semantic interactive elements (never clickable `<div>` without keyboard roles), valid `type` on buttons, and `aria-label`/alt tags.
|
|
59
|
+
3. *Security Sanitization*: DOMPurify sanitization on dynamic HTML; no `javascript:` pseudo-protocols.
|
|
60
|
+
- **Atomic-Strict Profile (`--profile=atomic-strict`)**: When building standalone design system libraries, the strict Zero-Raw-DOM rule applies: raw DOM elements are restricted strictly to the Atom tier (`a-*`).
|
|
61
|
+
- **Tab List & Complex Pattern Harmonization**:
|
|
62
|
+
- When repeated elements accumulate behavioral logic, accessibility handling, or styling variants across 3+ places (Rule of Three), extract into a canonical capsule (`m-tab-button`).
|
|
63
|
+
|
|
64
|
+
### H. AI Agent Codebase Query Machine Protocol
|
|
65
|
+
- **Search First Rule**: AI agents MUST invoke `pnpm chemx q "<query>"` (or `npx chemx search "<query>"`) before running broad ripgrep, find, or file dumping.
|
|
66
|
+
- **AST Architecture Intelligence**: Always leverage `pnpm chemx q` to inspect component tiers, exported symbols, props, and hooks with minimal token burn.
|
|
67
|
+
- **Mandatory Blast Radius Pre-Refactor Check**: Prior to modifying any foundational atom (`a-*`), shared molecule, or central composable (`use*`), agents MUST calculate the transitive blast radius (`pnpm chemx q <target> --blast-radius --json` or `chemx({ action: 'q', params: { query: '<target>', blastRadius: true } })`). Never perform blind refactors without mapping direct consumers, transitive dependents, and impacted tiers.
|
|
68
|
+
- **Hybrid RRF Discovery Protocol**: When discovering components, controllers, or state machines without an exact symbol name, agents MUST use hybrid search (`pnpm chemx q "<concept>" --hybrid --json` or `chemx({ action: 'q', params: { query: '<concept>', hybrid: true } })`). This blends BM25 keyword matching and vector cosine similarity via Reciprocal Rank Fusion (RRF), eliminating keyword misses and semantic hallucinations.
|
|
69
|
+
- **Semantic Vector Discovery**: Use `pnpm chemx q "<query>" --semantic --json` for purely conceptual lookups.
|
|
70
|
+
- **Inspect Mode**: Use `pnpm chemx q "<capsule-name>" --inspect` to examine props and hooks without reading entire source files into context.
|
|
71
|
+
- **JSON & Columnar Mode**: Use `pnpm chemx q "<query>" --json` for zero-overhead, machine-readable agent lookups in token-compact columnar format (`cols` and `rows`).
|
|
72
|
+
- **Tier Filtering**: Use `pnpm chemx q "<query>" --tier=molecule` (or `atom`, `organism`, `hook`) to narrow scope instantly.
|
|
73
|
+
|
|
74
|
+
### I. Capsule Trust-Tier Classification & Audit Escalation
|
|
75
|
+
- **Tier 1 (Pure / Stateless)**: Atoms, formatters, pure validators, and API client wrappers. Agents may trust exported interface contracts without inspecting internal implementation details.
|
|
76
|
+
- **Tier 2 (Stateful / Side-Effecting)**: Auth, payments, data mutation, session lifecycle, and transactional service layers. Declared explicitly in capsule `index.ts` metadata or capsule frontmatter (`trustTier: 2`).
|
|
77
|
+
- **Exemption from Shallow Interface Trust**: Tier 2 capsules are strictly exempted from "agent trusts interface, never reads implementation". Agents must inspect implementation details for state invariants and side-effect guarantees.
|
|
78
|
+
- **Automated Audit Escalation**: Query tools and audits automatically escalate review strictness for Tier 2 capsules, requiring deep verification of state transitions, mutation boundaries, and failure recoverability.
|
|
79
|
+
|
|
80
|
+
### J. Stateful Class & Shared Instance State Carve-Out
|
|
81
|
+
- **Atomic Unit Protection**: Stateful classes and services holding shared instance state across methods are treated as a single atomic unit.
|
|
82
|
+
- **Prohibition on Method Slicing**: Never split methods sharing internal instance state into isolated files or micro-functions. Atomization must not destroy the cohesive state machine.
|
|
83
|
+
- **Decomposition Protocol**: When approaching file line limits, decompose exclusively by extracting pure, stateless helper functions, mathematical derivations, and boundary validators out of the class into standalone utility capsules, preserving the class methods and instance state together.
|
|
84
|
+
|
|
85
|
+
### K. The Verification-First Protocol & Zero-Token-Burn Pipeline
|
|
86
|
+
- **Verification First Rule**: AI agents MUST NEVER execute raw, unthrottled `npm test`, `pnpm test`, `vitest`, `tsc --noEmit`, or `npm run build` directly in a bash subshell. Raw shell executions flood the context window with hundreds of lines of passing checkmarks, compiler noise, and bundle asset tables, burning thousands of tokens and causing premature context exhaustion.
|
|
87
|
+
- **MCP Verification Tools First**: Agents MUST invoke the dedicated Chemical X MCP tools or CLI wrappers (`pnpm chemx <subcommand>` or `npx chemx <subcommand>`):
|
|
88
|
+
1. `chemx_verify` (or `pnpm chemx verify --json` / `npx chemx verify --json`): Runs the full verification pipeline (AST Audit + Typecheck + Tests) and returns a single token-compact status card (~45 tokens if green).
|
|
89
|
+
2. `chemx_typecheck` (or `pnpm chemx typecheck --json` / `npx chemx typecheck --json`): Runs silent TypeScript typecheck; returns structured diagnostics only if errors exist.
|
|
90
|
+
3. `chemx_test` (or `pnpm chemx test --json` / `npx chemx test --json`): Runs silent project tests; suppresses passing tests and returns ONLY failing test assertions and stack diffs.
|
|
91
|
+
4. `chemx_audit_build` (or `pnpm chemx build --json` / `npx chemx build --json`): Runs silent production builds; catalogs diagnostics into TypeScript, Rollup, and style budgets.
|
|
92
|
+
- **Actionable Failure Focus**: If a verification step fails, agents consume the exact failure line and diff, fix the code surgically, and re-verify without ever paying the token penalty of passing checks.
|
|
93
|
+
|
|
94
|
+
### L. Database-First Swarm Coordination & The Zero-Markdown-Monolith Directive
|
|
95
|
+
- **Database as the Master Source of Truth**: The multi-agent orchestrator and subagents MUST record all milestones, task assignments, status changes, file locks, and architectural contracts directly in `.chemx/index.db` (`agent_tasks`, `file_lock_queue`, `agent_feed`) rather than creating monolithic, multi-thousand-token markdown specification files.
|
|
96
|
+
- **Prohibition on Monolithic Project Markdown Parsing**: Subagents MUST NOT load giant monolithic `PROJECT.md` or status markdown files into context. Subagents query only their assigned task slice and dependencies via `pnpm chemx team task list --agent=@my-id` or MCP `chemx_team_task`, slashing token consumption by 80%+.
|
|
97
|
+
- **Project Markdown as a Generated Read-Only Projection**: If a human-readable `PROJECT.md` is requested, it MUST be generated on-demand as a read-only projection compiled from the database state via `pnpm chemx team status` or export tools.
|
|
98
|
+
|
|
99
|
+
### M. The Master MCP Tool Protocol & Zero-Permission Dispatch
|
|
100
|
+
- **Master Gateway Rule**: When operating inside environments with per-tool permission controls (e.g. Antigravity, Claude Desktop, Cursor), AI agents MUST invoke the unified master MCP tool `chemx` (or `chemx({ action, params })`) rather than invoking fragmented tool names or dropping down to bash subshells.
|
|
101
|
+
- **Antigravity Tool Mapping**: In Google Antigravity, `chemx` is registered under server name `chemical-x` (`call_mcp_tool` with `ServerName: "chemical-x"`, `ToolName: "chemx"`). Always prioritize this tool for all AST reading, querying, testing, verification, and file operations.
|
|
102
|
+
- **Strict Ban on Fragmented Sub-Tool Calls**: Agents are strictly prohibited from calling individual tool names (such as `chemx_read`, `chemx_audit`, or `chemx_write`) directly when the master gateway tool is available. Every distinct tool name triggers a separate permission confirmation dialog for the user, resulting in severe prompt fatigue. Calling `chemx({ action, params })` or `chemx({ command })` routes through a single authorization point.
|
|
103
|
+
- **One-Time Approval Advantage**: The `chemx` master tool provides a single authorization point for the user. Once approved, all operations (`test`, `build`, `verify`, `typecheck`, `audit`, `check`, `patch`, `write`, `read`, `team`, `q`, `autofix`, `issue`) execute silently in-process with zero terminal confirmation prompts.
|
|
104
|
+
- **In-Band JSON-RPC Communication (Zero Disk Dumps)**: All query, inspection, and verification tools must communicate strictly in-band via MCP `CallToolResult` objects (`content: [{ type: "text", text: "..." }]`). Tools must never dump intermediate text files (.txt/.md) or scratch files to disk for AI consumption.
|
|
105
|
+
- **Command Forwarding Syntax**: Agents may invoke either structured action objects (`chemx({ action: 'test' })`, `chemx({ action: 'build' })`, `chemx({ action: 'audit', params: { path: 'src' } })`) or CLI command strings (`chemx({ command: 'test' })`, `chemx({ command: 'build' })`, `chemx({ command: 'audit src' })`).
|
|
106
|
+
- **Master Action & Parameter Dispatch Matrix**:
|
|
107
|
+
```typescript
|
|
108
|
+
// Discovery & Impact Analysis
|
|
109
|
+
chemx({ action: 'q', params: { query: 'a-button', blastRadius: true } });
|
|
110
|
+
chemx({ action: 'q', params: { query: 'button state', semantic: true } });
|
|
111
|
+
chemx({ action: 'q', params: { query: 'useAttentionCardController', hybrid: true } });
|
|
112
|
+
|
|
113
|
+
// Surgical AST Reading & Connections
|
|
114
|
+
chemx({ action: 'read', params: { path: 'src/...', symbol: 'ButtonVariant', connections: true } });
|
|
115
|
+
chemx({ action: 'read', params: { path: 'src/...', outline: true } });
|
|
116
|
+
// Component capsules only: outline + logic skeleton in one call (procedural modules: outline or symbol)
|
|
117
|
+
chemx({ action: 'read', params: { path: 'src/...', outline: true, enrich: true } });
|
|
118
|
+
// Component capsules: outline + logic + forward call trace card
|
|
119
|
+
chemx({ action: 'read', params: { path: 'src/...', outline: true, enrich: true, traceSymbol: 'handleCheckout' } });
|
|
120
|
+
// Component capsules: outline + logic + reverse caller chain card
|
|
121
|
+
chemx({ action: 'read', params: { path: 'src/...', outline: true, enrich: true, backtraceSymbol: 'handleCheckout' } });
|
|
122
|
+
|
|
123
|
+
// Surgical Modification & Rules Check
|
|
124
|
+
chemx({ action: 'patch', params: { path: 'src/...', target: 'oldCode', replacement: 'newCode' } });
|
|
125
|
+
chemx({ action: 'write', params: { path: 'src/...', content: '...' } });
|
|
126
|
+
chemx({ action: 'check', params: { path: 'src/...' } });
|
|
127
|
+
|
|
128
|
+
// Deterministic Parameterized Scaffolding (Universal Jig - 90%+ Token Reduction)
|
|
129
|
+
chemx({ action: 'generate', params: { jig: true, kind: 'service', name: 'payment-gateway', methods: [{ name: 'charge', params: 'amount: number' }] } });
|
|
130
|
+
chemx({ action: 'generate', params: { jig: true, kind: 'route', name: 'api-orders', routes: ['GET /orders', 'POST /orders'] } });
|
|
131
|
+
chemx({ action: 'generate', params: { jig: true, kind: 'store', name: 'session-store' } });
|
|
132
|
+
|
|
133
|
+
// Verification, Targeted Testing & Multi-Agent Swarm
|
|
134
|
+
chemx({ action: 'test', params: { target: 'src/services/payment-gateway.spec.ts' } });
|
|
135
|
+
chemx({ action: 'test', params: { target: 'cli/generator.spec.js', filter: 'jig' } });
|
|
136
|
+
chemx({ action: 'verify' });
|
|
137
|
+
chemx({ action: 'team', params: { action: 'task', subAction: 'claim', taskId: 1, as: '@agent' } });
|
|
138
|
+
chemx({ action: 'team', params: { action: 'task', subAction: 'done', taskId: 1, as: '@agent', force: true } });
|
|
139
|
+
chemx({ action: 'team', params: { action: 'lock', subAction: 'acquire', filePath: 'src/...', agentId: '@agent' } });
|
|
140
|
+
```
|
|
141
|
+
- **Strict Prohibition on Bash Escalation**: Agents MUST NOT spawn bash subshells (`run_command` with `pnpm chemx ...` or `node cli/...`) when an equivalent in-process `chemx` MCP action exists.
|
|
142
|
+
|
|
143
|
+
### N. Database-First Navigation, Symbol Connections & The Zero-Native-File-Dump Directive
|
|
144
|
+
- **Database Master Index First**: Before inspecting or modifying any file, AI agents MUST query the SQLite database (`.chemx/index.db`) or the AST Query Machine (`chemx({ action: 'team', params: { action: 'list' } })`, `chemx({ action: 'q', params: { query } })`) rather than exploring the filesystem with broad find or ripgrep commands.
|
|
145
|
+
- **Targeted Symbol-Only Extraction**: AI agents MUST NEVER dump entire source files into context. When an agent needs to inspect a function, hook, interface, or class, it MUST request only that specific symbol: `chemx({ action: 'read', params: { path, symbol: '<name>' } })`.
|
|
146
|
+
- **Read Window Auto-Outline**: Files longer than the chemx read window (100 lines by default), read without a target symbol or slice, automatically render an AST outline to prevent token exhaustion and host buffer spillovers (such as IDE `output.txt` dumps). The read window is a tool budget, not an architecture rule; file size is governed by 1.A.
|
|
147
|
+
- **Enrich Mode (Component Capsules Only)**: When an agent needs both exported signatures AND logic flow for a component capsule, use `enrich: true` with `outline: true`: one response card holds the outline and a compacted logic skeleton, optionally with a forward trace or reverse caller chain (`traceSymbol`, `backtraceSymbol`). The skeleton generator is tuned for components; on procedural modules (services, CLI code, utilities) enrich saves only a few percent over reading the whole file, so use plain `outline: true` or `symbol: '<name>'` there.
|
|
148
|
+
- **Symbol Connection Graph Over Multi-File Dumps**: Rather than reading multiple files to understand imports and consumers, agents MUST request symbol connections: `chemx({ action: 'read', params: { path, symbol: '<name>', connections: true } })` or `chemx({ action: 'q', params: { query, connections: true } })`. This instantly returns the definition, imported dependencies, and caller references in ~45 tokens.
|
|
149
|
+
- **Prohibition on Native File Analyzers (`view_file` Ban)**: AI agents are strictly prohibited from using native IDE file-viewing tools (`view_file`, `read_file`, `cat`, `head`, `tail`, or full-file context dumps). Dumping raw files burns thousands of tokens, causes premature context exhaustion, and defeats the token economics of the molecular architecture. All inspections MUST flow through Chemical X AST readers.
|
|
150
|
+
|
|
151
|
+
### O. Universal Programmatic File Jig & Closed-Loop Execution Protocol
|
|
152
|
+
- **Deterministic Parameterized Synthesis**: When creating non-UI files (services, API route handlers, state stores, database repositories, utilities, or test specs), AI agents MUST NOT emit hundreds of lines of mechanical boilerplate via raw file writing tools. Agents MUST invoke `chemx generate --jig=<kind>` or `chemx({ action: 'generate', params: { jig: true, kind, name, ... } })`.
|
|
153
|
+
- **The 90%+ Output Token Reduction Thesis**: Passing a 30-50 token structured parameter set replaces 1,000-2,500 output tokens of repetitive TypeScript, imports, error tuples, and test boilerplate.
|
|
154
|
+
- **The Closed-Loop ChemX Execution Cycle**:
|
|
155
|
+
1. *Generate (Jig)*: Stamp out compliant architecture via `chemx({ action: 'generate', params: { jig: true, ... } })`.
|
|
156
|
+
2. *Read (Outline)*: Inspect AST shape via `chemx({ action: 'read', params: { path, outline: true } })`.
|
|
157
|
+
3. *Patch (Surgical Edit)*: Ingest domain logic via `chemx({ action: 'patch', params: { path, target, replacement } })`.
|
|
158
|
+
4. *Test (Targeted Slice)*: Run isolated unit tests in milliseconds via `chemx({ action: 'test', params: { target: '<spec-path>' } })`.
|
|
159
|
+
5. *Verify (Full Guard)*: Validate AST score and types via `chemx({ action: 'verify' })`.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 2. Domain-Based Type Architecture & Data Integrity
|
|
164
|
+
|
|
165
|
+
### A. The Anti-Type-Monolith Rule & Domain-Scoped Capsules
|
|
166
|
+
- Strictly prohibit dumping thousands of unrelated entity types into a single monolithic `types.ts` or `global.d.ts`.
|
|
167
|
+
- Co-locate granular `types/*.d.ts` declaration files directly inside each molecule, organism, or feature directory capsule.
|
|
168
|
+
- Split type files by domain, not by line count: once a file declares entities from more than one domain, decompose it into granular domain files (`session.d.ts`, `auth.d.ts`, `billing.d.ts`). File length follows 1.A; there is no separate type-file line cap.
|
|
169
|
+
- Root `types/*.d.ts` is reserved strictly for universal system primitives (`ResultTuple<T>`, `AsyncDataState<T>`, base envelopes). It never contains domain entity models.
|
|
170
|
+
- Zero runtime logic in type files. Zero implicit `any`.
|
|
171
|
+
|
|
172
|
+
### B. Discriminated State Unions (Zero Impossible States)
|
|
173
|
+
- Model component and session state as strict discriminated/disjoint unions in domain `types/*.d.ts` rather than multiple conflicting booleans:
|
|
174
|
+
```typescript
|
|
175
|
+
export type SessionState =
|
|
176
|
+
| { readonly status: 'idle' }
|
|
177
|
+
| { readonly status: 'loading'; readonly progress: number }
|
|
178
|
+
| { readonly status: 'active'; readonly sessionId: string }
|
|
179
|
+
| { readonly status: 'fault'; readonly faultMessage: string };
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### C. Result Tuple Pattern (`toResult`)
|
|
183
|
+
- Avoid nested `try/catch` blocks in async flows. Return Go/Rust-style `[data, error]` tuples with top-of-function early guard clauses:
|
|
184
|
+
```typescript
|
|
185
|
+
const [data, fetchError] = await toResult(api.fetchEntity(id));
|
|
186
|
+
if (fetchError) {
|
|
187
|
+
handleError(fetchError);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
initializeEntity(data);
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### D. Zero Synthetic or Mock Data
|
|
194
|
+
- Never generate fake names, synthetic emails (`@gmail.com`), random phone numbers (`555-xxx`), mock license numbers, or fake entity arrays.
|
|
195
|
+
- Return genuine live API data or explicit empty states (`No records found`).
|
|
196
|
+
|
|
197
|
+
### E. Immutable State Action Boundaries
|
|
198
|
+
- Never mutate deep nested store properties inside child components. State transitions occur strictly through named, traceable store actions.
|
|
199
|
+
|
|
200
|
+
### F. Runtime API Boundary Guards
|
|
201
|
+
- External API and network payloads must be verified through pure, atomic runtime type guards before ingestion into reactive state.
|
|
202
|
+
|
|
203
|
+
### G. Backend Schema Ground-Truth Hierarchy
|
|
204
|
+
- **Schema as Single Source of Truth**: Backend database schemas (SQL/Prisma/migrations) and OpenAPI specifications constitute ground truth: domain types are strictly derived views.
|
|
205
|
+
- **Bidirectional Schema Validation**: Domain types and boundary interfaces must be validated against the active schema or OpenAPI contract rather than treated as independently authoritative.
|
|
206
|
+
- **Drift Prevention**: Never hand-craft unvalidated entity definitions. Mismatches in nullability, default values, or field mutations must fail compile-time checks or contract test suites before ingestion.
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 3. Control Flow & Self-Documenting Logic
|
|
211
|
+
|
|
212
|
+
### A. Named Conditions & Two-Stage Composition
|
|
213
|
+
> The `if` never asks a question. The question is asked and named before the branch, and the `if` reads the answer.
|
|
214
|
+
|
|
215
|
+
- Every conditional test is a named boolean: an identifier, its negation, or a call or member access whose name is an assertion (3.F). A raw comparison (`x === y`, `n >= 5`), a truthiness check on a non-boolean (`if (user)`, `if (obj.prop)`), inline compound logic (`a && b`), or a verb-named call (`RE.test(s)`, `fs.existsSync(p)`) inside the test is a violation.
|
|
216
|
+
- Naming is the point, not the ceremony: it forces the question inline code hides (why `<= 0` and not `=== -1`?), and an edit to a named condition changes its definition without touching the branch.
|
|
217
|
+
- **Stage 1** names each atomic concept. **Stage 2** names the decision, only when 2 or more concepts compose; a single comparison gets one name and no wrapper. Guard with early returns.
|
|
218
|
+
```typescript
|
|
219
|
+
if (hookCount > 5) return; // ❌ the if asks
|
|
220
|
+
const exceedsHookBudget = hookCount > 5; // ✅ the question, named
|
|
221
|
+
if (exceedsHookBudget) return; // the if reads the answer
|
|
222
|
+
|
|
223
|
+
const handleCheckout = () => {
|
|
224
|
+
// Stage 1: atomic concepts (Layer 1/2 predicates from 3.B where they exist)
|
|
225
|
+
const hasSufficientFunds = userBalance >= totalCost;
|
|
226
|
+
const isFormComplete = isAddressValid && hasAcceptedTerms;
|
|
227
|
+
// Stage 2: the decision
|
|
228
|
+
const canCheckout = hasItems(cart) && isFormComplete && hasSufficientFunds && !isProcessing;
|
|
229
|
+
if (!canCheckout) return;
|
|
230
|
+
processPayment();
|
|
231
|
+
};
|
|
232
|
+
```
|
|
233
|
+
- In React, booleans are pure in-render derivations: never use `useEffect` for computed/derived state.
|
|
234
|
+
|
|
235
|
+
### B. The Predicate Lexicon & Higher-Order Filter Extraction
|
|
236
|
+
- Named conditions come from three layers. A raw comparison belongs in a named declaration (3.A) or inside a Layer 1 or Layer 2 predicate body, never in a conditional test.
|
|
237
|
+
1. **Structural primitives** (`lib/is/`: `value`, `collection`, `text`, `fs`, `type`): subject-agnostic and finite (`isAbsent`, `hasItems`, `isNonEmptyString`, `pathExists`). They import nothing, and the set does not grow. Every primitive is a TypeScript type predicate (`(x: unknown): x is string`), never a plain `boolean`, or callers lose narrowing.
|
|
238
|
+
2. **Domain vocabulary** (`<subsystem>/<domain>-predicates.<ext>`, colocated with the subsystem it describes): built from Layer 1. A condition earns a domain predicate at its 2nd use; a threshold duplicated across files (`score >= 90`) silently disagrees the day one copy changes, so name it once (`isGradeA`). Promote threshold literals in predicate bodies to named constants (`score >= GRADE_A_THRESHOLD`).
|
|
239
|
+
3. **Decisions**: single-use composites declared at the call site per 3.A. Never extract them: extracting every condition is *indirection masquerading as modularity* (1.A).
|
|
240
|
+
- Before naming a new predicate, search for an existing one (`chemx({ action: 'q', params: { query: '<concept>', semantic: true } })`). A synonym beside an existing predicate (`hasNoItems` beside `isEmpty`) is lexicon rot.
|
|
241
|
+
- Repeated filter conditions are Layer 2 candidates: extract the predicate, compose a named higher-order filter, and keep derivations declarative:
|
|
242
|
+
```typescript
|
|
243
|
+
// ❌ Bad: inlined multi-clause predicate, repeated per derivation
|
|
244
|
+
const viewsFiles = computed(() => filteredFiles.value.filter(f => f.path.startsWith("src/") && (f.path.includes("views/") || f.tier === "views")));
|
|
245
|
+
|
|
246
|
+
// ✅ Good: domain predicate + named higher-order filter + declarative derivations
|
|
247
|
+
const isTierFile = (file: Capsule, tier: string): boolean => {
|
|
248
|
+
const isSrc = file.path.startsWith("src/");
|
|
249
|
+
if (!isSrc) return false;
|
|
250
|
+
return file.path.includes(`${tier}/`) || file.tier === tier;
|
|
251
|
+
};
|
|
252
|
+
const filterFiles = (tier: string) => filteredFiles.value.filter(f => isTierFile(f, tier));
|
|
253
|
+
const viewsFiles = computed(() => filterFiles("views"));
|
|
254
|
+
const organismsFiles = computed(() => filterFiles("organisms"));
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### C. Single-Action Command Handlers
|
|
258
|
+
- Event handlers are linear, unnested orchestrations of pure atomic verbs:
|
|
259
|
+
```typescript
|
|
260
|
+
const handleAction = async (id: string) => {
|
|
261
|
+
if (!canProceed.value) return;
|
|
262
|
+
triggerHapticFeedback();
|
|
263
|
+
recordTelemetryMetric('action:trigger', { id });
|
|
264
|
+
await executeServiceCall(id);
|
|
265
|
+
dismissActiveModal();
|
|
266
|
+
};
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### D. Ban on Nested Ternaries in Templates
|
|
270
|
+
- Never use nested ternaries in templates (`a ? (b ? 'x' : 'y') : 'z'`).
|
|
271
|
+
- Extract complex UI display states into dedicated computed descriptor objects returning `{ text: string, color: string }`.
|
|
272
|
+
|
|
273
|
+
### E. Keyed Map Dispatch Over Monolithic Switch Statements
|
|
274
|
+
- Prohibit monolithic `switch` statements used as procedural dispatch tables or value lookups.
|
|
275
|
+
- When branching performs uniform operations (e.g. mapping string keys to action handlers, CSS classes, prompt builders, or payload converters), extract into an O(1) keyed dictionary or method map (`const Registry = { ... }; Registry[key](...)`).
|
|
276
|
+
- **Branch Chains**: An `if` / `else if` chain of 3 or more branches testing the same subject is a lookup, not a series of decisions. Use a keyed map; do not hoist a named boolean per branch (3.A does not apply to such chains).
|
|
277
|
+
- **Prototype Pollution Guardrail**: Always guard dynamic object key access using `Object.hasOwn(Registry, key)` or `Object.prototype.hasOwnProperty.call(Registry, key)` before invoking mapped methods.
|
|
278
|
+
- **Architectural Benefits**:
|
|
279
|
+
- O(1) constant time lookup instead of O(N) linear string comparison branching.
|
|
280
|
+
- Eliminates boilerplate syntax duplication, drastically slashing token burn and AI context footprint.
|
|
281
|
+
- Complies with the Open-Closed Principle (OCP): new handlers can be registered dynamically without modifying the dispatcher AST.
|
|
282
|
+
- Enables granular unit testing and mocking of individual handlers in isolation.
|
|
283
|
+
|
|
284
|
+
### F. Name Quality, Assertion Prefixes & Adjacency
|
|
285
|
+
- **Assertion Prefixes**: A condition name starts with `is`, `are`, `has`, `have`, `can`, `could`, `should`, `would`, `does`, `did`, `needs`, `must`, `allows`, `enables`, `contains`, `includes`, `supports`, `requires`, `exceeds`, `matches`, or `wants`, followed by its subject (`isEscapeChar`, `exceedsHookBudget`). A bare verb callee (`test`, `existsSync`, `includes`, `startsWith`) is not a name: bind its result to one first.
|
|
286
|
+
- **Reject Restatements**: A name built only from the words of its own expression teaches nothing. `isChEqualsBackslash = ch === '\\'` and `isCountGreaterThanFive = count > 5` are rejected; `isEscapeChar = ch === '\\'` adds a domain term and passes. If a condition cannot be named in words absent from the condition itself, it is not yet understood: find out before branching on it.
|
|
287
|
+
- **Adjacency**: Declare a single-use named boolean on the statement immediately before its `if`. Hoist it only when it is referenced 2 or more times in the enclosing function, and then only to a point before its first use. A wall of `const is*` declarations at function top is a readability regression.
|
|
288
|
+
- **No Double Negation**: `if (!isNotFound)` names the wrong side. Name the positive and negate at the point of use.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 4. Reactivity, Composables & Hooks
|
|
293
|
+
|
|
294
|
+
### A. The Molecular Composable Destructuring Contract
|
|
295
|
+
1. **Safe Destructuring**: Composables must always return plain objects containing individual `ref()`, `computed()`, and pure functions. Never return a raw `reactive()` object.
|
|
296
|
+
2. **The Shape-Classification Contract**: Return values must classify strictly into three canonical buckets: State (domain data), Status (lifecycle/health info), and Actions (verb-prefixed functions flat at top level). No arbitrary property count ceiling applies. Unclassifiable properties (raw DOM refs, intermediate values, non-verb callbacks), nested action wrappers (`actions: {}`), and cross-hook naming inconsistencies are strictly prohibited. (Note: For stateful service classes holding shared instance state, refer to the Section 1.J carve-out).
|
|
297
|
+
3. **Standardized Aliasing**: Use standardized names (`data`, `isLoading`, `error`, `execute`) to enable clean concurrent destructuring.
|
|
298
|
+
4. **Autonomous Lifecycle Teardown**: Side effects (listeners, timers, observers) must be cleaned up automatically using `onScopeDispose()` or effect cleanup functions.
|
|
299
|
+
5. **Flexible Input Ergonomics**: Accept raw values, refs, or getters interchangeably via `toValue()` / `MaybeRefOrGetter<T>`.
|
|
300
|
+
|
|
301
|
+
### B. Clean 3-State Async Pipelines
|
|
302
|
+
- Every asynchronous operation follows a predictable state container (`data`, `isLoading`, `error`, `execute`):
|
|
303
|
+
```typescript
|
|
304
|
+
const { data: items, isLoading, error, execute: loadItems } = useAsyncData(fetchItemsApi);
|
|
305
|
+
const hasItems = computed(() => items.value.length > 0);
|
|
306
|
+
const shouldShowEmptyState = computed(() => !isLoading.value && !hasItems.value && !error.value);
|
|
307
|
+
const shouldShowErrorState = computed(() => !isLoading.value && Boolean(error.value));
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### C. Strict Lexical Declaration Order (TDZ Prevention)
|
|
311
|
+
To eliminate Temporal Dead Zone (TDZ) ReferenceErrors, `<script setup>` and controllers strictly follow this lexical declaration order:
|
|
312
|
+
1. Composables & Stores (`useRouter()`, `useStore()`)
|
|
313
|
+
2. Reactive Primitives (`ref()`, `reactive()`)
|
|
314
|
+
3. Computed State (`computed()`)
|
|
315
|
+
4. Helper Methods & Actions (`const handleClick = () => { ... }`)
|
|
316
|
+
5. Watchers (`watch()`, `watchEffect()`)
|
|
317
|
+
6. Lifecycle Hooks (`onMounted()`, `onUnmounted()`)
|
|
318
|
+
*Mandatory Rule*: Never reference a reactive value, computed property, or helper in an immediate watcher callback before its declaration.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
## 5. Design System, Styling & UI Performance
|
|
323
|
+
|
|
324
|
+
### A. The 4-Tier Zero-Inline-Style Rule
|
|
325
|
+
Raw inline `style="..."` attributes are strictly prohibited. Visual styling flows through the standardized 4-tier hierarchy:
|
|
326
|
+
1. **Level 1 (Atom Props)**: Semantic props on atoms (`:color="brandColor"`, `variant="glass"`, `size="lg"`).
|
|
327
|
+
2. **Level 2 (Mixins & Utilities)**: Centralized SCSS mixins (`@include glass;`, `@include glass-hover;`) and utility classes.
|
|
328
|
+
3. **Level 3 (Scoped BEM Classes)**: Scoped classes in component stylesheets referencing design tokens or encapsulating shorthand via `@apply`.
|
|
329
|
+
4. **Level 4 (Dynamic Root Variables)**: Dynamic runtime coordinates passed exclusively as root CSS custom properties (`:style="{ '--win-x': \`${x}px\`, '--win-y': \`${y}px\` }"`).
|
|
330
|
+
|
|
331
|
+
### B. The Anti-Tailwind-Soup Directive (Class Decoupling)
|
|
332
|
+
- Prohibit monolithic utility class chains (> 4-5 classes per element) directly inside HTML templates.
|
|
333
|
+
- Long strings of utility shorthand recreate the exact cognitive noise and AI context degradation of inline styles.
|
|
334
|
+
- Decouple visual styling into scoped classes via `@apply` or centralized SCSS mixins (`@include glass;`).
|
|
335
|
+
- Templates must read like a clean, semantic outline rather than an unreadable wall of styling shorthand.
|
|
336
|
+
|
|
337
|
+
### C. Wrapper Atoms & Explicit Slot Forwarding
|
|
338
|
+
- Never use dynamic slot iteration with `v-for="(_, slot) in $slots"` in wrapper components.
|
|
339
|
+
- Explicitly forward named slots: `<template #<slot-name>="scope"><slot :name="<slot-name>" v-bind="scope || {}" /></template>`.
|
|
340
|
+
- Always wrap default slot in `<template #default="scope"><slot v-bind="scope || {}" /></template>`.
|
|
341
|
+
|
|
342
|
+
### D. Flat CSS Specificity & Icon Safety
|
|
343
|
+
- Single-depth BEM semantic class naming. Never use `!important` overrides.
|
|
344
|
+
- **FontAwesome SVG Compliance**: Never attach `text-*` utility classes to FontAwesome icons (breaks SVG rendering). Use native `:color` prop or inline CSS.
|
|
345
|
+
|
|
346
|
+
### E. 60 FPS Non-Blocking UI Offloading
|
|
347
|
+
- Heavy computational operations (parsing, sorting, cryptographic hashing) must be offloaded to Web Workers or chunked micro-batches via `requestIdleCallback`.
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## 6. Timer & Macro-Task Discipline
|
|
352
|
+
|
|
353
|
+
### A. Zero `setInterval` in Component & Business Logic
|
|
354
|
+
- Polling with `setInterval` is strictly prohibited.
|
|
355
|
+
- Use `requestAnimationFrame` for animations and physics.
|
|
356
|
+
- Use `videoElement.requestVideoFrameCallback()` for camera/video streams.
|
|
357
|
+
- Use a single shared system clock composable (`useSystemClock()`) for time displays.
|
|
358
|
+
- Use Server-Sent Events or WebSockets for server state sync.
|
|
359
|
+
|
|
360
|
+
### B. Zero Render-Hack `setTimeout` (Mandatory `nextTick`)
|
|
361
|
+
- Never use `setTimeout(() => { ... }, 0)` to wait for DOM elements to render. Use `await nextTick()` or `watch(..., { flush: 'post' })`.
|
|
362
|
+
|
|
363
|
+
### C. Self-Cleaning Timer Composables
|
|
364
|
+
- Timers for real-world delays must be managed through self-cleaning composables (`useTimeoutFn`, `useDebounceFn`) that cancel automatically on component unmount via `onScopeDispose` or effect teardown.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## 7. Infrastructure, Extensibility & Global Hygiene
|
|
369
|
+
|
|
370
|
+
### A. Zero-Conditional `debug.log` Proxy
|
|
371
|
+
- Never use `if (import.meta.env.DEV)` or `if (isProd)` checks around logging statements. Use a central `debug` proxy that automatically silences in production while preserving errors.
|
|
372
|
+
|
|
373
|
+
### B. Typography Hygiene
|
|
374
|
+
- Never use em dashes anywhere in code, copy, markdown, or documentation. Use standard hyphens or colons.
|
|
375
|
+
|
|
376
|
+
---
|
|
377
|
+
|
|
378
|
+
## 8. Accessibility & Semantic Integrity
|
|
379
|
+
|
|
380
|
+
### A. Semantic HTML First
|
|
381
|
+
- Never reach for a generic `<div>` or `<span>` with a click handler where a native element (`<button>`, `<a>`, `<label>`, `<nav>`) already carries the correct behavior and semantics for free.
|
|
382
|
+
- Interactive elements must be genuinely interactive elements. A clickable `<div>` requires manually re-implementing keyboard focus, Enter/Space activation, and role semantics that native elements provide automatically.
|
|
383
|
+
|
|
384
|
+
### B. Keyboard & Focus Management
|
|
385
|
+
- Every interactive element must be reachable and operable via keyboard alone: Tab to focus, Enter/Space to activate, Esc to dismiss modals and overlays.
|
|
386
|
+
- Modals, drawers, and dropdowns must trap focus while open and return focus to the triggering element on close.
|
|
387
|
+
- Never remove default focus outlines (`outline: none`) without providing a visible, equivalent custom focus state.
|
|
388
|
+
|
|
389
|
+
### C. ARIA as a Last Resort, Not a First Layer
|
|
390
|
+
- Use ARIA attributes (`aria-label`, `aria-expanded`, `role`) only to fill genuine gaps semantic HTML cannot cover, not as a substitute for correct markup.
|
|
391
|
+
- Every image conveying meaning requires alt text; purely decorative images use `alt=""`.
|
|
392
|
+
- Form inputs require an associated `<label>`, not a placeholder alone.
|
|
393
|
+
|
|
394
|
+
### D. Color & Motion Safety
|
|
395
|
+
- Text and interactive elements must meet WCAG AA contrast ratios in both light and dark modes; verify new color tokens against both themes, not just one.
|
|
396
|
+
- Respect `prefers-reduced-motion` for non-essential animations and transitions.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## 9. Security & Content Safety
|
|
401
|
+
|
|
402
|
+
### A. Zero Unsanitized HTML Injection
|
|
403
|
+
- Never render user-supplied or externally-fetched content via `v-html`, `dangerouslySetInnerHTML`, or equivalent raw-HTML injection without passing it through a sanitizer (e.g. DOMPurify) first.
|
|
404
|
+
- Treat all externally-fetched content (API responses, user uploads, third-party embeds) as untrusted by default.
|
|
405
|
+
|
|
406
|
+
### B. Output Encoding & Injection Boundaries
|
|
407
|
+
- Never interpolate user input directly into constructed HTML strings, SQL queries, or shell commands. Use parameterized queries and framework-native escaping.
|
|
408
|
+
- Never build URLs for redirects or API calls by concatenating unvalidated user input; validate against an allowlist.
|
|
409
|
+
|
|
410
|
+
### C. Secrets & Credential Hygiene
|
|
411
|
+
- Never hardcode API keys, tokens, or credentials in source files, even temporarily during development. Use environment variables or a secrets manager.
|
|
412
|
+
- Never log full request/response payloads that may contain auth tokens, passwords, or PII.
|
|
413
|
+
|
|
414
|
+
### D. CSRF & Auth Boundaries
|
|
415
|
+
- State-changing requests (POST/PUT/DELETE) must carry CSRF protection appropriate to the framework's convention, not be assumed safe because they're behind a login.
|
|
416
|
+
- Never trust client-side role or permission checks as the sole gate for sensitive actions; the server must re-verify authorization independently.
|
|
417
|
+
|
|
418
|
+
---
|
|
419
|
+
|
|
420
|
+
## 10. Testing Discipline
|
|
421
|
+
|
|
422
|
+
### A. Co-located Test Files
|
|
423
|
+
- Test files live alongside the capsule they cover (`m-<feature>-card.spec.ts` inside the capsule directory), not in a separate parallel test tree that drifts from the source structure.
|
|
424
|
+
|
|
425
|
+
### B. What Must Be Covered
|
|
426
|
+
- Every exported pure function, composable, and domain type guard requires at least one test exercising its primary path and one exercising a failure/edge path.
|
|
427
|
+
- UI components require at least a render smoke test; interactive components require a test covering their primary user action.
|
|
428
|
+
|
|
429
|
+
### C. Refactor Discipline
|
|
430
|
+
- When decomposing a file per Section 1, existing tests move and are updated to match the new file boundaries in the same pass; a refactor is not complete until its tests pass against the new structure.
|
|
431
|
+
- Never delete or skip a failing test to unblock a commit; fix the code or the test, or flag the failure explicitly.
|
|
432
|
+
|
|
433
|
+
### D. No Fake Green
|
|
434
|
+
- Never write a test that trivially passes without exercising real logic (e.g. asserting `true === true`, mocking away the exact behavior under test).
|
|
435
|
+
|
|
436
|
+
### E. Silent Verification & Zero Passing Noise
|
|
437
|
+
- AI agents executing tests or verifying code MUST invoke `chemx_test` (or `npx chemx test --json`) and `chemx_verify` (or `npx chemx verify --json`).
|
|
438
|
+
- Strictly prohibit executing verbose raw `npm test` or `pnpm test` in the shell: hundreds of passing test markers pollute context. If tests pass, agents consume a ~25-token green acknowledgment; if tests fail, agents consume only the failing test name, assertion message, and diff.
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## 11. Naming Conventions
|
|
443
|
+
|
|
444
|
+
### A. Casing
|
|
445
|
+
- Files: kebab-case (`m-user-card.controller.ts`).
|
|
446
|
+
- Variables, functions, composables: camelCase (`isLoading`, `useAsyncData`).
|
|
447
|
+
- Types, interfaces, components: PascalCase (`SessionState`, `UserCard`).
|
|
448
|
+
- Constants meant to be immutable module-level config: SCREAMING_SNAKE_CASE (`MAX_RETRY_COUNT`).
|
|
449
|
+
|
|
450
|
+
### B. Boolean & Predicate Prefixes
|
|
451
|
+
- Booleans and predicates start with an assertion prefix from 3.F (`isLoading`, `hasItems`, `canCheckout`, `exceedsHookBudget`). Never name a boolean as a bare noun or adjective (`loading`, `valid`) that hides its type at the call site.
|
|
452
|
+
|
|
453
|
+
### C. Event & Handler Naming
|
|
454
|
+
- Emitted events describe what happened, not what to do (`item-selected`, not `select-item`).
|
|
455
|
+
- Handler functions describe the action taken, prefixed `handle` (`handleCheckout`), matching Section 3.C.
|
|
456
|
+
|
|
457
|
+
---
|
|
458
|
+
|
|
459
|
+
## 12. Documentation Discipline
|
|
460
|
+
|
|
461
|
+
### A. Derived Contract Synchronization
|
|
462
|
+
- Derived contract fields (signatures, parameters, payload structures, return types) in capsule documentation must be extracted directly from `types.d.ts`, never manually duplicated or hand-typed.
|
|
463
|
+
- Any change to `types.d.ts` must automatically propagate to or be validated against the capsule reference documentation.
|
|
464
|
+
|
|
465
|
+
### B. Mandatory Doc-Touch CI Gate
|
|
466
|
+
- A commit that modifies a capsule's implementation or controller without updating the corresponding documentation prose section must fail CI validation.
|
|
467
|
+
- Refactors and behavioral changes are not complete until documentation accurately reflects updated semantics, mirroring Section 10.C.
|
|
468
|
+
|
|
469
|
+
### C. "No Fake Doc-Sync" Anti-Pattern
|
|
470
|
+
- Mirroring the "No Fake Green" testing rule in Section 10.D, superficial doc edits (whitespace tweaks, comment formatting, minor typo fixes) made merely to pass CI touch-checks without addressing substantive semantic changes are strictly prohibited.
|
|
471
|
+
- Documentation reviews must verify substantive alignment between code behavior and documented contracts.
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
## Chemical X Codebase Query Machine Protocol
|
|
475
|
+
- Search First Rule: AI agents MUST invoke 'pnpm chemx q "<query>"' (or 'npx chemx search "<query>"') before running broad ripgrep, find, or file dumping.
|
|
476
|
+
- AST Architecture Intelligence: Always leverage 'pnpm chemx q' to inspect component tiers, exported symbols, props, and hooks with minimal token burn.
|
|
477
|
+
- Inspect Mode: Use 'pnpm chemx q "<capsule-name>" --inspect' to examine props and hooks without reading entire source files.
|
|
478
|
+
- JSON Mode: Use 'pnpm chemx q "<query>" --json' for zero-overhead, machine-readable agent lookups.
|
|
479
|
+
|
|
480
|
+
## Chemical X Verification-First Protocol & Zero-Token-Burn Pipeline
|
|
481
|
+
- Verification First Rule: AI agents MUST NEVER run raw, unthrottled "npm test", "pnpm test", "vitest", "tsc --noEmit", or "npm run build" directly in a bash subshell.
|
|
482
|
+
- MCP Verification Tools First: AI agents MUST invoke dedicated Chemical X MCP tools or CLI wrappers ('pnpm chemx verify', 'npx chemx verify', 'pnpm chemx build', 'npx chemx build') before running terminal commands.
|
|
483
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue';
|
|
3
|
-
import AButton from '
|
|
3
|
+
import AButton from '../atoms/a-button.vue';
|
|
4
4
|
import type { MSampleCardProps, SampleCardBadgeDescriptor } from './types';
|
|
5
5
|
|
|
6
6
|
const props = withDefaults(defineProps<MSampleCardProps>(), {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { resolveProjectName, resolveCostFigures } from '../navigator-banner-helpers.js';
|
|
2
|
+
|
|
3
|
+
const countHazards = (violations = []) => {
|
|
4
|
+
const counts = { critical: 0, highMedium: 0, low: 0 };
|
|
5
|
+
for (const v of violations) {
|
|
6
|
+
const isCritical = v.severity === 'CRITICAL';
|
|
7
|
+
const isHighOrMedium = v.severity === 'HIGH' || v.severity === 'MEDIUM';
|
|
8
|
+
if (isCritical) counts.critical += 1;
|
|
9
|
+
else if (isHighOrMedium) counts.highMedium += 1;
|
|
10
|
+
else counts.low += 1;
|
|
11
|
+
}
|
|
12
|
+
return counts;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const buildAuditSummary = (report, { projectRoot, scope }) => {
|
|
16
|
+
const gate = report.gate ?? {};
|
|
17
|
+
const summary = {
|
|
18
|
+
project: resolveProjectName(projectRoot),
|
|
19
|
+
scope,
|
|
20
|
+
files: report.metrics?.scannedFiles ?? 0,
|
|
21
|
+
loc: report.metrics?.totalLoc ?? 0,
|
|
22
|
+
tokens: { estimate: report.contextAnalysis?.estimatedTokens ?? 0, savingsPct: report.contextAnalysis?.potentialSavingsPct ?? 0 },
|
|
23
|
+
health: { score: report.health.score, grade: report.health.grade, label: report.health.label ?? null },
|
|
24
|
+
aiSlop: { score: report.aiSlop?.score ?? 100, grade: report.aiSlop?.grade ?? 'A+' },
|
|
25
|
+
hazards: countHazards(report.violations),
|
|
26
|
+
cost: resolveCostFigures(report.contextAnalysis),
|
|
27
|
+
gate: { passing: gate.isPassing ?? null, basis: gate.basis ?? null, regressions: (gate.regressions ?? []).slice(0, 5), note: gate.note ?? null }
|
|
28
|
+
};
|
|
29
|
+
return report.rebaseline ? { ...summary, rebaseline: report.rebaseline } : summary;
|
|
30
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { readRatchet, evaluateRatchet } from './ratchet.js';
|
|
2
|
+
|
|
3
|
+
const RATCHET_STATUSES = new Set(['pass', 'fail', 'invalid']);
|
|
4
|
+
|
|
5
|
+
const isSevereViolation = (v) => v.severity === 'CRITICAL' || v.severity === 'HIGH';
|
|
6
|
+
|
|
7
|
+
export const evaluateGateVerdict = ({ violations, ratchetEval }) => {
|
|
8
|
+
const isRatchetBasis = RATCHET_STATUSES.has(ratchetEval.status);
|
|
9
|
+
if (isRatchetBasis) {
|
|
10
|
+
return {
|
|
11
|
+
isPassing: ratchetEval.status === 'pass',
|
|
12
|
+
basis: 'ratchet',
|
|
13
|
+
regressions: ratchetEval.regressions,
|
|
14
|
+
note: ratchetEval.message ?? null
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
const hasSevereViolation = violations.some(isSevereViolation);
|
|
18
|
+
return { isPassing: !hasSevereViolation, basis: 'severity', regressions: [], note: ratchetEval.message ?? null };
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const PARTIAL_SCAN_EVAL = {
|
|
22
|
+
status: 'partial',
|
|
23
|
+
regressions: [],
|
|
24
|
+
message: 'Partial scan (--git, --changed, or --fast): the ratchet applies to full scans only; using severity gate.'
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const computeGateVerdict = ({ projectRoot, scope, violations, isPartialScan = false }) => {
|
|
28
|
+
const ratchetEval = isPartialScan ? PARTIAL_SCAN_EVAL : evaluateRatchet(readRatchet(projectRoot), { scope, violations });
|
|
29
|
+
return evaluateGateVerdict({ violations, ratchetEval });
|
|
30
|
+
};
|