<AiKnowledge ver="2.0">
  <Directives>
    <Sdd>
      <SddSetup>
        <File>ai/directives/sdd/setup.directive.xml</File>
        <Purpose>Creates or updates specs/README.md — Vision and Scope Graph. Sole owner of the Portal. Idempotent.</Purpose>
        <Triggers>new project · add scope · change project vision · register scope after discovery</Triggers>
        <SkipWhen>designing a specific scope · module decomposition · task scaffolding</SkipWhen>
        <Preconditions>None</Preconditions>
      </SddSetup>
      <SddDiscovery>
        <File>ai/directives/sdd/discovery.directive.xml</File>
        <Purpose>Scope-level discovery session. Creates or evolves specs/[scope]/[scope].spec.md. Branches by scope-type: infrastructure, contracts, library, product.</Purpose>
        <Triggers>design scope · raw idea for service/SDK/CLI/app · bootstrap infra tooling · refine or pivot existing scope</Triggers>
        <SkipWhen>approved spec exists and operator wants module decomposition · bug fix or local refactor · project-level vision change</SkipWhen>
        <Preconditions>greenfield: none. refine/pivot: specs/[scope]/[scope].spec.md exists</Preconditions>
      </SddDiscovery>
      <SddModuleDecomposition>
        <File>ai/directives/sdd/module-decomposition.directive.xml</File>
        <Purpose>Decomposes a product or library scope into module specs with closed-world entity inventory, public surfaces, DbC contracts (Ports / Adapters / Services).</Purpose>
        <Triggers>discovery complete · split into modules · build module map · list all entities · produce DbC · Ports and Adapters</Triggers>
        <SkipWhen>scope spec missing or not approved · discovery still open · scope-type is infrastructure or contracts · tasks already generated</SkipWhen>
        <Preconditions>specs/[scope]/[scope].spec.md with scope-type=product or library</Preconditions>
      </SddModuleDecomposition>
      <SddTaskScaffolding>
        <File>ai/directives/sdd/task-scaffolding.directive.xml</File>
        <Purpose>Builds DAG of compact task tickets from scope graph. Each ticket includes BDD, Effective Rules, Verification, Execution Log template.</Purpose>
        <Triggers>all scope specs ready · break into tasks · build DAG · produce execution plan · scaffold tickets</Triggers>
        <SkipWhen>module specs lack contracts · discovery or module-decomp not closed · tasks already generated</SkipWhen>
        <Preconditions>specs/README.md Scope Graph ✅; coding rule files exist for each language</Preconditions>
      </SddTaskScaffolding>
      <SddPhaseExecution>
        <File>ai/directives/sdd/phase-execution-protocol.xml</File>
        <Purpose>Execute ONE phase of ONE task ticket, dispatched by sdd-execute orchestrator. Read only what the phase needs; write only Target Files; emit typed Handoff for next phase / audit.</Purpose>
        <Triggers>orchestrator dispatches phase · phase ID + ticket path provided in prompt</Triggers>
        <SkipWhen>operator invokes directly without orchestrator · no phase ID</SkipWhen>
        <Preconditions>ticket has section 2 Phases Overview + section 3 Phases block for target phase ID; prior-phase Handoffs (if any) recorded in current Round</Preconditions>
      </SddPhaseExecution>
      <SddAudit>
        <File>ai/directives/sdd/audit.directive.xml</File>
        <Purpose>Post-execution verification. Compares spec ↔ ticket ↔ code. Detects drift, gaps, rules violations. Output: ephemeral findings routed to spec/ticket.</Purpose>
        <Triggers>audit · drift detection · post-implementation review · verify implementation · end of epic before merge</Triggers>
        <SkipWhen>no executed tasks · Execution Log empty · no spec to compare</SkipWhen>
        <Preconditions>spec exists; ticket with non-empty Execution Log; code committed</Preconditions>
      </SddAudit>
    </Sdd>
  </Directives>
  <Rules>
    <CheckPhaseOrder>typecheck test lint format</CheckPhaseOrder>

    <Coding>
      <Rule id="result-conventions">
        <File>ai/directives/coding/result-conventions.xml</File>
        <Purpose>ESLint enforcement of Result pattern conventions: no second generic, no object literals, no isErr short-circuit, no bare throw unknown.</Purpose>
        <Triggers>Target Files use Result from @tessell/core/result · task touches error-handling code · task adds new DML / service methods</Triggers>
        <SkipWhen>Config-only task; no Result usage in target files</SkipWhen>
        <ActivationHint>Before writing or reviewing any file that returns or propagates Result</ActivationHint>
        <CheckPhase>lint</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
      </Rule>
      <Rule id="typescript-rules">
        <File>ai/directives/coding/typescript-rules.xml</File>
        <Purpose>Writing code in the chosen language: typing, DbC, patterns, anti-patterns.</Purpose>
        <Triggers>Target Files include source code files (not config)</Triggers>
        <SkipWhen>Config-only task; infra-setup task without code files</SkipWhen>
        <ActivationHint>Before editing or creating any source code file</ActivationHint>
        <CheckPhase>typecheck</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
      </Rule>
      <Rule id="svelte5-runes">
        <File>ai/directives/coding/svelte5-runes.xml</File>
        <Purpose>Writing Svelte 5 components with runes ($state, $derived, $effect, $props, $bindable). Inherits typescript-rules; adds Svelte-specific reactivity, template syntax, component structure. Prevents React-pattern code in .svelte files.</Purpose>
        <Triggers>creating .svelte file · writing Svelte component · using runes · .svelte.ts module</Triggers>
        <SkipWhen>pure TypeScript without Svelte · React/Vue project · backend server code</SkipWhen>
        <ActivationHint>Before editing or creating any .svelte, .svelte.ts, or .svelte.js file. Inherits from typescript-rules — read both.</ActivationHint>
        <CheckPhase>typecheck</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="typescript-rules">Parent directive: inherits all TypeScript rules for language baseline.</CrossRef>
        <CrossRef id="sveltekit-rules">SvelteKit projects also activate sveltekit-rules (inherits from this directive).</CrossRef>
      </Rule>
      <Rule id="sveltekit-rules">
        <File>ai/directives/coding/sveltekit-rules.xml</File>
        <Purpose>Writing SvelteKit applications: file-based routing (+page, +layout, +server), server load functions, form actions, hooks, adapters, $app modules. Inherits svelte5-runes + typescript-rules transitively.</Purpose>
        <Triggers>creating SvelteKit route · load function · form actions · hooks.server.ts · server/client boundary</Triggers>
        <SkipWhen>standalone Svelte without SvelteKit · pure component library · non-SvelteKit project</SkipWhen>
        <ActivationHint>Before writing SvelteKit route files or server logic. Inherits from svelte5-runes — read both.</ActivationHint>
        <CheckPhase>typecheck</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="svelte5-runes">Parent directive: inherits all Svelte 5 runes rules.</CrossRef>
        <CrossRef id="typescript-rules">Transitive parent: inherits TypeScript rules through svelte5-runes.</CrossRef>
      </Rule>
    </Coding>
    <Testing>
      <Rule id="testing-common">
        <File>ai/directives/testing/common.xml</File>
        <Purpose>Shared testing core inherited by every runner-specific directive: contract boundary, case flow, phase anchors, unified context + factory, BDD mapping, snapshot operator-confirm, file budget.</Purpose>
        <Triggers>any runner-specific testing rule activates</Triggers>
        <SkipWhen>no test files in scope</SkipWhen>
        <ActivationHint>Auto-read whenever node-test or vitest-rules activates. Runner-specific files only state deltas.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
      </Rule>
      <Rule id="vitest-rules">
        <File>ai/directives/testing/vitest-rules.xml</File>
        <Purpose>Writing tests on Vitest runner.</Purpose>
        <Triggers>Target Test Files present AND stack uses Vitest</Triggers>
        <SkipWhen>Stack uses a different test runner; no test files in scope</SkipWhen>
        <ActivationHint>Before writing or modifying test files. Inherits testing-common.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="testing-common">Parent directive: read first for case flow, anchors, unified context, BDD mapping.</CrossRef>
      </Rule>
      <Rule id="node-test">
        <File>ai/directives/testing/node-test.xml</File>
        <Purpose>Writing tests on node:test runner.</Purpose>
        <Triggers>Target Test Files present AND stack uses node:test</Triggers>
        <SkipWhen>Stack uses a different test runner; no test files in scope</SkipWhen>
        <ActivationHint>Before writing or modifying test files. Inherits testing-common.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="testing-common">Parent directive: read first for case flow, anchors, unified context, BDD mapping.</CrossRef>
      </Rule>
      <Rule id="playwright-cli">
        <File>ai/directives/testing/playwright-cli.xml</File>
        <Purpose>Exploring web apps through Playwright CLI: AX Tree vision, aria snapshots, screenshots, trace viewer, codegen. Gives the agent eyes and hands for browser exploration.</Purpose>
        <Triggers>developing UI component · building a page · verifying visual layout · debugging failing e2e test · capturing aria snapshots</Triggers>
        <SkipWhen>pure backend logic · CLI command implementation · API endpoint without UI</SkipWhen>
        <ActivationHint>BEFORE writing any e2e test — explore the page first. Also when an e2e test fails and the agent needs to see what rendered.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="playwright-e2e">Transition to playwright-e2e when exploration complete.</CrossRef>
      </Rule>
      <Rule id="playwright-e2e">
        <File>ai/directives/testing/playwright-e2e.xml</File>
        <Purpose>Writing Playwright E2E tests: aria-snapshot-first contracts, role-based locators, fixture-based POM, auth via storageState, network mocking.</Purpose>
        <Triggers>writing e2e test · creating browser test · adding Playwright spec · testing user flow</Triggers>
        <SkipWhen>unit test · integration test without browser · exploration not done (use playwright-cli first)</SkipWhen>
        <ActivationHint>AFTER playwright-cli exploration. Before writing Playwright spec files.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="playwright-cli">MUST run playwright-cli exploration first.</CrossRef>
      </Rule>
      <Rule id="storybook-usage">
        <File>ai/directives/testing/storybook-usage.xml</File>
        <Purpose>Using Storybook MCP tools: reading manifests (component docs, props, stories), writing stories, running tests, self-verifying component rendering.</Purpose>
        <Triggers>developing UI component · using design system · creating story · fixing component bug · verifying component renders</Triggers>
        <SkipWhen>pure backend/CLI logic · no Storybook · MCP not installed (use storybook-setup first)</SkipWhen>
        <ActivationHint>Whenever working with UI components — BEFORE writing code, call MCP tools to check documented props.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="storybook-setup">MUST have Storybook + MCP running. If unreachable, invoke storybook-setup.</CrossRef>
      </Rule>
      <Rule id="svelte-testing">
        <File>ai/directives/testing/svelte-testing.xml</File>
        <Purpose>Testing Svelte 5 components: .svelte.test.ts extension, $effect.root isolation, flushSync for DOM, mount/unmount, @testing-library/svelte. Inherits node-test + vitest-rules.</Purpose>
        <Triggers>writing Svelte component test · testing runes · mounting Svelte component · Storybook interaction test for Svelte</Triggers>
        <SkipWhen>pure TS logic test without runes · E2E test with Playwright · non-Svelte project</SkipWhen>
        <ActivationHint>Before writing .svelte.test.ts. Inherits from node-test.xml and vitest-rules.xml.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="node-test">Inherits general testing rules (phase anchors, learning briefs, contract coverage).</CrossRef>
        <CrossRef id="vitest-rules">Inherits Vitest-specific rules (unified context, mock discipline).</CrossRef>
        <CrossRef id="svelte5-runes">Runes knowledge required (.svelte.test.ts, $effect.root, flushSync).</CrossRef>
      </Rule>
    </Testing>
    <Infra>
      <Rule id="eslint-setup">
        <File>ai/directives/infra/eslint-setup.xml</File>
        <Purpose>Configuring a linter: severity policy, autofix, config format, formatter integration.</Purpose>
        <Triggers>Task configures linter · installs linter · sets lint rules</Triggers>
        <SkipWhen>Coding/testing task that only RUNS lint, does not configure it</SkipWhen>
        <ActivationHint>Before writing linter config or modifying lint rules</ActivationHint>
        <CheckPhase>lint</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
      </Rule>
      <Rule id="git-setup">
        <File>ai/directives/infra/git-setup.xml</File>
        <Purpose>Configuring VCS: ignore baseline, branches, commits, hooks, secrets discipline.</Purpose>
        <Triggers>Task bootstraps repo · configures VCS ignore file · sets up hooks · commit convention</Triggers>
        <SkipWhen>Task only commits code changes (does not configure VCS itself)</SkipWhen>
        <ActivationHint>Before writing VCS ignore file or configuring hooks</ActivationHint>
        <CheckPhase></CheckPhase>
        <RequiresVerification></RequiresVerification>
      </Rule>
      <Rule id="nodejs-npm-setup">
        <File>ai/directives/infra/nodejs-npm-setup.xml</File>
        <Purpose>Runtime + package manager setup: version pinning, single package manager, module system, mandatory check script.</Purpose>
        <Triggers>Task writes package manager manifest · runtime version file · sets engines · chooses package manager</Triggers>
        <SkipWhen>Task does not touch package manager manifest or runtime config</SkipWhen>
        <ActivationHint>Before writing package manager manifest or runtime version file</ActivationHint>
        <CheckPhase></CheckPhase>
        <RequiresVerification></RequiresVerification>
      </Rule>
      <Rule id="storybook-setup">
        <File>ai/directives/infra/storybook-setup.xml</File>
        <Purpose>Installing Storybook + MCP server: agentic init, MCP addon, Vitest addon, agent registration, AGENTS.md update. Bootstraps component development environment.</Purpose>
        <Triggers>install Storybook · add Storybook to project · configure MCP server · bootstrap UI toolchain</Triggers>
        <SkipWhen>no UI components · Storybook already installed + MCP confirmed running</SkipWhen>
        <ActivationHint>When project needs Storybook for first time. Follow agentic init: npx storybook@latest init.</ActivationHint>
        <CheckPhase>test</CheckPhase>
        <RequiresVerification>check-command</RequiresVerification>
        <CrossRef id="storybook-usage">After setup (MCP running, manifest accessible), transition to storybook-usage.</CrossRef>
      </Rule>
    </Infra>
  </Rules>
</AiKnowledge>
