diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md new file mode 100644 index 000000000..465824ba1 --- /dev/null +++ b/THIRD_PARTY_NOTICES.md @@ -0,0 +1,21 @@ +# Third-Party Notices + +## claude-for-legal + +Portions of Mike's built-in legal workflows are derived from **claude-for-legal** +by Anthropic (https://github.com/anthropics/claude-for-legal), licensed under the +**Apache License, Version 2.0**. + +The skill prompt bodies under `commercial-legal/skills/` were adapted into Mike +"assistant" workflows (see `backend/src/lib/portedLegalWorkflows.ts` and +`frontend/src/app/components/workflows/portedLegalWorkflows.ts`, generated by +`backend/scripts/import-skills.ts`). Adaptations rewrite references to the +upstream per-team `CLAUDE.md` practice profile to Mike's per-user Practice +Profile, and references to external CLM/e-signature/storage connectors to Mike's +own document tools. + +A copy of the Apache 2.0 license is available at +https://www.apache.org/licenses/LICENSE-2.0. + +These workflows produce drafts for attorney review and do not constitute legal +advice. diff --git a/backend/migrations/001_practice_profile.sql b/backend/migrations/001_practice_profile.sql new file mode 100644 index 000000000..7138bf9df --- /dev/null +++ b/backend/migrations/001_practice_profile.sql @@ -0,0 +1,9 @@ +-- Per-user practice profile. +-- +-- A free-text "playbook" the user maintains (firm positions, house style, +-- escalation matrix, preferred governing law, etc.). It is injected into the +-- assistant system prompt so ported legal workflows can rely on the user's +-- configured positions instead of assuming defaults. Mirrors the per-team +-- CLAUDE.md practice profiles used by the claude-for-legal skill set. +alter table public.user_profiles + add column if not exists practice_profile text; diff --git a/backend/migrations/002_practice_profiles_by_area.sql b/backend/migrations/002_practice_profiles_by_area.sql new file mode 100644 index 000000000..651ea989f --- /dev/null +++ b/backend/migrations/002_practice_profiles_by_area.sql @@ -0,0 +1,9 @@ +-- Per-practice-area practice profiles. +-- +-- Complements user_profiles.practice_profile (the general, always-injected +-- profile) with an area-keyed map, e.g. +-- { "Litigation": "...", "Commercial Contracts": "..." } +-- The profile for the active workflow's practice area is injected alongside the +-- general one, mirroring claude-for-legal's per-plugin CLAUDE.md files. +alter table public.user_profiles + add column if not exists practice_profiles jsonb not null default '{}'::jsonb; diff --git a/backend/package-lock.json b/backend/package-lock.json index effa2adef..5fbb70d41 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "mike-backend", "version": "1.0.0", + "license": "AGPL-3.0-only", "dependencies": { "@anthropic-ai/sdk": "^0.90.0", "@aws-sdk/client-s3": "^3.787.0", @@ -25,6 +26,7 @@ "libreoffice-convert": "^1.6.0", "mammoth": "^1.9.0", "multer": "^1.4.5-lts.2", + "openai": "^6.39.1", "pdfjs-dist": "^4.10.38", "resend": "^4.5.1" }, @@ -33,9 +35,12 @@ "@types/express": "^4.17.21", "@types/multer": "^1.4.12", "@types/node": "^22.14.1", + "@types/supertest": "^7.2.0", "prettier": "^3.8.1", + "supertest": "^7.2.2", "tsx": "^4.19.3", - "typescript": "^5.8.3" + "typescript": "^5.8.3", + "vitest": "^4.1.7" } }, "node_modules/@anthropic-ai/sdk": { @@ -972,6 +977,40 @@ "node": ">=6.9.0" } }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.7", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", @@ -1437,6 +1476,13 @@ } } }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, "node_modules/@napi-rs/canvas": { "version": "0.1.97", "resolved": "https://registry.npmjs.org/@napi-rs/canvas/-/canvas-0.1.97.tgz", @@ -1687,6 +1733,38 @@ "url": "https://github.com/sponsors/Brooooooklyn" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", + "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodable/entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", @@ -1699,6 +1777,26 @@ ], "license": "MIT" }, + "node_modules/@oxc-project/types": { + "version": "0.133.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.133.0.tgz", + "integrity": "sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz", + "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -1781,6 +1879,270 @@ "react-dom": "^18.0 || ^19.0 || ^19.0.0-rc" } }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz", + "integrity": "sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz", + "integrity": "sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz", + "integrity": "sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz", + "integrity": "sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz", + "integrity": "sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz", + "integrity": "sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz", + "integrity": "sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz", + "integrity": "sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz", + "integrity": "sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz", + "integrity": "sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz", + "integrity": "sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz", + "integrity": "sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz", + "integrity": "sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz", + "integrity": "sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz", + "integrity": "sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", @@ -2513,6 +2875,13 @@ "node": ">=18.0.0" } }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, "node_modules/@supabase/auth-js": { "version": "2.102.1", "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.102.1.tgz", @@ -2599,10 +2968,21 @@ "node": ">=20.0.0" } }, - "node_modules/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "node_modules/@tybys/wasm-util": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", + "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "dev": true, "license": "MIT", "dependencies": { @@ -2610,6 +2990,17 @@ "@types/node": "*" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, "node_modules/@types/connect": { "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", @@ -2620,6 +3011,13 @@ "@types/node": "*" } }, + "node_modules/@types/cookiejar": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz", + "integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/cors": { "version": "2.8.19", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", @@ -2630,6 +3028,20 @@ "@types/node": "*" } }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/express": { "version": "4.17.25", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", @@ -2663,6 +3075,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/methods": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", + "integrity": "sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -2742,6 +3161,30 @@ "@types/node": "*" } }, + "node_modules/@types/superagent": { + "version": "8.1.10", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.10.tgz", + "integrity": "sha512-nbt4IWXABhW0jGmmpRzCFNlbmwCTzZ2gTUsNIr+X+ItdqPms+PAJZbWsNzpS2USqXjcoNLQcO6nXo60zcPQiIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cookiejar": "^2.1.5", + "@types/methods": "^1.1.4", + "@types/node": "*", + "form-data": "^4.0.0" + } + }, + "node_modules/@types/supertest": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/supertest/-/supertest-7.2.0.tgz", + "integrity": "sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/methods": "^1.1.4", + "@types/superagent": "^8.1.0" + } + }, "node_modules/@types/ws": { "version": "8.18.1", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", @@ -2751,6 +3194,119 @@ "@types/node": "*" } }, + "node_modules/@vitest/expect": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.7.tgz", + "integrity": "sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.7", + "@vitest/utils": "4.1.7", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.7.tgz", + "integrity": "sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.7", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.7.tgz", + "integrity": "sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.7.tgz", + "integrity": "sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.7", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.7.tgz", + "integrity": "sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.7", + "@vitest/utils": "4.1.7", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.7.tgz", + "integrity": "sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.7.tgz", + "integrity": "sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.7", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/@xmldom/xmldom": { "version": "0.8.12", "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.12.tgz", @@ -2803,12 +3359,36 @@ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/async": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -2935,6 +3515,39 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", @@ -2971,6 +3584,13 @@ "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", @@ -2986,6 +3606,13 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "license": "MIT" }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true, + "license": "MIT" + }, "node_modules/core-util-is": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", @@ -3036,6 +3663,16 @@ "node": ">=0.10.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -3055,6 +3692,27 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, "node_modules/dingbat-to-unicode": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dingbat-to-unicode/-/dingbat-to-unicode-1.0.1.tgz", @@ -3237,6 +3895,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz", + "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -3249,6 +3914,22 @@ "node": ">= 0.4" } }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.27.7", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz", @@ -3297,6 +3978,16 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -3306,6 +3997,16 @@ "node": ">= 0.6" } }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/express": { "version": "4.22.1", "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", @@ -3388,6 +4089,13 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "license": "Apache-2.0" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-xml-builder": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.5.tgz", @@ -3424,6 +4132,24 @@ "fxparser": "src/cli/cli.js" } }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/fetch-blob": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", @@ -3465,6 +4191,23 @@ "node": ">= 0.8" } }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -3477,6 +4220,24 @@ "node": ">=12.20.0" } }, + "node_modules/formidable": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", + "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", + "dezalgo": "^1.0.4", + "once": "^1.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -3647,6 +4408,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/hash.js": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", @@ -3912,38 +4689,309 @@ "immediate": "~3.0.5" } }, - "node_modules/long": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", - "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", - "license": "Apache-2.0" - }, - "node_modules/lop": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz", - "integrity": "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw==", - "license": "BSD-2-Clause", - "dependencies": { - "duck": "^0.1.12", - "option": "~0.2.1", - "underscore": "^1.13.1" - } - }, - "node_modules/mammoth": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.12.0.tgz", - "integrity": "sha512-cwnK1RIcRdDMi2HRx2EXGYlxqIEh0Oo3bLhorgnsVJi2UkbX1+jKxuBNR9PC5+JaX7EkmJxFPmo6mjLpqShI2w==", - "license": "BSD-2-Clause", + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", "dependencies": { - "@xmldom/xmldom": "^0.8.6", - "argparse": "~1.0.3", - "base64-js": "^1.5.1", - "bluebird": "~3.4.0", - "dingbat-to-unicode": "^1.0.1", - "jszip": "^3.7.1", - "lop": "^0.4.2", - "path-is-absolute": "^1.0.0", - "underscore": "^1.13.1", + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/lop": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/lop/-/lop-0.4.2.tgz", + "integrity": "sha512-RefILVDQ4DKoRZsJ4Pj22TxE3omDO47yFpkIBoDKzkqPRISs5U1cnAdg/5583YPkWPaLIYHOKRMQSvjFsO26cw==", + "license": "BSD-2-Clause", + "dependencies": { + "duck": "^0.1.12", + "option": "~0.2.1", + "underscore": "^1.13.1" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/mammoth": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/mammoth/-/mammoth-1.12.0.tgz", + "integrity": "sha512-cwnK1RIcRdDMi2HRx2EXGYlxqIEh0Oo3bLhorgnsVJi2UkbX1+jKxuBNR9PC5+JaX7EkmJxFPmo6mjLpqShI2w==", + "license": "BSD-2-Clause", + "dependencies": { + "@xmldom/xmldom": "^0.8.6", + "argparse": "~1.0.3", + "base64-js": "^1.5.1", + "bluebird": "~3.4.0", + "dingbat-to-unicode": "^1.0.1", + "jszip": "^3.7.1", + "lop": "^0.4.2", + "path-is-absolute": "^1.0.0", + "underscore": "^1.13.1", "xmlbuilder": "^10.0.0" }, "bin": { @@ -4160,6 +5208,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -4172,6 +5231,37 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/openai": { + "version": "6.39.1", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.39.1.tgz", + "integrity": "sha512-z3dO9fEWOXBzlXynVb/xZ/tujzUjFWQWn3C0n0mw6Vo0zJTbEkaN4b2cLWjhJ6haJQx8LlREoafHRl+Gu/Hl+A==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, "node_modules/option": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/option/-/option-0.2.4.tgz", @@ -4249,6 +5339,13 @@ "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", "license": "MIT" }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, "node_modules/pdfjs-dist": { "version": "4.10.38", "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.10.38.tgz", @@ -4270,6 +5367,74 @@ "url": "https://ko-fi.com/killymxi" } }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.15", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", + "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/prettier": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", @@ -4451,6 +5616,40 @@ "node": ">= 4" } }, + "node_modules/rolldown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.3.tgz", + "integrity": "sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.133.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.3", + "@rolldown/binding-darwin-arm64": "1.0.3", + "@rolldown/binding-darwin-x64": "1.0.3", + "@rolldown/binding-freebsd-x64": "1.0.3", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.3", + "@rolldown/binding-linux-arm64-gnu": "1.0.3", + "@rolldown/binding-linux-arm64-musl": "1.0.3", + "@rolldown/binding-linux-ppc64-gnu": "1.0.3", + "@rolldown/binding-linux-s390x-gnu": "1.0.3", + "@rolldown/binding-linux-x64-gnu": "1.0.3", + "@rolldown/binding-linux-x64-musl": "1.0.3", + "@rolldown/binding-openharmony-arm64": "1.0.3", + "@rolldown/binding-wasm32-wasi": "1.0.3", + "@rolldown/binding-win32-arm64-msvc": "1.0.3", + "@rolldown/binding-win32-x64-msvc": "1.0.3" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -4634,12 +5833,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -4649,6 +5872,13 @@ "node": ">= 0.8" } }, + "node_modules/std-env": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.1.0.tgz", + "integrity": "sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -4684,6 +5914,134 @@ ], "license": "MIT" }, + "node_modules/superagent": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", + "integrity": "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.1", + "cookiejar": "^2.1.4", + "debug": "^4.3.7", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.5", + "formidable": "^3.5.4", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.14.1" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/superagent/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/superagent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/supertest": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.2.2.tgz", + "integrity": "sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cookie-signature": "^1.2.2", + "methods": "^1.1.2", + "superagent": "^10.3.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supertest/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -4812,6 +6170,174 @@ "node": ">= 0.8" } }, + "node_modules/vite": { + "version": "8.0.15", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.15.tgz", + "integrity": "sha512-qpgllRxrLqwsMAGRdLhsEr9bepaOQk1rxH1xT2coBXLaEB/bfkqQj1j7RMxwMfnYrvO1ZnFMiwX+wBVgnsyn0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.4", + "postcss": "^8.5.15", + "rolldown": "1.0.3", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.1.18", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.7.tgz", + "integrity": "sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.7", + "@vitest/mocker": "4.1.7", + "@vitest/pretty-format": "4.1.7", + "@vitest/runner": "4.1.7", + "@vitest/snapshot": "4.1.7", + "@vitest/spy": "4.1.7", + "@vitest/utils": "4.1.7", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.7", + "@vitest/browser-preview": "4.1.7", + "@vitest/browser-webdriverio": "4.1.7", + "@vitest/coverage-istanbul": "4.1.7", + "@vitest/coverage-v8": "4.1.7", + "@vitest/ui": "4.1.7", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -4821,6 +6347,30 @@ "node": ">= 8" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, "node_modules/ws": { "version": "8.20.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", diff --git a/backend/package.json b/backend/package.json index 8451ab8b7..25e18d25c 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,7 +5,9 @@ "scripts": { "dev": "tsx watch src/index.ts", "build": "tsc", - "start": "node dist/index.js" + "start": "node dist/index.js", + "test": "vitest run", + "test:watch": "vitest" }, "dependencies": { "@anthropic-ai/sdk": "^0.90.0", @@ -25,6 +27,7 @@ "libreoffice-convert": "^1.6.0", "mammoth": "^1.9.0", "multer": "^1.4.5-lts.2", + "openai": "^6.39.1", "pdfjs-dist": "^4.10.38", "resend": "^4.5.1" }, @@ -33,9 +36,12 @@ "@types/express": "^4.17.21", "@types/multer": "^1.4.12", "@types/node": "^22.14.1", + "@types/supertest": "^7.2.0", "prettier": "^3.8.1", + "supertest": "^7.2.2", "tsx": "^4.19.3", - "typescript": "^5.8.3" + "typescript": "^5.8.3", + "vitest": "^4.1.7" }, "license": "AGPL-3.0-only" } diff --git a/backend/schema.sql b/backend/schema.sql index b6a4e934a..3cc98eb6d 100644 --- a/backend/schema.sql +++ b/backend/schema.sql @@ -18,6 +18,8 @@ create table if not exists public.user_profiles ( message_credits_used integer not null default 0, credits_reset_date timestamptz not null default (now() + interval '30 days'), tabular_model text not null default 'gemini-3-flash-preview', + practice_profile text, + practice_profiles jsonb not null default '{}'::jsonb, created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); diff --git a/backend/scripts/import-skills.ts b/backend/scripts/import-skills.ts new file mode 100644 index 000000000..36c70409a --- /dev/null +++ b/backend/scripts/import-skills.ts @@ -0,0 +1,250 @@ +/** + * Import claude-for-legal skills into Mike as built-in "assistant" workflows. + * + * The upstream repo (https://github.com/anthropics/claude-for-legal, Apache-2.0) + * ships practice-area plugins whose skills are markdown SKILL.md files: YAML + * frontmatter + a prompt body. A Mike "assistant" workflow is essentially the + * same thing — a markdown prompt the model loads via the read_workflow tool — + * so each document-task skill maps onto one workflow. + * + * This script: + * 1. reads a local checkout of claude-for-legal, + * 2. selects the user-invocable document-task skills (dropping plugin-runtime + * / config-management skills and non-invocable sub-skills that have no Mike + * equivalent), + * 3. adapts each body for Mike — the upstream skills read a per-team CLAUDE.md + * practice profile and reference external CLM/e-sign connectors; Mike has a + * per-user Practice Profile (injected into the system prompt) and its own + * document tools, so those references are rewritten, + * 4. emits generated workflow catalogues for the backend and the frontend. + * + * Usage: + * git clone --depth 1 https://github.com/anthropics/claude-for-legal /tmp/cfl + * npx tsx scripts/import-skills.ts /tmp/cfl + */ +import { readFileSync, writeFileSync, readdirSync, existsSync } from "node:fs"; +import { join } from "node:path"; +import { PRACTICE_AREA_SET } from "../src/lib/practiceAreas"; + +const SOURCE = process.argv[2] || process.env.SKILL_SRC || "/tmp/cfl"; + +// Plugin folders to import, with the Mike "practice" label each maps onto. +// The skill-marketplace meta plugin (legal-builder-hub) is intentionally +// excluded — it manages community skill discovery/trust, not legal tasks. +const AREAS: { folder: string; practice: string; slug: string }[] = [ + { folder: "ai-governance-legal", practice: "AI Governance", slug: "aigov" }, + { folder: "commercial-legal", practice: "Commercial Contracts", slug: "commercial" }, + { folder: "corporate-legal", practice: "Corporate / M&A", slug: "corporate" }, + { folder: "employment-legal", practice: "Employment", slug: "employment" }, + { folder: "ip-legal", practice: "Intellectual Property", slug: "ip" }, + { folder: "law-student", practice: "Law Student", slug: "lawstudent" }, + { folder: "legal-clinic", practice: "Legal Clinic", slug: "clinic" }, + { folder: "litigation-legal", practice: "Litigation", slug: "litigation" }, + { folder: "privacy-legal", practice: "Privacy & Data Protection", slug: "privacy" }, + { folder: "product-legal", practice: "Product", slug: "product" }, + { folder: "regulatory-legal", practice: "Regulatory", slug: "regulatory" }, +]; + +// Skills whose job is plugin/profile/workspace/scheduling management rather than +// a document task — they have no Mike equivalent (the Practice Profile is edited +// in Account settings; there are no scheduled agents, matter workspaces, study +// sessions, deadline trackers, or supervisor queues). +const RUNTIME_DENYLIST = new Set([ + "cold-start-interview", + "customize", + "matter-workspace", + "review-proposals", + // law-student / legal-clinic session & workspace-state skills: + "session", + "study-plan", + "ramp", + "semester-handoff", + "build-guide", + "client-comms-log", + "deadlines", + "supervisor-review-queue", +]); + +// Scheduled watchers and register-trackers (every area ships its own) — these +// rely on persistent state / background runs that Mike doesn't have. +const DENY_PATTERNS = [/-(monitor|watcher)$/, /^(renewal|leave)-tracker$/, /^log-/]; + +// Fail fast if an area label drifts from the canonical PRACTICE_AREAS list — +// otherwise ported workflows would tag a practice area the profile UI and +// injection don't know about. +for (const a of AREAS) { + if (!PRACTICE_AREA_SET.has(a.practice)) { + throw new Error( + `AREAS practice "${a.practice}" is missing from PRACTICE_AREAS ` + + `(backend/src/lib/practiceAreas.ts) — keep them in sync.`, + ); + } +} + +const PRACTICE_PROFILE_REF = + "your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)"; + +type Skill = { name: string; title: string; id: string; practice: string; prompt_md: string }; + +function parseFrontmatter(raw: string): { + fields: Record; + body: string; +} { + if (!raw.startsWith("---")) return { fields: {}, body: raw }; + const end = raw.indexOf("\n---", 3); + if (end === -1) return { fields: {}, body: raw }; + const fmBlock = raw.slice(3, end); + const body = raw.slice(raw.indexOf("\n", end + 1) + 1); + const fields: Record = {}; + for (const line of fmBlock.split("\n")) { + const m = /^([a-zA-Z-]+):\s*(.*)$/.exec(line); + if (m) fields[m[1]] = m[2].trim(); + } + return { fields, body }; +} + +const ACRONYMS: Record = { + nda: "NDA", + saas: "SaaS", + msa: "MSA", + cp: "CP", + sha: "SHA", + ip: "IP", + irac: "IRAC", + dpa: "DPA", + dsar: "DSAR", + pia: "PIA", + fto: "FTO", + oss: "OSS", + aia: "AIA", + qa: "Q&A", +}; + +function titleCase(name: string): string { + return name + .split("-") + .map( + (w) => + ACRONYMS[w.toLowerCase()] ?? + w.charAt(0).toUpperCase() + w.slice(1), + ) + .join(" "); +} + +function adaptBody(name: string, body: string): string { + let out = body.trim(); + // The per-team CLAUDE.md practice profile -> Mike's per-user Practice Profile. + // (Match this before the generic path rule below.) Swallow any surrounding + // backticks so we don't leave ``. + out = out.replace( + /`?~\/\.claude\/plugins\/config\/claude-for-legal\/[^\s`)]*\/CLAUDE\.md`?/g, + PRACTICE_PROFILE_REF, + ); + // Every other ~/.claude/plugins/... path is a local working-file the upstream + // skill reads/writes (deal-context, trackers, output dirs). Mike has no such + // filesystem — work from the project's documents instead. + out = out.replace( + /`?~\/\.claude\/plugins\/config\/claude-for-legal\/[^\s`)]*`?/g, + "the current project's documents", + ); + out = out.replace(/`?\bCLAUDE\.md\b`?/g, PRACTICE_PROFILE_REF); + + // Upstream slash-commands have no meaning in Mike. The cold-start/customize + // skills are replaced by the Account → Practice Profile UI; the rest were + // promoted to workflows, so point at the workflow by name. + out = out.replace( + /\/[a-z][a-z-]*-legal:([a-z][a-z-]*)/g, + (_m, skill: string) => + skill === "cold-start-interview" || skill === "customize" + ? "configure your Practice Profile (Account → Practice Profile)" + : `the “${titleCase(skill)}” workflow`, + ); + + const preamble = + `> Adapted for Mike from the Anthropic “claude-for-legal” skill “${name}” (Apache-2.0).\n` + + `> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use ${PRACTICE_PROFILE_REF} for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n`; + return preamble + out; +} + +const skills: Skill[] = []; +const skipped: { name: string; reason: string }[] = []; + +for (const area of AREAS) { + const skillsDir = join(SOURCE, area.folder, "skills"); + if (!existsSync(skillsDir)) { + console.error(`! skills dir not found: ${skillsDir}`); + continue; + } + for (const name of readdirSync(skillsDir).sort()) { + const file = join(skillsDir, name, "SKILL.md"); + if (!existsSync(file)) continue; + const { fields, body } = parseFrontmatter(readFileSync(file, "utf8")); + // We deliberately keep upstream `user-invocable: false` skills: that flag + // controls slash-command exposure in the Claude Code plugin runtime, but + // in Mike every workflow is explicitly user-selected, and those are the + // substantive review playbooks (vendor / NDA / SaaS) that the `review` + // router delegates to. They're useful standalone, so we promote them. + if (RUNTIME_DENYLIST.has(name)) { + skipped.push({ name, reason: "plugin/profile-management skill" }); + continue; + } + if (DENY_PATTERNS.some((re) => re.test(name))) { + skipped.push({ name, reason: "scheduled watcher / register-tracker" }); + continue; + } + // Upstream marks superseded skills "DEPRECATED — use /other" near the top. + if (/\bDEPRECATED\b/.test(body.slice(0, 300))) { + skipped.push({ name, reason: "deprecated upstream" }); + continue; + } + skills.push({ + name, + title: titleCase(name), + id: `builtin-cfl-${area.slug}-${name}`, + practice: area.practice, + prompt_md: adaptBody(name, body), + }); + } +} + +const HEADER = + "// @generated by backend/scripts/import-skills.ts — do not edit by hand.\n" + + "// Ported from Anthropic's claude-for-legal (https://github.com/anthropics/claude-for-legal),\n" + + "// licensed under Apache-2.0. Bodies are adapted for Mike's tools and Practice Profile.\n" + + "// Re-generate with: npx tsx scripts/import-skills.ts \n\n"; + +// Backend catalogue: shape buildWorkflowStore injects, plus `practice` so the +// active-workflow → practice-area lookup can pick the right per-area profile. +const backendOut = + HEADER + + "export const PORTED_LEGAL_WORKFLOWS: { id: string; title: string; practice: string; prompt_md: string }[] = [\n" + + skills + .map( + (s) => + ` {\n id: ${JSON.stringify(s.id)},\n title: ${JSON.stringify(s.title)},\n practice: ${JSON.stringify(s.practice)},\n prompt_md: ${JSON.stringify(s.prompt_md)},\n },`, + ) + .join("\n") + + "\n];\n"; +writeFileSync(join(__dirname, "..", "src", "lib", "portedLegalWorkflows.ts"), backendOut); + +// Frontend catalogue: the richer MikeWorkflow shape used by the workflow picker. +const frontendOut = + HEADER + + 'import type { MikeWorkflow } from "../shared/types";\n\n' + + "export const PORTED_LEGAL_WORKFLOWS: MikeWorkflow[] = [\n" + + skills + .map( + (s) => + ` {\n id: ${JSON.stringify(s.id)},\n user_id: null,\n is_system: true,\n created_at: "",\n title: ${JSON.stringify(s.title)},\n type: "assistant",\n practice: ${JSON.stringify(s.practice)},\n prompt_md: ${JSON.stringify(s.prompt_md)},\n columns_config: null,\n },`, + ) + .join("\n") + + "\n];\n"; +writeFileSync( + join(__dirname, "..", "..", "frontend", "src", "app", "components", "workflows", "portedLegalWorkflows.ts"), + frontendOut, +); + +console.log(`Imported ${skills.length} workflows:`); +for (const s of skills) console.log(` + ${s.id} (${s.title})`); +console.log(`\nSkipped ${skipped.length}:`); +for (const s of skipped) console.log(` - ${s.name}: ${s.reason}`); diff --git a/backend/src/index.ts b/backend/src/index.ts index 07b3b8490..813ea16d2 100644 --- a/backend/src/index.ts +++ b/backend/src/index.ts @@ -12,9 +12,9 @@ import { workflowsRouter } from "./routes/workflows"; import { userRouter } from "./routes/user"; import { downloadsRouter } from "./routes/downloads"; -const app = express(); const PORT = process.env.PORT ?? 3001; const isProduction = process.env.NODE_ENV === "production"; +const isTest = process.env.NODE_ENV === "test"; function envInt(name: string, fallback: number): number { const raw = process.env[name]; @@ -71,56 +71,70 @@ const uploadLimiter = makeLimiter({ message: "Too many upload requests. Please try again later.", }); -app.disable("x-powered-by"); -app.set("trust proxy", envInt("TRUST_PROXY_HOPS", 1)); - -app.use( - helmet({ - contentSecurityPolicy: false, - crossOriginEmbedderPolicy: false, - hsts: isProduction - ? { - maxAge: 15552000, - includeSubDomains: true, - } - : false, - referrerPolicy: { policy: "no-referrer" }, - }), -); - -app.use( - cors({ - origin: process.env.FRONTEND_URL ?? "http://localhost:3000", - credentials: true, - }), -); - -app.use(generalLimiter); - -app.use(express.json({ limit: "50mb" })); - -app.post("/chat", chatLimiter); -app.post("/projects/:projectId/chat", chatLimiter); -app.post("/tabular-review/:reviewId/chat", chatLimiter); -app.post("/tabular-review/:reviewId/generate", chatLimiter); -app.post("/chat/create", chatCreateLimiter); -app.post("/chat/:chatId/generate-title", chatCreateLimiter); -app.post("/single-documents", uploadLimiter); -app.post("/single-documents/:documentId/versions", uploadLimiter); -app.post("/projects/:projectId/documents", uploadLimiter); - -app.use("/chat", chatRouter); -app.use("/projects", projectsRouter); -app.use("/projects/:projectId/chat", projectChatRouter); -app.use("/single-documents", documentsRouter); -app.use("/tabular-review", tabularRouter); -app.use("/workflows", workflowsRouter); -app.use("/user", userRouter); -app.use("/users", userRouter); -app.use("/download", downloadsRouter); - -app.get("/health", (_req, res) => res.json({ ok: true })); - -app.listen(PORT, () => { - console.log(`Mike backend running on port ${PORT}`); -}); +export function createApp() { + const app = express(); + + app.disable("x-powered-by"); + app.set("trust proxy", envInt("TRUST_PROXY_HOPS", 1)); + + app.use( + helmet({ + contentSecurityPolicy: false, + crossOriginEmbedderPolicy: false, + hsts: isProduction + ? { + maxAge: 15552000, + includeSubDomains: true, + } + : false, + referrerPolicy: { policy: "no-referrer" }, + }), + ); + + app.use( + cors({ + origin: process.env.FRONTEND_URL ?? "http://localhost:3000", + credentials: true, + }), + ); + + // Rate limiters interfere with deterministic tests; skip them under test. + if (!isTest) { + app.use(generalLimiter); + } + + app.use(express.json({ limit: "50mb" })); + + if (!isTest) { + app.post("/chat", chatLimiter); + app.post("/projects/:projectId/chat", chatLimiter); + app.post("/tabular-review/:reviewId/chat", chatLimiter); + app.post("/tabular-review/:reviewId/generate", chatLimiter); + app.post("/chat/create", chatCreateLimiter); + app.post("/chat/:chatId/generate-title", chatCreateLimiter); + app.post("/single-documents", uploadLimiter); + app.post("/single-documents/:documentId/versions", uploadLimiter); + app.post("/projects/:projectId/documents", uploadLimiter); + } + + app.use("/chat", chatRouter); + app.use("/projects", projectsRouter); + app.use("/projects/:projectId/chat", projectChatRouter); + app.use("/single-documents", documentsRouter); + app.use("/tabular-review", tabularRouter); + app.use("/workflows", workflowsRouter); + app.use("/user", userRouter); + app.use("/users", userRouter); + app.use("/download", downloadsRouter); + + app.get("/health", (_req, res) => res.json({ ok: true })); + + return app; +} + +// Only bind a port when run directly (not when imported by tests). +if (require.main === module) { + createApp().listen(PORT, () => { + console.log(`Mike backend running on port ${PORT}`); + }); +} diff --git a/backend/src/lib/builtinWorkflows.ts b/backend/src/lib/builtinWorkflows.ts index 7154d7742..9e58e1643 100644 --- a/backend/src/lib/builtinWorkflows.ts +++ b/backend/src/lib/builtinWorkflows.ts @@ -1,7 +1,17 @@ -export const BUILTIN_WORKFLOWS: { id: string; title: string; prompt_md: string }[] = [ +import { PORTED_LEGAL_WORKFLOWS } from "./portedLegalWorkflows"; + +export type BuiltinWorkflow = { + id: string; + title: string; + practice: string; + prompt_md: string; +}; + +const HANDWRITTEN_WORKFLOWS: BuiltinWorkflow[] = [ { id: "builtin-cp-checklist", title: "Generate CP Checklist", + practice: "General Transactions", prompt_md: "## Generate Conditions Precedent Checklist\n\n" + "Review the uploaded credit agreement or financing document and generate a comprehensive " + @@ -22,6 +32,7 @@ export const BUILTIN_WORKFLOWS: { id: string; title: string; prompt_md: string } { id: "builtin-credit-summary", title: "Credit Agreement Summary", + practice: "General Transactions", prompt_md: "## Credit Agreement Summary\n\n" + "Review the uploaded credit agreement and produce a comprehensive legal summary covering the following topics. " + @@ -52,6 +63,7 @@ export const BUILTIN_WORKFLOWS: { id: string; title: string; prompt_md: string } { id: "builtin-sha-summary", title: "Shareholder Agreement Summary", + practice: "General Transactions", prompt_md: "## Shareholder Agreement Summary\n\n" + "Review the uploaded shareholder agreement and produce a comprehensive legal summary covering the following topics. " + @@ -74,3 +86,16 @@ export const BUILTIN_WORKFLOWS: { id: string; title: string; prompt_md: string } "Generate the summary as a downloadable Word document.", }, ]; + +// Hand-written transactional workflows plus the legal review/diligence skills +// ported from Anthropic's claude-for-legal (see portedLegalWorkflows.ts). +export const BUILTIN_WORKFLOWS: BuiltinWorkflow[] = [ + ...HANDWRITTEN_WORKFLOWS, + ...PORTED_LEGAL_WORKFLOWS, +]; + +// id -> practice area, for selecting the right per-area practice profile to +// inject when a built-in workflow is applied. +export const BUILTIN_WORKFLOW_PRACTICE: Map = new Map( + BUILTIN_WORKFLOWS.map((w) => [w.id, w.practice]), +); diff --git a/backend/src/lib/chatTools.ts b/backend/src/lib/chatTools.ts index 6d85c6aaa..4d13613d7 100644 --- a/backend/src/lib/chatTools.ts +++ b/backend/src/lib/chatTools.ts @@ -632,6 +632,48 @@ export async function enrichWithPriorEvents( return enriched; } +/** + * Wrap one practice profile in a clearly-delimited system-prompt block. + * `areaLabel` titles the block for a per-area profile. Returns an empty string + * when the profile is blank, so callers can splice it in unconditionally. + */ +export function formatPracticeProfile( + profile?: string | null, + areaLabel?: string, +): string { + if (!profile || !profile.trim()) return ""; + const header = areaLabel + ? `USER PRACTICE PROFILE — ${areaLabel}:` + : "USER PRACTICE PROFILE:"; + return ( + header + + "\n" + + "The user has configured the practice profile below. Treat it as authoritative " + + "for their firm's positions, house style, escalation rules, preferred governing " + + "law, and review preferences. When a workflow or task references a playbook, firm " + + "position, escalation matrix, or house style, use the values from this profile. If " + + "a value the task needs is not present here, ask the user rather than assuming a " + + "default.\n\n" + + profile.trim() + ); +} + +/** + * Build the combined practice-profile system block: the general profile plus + * the profile for the active workflow's practice `area` (when both are set). + */ +export function buildPracticeProfileBlock( + profiles: { general: string | null; byArea: Record }, + area: string | null, +): string { + const blocks: string[] = []; + if (profiles.general) blocks.push(formatPracticeProfile(profiles.general)); + if (area && profiles.byArea[area]?.trim()) { + blocks.push(formatPracticeProfile(profiles.byArea[area], area)); + } + return blocks.join("\n\n"); +} + export function buildMessages( messages: ChatMessage[], docAvailability: { @@ -2698,6 +2740,7 @@ type AssistantEvent = }[]; } | { type: "workflow_applied"; workflow_id: string; title: string } + | { type: "web_search"; query?: string } | { type: "doc_edited"; filename: string; @@ -2840,6 +2883,7 @@ export async function runLLMStream(params: { maxIterations: 10, apiKeys, enableThinking: true, + enableWebSearch: true, callbacks: { onContentDelta: (delta) => { iterText += delta; @@ -2874,6 +2918,20 @@ export async function runLLMStream(params: { })}\n\n`, ); }, + // Native web search runs server-side inside the provider turn. + // Flush any preceding prose so the indicator lands in order, then + // both stream it and persist it (unlike tool_call_start, which is + // a transient placeholder) so reloaded chats still show the search. + onWebSearch: (query) => { + flushText(); + events.push({ type: "web_search", query }); + write( + `data: ${JSON.stringify({ + type: "web_search", + query, + })}\n\n`, + ); + }, }, runTools: async (calls) => { // Emit any text the model produced before this tool turn so the diff --git a/backend/src/lib/llm/claude.ts b/backend/src/lib/llm/claude.ts index 9f86b1679..f46b972b7 100644 --- a/backend/src/lib/llm/claude.ts +++ b/backend/src/lib/llm/claude.ts @@ -7,6 +7,12 @@ import type { NormalizedToolResult, } from "./types"; import { toClaudeTools } from "./tools"; +import { + runStreamingLoop, + type ProviderSession, + type TurnContext, + type TurnResult, +} from "./driver"; type ContentBlock = | { type: "text"; text: string } @@ -41,26 +47,35 @@ function toNativeMessages( return messages.map((m) => ({ role: m.role, content: m.content })); } -export async function streamClaude( - params: StreamChatParams, -): Promise { +function createClaudeSession(params: StreamChatParams): ProviderSession { const { model, systemPrompt, tools = [], - callbacks = {}, - runTools, apiKeys, enableThinking, + enableWebSearch, } = params; - const maxIter = params.maxIterations ?? 10; const anthropic = client(apiKeys?.claude); - const claudeTools = toClaudeTools(tools); + // Combine caller-supplied function tools with Anthropic's native, + // server-executed web_search tool. The latter never surfaces as a + // `tool_use` block (it arrives as `server_tool_use` and is run by + // Anthropic), so it sits alongside the function tools without touching the + // tool-call loop. + const claudeTools = [ + ...toClaudeTools(tools), + ...(enableWebSearch + ? [{ type: "web_search_20250305", name: "web_search" }] + : []), + ]; const messages: NativeMessage[] = toNativeMessages(params.messages); - let fullText = ""; + // Holds the previous turn's assistant content blocks, which Claude requires + // verbatim on the follow-up turn that carries tool_result blocks. + let lastAssistantBlocks: ContentBlock[] = []; - for (let iter = 0; iter < maxIter; iter++) { + async function runTurn(ctx: TurnContext): Promise { + const { callbacks } = ctx; const stream = anthropic.messages.stream({ model, system: systemPrompt, @@ -86,6 +101,17 @@ export async function streamClaude( stream.on("text", (delta) => { callbacks.onContentDelta?.(delta); }); + // `contentBlock` fires when a block is fully assembled. A native + // web_search arrives as a completed `server_tool_use` block (with the + // query in its input) before Anthropic runs the search and streams the + // answer text — so firing here keeps the indicator ahead of the prose. + stream.on("contentBlock", (block) => { + const b = block as { type?: string; name?: string; input?: unknown }; + if (b.type === "server_tool_use" && b.name === "web_search") { + const query = (b.input as { query?: string } | undefined)?.query; + callbacks.onWebSearch?.(query); + } + }); if (enableThinking) { stream.on("thinking", (delta) => { sawThinking = true; @@ -94,17 +120,21 @@ export async function streamClaude( } const final = await stream.finalMessage(); + // Claude fires onReasoningBlockEnd before walking blocks for + // onToolCallStart — preserving the provider's callback ordering. if (sawThinking) callbacks.onReasoningBlockEnd?.(); const stopReason = final.stop_reason; const assistantBlocks = final.content as ContentBlock[]; + lastAssistantBlocks = assistantBlocks; // Extract text content and tool_use calls from the final assistant // message so we can accumulate text and drive the tool-call loop. + let turnText = ""; const toolCalls: NormalizedToolCall[] = []; for (const block of assistantBlocks) { if (block.type === "text") { const txt = (block as { text: string }).text; - if (typeof txt === "string") fullText += txt; + if (typeof txt === "string") turnText += txt; } else if (block.type === "tool_use") { const tu = block as { id: string; @@ -121,16 +151,21 @@ export async function streamClaude( } } - if (stopReason !== "tool_use" || !toolCalls.length || !runTools) { - break; - } - - const results = await runTools(toolCalls); + return { + toolCalls, + textForFullText: turnText, + stop: stopReason !== "tool_use", + }; + } + function recordToolResults( + _calls: NormalizedToolCall[], + results: NormalizedToolResult[], + ): void { // Record the assistant turn (preserving the original content blocks, // which Claude requires on the follow-up) and the user turn that // carries the tool_result blocks. - messages.push({ role: "assistant", content: assistantBlocks }); + messages.push({ role: "assistant", content: lastAssistantBlocks }); messages.push({ role: "user", content: results.map((r) => ({ @@ -141,7 +176,13 @@ export async function streamClaude( }); } - return { fullText }; + return { runTurn, recordToolResults }; +} + +export async function streamClaude( + params: StreamChatParams, +): Promise { + return runStreamingLoop(params, createClaudeSession); } export async function completeClaudeText(params: { diff --git a/backend/src/lib/llm/driver.ts b/backend/src/lib/llm/driver.ts new file mode 100644 index 000000000..af43cd831 --- /dev/null +++ b/backend/src/lib/llm/driver.ts @@ -0,0 +1,66 @@ +// Shared agentic streaming loop for all LLM providers. +// +// Each provider (Claude, OpenAI, Gemini) re-implemented the same skeleton: +// iterate up to `maxIterations`, stream one turn (emitting content/reasoning +// deltas and tool-call starts), accumulate `fullText`, collect tool calls and — +// if any — run them and feed the results back into provider-specific message +// state for the next turn. That triplication let the loop logic drift between +// providers, so the skeleton lives here once and each provider supplies only a +// thin "session" that owns its SDK call, event parsing, follow-up message +// state, and callback firing. + +import type { + NormalizedToolCall, + NormalizedToolResult, + StreamCallbacks, + StreamChatParams, + StreamChatResult, +} from "./types"; + +export type TurnContext = { + iter: number; + callbacks: StreamCallbacks; +}; + +export type TurnResult = { + // Tool calls discovered this turn. The session is responsible for having + // already emitted each via `onToolCallStart` (ordering is provider-specific + // and observable, so the driver never fires callbacks itself). + toolCalls: NormalizedToolCall[]; + // Text the driver should append to `fullText` for this turn. + textForFullText: string; + // Provider hard-stop (e.g. Claude `stop_reason !== "tool_use"`): ends the + // loop even if stray tool calls are present. + stop?: boolean; +}; + +export type ProviderSession = { + runTurn(ctx: TurnContext): Promise; + recordToolResults( + calls: NormalizedToolCall[], + results: NormalizedToolResult[], + ): void; +}; + +export type SessionFactory = (params: StreamChatParams) => ProviderSession; + +export async function runStreamingLoop( + params: StreamChatParams, + createSession: SessionFactory, +): Promise { + const maxIter = params.maxIterations ?? 10; + const callbacks = params.callbacks ?? {}; + const { runTools } = params; + const session = createSession(params); + let fullText = ""; + + for (let iter = 0; iter < maxIter; iter++) { + const turn = await session.runTurn({ iter, callbacks }); + fullText += turn.textForFullText; + if (turn.stop || !turn.toolCalls.length || !runTools) break; + const results = await runTools(turn.toolCalls); + session.recordToolResults(turn.toolCalls, results); + } + + return { fullText }; +} diff --git a/backend/src/lib/llm/gemini.ts b/backend/src/lib/llm/gemini.ts index e40fc6031..16ae21106 100644 --- a/backend/src/lib/llm/gemini.ts +++ b/backend/src/lib/llm/gemini.ts @@ -3,8 +3,15 @@ import type { StreamChatParams, StreamChatResult, NormalizedToolCall, + NormalizedToolResult, } from "./types"; import { toGeminiTools } from "./tools"; +import { + runStreamingLoop, + type ProviderSession, + type TurnContext, + type TurnResult, +} from "./driver"; type GeminiPart = { text?: string; @@ -49,25 +56,31 @@ function toNativeContents(messages: StreamChatParams["messages"]): GeminiContent })); } -export async function streamGemini( - params: StreamChatParams, -): Promise { - const { model, systemPrompt, tools = [], callbacks = {}, runTools, apiKeys, enableThinking } = params; - const maxIter = params.maxIterations ?? 10; +function createGeminiSession(params: StreamChatParams): ProviderSession { + const { model, systemPrompt, tools = [], apiKeys, enableThinking, enableWebSearch } = params; const ai = client(apiKeys?.gemini); const functionDeclarations = toGeminiTools(tools); + // Combine function declarations with the native googleSearch grounding + // tool. Gemini 2.0+ models accept both in the same request. + const geminiTools: unknown[] = []; + if (functionDeclarations.length) geminiTools.push({ functionDeclarations }); + if (enableWebSearch) geminiTools.push({ googleSearch: {} }); const contents: GeminiContent[] = toNativeContents(params.messages); - let fullText = ""; + // Stashed from the latest turn so recordToolResults can rebuild the model + // turn (text + functionCall parts) before appending the tool responses. + let lastTextParts: string[] = []; + let lastCallParts: GeminiPart[] = []; - for (let iter = 0; iter < maxIter; iter++) { + async function runTurn(ctx: TurnContext): Promise { + const { callbacks } = ctx; const stream = await ai.models.generateContentStream({ model, contents: contents as never, config: { systemInstruction: systemPrompt, - tools: functionDeclarations.length - ? [{ functionDeclarations } as never] + tools: geminiTools.length + ? (geminiTools as never) : undefined, // When enabled, ask Gemini to surface thought summaries. // When disabled, explicitly zero the thinking budget so the @@ -83,12 +96,25 @@ export async function streamGemini( const textParts: string[] = []; const callParts: GeminiPart[] = []; const toolCalls: NormalizedToolCall[] = []; + // googleSearch grounding reports its queries via groundingMetadata, + // which can repeat across chunks — dedupe so each search fires once. + const seenQueries = new Set(); let sawThinking = false; for await (const chunk of stream) { - const parts = - (chunk as { candidates?: { content?: { parts?: GeminiPart[] } }[] }) - .candidates?.[0]?.content?.parts ?? []; + const candidate = (chunk as { + candidates?: { + content?: { parts?: GeminiPart[] }; + groundingMetadata?: { webSearchQueries?: string[] }; + }[]; + }).candidates?.[0]; + for (const query of candidate?.groundingMetadata?.webSearchQueries ?? []) { + if (!seenQueries.has(query)) { + seenQueries.add(query); + callbacks.onWebSearch?.(query); + } + } + const parts = candidate?.content?.parts ?? []; for (const part of parts) { if (part.text) { @@ -115,27 +141,31 @@ export async function streamGemini( } } + // Gemini fires onToolCallStart mid-stream (above) and onReasoningBlockEnd + // after the stream — preserving the provider's callback ordering. if (sawThinking) callbacks.onReasoningBlockEnd?.(); - fullText += textParts.join(""); - - if (!toolCalls.length || !runTools) { - break; - } + lastTextParts = textParts; + lastCallParts = callParts; - const results = await runTools(toolCalls); + return { toolCalls, textForFullText: textParts.join("") }; + } + function recordToolResults( + calls: NormalizedToolCall[], + results: NormalizedToolResult[], + ): void { // Append the model's turn (text + functionCall parts, in that order) // and the matching functionResponse turn. const modelParts: GeminiPart[] = []; - if (textParts.length) modelParts.push({ text: textParts.join("") }); - for (const cp of callParts) modelParts.push(cp); + if (lastTextParts.length) modelParts.push({ text: lastTextParts.join("") }); + for (const cp of lastCallParts) modelParts.push(cp); contents.push({ role: "model", parts: modelParts }); contents.push({ role: "user", parts: results.map((r) => { - const match = toolCalls.find((c) => c.id === r.tool_use_id); + const match = calls.find((c) => c.id === r.tool_use_id); return { functionResponse: { ...(r.tool_use_id && !r.tool_use_id.startsWith(match?.name ?? "") @@ -149,7 +179,13 @@ export async function streamGemini( }); } - return { fullText }; + return { runTurn, recordToolResults }; +} + +export async function streamGemini( + params: StreamChatParams, +): Promise { + return runStreamingLoop(params, createGeminiSession); } export async function completeGeminiText(params: { diff --git a/backend/src/lib/llm/openai.ts b/backend/src/lib/llm/openai.ts index de07b5c96..04648957f 100644 --- a/backend/src/lib/llm/openai.ts +++ b/backend/src/lib/llm/openai.ts @@ -1,3 +1,4 @@ +import OpenAI from "openai"; import type { LlmMessage, NormalizedToolCall, @@ -6,35 +7,21 @@ import type { StreamChatParams, StreamChatResult, } from "./types"; +import { + runStreamingLoop, + type ProviderSession, + type TurnContext, + type TurnResult, +} from "./driver"; -const OPENAI_RESPONSES_URL = "https://api.openai.com/v1/responses"; const MAX_OUTPUT_TOKENS = 16384; +// The Responses API input is either a chat-style message or a tool-call +// result. We only ever feed it these two shapes. type ResponseInputItem = | { role: "user" | "assistant"; content: string } | { type: "function_call_output"; call_id: string; output: string }; -type ResponseFunctionTool = { - type: "function"; - name: string; - description?: string; - parameters: Record; -}; - -type ResponseFunctionCallItem = { - type: "function_call"; - call_id?: string; - name?: string; - arguments?: string; -}; - -type ResponseStreamEvent = { - type?: string; - delta?: string; - response?: { id?: string; output_text?: string }; - item?: ResponseFunctionCallItem; -}; - function apiKey(override?: string | null): string { const key = override?.trim() || process.env.OPENAI_API_KEY?.trim() || ""; if (!key) { @@ -45,12 +32,19 @@ function apiKey(override?: string | null): string { return key; } -function toResponseTools(tools: OpenAIToolSchema[]): ResponseFunctionTool[] { +function client(override?: string | null): OpenAI { + return new OpenAI({ apiKey: apiKey(override) }); +} + +function toResponseTools( + tools: OpenAIToolSchema[], +): OpenAI.Responses.Tool[] { return tools.map((tool) => ({ type: "function", name: tool.function.name, description: tool.function.description, parameters: tool.function.parameters, + strict: false, })); } @@ -61,32 +55,11 @@ function toResponseInput(messages: LlmMessage[]): ResponseInputItem[] { })); } -function extractSseJson(buffer: string): { events: unknown[]; rest: string } { - const events: unknown[] = []; - const chunks = buffer.split(/\n\n/); - const rest = chunks.pop() ?? ""; - - for (const chunk of chunks) { - const dataLines = chunk - .split("\n") - .map((line) => line.trim()) - .filter((line) => line.startsWith("data:")) - .map((line) => line.slice(5).trim()); - - for (const data of dataLines) { - if (!data || data === "[DONE]") continue; - try { - events.push(JSON.parse(data)); - } catch { - // Incomplete events stay buffered until the next read. - } - } - } - - return { events, rest }; -} - -function parseFunctionCall(item: ResponseFunctionCallItem): NormalizedToolCall { +function parseFunctionCall(item: { + call_id?: string; + name?: string; + arguments?: string; +}): NormalizedToolCall { let input: Record = {}; try { const parsed = JSON.parse(item.arguments || "{}"); @@ -104,156 +77,128 @@ function parseFunctionCall(item: ResponseFunctionCallItem): NormalizedToolCall { }; } -async function createResponse(params: { - model: string; - input: ResponseInputItem[]; - instructions?: string; - tools?: ResponseFunctionTool[]; - stream?: boolean; - maxTokens?: number; - previousResponseId?: string; - reasoningSummary?: boolean; - apiKey: string; -}): Promise { - const response = await fetch(OPENAI_RESPONSES_URL, { - method: "POST", - headers: { - Authorization: `Bearer ${params.apiKey}`, - "Content-Type": "application/json", - }, - body: JSON.stringify({ - model: params.model, - instructions: params.instructions || undefined, - input: params.input, - tools: params.tools?.length ? params.tools : undefined, - stream: params.stream, - max_output_tokens: params.maxTokens ?? MAX_OUTPUT_TOKENS, - previous_response_id: params.previousResponseId, - reasoning: params.reasoningSummary - ? { summary: "auto" } - : undefined, - }), - }); - - if (!response.ok) { - const text = await response.text().catch(() => ""); - const err = new Error( - `OpenAI request failed (${response.status}): ${text || response.statusText}`, - ); - (err as { status?: number }).status = response.status; - throw err; - } - - return response; -} - -export async function streamOpenAI( - params: StreamChatParams, -): Promise { +function createOpenAISession(params: StreamChatParams): ProviderSession { const { model, systemPrompt, tools = [], - callbacks = {}, runTools, apiKeys, enableThinking, + enableWebSearch, } = params; - const maxIter = params.maxIterations ?? 10; - const key = apiKey(apiKeys?.openai); + const openai = client(apiKeys?.openai); const responseTools = toResponseTools(tools); - let input = toResponseInput(params.messages); - let previousResponseId: string | undefined; - let fullText = ""; + // `hasTools` (which drives the pre-tool preamble buffering) keys off + // *function* tools only — the native web_search tool is server-executed + // and doesn't produce a function-call preamble, so it's appended + // separately and left out of that gate. const hasTools = responseTools.length > 0; + const requestTools: OpenAI.Responses.Tool[] = [ + ...responseTools, + ...(enableWebSearch + ? [{ type: "web_search" } as OpenAI.Responses.Tool] + : []), + ]; + + // Conversation state is carried server-side via `previous_response_id`; + // after the first turn `input` only carries fresh tool outputs. + let input: ResponseInputItem[] = toResponseInput(params.messages); + let previousResponseId: string | undefined; - for (let iter = 0; iter < maxIter; iter++) { - const response = await createResponse({ + async function runTurn(ctx: TurnContext): Promise { + const { callbacks } = ctx; + // The SDK returns a typed async iterable of SSE events — no manual + // fetch/TextDecoder/buffer parsing required. Conversation state is + // carried server-side via `previous_response_id`, so after the first + // turn we only send fresh input (tool outputs) and let the prior + // context (including instructions) persist. + const stream = await openai.responses.create({ model, - instructions: iter === 0 ? systemPrompt : undefined, - input, - tools: responseTools, + instructions: ctx.iter === 0 ? systemPrompt : undefined, + input: input as OpenAI.Responses.ResponseInput, + tools: requestTools.length ? requestTools : undefined, stream: true, - previousResponseId, - reasoningSummary: !!enableThinking, - apiKey: key, + max_output_tokens: MAX_OUTPUT_TOKENS, + previous_response_id: previousResponseId, + reasoning: enableThinking ? { summary: "auto" } : undefined, }); - if (!response.body) throw new Error("OpenAI response had no body"); - const reader = response.body.getReader(); - const decoder = new TextDecoder(); const toolCalls: NormalizedToolCall[] = []; const startedToolCallIds = new Set(); - let buffer = ""; + let turnText = ""; let pendingText = ""; let sawReasoning = false; - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - buffer += decoder.decode(value, { stream: true }); - const extracted = extractSseJson(buffer); - buffer = extracted.rest; - - for (const event of extracted.events as ResponseStreamEvent[]) { - if (event.response?.id) { + for await (const event of stream) { + switch (event.type) { + case "response.created": previousResponseId = event.response.id; - } + break; - if ( - event.type === "response.reasoning_summary_text.delta" && - typeof event.delta === "string" - ) { + case "response.reasoning_summary_text.delta": sawReasoning = true; callbacks.onReasoningDelta?.(event.delta); - } + break; - if ( - event.type === "response.output_text.delta" && - typeof event.delta === "string" - ) { + case "response.output_text.delta": + // When tools are in play we buffer text and only flush it + // once we know the model isn't going to call a tool — a + // tool-calling turn shouldn't surface partial prose. if (hasTools) { pendingText += event.delta; } else { - fullText += event.delta; + turnText += event.delta; callbacks.onContentDelta?.(event.delta); } - } - - if ( - event.type === "response.output_item.added" && - event.item?.type === "function_call" - ) { - const call = parseFunctionCall(event.item); - startedToolCallIds.add(call.id); - callbacks.onToolCallStart?.(call); - } + break; - if ( - event.type === "response.output_item.done" && - event.item?.type === "function_call" - ) { - const call = parseFunctionCall(event.item); - if (!startedToolCallIds.has(call.id)) { + case "response.output_item.added": + if (event.item.type === "function_call") { + const call = parseFunctionCall(event.item); + startedToolCallIds.add(call.id); callbacks.onToolCallStart?.(call); + } else if (event.item.type === "web_search_call") { + // Native web search runs server-side; surface it as a + // search indicator rather than a tool call. + const action = ( + event.item as { action?: { query?: string } } + ).action; + callbacks.onWebSearch?.(action?.query); } - toolCalls.push(call); - } + break; + + case "response.output_item.done": + if (event.item.type === "function_call") { + const call = parseFunctionCall(event.item); + if (!startedToolCallIds.has(call.id)) { + callbacks.onToolCallStart?.(call); + } + toolCalls.push(call); + } + break; } } + // OpenAI fires onToolCallStart mid-stream (above) and onReasoningBlockEnd + // after the stream — preserving the provider's callback ordering. if (sawReasoning) callbacks.onReasoningBlockEnd?.(); - if (!toolCalls.length || !runTools) { - if (pendingText) { - fullText += pendingText; - callbacks.onContentDelta?.(pendingText); - } - break; + // Buffered preamble text is surfaced only when this turn isn't going to + // run tools; in a tool-using turn it is dropped (neither streamed nor + // counted in fullText). Mirrors the driver's break condition. + if ((!toolCalls.length || !runTools) && pendingText) { + turnText += pendingText; + callbacks.onContentDelta?.(pendingText); } - const results = await runTools(toolCalls); + return { toolCalls, textForFullText: turnText }; + } + + function recordToolResults( + _calls: NormalizedToolCall[], + results: NormalizedToolResult[], + ): void { input = results.map((result) => ({ type: "function_call_output", call_id: result.tool_use_id, @@ -261,7 +206,13 @@ export async function streamOpenAI( })); } - return { fullText }; + return { runTurn, recordToolResults }; +} + +export async function streamOpenAI( + params: StreamChatParams, +): Promise { + return runStreamingLoop(params, createOpenAISession); } export async function completeOpenAIText(params: { @@ -271,29 +222,14 @@ export async function completeOpenAIText(params: { maxTokens?: number; apiKeys?: { openai?: string | null }; }): Promise { - const response = await createResponse({ + const openai = client(params.apiKeys?.openai); + const response = await openai.responses.create({ model: params.model, instructions: params.systemPrompt, - input: [{ role: "user", content: params.user }], - maxTokens: params.maxTokens ?? 512, - apiKey: apiKey(params.apiKeys?.openai), + input: params.user, + max_output_tokens: params.maxTokens ?? 512, }); - const json = (await response.json()) as { - output_text?: string; - output?: { - content?: { type?: string; text?: string }[]; - }[]; - }; - - if (typeof json.output_text === "string") return json.output_text; - - return ( - json.output - ?.flatMap((item) => item.content ?? []) - .filter((content) => content.type === "output_text") - .map((content) => content.text ?? "") - .join("") ?? "" - ); + return response.output_text ?? ""; } export type { NormalizedToolResult }; diff --git a/backend/src/lib/llm/types.ts b/backend/src/lib/llm/types.ts index a8409d80e..6cedda1a8 100644 --- a/backend/src/lib/llm/types.ts +++ b/backend/src/lib/llm/types.ts @@ -34,6 +34,14 @@ export type StreamCallbacks = { onReasoningBlockEnd?: () => void; onContentDelta?: (text: string) => void; onToolCallStart?: (call: NormalizedToolCall) => void; + /** + * Fired when the provider's native web-search tool issues a search. These + * searches run server-side (the provider executes them itself and folds + * the results into its response), so they never reach `runTools`; this + * callback exists purely so consumers can surface a "searching the web" + * indicator. `query` is the search string when the provider exposes it. + */ + onWebSearch?: (query?: string) => void; }; export type UserApiKeys = { @@ -58,6 +66,14 @@ export type StreamChatParams = { * one-shot completions should leave this off to save tokens and latency. */ enableThinking?: boolean; + /** + * Enable the provider's native web-search tool (Anthropic `web_search`, + * OpenAI Responses `web_search`, Gemini `googleSearch` grounding). The + * provider runs searches server-side and incorporates results into its + * answer; matching `onWebSearch` callbacks fire as searches happen. Off by + * default — only interactive chat surfaces should opt in. + */ + enableWebSearch?: boolean; }; export type StreamChatResult = { diff --git a/backend/src/lib/portedLegalWorkflows.ts b/backend/src/lib/portedLegalWorkflows.ts new file mode 100644 index 000000000..6399db3f7 --- /dev/null +++ b/backend/src/lib/portedLegalWorkflows.ts @@ -0,0 +1,559 @@ +// @generated by backend/scripts/import-skills.ts — do not edit by hand. +// Ported from Anthropic's claude-for-legal (https://github.com/anthropics/claude-for-legal), +// licensed under Apache-2.0. Bodies are adapted for Mike's tools and Practice Profile. +// Re-generate with: npx tsx scripts/import-skills.ts + +export const PORTED_LEGAL_WORKFLOWS: { id: string; title: string; practice: string; prompt_md: string }[] = [ + { + id: "builtin-cfl-aigov-ai-inventory", + title: "Ai Inventory", + practice: "AI Governance", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “ai-inventory” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /ai-inventory\n\n## When this runs\n\nThe user wants to manage their AI system inventory under the EU AI Act. The\ncore idea the skill exists to enforce: **role and tier are per-system, not\nper-company.** A single organization can be a *provider* of System A, a\n*deployer* of System B, and an *importer* of System C. Each combination\ntriggers a different set of obligations under the AI Act. The inventory\nexists so those assessments are tracked where you can find them — the\nobligations themselves are derived in conversation, not from a table.\n\n## What to do\n\n1. **Read the config.** Read\n your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n If it doesn't exist or still has `[PLACEHOLDER]` markers, direct the user\n to `configure your Practice Profile (Account → Practice Profile)` first.\n\n2. **Read the inventory.** Inventory lives at\n the current project's documents.\n If it doesn't exist, create it with an empty `systems:` list when the\n first `add` runs.\n\n3. **Dispatch on the argument:**\n\n - No argument, or `list` → show the inventory table (see **List** below).\n - `add` → run the **Add** flow.\n - `edit ` → show the current record, ask what to change, update one\n field, confirm, write.\n - `classify ` → run the **Classification walk-through** on an\n existing record, updating role, tier, role_basis, and tier_basis.\n - `show ` → show the full record.\n\n4. **On list, offer the dashboard:**\n \"Want the full dashboard? Filter by status / tier / EU nexus / owner.\n Say the word.\"\n\n5. **Close every action with a hook into the lawyer's work.**\n After any write, say:\n > Recorded. When you're ready to walk through obligations for this\n > system, just ask — I'll do it in-conversation and flag where the AI\n > Act article mapping needs your verification. I don't derive\n > obligations from a table because the mapping is complex and changing.\n\n## List format\n\nRender as a compact table:\n\n| ID | Name | Owner | Status | EU nexus | Role | Tier | Next review |\n|----|------|-------|--------|----------|------|------|-------------|\n| sys-001 | Resume screening | HR / Jamie | in_production | yes | deployer | high_risk | 2026-08-01 |\n| sys-002 | Email drafting assistant | IT / Priya | in_production | no | deployer | limited | 2026-12-01 |\n\nUnder the table, show counts by tier and a line: \"N systems flagged for\nreview within 30 days.\"\n\n## Add flow (interview)\n\nAsk, one field at a time (or accept a paste). The required fields are\n`name`, `owner`, `description`, `status`, `eu_nexus`. The rest can be\ndeferred — say so explicitly: \"you can come back to classification with\n`the “Ai Inventory” workflow classify `.\"\n\n1. **Name.** Short label for the system.\n2. **Owner.** Person or team accountable for it day-to-day.\n3. **Description.** One or two sentences. What does it do, and against\n what data?\n4. **Status.** `planned | in_development | in_production | deprecated`.\n5. **EU nexus.** Is the system deployed in the EU/EEA, offered to users in\n the EU/EEA, or used to produce outputs that affect people in the\n EU/EEA? If any of these are true, EU AI Act analysis applies.\n6. **Proceed to classification?** Offer to run the walk-through now, or\n skip and come back later.\n\nAssign an ID: `sys-NNN` where NNN is the next integer in the file.\n\n## Classification walk-through\n\nThe walk-through produces `role`, `role_basis`, `tier`, `tier_basis`. Both\nbases are tagged `[verify against current AI Act text]` — not because the\nskill is hedging, but because the article mapping is complex and the AI\nAct is still phasing in. The lawyer owns verification.\n\n### Step 1: Role\n\n> **Who does what to this system?**\n\nOptions, with the distinguishing test:\n\n- **Provider** — you develop it (or have it developed) and place it on the\n EU market or put it into service under your own name or trademark.\n- **Deployer** — you use it under your own authority, not for personal\n non-professional use. (Most common inside companies.)\n- **Importer** — you bring an AI system into the EU from a provider\n established outside the EU.\n- **Distributor** — you make an AI system available on the EU market\n without being the provider or importer.\n- **Authorized representative** — you act on behalf of a non-EU provider\n and are established in the EU.\n- **Product manufacturer** — you put a general-purpose AI system (or\n another AI system) into a product under your own name/trademark. Treated\n as provider for the product.\n\n**Dual-role flag.** If the user substantially modifies a vendor system\n(fine-tunes on their own data, changes the intended purpose, rebrands),\nthey may become a **provider** of the modified system even if they started\nas a deployer. Call this out when they describe any modification beyond\nconfiguration. `[verify against current AI Act text — Article 25, provider\nobligations and substantial modification]`\n\nWrite the role. Write `role_basis` in one sentence.\n\n### Step 2: Tier\n\n> **What does the system do, and does the use case fall into a regulated\n> category?**\n\nCheck in order:\n\n**A. Article 5 prohibited practices.** `[verify against current AI Act\ntext — Article 5]`\n\nSummaries, not definitive text:\n- Subliminal or deceptive techniques materially distorting behavior\n- Exploiting vulnerabilities (age, disability, socio-economic status) to\n materially distort behavior\n- Social scoring by public authorities leading to detrimental treatment\n- Real-time remote biometric ID in publicly accessible spaces for law\n enforcement (narrow exceptions)\n- Biometric categorization inferring race, political opinions, union\n membership, religious or philosophical beliefs, sex life, or sexual\n orientation\n- Emotion recognition in the workplace or education (medical and safety\n exceptions)\n- Facial image database scraping from the internet or CCTV\n- Predictive policing based solely on personality traits\n\nIf matched → tier is `prohibited`. Flag the use case as stop and route to\nthe governance team's prohibited-practice workflow.\n\n**B. Annex III high-risk areas.** `[verify against current AI Act text —\nAnnex III]`\n\nSummaries:\n1. Biometric identification and categorization\n2. Critical infrastructure (digital infrastructure, road traffic, supply of\n water / gas / heating / electricity)\n3. Education and vocational training (access, evaluation, proctoring,\n monitoring prohibited behavior)\n4. Employment, worker management, self-employment access — recruitment,\n selection, promotion, termination, task allocation, monitoring, performance\n5. Essential private and public services (public benefits, credit scoring\n for individuals, risk assessment and pricing for life/health insurance,\n emergency dispatch)\n6. Law enforcement (risk assessment, polygraphs, deepfake detection,\n reliability of evidence, profiling)\n7. Migration, asylum, border control (risk assessment, travel document\n verification, examination of applications)\n8. Administration of justice and democratic processes (research and\n interpretation, influencing elections)\n\nIf matched → tier is `high_risk`. Note the Annex III area and subsection.\n\n**C. GPAI.** `[verify against current AI Act text — Article 51 and\nsurrounding]`\n\n- **GPAI:** model trained on broad data at scale, designed for generality,\n capable of competently performing a wide range of distinct tasks.\n- **GPAI + systemic risk:** cumulative compute > 10^25 FLOPs, or designated\n by the Commission.\n\n**D. Limited risk.** Chatbots interacting with natural persons, deepfakes,\nemotion recognition and biometric categorization systems outside Article 5\nscope — transparency obligations apply.\n\n**E. Minimal risk.** Everything else.\n\nWrite the tier. Write `tier_basis` in one sentence, citing the article or\nAnnex entry that matched, tagged `[verify against current AI Act text]`.\n\n### Step 3: Recommendations\n\nOffer three next steps:\n1. \"Want me to walk through obligations for this system? I'll do it in\n conversation — I don't derive them from a table.\"\n2. \"Want to run `the “AIA Generation” workflow` to produce a full\n impact assessment?\"\n3. \"Want to set a next review date? I'll add it to the inventory.\"\n\n## Record format\n\n```yaml\nsystems:\n - id: sys-001\n name: \"Resume screening tool\"\n owner: \"HR / Jamie\"\n description: \"Filters inbound CVs against job criteria\"\n status: in_production # planned | in_development | in_production | deprecated\n eu_nexus: true # deployed, offered, or affects people in the EU/EEA\n role: deployer # provider | deployer | importer | distributor | authorized_rep | product_manufacturer\n role_basis: \"We license from VendorX and deploy internally [verify against current AI Act text]\"\n tier: high_risk # prohibited | high_risk | limited | minimal | gpai | gpai_systemic\n tier_basis: \"Annex III(4)(a) — employment, recruitment selection [verify against current AI Act text]\"\n obligations_assessed: false\n obligations_note: \"To assess: as deployer of a high-risk system — human oversight, input data quality, monitoring, record-keeping, informing workers, FRIA if public body/service — see Article 26 [verify against current AI Act text]\"\n next_review: \"2026-08-01\"\n review_trigger: \"on substantial modification or annually\"\n created: \"2026-05-11\"\n updated: \"2026-05-11\"\n```\n\n## Why this skill does NOT auto-derive obligations\n\nThe inventory stores role, tier, and the basis for each. It does NOT\ncontain a hardcoded role × tier → obligations table.\n\nWhen the user asks \"what are my obligations for System X?\", the skill\ndoes the analysis **in conversation**, tagged `[verify]`, and routes to\n`the “AIA Generation” workflow` for the formal impact assessment\nif needed.\n\nThis is deliberate:\n- Article mapping is complex and the AI Act is phasing in through 2027.\n- Confident-and-wrong on a compliance obligation ends up in a board memo.\n- The inventory is a registry for the lawyer. The lawyer owns the\n obligation analysis.\n\n## Guardrails\n\n- **Never classify silently.** The classification walk-through must be\n visible; do not auto-classify from a system description.\n- **`[verify]` tags stay.** They are not hedging — they are the point.\n Do not strip them in outputs.\n- **Flag substantial modification.** Whenever a system is modified beyond\n configuration, prompt the user to re-run `/ai-inventory classify` —\n modification can change role.\n- **Don't declare obligations from a table.** If asked, do the analysis\n in conversation and route to `/aia-generation` for anything that needs\n a formal record.", + }, + { + id: "builtin-cfl-aigov-aia-generation", + title: "AIA Generation", + practice: "AI Governance", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “aia-generation” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /aia-generation\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Confirm impact assessment house style is populated.\n2. Determine risk track (fast or full) from governance tier and use case characteristics, using the framework below.\n3. Run intake — conversational, not a form.\n4. Regulatory classification for each regime in the footprint — research tier, prohibited-practice exposure, and applicable obligations; cite primary sources.\n5. Write assessment in house style (from seed doc, or default if none captured).\n6. Policy diff against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) AI policy commitments.\n7. Output: assessment doc + conditions list + handoff flags (privacy PIA, vendor review if needed).\n\n```\nthe “AIA Generation” workflow \"AI résumé screening for HR\"\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nAn AI impact assessment is a documented decision, not a form. It answers: what\ndoes this AI system do, how does it reach its outputs, who's affected if it's\nwrong, what's the oversight, and is it okay to deploy. This skill structures that\nconversation and writes the output in this team's format — the one learned from the\nseed impact assessment during cold-start.\n\nAn AI impact assessment is not the same as a PIA. A PIA asks whether personal data\nis handled lawfully. An AIA asks whether the AI system is designed and deployed\nresponsibly. They often need to happen in parallel; they're not substitutes.\n\n## Load house style\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Impact assessment house style`. That has:\n- What triggers an impact assessment at this company\n- The structure template extracted from the seed assessment\n- Typical depth\n- Who signs off\n\nIf the seed structure is in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), **use it**. The point is that this assessment\nlooks like the other assessments this team produces.\n\n**Jurisdictional scope.** This assessment applies the regulatory regimes listed in `## Regulatory footprint` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). AI legal rules, risk classifications, and deployment obligations vary materially by jurisdiction and are moving fast. If this system is (or will be) deployed outside that footprint, or if a choice-of-law question is in play, this analysis may not apply as written — re-run or expand the footprint.\n\n---\n\n## Step 0: Is an impact assessment needed?\n\nCheck the trigger criteria in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n**Also check these regardless:**\n- Does this AI make or materially influence a decision affecting a person (employment,\n credit, access, pricing, content moderation)?\n- Does this AI process personal data about individuals?\n- Is this a customer-facing AI system rather than purely internal?\n- Does this AI use a third-party model where the company is the deployer?\n- Is the use case in the elevated or high governance tier per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)?\n\nIf none of the above and the house trigger isn't met:\n> \"Doesn't look like this needs a full impact assessment. Here's a one-paragraph\n> record for the file explaining why — in case anyone asks later.\"\n\n---\n\n## Step 1: Risk track\n\nBefore intake, determine which track to run. The tier definitions and the fast-track criteria come from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) (`## Use case registry` and `## Governance tiers`), not from any hardcoded regime-specific framework.\n\nResearch the applicable risk classification framework for each regime in the user's regulatory footprint. Many regimes distinguish by risk tier, affected population, and decision consequentiality — research the specific criteria. Note that most regimes treat employee data as personal data and employee monitoring as consequential; don't assume internal-only systems are out of scope.\n\n> **No silent supplement.** If a research query to the configured legal research tool (Westlaw, EUR-Lex, regulator sites, or firm platform) returns few or no results for a regime's risk tiers or triggers, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / topic]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against the issuing authority before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution tiering.** Tag every citation in the AIA — regulatory text, delegated acts, guidance, standards — with its source. For model-knowledge citations, use one of three tiers rather than a single blanket \"verify\" tag:\n>\n> - `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., GDPR Art. 22 as a concept, the existence of Regulation (EU) 2024/1689 as the EU AI Act). Still verify before certifying, but lower priority.\n> - `[verify]` — model-knowledge citations that are real but should be verified: specific delegated / implementing acts, regulator guidance, NYC DCWP rules, Colorado AI Act provisions, harmonized standards, effective dates, EEOC guidance, and anything post-2023.\n> - `[verify-pinpoint]` — pinpoint citations (specific EU AI Act article numbers, annex references, Colorado AI Act subsections, NYC LL 144 rule sections, sub-paragraph letters) carry the highest fabrication risk and should ALWAYS be verified against a primary source. EU AI Act article numbers in particular shifted during consolidation; every pinpoint cite to the Act should be verified against the Official Journal text.\n>\n> Tool-retrieved citations keep their source tag (`[Westlaw]`, `[EUR-Lex]`, `[regulator site]`, or the MCP tool name); web-search citations remain `[web search — verify]`; user-supplied citations remain `[user provided]`. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n>\n> **For non-lawyer users, uncertain dates go in a confirm-list, not inline.** A `[verify]` tag on \"effective February 1, 2026\" reads as \"effective February 1, 2026\" to a CISO who doesn't know what `[verify]` means. Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If Role is **Non-lawyer** and a date, deadline, phase-in, threshold, or effective-date assertion is uncertain (would carry `[verify]` or `[verify-pinpoint]` if inline), replace the inline assertion with \"effective date: confirm with counsel\" (or \"threshold: confirm with counsel\", etc.) and collect all uncertain assertions in a final AIA section titled:\n>\n> > **Things I'm not certain about — ask your attorney to confirm before relying on this:**\n>\n> List each uncertain item there with (1) what I said, (2) what I'm uncertain about, (3) why it matters to the assessment. This prevents a non-lawyer reader from mistaking a flagged best-guess for a checked fact. Lawyer-role users get the inline `[verify]` treatment — they know what the tag means.\n\n**Fast track vs. full assessment:** your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) defines what qualifies for abbreviated treatment. If your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) doesn't define fast-track criteria, default to full assessment and ask the user what criteria they want captured for next time.\n\nIf in doubt, run the full assessment. A fast track that turns out to be wrong\nis worse than a thorough assessment on something low-risk.\n\n---\n\n## Step 2: Intake\n\nBefore writing anything, get answers to these. Conversational is fine — this\nis not a form to send them.\n\n### The system\n\n- What does the AI do? Describe it in plain language, not marketing copy.\n- Which model or vendor is powering it? Fine-tuned or off-the-shelf?\n- Where does it sit in the workflow — is it assistive (human reviews output),\n augmentative (human can override but usually doesn't), or automated (no human\n in the loop)?\n- What's the output — generated text, a score, a classification, a recommendation,\n an action?\n\n### Who's affected\n\n- Who does the AI's output act on — employees, customers, third parties?\n- If the AI produces an error (false positive, false negative, hallucination), who\n bears the harm and what's the worst realistic case?\n- Are any vulnerable groups disproportionately in scope — minors, job applicants,\n people in financial distress, patients?\n\n### Inputs and data\n\n- What data does the AI take in?\n- Does it take in personal data? Whose?\n- Was the model trained on data from this company, or is it a foundation model\n with no company-specific training?\n- Where does input data go — does it leave the perimeter to a third-party model\n API?\n\n### Decisions and oversight\n\n- Does the AI output trigger an action automatically, or does a human decide what\n to do with the output?\n- If there's human review: how often does the human actually change the AI's output?\n (If the answer is \"rarely\" — the human isn't really reviewing; they're rubber-stamping.)\n- Is there an appeals or correction process for people affected by the AI's outputs?\n- Who is accountable for the AI system's outputs — is there a named owner?\n\n### Accuracy and failure\n\n- What's the known or estimated error rate? What testing has been done?\n- What happens when the AI is wrong — is the error surfaced, logged, corrected?\n- Has bias testing been done? Against what demographic groups?\n\n### Deployment stage and scale\n\nAsk:\n- **Stage:** \"Is this system (a) proposed and not yet built, (b) in pilot, (c) live in production, or (d) live and scaled?\"\n- **Scale:** \"Roughly how many individuals are affected per [month/year]? How long has it been running?\"\n- **History:** \"Has it been assessed before? Has it produced decisions that were challenged, appealed, or reversed?\"\n\nStage changes the assessment: a proposed system gets a design review (can we build it safely?). A pilot gets a design review plus a \"before you scale\" gate. A live system gets a retrospective impact check (has it caused harm?) AND a go-forward review. A live-and-scaled system gets all of the above plus a remediation plan if issues are found, because you can't just turn it off.\n\n---\n\n## Step 3: Regulatory classification\n\n**Step 3 pre-check — footprint freshness.** Before iterating over the captured `## Regulatory footprint`, compare the use case's affected population and decision type (from Step 2) against the footprint as written. The footprint was set at cold-start, based on the company's operating posture at that moment. If the use case introduces an affected population (e.g., children, employees in a new state, EU data subjects) or a decision type (e.g., hiring, creditworthiness, health diagnosis, law enforcement, critical infrastructure) that the footprint does not contemplate, **re-derive the applicable regimes rather than iterating over the stale list.**\n\nSay to the user:\n\n> \"The practice profile's regulatory footprint was set for [affected populations / decision types captured at cold-start]. This use case affects **[new population or decision type — e.g., employees in Colorado, minors under 13, credit decisions, biometric identification]**, which is not in the captured footprint. I'm going to re-derive the applicable regimes from the company's operating jurisdictions ([list from `## Company profile`]) and this use case's decision type ([Y]), rather than use the stale footprint. If this use case is representative of work you expect to see more of, update `## Regulatory footprint` at the end of this run so the next AIA doesn't have to re-derive.\"\n\nA common failure mode: the footprint lists EU AI Act + GDPR + NYC Local Law 144, and the use case is a hiring system being deployed into Illinois and Colorado. The footprint has no Illinois or Colorado entry, so iterating over it silently misses IL AIVIA, the new Colorado AI Act deployer obligations, and BIPA implications of any biometric component. Re-derive.\n\nA second failure mode: the footprint was set before a regime that now matters existed (or took effect). If re-derivation surfaces a regime not in the footprint, flag it in the output's recommendation section, cite the authority, and recommend updating the footprint.\n\nFor each regime in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Regulatory footprint` that applies to this system — **plus any regime surfaced by the re-derivation above** — research the currently operative risk classification framework and determine where the system lands.\n\nResearch tasks:\n- What is the regime's own tier taxonomy (e.g., prohibited / high-risk / limited / minimal, or the regime's equivalent)?\n- What are the criteria for each tier? Cite primary sources with pinpoint references.\n- Which tier does this system fall into given its function, affected parties, and decision consequentiality?\n- Are there prohibited practices the system might touch? Treat any possible match as critical — flag immediately.\n- Are there transparency obligations that apply regardless of tier (disclosure that a user is interacting with AI, labeling of AI-generated content, notice to people subject to automated decisions)?\n- If the company is a builder providing a general-purpose or foundation model, what provider-level obligations apply (technical documentation, training data transparency, copyright compliance, systemic-risk testing)?\n- **Does any regime in the footprint require a separate fundamental-rights impact assessment (FRIA)?** EU AI Act Art. 27 requires a FRIA for certain deployers of high-risk AI systems (public bodies and private entities providing public services, plus certain creditworthiness and insurance-risk-assessment use cases). Check each regime for an equivalent fundamental-rights or human-rights impact assessment that is a distinct deliverable from this AIA. If a FRIA (or regime equivalent) is required, flag it as a separate deliverable in the recommendation and conditions — do not treat this AIA as a substitute.\n\nDon't assume internal-only systems are out of scope — most regimes treat employee data as personal data and employee monitoring as consequential. Verify the specific rule.\n\n**Provider-vs-deployer split (when `AI role: Both`).** If your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Company profile` → `AI role` is `Both` (the company is both a provider/builder and a deployer), Section 6 MUST include a provider-vs-deployer mapping table per regime. Most regimes impose materially different obligations on providers (or builders) versus deployers (or users) — collapsing them into one undifferentiated list misses obligations and conflates risks. Do not combine provider and deployer obligations into a single section. Produce, per regime:\n\n| Obligation | As provider | As deployer |\n|---|---|---|\n| [specific obligation, pinpoint cite] | [what applies / does not apply / with what carve-outs] | [what applies / does not apply / with what carve-outs] |\n\n**If a high-risk or equivalent classification applies:**\nFlag in the assessment, citing the specific provision and regime. Note that this AIA documents the internal review but does not substitute for any formal conformity assessment the regime requires. Recommend external legal review before deployment in the affected jurisdiction.\n\nCapture the classification and the cited authority in the assessment output.\n\n---\n\n## Step 4: Write the assessment\n\n**Use the seed structure from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If none was captured, use this default:\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# AI Impact Assessment: [System/Feature Name]\n\n**Prepared by:** [name] | **Date:** [date] | **Status:** DRAFT / APPROVED\n**System owner:** [name] | **AI governance reviewer:** [name]\n**Governance tier:** [Standard / Elevated / High]\n**Track:** [Fast track / Full assessment]\n\n---\n\n## Executive summary\n\n[Two sentences: what this AI does and whether it's okay to deploy. E.g., \"This\nsystem uses a third-party LLM to draft initial responses to customer support tickets\nbefore human agent review. Processing is consistent with the company's AI policy;\nthree conditions required before production deployment.\"]\n\n**Overall risk:** 🟢 Low / 🟡 Medium / 🟠 High / 🔴 Very high\n\n---\n\n## 1. System description\n\n**What it does:** [plain English — not marketing]\n**Model / vendor:** [who's providing the AI]\n**Deployment mode:** [Assistive / Augmentative / Automated]\n**Output type:** [text / score / classification / recommendation / action]\n**Status:** [Not started / Pilot / Production]\n\n---\n\n## 2. Affected parties\n\n**Who it acts on:** [employees / customers / third parties]\n**Scale:** [how many people, how often]\n**Harm if wrong:** [most realistic worst case — specific, not generic]\n**Vulnerable groups in scope:** [yes — [who] / no]\n\n---\n\n## 3. Data inputs\n\n**Data categories used:** [specific fields, not \"user data\"]\n**Personal data:** [yes — [whose] / no]\n**Data leaves perimeter?** [yes — to [vendor] / no]\n**Model training:** [company data used / foundation model / fine-tuned on [dataset]]\n\n---\n\n## 4. Decision-making and oversight\n\n**Human in the loop:** [Always / Nominally (rubber-stamp risk) / No]\n**Override mechanism:** [how a human can intervene or correct]\n**Appeals / correction for affected parties:** [yes — [how] / no]\n**Named owner:** [name or role]\n\n---\n\n## 5. Accuracy and bias\n\n**Error rate:** [known / estimated / untested]\n**Failure mode:** [what happens when it's wrong — surfaced? logged? corrected?]\n**Bias testing:** [done — [results] / not done / not applicable]\n\n---\n\n## 6. Regulatory classification\n\n*[One subsection per regime in the regulatory footprint that applies to this system.]*\n\n**Regime:** [name]\n**Classification under this regime:** [tier, with pinpoint citation to the controlling provision]\n**Prohibited practices triggered:** [none identified / [specific provision and why]]\n**Applicable obligations:** [researched list with citations — transparency, documentation, human oversight, testing, registration, etc.]\n**Fundamental-rights impact assessment required?** [Yes — e.g., EU AI Act Art. 27 FRIA applies / regime equivalent / No / Not applicable. If yes, this is a separate deliverable, not subsumed by this AIA.]\n**Effective / enforcement date:** [date(s)]\n**Ambiguity or open interpretation:** [flag anything not yet settled]\n\n**Provider-vs-deployer obligation split (required if `AI role: Both`):**\n\n| Obligation | As provider | As deployer |\n|---|---|---|\n| [specific obligation + pinpoint cite] | [what applies / does not apply] | [what applies / does not apply] |\n\n---\n\n## 7. AI policy consistency\n\n| Policy commitment | Consistent? | Notes |\n|---|---|---|\n| [commitment from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) AI policy section] | 🟢 / 🟡 / 🟠 / 🔴 | |\n\n[If any item is 🟡 or worse: policy update needed before deployment, or design needs to change.\nOne of them has to change — not both flagged and left open.]\n\n---\n\n## 8. Risks and mitigations\n\n| # | Risk | Likelihood | Impact | Mitigation | Status | Owner |\n|---|---|---|---|---|---|---|\n| 1 | [specific risk tied to this design — not \"AI hallucination\" generically] | L/M/H | L/M/H | [specific control] | Done / Planned / Gap | [name] |\n\n**Residual risk after mitigations:** [assessment]\n\n---\n\n## 9. Recommendation\n\n**[APPROVED / APPROVED WITH CONDITIONS / CHANGES REQUIRED / NOT APPROVED]**\n\n**Conditions (if any):**\n- [ ] [specific action before deployment — owner, deadline]\n\n**Privacy review required?** [Yes — run `the “PIA Generation” workflow`, if the plugin is installed /\nNo]\n\n**Sign-off:** [name, date]\n\n---\n\n## Cite check\n\nRegulatory citations in Section 6 (and anywhere else) were generated by an AI model and have not been verified against primary sources. Before the assessment is certified or relied on, run a verification pass against a legal research tool (Westlaw, EUR-Lex, or your firm's platform) for each cited provision — confirm the pinpoint, currency, and any delegated or implementing acts. The AI regulatory landscape shifts quickly; verify before advising. Source tags on each citation (e.g., `[EUR-Lex]`, `[web search — verify]`) show where it came from; `verify` tags carry higher fabrication risk and should be checked first.\n```\n\n**Before certifying the AIA (the Sign-off step, marking Status: APPROVED):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Certifying this AIA has legal consequences — it becomes the record the company relies on if a regulator or affected party asks how this use case was assessed. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the system, the regulatory classification, the risks identified, the mitigations in place, residual risk, open questions, what to ask the attorney before certifying.]\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes. DRAFT assessments for attorney review do not require the gate — certification does.\n\n---\n\n## Risk quality standards\n\nSame standard as the PIA skill — risks must be **specific and tied to the design**.\n\n| Bad risk | Why bad | Better |\n|---|---|---|\n| \"AI hallucination\" | Applies to every LLM; says nothing | \"Model may generate plausible but incorrect legal citations — support agents have no current verification step before sending to customers\" |\n| \"Bias\" | Too vague | \"Résumé scoring model trained on historical hires; if historical cohort was demographically homogeneous, underrepresented candidates may be systematically scored lower\" |\n| \"Vendor risk\" | Circular | \"OpenAI's terms permit training on API inputs by default; unless the opt-out is confirmed in the agreement, customer support messages may be used to train the model\" |\n\nAim for 2-5 real risks, not 12 padded ones.\n\n---\n\n## AI policy diff\n\nEvery assessment should cross-check against the AI policy commitments in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\nCommon drift:\n\n- Policy prohibits AI use in [category] — this use case is that category. Stop.\n- Policy requires human review — this deployment has no human step. Design needs to change.\n- Policy requires disclosure to affected parties — disclosure mechanism hasn't been built.\n- Approved vendor list exists — this vendor isn't on it. Procurement step required.\n\nFlag every mismatch. One of them has to change before deployment.\n\n---\n\n## Handoffs\n\n- **To product / engineering:** Conditions list with owners and deadlines. Not\n \"add oversight\" — \"add a human review step before any automated email is sent,\n owner: [product lead], before launch.\"\n- **To privacy:** If personal data is involved, flag: \"Run `the “PIA Generation” workflow [system name]` in parallel, if the plugin is installed — the AIA doesn't substitute for a PIA.\"\n- **To vendor-ai-review:** If a new vendor is involved, flag: \"If there's no AI addendum reviewed for [vendor], run `the “Vendor Ai Review” workflow` before production.\"\n- **To reg-gap-analysis:** If new regulatory obligations emerged (EU AI Act high-risk, new sector rule), that skill tracks the gap.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't approve the deployment. A human signs the assessment.\n- It doesn't constitute any regulatory conformity assessment — where a regime (e.g., EU AI Act) requires a formal conformity assessment, that is a separate exercise requiring external legal review and technical documentation beyond what's here.\n- It doesn't design the mitigations. It describes what needs mitigating; engineering\n designs the fix.\n- It doesn't substitute for a PIA when personal data is involved. Run both.", + }, + { + id: "builtin-cfl-aigov-policy-starter", + title: "Policy Starter", + practice: "AI Governance", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “policy-starter” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /policy-starter\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the practice profile is unpopulated, stop and direct to `configure your Practice Profile (Account → Practice Profile)`.\n2. Use the framework below.\n3. Run the scope interview — which sections does the policy need to cover, who's the audience, what's the deployment context. Do not skip to drafting.\n4. Web search for the current published model policies and guidance relevant to the deployment context (ABA, state bars, ILTA, CLOC, NIST, peer-firm / peer-company policies, current state AI laws, EU AI Act, sector regulators as applicable).\n5. Draft the selected sections, sourced from the model policies, with `[review]` flags on every choice point and `[review]` open questions at the bottom of each section.\n6. Output with the draft header (\"DRAFT FOR INTERNAL LEGAL REVIEW — NOT FOR DISTRIBUTION\"), the sources block, the reviewer note, and the adoption checklist.\n7. Close with the next-steps decision tree.\n\n```\nthe “Policy Starter” workflow\nthe “Policy Starter” workflow \"we need an AI policy for our 30-lawyer firm\"\nthe “Policy Starter” workflow \"update our existing policy for the 2026 state AI laws\"\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nA lot of firms and in-house teams don't have a written AI usage policy yet, or\nare running on a 2024-vintage one that doesn't mention the state AI laws, the EU\nAI Act implementing acts, the 2025 COPPA amendments, or what they actually ended\nup doing with Copilot and Claude for Work. This skill produces a **draft** policy\nto bring to the decision-maker — GC, managing partner, executive committee,\nboard, head of IT, head of HR — not a finished policy to circulate.\n\nThe discipline of this skill:\n\n1. **Source from published model policies, not from invention.** Search for and\n read the ABA AI Toolkit, state bar guidance, ILTA's model policy, CLOC's\n templates, and peer-firm / peer-company policies that are public. Cite what\n each source says and adapt it — don't generate policy language out of thin\n air.\n2. **Decision-tree the scope before drafting.** A policy that tries to cover\n everything covers nothing. Ask the user what sections the policy needs. Let\n them pick. Then build each picked section with `[review]` flags on every\n choice point.\n3. **Flag every judgment call.** The output is a draft the attorney reviews and\n adopts; every threshold, every named tool, every disclosure trigger, every\n enforcement consequence is a `[review]` line.\n4. **Header signals the scope of the audience.** This output may be read beyond\n legal — by HR, IT, all staff. The header is adapted accordingly.\n\nThis skill does NOT finalize, distribute, publish, or even recommend a specific\nposition on the hard calls. It produces a draft and surfaces the choices.\n\n## Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) first\n\nBefore drafting, always read the practice profile. The sections that drive the\ndraft:\n\n- `## Company profile` — AI role (Builder / Deployer / Both), regulatory footprint,\n external commitments, practice setting\n- `## Use case registry` — what's already approved, conditional, or a red line\n- `## AI policy commitments` — what a prior or current policy already says\n- `## Vendor AI governance` — what the team already requires from vendors\n- `## Governance team and escalation` — who approves, who escalates\n- `## Who's using this` — Role (lawyer / non-lawyer) governs the header and the\n \"adopt this\" framing\n\nIf `## AI policy commitments` is populated, this is an UPDATE, not a new draft —\ntreat the existing policy as the base and propose changes. If it's empty, this\nis a first-cut draft.\n\n## Scope interview (do this BEFORE drafting)\n\nAsk the user which sections the policy should cover. Present as a checklist —\nthe user picks, you build. Do not pre-decide.\n\n> **What should the AI policy cover? Pick the sections you want in the draft:**\n> 1. **Scope** — who the policy applies to (all staff, certain roles, contractors), what tools it covers (GenAI only, all AI, specific vendors), what data is in/out of scope.\n> 2. **Permitted and prohibited uses** — the approved categories, the red lines, the \"ask first\" cases.\n> 3. **Approval and review** — who approves a new tool, who approves a new use case, how the review request is filed, what the SLA is.\n> 4. **Disclosure** — to clients (for firms), to courts, to counterparties, to employees, to end users of an AI feature.\n> 5. **Data handling** — what confidential/client/privileged data can go where, data residency, vendor retention terms, training-on-data posture.\n> 6. **Training and certification** — who has to take training, on what cadence, consequences for non-completion.\n> 7. **Incidents and reporting** — what counts as an AI incident, how to report, who handles.\n> 8. **Enforcement** — what happens when the policy is violated, link to disciplinary framework.\n> 9. **Review cadence and ownership** — how often the policy gets updated, who owns updates, how changes are communicated.\n> 10. **Glossary** — defined terms (GenAI, approved tool, high-risk use, consequential decision, confidential data, etc.).\n>\n> Default starter pack for a firm / in-house legal team that's never had a policy: 1, 2, 3, 4, 5, 9. Skip the rest for v1.\n\nAfter the user picks, ask the second question:\n\n> **Two more inputs before I draft:**\n> - **Audience** — who's reading this? (All staff / legal team only / attorneys plus staff / client-facing version also needed) This drives tone and the glossary.\n> - **Deployment context** — (a) law firm, (b) in-house legal at a company (policy covers legal or company-wide?), (c) legal aid / clinic, (d) government. This drives which model policies I search.\n\n## Source the model policies\n\nBefore drafting, run web searches for the most recent published model AI\npolicies and guidance.\n\n**Derive the model policy sources from the practice profile's `## Regulatory footprint`.** Don't hardcode US sources for a global user.\n\n| Jurisdiction | Model policy sources |\n|---|---|\n| US | ABA Formal Opinion 512, state bar guidance (CA, FL, NY, TX all have published AI guidance), ILTA model policy, CLOC templates, peer firm published AI policies |\n| UK | Solicitors Regulation Authority risk outlook, Law Society AI principles, ICO AI guidance, Bar Council guidance |\n| EU | EU AI Act compliance framework (Article 4 AI literacy, Article 17 quality management), national DPA AI guidance (CNIL, DSB, Garante, AEPD), EDPB guidelines, EU institutions' AI policies |\n| Australia | Law Council of Australia AI guidelines, OAIC AI guidance, state law society guidance, Australian AI Ethics Framework |\n| Singapore | PDPC Model AI Governance Framework, MinLaw guidance, MAS AI fairness principles (for financial services) |\n| Canada | Law Society of Ontario/BC/Alberta AI guidance, OPC AI guidance, TBS Directive on Automated Decision-Making |\n| Multi-jurisdiction | Use all applicable, and note where they diverge (e.g., EU requires human oversight documentation US doesn't; Australia focuses on voluntary ethics frameworks; Singapore focuses on sectoral regulation) |\n\nIf the practice profile's footprint is empty or `[PLACEHOLDER]`, ask: \"What jurisdiction(s) does your organization operate in? I'll draft from the model policies that match your regulatory environment and professional responsibility framework, not a US-centric template.\"\n\nFor each source the draft uses, **record it in a \"Sources\" block at the top of\nthe output** with: name, URL, date accessed, and what the draft took from it.\n\nIf a web search can't be run, note in the reviewer note: \"Could not run web\nsearch — draft sourced from training knowledge alone, verify against current\nversions of the cited sources before adopting.\" The verification log applies.\n\n## The draft\n\nOutput follows a consistent structure. **Every choice point gets a `[review]`\nflag.** The user has to decide; the skill presents options.\n\n### Header\n\n```\nDRAFT FOR INTERNAL LEGAL REVIEW — NOT FOR DISTRIBUTION\nPrepared for: [firm / company name from practice profile]\nDate: [today's date]\nPrepared by: ai-governance-legal policy-starter skill, adapted from published model policies\nNot for adoption, distribution, posting, or reliance until reviewed, adapted, and approved by [attorney / GC / managing partner / executive committee per the governance team section of the practice profile].\n```\n\nWhen the Role in `## Who's using this` is Non-lawyer: add a second line under\nthe header — \"If you are not a licensed attorney, solicitor, barrister, or other\nauthorised legal professional in your jurisdiction, bring this draft to your\nattorney contact ([name from practice profile]) before using any of it. This is\na starting draft for their review, not a policy you can adopt.\"\n\n### Sources block (at the top, under the header)\n\nA table of the model policies / guidance / regulations the draft drew from:\n\n| Source | URL | Accessed | What the draft took from it |\n|---|---|---|---|\n| ABA Formal Op. 512 | [url] | [date] | Disclosure and competence framing |\n| ILTA Model AI Policy v.[X] | [url] | [date] | Approval workflow, data handling |\n| [State] Bar Op. [X] | [url] | [date] | Disclosure to clients |\n| [peer firm] published AI policy | [url] | [date] | Scope language |\n| Colorado SB 24-205 | [url] | [date] | High-risk AI definition |\n| EU AI Act, Art. [X] | [url] | [date] | Vendor flow-down |\n\n### Executive summary\n\nThree paragraphs max. What the policy does, who it binds, what the reader has\nto do before it takes effect.\n\n### The sections\n\nOnly the sections the user picked, in the order above. For each:\n\n- A **header and scope** sentence.\n- The **substantive rules**, adapted from the cited model policies. Every\n specific threshold, number, named tool, named vendor, or escalation contact\n is `[review]`. Example: \"Confidential client data may not be entered into\n [general-purpose consumer AI tools] `[review — list tools, or reference the\n approved-tools list]`. Use of such data in [approved firm-licensed tools]\n `[review — list tools]` is permitted subject to the data handling section.\"\n- **Source attribution** inline where a rule is adapted from a specific source.\n Example: \"Attorneys must verify the accuracy of all AI-generated work product\n before using it in representation of a client `[ABA Formal Op. 512]`.\"\n- **Open questions** at the bottom of each section — 2-3 decisions the attorney\n needs to make before the section is ready. These are distinct from inline\n `[review]` flags — these are the \"we don't have a position here yet\" items,\n not the \"fill in the specifics\" items.\n\n### Adoption checklist\n\nAt the end of the draft, a checklist of the things that have to happen before\nthe policy is adopted. Don't invent these — pull from the practice profile's\ngovernance team and escalation section. Typical items:\n\n- [ ] Review by GC / managing partner `[review — name]`\n- [ ] Review by IT / security `[review — name]`\n- [ ] Review by HR (for enforcement / training sections) `[review — name]`\n- [ ] Board / executive committee approval (if required) `[review — confirm whether required]`\n- [ ] Training materials drafted\n- [ ] Announcement drafted\n- [ ] Effective date set `[review]`\n- [ ] Review cadence calendared `[review — annual is typical]`\n- [ ] Add policy to the `## AI policy commitments` section of the practice\n profile once adopted\n\n### Reviewer note\n\nThe standard reviewer note above the header, per the `## Outputs` section of\nthe practice profile. Use the block format:\n\n> **⚠️ Reviewer note**\n> - **Sources:** web search ✓ / not connected — cites from training knowledge\n> - **Read:** practice profile · [N] published model policies\n> - **Flagged for your judgment:** [N] `[review]` items inline · [N] open questions per section\n> - **Currency:** searched for developments since [date]\n> - **Before relying:** this is a DRAFT — bring to [approver from practice profile], don't distribute until adopted\n\n## Don'ts\n\n- **Don't invent policy language.** Every substantive rule in the draft must be\n traceable to a cited source or flagged `[review — adapted, no direct source]`.\n- **Don't pick the hard calls for the attorney.** \"Should paralegals be\n permitted to use AI for first-draft work?\" is a `[review]`, not a recommended\n position.\n- **Don't produce a finished-looking policy.** The header, the reviewer note,\n and the `[review]` flags throughout are the signal that this is a draft. Do\n not soften them.\n- **Don't skip the scope interview.** If the user says \"just draft a full\n policy,\" push back: \"A policy that tries to cover everything covers nothing.\n Which sections do you want? Here's the checklist.\" One round of negotiation\n is fine — two is also fine. Drafting without scope is the failure mode.\n- **Don't generate section content the user didn't ask for.** If they picked 1,\n 2, 3, 4, 5, 9, do those. Don't add section 6 because \"a real policy needs\n training.\"\n- **Don't recommend a specific vendor, tool, or consequence.** Flag those\n `[review]` with context on what a typical decision would be, not what the\n user's should be.\n- **Don't promise legal sufficiency.** The draft is a starting point for\n attorney review, not a tested policy.\n\n## Handoffs\n\nAfter the draft is produced, close with the decision tree from the practice\nprofile. The most common next steps:\n\n1. **Tune the draft** — the user walks through the `[review]` flags and resolves\n them with the attorney; the skill re-runs with the decisions baked in.\n2. **Stakeholder summary** — produce a one-page version for the board or\n executive committee explaining what the policy does and doesn't do.\n3. **Training materials** — once the policy is adopted, `the “AIA Generation” workflow` can be used to produce per-use-case training notes.\n4. **Vendor sweep** — once the policy is adopted, `the “Vendor Ai Review” workflow` should be run against the vendors the policy references to check conformance.\n5. **Gap check against new regulation** — pair with `the “Reg Gap Analysis” workflow` to test the draft against a specific regulation or guidance before adoption.\n\n## Output scope reminder\n\nThe document this skill produces reaches HR, IT, and the broader business — not\njust legal. Keep the language plain enough for non-lawyers to follow. The legal\nprecision is in the `[review]` flags and the sources, not in jargon.", + }, + { + id: "builtin-cfl-aigov-reg-gap-analysis", + title: "Reg Gap Analysis", + practice: "AI Governance", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “reg-gap-analysis” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /reg-gap-analysis\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Confirm regulatory footprint and use case registry are populated.\n2. Use the framework below.\n3. Scope: does this regulation apply? (Jurisdiction, threshold, builder/deployer, sector.) If not, one line and done.\n4. Extract requirements. Diff against current state in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n5. Prioritize gaps. Output: remediation plan with must-do / should-do / already compliant / accepted gaps.\n6. Save as dated markdown doc for the file.\n\n```\nthe “Reg Gap Analysis” workflow \"EU AI Act high-risk provisions\"\n```\n\n---\n\n## Purpose\n\nThe EU AI Act goes live. Colorado passes an AI law. The CFPB issues model risk\nguidance. The FTC publishes an AI enforcement policy. Something moves — and now\nyou need to know what, if anything, you have to change.\n\nThis skill diffs the new requirement against your current AI governance posture\n(per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — use case registry, vendor positions, impact assessment practices,\nand AI policy commitments) and produces a gap list with a remediation plan.\n\nThe AI regulatory landscape is moving faster than any other area of law right now.\nWhen a regulation is genuinely ambiguous, say so. Don't paper over uncertainty —\nlegal teams need to know when they're on solid ground versus when they're making a\njudgment call.\n\n## Load current state\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n- `## Regulatory footprint` — what already applies\n- `## Use case registry` — what AI you're actually running, and under what conditions\n- `## AI policy commitments` — what you've publicly or contractually committed to\n- `## Vendor AI governance` — what vendor positions are in place\n- `## Impact assessment house style` — what assessment practices exist\n\nIf the regulation clearly doesn't apply (wrong jurisdiction, below threshold,\nwrong sector, builder/deployer distinction eliminates you from scope), say so\ndirectly: \"Doesn't apply. Here's why: [reason]. No action needed.\"\n\n---\n\n## Research first, then workflow\n\nBefore running the gap analysis, research the currently operative AI regulatory regimes for the jurisdictions in the user's footprint. For each regime identify:\n\n- **Scope** — who's covered (provider/builder vs. deployer vs. distributor vs. user; sectoral carve-outs).\n- **Applicability thresholds** — revenue, user count, headcount, compute, model category, affected-population size.\n- **Risk-tier definitions** — how the regime distinguishes tiers (prohibited / high-risk / limited-risk / minimal), what's in each.\n- **Substantive obligations** — transparency, documentation, human oversight, bias testing, registration, incident reporting, vendor flow-down.\n- **Enforcement mechanism** — which regulator, what penalties, any private right of action.\n- **Effective dates** — many AI laws phase in obligations over 2-4 years; note which obligations are live vs. upcoming.\n\nCite the regulatory text with pinpoint references. Flag provisions subject to ongoing interpretation, delegated acts, or pending rulemaking. The AI regulatory landscape changes quickly — verify currency before advising.\n\nBuild the gap analysis from the researched requirements, not from hardcoded reference tables.\n\n## Workflow\n\n### Step 1: Scope the regulation\n\nBefore diffing, answer:\n\n- **Does it apply?** Jurisdiction, threshold, sector carve-outs, builder vs. deployer distinction. Research the specific scoping rules in the regulation — don't assume.\n\n *Builder/deployer matters a lot here.* Many AI regimes impose different obligations on the entity that develops/provides the AI system versus the entity that deploys/uses it. Research which role the company occupies under each regime's definitions. Scope first; don't gap-analyze a law that doesn't apply.\n\n- **When?** Effective date. Enforcement date (often different). Phase-in periods for specific provisions. Verify currency.\n\n- **What's actually new?** Some \"new\" AI laws largely restate existing legal principles (consumer protection, anti-discrimination, sectoral risk management) applied to AI. Others are genuinely new obligations. Identify the delta from what you already do, not the full text of the law.\n\n### Step 2: Extract requirements\n\nRead the regulation, guidance, or summary. List every substantive requirement:\n\n| # | Requirement | Citation | Category |\n|---|---|---|---|\n| 1 | [requirement] | [section] | [see categories below] |\n\n**Categories:**\n- **Transparency** — disclosures to users, employees, or affected parties about AI use\n- **Impact assessment** — required documentation before deployment\n- **Human oversight** — mandatory human review, override, or appeals mechanisms\n- **Accuracy / testing** — bias testing, accuracy documentation, validation\n- **Governance** — registration, record-keeping, designated responsible persons\n- **Vendor flow-down** — obligations to pass down to AI vendors or pass up from AI vendors\n- **Prohibited practices** — outright bans on specific AI capabilities or uses\n- **Rights** — what affected parties can request or invoke\n\n### Step 3: Diff against current state\n\nFor each requirement:\n\n```markdown\n### [Requirement #N]: [short name]\n\n**Regulation says:** [requirement, quoted or paraphrased]\n\n**We currently:** [what your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) / AI policy / use case registry / assessment\npractice shows]\n\n**Gap:** [None | Partial | Full]\n\n**If partial/full — what's missing:** [specific — not \"more documentation\" but\n\"no human review step is documented for [use case category]\"]\n\n**Effort to close:** [Policy update only | Process change | Product/system change |\nNew assessment required | Vendor renegotiation | Registration / filing]\n\n**Risk of non-compliance:** [penalty range, enforcement likelihood, reputational]\n```\n\n### Step 4: Prioritize\n\nNot every gap is equal. Sort by:\n\n1. **Hard deadline with teeth** — effective date + active enforcement + real penalties\n2. **Prohibited practice** — if the gap is a prohibition, not a process requirement,\n that's the first priority regardless of enforcement date\n3. **Effort-to-impact ratio** — updating policy language is cheap; adding human\n oversight to a deployed system is not\n4. **Use case overlap** — gaps that affect multiple use cases in the registry are\n higher priority than single-use-case gaps\n\n### Step 5: Remediation plan\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Remediation Plan: [Regulation name]\n\n**Effective date:** [date]\n**Enforcement begins:** [date if different]\n**Applies to us as:** [Builder / Deployer / Both]\n\n### Must-do before enforcement\n\n| Gap | Fix | Owner | Due | Status |\n|---|---|---|---|---|\n| [gap] | [specific fix] | [name] | [date] | [ ] |\n\n### Should-do (important but not blocking enforcement)\n\n[same table]\n\n### Already compliant\n\n[list of requirements where gap = None — useful context for the legal/executive\nsummary of where you actually stand]\n\n### Accepted gaps (risk accepted, not fixing)\n\n[if any — with documented rationale and who accepted the risk. Documenting accepted\nrisk is better governance than leaving it unaddressed silently.]\n```\n\n---\n\n## Research the regulation before building the gap analysis\n\nDo not rely on hardcoded reference tables for specific regimes. For each regulation in scope, research the currently operative text:\n\n- Which obligations apply to the company's role (provider/builder, deployer, importer, distributor)?\n- Which tier does the system fall into under the regime's own classification (prohibited / high-risk / limited-risk / minimal, or the regime's equivalent)?\n- What are the live vs. phase-in dates for each obligation?\n- Are there delegated acts, implementing acts, or regulator guidance that affect interpretation?\n- For builder contexts: are there model-level obligations (technical documentation, training data transparency, copyright compliance, systemic-risk testing)?\n- For prohibited-practice categories: check any use case in the registry that might touch them and flag as critical regardless of enforcement date.\n\nCite primary sources with pinpoint references. Flag ambiguity for attorney judgment.\n\n> **No silent supplement.** If a research query to the configured legal research tool (Westlaw, EUR-Lex, regulator sites, or firm platform) returns few or no results for a regime's text, delegated act, or guidance, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / topic]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against the issuing authority before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution tiering.** Tag every citation in the gap analysis with its source. For model-knowledge citations, use one of three tiers rather than a single blanket \"verify\" tag:\n>\n> - `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., GDPR Art. 22, the existence of Regulation (EU) 2024/1689 as the EU AI Act, Colorado AI Act as C.R.S. § 6-1-1701 et seq.). Still verify before filing, but lower priority.\n> - `[verify]` — model-knowledge citations that are real but should be verified: specific delegated / implementing acts, regulator guidance, standards, enforcement actions, case holdings, thresholds, effective dates, phase-in provisions, harmonized-standards references.\n> - `[verify-pinpoint]` — pinpoint citations (specific article numbers, annex references, subsection letters, paragraph numbers, standard-clause references) carry the highest fabrication risk and should ALWAYS be verified against a primary source. EU AI Act article numbers in particular shifted during consolidation; every pinpoint cite to the Act should be verified against the Official Journal text.\n>\n> Tool-retrieved citations keep their source tag (`[Westlaw]`, `[EUR-Lex]`, `[regulator site]`, or the MCP tool name); web-search citations remain `[web search — verify]`; user-supplied citations remain `[user provided]`. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n>\n> **For non-lawyer users, uncertain dates, thresholds, and phase-in provisions go in a confirm-list, not inline.** A `[verify]` tag on \"effective February 1, 2026\" reads as \"effective February 1, 2026\" to a non-lawyer who doesn't know what the tag means. Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If Role is **Non-lawyer** and a date, deadline, phase-in, threshold, or effective-date assertion is uncertain (would carry `[verify]` or `[verify-pinpoint]` if inline), replace the inline assertion with \"effective date: confirm with counsel\" (or \"threshold: confirm with counsel\") and collect all uncertain items in a final gap-analysis section titled: \"**Things I'm not certain about — ask your attorney to confirm before relying on this:**\" with each item listed (what I said, what's uncertain, why it matters to the gap). Lawyer-role users keep the inline `[verify]` treatment.\n\n---\n\n## Integration with other skills\n\n**From aia-generation:** AIAs flag regulatory obligations for specific\nsystems → those feed here when a regulation is new or coverage is uncertain.\n\n**From use case triage:** Newly triaged use cases that hit regulatory triggers →\ngap analysis runs on the specific requirement for that use case type.\n\n**To regulatory-legal plugin, if the plugin is installed:** This skill is the manual\nversion. The monitor plugin watches feeds and triggers this analysis automatically\nwhen something relevant changes.\n\n---\n\n## Output\n\nSave as a dated markdown doc. The remediation plan table becomes a tracker — update\nstatus as items close.\n\nIf the gap analysis concludes \"no gaps, we're compliant,\" still write the doc. It's\nuseful evidence that you looked, and useful baseline when the regulation is amended.\n\n**Cite check before relying on this.** Citations here were generated by an AI model and have not been verified against primary sources. Before relying on any citation — statute, regulation, delegated act, guidance, or case — run a verification pass against a legal research tool (Westlaw, CourtListener, or your firm's platform) for accuracy, currency, and subsequent history. Fabricated or misquoted citations in filed materials have resulted in sanctions. Source tags on each citation (e.g., `[EUR-Lex]`, `[web search — verify]`) show where it came from; `verify` tags carry higher fabrication risk and should be checked first.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't interpret ambiguous regulatory language authoritatively. The EU AI Act\n in particular has significant interpretive questions that aren't resolved yet.\n When the reg is genuinely ambiguous: say so, state the conservative read, and\n flag for outside counsel if the issue is material.\n- It doesn't track regulatory changes proactively. It runs when you point it at a\n change. For proactive monitoring, see the `regulatory-legal` plugin, if the plugin is installed.\n- It doesn't implement fixes. It plans them.\n- It doesn't substitute for sector-specific legal counsel where specialized knowledge\n is required (healthcare AI, financial services model risk management, etc.).", + }, + { + id: "builtin-cfl-aigov-use-case-triage", + title: "Use Case Triage", + practice: "AI Governance", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “use-case-triage” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /use-case-triage\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Confirm registry is populated — if not, stop and direct to setup.\n2. Use the framework below. Clarify the use case if vague.\n3. Registry lookup → red line check → classify.\n4. Output: classification, reasoning, conditions table (if conditional), governance tier, cross-plugin handoffs.\n5. Propose registry update if use case wasn't already in the registry.\n\n```\nthe “Use Case Triage” workflow \"Sales team wants to score leads with AI automatically\"\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nStop the conversation that happens in a hallway and starts as \"can we just use AI\nfor this?\" Give a fast, calibrated answer from the registry — and if the answer\nis conditional, make the conditions concrete and the next step obvious.\n\nThe triage skill is a gateway, not a destination. Its job is to classify, flag\nwhat's required, and route. The aia-generation skill does the deep work.\n\n## Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) first\n\nBefore triaging, always read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). The use case registry and red lines there\nare authoritative. Generic AI ethics reasoning is not a substitute for what this\ncompany has actually decided.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) contains `[PLACEHOLDER]`, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor the use case registry, red lines, and governance tiers to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll triage tailored to YOUR practice.\n> - Say **\"provisional\"** and I'll triage against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" run triage normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction, no registry (classify by general AI governance principles rather than matching to a registered entry). Tag the reviewer note and every finding block with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your registry, your jurisdiction, your risk appetite. 2 minutes.\"\n\n**Jurisdictional scope.** Triage applies the registry, red lines, and governance tiers configured for the regulatory footprint in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). AI rules vary materially by jurisdiction — an APPROVED classification in one footprint may be CONDITIONAL or prohibited in another. If deployment touches a jurisdiction not in the footprint, surface that and re-triage rather than extending by analogy.\n\n---\n\n## Triage process\n\n### Step 1: Understand the use case\n\nBefore classifying, make sure you understand what's actually being proposed. If\nthe description is vague, ask:\n\n- \"What is the AI doing, exactly — generating content, making a decision, surfacing\n recommendations, automating a task?\"\n- \"Who or what is the AI acting on — employees, customers, third parties, internal\n data only?\"\n- \"Is a human reviewing the AI output before anything happens, or is it automated?\"\n- \"Which vendor or tool is being proposed?\"\n- \"Is this internal-only, or does it touch customers or other external parties?\"\n\nDon't let \"we want to use AI for [vague thing]\" go untriaged. Get specific enough\nto classify accurately.\n\n---\n\n### Step 2: Registry lookup\n\nCheck the use case registry in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for a direct or close match.\n\n**Direct match:** If the registry has a directly matching entry, apply it.\n\n**Near match:** If the use case is similar to a registry entry but not identical,\nflag this: \"This looks like [registered use case] — I'm applying that classification,\nbut if the scope is meaningfully different, it may need its own assessment.\"\n\n**No match:** If the use case isn't in the registry, default to CONDITIONAL pending an AI impact assessment. Surface the preliminary read on risk and route to the AIA.\n\n> \"This use case isn't in your registry yet. Defaulting to CONDITIONAL pending an\n> AI impact assessment. Here's my preliminary read on risk: [preliminary read].\n> Next step: run the impact assessment, and I'll add the use case to the registry\n> once classification is settled.\"\n\n---\n\n### Source attribution (applies whenever the triage cites regulation)\n\nTriage typically stays high-level, but if the classification depends on citing a regulation, statute, rule, directive, standard, or guidance — tag the citation. Do not output untagged regulatory citations in the triage reasoning, the red-line explanation, or the conditions list. A triage that says \"Art. 22(1)\" without a tag is exactly where a fabricated pinpoint slips past the reader.\n\n**Source attribution tiering.** For model-knowledge citations, use one of three tiers:\n\n- `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., GDPR Art. 22 as a concept, the existence of Regulation (EU) 2024/1689 as the EU AI Act). Still verify before certifying, but lower priority.\n- `[verify]` — model-knowledge citations that are real but should be verified: specific delegated / implementing acts, regulator guidance, standards, effective dates, thresholds, post-2023 amendments.\n- `[verify-pinpoint]` — pinpoint citations (specific article numbers, annex references, subsection letters, paragraph numbers) carry the highest fabrication risk and should ALWAYS be verified against a primary source. EU AI Act article numbers in particular shifted during consolidation; every pinpoint cite to the Act should be verified against the Official Journal text.\n\nOther sources keep their own tags: `[registry]` when drawn from the practice profile's use case registry; `[Westlaw]`, `[EUR-Lex]`, `[regulator site]`, or the MCP tool name when retrieved from a connected legal research tool; `[web search — verify]` for web-search citations; `[user provided]` for user-supplied citations. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n\n**For non-lawyer users, uncertain dates and thresholds go in a confirm-list, not inline.** A `[verify]` tag on \"effective February 1, 2026\" reads as \"effective February 1, 2026\" to someone who doesn't know what the tag means. Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If Role is **Non-lawyer** and an effective date, phase-in, threshold, or deadline is uncertain (would carry `[verify]` or `[verify-pinpoint]` if inline), replace the inline assertion with \"effective date: confirm with counsel\" (or \"threshold: confirm with counsel\") and collect all uncertain assertions in a final triage section titled: \"**Things I'm not certain about — ask your attorney to confirm before relying on this:**\" with each item listed (what I said, what's uncertain, why it matters). Lawyer-role users keep the inline `[verify]` treatment.\n\n---\n\n### Step 3: Red line check\n\nBefore going further, check the red lines in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\nIf the use case triggers a red line — even partially, even in a charitable reading —\nsay so immediately.\n\n> \"This use case touches [red line]. Your red lines treat this as an automatic no.\n> If there's something different about this situation, that's a conversation for\n> legal sign-off — not a triage call.\"\n\nDo not soften red line outcomes. If it's a no, it's a no.\n\n---\n\n**Jurisdictional scope.** Ask: \"Who's affected, and where are they? (Employees / customers / the general public / specific groups.) Which jurisdictions? (Not just where your company is — where the affected people are.)\"\n\nThen check the use case against EVERY regime in the practice profile's `## Regulatory footprint`, not just the primary one. Flag conflicts:\n- \"APPROVED under US law, but triggers EU AI Act Article 27 FRIA if EU residents are affected — confirm whether any affected individuals are in the EU.\"\n- \"Standard tier under your governance framework, but NYC LL144 requires a bias audit if used for hiring decisions affecting NYC residents.\"\n- \"Low risk under Australian AI Ethics Framework, but may be high-risk under the Colorado AI Act if Colorado residents are affected.\"\n\nA use case that crosses jurisdictions gets the strictest applicable treatment, not the most convenient one.\n\n---\n\n### Step 4: Classification and output\n\nThe APPROVED / CONDITIONAL / NOT APPROVED buckets, the red-line definitions, and the CONDITIONAL required-controls list all come from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## AI use case triage criteria` and `## Use case registry`. If the playbook doesn't define a criterion the use case turns on, ask the user: \"Your playbook doesn't cover [specific question]. What's your default position? I'll add it to your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) so the next triage is consistent.\"\n\n**Before issuing an APPROVED classification (approving an AI use case for deployment):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Approving this use case for deployment has legal consequences. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the use case and its scope, how it maps to the registry, what policies or red lines it touches, what could go wrong in deployment, what to ask the attorney before green-lighting.]\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes. CONDITIONAL outputs do not require the gate.\n\n**Before issuing a NOT APPROVED classification that cuts off a proposed use case:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer, a symmetric gate applies — wrongly rejecting a use case is also a consequential error, and the business will push back regardless of the triage call:\n\n> This is a full stop for a business ask. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the use case and its scope, the specific red line or registry entry that blocks it, what a narrower version could look like that might clear elevated tier (if anything), what the business will likely ask the attorney for, and the three questions to ask the attorney before accepting the no.]\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes. A non-lawyer issuing a hard no on the AI plugin's behalf, without an attorney in the loop, is the mirror failure of a non-lawyer issuing a hard yes.\n\n**Format for each triage output:**\n\n---\n\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n**USE CASE:** [State the use case as you understand it]\n\n**CLASSIFICATION:** [APPROVED / CONDITIONAL / NOT APPROVED]\n\n**Registry match:** [Direct match / Near match — [name] / No match]\n\n**Reasoning:**\n[1-3 sentences on why this classification. If approved, what makes it safe. If\nconditional, what creates the risk that conditions are managing. If not approved,\nwhat red line or policy position applies.]\n\n**Red lines triggered:** [None / List any that apply]\n\n---\n\n*If CONDITIONAL — required before proceeding:*\n\n| Requirement | Owner | Done? |\n|---|---|---|\n| [e.g., AI impact assessment] | [AI governance counsel] | ☐ |\n| [e.g., Privacy review / PIA] | [Privacy counsel] | ☐ |\n| [e.g., Human-in-the-loop requirement — no automated decisions] | [Product] | ☐ |\n| [e.g., Disclosure to affected parties] | [Product / Legal] | ☐ |\n| [e.g., Specific vendor only — [approved vendor name]] | [Procurement] | ☐ |\n| [e.g., Legal sign-off] | [GC] | ☐ |\n\n**Governance tier:** [Standard / Elevated / High — per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\n**Approval path:** [Who needs to sign off, per tier]\n\n**Next step — offer to continue:**\n\nAfter presenting a CONDITIONAL result, always end with:\n\n> \"Want me to start the impact assessment now? I can run the intake questions\n> and produce the assessment document without you needing to run a separate command.\"\n\nIf they say yes, load the `aia-generation` skill and continue in the same\nconversation — no need to restart. Pass the use case description and governance\ntier already determined.\n\nIf they say no (or don't respond), the triage result stands as a standalone output.\nThe AIA can be run any time with:\n`the “AIA Generation” workflow [use case]`\n\n---\n\n*If NOT APPROVED:*\n\n**Reason:** [Specific red line, policy prohibition, or registry entry]\n\n**If there's a version of this that could work:** [Optional — \"A narrower version\nthat keeps a human in the loop for every adverse decision might clear the elevated\ntier. That would require...\"] Only include if genuinely true. Don't offer a workaround\nfor every no.\n\n---\n\n### Step 5: Cross-plugin handoffs\n\n**Privacy handoff:** If the use case involves personal data — employee data,\ncustomer data, behavioral data — flag it:\n\n> \"This use case involves personal data. A PIA is likely required in addition to\n> an AI impact assessment. Use `the “PIA Generation” workflow [use case]`, if the\n> plugin is installed, to run that in parallel.\"\n\n**Product counsel handoff:** If this is a new product feature involving AI:\n\n> \"If this use case is part of a product launch, loop in product counsel.\n> Use `the “Launch Review” workflow`, if the plugin is installed — it will detect\n> the AI component and route to this plugin.\"\n\nOnly flag handoffs that are actually relevant. Don't append both as boilerplate\nto every triage.\n\n---\n\n### Step 6: Registry update suggestion\n\nIf this triage resulted in a classification that isn't in the registry yet — either\na no-match or a near-match that revealed a gap:\n\n> \"I'd suggest adding this to your use case registry. Proposed entry:\"\n\n```\n| [Use case description] | [Approved/Conditional/Never] | [Conditions if any] | [Reason if Never] |\n```\n\n> \"Add to your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Use case registry. This means next time the same request\n> comes up, the answer is documented and consistent.\"\n\n---\n\n## Batch triage\n\nIf the user presents multiple use cases at once — a list, a backlog, a product\nroadmap — run through each one and output a summary table first, then expand\neach conditional or not-approved entry:\n\n| # | Use case | Classification | Key condition / blocker |\n|---|---|---|---|\n| 1 | [use case] | 🟢 Approved | — |\n| 2 | [use case] | 🟡 Conditional | Impact assessment required |\n| 3 | [use case] | 🔴 Not approved | Automated adverse decision — red line |\n\nThen expand each row that isn't a clean approved.\n\n---\n\n## Edge cases and failure modes\n\n**\"We're already doing this\" triage:**\nIf someone is asking for retroactive triage — the use case is already deployed —\nsay so plainly, and before classifying from scratch, search the registry for an\nexisting entry covering the deployed version. Retroactive triages often surface a\nsuperseded registry entry whose conditions have drifted from current practice;\nupdating that entry is usually the right follow-up rather than adding a new row.\n> \"This looks like retroactive triage. If this is already running without an\n> assessment, that's a gap to document, not to wave through. I'm searching the\n> registry for any existing entry covering this deployment before running the\n> triage fresh. Here's the classification: [run normal triage]. If it's\n> conditional, those conditions should be confirmed in place now, not assumed.\n> If the registry has an existing entry and the deployed version has drifted,\n> the right follow-up is updating that entry rather than adding a new one.\"\n\n**\"It's just internal\" doesn't change the analysis:**\nInternal AI use affecting employees (screening, monitoring, evaluation) is often\nhigher-risk than customer-facing AI. Flag this if the user implies internal scope\nreduces risk.\n\n**\"The vendor says it's safe\":**\nVendor representations don't substitute for your own impact assessment. Flag it:\n> \"The vendor's position doesn't substitute for your own assessment — especially\n> for anything in the elevated or high tier.\"\n\n**\"We're just piloting\":**\nA pilot that touches real employee or customer data is not exempt from triage or\nimpact assessment. Apply the same classification; if conditions include an impact\nassessment, the pilot should have one too.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-aigov-vendor-ai-review", + title: "Vendor Ai Review", + practice: "AI Governance", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “vendor-ai-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /vendor-ai-review\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Confirm vendor governance positions are populated — if not, stop and direct to setup.\n2. Use the framework below.\n3. Confirm document type (AI addendum / main agreement AI provisions / ToS). If only an AUP was provided, ask for the full terms.\n4. Term-by-term review: training on data, confidentiality of inputs, model changes, output IP, liability, incident notification, human review rights, use restrictions, audit rights.\n5. AI addendum gap check if DPA exists but no AI addendum.\n6. AI policy consistency diff vs. your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n7. Output: bottom line, term-by-term, recommended redlines, if-they-won't-move routing.\n\n```\nthe “Vendor Ai Review” workflow openai-enterprise-agreement.pdf\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nVendor AI terms are where your governance positions actually get tested. The cold-start\ninterview captures what you *want*. This skill checks what you *agreed to* — and flags\nthe gaps between those two things.\n\nThe direction here is always the same: we are the deployer or buyer reviewing the\nvendor's terms. This is the opposite posture from the DPA review controller/processor\nquestion — there's no flip.\n\nWhat varies is the *input*:\n- A standalone AI agreement or AI addendum (most structured)\n- A vendor's universal terms of service with AI provisions embedded (often buried)\n- An acceptable use policy (tells you what you can't do; says nothing about what\n the vendor can do with your data or outputs)\n- A combination — master agreement + DPA + AI addendum (common for serious enterprise\n AI vendors)\n\nWhen there's a DPA already in place, this review complements it — it's not a\nsubstitute. The DPA governs data protection obligations; the AI terms govern\nmodel-specific rights and risks. Both need to be reviewed.\n\n---\n\n## Load the playbook\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Vendor AI governance`. Also read `## AI policy commitments`\n— vendor terms can't be consistent with a use restriction our own policy imposes if\nwe've agreed to something different.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) contains `[PLACEHOLDER]`, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor vendor governance positions to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll review tailored to YOUR positions.\n> - Say **\"provisional\"** and I'll review against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" run the vendor AI review normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction, no playbook (flag all common vendor-AI risks from first principles rather than matching to configured positions). Tag the reviewer note and every finding block with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your vendor governance positions, your jurisdiction, your risk appetite. 2 minutes.\"\n\n---\n\n## Before reading the document\n\nIf the user hasn't shared the actual vendor terms, ask:\n\n> \"Can you share the vendor's AI terms? The most useful thing is the actual contract\n> language — the AI addendum if there is one, or the main agreement with AI provisions\n> highlighted. An acceptable use policy alone won't tell us what the vendor can do\n> with our inputs; it only tells us what we're allowed to do.\"\n\nIf they share an acceptable use policy only:\n> \"This is the acceptable use policy — it tells us what we can't do with the vendor's\n> AI. That's useful context, but it doesn't address the commercial terms: whether\n> the vendor can train on our data, what their liability is for AI errors, whether\n> they notify us when the model changes. Do you have the service agreement or AI\n> addendum?\"\n\n---\n\n## The term-by-term review\n\n### Core AI-specific terms (check every vendor AI agreement)\n\nReview each term below. For each, extract what the vendor's contract actually says and compare it against the position in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Vendor AI governance` (standard / acceptable fallback / automatic no). The default positions come from the team's playbook, not from this skill.\n\n| Term | What to look for |\n|---|---|\n| **Training on our data** | Does the vendor use our inputs to train, fine-tune, or improve models? Is there an explicit opt-out or prohibition? Is training opt-in or opt-out by default? |\n| **Confidentiality of inputs** | Are our prompts, documents, and data confidential? Any \"quality review\" or human-review carveouts that would let vendor staff read inputs? |\n| **Model changes** | Any notice obligation for material changes to the model? Version pinning available? |\n| **Output ownership / IP** | Who owns AI-generated content? Any license-back to the vendor on outputs? Any IP indemnity? |\n| **Liability for outputs** | Does the vendor accept any liability if the AI produces harmful, incorrect, or infringing outputs? Cap structure? Carve-outs? |\n| **Incident notification** | How and when are we notified if the AI system fails, is compromised, or produces systematic errors affecting us? |\n| **Human review rights** | Can we require human review of outputs in specific cases? Can we appeal or dispute an AI decision? |\n| **Use restrictions** | What are we prohibited from doing? Does it match what we actually want to use the tool for? Any definitional terms (e.g., \"automated decision-making\") that could sweep in our intended uses? |\n| **Audit / auditability** | SOC 2, third-party audits, bias testing results — any audit rights? |\n| **Subprocessors / model providers** | Does the vendor use sub-vendors for the model? Are they disclosed? Whose terms govern? |\n| **Data residency** | Where is our data processed? Where does it go for inference? |\n| **Term and termination** | What happens to our data when we terminate? Deletion timelines? |\n| **Stacked-vendor accountability** | Is this vendor the model provider (e.g., Anthropic, OpenAI, Google, Meta), or are they a deployer of someone else's model (e.g., a SaaS wrapper of Claude, ChatGPT, or Gemini) or a reseller of infrastructure-hosted foundation models (Anthropic-on-Bedrock, Claude-on-Vertex, OpenAI-on-Azure)? If the latter: there are TWO vendors' terms in play — the one you're reviewing, plus the upstream model provider's terms. Identify (a) whose terms govern training on inputs, retention, and safety, (b) who is contractually liable for model behavior, and (c) whether each upstream commitment (e.g., \"no training on inputs\") is flowed down to you, or remains between the vendor and the upstream provider only. Flag any clause where one party disclaims responsibility for the other (e.g., \"Anthropic is not responsible for Bedrock or any other services it receives from AWS\"; \"Azure disclaims responsibility for OpenAI model outputs\") and whether the counter-party's contract closes the gap. Do not review the two contracts in isolation. |\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) doesn't define a position for a term on this list, ask: \"Your playbook doesn't cover [term]. What's your default position, your acceptable fallback, and your automatic no? I'll add it to your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) so the next review is consistent.\"\n\n---\n\n## Playbook comparison\n\nFor each term above, compare what we found to the positions in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n**Output format for each term:**\n\n> **[Term name]**\n> 🟢 / 🟡 / 🟠 / 🔴\n> **Vendor says:** [summary of what the contract actually says]\n> **Our position:** [from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n> **Gap:** [specific delta — or \"Aligned\"]\n> **Proposed fix:** [specific redline language, or \"escalate — outside fallback\"]\n\nUse the severity ratings consistently (calibrated against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) positions):\n\n- 🟢 **Aligned** — at or better than the standard position in the playbook.\n- 🟡 **Note** — within fallback but worse than standard; flag for awareness, not a blocker.\n- 🟠 **Significant** — outside standard position but within fallback; needs redline before signing.\n- 🔴 **Critical** — outside fallback; deployment should not proceed without resolution. Escalate per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n---\n\n## AI addendum gap check\n\n**If the vendor has a DPA but no AI addendum:**\n\n> \"There's a DPA in place but no AI-specific addendum. The DPA covers data protection\n> obligations but doesn't address: training on our data, model change notification,\n> liability for AI outputs, or incident notification for AI system failures.\n>\n> For a [Standard / Elevated / High] tier use case, this gap is [acceptable at\n> Standard tier / a blocker at Elevated or High tier]. Recommend requesting an\n> AI addendum or at minimum negotiating AI-specific terms into the next renewal.\"\n\n**If there are no AI terms at all:**\n\n> \"There are no AI-specific terms in this agreement. The vendor is providing an\n> AI-powered service under general service terms — which means we have no\n> contractual protection on the highest-risk AI governance items (training, liability,\n> model changes). This is a 🔴 for any Elevated or High tier use case.\"\n\n---\n\n## AI policy consistency check\n\nCross-check the vendor's terms against our AI policy commitments in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\nCommon conflicts:\n- Our policy prohibits vendor training on our data — the vendor's terms permit it by\n default. (Contract needs explicit prohibition or opt-out confirmation.)\n- Our policy requires human review for certain use cases — vendor's terms say AI outputs\n are final. (Workflow needs to impose the human step, not the vendor terms.)\n- Our approved vendor list doesn't include this vendor — or blocklist does.\n- Our policy requires disclosure to affected parties — vendor's terms impose a\n confidentiality obligation on AI system capabilities that would prevent disclosure.\n\nFlag every mismatch. One of them has to change.\n\n---\n\n## Redline granularity\n\n**Edit at the smallest possible granularity.** A redline is a negotiation artifact, not a rewrite. Wholesale clause replacement signals \"we threw out your drafting\" — it's aggressive, it forces the counterparty to re-read the whole clause, and it discards the parts of their drafting that were fine. Surgical redlines — strike a word, insert a phrase, restructure a subclause — signal \"we have specific asks\" and are faster to read, understand, and accept.\n\nDefault to the smallest edit that achieves the playbook position:\n- Replace a **word** before a phrase. (\"twelve (12)\" → \"twenty-four (24)\")\n- Replace a **phrase** before a sentence. (\"paid by the Buyer\" → \"paid and payable by the Buyer\")\n- Restructure a **subclause** before replacing the sentence. (Add \"(a)\" and \"(b)\" to split a compound condition.)\n- Replace a **sentence** before replacing the clause.\n- Only replace a **whole clause** when the counterparty's version is so far from your position that surgical edits would be harder to read than a fresh draft — and when you do, say so in the transmittal: \"We've replaced §8.2 rather than marking it up because the changes were extensive. Happy to walk you through the delta.\"\n\nWhen in doubt, smaller. A client who receives a surgical redline trusts that you read carefully. A client who receives a wholesale replacement wonders whether you read at all.\n\n## Output\n\n**Before recommending signature of a vendor AI agreement (the version the company will execute):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Signing this vendor AI agreement has legal consequences. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the vendor and the use case, the key terms reviewed (data use, liability, auditability, model change, human review), where vendor positions diverge from policy, what's being accepted, what could go wrong, what to ask the attorney.]\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes. Review/redline drafts for attorney consideration do not require the gate — signature does.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n*This review is derived from vendor contract terms that are typically confidential under NDA, and it may itself be privileged. It inherits the source's confidentiality and privilege status. Distributing it beyond the privilege circle (e.g., forwarding to the vendor, sharing in an open channel) can waive privilege and breach the NDA. Mark, store, and route accordingly.*\n\n# Vendor AI Review: [Vendor Name]\n\n**Document reviewed:** [AI addendum / main agreement AI provisions / ToS]\n**Reviewed:** [date]\n**Use case(s):** [what we're deploying this vendor's AI for]\n**Governance tier:** [Standard / Elevated / High]\n\n---\n\n## Bottom line\n\n[Two sentences. Can we deploy under these terms? What has to change first?]\n\n**Issues:** [N]🔴 [N]🟠 [N]🟡 [N]🟢\n\n---\n\n## Term-by-term\n\n[For each term above — vendor position, our position, gap, severity, proposed fix]\n\n---\n\n## AI addendum status\n\n[Present / Absent — and what that means for this deployment]\n\n---\n\n## AI policy consistency\n\n[🟢 Consistent | 🟡 Flags: list]\n\n---\n\n## Recommended redlines\n\n[Consolidated draft redlines. Review with counsel before sending externally. For critical\nissues where no fallback exists, flag for escalation rather than proposing language.]\n\n---\n\n## If they won't move\n\n[For each 🔴 and 🟠: the fallback from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), or \"escalate — outside fallback\"\nand routing per escalation table]\n```\n\n---\n\n## Practical notes\n\n**The training-on-data clause is the one most people miss.**\nVendor AI terms have historically varied widely on whether API inputs can be used\nto train or improve models — some vendors permit it by default, others prohibit it,\nand many have changed their position over time. Do not assume any particular vendor's\ncurrent stance without reading the specific agreement in front of you. This is almost\nalways the most important term for any company with confidential or sensitive data,\nand it must be confirmed in writing, not assumed from reputation or prior experience.\n\n**Map the AI stack.** Modern AI deployments are layered. Before reviewing terms, map the layers:\n1. **End-user SaaS application** (e.g., a legal tech tool, a CRM with AI scoring, a document assistant) — the tool your org signs up for\n2. **API gateway / orchestration layer** (e.g., Azure OpenAI Service, AWS Bedrock, Google Vertex, LangChain-hosted) — often invisible, always has its own terms\n3. **Model provider** (e.g., Anthropic, OpenAI, Google, Meta) — the LLM\n4. **Hosted knowledge base / RAG source** (e.g., a vector database, a third-party data corpus, a retrieval service) — the data Claude reads from\n5. **Additional subprocessors** — analytics, logging, fine-tuning partners\n\nAsk: \"Walk me through the stack — what does [SaaS tool] use under the hood? Is it built on a cloud AI service? Does it call a model provider directly or through a gateway? Does it use a hosted knowledge base?\" Then review terms at EACH layer, not just the top.\n\nEach handoff between layers is a flow-down risk. A commitment at layer 1 (\"we won't train on your data\") means nothing if layer 3's terms say otherwise and layer 1 never flowed the commitment down.\n\n**Flow-down test.** For each flagged stacked-vendor term — especially training-on-data, data retention, subprocessor changes, and liability — don't just flag \"check upstream terms.\" DO THE CHECK:\n\n1. **Search the contract for flow-down language.** Look for: \"subprocessor obligations no less protective than,\" \"flow-down of data commitments,\" \"back-to-back terms,\" \"Provider shall ensure that its subprocessors are bound by,\" \"equivalent obligations.\"\n2. **If present:** Quote it, verify it covers the specific flagged term, and flag whether it's enforceable (who can enforce it — you, or only the intermediate vendor?).\n3. **If absent:** Produce a specific redline requiring it:\n > \"Add to §[X]: Provider shall ensure that any third-party model providers, infrastructure providers, or subprocessors used in delivering the Services are bound by obligations with respect to [Customer Data / AI training / data retention / confidentiality] no less protective than those set forth in this Agreement, and shall be responsible for any breach of this Agreement caused by such third parties.\"\n4. **Flag the gap with a severity:** 🔴 if the term is training-on-data or liability and there's no flow-down; 🟡 if the term is less sensitive or there's partial flow-down.\n\n\"Escalate and check upstream\" is where compliance dies. Produce the test and the redline.\n\n**Acceptable use policies flip the frame.**\nAUPs tell you what you can't do; they don't tell you what the vendor can do.\nDon't let a clean AUP review substitute for reading the data use and liability terms.\n\n**Renewals are leverage points.**\nIf the current agreement is unfavorable and the vendor won't renegotiate mid-term,\ndocument the gaps now and flag them for the renewal. Flag to procurement:\n\"This renewal should not close without AI addendum addressing [list].\"\n\n**Builder context adds a layer.**\nIf the company is a builder using a vendor's model as a foundation, the vendor's terms\nalso govern what the company can offer its own customers. Some terms prohibit certain\ndownstream uses. Check use restrictions against the product roadmap, not just current\ninternal workflows.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't review the DPA provisions of the same agreement — run\n `the “DPA Review” workflow`, if the plugin is installed, for that.\n- It doesn't decide whether to accept terms outside the fallbacks. It routes those\n per the escalation table in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n- It doesn't evaluate vendor security posture beyond what's in the agreement —\n that's a security team function.", + }, + { + id: "builtin-cfl-commercial-amendment-history", + title: "Amendment History", + practice: "Commercial Contracts", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “amendment-history” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /amendment-history\n\nLoads a base agreement and all amendments, then either summarizes what\nchanged over time or traces a specific provision to its current\ncontrolling language.\n\n## Instructions\n\n1. **Get the documents:** From file upload, [CLM ID (coming soon)], or [repository link (coming soon)]. Accept multiple files in one invocation. If none\n provided, ask.\n\n2. **Detect the mode** by parsing the request per the mode\n detection rules below. If a provision name is clearly stated, go straight\n to Mode 2. If no provision is mentioned, run Mode 1. Ask only if\n genuinely ambiguous.\n\n3. **Run the workflow below.** Follow it fully.\n\n4. **Offer follow-ups after output:**\n - \"Want me to trace another provision?\"\n - \"Want a full playbook review of the current agreement as amended?\"\n (routes to vendor-agreement-review)\n - \"Want a stakeholder summary of the key changes?\"\n (routes to stakeholder-summary)\n\n## Examples\n\n```\nthe “Amendment History” workflow acme-msa.pdf amendment-1.pdf amendment-2.pdf\n```\n\n```\nthe “Amendment History” workflow --provision indemnity\n```\n\n```\nthe “Amendment History” workflow\n[paste agreement and amendment text]\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nContracts accumulate amendments. By the third amendment, nobody remembers\nwhat the original said or which version of a clause controls. This skill\nreads the base agreement and all amendments in chronological order and\neither summarizes what changed across the whole contract or traces a\nspecific provision through every version to find the current controlling\nlanguage.\n\n## Mode detection\n\nParse the user's request to determine which mode to run. Do not ask\nwhich mode unless the request is genuinely ambiguous.\n\n**Mode 1 — Summary** (no specific provision mentioned)\nTrigger phrases: \"what changed\", \"amendment history\", \"show me changes\nover time\", \"summarize amendments\", \"what does this contract look like now\"\n\n**Mode 2 — Provision trace** (specific clause or topic named)\nTrigger phrases: \"where's the [clause]\", \"latest [provision]\", \"how did\n[term] change\", \"find the indemnity\", \"what does it say now about [topic]\"\n\nCommon provision mappings:\n- \"indemnity\" / \"indemnification\" → indemnification section\n- \"liability\" / \"liability cap\" → limitation of liability\n- \"termination\" → term and termination\n- \"data\" / \"privacy\" / \"DPA\" → data protection provisions\n- \"IP\" / \"intellectual property\" → IP ownership and licenses\n- \"price\" / \"fees\" / \"payment\" → payment terms\n- \"auto-renewal\" / \"renewal\" → renewal mechanics\n\nIf the term is ambiguous and maps to more than one provision, list the\ncandidates and ask which one:\n> \"I found [N] provisions related to [term] — [list them]. Which one?\"\n\nIf the overall request is ambiguous between modes, ask one question:\n> \"Summary of all changes across the contract, or trace a specific\n> provision — like indemnity, liability, or termination?\"\n\n---\n\n## Step 1: Load and order the documents\n\nAccept documents from any of these sources:\n\n**[CLM integration coming soon] (if connected):**\nSearch by counterparty name or agreement title. Pull the base agreement\nand all amendments. Record metadata typically includes execution dates —\nuse these to establish chronological order.\n\n**[Document repository integration coming soon] (if connected):**\nSearch by counterparty name or filename. Look for files matching patterns\nlike \"Amendment\", \"Addendum\", \"Amendment No. 1\", \"First Amendment\", or\nnumbered suffixes. Pull all matches and sort by file date or filename\nnumbering.\n\n**Direct upload:**\nUser provides files directly. In most cases the ordering is\nself-explanatory from document titles (e.g., \"Amendment No. 1\",\n\"Second Amendment\", \"Addendum A\") or dates visible in the filename\nor document header — proceed without asking.\n\nOnly ask the user to confirm ordering if:\n- Filenames give no indication of sequence (e.g., \"agreement-final.pdf\",\n \"agreement-v2.pdf\", \"agreement-markup.pdf\")\n- Dates are absent from both filenames and document headers\n- Two documents appear to be the same amendment version\n\nIf ordering was inferred rather than confirmed, note confidence at the\ntop of the output only where uncertain:\n> \"Order inferred from document titles — one item I was less certain\n> about: [specific document]. Confirm if this affects your review.\"\n\n**Ordering rules:**\n- Always establish chronological order before reading content.\n- If execution dates are available in metadata, use them.\n- If not, look for dates in the document header or recitals\n (\"This Amendment, dated as of...\").\n- Amendments often reference the agreement they modify (\"this Amendment\n to the Master Services Agreement dated [X]\") — use these references\n to confirm the chain.\n\n---\n\n## Privilege inheritance\n\nThis skill reads the base agreement and amendments — often privileged or confidential in their own right, and typically used for privileged analysis. The output inherits the source's privilege and confidentiality status. Prepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` to every output below, distribute only within the privilege circle, and store it where privileged materials live. Strip the header before any external delivery.\n\n## Step 2: Read and index\n\nRead each document in chronological order. For each, extract:\n- Document type (base agreement, amendment number, addendum, etc.)\n- Execution date\n- Parties (confirm they match across documents — flag if a new party\n was added or a party name changed)\n- A list of provisions explicitly modified, added, or deleted\n\nBuild a working index before producing output. Use it internally to\ndrive the output — do not show it to the user.\n\n---\n\n## Mode 1: Summary of all changes\n\n### Section reference rule\n\nEvery finding must include an inline section reference so the reader\ncan verify against the source document without searching:\n\n \"Termination for convenience (§12.3): Added. Customer may terminate\n on 90 days written notice with no fee after the initial term.\"\n\nIf a provision spans multiple sections or the section number changed\nacross amendments, cite all references:\n \"Indemnification (§9.1 base; §9.1 restated in Amendment 5)\"\n\n### Output format\n\n```markdown\n# Amendment History: [Counterparty] — [Agreement type]\n\n**Base agreement:** [date]\n**Amendments:** [N] ([date of first] → [date of last])\n**Last amended:** [date]\n\n---\n\n## What changed — chronological\n\n### Amendment 1 — [date]\n**Purpose:** [one sentence — why this amendment existed, from recitals\nor clear from context. If not stated, omit rather than guess.]\n\n**Material changes:**\n- [Provision] (§[X.X]): [what it said before → what it says now,\n in plain English]\n- [New provision added] (§[X.X]): [what it does]\n- [Provision deleted] (§[X.X]): [what was removed and why it matters]\n\n### Amendment 2 — [date]\n[same structure]\n\n[repeat for each amendment]\n\n---\n\n## Net current state\n\n| Provision | Current position | §Ref | Last changed |\n|---|---|---|---|\n| [clause] | [plain English summary] | §[X.X] | Amendment N, [date] |\n| [clause] | [unchanged from base] | §[X.X] | Base agreement |\n\n---\n\n## Watch items\n[Flag anything that looks inconsistent — e.g., an amendment modifying\na provision that was already deleted, contradictory language between\namendments, a party name that changed without a formal assignment,\nor a provision where the section number shifted across documents.\nInclude section references on every flag.]\n```\n\n---\n\n## Mode 2: Provision trace\n\n### Output format\n\nShow only what changed. Do not list amendments where the provision\nwas untouched — skip them entirely.\n\n```markdown\n# Provision Trace: [Provision name]\n## [Counterparty] — [Agreement type]\n\n---\n\n### Original — [Base agreement date], §[X.X]\n> \"[exact quote]\"\n\n*Plain English:* [one sentence]\n\n---\n\n### Amendment [N] — [date], §[X.X]\n\n**Was:**\n> \"[exact quote of prior language]\"\n\n**Now:**\n> \"[exact quote of replacement language]\"\n\n*What changed:* [one sentence — practical effect on the parties]\n\n---\n\n[Only subsequent amendments that touched this provision appear here.\nAll others are omitted.]\n\n---\n\n## Current controlling language\n\n**§[X.X] — [source document, date]**\n> \"[exact quote]\"\n\n*Plain English:* [one sentence]\n\n---\n\n## Watch items\n[Flags, inconsistencies, open questions — with section references.\nCommon items to check: whether the provision is subject to or carved\nout of the liability cap; whether the section number shifted across\namendments; whether the amendment language conflicts with another\nprovision.]\n```\n\nIf the provision was never amended after the base agreement:\n> \"This provision has not been modified by any amendment. Original\n> language controls. §[X.X], base agreement, [date].\"\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It does not determine which document controls in the event of a\n conflict between the base agreement and an amendment — that is a\n legal interpretation question. It flags conflicts and routes to Legal.\n- It does not draft new amendments.\n- It does not compare against the playbook in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — that is the\n vendor-agreement-review skill's job. This skill is purely historical.\n- It does not infer what an amendment means if the language is\n ambiguous — it quotes exactly and flags ambiguity for Legal.", + }, + { + id: "builtin-cfl-commercial-escalation-flagger", + title: "Escalation Flagger", + practice: "Commercial Contracts", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “escalation-flagger” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /escalation-flagger\n\nNames the approver for a contract issue per the your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) escalation matrix and drafts the message so you're not writing \"hey got a sec\" at 5pm.\n\n## Instructions\n\n1. **Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)** → Escalation section. If missing, say so — the practice profile needs editing.\n\n2. **Characterize the issue:** dollar threshold / term deviation / automatic trigger / business decision.\n\n3. **Match to matrix, name the approver.** Be specific — a person or role, not \"legal leadership.\"\n\n4. **Draft the ask** per the template below: what the contract says, what playbook says, options with recommendation, decision-by date.\n\n5. **Do not send.** Draft it, show it, let the lawyer send.\n\n## Examples\n\n```\nthe “Escalation Flagger” workflow\nThe Acme MSA has uncapped liability — who approves and what do I say?\n```\n\n```\nthe “Escalation Flagger” workflow\nReference: acme-review-memo.md\nIssue: §8.2 indemnity carveouts\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nEvery contracts team has an escalation matrix, written or not. This skill reads the written one (in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)), matches a contract issue against it, names the approver, and drafts the ask so the lawyer isn't writing \"hey do you have a sec\" messages at 5pm.\n\n## Load the matrix\n\n**Which side?** Before matching to the matrix, determine which side the company is on for the contract whose issue is being escalated. Usually obvious: if the counterparty is a vendor/supplier providing goods or services, you're purchasing-side. If the counterparty is a customer buying your product/service, you're sales-side. If it's not obvious, ask. Read the matching playbook section (`### Sales-side playbook` or `### Purchasing-side playbook`) to evaluate whether the term is inside fallbacks or triggers an automatic escalation — a term that's fine on one side can be a hard-no on the other. Note which side in the drafted ask so the approver knows which playbook was applied.\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Escalation`. If it's missing or vague, say so — the cold-start interview should have captured this, and if it didn't, the practice profile needs editing.\n\nExpected structure:\n\n| Can approve | Threshold | Escalates to | Via |\n|---|---|---|---|\n| Paralegal | Standard terms, <$50K | Counsel | Slack |\n| Counsel | Non-standard but within fallbacks, <$500K | GC | Slack or email |\n| GC | Everything else | CFO/Board | Meeting |\n\nPlus **automatic escalation triggers** — things that escalate regardless of dollar value. Typically: unlimited liability, IP assignment, anything on the \"never accept\" lists.\n\n## Workflow\n\n### Step 1: Characterize the issue\n\nWhat's being escalated?\n\n- **Dollar threshold:** Contract value exceeds someone's approval authority\n- **Term deviation:** A term is outside the playbook fallbacks — someone more senior needs to decide whether to accept\n- **Automatic trigger:** One of the always-escalate items is present\n- **Business decision:** Not a legal call — needs the business owner, not legal leadership\n\nDon't escalate things that are actually fine. If the term is within the fallbacks in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), it doesn't need to go up.\n\n### Step 2: Match to the matrix\n\n```\nIs the issue an automatic trigger?\n → YES: escalate to [person named for that trigger]\n → NO: continue\n\nIs the contract value above the reviewer's threshold?\n → YES: escalate to whoever has authority at that dollar level\n → NO: continue\n\nIs the term deviation outside all documented fallbacks?\n → YES: escalate to whoever can approve non-standard terms\n → NO: reviewer can approve — no escalation needed\n```\n\n### Step 3: Name the approver\n\nBe specific. Not \"escalate to legal leadership\" — name the person or role from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the matrix doesn't name anyone for this situation, say so: \"The escalation matrix doesn't cover [situation]. Suggest asking [GC name] who owns this.\"\n\n### Step 4: Draft the ask\n\nThe approver should be able to decide from the message alone — no \"let me pull up the contract.\"\n\n```markdown\n**Escalating to:** [name]\n**Via:** [Slack #channel / email / meeting — per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n**Urgency:** [deadline if there is one]\n\n---\n\nHey [name] —\n\nNeed your call on the [Counterparty] [agreement type]. [One sentence on deal context.]\n\n**The issue:** [Plain English, one paragraph. What they want, why it's outside\nour standard, what the risk actually is.]\n\n**What the contract says:**\n> \"[exact quote]\"\n\n**What our playbook says:** [quote from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\n**Options:**\n1. **Accept** — [one line on why this might be okay]\n2. **Push back with:** \"[proposed counter-language]\" — [one line on likely counterparty reaction]\n3. **Walk** — [one line on whether that's realistic given the business context]\n\n**My recommendation:** [which option and why, briefly]\n\n**Need a decision by:** [date, if there is a deadline]\n\n[Link to full review memo]\n```\n\n### Step 5: Record the escalation\n\nIf this team uses a ticket system or [CLM] approval workflows, log it. If not, note in the review memo that the escalation was sent, to whom, and when. The next person who reads the memo should see the status.\n\n## Calibration: when in doubt, escalate with a note\n\nThe cost of an unnecessary escalation is ~30 seconds of the approver's time — they read, say \"fine, proceed,\" and the record shows they saw it. The cost of a missed escalation is signing an unapproved term, which is a one-way door. The costs are not symmetric. **When in doubt, escalate.**\n\nThe calibration for what warrants escalation lives in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), not in this skill. Check the playbook's stated position, its fallbacks, and its \"automatic escalation regardless of dollar value\" list:\n\n- **Clearly inside the fallback range:** no escalation needed.\n- **Clearly outside the range, or on the automatic-escalation list:** escalate.\n- **Uncertain — the term is ambiguous, novel, or arguably inside the range but the argument is a stretch:** escalate anyway, and note the uncertainty explicitly. The draft flags the specific question the approver needs to decide and why the skill couldn't confidently place it inside the fallback. The approver narrows; the skill does not.\n\nDo not suppress an escalation because over-escalation might train approvers to skim. That's an approver-experience problem the attorney solves by adjusting thresholds in the playbook, not a problem the skill solves by making its own subjective call on a term it's uncertain about.\n\nIf a term comes up that the playbook doesn't address, don't guess the threshold — ask the reviewing attorney whether this class of issue should escalate, and offer to record the answer in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) so future reviews are consistent.\n\n## What this skill does not do\n\n- It does not approve anything. It routes.\n- It does not decide between the options. The draft includes a recommendation but the approver decides.\n- It does not send the escalation message — it drafts it. The lawyer sends it after reading.", + }, + { + id: "builtin-cfl-commercial-nda-review", + title: "NDA Review", + practice: "Commercial Contracts", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “nda-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# NDA Review\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nMost inbound NDAs are fine. A few have landmines. This skill sorts them in under a minute so legal only reads the ones that matter.\n\n**The goal:** a GREEN NDA should need nothing more than a signature. A YELLOW needs a lawyer's eyes on one or two specific things. A RED stops before anyone wastes time.\n\n## Load the playbook first\n\n**Which side?** Before applying the playbook, determine which side the company is on for this NDA. Usually obvious from the context: if the counterparty is a vendor or partner evaluating your product, you're sales-side; if you're evaluating theirs, you're purchasing-side. Mutual NDAs still have a side — whose paper is it, and which direction is the evaluation running. If it's not obvious, ask. Read the matching playbook section (`### Sales-side playbook` or `### Purchasing-side playbook`) from the config. Note which side in the output so the reviewer knows which playbook was applied. If the matching side is `[Not configured]`, stop and tell the user to run `configure your Practice Profile (Account → Practice Profile) --side ` before this triage can proceed.\n\n**Before triaging anything, read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Playbook` → the matching side → `NDA triage positions`.** That section is the source of truth for what makes an NDA GREEN, YELLOW, or RED for *this* team on *this* side. This skill does not ship with default positions on NDA terms — the law, the market, and each team's risk tolerance vary too much for hardcoded defaults to be safe.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) doesn't have an `NDA triage positions` section yet, or it's silent on a term that comes up in the NDA you're reviewing, ask the user:\n\n> Your playbook doesn't cover [term — e.g., \"residuals clauses,\" \"survival period,\" \"one-way NDAs where you're the receiver\"]. What's your default position — when should this be GREEN, when YELLOW, when RED? I'll add it to your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) so the next review is consistent.\n\nThen record the answer in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) and proceed with the triage using the new position.\n\n## Scope check\n\n**Before reviewing NDA-specific provisions, check whether the document is doing more than its name suggests.** Mutual commercial NDAs can hide: standstills, licensing grants, exclusivity, non-solicits, non-competes, IP assignments, right of first refusal, most-favored-nation clauses, and arbitration/jurisdiction clauses that govern far more than confidentiality disputes.\n\nIf the NDA contains obligations beyond confidentiality: **auto-YELLOW regardless of the NDA-term analysis.** Flag the non-NDA provisions:\n\n> This document is labeled an NDA but contains [standstill / license grant / non-solicit / exclusivity / IP assignment / ROFR / MFN / broad arbitration]. It's more than an NDA. Route for attorney review.\n\nDo not silently push a document labeled \"NDA\" through NDA triage when the substantive obligations are a services agreement, a term sheet, or a covenant package in NDA clothing.\n\n## The triage\n\nClassify the NDA into one of three buckets by applying the positions from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). The bucket definitions below are stable; the *criteria* that fill each bucket come from the playbook.\n\n### GREEN — route to signature\n\nThe NDA satisfies every position in the team's playbook, and no term triggers a RED flag per the playbook. Examples of checks the playbook typically covers: mutuality, term length, survival period, carveouts, governing law, restrictive covenants, fee-shifting. Confirm each one against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) before calling GREEN.\n\n**GREEN requires attorney-reviewed playbook positions.** GREEN is the only path to signature without lawyer review. It cannot be issued against default or absent positions. Before issuing GREEN, check: does the practice profile have an attorney-reviewed `## NDA triage positions` section? If not:\n\n> I can't issue GREEN without attorney-reviewed NDA positions in your practice profile. Run `configure your Practice Profile (Account → Practice Profile) --full` with your commercial counsel to set them, or route this NDA for attorney review. Issuing GREEN against defaults means a non-lawyer set the positions the next non-lawyer relies on.\n\nDo not route to signature on defaults. YELLOW is the right call when positions are missing — it surfaces the NDA to a human who can decide.\n\n**Output:**\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n## NDA Triage: [Counterparty]\n\nGREEN — route to signature\n\n### Executive Summary\n\nNo red flags identified under the playbook. Route for signature per standard process.\n\n| Check | Status | Playbook reference |\n|---|---|---|\n| [Each playbook check] | [pass/fail] | [your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) section] |\n\n**Next step:** [Submit to [CLM] standard NDA workflow | Send to [approver from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)] for signature]\n```\n\n**Before proceeding past GREEN to signature:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> This step has legal consequences (countersigning an NDA binds the company). Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: counterparty, NDA direction (mutual / one-way), the playbook checks run, anything the playbook didn't cover, what could go wrong if signed as-is, and the three things to ask the attorney.]\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not proceed past this gate without an explicit yes.\n\n### YELLOW — needs a lawyer's eyes on specific items\n\nOne or more terms deviate from the playbook but aren't categorical deal-breakers, OR a term appears that the playbook doesn't address. Surface each item individually so the approver can make the call.\n\n**Output:**\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n## NDA Triage: [Counterparty]\n\nYELLOW — flag for [approver name from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\n### Executive Summary\n\n- [One-line actionable edit, e.g. \"Strike non-solicit clause (Section 6)\"]\n- [One-line actionable edit]\n\n### Flagged items\n\n**1. [Issue]** — Section [X]\n What: [one line]\n Why flagged: [one line — which playbook position this hits, or \"playbook is silent on this\"]\n **Legal risk:** [🔴/🟠/🟡/🟢] | **Business friction:** [🔴 Blocks deals / 🟠 Slows deals / 🟡 Confuses customers / 🟢 Invisible]\n Likely resolution: [accept / push back on X / depends on deal context]\n\n[repeat for each flag]\n\n### Everything else\n\n| Check | Status | Playbook reference |\n|---|---|---|\n| [playbook checks that passed] | pass | [your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) section] |\n\n**Next step:** Ask [approver] about the flagged items, then route to signature if they're okay with it.\n```\n\n### RED — stop, talk to legal first\n\nThe NDA hits a position on the playbook's \"never accept\" list, or the structure of the agreement is incompatible with the team's standard posture (e.g., a one-way NDA where the team's playbook requires mutual; a perpetual term where the playbook caps at a finite period; governing law on the \"never\" list).\n\n**Output:**\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n## NDA Triage: [Counterparty]\n\nRED — do not submit, talk to legal first\n\n### Executive Summary\n\n- [One-line actionable edit, e.g. \"Section 4 — route to Legal for review\"]\n- [One-line actionable edit]\n\n### Critical issues\n\n**1. [Issue]** — Section [X]\n > \"[exact quote]\"\n Why this is a problem: [specific risk; cite the playbook position it violates]\n **Legal risk:** [🔴/🟠/🟡/🟢] | **Business friction:** [🔴 Blocks deals / 🟠 Slows deals / 🟡 Confuses customers / 🟢 Invisible]\n Recommended response: [use our paper instead | push back with specific language | walk]\n\n**Next step:** Send this triage to [GC or named escalation person from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]. Do not send to [CLM or approvals workflow]. Do not tell the counterparty we'll sign.\n```\n\n## Redline granularity\n\n**Edit at the smallest possible granularity.** A redline is a negotiation artifact, not a rewrite. Wholesale clause replacement signals \"we threw out your drafting\" — it's aggressive, it forces the counterparty to re-read the whole clause, and it discards the parts of their drafting that were fine. Surgical redlines — strike a word, insert a phrase, restructure a subclause — signal \"we have specific asks\" and are faster to read, understand, and accept.\n\nDefault to the smallest edit that achieves the playbook position:\n- Replace a **word** before a phrase. (\"twelve (12)\" → \"twenty-four (24)\")\n- Replace a **phrase** before a sentence. (\"paid by the Buyer\" → \"paid and payable by the Buyer\")\n- Restructure a **subclause** before replacing the sentence. (Add \"(a)\" and \"(b)\" to split a compound condition.)\n- Replace a **sentence** before replacing the clause.\n- Only replace a **whole clause** when the counterparty's version is so far from your position that surgical edits would be harder to read than a fresh draft — and when you do, say so in the transmittal: \"We've replaced §8.2 rather than marking it up because the changes were extensive. Happy to walk you through the delta.\"\n\nWhen in doubt, smaller. A client who receives a surgical redline trusts that you read carefully. A client who receives a wholesale replacement wonders whether you read at all.\n\n## Jurisdiction assumption\n\nThis triage applies the governing-law and restrictive-covenant positions recorded in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Legal rules (enforceability of non-competes, non-solicits, fee-shifting, choice of law) vary materially by jurisdiction. If the NDA involves a jurisdiction outside the team's configured posture, flag it in the output and note that the triage may not transfer as written.\n\n## Output rules\n\n**Complexity filter:** If addressing an issue would require drafting new\nlanguage, restructuring a clause, or inserting substantive new\nprovisions — do not attempt it. Instead write:\n\"Section [X] — route to Legal for review.\"\nOnly include simple, mechanical actions in the Executive Summary\n(strike, delete, replace a word or phrase).\n\n**Clean NDA rule:** If the NDA passes all checks with no flags, the Executive Summary\nshould say only: \"No red flags identified. Route for signature per\nstandard process.\"\n\nDo not produce a lengthy report for a clean NDA.\n\n## Detailed check reference\n\nFor each check below, the bucket (GREEN/YELLOW/RED) is determined by your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). This skill lists the *categories* to check; it does not hardcode thresholds.\n\n### Mutuality\n\nIs the NDA mutual or one-way? Apply the team's position from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the playbook doesn't address one-way NDAs for this context, run the one-way questionnaire below and surface the result for a human.\n\n**One-way NDA questionnaire**\n\nWhen the NDA is unilateral (one party discloses, the other only receives), do not immediately flag RED or exit. Ask:\n\n> A one-way NDA is appropriate in some situations. Before flagging this,\n> let me ask a few quick questions:\n>\n> 1. In this relationship, are you the only party disclosing confidential\n> information? (i.e., the other side shares nothing back)\n> 2. Is this for a limited, specific disclosure — for example, sharing\n> your technology with a vendor who will work on it, but not sharing\n> theirs with you?\n> 3. Is this related to M&A, employment, or investment? (If yes, stop —\n> this skill is for commercial MNDAs only. Route to Legal.)\n\nUse the answers plus the your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) position to decide GREEN/YELLOW/RED. If your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) doesn't take a position on this fact pattern, flag YELLOW and surface the questionnaire answers for the approver.\n\n### Definition of Confidential Information\n\nCheck scope (marked-only vs. everything-disclosed), marking requirements, and oral-disclosure confirmation windows. Apply the team's position from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the playbook is silent on any of these, ask.\n\n### Carveouts\n\nThe five carveouts typically present in an NDA:\n\n1. Information that is or becomes public (other than through breach)\n2. Information the receiving party already had\n3. Information independently developed without reference to the CI\n4. Information received from a third party without restriction\n5. Information required to be disclosed by law or court order (with notice to discloser where legally permitted)\n\nWhich carveouts the team requires, and how strictly, is a playbook question. Check your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the team's position on required carveouts, acceptable variations in wording, and what happens when one is missing.\n\n### Residuals\n\nA residuals clause lets the receiving party use information retained in unaided memory. Whether this is acceptable — and under what conditions (e.g., narrow \"unaided memory\" wording vs. broader scope covering notes or copies) — is a playbook question. Apply your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the playbook doesn't address residuals, ask.\n\n### Term and survival\n\nCheck the initial term length, the post-term survival period for confidentiality obligations, and whether trade secrets are carved out with longer protection. Apply the team's position from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the playbook doesn't cover one of these, ask.\n\n### Restrictive covenants\n\nCheck for non-solicits (employee, customer), non-competes, exclusivity, and any restriction on who else the receiving party can engage with. Apply your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the playbook is silent, ask — restrictive covenants are jurisdiction-sensitive and the team's posture matters.\n\n### Attorneys' fees\n\nCheck for fee-shifting provisions and whether they are mutual, one-sided, or prevailing-party. Apply your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n### Backup and archival carveout\n\nCheck whether the destruction/return clause includes an exception for standard backup and archival retention systems. Apply the team's position from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — some teams require this carveout and will push to add it; others accept an NDA without it. If the playbook doesn't address this, ask.\n\n### Governing law\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Playbook` → `Governing law and venue`.\n\n## Counterparty context\n\n**BigCo NDAs:** Fortune 500 counterparties generally won't negotiate NDAs. Calibrate: is the RED flag truly a deal-breaker, or is it \"different from our form\"? If the business relationship matters, the call is whether to accept their paper — escalate that decision, don't make it.\n\n**Startup NDAs:** Will usually take our paper. If their NDA has issues, the fastest path is often \"let's use ours\" rather than redlining theirs.\n\n## Integration: CLM\n\nIf connected:\n- GREEN → offer to create the CLM record in the standard NDA workflow\n- YELLOW → offer to create it with a note attached listing the flagged items\n- RED → do not create a record; the lawyer decides what happens next\n\n## What this skill does NOT do\n\n- It does not negotiate. It sorts.\n- It does not draft an NDA. If the answer is \"use our paper,\" the user pulls our form from [CLM or document system].\n- It does not make the call on YELLOW items. It surfaces them for a human.\n- It does not state a position on any NDA term. Positions live in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Closing action\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## NDA triage preferences` → `closing_action`.\n\nIf configured, append the closing action verbatim at the end of every\noutput. Example configurations:\n\n```\nclosing_action: \"Send the full text of this analysis along with a copy\nof the NDA to Legal at legal@[yourcompany].com for final confirmation before\nsigning.\"\n\nclosing_action: \"Submit to [CLM] using the standard NDA workflow.\nLegal will confirm before routing for signature.\"\n\nclosing_action: \"Forward this output and the NDA to your contracts\nmanager.\"\n```\n\nIf `closing_action` is not configured in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), append:\n\"Route final NDA through your standard approval process.\"\n\nThe cold-start interview asks: \"When someone finishes an NDA\ntriage, what do you want them to do with the output? I'll add that as\na standing instruction at the end of every review.\"\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-commercial-review", + title: "Review", + practice: "Commercial Contracts", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /review\n\nReviews an inbound agreement against the playbook in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Identifies the agreement structure from titles, selects the appropriate skill(s), and — if confirm_routing is enabled — checks with the user before proceeding.\n\n## Instructions\n\n1. **Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If placeholders present, stop and prompt: \"Run `configure your Practice Profile (Account → Practice Profile)` first — I need to learn your playbook before I can review against it.\"\n\n Also read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Review preferences` → `confirm_routing`. If the field is missing, treat it as `true`.\n\n2. **Get the agreement:** From file path, Drive link, [CLM ID], or pasted text. If none provided, ask.\n\n3. **Read the document structure — titles first.**\n\n Before reading the body, extract:\n - The main agreement title (e.g., \"Master Services Agreement\", \"Non-Disclosure Agreement\")\n - All exhibit, schedule, addendum, and attachment titles (e.g., \"Exhibit A — Data Processing Addendum\", \"Schedule 1 — Subscription Order Form\", \"Annex B — Service Level Agreement\")\n\n This is the routing signal. Do not rely on body keywords alone — a 40-page MSA with \"confidential\" throughout is not an NDA.\n\n4. **Select the skill(s) based on document structure.**\n\n Map each identified document or section to a skill:\n\n | Document / section title contains | Skill |\n |---|---|\n | Non-Disclosure, NDA, Confidentiality Agreement (as the *main* agreement) | **nda-review** |\n | Master Services Agreement, Professional Services, Statement of Work, Consulting Agreement | **vendor-agreement-review** |\n | Subscription, SaaS, Cloud Services, Order Form with auto-renewal, Software License with recurring fees | **saas-msa-review** (overlay on vendor-agreement-review) |\n | Data Processing Addendum, DPA, Data Processing Agreement (as exhibit or standalone) | note for **vendor-agreement-review** → data protection section |\n | Service Level Agreement, SLA (as exhibit) | note for **saas-msa-review** → SLA section |\n\n Multiple skills may apply. Common combinations:\n - MSA + DPA exhibit → vendor-agreement-review, with DPA noted\n - SaaS subscription + Order Form + SLA exhibit → saas-msa-review (covers all three)\n - MSA + Order Form with auto-renewal → vendor-agreement-review + saas-msa-review overlay\n\n When the structure is genuinely ambiguous after reading titles (e.g., a document titled \"Agreement\" with no exhibits listed), read the first two pages of the body to resolve it — then stop and route.\n\n5. **Confirm routing if enabled.**\n\n If `confirm_routing` is `true` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) (or field is absent):\n\n ```\n I'm going to review this as: [agreement type(s)].\n\n Documents identified:\n - [Main agreement title] → [skill]\n - [Exhibit A title] → [how it will be handled]\n - [Exhibit B title] → [how it will be handled]\n\n Sound right? (yes / no — or tell me what I got wrong)\n ```\n\n Wait for confirmation before proceeding. If the user corrects the routing, apply their instruction and proceed.\n\n If `confirm_routing` is `false`: proceed silently. Log the routing decision at the top of the review memo so the user can see what was applied.\n\n6. **Run the skill(s).** Follow each skill's workflow fully. If multiple skills apply, run them in sequence and integrate the output into a single memo — don't produce separate memos.\n\n7. **Check for escalations:** If any issue exceeds the reviewer's authority per the your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) matrix, invoke **escalation-flagger** to route and draft the ask.\n\n8. **Offer follow-ups:**\n - Stakeholder summary for the business owner\n - Redline .docx with tracked changes\n - [CLM] record creation (if connected)\n - Add to renewal register (if auto-renewal found)\n\n## Configuring confirm_routing\n\nAdd to your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Review preferences`:\n\n```markdown\n## Review preferences\n\nconfirm_routing: true # Set to false to skip routing confirmation and proceed automatically\n```\n\nThe cold-start interview should ask about this preference. Default is `true` — confirmation on. As trust builds, the user can set it to `false`.\n\n## Examples\n\n```\nthe “Review” workflow vendor-msa.pdf\n```\n\n```\nthe “Review” workflow https://drive.google.com/file/d/ABC123\n```\n\n```\nthe “Review” workflow\n[paste agreement text]\n```\n\n## Output\n\nFull review memo per the skill's format. Routing decision logged at the top. Deviation-by-deviation, specific redline language, named approver. Saved where your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → House style says work product goes.", + }, + { + id: "builtin-cfl-commercial-saas-msa-review", + title: "SaaS MSA Review", + practice: "Commercial Contracts", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “saas-msa-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# SaaS / Subscription Agreement Review\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nSaaS agreements have a distinct risk profile from one-time vendor contracts. The dollars compound over renewals, the data accumulates, and the switching cost grows every month. This skill reviews with that in mind.\n\nIt runs the standard playbook check from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) and adds a SaaS-specific overlay on the terms that bite hardest in subscription deals.\n\n## Jurisdiction assumption\n\nSaaS terms (auto-renewal notice requirements, price-escalation caps, data-portability mandates, subprocessor rules) are jurisdiction-sensitive — California, New York, and EU rules diverge materially, and some states have auto-renewal statutes that override private contract terms. This review applies the team's positions from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), which assume the governing law recorded there. If the agreement picks a different governing law, or the deal spans jurisdictions with statutory overrides (e.g., EU-based users, California consumers), flag it — the analysis may not transfer as written.\n\n> **No silent supplement.** If a research query to the configured legal research tool (Westlaw, or firm platform) returns few or no results for a statutory override that might bear on the deal (auto-renewal statute, data-portability mandate, consumer-protection rule), report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [jurisdiction / rule]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Where the review cites a statute, regulation, or case (e.g., a state auto-renewal law overriding contract terms), tag the citation: `[Westlaw]`, `[statute / regulator site]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations from the counterparty draft or house files. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n## Load the playbook\n\n**Which side?** Before applying the playbook, determine which side the company is on for this SaaS agreement. Usually obvious: if the counterparty is a SaaS vendor selling you their platform, you're purchasing-side. If you are the SaaS vendor and the counterparty is your customer, you're sales-side. If it's not obvious (a reseller arrangement, a white-label deal), ask: \"Which side is [company] on for this agreement — vendor or customer?\" Read the matching playbook section (`### Sales-side playbook` or `### Purchasing-side playbook`) from the config. Note which side in the output so the reviewer knows which playbook was applied. If the matching side is `[Not configured]`, stop and tell the user to run `configure your Practice Profile (Account → Practice Profile) --side ` before this review can proceed.\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) first. The general playbook for the matching side (liability, indemnity, termination, governing law) applies fully — run all the standard checks from the vendor-agreement-review skill.\n\nThen look for a `## Playbook` → matching side → `SaaS positions` section. That's where the team records its positions on auto-renewal notice windows, acceptable price escalators, data export rights, SLA thresholds, subprocessor approval rights, and deprecation notice. This skill does not ship with defaults for these — the right numbers vary by deal size, vendor leverage, and the team's risk tolerance.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) doesn't address a SaaS-specific term that comes up in this review, ask:\n\n> Your playbook doesn't cover [term — e.g., \"maximum acceptable auto-renewal notice window\" or \"whether vendor retention of anonymized derivatives is acceptable\"]. What's your team's position? I'll add it to your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\nRecord the answer and proceed.\n\n## SaaS-specific overlay\n\nFor each category below, list what you found in the contract and compare to the team's position in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Do not apply hardcoded thresholds from this skill.\n\n### 1. Auto-renewal mechanics\n\nThe single most common way a SaaS deal goes wrong: nobody notices the renewal notice window and we're locked in for another year at a higher price.\n\nCheck each element and compare against the team's `SaaS positions` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Renewal term length** (e.g., same as initial, longer, multi-year auto-convert)\n- **Notice-to-cancel window** (number of days before renewal)\n- **Notice method** (email, written notice to legal, portal-only, certified mail)\n- **Price on renewal** (same, CPI-capped, then-current list, uncapped discretionary)\n\n**Extract and record** the exact renewal date and the notice window regardless of whether any item is flagged. This feeds the renewal-tracker skill.\n\n### 2. Price escalation\n\nCheck each element against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Annual escalator** (fixed %, CPI, uncapped, etc.)\n- **Usage overage pricing** (published rate card, premium rate, unspecified)\n- **Scope of \"fees\"** (subscription only vs. \"additional services\" broadly defined)\n\n### 3. Data portability and exit\n\nWhen (not if) we leave this vendor, can we get our data out? Check each element against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Export format** (open/standard, proprietary-but-documented, \"commercially reasonable\")\n- **Export availability** (self-serve anytime, on request during term, only at termination)\n- **Post-termination access** (days available to export after termination)\n- **Export cost** (free, T&M, per-GB or per-record)\n- **Deletion certification** (certified on request, none, vendor retains derivatives)\n\nVendor retention of \"anonymized\" or \"aggregated\" derivatives is a material position — confirm the team's stance in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) and flag either way.\n\n### 4. Uptime and SLA\n\nOnly matters if the business actually depends on this service being up. If it's a nice-to-have tool, skip this section — don't spend negotiating capital on SLAs for a survey tool.\n\nCheck each element against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Uptime commitment** (percentage, or \"commercially reasonable efforts\")\n- **Measurement period** (monthly, quarterly, annual)\n- **Remedy** (service credits — how calculated, whether capped, whether sole remedy)\n- **Scheduled maintenance exclusions** (defined window, advance notice, unlimited)\n- **Credit-as-sole-remedy** interaction with the liability cap\n\n### 5. Subprocessors\n\nThis is a data protection issue but it's SaaS-specific because the subprocessor list *changes* over the life of the subscription.\n\nCheck each element against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Current list** (published, on request, unavailable)\n- **Change notification** (advance notice period, or none)\n- **Objection rights** (blocking, notice-and-terminate, notice-only, none)\n\n### 6. Service changes and deprecation\n\nSaaS vendors change their product. Usually fine. Sometimes they deprecate the thing you bought.\n\nCheck each element against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Material adverse changes** (right to terminate on material degradation, notice-only, unrestricted)\n- **Deprecation notice period** for features the team relies on\n- **Feature parity on replacement** (same price tier, higher tier)\n\n\n\n## AI and machine learning rights\n\n**AI/ML data rights decision procedure.** Don't just check whether an AI training clause exists. The #1 emerging negotiation point in SaaS contracts is structurally more than a one-line existence check. Work through:\n\n1. **Explicit grant.** Does the contract explicitly grant the vendor rights to use Customer Data / Customer Content / Usage Data for AI training, model improvement, or ML development? Purchasing-side: this is usually a NO — customer data training the vendor's models means the customer is subsidizing the vendor's product and possibly leaking competitive information. Sales-side: this is revenue if you get it, reputation risk if you abuse it.\n2. **Implicit grant via policy.** Does the contract incorporate the vendor's privacy policy or terms of service by reference? Can the vendor add training rights via a unilateral policy update? Check: \"The parties agree to the Provider's Privacy Policy as updated from time to time\" is a training-rights grant waiting to happen. Also watch for \"service improvement\" or \"analytics\" catch-alls and \"usage data\" definitions that carve logs/telemetry out of the Customer Data definition so data-use restrictions don't apply.\n3. **Anonymization standard.** If the vendor claims it only trains on \"anonymized\" or \"aggregated\" data, what's the standard? \"Anonymized\" without a definition is weak. Does it meet GDPR Recital 26 / HIPAA Safe Harbor / a named standard? Is it reversible?\n4. **Competitive contamination.** Does the vendor serve your competitors? If so, training on your data could leak competitive intelligence into outputs your competitors see. Is there a competitive isolation commitment?\n5. **Opt-out scope and durability.** If there's an opt-out, does it cover all AI uses or only some? Does it survive renewals and TOS updates? Is it per-user or per-org? Many vendors default to training and offer an opt-out buried in an admin console — check whether the contract makes the default explicit.\n6. **Output ownership.** If the SaaS product is itself AI-generated (drafting, summarization, analysis), who owns the outputs? Can the vendor use your outputs as training examples? Check third-party AI subprocessors too — the vendor may send customer data to a third-party LLM (OpenAI, Anthropic, Google) and the subprocessor list / data flow is where that shows up.\n7. **Downstream regulatory chain.** Does the vendor's use of your data for AI create regulatory exposure for YOU? EU AI Act deployer obligations, FTC §5 undisclosed data-sharing exposure (see *FTC v. Humor Rainbow/OkCupid*), state AI laws.\n\nMatch each to a playbook position. The practice profile's `## AI/ML training rights` section should have positions for each. If the agreement is silent on all seven, that's still a finding: \"The agreement is silent on AI/ML training rights — request an explicit prohibition or a defined carve-out tied to each of the seven dimensions above.\"\n\n## Liability cap decision procedure\n\n**The cap amount is the least important part of the cap.** Limitation-of-liability is not a single \"check against playbook\" item. Work through:\n\n1. **Direct vs. indirect/consequential damages.** Does the cap apply to ALL liability, or only direct damages? A 12-month cap on direct damages with uncapped consequential damages is a completely different position than a 12-month aggregate cap. State both treatments explicitly.\n\n2. **The cap base — quote it verbatim.** \"12-month cap\" could mean: (a) fees paid in the 12 months preceding the claim, (b) fees payable in the current 12-month period, (c) fees over the last 12 months of usage, (d) fees under the current order form, (e) total fees ever paid. These can differ by an order of magnitude. Quote the exact language. If ambiguous, flag it: \"Cap base is ambiguous — `[the quoted language]` — could mean [X] or [Y]. Confirm before signing.\"\n\n3. **Cap-carveout interaction.** A $100K cap with uncapped indemnity for data breach, IP, and confidentiality is functionally uncapped for the claims that actually arise in SaaS disputes. Enumerate what sits ABOVE the cap (the carveouts), what sits BELOW (what's actually capped), and assess whether the capped surface is meaningful: \"The cap covers [general contract breach]. Data breach, IP indemnity, and confidentiality are carved out and uncapped. For this vendor's risk profile, the capped surface is [meaningful / nominal].\"\n\n4. **Your playbook position per dimension.** The practice profile should have positions for: direct cap (multiple of fees), indirect damages (excluded / capped / uncapped), carveout list (what's acceptable above the cap), and cap base (which definition you'll accept). If the playbook has one \"standard position\" field, note: \"Your playbook has a single cap position — consider splitting into direct/indirect/carveouts/base for more precise review.\"\n\n## Jurisdiction delta check\n\n**The playbook applies one governing-law preference globally. Enforceability varies materially.** Check the SaaS contract's actual governing law against the top divergences before accepting playbook positions at face value:\n\n- **Non-solicits/non-competes:** Unenforceable in CA (Bus. & Prof. Code §16600). Restricted in many EU jurisdictions. Enforceable with limitations elsewhere. `[jurisdiction — verify]`\n- **Auto-renewal:** CA GBL §17600-17606, NY GBL §527-a, IL 815 ILCS 601 have specific consumer/B2B notice requirements. Other states vary. `[jurisdiction — verify]`\n- **Liability exclusions:** EU and UK unfair contract terms rules (UCTA 1977, Consumer Rights Act 2015) constrain consumer exclusions. Some US states limit exclusion of gross negligence or willful misconduct. `[jurisdiction — verify]`\n- **Indemnification:** Some states void indemnification for the indemnitee's own negligence. `[jurisdiction — verify]`\n- **Confidentiality term:** Some jurisdictions limit \"perpetual\" confidentiality to a reasonable period. `[jurisdiction — verify]`\n\nWhen the playbook position conflicts with the contract's governing-law enforceability, flag: \"Your playbook prefers [X], but this contract is governed by [Y] law where [X] is [unenforceable / restricted / subject to statutory override]. `[jurisdiction — verify]`\"\n\n## Redline granularity\n\n**Edit at the smallest possible granularity.** A redline is a negotiation artifact, not a rewrite. Wholesale clause replacement signals \"we threw out your drafting\" — it's aggressive, it forces the counterparty to re-read the whole clause, and it discards the parts of their drafting that were fine. Surgical redlines — strike a word, insert a phrase, restructure a subclause — signal \"we have specific asks\" and are faster to read, understand, and accept.\n\nDefault to the smallest edit that achieves the playbook position:\n- Replace a **word** before a phrase. (\"twelve (12)\" → \"twenty-four (24)\")\n- Replace a **phrase** before a sentence. (\"paid by the Buyer\" → \"paid and payable by the Buyer\")\n- Restructure a **subclause** before replacing the sentence. (Add \"(a)\" and \"(b)\" to split a compound condition.)\n- Replace a **sentence** before replacing the clause.\n- Only replace a **whole clause** when the counterparty's version is so far from your position that surgical edits would be harder to read than a fresh draft — and when you do, say so in the transmittal: \"We've replaced §8.2 rather than marking it up because the changes were extensive. Happy to walk you through the delta.\"\n\nWhen in doubt, smaller. A client who receives a surgical redline trusts that you read carefully. A client who receives a wholesale replacement wonders whether you read at all.\n\n## Output\n\nUse the vendor-agreement-review memo structure, with a SaaS-specific section added after the standard playbook checks. The vendor-agreement-review memo already carries the privilege header.\n\n**Dual severity.** Every SaaS-specific finding carries both axes (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Dual severity`):\n- **Legal risk:** 🔴 Critical | 🟠 High | 🟡 Medium | 🟢 Low\n- **Business friction:** 🔴 Blocks deals | 🟠 Slows deals | 🟡 Confuses customers | 🟢 Invisible\n\nData-exit, auto-renewal, and price-escalation findings are the ones most likely to be 🟢 legal / 🔴 business — the clause is enforceable, but it's the reason a customer can't leave or a renewal surprises finance. Surface those at the business-friction severity, not the legal one.\n\n```markdown\n### Bottom line\n\n[Can you sign / Need to fight for X first / Walk — one-sentence why]\n\n### AI and machine learning rights\n\n[The #1 emerging SaaS negotiation point. Flag: explicit ML training clauses, \"service improvement\" catch-alls, usage data definitions, output ownership, third-party AI subprocessors, opt-out vs opt-in. If the agreement is silent: \"Silent on AI/ML training rights — request explicit prohibition or defined carve-out.\"]\n\n## SaaS-specific findings\n\n### Auto-renewal\n**Renewal date:** [date]\n**Notice window:** Cancel by [date] ([N] days before renewal)\n**Renewal price mechanism:** [as written]\n**Playbook fit:** [within position / deviation / not addressed]\n**Flag for renewal-tracker:** [yes — and the record the tracker needs]\n\n### Price escalation\n[findings against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) positions]\n\n### Data exit\n[findings — this is the one the business owner should read]\n\n### SLA\n[findings, or \"Skipped — service is not business-critical per [stakeholder]\"]\n\n### Subprocessors\n[findings against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) positions]\n\n### Service changes\n[findings against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) positions]\n```\n\n## Handoffs\n\n**To renewal-tracker:** When you find the renewal date and notice window, hand them off. The renewal-tracker register expects the following fields (see `skills/renewal-tracker/references/renewal-register.yaml` for the full schema):\n\n```yaml\ncounterparty: [name]\nagreement: [title]\nsigned_date: [ISO date]\ninitial_term_end: [ISO date]\nrenewal_mechanism: [e.g., \"auto-renew annual\"]\nnotice_period_days: [integer]\ncancel_by_effective: [ISO date — initial_term_end minus notice_period_days]\nprice_on_renewal: [mechanism as written]\nannual_value: [integer, if stated]\nbusiness_owner: [email, if known]\nclm_id: [id if available]\nstatus: active\n```\n\nIf any field is not determinable from the contract or context, leave it out and note which fields were missing so the human can fill them in. `clm_id`, `annual_value`, and `business_owner` are especially likely to need human input.\n\n**To escalation-flagger:** If any of the SaaS-specific checks hits the team's \"never accept\" or escalation-trigger list in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), the escalation-flagger skill routes it.\n\n## A note on what to fight over\n\nSaaS vendors, especially large ones, negotiate their paper about as willingly as airlines negotiate ticket terms. Pick battles *per the team's playbook* — the `SaaS positions` section in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) should distinguish between terms the team will always push on, terms it fights over only for material deals, and terms it lets slide. If the playbook doesn't draw those lines, ask.\n\nCalibrate based on contract value and switching cost. A $5K/year tool with easy alternatives gets a lighter touch than a $500K/year platform we'll build on top of.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-commercial-stakeholder-summary", + title: "Stakeholder Summary", + practice: "Commercial Contracts", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “stakeholder-summary” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Stakeholder Summary\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nThe business owner who asked for this contract doesn't want a legal memo. They want to know: can I sign it, what's the catch, and what do I need to do. This skill takes a completed review and turns it into that.\n\n## Which side?\n\nThe underlying review memo was run against either the sales-side or the purchasing-side playbook. Carry that framing through. A purchasing-side summary tells the business owner \"here's what we're getting and what we agreed to give up\"; a sales-side summary tells them \"here's what we're selling and what we're on the hook for.\" Check which side the review was run on (it should be noted at the top of the review memo) and match the voice. If it's not obvious from the memo, ask the lawyer before summarizing.\n\n## Audience calibration\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## House style` → who reads stakeholder summaries, how long should they be. If not specified, default to: procurement or a department head, two paragraphs max, no legal terms of art.\n\nDifferent audiences need different summaries:\n\n| Audience | Cares about | Doesn't care about |\n|---|---|---|\n| **Procurement** | Price, renewal mechanics, approval routing | Liability cap structure |\n| **Department head (budget owner)** | Can their team use it, what happens if it breaks, cost | Indemnity scope |\n| **Finance** | Total cost of ownership, renewal price risk, off-balance-sheet commitments | Governing law |\n| **Security / IT** | Data handling, subprocessors, SOC 2, where data lives | Everything else |\n| **Executive sponsor** | Is this going to embarrass us, is legal a blocker | Details |\n\nAsk who this is for if it's not obvious from context.\n\n## The summary\n\n### Length cap — enforced\n\nThe summary is:\n- **One paragraph** for the verdict and what this is (business terms, plain English)\n- **One paragraph** for the catch — the thing the stakeholder would be surprised by later if nobody told them now\n- **A 2-3 item checklist** for what the stakeholder actually needs to do (at most three items; if you want a fourth, the first three aren't tight enough)\n- **A one-line close** with approval timing\n\n**Under 200 words total.** If you're writing more, you're including detail the stakeholder doesn't need — they have the memo for that. This is the quick read before the stakeholder hits reply.\n\nIf the close needs a third paragraph, fold it into the checklist instead. Don't let the close grow into a fourth block.\n\n### Scope of quote — discipline\n\nWhen quoting a contract clause (in the summary, in the \"catch\" paragraph, or in the checklist), quote the **full conditional sentence**, not a truncated version. A clause that reads \"Except as expressly provided in the Order Form, renewal of promotional or one-time priced subscriptions resets to list price\" means something different from \"renewal resets to list price\" — the truncation drops the condition and misrepresents what the term does.\n\nIf a full conditional quote doesn't fit the summary's length cap, paraphrase rather than truncate. \"For promotional pricing, renewal resets to list\" is a fair paraphrase; \"renewal resets to list\" is not — it promotes the exception to the rule.\n\n### Format\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n\n**[Counterparty] [Agreement type]** — [READY TO SIGN | NEEDS CHANGES | BLOCKED]\n\n[One paragraph: what this agreement does, in business terms. Not \"Master Services\nAgreement for the provision of cloud-based analytics\" — \"this is the contract\nfor the dashboard tool the marketing team wants.\"]\n\n[One paragraph: what the stakeholder needs to know. The catch, if there is one.\nThe thing that will surprise them later if nobody tells them now. E.g., \"Heads\nup: this auto-renews every year and we have to cancel 60 days out. I've added\nit to the tracker but you should know.\" Or: \"Clean agreement, no surprises,\ncleared to sign.\"]\n\n\n\n**Verify tracker entries before asserting them.** Before the summary says \"I've added it to the tracker\" (or any equivalent — \"it's in the tracker,\" \"tracked,\" \"set a reminder\"), verify that `renewal-tracker` has been run for this contract. Check the outputs folder or the matter folder for a `renewal-tracker` output that names this counterparty / agreement. If there isn't one:\n\n- Either run `renewal-tracker` for this contract first, then write the summary.\n- Or write the summary without asserting the tracker entry, and include an action item: \"Add to renewal tracker — not yet done.\"\n\nClaiming a tracker entry exists when it does not is worse than omitting the reassurance. The stakeholder then trusts the reminder that will never fire. If the truthful statement is \"tracked,\" the skill runs the tracker. If it's \"you should add this to your calendar — I haven't logged it,\" say that.\n\n**What you need to do:**\n- [ ] [Action item, if any — \"confirm the team is okay with data living in EU\"\n or \"nothing — I'll route for signature\"]\n\n**Approval:** [who's approving and expected timing]\n```\n\n### What to translate\n\n| Legal finding | Business translation |\n|---|---|\n| \"Liability capped at 12 months fees\" | \"If they break something, the most we can recover is a year's worth of what we paid them.\" |\n| \"No termination for convenience\" | \"Once we sign, we're locked in for the full term — we can't just cancel if we stop using it.\" |\n| \"Auto-renewal with 60-day notice\" | \"This renews automatically every year. To cancel, we have to tell them two months before the renewal date.\" |\n| \"No IP indemnity\" | \"If someone sues us claiming this tool infringes their patent, the vendor isn't on the hook to defend us.\" |\n| \"Subprocessor list not disclosed\" | \"We don't know what other companies will have access to our data through them.\" |\n| \"Data deletion within 30 days of termination\" | \"When we cancel, they delete our data within a month. Export anything you need before then.\" |\n| \"SLA credits capped at 10% of monthly fee\" | \"If the service goes down, we get a small credit back. It won't cover the cost of the downtime to the business.\" |\n\n### What NOT to include\n\n- Section numbers\n- Defined terms in quotes\n- The word \"indemnification\" (say \"they cover us if\" / \"we cover them if\")\n- The word \"notwithstanding\"\n- Risk matrices with colored dots (unless this stakeholder has specifically asked for them before)\n- Caveats about how this isn't legal advice — the stakeholder knows who sent it\n\n## When the review found problems\n\nIf the review has 🔴 or 🟠 issues, the summary still needs to be two paragraphs — but the second paragraph is \"here's what we're pushing back on and why.\"\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n\n**[Counterparty] [Agreement type]** — NEEDS CHANGES\n\n[What it is, one paragraph.]\n\nWe're going back to them on [N] things before this is ready. The main one:\n[the critical issue in plain English — \"they want the right to use our data\nto improve their product, which means our competitors' instance gets smarter\nfrom our data\"]. We've asked them to strike it. [Realistic assessment: \"They'll\nprobably agree\" / \"This might be a sticking point — will keep you posted.\"]\n\n**What you need to do:**\n- [ ] Nothing yet — I'll let you know when it's back from them.\n OR\n- [ ] [Business decision they need to make: \"If they won't budge on X, are you\n okay with Y, or do we walk?\"]\n```\n\n## Handoffs\n\n**From vendor-agreement-review / saas-msa-review:** Those skills produce the full memo. This skill reads the memo and compresses it. Don't re-review the contract — read the review.\n\n**To the stakeholder:** Via whatever channel your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) says. If Slack, keep it under 150 words. If email, the format above is fine as-is.\n\n## Escalation-fan-out reconciliation\n\nThe upstream review is a one-to-many producer: it can name five escalation targets (Deputy GC, CISO, Privacy Officer, CFO, business owner) across different findings. `escalation-flagger` routes one finding at a time. Without a reconciliation step, the Deputy GC sees the memo and the other four approvers never do.\n\nBefore producing the summary, read the upstream review memo and tally escalations:\n\n1. **Count the escalation targets the review named.** Look for the routing / escalation block at the end of the review, or for per-finding \"escalate to [X]\" tags. De-dupe by approver name — a reviewer named for two findings counts once.\n2. **Count the escalations actually routed.** Read the review folder (or matter folder) for `escalation-*.md` drafts produced by `escalation-flagger` since the review was written. Each draft names one approver.\n3. **Reconcile.** If N approvers were named and M drafts exist, (N − M) escalations have not been routed.\n\nInclude a short reconciliation block in the summary — above the checklist, below the catch paragraph:\n\n```markdown\n**Escalation status:** [M] of [N] escalation targets routed. The following have not been routed and require action:\n- [Approver name] — [one line on the finding that named them]\n- [Approver name] — [one line]\n```\n\nIf all N have been routed:\n```markdown\n**Escalation status:** [N] of [N] escalation targets routed.\n```\n\nIf the upstream review surfaced no escalations, omit the block.\n\n**Do not omit a named approver from the reconciliation because the stakeholder wouldn't recognize the name.** Business stakeholders often do not know who the Privacy Officer or CISO is. The reconciliation is internal-facing — it tells the lawyer sending the summary whether all the routing is done, not the stakeholder. If the stakeholder-facing summary needs to stay narrow, the reconciliation can live in a \"routing status\" footer or attached note — but it has to exist. A summary that implies routing is complete when it is not is worse than no summary.\n\n**Word-count carve-out.** The escalation reconciliation block is exempt from the 200-word cap. Length-cap discipline on the summary body stays; the reconciliation is housekeeping, not narrative.\n\n**When no escalation-flagger drafts exist.** If the upstream review named approvers and no drafts are in the folder, treat the count as M = 0. The reconciliation block lists all N as unrouted. That is the finding.\n\n## A note on tone\n\nStakeholders remember two things about legal: did it block me, and did it make sense. This skill is how legal makes sense. Write like you're explaining it to a smart colleague over coffee, not like you're writing a memo to file.\n\nIf the honest summary is \"this is fine, sign it,\" say that. Don't pad a clean review into three paragraphs to look thorough.", + }, + { + id: "builtin-cfl-commercial-vendor-agreement-review", + title: "Vendor Agreement Review", + practice: "Commercial Contracts", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “vendor-agreement-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Vendor Agreement Review\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nRead a vendor agreement against the playbook this team actually uses (in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)), find every term that deviates, and tell the lawyer what to do about each one — with specific redline language, not vague \"consider revising.\"\n\nThe output is a review memo the lawyer can act on in one pass. Every issue has a severity, a business-impact explanation, a proposed fix, and an escalation call if one is needed.\n\n## Precondition: load the playbook\n\n**Before reading the contract, read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If it's missing or still has placeholders, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor playbook positions, escalation, and house style to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll review tailored to YOUR playbook.\n> - Say **\"provisional\"** and I'll review against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook (flag all common vendor-contract risks from first principles) — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" run the review normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction, no playbook (flag the common vendor-side risks from first principles — unlimited liability, no data-breach carveout, uncapped indemnity, auto-renewal without notice, etc. — rather than matching to configured positions). Tag the reviewer note and every finding block with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your playbook, your jurisdiction, your risk appetite. 2 minutes.\"\n\n**Which side?** Before applying the playbook, determine which side the company is on for this contract. Usually obvious: if the counterparty is a vendor/supplier providing goods or services, you're purchasing-side. If the counterparty is a customer buying your product/service, you're sales-side. If it's not obvious (a reseller agreement, a partnership, a revenue share), ask: \"Which side is [company] on for this agreement — vendor or customer?\" Read the matching playbook section (`### Sales-side playbook` or `### Purchasing-side playbook`) from the config. Note which side in the output so the reviewer knows which playbook was applied. If the matching side is `[Not configured]`, stop and tell the user to run `configure your Practice Profile (Account → Practice Profile) --side ` before this review can proceed.\n\nThis skill is typically used for purchasing-side contracts (vendors supplying you), but the side check still applies — a \"vendor agreement\" could be your own template sent to a vendor as part of a reseller arrangement (sales-side).\n\nThe playbook in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) is the source of truth. It tells you:\n- What this team's standard positions are (not market standard — *their* standard)\n- What fallbacks they've accepted before\n- What they never accept\n- Who approves what\n- The one deal-breaker to check first\n\nIf the contract has the deal-breaker, flag it at the top of the memo and stop the detailed review. There's no point spending 30 minutes on liability caps if the agreement gives the vendor rights to use customer data for training.\n\n## Workflow\n\n### Step 1: Orient\n\nRead the whole agreement once, fast. Answer:\n\n| Question | Answer |\n|---|---|\n| What kind of agreement is this? | MSA / SaaS subscription / Professional services / License / Other |\n| Who are we? | Customer / Vendor (this plugin assumes customer — flag if not) |\n| Counterparty | Name, and are they a BigCo (won't negotiate) or a startup (will)? |\n| Dollar value | Annual / total contract value if stated |\n| Term | Length, renewal mechanics |\n| Is there a DPA? | Attached / referenced by URL / missing |\n| Is there an order form? | Separate doc or integrated |\n\n**Dollar-value handling.** If the main agreement does not state a dollar value (the MSA sets terms but the Order Form carries price, which is typical), **stop and ask** before running escalation math or applying dollar thresholds:\n\n> The MSA itself doesn't state an annual contract value. The Order Form carries the price. Your escalation threshold is $[X from the matrix]. Before I route this, I need the ACV. Options:\n> 1. Paste the Order Form value (preferred — I'll use it for routing and the memo).\n> 2. Tell me if this is above or below $[threshold] and I'll route accordingly; the memo will flag that the routing assumed [above/below threshold] without an ACV in hand.\n> 3. Route conservatively to the higher approver regardless — safer for a review you haven't priced.\n\nDo NOT silently assume a value and then use the assumed value to drive routing. The assumption propagates into the approval call, which is a place the review shouldn't be guessing.\n\n**DPA-by-reference handling.** If the main agreement incorporates a DPA \"available at [URL]\" or \"as set forth at [URL]\" or similar by reference, the DPA is part of the contract but is not in front of you. Note it explicitly in the Orient table and in the review memo:\n\n> This agreement incorporates a DPA by URL reference at `[URL]`. The DPA carries the real data terms — subprocessor rights, breach-notification timing, data-return mechanics, standard contractual clauses, audit rights. Without reading it, the data-protection analysis below is partial. Offer to route the DPA to `the “DPA Review” workflow` (if installed) for a separate review, or fetch and read it inline before completing Step 3's data-protection analysis.\n\nIf the user is installed with `privacy-legal`, explicitly offer:\n\n> Want me to hand the DPA URL to `the “DPA Review” workflow` once you're ready? That skill is built for the DPA work and will catch subprocessor / SCC / breach-notification issues that this skill only flags at the gate.\n\nDo not silently proceed as if the DPA were absent when it is incorporated by reference. A missing DPA and an unread DPA are different gaps — label them differently.\n\n### Step 2: Deal-breaker check\n\nCheck the \"one thing\" from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) first. If present:\n\n```markdown\n## ⛔ DEAL-BREAKER PRESENT\n\n**Section [X.X]** contains [the deal-breaker]. Per the team playbook, this is a\nhard no. Recommend:\n\n- [ ] Push back — propose [specific alternative language]\n- [ ] Walk — if counterparty won't move, we don't sign\n\nDetailed review below is provided for completeness but is moot unless this is\nresolved.\n```\n\n### Step 3: Term-by-term comparison\n\nFor each playbook category in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), find the corresponding contract section and compare.\n\n**For each deviation, produce:**\n\n```markdown\n### [Section X.X]: [Issue name]\n\n**Playbook says:** [our standard position, quoted from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\n**Contract says:**\n> \"[exact quote from the contract]\"\n\n**Gap:** [Missing term | Weaker than standard | Weaker than fallback | Non-standard structure | Unacceptable]\n\n**Legal risk:** 🔴 Critical | 🟠 High | 🟡 Medium | 🟢 Low\n**Business friction:** 🔴 Blocks deals | 🟠 Slows deals | 🟡 Confuses customers | 🟢 Invisible\n\n**Why it matters:** [one or two sentences in plain English — what goes wrong\nfor the business if this term stays as-is]\n\n**Proposed redline:**\n> \"[the specific replacement language — ready to paste into a markup]\"\n\n**If they won't move:** [the fallback from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), or \"escalate to [person]\"\nif no fallback exists]\n```\n\n**Severity calibration:**\n\n| Level | Means |\n|---|---|\n| 🔴 Critical | Don't sign without fixing. A term on the team's \"never accept\" list in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), or a deal-breaker. |\n| 🟠 High | Strongly push; escalate if they won't move. A term outside the playbook's stated fallback range. |\n| 🟡 Medium | Push in first round; accept if it's the last open item. A term inside the fallback range but short of the standard position. |\n| 🟢 Low | Note it, don't spend capital. A term the playbook explicitly tolerates, or a purely stylistic deviation. |\n\nSeverity is always applied *against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)*. If a term doesn't map cleanly to a playbook position, ask the user which bucket it belongs in and offer to record the answer in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n#### Liability cap decision procedure\n\n**The cap amount is the least important part of the cap.** When reviewing the limitation-of-liability clause, do not produce a single \"check liability cap against playbook\" line item. Work through the four dimensions below and state each one explicitly in the finding:\n\n1. **Direct vs. indirect/consequential damages.** Does the cap apply to ALL liability, or only direct damages? A 12-month cap on direct damages with uncapped consequential damages is a completely different position than a 12-month aggregate cap. State both treatments explicitly.\n\n2. **The cap base — quote it verbatim.** \"12-month cap\" could mean: (a) fees paid in the 12 months preceding the claim, (b) fees payable in the current 12-month period, (c) fees over the last 12 months of usage, (d) fees under the current order form, (e) total fees ever paid. These can differ by an order of magnitude. Quote the exact language. If ambiguous, flag it: \"Cap base is ambiguous — `[the quoted language]` — could mean [X] or [Y]. Confirm before signing.\"\n\n3. **Cap-carveout interaction.** A $100K cap with uncapped indemnity for data breach, IP, and confidentiality is functionally uncapped for the claims that actually arise in SaaS disputes. Enumerate what sits ABOVE the cap (the carveouts), what sits BELOW (what's actually capped), and assess whether the capped surface is meaningful: \"The cap covers [general contract breach]. Data breach, IP indemnity, and confidentiality are carved out and uncapped. For this vendor's risk profile, the capped surface is [meaningful / nominal].\"\n\n4. **Your playbook position per dimension.** The practice profile should have positions for: direct cap (multiple of fees), indirect damages (excluded / capped / uncapped), carveout list (what's acceptable above the cap), and cap base (which definition you'll accept). If the playbook has one \"standard position\" field, note: \"Your playbook has a single cap position — consider splitting into direct/indirect/carveouts/base for more precise review.\"\n\n#### Jurisdiction delta check\n\n**The playbook applies one governing-law preference globally. Enforceability varies materially.** Check the contract's actual governing law against the top divergences before accepting playbook positions at face value:\n\n- **Non-solicits/non-competes:** Unenforceable in CA (Bus. & Prof. Code §16600). Restricted in many EU jurisdictions. Enforceable with limitations elsewhere. `[jurisdiction — verify]`\n- **Auto-renewal:** CA GBL §17600-17606, NY GBL §527-a, IL 815 ILCS 601 have specific consumer/B2B notice requirements. Other states vary. `[jurisdiction — verify]`\n- **Liability exclusions:** EU and UK unfair contract terms rules (UCTA 1977, Consumer Rights Act 2015) constrain consumer exclusions. Some US states limit exclusion of gross negligence or willful misconduct. `[jurisdiction — verify]`\n- **Indemnification:** Some states void indemnification for the indemnitee's own negligence. `[jurisdiction — verify]`\n- **Confidentiality term:** Some jurisdictions limit \"perpetual\" confidentiality to a reasonable period. `[jurisdiction — verify]`\n\nWhen the playbook position conflicts with the contract's governing-law enforceability, flag: \"Your playbook prefers [X], but this contract is governed by [Y] law where [X] is [unenforceable / restricted / subject to statutory override]. `[jurisdiction — verify]`\"\n\n### Step 4: Favorable terms and gaps\n\nTwo short lists:\n\n**Better than our standard:** Terms where the vendor gave us more than we'd ask for. Note these — they're trade bait if you need to give something up elsewhere.\n\n**Missing entirely:** Standard provisions that just aren't there. Most common: assignment restrictions, audit rights (if we want them), force majeure, insurance requirements.\n\n### Step 5: Escalation routing\n\nCheck the escalation matrix in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) against:\n- Contract dollar value\n- Presence of any 🔴 critical issues\n- Any automatic-escalation triggers (unlimited liability, IP assignment, etc.)\n\nState clearly who needs to approve this:\n\n```markdown\n## Approval routing\n\nBased on [dollar value / issue severity], this agreement requires:\n\n- [ ] **[Name/role]** approval — [reason]\n- [ ] **Business owner sign-off** on [specific commercial term they should weigh in on]\n\n**Recommended next step:** [Send redlines to counterparty | Escalate to GC before\nresponding | Get business input on commercial term X before legal responds]\n```\n\n**Before proceeding to send redlines to the counterparty:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Sending redlines is a legal act — the counterparty will treat every edit as our negotiating position. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: counterparty, agreement type, the specific redlines proposed, the playbook positions behind each, the fallbacks, and what to ask the attorney before the package leaves.]\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not proceed past this gate without an explicit yes.\n\n## Redline granularity\n\n**Edit at the smallest possible granularity.** A redline is a negotiation artifact, not a rewrite. Wholesale clause replacement signals \"we threw out your drafting\" — it's aggressive, it forces the counterparty to re-read the whole clause, and it discards the parts of their drafting that were fine. Surgical redlines — strike a word, insert a phrase, restructure a subclause — signal \"we have specific asks\" and are faster to read, understand, and accept.\n\nDefault to the smallest edit that achieves the playbook position:\n- Replace a **word** before a phrase. (\"twelve (12)\" → \"twenty-four (24)\")\n- Replace a **phrase** before a sentence. (\"paid by the Buyer\" → \"paid and payable by the Buyer\")\n- Restructure a **subclause** before replacing the sentence. (Add \"(a)\" and \"(b)\" to split a compound condition.)\n- Replace a **sentence** before replacing the clause.\n- Only replace a **whole clause** when the counterparty's version is so far from your position that surgical edits would be harder to read than a fresh draft — and when you do, say so in the transmittal: \"We've replaced §8.2 rather than marking it up because the changes were extensive. Happy to walk you through the delta.\"\n\nWhen in doubt, smaller. A client who receives a surgical redline trusts that you read carefully. A client who receives a wholesale replacement wonders whether you read at all.\n\n### Step 6: Assemble the memo\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\nThis memo and the underlying agreement may be privileged, confidential, or both. The output inherits that status from the source. Distribute only within the privilege circle; mark and store it where privileged materials live; strip the work-product header before any external delivery (e.g., counterparty redlines, stakeholder summaries).\n\nThe playbook positions applied below reflect the jurisdiction recorded in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `Governing law and venue`. Legal rules and enforceability vary materially by jurisdiction. If this deal implicates a different governing law or a choice-of-law question, flag it in the memo — the analysis may not transfer as written.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for a rule the memo needs (enforceability of a limitation clause, indemnity scope, governing-law choice), report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / jurisdiction]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Where the memo cites a statute, regulation, or case, tag the citation: `[Westlaw]`, `[statute / regulator site]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations from the counterparty draft or house files. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n# Vendor Agreement Review: [Counterparty] [Agreement Type]\n\n**Reviewed:** [date]\n**Contract value:** $[amount] / [term]\n**Our role:** Customer\n\n---\n\n## Bottom line\n\n[Two sentences. Can we sign this? What has to change first?]\n\n**Issues (legal risk):** [N]🔴 [N]🟠 [N]🟡 [N]🟢\n**Issues (business friction):** [N]🔴 [N]🟠 [N]🟡 [N]🟢\n\n**Approval needed from:** [name]\n\n---\n\n## Deal-breaker check\n\n[✅ Clear | ⛔ Present — see above]\n\n---\n\n## Issues by severity\n\n[All the deviation blocks from Step 3, grouped Critical → Low]\n\n---\n\n## Favorable terms\n\n[list]\n\n## Missing provisions\n\n[list]\n\n---\n\n## Approval routing\n\n[from Step 5]\n\n---\n\n## Redline package\n\n[If requested: consolidated markup-ready language for all proposed changes]\n```\n\n## Integration: [CLM]\n\nIf a [CLM] MCP is connected, after the review:\n\n- Check if this counterparty already has agreements with us (may inform negotiating posture — \"we already gave them 24-month cap on the last deal\")\n- Pull the workflow template that matches this agreement type\n- Offer to create the [CLM] record with the review memo attached and approvers pre-routed\n\n## Integration: DocuSign\n\nIf DocuSign MCP is connected and the agreement is ready to sign (all greens or all issues accepted), offer to:\n- Generate the envelope\n- Route to signers in the right order per the escalation matrix\n\nDo **not** send anything for signature without explicit instruction. \"Ready to sign\" is the lawyer's call, not yours.\n\n**Before generating a signature envelope or routing for countersignature:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> This step has legal consequences (signing binds the company to the whole agreement). Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: counterparty, contract value, the issues found and how they resolved, any risk the lawyer accepted, and what to ask the attorney before envelope goes out.]\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not proceed past this gate without an explicit yes.\n\n## Output formats\n\n**Full memo (default):** As above. Goes in the [CLM] record or the Drive folder from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) house-style section.\n\n**Slack-sized summary:** Two lines and a link. For when someone asks \"is this okay?\" in a channel.\n\n```\n[Counterparty] [type] — NEEDS WORK. 1🔴 (uncapped liability §8.2), 2🟠. Full review: [link]. Needs [GC] approval.\n```\n\n**Redline doc:** If the user asks for it, output a .docx with tracked changes. Use the docx skill. Comments on each change cite the playbook position.\n\n## Quality checks before delivering\n\n- [ ] your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) was loaded and quoted — not generic market positions\n- [ ] Deal-breaker checked first\n- [ ] Every issue has specific replacement language\n- [ ] Risk levels are calibrated (not everything is Critical)\n- [ ] Approver is named, not \"escalate to legal\"\n- [ ] Counterparty context considered (BigCo vs. startup — affects what's worth fighting over)\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-corporate-ai-tool-handoff", + title: "Ai Tool Handoff", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “ai-tool-handoff” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# AI Tool Handoff\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nLuminance and Kira are good at one thing: reading 500 contracts and finding every change-of-control clause. They're less good at judgment — deciding whether a particular CoC provision is actually triggered by this deal structure.\n\nThis skill hands off the bulk extraction to the right tool, then runs the QA layer on what comes back.\n\n**Before you hand off:** try `tabular-review` first (`the “Tabular Review” workflow`). For anything the user's environment can handle — a few hundred documents, a defined column schema — native tabular review is faster to set up, has no per-document cost, and keeps the work product local. Hand off to Luminance/Kira when the corpus is genuinely too large, the team already has a license and workflow, or the matter requires a tool with a validated provenance chain.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → AI-assisted review:\n- Tool in use (Luminance / Kira / none)\n- What it's used for (which clause types)\n- Trust level (use as-is / spot-check / full re-review)\n- Handoff process (who loads, who QAs)\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) says no AI tool → this skill is a no-op. Everything goes through diligence-issue-extraction directly.\n\n## When to hand off\n\nHand off when all of:\n- Category has >50 documents (below that, faster to just read them)\n- Extraction target is a clause type the tool is good at (CoC, assignment, exclusivity, MFN, termination, auto-renewal)\n- Documents are reasonably uniform (all customer contracts on similar paper — not a mix of contracts, letters, and board minutes)\n\nDon't hand off:\n- Bespoke or heavily negotiated documents\n- Side letters and amendments (context-dependent, tools miss the interaction with the main agreement)\n- Anything where the question is \"what does this mean for the deal\" not \"does this clause exist\"\n\n## The handoff\n\n### Step 1: Prepare the batch\n\n- Identify documents for the batch (from VDR inventory)\n- Specify extraction targets per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) (which clause types)\n- Note the materiality threshold so tool output can be filtered\n\n### Step 2: Load (or instruct the loader)\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — who loads. If it's you, generate the load instructions. If it's someone else, generate the request:\n\n```markdown\n## [Tool] Load Request — [Deal code] — [Category]\n\n**Documents:** [N] docs from VDR folder [path]\n**Load to:** [Tool workspace/matter]\n**Extraction targets:**\n- Change of control / assignment\n- Exclusivity\n- [etc. per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\n**Filter output:** Flag only where extraction target is present — no need for \"no CoC clause found\" for every doc.\n\n**Return by:** [date]\n```\n\n### Step 3: QA the output\n\nWhen the tool returns results, apply the trust level:\n\n**\"Use as-is\":** Ingest directly into diligence findings. (Only if your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) says this — it's rare.)\n\n**\"Spot-check X%\":** Randomly sample X% of flagged documents. For each, read the actual clause and compare to the tool's extraction. If error rate is low, accept the batch. If errors found, widen the sample.\n\n**\"Full human review of flagged\":** Tool narrows the universe (500 docs → 80 with CoC clauses). Human reads all 80. Tool saved the time of reading the 420 clean ones.\n\n### Step 4: Judgment layer\n\nThe tool found the clauses. Now apply judgment:\n\nFor each flagged CoC provision: is it actually triggered by this deal?\n- Stock sale vs. asset sale vs. merger — different triggers\n- \"Change of control\" defined how in the contract — majority ownership? board control? something else?\n- Is there a carve-out for this type of transaction?\n\nThis is the part the tool can't do. Output goes to diligence findings in house format.\n\n## Output\n\n> The QA summary below is derived from VDR documents that are privileged, confidential, or both. It inherits the sources' privilege and confidentiality status — distribution beyond the privilege circle can waive privilege. Store with the matter's privileged files.\n\n```markdown\n## AI Tool Handoff Summary — [Category]\n\n**Tool:** [Luminance / Kira]\n**Documents processed:** [N]\n**Extraction targets:** [clause types]\n\n### QA\n\n**Trust level:** [per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n**Sample size:** [N] docs spot-checked\n**Error rate:** [X]% — [Accepted / Widened sample / Full re-review triggered]\n\n### Results\n\n| Clause type | Docs flagged | After judgment layer | Material |\n|---|---|---|---|\n| Change of control | [N] | [N actually triggered by deal structure] | [N above threshold] |\n| Assignment | [N] | [N] | [N] |\n\n**→ [N] findings added to diligence issues**\n**→ [N] consents added to closing checklist**\n```\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't run Luminance or Kira — it manages the handoff and QA. A human (or the tool's own interface) runs the extraction.\n- It doesn't replace the tool's output with its own judgment entirely — if your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) says spot-check 10%, check 10%, not 100%.\n- It doesn't decide the trust level — that's in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), set at cold-start based on the team's experience with the tool.", + }, + { + id: "builtin-cfl-corporate-board-minutes", + title: "Board Minutes", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “board-minutes” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Board Minutes\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nBoard minutes are a legal record. They need to be accurate, complete, and in a format that will hold up under scrutiny — whether that's a financing due diligence review, a regulatory inquiry, or an M&A data room. This skill drafts them in your house format so you spend your time reviewing and correcting, not formatting and re-typing.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Board & Secretary` section:\n - Minutes format (long-form narrative / action minutes / hybrid)\n - Minutes template extracted from seed documents (structure, resolution language, header format)\n - Board composition and committees\n - Written consents — what they're used for and any limits\n- If your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) has no minutes format: run cold-start first. Do not proceed with a generic format.\n\n---\n\n## Step 1: Identify the meeting\n\n### Calendar detection\n\nIf the calendar connector is authorized, search for upcoming events matching board and committee keywords:\n\n**Search terms:** \"Board of Directors\", \"Board Meeting\", \"Audit Committee\", \"Compensation Committee\", \"Comp Committee\", \"Nominating\", \"Nom/Gov\", \"Governance Committee\", \"Special Committee\", \"Board of Directors — [Company]\"\n\n**Time window:** Look 30 days forward. If no upcoming meeting is found, look 14 days back (minutes are often drafted after the fact).\n\nPresent what you find:\n\n> I found the following board or committee meetings on your calendar:\n>\n> 1. **[Meeting name]** — [Date], [Time], [Location/Virtual]\n> 2. **[Meeting name]** — [Date], [Time], [Location/Virtual]\n>\n> Which one are these minutes for? Or is it a different meeting not on here?\n\nIf the calendar connector is not authorized or returns nothing: ask directly — what meeting, what date, what type (full board / which committee)?\n\n### Meeting metadata to confirm\n\nOnce the meeting is identified, confirm or fill in:\n\n- **Meeting type:** Full Board of Directors / [Committee name]\n- **Date and time**\n- **Location or platform** (in-person address / Zoom / Teams / telephonic)\n- **Called by / Notice:** Was proper notice given? (Yes / waived — waiver of notice is a common exhibit)\n\n---\n\n## Step 2: Attendance\n\nAsk for the attendee list, or offer to pull from the calendar invite if the connector is authorized.\n\n**Directors present:**\n- Pull from board composition in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) as the starting point\n- Ask who was actually present, who was absent, and whether any absent directors had advance notice\n\n**Management present:**\n- Who from management attended? (CFO, CAO, CTO, etc.)\n- Note: management attendees are typically listed separately from directors\n\n**Guests:**\n- Outside counsel present? (Name and firm)\n- Investment bankers, auditors, or other advisors?\n- Any guests who attended for specific agenda items only (note their attendance as limited to that item)\n\n**Chair:**\n- Who chaired the meeting?\n- Who acted as secretary?\n\n**Quorum:**\n\n- Check the charter and bylaws for the quorum requirement. If the charter is silent, research the applicable state corporate law for the default rule for this entity type. Record what you confirmed (source and pinpoint) in the drafting notes.\n- Confirm quorum was present. If not: stop and flag before drafting. Do not produce minutes that imply a valid meeting occurred. Surface the question to outside counsel — the remediation path (ratification, re-meeting, written consent, other) depends on the state of incorporation and the nature of the action.\n\n---\n\n## Step 3: Materials\n\nAsk for the meeting materials. These are the source for the agenda items and any resolutions.\n\n> Can you share the agenda and any pre-read materials for this meeting? Even a rough agenda is enough to structure the minutes. If there were board slides or a management presentation, upload those too — I'll use them to fill in the agenda item summaries.\n>\n> If materials weren't distributed in advance, tell me the agenda items and I'll draft placeholders for each.\n\n**From the agenda and slides, extract:**\n- Agenda items in order\n- Any resolutions proposed (look for board approval language: \"approve,\" \"authorize,\" \"ratify,\" \"adopt,\" \"elect\")\n- Any exhibits referenced (management presentations, financial reports, legal memos, valuations)\n- Any votes expected\n\n**If no materials:** Ask for the agenda items verbally and proceed with placeholders for discussion content.\n\n---\n\n## Step 4: Draft the minutes\n\nUse the house format from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Do not default to a generic format. The seed minutes are the template — replicate the structure, the header, the resolution language, the level of discussion detail.\n\n### Standard structure (adapt to house format)\n\n**Header block:**\n```\nMINUTES OF [MEETING TYPE] OF THE BOARD OF DIRECTORS\n[OR: MINUTES OF THE [COMMITTEE NAME] OF THE BOARD OF DIRECTORS]\nOF [COMPANY NAME]\n\n[Date]\n[Location / Telephonic / Video Conference]\n```\n\n**Opening:**\n- Meeting called to order by [Chair name] at [time]\n- Notice: [proper notice given / notice waived — attach waiver as exhibit if applicable]\n- Quorum confirmed: [N of M directors present]\n- Secretary: [name]\n\n**Attendees:**\n- Directors present: [list]\n- Directors absent: [list, if any]\n- Also present: [management, outside counsel, guests — with roles]\n\n**Previous minutes:**\nStandard language: approval of minutes from prior meeting. Pull date of prior meeting from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) board calendar if available, otherwise leave as [DATE OF PRIOR MEETING].\n\n**Agenda items — one section per item:**\n\n```\n[AGENDA ITEM TITLE]\n\n[Chair/presenter name] [presented / reported on / led a discussion of] [topic].\n\n[Discussion summary — see drafting notes below]\n\n[If resolution follows:]\nUpon motion duly made and seconded, the following resolution was adopted [by unanimous vote / by a vote of N for, N against, N abstaining]:\n\nRESOLVED, that [resolution text in house language from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)].\n```\n\n**Adjournment:**\nStandard language: meeting adjourned at [time], there being no further business.\n\n**Signature block:**\nSecretary signature line. Some formats include a chair countersignature.\n\n---\n\n### Drafting notes\n\n**Discussion summaries:** The hardest part of minutes is deciding how much discussion to capture. Follow the house format from seed documents exactly:\n\n- *Long-form narrative:* Summarise the substance of the discussion — what questions were raised, what information was presented, what factors the board considered. Do not quote individuals unless the specific attribution matters legally.\n- *Action minutes:* Note only what was presented and what action was taken. No discussion content beyond \"the board discussed the matter.\"\n- *Hybrid:* Full narrative for major items (acquisitions, financials, significant approvals), action-only for routine items.\n\nWhen materials were provided: pull summary content from the slides and management presentation. The board \"received and reviewed\" a presentation — summarize what the presentation covered.\n\nWhen no materials: insert `[PLACEHOLDER — summarize discussion here]` and flag it clearly. Do not fabricate discussion content.\n\n**Resolutions:** Use the exact resolution language from the seed minutes — \"RESOLVED, THAT\" vs. \"BE IT RESOLVED\" vs. \"RESOLVED\" alone. The language is house style, not interchangeable.\n\n**Exhibit references:** Number exhibits in the order they appear (Exhibit A, B, C). Common exhibits: management presentation, financial statements, valuation reports, legal opinions, waivers of notice, consents.\n\n---\n\n## Step 4.5: Consequential-action gate (adopt minutes)\n\n**Before adopting minutes as final:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Adopting minutes makes them the official record of what the board decided — they're the primary evidence of authorization for the actions taken at the meeting. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - What was decided (resolutions, votes, who was present)\n> - What the draft captures and what is still a placeholder\n> - Open questions (any flagged attendance, quorum, or conflict notes)\n> - What could go wrong (misstated resolutions, missing disclosures, quorum defects, privilege leakage in discussion summaries)\n> - What to ask the attorney (is the discussion depth right for this board's practice; are exec-session notes properly segregated; do any items need more documentation)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not produce the final adoption-ready version past this gate without an explicit yes. A marked-DRAFT for attorney review is fine.\n\n---\n\n## Step 5: Output and review prompts\n\nProduce the full draft. The minutes themselves are a corporate record, not privileged; do not apply the work-product header to the minutes as circulated. The drafting notes, placeholder flags, and review checklist below are work product — prepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`):\n\n```\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n```\n\nAfter the draft, add a review checklist:\n\n```\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\nREVIEW CHECKLIST — please verify before circulating:\n\n□ All directors confirmed present/absent (check against actual attendance)\n□ Quorum confirmed correct\n□ Resolution language matches what was actually approved (check wording carefully)\n□ Votes recorded correctly — any abstentions or dissents to note?\n□ Exhibits numbered and referenced correctly\n□ Any executive sessions held? (Add separate executive session note if so)\n□ Any conflicts of interest disclosed? (Director recusal to note if applicable)\n□ Time of adjournment to fill in\n□ Outside counsel reviewed? (If required by your process)\n```\n\nFlag any sections where content is a placeholder and needs the attorney's input before the minutes are accurate.\n\nAdd as a final pre-adoption note on the draft, stripped before adoption:\n\n> This is a draft for attorney review, not adopted minutes. Adopted minutes are the official record of board action and carry legal consequences — a licensed attorney reviews, edits, and takes professional responsibility before adoption. Do not adopt this draft unreviewed.\n\n---\n\n## Written consents\n\nFor drafting written consents in lieu of a meeting, use `the “Written Consent” workflow`. That skill handles precedent search, state-law confirmation, and the scope warning for major one-off actions.\n\n---\n\n## What this skill does not do\n\n- It does not attend the meeting or capture real-time discussion — it drafts from materials and attorney input.\n- It does not determine whether a resolution is legally valid or sufficient — it drafts in house format; legal judgment on adequacy is the attorney's call.\n- It does not finalize minutes — the draft requires attorney review before circulation.\n- It does not distribute minutes — output is for the attorney to review, edit, and circulate via their own process.", + }, + { + id: "builtin-cfl-corporate-closing-checklist", + title: "Closing Checklist", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “closing-checklist” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /closing-checklist\n\n1. Read the current project's documents and use the modes below.\n2. If status update provided: Mode 3 (update item).\n3. Otherwise Mode 4: blocking items, critical path, days to close.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nDeals close when the checklist is done. Everything on it, done. Nothing missing. This skill maintains the list, ingests new items as they surface from diligence, and tells the team what's blocking.\n\n## The checklist\n\nLives at the current project's documents. Structure:\n\n```yaml\ndeal_code: \"Project Falcon\"\ntarget_close: [DATE]\nsigning_date: [DATE]\nlast_updated: [DATE]\n\nconditions_precedent:\n - id: CP-001\n item: \"HSR waiting period expiration\"\n category: \"Regulatory\"\n responsible: \"Buyer counsel\"\n due: 2026-04-15\n status: \"Filed 2026-03-01, waiting period runs\"\n blocking: true\n source: \"Purchase Agreement §7.1(a)\"\n\n - id: CP-002\n item: \"Acme Corp consent to assignment\"\n category: \"Third-party consents\"\n responsible: \"Target — Jane Doe\"\n due: 2026-04-20\n status: \"Request sent 2026-03-10, no response\"\n blocking: true\n source: \"Schedule 3.12(a)(4); Acme MSA §14.2\"\n\nclosing_deliverables:\n - id: CD-001\n item: \"Certificate of good standing — Target (DE)\"\n category: \"Corporate\"\n responsible: \"Target counsel\"\n due: 2026-04-28\n status: \"Not started\"\n blocking: true\n source: \"Purchase Agreement §2.3(b)(iv)\"\n\n # ... etc\n```\n\n## Modes\n\n### Mode 1: Initialize from the purchase agreement\n\nRead the signed (or near-final) purchase agreement. Extract:\n\n- Every condition precedent (location varies by agreement — read the actual section headings)\n- Every closing deliverable (closing deliverables schedule or corresponding section)\n- Every covenant with a pre-closing deadline\n\nEach becomes a checklist item with a source cite to the agreement section.\n\n**Research obligations before populating regulatory/approval items.** Antitrust, foreign-investment, and sector-specific approvals (for example, HSR-style filings, CFIUS, industry regulators) have jurisdiction-specific mechanics, thresholds, and timing windows that change. Extract the name of each regulatory condition from the PA, then research the currently operative mechanics (who files, when, what triggers a second request, what the waiting period is). Cite primary sources and verify currency. Do not populate a timing assumption from memory.\n\n**Material-adverse-effect / material-adverse-change closing conditions.** Pull the defined term from the PA — MAC/MAE framing is negotiated, not a standard. Research the governing-law interpretation of the specific language used (Delaware, New York, and other jurisdictions treat carve-outs and quantitative tests differently) before flagging an event as a potential MAC trigger.\n\n**Consent-requirement extraction from material contracts** depends on governing-law default rules and the specific anti-assignment language in each contract. Research the applicable rule per contract rather than assuming a default.\n\n### Mode 2: Ingest from diligence (the \"self-updating\" part)\n\nMode 2 is triggered when an upstream skill produces a finding with a pre-closing action. The upstream skills and output types this mode ingests:\n\n- **`diligence-issue-extraction` findings** — any finding flagged for a closing action (consent, shareholder vote, board resolution, regulatory filing, release, escrow mechanic, pay-off letter). Not just \"consents\" — see the extraction skill's Handoffs section for the full list.\n- **`material-contract-schedule` CoC / assignment items** — change-of-control provisions, anti-assignment clauses, MFN triggers surfaced during schedule build.\n- **`deal-team-summary` output** — the exec-tier brief aggregates extraction findings and sometimes surfaces a closing-action item that a mechanical read of the individual extraction memos would miss (e.g., a §280G cleansing vote rolled up across multiple employment agreements, or a composite consent package). Mode 2 reads the latest deal-team-summary in the deal folder and reconciles its closing-action items against the checklist. Anything flagged by deal-team-summary as requiring pre-closing action that is not already on the checklist is appended.\n\nThe handoff schema covers the full range of pre-closing actions, not just consents:\n\n```yaml\nhandoff:\n # Required fields\n item: \"[Counterparty or action, one line]\"\n category: \"[Third-party consents | Shareholder / board action | Regulatory filing | Release / termination | Escrow / holdback | Closing deliverable]\"\n source: \"[Contract name / statutory section / VDR path + Bates]\"\n blocking: true # unless the agreement has a materiality qualifier\n severity: \"[🔴 / 🟠 / 🟡 / 🟢 — carried from upstream, see severity-floor rule in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\"\n\n # Consent / third-party action fields\n counterparty: \"[e.g., Dunmore Holdings LLC]\"\n guarantor: \"[e.g., Buyer parent guaranty required, or N/A]\"\n conditions: \"[any substantive condition the counterparty attached — e.g., 'replacement guaranty from buyer parent required before consent effective']\"\n notice_deadline: \"[e.g., 30 days prior to closing, or specific date]\"\n\n # Corporate action fields\n approval_body: \"[Shareholders | Board | Committee | Regulator]\"\n approval_threshold: \"[e.g., 75% disinterested stockholder vote for §280G cleansing]\"\n statutory_or_charter_source: \"[e.g., IRC §280G(b)(5)(B); Charter Art. IV §2]\"\n\n # Timing\n estimated_time_to_complete: \"[e.g., 30 days]\"\n must_occur_before: \"[e.g., closing | signing | end of hiatus period]\"\n```\n\nPreserve every field the upstream skill populated. A \"Dunmore consent required, with replacement guaranty condition and 30-day notice\" should surface on the checklist with all three elements (consent, guarantor, notice), not collapse to \"Dunmore consent to change of control.\" When the upstream skill provides a severity, carry it — see the cross-skill severity floor rule in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\nAppend to the checklist. De-dupe on (counterparty + action type), not on the freeform item name — a Dunmore consent and a Dunmore release are different items even though both name Dunmore. When de-duping, merge fields rather than overwrite: if one handoff populated `guarantor` and a later handoff populated `notice_deadline`, the checklist row carries both.\n\n### Mode 3: Status update\n\nUser (or dataroom-watcher agent) provides a status update. Find the item, update status and last-updated.\n\n```\nthe “Closing Checklist” workflow\nCP-002: Acme responded, consent form attached, needs countersignature\n```\n\n### Mode 4: What's blocking\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n> This status report is derived from the purchase agreement, diligence findings, and internal deal records. It inherits their privilege and confidentiality status — distribution beyond the privilege circle (counterparty, broader business teams) can waive privilege. Confirm the distribution list before sending.\n\n## Closing Checklist Status — [Deal code] — [date]\n\n**Target close:** [date] ([N] days out)\n**Items:** [N] total — [N] done, [N] in progress, [N] not started\n\n### 🔴 Blocking and at risk\n\n| ID | Item | Due | Status | Days to due |\n|---|---|---|---|---|\n| [CP-XXX] | [item] | [date] | [status] | **[N]** |\n\n### 🟡 Blocking, on track\n\n[same table]\n\n### ✅ Complete\n\n[N] items — [collapsed list]\n\n### Not blocking (post-closing, informational)\n\n[N] items\n\n---\n\n**Critical path:** [The item(s) that, if they slip, push the close date]\n```\n\n## Critical path analysis\n\nNot all blocking items are equal. A consent that takes 30 days to get is critical path. A good-standing certificate that takes 2 days is not, even though both are blocking.\n\nFor each blocking item, estimate time-to-complete. The ones where `(due date - today) < estimated time` are at risk. Those go at the top of every status report.\n\nIf the checklist has more than ~10 items, or any time the user asks: offer the dashboard (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs → Dashboard offer for data-heavy outputs`). Shape the offer for this output — counts by status (done / in progress / not started / at risk), a critical-path view grouped by workstream, and a sortable grid with item, owner, due date, and days-to-due.\n\n## Integration: dataroom-watcher agent\n\nThe agent checks the checklist daily, pulls any status updates from email/Slack if connected, and posts the \"what's blocking\" report to the deal team channel. Mode 4 is the agent's output.\n\n## Consequential-action gate (certify closing)\n\n**Before producing a \"ready to close / all CPs satisfied\" certification or closing memo:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Certifying that closing conditions have been satisfied (or producing a closing memo asserting this) has legal consequences — it's the signal that drives funds flow and post-closing obligations. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - The full CP list with status (what's done, what's in progress, what's not started)\n> - Anything where evidence of completion is weak or missing\n> - Any waivers or side letters needed for items that won't close in time\n> - Open questions (counterparty consents still pending, any MAC/bring-down risk)\n> - What to ask the attorney (is this ready to call closed; are any conditions being walked past that shouldn't be; what needs to go on a schedule of exceptions)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not produce a final \"ready to close\" certification past this gate without an explicit yes. Status tracking and \"what's blocking\" reports do not require the gate.\n\n---\n\n## What this skill does not do\n\n- It doesn't obtain consents, file forms, or draft documents. It tracks that they need to happen.\n- It doesn't decide what's blocking — the purchase agreement decides that. This skill reads the agreement.\n- It doesn't close the deal. It tells you when you can.", + }, + { + id: "builtin-cfl-corporate-deal-team-summary", + title: "Deal Team Summary", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “deal-team-summary” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Deal Team Summary\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nThe deal lead doesn't read 200 findings. They read: what's material, what changed since last brief, what needs a decision. This skill compresses the diligence output to the right level for the reader.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Deal team briefing (cadence, format, what the business reads)\n- the current project's documents → deal lead, timeline\n- Current findings from diligence-issue-extraction output\n\n## Audience tiers\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — what the business reads vs. what's for the file. Default tiers:\n\n| Audience | Gets | Doesn't get |\n|---|---|---|\n| **Board / exec sponsor** | Top 3-5 material issues, price/structure impact, decision items | Category detail, green findings, process |\n| **Deal lead** | All reds, all yellows, progress, decision items, next steps | Green finding detail |\n| **Working team** | Everything — full findings, status by category, gaps | Nothing withheld |\n\nAsk which tier if not obvious.\n\n## The summary\n\n### Exec tier\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n> This brief aggregates privileged diligence findings and inherits the sources' privilege and confidentiality status. Distribution beyond the privilege circle (including to broader business teams) can waive privilege — confirm the distribution list matches the privilege circle before sending.\n\n# [Deal code] — Diligence Brief — [date]\n\n**Status:** [On track / Issues identified / Material findings]\n**Coverage:** [X]% of VDR reviewed\n\n## Material findings\n\n[3-5 max. One paragraph each. What it is, why it matters to the deal, what\nwe're doing about it.]\n\n## Decisions needed\n\n- [ ] [Specific decision — price adjustment, indemnity ask, walk-away trigger]\n — [who decides] — [by when]\n\n## Since last brief\n\n[What changed. New findings, findings resolved, coverage progress.]\n```\n\n### Deal lead tier\n\nSame as above plus:\n\n```markdown\n## All open issues by category\n\n### 🔴 Red\n[Finding title + one-line — link to full finding for detail]\n\n### 🟡 Yellow\n[same]\n\n## Progress\n\n| Category | Docs reviewed | Coverage | Reds | Yellows | Status |\n|---|---|---|---|---|---|\n| [name] | [N/M] | [%] | [N] | [N] | [Complete / In progress / Blocked] |\n\n## Gaps and follow-ups\n\n- [Supplemental request items outstanding]\n- [Questions to management]\n\n## Next 72 hours\n\n[What's getting reviewed, what briefings are scheduled]\n```\n\n### Working team tier\n\nFull finding detail. Same structure as above but every finding gets its full house-format block, not a one-liner.\n\n## Deltas\n\nIf this is a recurring brief (per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) cadence), lead with what changed:\n\n- New findings since last brief\n- Findings upgraded/downgraded in severity\n- Findings resolved (consent obtained, issue clarified away)\n- Coverage movement\n\nDeal leads care more about movement than state. \"Still 12 yellows\" is less useful than \"2 new yellows, 3 resolved.\"\n\n## Handoffs\n\n- **From diligence-issue-extraction:** This skill reads the accumulated findings.\n- **To closing-checklist:** Any \"decision needed\" items that resolve into closing conditions go on the checklist.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't make the materiality call — it reports the calls that were made at extraction time.\n- It doesn't decide what the deal team does about a finding — it surfaces the decision.\n- It doesn't distribute the brief — drafts it, human sends.", + }, + { + id: "builtin-cfl-corporate-diligence-issue-extraction", + title: "Diligence Issue Extraction", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “diligence-issue-extraction” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /diligence-issue-extraction\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) + the current project's documents.\n2. Use the workflow below.\n3. Check `ai-tool-handoff` — if category is bulk and tool is configured, hand off first.\n4. Read docs, apply materiality filter, extract per category.\n5. Findings in house memo format. Hand off consents to closing checklist.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nThe VDR has 2,000 documents. Somewhere in there are the 30 that matter for the deal. This skill reads documents against the diligence categories and materiality thresholds from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), extracts issues, and writes them in house memo format.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Diligence structure (categories, materiality thresholds)\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Issues memo format (how findings are stated)\n- the current project's documents → deal-specific thresholds, VDR location\n\nIf deal-context.md doesn't exist, ask which deal this is for.\n\n## Workflow\n\n### Step 1: Inventory the VDR\n\nIf VDR MCP (Box/Intralinks/Datasite) is connected, pull the index. Map VDR folders to diligence request list categories. Note gaps — request list categories with no corresponding VDR content.\n\n```markdown\n## VDR Inventory: [Deal code]\n\n| Request category | VDR folder | Docs | Status |\n|---|---|---|---|\n| Corporate & Organizational | /01-Corporate | 45 | Reviewed |\n| Material Contracts | /02-Contracts | 312 | In progress |\n| IP | /03-IP | 89 | Not started |\n| [etc.] | | | |\n\n**Gaps:** [Request categories with no VDR content — follow-up request needed]\n```\n\n### Step 2: Apply materiality filter\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) / deal-context thresholds. Don't review everything if the threshold says contracts >$X.\n\nFor contracts specifically: sort by stated value (if in filename/metadata) or by counterparty significance. Review top-down until you hit the threshold or the category is exhausted.\n\n### Step 3: Extract issues\n\nFor each document read, check against the standard diligence concerns for its category:\n\n**Material contracts — standard extraction set:**\n- Change of control provision (triggered by this deal? consent required?)\n- Assignment restriction (can the contract move to buyer?)\n- Exclusivity / non-compete (restricts buyer's business?)\n- MFN (most favored nation — pricing constraints)\n- Termination rights (can counterparty walk because of the deal?)\n- Unusual indemnities or liability exposure\n\n**Corporate — standard extraction set:**\n- Cap table accuracy, outstanding options/warrants\n- Board consent requirements for the transaction\n- Stockholder agreement restrictions (drags, tags, ROFR)\n- Subsidiary structure and intercompany arrangements\n\n**IP — standard extraction set:**\n- Ownership chain (assignments from founders/employees in place?)\n- Open source in the product (copyleft risk)\n- Key IP licensed vs. owned\n- Pending or threatened IP litigation\n\n**Employment — standard extraction set:**\n- Change-of-control severance triggers (parachute cost)\n- Key employee retention risk\n- Pending employment litigation\n- Classification risk (contractors who look like employees)\n\n**Litigation — standard extraction set:**\n- Pending matters and reserves\n- Threatened claims\n- Regulatory inquiries\n- Pattern litigation (consumer class actions, etc.)\n\n### Step 4: State each finding\n\n> **Source attribution.** Where a finding references a statute, regulation, case, or regulator action — e.g., a change-of-control provision analyzed under an applicable law, an IP ownership gap cited against a specific doctrine, a pending litigation matter with a case citation — tag the citation with where it came from: `[Westlaw]`, `[CourtListener]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations from the VDR, deal-team memos, or outside-counsel feedback. Document-source citations (VDR path, Bates, filename) retain their native reference. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n>\n> **When disagreeing with a user's cited statute, quote the text or decline to characterize it.** If the user (or a deal-team note, or a sell-side disclosure) cites a statute for a proposition you don't think is correct, and you don't have the statute text available from a connected research tool or the VDR, do not invent a description of what the statute says. Say instead: \"That section doesn't match what I'd expect a [bulk-sales notice / successor-liability / whatever] requirement to say — I'd need to pull the actual text to tell you what it actually covers. `[statute unretrieved — verify]`\" Then either (a) retrieve the text via the configured research tool and quote it, (b) ask the user to paste the text, or (c) flag for outside counsel. A confident wrong description of a real statute is worse than \"I don't know\" — a deal-team memo citing a fabricated subchapter is harder to un-believe than a gap. Applies in every skill that characterizes a statute, not just issue extraction.\n>\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for a legal basis the finding needs (e.g., the rule governing a change-of-control consent requirement, an IP assignment doctrine, an employment classification test), report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / doctrine]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n\nPer the finding template in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the seed memo used this:\n\n```\nIssue #N: [Title]\nCategory: [request list category]\nSeverity: [level per house scheme]\nDocuments: [VDR path + doc name]\nFinding: [what the document says and why it matters]\nRecommendation: [price adjustment / indemnity / consent required / rep & warranty / walk]\n```\n\n...then use exactly that. If the seed memo was bullets, write bullets.\n\n**Severity calibration** (if house scheme is R/Y/G):\n- 🔴 **Red:** Affects deal value or structure. Change of control requiring major customer consent. Undisclosed material litigation. IP ownership gap.\n- 🟡 **Yellow:** Needs attention, solvable. Consent required but likely obtainable. Open source requiring remediation. Employment classification risk.\n- 🟢 **Green:** Noted for file. Consistent with reps. No action needed beyond the rep.\n\n### Step 5: Assemble per category\n\nGroup findings by request list category. Within category, sort by severity.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n> This output is derived from VDR materials that are privileged, confidential, or both. It inherits the source's privilege and confidentiality status — distribution beyond the privilege circle can waive privilege. Store with the matter's privileged files and make distribution decisions deliberately.\n\n# Diligence Issues: [Deal code] — [Category]\n\n**Documents reviewed:** [N] of [M] in category\n**Coverage:** [All | >$X threshold | Top N]\n**Findings:** [N]🔴 [N]🟡 [N]🟢\n\n---\n\n### Bottom line\n\n[🔴 N blocking · 🟠 N high · 🟡 N medium] — [the one thing the deal team needs to know]\n\n---\n\n[Each finding in house format]\n\n---\n\n## Gaps\n\n- [Request list item with no responsive document]\n- [Document referenced but not in VDR]\n```\n\n## Handoffs\n\n- **To ai-tool-handoff:** If Luminance/Kira is in use per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), hand bulk contract review there. This skill handles the nuanced documents (side letters, amendments, anything the AI tool struggles with).\n- **To deal-team-summary:** Aggregated findings feed the deal team brief.\n- **To material-contract-schedule:** Contract-level extractions feed the disclosure schedule.\n- **To closing-checklist:** Any finding that implies a discrete pre-closing action becomes a checklist item. The handoff is not limited to third-party consents — it also covers:\n - **Shareholder vote / other closing action** — §280G cleansing votes, required stockholder consents, required board resolutions, appraisal-rights notice periods, conversion mechanics, or any other corporate approval the deal needs to close. Characterize the action, the approval threshold, the statutory or charter source, and the timing constraint.\n - **Regulatory filings and approvals** — HSR, CFIUS, foreign-investment review, sector-specific approvals flagged during extraction.\n - **Consents from counterparties** — change-of-control, anti-assignment, MFN-triggering consents.\n - **Releases, terminations, or pay-offs** — employment releases tied to change-of-control, payoff letters, lien releases.\n - **Escrow / holdback mechanics** — if extraction surfaces an indemnity escrow, R&W insurance deliverable, or holdback tied to a specific issue.\n Every finding with a pre-closing action tag should reach closing-checklist, not just the ones labeled \"consent.\" If a finding sits in the gray zone (might need a closing action, might be a post-closing covenant), hand it off with a flag — closing-checklist can drop it if the purchase agreement says otherwise. Under-handoff is a one-way door; over-handoff is corrected in review.\n\n\n**Successor liability.** Flag: pending or threatened tort/products-liability claims, environmental matters and cleanup obligations, bulk-sale/fraudulent-transfer exposure (is the seller retaining enough assets to pay its remaining creditors?), seller's post-closing dissolution plan (if seller dissolves, plaintiffs chase the buyer), and whether the purchase agreement has an assumed/excluded-liabilities schedule that actually covers the known exposures. Even in asset deals, the \"de facto merger,\" \"mere continuation,\" and \"product line\" doctrines can transfer liability — this is the analysis that surprises buy-side clients who think they're buying assets clean.\n\n## Batch processing\n\nFor large categories (300 contracts), process in batches. After each batch, update the running issues list and flag anything 🔴 immediately — don't wait for the full category to surface a deal-affecting issue.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\nIf the extraction surfaced more than ~10 issues, or any time the user asks: offer the dashboard (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs → Dashboard offer for data-heavy outputs`). Shape the offer for this output — counts by severity (🔴 / 🟠 / 🟡 / 🟢), counts by house category, and a sortable grid of issues with materiality, category, and VDR source.\n\n## What this skill does not do\n\n- It doesn't make the materiality call on close cases. It applies the threshold; a human decides the borderline.\n- It doesn't negotiate reps and warranties. It produces the findings that inform them.\n- It doesn't replace bulk AI review. For high-volume clause extraction, hand off to Luminance/Kira per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). This skill is for the judgment layer.", + }, + { + id: "builtin-cfl-corporate-entity-compliance", + title: "Entity Compliance", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “entity-compliance” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /entity-compliance\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Entity Management` (entity table, jurisdictions, registered agent).\n2. Route to the correct mode below based on flag:\n - No flag or `--init`: Mode 1 — initialize tracker from entity table\n - `--report`: Mode 2 — surface upcoming deadlines and overdue items\n - `--update`: Mode 3a (manual) or 3b (--from-report upload) — update status\n - `--sweep`: Mode 3c — walk through unknown/overdue items one by one\n - `--audit`: Mode 4 — full health audit\n - `--export`: Mode 5 — produce CSV or table export\n3. Read/write the current project's documents.\n4. After any update: show summary of changes and next action.\n\n---\n\n## Purpose\n\nAnnual reports, franchise taxes, Statements of Information, biennial filings —\nevery entity in every state has its own schedule and its own consequences for\nmissing the deadline. This skill maintains a single YAML tracker that knows\nwhat's due, when, and for which entity. It's lightweight by design: the tracker\nis a file you own, Claude updates it on command, and you export it when you need\nto share it.\n\n## Important: deadline reference caveat\n\n> The filing deadlines in this skill's reference table reflect publicly available\n> requirements as of the skill's build date. State filing requirements and due\n> dates can change. **Always confirm deadlines with your registered agent or\n> directly with the relevant Secretary of State before relying on them for\n> compliance purposes.** If you use CT Corp, National Registered Agents, or\n> another registered agent service, their compliance calendar is authoritative\n> for your specific entities — use this tracker to organize and surface their\n> data, not to replace it.\n\n## Jurisdiction assumption\n\n> This tracker computes deadlines against the state or country of formation / qualification recorded per entity. Filing rules, due-date mechanics, and fee structures vary materially by jurisdiction. If an entity's actual footprint differs from what's in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) (undisclosed foreign qualification, dissolved entities, jurisdictional re-domestication, international filings managed by a local agent), the output may not apply as written — confirm with the registered agent or local counsel for that jurisdiction.\n\n## Entity-type disambiguation (especially Delaware)\n\n> The filing calendar depends on **entity type**, not just jurisdiction. Treating a \"Delaware entity\" as a single bucket is a common and consequential error — DE corporations, DE LLCs, and DE LPs have different filings, different deadlines, and different consequences for a miss. Confirm the entity type from the entity table before computing or reporting a deadline, and never copy a deadline from one entity-type to another in the same state.\n>\n> **Delaware — the split that matters:**\n>\n> - **DE Corporation (Inc., Corp.):** Annual report AND franchise tax, both due **March 1**. Franchise tax is calculated by the authorized-shares method or the assumed-par-value capital method (whichever is lower); the annual report captures director / officer information. Statutory basis: 8 Del. C. §§ 501–502 [verify current].\n> - **DE LLC:** No annual report required. Annual tax is a **flat $300**, due **June 1**. Statutory basis: 6 Del. C. § 18-1107(d) [verify current fee and date].\n> - **DE LP:** No annual report required. Annual tax is a **flat $300**, due **June 1** (parallel to the LLC rule). Statutory basis: 6 Del. C. § 17-1109 [verify current].\n>\n> A DE LLC is NOT required to file a March 1 annual report — writing that deadline for an LLC carries real risk (spurious \"overdue\" flags that mask actual June 1 exposure, or worse, the inverse: a user who treats the March 1 corporation rule as universal and misses the June 1 LLC deadline). If the entity table records a Delaware entity without a type, flag it as `type_unknown` and ask the user to confirm before computing either deadline.\n>\n> The same entity-type discipline applies in every other jurisdiction with divergent filing regimes by entity type (e.g., CA corp Statement of Information vs. CA LLC SOI cadence; TX franchise tax applies to corporations, LLCs, and LPs but with different no-tax-due thresholds). When the reference table for a jurisdiction is populated, make sure it is indexed by entity type, not just by state.\n\n---\n\n## Tracker file\n\nLives at the current project's documents. Structure:\n\n```yaml\n# Entity Compliance Tracker\n# Generated: [date]\n# Last updated: [date]\n# Disclaimer: deadlines are reference only — confirm with registered agent or Secretary of State\n\nmetadata:\n company: \"[Company Name]\"\n generated: \"[date]\"\n last_updated: \"[date]\"\n last_audit: \"[date or null]\"\n\ncustom_jurisdictions: # manually added — US states or countries not in built-in reference table\n [] # populated when a new jurisdiction is encountered\n\nentities:\n - name: \"[Entity Name]\"\n type: \"[Corporation / LLC / LP / other]\"\n state_of_formation: \"[state]\"\n formation_date: \"[date or null]\"\n status: \"[active / dormant / dissolving]\"\n registered_agent: \"[CT Corp / National / in-house / other]\"\n notes: \"\"\n\n jurisdictions:\n - state: \"[state]\"\n qualification: \"[domestic / foreign]\"\n qualified_date: \"[date or null]\"\n agent_managed: false # set true for international entities where a local agent handles compliance\n local_agent: \"[name or null]\"\n filings:\n - type: \"[Annual Report / Franchise Tax / Statement of Information / Biennial Statement / other]\"\n due_date: \"[YYYY-MM-DD]\"\n due_basis: \"[fixed date / anniversary month / other]\"\n last_filed: \"[date or null]\"\n last_fee: \"[amount or null]\"\n status: \"[current / due_soon / overdue / unknown]\"\n confirmed_good_standing: \"[date or null]\"\n notes: \"\"\n```\n\nStatus values:\n- `current` — filed for current period, nothing due within 90 days\n- `due_soon` — due within 90 days\n- `overdue` — past due date with no filed date recorded\n- `unknown` — no information; needs manual confirmation\n\n---\n\n## Mode 1: Initialise\n\nRun when no tracker exists, or with `--rebuild` to regenerate from scratch.\n\n### Step 1: Load entity table\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Entity Management` → Entity table. If the entity table\nis populated (from org chart upload at cold-start), use it directly. If not,\nask the user to either run the cold-start module or provide the entity list.\n\n### Step 2: For each entity × jurisdiction, confirm the filing requirements\n\nFor each entity, confirm the current filing schedule with the registered agent or the relevant Secretary of State. State filing schedules change (some states move from fixed dates to anniversary-based schedules and back, fee structures are revised, filing categories are reclassified). Do not rely on a cached schedule. The tracker below records the dates you confirm; update them when your registered agent sends reminders.\n\nFor each jurisdiction where the entity is registered (domestic or foreign):\n\n1. Ask the user whether they have a current compliance report from the registered agent — that's the most authoritative source.\n2. If not, ask the user what they know (filing type, due-date basis, last filed date, typical fee). Record what they provide.\n3. For anything the user does not know, flag the entity × jurisdiction entry as `unknown` — do not populate dates from a cached reference. The user's next step is to confirm with the registered agent or Secretary of State.\n\n**Capture details in the tracker rather than a reference table:**\n\n> I don't have filing requirements for [Jurisdiction] in the reference table.\n> Let me capture them so we can track this going forward.\n>\n> For [Entity] in [Jurisdiction]:\n> 1. What type of filing is required? (Annual report, franchise tax, confirmation\n> statement, annual return, or something else?)\n> 2. When is it due? (Fixed date like May 1, anniversary month, or other?)\n> 3. What's the typical fee? (Approximate is fine — or \"unknown\".)\n> 4. Who is your registered agent or local filing agent there?\n\nStore the answer in a `custom_jurisdictions` block in the tracker:\n\n```yaml\ncustom_jurisdictions:\n - jurisdiction: \"[State / Country]\"\n jurisdiction_type: \"[US state / Canada province / EU member state / other]\"\n filings:\n - type: \"[filing type]\"\n due_basis: \"[fixed: MM-DD / anniversary month / other description]\"\n typical_fee: \"[amount or unknown]\"\n notes: \"[any other relevant information — e.g., local agent required, filing in local language]\"\n added_by: \"manual\"\n added_date: \"[date]\"\n```\n\nThis custom definition is then applied to all entities in that jurisdiction.\nFuture `--init` runs and entity additions will use it automatically.\n\n**International jurisdictions specifically:**\n\nInternational filings vary enormously by jurisdiction. Always go through the\ncustom definition flow above — confirm the filing type, cadence, and fee with\nthe local filing agent or registered office agent before populating the tracker.\n\nFor international entities, also ask:\n- Is there a local filing agent or registered office agent handling compliance?\n If yes, note the agent name — the tracker can flag when to follow up with them\n rather than calculating due dates independently.\n- Is the entity required to file any group-level reports in this jurisdiction\n (e.g., country-by-country reporting, beneficial ownership registers,\n economic substance filings)?\n\nFlag international entities with a local agent as `agent_managed: true` in the\ntracker. The report mode will list them separately with a note to confirm status\nwith the local agent rather than showing a calculated due date.\n\nFor anniversary-based filings: calculate from the formation_date in the tracker.\nIf formation_date is null: set status to `unknown` and flag for confirmation.\n\n### Step 3: Write the tracker\n\nGenerate the current project's documents with all entities and their\ncalculated filing requirements. Set initial status:\n- `current` if last_filed is within the current filing period\n- `due_soon` if due within 90 days and no last_filed for current period\n- `overdue` if due date has passed and no last_filed for current period\n- `unknown` if formation_date is missing or state is not in reference table\n\nShow a summary after generating:\n\n```\nEntity compliance tracker initialized.\n\nEntities: [N]\nTotal jurisdictions: [N]\nFilings tracked: [N]\n\nStatus summary:\n ✅ Current: [N]\n ⏰ Due soon: [N] (next 90 days)\n 🔴 Overdue: [N]\n ❓ Unknown: [N] (confirm with registered agent)\n\nRun the “Entity Compliance” workflow --report to see what's due.\n```\n\n---\n\n## Mode 2: Report\n\nSurfaces upcoming deadlines and flags overdue items. Default: next 90 days.\n\n```\nthe “Entity Compliance” workflow --report [--days 30|60|90|180]\n```\n\nOutput format:\n\n```\nENTITY COMPLIANCE REPORT — [date]\n[Company Name]\n\n🔴 OVERDUE ([N]):\n [Entity] / [State] / [Filing type] — was due [date]\n\n⏰ DUE WITHIN [N] DAYS ([N]):\n [Entity] / [State] / [Filing type] — due [date] [registered agent]\n [Entity] / [State] / [Filing type] — due [date]\n\n✅ RECENTLY FILED ([N] in last 90 days):\n [Entity] / [State] / [Filing type] — filed [date]\n\n❓ UNKNOWN STATUS ([N]):\n [Entity] / [State] / [Filing type] — no information; confirm with registered agent\n\n🌐 AGENT-MANAGED ([N]):\n [Entity] / [Country] / [Filing type] — managed by [local agent]; confirm status directly\n [Entity] / [Country] — no local agent recorded; add one with --update\n\nGOOD STANDING:\n Last confirmed: [date]\n Entities with confirmed good standing: [N] of [total]\n Entities not confirmed in last 12 months: [list]\n```\n\nIf the tracker covers more than ~10 entities, or any time the user asks: offer the dashboard (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs → Dashboard offer for data-heavy outputs`). Shape the offer for this output — counts by filing status (overdue / due soon / filed / unknown), counts by good-standing state, and a sortable entity table with jurisdiction, filing type, and next due date.\n\n---\n\n## Mode 3: Update\n\nUpdates one or more entities in the tracker. Three sub-modes:\n\n### Consequential-action gate (file SOI / annual report)\n\n**Before directing or confirming a filing:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Filing a Statement of Information, annual report, or franchise tax return with a Secretary of State has legal consequences — it's a formal representation from the entity, it carries fees, and missed or incorrect filings can cause loss of good standing or franchise-tax defaults. Have you reviewed this with an attorney (or a qualified registered agent) before filing? If yes, proceed to record the filing. If no, here's a brief to bring to them:\n>\n> - Entity, jurisdiction, filing type, and due date\n> - What the tracker says about the last filing (date, fee, officer/director information last reported)\n> - Open questions (is the officer/director information still accurate; has the registered agent changed; has the principal office changed)\n> - What could go wrong (out-of-date officer information, missed deadline triggering franchise tax or dissolution, fee calculation error)\n> - What to ask the attorney (is a filing actually needed this year; are there any charter amendments or officer changes that need to be reflected; who should sign)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not record a new `last_filed` date past this gate without an explicit yes. Tracker reads, deadline reports, and \"what's due soon\" output do not require the gate.\n\n### 3a: Manual update\n\n```\nthe “Entity Compliance” workflow --update\n```\n\nAttorney tells Claude what was filed:\n> \"We filed the Delaware annual report for [Entity] on March 1. Fee was $450.\"\n\nClaude updates:\n- `last_filed` → March 1 date\n- `last_fee` → $450\n- `status` → `current`\n- `last_updated` in metadata\n\n### 3b: Registered agent report upload\n\n```\nthe “Entity Compliance” workflow --update --from-report\n```\n\nUser uploads a CT Corp, National Registered Agents, or similar compliance\nreport (PDF, CSV, or Excel). Claude reads it and updates matching entities:\n\nFrom the report, extract for each entity:\n- Filing type and due date\n- Last filed date (if present)\n- Good standing status and date confirmed\n- Any flags or warnings from the agent\n\nMatch report entities to tracker entities by name (flag near-matches for\nconfirmation — \"Acme Holdings LLC\" vs. \"Acme Holdings, LLC\" are probably\nthe same entity).\n\nAfter processing:\n```\nUpdated [N] entities from report.\n\nMatched: [N]\nUnmatched (in report, not in tracker): [list — may need to add to entity table]\nNot in report (in tracker, no update): [list — status unchanged]\n```\n\n### 3c: Bulk status sweep\n\n```\nthe “Entity Compliance” workflow --sweep\n```\n\nWalks through each entity with `unknown` or `overdue` status and asks for\ncurrent information one at a time:\n\n> [Entity] / [State] / [Filing type] — currently showing as [status].\n> Has this been filed? If yes, when and what was the fee?\n\nUpdates tracker after each confirmation. Produces a completion summary.\n\n---\n\n## Mode 4: Health audit\n\n```\nthe “Entity Compliance” workflow --audit\n```\n\nBroader review beyond just filing status. Surfaces:\n\n**Filing compliance:**\n- Overdue items (from report mode)\n- Unknown status items\n\n**Entity health:**\n- Entities marked as `dormant` — flag for review: should these be dissolved?\n Carrying dormant entities costs money (annual fees, registered agent fees)\n and creates ongoing compliance obligations.\n- Entities with formation_date older than 5 years and status `dormant` — flag\n as dissolution candidates.\n- Entities missing formation_date — flag as data gap.\n\n**Good standing gaps:**\n- Entities with no `confirmed_good_standing` date — unknown whether in good\n standing; risk if a transaction requires a certificate on short notice.\n- Entities with `confirmed_good_standing` older than 12 months — stale; worth\n refreshing, especially if M&A or financing is anticipated.\n\n**Foreign qualification gaps:**\n- Based on your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) entity table: are there states in the company's\n operational footprint (offices, employees) where entities are not foreign\n qualified? This requires the attorney to confirm operational presence —\n Claude can flag the question but cannot determine presence independently.\n\n**Intercompany agreement gaps:**\n- From your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile): if intercompany agreements are marked as partial or no,\n flag which entity relationships likely need agreements (parent-subsidiary\n services, IP licenses, loans).\n\nOutput format:\n\n```\nENTITY HEALTH AUDIT — [date]\n\nFILING COMPLIANCE\n Overdue: [N]\n Unknown status: [N]\n Action: run --sweep to confirm unknown items\n\nDORMANT ENTITIES ([N])\n [List of dormant entities with age and annual carrying cost if known]\n Dissolution candidates (>5 years dormant): [list]\n\nGOOD STANDING\n No record: [N] entities\n Stale (>12 months): [N] entities\n Consider refreshing before: [any upcoming transactions or contract renewals if known]\n\nPOTENTIAL GAPS\n Foreign qualification: [flag question — confirm operational presence in:]\n [list of states from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) footprint not in tracker as qualified]\n Intercompany agreements: [status from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\nRECOMMENDED ACTIONS\n 1. [Highest priority action]\n 2. [etc.]\n```\n\n---\n\n## Mode 5: Export\n\n```\nthe “Entity Compliance” workflow --export [--format csv|table]\n```\n\nProduces a flat export suitable for sharing with finance, legal ops, or\noutside registered agent. Default: CSV.\n\nCSV columns:\n`Entity Name, Entity Type, State of Formation, Formation Date, Status,\nRegistered Agent, Jurisdiction, Qualification Type, Filing Type, Due Date,\nLast Filed, Last Fee, Good Standing Confirmed, Notes`\n\nOne row per filing per jurisdiction. Multiple rows per entity (one per\njurisdiction × filing type combination).\n\nIf `--format table`: produce a markdown table suitable for pasting into\na report or Slack message, showing only the next 90 days of filings.\n\n---\n\n## What this skill does not do\n\n- It does not file anything. Output is a tracker and a to-do list; filing\n is done by the attorney, outside counsel, or registered agent.\n- It does not pull good standing certificates. It tracks when certificates\n were last confirmed; obtaining them is manual or via registered agent.\n- It does not determine whether foreign qualification is required in a given\n state. That analysis depends on facts about business activity that the\n attorney must confirm.\n- It does not replace a registered agent service for companies with complex\n multi-entity structures. CT Corp, National Registered Agents, and similar\n services have dedicated compliance teams and direct state relationships.\n This skill is best suited for smaller organizations without agent support,\n or as a lightweight layer on top of agent data for organizations that do\n have support.\n- The filing deadline reference table is not legal advice and may not reflect\n current requirements. Confirm all deadlines before relying on them.\n\n\n## Formula injection defense\n\nBefore writing any cell in Excel, Sheets, or CSV output, neutralize formula injection. Counterparty-sourced text (contract quotes, party names, registered agent data, CLM exports) is attacker-controlled. A cell starting with `=`, `+`, `-`, `@`, `\t`, `\n`, or `\n` will be interpreted as a formula or break the row structure.\n\n- **Prefix with a single quote:** `'=SUM(A1:A10)` → `=SUM(A1:A10)` (displayed as text, not executed)\n- **Applies to every cell that contains text sourced from a document, a tool result, or a user paste.** Column headers you control and computed values you produce are safe.\n- **CSV: also escape embedded commas, double quotes, newlines** (RFC 4180 quoting).\n- This is not optional. A spreadsheet your user opens in Excel that triggers a macro or exfiltrates data via DDE is a supply-chain attack on your user.", + }, + { + id: "builtin-cfl-corporate-integration-management", + title: "Integration Management", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “integration-management” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /integration-management\n\n1. Load `deal-context.md` for deal code, target, close date, deal lead.\n2. Load `integration-tracker.yaml` if it exists (or create on --init).\n3. Use the workflow below.\n4. Route by flag:\n - `--init`: Mode 1 — read PA, build phased workplan, consent tracker\n - `--contracts`: Mode 2 — import contract list (repository or upload), tier and classify\n - `--report`: Mode 3 — generate status report\n - `--update`: Mode 4 — manual update or parse uploaded status document\n - `--export`: Mode 5 — CSV or table export\n5. Read/write the current project's documents.\n6. After any write: show summary of changes and surface any new flags.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nOutside counsel closes the deal. Legal inherits the mess. This skill is the\nprogram management layer for post-closing integration — not the business\nintegration, not IT systems, not HR org design. The legal workstream: consents,\ncontract assignments, entity rationalization, IP recordals, PA obligations.\nIt tracks what's done, what's due, what's blocked, and what needs a decision.\n\n---\n\n## Tracker file\n\nLives at the current project's documents. Read `deal-context.md` for\nthe deal code, target name, close date, and deal lead. Inherit any post-close\nitems from `closing-checklist.yaml` if it exists.\n\n```yaml\n# integration-tracker.yaml\n\nmetadata:\n deal_code: \"[code]\"\n target: \"[company name]\"\n close_date: \"[YYYY-MM-DD]\"\n deal_lead: \"[name]\"\n outside_counsel: \"[firm and lead attorney]\"\n last_updated: \"[date]\"\n last_status_report: \"[date or null]\"\n\npa_dates:\n required_consents_deadline: \"[YYYY-MM-DD — extract from PA]\"\n rep_survival_expires: \"[YYYY-MM-DD]\"\n escrow_release: \"[YYYY-MM-DD or null]\"\n earnout_milestones:\n - description: \"[milestone]\"\n measurement_date: \"[YYYY-MM-DD]\"\n payment_date: \"[YYYY-MM-DD]\"\n owner: \"finance\" # always finance — legal tracks date only\n\nworkplan:\n day_1:\n target_date: \"[close_date + 7 days]\"\n items: []\n day_30:\n target_date: \"[close_date + 30 days]\"\n items: []\n day_90:\n target_date: \"[close_date + 90 days]\"\n items: []\n day_180:\n target_date: \"[close_date + 180 days]\"\n items: []\n\nrequired_consents: []\ndesired_consents: []\n\ncontracts:\n source: \"[repository / manual-upload / disclosure-schedule]\"\n repository_path: \"[path or null]\"\n last_imported: \"[date]\"\n total: 0\n tier_1: []\n tier_2: []\n tier_3: []\n tier_4: []\n```\n\n**Workplan item structure:**\n```yaml\n- id: \"W-001\"\n description: \"[action item]\"\n phase: \"[day_1 / day_30 / day_90 / day_180]\"\n owner: \"[legal-owns / legal-supports]\"\n workstream: \"[legal / hr / it / finance / real-estate / other]\"\n priority: \"[critical / high / medium / low]\"\n deadline: \"[YYYY-MM-DD or null]\"\n deadline_basis: \"[pa-obligation / regulatory / best-practice]\"\n status: \"[not_started / in_progress / complete / blocked / deferred]\"\n blocker: \"[description or null]\"\n depends_on: \"[item id or null]\"\n notes: \"\"\n```\n\n**Consent entry structure:**\n```yaml\n- id: \"CON-001\"\n counterparty: \"[name]\"\n contract_type: \"[customer / vendor / lease / IP-license / financial / other]\"\n required_consent: true # true = named in PA Required Consents schedule\n pa_deadline: \"[YYYY-MM-DD]\" # only for required_consent: true\n status: \"[not_started / outreach_sent / in_negotiation / obtained / waived / refused]\"\n assigned_to: \"[name or null]\"\n outreach_date: \"[date or null]\"\n obtained_date: \"[date or null]\"\n notes: \"\"\n```\n\n**Contract entry structure:**\n```yaml\n- id: \"C-001\"\n name: \"[contract name or filename]\"\n counterparty: \"[party name]\"\n contract_type: \"[MSA / SaaS / lease / IP-license / employment / NDA / other]\"\n annual_value: \"[amount or unknown]\"\n assignment_mechanism: \"[auto-assign / consent-required / coc-provision / silent]\"\n tier: 1 # 1=Required Consent, 2=material+consent-required, 3=CoC, 4=auto-assign\n required_consent: false\n pa_deadline: \"[YYYY-MM-DD or null]\"\n status: \"[not_reviewed / no_action / consent_pending / outreach_sent / in_negotiation / consent_obtained / assignment_complete / waived / refused / coc_triggered]\"\n assigned_to: \"[name or null]\"\n notes: \"\"\n last_updated: \"[date]\"\n```\n\n---\n\n## Mode 1: Initialize\n\n```\nthe “Integration Management” workflow --init [--deal [code]]\n```\n\n### Step 1: Load deal context\n\nRead the current project's documents. If not found: ask for deal code name,\ntarget company, close date, deal lead, and outside counsel. Write to\ndeal-context.md if it doesn't exist.\n\nRead the current project's documents if it exists. Any items marked as\npost-closing become Day 1 or Day 30 workplan items (inherit status from\nclosing-checklist).\n\n### Step 2: Read deal inputs\n\n**A full purchase agreement produces the most complete tracker.** The PA's Required\nConsents schedule and post-closing covenants section are the authoritative source\nfor hard deadlines and legal obligations. But the skill can initialize usefully\nfrom whatever is available — partial inputs produce a starter tracker the attorney\nfills in rather than an empty page.\n\n> What deal artifacts do you have available? Share whatever exists:\n>\n> **Ideal:** The purchase agreement (upload or connected document path). I'll read\n> the post-closing covenants, Required Consents schedule, survival periods, escrow\n> terms, and earn-out provisions.\n>\n> **Also useful — share any combination of:**\n> - Deal summary or term sheet (gives me the key economics and timeline)\n> - Integration to-do list or post-close checklist from outside counsel\n> - Existing workplan or integration tracker (I'll import and continue from it)\n> - Closing checklist — if generated by the M&A cold-start skill, I'll inherit it\n> automatically from the current project's documents\n> - Required Consents list alone (if the PA is held by outside counsel)\n>\n> **If you have nothing written down:** Tell me the deal in plain terms — who was\n> acquired, when it closed, what the main open items are — and I'll build a\n> starter tracker from the standard Day 1/30/90/180 workplan that you edit.\n\n**What changes based on what's provided:**\n\n| Input | What you get |\n|---|---|\n| Full PA | Complete workplan + Required Consents with deadlines + PA dates |\n| PA + contract list | Full tracker + contract assignment tier list |\n| Deal summary / to-do list | Standard workplan skeleton, Required Consents as placeholders |\n| Nothing | Standard workplan scaffold; attorney fills in consents and contract lists |\n\nThe tracker is designed to be built out progressively — a skeleton today, filled\nin as more information becomes available.\n\n**From the PA extract:**\n\n*Required Consents schedule:*\n- For each consent: counterparty name, contract type, and the contractual\n deadline. Set as required_consent: true with pa_deadline populated.\n\n*Post-closing obligations:*\n- Map each obligation to a workplan item. Assign to the correct phase based\n on the deadline. Tag as pa-obligation in deadline_basis.\n\n*Key dates:*\n- Required Consents deadline — extract from the PA\n- Rep and warranty survival expiry — pull the specific survival periods from the PA.\n General, fundamental, and tax reps typically have different survival periods; pull\n each one the PA defines and record them separately. Do not assume a default.\n- Escrow release date(s) — extract from the PA\n- Any earn-out measurement and payment dates — add to pa_dates.earnout_milestones,\n owner always set to \"finance\"\n\n### Step 3: Build the phased workplan\n\nGenerate standard workplan items for each phase. Add PA obligations extracted\nin Step 2. Items inherited from the closing checklist are pre-populated.\n\n**Day 1 — legal-owns:**\n- Entity name change filing (if acquired entity is being renamed) [priority: critical]\n- Bank account signatory updates — notify bank with closing documentation [priority: critical]\n- Registered agent notification of ownership change [priority: high]\n- Key IP assignment execution — if any IP assignments were deferred from closing [priority: critical]\n- Domain name and social media account transfer [priority: high]\n- D&O insurance — confirm tail policy is bound for acquired entity directors [priority: critical]\n- Secretary of State ownership notifications where required by state law [priority: high]\n\n**Day 1 — legal-supports:**\n- Employee announcement and communications (HR owns, legal reviews) [priority: critical]\n- Benefits day-1 coverage confirmation (HR owns, legal advises on COBRA and plan terms)\n- Customer communication letters (business owns, legal reviews for accuracy)\n\n**Day 30 — legal-owns:**\n- Required Consents initial push — contact all counterparties, document outreach [priority: critical]\n- IP assignment recordal at USPTO (patents, trademarks) [priority: high]\n- Copyright assignment filing [priority: medium]\n- Trademark assignment recording [priority: high]\n- Material contract review — complete tier 1 and tier 2 contract assignment analysis [priority: high]\n- Insurance tail policy final confirmation [priority: high]\n\n**Day 30 — legal-supports:**\n- Data migration privacy review (IT owns, legal advises on data transfer mechanisms)\n- Real estate lease review for assignment provisions (facilities owns, legal advises)\n\n**Day 90 — legal-owns:**\n- Required Consents deadline — all Required Consents must be obtained or escalated [priority: critical, deadline: pa_dates.required_consents_deadline]\n- Entity rationalization decision — recommend keep separate / merge / dissolve [priority: high]\n- Benefits plan assumption or termination documentation [priority: high]\n- Secondary consent push — remaining outstanding consents [priority: high]\n- Tier 3 change of control contract resolution [priority: critical]\n\n**Day 90 — legal-supports:**\n- Full HR harmonization documentation (HR owns, legal advises on employment law)\n\n**Day 180 — legal-owns:**\n- Entity merger filing — if rationalization decision is to merge [priority: high]\n- Entity dissolution filing — if rationalization decision is to wind down [priority: high]\n- Full contract novation — contracts requiring acquiror's name [priority: high]\n- Rep survival tracking — note upcoming expiry date [priority: medium]\n\nShow summary after generating:\n\n```\nIntegration tracker initialized — [Deal code] / [Target]\n\nClose date: [date]\nRequired Consents deadline: [date] ([N] days from today)\nRep survival expires: [date]\n\nWorkplan items: [N] ([N] legal-owns, [N] legal-supports)\nRequired Consents: [N] (from PA schedule)\nDesired Consents: [N] (from diligence — no PA deadline)\n\nContract assignment: not yet imported — run --contracts to populate\n\nNext step: run the “Integration Management” workflow --contracts to import the\ncontract list, then --report to see your first status summary.\n```\n\n---\n\n## Mode 2: Contract Assignment\n\n```\nthe “Integration Management” workflow --contracts [--deal [code]]\n```\n\nThis is the dedicated contract assignment initialization. Separate from the\nmain init so it can be run independently and re-run when the contract list\nchanges.\n\n### Step 1: Get the contract list\n\nTwo paths — use whichever applies:\n\n**Path A: Connected repository**\n\n> Is your contract repository connected? (Google Drive, Box, SharePoint,\n> or a VDR that's still accessible post-close?)\n>\n> If yes: give me the folder path or folder name for the acquired company's\n> contracts. I'll pull a list of what's there and read each contract for the\n> assignment clause and counterparty.\n\nSearch the connected repository. For each document found:\n- Extract filename and file path\n- Read the document — identify: contract party (counterparty name), contract\n type (from header or subject matter), assignment clause text, change of\n control clause text if present, and annual value if stated.\n\n**Path B: Manual list upload**\n\n> Upload a contract list. This can be:\n> - The Material Contracts schedule from the PA disclosure schedules\n> - A CSV or Excel export from their contract management system\n> - A manually prepared list\n>\n> Minimum required columns: Contract Name, Counterparty. Helpful but optional:\n> Contract Type, Annual Value, Assignment Clause text.\n\nRead the uploaded list. For contracts where no assignment clause text is\nprovided, set assignment_mechanism to \"not_reviewed\" and flag for follow-up.\n\n**Path C: Disclosure schedule**\n\nIf neither repository nor list is available, read the Material Contracts\nschedule from the PA disclosure schedules (from the PA uploaded in --init).\nThis gives the minimum required list — parties and contract types. Assignment\nclauses will need manual review.\n\n### Step 2: Determine assignment mechanism\n\nFor each contract, classify the assignment mechanism:\n\n| Mechanism | Definition | Tier |\n|---|---|---|\n| `consent-required` | Explicit clause prohibiting assignment without counterparty consent | 1 or 2 |\n| `coc-provision` | Change of control clause giving counterparty termination or consent right triggered by the deal | 3 |\n| `auto-assign` | No restriction, or explicit permission to assign to affiliates or successors | 4 |\n| `silent` | No assignment clause — default to governing law. Research the governing-law default for contract assignment when the contract is silent and cite the controlling rule. Flag for attorney review. | 2 |\n| `not_reviewed` | Could not read or locate assignment clause | Flag for manual review |\n\nFor contracts flagged in the Required Consents PA schedule: override tier to 1\nregardless of assignment mechanism classification.\n\n### Step 3: Tier assignment\n\n```\nTier 1 — Required Consents: [N] contracts\n Named in PA schedule, hard deadline [date], must obtain consent\n\nTier 2 — Material, consent required: [N] contracts\n Assignment restriction present, not in PA schedule\n Recommended timeline: obtain within Day 90\n\nTier 3 — Change of control provisions: [N] contracts ⚠️\n Counterparty has termination or consent right triggered by close\n ACTION REQUIRED: contact counterparty immediately — CoC may already be triggered\n\nTier 4 — Auto-assign / no action: [N] contracts\n Assigns automatically or by affiliate/successor provision\n Tracking only — no outreach needed\n\nNot reviewed: [N] contracts\n Could not determine assignment mechanism — manual review required\n```\n\nShow tier 3 separately and prominently. A change of control clause may have\nalready triggered on the close date — counterparty may have a right to terminate\nthat is running right now.\n\n### Step 4: Generate status entries\n\nFor each contract, create a tracker entry with:\n- All extracted fields (counterparty, type, value, mechanism, tier)\n- Initial status: tier 4 → `no_action`; tier 3 → `coc_triggered`; tiers 1/2 → `consent_pending`; not_reviewed → `not_reviewed`\n- pa_deadline populated for tier 1 from Required Consents schedule\n\n---\n\n## Mode 3: Status Report\n\n```\nthe “Integration Management” workflow --report [--deal [code]]\n```\n\nReads current tracker state. Produces:\n\n```\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n> This status report is derived from the purchase agreement, diligence findings, and post-closing integration records. It inherits their privilege and confidentiality status — distribution beyond the privilege circle can waive privilege. Confirm the recipient list before sending.\n\nINTEGRATION STATUS — [Deal code] / [Target]\n[Date] — Day [N] post-close\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nEXECUTIVE SUMMARY\n[2-3 sentence paragraph: overall status, biggest risk, key win since last report]\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nREQUIRED CONSENTS [deadline: DATE — N days remaining]\n Obtained: [N] of [total] ████████░░ [%]\n In negotiation: [N]\n Outreach sent: [N]\n Not started: [N]\n Refused: [N] ⚠️\n\n⚠️ AT RISK: [counterparty] — deadline in [N] days, no response to outreach\n⚠️ REFUSED: [counterparty] — PA obligation not met; escalate to outside counsel\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nCONTRACT ASSIGNMENT\n Tier 1 (Required Consents): [N] complete / [N] in progress / [N] pending\n Tier 2 (Material contracts): [N] complete / [N] in progress / [N] pending\n Tier 3 (CoC provisions): [N] resolved / [N] outstanding ⚠️\n Tier 4 (Auto-assign): [N] — no action required\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nWORKPLAN — LEGAL OWNS\n 🔴 OVERDUE ([N]):\n [item] — was due [date]\n\n ⏰ DUE THIS WEEK ([N]):\n [item] — due [date]\n\n ✅ COMPLETED SINCE LAST REPORT ([N]):\n [item] — completed [date]\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nBLOCKERS & DECISIONS NEEDED\n [item] — blocked on: [description] — owner: [name]\n [item] — decision needed: [description] — recommend: [option]\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\nKEY DATES COMING UP\n [date] — [milestone / deadline]\n [date] — Rep survival expires — confirm no pending indemnification claims\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n```\n\n---\n\n## Mode 4: Update\n\n```\nthe “Integration Management” workflow --update [--deal [code]]\n```\n\n**Manual update:** Attorney tells Claude what changed.\n\n> \"We got the Salesforce consent. Mark it obtained, assigned to [name], date today.\"\n> \"The entity rationalization decision is to merge. Update status and add the merger\n> filing to Day 180.\"\n> \"[Counterparty] refused consent. Flag it and note we need outside counsel on\n> whether this triggers a PA indemnification claim.\"\n\nClaude updates the relevant tracker entry, recalculates any downstream status\n(e.g., if all tier 1 consents are now obtained, flag the PA obligation as met),\nand shows what changed.\n\n**Upload update:** Workstream owner or outside counsel sends a status document.\n\n> Upload the status update from [outside counsel / HR lead / corp dev team].\n> I'll parse it and update the tracker.\n\nRead the uploaded document. Match described items to tracker entries by\ncounterparty name or workplan item description. Update status fields.\nFlag any items in the update that don't match an existing tracker entry —\nmay be new items to add.\n\nAfter any update, show:\n```\nUpdated [N] items.\n\nChanges:\n CON-003 Salesforce: not_started → obtained\n W-014 Entity rationalization: in_progress → complete\n\nNew flags:\n CON-007 [Counterparty]: refused — PA obligation may be unmet. Consider:\n outside counsel review of indemnification claim. ⚠️\n```\n\n---\n\n## Mode 5: Export\n\n```\nthe “Integration Management” workflow --export [--format csv|table] [--section all|consents|contracts|workplan]\n```\n\nProduces a flat CSV or markdown table. Default: all sections, CSV.\n\nCSV format — one row per item, section indicated by a `section` column.\nColumns vary by section:\n\n*Workplan:* id, phase, description, owner, workstream, priority, deadline, status, blocker\n\n*Consents:* id, counterparty, contract_type, required_consent, pa_deadline, status, assigned_to, obtained_date, notes\n\n*Contracts:* id, name, counterparty, contract_type, annual_value, assignment_mechanism, tier, required_consent, pa_deadline, status, assigned_to, notes\n\nExport is the shareable format — suitable for outside counsel, corp dev, or a\nboard integration update.\n\n---\n\n## What this skill does not do\n\n- It does not manage business integration workstreams (IT, HR, finance, real\n estate). It tracks legal's touchpoints in those workstreams and flags when\n legal input is needed. Ownership stays with the business function.\n- It does not draft the consent request letters or novation agreements — those\n are produced by the written-consent skill or by outside counsel.\n- It does not advise on indemnification claims or PA breach. When a consent is\n refused or a deadline is missed, it flags the situation — the legal analysis\n of consequences is the attorney's call.\n- It does not track earn-out performance. Earn-out milestones and payment dates\n appear in the tracker as reference dates with owner set to finance. The\n business drives the numbers.\n- It does not read contracts in real time during status reporting. Contract\n status is what the attorney has updated in the tracker. The skill reads the\n tracker, not the contracts, at report time.\n\n\n## Formula injection defense\n\nBefore writing any cell in Excel, Sheets, or CSV output, neutralize formula injection. Counterparty-sourced text (contract quotes, party names, registered agent data, CLM exports) is attacker-controlled. A cell starting with `=`, `+`, `-`, `@`, `\t`, `\n`, or `\n` will be interpreted as a formula or break the row structure.\n\n- **Prefix with a single quote:** `'=SUM(A1:A10)` → `=SUM(A1:A10)` (displayed as text, not executed)\n- **Applies to every cell that contains text sourced from a document, a tool result, or a user paste.** Column headers you control and computed values you produce are safe.\n- **CSV: also escape embedded commas, double quotes, newlines** (RFC 4180 quoting).\n- This is not optional. A spreadsheet your user opens in Excel that triggers a macro or exfiltrates data via DDE is a supply-chain attack on your user.", + }, + { + id: "builtin-cfl-corporate-material-contract-schedule", + title: "Material Contract Schedule", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “material-contract-schedule” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /material-contract-schedule\n\n1. Load purchase agreement → Material Contract definition + schedule format.\n2. Use the workflow below.\n3. Apply definition to diligence findings. Flag edge cases.\n4. Format per agreement. Consent overlay feeds closing checklist.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nThe purchase agreement has a rep: \"Schedule 3.X lists all Material Contracts.\" This skill builds that schedule from the diligence findings — which contracts are material per the agreement's definition, in the format the agreement requires.\n\n## Load context\n\n- Purchase agreement draft — for the definition of \"Material Contract\" and the schedule format\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → materiality thresholds (may differ from the agreement definition — use the agreement's)\n- Diligence findings from diligence-issue-extraction — contract-level data\n\n## Workflow\n\n### Step 1: Get the definition\n\nPull the definition of \"Material Contract\" from the purchase agreement — the PA definition controls. Deal-structure differences (stock vs. asset vs. merger) can change how a prong is interpreted, and regulated-industry overlays (healthcare, defense, financial services, telecom, government contracting) can add consent requirements that live outside the PA. If the deal involves any of those overlays, research the applicable anti-assignment or novation rules (for example, federal contracts, government contracting novation, sector-specific consent statutes) and cite the controlling rule.\n\nCommon prong categories to look for in the PA definition — these are not a substitute for reading the PA, and the list the PA uses controls:\n\n- Dollar-value threshold (annual or aggregate)\n- Term length\n- Change-of-control or anti-assignment provision\n- Exclusivity or non-compete\n- Top N customer or supplier contracts\n- Real property leases\n- IP licenses (in-bound and out-bound)\n- Related-party agreements\n- Government contracts\n- Contracts outside the ordinary course\n\nThe PA's definition is the test. Apply it mechanically — every contract that meets any prong in the PA's definition goes on the schedule.\n\n### Step 2: Apply the definition to the findings\n\nFor each contract reviewed in diligence:\n\n| Contract | Meets prong(s) | Include |\n|---|---|---|\n| [name] | [$X+ annual value; CoC provision] | Yes |\n| [name] | [none] | No |\n\n**Edge cases to flag for human decision:**\n- Contract is $X-1 (just under threshold) but important to the business\n- Contract meets a prong but is being terminated anyway\n- Oral agreements or side letters that may or may not count\n\n### Step 3: Gather schedule data\n\nFor each included contract, the schedule typically needs:\n\n| Field | Source |\n|---|---|\n| Counterparty name | Contract |\n| Contract title/type | Contract |\n| Date | Contract |\n| Term / expiration | Contract |\n| Annual/total value | Contract or management data |\n| Which materiality prong it meets | Step 2 analysis |\n| Consent required for the deal | Diligence finding |\n| VDR reference | Diligence inventory |\n\nPull from existing diligence extractions. If a field is missing, flag it — don't guess.\n\n### Step 4: Format per the agreement\n\nDisclosure schedules have a format — usually a numbered list or a table, sometimes with sub-parts by contract type. Match the format of the other schedules in the draft agreement.\n\n```markdown\n## Schedule 3.[X] — Material Contracts\n\nThe following are the Material Contracts as of the date hereof:\n\n### (a) Customer Contracts\n\n1. [Agreement Title], dated [date], between [Target] and [Counterparty].\n [Brief description if the format calls for it.]\n [VDR: path]\n\n2. [...]\n\n### (b) Supplier Contracts\n\n[...]\n\n### (c) Real Property\n\n[...]\n\n[etc. — sub-parts per the agreement's definition structure]\n```\n\n### Step 5: Consent tracking overlay\n\nSeparately (not in the schedule itself — this is internal), track which scheduled contracts require consent.\n\n> The consent overlay and any pre-delivery working draft of the schedule are derived from privileged diligence materials and inherit their privilege and confidentiality status — distribution beyond the privilege circle can waive privilege. The schedule itself, once delivered as an exhibit to the executed PA, is a deal document and is not privileged; strip any internal annotations before delivery.\n\n\n| Schedule # | Counterparty | Consent required | Status | Owner | Due |\n|---|---|---|---|---|---|\n| 3.X(a)(1) | [name] | Yes — CoC §12.2 | Requested | [name] | [date] |\n\nThis feeds closing-checklist.\n\n## Cross-check\n\nBefore delivering:\n\n- Every contract that met a prong is on the schedule (completeness)\n- No contract is on the schedule that doesn't meet a prong (no over-disclosure — it's a rep, not a data dump)\n- Schedule is consistent with the other reps (a contract on Schedule 3.X that creates a lien should also be on the liens schedule)\n- Every entry has a VDR cite so buyer's counsel can find the underlying doc\n\n## Handoffs\n\n- **From diligence-issue-extraction:** Contract-level findings are the input.\n- **To closing-checklist:** Consent items go on the checklist.\n\n## What this skill does not do\n\n- It doesn't decide the materiality definition — that's in the purchase agreement.\n- It doesn't obtain consents — it tracks which ones are needed.\n- It doesn't draft the rep — it populates the schedule the rep references.", + }, + { + id: "builtin-cfl-corporate-tabular-review", + title: "Tabular Review", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “tabular-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /tabular-review\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → diligence structure, thresholds, house format.\n2. Confirm: what documents, what columns, where does the output go.\n3. Build the typed schema. Write `.review-schema.yaml`. Confirm with the user.\n4. Sample run (3–5 docs). Adjust schema. Confirm.\n5. Fan out — one sub-agent per document, parallel. Each cell: value + state + verbatim quote + location.\n6. Normalization pass. Flag outliers and inconsistencies.\n7. Output: `.xlsx` or Google Sheets (ask which), plus `.csv` + `_sources.csv` + markdown always. Work-product header.\n8. Summary: verification workload (counts of not_present / unclear / needs_review per column), flagged columns, where the files are, reminder that every cell is a lead not a finding.\n\n```\nthe “Tabular Review” workflow\nthe “Tabular Review” workflow --schema .review-schema.yaml --docs ./vdr/02-Contracts/\nthe “Tabular Review” workflow --template ma-diligence\n```\n\n**`--schema `:** Use an existing schema file instead of building one. Useful for re-runs and incremental additions.\n\n**`--template `:** Start from a template in `references/`. Currently: `ma-diligence`.\n\n**`--docs `:** Document source. A local folder, a Drive folder ID, or a VDR path. If omitted, asks.\n\n**`--output `:** Output format. If omitted, asks.\n\n**`--sample `:** Sample size for the schema check. Default 5.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nYou have a pile of documents and a list of questions you need answered consistently across every one. A diligence request list. A vendor contract audit. A lease portfolio review. The output is a table: document rows, data-point columns, and every cell traceable to the exact words in the source.\n\nThis is not issue spotting. `diligence-issue-extraction` finds the 30 problems hiding in 2,000 documents. This skill answers the same 15 questions about all 2,000 documents. Both are legitimate; they answer different questions.\n\nThis is also not a replacement for a human reading the document. Every cell this skill produces is a **lead that needs verification**, not a finding. The output is designed to make verification fast, not to skip it.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → diligence structure, materiality thresholds, house format preferences\n- the current project's documents if working a specific deal\n- An existing schema file if the user has one (`.review-schema.yaml`)\n\n## The column type system\n\nThe thing that makes a tabular review useful is that Column C means the same thing in row 1 as in row 200. Free text drifts. Types hold.\n\nEvery column has a **type** that constrains the answer format:\n\n| Type | What it returns | Use for |\n|---|---|---|\n| `verbatim` | Exact quote from the document, character-for-character | Defined terms, operative clause language, anything where the words matter |\n| `classify` | One value from a fixed list you define | Yes/No, present/absent, clause variants (e.g., \"sole consent\" / \"consent not unreasonably withheld\" / \"silent\") |\n| `date` | ISO date | Effective date, expiration, termination notice deadline |\n| `duration` | Number + unit | Term length, notice period, survival period |\n| `currency` | Number + currency code | Caps, thresholds, fees, purchase price references |\n| `number` | Bare number | Counts, percentages, page references |\n| `free` | Short free text summary | Use sparingly — this is the type that drifts. Only when the others genuinely don't fit. |\n\n**The verbatim rule:** Every non-`verbatim` column also captures the exact source quote that supports the answer, as a companion field. The answer in the cell is the interpretation; the quote is the evidence. A `classify` cell that says \"consent not unreasonably withheld\" is useless without the sentence it came from, because the reviewer's job is to check whether that's the right read.\n\n## The three states of \"not found\"\n\nA blank cell hides information. Force one of three explicit states whenever you can't produce a positive answer:\n\n| State | Meaning | When to use |\n|---|---|---|\n| `not_present` | The document was read and the clause is not there | You are confident the subject matter isn't addressed |\n| `unclear` | Something is there but you can't classify it confidently | Ambiguous drafting, partial clause, conflicting provisions |\n| `needs_review` | You found something but a human must make the call | Edge case, unusual drafting, the answer depends on a judgment the schema doesn't capture |\n\nThese are three different pieces of information. A deal team handles \"the contract is silent on assignment\" very differently from \"the assignment clause is ambiguous.\" Collapsing them into one blank cell loses the distinction.\n\n## Workflow\n\n### Step 0: What and where\n\nConfirm:\n1. **Documents.** Where are they? VDR MCP (Box, Datasite, iManage), local folder, Google Drive folder, or a list of files. How many? If >200, warn that this will take a while and offer to start with a materiality-filtered subset.\n2. **Schema.** What columns? Two paths:\n - User picks a template from `references/` (M&A diligence standard is the default)\n - User describes columns in natural language and you structure them into the typed schema\n3. **Output.** Excel (`.xlsx`) or Google Sheets — ask which the team works in. CSV and markdown always written as fallbacks. Output goes to the deal folder, Drive, or wherever the user says.\n\n### Step 1: Build and confirm the schema\n\nTurn the user's column list into a structured schema. For each column: a stable `id`, a human `label`, a `type`, a `prompt` (the question a reviewer reading the document would ask), and for `classify` columns an `options` list.\n\nWrite it to `.review-schema.yaml` next to the output. This file is the reusable artifact — the user can edit it, add a column, re-run against new documents. Show it to the user and confirm before fanning out.\n\n```yaml\nschema:\n name: \"M&A Diligence — Project [Code]\"\n created: 2026-05-07\n columns:\n - id: counterparty\n label: \"Counterparty\"\n type: verbatim\n prompt: \"Who is the contracting party other than the target?\"\n - id: effective_date\n label: \"Effective Date\"\n type: date\n prompt: \"When did the agreement become effective?\"\n - id: change_of_control\n label: \"Change of Control\"\n type: classify\n options: [silent, consent_required, consent_not_unreasonably_withheld, automatic_termination, notice_only]\n prompt: \"Does the agreement address a change of control of the target? What does it require?\"\n - id: assignment\n label: \"Assignment Restrictions\"\n type: classify\n options: [silent, consent_required, consent_not_unreasonably_withheld, freely_assignable, assignable_to_affiliates]\n prompt: \"Can the target assign this agreement? What restrictions apply?\"\n # ... more columns\n```\n\n### Step 2: Sample run\n\nDo not fan out to 200 documents on an untested schema. Run 3–5 documents first. Show the user the rows. Look for:\n- Columns where most answers are `unclear` — the prompt is ambiguous, rewrite it\n- `classify` columns where answers don't fit the options — add options or change to `free`\n- `verbatim` columns returning paraphrases — reinforce that it must be character-for-character\n\nAdjust the schema, re-run the sample, confirm. This saves the user from a full run that has to be thrown out.\n\n### Step 3: Fan out\n\nOne sub-agent per document, in parallel. Each sub-agent:\n\n1. Reads the entire document (not a RAG chunk — the whole thing).\n2. For each column, finds the relevant provision.\n3. Returns a structured row: for each column, `{value, state, quote, location}`.\n - `value` is the typed answer (or null if `state` is not `answered`)\n - `state` is `answered | not_present | unclear | needs_review`\n - `quote` is the verbatim supporting text (exact, no paraphrase, no ellipsis inside a sentence — if you cut, cut at sentence boundaries and mark it)\n - `location` is where the quote lives (section number, heading, page — whatever the document gives you)\n\n**The quote is not optional, and the verbatim rule is mechanical, not exhortation.** Each sub-agent must comply with all of the following before returning a cell with `state: answered`:\n\n- The `quote` MUST be a character-for-character copy of contiguous text from the source document, retrievable at the `location` the sub-agent cites. Do NOT compose a quote from a section heading plus standard boilerplate you expect to be there. Do NOT paraphrase and call it verbatim. Do NOT reconstruct a quote from memory of how such clauses \"usually\" read. Do NOT fill gaps in the source with ellipsis-stitching across non-contiguous text.\n- The `location` must be specific enough for the normalization pass to re-open the document and re-read the same span — a section number, heading, or page reference the reviewer can navigate to.\n- If the sub-agent cannot locate and copy the exact text (source truncated, OCR garbage, provision implied but not written, section heading visible but body not loaded), the cell state is `needs_review`, the `value` is null, and `notes` MUST contain `quote_unavailable: `. It is NEVER acceptable to set `state: answered` with a composed or reconstructed quote.\n- The same rule applies to `verbatim`-typed columns AND to the companion source quotes attached to `classify` / `date` / `duration` / `currency` / `number` / `free` cells. The supporting quote carries the same verbatim obligation as the cell value.\n\nThe normalization pass in Step 4 spot-checks this by re-reading the source at the cited `location` and comparing the stored `quote` character-for-character against the source text. A mismatch downgrades the cell to `needs_review`, notes `quote_mismatch`, and flags the whole column for a wider spot-check — if one sub-agent composed a quote, others in the same run may have too.\n\n### Step 4: Normalize\n\nAfter the fan-out, read the whole table column by column. This is the pass that catches the failure mode of every tabular review tool: the same clause interpreted inconsistently across documents.\n\nFor each `classify` column:\n- Check that every `answered` value is in the options list. Outliers get re-classified or bumped to `needs_review`.\n- Check for clusters: if 180 documents say `consent_required` and 20 say `consent_not_unreasonably_withheld`, that's probably real. If 195 say `consent_required` and 5 say `freely_assignable`, look at the 5 — they're either genuinely different or misclassified.\n\nFor each `date` / `duration` / `currency` column:\n- Check format consistency. Normalize.\n- Flag implausible values (a 99-year term, a $1 cap) as `needs_review`.\n\nFor each `verbatim` column AND for the companion source quotes on every other column:\n- Spot-check by re-opening the source document at the cited `location` for a random sample (at least 3–5 rows per column, or 10% of rows, whichever is larger) and comparing the stored `quote` character-for-character against the source.\n- If any quote is composed, paraphrased, reconstructed, or cannot be located at the cited span: downgrade that cell to `needs_review` with `quote_mismatch` in notes, and flag the whole column — expand the spot-check to the rest of the column rather than assuming the other rows are clean. One fabricated quote is enough to justify widening the check.\n- A cell with `state: answered` and a mismatched quote is a higher-severity failure than an `unclear` or `needs_review` cell — it misrepresents the evidence trail. Downgrade aggressively.\n\n### Step 5: Output\n\nWrite the table in three formats:\n\n**Markdown** (always, for in-session review):\n```markdown\n| Document | Counterparty | Effective Date | Change of Control | Assignment | ⚠️ Flags |\n|---|---|---|---|---|---|\n| Vendor MSA — Acme | Acme Corp | 2023-04-01 | consent_required | consent_required | — |\n| Supply Agmt — Beta | Beta LLC | 2021-11-15 | ⚠️ unclear | silent | CoC ambiguous §14.2 |\n```\n\n**CSV** (`.csv`, always):\nOne file for the values, one companion file for the quotes and locations (`_sources.csv`). Keeps the main file clean and the evidence trail complete.\n\n**Excel** (`.xlsx`) or **Google Sheets** — whichever the user works in. Ask; don't guess. Both follow the same workbook structure (see `references/excel-output.md` and `references/gsheets-output.md`). For Excel: Claude in Excel (Office agent) if available, `openpyxl` fallback. For Sheets: Sheets MCP if available, Sheets API via ADC, CSV-import fallback. In the spreadsheet output:\n- Each data column is paired with a hidden source column containing the quote and location. Cell comments (Excel) or notes (Sheets) on the visible column surface the quote on hover.\n- Color code by state: white = answered, yellow = unclear or needs_review, gray = not_present.\n- A `Verified` column per data column, blank by default. The reviewer marks it. This is the verify/flag pattern that makes the table auditable — the deal team can see at a glance what a human has actually checked.\n- A `_schema` sheet with the column definitions, so the file is self-documenting.\n\nPrepend the work-product header from the plugin config `## Outputs` as a top row. Alongside it, include a distribution note:\n\n> This review is derived from source documents that may be privileged, confidential, or both. It inherits the sources' privilege and confidentiality status — distribution beyond the privilege circle can waive privilege. Store with the matter's privileged files and make distribution decisions deliberately.\n\n### Step 6: Summary\n\nAfter the table is written, give the user a one-screen readout:\n- Document count, column count, rows completed\n- Count of `not_present`, `unclear`, `needs_review` per column — this is the verification workload\n- Any columns where the normalization pass flagged >10% of rows\n- Where the output files are\n- A reminder: every cell is a lead, not a finding. Verification required before this informs a rep, a schedule, or a memo.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **It does not replace reading the documents.** It tells you where to look.\n- **It does not produce confidence scores.** A 0.73 is not information. The `unclear` / `needs_review` states and the verbatim quotes are the confidence signal — if the quote doesn't support the value, flag it.\n- **It does not silently skip documents.** Every document the user pointed at gets a row. A document that couldn't be read gets a row of `needs_review` with a note.\n- **It does not pretend a paraphrase is a quote.** The evidence trail is the whole point.\n\n## Relationship to other skills\n\n- `diligence-issue-extraction` finds issues; this extracts data points. If an extraction reveals an issue (a MAC clause that references a specific earnings target, a poison pill), note it and suggest running diligence-issue-extraction on that document.\n- `material-contract-schedule` builds one specific table (the disclosure schedule). It can consume this skill's output directly — the schedule is a filtered, reformatted view of a tabular review.\n- `ai-tool-handoff` hands bulk review to Luminance/Kira when the corpus is too large or the team prefers a dedicated platform. This skill is the in-house option for anything it can handle — run it first, hand off the residue.\n\n## Output safeguards\n\nEvery output gets the work-product header. Every cell gets a source citation or a flagged state. The summary explicitly says verification is required. The Excel `Verified` column makes the verification state auditable. This is not a tool that lets you skip reading; it's a tool that makes reading faster.", + }, + { + id: "builtin-cfl-corporate-written-consent", + title: "Written Consent", + practice: "Corporate / M&A", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “written-consent” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /written-consent\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Board & Secretary (consents repository, resolution language, state of incorporation, board composition).\n2. Use the workflow below.\n3. Identify the action and classify (routine / review-flag).\n4. If review-flag: show outside counsel warning and confirm before proceeding.\n5. Search consents repository for closest precedent. If no repository: use seed consents from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n6. Draft consent in house format using precedent as base.\n7. Output: consent draft + signatory checklist + review prompts.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nMost routine board approvals don't need a meeting. Officer appointments, equity grants, bank authorizations, contract approvals above the officer threshold, intercompany arrangements — these happen by unanimous written consent. This skill drafts them quickly in your house format, finds the prior consent that's closest to what you need, and flags the actions where you should be getting outside counsel eyes before anyone signs.\n\n## Scope warning — read before drafting\n\n> **This skill is designed for day-to-day consents with direct precedents in your repository or seed documents.** Routine actions — officer appointments, equity grants, annual authorizations, standard contract approvals — are the right use case. The skill finds a prior consent that closely matches, adapts it to the current action, and produces a clean draft.\n>\n> **For major one-off actions, outside counsel review is prudent regardless of what this skill produces.** This includes: M&A transactions (asset purchases, stock purchases, mergers, investments), financing rounds, equity issuances to new investors, change-of-control provisions, dissolution or winding down, material real estate transactions, and any action that will be scrutinized in a subsequent due diligence process.\n>\n> The skill will flag automatically when the action looks like a major one-off. That flag is not a block — you can proceed. It is a prompt to think about whether a clean precedent-adapted draft is sufficient for this particular action.\n\n---\n\n## Major action + urgency = stop\n\nA board consent for a major one-off action (M&A, financing, dissolution, capital structure change, director election tied to a financing or M&A) that the user wants signed TODAY — \"send for DocuSign this afternoon,\" \"meeting in an hour,\" \"signing tonight,\" \"we need this before market open\" — goes through outside counsel review. Not because the plugin can't draft it — because a wrong consent on a major action is a one-way door, and the urgency pressure is exactly when mistakes happen.\n\nTrigger (both must be true):\n\n1. The action is in the **Review flag — major one-off** category below (M&A, financing, dissolution, capital structure change, change-of-control provision, director election tied to a financing or M&A, material real estate transaction, any action that will appear in a future financing or M&A data room).\n2. The user's ask contains an irreversibility signal — \"send for DocuSign,\" \"sign today,\" \"board is signing this afternoon/tonight,\" \"need this before [market open / closing / the meeting at X],\" any phrasing that commits the consent to signature on the same turn.\n\nWhen both are true, output this and stop:\n\n> ⛔ **Major action + same-day signature — I won't mark this ready to sign.**\n>\n> This is [action type], which is a one-way door. You've asked for it to be signed today. That combination is exactly when mistakes on a board consent become hardest to unwind.\n>\n> I'll draft it — happily — but I won't mark it ready to sign without an outside-counsel look. If outside counsel is already engaged on this deal, hand them this draft. If not, this is the thing outside counsel is for. Your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) can point you to a lawyer referral service that can find one same-day if needed.\n>\n> Two ways forward:\n>\n> 1. **I draft, outside counsel reviews, then signatures** — the normal path for a major corporate action. Tell me to draft and I will.\n> 2. **Outside counsel is already on this deal and cleared the draft path** — tell me who reviewed and when. I'll proceed and include a note that outside counsel has the draft.\n>\n> I will not draft in \"ready-to-send\" form under same-day pressure without one of those two. This is not a delay — it's the only way a same-day major-action consent is defensible if anyone ever looks at the file.\n\nDo not proceed to Step 1 or any drafting under this gate without an explicit response choosing path 1 or path 2. A routine consent with no major-action trigger, or a major-action consent without the same-day signature ask, follows the normal flow below — the \"Outside counsel review recommended\" flag on the major-one-off category still applies but does not hard-stop.\n\n---\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Board & Secretary`:\n - Consents repository location\n - House resolution language\n - State of incorporation (for notice requirements)\n - Board composition (for signatory list)\n - Written consents — scope and any limits\n\n### No-precedent hard stop\n\nIf (a) no consents repository is configured in `## Board & Secretary` → Consents repository, AND (b) no seed consent document has been provided to this skill (either uploaded this session or referenced in the `## Board & Secretary` → Consent format section with extracted resolution/recital/authorisation language from a specific seed), **STOP before drafting**. Do not proceed to Step 1 intake, do not draft from a generic template, do not \"get started\" with a filler format.\n\nOutput exactly this block and wait for a response:\n\n> **No precedent available — stopping before draft.**\n>\n> I don't have a precedent to match. A board consent drafted without your house format will need more correction than it saves — resolution language, recital depth, authorisation boilerplate, and signature-block conventions all carry house-specific choices that the reviewer will rewrite from scratch if I start from a generic template.\n>\n> Two ways to unblock:\n>\n> 1. **Paste or upload a prior consent** (any recent UWC from this company in any category — I extract the format, not the substance), OR\n> 2. **Tell me \"draft from a generic template anyway — I'll adjust the formalities myself\"** — only pick this if you know you'll rework the resolution language, recital style, and authorisation block by hand before circulation. Say it explicitly; I will not infer it.\n>\n> Which do you want to do?\n\nDo NOT proceed without an explicit response choosing one of those two paths. Draft attempts absent a precedent are the highest-rework-to-value output this skill can produce — the hard stop is intentional.\n\n---\n\n## Step 1: Identify the action\n\nAsk the user what action the board needs to approve. Gather:\n\n- **What is being approved?** (One sentence.)\n- **Any supporting detail?** For example: the name of the officer being appointed, the grant amount and price for an equity grant, the counterparty and contract value for a contract approval.\n- **Effective date:** Today, or a specific date?\n- **Signatories:** Full board, or a specific committee? If the your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) written-consent scope says certain actions require a meeting rather than consent, flag it now.\n- **Any director conflict?** Does any director have a material interest in the action being approved? If yes: flag it. The conflicted director may still be able to sign depending on state law and the nature of the conflict, but the consent should disclose it and the user should confirm.\n\n### Action classification\n\nClassify the action before searching for precedent:\n\n**Routine — direct precedent likely:**\n- Officer appointment or removal\n- Equity grant (option, RSU, restricted stock) to existing plan participants\n- Bank account authorization or signatory update\n- Approval of a contract below a material threshold\n- Annual authorization resolutions (tax matters, benefits plans, etc.)\n- Intercompany loan or services agreement at arm's length terms\n- Registered agent or registered office change\n\n**Review flag — major one-off, outside counsel prudent:**\n- M&A transaction (acquisition, merger, asset purchase, investment)\n- New financing round or debt facility\n- Equity issuance to a new investor\n- Change-of-control provision or trigger\n- Approval of an agreement that itself requires board approval under the company's charter or stockholder agreements\n- Dissolution, winding down, or bankruptcy filing\n- Material real estate transaction\n- Any action that will appear as a board approval exhibit in a future financing or M&A data room\n\nIf the action is in the review-flag category, show this before drafting:\n\n> ⚠️ **Outside counsel review recommended.** This looks like [action type], which is a major corporate action where a precedent-adapted draft may not be sufficient. Consider having outside counsel review before circulation. Want me to proceed with a draft anyway?\n\n---\n\n## Step 2: Search for precedent\n\n### If consents repository is connected\n\nSearch the repository for the closest prior consent. Search strategy:\n\n1. Search by action type keyword (e.g., \"officer appointment\", \"equity grant\", \"bank authorization\")\n2. Return the most recent matching consent, or ask the user to choose if multiple close matches exist:\n\n> I found [N] prior consents that look like this:\n>\n> 1. [Consent title / description] — [Date]\n> 2. [Consent title / description] — [Date]\n>\n> Which one is closest to what you need? Or should I use the most recent?\n\n3. Read the selected consent. Extract: resolution language, recital structure, authorization language, any specific conditions or carve-outs.\n4. Note any differences between the prior action and the current one that will need to be updated in the draft.\n\n### If no repository (seed documents only)\n\nExtract the format from the seed consents in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Note that no precedent search is available — the draft will follow house format but without substantive precedent matching. Flag this to the user:\n\n> No consents repository is connected, so I'm working from your seed documents for format. For this action type specifically, you may want to check whether you have a prior consent to use as a substantive starting point.\n\n---\n\n## Step 3: Draft the consent\n\nUse the house format. The structure below is the standard — adapt to match the precedent or seed format exactly.\n\n```\nUNANIMOUS WRITTEN CONSENT\n[OF THE BOARD OF DIRECTORS / OF THE [COMMITTEE NAME]]\nOF [COMPANY NAME]\n\n[Date]\n\nThe undersigned, constituting all of the members of the\n[Board of Directors / [Committee]] of [Company Name], a [State] [corporation /\nlimited liability company] (the \"Company\"), hereby adopt the following\nresolutions by written consent pursuant to [Section X of the [State] General\nCorporation Law / applicable operating agreement], in lieu of a meeting:\n\n[AGENDA ITEM / ACTION HEADING — if multiple resolutions]\n\nWHEREAS, [background recital — one or two sentences stating the relevant facts\nand why the board is being asked to act]; and\n\nWHEREAS, [additional recital if needed]; and\n\nNOW, THEREFORE, BE IT RESOLVED, that [the specific action being approved,\nin precise language — name names, state amounts, reference the specific\nagreement or instrument where applicable];\n\nRESOLVED FURTHER, that [any related or implementing resolution — e.g., the\nspecific officers authorized to sign documents, the authority granted];\n\nRESOLVED FURTHER, that the officers of the Company are, and each of them\nhereby is, authorized and directed, in the name and on behalf of the Company,\nto take all actions and to execute and deliver all documents, instruments,\ncertificates and agreements as such officers may deem necessary or appropriate\nto carry out the intent and purposes of the foregoing resolutions; and\n\nRESOLVED FURTHER, that any actions previously taken by any officer of the\nCompany in connection with the foregoing are hereby ratified, confirmed and\napproved in all respects.\n\n[Repeat WHEREAS / RESOLVED block for each additional action if multi-resolution consent]\n\nThis Written Consent may be executed in one or more counterparts, each of\nwhich shall be deemed an original and all of which together shall constitute\none and the same instrument. Electronic signatures shall be deemed original\nsignatures for all purposes.\n\n[SIGNATURE BLOCKS — one per required signatory]\n\n_______________________________\n[Director Name]\n[Title, if applicable]\nDate: _______________\n\n[Repeat for each director / committee member]\n```\n\n### Resolution drafting notes\n\n- **Be precise.** Vague resolutions create problems in due diligence. \"Approved the transaction\" is not useful. \"Approved the Asset Purchase Agreement dated [date] between [Buyer] and [Company], substantially in the form attached hereto as Exhibit A\" is.\n- **Name the authorized signatories.** Don't just say \"officers\" if a specific officer needs authority for a specific thing. Name them.\n- **Reference exhibits.** If a document is being approved, attach it as an exhibit and reference it in the resolution. The consent is only as useful as its specificity.\n- **Match the house language exactly.** \"RESOLVED, THAT\" vs. \"BE IT RESOLVED\" vs. \"RESOLVED\" — use whatever is in the precedent or seed documents. Do not switch formats within a consent.\n\n---\n\n## Step 4: Confirm the consent rules for the state of incorporation\n\nCheck the state of incorporation in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Research the written-consent requirements for that state before drafting:\n\n- Is unanimity required for a board written consent, or is a lower threshold permitted?\n- Is notice to non-signatory directors required? On what timing?\n- Is notice to non-signatory stockholders required (for stockholder consents)? On what timing?\n- What form of signature is valid (wet ink, electronic, counterparts)?\n- Does the charter or bylaws override any default rule — e.g., a higher signature threshold, a different notice window, a restriction on which actions can be taken by consent?\n\nCite the controlling statute section and any charter/bylaw provisions relied on. Verify currency — state corporate codes are amended regularly. Flag uncertainty for attorney verification rather than stating a rule you haven't confirmed.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) records a house position on any of these questions, apply it and note the legal backstop being relied on. Add a short \"State-law notice\" block to the output summarizing what you confirmed (or flagged) so the user isn't left wondering.\n\n---\n\n## Step 4.5: Consequential-action gate (execute consent)\n\n**Before proceeding to output:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Executing a written consent has legal consequences — it binds the entity and becomes a corporate record. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - What the action is (the resolution)\n> - What the analysis found (state-law notice, signature threshold, any flagged conflicts)\n> - Open questions (anything flagged for attorney verification above)\n> - What could go wrong (invalid consent, breach of fiduciary duty, signature defect, conflict not properly handled)\n> - What to ask the attorney (is this the right vehicle; are there missing recitals; does the charter/bylaws permit consent for this action)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not produce the final signatory-ready draft past this gate without an explicit yes. Research, format extraction, and a marked-DRAFT for attorney review are fine.\n\n---\n\n## Step 5: Output\n\nProduce:\n\n1. **The consent draft** — complete, ready to review and circulate. The executed written consent itself is a corporate record, not privileged; do not apply the work-product header to the consent as circulated. The drafting notes, signatory tracker, and analysis below are work product — prepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`):\n\n ```\n [WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n ```\n\n2. **Signatory checklist:**\n```\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\nSIGNATORY CHECKLIST — [Action] — [Date]\n\nRequired signatories (unanimous consent required):\n□ [Director Name 1]\n□ [Director Name 2]\n□ [Director Name 3]\n[etc. — pulled from board composition in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\nConflict disclosures:\n[None / [Director Name] has a disclosed interest — confirm whether recusal or disclosure is appropriate]\n\nState law notice: [confirmed-rule-for-state-of-incorporation / confirm]\n```\n\n3. **Review prompts:**\n```\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\nBEFORE CIRCULATING — check:\n□ Resolution language precisely describes the action (no vague approvals)\n□ Correct effective date\n□ All required exhibits attached and referenced\n□ Authorised signatories named correctly\n□ Any director conflicts disclosed or resolved\n□ For major actions: outside counsel has reviewed\n```\n\n4. **Final note on the draft — add before circulation.** Prepend to the consent draft as a separate pre-execution note, then strip before the consent is signed:\n\n> This is a draft for attorney review, not an executed consent. Executing it binds the entity and becomes a corporate record — a licensed attorney reviews, edits as needed, and takes professional responsibility before it goes out. Do not circulate for signature unreviewed.\n\n---\n\n## What this skill does not do\n\n- It does not determine whether an action legally requires board approval — that judgment belongs to the attorney.\n- It does not advise on director fiduciary duties or conflict of interest resolution — it flags conflicts, the attorney handles them.\n- It does not replace outside counsel review for major transactions — the scope warning is genuine, not boilerplate.\n- It does not circulate the consent — output is for the attorney to review and send via their own process.\n- It does not track returned signatures — the signatory checklist is a starting point; signature tracking is manual or handled by your document management process.", + }, + { + id: "builtin-cfl-employment-expansion-kickoff", + title: "Expansion Kickoff", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “expansion-kickoff” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /expansion-kickoff\n\nStarts an international expansion project for a new country — gathers intake,\nruns EOR vs. entity framing, drafts cross-functional questions, surfaces\ncountry-specific flags, and creates a persistent tracker.\n\n## Instructions\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, escalation table.\n2. Load the `international-expansion` reference skill and run the full workflow.\n3. If a tracker file already exists for this country (the current project's documents),\n flag it: \"An expansion tracker for [country] already exists. Use\n `the “Expansion Update” workflow [country]` to update it, or confirm\n you want to start over.\"\n4. Create the current project's documents on completion.\n\n## Examples\n\n```\nthe “Expansion Kickoff” workflow Germany\n```\n\n```\nthe “Expansion Kickoff” workflow\n(skill will ask which country)\n```\n\n> Detailed EOR vs. entity framework, cross-functional questions, briefing\n> templates, and tracker schema live in the `international-expansion`\n> reference skill — load it before doing substantive work.", + }, + { + id: "builtin-cfl-employment-expansion-update", + title: "Expansion Update", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “expansion-update” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /expansion-update\n\nReturns to an open expansion tracker and updates item status based on what\nhas happened since the last session. Recalculates what is now unblocked,\nflags anything overdue, and surfaces the next priorities.\n\n## Instructions\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n2. Identify the tracker file: the current project's documents. If it doesn't\n exist, respond: \"No expansion tracker found for [country]. Run\n `the “Expansion Kickoff” workflow [country]` to start one.\"\n\n3. Read the tracker. Show the current state:\n\n```\n[Country] Expansion — last updated [date]\nOpen: [N] | In progress: [N] | Done: [N] | Blocked: [N]\n\nNext priorities (open items with earliest due dates or highest-dependency):\n [item] — owner: [owner]\n [item] — owner: [owner]\n [item] — owner: [owner]\n```\n\n4. Ask for updates in a single prompt — do not ask about each item one by one:\n\n > Which items have moved since we last looked? Tell me what's changed\n > (e.g., \"EOR decision made — going with Deel\", \"outside counsel engaged —\n > call scheduled for Thursday\", \"PE analysis still open, waiting on tax\").\n > You can also add new items or change due dates.\n\n5. Apply updates to the tracker file. For any item newly marked `done`,\n check whether it unblocks other items and flag those as now actionable.\n\n6. If any item has a due date that has passed and is still `open` or\n `in-progress`, flag it:\n\n```\n⚠️ Overdue: [item] — was due [date], owner: [owner]\n```\n\n7. Write the updated tracker. Confirm:\n\n```\nTracker updated — [N] items closed, [N] still open.\nNext priority: [top open item].\n```\n\n## Examples\n\n```\nthe “Expansion Update” workflow Germany\n```\n\n```\nthe “Expansion Update” workflow\n(will ask which country if multiple trackers exist)\n```\n\n> Detailed tracker schema, item-status rules, and dependency logic live in the\n> `international-expansion` reference skill — load it before doing substantive\n> work.", + }, + { + id: "builtin-cfl-employment-handbook-updates", + title: "Handbook Updates", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “handbook-updates” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Handbook Updates\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nHandbook changes have ripple effects. Change the PTO policy and you've affected the final pay calculation, the leave policy cross-reference, and three state supplements. This skill finds the ripples before they become inconsistencies.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → handbook location, state supplements list, update cadence.\n\n## Workflow\n\n### Step 1: Get the change\n\n- What section is changing?\n- What's the new language?\n- Why? (Legal requirement, policy decision, cleanup)\n\n### Step 2: Diff against current\n\nRead the current handbook section. Show the diff:\n\n```diff\n- [old language]\n+ [new language]\n```\n\n### Step 3: Find cross-references\n\nSearch the handbook for references to the changed section:\n\n- Other policies that cite this one (\"see the PTO policy for accrual rates\")\n- Defined terms that this section uses or defines\n- State supplements that modify this section\n\nEach cross-reference: does it still make sense after the change? Flag any that break.\n\n### Step 4: State supplement impact\n\nFor each state supplement in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- Does this supplement modify the section being changed?\n- Does the change make the supplement obsolete, wrong, or incomplete?\n- Does the change create a need for a *new* supplement in a state that didn't need one before?\n\n### Step 5: Promise check\n\nIs the change reducing something the old version promised?\n\nIf yes: that's a risk. Some states treat handbook policies as contractual. Reducing a benefit may need more than just updating the document — advance notice, consideration, or in some cases it can't be done retroactively.\n\nFlag this. Don't block it — but flag it.\n\n## Output\n\n```markdown\n## Handbook Update: [Section name]\n\n### Change\n\n[diff]\n\n### Cross-reference impact\n\n| Section | References changed section | Still accurate? | Fix needed |\n|---|---|---|---|\n| [name] | [how] | ✅/⚠️ | [what] |\n\n### State supplement impact\n\n| State | Current supplement | After change | Action |\n|---|---|---|---|\n| [state] | [what it says] | [still valid / obsolete / needs update] | [none / update / new supplement needed] |\n\n### Promise check\n\n[If reducing a benefit: flag + jurisdictional risk note]\n\n### Ready to publish\n\n- [ ] Cross-references updated\n- [ ] State supplements updated\n- [ ] [If benefit reduction: notice/consideration addressed]\n- [ ] Version number and date updated\n- [ ] Acknowledgment process (if required)\n```\n\n## What this skill does not do\n\n- Approve handbook changes. HR/legal leadership does.\n- Communicate changes to employees.\n- Track acknowledgments.", + }, + { + id: "builtin-cfl-employment-hiring-review", + title: "Hiring Review", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “hiring-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /hiring-review\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, hiring review triggers, restrictive covenant policy.\n2. Use the workflow below.\n3. Check: jurisdiction, classification, restrictive covenants, background check compliance.\n4. Flag anything that hits the jurisdiction-specific escalation table.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nOffer letters are mostly boilerplate until they're not. The jurisdiction check\nand the restrictive-covenant check are where this skill earns its keep. The\nskill does not state the law — every jurisdiction-specific rule is researched\nand cited at the time of review.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, hiring review triggers, restrictive\ncovenant policy, offer letter template location.\n\n## Output header\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` (it differs by user role — see `## Who's using this`).\n\n## Workflow\n\n### Step 1: Jurisdiction\n\nWhere will this person work? Not where HQ is — where *they* are.\n\nIf remote: their home state/country governs. If hybrid: usually their home\nstate, but check the offer letter's choice-of-law clause (may or may not hold\nup).\n\nCheck the jurisdiction table in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for this state/country. If it's\nnot in the table — new jurisdiction — flag that: \"First hire in [state]. The\njurisdiction table doesn't cover this. Research needed before offer goes out.\"\n\n### Step 2: Classification\n\nExempt or non-exempt? The offer should say, and the role should support it.\n\n| Test | Check |\n|---|---|\n| Salary basis | Paid a fixed salary regardless of hours? |\n| Salary level | Above the applicable federal and state thresholds? |\n| Duties test | Does the role actually involve the exempt duties? |\n\n> **Research before calling exemption.** Identify the currently operative\n> salary thresholds (federal and state — several states index annually and\n> several have tiered thresholds by employer size) and the applicable duties\n> test(s) for the role. Cite primary sources. Verify currency.\n\nIf the offer says exempt but the role description does not support the\nexempt duties — flag it. Misclassification is expensive.\n\n### Step 3: Restrictive covenants\n\nIf the offer includes a non-compete, customer non-solicit, employee\nnon-solicit, or confidentiality/IP assignment:\n\n> **Research enforceability before advising.** For the employee's jurisdiction,\n> identify the currently operative rules on each restrictive covenant in the\n> offer. Non-compete enforceability in particular has shifted in multiple\n> states in recent years through legislation, agency action, and litigation —\n> do not rely on prior memory of which states permit non-competes. Note:\n> - The specific type of covenant (non-compete, customer non-solicit, employee\n> non-solicit, confidentiality/trade-secret, IP assignment) — each has its\n> own rules.\n> - Any salary or income threshold that conditions enforceability.\n> - Any notice, consideration, or garden-leave requirements.\n> - Any industry-specific carve-outs (e.g., healthcare, broadcasting).\n> - Duration and geographic-scope reasonableness tests.\n> - Choice-of-law and choice-of-forum enforceability for out-of-state covenants.\n> Cite primary sources. Verify currency.\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) restrictive covenant policy: does this hire even get one?\nSome companies use them selectively. Apply the house policy first, then\nresearch overlays from the jurisdiction.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for the jurisdiction's exemption thresholds, restrictive-covenant rules, pay-transparency law, or any other item you're researching, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [jurisdiction / topic]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Tag every citation in the review with where it came from: `[Westlaw]`, `[CourtListener]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the user supplied. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n### Step 4: Jurisdiction-specific requirements\n\nCheck the your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) table for this jurisdiction. Common categories to\nresearch for each hire:\n\n- **Pay transparency** — does the jurisdiction require a salary range in the\n posting? If so, is this offer within the posted range? Research the current\n rule (including any recent amendments or new enforcement guidance).\n- **Ban-the-box** — does the jurisdiction or locality restrict the timing or\n scope of criminal-history inquiries?\n- **Salary-history limits** — is the jurisdiction one that restricts asking\n about or relying on prior salary? Research current rules and recent\n amendments.\n- **Required offer-letter or onboarding notices** — some jurisdictions require\n specific notices at offer or hire (wage-notice statutes, sick-leave notices,\n etc.). Research what is currently required and whether a template exists.\n\nCite primary sources. Verify currency.\n\n### Step 5: Offer letter content\n\nRead the letter. Check:\n\n**Employment-at-will is US-only.** \"At-will\" means either party can terminate without cause or notice (subject to statutory exceptions). This concept does not exist outside the US:\n\n- **US (most states):** At-will is the default. Offer letters often include \"at-will\" language to defeat implied-contract arguments. Check that it's present if US.\n- **Montana:** Not at-will — Wrongful Discharge from Employment Act requires cause after probation.\n- **UK:** No at-will. Employees have statutory protections from day 1 (unfair dismissal after 2 years of service, automatic unfair dismissal for protected reasons from day 1). The offer letter must contain the written statement of particulars (ERA 1996 s.1): pay, hours, notice period, holidays, pension, disciplinary/grievance procedures.\n- **EU:** No at-will. Termination requires cause, notice, and often works council consultation or collective redundancy procedures. The offer letter requirements vary by member state but notice periods and written particulars are standard.\n- **Australia:** No at-will. Fair Work Act minimum notice periods, unfair dismissal protections, NES.\n- **Canada:** No at-will. Common law reasonable notice (can be months), ESA minimums, wrongful dismissal exposure.\n- **Singapore, other APAC:** No at-will. Employment Act and contract-based protections.\n\n**Check for at-will language ONLY if the jurisdiction is US.** For non-US jurisdictions, check instead for: notice period (and whether it meets statutory minimum), the written-statement particulars the jurisdiction requires, probation period terms, and any jurisdiction-specific mandatory clauses.\n\n**Never recommend adding at-will language to a non-US offer letter.** It's legally meaningless, it can conflict with mandatory statutory terms, and it signals to the employee's lawyer that the employer didn't understand the jurisdiction.\n\n- At-will language present and not undermined elsewhere (US only — see above)\n- Contingencies clear (background check, reference, I-9 if US / right-to-work verification for the applicable jurisdiction)\n- Start date, title, salary, reporting structure stated\n- Equity terms (if any) consistent with the plan\n- Integration clause so the letter is the whole deal\n- For non-US: notice period meets statutory minimum, jurisdiction's required written-statement particulars included, probation period compliant with local rules\n\n## Output\n\n> **Jurisdiction assumption.** This review applies the rules of the employee's work jurisdiction identified in Step 1. Enforceability of restrictive covenants, exemption thresholds, pay-transparency obligations, salary-history limits, and required notices vary materially by state and locality, and several have shifted recently. If the candidate's work location changes, or the role spans jurisdictions, this review may not apply as written.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Hiring Review: [Candidate] — [Role] — [Jurisdiction]\n\n**Overall:** [Clear to send | Changes needed | Escalate]\n\n### Jurisdiction: [State/Country]\n[Jurisdiction table entry. Any auto-escalate triggers that fire.]\n\n### Classification\n[Exempt/non-exempt call, grounded in researched thresholds and duties test.\nAny flags.]\n\n### Restrictive covenants\n[If any. Enforceability call per researched jurisdiction rules, with pinpoint\ncites and currency note. Suggested changes.]\n\n### Jurisdiction-specific requirements\n[Pay transparency, notices, salary-history rules, etc. — each researched and\ncited, or flagged as needing research.]\n\n### Offer letter\n[Any issues with the letter itself]\n\n### Action items\n- [ ] [specific change needed before sending]\n```\n\n## Consequential-action gate (make an offer)\n\n**Before producing a \"Clear to send\" recommendation or a final offer letter for signature:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Making an offer has legal consequences — the letter is a contract, and restrictive covenants, classification, and jurisdiction-specific terms are difficult to reset once sent. Have you reviewed this offer with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - Candidate, role, jurisdiction (where they'll actually work)\n> - Classification call (exempt/non-exempt) and why\n> - Restrictive covenants in the offer and the enforceability analysis\n> - Jurisdiction-specific requirements that apply (pay transparency, wage notices, salary-history rules)\n> - Open questions and what's unresolved\n> - What could go wrong (misclassification liability, unenforceable non-compete, missing required notice, conflicting at-will language)\n> - What to ask the attorney (is this the right form for this jurisdiction; can we use our standard non-compete here; what notices need to go with the letter)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not produce a \"Clear to send\" output past this gate without an explicit yes. A marked-DRAFT flagged for attorney review is fine.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- Draft the offer letter — reviews it.\n- Make the hire decision — checks the paperwork.\n- State restrictive-covenant or exemption rules from memory — every\n jurisdiction-specific call is based on researched, cited sources verified\n for currency.\n- Research a new jurisdiction in depth on its own — flags that research is\n needed, and uses `wage-hour-qa` or outside counsel to fill in.", + }, + { + id: "builtin-cfl-employment-internal-investigation", + title: "Internal Investigation", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “internal-investigation” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Internal Investigation Skill\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Output header\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` (it differs by user role — see `## Who's using this`). Every file, log, memo, and summary produced by this skill opens with that header.\n\n> **Distribution discipline.** Every file this skill creates — log entries, memo drafts, audience summaries, document notes — inherits the privilege and confidentiality status of the underlying investigation. Distribution beyond the privilege circle (forwarding to non-attorneys outside the investigation team, cc'ing HR without scoping, handing to the business side) can waive privilege over the entire investigation. Store these files where privileged materials live, label per the work-product header, and make every distribution decision deliberately.\n\n## ⚠️ Privilege notice — read before proceeding\n\n**Marking does not create privilege.** The header above reflects the intended\nprotection and is important to include — but it does not itself establish\nprivilege. Whether any given output is actually privileged depends on whether\nthe investigation is attorney-directed, the purpose for which documents are\ncreated, and how they are subsequently used or disclosed.\n\n**Before opening a matter, confirm:** Is this investigation attorney-directed?\nIf it is not — if HR is running it with legal in an advisory role, or if it was\nnot initiated at the direction of counsel for the purpose of obtaining legal advice —\nthe privilege analysis changes materially and this skill's default labeling may\nbe misleading. Flag that question to the attorney before creating any log or file.\n\nIf there is any doubt about privilege applicability, the attorney should resolve it\nbefore investigation files are created. Improperly labeled materials can create\nproblems in discovery if privilege is later challenged.\n\n---\n\n## Purpose\n\nInternal investigations fail in two ways: coverage gaps (sources that were\nnever gathered) and synthesis gaps (evidence that was gathered but never\nconnected). This skill handles both — it tracks what has and hasn't been\ngathered, processes document dumps to surface what matters without burying\nthe attorney, and maintains a structured log that can be turned into a\nprivileged memo at any point.\n\n## Privilege note\n\nAll files created by this skill carry the privilege marking above.\nSee the notice at the top of this skill for the full caveat on what that\nmarking does and does not do.\n\n## Load context\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → escalation table, any investigation protocols noted.\n\n---\n\n## Mode 1: Open a new matter\n\nTriggered by `the “Investigation Open” workflow` or \"open an investigation\"\nor \"start an investigation into\".\n\n### Step 1 — Intake\n\nAsk the following in a single block:\n\n> To open the investigation log I need a few things:\n>\n> **The matter**\n> - What is the allegation or concern in plain terms?\n> - Who is the complainant (or what triggered this — complaint, tip, audit,\n> manager observation)?\n> - Who is the respondent or subject?\n> - What is the approximate timeframe the alleged conduct occurred?\n> - Is this attorney-directed? (If yes: work product protection applies.\n> If no: flag privilege risk before proceeding.)\n>\n> **Investigation type** (helps me suggest the right sources checklist)\n> - HR: harassment / discrimination / retaliation\n> - Financial misconduct: expense fraud / procurement irregularities / embezzlement\n> - Executive misconduct: COI / undisclosed relationships / governance failures\n> - Whistleblower: retaliation for protected activity\n> - Other: describe briefly\n>\n> **Representation and employer status** (surfaces parallel legal frameworks\n> that change interview procedure)\n> - Is the respondent, the complainant, or any anticipated witness represented\n> by a union or covered by a collective bargaining agreement? (If yes, flag\n> for Weingarten research — representational rights at investigatory\n> interviews may apply and change the interview protocol.)\n> - Is the company a public employer (government entity, public university,\n> state or municipal agency) or otherwise acting under color of state law?\n> (If yes, flag for Garrity research — compelled statements in public-sector\n> investigations have special use-immunity consequences and change how\n> interviews must be conducted and documented.)\n\nIf either flag fires, research the applicable rules (NLRA / state\npublic-sector labor statutes for Weingarten; 5th Amendment and the Garrity\nline of cases, plus any state analogs) before conducting interviews. Cite\nprimary sources. Verify currency. Do not interview until the protocol is\nadjusted.\n\n### Step 2 — Create the matter directory and files\n\nCreate the following files:\n\nthe current project's documents:\n\n```yaml\n# [WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\nmatter: \"[matter name]\"\nmatter_slug: \"[slug]\"\nopened: \"[ISO date]\"\nattorney_directed: [true/false]\nallegation: \"[plain-language summary]\"\ncomplainant: \"[name/role or anonymous]\"\nrespondent: \"[name/role]\"\nconduct_timeframe: \"[approximate dates]\"\ninvestigation_type: \"[HR/financial/executive/whistleblower/other]\"\nstatus: open\nlast_updated: \"[ISO date]\"\n\nissues:\n - \"[Issue 1 — derived from allegation, e.g. 'alleged hostile work environment']\"\n - \"[Issue 2 if applicable]\"\n\nentries: []\n\nevidentiary_gaps: []\n```\n\nthe current project's documents:\n\nGenerated from the investigation type. See sources checklist templates below.\n\nthe current project's documents:\n\n```yaml\n# [WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\nmatter: \"[matter name]\"\ntotal_reviewed: 0\ntotal_surfaced: 0\nlast_updated: \"[ISO date]\"\ndocuments: []\n```\n\n### Step 3 — Sources checklist\n\nGenerate the appropriate checklist based on investigation type. Present it\nto the attorney and ask: \"Does this fit your matter? Let me know if any items\nare not applicable (I'll mark them N/A) or if there are additional sources\nspecific to this situation.\"\n\n**HR investigation sources (harassment/discrimination/retaliation):**\n```yaml\nsources:\n - id: 1\n source: \"Complainant interview\"\n status: open\n notes: \"\"\n - id: 2\n source: \"Respondent interview\"\n status: open\n notes: \"\"\n - id: 3\n source: \"Witness interviews — identify from complainant and respondent accounts\"\n status: open\n notes: \"\"\n - id: 4\n source: \"Email/messaging review — parties, relevant date range\"\n status: open\n notes: \"\"\n - id: 5\n source: \"HR records — respondent's performance history, prior complaints,\n prior discipline\"\n status: open\n notes: \"\"\n - id: 6\n source: \"Prior complaints — any prior complaints against respondent in\n HR system\"\n status: open\n notes: \"\"\n - id: 7\n source: \"Comparator data — how were similar situations handled\"\n status: open\n notes: \"\"\n - id: 8\n source: \"Relevant policies — harassment, code of conduct, reporting\n procedures (version in effect at time of alleged conduct)\"\n status: open\n notes: \"\"\n - id: 9\n source: \"Org chart and reporting relationships at time of alleged conduct\"\n status: open\n notes: \"\"\n - id: 10\n source: \"Calendar records — any meetings or events mentioned in accounts\"\n status: open\n notes: \"\"\n - id: 11\n source: \"Upjohn warning documentation — confirm interviews were preceded\n by Upjohn warnings and documented\"\n status: open\n notes: \"\"\n```\n\n**Financial misconduct sources:**\n```yaml\nsources:\n - id: 1\n source: \"Expense reports — subject, relevant period\"\n status: open\n notes: \"\"\n - id: 2\n source: \"Approval records — who approved the expenses or transactions\"\n status: open\n notes: \"\"\n - id: 3\n source: \"Vendor/contractor records — contracts, invoices, payment records\"\n status: open\n notes: \"\"\n - id: 4\n source: \"Financial system records — AP, GL entries for relevant accounts\"\n status: open\n notes: \"\"\n - id: 5\n source: \"Email/messaging review — subject, approvers, counterparties\"\n status: open\n notes: \"\"\n - id: 6\n source: \"Subject interview\"\n status: open\n notes: \"\"\n - id: 7\n source: \"Approver interviews\"\n status: open\n notes: \"\"\n - id: 8\n source: \"Counterparty/vendor interviews (if accessible)\"\n status: open\n notes: \"\"\n - id: 9\n source: \"Audit logs — system access logs for relevant accounts/systems\"\n status: open\n notes: \"\"\n - id: 10\n source: \"Prior audits or reviews covering the relevant period\"\n status: open\n notes: \"\"\n - id: 11\n source: \"Upjohn warning documentation\"\n status: open\n notes: \"\"\n```\n\n**Executive misconduct sources:**\n```yaml\nsources:\n - id: 1\n source: \"Subject interview\"\n status: open\n notes: \"\"\n - id: 2\n source: \"Board/compensation committee records — relevant resolutions,\n minutes, approvals\"\n status: open\n notes: \"\"\n - id: 3\n source: \"Employment agreement and any amendments\"\n status: open\n notes: \"\"\n - id: 4\n source: \"Equity records — grants, exercises, vesting\"\n status: open\n notes: \"\"\n - id: 5\n source: \"Expense reports and approval records\"\n status: open\n notes: \"\"\n - id: 6\n source: \"Email/messaging review — subject, relevant counterparties\"\n status: open\n notes: \"\"\n - id: 7\n source: \"Conflict of interest disclosures (or absence thereof)\"\n status: open\n notes: \"\"\n - id: 8\n source: \"Outside business activity records\"\n status: open\n notes: \"\"\n - id: 9\n source: \"Witness interviews — direct reports, peers, board members\"\n status: open\n notes: \"\"\n - id: 10\n source: \"Prior complaints or concerns raised about subject\"\n status: open\n notes: \"\"\n - id: 11\n source: \"Upjohn warning documentation\"\n status: open\n notes: \"\"\n```\n\n**Whistleblower sources:**\n```yaml\nsources:\n - id: 1\n source: \"Complainant interview\"\n status: open\n notes: \"\"\n - id: 2\n source: \"Original complaint or tip — written form if exists\"\n status: open\n notes: \"\"\n - id: 3\n source: \"Records related to the underlying allegation (the thing\n complainant blew the whistle on)\"\n status: open\n notes: \"\"\n - id: 4\n source: \"Records related to any adverse action taken against complainant\n after the protected activity\"\n status: open\n notes: \"\"\n - id: 5\n source: \"Decision-maker interviews — who made the adverse action decision\"\n status: open\n notes: \"\"\n - id: 6\n source: \"Comparator data — treatment of similarly situated employees\n who did not engage in protected activity\"\n status: open\n notes: \"\"\n - id: 7\n source: \"Email/messaging review — decision-makers, relevant timeframe\"\n status: open\n notes: \"\"\n - id: 8\n source: \"Timing analysis — proximity of protected activity to adverse\n action\"\n status: open\n notes: \"\"\n - id: 9\n source: \"Respondent/decision-maker interviews\"\n status: open\n notes: \"\"\n - id: 10\n source: \"Upjohn warning documentation\"\n status: open\n notes: \"\"\n```\n\nAfter presenting the checklist, write it to\nthe current project's documents.\n\n---\n\n## Mode 2: Add data\n\nTriggered by `the “Investigation Add” workflow` or \"add to the [matter]\ninvestigation\" or when the attorney pastes documents or interview notes.\n\n### Step 1 — Identify the matter\n\nIf multiple investigation folders exist in the current project's documents, ask which matter this\ndata belongs to. If only one, proceed.\n\n### Step 2 — Identify the data type\n\nAsk (if not clear from context):\n- Interview notes (whose interview?)\n- Document batch (emails, records, files)\n- Attorney notes or observations\n- Upjohn warning confirmation\n\n### Step 3 — Document pull criteria\n\nFor any document batch, apply the following pull criteria. A document is\nsurfaced if it meets ANY of the following. The criteria are intentionally\nset to pull slightly aggressively — it is better to surface a false positive\nthan to miss a significant item.\n\n**Pull criteria:**\n1. Contains the name of any party to the investigation (complainant,\n respondent, witnesses named in prior log entries)\n2. Was authored or received by a party during the key conduct timeframe\n3. Contains keywords related to the allegation type (identified at intake\n and from prior log entries — update the keyword list as new terms emerge\n from accounts)\n4. Contains explicit or implicit admissions (\"I shouldn't have,\" \"I know\n how this looks,\" \"don't put this in writing,\" \"delete this\")\n5. Contains language contradicting any account already in the log — flag\n the specific contradiction and the log entry it conflicts with\n6. Contains language that would be sensitive in litigation: discriminatory\n terms, threats, discussions of protected characteristics or activities,\n financial irregularities matching the allegation pattern\n7. Is a document type that has been mentioned in prior accounts but has\n not yet appeared in the document set (e.g., a meeting was mentioned in\n an interview but no calendar invite has been reviewed) → log as\n evidentiary gap, not a surfaced document\n\n**Disposition for every document reviewed:**\n- `surfaced`: meets one or more pull criteria — added to log as a log entry\n- `reviewed-nothing-significant`: reviewed, does not meet pull criteria —\n logged in documents-reviewed.yaml with one-line description only\n\n**After processing a document batch, report:**\n\n```\nDocument review complete.\nReviewed: [N] documents\nSurfaced: [N] as potentially significant\nLogged as reviewed / nothing significant: [N]\nNew evidentiary gaps identified: [N]\n\nSurfaced items:\n[list with one-line description and which pull criterion triggered]\n```\n\nThis report is the answer to \"what about missed needles.\" The pull criteria\nare documented, the surface ratio is visible, and the attorney can review\nthe full document log at any time. In Q&A mode, \"I have not seen any document\non [topic] in the [N] documents reviewed\" is a meaningful statement only\nbecause every document reviewed is logged.\n\n### Step 4 — Write log entries\n\nFor each surfaced item, append to `log.yaml`:\n\n```yaml\n- entry_id: [auto-increment]\n entry_type: [interview / document / attorney-note / gap]\n date_of_event: \"[date the event occurred — not when logged]\"\n date_logged: \"[ISO datetime]\"\n source: \"[witness name/role, or document filename/description]\"\n source_type: [complainant / respondent / witness / document / attorney-note]\n issues: [\"[which investigation issue(s) this entry relates to]\"]\n significance: [high / medium / background]\n summary: \"[what this entry adds to the record — 2-5 sentences]\"\n quote: \"[verbatim quote if significant — otherwise empty]\"\n contradicts_entry: [entry_id or null]\n corroborates_entry: [entry_id or null]\n credibility_note: \"\"\n pull_criterion: \"[which criterion triggered — for documents]\"\n privilege: attorney-work-product\n```\n\nFor evidentiary gaps:\n\n```yaml\n- gap_id: [auto-increment]\n description: \"[what document/source should exist but hasn't been found]\"\n identified_from: \"[which log entry or account raised this]\"\n source_to_obtain: \"[where to get it]\"\n priority: [high / medium / low]\n status: open\n```\n\n### Step 5 — Update sources checklist\n\nIf the data added corresponds to a checklist item, ask the attorney if it\nshould be marked complete or in-progress. Do not auto-mark complete —\nthe attorney decides when a source is adequately covered.\n\n---\n\n## Mode 3: Query the log\n\nTriggered by `the “Investigation Query” workflow` or any question\nphrased against the investigation (e.g., \"what did [witness] say about\",\n\"what documents corroborate\", \"what do we still need\", \"what's the\nstrongest evidence on each side\").\n\nRead the full log before answering. Answer types:\n\n**Factual query** (\"what did X say about Y\"):\nAnswer from the log entries, citing entry IDs. If the log contains nothing\non the topic: \"I have not seen any information on [topic] in this\ninvestigation log ([N] entries reviewed). This may be worth flagging as\na gap.\"\n\n**Conflict query** (\"where do accounts conflict\"):\nSurface all contradicts_entry links. For each conflict: state what the\nconflict is, which entries are in tension, and what (if any) documentary\nevidence bears on the conflict.\n\n**Coverage query** (\"what do we still need\" / \"what are our gaps\"):\nRead sources-checklist.yaml and evidentiary_gaps in log.yaml. Report:\n- Checklist items still open\n- Evidentiary gaps logged\n- Any accounts that reference sources not yet gathered\n\n**Strength query** (\"what's the strongest evidence on each issue\"):\nFor each issue in the log, identify: the highest-significance log entries,\nany documentary corroboration, and any unresolved conflicts. Present\nissue by issue.\n\n**Upjohn query** (\"have we documented Upjohn warnings\"):\nCheck checklist item and any log entries tagged as Upjohn documentation.\nFlag if not yet completed.\n\n---\n\n## Mode 4: Draft or update the memo\n\nTriggered by `the “Investigation Memo” workflow` or \"draft the memo\"\nor \"update the memo\".\n\n### If no memo exists — first draft\n\nRead the full log. Do not draft until the following are complete (warn if\nnot):\n- At least one entry for each open issue\n- Complainant and respondent entries present\n- Sources checklist reviewed (flag any high-priority open items)\n\nDraft the memo in the following structure, following standard internal\ninvestigation memorandum practice:\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n---\n\n**MEMORANDUM**\n\nTo: [Attorney to fill in]\nFrom: [Attorney to fill in]\nDate: [Date]\nRe: Internal Investigation — [Matter name]\nStatus: PRELIMINARY DRAFT\n\n---\n\n## Executive Summary\n\n[2-3 paragraphs: allegation in plain terms, investigation scope and\nmethodology summary, key findings in bullet form (Sustained / Not\nSustained / Inconclusive), recommended actions. Written last but\nappears first.]\n\n---\n\n## Background and Scope\n\n**Triggering event:** [What initiated the investigation]\n\n**Allegations investigated:**\n[Each issue from the log as a numbered allegation]\n\n**Out of scope:** [Anything explicitly not investigated and why]\n\n**Investigation period:** [Dates of conduct alleged]\n**Investigation conducted:** [Date opened] to [present or close date]\n\n---\n\n## Methodology\n\n**Interviews conducted:**\n| Witness | Role | Date | Notes |\n|---|---|---|---|\n[Populated from log entries with source_type = interview]\n\n**Documents reviewed:**\n[Summary of document categories reviewed, volume, date range.\nFull document log is maintained separately.]\n\n**Other sources:**\n[Any other sources from checklist — policies, HR records, etc.]\n\n**Limitations:** [Any sources requested but not obtained, any constraints]\n\n---\n\n## Factual Findings\n\n*[Organized by issue — one section per allegation. Not by witness,\nnot purely chronological.]*\n\n### Issue 1: [Allegation]\n\n[Narrative of what the evidence shows on this issue. Cite log entry IDs\ninline in brackets. Where accounts conflict, present the conflict directly\n— do not smooth it over. Documentary evidence presented with quotes where\nsignificant.]\n\n### Issue 2: [Allegation]\n\n[Same structure]\n\n[Continue for each issue]\n\n---\n\n## Credibility Assessment\n\n*[Standalone section. Address only witnesses whose credibility is\ndeterminative — i.e., where the finding on an issue depends on which\naccount is credited.]*\n\n### [Witness name/role]\n\n**Internal consistency:** [Consistent / Inconsistent — note specifics]\n**Corroboration:** [What documentary or other evidence corroborates\nor undermines the account]\n**Motive:** [Any reason to credit or discount the account]\n**Demeanor:** [Attorney's observations if interviews were in person —\nleave blank if not applicable or not observed]\n**Assessment:** [Credit / Do not credit / Partially credit — with basis]\n\n---\n\n## Relevant Policies\n\n[Policies in effect at the time of alleged conduct that bear on the issues.\nCite the version. Do not cite policies that were adopted after the conduct.]\n\n---\n\n## Conclusions\n\n| Issue | Finding | Basis |\n|---|---|---|\n| [Issue 1] | Sustained / Not Sustained / Inconclusive | [One sentence] |\n| [Issue 2] | ... | ... |\n\n*Findings are based on a preponderance of the evidence standard.*\n\n---\n\n## Recommendations\n\n[Organized by action type:]\n\n**Disciplinary action:** [If any — state the basis, not just the outcome]\n**Policy or process changes:** [If any gap in policies contributed]\n**Training:** [If indicated]\n**Further investigation:** [Any threads not fully resolved]\n**Monitoring:** [Any follow-up needed]\n\n---\n\n## Appendix A: Chronology of Events\n\n[Auto-generated from log entries sorted by date_of_event, not date_logged.\nFormat: Date | Summary | Source (Entry ID)]\n\n## Appendix B: Documents Reviewed\n\n[Summary table from documents-reviewed.yaml]\n```\n\nWrite the draft to the current project's documents.\n\n### If memo already exists — update\n\nRead the memo and the log. Identify log entries added since the memo was\nlast drafted (compare date_logged against memo's last-updated date).\n\nReport what has changed:\n\n```\nSince the last memo draft ([date]), the following has been added to the log:\n\n[N] new entries\nNew issues: [any]\nNew conflicts: [any]\nResolved gaps: [any]\n\nSections that need updating:\n Factual findings: [which issues are affected]\n Credibility: [any new credibility-relevant entries]\n Conclusions: [any findings that should be revisited]\n Appendix A: [N] new chronology entries\n```\n\nAsk: \"Want me to update the full memo, or just the affected sections?\"\n\nApply updates. Preserve prior drafting. Mark changed sections with\n`[UPDATED: date]` until the attorney reviews.\n\n---\n\n## Mode 5: Draft audience summary\n\nTriggered by `the “Investigation Summary” workflow` or \"draft a\nsummary for [audience]\".\n\nAsk: who is the audience and what decision or action does this summary\nsupport?\n\n**HR summary** (for HR decision on disciplinary action):\n- What happened (factual summary, no legal analysis)\n- Finding on each allegation (Sustained/Not Sustained/Inconclusive)\n- Recommended action\n- What is NOT in this summary: privilege analysis, credibility methodology,\n legal exposure assessment, attorney mental impressions\n- Header: \"Confidential — HR Use Only — Do Not Distribute\"\n- Do not include entry IDs or document citations — those stay in the memo\n\n**Leadership/Board summary** (for governance decision):\n- The allegation and scope in one paragraph\n- Key findings\n- Business impact / exposure (high level — no specific legal analysis)\n- What the company is doing about it\n- Header: \"[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\"\n\n**Outside counsel briefing** (handing off for litigation or deeper review):\n- Full context including legal exposure analysis\n- Open evidentiary threads\n- Credibility issues that remain contested\n- Documents that would be most significant in litigation\n- Header: \"[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\"\n\n---\n\n## Consequential-action gate (respond to a demand or complaint)\n\n**Before producing a summary, memo, or content intended for an external response (EEOC/DFEH/state agency charge response, plaintiff's-counsel demand letter response, regulator response, or any formal complaint reply):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Responding to a demand, charge, or complaint has legal consequences — positions taken here are admissions in later proceedings, waivers of defenses can be inadvertent, and privilege over the underlying investigation can be lost. Have you reviewed this response with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - The allegation, the forum, and the deadline\n> - What the investigation surfaced (findings by allegation; documents reviewed; witnesses interviewed; Upjohn warnings given or not)\n> - Any unresolved evidentiary threads or credibility contests\n> - What the proposed response says and what it implicitly concedes\n> - Open questions and what's unresolved\n> - What could go wrong (privilege waiver, inconsistent factual statements, missed affirmative defense)\n> - What to ask the attorney (is this the right theory; are we preserving defenses; should an outside firm take this over; what needs redaction or a privilege log)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service. Agency and demand-letter responses are a place where untrained replies regularly create more exposure than the underlying allegation did.\n\nDo not produce an external-response draft past this gate without an explicit yes. Internal memos, HR summaries, and leadership briefings used only within the organization do not trip this gate (but the privilege-formation caveat at the top of this skill still applies).\n\n---\n\n## What this skill does NOT do\n\n- Make disciplinary decisions — it supports the attorney's findings,\n not HR's action\n- Guarantee privilege — privilege depends on how the investigation is\n structured, not on how the memo is labeled\n- Process documents it cannot read — if files are in formats that cannot\n be parsed, flag them for manual review\n- Conduct interviews — it logs interview notes, it does not interview witnesses\n- Replace Upjohn warnings — it tracks whether they were given, it does not\n give them\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-employment-international-expansion", + title: "International Expansion", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “international-expansion” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# International Expansion Skill\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nInternational hiring gets handled sloppily at scaleups because nobody owns\nthe full picture. Legal knows the employment-law questions but not the PE\nrisk questions. Finance knows the cost model but not the employee-representation\ntriggers. HR knows the comp benchmarks but not the Day 1 compliance requirements.\n\nThis skill doesn't replace any of those functions. It maps the terrain, drafts\nthe right questions for each stakeholder, produces a briefing request that\nwalks outside counsel through the country-specific issues, and creates a\ntracker that keeps the project moving across sessions.\n\nThis skill assumes expansion is decided. It is not a \"should we expand?\"\nframework.\n\nThis skill does not contain country-specific employment law. The substantive\nrules change frequently and vary by role, headcount, and industry — the skill\nroutes every country through an outside-counsel briefing rather than relying\non a stored reference table.\n\n## Load context\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, escalation table, any existing\nexpansion notes.\n\n## Output header\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` (it differs by user role — see `## Who's using this`).\n\n## Workflow\n\n### Step 1 — Information gathering\n\nAsk all of the following in a single block:\n\n> Before I build the expansion plan I need to understand the shape of this\n> expansion. Please answer what you can — gaps in the answers are themselves\n> useful data:\n>\n> **The expansion**\n> - Which country?\n> - What roles are you hiring? (Job function matters — a sales rep closing\n> deals creates different legal exposure than an engineer writing code)\n> - How many hires are planned in the next 12 months?\n> - When do you need the first person to start?\n>\n> **Current state**\n> - Do you already have a legal entity in this country?\n> - Have you used an EOR provider before? Are you already considering one?\n> - Has tax or finance been looped in yet?\n> - Do you have outside employment counsel in this country?\n>\n> **Strategic context**\n> - Is this a long-term strategic commitment (building a real team) or\n> testing the market (one or two hires, see how it goes)?\n> - Who is the executive sponsor making the structure decision?\n\nWait for responses before proceeding.\n\n### Step 2 — EOR vs. entity framing\n\nDo not make this decision. Frame it with enough precision that the CFO and\ntax counsel can make it.\n\nWork through the following factors against the intake answers and produce a\nstructured framing document:\n\n**The core trade-off:**\n\n| Factor | Points toward EOR | Points toward Entity |\n|---|---|---|\n| Headcount in 12 months | Fewer hires | More hires |\n| Timeline to first hire | Short runway | Longer runway available |\n| Strategic commitment | Testing the market | Long-term presence |\n| Cost sensitivity | EOR markup acceptable | Scale makes entity more efficient |\n| Control needs | Low — EOR employer handles local HR | High — want direct employer relationship |\n| IP sensitivity | Lower | Higher — entity ownership cleaner |\n\nSpecific headcount break-even points, EOR markup ranges, setup costs, and\ntimelines vary by country and provider — do not hardcode them. Route those\nquestions to tax/finance and the EOR provider.\n\n**PE risk flag (route to tax counsel):**\nIf roles include sales, business development, account management, or anyone\nwith authority to negotiate or sign contracts on behalf of the company —\nflag this explicitly:\n\n> PE Risk: [Role type] may create a taxable permanent establishment in\n> [country] even before a legal entity exists. This is a tax question, not\n> an employment question. Tax counsel must assess before the first hire.\n\n**Produce the question for the CFO/tax:**\n\n> Questions for your CFO and tax counsel:\n> - At [N] hires over 12 months, at what headcount does entity setup become\n> more cost-effective than EOR (accounting for EOR markup, setup costs,\n> and ongoing compliance burden)?\n> - [If PE-risk roles:] Do these role types create a taxable permanent\n> establishment in [country]? If yes, does that change the entity timeline?\n> - If we start with EOR and convert to entity later, what are the transition\n> risks for the employees already on the EOR?\n> - Who is our preferred EOR provider for this country, and have we vetted\n> their local compliance track record?\n\n### Step 3 — Cross-functional triggers\n\nFor each function that needs to be looped in, state: what they need to do,\nand the specific questions legal should ask them. Do not just say \"loop in\nfinance.\" Draft the ask.\n\n**Tax counsel** (always required before first hire)\n\nWhat they need to do: PE risk analysis, determine whether entity is required\nfor tax purposes, advise on equity tax treatment in this jurisdiction.\n\nQuestions legal should ask:\n- Does hiring a [role type] in [country] create a permanent establishment or\n taxable nexus before we have an entity?\n- What is our exposure window if we start hiring before the PE question is\n resolved?\n- How are our equity awards (RSUs/options) taxed in [country]? Do we need\n local tax counsel to advise employees at grant and vesting?\n- If we set up an entity, what intercompany services agreement is needed\n between the subsidiary and the US parent?\n\n**Finance / Payroll** (required before first paycheck)\n\nWhat they need to do: identify local payroll provider (or confirm EOR handles\nit), budget mandatory employer contributions, set up local banking if entity.\n\nQuestions legal should ask:\n- Have we identified a local payroll provider? (If EOR: confirm EOR handles\n payroll including local social contributions)\n- What are the mandatory employer contributions in [country] — pension,\n social insurance, healthcare — and are these budgeted in the comp model?\n- How will equity grants be administered for employees in [country]? Has\n anyone modeled the employer-side tax withholding obligations at vesting?\n\n**HR / Total Rewards** (required before offer is made)\n\nWhat they need to do: benefits benchmarking, comp benchmarking against local\nmarket, confirm mandatory vs. supplemental benefits.\n\nQuestions legal should ask:\n- What benefits are legally mandatory in [country] vs. market-standard? (Do\n not want to accidentally promise more than required or less than market)\n- Is our standard equity package competitive in this market, or does local\n practice differ significantly?\n- Who will be this person's day-to-day manager — local or remote from HQ?\n (Affects employee-representation analysis and employment agreement terms\n in some jurisdictions)\n\n**Outside counsel** (required — do not skip)\n\nWhat they need to do: research and advise on the local employment framework\nfor this role and headcount, review/draft local employment agreement, flag\nany structural issues with the proposed arrangement.\n\nThe outside-counsel briefing request in Step 4 is the agenda for this\nengagement. Send it at the start — do not ask piecemeal.\n\n### Step 4 — Country-specific briefing request\n\nInstead of a stored country reference table, this skill produces a structured\noutside-counsel briefing request. Substantive local law (entity requirements,\nstatutory benefits and contributions, termination protections, notice periods,\nemployee-representation / works-council / collective-bargaining obligations,\nmandatory leave, restrictive covenants, data protection, work authorization)\nvaries by country *and* by role and headcount *and* by industry, and changes\nfrequently. Treat every country as a country that requires verification — do\nnot rely on the skill's own knowledge.\n\nDraft the briefing request below, tailored to the intake answers:\n\n**Outside counsel briefing request — [Country]**\n\n> We are planning to hire [N] employees in [Country] starting [date], in the\n> following roles: [roles]. Target headcount over 12 months: [N]. Preferred\n> structure (subject to your advice and tax counsel): [EOR / entity /\n> undecided]. We need a briefing covering each of the following. Please\n> answer as questions with cites to primary law, not as a reference table —\n> we want to be able to track changes over time.\n>\n> 1. **Entity and engagement structure** — what are our options (direct\n> hire via entity, EOR, contractor) and what are the practical and legal\n> trade-offs for this headcount and these roles?\n>\n> 2. **Employment contract requirements** — what form is required or standard?\n> What must be included? What cannot be included or is unenforceable?\n> What language or translation requirements apply?\n>\n> 3. **Termination** — what are the notice requirements and severance\n> obligations? How difficult is termination in practice (protected-cause\n> standards, social-selection rules in RIFs, reasonable-notice common-law\n> exposure)? What documentation standard should we establish from day one?\n>\n> 4. **Mandatory benefits and employer contributions** — what must we provide\n> by law (pension, social insurance, healthcare, paid leave, bonuses)?\n> What are the current employer contribution rates we should budget?\n> Please cite the controlling statute and verify currency.\n>\n> 5. **Restrictive covenants** — are non-competes enforceable? Under what\n> conditions and with what compensation requirements? What confidentiality\n> and IP assignment language holds up?\n>\n> 6. **Employee representation** — are there works council, employee\n> representation, union, or collective bargaining requirements? At what\n> headcount do they trigger? What consultation or co-determination rights\n> apply? Are we covered by any sectoral collective agreement even if we\n> are not unionized?\n>\n> 7. **Data protection** — what obligations apply to employee data? Is there\n> a data transfer mechanism needed for employee data flowing to the US?\n>\n> 8. **Work authorization** — what permits or visas are required for foreign\n> nationals? What are the processing timelines?\n>\n> 9. **Industry-specific rules** — are there sector rules, awards, or\n> collective agreements that apply to our industry regardless of whether\n> we are unionized?\n>\n> 10. **Contractor/independent-contractor risk** — what is the country's test\n> for classification, and what are the deemed-employment or reclassification\n> risks for any contractor arrangements we may consider?\n>\n> 11. **Equity / incentive compensation** — any local tax, securities, or\n> employment-law rules that govern how we grant RSUs, options, or other\n> equity here?\n>\n> 12. **Day 1 compliance** — what must be in place before the first employee\n> starts? Registration requirements, notices, filings, posters?\n>\n> 13. **Top 2-3 things that surprise US companies hiring here for the first\n> time** — what do you wish clients had asked you earlier? What has\n> *changed recently* that a US team might not have caught?\n\nAdd this briefing request to the expansion tracker as a single open item:\nowner = Outside Counsel, status = open, with the full briefing agenda in\nthe questions field. If the jurisdiction is one the team has asked about\nbefore, still send the briefing — this is a currency check, not a first\ncontact.\n\n### Step 5 — Create the expansion tracker\n\nWrite a new file to the current project's documents with all open items\nidentified in Steps 2-4. This file persists across sessions.\n\nFormat:\n\n```yaml\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\ncountry: [Country name]\ncountry_slug: [lowercase-hyphenated]\nkickoff_date: [ISO date]\nfirst_hire_target: [ISO date or \"TBD\"]\nheadcount_12mo: [N]\nroles: [list]\nstrategic_commitment: [testing / long-term]\neor_or_entity: [EOR / entity / undecided]\noutside_counsel_engaged: [true / false]\npe_risk_flagged: [true / false]\nlast_updated: [ISO date]\n\nopen_items:\n - id: 1\n category: [structure / tax / finance / hr / outside-counsel / compliance]\n item: \"[what needs to happen]\"\n owner: \"[function or person]\"\n status: [open / in-progress / done / blocked]\n due: [ISO date or null]\n questions:\n - \"[specific question drafted in Steps 2-4]\"\n notes: \"\"\n\n - id: 2\n [etc.]\n```\n\nGenerate one open item per action identified across Steps 2-4. Do not collapse\nmultiple actions into one item — each item should be completable and\nattributable to a single owner.\n\n### Step 6 — Output\n\n> **Jurisdiction assumption.** This plan frames the expansion to the single country identified in intake. Local employment law, tax rules, employee-representation obligations, and data-protection requirements vary materially by country, region, industry, and headcount, and change frequently. Every substantive local-law answer comes from the outside-counsel briefing request, not from this skill. If the plan is adapted for another country later, re-run the briefing.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## International Expansion: [Country] — [Date]\n\n**First hire target:** [date]\n**Headcount (12 months):** [N]\n**Roles:** [list]\n**Tracker:** the current project's documents\n\n---\n\n### EOR vs. Entity\n\n[Framing from Step 2 — table, PE risk flag if applicable, questions for CFO/tax]\n\n---\n\n### Who needs to be looped in — and what to ask them\n\n**Tax counsel** — [N] questions\n[Questions from Step 3]\n\n**Finance / Payroll** — [N] questions\n[Questions from Step 3]\n\n**HR / Total Rewards** — [N] questions\n[Questions from Step 3]\n\n**Outside counsel** — see briefing request below\n[Full briefing request from Step 4]\n\n---\n\n### Open items ([N] total)\n\n| # | Item | Owner | Status |\n|---|---|---|---|\n| 1 | [item] | [owner] | Open |\n[etc.]\n\n---\n\nRun `the “Expansion Update” workflow [country]` to update status\nas items close.\n```\n\n## What this skill does NOT do\n\n- Advise on specific local employment law — that is outside counsel's job.\n- Make the EOR vs. entity decision — frames it for the right decision-makers.\n- Draft the local employment agreement — flags that outside counsel must do\n this.\n- State country-specific rules from its own knowledge — every country is\n routed through an outside-counsel briefing.\n- Substitute for outside counsel engagement — every new country requires\n local counsel, no exceptions.", + }, + { + id: "builtin-cfl-employment-investigation-add", + title: "Investigation Add", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “investigation-add” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /investigation-add\n\nAdds data to an open investigation log. Processes document batches using\ndocumented pull criteria, surfaces significant items, logs everything\nreviewed for coverage verification.\n\n## Instructions\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n2. Load the `internal-investigation` reference skill and run Mode 2 (Add data).\n3. After processing, show the surface ratio and list of surfaced items.\n4. Prompt to update the sources checklist if the data covers a checklist item.\n\n## Examples\n\n```\nthe “Investigation Add” workflow [matter name]\n[paste interview notes]\n```\n\n```\nthe “Investigation Add” workflow [matter name]\n[attach email export]\n```\n\n> Detailed needle-finding process, log entry format, surface-ratio rules, and\n> sources-checklist tracking live in the `internal-investigation` reference\n> skill — load it before doing substantive work.", + }, + { + id: "builtin-cfl-employment-investigation-memo", + title: "Investigation Memo", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “investigation-memo” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /investigation-memo\n\nDrafts the first cut of the privileged investigation memo from the log,\nor updates an existing draft when new data has been added.\n\n## Instructions\n\n1. Load the `internal-investigation` reference skill and run Mode 4 (Draft or update memo).\n2. If drafting for the first time, warn if high-priority sources are still\n open on the checklist.\n3. If updating, show what changed before rewriting.\n4. All output is marked PRIVILEGED AND CONFIDENTIAL — ATTORNEY WORK PRODUCT.\n\n## Examples\n\n```\nthe “Investigation Memo” workflow [matter name]\n```\n\n```\nthe “Investigation Memo” workflow [matter name]\n(updates existing memo if one exists)\n```\n\n> Detailed memo structure, credibility-assessment framework, and update rules\n> live in the `internal-investigation` reference skill — load it before doing\n> substantive work.", + }, + { + id: "builtin-cfl-employment-investigation-open", + title: "Investigation Open", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “investigation-open” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /investigation-open\n\nOpens a new investigation matter — runs intake, generates the sources\nchecklist, and creates the persistent investigation log.\n\n## Instructions\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n2. Load the `internal-investigation` reference skill and run Mode 1 (Open).\n3. If a matter with the same slug already exists, warn before overwriting.\n\n## Examples\n\n```\nthe “Investigation Open” workflow\nHarassment complaint filed against a manager in the Austin office.\n```\n\n```\nthe “Investigation Open” workflow\n(skill will ask for details)\n```\n\n> Detailed intake, privilege-formation requirements, sources checklist, and log\n> templates live in the `internal-investigation` reference skill — load it\n> before doing substantive work.", + }, + { + id: "builtin-cfl-employment-investigation-query", + title: "Investigation Query", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “investigation-query” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /investigation-query\n\nAnswers questions against the investigation log — what witnesses said,\nwhere accounts conflict, what gaps exist, what the strongest evidence is\non each issue.\n\n## Instructions\n\n1. Load the `internal-investigation` reference skill and run Mode 3 (Query).\n2. Always cite log entry IDs in the answer.\n3. If the log contains nothing relevant to the question, say so explicitly —\n \"I have not seen any information on [topic] in this investigation log\n ([N] entries reviewed)\" — and offer to flag it as a gap.\n\n## Examples\n\n```\nthe “Investigation Query” workflow [matter name]\nWhat did the respondent say about the December team dinner?\n```\n\n```\nthe “Investigation Query” workflow [matter name]\nWhere do the complainant's and respondent's accounts conflict?\n```\n\n```\nthe “Investigation Query” workflow [matter name]\nWhat do we still need?\n```\n\n> Detailed log-query process, citation rules, and gap-flagging templates live\n> in the `internal-investigation` reference skill — load it before doing\n> substantive work.", + }, + { + id: "builtin-cfl-employment-investigation-summary", + title: "Investigation Summary", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “investigation-summary” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /investigation-summary\n\nDrafts a stripped-down, audience-appropriate summary from the privileged\ninvestigation memo. HR summaries contain no privilege analysis. Leadership\nsummaries are high-level. Outside counsel briefings include full context.\n\n## Instructions\n\n1. Load the `internal-investigation` reference skill and run Mode 5 (Audience summary).\n2. If no memo exists yet, offer to draft the memo first.\n3. HR summaries must not include attorney mental impressions, credibility\n methodology, or legal exposure analysis.\n\n## Examples\n\n```\nthe “Investigation Summary” workflow [matter name] hr\n```\n\n```\nthe “Investigation Summary” workflow [matter name] leadership\n```\n\n```\nthe “Investigation Summary” workflow [matter name] outside-counsel\n```\n\n> Detailed audience-stripping rules and summary templates live in the\n> `internal-investigation` reference skill — load it before doing substantive\n> work.", + }, + { + id: "builtin-cfl-employment-policy-drafting", + title: "Policy Drafting", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “policy-drafting” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /policy-drafting\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, handbook location.\n2. Use the workflow below.\n3. Draft core policy. Check each jurisdiction in footprint for required variants.\n4. Output: core policy + state supplements. Flag where law is currently shifting.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nA policy that's right for California may be wrong (or unnecessary) in Texas. This skill drafts a core policy and generates state supplements where the footprint requires different rules.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, handbook location and format.\n\n## Workflow\n\n### Step 1: Scope the policy\n\n- What's the policy for? (Remote work, parental leave, social media, etc.)\n- Why now? (Legal requirement, incident, growth, gap noticed)\n- Who does it apply to? (All employees, certain roles, certain locations)\n\n### Step 2: Jurisdictional scan\n\nFor each state/country in the footprint, check: does this jurisdiction have a specific rule on this topic?\n\n**Common topics with jurisdictional variance:**\n\n| Topic | Variance |\n|---|---|\n| Paid leave | State mandates (CA, NY, CO, WA, etc.) with different accrual rates, uses, carryover |\n| Parental leave | State programs layer on top of FMLA (CA PFL, NY PFL, etc.) |\n| Meal and rest breaks | CA is the outlier (penalty pay); most states minimal |\n| Expense reimbursement | CA requires; most states don't |\n| Pay transparency | Growing list of states requiring ranges in postings |\n| Non-competes | See hiring-review skill — unenforceable in some states |\n| Final pay | Timing varies widely |\n\nIf the topic has no jurisdictional variance (dress code, say), skip this step.\n\n### Step 3: Draft the core policy\n\nOne policy. Applies everywhere. Clear and readable — employees should understand it without a lawyer.\n\nStructure:\n- Purpose (one sentence — why this policy exists)\n- Scope (who it applies to)\n- The rule (what's required/permitted/prohibited)\n- Process (how to request, who approves, what happens if)\n- Questions (who to ask)\n\nAvoid: \"heretofore,\" \"notwithstanding,\" nested exceptions. This is a handbook policy, not a contract.\n\n### Step 4: State supplements\n\nFor each jurisdiction where the rule differs, a supplement:\n\n```markdown\n### [State] Supplement\n\nEmployees working in [State] are subject to the following in addition to / instead of the core policy:\n\n- [Specific difference]\n- [Cite the state law if helpful]\n```\n\nKeep supplements tight. Only what's different — don't repeat the core.\n\n### Step 5: Cross-check\n\n- Does this policy conflict with anything already in the handbook?\n- Does it promise more than the company intends to deliver? (A policy is a promise — courts hold employers to handbook promises.)\n- Does it inadvertently create a contract? (Some states treat handbook policies as contractual — include the standard \"this is not a contract\" language if the handbook doesn't already.)\n\n## Output\n\n```markdown\n# [Policy Name]\n\n## Core Policy\n\n[Full text]\n\n## State Supplements\n\n### [State 1]\n[Supplement]\n\n### [State 2]\n[Supplement]\n\n---\n\n## Drafting Notes (internal — remove before handbook insertion)\n\n- **Jurisdictional scan:** [which states checked, which have variance]\n- **Conflicts with existing handbook:** [none | list]\n- **Law currently shifting:** [any state where this is in flux]\n- **Review cadence:** [when to revisit — annual, or when X happens]\n```\n\n> **Draft, not a policy in effect.** This is a drafting aid for attorney review, not a policy you can publish. Publishing a handbook policy has legal consequences — in several states it can bind the company as a contractual promise, and wage/leave/accommodation policies are routinely read against the employer. A licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction reviews, edits as needed, and takes professional responsibility before the policy is rolled out. Do not publish or distribute this draft unreviewed.\n\n## Handoff\n\nTo handbook-updates skill: when this policy is approved, it diffs against the current handbook and flags what changes.\n\n## What this skill does not do\n\n- Approve the policy. It drafts; a human approves.\n- Roll out the policy. Communication to employees is an HR workflow.\n- Cover every jurisdiction on earth — only the ones in the footprint. If the footprint expands, re-run.", + }, + { + id: "builtin-cfl-employment-termination-review", + title: "Termination Review", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “termination-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /termination-review\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → termination review triggers, high-risk flags, severance practice, jurisdiction rules.\n2. Use the workflow below.\n3. Walk the checklist. Check every high-risk flag.\n4. Final pay timing per employee's jurisdiction. Severance + release if applicable.\n5. If any high-risk flag fires: escalate per table, don't proceed without sign-off.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nMost terminations are fine. A few are lawsuits waiting to happen. This skill\nruns the checklist that catches the second kind before the decision is final.\nThe skill does not state the law — every jurisdiction-specific rule and\nrelease-period requirement is researched and cited at the time of review.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → termination review triggers, high-risk flags, standard severance,\njurisdiction table.\n\n## Output header\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` (it differs by user role — see `## Who's using this`). Match the memo format from seed term memos referenced in that config where one exists. The work-product header is always first.\n\n## Workflow\n\n### Step 1: The basic facts\n\n- Employee name (or role if staying abstract)\n- Jurisdiction (where they work)\n- Reason for termination (performance, misconduct, RIF, position elimination)\n- How long employed\n- Age (relevant to release requirements for older-worker protections)\n- Whether any other employees are being terminated as part of the same\n decisional unit or program (relevant to group-termination release rules)\n- When is the planned term date\n\n### Step 2: High-risk flag scan\n\nThis is the most important step. Check every flag from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Default\nset:\n\n| Flag | Why it's high-risk | Check |\n|---|---|---|\n| **Recent complaint** | Retaliation claim | Has this employee filed any complaint (HR, ethics hotline, regulatory) recently? |\n| **Protected leave** | Leave-law interference/retaliation | Currently on or recently returned from protected leave (FMLA/state equivalents, disability, parental, military)? |\n| **Protected class + timing** | Discrimination claim | Protected class AND recently disclosed/visible (pregnancy announcement, religious accommodation request, disability disclosure)? |\n| **Whistleblower** | Federal and state whistleblower statutes | Has this employee raised concerns about illegality, safety, fraud? |\n| **Thin documentation** | \"Why now?\" problem | For performance terms: is there a PIP, written warnings, documented feedback? Or did this come out of nowhere? |\n| **Comparator problem** | Disparate treatment | Is someone else doing the same thing and not being terminated? |\n| **Contract/handbook promise** | Breach | Does the offer letter, handbook, or any writing promise a process that isn't being followed? |\n| **Exempt misclassification** | FLSA + state wage claim with liquidated damages | See the classification check below. Fires on state + classification + title. |\n\n**Exempt/non-exempt classification flag.** Fire this flag when ALL of the\nfollowing are true:\n\n1. The employee works in a state with a high exempt salary threshold — **CA,\n NY, WA, CO, AK** (and any other state listed in\n your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) →\n `## Wage & hour` → Known classification risk areas as a high-threshold\n state) — **AND**\n2. The employee is classified **exempt** (salaried, no overtime) — **AND**\n3. The employee's title contains **\"supervisor,\" \"lead,\" \"coordinator,\"\n \"analyst,\" \"administrator,\"** or **\"specialist\"** (case-insensitive, and\n any equivalent-scope title the practice profile flags as risky).\n\nWhen all three fire, emit:\n\n> 🔴 **Potential exempt misclassification** — [title] earning $[X] in\n> [state]. The exempt salary threshold in [state] is approximately $[Y]\n> `[model knowledge — verify]`. Before termination, route to\n> `the “Wage Hour Q&A” workflow` for a classification check — a misclassified\n> employee who's terminated has a ready-made FLSA and state-wage claim with\n> liquidated damages, attorneys' fees, and (in CA) PAGA exposure, which\n> the separation agreement may not be able to release cleanly. A terminated\n> plaintiff with unpaid-OT exposure is the most litigated wage-and-hour\n> fact pattern in these states.\n\nDo not suppress this flag because the title \"looks managerial\" — the whole\npremise of the misclassification claim is that titles lie. Route to\n`the “Wage Hour Q&A” workflow` for the actual duties-and-salary test.\n\n**If a back-pay number is being computed as part of this review (severance\nmodeling, settlement posture, exposure estimate), do NOT compute it in this\nskill.** Route to `wage-hour-qa` → Step 2a and use its regular-rate\nscaffold: §207(e) inclusions (non-discretionary bonuses, commissions,\nshift diffs) in the regular rate, 0.5× premium when straight time was\nalready paid for OT hours (else 1.5×), liquidated damages under §216(b),\nand 2-year / 3-year willful SOL under §255(a). Every back-pay number\ncarries `[verify — consult wage-and-hour counsel before asserting or\npaying]`. A clean-looking wrong number here is the specific failure mode\nthis scaffold prevents.\n\n**Any flag fires → escalate per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) before the term proceeds.** Not\nafter. Before.\n\n### Step 3: Jurisdiction-specific requirements\n\n> **Research the applicable rules for the employee's jurisdiction before\n> finalizing the plan.** Specifically:\n>\n> - Final-pay timing — this varies widely by state and often depends on\n> whether the employee was terminated or resigned. Research the currently\n> operative rule, including any waiting-time or late-pay penalties.\n> - Accrued-PTO payout — research whether the jurisdiction requires payout,\n> and any interaction with accrual-cap or use-it-or-lose-it policies.\n> - Required notices — research any jurisdiction-specific notices required at\n> termination (e.g., state unemployment, continuation-coverage notices\n> beyond federal COBRA, benefits continuation).\n> - Mass-layoff / plant-closing notices — research federal WARN Act and any\n> state \"mini-WARN\" or local ordinance that may apply if this is part of a\n> larger reduction. Coverage thresholds and notice periods differ.\n>\n> Cite primary sources. Verify currency.\n>\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for the jurisdiction's final-pay, PTO, notice, or WARN rule, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [jurisdiction / rule]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) stop here and flag for attorney verification. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Tag every citation in the plan — final-pay rule, PTO rule, notices, WARN / mini-WARN, OWBPA consideration periods, state release restrictions — with where it came from: `[Westlaw]`, `[CourtListener]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the user supplied. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n### Step 4: Severance and release\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → standard severance:\n\n- Is severance being offered? Per formula or discretionary?\n- Release required? (Usually yes if paying severance — that's the\n consideration.)\n\n> **Research the applicable release-consideration rules.** If the employee is\n> 40 or over, federal law (OWBPA) imposes specific requirements that affect\n> the consideration period, revocation period, required advisements, and —\n> for group terminations — required decisional-unit disclosures. The specific\n> consideration period differs between an individual termination, a group\n> RIF, and a group exit incentive; the rule also depends on the employee's\n> age and the number of employees affected. Do not state the day count from\n> memory — research the currently operative rule for the specific situation\n> and cite primary sources. Also research any state-law analogs or parallel\n> release requirements. Verify currency.\n\nSeparately, consider whether any of the following apply to the release:\n- State-specific waiver restrictions (some states limit what can be released\n or require specific language).\n- Federal or state restrictions on non-disclosure or non-disparagement\n clauses that relate to sexual harassment, discrimination, or other\n protected categories.\n- Separation-agreement rules on NLRA-protected activity.\n\n### Step 5: Documentation check\n\nFor performance terminations especially:\n\n- Is there a paper trail? Written warnings, PIP, feedback docs?\n- Does the paper trail tell a consistent story?\n- Is there anything in writing that contradicts the reason (recent positive\n review, bonus, promotion)?\n\nThe \"why now\" question: if this person has been underperforming for a year,\nwhat changed? The answer should be documented.\n\n## Output\n\n> **Research-connector pre-flight.** Before emitting the memo, check whether a legal research connector is reachable for this session — Westlaw, CourtListener, or any firm-configured research MCP. Collect this into the reviewer note per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`: if no connector returns results in Step 3 (or none is configured at run time), record it in the **Sources:** line of the reviewer note — e.g., `not connected — cites from training knowledge; the highest-fabrication topics in termination-law memos are final-pay timing, OWBPA group/individual distinctions, state-specific NDA / non-disparagement rules (e.g., CA SB 331), and NLRB positions (e.g., McLaren Macomb) — spot-check those first`. Per-citation `[model knowledge — verify]` tags remain inline. Do not emit a standalone banner above the memo.\n\n> **Jurisdiction assumption.** This review assumes the employee's jurisdiction as stated in Step 1 and any defaults from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Jurisdictional footprint. Employment rules, final-pay timing, release requirements, and notice obligations vary materially by jurisdiction. If the employee works in a different state or country, or if choice-of-law is contested, this analysis may not apply as written.\n\nMatch the memo format from seed term memos referenced in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If none:\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Termination Review: [Role/Name] — [Date]\n\n**Jurisdiction:** [State]\n**Reason:** [Performance / Misconduct / RIF / Elimination]\n**Planned date:** [Date]\n\n---\n\n### Bottom line\n\n[Can you proceed / Need to fix X first / Stop — one-sentence why]\n\n---\n\n### High-risk flags\n\n[Every flag from Step 2. ✅ Clear or 🔴 FLAG with detail.]\n\n**Escalation:** [None needed | Escalate to [name] before proceeding — [which flag]]\n\n---\n\n### Jurisdiction requirements ([State])\n\n- Final pay: [researched rule and cite; state whether PTO is included per the\n researched rule and any team policy]\n- Required notices: [list, each researched and cited]\n- Mass-layoff notice (if applicable): [researched rule and cite]\n\n---\n\n### Severance and release\n\n- Severance: [amount per formula / none]\n- Release: [required / not — if required, research and apply the\n consideration-period, revocation-period, advisement, and (for groups)\n decisional-unit-disclosure requirements that govern this specific\n situation; cite primary sources and verify currency]\n- [Any state-law release rules or non-disclosure/non-disparagement\n restrictions that apply]\n\n---\n\n### Documentation\n\n[Assessment of paper trail. Gaps flagged.]\n\n---\n\n### Go / No-go\n\n[Clear to proceed | Proceed with changes below | Hold — escalation pending]\n\n### Checklist for term day\n\n- [ ] Final paycheck ready, correct amount, delivered per researched rule\n- [ ] Continuation-coverage notices (COBRA / state analogs) prepared\n- [ ] [State] unemployment notice prepared\n- [ ] Severance agreement (if applicable) with the consideration period\n required for this specific situation\n- [ ] Return of property / access cutoff coordinated\n- [ ] [etc.]\n```\n\n## Consequential-action gate (terminate an employee)\n\n**Before producing a \"Go\" recommendation or a term-day checklist marked ready:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Terminating an employee has legal consequences — wrongful-termination, discrimination, retaliation, and wage-law claims all trace back to how this decision is structured. Have you reviewed this termination with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - Employee, jurisdiction, reason, planned date\n> - Every high-risk flag the review surfaced (recent complaint, protected leave, protected class + timing, whistleblower, thin documentation, comparator, contract/handbook promise) — with detail\n> - Jurisdiction-specific findings (final pay, PTO, required notices, mass-layoff rules) and where they were cited from\n> - Severance/release analysis, including any OWBPA/older-worker-protection angles\n> - Open questions and what's unresolved\n> - What could go wrong (the claim theory this fact pattern supports)\n> - What to ask the attorney (is this a clean term; do we need more documentation first; does the release need specific language; do we need to stagger decisional units)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service. Employment is one of the practice areas where a short consult before the termination meeting consistently outvalues a post-termination claim defense.\n\nDo not produce a \"Clear to proceed\" output past this gate without an explicit yes. A marked-DRAFT flagged for attorney review is fine.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- Make the termination decision. It checks the decision.\n- Have the conversation. The manager does that.\n- State release or jurisdiction rules from memory — every rule is researched\n and cited at the time of review.\n- Guarantee no lawsuit. It reduces the risk by catching the obvious problems.", + }, + { + id: "builtin-cfl-employment-wage-hour-qa", + title: "Wage Hour Q&A", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “wage-hour-qa” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /wage-hour-qa\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint.\n2. Use the workflow below.\n3. Identify jurisdiction the question is about. If not specified, ask.\n4. Answer per that jurisdiction's rule. Cite. Flag if it's a close call or law is shifting.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\n\"It depends\" is true but unhelpful. This skill produces a jurisdiction-specific\nanswer grounded in researched, cited primary sources — and flags when the\nquestion is close enough to need human judgment. It does not state rules from\nmemory: wage-and-hour thresholds, exemption criteria, and final-pay timing\nchange frequently and vary meaningfully by state.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint. If the question doesn't specify a\njurisdiction, ask — or answer for the state with the most employees and note\nthat.\n\n## The answer\n\n### Step 1: Jurisdiction\n\nWhich state/country is this about? If not stated:\n- If it's about a specific employee: where do they work?\n- If it's a policy question: identify the jurisdictions in the footprint that\n are most likely to be the most restrictive on the question at hand, then\n research those.\n\n### Step 2: Research the rule, then state it\n\n> **Research before answering.** For the jurisdiction and question, identify\n> the currently operative rule. Cite the controlling primary source (statute,\n> regulation, wage order, or case) with a pinpoint cite. Note the effective\n> date and whether the rule has been recently amended, indexed, or is in\n> litigation. If you are uncertain or cannot verify the current state of the\n> law, say so and flag for attorney verification — do not state a rule you\n> haven't confirmed.\n\nState the rule in one paragraph, tied to the cite. Use your tools (web search,\nlegal research integrations, team reference materials) to verify currency —\nespecially for:\n\n> **No silent supplement.** If a research query to the configured legal research tool (Westlaw, CourtListener, or firm platform) returns few or no results for the jurisdiction-and-question, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [jurisdiction / question]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag the question as unverified and stop here. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Tag every citation in the answer with where it came from: `[Westlaw]`, `[CourtListener]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the user supplied. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n\n- Salary thresholds for any exemption (federal and state — several states\n index annually and several have tiered thresholds by employer size).\n- Final-pay timing on termination vs. resignation (many states differ).\n- PTO payout requirements (jurisdiction-specific; some require, some leave\n it to policy, some depend on accrual-plan design).\n- Meal and rest break rules and any penalty-pay consequence.\n- Daily or weekly overtime rules (some states have daily overtime and\n double-time rules that federal law does not).\n- Classification tests — see the worker-classification skill; the applicable\n test depends on jurisdiction and purpose.\n\nCommon question types you may be asked — for each, the answer is\njurisdiction-specific and time-sensitive. Do not state the rule here; route\nto research:\n\n- \"Is this role exempt?\" — Research the applicable federal and state salary\n thresholds (verify current amounts and any employer-size tiers) and the\n applicable duties test(s).\n- \"Do we have to pay overtime for X?\" — Research federal FLSA overtime plus\n any state-specific overtime rules (daily OT, double-time, alternative\n workweeks).\n- \"Do we have to provide meal/rest breaks?\" — Research the applicable\n state rule and any penalty-pay consequence for missed breaks.\n- \"When is final pay due?\" — Research the applicable state rule, including\n whether timing differs for termination vs. resignation and whether\n waiting-time or late-pay penalties apply.\n- \"Do we have to pay out accrued PTO?\" — Research the applicable state rule\n and any carve-out for accrual-cap or use-it-or-lose-it policies.\n- \"Can we classify this person as a contractor?\" — Route to\n `the “Worker Classification” workflow` if the facts are not already clear.\n\n### Step 2a: FLSA regular-rate and back-pay calculations\n\nWhen the question is a back-pay computation, unpaid-OT computation, or any\nquestion that turns on the FLSA \"regular rate,\" use this scaffold. Do not\nanswer from bare hourly wage × OT hours; that's the two most common errors\nthis skill exists to catch.\n\n**The regular rate is NOT just the hourly wage.** Under 29 U.S.C. §207(e),\nthe regular rate is **all remuneration** for employment EXCEPT the eight\nstatutory exclusions in §207(e)(1)–(8) (e.g., discretionary bonuses, gifts,\npremium pay, expense reimbursements, profit-sharing plans meeting the DOL\nregs, stock options meeting §207(e)(8), retirement/insurance contributions).\nAnything NOT within those eight exclusions is IN.\n\n1. **Non-discretionary bonuses are IN the regular rate.** Productivity\n bonuses, attendance bonuses, commissions, shift differentials, contest\n awards, and most \"bonuses\" a reasonable employee would expect as a matter\n of course are non-discretionary under §207(e)(3) and 29 C.F.R. §778.211.\n Divide the bonus by the total hours worked in the bonus period to get\n the per-hour increase to the regular rate. True discretionary bonuses\n (§207(e)(3)) require both the fact of payment AND the amount to be\n within the employer's sole discretion, determined at or near the end of\n the period — narrow category.\n2. **The unpaid OT premium is 0.5×, not 1.5× — when straight time was\n already paid for all hours.** If the employee was paid straight time for\n every hour (including the OT hours) but no premium, they are owed the\n **half-time premium** on OT hours, not time-and-a-half: `unpaid OT =\n 0.5 × regular rate × OT hours`. 29 C.F.R. §778.110(b). If the employee\n was NOT paid for the OT hours at all, the owed amount is 1.5× the\n regular rate on those hours. **State which pay posture you're assuming\n before you compute** — it determines 0.5× vs. 1.5× and is the most\n common error in this computation.\n3. **Show your math.** Print the formula and the inputs explicitly:\n ```\n Regular rate = (straight-time wages + non-discretionary bonuses + other non-excluded comp) ÷ total hours worked\n OT premium owed = 0.5 × regular rate × OT hours [if straight time already paid for OT hours]\n = 1.5 × regular rate × OT hours [if OT hours were unpaid]\n ```\n A number without the formula is not usable by a wage-and-hour lawyer.\n4. **Liquidated damages double the back-pay.** 29 U.S.C. §216(b). Liquidated\n damages equal the unpaid back-pay amount unless the employer proves, to\n the court's satisfaction, that the violation was in good faith and based\n on reasonable grounds to believe it was not a violation. 29 U.S.C.\n §260. Default assumption is liquidated damages apply; the employer bears\n the burden to avoid them.\n5. **Statute of limitations is 2 years; 3 for willful.** 29 U.S.C. §255(a).\n State the lookback explicitly and compute both bookends unless the\n willfulness posture is already established by the user.\n6. **State overlay.** Many states have longer lookback, higher overtime\n multipliers (daily OT, double-time), and different regular-rate rules.\n Check state wage-and-hour law against the jurisdiction gate from Step 1\n and flag where state law compounds (higher cap) or replaces (different\n rate) federal. California, New York, Massachusetts, and Washington are\n the most frequent overlay hits.\n7. **Attach the verify tag to the number.** Any back-pay amount produced by\n this skill carries `[verify — consult wage-and-hour counsel before\n asserting or paying]` on the line the number appears. The computation is\n specialist work; the skill is scaffolding, not opinion.\n\nIf the question is a back-pay calculation and any of these inputs are\nmissing (bonus breakdown, whether straight time was paid for OT hours,\nwillfulness posture, state jurisdiction), **ask before computing**. A\nconfident wrong number is the worst output this skill can produce.\n\n### Step 3: The flag\n\nIs this a close call? Be honest.\n\n- If the answer is clear on the researched rule: say so. \"Exempt — meets\n each element of the applicable duties test and the current salary\n threshold.\"\n- If it's close: say so. \"The duties test is borderline — this role could\n go either way. Recommend classifying as non-exempt to be safe, or getting\n a formal opinion.\"\n- If the law is in flux: say so. \"This rule has been amended recently — the\n current version takes effect [date]. Confirm effective date before relying\n on this answer.\"\n- If you could not verify currency: say so. Do not guess.\n\n## Output format\n\nConversational. This is a Q&A, not a memo.\n\n> **Research-connector pre-flight.** Before emitting the answer, check whether a legal research connector is reachable for this session — Westlaw, CourtListener, or any firm-configured research MCP. Collect this into the reviewer note per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`: if no connector returns results in Step 2 (or none is configured at run time), record it in the **Sources:** line of the reviewer note — e.g., `not connected — cites from training knowledge; pinpoint cites (volume/page/subsection) carry the highest fabrication risk, spot-check those first`. Per-citation `[model knowledge — verify]` tags remain inline. Do not emit a standalone banner above the output.\n\n> **Jurisdiction assumption.** Answers apply only to the jurisdiction identified. Wage-hour rules, exemption thresholds, and final-pay timing vary materially by state and country, and many rules index or change year over year. If the employee works in another jurisdiction, or the question is answered for the default-footprint state, this answer may not apply as written.\n\n```\n**[Jurisdiction]:** [The researched rule, one paragraph, with pinpoint cite\nand currency note.]\n\n[If close call or shifting law: the flag.]\n\n[If the answer differs in other footprint jurisdictions: one line noting that,\nand whether the differences are material.]\n```\n\n> **Verify citations.** Any case, statute, regulation, or wage-order cite above was generated with AI assistance. Before relying on a cite, check it against Westlaw, CourtListener, the relevant state agency's site, or your firm's research tool for accuracy, currency, and subsequent history. Fabricated or misquoted citations in filings or formal advice have resulted in sanctions.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- State the rule from memory — every answer is grounded in a researched,\n cited primary source verified for currency.\n- Make classification decisions for borderline cases. It states the rule and\n flags the close call. Human decides.\n- Give a 50-state survey unless asked. Answers for the relevant\n jurisdiction(s).\n- Track when the answer changes. If thresholds index or law shifts, the\n answer goes stale. Re-ask for current.", + }, + { + id: "builtin-cfl-employment-worker-classification", + title: "Worker Classification", + practice: "Employment", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “worker-classification” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /worker-classification\n\nRuns the applicable classification tests for the jurisdiction and flags where\nthe proposed arrangement doesn't match the structure you're trying to use.\nProspective only — for existing relationships, consult counsel.\n\n## Instructions\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, escalation table.\n2. Run the full workflow below.\n3. If the attorney provides details upfront, extract what's available and ask\n only about the gaps. Do not re-ask information already provided.\n\n## Examples\n\n```\nthe “Worker Classification” workflow\nWe want to bring on a data scientist for 6 months, working out of our\nSF office, using our tools, embedded in our analytics team.\n```\n\n```\nthe “Worker Classification” workflow\nIs our recruiter contractor arrangement okay? She works exclusively for\nus, sets her own hours, uses her own laptop, project fee per placement.\n```\n\n```\nthe “Worker Classification” workflow\n(skill will ask for details)\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nThe most expensive classification decision is the one nobody made consciously.\nSomeone describes what they want (\"a contractor\"), the engagement starts, and\ntwo years later the facts look like employment. This skill walks the applicable\ntests on the proposed arrangement before it starts — and tells you when what\nyou're describing doesn't match the structure you're trying to use.\n\nThis skill teaches the reasoning pattern. It does not state the law. Every\ntest formulation, statutory citation, threshold, and carve-out must come from\ncurrent research for the applicable jurisdiction.\n\n## Prospective-only hard gate — run BEFORE intake\n\n**This skill analyzes a PROPOSED engagement before the work starts.** Before any substantive intake (Step 1), ask:\n\n> Has this work already started? Is the worker currently engaged, or have they been performing work under this arrangement for any period of time (days, weeks, months, or years)?\n\nIf the answer is yes — the engagement already exists, in any form, for any duration — **STOP**. Do not proceed to Step 1 intake. Classifying an existing arrangement is not a planning exercise; it's a liability assessment with remediation implications: back pay (OT, meal/rest premiums), unpaid employer-side payroll tax, benefits eligibility that was denied, unemployment and workers' comp back-exposure, state penalties (in CA, PAGA), IRS § 530 relief analysis, and — in strict-test jurisdictions with ongoing work — the prospective exposure of letting it run another day. That analysis is privileged, led by counsel, and coupled with a remediation plan.\n\nOutput exactly this block and wait for a response:\n\n> **Out of scope — existing arrangement.**\n>\n> This skill is designed to analyze a worker engagement *before it starts*, so the classification choice informs how to structure the contract and operations. You've described an arrangement that already exists. Analyzing an existing engagement retroactively is a different exercise: reclassification risk assessment coupled with remediation planning — back-pay exposure, payroll-tax back-exposure, penalty exposure, benefits exposure, IRS § 530 relief analysis, and prospective restructuring. That work should be privileged, led by an attorney, and likely coupled with outside-counsel review given the dollar and enforcement exposure.\n>\n> Recommended next step: escalate per your config's escalation table (for retroactive classification, this typically routes to GC + outside employment counsel). I've flagged this for escalation routing.\n>\n> **If you want to proceed with the prospective-style analysis anyway for planning purposes, say \"proceed anyway\" — but understand:**\n>\n> - The output is NOT a remediation plan and should not be treated as one.\n> - The output does NOT scope back-pay, penalty, or payroll-tax exposure for the period already worked.\n> - The output does NOT substitute for the reclassification-risk assessment that this fact pattern actually calls for.\n> - The output will carry a prominent banner reflecting this scope mismatch, and the consequential-action gate will require an attorney yes before the analysis is treated as reliable.\n>\n> Only say \"proceed anyway\" if you're using this skill for forward-looking planning (e.g., \"if we were structuring this fresh today, how should we think about it?\") and you have a separate plan for the remediation question.\n\n**Only proceed past this gate with an explicit `\"proceed anyway\"` (or equivalent user instruction). A hesitant \"I guess\" does not count — re-prompt. If the user proceeds anyway, prepend this banner to every output of this skill for this session:**\n\n```\n⚠️ SCOPE MISMATCH — OUT-OF-SCOPE USE\nThis skill analyzes prospective worker engagements. The arrangement here\nalready exists. This output is the prospective-style analysis the user\nrequested for planning purposes only — it is NOT a remediation plan, does\nNOT scope existing back-pay / penalty / payroll-tax exposure, and does\nNOT substitute for the reclassification-risk assessment this fact pattern\nrequires. The remediation question has been flagged for escalation to\ncounsel per your config's escalation table.\n```\n\nIf the answer to \"has this work already started?\" is no (the engagement is genuinely prospective, not yet begun), proceed to load context.\n\n---\n\n## Load context\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdictional footprint, any classification history or\nprior settlements noted, escalation table, and any house classification\npolicy the team has recorded.\n\n## Output header\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` (it differs by user role — see `## Who's using this`).\n\n## Workflow\n\n### Step 1 — Information gathering\n\nAsk all of the following in a single block. Do not drip questions one at a\ntime. Briefly explain why you're asking — attorneys answer better when they\nunderstand what the question is testing.\n\n> To run the right classification tests I need to understand the proposed\n> arrangement in detail. Please answer as many of these as you can — the more\n> complete the picture, the more accurate the analysis:\n>\n> **The work**\n> - What will this person actually do day-to-day?\n> - Is this work part of your company's core business, or peripheral to it?\n> (e.g., a software engineer at a software company = core; an IT\n> contractor at a law firm = more peripheral)\n> - Is this a defined project with a clear end, or ongoing indefinite work?\n> - How specialized is the skill? Does this person have expertise your team\n> doesn't?\n>\n> **Control**\n> - Who sets their hours and schedule — them or you?\n> - Where will they work — your office, their location, or either?\n> - Will you direct how they do the work (methods, process, sequence), or\n> just what the end result should be?\n> - Will they supervise any of your employees?\n>\n> **Economics**\n> - How will they be paid — hourly, daily, or fixed project fee?\n> - Will you provide equipment, tools, or software, or do they use their own?\n> - Do they work for other companies, or will this be exclusive?\n> - Will they bear any financial risk — can they profit beyond the fee, or\n> lose money on the engagement?\n> - Do they have their own business entity (LLC, S-corp, sole proprietor)?\n>\n> **The arrangement**\n> - How do you want to structure this — direct contractor, staffing agency\n> temp, or vendor/SOW (company-to-company)?\n> - If staffing agency: who pays the worker — the agency or you? Who controls\n> day-to-day work?\n> - Will there be a written contract? Do you have a template in mind?\n> - Roughly how long is the engagement — weeks, months, over a year?\n> - Will they work alongside your employees doing similar work?\n>\n> **Purpose(s) of the classification**\n> - What legal purposes does the classification need to serve — federal\n> payroll tax, FLSA wage/hour, state wage/hour, unemployment insurance,\n> workers' compensation, benefits eligibility? Different purposes are often\n> governed by different tests, and the answers can diverge.\n>\n> **Jurisdiction**\n> - Where will this person physically perform the work?\n\nWait for responses before proceeding. If the attorney can't answer certain\nquestions, note the gaps — they affect the analysis.\n\n### Step 2 — Identify the applicable tests\n\n> **Research the applicable tests before proceeding.** For the jurisdiction(s)\n> and purpose(s) identified in intake, research the currently operative\n> classification test(s). Jurisdictions commonly use one or more of: an ABC\n> test, an economic-realities test, a common-law right-to-control test, a\n> hybrid, or a purpose-specific statutory test. The test that governs for\n> federal payroll tax may not be the same test that governs for state\n> wage/hour, unemployment, or workers' compensation — run each purpose on its\n> own track. Cite the controlling statute, regulation, or case. Note the\n> effective date of each rule and whether it has been recently amended.\n> Identify any carve-outs or exceptions that may apply (e.g., B2B,\n> professional services, construction, referral-agency, business-to-business\n> contracting relationship). Verify currency. If you are uncertain about the\n> current state of the law in any jurisdiction, flag it for attorney\n> verification — do not state a test you haven't confirmed.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) records the company's house classification policy, apply it\nfirst and flag any tension with the researched test.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for a jurisdiction-and-purpose combination, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [jurisdiction / purpose / test]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Tag every citation — each classification test, statute, regulation, or case — with where it came from: `[Westlaw]`, `[CourtListener]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the attorney supplied. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n### Step 3 — Apply the researched tests to the facts\n\nFor each test identified in Step 2, apply it to the intake facts. Score each\nfactor or prong explicitly — do not summarize. The attorney needs to see which\nfactors are clean and which are problems.\n\nUse a structure like the one below, but populate the *factors* from the\nresearched test, not from this file:\n\n```\nTest: [name of test, per research]\nPurpose: [what this test governs — federal tax / state wage-hour / UI / etc.]\nSource: [pinpoint cite to statute/regulation/case]\nCurrency: [verified as of date]\n\n| Factor / prong | Intake facts | Signal / pass-fail |\n|---|---|---|\n| [Factor 1 from researched test] | [from intake] | [direction or pass/fail] |\n| [Factor 2] | [from intake] | [direction or pass/fail] |\n| ... | | |\n\nStructure of the test:\n[How the test weighs factors — e.g., a multi-factor balancing test, or a\nconjunctive test where each prong must be satisfied, or a hybrid. State this\nfrom research, not from memory.]\n\nResult under this test:\n[Employee-leaning / IC-leaning / Fails prong X / Uncertain — contested prong]\n```\n\nRepeat for each applicable test.\n\n**Notes on contested prongs.** Some prongs of some tests are heavily contested\nin case law and fact-sensitive. Identify contested prongs explicitly — do not\npaper over them. The fact that a test is stated does not mean its application\nto these facts is settled; flag prongs that require attorney judgment or that\nhave generated recent litigation in the jurisdiction.\n\n### Step 4 — Classify and flag gaps\n\n**The classification call**\n\nBased on the test results, state the most accurate classification for this\nproposed arrangement:\n\n- **Employee (W-2):** Facts support employment under one or more applicable\n tests for the relevant purpose(s).\n- **Independent Contractor (1099):** Facts support IC status under all\n applicable tests for the relevant purpose(s).\n- **Temp via staffing agency:** Worker will be on the agency's payroll;\n company is a client — co-employment risk exists if company exercises\n day-to-day control. Research the applicable joint-employer standard if\n relevant.\n- **Vendor/SOW:** Company-to-company engagement; worker is employed by the\n vendor entity — cleanest structure if facts support it.\n- **Unclear / close call:** Facts cut both ways under one or more tests —\n state which test is the problem and why.\n\nIf tests give different answers for different purposes (e.g., defensible as\nIC for federal tax but fails a state wage/hour test), say so explicitly and\nname the controlling purpose and jurisdiction.\n\n**The gap analysis**\n\nThis is the most important output. Compare the intended structure against what\nthe facts actually support:\n\n```\nIntended structure: [what they said they want]\nWhat the facts suggest: [what the researched tests say this actually is]\n\nGaps — where the arrangement doesn't match the intended structure:\n🔴 [Factor]: [What they described] conflicts with [intended classification]\n because [specific researched test language + cite]. This is a significant\n misclassification risk if the engagement proceeds as described.\n🟡 [Factor]: [What they described] is a weaker point under [test]. Not\n disqualifying alone, but combined with other factors increases risk.\n✅ [Factor]: Supports [intended classification]. No issue.\n```\n\n**Escalation trigger**\n\nEscalate per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) if any of the following, or any team-specific\ntriggers recorded in that config:\n- The jurisdiction uses a strict test and the proposed work is core to the\n company's business — do not proceed without counsel review.\n- Prior misclassification settlement or audit noted in the config — heightened\n scrutiny applies.\n- Worker will supervise employees or have significant budget authority.\n- Engagement expected to exceed 12 months with no clear project endpoint.\n- Any contested prong where the outcome changes the classification.\n\n### Step 5 — Output\n\n> **Research-connector pre-flight.** Before emitting the analysis, check whether a legal research connector is reachable for this session — Westlaw, CourtListener, or any firm-configured research MCP. Collect this into the reviewer note per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`: if no connector returns results in Step 2 (or none is configured at run time), record it in the **Sources:** line of the reviewer note — e.g., `not connected — cites from training knowledge; the highest-fabrication pinpoints in classification analyses are ABC-test codifications, state carve-out subsections (e.g., CA Lab. Code §§ 2775/2776/2783), element counts in B2B exemptions, and purpose-specific test selection — spot-check those first`. Per-citation `[model knowledge — verify]` tags remain inline. Do not emit a standalone banner above the output.\n\n> **Jurisdiction assumption.** This analysis applies the tests operative in the jurisdiction(s) identified in intake. Classification rules vary materially by state and country, and the test that governs for one purpose (e.g., federal payroll tax) often differs from the test that governs another (e.g., state wage/hour). If the work will be performed in a jurisdiction not analyzed here, or if a new purpose is added later, this analysis may not apply as written.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Worker Classification Analysis\n**Proposed arrangement:** [what they described]\n**Jurisdiction:** [state/country]\n**Purpose(s):** [federal tax / state wage-hour / UI / WC / benefits]\n**Tests applied:** [list, each with pinpoint cite and currency date]\n\n---\n\n### Bottom line\n\n[Can you proceed / Need to fix X first / Stop — one-sentence why]\n\n---\n\n### Classification\n\n**Closest classification:** [Employee / IC / Temp via agency / Vendor-SOW / Unclear]\n\n[One paragraph summary of why — test results in plain language, tied to the\ncited sources.]\n\n---\n\n### Test results\n\n#### [Test name — per research]\nPurpose: [...] | Source: [...] | Currency: [...]\n[Scored table from Step 3]\n**Result:** [Employee-leaning / IC-leaning / Fails prong X / Mixed]\n\n#### [Additional researched tests — repeat the block]\n\n---\n\n### Gap analysis\n\n[Flags as structured in Step 4 — 🔴 significant risks, 🟡 weaker points,\n✅ clean factors]\n\n---\n\n### Escalation\n\n[None needed | Escalate to [name] before proceeding — [reason]]\n\n---\n\n### Next steps\n\n[If IC viable: \"Proceed — ensure the written agreement reflects the terms that\nsupport IC status under the researched test.\"]\n[If gaps exist: \"Address the following before using IC structure: [list]\"]\n[If agency/vendor is cleaner: \"Consider restructuring as [agency/SOW] — here's\nwhy it's cleaner for this fact pattern.\"]\n[If escalation needed: \"Do not proceed until counsel reviews the [specific\nissue].\"]\n[If employee confirmed: \"Classification confirmed as W-2 employee — run\n`the “Hiring Review” workflow` to review the offer letter, restrictive\ncovenants, and jurisdiction-specific requirements.\"]\n[If IC confirmed: \"Classification confirmed as independent contractor — no\noffer letter review needed. Ensure the written agreement reflects IC-supporting\nterms before the engagement starts.\"]\n[If agency/vendor: \"Engagement should be structured through [agency/vendor\nentity] — coordinate with them on worker agreement. No `/hiring-review` needed.\"]\n```\n\n## Consequential-action gate (classify a worker)\n\n**Before producing a \"Proceed as IC / employee / agency / vendor\" final recommendation:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Classifying a worker has legal consequences — misclassification exposes the company to back wages, taxes, benefits, penalties, and private-action risk, and in several states is strict-liability. Have you reviewed this classification call with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - The arrangement (work, control, economics, structure) as described\n> - Jurisdiction and which tests were applied\n> - Test-by-test results with cites and currency\n> - Gap analysis (🔴 / 🟡 / ✅) with the weak prongs called out\n> - Open questions and what's unresolved\n> - What could go wrong (the misclassification theory this arrangement most likely fails on; prior-audit/settlement overlay if any)\n> - What to ask the attorney (is IC viable here; would restructuring through an agency or vendor remove the risk; what contract terms do we need to support the classification)\n>\n> If you need to find an attorney, solicitor, barrister, or other authorised legal professional: contact your professional regulator (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent) for a referral service.\n\nDo not produce a final \"IC viable\" / \"use this classification\" output past this gate without an explicit yes. A marked-DRAFT analysis for attorney review is fine.\n\n---\n\n## What this skill does NOT do\n\n- Analyze an existing relationship retroactively — this is prospective only.\n- Draft the contractor agreement or SOW.\n- Advise on remediation if misclassification has already occurred.\n- State the law for any jurisdiction on its own — every test, factor, and\n carve-out must come from verified current research.\n- Substitute for outside counsel on close calls — strict-test jurisdictions,\n contested prongs, and prior-audit situations should always get a human\n review before the engagement starts.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-ip-cease-desist", + title: "Cease Desist", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “cease-desist” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /cease-desist\n\nTwo modes. Pick one:\n\n- `the “Cease Desist” workflow --send` — draft a cease-and-desist letter calibrated to your enforcement posture. Loud gate runs before delivery.\n- `the “Cease Desist” workflow --receive` — triage a C&D someone sent you. Produces an options memo with a recommendation.\n\n## Instructions\n\n1. **Read the practice profile.** Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If it contains `[PLACEHOLDER]` markers or does not exist, stop and say: \"This plugin needs setup before it can give you useful output. Run `configure your Practice Profile (Account → Practice Profile)` — the C&D skill depends on your enforcement posture, approval matrix, and practice-area mix, none of which are configured yet.\"\n\n2. **Check matter workspaces.** Per `## Matter workspaces`: if `Enabled` is `✗`, skip — skills use practice-level context. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\"\n\n3. **Dispatch on `$ARGUMENTS`:**\n - If `--send` is present: run send mode (below). Walk through identify-the-right, identify-the-conduct, identify-the-relationship, identify-the-demand, calibrate-to-posture, draft, and the pre-delivery gate.\n - If `--receive` is present: run receive mode (below). Ask for the incoming letter (path or pasted text), then assess, identify exposure, present options, and write the triage memo.\n - If neither flag is present: ask once — \"Are we sending a cease-and-desist (you're asserting) or triaging one we received (you're defending)?\" — and then dispatch.\n\n4. **Respect the gate.** In send mode, the loud gate runs before any final draft is written to disk. Do not skip it.\n\n5. **Respect the approval matrix.** Pull the approver for the C&D row from `## Enforcement posture → Approval matrix`. Pull automatic escalations. Surface both in the gate; do not smother them.\n\n6. **Hand off where appropriate.** In receive mode, if the recommendation is to respond firmly, offer to chain into `the “Cease Desist” workflow --send` pre-populated with the response context. If the recommendation is to pre-empt with a DJ action or TTAB cancellation, escalate to outside counsel per the practice profile's IP litigation row — do not draft.\n\n## Examples\n\n```\nthe “Cease Desist” workflow --send\nthe “Cease Desist” workflow --receive ~/Downloads/incoming-cd-acme.pdf\nthe “Cease Desist” workflow\n```\n\n## Notes\n\n- The outgoing C&D does not carry the work-product header. The internal draft, the pre-send brief, and the triage memo do.\n- Trademark rights are territorial; the draft assumes the jurisdictions declared in your practice profile's `Registered in:` footprint. If the conduct or counterparty is somewhere else, flag before drafting.\n- Every `[CITE:___]` is unverified until a citator run. Source attribution tags stay on the draft.\n- Non-lawyer users get a one-page brief for the attorney conversation before the gate clears.\n\n---\n\n## Purpose\n\nA cease-and-desist letter asserts a legal right and demands that someone stop doing something. It is one of the most consequential letters an IP practice sends or receives. Sending one is a first step toward litigation — recipients can file a declaratory judgment action in a forum of their choosing, and overbroad or bad-faith assertions can be used against the sender. Receiving one starts a clock and forces a decision. This skill handles both sides with the guardrails the decision deserves.\n\nTwo modes:\n\n- `--send` — you are asserting. Draft a C&D calibrated to the posture, gate before delivery.\n- `--receive` — you are defending. Triage the incoming letter, produce an options memo, route to matter creation if warranted.\n\nIf the user does not pass a flag, ask once: \"Are we sending a cease-and-desist (you're asserting) or triaging one we received (you're defending)?\"\n\n> **External deliverable (send mode):** the drafted C&D is sent to counterparty. Do NOT include the `PRIVILEGED & CONFIDENTIAL — ATTORNEY WORK PRODUCT` header on the outgoing letter. Internal drafts, pre-send briefs, and triage memos keep the header per plugin config `## Outputs`.\n\n## Jurisdiction assumption\n\nTrademark rights are territorial — a US registration does not travel. Copyright is Berne-multilateral but enforcement is jurisdiction-specific, and statutory remedies (including US §504 statutory damages) turn on local law. This skill assumes the jurisdiction declared in the matter or the practice profile's `Registered in:` footprint. If the infringing conduct, counterparty, or forum is somewhere else, flag it — the draft may not apply as written.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Enforcement posture` (posture, C&D triggers, soft-letter criteria, approval matrix, automatic escalations), `## IP practice profile` (practice area mix, registered jurisdictions, outside counsel roster), `## Outputs` (work-product header, role), `## Who's using this` (role — lawyer vs. non-lawyer)\n- Any C&D template or enforcement playbook referenced in the practice profile's seed documents — read it, match the structure\n- **Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip matter machinery — skills use practice-level context. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific overrides (e.g., posture override, approver override). Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n## Send mode — drafting the C&D\n\n### Step 1: Identify the right\n\nAsk, in one batch:\n\n> Which IP right are we asserting?\n>\n> - **Trademark** — is it registered? Where (USPTO, EUIPO, UKIPO, national)? Reg number and class(es)? Or common-law-only (first-use date, geographic scope)?\n> - **Copyright** — is it registered? Title, registration number, date? Or unregistered (note: US suits require registration for filed claims; statutory damages and fees require pre-infringement registration)?\n> - **Both** — identify each.\n\nRecord each right. Registered rights get cited by number. Common-law rights get the first-use evidence paragraph. Unregistered copyrights get a flag: \"We may not be able to file suit on an unregistered US copyright without registering first — `[SME VERIFY]` before the letter threatens litigation.\"\n\n### Step 2: Identify the conduct\n\n> Describe the infringing conduct in specifics, not adjectives:\n>\n> - **Who** is doing it — entity name, individual, platform handle?\n> - **What** — the accused mark, the accused copy, the accused product? Attach or describe samples.\n> - **Where** — website URL, marketplace listing, physical retail, social media?\n> - **Since when** — date first observed, date of the earliest use you can document?\n> - **Evidence** — screenshots, receipts, watch-service hit, customer confusion reports?\n\nFacts go in specific. \"You sold product X on [URL] bearing the mark [Y] on [date]\" beats \"You have been infringing our rights.\" Adjectives tell on a thin record.\n\n### Step 3: Identify the relationship\n\n> What's the relationship between us and the recipient?\n>\n> - **Competitor** (direct or adjacent) — standard posture applies\n> - **Reseller / channel partner** — tone adjusts; consider the soft-letter path\n> - **Former licensee / ex-employee / former partner** — contract provisions likely apply; cite them\n> - **Stranger / random infringer** — standard\n> - **Current customer / partner** — automatic escalation per practice profile; flag before drafting\n\nThis changes tone, approver, and whether to draft at all without escalation.\n\n### Step 4: Identify the demand\n\n> What does the client actually want?\n>\n> - **Stop** — cease the infringing use\n> - **Account** — report sales, profits, volumes (for damages baseline)\n> - **Destroy** — destroy or recall infringing inventory\n> - **Damages** — monetary settlement\n> - **Transfer / assign** — transfer the domain, hand over the account, assign the accused mark or copyright\n> - **Public correction** — takedown of offending content, public statement\n> - **Confirm in writing** — compliance undertaking by a date\n\nPick the actual remedies. The demand must be proportionate to the harm — an overbroad demand is evidence of bad faith if the matter is ever litigated.\n\n**Channel-takedown parallel path (marketplace infringement).** If the accused conduct is on a marketplace (Amazon, Etsy, eBay, Alibaba, TikTok Shop, AliExpress, Walmart Marketplace, Shopify-hosted storefronts), flag the platform's brand-protection / IP-infringement reporting path as a faster, cheaper parallel track that does not require a C&D or litigation:\n\n- **Amazon Brand Registry** (trademark and copyright takedown, counterfeit removal)\n- **Etsy IP Infringement reporting** (trademark / copyright / patent forms)\n- **eBay VeRO** (Verified Rights Owner program)\n- **Alibaba IPP** (IP Protection Platform)\n- **TikTok Shop IP Protection**\n- **Shopify DMCA / trademark reporting**\n\nA marketplace takedown often resolves in days; a C&D gives the infringer time to sell through inventory while negotiating. The two paths are not mutually exclusive — recommend filing both when the conduct is marketplace-based, with the C&D covering off-platform conduct (DTC site, wholesale, social, physical retail) that the platform report cannot reach. Note in the pre-send brief whether the parallel-path has been filed, is queued, or is declined (and why).\n\n### Step 5: Calibrate to posture\n\nRead `## Enforcement posture` → `Default posture:` and apply:\n\n- **Aggressive** — firm letter, short deadline (often 7–14 days), explicit consequence language (litigation, statutory damages, fees, injunctive relief), no settlement softening\n- **Measured** — firm but professional, standard deadline (14–30 days), consequences noted without theatrics, openness to discussion if they respond\n- **Conservative** — soft letter framing, longer deadline or no hard deadline, \"we'd like to discuss\" opening, consequence language muted or absent\n\nAlso read `When we send a C&D`, `When we send a soft letter first`, and `When we just file`. If the facts suggest this should be a soft letter or a direct filing per the practice profile, flag it before drafting: \"Per your enforcement posture, this pattern matches [soft letter / filing]. Do you still want a C&D, or would you prefer [alternative]?\"\n\nMatter-level overrides in `matter.md` beat the practice default.\n\n### Step 5.5: Counterparty diligence — REQUIRED PRECONDITION\n\n**Before drafting, run counterparty diligence and present the results to the user.** This is not conditional on \"if the counterparty looks big.\" Every C&D assertion carries DJ / fee-shifting / bad-faith exposure calibrated to *who* the recipient is. The skill does not draft a C&D until the user has seen the diligence and confirmed they still want to pick this fight.\n\nCollect and present — in one block, for user sign-off — the following:\n\n- **Legal entity** — exact corporate name, state/country of formation, registered agent, any `d/b/a` aliases. USPTO / EUIPO ownership records; state Secretary of State business search; public company filings if any. Flag `[SME VERIFY]` if the source is unconfirmed.\n- **Size and resources** — approximate headcount, revenue band if publicly known, funding if a startup, parent company if a subsidiary. Public sources (LinkedIn headcount, press, Crunchbase, SEC filings). Flag honestly if size can't be determined.\n- **IP portfolio** — do they hold registered marks, patents, or copyrights in adjacent classes? A counterparty with its own IP portfolio is more likely to (a) understand the posture, (b) counter-assert, and (c) file DJ. USPTO TESS / TSDR quick search on the accused entity and affiliates.\n- **Litigation history** — PACER / Court Listener quick pass for prior IP litigation as plaintiff or defendant. A repeat litigant or DJ-happy counterparty changes the calculus. Flag any prior C&D campaigns in the industry.\n- **Counsel** — do they have known outside IP counsel? Firm, lead partner if identifiable from prior filings. \"No counsel on file\" is itself a data point.\n- **DJ-plaintiff risk posture** — given size, IP portfolio, litigation history, counsel, and forum: is this a counterparty likely to welcome a C&D as an invitation to file DJ in a forum of their choosing? Flag high / medium / low with a one-sentence reason.\n- **Relationship risk** — are we a customer of theirs, do we share investors, are they a potential acquirer or partner? \"Not a customer\" confirmation pulled from the practice profile; anything else flagged.\n\nPresent this as a short memo in-chat BEFORE the draft:\n\n```\n## Counterparty diligence — [Entity Name]\n\n- **Entity:** [name, state of formation, parent if any]\n- **Size:** [headcount band, revenue band, funding stage] — [source, `[SME VERIFY]` where applicable]\n- **IP portfolio:** [registered marks / patents / copyrights in adjacent classes — or \"none found\"]\n- **Litigation history:** [prior IP cases as plaintiff or defendant — or \"none found in quick pass\"]\n- **Counsel:** [known outside IP counsel — or \"none identified\"]\n- **DJ-plaintiff risk:** [high / medium / low — reasoning]\n- **Relationship risk:** [any customer / investor / partner / acquirer overlap — or \"none identified\"]\n\n**Automatic escalations this triggers** (per practice profile `## Enforcement posture` → Automatic escalations):\n- [list each trigger that this diligence surfaces]\n\n**Confirm before I draft:**\n- Do you want to proceed with a C&D against this counterparty, given the diligence above?\n- Any of the automatic escalations applicable? If yes, the approver named in the profile signs off before drafting, not after.\n```\n\n**Do not proceed to Step 6 (Draft) until the user has engaged with the diligence block.** A blank \"ok\" is worse than no confirmation — push back: \"Before I draft — anything in the diligence that changes the calculus? Size, prior litigation, their counsel, relationship?\"\n\nIf diligence surfaces anything in the practice profile's automatic-escalation list (customer, bigger counterparty, patent matter, press-attracting, etc.), route to the named approver per the profile — do not draft on the reviewer's behalf until the approver has signed off on going forward.\n\nIf critical diligence items cannot be answered (e.g., entity cannot be confirmed, size is unknown and the counterparty is not on any public register), say so and flag: \"I can't confirm [entity / size / counsel] from available sources. Do you have this, or should we pause until a paralegal or OC runs the confirmation?\"\n\n### Step 6: Draft\n\nDraft structure:\n\n1. **Sender / letterhead and date**\n2. **Recipient block**\n3. **Re: line** — concise, does not reveal privileged strategy. `Re: Unauthorized use of [MARK] (US Reg. No. [•])`\n4. **Opening** — identify the sender, the right, the registration (if any), and the fact of the letter\n5. **The right** — trademark: reg number, class, first-use date, registration status; copyright: registration number, title, year, work description; common-law: first-use date, geographic scope, evidence of acquired distinctiveness\n6. **The infringing conduct** — specific: who, what, where, when, evidence\n7. **The legal basis** — `[CITE: Lanham Act §32 / §43(a) / 17 U.S.C. §501 / state UCL / contract §]` as applicable\n8. **The demand** — numbered, specific, proportionate\n9. **The deadline** — calendar date, method of confirmation\n10. **Consequences of non-compliance** — calibrated to posture\n11. **Preservation demand** — documents, communications, metadata related to the accused conduct\n12. **Reservation of rights** — \"without waiver of any claims or remedies, whether at law or in equity\"\n13. **Signature block** — approver per practice profile\n\n**Drafting rules:**\n\n- **Specificity over adjectives.** Dates, URLs, reg numbers, samples. Adjectives are a draftsperson's tell that the facts are thin.\n- **No overbroad assertions.** If the mark is registered in one class and the accused use is in a different class, say so — don't pretend the registration covers both. Overbroad C&Ds are evidence of bad faith and can support §43(a)(1)(B) or Rule 11 exposure.\n- **Citations as placeholders unless verified.** `[CITE: Lanham Act §32, 15 U.S.C. §1114]` stays as a placeholder unless the user provided the cite or a research tool returned it. Tag every citation with source — `[Westlaw]`, `[user provided]`, `[model knowledge — verify]`, `[web search — verify]`. Never strip the tags.\n- **Consequence language matches posture.** Aggressive → specific relief threatened (injunction, statutory damages under 15 U.S.C. §1117 / 17 U.S.C. §504, attorneys' fees). Measured → \"we reserve all rights.\" Conservative → \"we'd like to discuss before considering further steps.\"\n- **Jurisdiction-specific hooks** — if US, watch for Anti-Cybersquatting (15 U.S.C. §1125(d)) for domain matters, §43(a) for unregistered marks, §504(c) for pre-registration timing. Non-US: flag the forum and note the draft may need foreign associate review.\n\n### Step 7: The loud gate before delivery\n\nBefore presenting the draft in-chat or writing the .docx, display this gate verbatim. **The user must engage with it** — a blank acknowledgment is worse than no gate.\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ BEFORE THIS DRAFT GOES ANYWHERE │\n├─────────────────────────────────────────────────────────────┤\n│ │\n│ This is a draft for attorney review — not a letter to │\n│ send. Sending a cease-and-desist letter is an assertion │\n│ of legal rights with real consequences: │\n│ │\n│ • It can trigger a declaratory judgment action in a │\n│ jurisdiction of the recipient's choosing. A well-funded │\n│ recipient can use a C&D as an invitation to pick a │\n│ hostile forum. │\n│ │\n│ • Overbroad or bad-faith assertions can be used against │\n│ the sender — §43(a)(1)(B) claims, Rule 11 sanctions, │\n│ attorneys' fees under the Lanham Act / Copyright Act. │\n│ │\n│ • It starts a dispute that may not settle cheaply. │\n│ │\n│ Confirm before the letter leaves: │\n│ │\n│ 1. The rights asserted are valid — registered (pulled │\n│ from the register, not assumed) or solidly common │\n│ law with evidence of acquired distinctiveness. │\n│ 2. The claim is colorable — a reasonable practitioner │\n│ would make it on these facts. │\n│ 3. The demand is proportionate — we are asking for │\n│ relief the conduct warrants, not everything. │\n│ 4. Whoever has authority to start a fight has approved. │\n│ 5. Counterparty diligence (Step 5.5) was presented │\n│ and confirmed — entity, size, IP portfolio, prior │\n│ litigation, counsel, DJ-plaintiff risk, and │\n│ relationship risk. Not conditional. Required. │\n│ │\n│ Approver per your practice profile: [approver name/role │\n│ from Enforcement posture → Approval matrix → C&D row] │\n│ │\n│ Automatic escalations that apply here: [list any from the │\n│ practice profile that this matter triggers — customer, │\n│ bigger counterparty, patent, press-attracting, etc. — │\n│ surfaced in Step 5.5 diligence] │\n│ │\n│ Parallel-path status (marketplace conduct): [filed / │\n│ queued / declined — from Step 4. \"Not applicable\" if │\n│ conduct is not on a marketplace.] │\n│ │\n└─────────────────────────────────────────────────────────────┘\n```\n\nIf the user is a non-lawyer (per `## Who's using this`), add:\n\n> Sending a C&D has legal consequences that go beyond the recipient's response — it is an affirmative assertion of rights that can be held against you. Have you reviewed this with an attorney? If not, here's a brief to bring to them: [generate a 1-page summary: parties, rights asserted, infringing conduct, demand, posture, risks flagged above, what could go wrong, specific questions for the attorney].\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent). The ABA IP section and state IP associations (US), CIPA/ITMA (UK), and equivalent bodies elsewhere maintain referral rosters for trademark and copyright practitioners.\n\nDo not write the .docx or mark the draft as ready without explicit engagement with the gate.\n\n### Step 8: Output\n\n**Primary:** `/cease-desist//draft-v.docx` (or `cease-desist//draft-v.docx` at practice level). Use the `docx` skill. Letter-formatted per the draft structure above. Strip the work-product header from the outgoing letter.\n\n**In-chat:** show the draft as plain text for review before writing the .docx. Iterate before committing to disk.\n\n**Reviewer-facing closing note** (appended to the in-chat preview only, stripped from the .docx):\n\n> This is a draft cease-and-desist letter for attorney review, not a letter ready to send. Sending it is an assertion of legal rights with the consequences described in the pre-delivery gate. A licensed attorney reviews, edits, and takes professional responsibility before sending. Do not send this draft unreviewed.\n\n**Citation verification.** Every `[CITE:___]` and every cite carried from a template or provided authority is unverified until run through a citator. Before sending, verify each cite is good law on a legal research platform. Fabricated or misquoted cites in sent assertion letters are professional responsibility exposure. Preserve the source-attribution tags — `[Westlaw]`, `[CourtListener]`, `[Descrybe]`, `[user provided]`, `[model knowledge — verify]`, `[web search — verify]` — tags flagged `verify` get checked first.\n\n**No silent supplement.** If a configured research tool returns few or no results for an authority the draft needs, report what was found and stop. Do NOT backfill from web search or model knowledge without asking. Present options — broaden the query, try a different tool, accept web search with tags, leave the placeholder — and let the user decide.\n\n**Post-send checklist.** After the draft is approved, write `/cease-desist//checklist.md` with: final read by approver, all `[VERIFY]` resolved, all `[CITE]` filled and verified, privilege markings stripped from the outgoing letter, approver signed, delivery method executed, proof of delivery retained, compliance deadline calendared, escalation plan if no response, matter created in `matters/` if not already.\n\n## Receive mode — triaging the incoming C&D\n\n### Step 1: Read the letter\n\nExtract:\n\n- **Sender** — entity, signer, outside counsel if any\n- **Recipient** — which of our entities/people\n- **Delivery method and date**\n- **Asserted right** — trademark (reg number? jurisdiction?), copyright (registered? title?), both, something else\n- **Alleged conduct** — their version of what we're doing\n- **Legal basis** — statutes, contract provisions, theories cited\n- **Demand** — what they want; is the deadline stated?\n- **Threats** — what they say they'll do\n- **Tone** — firm / soft / scorched-earth; counsel signature usually signals seriousness\n\n### Step 2: Assess the assertion\n\nNot a legal opinion — a structured read:\n\n- **Rights validity.** Are the asserted registrations real and active? (Check USPTO TSDR, EUIPO eSearch, Copyright Office records — flag any that look dormant or not in force.) For common-law claims, what evidence do they actually cite?\n- **Plausibility of confusion / similarity / infringement.** On the facts as alleged, is this a colorable claim or is it stretching? For trademark: likelihood of confusion turns on multi-factor tests (Polaroid / AMF / Sleekcraft depending on circuit — `[SME VERIFY]` the forum's test). For copyright: access + substantial similarity. Flag where the claim looks weakest.\n- **Overbreadth.** Are they demanding more than the conduct warrants? (They want the mark transferred when registration would at most cover re-labeling? They want all sales when only one channel touched the right?) Overbroad demands weaken leverage and strengthen a §43(a)(1)(B) / unclean-hands counter.\n- **Timing.** Laches, statute of limitations, registration timing (for US copyright statutory damages) — flag any date issues on the face of the letter.\n- **Forum.** Where would they sue? Is the forum contractually fixed (most unlikely in a stranger IP dispute)? Is there a DJ opportunity for us?\n\n### Step 3: Assess our exposure\n\n- **Are we actually infringing?** Honest look. What does the record show?\n- **Could we stop easily?** Cost of compliance vs. cost of fight.\n- **Is the sender a troll or a real claimant?** Repeat-plaintiff? Known-willing-to-fight? Recent C&D campaign on comparable use? Check public dockets if time permits.\n- **What's at stake beyond this dispute?** Brand equity, customer relationships, precedent for similar inbound C&Ds.\n\n### Step 4: Options\n\nPresent 4-5 options with tradeoffs:\n\n**A — Comply quickly**\n- When: the claim is colorable, compliance is cheap, and the fight isn't worth it\n- Tradeoff: establishes a concession they may point to later; may embolden future assertions\n- Next step: confirm compliance in writing (narrow), do not concede broader theory\n\n**B — Negotiate**\n- When: there's a middle-ground business deal (license, coexistence, rebranding timeline) that resolves it\n- Tradeoff: commits time; requires care on settlement-communication posture (FRE 408 or state equivalent; protection attaches from substance and context, not labeling alone)\n- Next step: holding letter + opening negotiation track\n\n**C — Respond firmly (reject)**\n- When: their claim is weak, overbroad, or factually wrong; we want to close this down without litigating\n- Tradeoff: locks in a position; if the claim is in fact colorable, our response becomes an exhibit\n- Next step: draft a response letter — consider running it through `the “Cease Desist” workflow --send` reframed as a response\n\n**D — Ignore (and preserve)**\n- When: the claim is frivolous, the sender has no apparent capacity to sue, the deadline has no legal consequence\n- Tradeoff: silence can be used as non-denial in some contexts; legal hold required regardless; risk that filing follows\n- Next step: issue legal hold via matter-level process; log the demand; move on\n\n**E — Pre-empt with a DJ action or cancellation**\n- When: we face real business uncertainty, the claim is weak, and we benefit from our own forum\n- Tradeoff: we go on offense; budget and leadership sign-off required; now there's a lawsuit\n- Next step: escalate to outside counsel per practice profile, do not draft\n\n**F — File to cancel their mark (TTAB) or invalidate their copyright registration**\n- When: their rights themselves are vulnerable and we want to take the instrument off the board\n- Tradeoff: slow, expensive, public; separate from the dispute itself\n- Next step: escalate to outside counsel\n\nRecommend one with two sentences of rationale. Be specific about why.\n\n### Step 5: Deadline triage\n\n- Their stated deadline — note it, but it doesn't legally bind us (unless a specific statute gives it teeth).\n- Our internal decision deadline — typically stated deadline minus enough time to draft, review, and approve a response. Flag it on the calendar.\n- Legal deadlines — statute of limitations on any underlying claim, contractual cure periods, forum-specific timelines.\n\nIgnoring a stated deadline entirely is a choice, not a default. Note that filing usually follows silence, not the deadline date.\n\n### Step 6: Write the triage memo\n\nOutput: `/cease-desist/inbound//triage.md` (or at practice level if matter workspaces are off).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n[PRIVILEGE INHERITANCE BLOCK — pick by role and matter type; see guidance below the template]\n\n# C&D Received — Triage\n\n> **READ FOR TRIAGE, NOT OPINION.** This is an intake scan and options analysis — not a legal merit opinion. The assessment below is a structured read to support counsel's decision on routing and response. Every cited statute, rule, or case is flagged for SME verification; every merit call is the counsel's, not this skill's.\n\n**Slug:** [slug]\n**Received:** [YYYY-MM-DD]\n**Received by:** [entity / person]\n**Incoming file:** [path]\n\n## The assertion\n\n**Sender:** [entity, signer, counsel]\n**Asserted right:** [trademark / copyright / both — with specifics, reg numbers, jurisdictions]\n**Alleged conduct:** [their version, one paragraph]\n**Demand:** [list — specific asks]\n**Their stated deadline:** [date]\n**Tone:** [firm / soft / scorched-earth]\n\n## Rights validity\n\n[Registrations as asserted — `[SME VERIFY]` against the register; common-law claims evaluated against the evidence cited]\n\n## Legal basis cited\n\n[Each citation inline-tagged with `[SME VERIFY: applicability / currency / jurisdiction]` and source `[Westlaw / user provided / model knowledge — verify / web search — verify]`. Do not rely on any citation here without independent check.]\n\n## Plausibility assessment\n\n- **Confusion / similarity / infringement on the facts:** [read]\n- **Overbreadth:** [read]\n- **Timing issues (laches, SoL, registration timing):** [read]\n- **Forum:** [their likely forum; DJ opportunity]\n\n## Our exposure\n\n- **Actually infringing?** [honest look]\n- **Cost of compliance vs. cost of fight:** [read]\n- **Sender credibility:** [troll / real claimant / repeat plaintiff — with any public-docket evidence]\n- **Collateral stakes:** [brand, customers, precedent]\n\n**Triage rating:** [substantial / debatable / weak / frivolous] — *structured read for routing, not a merit opinion; `[SME VERIFY]`*\n\n## Options\n\n### A. Comply quickly\n[Rationale, tradeoffs, next step]\n\n### B. Negotiate\n[Rationale, tradeoffs, next step]\n\n### C. Respond firmly\n[Rationale, tradeoffs, next step]\n\n### D. Ignore + preserve\n[Rationale, tradeoffs, next step]\n\n### E. Pre-empt (DJ)\n[Rationale, tradeoffs, next step]\n\n### F. File to cancel / invalidate\n[Rationale, tradeoffs, next step]\n\n**Recommendation:** [A/B/C/D/E/F] — [two sentences why] — `[SME VERIFY: counsel to confirm before executing]`\n\n## Deadlines\n\n- **Their stated deadline:** [date]\n- **Our internal decision deadline:** [date]\n- **Legal deadlines on any underlying claim:** [SoL, cure, procedural — with dates]\n\n## Immediate actions\n\n- [ ] Legal hold issued — [yes/no]\n- [ ] Matter created in log — [yes/no/TBD]\n- [ ] Counsel assigned — [who]\n- [ ] Insurance tendered — [yes/no/N-A]\n- [ ] Internal escalation — [who/when]\n```\n\n**Privilege inheritance block — pick by role and matter type.** Read `## Who's using this` (Role) in the plugin config and the matter type (trademark / copyright / patent / OSS / other). This triage records a first-pass merit read on an adverse assertion; whether it's actually privileged depends on who prepared it and what it's about. Getting this wrong in either direction is harmful — a false \"privileged\" marking creates a discoverable admission that reads as a concession; under-marking a genuinely privileged memo can waive the protection. Insert exactly one of the following:\n\n- **Role = Lawyer / legal professional:**\n > **Privilege inheritance.** This triage records our first-pass merit read and response posture on an adverse assertion. It is attorney-client and/or work-product material. Do not forward, attach to an insurance tender without scrubbing, or share with counterparty. Store with privileged matter material and mark per house privilege conventions.\n\n- **Role = Registered patent agent, matter is a patent matter before the USPTO:**\n > **Privilege (patent agent-client).** This triage is privileged under the federal patent agent-client privilege recognized in *In re Queen's University at Kingston*, 820 F.3d 1287 (Fed. Cir. 2016), because it relates to a matter reasonably necessary and incident to the prosecution of patents before the USPTO. That privilege is narrow: it does not extend to matters outside USPTO practice. Do not forward, attach to an insurance tender without scrubbing, or share with counterparty. Bring to supervising counsel for matter-specific privilege decisions.\n\n- **Role = Registered patent agent, matter is NOT a patent matter** (trademark, copyright, OSS, trade secret, contract, or anything else outside USPTO practice):\n > **CONFIDENTIAL — NOT PRIVILEGED.** This triage is not privileged because a registered patent agent's privilege is limited to patent prosecution before the USPTO (*In re Queen's University at Kingston*, 820 F.3d 1287 (Fed. Cir. 2016)). A trademark, copyright, OSS, or other non-patent matter falls outside that privilege. Treat this document as confidential, store it with care, bring it to counsel, and let counsel mark it. Do not forward it as a privileged document.\n\n- **Role = Non-lawyer and not a registered patent agent:**\n > **CONFIDENTIAL — NOT PRIVILEGED.** This document is not privileged unless and until reviewed by a licensed attorney. Treat it as confidential; do not forward to anyone outside the legal review chain; bring it to counsel and let counsel mark it. Forwarding this document as \"privileged\" before an attorney reviews it does not make it so and can harm you if the matter becomes contested.\n\nClose the in-chat presentation with this guardrail verbatim:\n\n> This is a triage memo, not advice. The strength assessment above is a first read based on the letter alone — it does not account for facts you haven't told me, registrations I can't verify, or jurisdictional issues. An attorney evaluates before you respond, decide to ignore, or commit to a path.\n\nIf the user is a non-lawyer, add the \"find-an-attorney\" routing paragraph from send mode.\n\n### Step 7: Hand off\n\nBased on the recommendation and user confirmation:\n\n- Respond firmly → hand off to `the “Cease Desist” workflow --send` with context pre-populated as a response letter (this triggers the send-mode gate anew).\n- Negotiate → start a holding letter / negotiation track in the matter.\n- Pre-empt or file to cancel → escalate to outside counsel per the practice profile's IP litigation row; do not draft.\n- Matter creation → if there isn't one and the matter is material, offer `the “Matter Workspace” workflow new ` pre-populated.\n- Comply / ignore → log the decision in the matter history; issue or confirm the legal hold; close the triage record.\n\n## Decision posture\n\nPer `## Decision posture on subjective legal calls` in the practice profile: when uncertain whether there is infringement, whether a mark is confusingly similar, whether a work is substantially similar, whether a claim is colorable, or whether sending is safe — do not silently decide it's fine. Flag for attorney review, surface the factors cutting both ways, note the uncertainty. Sending a C&D on an assumption is a one-way door; surfacing doubt is a two-way door.\n\n## What this skill does not do\n\n- **Send the letter.** Drafting only. The user sends, after approval.\n- **Research citations.** Placeholders stay as placeholders unless the user provides authorities or a connected research tool returns them. Inventing cites is professional responsibility exposure.\n- **Bypass the gate.** The send-mode gate runs every time. Even with an `--skip-gate` flag (none is provided), the skill would log the skip in the draft file.\n- **Decide merit definitively on the receive side.** The rating is a structured read for routing; a formal merit opinion lives with counsel.\n- **Validate the sender's cited law.** Flags for the user; does not autonomously call a claim valid or invalid.\n- **Make the matter-creation call.** Surfaces the recommendation; user decides.", + }, + { + id: "builtin-cfl-ip-clearance", + title: "Clearance", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “clearance” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /clearance\n\n**This is a triage, not a clearance opinion.** A trademark clearance opinion\nrequires a full professional search and registered trademark counsel's\njudgment. A \"no obvious conflicts\" result means the triage\ndidn't find anything — it does not mean the mark is clear. Clients have been\nsued over marks that passed a knockout search.\n\n## Instructions\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If it\n contains `[PLACEHOLDER]`, stop and direct to `configure your Practice Profile (Account → Practice Profile)`.\n2. Follow the workflow below.\n3. Run intake (mark, goods/services, classes, jurisdictions, visual/stylization).\n4. Knockout check for intrinsic bars — generic, descriptive, deceptive,\n geographic, surname, false connection, prohibited matter, functional.\n5. Similar-marks search against what's connected (Solve Intelligence, CourtListener, Descrybe, or whatever MCP is available). If nothing is\n connected, say so in the output and proceed with the factor analysis only.\n6. Walk the applicable circuit's likelihood-of-confusion factors — du Pont /\n Polaroid / Sleekcraft / other. Flag each; never conclude.\n7. Write the triage memo to the matter folder (if a matter is active) or the\n practice outputs folder. Apply the work-product header per role.\n8. End with recommended next steps and the non-lawyer gate if the role is\n non-lawyer.\n\nThis skill never concludes a mark is clear. If uncertain, flag — the attorney\ndecides.\n\n## Examples\n\n```\nthe “Clearance” workflow \"APEXLEAF for an outdoor apparel line, planned launch US + EU\"\n```\n\n```\nthe “Clearance” workflow\n```\n\n(And the skill will ask for the mark, goods, classes, and jurisdictions.)\n\n---\n\n## THIS IS A FIRST PASS, NOT A CLEARANCE OPINION\n\n**Say this at the top of every output. Do not drop it. Do not soften it.**\n\n> **This is a first pass, not a clearance opinion.** A trademark clearance opinion\n> requires a full professional search (TESS, state registries, common law sources,\n> international registries, domain and social, trade dress and design marks where\n> relevant) and attorney judgment on likelihood of confusion, which depends on\n> factors a structured triage cannot fully assess. A \"no obvious conflicts\" result\n> from this skill means the triage didn't find anything — it does not mean the\n> mark is clear. Clients have been sued over marks that passed a knockout search.\n> A registered trademark attorney evaluates before anyone adopts, files, or\n> invests in this mark.\n\nThis is the loudest guardrail in the plugin. Under-calling a conflict is a\none-way door — a logo on trucks, a product launched, a TM application filed, all\nwith a problem underneath. Over-calling is a two-way door — the attorney narrows\nthe list in review. Stay on the two-way door side.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Load the practice profile first\n\nBefore running clearance, read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Pull:\n\n- **Role** from `## Who's using this` (lawyer vs. non-lawyer changes the work-product header and the non-lawyer gate below).\n- **Registered in** and **enforce where** from `## IP practice profile` and `## Enforcement posture` (default jurisdictions if the user doesn't specify).\n- **Integrations** from `## Available integrations` (CourtListener / Solve Intelligence / Descrybe — each determines what searches are available to run, what the fallback is, and what gets attributed in the output).\n- **Decision posture** from `## Decision posture on subjective legal calls` — this skill never concludes \"not confusingly similar.\"\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) contains `[PLACEHOLDER]` or `[Your Company Name]`, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor posture, jurisdictions, and approval chain to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll run this tailored to YOUR practice.\n> - Say **\"provisional\"** and I'll run this against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" run the clearance normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction (USPTO + common-law), no playbook (do the full analysis rather than matching against a position list). Tag the reviewer note and every finding block with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your playbook, your jurisdiction, your risk appetite. 2 minutes.\"\n\n---\n\n## Intake\n\nAsk once, in a single batch (don't drag out a quick job):\n\n> A few questions before I run the triage:\n>\n> 1. **Proposed mark.** Exact spelling, any stylization, and whether it's a word mark, logo, or both.\n> 2. **Goods or services.** What's actually being sold or offered under this mark. A sentence or two — I'll map to international classes.\n> 3. **Classes.** If you already know the Nice classes, list them. Otherwise describe the goods/services and I'll suggest the likely classes and confirm with you before running the search.\n> 4. **Jurisdictions.** Where do you plan to use, register, or enforce? (US / EU / UK / Madrid / specific countries — I'll default to `Registered in` from your practice profile if you don't say.)\n> 5. **How it will appear in use.** Any taglines, adjacent product names, trade dress, or design elements that would show up with it in market.\n\nWait for the answer. If the description is vague (\"AI tool,\" \"platform\"), push once:\n\n> Give me the actual thing a customer sees — is it a consumer mobile app, enterprise API, physical product, service? The classes turn on this.\n\n---\n\n## Knockout check\n\nBefore any database search, run the intrinsic problems that kill a mark regardless\nof prior registrations. For each, assess plainly and flag. Do not rationalize away\na clear issue.\n\n| Bar | What it means | Flag when |\n|---|---|---|\n| **Generic** | The term IS the category (e.g., \"Soap\" for soap) | The mark names what the thing is |\n| **Descriptive** | Directly describes a feature, function, quality, or ingredient | A consumer reads the mark and knows what the product does without imagination |\n| **Deceptive / deceptively misdescriptive** | Misrepresents a material feature | The mark suggests a quality the goods don't have and that quality would matter |\n| **Primarily geographically descriptive / deceptive** | Mark is primarily a place name and goods come from (or don't) that place | Mark = place + generic; or place + goods where customers would assume origin |\n| **Primarily merely a surname** | Mark is primarily a surname | Mark reads as someone's last name to the relevant consumer |\n| **False connection** | Mark falsely suggests connection with person, institution, national symbol | Mark invokes a specific identifiable person or institution |\n| **Prohibited matter** | Flags, coats of arms, insignia, specific prohibited categories | Mark contains a prohibited element |\n| **Functional (for design marks / trade dress)** | The feature is essential to use or affects cost/quality | Design mark — and the feature performs a function |\n\nNote on scandalous/immoral marks: after *Iancu v. Brunetti* (2019) and *Matal v.\nTam* (2017), the USPTO no longer refuses registration on those bases. The\nsurviving statutory bar in this zone is false connection under §2(a). Apply that;\ndon't flag under the struck-down bars.\n\n**Output:** for each knockout category, either \"no issue identified\" or a\nspecific flag with a one-line reason. Don't produce a blank table of passes.\n\n---\n\n## Similar marks check\n\nThe purpose here is to **find potentially confusingly similar prior marks**, not\nto decide whether confusion is likely. That is the attorney's call.\n\n### What the user has connected\n\nRead `## Available integrations` from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **If a trademark search connector is available** (Solve Intelligence,\n Descrybe — or any MCP exposing TM-registry search): run a preliminary search\n across the relevant classes and jurisdictions. Attribute every result to its\n source. Note the date of the search and the scope (which registries, which\n classes, exact-match vs. fuzzy, design search or not).\n- **If a legal research connector is available** (CourtListener for litigation for case law and TTAB decisions): sweep for reported disputes involving\n the mark or a close variant. Same attribution rule.\n- **If no search connector is available:** say so, explicitly, in the output.\n Do not infer results from model knowledge and present them as search findings.\n\n### Fallback when no database access exists\n\nWrite out, in the output, this exact statement:\n\n> **No database search was run.** This triage did not hit TESS, Solve\n> Intelligence, Descrybe, CourtListener, state registries, Madrid/WIPO, or any\n> common law / unregistered-mark sources. A knockout or full search across those\n> databases is required before any conclusion about availability. The triage\n> below is limited to intrinsic-bar analysis and structured confusion factors\n> against marks the user has identified or that come up in the conversation.\n\nThen proceed — the intrinsic checks and the factors analysis are still useful,\njust labeled honestly.\n\n### For each similar mark found (or supplied)\n\nCapture:\n\n- **Mark** (exact characters, any stylization)\n- **Source** (TESS registration no., Madrid designation, state registry, case\n citation, domain, social handle — whichever)\n- **Classes / goods-services description** from the register\n- **Owner**\n- **Status** (registered / pending / abandoned / cancelled — a dead mark is not a\n bar but can be relevant to fame and to a predecessor's rights)\n- **First-use date if available**\n\n**Do not supplement silently.** If you cite a USPTO registration number, it came\nfrom the search you ran; if you describe a mark the user mentioned, say that.\nNever invent a registration and never \"fill in\" a detail the record doesn't\nsupport. If the search didn't return a first-use date, write \"first-use date not\navailable from search result\" — do not guess.\n\n### Adjacent families sweep (required before concluding)\n\nA clearance that only checks exact and near-exact matches misses the marks a\ncompetitor adopted *because* yours was taken. Before concluding, identify 3–5\nadjacent word families the practitioner should also sweep, and ask the user to\nconfirm or add to the list.\n\nAdjacent families are category-conventional substitutes a reasonable competitor\nwould consider when the direct mark is unavailable. For a mark like\n`NEXUS HOME` in the smart-home hub space, the adjacent families include at\nminimum:\n\n- **Category synonyms** for NEXUS: `HUB`, `NEST`, `CORE`, `LINK`, `CONNECT`,\n `BRIDGE`, `CENTRAL`, `GATEWAY`.\n- **Assistant-style names** in the same product category: `ALEXA`,\n `ECHO`, `SIRI`, `GOOGLE HOME`, `CORTANA`, `HOMEY`, `HOMEBASE`.\n- **HOME / HOUSE / SMART variants**: `SMART HOME`, `HOUSEHOLD`, `HOUSE`,\n `ABODE`, `CASA`, `DOM`.\n- **Phonetic twins** on the root: `NEXIS`, `NEKSUS`, `NEXXUS`, `NECTIS`,\n `KNOXUS` (depending on how the word sits in the market).\n\nThe skill should output an adjacent-families block in the Similar Marks section\nwith a confirmation prompt:\n\n> **Adjacent families to sweep (please confirm or add):**\n>\n> - [family 1 — e.g., HUB / NEST / LINK / CONNECT]\n> - [family 2 — e.g., ALEXA-style assistant names]\n> - [family 3 — e.g., HOME / HOUSE / SMART variants]\n> - [family 4 — phonetic twins on the root]\n>\n> A clearance that only checks exact and near-exact matches misses the marks a\n> competitor adopted because yours was taken. Confirm this list is complete for\n> the category before I continue.\n\n> **When non-English-speaking jurisdictions are in scope,** the English-only phonetic sweep misses the most common source of cross-border conflicts. Add:\n> - **Translation equivalents.** The mark translated into the relevant languages. The EU's foreign-equivalents doctrine treats a translation as the same mark for confusion purposes.\n> - **Transliteration.** The mark written in the relevant script (Cyrillic, Chinese/Japanese/Korean, Arabic, Hangul, Thai). Phonetic equivalence across scripts is a recognized conflict basis.\n> - **Script variations.** Marks registered in a non-Latin script that sound like your mark when romanized.\n>\n> If you can't perform cross-language analysis, say so: \"Cross-language phonetic and translation-equivalent analysis not performed — this is the most common source of cross-border conflicts. A clearance search in [jurisdiction] should include it.\"\n\nIf the practitioner has a connected TM search tool, re-run the sweep against\neach confirmed adjacent family (exact + phonetic + translation-of-foreign-equivalent\nwhere relevant) and add the results to the Similar Marks table with the\n`Adjacent family` source noted. If no connector is available, say so, and list\nthe families as the explicit next-step input for a full professional search —\ndo not silently skip the sweep.\n\n---\n\n## Likelihood-of-confusion factors\n\n> **Confusion framework is jurisdiction-specific.** The US and EU assess likelihood of confusion differently. Don't apply the wrong one.\n>\n> - **US (federal circuits):** Multi-factor tests (*du Pont*, *Polaroid*, *Sleekcraft*) — strength of the mark, similarity (sight/sound/meaning), proximity of goods, channels, buyer sophistication, actual confusion, intent.\n> - **EU (Art. 8(1)(b) EUTMR):** Global appreciation — all relevant factors assessed holistically through the eyes of the average consumer. Key differences: greater weight on phonetic similarity; translation equivalents as standard (the mark translated into EU languages); \"likelihood of association\" beyond source confusion; the distinctiveness of the earlier mark carries more weight.\n> - **UK (TMA 1994 §5(2)):** Follows the EU global appreciation approach post-Brexit but diverging case law. Check for UK-specific decisions.\n> - **Other jurisdictions:** If the intake includes a jurisdiction without a framework above, say: \"I don't have [jurisdiction]'s confusion framework. Applying the US test would give you a wrong answer that looks right. Options: (a) I search for the applicable standard, (b) you route to a [jurisdiction] trademark specialist, (c) I note this jurisdiction is out of scope.\" Never silently apply US doctrine.\n\nThe relevant circuit's test determines the factors to walk through. Cite the\ntest that applies:\n\n- **TTAB / Federal Circuit:** *In re E. I. du Pont de Nemours & Co.*, 476 F.2d\n 1357 (C.C.P.A. 1973) (13 factors).\n- **Second Circuit:** *Polaroid Corp. v. Polarad Electronics Corp.*, 287 F.2d 492\n (2d Cir. 1961) (8 factors).\n- **Ninth Circuit:** *AMF Inc. v. Sleekcraft Boats*, 599 F.2d 341 (9th Cir. 1979)\n (8 factors).\n- **Other circuits:** walk through the circuit's named multi-factor test (e.g.,\n *Frisch's Restaurants* in the Sixth Circuit, *Scotch Whisky Association* in the\n Seventh, *Lapp* in the Third).\n\nPick based on where the user plans to enforce (practice profile), the TTAB if\nthe immediate forum is registration, or the primary commercial forum otherwise.\nNote your pick in the output.\n\nFor each factor, produce a **flag**, not a verdict. Each factor should say what\ncuts each way and where the uncertainty is:\n\n- **Similarity of marks** (appearance, sound, meaning / connotation, commercial\n impression). Sight-sound-meaning, considered together.\n- **Similarity of goods or services.** Not whether the goods are identical —\n whether consumers would expect them to come from the same source.\n- **Channels of trade.** Where each side actually sells (or would sell). Same\n stores? Same distribution? Same trade shows? Online-only?\n- **Sophistication of consumers.** Impulse buy at a gas station vs. considered\n enterprise purchase changes the standard of care.\n- **Strength of prior mark found.** Fanciful / arbitrary / suggestive /\n descriptive / generic, and fame evidence if any. A strong prior mark gets\n wider protection.\n- **Intent.** Evidence of intent to trade on goodwill — a near-copy with similar\n trade dress in an adjacent class is different from an independent coinage.\n- **Actual confusion.** Any evidence (misdirected inquiries, surveys, reviews,\n social posts).\n- **Likelihood of expansion** (bridge-the-gap). Whether the senior user is\n likely to expand into the junior's lane, and vice versa.\n\nPer the decision posture in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Never conclude \"not confusingly similar.\"**\n- If uncertain, write: \"Similar marks found — confusion assessment required\n before adoption.\" Or: \"Factors cut both ways; attorney judgment required.\"\n- Clear space for \"no similar marks found in the databases searched\" is fine\n *only* if a real search was run; see the no-search fallback above otherwise.\n\n---\n\n## Recommended next steps\n\nEvery clearance output ends with concrete next steps, bucketed by what the\ntriage found:\n\n- **If knockout issues found:** reframe the mark, or accept the descriptiveness\n bar and plan for secondary-meaning over time; route for attorney review before\n adopting.\n- **If similar marks found in the databases searched:** attorney review is\n required before adopting, filing, or marketing. Often the next step is a full\n professional search to find everything the triage missed.\n- **If no similar marks found but no database search ran:** a full search is\n required before adoption. Name the databases that need to be hit.\n- **If similar marks found and the senior mark is weak, old, in a different\n class, or abandoned:** flag for attorney review — the triage will not make\n this call.\n- **Always:** a full clearance opinion from registered trademark counsel, scaled\n to the investment the mark will carry. A mark you'll put on a product line and\n a Super Bowl ad carries more weight than a mark for a one-off pop-up.\n\n---\n\n## Output format\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`.\n\n```markdown\n[WORK-PRODUCT HEADER]\n\n# Trademark Clearance — First Pass (NOT AN OPINION)\n\n**This is a first pass, not a clearance opinion.** A clearance opinion requires\na full professional search and attorney judgment. A \"no obvious conflicts\"\nresult here means the triage didn't find anything — it does not mean the mark\nis clear. A registered trademark attorney evaluates before anyone adopts, files,\nor invests in this mark.\n\n**Triage result:** [GREEN / YELLOW / RED — one sentence why]\n\n## Proposed mark\n\n- **Mark:** [exact text, stylization noted]\n- **Mark type:** [word / design / composite]\n- **Goods / services:** [description]\n- **Classes:** [Nice class numbers with one-line descriptions]\n- **Jurisdictions:** [US / EU / UK / Madrid / specific countries]\n- **Confusion test applied:** [du Pont / Polaroid / Sleekcraft / other — with the\n reason it's the right one]\n\n## Knockout issues\n\n| Bar | Flag | Note |\n|---|---|---|\n| Generic / descriptive / deceptive / geographic / surname / false connection / prohibited / functional | [none / flagged] | [one line if flagged] |\n\n## Similar marks check\n\n**Sources searched:** [registries and databases hit, with dates — or \"no database\nsearch run; see scope note below.\"]\n**Scope:** [classes, jurisdictions, exact-vs-fuzzy, design search or not]\n\n**Adjacent families swept (confirmed with user):**\n- [family 1 — e.g., HUB / NEST / LINK / CONNECT / BRIDGE / GATEWAY]\n- [family 2 — e.g., ALEXA-style assistant names]\n- [family 3 — e.g., HOME / HOUSE / SMART variants]\n- [family 4 — phonetic twins on the root]\n\n*A clearance that only checks exact and near-exact matches misses the marks a\ncompetitor adopted because yours was taken. If any family was not swept (no\nconnector, time not available), it is listed explicitly as a next-step input\nto the full professional search — not silently skipped.*\n\n| Mark | Source | Classes / G&S | Owner | Status | First use | Note |\n|---|---|---|---|---|---|---|\n| [exact] | [registration no. / citation / URL] | [class list] | [owner from record] | [reg/pending/abandoned/cancelled] | [date or \"not available\"] | [why it matters — exact match / adjacent family] |\n\n*If no search was run:* **No database search was run.** This triage did not hit\nTESS, Solve Intelligence, Descrybe, CourtListener, state registries,\nMadrid/WIPO, or any common law / unregistered-mark sources. A knockout or full\nsearch across those databases is required before any conclusion about availability.\n\n## Confusion factors — flags for attorney review\n\nFor each of the factors under the test applied, a one-line flag noting what cuts\neach way.\n\n| Factor | Flag | Direction |\n|---|---|---|\n| Similarity of marks (sight / sound / meaning / commercial impression) | [note] | [weighs toward / against conflict / mixed] |\n| Similarity of goods or services | [note] | [direction] |\n| Channels of trade | [note] | [direction] |\n| Consumer sophistication | [note] | [direction] |\n| Strength of prior mark | [note] | [direction] |\n| Intent | [note] | [direction] |\n| Actual confusion | [note or \"no evidence surfaced\"] | [direction] |\n| Likelihood of expansion / bridge-the-gap | [note] | [direction] |\n\n**Conclusion on confusion:** *This skill does not conclude.* Either:\n- \"Similar marks found; attorney confusion assessment required before adoption.\"\n- \"No similar marks found in the databases searched; full clearance required\n before adoption.\"\n- \"Factors cut both ways; attorney judgment required.\"\n\n## Recommended next steps\n\n- [specific next step 1 — e.g., \"Full professional search across USPTO, state\n registries, common law sources, EUIPO, and UK IPO before adoption\"]\n- [specific next step 2 — e.g., \"Design-around review of the `APEXLEAF` mark\n in Class 25 if the intent is to proceed\"]\n- [specific next step 3 — e.g., \"Reframe the mark — current form is descriptive\n and will require secondary meaning\"]\n- [routing per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) —\n trademark OC or in-house IP counsel named in the practice profile]\n\n## Citation verification\n\nEvery case, registration number, statute, and database result in this memo must\nbe verified against the authoritative source before relying on it. Registration\nnumbers, class designations, and first-use dates are the most common sites of\nerror. Do not cite a result you cannot open.\n```\n\n---\n\n## Non-lawyer gate\n\nBefore issuing the output, read `## Who's using this`. If the Role is Non-lawyer:\n\n> This output is a research triage, not legal advice. Adopting, filing, or\n> investing in this mark based on this triage alone has legal consequences —\n> including being sued for infringement over a mark that \"passed\" this check.\n> A registered trademark attorney needs to evaluate before you move.\n>\n> Here's a brief to bring to an attorney — it'll cut the time the conversation\n> takes:\n>\n> [Generate a 1-page summary: the proposed mark, the goods/services and classes,\n> the knockout issues (if any), the similar marks surfaced (if any), what was\n> and wasn't searched, and the three questions to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent). The INTA (International Trademark Association)\n> maintains a member directory of registered trademark practitioners.\n\nDeliver the full triage memo alongside the brief. Do not withhold the analysis.\n\n---\n\n## Output location\n\nIf matter workspaces are enabled and a matter is active, write the output to\nthe current project's documents.\nOtherwise write to\nthe current project's documents\nand surface the path to the user.\n\nAppend a one-line entry to the matter's `history.md` if a matter is active.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Conclude a mark is clear.** Ever. The loudest guardrail in the plugin.\n- **Substitute for TESS search, state-registry search, common-law search,\n international search, watch-service check, or design-mark search.**\n- **File a trademark application.** Filing is an attorney task; this skill\n informs the decision to file.\n- **Evaluate trade dress, trademark dilution, or famous-mark claims** beyond a\n preliminary flag. Dilution under the TDRA requires a fame analysis this\n skill does not attempt.\n- **Address foreign local-law bars** (e.g., phonetic similarity standards in\n Japan, translation-of-foreign-equivalents in the EU) beyond flagging that\n foreign analysis is required when a foreign jurisdiction is in scope.\n- **Quote outputs to customers, counterparties, or the press.** This is\n internal research. Privileged if the header at the top applies.\n\n---\n\n## Tone\n\nCrisp, concrete, honest about scope. The lawyer reading this output should know\nin ten seconds what the triage found, what it didn't, and what has to happen\nbefore anyone adopts the mark. No hedging prose. The guardrail at the top and\nthe \"this skill does not conclude\" line on confusion do the scope work.", + }, + { + id: "builtin-cfl-ip-fto-triage", + title: "FTO Triage", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “fto-triage” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /fto-triage\n\n**This is not a freedom-to-operate opinion.** A formal FTO opinion requires a\ncomprehensive search, full claim construction, and element-by-element\ninfringement analysis by registered patent counsel. Patent infringement is\nstrict liability; willful infringement triples damages. A \"no obvious blocking\npatents\" result from this skill means the triage didn't find one — it does\nnot mean the product is clear.\n\n## Instructions\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If it\n contains `[PLACEHOLDER]`, stop and direct to `configure your Practice Profile (Account → Practice Profile)`.\n2. Follow the workflow below.\n3. Run intake (product/process, technical detail, jurisdictions, known patents,\n timing).\n4. Run a preliminary patent search if a connector is available (Solve\n Intelligence Patents, or other patent-research MCP). Otherwise say\n so in the output and proceed with the patents the user has supplied.\n5. For the 2–5 most plausible patents, build a claim-chart first pass against\n each independent claim — element by element. Literal read first; flag\n doctrine-of-equivalents separately; flag indirect / divided infringement.\n6. List open questions a real FTO study would resolve (enforceability,\n prosecution history, IPR outcomes, license availability, enforcement\n history of the assignee).\n7. Write the triage memo to the matter folder or practice outputs folder. Apply\n the work-product header per role.\n8. End with recommended next steps, a willfulness note (knowledge of specific\n patents factors into willfulness if the company proceeds without further\n counsel review), and the non-lawyer gate if the role is non-lawyer.\n\nThis skill never concludes that a product is clear to launch. If uncertain,\nflag — patent counsel decides.\n\n## Examples\n\n```\nthe “FTO Triage” workflow \"an on-device speech recognition model for consumer wearables, US launch first\"\n```\n\n```\nthe “FTO Triage” workflow\n```\n\n---\n\n## THIS IS NOT A FREEDOM-TO-OPERATE OPINION\n\n**The loudest guardrail in the plugin. Say this at the top of every output. Do\nnot drop it. Do not soften it. Do not let the reader skim past it.**\n\n> **This is not a freedom-to-operate opinion.** An FTO opinion is a professional\n> legal judgment, usually by registered patent counsel, based on a comprehensive\n> search, full claim construction, and an element-by-element infringement\n> analysis against each claim of each relevant patent. This triage is a\n> structured first look at what might be out there. A \"no obvious blocking\n> patents\" result means the triage didn't find one — it does not mean the\n> product is clear. Patent infringement is strict liability; willful\n> infringement (which can follow from knowing about a patent and proceeding\n> anyway) triples damages under 35 U.S.C. § 284. The decision to launch, make,\n> use, sell, or import is a business decision informed by a formal FTO study\n> and counsel's judgment — not by this triage. A registered patent attorney or\n> agent evaluates before anyone relies on this for a product decision.\n\nUnder-flagging a blocking patent is a one-way door — a product launched, a\ndeposition a year later, treble damages on the table. Over-flagging is a\ntwo-way door — the attorney narrows the list in a read-through. Stay on the\ntwo-way door side. Always.\n\n### A note on willfulness\n\nReading this triage is reading something about patents. Reading something about\npatents can, in some circumstances, factor into a willfulness analysis down the\nroad. This is one reason the output is marked as privileged when a lawyer is\nusing it, and why the non-lawyer output is framed as research to take to\ncounsel. Do not discuss specific patents surfaced by this triage outside\nprivileged channels.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\nPatent FTO matters are particularly common candidates for **clean-team** or\n**heightened** confidentiality at matter-open. Respect the matter's confidentiality\nmarking from `matter.md`.\n\n---\n\n## Load the practice profile first\n\nBefore running triage, read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Pull:\n\n- **Role** from `## Who's using this` (lawyer vs. non-lawyer changes the\n work-product header and the non-lawyer gate below).\n- **Registered in** and **enforce where** from `## IP practice profile` and\n `## Enforcement posture` (useful for defensive-portfolio cross-check and for\n jurisdiction defaults).\n- **Patent OC** from `## IP practice profile` → `Outside counsel roster` for\n the routing step.\n- **Integrations** from `## Available integrations` — specifically Solve\n Intelligence, or any patent-research MCP. Determines what searches\n are available.\n- **Decision posture** from `## Decision posture on subjective legal calls` —\n this skill never concludes \"does not infringe.\"\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) contains `[PLACEHOLDER]` or `[Your Company Name]`, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor posture, jurisdictions, and approval chain to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll run this tailored to YOUR practice.\n> - Say **\"provisional\"** and I'll run this against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" run the FTO triage normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction, no playbook (do the full analysis rather than matching against a position list). Tag the reviewer note and every finding block with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your playbook, your jurisdiction, your risk appetite. 2 minutes.\"\n\n---\n\n## Intake\n\nAsk in a single batch:\n\n> I'll run an FTO triage. A few questions first:\n>\n> 1. **Product, process, or feature.** What's being made, used, offered for\n> sale, sold, or imported? Describe it plainly — the technical essence, not\n> the marketing pitch.\n> 2. **Technical detail.** Any architectural diagrams, claim-relevant specs, a\n> public product page, or a spec document you can share? (The more detail,\n> the more real the triage.)\n> 3. **Jurisdictions.** Where will it be made, used, sold, offered for sale,\n> imported? (Each is a separate infringing act under 35 U.S.C. § 271. I'll\n> default to the US if you don't specify.)\n> 4. **Known patents.** Are there patents already on your radar — a competitor's\n> portfolio, a known SEP pool, an NPE letter, something an engineer\n> mentioned?\n> 5. **Timing.** How close is this to launch? If it's months out, the triage\n> is early and design-around is on the table. If it's already shipping,\n> we're in cover-our-downside mode.\n\nWait for the answer. If the description is vague (\"an AI agent,\" \"a database\"),\npush once:\n\n> Give me the technical essence — what does the thing do, how does it do it,\n> and what's the piece you think might be novel? Patent claims live at that\n> level.\n\n---\n\n## Scope — utility patents only\n\n**This skill analyzes utility patents.** If a patent on the radar has a `D`,\n`RE`, or `PP` prefix, flag it and route out, do not claim-chart it:\n\n- **`D` (design patent).** Different test entirely — ordinary observer under\n *Egyptian Goddess, Inc. v. Swisa, Inc.*, 543 F.3d 665 (Fed. Cir. 2008) (en\n banc), overall ornamental appearance, no claim chart. Route to the\n `infringement-triage` design patent branch and to design patent counsel.\n **Design patents are not analyzed in this FTO triage** — a design-patent\n overlap must be flagged as a separate workstream.\n- **`RE` (reissue).** Treat as a utility patent with added §252 intervening-\n rights and recapture-rule flags.\n- **`PP` (plant patent).** Route to plant-patent counsel; out of scope.\n\nAlso cross-flag **trade dress**: if the product's appearance is the risk,\nthe same facts may be a §43(a) product-configuration claim that requires\nsecondary meaning (*Wal-Mart Stores, Inc. v. Samara Bros., Inc.*, 529 U.S.\n205 (2000)) and non-functionality (*TrafFix Devices, Inc. v. Marketing\nDisplays, Inc.*, 532 U.S. 23 (2001)). Flag as a parallel track.\n\n---\n\n## Search\n\n### What the user has connected\n\nRead `## Available integrations`:\n\n- **Solve Intelligence connected:** run a preliminary search across the\n technical description. Note the date of the search, the query used, the\n jurisdictions covered, and any date window (current in-force patents; recent\n published applications).\n- **Patent-research MCP (Google Patents Public Datasets, PatSnap\n export): available:** use it.\n- **None of the above:** explicitly say so. Do not infer patents from model\n knowledge and present them as search results.\n\n### Fallback when no patent database is connected\n\nWrite this exact statement in the output:\n\n> **No patent database search was run.** This triage did not hit Solve\n> Intelligence Patents, USPTO Patents Full-Text, EPO Espacenet,\n> Google Patents, PatSnap, or any other patent corpus. A structured search\n> across the jurisdictions in scope is required before relying on this triage\n> for any launch decision. The analysis below is limited to patents and\n> applications the user has named or that come up in the conversation.\n\nThen proceed. The claim-chart-first-pass work below is still valuable — just\nlabel the scope honestly.\n\n### Supplementary signals (not a substitute)\n\nIf available and the user allows, sweep for non-patent signals that flag a\npatent concern:\n\n- **Competitor patent filings** around the product area.\n- **Known NPE targeting** of the technology class (e.g., network-coding NPEs in\n Eastern District of Texas / Delaware / Western District of Texas).\n- **Standards-essential declarations** (IEEE, ETSI, 3GPP) if the product touches\n a relevant standard.\n- **Reported litigation** in the technology space (CourtListener / RECAP, Unified\n Patents, Lex Machina).\n\nEach signal is a reason to look harder, not a patent hit. Mark them as signals\nin the output, not as identified patents.\n\n---\n\n## For each relevant patent found or supplied\n\nCapture:\n\n- **Patent number** (with application number if different) and **jurisdiction**\n- **Title**\n- **Assignee and inventors**\n- **Priority date and issue date**\n- **Expiration date** (per USPTO PAIR / PatentCenter / foreign equivalent —\n check term adjustments, term extensions, and terminal disclaimers)\n- **Maintenance fee status / in-force status** — if a US patent has failed a\n 3.5/7.5/11.5-year maintenance fee, it's expired and not a bar\n- **Claim count — independent and dependent**\n- **Independent claims as issued** (and any relevant amended claims from\n post-grant proceedings)\n- **Related proceedings** — IPRs, PGRs, reexaminations, litigation history,\n PTAB outcomes\n- **File wrapper highlights** — prosecution disclaimers, amendments that\n narrowed the claims, statements about scope\n\n**Do not supplement silently.** If a search surfaces a patent, attribute the\nresult. If the user mentioned a patent, say that. Never invent a patent\nnumber, never \"fill in\" a claim element the file doesn't support, never\nimagine an expiration date. If maintenance fee status isn't available, write\n\"maintenance fee status not verified from search result — confirm in PAIR\nbefore relying on in-force status.\"\n\n---\n\n## Claim-chart first pass\n\nThis is the core of the triage. Pick the patents with the most plausible read\non the product — usually the 2–5 with the closest technical mapping — and walk\neach independent claim element-by-element.\n\n**For each selected patent, write out one claim chart per independent claim:**\n\n| Claim element | Does the product practice this? | Basis |\n|---|---|---|\n| \"A [preamble phrase]\" | [yes / no / possibly / depends on construction] | [one sentence — what in the product maps; what doesn't; what's ambiguous] |\n| \"comprising [element 1]\" | [yes / no / possibly] | [mapping or gap] |\n| \"wherein [element 2]\" | [yes / no / possibly] | [mapping or gap] |\n| [continue for every element] | | |\n\n**Rules for the chart:**\n\n- **Every element matters.** A claim is infringed only if the accused product\n practices every element of at least one claim (all-elements rule). Missing one\n element literally means no literal infringement on that claim. Do not skip.\n- **Doctrine of equivalents is a separate pass.** First chart literal\n infringement. Then, for any \"no\" elements, note whether a DOE read is\n plausible (insubstantial differences / function-way-result). Flag DOE\n analysis as requiring attorney judgment — prosecution history estoppel and\n claim vitiation are common bars and the triage does not adjudicate them.\n- **Claim construction is the attorney's job.** Where a term could be\n construed narrowly or broadly and the answer changes the infringement read,\n flag the term and note both constructions. Do not pick one silently.\n- **Indirect infringement (induced, contributory) and divided infringement**\n are flags only. Do not attempt a full analysis; note that these may apply and\n require patent counsel.\n\n> **Patent systems differ by jurisdiction.** The US claim chart (all-elements rule, doctrine of equivalents, prosecution history estoppel, §284/§289 damages) does not transfer to other systems:\n> - **Germany:** Utility models (Gebrauchsmuster), the Schneidmesser/Kunststoffrohrteil questions for DOE, bifurcated validity/infringement proceedings.\n> - **China:** Utility models (shiyong xinxing), CNIPA examination, different claim construction.\n> - **Japan:** Utility models, JPO examination, a narrower DOE.\n> - **Europe (unified patent court):** UPC procedure as of 2023.\n>\n> When non-US jurisdictions are in scope: \"This analysis uses the US claim-charting framework. A product manufactured in China and sold in the EU needs CNIPA and EP analysis, not a US claim chart. I can flag the issues a US analysis surfaces, but the infringement and validity calls require [jurisdiction]-specific review.\"\n\n**Decision posture:** per the practice profile, this skill never concludes \"no\ninfringement.\" Either:\n\n- \"Product practices every element of Claim X as written; attorney review\n required before proceeding.\"\n- \"One or more elements are not clearly present; attorney review required to\n assess literal infringement and doctrine of equivalents.\"\n- \"Claim construction is dispositive on element [Y]; attorney construction\n required before proceeding.\"\n\n---\n\n## Open questions\n\nEvery patent surfaced in the triage should produce a list of open questions\nthat a real FTO study would answer. Examples:\n\n- Is the patent enforceable — has the assignee been named, any standing issues,\n any inventorship defects, any recorded assignments?\n- What did the applicant say about term [X] in prosecution, and does that\n limit the claim?\n- Has this claim been the subject of an IPR or reexamination — what did the\n PTAB say about scope or validity?\n- Is there a license already available (standards pool, patent marking, open\n patent non-assertion commitment)?\n- What's the real-world enforcement history of this assignee?\n\nList them plainly.\n\n---\n\n## Recommended next steps\n\nBucket by what the triage found:\n\n- **If every element of an independent claim maps to the product (literal read):**\n *Stop and get patent counsel.* Options typically include formal FTO opinion,\n design-around, license, challenge validity (IPR/PGR), or (rarely) proceed at\n risk. The choice is a business decision informed by counsel.\n- **If elements cut both ways or claim construction is dispositive:**\n Full FTO study by registered patent counsel. Do not launch on this triage.\n- **If the patent appears expired, abandoned, or unenforceable:** Attorney\n confirms the in-force status — the triage does not.\n- **If no patents were identified in the search but no database access\n existed:** Formal search is the next step, not a launch decision.\n- **Always:** flag a willfulness risk. If the triage surfaces a specific\n patent, the company now has knowledge of it. Proceeding without further\n analysis can support a willfulness finding. Counsel should document the\n path forward.\n\n---\n\n## Output format\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Mark the document as privileged if the role is lawyer; see the non-lawyer gate below if not.\n\n```markdown\n[WORK-PRODUCT HEADER]\n\n# FTO Triage — First Pass (NOT AN OPINION)\n\n**This is not a freedom-to-operate opinion.** A formal FTO opinion requires a\ncomprehensive search, full claim construction, and element-by-element\ninfringement analysis by registered patent counsel. Patent infringement is\nstrict liability; willful infringement triples damages. A \"no obvious blocking\npatents\" result means the triage didn't find one — it does not mean the product\nis clear. A registered patent attorney or agent evaluates before anyone relies\non this for a product decision.\n\n**Triage result:** [GREEN / YELLOW / RED — one sentence why]\n\n## Subject\n\n- **Product / process / feature:** [description, technical essence]\n- **Technical detail relied on:** [what was reviewed — spec, diagram, public\n page, code, engineer's description]\n- **Jurisdictions in scope:** [make / use / sell / offer / import — per § 271]\n- **Timing:** [pre-launch / near-launch / shipping]\n\n## Search scope\n\n- **Databases searched:** [Solve Intelligence / Google Patents /\n Espacenet / PatSnap — or \"no database search run\"]\n- **Query / approach:** [query text, technology classes, keywords, classifications]\n- **Date / date window:** [search date; in-force patents + applications\n published since YYYY-MM-DD]\n- **Jurisdictions covered by the search:** [list]\n- **What wasn't searched:** [named-assignee sweeps, SEP declarations, NPE\n portfolios, design patents, foreign equivalents — as applicable]\n\n*If no database search was run:* **No patent database search was run.** This\ntriage did not hit Solve Intelligence Patents, USPTO Patents Full-Text,\nEPO Espacenet, Google Patents, PatSnap, or any other patent corpus. A\nstructured search across the jurisdictions in scope is required before\nrelying on this triage for any launch decision.\n\n## Patents identified\n\n| Patent | Jurisdiction | Assignee | Priority / Issue | Expiration | In-force? | Source |\n|---|---|---|---|---|---|---|\n| [number] | [US/EP/...] | [assignee] | [dates] | [date] | [yes/no/unverified] | [search result link or \"user-supplied\"] |\n\n## Claim charts — first pass\n\n### [Patent number] — independent Claim [N]\n\n> \"[Exact text of Claim N]\"\n\n| Element | Practiced by the product? | Basis |\n|---|---|---|\n| [element 1] | [yes/no/possibly] | [mapping or gap] |\n| [element 2] | [yes/no/possibly] | [mapping or gap] |\n\n**Literal read:** [every element maps / one or more elements do not clearly\nmap / claim construction is dispositive on element [Y]]\n\n**Doctrine of equivalents (flag only):** [DOE read plausible on element [Y] —\nattorney construction required / not plausible on the surfaced elements /\nprosecution history suggests estoppel]\n\n**Indirect / divided infringement (flag only):** [note if any read depends on\ninduced, contributory, or divided infringement theories — attorney analysis\nrequired]\n\n*(Repeat for each independent claim of each selected patent.)*\n\n## Open questions\n\n- [question 1]\n- [question 2]\n\n## Signals (not confirmed patents)\n\n- [competitor filings / NPE activity / SEP declarations / litigation in the\n technology space — each a reason to search harder, not an identified patent]\n\n## Recommended next steps\n\n- [full FTO study by patent counsel — first-line recommendation unless the\n search found nothing and comprehensive search already ran]\n- [design-around options if a literal read was found]\n- [license / IPR / PGR / at-risk analysis as counsel directs]\n- [routing per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) —\n patent OC named in the practice profile]\n\n## Willfulness note\n\nThis triage surfaces specific patents. Proceeding with the product without\nfurther counsel review after this knowledge can support a willfulness finding\nand enhanced damages under § 284. The path forward should be documented by\npatent counsel; the business decision to launch, design around, or license is\ninformed by a formal FTO opinion and counsel's judgment, not by this triage.\n\n## Citation verification\n\nEvery patent number, claim quote, date, and prosecution fact in this memo must\nbe verified against the authoritative source (USPTO PatentCenter / PAIR, EPO\nregister, national equivalent) before relying on it. Claim quotes are the\nmost common error site — a single word changes the analysis. Do not cite a\nresult you cannot open.\n```\n\n---\n\n## Non-lawyer gate\n\nBefore issuing the output, read `## Who's using this`. If the Role is Non-lawyer:\n\n> This output is a research triage, not legal advice. Launching, continuing to\n> sell, or investing in this product based on this triage alone has legal\n> consequences — including strict liability for patent infringement, with\n> enhanced damages for willfulness. Patent counsel needs to evaluate before\n> you move.\n>\n> Here's a brief to bring to an attorney — it'll cut the time the conversation\n> takes:\n>\n> [Generate a 1-page summary: the product description, the jurisdictions in\n> scope, the search run (and what wasn't searched), the patents surfaced and\n> the claim-chart-first-pass reads, the open questions, and the three\n> questions to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: for US patent work, a registered patent attorney or patent agent is required (not every lawyer is registered — the USPTO\n> Office of Enrollment and Discipline maintains a directory). For other jurisdictions, use the relevant patent office register (EPO, UK IPO, etc.). Your professional regulator's referral service is a starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent); specifically ask for registered\n> patent counsel.\n\nDeliver the full triage memo alongside the brief. Do not withhold the analysis.\nFlag that the triage itself is a privileged research document and should not\nbe forwarded to non-attorney third parties.\n\n---\n\n## Output location\n\nIf matter workspaces are enabled and a matter is active, write the output to\nthe current project's documents.\nOtherwise write to\nthe current project's documents\nand surface the path.\n\nAppend a one-line entry to the matter's `history.md` if a matter is active.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Issue an FTO opinion.** Ever. The loudest guardrail in the plugin.\n- **Construe claims.** Where construction is dispositive, it flags the term and\n both plausible constructions. It does not pick one.\n- **Adjudicate validity.** It may note known PTAB proceedings; it does not\n opine on novelty, obviousness, § 112, § 101, or enablement.\n- **Draft patent claims.** This plugin does not go there; route to prosecution\n counsel.\n- **Assess damages exposure.** Damages modeling is an expert's job.\n- **Handle trade-secret or trademark analysis** — use `the “Infringement Triage” workflow`\n with the right mode.\n- **Quote outputs to counterparties or non-privileged audiences.** This is a\n privileged research document.\n\n---\n\n## Tone\n\nTechnically precise. Element-by-element. Every flag is specific to a claim\nelement or a known patent. No hedging prose in the body — the guardrails at\nthe top and bottom do the scope work, and the analysis does the analysis. The\nreader should leave knowing what the triage looked at, what it didn't, and\nwhat the next step is.", + }, + { + id: "builtin-cfl-ip-infringement-triage", + title: "Infringement Triage", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “infringement-triage” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /infringement-triage\n\n**This is a triage, not a finding of infringement or non-infringement.**\nInfringement analysis is fact-intensive and legally complex. Acting on a\ntriage — sending a cease-and-desist, refusing to stop, filing suit, or\ndeciding not to — without attorney review is how companies end up on the\nwrong side of fee awards, Rule 11 sanctions, declaratory-judgment actions,\nand (for patents) treble damages.\n\n## Instructions\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If it\n contains `[PLACEHOLDER]`, stop and direct to `configure your Practice Profile (Account → Practice Profile)`.\n2. Follow the workflow below.\n3. Ask which right is at issue — trademark / copyright / patent / trade secret\n / mixed. If mixed, run each separately; do not blend.\n4. Run common intake (party posture — senior or accused, jurisdiction, timing,\n exhibits).\n5. Walk the mode-specific factors:\n - **Trademark** — circuit's confusion test + dilution (if famous) +\n false advertising (if a comparative claim).\n - **Copyright** — ownership + registration + access + substantial\n similarity + fair use + DMCA safe harbor (if applicable).\n - **Patent** — claim-chart first pass (route to `fto-triage` output\n structure); literal + DOE; indirect + divided; invalidity defenses to\n consider.\n - **Trade secret** — secrecy + reasonable measures + misappropriation;\n preemption + reverse-engineering flags.\n6. Produce a flag list with direction — what cuts toward the senior party,\n what cuts toward the accused, what's mixed. Never conclude.\n7. Write the triage memo to the matter folder or practice outputs folder. Apply\n the work-product header per role.\n8. End with recommended next steps, the non-lawyer gate if the role is\n non-lawyer, and — if the practice posture supports assertion — an offer to\n draft the C&D via `the “Cease Desist” workflow` or the takedown via\n `the “Takedown” workflow`. Do not draft automatically.\n\nThis skill never concludes. If uncertain, flag — the attorney decides.\n\n## Examples\n\n```\nthe “Infringement Triage” workflow \"competitor launched a tool called APEXSEED in class 9 — we have APEXLEAF registered in class 9; likely confusion?\"\n```\n\n```\nthe “Infringement Triage” workflow \"former engineer took notes on our model architecture to a competitor — possible trade secret?\"\n```\n\n```\nthe “Infringement Triage” workflow\n```\n\n(And the skill will ask which right and for the facts.)\n\n---\n\n## THIS IS A TRIAGE, NOT A FINDING\n\n**The loudest guardrail in the plugin. Say this at the top of every output. Do\nnot drop it. Do not soften it.**\n\n> **This is a triage, not a finding of infringement or non-infringement.**\n> Infringement analysis is fact-intensive and legally complex. The triage\n> identifies the factors and flags the ones that matter most; it does not\n> conclude. A conclusion that something does or does not infringe is a legal\n> opinion that requires an attorney's judgment on the facts, the claim or\n> right scope, the relevant jurisdiction's law, and the likely defenses.\n> Acting on a triage — sending a cease-and-desist, refusing to stop, filing\n> suit, or deciding not to — without attorney review is how companies end up\n> on the wrong side of fee awards, Rule 11 sanctions, declaratory-judgment\n> actions, and (for patents) treble damages.\n\nUnder-calling a conflict is a one-way door — a C&D not sent and a mark goes\ngeneric in the market; a claim not chased and the statute of limitations runs;\na copied copyrighted work kept on the site. Over-calling is a two-way door —\nthe attorney narrows. Stay on the two-way door side.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\nInfringement triages often lead into cease-and-desist drafting or takedown\nrouting. Open a matter if one isn't active and the practice is private — the\ntriage, the C&D, and any downstream response belong in one workspace.\n\n---\n\n## Load the practice profile first\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Pull:\n\n- **Role** from `## Who's using this`.\n- **Enforcement posture** from `## Enforcement posture` — the triage output\n should end with a routing suggestion consistent with the stated posture\n (aggressive / measured / conservative) and the named approver for the\n relevant letter type.\n- **Registered in / enforce where** from `## IP practice profile` — determines\n which circuit / jurisdiction test to apply by default.\n- **Integrations** from `## Available integrations` — CourtListener,\n Solve Intelligence each affects whether the triage can cite to case law,\n prior rulings, or prior art.\n- **Decision posture** from `## Decision posture on subjective legal calls` —\n this skill never concludes on a subjective threshold.\n\nIf the config has `[PLACEHOLDER]`, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor posture, jurisdictions, and approval chain to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll run this tailored to YOUR practice.\n> - Say **\"provisional\"** and I'll run this against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" run the infringement triage normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction, no playbook (do the full analysis rather than matching against a position list). Tag the reviewer note and every finding block with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your playbook, your jurisdiction, your risk appetite. 2 minutes.\"\n\n---\n\n## Mode selection\n\nAsk at the top, before anything else:\n\n> Which right are we triaging?\n>\n> 1. **Trademark** — confusion, dilution, or false advertising\n> 2. **Copyright** — substantial similarity, fair use, DMCA safe harbor\n> 3. **Patent** — claim-chart first pass, literal read + doctrine of equivalents\n> 4. **Trade secret** — secrecy, reasonable measures, misappropriation\n> 5. **Mixed / not sure** — describe the facts and I'll pick\n\nIf the user picks \"not sure,\" help them sort. The same facts can implicate\nmultiple rights (e.g., a competitor's product uses our logo — trademark; and\nthe product is a near-copy of ours — possible patent, copyright on packaging,\npossible trade dress; and a former employee launched it — trade secret).\n\n**If more than one right is in play, run the triage for each, separately.**\nDon't mash them together. Each right has different factors, different\njurisdictional rules, and different remedies.\n\n---\n\n## Intake (common to all modes)\n\n> Before I walk factors:\n>\n> 1. **Posture.** Are you the potentially senior party (they're taking\n> yours) or the potentially accused party (we're the ones being looked at)?\n> The factors are symmetric but the output differs — a \"mine's being\n> copied\" triage routes toward an assertion letter; a \"we might be\n> exposed\" triage routes toward a risk memo.\n> 2. **Jurisdiction.** Which country / circuit / court? US federal default if\n> not specified. Flag if foreign law may apply.\n> 3. **Timing.** Is a statute of limitations or laches clock running?\n> 4. **What exhibits / evidence / source documents do you have?** A screenshot,\n> a URL, a packaging photo, a code excerpt, an ex-employee contract.\n\nWait for the answer before walking factors.\n\n---\n\n## Trademark mode\n\n### Confusion\n\nUse the applicable circuit's multi-factor test. Cite the test (du Pont /\nPolaroid / Sleekcraft / other — see the `clearance` skill for the case\ncitations and pick logic). Walk each factor and flag what cuts each way.\n\n- **Similarity of marks** — sight / sound / meaning / commercial impression.\n- **Similarity of goods or services** — expected-source test, not identity.\n- **Channels of trade.**\n- **Consumer sophistication.**\n- **Strength of the senior mark** — fanciful / arbitrary / suggestive /\n descriptive with secondary meaning / generic.\n- **Intent** — evidence of copying, knock-off trade dress, near-miss mark.\n- **Actual confusion** — any evidence (surveys, misdirected inquiries, social).\n- **Likelihood of expansion / bridge-the-gap** — whether the zones overlap\n commercially.\n\n### Dilution\n\nApply the federal TDRA (15 U.S.C. § 1125(c)) and any applicable state statute.\n\n- **Fame threshold.** The senior mark must be famous to the general consuming\n public — a niche-famous mark is not enough. *Starbucks Corp. v. Wolfe's\n Borough Coffee, Inc.*, 588 F.3d 97 (2d Cir. 2009) is representative.\n- **Blurring vs. tarnishment.** Blurring = distinctiveness harm; tarnishment\n = reputation harm.\n- **Defenses** — comparative advertising, news reporting, fair use,\n non-commercial use.\n\nIf the senior mark is not plainly famous nationally, flag dilution as a\nstretch.\n\n### False advertising / comparative claims\n\nIf the triage is prompted by a competitor's comparative ad or a claim about\nproduct attributes:\n\n- Apply Lanham Act § 43(a) / 15 U.S.C. § 1125(a) for the materiality,\n falsity-or-misleading, deception, commercial-speech, and injury elements.\n- Flag whether the statement is literally false, implicitly false, or\n puffery. Puffery is not actionable.\n- Substantiation evidence the claimant has or needs.\n\n### Output\n\nFactors table; what cuts each way; a \"not a finding\" conclusion line. End with\na routing suggestion against the enforcement posture in the practice profile.\n\n---\n\n## Copyright mode\n\n### Ownership\n\nIs the claimant the owner (or exclusive licensee with standing)? Work-for-hire\nissues; joint authorship; assignments; and termination rights all flag.\n\n### Registration\n\n17 U.S.C. § 411 requires registration (or preregistration) as a precondition\nto filing an infringement action in US federal court. *Fourth Estate Public\nBenefit Corp. v. Wall-Street.com, LLC*, 586 U.S. 296 (2019) — registration\nmeans actually issued, not just applied for. Flag registration status; if\nnot registered, flag the practical bar on filing.\n\n### Access + substantial similarity\n\nTwo paths to proving copying:\n\n- **Access + probative similarity** — defendant had access and the works share\n features probative of copying.\n- **Striking similarity** — even absent proof of access, the similarity is so\n striking that independent creation is unlikely.\n\nFor substantial similarity, apply the circuit's test (Second Circuit's\nordinary-observer; Ninth Circuit's extrinsic / intrinsic under *Krofft* and\n*Swirsky*; Fourth / Seventh / Eleventh circuits' variations). Flag which\ntest applies.\n\n### Fair use\n\n17 U.S.C. § 107 four factors, analyzed as a whole:\n\n1. Purpose and character of the use (transformativeness; commercial vs.\n non-commercial).\n2. Nature of the copyrighted work (factual / functional vs. creative).\n3. Amount and substantiality of the portion used.\n4. Effect on the market for the original.\n\nRecent touchstones: *Google LLC v. Oracle America, Inc.*, 593 U.S. 1 (2021);\n*Andy Warhol Found. for the Visual Arts, Inc. v. Goldsmith*, 598 U.S. 508\n(2023). Flag the transformativeness analysis carefully — *Warhol* narrowed\nthe scope of transformative use and is still being applied by lower courts.\n\n### DMCA safe harbor\n\n17 U.S.C. § 512. If the accused is a service provider hosting user content,\nflag whether § 512(c) applies: designated agent, notice-and-takedown\nprocedure, no actual or red-flag knowledge, no financial benefit\nattributable to infringement the provider could control, expeditious\ntakedown on valid notice. Repeat-infringer policy required. Safe harbor does\nnot cover direct infringement by the service provider itself.\n\n### Output\n\nFactors flagged; fair-use balance with \"the triage does not conclude\";\nownership / registration / safe-harbor threshold notes. Routing per posture.\n\n---\n\n## Patent mode\n\n**Route to `the “FTO Triage” workflow` for the detailed framework.** This mode is the\nmirror image of the FTO skill — same claim charts, same doctrine-of-equivalents\nflag, same all-elements rule — applied to an accused product instead of one's\nown.\n\n### Design patent (D-number) — branch before the workflow\n\n**Check the asserted patent's registration number FIRST.** If it has a `D`,\n`RE`, or `PP` prefix (e.g., `D712,345`), it's not a utility patent and the\nworkflow below does NOT apply. Branch per prefix:\n\n- **`D` prefix — design patent (35 U.S.C. §171).** Different test, different\n claim structure, different damages. Do NOT build a claim chart, do NOT run\n doctrine of equivalents, do NOT do element-by-element mapping. Design\n patents have a single claim defined by the drawings; charting a figure as\n if it were a utility claim element list is wrong doctrine.\n- **`RE` prefix — reissue patent.** Treat as the utility patent it reissued,\n but flag reissue-specific defenses (intervening rights under §252,\n recapture rule, original-patent requirement).\n- **`PP` prefix — plant patent.** Separate regime (35 U.S.C. §161). Asexually\n reproduced plant varieties. Route to plant-patent counsel; this skill does\n not analyze plant patents.\n\n**Design patent infringement test — ordinary observer.** *Egyptian Goddess,\nInc. v. Swisa, Inc.*, 543 F.3d 665 (Fed. Cir. 2008) (en banc). The question\nis whether an ordinary observer, **familiar with the prior art designs**,\nwould be deceived into thinking the accused design is the same as the\npatented design. Compare **overall ornamental appearance**, not individual\nelements. The accused product must appropriate the **novelty** that\ndistinguishes the patented design from the prior art (the \"point of novelty\"\nsurvives as a guidepost inside the ordinary-observer test, not as a separate\ntest).\n\n**Functional-vs-ornamental filter.** Design patents protect ornamental\nfeatures only; functional features are not protected. If the accused\nsimilarity is in features dictated by function, flag that the overlap may\nfall outside the patented scope.\n\n**§289 total-profit damages flag.** Design patent damages under 35 U.S.C.\n§289 are the infringer's **total profits on the \"article of manufacture,\"**\nwhich can be the whole product or a component. *Samsung Electronics Co. v.\nApple Inc.*, 580 U.S. 53 (2016). This is a separate analysis from utility\npatent reasonable-royalty / lost-profits and is specialist work — do not\ncompute.\n\n**Trade dress cross-flag.** The same ornamental-shape facts are usually also\na **trade dress** question under Lanham Act §43(a) (15 U.S.C. §1125(a)).\nProduct configuration trade dress requires **secondary meaning** (*Wal-Mart\nStores, Inc. v. Samara Bros., Inc.*, 529 U.S. 205 (2000)) and must be\n**non-functional** (*TrafFix Devices, Inc. v. Marketing Displays, Inc.*,\n532 U.S. 23 (2001)). Flag trade dress as a parallel track; the tests are\ndifferent but the evidence overlaps.\n\n### Design patent triage — output\n\nBecause you cannot see the patent drawings or the accused product directly,\nthe design patent triage is mostly a request for the materials and a frame\nfor the analysis:\n\n- **Ask for the drawings.** \"I can't run the ordinary-observer test without\n seeing the patent figures and the accused product. Paste or attach: (a)\n the patent drawings (all figures, including any broken-line disclaimers),\n (b) photos of the accused product from comparable angles, (c) any prior\n art designs you're aware of.\"\n- **Prior-art landscape.** Ordinary observer is a *comparison* test — the\n observer is \"familiar with the prior art,\" so the scope of the patented\n design narrows as the prior-art field crowds. Flag what prior art is\n known and what's missing.\n- **Functional-vs-ornamental analysis.** Walk the features and flag which\n look functional (and therefore unprotected) vs. ornamental.\n- **Broken lines.** Design patents use solid lines for claimed features and\n broken lines for unclaimed environmental context. Flag whether the\n alleged copying is in claimed (solid-line) or unclaimed (broken-line)\n territory.\n- **§289 damages flag** as above.\n- **Trade dress cross-flag** as above.\n\n**Route to a design patent specialist for anything beyond first-pass triage.**\nDesign patent litigation is a subspecialty (Perkins Coie, Sterne Kessler,\nDesmarais, Kirkland's design team, Gibson Dunn's design group are\nrepresentative; use your practice profile's IP litigation OC as the starting\npoint). This skill flags issues; it does not assess infringement.\n\n### Utility patent workflow\n\nThe rest of this mode assumes the asserted patent is a **utility patent**\n(no `D`/`RE`/`PP` prefix). If the D-number branch above applies, stop here.\n\n> **Patent systems differ by jurisdiction.** The US claim chart (all-elements rule, doctrine of equivalents, prosecution history estoppel, §284/§289 damages) does not transfer to other systems:\n> - **Germany:** Utility models (Gebrauchsmuster), the Schneidmesser/Kunststoffrohrteil questions for DOE, bifurcated validity/infringement proceedings.\n> - **China:** Utility models (shiyong xinxing), CNIPA examination, different claim construction.\n> - **Japan:** Utility models, JPO examination, a narrower DOE.\n> - **Europe (unified patent court):** UPC procedure as of 2023.\n>\n> When non-US jurisdictions are in scope: \"This analysis uses the US claim-charting framework. A product manufactured in China and sold in the EU needs CNIPA and EP analysis, not a US claim chart. I can flag the issues a US analysis surfaces, but the infringement and validity calls require [jurisdiction]-specific review.\"\n\n### Workflow\n\n- Accused product / process / method — described in technical detail.\n- Identified patent(s) at issue.\n- Claim chart for each independent claim: element-by-element mapping to the\n accused product.\n- Literal infringement first. DOE as a flag.\n- Indirect (induced, contributory) and divided infringement as flags.\n- **Invalidity defenses to consider** — anticipation (§ 102), obviousness\n (§ 103), § 112 written-description / enablement / definiteness, § 101\n subject-matter eligibility (*Alice* / *Mayo*). Known IPR or PGR outcomes,\n known prior art, known prosecution history. Flag each; do not opine.\n- **Unenforceability defenses** — inequitable conduct flag, prosecution\n laches flag, assignor / licensee estoppel flag. Each is attorney-only.\n- **Damages posture** — lost profits vs. reasonable royalty (Georgia-Pacific\n factors), marking, pre-suit notice, willfulness (reading this triage may\n factor into willfulness — see the FTO skill's willfulness note).\n\n### Output\n\nClaim charts. Element flags. Defense flags. Routing to patent counsel. See\nthe `fto-triage` skill for the full output structure — the infringement-triage\npatent mode uses the same format with \"accused product\" substituted for\n\"own product.\"\n\n### Handoff to the full claim chart\n\nFor a detailed element-by-element claim chart suitable for infringement or\ninvalidity contentions, run `the “Claim Chart” workflow`. This triage's\nclaim chart is a first pass to identify the strongest and weakest mappings;\nthe litigation claim chart builds the full chart with pin cites, claim\nconstruction flags, dependent claims, and the verification workflow that\ncontentions require.\n\n---\n\n## Trade secret mode\n\n### Was it a secret?\n\nApply the Defend Trade Secrets Act (18 U.S.C. § 1836 et seq.) for federal\npurposes and the applicable state UTSA (or, in New York / Massachusetts /\nother non-UTSA jurisdictions, the state's common-law test). Flag:\n\n- **Not generally known** — to the public or to others in the industry who can\n obtain economic value from disclosure.\n- **Economic value from secrecy** — independent economic value actual or\n potential, derived from not being generally known.\n- **Combinations and compilations** — a combination of public elements can\n be a trade secret (*Altavion v. Konica Minolta*, and the Restatement view).\n\n### Reasonable measures\n\n- NDAs with employees, contractors, counterparties. Scope, signed, enforced?\n- Access controls — technical (role-based), physical (doors, badges),\n organizational (need-to-know).\n- Marking — confidentiality legends on documents, code, data.\n- Exit interviews / return of materials on termination.\n- Trade-secret policy / training.\n\nFlag what's in place and what's missing. *Reasonable* is fact-specific; the\ntriage does not decide whether the measures were reasonable — it lists them.\n\n### Misappropriation\n\nAcquisition by improper means, or disclosure / use in breach of duty.\nImproper means includes theft, bribery, misrepresentation, breach or\ninducement of breach of a duty to maintain secrecy, or espionage (electronic\nor otherwise). 18 U.S.C. § 1839(6).\n\n- **Former employee fact pattern:** new employer, overlapping work,\n departure timing, documents taken (and returned?), access logs, recruiting\n channels, assignment and invention-assignment agreements.\n- **Inadvertent disclosure:** Was disclosure made by a person with a duty? Did\n the recipient know or have reason to know of the breach?\n- **Reverse engineering** — a defense if the means were lawful. Flag whether\n reverse engineering is plausible on the facts.\n\n### Preemption\n\nWhere state tort claims (unfair competition, conversion, breach of confidence)\nmight be preempted by the UTSA, flag preemption. Some jurisdictions preserve\ncontract claims; others preempt most tort claims addressing the same facts.\n\n### Output\n\nThree flag groups — secrecy, measures, misappropriation — each with what cuts\neach way. Routing per posture.\n\n---\n\n## Output format (all modes)\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`.\n\n```markdown\n[WORK-PRODUCT HEADER]\n\n# Infringement Triage — [Trademark | Copyright | Patent | Trade Secret] (NOT A FINDING)\n\n**This is a triage, not a finding of infringement or non-infringement.** The\ntriage identifies factors and flags what matters most; it does not conclude.\nA conclusion requires an attorney's judgment on the facts, the right scope,\njurisdiction, and defenses. Acting on a triage without attorney review is\nhow companies end up on the wrong side of fee awards, Rule 11 sanctions,\ndeclaratory-judgment actions, and enhanced damages.\n\n**Triage result:** [GREEN / YELLOW / RED — one sentence why]\n\n## Posture and scope\n\n- **Party posture:** [senior / accused]\n- **Right at issue:** [trademark / copyright / patent / trade secret]\n- **Jurisdiction:** [US federal — specific circuit / state / foreign]\n- **Legal framework applied:** [cite the governing test and statute]\n- **Statute of limitations / laches posture:** [clock status]\n- **Exhibits / evidence reviewed:** [list]\n\n## Factor analysis\n\n[Mode-specific factor table — confusion factors / fair-use factors / claim chart\n/ trade-secret elements. Each factor has a flag and a direction. This is\na flag list, not a verdict.]\n\n## Defenses and thresholds\n\n[Mode-specific: dilution fame threshold / registration prerequisite /\n§ 512 safe harbor / invalidity / inequitable conduct / preemption /\nreverse-engineering / consent / license / laches / statute of limitations.\nFlag each.]\n\n## What cuts which way — summary\n\n| Factor | Flag | Direction (senior / accused / mixed) |\n|---|---|---|\n| [factor 1] | [note] | [direction] |\n\n**Conclusion:** *This skill does not conclude.* Attorney judgment required\nbefore acting. The factors cutting [direction] are [brief summary]; the\nfactors cutting [direction] are [brief summary].\n\n## Recommended next steps\n\n- [formal opinion from counsel / route to IP OC named in the practice profile]\n- [evidence preservation and hold — if a litigation clock is running]\n- [fact development needed before a decision — e.g., access logs, prosecution\n history, market studies, survey evidence]\n- [routing per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)\n `## Enforcement posture`, if the posture is to assert]\n\n## Citation verification\n\nEvery case, statute, registration number, claim quote, and exhibit cited here\nmust be verified against the authoritative source before relying on it.\nJurisdictional tests vary by circuit and change over time — confirm the\ncurrent controlling authority.\n```\n\n---\n\n## Non-lawyer gate\n\nBefore issuing the output, read `## Who's using this`. If the Role is Non-lawyer:\n\n> This output is a research triage, not legal advice. Sending a C&D, deciding\n> not to stop, filing suit, or relying on \"it's fair use\" based on this triage\n> alone has legal consequences — including Rule 11 sanctions for a baseless\n> assertion, declaratory-judgment exposure for a threatening letter, treble\n> damages on the patent side, and fee awards in unfair-competition cases.\n> An attorney needs to evaluate before you move.\n>\n> Here's a brief to bring to an attorney:\n>\n> [Generate a 1-page summary: the right at issue, the posture, the facts and\n> evidence, the factors surfaced, the defenses flagged, and the three\n> questions to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is\n> the starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent). For patents in the US, the attorney must be registered before the\n> USPTO; for other jurisdictions, use the relevant patent office register. For trademarks, INTA maintains a directory of practitioners worldwide.\n\nDeliver the triage alongside the brief.\n\n---\n\n## Output location\n\nIf matter workspaces are enabled and a matter is active, write to\nthe current project's documents.\nOtherwise write to\nthe current project's documents\nand surface the path.\n\nAppend a one-line entry to the matter's `history.md` if a matter is active.\n\n---\n\n## Handoff to enforcement skills\n\nIf the triage output points toward an assertion and the practice profile's\nposture supports it, offer:\n\n> Want me to draft a cease-and-desist on this? Run `the “Cease Desist” workflow`.\n> I'll use the flag list from this triage as the factual basis and apply the\n> approval chain from your practice profile — the letter won't go anywhere\n> without the approver signing off.\n\nOr, if the mode is copyright and the accused is hosted content:\n\n> Want me to prepare a DMCA takedown? Run `the “Takedown” workflow`.\n\nDo not draft the letter automatically from the triage. The decision to assert\nis the approver's, not the triage's.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Conclude infringement or non-infringement.** Ever. The loudest guardrail.\n- **Substitute for survey evidence, damages experts, or claim construction.**\n- **Evaluate jurisdiction-specific defenses outside the triage's jurisdiction\n scope.** If the facts cross borders, flag that foreign-law analysis is\n required.\n- **Decide fair use as a matter of law.** Fair use is fact-intensive and\n reserved for the attorney and, ultimately, the court.\n- **Draft the C&D, takedown, or complaint.** Those are separate skills\n (`the “Cease Desist” workflow`, `the “Takedown” workflow`) gated by the approval\n chain in the practice profile.\n- **Quote outputs to counterparties.** Privileged if the header applies.\n\n---\n\n## Tone\n\nFactor-by-factor, flag-by-flag. No hedging prose. The guardrail at the top\ndoes the scope work; the analysis does the analysis. A lawyer should leave\nthe output knowing exactly which factors are flagged, which defenses apply,\nand what they need to do next to either assert or stand down.", + }, + { + id: "builtin-cfl-ip-invention-intake", + title: "Invention Intake", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “invention-intake” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /invention-intake\n\n**This is a first-pass screen by a non-specialist, not a patentability\nopinion.** The screen never concludes that an invention is patentable — it\nconcludes that it passes the initial screen and warrants a prior-art search\nand registered-practitioner review, that it needs more information, or that\nit hits a disqualifier. A prior-art search is a separate step; this skill\ndoes not do one.\n\n## Instructions\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If it\n contains `[PLACEHOLDER]`, stop and direct to `configure your Practice Profile (Account → Practice Profile)`. If the\n practice profile shows trademark- or copyright-only (no patent practice),\n say so and route the user elsewhere — this is the wrong tool.\n2. Follow the workflow below.\n3. Run intake. If the user pasted or uploaded a disclosure, read it. If not,\n ask the seven intake questions (what / problem / differences / inventors /\n public disclosure / status / technology area) in one batch and wait.\n4. Run the six screens: novelty signals, obviousness flags, § 101 eligibility,\n public disclosure / bar dates, detectability, strategic value. Each screen\n gets a ✓ / 🟡 / 🔴 verdict with one-line reasoning.\n5. Write the invention screen memo to the matter folder (if a matter is\n active) or the practice outputs folder. Apply the work-product header per\n role.\n6. Bottom-line verdict: **PURSUE** (schedule prior-art search and attorney\n review) / **INVESTIGATE** (needs more info on a specific open item) /\n **DECLINE** (state the concrete reason). Never say \"patentable.\"\n7. Close with the decision tree (prior-art search / inventor follow-up /\n specialist review / decline + thank-you / trade-secret route) and the\n non-lawyer gate if the role is non-lawyer.\n8. If the screen hit a within-one-year US disclosure or any public disclosure\n with foreign rights in scope, flag at the top: **time-sensitive**.\n\nThis skill never concludes that an invention is patentable. If uncertain,\nflag — a registered patent attorney or agent decides.\n\n## Examples\n\n```\nthe “Invention Intake” workflow \"a new cache-eviction algorithm that uses a learned model rather than LRU; conceived Q1 this year, not yet disclosed, engineering prototype in internal staging\"\n```\n\n```\nthe “Invention Intake” workflow\n```\n\n(And the skill will ask for the invention, the problem it solves, how it\ndiffers, inventors, public disclosure status, usage status, and technology\narea.)\n\n---\n\n## THIS IS A FIRST-PASS SCREEN, NOT A PATENTABILITY OPINION\n\n**Say this at the top of every output. Do not drop it, do not soften it.**\n\n> **This is a first-pass screen by a non-specialist, not a patentability\n> opinion.** A patentability opinion requires a prior-art search, full claim\n> construction, and the judgment of a registered patent attorney or agent. This\n> screen does not do a prior-art search, does not assess what is in the art, and\n> does not construct claims. It screens for the obvious disqualifiers (the\n> invention is already on the market, it was publicly disclosed two years ago,\n> it is plainly an abstract idea) and the obvious go-aheads (new mechanism,\n> technical advance, recent conception, in-use secretly). Everything in between\n> needs a prior-art search and a registered practitioner's review. This screen\n> never concludes that something is \"patentable\" — it concludes that it \"passes\n> the initial screen, warrants investigation\" or that it does not.\n\nUnder-flagging an invention that should have been filed is a one-way door — the\none-year US bar runs, foreign rights are lost at first public disclosure, the\ncompetitor files first. Over-flagging just means a prior-art search that comes\nback empty. Stay on the two-way door side.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest\nof this paragraph — skills use practice-level context and the matter machinery\nis invisible. If enabled and there is no active matter, ask: \"Which matter is\nthis for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load\nthe active matter's `matter.md` for matter-specific context and overrides.\nWrite outputs to the matter folder at\nthe current project's documents.\nNever read another matter's files unless `Cross-matter context` is `on`.\n\nInvention disclosures are particularly common candidates for **clean-team** or\n**heightened** confidentiality at matter-open. Respect the matter's\nconfidentiality marking from `matter.md`. Invention content is inherently\nsensitive — do not summarize, quote, or reference it outside privileged\nchannels.\n\n---\n\n## Load the practice profile first\n\n**Before reading the disclosure, read\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If it is\nmissing or still contains placeholders, stop and run `configure your Practice Profile (Account → Practice Profile)`. The\npractice profile tells you:\n\n- The company's **patent filing strategy** — offensive (building an assertion\n portfolio), defensive (filing to protect freedom to operate), hybrid, or\n licensing-revenue. This determines the strategic-value bar.\n- The **technology areas of interest** — where the company files and where it\n does not. An invention that falls outside the areas of interest is often a\n decline even if the technical screen is clean.\n- The **filing budget posture** — aggressive (file everything that passes the\n screen), selective (file the best few), or minimal (only what the business\n needs to protect). This shapes the output's recommendation.\n- The **approval chain** — who signs off on a filing decision, and who the\n invention gets routed to if it passes the screen.\n\nIf the practice profile shows trademark-only or copyright-only (no patent\npractice), this skill is the wrong tool — say so and route the user elsewhere.\n\n---\n\n## Workflow\n\n### Step 1: Intake the disclosure\n\nIf the user pastes or uploads a disclosure, read it. If not, ask — in one\nbatch, not one at a time:\n\n> To screen this, I need:\n>\n> 1. **What is the invention?** In plain language — what does it do, what makes\n> it work, what is the key idea.\n> 2. **What problem does it solve?** What was broken or missing before.\n> 3. **How does it differ from what existed before?** What did people do\n> previously? What does this do differently?\n> 4. **Who invented it, and when?** Names and rough conception date.\n> 5. **Has it been publicly disclosed?** Published, sold, offered for sale,\n> demonstrated at a conference, shown to a customer under an NDA, posted to\n> a public repo, written up in a paper, included in a product release note.\n> If yes, when and where.\n> 6. **Is it in use or planned?** Shipping now? In a limited pilot? On the\n> roadmap? Still on paper?\n> 7. **What technology area?** (Software, hardware, mechanical, biotech,\n> method-of-doing-business, AI/ML, etc.)\n\nWait for answers. Do not proceed on a half-disclosure — a screen of \"a new\nmachine learning thing that helps users\" is worse than no screen.\n\nIf the disclosure is a formal invention disclosure form (IDF) from an IPMS or\na template, extract these fields from the form and only ask for what's missing.\n\n### Step 2: Screen against the checklist\n\nWalk the five screens in order. Each produces a per-screen verdict:\n`✓ clear`, `🟡 flagged — needs further look`, or `🔴 red flag`. Explain the\nreasoning briefly; do not pad.\n\n#### Screen 1: Novelty signals\n\nDoes the disclosure describe something new? This is not a full novelty\nanalysis — that requires a prior-art search. This screens the disclosure's own\ndescription for self-evident novelty problems.\n\n**Red flags (🔴):**\n- \"We just applied [known technique] to [new domain]\" — e.g., \"we took\n gradient boosting and applied it to predicting customer churn\"\n- \"It's like [existing product] but for [X]\" — Uber-for-dog-walking framing\n- \"Competitors do something similar\" — if the disclosure itself says this,\n novelty is in question\n- The disclosure describes a feature of an existing public product with minor\n tuning\n\n**Green flags (✓):**\n- A new **mechanism** — a new way of doing the thing, not a new application\n- A new **combination** that produces an unexpected result (not just\n additive — \"faster,\" \"smaller,\" \"cheaper\" are sometimes unexpected, sometimes\n obvious)\n- Solving a problem the field **had not solved** — the disclosure explains why\n the prior approaches failed and how this one doesn't\n\n**Flagged (🟡):** anything ambiguous. Prior-art search settles it.\n\n#### Screen 2: Obviousness flags\n\nWould a person of ordinary skill in the art (POSA) have arrived at this\ncombination based on what's known? This is a screen, not a § 103 analysis —\nflag for further investigation, never conclude obviousness or non-obviousness.\n\n**Red flags (🔴) for further investigation:**\n- Combining **known elements in a predictable way** — putting a known sensor\n on a known machine to measure a known thing\n- **Routine optimization** — \"we tuned the existing parameter from X to Y and\n got better results\"\n- **Design choice without functional advantage** — aesthetic, ergonomic, or\n stylistic changes that don't change how the thing works\n- **Obvious to try** — one of a small number of identified solutions with a\n reasonable expectation of success\n\n**Green flags (✓):**\n- Teaching away — prior art expected the opposite result or said this approach\n wouldn't work\n- Unexpected result — the combination produces something the POSA would not\n have predicted\n- Long-felt need — the problem was known, and attempts to solve it had failed\n\n#### Screen 3: Subject-matter eligibility (§ 101)\n\nIs this an abstract idea, law of nature, or natural phenomenon? This is the\nhardest screen, the most litigated, and the one most likely to require a\nspecialist read. Flag anything borderline for specialist review.\n\n**Red flags (🔴) for § 101:**\n- Pure **business method** without technical implementation — \"a method of\n pricing widgets more efficiently\"\n- **Mathematical algorithm** on its own — even as dressed up in pseudocode\n- **Organizing human activity** — scheduling, pairing, matching, reviewing —\n without a technical improvement\n- Claim that reads as \"**do [known thing] on a computer**\" with no\n improvement to the computer itself\n- AI/ML invention where the claim is the **function** (recommend, classify,\n predict) without the specific technical means that improves how the computer\n performs the function\n\n**Green flags (✓) for software/AI inventions:**\n- Technical improvement to the **computer itself** — new architecture, new\n training technique, new hardware/software interface, new security mechanism\n- Specific technical means, not just results\n- Improvement to a **technical field** (image processing, compression,\n cryptography, robotics) with the technical means described\n\n**Anything borderline gets a 🟡 with \"§ 101 — route to specialist for\nAlice/Mayo analysis.\"** A non-specialist should not call a close § 101\nquestion.\n\nFor **biotech / diagnostic** inventions, also flag for § 101 if the claim\nrecites:\n- A natural correlation (\"if level of X is above Y, patient has Z\")\n- A naturally occurring substance (isolated gene, natural product) without\n significant human modification\n\n> **§101 is a US standard. Other patent offices are different.** The EPO's \"technical effect\" test (Art. 52 EPC) is materially more permissive for software and AI inventions than US §101 post-*Alice*. JPO and CNIPA also apply different standards. An invention that screens 🔴 under *Alice* may be perfectly eligible at EPO/JPO/CNIPA.\n>\n> When the practice profile includes non-US jurisdictions: \"This §101 screen is US-only. If you file internationally, the eligibility posture may be different — particularly for software, AI/ML, and business methods, which EPO is more permissive on. Don't decline based on US §101 alone if you have EP/JP/CN filing plans.\"\n\n#### Screen 4: Public disclosure / bar dates\n\nHas the invention been disclosed, sold, offered for sale, or publicly used?\nThis is the most time-sensitive screen — the answer can kill patentability\nabsolutely, or start a clock that cannot be stopped.\n\nCategorize the disclosure status:\n\n**🔴 Likely barred:**\n- Publicly disclosed, sold, or offered for sale **more than 12 months ago**\n in the US — 35 U.S.C. § 102(b) one-year grace period has run\n- **Any** public disclosure, anywhere, before filing — absolute novelty bar in\n the EU, China, Japan, and most countries outside the US. If the business\n cares about foreign rights, this is potentially fatal even if US is still\n open.\n\n**🟡 Clock is running:**\n- Publicly disclosed within the last 12 months — US one-year clock is running,\n foreign rights may already be lost. Urgent. Confirm the disclosure date and\n route to filing immediately.\n\n**✓ Clear:**\n- No public disclosure. Confidential customer demonstrations under NDA, internal\n use, beta releases to named parties under NDA, draft papers not yet submitted\n — usually not \"public\" for § 102 purposes, but depends on the facts. When the\n disclosure was to a customer or external party, even under NDA, flag the\n specifics for the prosecution team to assess.\n\n**Ask specifically about:**\n- Papers submitted to journals or conferences (submission ≠ publication; but\n check the journal's policy and whether preprints were posted)\n- Talks given at conferences, meetups, internal company events open to\n non-employees\n- Posts to public repos, blogs, social media, or forums\n- Product releases, even in limited beta\n- Sales activity including quotes, RFP responses, and offers for sale\n- Disclosures to investors or board members who are not under NDA\n\nThe **on-sale bar** catches offers for sale of a product embodying the\ninvention, not just completed sales. An RFP response describing the invention\ncan trigger it.\n\n#### Screen 5: Detectability\n\nIf a competitor were to infringe this invention, could you tell? An invention\nthat's practiced in secret — server-side processing, back-office operations,\ninternal manufacturing techniques — may be better protected as a **trade\nsecret** than as a patent. Publishing a patent on an undetectable invention is\ngiving it to competitors in exchange for an asset you can never enforce.\n\n**🔴 Low detectability flags:**\n- Server-side algorithm with no observable output pattern\n- Internal manufacturing process (e.g., a novel etch step in a semiconductor\n process)\n- Data-pipeline or analytics methodology that happens inside a competitor's\n infrastructure\n- Training data composition or training technique for an ML model — visible\n only through fine-grained probing, if at all\n\nFor these, flag for the **patent-vs-trade-secret decision**. The question is\nnot \"is this patentable\" but \"should we patent it if we could.\" Route to\nwhoever in the practice profile owns trade-secret classification decisions.\n\n**✓ High detectability:**\n- Consumer product — visible in the product\n- Published API, SDK, protocol — visible in network traffic or integration\n docs\n- Physical mechanism in a distributed product — reverse-engineerable\n- Compiled code with distinctive signatures in a distributed binary\n\n#### Screen 6: Strategic value\n\nDoes this align with the company's patent strategy from the practice profile?\nThis is where the screen becomes company-specific rather than doctrinal.\n\nCheck against the profile:\n\n- **Offensive strategy (build to assert):** is this asset assert-worthy? A\n narrow, easily designed-around patent has lower offensive value than a broad\n mechanism claim. Is the competitive landscape one where you would want to\n sue?\n- **Defensive strategy (build to protect FTO):** does this cover a technology\n area where competitors are filing? A defensive filing in an area nobody\n files in is a wasted spend.\n- **Licensing / revenue strategy:** is this licensable? Who would pay for it,\n and under what circumstances?\n\nAlso check:\n\n- Is this **core** technology (part of the product's differentiation) or\n **peripheral** (incidental to a side feature)? Core is worth more.\n- What is the **competitive landscape**? Patent-heavy (semiconductors,\n pharmaceuticals) — file early or lose the race. Patent-light (many\n open-source-heavy software segments) — sometimes skip entirely and spend\n the money elsewhere.\n- Is the technology area on the company's list of **tech areas of interest**\n from the practice profile? If not, it is often a decline regardless of\n doctrine.\n\n### Step 3: Assemble the invention screen memo\n\nFormat:\n\n> **Invention screen memo — [invention title]**\n>\n> **Bottom line: [PURSUE / INVESTIGATE / DECLINE]**\n>\n> *[One sentence — the reason in plain language.]*\n>\n> ---\n>\n> ### Screen results\n>\n> | Screen | Verdict | Notes |\n> |---|---|---|\n> | Novelty signals | [✓ / 🟡 / 🔴] | [one-line reasoning] |\n> | Obviousness flags | [✓ / 🟡 / 🔴] | [one-line reasoning] |\n> | § 101 eligibility | [✓ / 🟡 / 🔴] | [one-line reasoning] |\n> | Public disclosure / bar dates | [✓ / 🟡 / 🔴] | [one-line reasoning + dates] |\n> | Detectability | [✓ / 🟡 / 🔴] | [one-line reasoning] |\n> | Strategic value | [✓ / 🟡 / 🔴] | [one-line reasoning, referenced to profile] |\n>\n> ---\n>\n> ### Open questions\n>\n> *Things that would change the answer. The inventor, the prosecution team, or\n> a specialist would need to address these before this screen converts to a\n> filing decision.*\n>\n> - [question]\n> - [question]\n>\n> ### Next steps (decision tree)\n>\n> Pick one and I'll help you build it out:\n>\n> 1. **Commission the prior-art search** — I'll draft the search request for\n> [outside counsel / search vendor] with the claim concepts, inventors,\n> technology classification, and any known references.\n> 2. **Go back to the inventor for more facts** — I'll draft the follow-up\n> questions on [specific open items above].\n> 3. **Route to outside counsel for § 101 / patent-vs-trade-secret judgment** —\n> I'll draft a transmittal summarizing what the screen found and what\n> specialist judgment is needed.\n> 4. **Decline and send the standard thank-you** — I'll draft the inventor\n> thank-you and archive the disclosure with the declination reason.\n> 5. **Flag for trade secret instead** — I'll draft a note to whoever owns\n> trade-secret classification explaining why a trade-secret approach is a\n> better fit.\n\nApply the work-product header per role. Apply the reviewer note. Keep the\ndeliverable clean of internal narration (\"I'm using the invention-intake\nskill...\" etc.).\n\n### Step 4: Recommend the bottom-line verdict\n\nThe bottom line is one of three:\n\n- **PURSUE** — enough screens are clear (or clearly fixable) to warrant a\n prior-art search and attorney review. This is NOT \"patentable\" — it is\n \"passes the initial screen, investigation warranted.\"\n- **INVESTIGATE** — one or more screens flagged something that needs more\n information, specialist review, or a clarifying question back to the\n inventor before a pursue/decline decision can be made. Name the specific\n open item.\n- **DECLINE** — a screen hit a fatal flag (barred by disclosure over 12\n months old with no foreign rights concern, plainly obvious, plainly abstract\n under Alice, outside the company's technology areas of interest, fundamentally\n undetectable with no trade-secret path). State the reason clearly.\n\nA DECLINE should always be backed by a concrete reason the inventor can\nunderstand. \"Not patentable\" is not an acceptable decline reason; \"barred by\nyour paper at NeurIPS 2023 — the US one-year bar ran in December 2024\" is.\n\n## Guardrails\n\n**Never say \"patentable.\"** The closest you can come is \"passes the initial\nscreen, warrants further investigation.\" Patentability is a conclusion a\nregistered practitioner reaches after a prior-art search and claim\nconstruction.\n\n**Never do a prior-art search in this skill.** A WebSearch for \"does this\nalready exist\" is not a prior-art search — it's a credibility check the\nuser can also run. If you want to sanity-check novelty, say so explicitly\n(\"quick web check — the technique was discussed in [X] — this is not a prior-\nart search, it's context for the screen\") and flag it as `[web — verify]`.\n\n**Defer on § 101 calls.** For anything borderline under Alice/Mayo, flag for\nspecialist review. § 101 is where practitioners routinely disagree and where\na non-specialist's confident call ages badly.\n\n**Flag detectability before strategic value.** An undetectable invention that\nwould be \"high strategic value\" as a patent is usually higher strategic value\nas a trade secret. Do not recommend PURSUE on an undetectable invention\nwithout addressing the trade-secret alternative.\n\n**Urgent cases get urgent flagging.** If the screen hits a within-one-year\npublic disclosure in the US, or any public disclosure with foreign rights in\nscope, say so at the top of the memo. Bottom line, then: \"**Time-sensitive —\nUS bar runs [date], foreign rights already at risk.**\" This is the kind of\nfinding a lawyer needs to see in the first three seconds.\n\n**Respect the routing.** Per the practice profile, this screen is a triage\nstep. The person who decides what to file is the attorney or agent responsible\nfor patent prosecution. The screen feeds that person; it does not replace them.\n\n## Non-lawyer gate\n\nIf the role is **non-lawyer** (with or without attorney access), close the\nmemo with:\n\n> **This is a screening tool for your disclosure, not a patentability opinion.\n> The decision about whether to file — and how — belongs to a registered\n> patent attorney or agent. If this screen says PURSUE or INVESTIGATE, your\n> next step is not to file or draft claims; it is to share this memo (and the\n> underlying disclosure) with patent counsel. If there is no counsel engaged\n> yet, [contact from profile / \"your professional regulator's IP referral service — state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent\"] is the\n> starting point.**", + }, + { + id: "builtin-cfl-ip-ip-clause-review", + title: "IP Clause Review", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “ip-clause-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /ip-clause-review\n\nReviews the IP clauses in an agreement against the practice profile in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Flags assignment gaps, ownership ambiguity, license-scope issues, and IP warranty/indemnity problems. Produces a memo with per-clause findings, prioritized by risk, with suggested redline language where appropriate.\n\n## Instructions\n\n1. **Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If placeholders present, stop and prompt: \"Run `configure your Practice Profile (Account → Practice Profile)` first — I need to learn your practice profile before I can review IP clauses against it.\"\n\n2. **Get the agreement:** From file path, Drive link, or pasted text. If none provided, ask.\n\n3. **Follow the workflow below.** In particular:\n - Establish the agreement type and which side the company is on for IP (granting / receiving / both). The side question is per-document, not a one-time setup answer.\n - Run the assignment gap check first if the agreement is an employment, consulting, SOW, or work-for-hire document.\n - Produce per-clause findings prioritized by risk.\n - Check cross-clause consistency, not just clause-by-clause.\n - Note jurisdiction implications (moral rights, work-for-hire, implied license, patent indemnity).\n\n4. **Output the memo** per the template below — work-product header first, bottom line, assignment gap check, clauses by severity, consistency flags, jurisdiction note, approval routing.\n\n5. **Respect the decision posture.** When a clause could be read to allocate IP either way, flag for attorney review and surface the factors cutting both ways. Never silently decide a subjective allocation question.\n\n## Examples\n\n```\nthe “IP Clause Review” workflow ~/Documents/vendor-sow.pdf\nthe “IP Clause Review” workflow https://docs.google.com/document/d/...\nthe “IP Clause Review” workflow\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nRead the IP clauses in an agreement and tell the lawyer what each one does, how it deviates from market or from the team's standard position, what the risk is, and — where appropriate — the specific redline to propose. The goal is a memo the lawyer can act on in one pass.\n\n**The highest-stakes clauses in most agreements are IP ownership and assignment.** They are hard to fix later. A failure to get a clean assignment on an employment or consulting agreement surfaces in M&A diligence, in financing, and in litigation, sometimes years after the agreement was signed. If assignment language is weak or missing in a document that should have it, flag it loudly at the top of the memo — not buried as one line item among many.\n\n## Precondition: load the practice profile\n\n**Before reading the agreement, read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If it is missing or still contains placeholders, stop and run `configure your Practice Profile (Account → Practice Profile)`. The practice profile tells you:\n\n- The jurisdiction footprint — which affects whether moral rights waivers are enforceable, whether work-for-hire applies, whether implied assignment fills a gap, how broad license grants can be\n- Who approves deviations and at what severity\n- The work-product header to prepend to outputs\n\n## Workflow\n\n### Step 1: Orient\n\nRead the whole agreement once, fast. Answer:\n\n| Question | Answer |\n|---|---|\n| What kind of agreement is this? | Employment / consulting or SOW / vendor MSA / in-license / out-license / collaboration or JDA / settlement / acquisition or asset purchase / other |\n| Which side are we on for IP? | Granting rights or receiving them / assigning IP or acquiring it / licensor or licensee |\n| Who is the counterparty? | Name, and sophistication — individual, startup, BigCo |\n| Is there consideration flowing for the IP specifically? | Salary, fee, royalty, upfront payment, equity, none |\n| Governing law and venue | What does it say — and does our practice profile flag that jurisdiction as escalate/never? |\n\nThe side question is per-document, not a one-time setup answer. An in-house counsel reviewing an employment agreement is on the \"receiving\" side; reviewing an out-license the same day, on the \"granting\" side. The posture inverts.\n\nIf the side is ambiguous (a collaboration agreement where both parties contribute and both receive rights, a reseller agreement with flow-through IP), ask:\n\n> Which side is [company] on for this agreement's IP? Granting rights, receiving rights, or both? If both, I'll review each direction separately.\n\n### Step 2: Assignment gap check (highest priority)\n\nIf the agreement is an employment agreement, consulting agreement, SOW, work-for-hire contract, or anything else where the company should be receiving an assignment of the counterparty's IP in work product — check the assignment language first.\n\nLook for:\n\n- **Present-tense assignment** (\"hereby assigns\" or \"hereby irrevocably assigns and agrees to assign\"). A bare \"agrees to assign\" is a promise to assign, not an assignment, and can require a second document to perfect.\n- **Scope** — does it cover all IP created in the course of engagement, or only IP related to the company's business, or only IP created using company resources? Narrow scope is a gap if work product is expected to range broadly.\n- **Moral rights waiver** (for jurisdictions that recognize moral rights — EU member states, Canada, many others — the US recognizes a narrow version for visual art). If the agreement is governed by or has counterparties in a moral-rights jurisdiction, a waiver or non-assertion covenant matters.\n- **Further assurances** clause — counterparty agrees to sign whatever else is needed to perfect the assignment later.\n- **Pre-existing IP carveout** — what does the counterparty exclude from the assignment, and is that list specific or open-ended?\n\nIf any of the above is missing or weak, flag at the top of the memo with a 🔴 or 🟠 severity and a specific redline.\n\n```markdown\n## ⚠️ ASSIGNMENT GAP\n\n**Section [X]** assigns IP in the work product, but: [specific issue — e.g.,\n\"'agrees to assign' rather than 'hereby assigns,'\" or \"no moral rights waiver\nand governing law is France,\" or \"no carveout list is provided and the\ncounterparty has pre-existing platform IP\"].\n\n**Risk:** This is the kind of gap that surfaces in M&A diligence years later.\nThe counterparty (or a successor) may have residual rights in work product we\nthought we owned.\n\n**Proposed redline:**\n> \"[specific replacement language]\"\n\n**Escalation:** Per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), assignment-scope gaps escalate to [approver].\n```\n\n> **Can the assignment convey AI-generated content?** *Thaler v. Perlmutter* and the Copyright Office's 2023 AI registration guidance suggest that AI-generated works without any human authorship may not be copyrightable, though the boundaries remain unclear and this area is evolving. If the contractor uses AI for substantial portions of the deliverables, the copyright status of those portions is uncertain — and an assignment clause can only convey rights that exist.\n>\n> Check: does the agreement have an AI-use disclosure obligation? A representation about the role of AI in the deliverables? A mechanism to identify which portions are AI-assisted vs. human-authored?\n>\n> If absent and AI-assisted creation is foreseeable (consulting, development, content creation, design): 🟠 High. \"The assignment clause is well-drafted but there's no AI-use disclosure. The copyright status of AI-generated content is unsettled, and without a disclosure obligation you won't know which portions are affected. Add an AI-use representation and a disclosure obligation.\" `[review — copyright status of AI-generated works is an evolving area; verify against current Copyright Office guidance and case law]`\n\n> **AI-assisted inventorship.** A patent filed with incorrect inventorship is unenforceable. If a consultant uses AI tools that contribute to an inventive concept, the inventorship question is unsettled and the patent is at risk. For any agreement with patent assignment provisions covering potentially patentable work product:\n>\n> Check: does the agreement have an AI-use representation? A process for determining inventorship where AI contributed? A disclosure obligation about AI use in the inventive process?\n>\n> If absent: flag. \"Patent assignment without an AI-use representation. If AI tools contributed to the inventive concept, inventorship determination is complicated and an incorrectly-attributed patent is unenforceable. Add an AI-use representation and inventorship protocol.\"\n\n### Step 3: Clause-by-clause review\n\nFor every IP-relevant clause, produce a block. The clauses to look for:\n\n- **Assignment / work-for-hire** — who owns what's created under the agreement\n- **Ownership of deliverables** — distinct from assignment; often states the output of the engagement\n- **Improvements and derivatives** — who owns improvements to pre-existing IP, who owns derivative works\n- **Background IP vs. foreground IP** — does the agreement define pre-existing IP and newly-created IP separately, and license the background IP to the extent needed?\n- **License grants** — scope, exclusivity, territory, field of use, sublicensability, term, termination triggers, royalty or fee structure\n- **IP warranties** — non-infringement of third-party rights, authority to grant, original work\n- **IP indemnities** — scope, cap, procedure, exclusions (user modifications, combinations, unauthorized use)\n- **Moral rights waiver** — jurisdiction-dependent\n- **Open source representations** — representations about what OSS is and is not embedded in deliverables\n- **Trademark use** — any grant or restriction on use of the other party's marks; brand guidelines; quality control for licensor\n- **Confidentiality / trade secrets** — treatment of trade secret material, reasonable measures, return or destruction, post-term obligations\n\nFor each clause present, produce:\n\n```markdown\n### [Section X.X]: [Clause name]\n\n**What it says:** [plain-English summary, one or two sentences]\n\n**What's market (for this agreement type, this side, this jurisdiction):**\n[brief reference point]\n\n**Risk:** 🔴 Critical | 🟠 High | 🟡 Medium | 🟢 Low\n\n**Why it matters:** [one or two sentences — what goes wrong for the business\nif this stays as-is]\n\n**Proposed redline (if needed):**\n> \"[specific replacement language]\"\n\n**Decision call:** [If uncertain whether the clause achieves the intended IP\nallocation, flag for attorney review and state the factors cutting both\nways. Do not silently decide a subjective allocation question.]\n```\n\n**Severity calibration:**\n\n| Level | Means |\n|---|---|\n| 🔴 Critical | Don't sign without fixing. Assignment gap in a document that should have one. Unlimited license where a narrow one was intended. Exclusive grant where non-exclusive was intended. |\n| 🟠 High | Strongly push; escalate if they won't move. Ambiguous scope, missing moral rights waiver in a moral rights jurisdiction, missing further assurances, narrow indemnity. |\n| 🟡 Medium | Push in first round; accept if it's the last open item. Cosmetic but imprecise language, survival periods shorter than standard. |\n| 🟢 Low | Note it, don't spend capital. A stylistic deviation that doesn't change the allocation. |\n\n### Step 4: Cross-clause consistency\n\nIP clauses fail as a system. Check:\n\n- **Does the license grant match the scope of what's being licensed?** (A license to \"use\" the deliverable is narrower than a license to \"use, modify, and create derivative works.\")\n- **Do the warranties cover everything the grant covers?** (A warranty of non-infringement limited to patents, in a license that also covers copyrights and trade secrets, leaves gaps.)\n- **Does the indemnity cover what the warranty promises?** (A warranty without indemnity is a promise without a remedy.)\n- **Does termination pull the license back?** (Or does a paid-up license survive termination? Either is defensible — the question is whether it matches intent.)\n- **Is the IP allocation between this agreement and any related SOW, order form, or related side letter consistent?** Flag conflicts.\n\n### Step 5: Jurisdiction note\n\nIP rules are jurisdiction-specific in ways that change the outcome. Flag if the agreement implicates any of these:\n\n- **Moral rights** — EU member states, Canada, much of the civil-law world recognize moral rights (paternity, integrity) that may not be fully assignable or waivable. US recognition is narrow (VARA, for visual art).\n- **Work-for-hire** — US doctrine is statutory (17 U.S.C. § 101) and only applies to enumerated categories for independent contractors. UK implies assignment in the employment context but not always for contractors. Civil-law jurisdictions handle this differently again.\n- **Implied license** — common-law jurisdictions may read in an implied license where the written grant is silent. Civil-law jurisdictions tend not to.\n- **Patent indemnity exclusions** — combinations, modifications, and user supply of accused features are standard US exclusions; the interaction with EU patent and UPC is still developing.\n\nState what jurisdiction the agreement is governed by, and whether the practice profile flags that jurisdiction as standard, escalate, or never.\n\n## Redline granularity\n\n**Edit at the smallest possible granularity.** A redline is a negotiation artifact, not a rewrite. Wholesale clause replacement signals \"we threw out your drafting\" — it's aggressive, it forces the counterparty to re-read the whole clause, and it discards the parts of their drafting that were fine. Surgical redlines — strike a word, insert a phrase, restructure a subclause — signal \"we have specific asks\" and are faster to read, understand, and accept.\n\nDefault to the smallest edit that achieves the playbook position:\n- Replace a **word** before a phrase. (\"twelve (12)\" → \"twenty-four (24)\")\n- Replace a **phrase** before a sentence. (\"paid by the Buyer\" → \"paid and payable by the Buyer\")\n- Restructure a **subclause** before replacing the sentence. (Add \"(a)\" and \"(b)\" to split a compound condition.)\n- Replace a **sentence** before replacing the clause.\n- Only replace a **whole clause** when the counterparty's version is so far from your position that surgical edits would be harder to read than a fresh draft — and when you do, say so in the transmittal: \"We've replaced §8.2 rather than marking it up because the changes were extensive. Happy to walk you through the delta.\"\n\nWhen in doubt, smaller. A client who receives a surgical redline trusts that you read carefully. A client who receives a wholesale replacement wonders whether you read at all.\n\n### Step 6: Assemble the memo\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` (it differs by user role — see `## Who's using this`).\n\nThis memo and the underlying agreement may be privileged, confidential, or both. The output inherits that status from the source. Distribute only within the privilege circle; mark and store it where privileged materials live; strip the work-product header before any external delivery.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for a rule the memo needs (enforceability of a moral rights waiver in a given jurisdiction, scope of an implied license, standard for an IP warranty survival period), report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / jurisdiction]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Where the memo cites a statute, regulation, case, or treatise, tag the citation: `[Westlaw]`, `[statute / regulator site]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations from the counterparty draft or house files. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n# IP Clause Review: [Counterparty] [Agreement Type]\n\n**Reviewed:** [date]\n**Our side for IP:** [Granting / Receiving / Both]\n**Governing law:** [jurisdiction]\n\n---\n\n## Bottom line\n\n[Two sentences. Can the IP allocation stand? What has to change first?]\n\n**Issues:** [N]🔴 [N]🟠 [N]🟡 [N]🟢\n\n**Approval needed from:** [name, per practice profile]\n\n---\n\n## Assignment gap check\n\n[✅ Clear | ⚠️ Gap present — see above]\n\n---\n\n## Clauses by severity\n\n[All clause blocks from Step 3, grouped Critical → Low]\n\n---\n\n## Cross-clause consistency\n\n[Flags from Step 4]\n\n---\n\n## Jurisdiction note\n\n[Flags from Step 5]\n\n---\n\n## Approval routing\n\n[From practice profile — who approves, what triggers automatic escalation]\n```\n\n## Decision posture\n\nWhen a clause could be read to allocate IP either way, or when it is unclear whether the drafter's chosen words achieve the stated intent, **flag it for attorney review and surface the factors cutting both ways**. Do not silently decide a subjective allocation question. An unresolved IP allocation that gets signed is a one-way door — the error surfaces in diligence, financing, or litigation. Flagging an ambiguous clause that turns out to be fine is a two-way door.\n\n## Quality checks before delivering\n\n- [ ] Practice profile was loaded and the jurisdiction note reflects what's there\n- [ ] Assignment gap checked first (for employment/consulting/SOW/WFH)\n- [ ] Every 🔴 and 🟠 issue has specific replacement language\n- [ ] Cross-clause consistency checked, not just clause-by-clause\n- [ ] Source tags applied to citations; no stripped `verify` tags\n- [ ] Approver named per practice profile, not \"escalate to legal\"\n- [ ] Output marked with the work-product header\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-ip-oss-review", + title: "OSS Review", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “oss-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /oss-review\n\nRuns an open source license compliance check against the practice profile in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Classifies dependencies by license family, maps obligations to the deployment model, flags license-unknown and non-OSI-posing-as-OSS packages, and recommends actions — comply, replace, remove, seek legal review, seek commercial license.\n\n## Instructions\n\n1. **Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If placeholders present, stop and prompt: \"Run `configure your Practice Profile (Account → Practice Profile)` first — I need to learn your practice profile (and OSS policy, if any) before I can review.\" If the practice profile points at an uploaded OSS policy, read that too — it is the source of truth for accepted / review / banned licenses on this team.\n\n2. **Establish the scope:** a dependency list (package.json, requirements.txt, go.mod, Gemfile, Cargo.toml, pom.xml, SBOM), a single library, or outbound code the team is preparing to open-source. If the user passed a path, infer from the file; otherwise ask.\n\n3. **Establish the deployment model** before classifying obligations — SaaS, distributed binary, internal only, or embedded. The same dependency list triggers different obligations depending on this.\n\n4. **Follow the workflow below.** In particular:\n - Read the actual license text, not just metadata — LICENSE files can be wrong, package metadata can be stale.\n - Classify each package into permissive / weak copyleft / strong copyleft / public domain / non-OSI / unknown.\n - Flag license-unknown as \"needs review,\" not permissive by default.\n - Flag non-OSI source-available licenses (SSPL, BUSL, Commons Clause, Elastic License, fair-source) — these are not open source.\n - For outbound code, check that the chosen outbound license is compatible with every embedded dependency.\n\n5. **Output the memo** per the template below — work-product header first, bottom line, top-of-memo flags, per-package blocks grouped by severity, jurisdiction note, outbound check (if applicable), approval routing.\n\n6. **Respect the decision posture.** When a copyleft-trigger analysis turns on a contested question (AGPL's \"interacts over a network,\" GPL-3.0's \"conveying,\" LGPL linking scope), flag for attorney review and surface the factors cutting both ways. Anything flagged as strong copyleft or license-unknown goes to an attorney before the dependency ships or the code is released.\n\n## Examples\n\n```\nthe “OSS Review” workflow ~/code/my-project/package.json\nthe “OSS Review” workflow ~/code/my-project/requirements.txt\nthe “OSS Review” workflow redis\nthe “OSS Review” workflow ~/code/my-project # repo root — scan all manifests\n```\n\n---\n\n## Works better connected\n\nOSS clearance requests usually come in via a ticketing system. Connected to\nJira, Linear, or Asana, this skill can: monitor incoming OSS requests, respond\nwith guidance directly in the ticket (flagging incomplete info, asking for the\nrepo link, returning the license-family classification), and track clearance\nstatus across requests.\n\nWithout a connector, paste the ticket or describe the request and I'll handle\nit one at a time. See `CONNECTORS.md` at the repo root for how to add a\nticketing connector.\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nTell the user what licenses are in their dependency tree, what obligations those licenses trigger given how the code will be deployed, and what to do about each one. The output is a memo the lawyer (or the engineer with attorney access) can act on — comply, replace, remove, seek legal review, seek commercial license.\n\n**This is a first-pass classification.** Copyleft analysis depends on the deployment model, the degree of linking, the jurisdiction, and sometimes on legal questions that have not been tested in court (notably AGPL's \"interacts over a network,\" GPL-3.0's patent clause). For anything that classifies as strong copyleft or license-unknown, an attorney evaluates before the dependency ships or the code is released. The skill reports what it found; the lawyer decides what to do.\n\n## Precondition: load the practice profile\n\n**Before scanning dependencies, read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If it is missing or still contains placeholders, stop and run `configure your Practice Profile (Account → Practice Profile)`. The practice profile tells you:\n\n- Who owns OSS review on this team (often engineering with legal sign-off)\n- Escalation routing for copyleft obligations\n- The work-product header to prepend\n\nIf the practice profile has an OSS policy uploaded, read that too — it is the source of truth for which licenses the team accepts, which trigger review, and which are banned.\n\n## Workflow\n\n### Step 1: What's the scope?\n\nAsk (or infer from what the user provided):\n\n> What are we reviewing?\n>\n> 1. **A dependency list** — `package.json`, `requirements.txt`, `go.mod`, `Gemfile`, `Cargo.toml`, `pom.xml`, an SBOM (SPDX / CycloneDX), a lockfile\n> 2. **A single library** — one specific package you're considering adding\n> 3. **Our own code** — we're planning to open-source this and need to check what's embedded\n\nThe analysis path differs:\n\n- Dependency list → classify every entry, roll up obligations\n- Single library → classify one package and walk its transitive dependencies if available\n- Outbound code → check what's embedded (direct and transitive), check whether chosen outbound license is compatible with all embedded licenses, check that LICENSE / NOTICE files are correct\n\n### Step 2: What's the deployment model?\n\nThis is the single most important input after the license list — the same library carries different obligations depending on how the software is delivered. Ask:\n\n> How will this be deployed?\n>\n> 1. **SaaS / hosted service** — users access over a network; nothing ships to the user\n> 2. **Distributed binary** — we ship compiled code to users (desktop app, mobile app, on-prem server, CLI tool)\n> 3. **Internal only** — used only inside the company, not distributed outside\n> 4. **Embedded / firmware** — shipped in hardware or as closed-system firmware\n\n| Deployment | Licenses that materially matter |\n|---|---|\n| SaaS | AGPL (network-trigger), permissive attribution in any UI, SSPL/BUSL/Elastic if repurposing as competing service |\n| Distributed binary | GPL, LGPL, MPL, EPL (all trigger on distribution), permissive attribution |\n| Internal only | Most copyleft does not trigger — no distribution. Permissive attribution still good hygiene. AGPL still triggers if users outside the company interact over the network. |\n| Embedded / firmware | GPL is especially hard to comply with here (source disclosure + reproducible build + installation information in some cases). Plan for this before shipping, not after. |\n\nFlag the deployment model in the output memo — the same dependency list reviewed against \"SaaS\" vs. \"distributed binary\" yields different obligations.\n\n### Step 3: Classify each dependency\n\nFor every package, determine the license. Read the actual license text, not just the metadata — LICENSE files can be wrong (the file says MIT but the headers say GPL; the README claims Apache but there's no license file), and package manager metadata can be stale.\n\nClassify into:\n\n| Bucket | Examples | Key obligations |\n|---|---|---|\n| **Permissive** | MIT, BSD-2-Clause, BSD-3-Clause, Apache-2.0, ISC, Zlib, Unlicense | Attribution, preserve license text, Apache-2.0 adds patent grant + NOTICE requirement |\n| **Weak copyleft** | LGPL-2.1, LGPL-3.0, MPL-2.0, EPL-1.0, EPL-2.0, CDDL | File-level or library-level source disclosure; linking rules vary |\n| **Strong copyleft** | GPL-2.0, GPL-3.0, AGPL-3.0, OSL, EUPL (depending on version) | Broad source disclosure; AGPL extends to network use |\n| **Public domain / dedication** | CC0, Unlicense, WTFPL | Typically no obligations, but some are contested in jurisdictions that don't recognize dedication to public domain |\n| **Non-OSI source-available** | SSPL, BUSL, Commons Clause, Elastic License, Confluent Community, fair-source family | Not open source — restrict commercial use, competing-service use, or both. Read the specific license. |\n| **Other / custom / unknown** | vendor-specific, proprietary, missing license file, license conflict between file and headers | Stop — do not treat as permissive by default |\n\nFlag:\n\n- **Dual-licensed packages** — which license are we using? The choice may change obligations.\n- **Deprecated packages** — the package is no longer maintained; is there a supported replacement?\n- **Packages with a copyleft dependency in their own tree** — the top-level license is permissive but a transitive dependency is copyleft.\n- **Packages that changed license recently** — Redis, MongoDB, Elastic, HashiCorp — make sure the version pinned is under the license you think it is.\n\n### Step 4: Map obligations to the deployment model\n\nFor each classified dependency, state what the deployment model triggers:\n\n```markdown\n### [package@version] — [License]\n\n**Classification:** [Permissive / Weak copyleft / Strong copyleft / Public domain / Non-OSI / Unknown]\n\n**Obligations for our deployment ([SaaS / binary / internal / embedded]):**\n\n- [ ] [Specific obligation — e.g., \"Include attribution in a NOTICES file shipped with the app\"]\n- [ ] [e.g., \"If we modify and distribute, publish source of our modifications\"]\n- [ ] [e.g., \"AGPL network trigger — if users access our modified version over a network, source must be offered to them\"]\n\n**Risk:** 🔴 Critical | 🟠 High | 🟡 Medium | 🟢 Low\n\n**Recommendation:** [Comply with obligations | Replace with [alternative] | Remove | Attorney review before shipping | Seek commercial license from [vendor]]\n```\n\n> **How is the copyleft dependency consumed?** The linking relationship determines whether copyleft actually triggers. Ask or determine:\n> - **Static linking / compilation together:** The works are combined into one binary. Strong signal that copyleft triggers (LGPL \"work based on the Library,\" GPL derivative work).\n> - **Dynamic linking / shared library:** The works remain separable at runtime. LGPL explicitly permits this (\"work that uses the Library\"). GPL's position is contested (FSF says derivative, others disagree).\n> - **Header inclusion / inline functions:** Can create a derivative work depending on how much is included.\n> - **Subprocess / IPC:** Separate processes communicating over well-defined interfaces. Generally not derivative.\n> - **Network API call:** For most licenses, no. For **AGPL**, the network-interaction clause means serving the software over a network IS distribution. In a microservices architecture, an AGPL component behind an API still triggers.\n> - **File-scope copyleft (MPL):** Only the modified files carry copyleft, not the whole work. Check whether any copyleft files were modified.\n>\n> **The severity rating depends on this.** \"LGPL — weak copyleft, linking rules vary\" without the linking analysis is the answer that gets an engineer sued. Static-linked LGPL in a proprietary product is 🔴 Critical. Dynamic-linked LGPL is 🟢 Low. Same license, opposite rating.\n\n**Severity calibration:**\n\n| Level | Means |\n|---|---|\n| 🔴 Critical | Strong copyleft in a deployment that triggers it (e.g., GPL in a distributed binary, AGPL in a SaaS). Non-OSI license that the business model actually conflicts with (e.g., SSPL while we're building a managed service). License cannot be determined and the package is load-bearing. |\n| 🟠 High | Weak copyleft with obligations the team hasn't set up for (file-level disclosure, NOTICE requirements). Dual-licensed where the chosen license is ambiguous. License file says one thing, headers say another. |\n| 🟡 Medium | Permissive with attribution requirements that haven't been wired into the build (missing NOTICES file, missing LICENSE in distribution). Transitive copyleft in a position that may or may not trigger, depending on how the library is consumed. |\n| 🟢 Low | Permissive with obligations already satisfied. Copyleft in a deployment model that doesn't trigger it (e.g., GPL library used internally only, with no redistribution). |\n\n### Step 5: Flag failure modes\n\nCall out any of the following in a top-of-memo section:\n\n- **License unknown** — classify as \"needs review,\" not permissive. An unclassified dependency should stop a ship decision, not slip through.\n- **License file conflicts with file headers** — read both and report the conflict.\n- **Incompatible combinations** — GPL-2.0 only + Apache-2.0 historically a known incompatibility; check MPL / EPL / GPL combinations carefully.\n- **Non-OSI licenses posing as open source** — SSPL, BUSL, Commons Clause, Elastic License, Confluent Community. Read the license; don't rely on GitHub's \"open source\" badge.\n- **License changes** — if a prior version was permissive and the current version is source-available, the pin matters.\n\n### Step 6: Outbound check (if reviewing our own code before open-sourcing)\n\nIf the user is preparing to open-source code:\n\n- Confirm the chosen outbound license is compatible with every embedded dependency's license (e.g., you cannot release under MIT if you've embedded GPL code — the combined work must be GPL)\n- Confirm LICENSE file is present and correct\n- Confirm NOTICE file is present and lists required attributions (Apache-2.0 and others)\n- Confirm third-party license texts are bundled where required\n- Confirm no proprietary or confidential code, no customer data, no embedded credentials in the repo history\n- Confirm trademark and brand policy for any project name (separate from the copyright license)\n\n### Step 7: Assemble the memo\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` (differs by user role — see `## Who's using this`).\n\nThis memo and any dependency list reviewed may be privileged, confidential, or both. The output inherits that status from the source. Distribute only within the privilege circle; strip the work-product header before any external delivery (including before attaching the memo to an engineering ticket outside the privilege circle).\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for a rule the memo needs (enforceability of AGPL's network trigger in a given jurisdiction, scope of GPL-3.0's patent grant, latest license text for a recently-relicensed package), report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / license / jurisdiction]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Where the memo cites a license text, a court decision interpreting a license, or guidance from a steward (FSF, OSI, SPDX, SFLC), tag the citation: `[OSI]`, `[SPDX]`, `[FSF]`, `[SFC/SFLC]`, `[Westlaw]`, or the MCP tool name for citations retrieved from a connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for license text read directly from the repo. Citations tagged `verify` carry higher fabrication risk. Never strip or collapse the tags.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n# OSS Review: [Project / Dependency List / Package]\n\n**Reviewed:** [date]\n**Scope:** [Dependency list / Single library / Outbound code]\n**Deployment model:** [SaaS / Binary / Internal / Embedded]\n\n---\n\n## Bottom line\n\n[Two sentences. Can this ship? What has to happen first?]\n\n**Packages reviewed:** [N]\n**By classification:** [N permissive, N weak copyleft, N strong copyleft, N public domain, N non-OSI, N unknown]\n**Issues:** [N]🔴 [N]🟠 [N]🟡 [N]🟢\n\n**Approval needed from:** [name, per practice profile]\n\n---\n\n## Top-of-memo flags\n\n[License-unknown list, license-conflict list, non-OSI-posing-as-OSS list, incompatible combinations]\n\n---\n\n## By package\n\n[Blocks from Step 4, grouped by severity]\n\n---\n\n## Jurisdiction note\n\nOSS license enforceability varies — AGPL's network trigger has not been broadly tested in court; GPL-3.0's patent clause reads differently under US vs. EU patent law; dedications to public domain are not universally recognized. State the governing-law choice for any downstream distribution (e.g., vendor agreements incorporating the code) and flag jurisdictions the practice profile marks as escalate.\n\n---\n\n## Outbound check (if applicable)\n\n[From Step 6]\n\n---\n\n## Approval routing\n\n[From practice profile — who approves, what triggers automatic escalation]\n```\n\n## Decision posture\n\nWhen a license cannot be confidently classified, flag it as **\"needs review\"** — do not call it permissive. Under-classifying license risk is a one-way door: a ship decision made on a permissive-by-default assumption becomes a source-disclosure obligation or an injunction months later. Over-flagging is a two-way door — the attorney narrows the list in review.\n\nLikewise, when the copyleft-trigger analysis turns on a contested question (AGPL's \"interacts over a network,\" GPL-3.0's \"conveying,\" the scope of LGPL linking), flag for attorney review and surface the factors cutting both ways.\n\n## Quality checks before delivering\n\n- [ ] Practice profile and any OSS policy were loaded\n- [ ] Deployment model was established before classifying obligations\n- [ ] Every dependency has a classification, including transitives where available\n- [ ] License-unknown packages are flagged, not defaulted to permissive\n- [ ] License text was read (not just metadata) for any copyleft or non-OSI finding\n- [ ] Source tags applied to citations; no stripped `verify` tags\n- [ ] Approver named per practice profile\n- [ ] Output marked with the work-product header\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\nIf the scan surfaced more than ~10 packages, or any time the user asks: offer the dashboard (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs → Dashboard offer for data-heavy outputs`). Shape the offer to what's useful here — counts by license family (permissive / weak copyleft / strong copyleft / AGPL / proprietary / unknown), risk distribution, and a table of findings with severity and package version.", + }, + { + id: "builtin-cfl-ip-portfolio", + title: "Portfolio", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “portfolio” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /portfolio\n\nSurfaces what's renewing, adds assets, records filings, and audits the register.\n\n## Instructions\n\n1. **Follow the workflow below** and read\n the current project's documents.\n\n2. **Default (no args):** equivalent to `--report` — show deadlines in the\n next 90 days grouped by urgency (🔴 lapsed/grace, ⏰ due within window,\n 🟡 upcoming, 🌐 agent-managed, ❓ unknown).\n\n3. **`--report [--days N]`:** Mode 2. Change the window with `--days`\n (30 / 60 / 90 / 180 typical). Always prepend the work-product header\n per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Outputs. Always close with the verification caveat.\n\n4. **`--add`:** Mode 3. Walk through a new asset interactively — type,\n jurisdiction, number, dates, owner, business owner. Capture a custom\n rule if the jurisdiction isn't built in.\n\n5. **`--update`:** Mode 4. Record that a maintenance filing or fee payment\n was made, sync with the IP management system, or change an asset's\n status. Enforce the consequential-action gate before setting any\n deadline to `filed`.\n\n6. **`--audit`:** Mode 5. Broader health check — deadline hygiene,\n registration gaps, use-in-commerce questions on §8-approaching marks,\n owner inconsistencies, expiration horizon, unwatched marks.\n\n7. **If the register is empty and an IP management system is connected:**\n Offer Mode 1 — pull the portfolio from the system of record and\n initialise the register.\n\n8. **Guardrail reminder:** Computed deadlines are reference only. Every\n output closes with a line directing verification against the USPTO\n TSDR, WIPO, or relevant registry before filing or paying. A\n docketed-but-wrong deadline creates false confidence; do not let the\n user treat this as the system of record unless the IP management\n system is sync-integrated.\n\n## Examples\n\n```\nthe “Portfolio” workflow\n```\n\n```\nthe “Portfolio” workflow --report --days 180\n```\n\n```\nthe “Portfolio” workflow --add\n```\n\n```\nthe “Portfolio” workflow --update\n```\n\n```\nthe “Portfolio” workflow --audit\n```\n\n---\n\n## Works better connected\n\nThis skill tracks deadlines from what you tell it. It works much better\nconnected to:\n\n- **An IP management system (IPMS) via MCP** — Anaqua, Clarivate IPfolio,\n AppColl, Patrix, Alt Legal, FoundationIP. A connected IPMS gives you the\n full docket, maintenance fee schedules, and incoming correspondence in one\n place, instead of the register being whatever the lawyer remembers to\n paste. Ask your IPMS vendor if they have an MCP connector, or see\n `CONNECTORS.md` at the repo root for how to get one added.\n- **USPTO directly via customer number** — pulls status, deadlines, and\n correspondence for your whole portfolio rather than one application at a\n time. Not currently available as an MCP; on the wish list in\n `CONNECTORS.md`.\n\nWithout either, paste your docket or upload a spreadsheet and I'll track from\nthere.\n\n## Purpose\n\nA trademark registration that isn't renewed on time can be cancelled. A patent\nwithout its maintenance fee paid lapses. A domain that expires can be sniped\nwithin the hour. All of this is avoidable, and all of it depends on one thing:\nthe right deadline is on someone's calendar, tied to the right registration\nnumber, in the right jurisdiction.\n\nThis skill maintains that calendar.\n\n## Important: deadline reference caveat\n\n> The deadline rules this skill applies reflect publicly available requirements\n> as of the skill's build date. IP office requirements, grace periods, fee\n> structures, and maintenance schedules change. **Always confirm computed\n> deadlines against the USPTO TSDR / Patent Center, WIPO Madrid Monitor /\n> Patentscope, EUIPO eSearch, UKIPO online records, or the relevant national\n> registry before acting.** If you use Anaqua, CPA Global, Clarivate, Alt Legal,\n> or another IP management system, their docket is authoritative for your\n> assets — use this tracker to organize and surface their data, not to replace\n> it.\n>\n> A docketed-but-wrong deadline is worse than an undocketed one: it creates\n> false confidence. \"No deadline soon\" outputs especially deserve a second\n> look before you rely on them.\n\n## Jurisdiction and type assumptions\n\nMaintenance mechanics vary by jurisdiction and asset type:\n\n- **US trademarks:** §8 Declaration of Use between 5th and 6th anniversary of\n registration (or §71 for Madrid designations), then combined §8/§9 renewal\n at 10 years and every 10 years thereafter. §15 Incontestability available\n after 5 years of continuous use. 6-month grace period with surcharge for §8\n and §9; no grace for the underlying use itself.\n- **Madrid International trademarks:** 10-year registration term renewable at\n WIPO; individual designated countries may have local use or declaration\n requirements (e.g., US §71).\n- **EUIPO trademarks:** 10-year renewal; 6-month grace with surcharge.\n- **US utility patents:** Maintenance fees due at 3.5, 7.5, and 11.5 years\n from grant. 6-month grace window with surcharge; after that, potential\n revival by petition if lapse was unintentional.\n- **US design patents:** No maintenance fees — 15-year term from grant for\n applications filed on or after May 13, 2015 (14 years if earlier). No action\n required mid-term.\n- **EPO / national patents:** Annuities typically due annually from filing or\n from national phase entry. National rules vary — confirm per jurisdiction.\n- **US copyright:** No maintenance for works created 1978 or later.\n Pre-1978 works may have had renewal obligations; flag for attorney review\n if the asset pre-dates 1964 (rarely in scope for modern portfolios).\n- **Domains:** Annual or multi-year renewal per registrar; typical 30-day\n grace then redemption period (~30 days at high fee) then drop.\n\nIf the portfolio includes assets in jurisdictions not listed above, capture\nthe maintenance mechanic in the register's `custom_rules` block and the\nreport will surface them as `agent_managed` — confirm status with the\nforeign associate rather than computing a date this skill doesn't understand.\n\n---\n\n## The register\n\nLives at the current project's documents.\nStructure:\n\n```yaml\n# IP Portfolio Register\n# Generated: [date]\n# Last updated: [date]\n# Disclaimer: computed deadlines are reference only — confirm with USPTO/WIPO/\n# relevant registry or the IP management system of record before acting.\n\nmetadata:\n company: \"[Company Name]\"\n generated: \"[date]\"\n last_updated: \"[date]\"\n last_audit: \"[date or null]\"\n source_system: \"[Anaqua / CPA Global / manual / none]\"\n\ncustom_rules: # non-built-in jurisdictions captured manually\n []\n\nassets:\n - id: \"TM-US-001\"\n type: \"trademark\" # trademark / patent / copyright / design / domain\n jurisdiction: \"US\"\n mark_or_title: \"[Mark or title]\"\n owner: \"[Record owner — registered entity name]\"\n status: \"registered\" # pending / registered / lapsed / abandoned / cancelled\n application_number: \"[number or null]\"\n registration_number: \"[number or null]\"\n classes: [\"9\", \"42\"] # Nice classes for TM; CPC/IPC for patents; null otherwise\n filing_date: \"[YYYY-MM-DD or null]\"\n registration_date: \"[YYYY-MM-DD or null]\"\n priority_date: \"[YYYY-MM-DD or null]\"\n grant_date: \"[YYYY-MM-DD or null]\" # patents\n next_deadlines: # computed; refreshed on --report and --audit\n - type: \"§8 Declaration of Use\"\n due_date: \"[YYYY-MM-DD]\"\n grace_end: \"[YYYY-MM-DD or null]\"\n basis: \"5th-6th anniversary of registration\"\n action: \"File §8 Declaration of Use (or excusable nonuse)\"\n status: \"upcoming\" # upcoming / due_soon / overdue / grace / filed\n use_in_commerce: true # TM only — drives §8 analysis\n agent_managed: false # true for foreign associate / outside counsel managed\n local_agent: null\n docket_id: \"[IP-mgmt-system ID or null]\"\n outside_counsel: \"[firm or null]\"\n business_owner: \"[email or team]\"\n notes: \"\"\n\n - id: \"PAT-US-001\"\n type: \"patent\"\n jurisdiction: \"US\"\n mark_or_title: \"[Invention title]\"\n owner: \"[Owner]\"\n status: \"granted\"\n application_number: \"[number]\"\n registration_number: \"[patent number]\"\n filing_date: \"[YYYY-MM-DD]\"\n grant_date: \"[YYYY-MM-DD]\"\n priority_date: \"[YYYY-MM-DD or null]\"\n expiration_date: \"[YYYY-MM-DD]\" # 20 years from earliest non-provisional filing\n next_deadlines:\n - type: \"3.5-year maintenance fee\"\n due_date: \"[YYYY-MM-DD]\"\n grace_end: \"[YYYY-MM-DD]\"\n basis: \"3.5 years from grant\"\n action: \"Pay maintenance fee (small/micro entity if applicable)\"\n status: \"upcoming\"\n claims_count: 20\n entity_size: \"large\" # large / small / micro (drives USPTO fees)\n docket_id: null\n outside_counsel: null\n business_owner: null\n notes: \"\"\n```\n\nStatus values for `next_deadlines`:\n- `upcoming` — more than 90 days out\n- `due_soon` — due within 90 days, not yet filed\n- `overdue` — past the primary due date, within grace window (if any)\n- `grace` — in the grace period (explicit flag — carries surcharge)\n- `lapsed` — past grace with no action; asset effectively lost unless revivable\n- `filed` — action completed this cycle\n\n---\n\n## Mode 1: Initialise\n\nRun when no register exists, or with `--rebuild`.\n\n### Step 1: Determine the source\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n- **IP management system connected** (Anaqua, CPA Global, etc.): pull the portfolio via its integration. The IP system is the authoritative source; this register mirrors it and adds no deadlines the system doesn't already have.\n- **No IP management system, but spreadsheet / export available:** ask the user to share the export. Import what's present; flag any asset missing a registration or grant date as `unknown` for deadline computation.\n- **Nothing at hand:** walk through assets interactively — type, jurisdiction, number, key dates, owner.\n\n### Step 2: For each asset, compute deadlines\n\nApply the rules at the top of this file. Populate `next_deadlines` with the\ntwo or three closest upcoming items — further-out deadlines (10-year renewals\ndecades away) are computed on demand during reports rather than stored\nspeculatively.\n\n**For assets the skill cannot confidently schedule:**\n- Unknown jurisdiction rules → add a stub under `custom_rules` and flag the\n asset `agent_managed: true` with a TODO to confirm with the foreign associate.\n- Missing dates needed for computation (no grant date for a patent, no\n registration date for a TM) → set `next_deadlines` empty with a note in\n `notes`, and list the asset as `unknown` in the initialisation summary.\n\n### Step 3: Write the register\n\nGenerate `portfolio.yaml` at the config path. Show a summary:\n\n```\nPortfolio register initialised.\n\nAssets: [N]\n Trademarks: [N] ([N registered] / [N pending])\n Patents: [N] ([N granted] / [N pending])\n Copyrights: [N]\n Designs: [N]\n Domains: [N]\n\nDeadlines computed: [N]\nAgent-managed / jurisdiction TBC: [N] — confirm with foreign associates\nUnknown (missing key dates): [N] — fill in before relying on reports\n\nRun the “Portfolio” workflow --report to see what's due.\n```\n\n---\n\n## Mode 2: Report\n\n```\nthe “Portfolio” workflow --report [--days 30|60|90|180]\n```\n\nDefault window: 90 days. Refresh computed deadlines for every asset before\nproducing the report — don't rely on stored dates alone.\n\nOutput (prepend work-product header per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Outputs):\n\n```\nIP PORTFOLIO DEADLINE REPORT — [date]\n[Company Name] — window: next [N] days\n\n🔴 LAPSED / IN GRACE ([N])\n [Asset ID] / [Jurisdiction] / [Type] / [Mark or title]\n [Action] — original due [date], grace ends [date]\n Status: [grace / lapsed]\n\n⏰ DUE WITHIN [N] DAYS ([N])\n [Asset ID] / [Jurisdiction] / [Type] / [Mark or title]\n [Action] — due [date]\n Basis: [e.g., \"5th-6th anniversary of registration\"]\n [Agent: firm / docket: id — if present]\n\n🟡 UPCOMING (next window beyond 30 days, within [N] days)\n [list]\n\n🌐 AGENT-MANAGED ([N])\n [Asset ID] / [Jurisdiction] — managed by [local agent]; confirm directly\n [Asset ID] / [Jurisdiction] — no local agent recorded; add with --update\n\n❓ UNKNOWN ([N])\n [Asset ID] — missing [field]; cannot compute deadline\n Confirm with [IP management system / USPTO TSDR / relevant registry] before relying on this report.\n\nSUMMARY\n Total assets tracked: [N]\n Deadlines in window: [N]\n Last audit: [date]\n```\n\nClose the report with the caveat line: *\"Computed from portfolio register. Verify each deadline against the USPTO/WIPO/registry of record before filing or paying.\"*\n\nIf the report lists more than ~10 assets, or any time the user asks: offer the dashboard (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs → Dashboard offer for data-heavy outputs`). Shape the offer for this output — counts by registration status (live / in grace / lapsed / pending), a deadline timeline, and a sortable portfolio table with jurisdiction, type, and next-action date.\n\n---\n\n## Mode 3: Add\n\n```\nthe “Portfolio” workflow --add\n```\n\nInteractive add of a single asset. Ask for:\n1. Type (trademark / patent / copyright / design / domain)\n2. Jurisdiction\n3. Mark or title / invention name\n4. Owner (record owner — matters for §8 filings and assignments)\n5. Key dates (per type: filing, registration, grant, priority, expiration)\n6. Number(s)\n7. Classes / claims count\n8. Source — is this being tracked in the IP management system under a docket ID?\n9. Outside counsel / foreign associate, if any\n10. Business owner (who does this matter to — product line, brand manager)\n\nAfter capture:\n- Compute next deadlines per the rules at the top of this file.\n- If jurisdiction rules aren't built in, walk through the `custom_rules` capture flow (see below).\n- Append to `assets:` in `portfolio.yaml`.\n\n### Custom rules capture\n\nWhen a jurisdiction isn't in the built-in list:\n\n> I don't have maintenance rules for [Jurisdiction] / [Asset type] built in.\n> Let me capture them so we can track this going forward.\n>\n> 1. What maintenance events apply? (Renewal every N years? Annuities annually?\n> Declarations of use? Something else?)\n> 2. What triggers the due date — filing date, registration date, grant date,\n> national phase entry, anniversary of something else?\n> 3. Is there a grace period? At what cost?\n> 4. Is there a foreign associate or local agent managing this?\n\nStore under `custom_rules:` and apply to future assets in that jurisdiction.\n\n---\n\n## Mode 4: Update\n\n```\nthe “Portfolio” workflow --update\n```\n\n### Consequential-action gate\n\n**Before recording that a maintenance filing or fee payment was made:** Read\n`## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Recording a §8 declaration, a §9 renewal, a patent maintenance fee payment,\n> or an international annuity as \"filed\" has consequences. If the record is\n> wrong — missed due date, wrong entity size, wrong specimen of use — the\n> deadline doesn't move, and the asset can still lapse. Have you confirmed\n> this with the attorney or foreign associate who actually made the filing\n> (or with the USPTO TSDR / WIPO Madrid Monitor / relevant registry)? If yes,\n> proceed. If no:\n>\n> - Do not record as filed yet.\n> - Here is what to bring to the attorney: asset ID, jurisdiction, deadline\n> type, what the IP management system shows, what you believe was filed and\n> when, and the source of that belief.\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service\n> is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not set a deadline's `status` to `filed` past this gate without an\nexplicit yes. Status refresh, report generation, and upcoming-deadline\nsurfacing do not require the gate.\n\n### Sub-modes\n\n**Manual update:** \"We filed the §8 for TM-US-001 on March 4, specimen\nattached.\" Update the matching deadline: `status: filed`, `filed_date`,\nand compute the next deadline in its lifecycle (for §8 that's the §9\nrenewal 10 years out).\n\n**From IP management system sync:** If Anaqua / CPA Global / similar is\nconnected, pull the latest docket and reconcile. Flag mismatches between\nthe register and the system of record — the system of record wins; update\nthe register to match and surface anything the register had that the\nsystem doesn't.\n\n**Status change:** \"Mark TM-US-004 as abandoned.\" Update `status`, clear\n`next_deadlines`, note the date abandoned.\n\n---\n\n## Mode 5: Audit\n\n```\nthe “Portfolio” workflow --audit\n```\n\nBroader health check beyond this month's deadlines:\n\n**Deadline hygiene**\n- Any deadlines in `grace` status right now? (In progress but surcharge-costing.)\n- Any `lapsed` assets that aren't marked `abandoned` or `cancelled`? Either\n revive or update status.\n- Any assets with no `next_deadlines` computed? Either missing data or a\n jurisdiction the skill doesn't know.\n\n**Registration gaps**\n- Trademark applications filed more than 18 months ago still `pending`?\n Flag for status check at the office — may need response to an action.\n- Patents filed more than 4 years ago still `pending`? Flag for prosecution\n check.\n\n**Use-in-commerce (TM only)**\n- §8 approaching on a mark flagged `use_in_commerce: false` or uncertain?\n The §8 requires use; mark needs a use audit before filing or an excusable\n nonuse declaration.\n\n**Ownership hygiene**\n- Any assets where the `owner` is not a currently active entity per the\n entity register (if available)? Flag — may need recordal of assignment.\n- Owner name inconsistencies across assets (same entity, different name\n strings)? Surface for cleanup.\n\n**Expiration horizon**\n- Any patents expiring in the next 24 months? Even without a maintenance\n deadline, the business may want to know — product planning, continuation\n strategy, licensing window.\n\n**Unwatched assets**\n- Any registered marks not on the watch list in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Brand protection?\n Flag as a gap for the attorney to decide whether to add.\n\nOutput format:\n\n```\nIP PORTFOLIO AUDIT — [date]\n\nDEADLINE HYGIENE\n In grace: [N] — acting now avoids lapse\n Lapsed (not marked abandoned): [N] — confirm status\n Missing next-deadline computation: [N] — fill data or mark agent-managed\n\nREGISTRATION GAPS\n TM applications pending >18 months: [list]\n Patent applications pending >4 years: [list]\n\nUSE IN COMMERCE (TM)\n §8 approaching on uncertain-use marks: [list]\n\nOWNERSHIP\n Assets with unrecognised owner strings: [N]\n Owner name inconsistencies: [list]\n\nEXPIRATION HORIZON (24 months)\n Patents expiring: [list]\n\nBRAND WATCH\n Registered marks not on watch list: [list]\n\nRECOMMENDED ACTIONS\n 1. [highest priority]\n 2. [etc.]\n```\n\n---\n\n## Integration: ip-renewal-watcher agent\n\nThe `ip-renewal-watcher` agent in this plugin runs this skill on a schedule\n(weekly by default) and posts the Mode 2 report to the channel named in\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Renewal alerts. If 🔴 items appear (grace / lapsed), the agent\nposts them immediately regardless of schedule.\n\n## Handoffs\n\n- Receives: new asset records from prosecution skills (when an application\n is filed or a mark clears), from clearance skills (when a mark is adopted\n and a filing is queued), and from assignment recordals.\n- Sends: \"file §8 now\" triggers to the attorney — this skill doesn't file\n anything; it tells the attorney the deadline and what to bring.\n\n## What this skill does not do\n\n- It does not file anything. Every action it surfaces is for the attorney\n or foreign associate to execute.\n- It does not verify deadlines against the USPTO TSDR, WIPO, or any other\n registry. It computes them from the dates you give it. The register is\n a working copy; the registry is the source of truth.\n- It does not decide whether to renew. Renewal is a business call — is the\n mark still in use, is the patent still valuable, does the domain still\n matter. This skill surfaces the deadline and the cost; the business and\n the attorney decide.\n- It does not replace an IP management system for multi-hundred-asset\n portfolios. Anaqua, CPA Global, Clarivate, Alt Legal, and similar systems\n have direct registry feeds, deadline automation, and annuity payment\n services. This skill is best suited for smaller portfolios, or as a\n lightweight layer that surfaces what the system of record shows.\n- It does not read office records to verify status. A §8 shown as \"filed\"\n here means someone told it so — not that the USPTO accepted it. Confirm\n acceptance through TSDR or the IP management system.", + }, + { + id: "builtin-cfl-ip-takedown", + title: "Takedown", + practice: "Intellectual Property", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “takedown” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /takedown\n\nThree modes. Pick one:\n\n- `the “Takedown” workflow --send` — draft a §512(c)(3) takedown notice. Fair-use gate (*Lenz*) + loud perjury / §512(f) gate before delivery.\n- `the “Takedown” workflow --respond` — triage a takedown someone sent you. Options: comply / counter / engage / ignore.\n- `the “Takedown” workflow --counter` — draft a §512(g)(3) counter-notice. Loud gate for the federal-jurisdiction admission and the perjury statement.\n\n## Instructions\n\n1. **Read the practice profile.** Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If it contains `[PLACEHOLDER]` markers or does not exist, stop and say: \"This plugin needs setup before it can give you useful output. Run `configure your Practice Profile (Account → Practice Profile)` — the takedown skill depends on your approval matrix and practice profile.\"\n\n2. **Check matter workspaces.** Per `## Matter workspaces`: if `Enabled` is `✗`, skip. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\"\n\n3. **Dispatch on `$ARGUMENTS`:**\n - `--send` → run send mode (below). Walk identify-the-work, identify-the-infringing-material, fair-use gate (*Lenz*), good-faith belief, accuracy/authority, draft the §512(c)(3) notice, run the loud gate, write output.\n - `--respond` → run respond mode (below). Read the incoming notice, assess (license, fair use, defects, host §512(g) compliance, sender credibility), present the four options, recommend, write the triage memo.\n - `--counter` → run counter mode (below). Confirm the predicate (taken down in response to a §512 notice, good-faith belief of mistake/misidentification, ready for federal-jurisdiction admission, attorney in the loop), draft the §512(g)(3) counter-notice, run the loud gate, write output.\n - No flag → ask once: \"Are we sending a DMCA takedown, triaging one we received, or drafting a counter-notice?\"\n\n4. **Respect the gates.** In `--send` and `--counter`, the loud gate runs before any final output is written. The fair-use gate in `--send` is separate and runs earlier; \"debatable\" or \"likely\" fair use stops the draft and routes to attorney review.\n\n5. **Jurisdiction note.** DMCA §512 is US federal law. If the service provider, content, or infringer sits outside US jurisdiction, flag before drafting — you may need an EU DSA notice, UK OSA notice, or local-regime instrument instead of (or in addition to) a DMCA notice.\n\n6. **Hand off where appropriate.** `--respond` with a counter-notice recommendation chains into `the “Takedown” workflow --counter` — but only after the triage memo has been reviewed and the decision to counter has been made deliberately.\n\n## Examples\n\n```\nthe “Takedown” workflow --send\nthe “Takedown” workflow --respond ~/Downloads/youtube-takedown-notice.pdf\nthe “Takedown” workflow --counter\nthe “Takedown” workflow\n```\n\n## Notes\n\n- The outgoing notice and counter-notice do not carry the work-product header. Internal drafts, fair-use analyses, and triage memos do.\n- §512(c)(3) and §512(g)(3) are element-by-element statutes — every required element must be present or the notice is defective.\n- Counter-notices consent to federal court jurisdiction in the claimant's district (or a designated district for non-US subscribers). This is not a formality.\n- Non-lawyer users get a one-page brief for the attorney conversation before the gate clears — particularly important for counter-notices, which are the step before litigation.\n\n---\n\n## Purpose\n\nThe DMCA §512 notice-and-takedown system is fast, cheap, and consequential in equal measure. A takedown is a sworn statement under penalty of perjury that gets content pulled with no judicial review. A counter-notice is another sworn statement that consents to federal jurisdiction and puts the content back. Both decisions can become litigation. This skill handles all three moves with the guardrails each warrants.\n\nThree modes:\n\n- `--send` — draft a §512(c)(3) takedown notice\n- `--respond` — triage a takedown someone sent you; produce options\n- `--counter` — draft a §512(g)(3) counter-notice\n\nIf the user does not pass a flag, ask once: \"Are we sending a DMCA takedown, triaging one we received, or drafting a counter-notice?\"\n\n> **External deliverables (send and counter modes):** the outgoing notice/counter-notice goes to the service provider's designated agent. Do NOT include the `PRIVILEGED & CONFIDENTIAL — ATTORNEY WORK PRODUCT` header on the outgoing document. The notice itself is not privileged — it's a statement made in a statutory process. Internal drafts, pre-send briefs, fair-use analyses, and triage memos keep the header per plugin config `## Outputs`.\n\n## Jurisdiction assumption\n\nDMCA §512 is **US federal law**. It runs against service providers subject to US jurisdiction. Other jurisdictions have their own notice-and-action regimes — EU Digital Services Act Art. 16, UK Online Safety Act, India IT Rules 2021, etc. — that differ materially in required elements, counter-notice mechanics, and liability for misuse. If the service provider, content, or infringer sits outside US jurisdiction, flag it — a US DMCA notice may be the wrong instrument, or may need to be paired with a local regime's notice. Copyright subsistence itself is Berne-multilateral, but enforcement mechanics are jurisdiction-specific.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## IP practice profile` (copyright registrations if any), `## Enforcement posture` → `Approval matrix → DMCA takedown (ordinary)` row, `## Outputs` (work-product header, role), `## Who's using this` (role — lawyer vs. non-lawyer)\n- **Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (in-house default), skip matter machinery. If enabled and no active matter, ask: \"Which matter? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Write outputs to the active matter's folder at the current project's documents (or `takedown//` at practice level). Never read another matter's files unless `Cross-matter context` is `on`.\n\n## Send mode — drafting a §512(c)(3) takedown notice\n\n### Step 1: Identify the copyrighted work\n\n> What is the copyrighted work?\n>\n> - **Title / description** — what is the work (software, image, text, video, audio)?\n> - **Registration status** — US Copyright Office registration number and date (if any). Registration is NOT required to send a takedown, but it is required to file suit on a US work and its pre-infringement timing controls statutory damages and fees.\n> - **Ownership** — do we own it outright, or hold an exclusive license with takedown authority? (Non-exclusive licensees typically cannot send takedowns on the licensor's work.)\n> - **Prior licensing** — have we ever licensed this use, or a broader use that might cover it?\n\nOwnership and authority are the first things §512(f) cases look at. Get them clearly on the record before drafting.\n\n### Step 2: Identify the infringing material and its location\n\n> Where is the infringing material?\n>\n> - **Platform / service provider** — YouTube, Twitter/X, GitHub, Reddit, Amazon, a web host, etc.\n> - **URL(s)** — specific permalinks to the infringing material. One notice can cover multiple URLs if they're all from the same service.\n> - **Description** — what is the infringing material and how does it infringe (verbatim copy, substantially similar, derivative)?\n> - **Screenshots / evidence** — preserved with timestamp and URL visible\n\n§512(c)(3) requires \"information reasonably sufficient to permit the service provider to locate the material.\" URLs alone are usually enough; be precise.\n\n### Step 3: Fair-use gate\n\nUnder *Lenz v. Universal Music Corp.*, 801 F.3d 1126 (9th Cir. 2015), a copyright holder must consider fair use before sending a takedown. This is not a judgment about fair use — it is a consideration step that the sender must take and can prove they took.\n\nAsk:\n\n> Before we draft the notice, walk through fair use. Under *Lenz*, you have to consider it before sending — even if the conclusion is \"not fair use.\" The four factors:\n>\n> 1. **Purpose and character** — commercial? transformative? criticism, comment, news reporting, teaching, scholarship, research?\n> 2. **Nature of the copyrighted work** — factual or creative? published or not?\n> 3. **Amount and substantiality** — how much of the work is used? is it the heart of the work?\n> 4. **Effect on the market** — does the use substitute for the original or harm a derivative market?\n>\n> Your read on each? And your conclusion — fair use unlikely, debatable, likely?\n\nRecord the answer in the notice file. If \"debatable\" or \"likely,\" do not draft. Stop and route to attorney review: \"Fair use is debatable/likely on these facts. Sending a takedown on a use that is protected by fair use is the exact §512(f) exposure the statute creates. Route this to counsel before any notice goes out.\"\n\n### Step 4: Good-faith belief\n\n§512(c)(3)(A)(v) requires \"a statement that the complaining party has a good faith belief that use of the material in the manner complained of is not authorized by the copyright owner, its agent, or the law.\"\n\nThe sender forms this belief on the record. Have they:\n\n- Confirmed the work is theirs (or they have takedown authority via exclusive license)?\n- Confirmed the use is not licensed (no prior deal, no implied license, no Creative Commons grant that would cover it)?\n- Considered fair use (Step 3)?\n- Reviewed the accused content directly (not just a report about it)?\n\nIf yes on all four, the good-faith belief is colorable. If no on any, pause.\n\n### Step 5: Accuracy and agent authority\n\n§512(c)(3)(A)(vi) requires \"a statement that the information in the notification is accurate, and under penalty of perjury, that the complaining party is authorized to act on behalf of the owner of an exclusive right that is allegedly infringed.\"\n\nThis is the perjury statement. It applies to the accuracy of the identification and the authority — not to the fair-use determination itself, though §512(f) liability reaches both.\n\nConfirm signer: who is sending this on behalf of whom, and do they have authority to do so?\n\n### Step 6: Draft the notice\n\n§512(c)(3)(A) elements — every one must be present:\n\n1. **Signature** (physical or electronic) of the rights holder or authorized agent\n2. **Identification of the copyrighted work** — \"Copyrighted work: [title, description, registration no. if any]\"\n3. **Identification of the infringing material** with location information — \"Infringing material: [URL(s), description, how it infringes]\"\n4. **Contact information** — address, phone, email of the complaining party or agent\n5. **Good-faith belief statement** — verbatim, adapted: \"I have a good faith belief that use of the copyrighted material described above is not authorized by the copyright owner, its agent, or the law.\"\n6. **Accuracy and authority statement under penalty of perjury** — verbatim, adapted: \"I swear, under penalty of perjury, that the information in this notification is accurate and that I am the copyright owner, or am authorized to act on behalf of the owner, of an exclusive right that is allegedly infringed.\"\n\nStructure:\n\n- Sender address block / date\n- Recipient: designated DMCA agent at [service provider] (find via Copyright Office's DMCA Designated Agent Directory — `https://www.copyright.gov/dmca-directory/`)\n- Re: Notice of Copyright Infringement pursuant to 17 U.S.C. §512(c)\n- The six elements above, numbered or clearly set apart\n- Signature line\n\nMost service providers publish a preferred form or a web intake (YouTube Content ID / Copyright webform, Twitter / X copyright report, GitHub DMCA repo, etc.). The skill produces the notice content; the user submits through the provider's path. Note in the output which intake path is expected for the named service provider.\n\n### Step 7: The loud gate before delivery\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ BEFORE THIS TAKEDOWN GOES ANYWHERE │\n├─────────────────────────────────────────────────────────────┤\n│ │\n│ A DMCA takedown is a statement under penalty of perjury. │\n│ Signing and sending it is not a routine administrative │\n│ step — it is a sworn declaration with specific legal │\n│ consequences. │\n│ │\n│ • 17 U.S.C. §512(f) creates LIABILITY for knowing │\n│ material misrepresentations. People have been sued, │\n│ and have lost, for bad-faith takedowns — *Lenz v. │\n│ Universal*, 801 F.3d 1126 (9th Cir. 2015); *Online │\n│ Policy Group v. Diebold*, 337 F. Supp. 2d 1195 (N.D. │\n│ Cal. 2004); *Stephens v. Clash*, 796 F.3d 281 (3d │\n│ Cir. 2015). │\n│ │\n│ • The accuracy and authority statement is sworn under │\n│ penalty of perjury. That is a real statement, not a │\n│ formality. │\n│ │\n│ • Sending a takedown on material that is in fact │\n│ licensed, owned by someone else, or fair use is the │\n│ fact pattern §512(f) was written for. │\n│ │\n│ Confirm before the notice leaves: │\n│ │\n│ 1. You own the copyright, or you hold an exclusive │\n│ license with takedown authority. │\n│ 2. The accused use is not authorized — you have │\n│ checked licenses, grants, and any prior consents. │\n│ 3. You considered fair use per *Lenz* (see Step 3 of │\n│ this draft); your conclusion is on the record. │\n│ 4. Whoever has authority to sign approves sending. │\n│ │\n│ Approver per your practice profile: [approver from │\n│ Enforcement posture → Approval matrix → DMCA takedown │\n│ (ordinary) row] │\n│ │\n│ Automatic escalations that apply here: [list any from │\n│ the practice profile that this matter triggers] │\n│ │\n└─────────────────────────────────────────────────────────────┘\n```\n\nIf the user is a non-lawyer (per `## Who's using this`), add:\n\n> A DMCA takedown is sworn under penalty of perjury and creates §512(f) exposure for bad-faith or overbroad use. Have you reviewed this with an attorney? If not, here's a brief to bring to them: [generate a short summary: work, ownership, accused use, licensing check, fair-use analysis, signer, service provider]. A few thousand dollars of attorney time now is materially cheaper than a §512(f) suit.\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent); ABA IP section referral roster (US); law school IP clinics for individual creators and small businesses.\n\nDo not write the final output without explicit engagement with the gate.\n\n### Step 8: Output\n\n**Primary:** `/takedown//notice-v.md` (or .docx if the service provider accepts it — most accept pasted text or web-form submission). The notice content, ready to paste into the service provider's DMCA intake form or send to its designated agent.\n\n**In-chat:** show the notice as plain text for review before writing. Iterate before committing to disk.\n\n**Reviewer-facing closing note** (in the in-chat preview only):\n\n> This is a draft DMCA notice for attorney review, not a notice ready to send. Sending it is a sworn statement with §512(f) exposure. A licensed attorney reviews, edits, and takes professional responsibility before submission. Do not send this unreviewed.\n\n**Citation verification.** Any case or statutory citation included (for example, in internal memoranda around the notice) must be verified on a legal research tool. Source-tag each — `[Westlaw]`, `[CourtListener]`, `[user provided]`, `[model knowledge — verify]`, `[web search — verify]`. Citations tagged `verify` get checked first. No silent supplement from web or model knowledge if a configured research tool comes up thin — present options to the user.\n\n**Post-send record.** After submission, write `/takedown//submission.md`: service provider, designated agent used (address or web form URL), date submitted, confirmation ID if returned, URLs targeted, counter-notice watch date (generally 10–14 business days), legal hold refreshed.\n\n## Respond mode — triaging a takedown you received\n\nYour content was taken down. A service provider has notified you of a §512(c)(3) notice. You have options.\n\n### Step 1: Read the notice you received\n\nExtract:\n\n- **Sender** — entity, signer, address, email\n- **Service provider** — who notified you (the platform)\n- **Claimed work** — what they say is theirs\n- **Your content alleged to infringe** — URL(s) or identifiers as they named them\n- **Date of takedown / notice**\n- **Whether the notice appears to meet §512(c)(3) on its face** — flag missing elements; a defective notice is not a proper notice\n\n### Step 2: Assess\n\n- **Do we have a license?** Negotiated, implied, Creative Commons, prior settlement, assignment — anything that authorizes the use.\n- **Is it fair use?** Walk the *Lenz* four factors. Be honest; this is for us, not the response.\n- **Is the notice defective?** Missing any of the §512(c)(3)(A) elements, lacking the perjury statement, signed by someone without apparent authority? Defective notices are not properly compliant; the host may still act on them but the sender's §512(f) exposure rises and our leverage rises.\n- **Did the host comply properly with §512(g)?** Were we given notice and an opportunity to counter? If the host acted without giving us the chance, that is a separate issue with the host (not the sender).\n- **Is the sender a troll?** Repeat pattern of overbroad takedowns on this platform?\n\n### Step 3: Options\n\nPresent 4 options with tradeoffs:\n\n**A — Comply (let the takedown stand)**\n- When: they're right, or the fight isn't worth it\n- Tradeoff: content stays down; may affect SEO, accounts with strikes policies, livelihood for creators\n- Next step: log the event, confirm no counter-notice deadline issues, move on\n\n**B — Send a counter-notice** (§512(g)(3))\n- When: we have a good-faith belief the material was misidentified or removed by mistake — often applies where the use is licensed, fair use, or the sender doesn't own the work\n- Tradeoff: sworn under penalty of perjury, consents to federal court jurisdiction in the sender's district (or our own if outside the US and we designate), puts the decision in the sender's hands for 10–14 business days — if they sue, content stays down; if they don't, content is restored\n- Next step: `the “Takedown” workflow --counter`\n\n**C — Engage the sender directly**\n- When: there's room for a business resolution (license, credit, takedown of a narrower portion)\n- Tradeoff: the content stays down during the conversation; settlement-communication hygiene matters (FRE 408 or equivalent; protection from substance and context, not labeling)\n- Next step: outreach letter to the sender; do not send the counter-notice while discussions are live\n\n**D — Ignore and let it stand; raise it elsewhere**\n- When: the harm is small, we don't want the federal-jurisdiction admission, and we'd rather deal with the sender separately\n- Tradeoff: content stays down; if the takedown itself was bad-faith, we may have §512(f) to assert on our own schedule — but that's its own fight\n\nRecommend one with two sentences of rationale.\n\n### Step 4: Write triage memo\n\nOutput: `/takedown/inbound//triage.md`.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n> **Privilege inheritance.** This triage records our first-pass assessment of an adverse takedown. It is attorney-client and/or work-product material. Do not forward outside the privilege circle or attach to counter-notice submissions without scrubbing.\n\n# DMCA Takedown Received — Triage\n\n> **READ FOR TRIAGE, NOT OPINION.** Structured intake scan, not a legal merit opinion. Every authority flagged for SME verification; every merit call is counsel's.\n\n**Slug:** [slug]\n**Received:** [YYYY-MM-DD]\n**Service provider:** [platform]\n**Incoming file:** [path]\n\n## The notice\n\n**Sender:** [entity, signer, counsel if any]\n**Claimed work:** [title, description, reg no. if provided]\n**Our content targeted:** [URLs / identifiers]\n**Date of takedown:** [YYYY-MM-DD]\n**Notice meets §512(c)(3) on its face:** [yes / no — list any missing elements]\n\n## Assessment\n\n**License / authorization check:** [read]\n**Fair use walkthrough (Lenz factors):** [read — each factor + conclusion; `[SME VERIFY]`]\n**Notice defects:** [list or none]\n**Host compliance with §512(g):** [were we given notice and opportunity]\n**Sender credibility:** [troll / real claimant / repeat takedown pattern]\n\n## Options\n\n### A. Comply\n### B. Counter-notice (§512(g)(3))\n### C. Engage sender\n### D. Ignore\n\n**Recommendation:** [A/B/C/D] — [two sentences why] — `[SME VERIFY: counsel to confirm before executing]`\n\n## Deadlines\n\n- **Counter-notice watch window:** 10–14 business days after counter-notice is submitted — content stays down if sender files suit in that window\n- **Sender's suit filing timing:** typically on our counter-notice clock, if we counter\n- **Any contractual deadlines with the host:** [check]\n\n## Immediate actions\n\n- [ ] Legal hold issued on the accused work and our related content — [yes/no]\n- [ ] Business impact assessed (revenue, account strikes, SEO) — [yes/no]\n- [ ] Matter created in log — [yes/no/TBD]\n- [ ] Counsel assigned — [who]\n```\n\nClose the in-chat presentation with:\n\n> This is a triage memo, not advice. The assessments above are a first read from the four corners of the notice. An attorney evaluates before you counter-notice (which consents to federal jurisdiction) or decide not to respond.\n\n## Counter mode — drafting a §512(g)(3) counter-notice\n\nCounter-notices put content back up unless the original sender sues within 10–14 business days. They are the step before litigation.\n\n### Step 1: Confirm the predicate\n\n- The content was taken down in response to a §512 notice (not a terms-of-service action by the host).\n- You have a good-faith belief the material was removed by mistake or misidentification — the statutory test.\n- You are prepared to consent to federal court jurisdiction in the original sender's district (or designate if you are outside the US).\n- The decision has been made deliberately — not in reaction, not without attorney input.\n\n### Step 2: Draft per §512(g)(3)\n\n§512(g)(3) elements — every one must be present:\n\n1. **Signature** (physical or electronic) of the subscriber\n2. **Identification of the material removed** and its location before removal (the URL where the content was)\n3. **Statement under penalty of perjury that the subscriber has a good faith belief the material was removed or disabled as a result of mistake or misidentification** — verbatim, adapted\n4. **Subscriber's name, address, telephone number** — and, critically, **consent to the jurisdiction of the federal district court** for the district where the subscriber's address is located (or, if outside the US, any district in which the service provider may be found), and acceptance of service of process from the person who provided notification or that person's agent\n\nStructure:\n\n- Subscriber address block / date\n- Recipient: designated DMCA agent at the service provider (same agent that received the original takedown)\n- Re: Counter-Notification pursuant to 17 U.S.C. §512(g)\n- The four elements above, numbered or clearly set apart\n- Signature line\n\n### Step 3: The loud gate before delivery\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ BEFORE THIS COUNTER-NOTICE GOES ANYWHERE │\n├─────────────────────────────────────────────────────────────┤\n│ │\n│ A DMCA counter-notice is a statement under penalty of │\n│ perjury AND consents to federal court jurisdiction. It │\n│ is the step before litigation. │\n│ │\n│ • If the original claimant files suit within 10–14 │\n│ business days after your counter-notice, the content │\n│ stays down pending the suit. 17 U.S.C. §512(g)(2)(C). │\n│ │\n│ • If they do not sue within the window, the host must │\n│ restore the content within 14 business days of your │\n│ counter-notice. │\n│ │\n│ • You are consenting to be sued in federal court in the │\n│ claimant's judicial district (or, if you are outside │\n│ the US, designating a district). This is a jurisdiction │\n│ admission you make by signing. │\n│ │\n│ • The perjury statement is real. §512(f) liability runs │\n│ in both directions — senders and counter-senders. │\n│ │\n│ Confirm before the counter-notice leaves: │\n│ │\n│ 1. The material was removed in response to a §512 │\n│ notice (not a TOS action). │\n│ 2. You have a good-faith belief the removal was a │\n│ mistake or misidentification — because the use is │\n│ licensed, fair use, not actually infringing, or the │\n│ sender doesn't own the work. │\n│ 3. You are prepared to be sued in federal court in the │\n│ claimant's district. Budget, counsel, and risk │\n│ tolerance are all set. │\n│ 4. An attorney has reviewed this before it is sent. │\n│ │\n│ Approver per your practice profile: [approver from │\n│ Enforcement posture → Approval matrix — counter-notices │\n│ generally route above the DMCA takedown (ordinary) │\n│ approver because of the federal-jurisdiction admission] │\n│ │\n└─────────────────────────────────────────────────────────────┘\n```\n\nIf the user is a non-lawyer:\n\n> A counter-notice consents to federal court jurisdiction and is sworn under penalty of perjury. Have you reviewed with a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction? This is not the Claude-review layer; this is the step where you need licensed professional judgment. Brief for the conversation: [generate a 1-page summary]. Referral resources: your professional regulator's referral service (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent); law school IP clinics; ABA IP section (US).\n\nDo not write the final output without explicit engagement.\n\n### Step 4: Output\n\n**Primary:** `/takedown//counter-notice-v.md` — the counter-notice content, ready to submit via the service provider's counter-notice intake.\n\n**In-chat:** present as plain text for review before committing.\n\n**Reviewer-facing closing note** (in-chat only):\n\n> This is a draft counter-notice for attorney review, not a counter ready to send. Sending it is a sworn statement and consents to federal court jurisdiction in the claimant's district. A licensed attorney reviews before submission. Do not send this unreviewed.\n\n**Post-submission record.** After submission, write `/takedown//counter-submission.md`: service provider, date submitted, confirmation ID, 10–14 business-day watch window end date calendared, watch for suit filing in the claimant's district, plan if content is restored, plan if suit is filed.\n\n## Decision posture\n\nPer `## Decision posture on subjective legal calls` in the practice profile: when uncertain whether the use is fair, whether the rights holder is us, whether the work is actually ours, whether fair use defeats the claim on the receiving side — do not silently decide. Fair use is the paradigmatic uncertain call. Flag for attorney review; surface the factors. Sending a takedown or a counter-notice on an assumption is a one-way door.\n\n## What this skill does not do\n\n- **Submit the notice.** Drafting only. The user submits through the service provider's designated channel.\n- **Pick a service provider's intake form for the user.** Notes which path is expected; does not auto-submit.\n- **Decide fair use.** Walks the four factors; flags. An attorney decides whether to proceed.\n- **Validate the sender's claim on the receive side.** Structured read; every authority flagged for SME verification.\n- **Bypass the gate.** The gate runs every time in `--send` and `--counter` modes.\n- **Invent citations.** Any cites included are source-tagged and flagged for verification; no silent supplement.\n- **Handle non-US regimes.** DMCA is US-specific. For EU DSA, UK OSA, India IT Rules, and other regimes — flag and route.", + }, + { + id: "builtin-cfl-lawstudent-bar-prep-questions", + title: "Bar Prep Questions", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “bar-prep-questions” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /bar-prep-questions\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → bar jurisdiction, exam format (NextGen / traditional UBE / state-specific), weak subjects, prep course.\n2. Also load the current project's documents if it exists — it tells you what subject is scheduled for today and what subtopics are still weak.\n3. Apply the framework below.\n4. **Exam-type gate (do not skip).** If exam format or jurisdiction isn't in the practice profile, ask before generating anything. The NextGen Bar Exam and the traditional UBE test materially different subjects — studying the wrong list is the one mistake that isn't recoverable. Point the student at the NCBE's jurisdiction page () to confirm their exam format and subject scope.\n5. **Jurisdiction-rule gate.** If the student's jurisdiction has a state-specific component (CA, LA, NY Law Exam, FL state essay, VA, etc.) AND the subject is one where majority-vs-state rules diverge (Evidence, PR, Civ Pro, Criminal), ask whether this session is UBE/majority-rule, state-specific, or mixed. Do not silently default.\n6. Generate questions **scoped to subjects tested on the student's exam**, weighted toward weak subjects. Label each question by rule body (`[UBE/majority]` or `[CA-specific]` / `[NY-specific]` / etc.) when running mixed.\n7. When rules diverge between UBE/majority and the student's jurisdiction, explain the split explicitly in the answer — see `## Jurisdiction handling` below.\n8. After each answer: explain why right/wrong. Track patterns in misses.\n9. `--session ` runs a focused N-question session and writes results to `study-plan.yaml` under `session_history`.\n\n---\n\n## Real-matter check\n\nIf the question the student is asking sounds like it's about a REAL situation — their lease, their parking ticket, their family's business, their friend's arrest, a real dollar amount, a real deadline, a real party name — stop.\n\n> \"This sounds like a real situation, not a hypothetical. I can't give you legal advice, and you can't give it either — you're not a lawyer yet. If this is real, [the person] needs an actual lawyer: legal aid, your school's clinic, a lawyer referral service (your jurisdiction's bar association, law society, or legal aid body), or (if there's money) a private attorney. I'm happy to help you understand the general legal concepts involved, but that's study, not advice.\"\n\nWatch for: real names, real addresses, real dates, specific dollar amounts, \"my landlord/boss/parent/friend,\" \"I got a ticket/letter/notice,\" deadlines measured in days. Any one of these is a trigger.\n\n## Purpose\n\nThe bar exam tests a defined body of subjects. This skill drills you on them — weighted toward your weak spots.\n\n## Exam type — ask first, do not assume\n\n**The bar exam is in transition.** As of the July 2026 administration, the NextGen Bar Exam (developed by the NCBE) has launched in some jurisdictions, while others continue to administer the traditional Uniform Bar Exam (UBE). State-specific exams (California, Louisiana, Puerto Rico, etc.) are their own thing. The subject scope is materially different between the NextGen and the traditional UBE — **subjects no longer independently tested on the NextGen include Trusts & Estates, Family Law, Conflict of Laws, and Secured Transactions** (some underlying concepts may appear inside integrated \"foundational concepts and skills\" questions, but they are not standalone tested subjects the way they were on MEE).\n\nDo not assume the subject list. Before generating any questions:\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) and read the bar jurisdiction and bar date.\n2. If the practice profile does not specify which exam format the student is sitting for (NextGen / traditional UBE / state-specific), **ask**:\n\n > Which bar exam are you sitting for?\n > 1. **NextGen Bar Exam** (NCBE, launched July 2026 in some jurisdictions)\n > 2. **Traditional Uniform Bar Exam (UBE)** (MBE + MEE + MPT)\n > 3. **State-specific exam** (California, Louisiana, Puerto Rico, Washington, etc. — tell me which)\n >\n > And which jurisdiction? The scope of what's tested depends on both.\n\n3. **Point the student at the authoritative source.** Jurisdiction-by-jurisdiction exam format (and whether a given state has moved to NextGen) is on the NCBE's website at under \"Exams\" → jurisdiction information. The NextGen subject outline lives at . The traditional UBE subjects (MBE and MEE) are at and .\n\n> **Verify your jurisdiction's exam format and subject list against the NCBE's current outline before studying. This is the single most important thing you can get right** — studying the wrong subject list is the one mistake this skill can't undo for you. If your prep course (Barbri/Themis/Kaplan) and the NCBE outline disagree, go with the NCBE outline and tell your prep course.\n\nScope every question-generation session to the subjects actually tested on the student's exam. If the practice profile lists a weak subject that is not tested on their exam (e.g., Secured Transactions for a NextGen jurisdiction), flag it:\n\n> You listed Secured Transactions as a weak essay subject, but the NextGen Bar Exam doesn't test it as a standalone subject. Do you want to (a) skip it, (b) drill the UCC Article 9 concepts that may appear inside integrated NextGen questions, or (c) drill it anyway because you're curious / auditing the area?\n\n## Jurisdiction handling\n\nThe bar exam is not one exam. It is a family of exams. Rules that are \"correct\" on one are \"wrong\" on another. Getting this right matters more than almost anything else this skill does.\n\n### Two things to distinguish\n\n1. **Exam structure.** What does the student's jurisdiction administer?\n - **Pure UBE** jurisdictions: MBE + MEE + MPT, one set of rules, no state-specific content tested.\n - **UBE + state-specific component:** many UBE states require a separate state law component (e.g., NY Law Exam, DC Mandatory Course). These are pass/fail or supplementary, not graded into the UBE score.\n - **Non-UBE state-specific exams:** California runs its own exam (GBX + essays with California-specific subjects — Community Property, CA Civil Procedure/Evidence distinctions, CA Professional Responsibility — plus a Performance Test). Louisiana runs a civil-law exam that shares almost nothing with the UBE. Florida, Virginia, and several others keep state-specific essay days alongside or instead of the MEE.\n - **NextGen jurisdictions** (rolling out starting July 2026): integrated foundational concepts format, drops Trusts & Estates / Family Law / Conflict of Laws / Secured Transactions as standalone tested subjects.\n\n Before generating questions, confirm structure via the `## Exam type` gate above. Do not assume.\n\n2. **Rule content — where majority rule, UBE default, and the student's jurisdiction's rule can diverge.** Common divergence areas:\n - **Criminal law:** common-law vs. MPC vs. state code (e.g., CA Penal Code on murder degrees, felony murder scope, consent defenses).\n - **Evidence:** FRE vs. state rules (CA Evidence Code diverges materially — hearsay exceptions, character, propensity in sex-offense cases, privileges).\n - **Civil procedure:** FRCP vs. state (CA Code of Civil Procedure — 170.6 peremptory challenges, demurrers vs. 12(b)(6), different discovery scope).\n - **Community property states** (CA, TX, AZ, NV, NM, WA, ID, LA, WI): tested on state-specific essays in CA; irrelevant on pure UBE.\n - **Professional responsibility:** MPRE tests ABA Model Rules; CA tests California Rules of Professional Conduct (which diverge on confidentiality, conflicts, fees).\n\n### Rule when generating questions\n\nFor every question, internally classify by which body of rules applies:\n\n- **General / federal / majority-rule questions** (MBE-style, federal courts, FRE, FRCP, constitutional, common-law core): the \"correct answer\" is the UBE/majority rule. State.\n- **Jurisdiction-specific questions** (CA PR, CA Evidence, community property, LA civil code, NY Law Exam topics): the \"correct answer\" is the student's jurisdiction's rule. State that.\n\n### Divergence tags — per-rule, not per-subject\n\n**Tag divergences at the rule level, not the subject level.** \"[CA does not materially diverge on this rule]\" stamped on every question in a subject is noise — a student sees the same tag on every Contracts question and stops reading. Scope the tag to the specific rule being tested.\n\nRules to apply when emitting divergence tags:\n\n- If the specific rule tested in a question has no material CA/NY/LA/etc. divergence, tag **at the rule level** within that question: `[CA does not diverge on UCC § 2-207 — this answer holds on the CA bar.]`\n- If the specific rule tested has a material divergence, fire the `**Your jurisdiction (X) diverges:**` block per the format above. Do not use a subject-level tag when a rule-level divergence exists.\n- Do NOT blanket-apply a subject-level tag like \"[CA does not materially diverge on this subject]\" across all questions in a subject. Contracts-as-a-subject has both divergent rules (CA statute of frauds specific carve-outs, CA-specific consumer contract rules) and non-divergent ones (UCC § 2-207, Restatement § 71 consideration), and stamping them all with the same tag hides the divergences that matter.\n- If a question is CA-specific by construction (e.g., a CA Community Property question on a state-specific essay day), skip the tag — the CA-specific framing is already explicit.\n\nShort rule: the tag lives inside the question (at the rule being tested), not outside it (at the subject level).\n\n### Rule when the rules diverge\n\nWhen a question's answer differs between the majority/UBE rule and the student's jurisdiction's rule, the explanation must say so explicitly:\n\n```markdown\n**Correct: C**\n\n**Why C (UBE/majority rule):** [rule + application]\n\n**Your jurisdiction (CA) diverges:** Under [California Evidence Code § X / CRPC Rule Y / CA Penal Code § Z], the rule is [jurisdiction-specific rule]. Under that rule, the answer would be [A/B/C/D].\n\n**On the bar exam:** On the MBE and MEE portions, the default answer is the UBE/majority rule unless the question tells you to apply state law. On a state-specific essay day (e.g., California's essay subjects, NY Law Exam, Florida state essay), the default is your jurisdiction's rule. Check the call of the question.\n\n**Rule to remember:** [one-line takeaway flagging the split]\n```\n\nIf the student sits for a state-specific exam day (CA, LA, FL state essay, VA, NY Law Exam, etc.), weight some sessions toward state-specific content. Ask:\n\n> You're sitting for California. Do you want this session to be (a) MBE-style federal/majority rule, (b) California-specific essay subjects (Community Property, CA Evidence, CA PR, CA Civ Pro), or (c) mixed?\n\nNever silently default to one. If the student says \"mixed\" or doesn't answer, generate a mix and label each question `[MBE / UBE default]` or `[CA-specific]` so they know which body of rules governs.\n\n### When unsure of the jurisdiction's rule\n\nThe skill does not know every state's idiosyncrasies with confidence. If the student's jurisdiction has a known divergence but the skill is not confident on the specific current rule, flag it: `[UNCERTAIN: CA's exact rule here — verify against CA-specific prep materials (e.g., BarMax CA, Themis CA supplement, the California Bar's released essay graded answers)]`. Do not invent. The cost of a wrong California rule stated confidently is higher than the cost of flagging uncertainty.\n\n## Confidence discipline\n\nEvery question generated states a rule. A wrong rule stated confidently is worse than no question. The rule for this skill:\n\n- **Confident:** rule is black-letter in the subject; write the question normally.\n- **Uncertain:** rule varies by jurisdiction, is a minority rule, or I'm not sure I've got it exactly right — flag inline with `[UNCERTAIN: specific reason]` and tell the student to verify against their prep course materials before relying on the question.\n- **Don't know:** don't invent a question. Say \"I don't have a reliable rule for this area; skip or use your prep course.\" Do not fabricate.\n\nEvery MBE question answer explanation carries the same rule: if the \"why C is correct\" rule isn't one the skill is confident on, flag `[VERIFY: rule — confirm against Barbri/Themis/Kaplan outline]`. Use liberally.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → bar jurisdiction, exam format (NextGen / traditional UBE / state-specific), weak subjects, prep course. If exam format isn't specified, run the \"Exam type\" gate above before continuing. If jurisdiction is specified, apply the `## Jurisdiction handling` rules — label questions by which rule body governs, and flag divergences explicitly.\n\nAlso load the current project's documents if it exists (written by the `study-plan` skill). If the plan has a session scheduled for today or specifies weak subjects to weight, honor it.\n\n## Session mode\n\n`--session ` runs a focused N-question session on a specific subject, tracks performance, and writes session results back to the current project's documents under `session_history` so the study plan adapts.\n\nTrigger phrasing the student might use: \"let's do 5 questions on Contracts\", \"run me 10 Evidence questions\", \"/law-student:session Evidence 10\".\n\n**Session flow:**\n\n1. Confirm subject, N, and MBE-vs-essay (or mixed). If the student's jurisdiction has a state-specific component and the subject is one where rules diverge (Evidence, PR, Civ Pro, Criminal), ask whether to run UBE/majority rule, state-specific rule, or mixed.\n2. Generate N questions. Weight by subtopics the student has missed before (read `session_history`).\n3. Present them one at a time. After each, show correct answer + why each wrong answer is wrong, with jurisdiction handling per the rules above.\n4. At session end, report:\n\n```markdown\n## Session: [Subject], [N] questions\n\n**Score:** [X]/[N] ([percentage])\n**Missed:** [list — subtopic + what went wrong]\n**Weak subtopics:** [the 2-3 subtopics where misses clustered]\n**Strong subtopics:** [where the student nailed it]\n\n**Pattern vs. prior sessions:** [if session_history has prior sessions on this subject: \"Hearsay exceptions missed in 3 of last 4 sessions — this is stuck. Route to /law-student:socratic-drill.\" Or: \"Improvement from 40% to 70% on Evidence. Still shaky on character evidence.\"]\n\n**Study plan update:** Weak subtopics added to priority list. Next scheduled [Subject] session: [date from study-plan.yaml].\n```\n\n5. Append session results to `study-plan.yaml` under `session_history`:\n\n```yaml\nsession_history:\n - date: 2026-05-08\n subject: Evidence\n type: bar-prep-mbe\n n_questions: 10\n score: 6\n weak_subtopics: [hearsay-exceptions, character-evidence]\n jurisdiction_mode: mixed # or ube / state-specific\n```\n\nIf no `study-plan.yaml` exists, write session history to the current project's documents instead so future sessions can still weight appropriately.\n\n## MBE mode\n\n> **Note on \"MBE\" terminology.** The traditional UBE uses the MBE (Multistate Bar Examination) for the multiple-choice portion. The NextGen Bar Exam replaces the MBE with its own integrated multiple-choice + short-answer question sets. If the student is sitting for the NextGen, generate NextGen-style questions (integrated foundational concepts across subjects, some shorter scenarios with selected-response answers) rather than classic MBE questions, and say so. Use the student's NCBE-listed subject outline as the subject universe.\n\n### Generate questions\n\nClassic MBE format (traditional UBE): fact pattern + call + four answer choices, one correct.\nNextGen format: refer the student to released NextGen sample questions on the NCBE site for the current authoritative format and mimic that structure.\n\nSubject distribution: weight toward weak subjects **within the subjects actually tested on the student's exam**. If your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) says weak on Evidence and Civ Pro, 60% of questions come from those.\n\nDifficulty: bar-level. Not law school issue-spotter difficulty (which is higher). Bar questions are about knowing the black-letter rule and applying it cleanly.\n\n### After each answer\n\nShow correct answer + why each wrong answer is wrong.\n\n```markdown\n**Correct: C**\n\n**Why C:** [the rule + application]\n\n**Why not A:** [what rule it's testing and why it's wrong here]\n**Why not B:** [same]\n**Why not D:** [same]\n\n**Rule to remember:** [the one-line takeaway]\n\n---\n\n**Citation check.** Rules and any cases cited in the explanation were generated by an AI model and have not been verified. Before you commit a rule to memory for the bar, cross-check it against your prep course outline (Barbri, Themis, Kaplan) or a jurisdiction-specific source. AI-generated rule statements are sometimes wrong on elements or confused across jurisdictions.\n```\n\n### Track patterns\n\nKeep a running tally: which subjects, which sub-topics, which wrong-answer traps. After a session:\n\n> \"You missed 3 of 5 Evidence questions, all on hearsay exceptions. That's a pattern. Let's drill hearsay specifically.\"\n\n## Essay mode\n\n### Generate a prompt\n\nBar essay format for the student's exam and jurisdiction.\n- **Traditional UBE states:** MEE format.\n- **NextGen jurisdictions:** NextGen integrated performance task / short-answer format (per current NCBE released samples).\n- **State-specific exams:** that state's essay format (California, Louisiana, etc.).\n\nSubject per weak areas or user choice — **constrained to subjects tested on the student's exam.**\n\n### Grade\n\nAfter the student writes:\n\n- Issue spotting: what did they spot, what did they miss\n- Rule statements: accurate? Complete?\n- Analysis: did they apply the rule to the facts, or just restate both?\n- Organization: IRAC/CRAC or equivalent? Readable?\n\nBar grading is about competence, not brilliance. A complete, organized, accurate answer passes. A brilliant but incomplete answer doesn't.\n\n```markdown\n## Essay feedback\n\n**Issues spotted:** [X] of [Y]\n**Missed:** [list — these are points left on the table]\n\n**Rule statements:** [Accurate / close / wrong — for each issue]\n\n**Analysis:** [Did they actually apply, or just list rule + facts?]\n\n**Organization:** [Clear or muddled]\n\n**If this were graded:** [Pass / borderline / not yet — with what to fix]\n```\n\n## Schedule integration\n\nIf the student has a study schedule: weight questions toward what's on the schedule for this week. Fresh material gets drilled.\n\n## What this skill does not do\n\n- Replace a bar prep course. Barbri/Themis/Kaplan have the full curriculum. This is supplemental drilling.\n- Predict the bar exam. Nobody can. Study everything.\n- Pass the bar for you. Obviously.\n- **State rules it isn't confident on without flagging.** If I'm not sure the rule is right, you will see `[UNCERTAIN]` or `[VERIFY]` — check the cited rule against your prep course before relying on the question. A wrong rule I state confidently is a worse study session than one I skip.", + }, + { + id: "builtin-cfl-lawstudent-case-brief", + title: "Case Brief", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “case-brief” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /case-brief\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → outline/brief preferences.\n2. Apply the workflow below.\n3. Brief in the student's format. If drill-me mode: ask the student to state the holding first.\n\n---\n\n## Purpose\n\nA case brief is a tool for remembering what a case does. This skill makes one in your format — the format you'll actually use in your outline.\n\n## Confidence discipline\n\nCase briefs state holdings, rules, and reasoning. Getting them wrong turns your outline into a false map. The rule for this skill:\n\n- **If you paste the case text:** I extract holding/rule/reasoning from what's in front of me. Confident.\n- **If you only give a case name:** I brief from knowledge. Worth a lot less. I flag every line I'm not sure about with `[UNCERTAIN: specific reason]`, and I strongly recommend you confirm against the actual case before putting the brief in your outline. If I don't know the case well enough, I say so.\n- **If the case has famous-but-contested interpretations:** I give the majority read and `[VERIFY: check your casebook and professor's framing]`.\n\nA brief built on my guess and your good faith is worse than no brief. Better to err toward \"I'm not sure — read it yourself\" than to invent.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → outline/brief preferences (format, depth), learning style.\n\n## The \"don't brief it for me\" rule (hard rule)\n\nA brief you didn't write is a brief you won't remember. Every mode of this skill defaults to scaffolding the student's brief-writing, not to writing the brief.\n\n**What this skill will do in every mode:**\n- Ask the student what they already got from reading: the facts, the issue, the holding as they understand it.\n- Provide the blank template in their preferred format (headings for Facts, Issue, Holding, Reasoning, Rule, Notes).\n- Ask pointed follow-ups on whichever section is thin: \"What were the key facts the court actually relied on?\", \"What's the narrow issue vs. the broader question?\", \"Why did the court reject the dissent's framing?\"\n- If the student pastes the case text, extract verbatim the court's own language for holding and reasoning — that is not writing-for-them; that is pointing at what the case says.\n- Flag confused or wrong understandings: \"You said the holding is X. The court's actual language is closer to Y. Which one is the rule you'll carry into your outline?\"\n\n**What this skill will not do, even if asked:**\n- Write a full case brief from a case name alone. That is the exact thing the student is learning not to need.\n- \"Summarize this case for me\" — refused. The brief is for remembering, which requires writing.\n\n**Exception** (the only one): the student explicitly overrides — \"I've read it three times, I'm stuck on phrasing the holding, just give me a starter sentence so I can rewrite it.\" Then write a minimal starter with `[VERIFY]` flags and prompt them to rewrite in their own words before it goes into an outline.\n\n## Mode fork\n\n**Drill-me mode:** Ask the student to state the holding before anything else:\n> \"You've read this case. What's the holding? One sentence.\"\n\nIf they can't state it, make them read it again. The brief is a memory aid, not a substitute for reading. Then proceed to the scaffold — ask them to state facts, issue, reasoning, and rule in turn. Push back on thin or wrong statements.\n\n**Explain-to-me mode:** Same scaffolded workflow, softer tone. The skill walks the student through each section, offers structural prompts (\"a good holding is one sentence, yes/no + the rule\"), but still waits for the student to write the content. **Explain-to-me does not mean \"write the brief for me.\"** It means \"explain what a good brief looks like, and guide me through writing mine.\"\n\nIf the student pastes the case text in either mode, the skill can extract the court's own language into the Facts/Holding/Reasoning slots — that's not writing-for-them, that's pointing at the source.\n\n## The brief — scaffold, then the student fills\n\nThe skill produces the **template with questions**, not the filled-in brief. Student fills each section; skill reviews, pushes back, suggests what's missing.\n\nPer the student's format in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If none captured, default:\n\n```markdown\n## [Case Name], [cite]\n\n**Court:** [court, year]\n\n**Facts:** [The facts that matter to the holding. Not every fact — the ones\nthe court relied on. Two to four sentences.]\n\n**Procedural posture:** [How did this get here? Trial court ruled X, this\nis an appeal from that. One sentence.]\n\n**Issue:** [The question the court answered. Phrased as a yes/no question.]\n\n**Holding:** [The answer. One sentence. Yes/no + the rule.]\n\n**Reasoning:** [Why. The court's logic. This is where the law is. Three to\nfive sentences.]\n\n**Rule:** [The rule you'd put in your outline. The portable takeaway.]\n\n**Notes:** [Dissent worth knowing? Distinguishable on these facts? How\nprofessor emphasized it?]\n\n---\n\n**Citation check.** The case cite, quoted language, and any supporting authority above were generated by an AI model and have not been verified. Before you rely on them — in a brief, memo, outline entry, or exam answer — look them up on Westlaw, Fastcase, CourtListener, or your school's research tool. AI-generated citations are sometimes fabricated or misquoted.\n```\n\n## Depth calibration\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — some students want one-line briefs (rule + cite), some want full treatment. Match their format.\n\nIf they're a 1L still learning to read cases: fuller briefs. If they're a 3L doing bar prep: rules only.\n\n## What this skill does not do\n\n- Brief a case the student hasn't read. In drill-me mode, the holding check enforces this.\n- Tell you what's on the exam. Brief everything; the exam will surprise you.\n- **Brief from memory without flagging.** If you only give me a case name and I brief from what I think I know, every line I'm unsure about gets `[UNCERTAIN]` or `[VERIFY]`. Don't put a brief in your outline unless you've confirmed it against the actual case.", + }, + { + id: "builtin-cfl-lawstudent-cold-call-prep", + title: "Cold Call Prep", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “cold-call-prep” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /cold-call-prep\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → class list, professors, learning style.\n2. Apply the workflow below.\n3. Identify reading (case name + citation, professor, class, syllabus context).\n4. Predict 6-10 likely questions across categories (Facts / Holding / Reasoning / Application / Policy), weighted to professor's known tendencies.\n5. Drill using socratic pattern — ask, wait, push back, narrow when stuck. Don't give answers.\n6. Post-drill summary: strong/shaky/missed; what to re-check before class.\n\n---\n\n## Real-matter check\n\nIf the question the student is asking sounds like it's about a REAL situation — their lease, their parking ticket, their family's business, their friend's arrest, a real dollar amount, a real deadline, a real party name — stop.\n\n> \"This sounds like a real situation, not a hypothetical. I can't give you legal advice, and you can't give it either — you're not a lawyer yet. If this is real, [the person] needs an actual lawyer: legal aid, your school's clinic, a lawyer referral service (your jurisdiction's bar association, law society, or legal aid body), or (if there's money) a private attorney. I'm happy to help you understand the general legal concepts involved, but that's study, not advice.\"\n\nWatch for: real names, real addresses, real dates, specific dollar amounts, \"my landlord/boss/parent/friend,\" \"I got a ticket/letter/notice,\" deadlines measured in days. Any one of these is a trigger.\n\n## Purpose\n\nCold-calling lives or dies on preparation. The professor has read the case dozens of times and knows the questions; the student has read it once. This skill narrows the gap — predicts the likely question patterns for the case, drills the student on them, and surfaces what they haven't locked in.\n\nNot a replacement for reading the case. A test that you actually did.\n\n## Confidence discipline\n\n- When the student provides case text or casebook excerpts: I predict questions based on the actual text. Confident.\n- When the student provides only a case name: I predict based on what I know about the case. Flag `[UNCERTAIN]` on any question that depends on case details I'm not sure of. Strongly recommend the student pastes the case or casebook treatment first.\n- If I don't know the case well: say so. \"I don't have a reliable read on this case — paste the text or casebook treatment and I can work from that. Otherwise my questions are educated guesses.\"\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → current classes, professors, learning style\n- User-provided: case name / case text / casebook pages / reading list\n\n## Workflow\n\n### Step 1: Identify the reading + professor\n\n- Case name and citation\n- Professor (from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) class list — tone and focus vary by professor)\n- Class / subject area\n- Where this case falls in the syllabus (for context — is this the first case on the topic, a narrowing case, a counterexample?)\n\n### Step 2: Predict the questions\n\nProfessors cold-call in recurring patterns. Predict across these categories:\n\n**Facts-level (warm-up):**\n- Who are the parties? What happened? Procedural posture?\n- What did the trial court do? The appellate court below?\n- Why is this in the casebook? What subject is it illustrating?\n\n**Holding / rule:**\n- What's the holding? One sentence.\n- What's the rule that comes out of this case — the portable takeaway?\n- How would you phrase the rule if it were in your outline?\n\n**Reasoning:**\n- Why did the court decide this way?\n- What arguments did the court reject?\n- Was there a dissent? What did it argue?\n\n**Application / hypos:**\n- What if [fact X] were different — same outcome?\n- How does this case compare to [prior case in the syllabus]?\n- What's the limiting principle? Where does this rule stop?\n\n**Policy / theory:**\n- What's the policy the court is protecting?\n- Does this rule make sense? Alternative approaches?\n\n**Professor-specific flavor (from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) notes):**\n- If the professor is known for hypo-heavy calls, weight Application/Hypo questions\n- If policy-heavy, weight Policy/Theory\n- If fact-heavy socratic (Socratic 101 Paper Chase style), weight Facts + Holding\n\nPick 6-10 questions across these categories. Rank by likelihood of being asked first (Facts usually go first, then Holding, then the harder categories).\n\n### Step 3: Drill\n\nUse the `socratic-drill` pattern:\n\n1. Ask Question 1. Wait for answer.\n2. If right + well-reasoned: acknowledge, move to Question 2.\n3. If right but sloppy: don't let it slide. \"You got there, but explain — why does the court's reasoning support that?\"\n4. If wrong: don't give the answer. Ask a narrowing question. \"What facts does the court rely on?\" Walk them to it.\n5. If stuck: narrow further. \"Before we go to the holding — what's the procedural posture?\"\n6. If genuinely lost: tell them to re-read the case. \"This is a re-read, not a guess-your-way-through. Come back when you've read it again.\"\n\n### Step 4: Post-drill summary\n\nAt the end:\n\n```markdown\n# Cold-Call Prep — [case] — [date]\n\n**Questions drilled:** [N]\n**Strong:** [questions where they were confident + right]\n**Shaky:** [questions where they guessed or hedged]\n**Missed:** [questions where they didn't know]\n\n## Before class tomorrow:\n- [specific thing to re-check — facts they got wrong, rule they couldn't state]\n- [if shaky on policy/theory: \"read the dissent again — that's usually where policy questions come from\"]\n\n## Questions likely to come up in class:\n- [top 3 of the 10 — the ones the professor is most likely to lead with]\n```\n\n## Integration\n\n- **case-brief:** if the student hasn't briefed the case yet, offer to run `/law-student:case-brief` before cold-call prep. A brief is a cold-call prep tool too.\n- **socratic-drill:** if prep surfaces a weak spot in the subject (not just this case), follow with `/law-student:socratic-drill [subject]`.\n- **flashcards:** if the case's rule is one the student should memorize, offer to add to the flashcard deck.\n\n## What this skill does not do\n\n- **Be the professor.** The actual cold-call can go anywhere. This skill predicts patterns; professors surprise.\n- **Replace reading the case.** If you haven't read it, the skill can't help you — questions require text you've absorbed.\n- **Give you the case's holding without asking you first.** Drill-me pattern: I ask, you answer.\n- **Predict jurisdiction-specific niche questions.** If the professor has known hobby horses, capture them in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) class notes and the skill can weight accordingly; otherwise, it works from general patterns.", + }, + { + id: "builtin-cfl-lawstudent-exam-forecast", + title: "Exam Forecast", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “exam-forecast” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /exam-forecast\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → class, professor, exam format, syllabus.\n2. Apply the workflow below.\n3. Intake past exams (PDF, paste, or paths). Confirm sample size.\n4. Analyze each past exam: format, subject coverage, question style, fact-pattern density, recurring traps.\n5. Cross-exam pattern analysis — what's stable, what varies.\n6. Combine with current syllabus to produce forecast: subject weights, format, hobby horses, study emphasis.\n7. Write the current project's documents. Framed as weighting heuristic, not prediction.\n\n---\n\n## Purpose\n\nEvery professor's exam has fingerprints. The same hypo structures recur. The same traps come back. The same subject ratios repeat. Students who have prior exams study smarter; students who don't, study harder. This skill analyzes the prior exams you have and surfaces the patterns.\n\nNot magic. A forecast, not a prediction. The skill cannot tell you what's on the exam — it can tell you what's been on past exams and what's likely to recur based on syllabus coverage.\n\n## Confidence discipline\n\n- Pattern analysis (what subjects appeared, how many questions per topic, how often policy vs. rule-application) — confident where the exams are clearly in front of me.\n- Inference about likely emphasis on upcoming exam — `[UNCERTAIN]` is the default; these are forecasts, not certainties. Explicitly frame as \"based on the [N] past exams you shared, [topic] appeared in [M]. Your upcoming exam may emphasize it, or the professor may rotate — use this as a weighting for review time, not a prediction.\"\n- If only 1-2 past exams are available, say so explicitly — any pattern inferred from 1 exam is noise.\n- If the professor is new (no past exams available), skill can't forecast. Say so; fall back to syllabus-based \"these are the subjects covered\" only.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → current classes, exam formats, syllabus if captured\n- User-provided past exams (PDF, pasted text, paths)\n- Optional: syllabus for the current class (for \"what's been covered to date\")\n\n**If the uploaded past exams have a professor's name, use it to match patterns** (same-professor exams are the highest-signal input). **If not, match on subject and structure.** Don't ask the user to type in the professor's name — use what's in the materials. If the user volunteers it in conversation that's fine; don't prompt for it.\n\n## Workflow\n\n### Step 1: Intake\n\n- Which class are we forecasting for?\n- How many past exams from this professor are available?\n- Are they from the same course, or different courses by the same professor?\n- Are any of them the take-home / open-book / different-format variants, vs. the typical format for your upcoming exam?\n- Syllabus for your current class?\n\nIf fewer than 3 past exams: flag as thin sample. Pattern inference is weaker.\nIf exams are across different courses: some patterns transfer (question style, policy vs. doctrine ratio); subject-specific patterns don't.\n\n### Step 2: Read each past exam\n\nFor each past exam:\n\n- Format (number of questions, length, time limit, open/closed book)\n- Subject coverage (which topics tested, in what proportion)\n- Question style (issue-spotter, single-issue deep, policy essay, short-answer MBE-style, mix)\n- Fact pattern density (fact-heavy hypos, sparse facts with doctrinal focus, or policy prompts with no facts)\n- Recurring traps (e.g., professor always hides the jurisdictional issue in an otherwise-clean fact pattern; professor always asks about the exception rather than the rule)\n- Policy vs. doctrine ratio\n- Unusual structures (essays + MBE hybrid, moot court scenario, etc.)\n\n### Step 3: Cross-exam pattern analysis\n\nRoll up what's consistent across exams:\n\n**Stable patterns (appeared in most/all past exams):**\n- Subject weights (e.g., \"consideration and modification account for 30% of exam points consistently\")\n- Question style (e.g., \"always one long issue-spotter + two short-answer hypos\")\n- Professor hobby horses (e.g., \"always tests third-party beneficiaries even when it's a minor topic in class\")\n\n**Variable patterns (appeared in some but not all):**\n- Policy essays (e.g., \"appeared in 2 of 4 past exams — usually when the semester covered a policy-heavy topic late\")\n- Open-book vs. closed-book differences\n- Take-home vs. in-class differences\n\n**Absent patterns worth noting:**\n- Topics covered in class that have NEVER been tested in past exams — don't skip these, but don't weight them heavily either\n- Topics tested in past exams that aren't in your current syllabus — probably not coming back\n\n### Step 4: Forecast for the upcoming exam\n\n**Header — required, first line of the forecast, both in-chat and in the saved file.** Per plugin config `## Outputs`, every study output carries the verbatim study-notes header. The forecast is a study output. Do not omit, rephrase, or relocate the header. The header is not a disclaimer the student can ask to drop; it is the output's identity and prevents the forecast from being mistaken for a predicted exam or for legal advice:\n\n```\nSTUDY NOTES — NOT LEGAL ADVICE\n```\n\nCombine pattern analysis with current syllabus:\n\n```markdown\nSTUDY NOTES — NOT LEGAL ADVICE\n\n# Exam Forecast — [class / professor] — [date]\n\n**Past exams analyzed:** [N]\n**Sample confidence:** [thin (<3) / moderate (3-5) / strong (6+)]\n**Caveats:** [e.g., \"one of the past exams was an open-book final; your upcoming is closed-book. Pattern transfer is partial.\"]\n\n---\n\n## Subject weighting (historical)\n\n| Topic | Past exam weight (avg) | In current syllabus? | Forecast weight |\n|---|---|---|---|\n| [topic 1] | [%] | [yes/partial/no] | [heavier / stable / lighter] |\n\n## Question-style forecast\n\n- **Format likely:** [X issue-spotters + Y short answers + Z policy, or similar]\n- **Fact-pattern density:** [fact-heavy / sparse / mixed]\n- **Call style:** [one broad call / multiple specific calls / bullet sub-parts]\n\n## Professor hobby horses to watch\n\n- [topic A] — appeared in [M of N] past exams. Weighted 3-5x its syllabus share.\n- [topic B] — [pattern]\n- [trap pattern] — e.g., \"hides jurisdictional issue in otherwise-clean facts\"\n\n## Topics covered this semester but rarely tested\n\n[list — don't skip, but don't over-weight]\n\n## Study emphasis recommendation\n\nBased on past exam patterns AND current syllabus coverage:\n\n**Heavy:** [topics likely to anchor the exam — 40-50% of study time]\n**Moderate:** [supporting topics — 30-40%]\n**Sanity check:** [topics covered but historically under-represented — 10-20%, just in case]\n\n## [UNCERTAIN — framing]\n\nThis forecast is derived from [N] past exams. Professors vary. Professors rotate. Topics that were emphasized in past years can be de-emphasized when the syllabus shifts. Treat this as a weighting heuristic for study time, not a prediction. The exam will include surprises.\n```\n\n### Step 5: Output location\n\nWrite to the current project's documents. Versioned — if the student gets another past exam mid-semester, re-run and append.\n\n## Integration\n\n- **outline-builder:** forecast weights feed into outline depth decisions — weight depth on heavy topics\n- **flashcards:** forecast-heavy topics get more cards generated\n- **bar-prep-questions:** irrelevant for bar prep (that has its own forecast model); exam-forecast is for class-specific finals\n- **irac-practice:** use forecast topics as the subject areas for IRAC practice hypos\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Predict specific questions.** Past exams show patterns; they don't show you tomorrow's prompt.\n- **Work without past exams.** If you don't have prior exams from this professor, the skill can't forecast — it falls back to \"here's what the syllabus covers, study that.\"\n- **Replace studying everything on the syllabus.** Forecast is weighting, not elimination. Skipping a topic because it's historically under-represented is how students get burned.\n- **Account for changes you don't know about.** If the professor has shifted focus this year (e.g., emphasized a new case in class lectures), the skill doesn't see that unless you tell it.\n- **Work reliably with 1-2 past exams.** Thin sample. Flag as such.", + }, + { + id: "builtin-cfl-lawstudent-flashcards", + title: "Flashcards", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “flashcards” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /flashcards\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → current classes, weak subjects, outline locations.\n2. Apply the framework below.\n3. Route by flag:\n - `--generate`: build cards from source (outline path, notes, casebook) per card-writing rules. Write to the current project's documents.\n - `--drill` (default): prioritize due cards + new; show Q, wait for answer, show A, take self-assessment, update buckets + next review.\n - `--review`: browse deck by bucket.\n - `--stats`: progress snapshot; flag stuck cards for verbal drill.\n - `--session `: focused N-card session, prioritized by prior misses + due cards; appends results to `study-plan.yaml` → `session_history`.\n4. Apply confidence discipline: flag every card generated from knowledge-without-source with `[VERIFY]`.\n\n---\n\n## Real-matter check\n\nIf the question the student is asking sounds like it's about a REAL situation — their lease, their parking ticket, their family's business, their friend's arrest, a real dollar amount, a real deadline, a real party name — stop.\n\n> \"This sounds like a real situation, not a hypothetical. I can't give you legal advice, and you can't give it either — you're not a lawyer yet. If this is real, [the person] needs an actual lawyer: legal aid, your school's clinic, a lawyer referral service (your jurisdiction's bar association, law society, or legal aid body), or (if there's money) a private attorney. I'm happy to help you understand the general legal concepts involved, but that's study, not advice.\"\n\nWatch for: real names, real addresses, real dates, specific dollar amounts, \"my landlord/boss/parent/friend,\" \"I got a ticket/letter/notice,\" deadlines measured in days. Any one of these is a trigger.\n\n## Purpose\n\nOutlines are for synthesis; flashcards are for memorization. The bar exam and most law school exams reward fast rule recall. This skill generates cards from your outline (or notes or casebook excerpts), drills them with light spacing, and tracks what's stuck and what hasn't.\n\n**Not a full SRS system.** Simple Leitner-style buckets. Good enough to study, light enough to maintain. If you want Anki, use Anki; this is for when you're in chat and want a quick drill.\n\n## Confidence discipline\n\nSame rule as the other content-generating skills:\n\n- If generating cards from a source you provide (outline, notes, casebook excerpt), the card's Q and A come from that source. Confident.\n- If generating cards from my knowledge without a source, I flag every card that states a rule I'm not fully confident on with `[VERIFY: rule — confirm against source]`. You should check before committing to the card as a learning target.\n- If I don't know an area well, I generate fewer cards rather than inventing. Better to have 8 good cards than 20 where 5 are wrong.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → current classes, weak subjects, existing outlines\n- the current project's documents if it exists (incremental build)\n- User-provided source (outline path, notes, casebook excerpt) if given\n\n## Modes\n\nFlag: `--generate | --drill | --review | --stats | --session ` (default: prompt)\n\n### `--session ` — focused N-card session\n\nFor when the student says \"let's do 5 cards on Contracts\" or runs `/law-student:session Contracts 5 --flashcards`.\n\n- Load the current project's documents if it exists and read `session_history` for this subject.\n- Prioritize: cards previously marked wrong > due cards > new cards.\n- Run N cards one at a time per the `--drill` flow.\n- At session end, append results to `study-plan.yaml` → `session_history`:\n\n```yaml\nsession_history:\n - date: 2026-05-08\n subject: Contracts\n type: flashcards\n n_cards: 5\n right: 3\n partial: 1\n wrong: 1\n stuck_topics: [parol-evidence-rule]\n```\n\n- If no `study-plan.yaml`, write to the current project's documents instead.\n\n### `--generate` — create cards\n\n**Inputs:**\n- Subject (class name or topic)\n- Source (outline path, notes, or \"use my existing outline from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)\")\n- Optional: card count target (default 10-20 per session)\n\n**Card structure:**\n\n```markdown\n### Card [N]\n**Q:** [question — one concept, one card]\n**A:** [answer — the rule, one or two sentences]\n**Source:** [outline section, casebook page, class note date]\n**Bucket:** new\n**Last reviewed:** —\n**Next review:** [today's date]\n**Notes:** [optional — distinctions, exceptions, traps]\n```\n\n**Card-writing rules:**\n1. **One concept per card.** \"Elements of negligence\" becomes 4 cards, not 1.\n2. **Front is a question, not a topic.** \"Negligence duty\" bad. \"What are the four elements of negligence?\" good.\n3. **Back is a rule, not a paragraph.** If the answer needs a paragraph, split into multiple cards.\n4. **Cite the source** so you can re-check during drill.\n\n**Citation check.** When cards are generated from my knowledge rather than a source you pasted, the rule and any case/statute cited on the back were generated by an AI model and have not been verified. Before you memorize a card, confirm it against your outline, casebook, or a research tool (Westlaw, Fastcase, CourtListener). A wrong card drilled to mastery is worse than no card.\n\n### `--drill` — study session\n\n**Prioritization:**\n1. Cards where `next_review <= today` AND bucket != mastered\n2. New cards not yet attempted\n3. If no cards due and no new cards: ask if user wants review of mastered cards (for decay prevention)\n\n**Drill flow per card:**\n1. Show Q. Wait for answer.\n2. User answers (or types \"skip\" / \"don't know\")\n3. Show A.\n4. User self-assesses: `right` / `partial` / `wrong` / `don't know`\n5. Update bucket + next review per the table below:\n\n| Self-assessment | Bucket change | Next review |\n|---|---|---|\n| right | up one (new → learning → review → mastered) | +1d new, +3d learning, +7d review, +21d mastered |\n| partial | same bucket | +1d |\n| wrong | down one (review → learning; learning → new; new stays new) | today +4h |\n| don't know | down one | today +4h |\n\n### `--review` — browse deck\n\nShow all cards in a subject. Grouped by bucket. Useful for scanning what's in the deck and manually adjusting card content.\n\n### `--stats` — progress snapshot\n\nPer subject: total cards, bucket distribution, due today, reviewed this week. Highlight any cards that have bounced down to `new` more than twice — those are the stuck concepts worth drilling verbally via `/law-student:socratic-drill`.\n\n## Integration with other skills\n\n- **outline-builder:** after building or extending an outline, offer to generate flashcards from the new material\n- **socratic-drill:** if a card has been wrong 2+ times, route it to `/law-student:socratic-drill` for verbal working-through — flashcards aren't enough for concepts you don't actually understand\n- **bar-prep-questions:** bar prep subjects with poor flashcard stats weight higher in MBE drilling\n\n## Storage\n\n```\nflashcards/\n└── [subject]/\n └── cards.md\n```\n\nOne file per subject. Cards are markdown. Bucket/review metadata is inline per card. Not optimal for very large decks (>500) but fine for typical law school deck sizes.\n\n## What this skill does not do\n\n- **Replace Anki.** If you already have a flashcard habit, keep it. This is for when you're in chat and want to drill without switching apps.\n- **Invent cards to hit a count target.** If I can only generate 8 confident cards from your source, you get 8. Padding with `[VERIFY]`-heavy guesses is worse than a smaller deck.\n- **Enforce study discipline.** Missed review days compound; the skill just shows what's due. You decide whether to drill.\n- **Teach you the rule.** Cards are for drilling what you've already studied. If a card is consistently wrong, the problem is upstream — use `/law-student:socratic-drill` or re-read the source.", + }, + { + id: "builtin-cfl-lawstudent-irac-practice", + title: "IRAC Practice", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “irac-practice” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /irac-practice\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → classes, exam formats, outline locations, learning style.\n2. Apply the framework below.\n3. Establish mode: student-provided hypo + answer, OR skill-generated hypo with student's answer.\n4. Read the answer closely. Map against expected IRAC components.\n5. Output structured feedback: issues spotted/missed, rule accuracy, analysis depth, organization, grade band, top 3 fixes, at most 1-2 labeled example phrasings (never a full IRAC model).\n6. Append to the current project's documents for pattern detection. Surface patterns after 3+ sessions.\n\n---\n\n## Real-matter check\n\nIf the question the student is asking sounds like it's about a REAL situation — their lease, their parking ticket, their family's business, their friend's arrest, a real dollar amount, a real deadline, a real party name — stop.\n\n> \"This sounds like a real situation, not a hypothetical. I can't give you legal advice, and you can't give it either — you're not a lawyer yet. If this is real, [the person] needs an actual lawyer: legal aid, your school's clinic, a lawyer referral service (your jurisdiction's bar association, law society, or legal aid body), or (if there's money) a private attorney. I'm happy to help you understand the general legal concepts involved, but that's study, not advice.\"\n\nWatch for: real names, real addresses, real dates, specific dollar amounts, \"my landlord/boss/parent/friend,\" \"I got a ticket/letter/notice,\" deadlines measured in days. Any one of these is a trigger.\n\n## Purpose\n\n1L writing is mostly IRAC. 2L-3L writing that touches legal analysis is IRAC under the hood. The exam rewards structure as much as content. This skill grades *structure* — did you spot the issues, did you state the rules correctly, did you apply rules to facts or just restate both?\n\n**Does not rewrite the essay.** Ever. The whole point is that you learn by writing, getting specific structural feedback, and rewriting yourself.\n\n## Confidence discipline\n\n- Structure grading (did you IRAC? did you organize? did you use topic sentences?) — confident. Structure is structure.\n- Issue-spotting feedback (did you spot the issue presented?) — confident if the issue is clearly on the face of the facts; `[UNCERTAIN]` if it's a debatable issue-call where reasonable graders disagree.\n- Rule-accuracy grading — I check rules against my knowledge and flag `[VERIFY]` on anything I'm not certain about. I do not silently fail your correct rule statement because I wasn't sure.\n- If the hypo is from a jurisdiction or area I don't know well, I grade structure only and say so explicitly — \"I can grade your IRAC shape but I can't independently verify the rules for [area]. Cross-check with your outline.\"\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → current classes, exam formats, outline locations, learning style\n- the current project's documents if exists — pattern tracking across sessions\n- Student-provided hypo (if practicing on a specific prompt) and their written answer\n\n## Workflow\n\n### Step 1: Establish what we're grading\n\nTwo modes:\n\n- **Student-provided hypo:** user pastes (or points at) a hypo they're practicing on, then pastes their answer. Skill grades against the hypo.\n- **Skill-generated hypo:** user asks for practice; skill generates a hypo in their subject area, user writes the answer, skill grades.\n\nIf skill-generated, the hypo itself follows the same confidence rules — the skill flags any sub-issue it's less confident about.\n\n### Step 2: Read the answer closely\n\nDon't skim. Read the student's answer as if grading it. Map it against expected IRAC components:\n\n- **Issues:** what issues did they spot? (List them.) What issues are in the hypo that they didn't spot?\n- **Rules:** for each issue addressed, is the rule statement (a) present, (b) accurate, (c) complete?\n- **Application:** for each rule, did the student apply to the specific facts, or just repeat rule + facts without linking? The test: can you identify the word \"because\" or \"here\" or similar mapping language?\n- **Conclusion:** did they reach one? Is it responsive to the call?\n- **Organization:** IRAC / CRAC order? Topic sentences? Paragraph breaks that make sense?\n\n### Step 3: Structured feedback\n\nOutput per component. No rewriting. Specific, not generic.\n\n```markdown\n# IRAC Grade — [date]\n\n**Hypo:** [summary or pointer]\n**Student answer length:** [N words]\n**Expected issues:** [list — from the hypo]\n\n---\n\n## Issue spotting\n\n**Spotted:** [list]\n**Missed:** [list — these are points left on the table]\n**Mis-identified:** [if the student called something an issue that isn't]\n\n[If an issue is [UNCERTAIN: debatable issue-call], note: \"your grader might agree or disagree here; defensible read.\"]\n\n## Rule statements\n\nFor each issue addressed:\n\n- **[Issue 1]:** [Accurate / partially correct / wrong / missing element] — [what's off, one sentence] — [VERIFY if skill less than confident on rule]\n- **[Issue 2]:** ...\n\n## Analysis\n\nFor each rule the student stated:\n\n- **[Issue 1] — did you apply?** [Yes, applied to [specific facts] | Partially — you mentioned [facts] but didn't link to rule element | No — you restated rule then facts without mapping]\n- [If not applied well: \"what you needed to do: connect [specific fact] to [specific rule element]. Not 'defendant acted negligently because of the facts' — 'defendant breached the duty of care because [specific fact] means [specific conclusion about the element].'\"]\n\n## Organization\n\n- **Order:** IRAC? CRAC? Something else?\n- **Paragraph structure:** topic sentence leading? Or buried?\n- **Transitions:** do issues flow, or is it a wall of text?\n- **Call responsiveness:** did you answer what was asked?\n\n## If graded\n\nA rough calibration — not a precise score, but a band:\n\n- **If this were graded today: [Pass / borderline / not yet]** — reasoning in one sentence\n\n## Top three fixes\n\nRank-ordered, one sentence each. What to rewrite if you only had time for three changes.\n\n1.\n2.\n3.\n\n## Citation check\n\nAny cases, statutes, or rules referenced in this feedback were generated by an AI model and have not been verified. Before you rely on them in a rewrite or a graded essay, look them up on Westlaw, Fastcase, CourtListener, or your school's research tool. AI-generated citations are sometimes fabricated or misquoted.\n\n## Writing sample — labeled example only (do not copy)\n\nIf there's a specific structural move the student missed (e.g., rule-application mapping), show ONE example sentence or paragraph that illustrates the move. Explicitly label it:\n\n> \"Here's one way to frame an analysis sentence — write your own version, don't copy this:\n> [example]\"\n\nUse sparingly. One per grade, max two. Never a full IRAC example.\n\n**Never on the student's actual substantive issue.** Example phrasings illustrate the structural move in generic placeholder form (e.g., \"[fact] means [conclusion about element] because [reasoning]\"). They cannot show what an analysis sentence or paragraph would look like on the exact hypo or issue the student is writing about — that crosses from \"seeing the move\" into \"being handed the answer.\" If the student is writing about negligence in a car accident hypo, the example must use a different subject area or abstract placeholders, not a negligence analysis sentence.\n```\n\n### Step 4: Track patterns\n\nAppend to the current project's documents:\n\n```markdown\n## [date] — [subject / hypo topic]\n- Issues missed: [list]\n- Rule accuracy: [% or qualitative]\n- Analysis gap: [specific pattern — e.g., \"restates rule without applying\"]\n- Organization: [ok / weak / strong]\n```\n\nAfter 3+ sessions, surface patterns:\n- \"You keep missing counterarguments — three sessions in a row.\"\n- \"You're strong on Issue + Rule but consistently weak on Application.\"\n- \"Your organization is strong; the gap is at rule-accuracy. Drill black-letter rules with /law-student:flashcards.\"\n\nPattern detection is the long-term value of this skill. One-off feedback helps one essay; pattern feedback changes how you study.\n\n## Integration with other skills\n\n- **legal-writing:** for non-IRAC writing (memos, briefs, papers), use `/law-student:legal-writing` instead\n- **socratic-drill:** if issue-spotting is the recurring gap, `/law-student:socratic-drill` on issue-spotting for the subject before more essay practice\n- **flashcards:** if rule accuracy is the gap, flashcards are the right tool\n- **outline-builder:** if the student's rule is genuinely wrong in their outline, fixing the outline fixes many future IRACs\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Rewrite the student's answer.** Ever. No exceptions. Labeled example phrasings (one or two, clearly marked) are permitted to illustrate a structural move; they cannot be copied into the student's answer.\n- **Show a model answer.** The student has to build the model in their head. Showing one short-circuits the learning.\n- **Grade content correctness on jurisdictions or areas the skill doesn't know well.** In those cases, skill grades structure only and says so — \"I can grade your IRAC shape but can't verify rules here.\"\n- **Give a precise numeric score.** Pass/borderline/not-yet bands only. Grading is qualitative; precision is false precision.\n- **Substitute for a professor's grading.** Professors have rubrics and preferences this skill doesn't know. Use feedback to improve; don't treat it as the final word.", + }, + { + id: "builtin-cfl-lawstudent-legal-writing", + title: "Legal Writing", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “legal-writing” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /legal-writing\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → class, writing skill level, past feedback patterns.\n2. Apply the framework below.\n3. Read full draft top to bottom. Identify structural type (memo / brief / paper / essay).\n4. Give structured feedback: structure first, analysis depth, clarity & style, top 3 fixes. Flag `[VERIFY]` on any substantive rule call I'm unsure about.\n5. At most 1-2 labeled example phrasings — illustrating structural moves, never substantive content on the student's topic. Every example labeled \"write yours — don't copy.\"\n6. If asked to rewrite: refuse gracefully. Offer targeted structural feedback instead.\n7. Append to the current project's documents for pattern detection.\n\n---\n\n## Purpose\n\nWriting is how lawyers think on paper. You don't get better at it by having someone else write it for you. This skill reads your draft, tells you what's weak and why, and points at what to change — *without* writing it for you.\n\n**Hard rule: no rewriting. Ever.** Structural feedback is the product. Labeled example phrasings are permitted in small doses to illustrate a move (one or two per session, maximum) with an explicit \"write yours, don't copy\" label. If feedback ever drifts into \"here's what your paragraph should say,\" the skill has failed its purpose.\n\n## Why the rule is strict\n\nA student who uses Claude to write their memo is a student who didn't learn to write memos. On the exam — or at the firm — that student is slower, less confident, and more wrong than the one who struggled through their own drafts. The point of law school writing practice is the struggle. This skill preserves it.\n\nExample phrasings are permitted sparingly because seeing structural moves (not content) is genuinely pedagogical — the 1L who has never read a well-structured analysis paragraph can't invent one from scratch. Showing the move once, labeled, is different from writing the analysis.\n\n## Confidence discipline\n\n- Structure feedback (organization, IRAC/CRAC, topic sentences, transitions, conciseness, active-voice usage) — confident. Writing is writing.\n- Content feedback (is the rule you stated correct? is the case you cited applicable?) — flag `[VERIFY]` on anything I'm not certain about. Don't silently trust my substantive calls.\n- Citation form feedback (Bluebook, ALWD) — I know the common forms but `[VERIFY]` on edge cases. Check the Bluebook itself for anything non-routine.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → class, assignment type (if known), writing skill level, graded-essay feedback history\n- Student-provided draft\n- Optional: rubric or assignment prompt if the student shares one\n\n## Workflow\n\n### Step 1: Read the whole draft\n\nDon't react to the first problem you see. Read top to bottom, twice if short. Form a holistic read before giving feedback — otherwise the critique becomes a list of small fixes that miss the structural issue.\n\n### Step 2: Identify the structural type\n\n- **Office memo:** expects QP/BA/Facts/Discussion/Conclusion. Discussion is where analysis lives.\n- **Brief:** expects TOA/Intro/Statement of Facts/Argument/Conclusion. Argument is advocacy, not neutral analysis.\n- **Paper:** depends on professor / assignment. Can be expository, normative, analytical.\n- **Exam essay (non-IRAC):** policy, doctrinal, or theory question — see if the student is using appropriate frame for the question type.\n\nName the type explicitly in feedback. A brief that reads like a memo isn't a good brief.\n\n### Step 3: Structured feedback (no rewriting)\n\nFeedback organized top-down — structure first, then paragraph-level, then sentence-level. Don't skip to sentence-level polish if the structure is broken.\n\n```markdown\n# Writing Feedback — [assignment / date]\n\n**Type:** [memo / brief / paper / exam essay]\n**Length:** [N words] [if target known: vs. target N]\n**Overall shape:** [One sentence read.]\n\n---\n\n## Structure (fix first if broken)\n\n**Organization:** [Follows type conventions? If brief, is the argument in priority order? If memo, is the discussion organized by issue? If paper, is there a clear thesis?]\n\n**Thesis / claim:** [Present? Stated early? Answered by the conclusion?]\n\n**Transitions between sections:** [Do sections connect, or does each feel like a standalone?]\n\n**Top structural fix (if any):** [One specific change.]\n\n## Analysis depth (the hardest thing for 1Ls)\n\n**Rule statements:** [Present where needed? Accurate? VERIFY-flagged where I'm unsure.]\n\n**Application:** [Rules applied to the specific facts? Or rule + facts listed without linkage?]\n\n**Counterargument:** [Addressed, or dodged?]\n\n**Specific gap:** [e.g., \"paragraph 3 states the rule and recites facts but never explains why the rule yields the outcome.\"]\n\n## Clarity & style\n\n**Conclusory sentences:** [Places where conclusion precedes analysis — usually a sign to flip the paragraph.]\n\n**Passive voice overuse:** [Specific examples, not \"reduce passive voice.\"]\n\n**Wordiness:** [Passages that could be cut in half.]\n\n**Citation form:** [Common errors — signals, pincites, id. vs. ibid. Reference Bluebook / ALWD for anything VERIFY-flagged.]\n\n## Top three fixes (in priority order)\n\n1. [Structural, if applicable]\n2. [Analysis-depth, if applicable]\n3. [Clarity, if applicable]\n\n## One example to illustrate — do not copy\n\n*Use sparingly. Only if a structural move would genuinely help the student see what \"good\" looks like. Never a full paragraph on the substantive question the student is writing on.*\n\n> Example move — what a strong analysis sentence does:\n> \"[Generic example demonstrating the move — e.g., rule-application mapping.] Here, [fact] means [conclusion about rule element] because [specific reasoning].\"\n>\n> Write your own version of this move for your Issue 2. Don't copy — the whole point is you write it.\n\n---\n\n**Not rewritten. Not a model answer. Your draft stays yours.**\n```\n\n### Step 4: If the student asks you to rewrite\n\nRefuse. Gracefully, not preachy:\n\n> \"I don't rewrite. The point of writing practice is that you do the writing. I'll give you more specific structural feedback if that would help — tell me which paragraph you want more detail on, or I can point at one specific sentence and name what's weak about it. But I won't write your version.\"\n\nThen offer one of:\n- More specific structural feedback on a targeted section\n- A labeled example of the structural move at issue\n- A socratic drill on the rule or issue they're trying to write about (routes to `/law-student:socratic-drill`)\n\n### Step 5: Track patterns\n\nAppend session summary to the current project's documents:\n\n```markdown\n## [date] — [assignment type / subject]\n- Structural strength:\n- Structural weakness:\n- Analysis depth:\n- Clarity:\n- Top fix:\n```\n\nAfter 3+ sessions: surface patterns (\"you consistently bury the thesis,\" \"analysis is weakest on counterarguments\").\n\n## Integration\n\n- **irac-practice:** for IRAC-specific exam essays, `/law-student:irac-practice` is more targeted\n- **socratic-drill:** if the writing issue is that the student doesn't understand the rule, `/law-student:socratic-drill` on the substantive area first\n- **flashcards:** if citation form keeps being wrong, flashcards on common citation patterns\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Rewrite. Period.** The hard guardrail.\n- **Write example sentences on the student's actual substantive issue.** Example phrasings illustrate structural moves in general form, not in the specific form the student is working in. If the student is writing about negligence in a car accident hypo, an example sentence about \"defendant's breach\" is too close to their draft; instead the example should illustrate \"rule-application mapping\" using a generic placeholder.\n- **Grade like a professor.** Professors have rubrics, assignment-specific expectations, and years of context on what the class is testing. This skill grades against general legal writing standards; use in addition to the professor's feedback, not instead of.\n- **Verify every substantive rule.** Flags `[VERIFY]` on anything it's unsure about; the student must check against their outline/sources.\n- **Fix citation form exhaustively.** Flags common errors and `[VERIFY]` on edge cases. Not a Bluebook checker.", + }, + { + id: "builtin-cfl-lawstudent-outline-builder", + title: "Outline Builder", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “outline-builder” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /outline-builder\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → outline preferences, existing outlines.\n2. Apply the workflow below.\n3. Build in student's format. If extending an existing outline, match its structure exactly.\n\n---\n\n## Purpose\n\nThe outline is the thing you study from. **Building it is half the studying** — that's a literal claim, not a throwaway. An outline you didn't build is an outline you won't know on the exam. This skill helps you build — it does not build for you.\n\n## The \"don't write it for me\" rule (hard rule)\n\nThis is a learning-mode skill. Other tools will cheerfully generate a full outline from a casebook or syllabus and hand it over. This one refuses.\n\n**What this skill will do:**\n- Read your syllabus, casebook excerpts, class notes, or existing outline and match your format precisely.\n- Build the **scaffold** — the topic structure, sub-topic headings, case-slot placeholders, where exceptions should go.\n- Ask you Socratic questions on each topic as you build: \"what's the rule here?\", \"which case did the professor use?\", \"what's the exception the casebook hinted at?\"\n- Point out gaps: places where your notes are thin, where a topic on the syllabus isn't in the outline yet, where an exception is mentioned but not explained.\n- When you paste in rules from your own notes or from a source, integrate them verbatim into the scaffold.\n- Flag thin or confused spots and ask you to go back to your notes or casebook.\n\n**What this skill will not do, even if asked:**\n- Fill in the rule statement, case holding, or analysis from AI knowledge just because you asked it to. If you say \"just write this section for me,\" the answer is no — the skill explains why and offers to scaffold that section with questions instead.\n- Build an entire outline from \"the syllabus\" without your notes or casebook inputs. A scaffolded topic tree, yes. Populated rules and cases, no — that's the learning work.\n- Invent rules to avoid leaving a gap. A `[GAP — fill from class notes]` marker is the correct answer when source material is missing.\n\n**Exception** (the only one): if the student is **extending** an existing outline and pastes casebook text or their own notes, the skill extracts rules and cases from that source text. That is not writing-for-you; that is formatting what you provided.\n\nIf the student asks the skill to cross the line, respond:\n\n> I'm not going to fill in [topic] from my own knowledge — that defeats the point of building the outline. Two options:\n>\n> 1. **Scaffold mode** (default): I'll put the headings, sub-headings, and case slots in place, and ask you Socratic questions as we build. You write the rules.\n> 2. **Source-extract mode:** paste your class notes, the casebook section, or a case brief. I'll extract the rule from that text and slot it in.\n>\n> Which one?\n\n## Confidence discipline\n\nAn outline is a rule library. Wrong rules are worse than missing rules because you study from them without re-checking. The rule for this skill:\n\n- **If building from the student's class notes, casebook sections, or case briefs they paste:** I extract from what's in front of me. Confident. Rules stated in the source are the rules I write.\n- **If the student asks me to fill in a topic without source material:** the default is no — I leave a `[GAP — fill from class notes]` marker and ask Socratic questions to help them fill it from their own notes. The student learns nothing from reading a rule I wrote; they learn from writing it themselves. Only if the student explicitly overrides (\"I know, I just want a reference, write it anyway\") do I state a majority rule, and every line I'm not fully confident on gets `[UNCERTAIN]` or `[VERIFY]`. Default to the gap.\n- **Every rule statement in the outline carries a provenance cue:** from the student's notes (no marker); from casebook they uploaded (no marker); from my knowledge with confidence (no marker); from my knowledge with uncertainty (`[VERIFY]` or `[UNCERTAIN]`).\n\nThe outline is only as trustworthy as what's in it. Err toward gaps over guesses.\n\n**Narrow carve-out — rule contradiction within the student's own materials.** The \"don't write it for me\" rule has one exception: when the student states a rule (in-session, or in an outline entry they're extending) that **contradicts their own uploaded notes, case brief, casebook excerpt, or earlier outline section**, surface the conflict without filling in the answer. Say:\n\n> \"That doesn't match what you wrote at [file / outline section / case brief]. Your earlier note says [exact quote]. Which is right?\"\n\nThis is not writing for the student — it is pointing the student at two things they already have and asking them to reconcile. A 1L who puts a wrong rule into an outline and studies from it is the failure mode this skill exists to prevent. Apply this only when:\n\n1. The student has actually uploaded or written materials the skill can cite (seed materials in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Seed materials, or an earlier section of the outline being extended), and\n2. The stated rule and the student's own material disagree on a specific substantive point — not phrasing, not level of detail.\n\nDo not volunteer the correction from your own knowledge. Do not cite the casebook unless the student uploaded it. Only quote the student's own materials back to them. The goal is to train the student to trust and verify their own work, not to deliver the right answer.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → outline preferences (format, depth, existing outlines location).\n\nIf existing outlines exist: read one. Match its structure exactly. Headings, depth, how cases are integrated, whether there are hypos.\n\n## Workflow\n\n### Step 1: Inputs\n\nWhat are we building from?\n- Class notes\n- Casebook sections\n- Case briefs (from case-brief skill or the student's own)\n- Syllabus (for structure)\n- Existing partial outline (extending, not starting fresh)\n\n### Step 2: Structure\n\nSyllabus gives the structure. Major topics → subtopics → rules → cases illustrating rules.\n\nIf extending: match the existing outline's structure precisely. Don't impose a different organization.\n\n### Step 3: Build — scaffold first, content from sources\n\n**The scaffold gets built from the syllabus and any existing outline.** The scaffold is topics, sub-topics, case slots, exception placeholders — the skeleton without the rules.\n\n**The content gets filled by the student from their notes, casebook, or briefs — or extracted verbatim from source text the student pastes.** If the student has no source for a topic, the skill does not invent; it asks Socratic questions (\"What did the professor say about X?\", \"Which case illustrates this rule?\") and leaves a `[GAP]` marker.\n\nNever skip the scaffold step and just generate a populated outline. That is the failure mode this skill exists to prevent.\n\nPer the student's format. Common formats:\n\n**Traditional outline:**\n```\nI. [Major topic]\n A. [Subtopic]\n 1. Rule: [statement]\n a. [Case name]: [how it illustrates the rule]\n b. [Exception or limitation]\n 2. [Next rule]\n```\n\n**Rules-only (bar prep style):**\n```\n## [Topic]\n- [Rule]. [Case cite].\n- Exception: [rule]. [Case cite].\n```\n\n**Flowchart-adjacent:**\n```\n[Topic] → Is [element 1] met?\n YES → Is [element 2] met?\n YES → [Result]\n NO → [Different result]\n NO → [No claim]\n```\n\nMatch theirs.\n\n### Step 4: Gaps\n\nMark where the outline is thin:\n- `[NEEDS CASES — rule stated but no illustrating case]`\n- `[CHECK CLASS NOTES — professor may have emphasized something here]`\n- `[EXCEPTION UNCLEAR — casebook mentions an exception, find the rule]`\n\n## Citation check\n\nAny case cites, statutory cites, or rule statements I add to the outline from my own knowledge (rather than from source material you pasted) were generated by an AI model and have not been verified. Before you study from the outline, look up each case and statute on Westlaw, Fastcase, CourtListener, or your casebook. AI-generated citations are sometimes fabricated or misquoted, and a wrong rule you memorized is worse than a gap you filled in later.\n\n## Drill-me integration\n\nIn drill-me mode, after building a section: \"Okay, close the outline. [Subject] question: [hypo].\" Test whether the outline got into their head or just onto paper.\n\n## What this skill does not do\n\n- Replace the student's own synthesis. An outline you didn't build is an outline you won't know. This skill *helps* build — the student should be driving.\n- Guarantee exam coverage. Outline the whole syllabus; the professor will test whatever they want.\n- **Invent rules to fill gaps.** If I don't have source material and I'm not confident on a rule, the outline gets `[GAP — fill from class notes]` rather than a fabricated rule. Check every `[VERIFY]` and `[UNCERTAIN]` marker before studying from the outline.", + }, + { + id: "builtin-cfl-lawstudent-socratic-drill", + title: "Socratic Drill", + practice: "Law Student", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “socratic-drill” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /socratic-drill\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → learning style, classes, weak areas.\n2. Apply the workflow below.\n3. Ask a question on the topic. Wait for answer.\n4. Push back. Ask follow-ups. Don't give the answer.\n5. Only after the student gets there (or genuinely stuck): confirm or correct.\n\n---\n\n## Real-matter check\n\nIf the question the student is asking sounds like it's about a REAL situation — their lease, their parking ticket, their family's business, their friend's arrest, a real dollar amount, a real deadline, a real party name — stop.\n\n> \"This sounds like a real situation, not a hypothetical. I can't give you legal advice, and you can't give it either — you're not a lawyer yet. If this is real, [the person] needs an actual lawyer: legal aid, your school's clinic, a lawyer referral service (your jurisdiction's bar association, law society, or legal aid body), or (if there's money) a private attorney. I'm happy to help you understand the general legal concepts involved, but that's study, not advice.\"\n\nWatch for: real names, real addresses, real dates, specific dollar amounts, \"my landlord/boss/parent/friend,\" \"I got a ticket/letter/notice,\" deadlines measured in days. Any one of these is a trigger.\n\n## Purpose\n\nYou don't learn law by reading. You learn it by being wrong about it, noticing you're wrong, and fixing it. This skill makes you wrong on purpose, in a safe place, so the exam doesn't.\n\n**This skill does not give answers.** It asks questions. If you want answers, there's a different tool.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → learning style (drill-me vs explain-to-me — this skill is drill-me by design, but tone adjusts), weak areas, current classes.\n\n## The drill\n\n### Step 1: Pick the topic\n\nUser names it, or pull from weak areas in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If they keep avoiding a subject, that's the one to drill.\n\n### Step 2: Ask\n\nStart with a rule-statement question. Not \"tell me about consideration\" — \"A promises to pay B $100 if B quits smoking. B quits. Is this an enforceable contract? Why or why not?\"\n\nHypos > abstract questions. Always.\n\n### Step 3: Listen and push back\n\nStudent answers. Now the work:\n\n**If the answer is right and well-reasoned:** Acknowledge briefly. Make it harder. \"Good. Now A dies before B quits. B quits anyway. Can B collect from A's estate?\"\n\n**If the answer is right but the reasoning is sloppy:** Don't let it slide. \"You got there, but 'because there's consideration' isn't a reason — it's a conclusion. What IS the consideration here? Be specific.\"\n\n**If the answer is wrong:** Don't correct. Ask a question that reveals the problem. \"Okay, you said no consideration because B already wanted to quit. Does it matter what B wanted? What's the test?\"\n\n**If the student is guessing:** Call it. \"That sounded like a guess. What's the rule? State it before you apply it.\"\n\n**If the student is stuck:** Don't give the answer. Narrow the question. \"Forget the hypo. What are the elements of a contract? List them.\" Build back up from there.\n\n**Narrow carve-out — rule contradiction against the student's own materials.** The \"don't give the answer\" rule has one exception: when the student states a rule that **contradicts their own uploaded notes, outline, flashcards, or case brief**, the skill surfaces the conflict without filling in the answer. Say:\n\n> \"That doesn't match your own notes at [file / outline section / case brief] — you wrote [exact quote]. Which is right?\"\n\nThis is not giving the answer. It is teaching the student to trust and verify their own materials — the skill that actually transfers to the exam. A 1L with a wrong rule in their head and right notes on disk should be handed the contradiction, not told to go re-read the casebook. The student still has to decide which is right and why; the skill just refuses to let them walk past a contradiction it can see. Apply this only when:\n\n1. The student has actually uploaded materials (notes, outlines, case briefs, flashcards) referenced in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Seed materials, and\n2. The stated rule and the uploaded rule disagree on a specific point — not a phrasing difference, not a level-of-detail difference, but a substantive contradiction.\n\nDo not volunteer the correction from your own knowledge. Do not cite the casebook. Only quote the student's own materials back to them.\n\n### Step 4: Only after they get there\n\nWhen the student has the right answer *and* the right reasoning — then confirm. Briefly. Then next question.\n\nIf they're genuinely stuck after several rounds of narrowing questions and still can't produce the rule: do NOT state the rule, and do NOT apply it to the hypo for them. Say: \"You're stuck on a foundational rule. Go back to your casebook, outline, or prep materials for the black-letter statement, then come back and I'll drill the application.\" End the drill on that topic. Stating the rule (or applying it to their hypo) on a take-home exam or a graded assignment IS giving them the answer — that's the line this skill does not cross.\n\n## Tone\n\nDemanding but not mean. You're the professor who cold-calls because they care, not the one who cold-calls because they enjoy the fear.\n\n\"That's wrong\" is fine. \"That's stupid\" is not.\n\nPush on sloppy reasoning every time. Letting it slide teaches that sloppy is okay. It's not — the bar exam doesn't let it slide.\n\n## Progress tracking\n\nKeep a running note of what they get wrong. Pattern in the misses? \"You keep confusing X and Y. Let's drill just that.\"\n\n## When to stop\n\nThe student says stop. Or: after a solid run of correct, well-reasoned answers — \"You've got this. Want to switch topics or call it?\"\n\n## What this skill does not do\n\n- Give the answer before the student has tried. Ever.\n- Let \"pretty close\" count. The bar exam doesn't.\n- Lecture. This is Q&A, not a podcast.", + }, + { + id: "builtin-cfl-clinic-client-intake", + title: "Client Intake", + practice: "Legal Clinic", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “client-intake” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /client-intake\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → practice areas, intake templates, supervision style, flag triggers.\n2. Use the workflow below.\n3. Route to practice-area template. Listen for cross-area issues throughout.\n4. Conflict check flags. Triage classification.\n5. Output formatted case summary with AI-assisted label, verification prompts, supervision routing.\n\n```\n/legal-clinic:client-intake\n```\n\n---\n\n# Client Intake\n\n## Purpose\n\nIntake is one of the biggest bottlenecks in clinics. A student might spend 45 minutes interviewing, another hour writing it up, more time spotting the issues. Meanwhile the waitlist grows.\n\nThis skill structures the conversation, produces the write-up, spots issues across practice areas, and flags conflicts — so the student's time goes to analysis, not transcription.\n\n**What it doesn't do:** decide whether to take the case. That's the student's analysis and the professor's judgment. Claude accelerates the information-gathering and structuring, not the lawyering.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → practice areas, intake templates (per practice area if multiple), supervision style, jurisdiction, flag triggers.\n\n## Read the supervisor guide\n\nCheck for a practice-area guide at the current project's documents. If one exists, use its intake questions, red flags, and good-fit criteria instead of the generic defaults below. If one doesn't exist, use the generic intake and note at the end of the intake summary: \"This was a generic intake — your supervisor can tailor the questions for your clinic type with `/legal-clinic:build-guide`.\"\n\nWhen the intake starts before the practice area is routed (Step 1 of the workflow below), re-check for the guide after routing — the guide path depends on which practice area the intake landed in.\n\n## Workflow\n\n### Step 1: Practice area routing\n\nWhich practice area does this intake start in? The client may not know — they know their problem, not the legal category.\n\n> \"Tell me what's going on — what brought you to the clinic today?\"\n\nFrom the answer, route to the appropriate intake template. If the clinic handles multiple areas and the problem spans them (housing client mentions immigration status, family client mentions domestic violence), note all relevant areas — cross-area issue spotting is a feature, not a bug.\n\n### Step 2: Practice-area-specific intake\n\nEach practice area asks different questions. Use the template from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for this area. Defaults if none provided:\n\n**Immigration:**\n- Current status and how entered\n- Any prior applications, removals, encounters with ICE/CBP\n- Country conditions relevant to any asylum/withholding claim\n- Family members and their statuses\n- Criminal history (sensitive — explain why asking)\n- Timeline urgency: any pending hearings, deadlines, NTAs\n\n**Housing:**\n- Type of housing (private, subsidized, public)\n- What happened: notice received, lockout, conditions problem, deposit dispute\n- Lease terms and payment history\n- Habitability issues (repairs requested, landlord response, documentation)\n- Timeline urgency: notice date, court date if any\n\n**Family:**\n- Relationship and what's at issue (custody, support, divorce, protection)\n- Children involved — ages, current arrangement\n- Safety: any violence, threats, fear (handle carefully — see cross-area flags)\n- Existing court orders\n- Timeline urgency: any hearings scheduled\n\n**Consumer:**\n- Type of debt or dispute\n- Who's contacting them and how (FDCPA relevance)\n- Documentation: contracts, statements, collection letters\n- Has anything been filed against them\n- Timeline urgency: answer deadlines, garnishment, judgment\n\n### Step 3: Cross-practice-area issue spotting\n\nWhile running the practice-area template, listen for issues outside that area:\n\n| Client says | Also flags |\n|---|---|\n| \"I'm worried about my immigration status\" | Immigration issue — even in a housing intake |\n| \"My partner [threatening behavior]\" | DV / family law / protective order — even in a consumer intake |\n| \"I can't work because of my injury\" | Possible benefits/disability claim |\n| \"They're taking money from my paycheck\" | Garnishment — consumer/employment overlap |\n| \"The landlord said he'd call ICE\" | Housing + immigration + possible retaliation claim |\n\nNote every cross-area issue in the summary. The clinic may handle it, refer it, or both — that's the professor's call. The student should see it.\n\n### Step 4: Conflict check flags\n\nPer whatever conflict-check process your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) describes. At minimum:\n\n- Opposing party name(s) — does the clinic represent or have represented them?\n- Related parties — anyone else the student or clinic might have a conflict with?\n- Positional conflicts — is this case asking for something that would hurt another clinic client?\n\nFlag for professor review. Don't resolve the conflict — surface it.\n\n### Step 5: Triage classification\n\nNot a case-acceptance decision — a triage input:\n\n| Classification | Means |\n|---|---|\n| **Urgent** | Deadline in days, safety issue, irreversible harm imminent |\n| **Time-sensitive** | Deadline in weeks, harm ongoing but not immediately irreversible |\n| **Standard** | No immediate deadline, can queue normally |\n| **May be out of scope** | Issue is outside clinic's practice areas — flag for referral assessment |\n\n### Step 6: Supervision flag check\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) supervision style and flag triggers. If formal queue or configurable flags are enabled, and a trigger is present (deadline mentioned, DV indicator, immigration status at issue, etc.), note the flag.\n\n### Step 7: Deadline handoff — required deliverable\n\nIf the intake surfaces any timeline deadline (answer due, hearing, statute-of-limitations cutoff, cure period, filing window, notice window, ICE check-in, removal hearing, eviction court date, protective order renewal), **emit a copy-paste-ready `/legal-clinic:deadlines --add ...` block as part of the intake output**. This is a required deliverable, not a suggestion — the intake identifies deadlines, and the student shouldn't have to re-transcribe them into the deadline skill.\n\nFormat each deadline as a fenced code block the student can copy, with every field pre-populated from the intake:\n\n```\n/legal-clinic:deadlines --add\n case=[case slug or client-last-name-keyword]\n type=[response|hearing|statute-of-limitations|discovery|cure-period|filing-window|notice|other]\n description=\"[one-line description of what is due]\"\n due=[VERIFY — student + supervisor compute from triggering event]\n source=\"[triggering event + statute/rule cite, e.g., 'UD complaint served 2026-05-04, CCP § 1167']\"\n owner=[student name]\n warnings=[14,7,3,1]\n```\n\nRules:\n- One block per deadline surfaced. Do not combine. Each one will route through the deadlines skill's pre-add duplicate check.\n- Leave the `due=` value as `[VERIFY — student + supervisor compute]` when the deadline is jurisdictional (response deadline, SOL, notice window under a specific rule). The deadlines skill will not compute for you; the student + supervisor do the math and update the entry.\n- When a date is given in the triggering document (a hearing date on a summons, an ICE check-in date, a renewal deadline on a protective order), put that date in `due=`. When the date is computed (count N days from triggering event), leave the `[VERIFY]` marker.\n- If no deadline is surfaced in the intake, omit this section — don't fabricate one.\n\n## Output\n\n```markdown\n# Intake Summary: [Client name or ID]\n\n---\n[AI-ASSISTED DRAFT — requires student analysis and attorney review]\n\n**Privilege and confidentiality.** This summary is derived from client communications that may be privileged, confidential, or both. It inherits the source's privilege status. Distributing it beyond the privilege circle (including outside the clinic) can waive privilege. Keep it in the clinic's privileged file store, mark it appropriately, and make distribution decisions with your supervisor.\n---\n\n**Date:** [date] | **Intake by:** [student] | **Practice area:** [primary + any cross-area]\n\n## Bottom line\n\n[Take the case / Decline because X / Need more info on Y — next step is Z]\n\n## Client's situation (in their words)\n\n[The narrative the client gave, before legal categorization. This is the human story.]\n\n## Legal issues identified\n\n*Every statutory, ordinance, regulatory, rule, or case citation in this section carries a provenance tag (see plugin your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Shared guardrails` for the tag vocabulary). `[user provided]` if the supervisor uploaded the text, `[statute / regulator site]` if you fetched it this session from an official source, a research-connector tag (`[CourtListener]`, etc.) if it came from a tool result in this conversation, `[model knowledge — verify]` otherwise. The default is `[model knowledge — verify]`. A supervising attorney who cannot verify a cite against a connector needs to see the tag to know what to check first.*\n\n### Primary ([practice area])\n- [Issue 1]: [one line with any cite tagged, e.g., \"RLTO §5-12-080 `[model knowledge — verify]`\"]\n- [Issue 2]: [one line]\n\n### Cross-practice-area flags\n- [Other area]: [what the client said that raised it]\n [UNCERTAIN: whether clinic handles this or refers — professor call]\n\n## Key facts\n\n| Fact | Source | Documentation |\n|---|---|---|\n| [fact] | [client statement / document provided] | [have it / need it] |\n\n## Conflict check\n\n**Opposing party:** [name(s)]\n**Related parties:** [any]\n**Flag:** [clear / needs conflict check against clinic database]\n\n## Triage\n\n**Classification:** [Urgent / Time-sensitive / Standard / May be out of scope]\n**Driving deadline:** [if any — date and what it is]\n\n## Deadlines to log\n\n[One `/legal-clinic:deadlines --add ...` block per surfaced deadline — Step 7.\nIf none, omit this section.]\n\n## Jurisdictional notes\n\n*Every statute, ordinance, rule, or case citation in this section carries a provenance tag — same vocabulary as `## Legal issues identified`. Default `[model knowledge — verify]`. When no research connector is reachable for this session, record it in the **Sources:** line of the reviewer note (see plugin your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`) — do not emit a standalone banner.*\n\n[State-specific or local-rule-specific issues relevant to this case type, per\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) jurisdiction, with each cite tagged]\n\n## Supervision flags\n\n[If supervision style includes flags: which fired and why. If formal queue:\n\"QUEUED for [professor].\"]\n\n---\n\n## Verification prompts for the student\n\nBefore analysis, verify:\n- [ ] [Specific fact the intake relies on — confirm with client or documents]\n- [ ] [Deadline date — confirm from the actual notice/court document, not client's memory]\n- [ ] [Any legal conclusion above is a starting hypothesis — research before relying on it]\n\n## What this summary does NOT do\n\nThis summary does not decide whether the clinic takes this case. That's your\nanalysis and [Professor]'s judgment. It structures what the client told you\nso you can spend your time on the analysis instead of the write-up.\n```\n\n## Practice-area intake template references\n\nStore practice-area-specific question sets at `references/intake-templates/[area].md`. Cold-start populates these from the professor's intake form(s); if none provided, use the defaults above.\n\n## What this skill does NOT do\n\n- **Decide case acceptance.** Student analyzes, professor decides.\n- **Resolve conflicts.** Flags them for the professor.\n- **Give advice during intake.** Intake is gathering; advice comes after analysis and professor review.\n- **Produce a final document.** The summary is a starting point — the student reads it, corrects anything mischaracterized, and builds the analysis from it.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-clinic-client-letter", + title: "Client Letter", + practice: "Legal Clinic", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “client-letter” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /client-letter\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → plain-language standards, supervision style, clinic contact info.\n2. Use the templates and workflow below.\n3. Match type to template. Plain-language check.\n4. Output with AI-assisted label, supervision routing.\n\nScope: routine only. Substantive advice → `/status client` or a conversation with the professor.\n\n```\n/legal-clinic:client-letter appointment\n```\n\n```\n/legal-clinic:client-letter doc-request\n```\n\n---\n\n# Client Letter: Routine Correspondence\n\n## Purpose\n\nClinics send a lot of routine correspondence: \"your appointment is Tuesday at 2pm,\" \"please bring your lease,\" \"we filed your answer.\" This skill handles those from templates so students aren't typing the same letter every week.\n\n**Scope: routine only.** Substantive advice, bad news, case strategy — those are `/status client` or a conversation, not a template letter.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → plain-language standards, supervision style, clinic contact info.\n\n## Pedagogy check\n\nRead the supervisor guide for this practice area at the current project's documents. Check the `pedagogy_posture` setting:\n\n- **`guide` (default):** Produce the structure and the checklist (required elements, plain-language targets, sign-off per student practice rule). Ask the student to draft each section. Give feedback on their draft (register, reading level, required elements, what they missed). Offer to fill a section only when the student has tried once.\n- **`assist`:** Produce the letter. Flag items for student review. The student edits and learns by reviewing.\n- **`teach`:** Don't produce the letter. Ask the student to draft it. Give feedback. Ask leading questions when they're stuck. Only show a model paragraph after two attempts, and only the section they're stuck on. Track what they got right and wrong so the supervisor can see progress.\n\nIf no guide exists, use `guide`. If the guide exists but doesn't set a posture, use `guide`.\n\nWhatever the posture, the output always includes: \"**Pedagogy mode: [assist/guide/teach]** — set by your supervisor's guide. This means I [description of what the student did vs what the skill did].\"\n\n## Sign-off and student-attorney disclosure\n\nCheck your jurisdiction's student practice rule for required disclosure language in letters signed by a law student. Some jurisdictions require specific forms; most require that the student identify themselves as a law student / certified legal intern and identify the supervising attorney. The templates below use a generic form — conform the sign-off to your rule before sending.\n\n## Letter types\n\n> **Review label goes OUTSIDE the letter.** The `[AI-ASSISTED DRAFT — requires review per plugin config supervision step]` tag is a note to the student, not part of the letter body. Place it above the rendered template (or in a header the student deletes before sending), never inside the fenced letter content. If it ends up in the client-facing copy, the skill has failed.\n\n### Appointment confirmation\n\n*Review label for the student (not for the client — strip before sending):*\n`[AI-ASSISTED DRAFT — requires review per plugin config supervision step]`\n\n```markdown\nDear [Client],\n\nThis confirms your appointment with [Clinic name]:\n\n**Date:** [date]\n**Time:** [time]\n**Where:** [address / room / or \"by phone at [number]\"]\n**With:** [student name]\n\n**Please bring:** [documents needed — from case notes or leave as prompt\nfor student to fill]\n\nIf you need to reschedule, call us at [clinic phone] at least 24 hours before.\n\n[Student name]\nLaw Student, Certified Legal Intern\nUnder the supervision of [Supervising Attorney]\n[Clinic name] | [phone] | [hours]\n```\n\n### Document request\n\n*Review label for the student (not for the client — strip before sending):*\n`[AI-ASSISTED DRAFT — requires review per plugin config supervision step]`\n\n```markdown\nDear [Client],\n\nTo move your case forward, we need the following documents from you:\n\n- [Document 1 — e.g., \"Your lease agreement\"]\n- [Document 2 — e.g., \"The notice you received from your landlord\"]\n- [Document 3]\n\n**How to get them to us:** [drop off at clinic / email to [address] / bring\nto next appointment]\n\n**Please send by:** [date — if there's a deadline, say why: \"We need these\nby [date] so we can file your answer before the court deadline.\"]\n\nIf you don't have some of these or aren't sure what we mean, call us at\n[clinic phone] and we can help.\n\n[Student name]\nLaw Student, Certified Legal Intern\nUnder the supervision of [Supervising Attorney]\n[Clinic name] | [phone] | [hours]\n```\n\n### Brief status update\n\nFor routine \"we filed it\" / \"we're waiting\" updates. (Fuller status updates → `/status client`.)\n\n*Review label for the student (not for the client — strip before sending):*\n`[AI-ASSISTED DRAFT — requires review per plugin config supervision step]`\n\n```markdown\nDear [Client],\n\nQuick update: [one-line what happened — \"We filed your answer with the court\non [date]\" / \"We sent the demand letter to your landlord on [date]\"].\n\n**What's next:** [one line — \"We're waiting for their response\" / \"The court\nwill schedule a hearing and let us know the date\"].\n\nYou don't need to do anything right now. We'll let you know when we do.\n\n[Student name]\nLaw Student, Certified Legal Intern\nUnder the supervision of [Supervising Attorney]\n[Clinic name] | [phone] | [hours]\n```\n\n## Before sending\n\nSending a letter to a client is a consequential action. This plugin's gate is the supervision workflow described in `## Supervision style` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), reinforced by the Part 0 role check that confirms a licensed supervising attorney owns the clinic setup. That gate still holds: every letter clears review before it leaves the clinic.\n\nBefore sending any of the letters above, confirm:\n\n1. The draft has been reviewed per the supervision protocol in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) (queue / flag / lighter-touch).\n2. All internal review labels (`[AI-ASSISTED DRAFT]`, any `[VERIFY]` or `[FACT NEEDED]` tags) have been removed from the client-facing copy.\n3. The sign-off conforms to your jurisdiction's student practice rule for law-student-signed correspondence.\n\n**This is a student draft for supervising-attorney review, not a final letter.** Sending it has legal consequences for the client and may constitute legal advice or communication on the client's behalf. A licensed supervising attorney reviews, edits, and signs off before the letter leaves the clinic. Do not send without supervisor approval.\n\n## Plain-language check\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) standards. Short sentences. No jargon. Reading level target enforced. If a template above includes a legal term the client might not know, explain it the first time: \"We filed your 'answer' — that's the document that tells the court your side of the story.\"\n\n## Supervision routing\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Routine correspondence may or may not be a flag trigger depending on the supervision style the professor chose. If lighter-touch: these go out after student review without a queue step. If formal queue: even routine letters queue.\n\n## What this skill does NOT do\n\n- **Substantive advice.** If the letter would say \"here's what I think about your case\" or \"here's what you should do,\" that's not routine — that's `/status client` or a conversation with the professor first.\n- **Bad news.** Case closing, adverse ruling, can't-help — those need thought, not a template. Flag for professor.\n- **Anything to opposing counsel or a court.** Different audience, different skill (`/draft` or `/status court`).", + }, + { + id: "builtin-cfl-clinic-draft", + title: "Draft", + practice: "Legal Clinic", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “draft” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /draft\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → practice-area templates, jurisdiction, local rules, supervision style.\n2. Use the workflow below.\n3. Match doc type to template. Gather facts from case notes — flag missing, never guess.\n4. Apply jurisdiction formatting. Draft with `[FACT NEEDED]`, `[VERIFY]`, `[UNCERTAIN]` flags inline.\n5. Output with prominent AI-assisted label, student review checklist, supervision routing.\n\n```\n/legal-clinic:draft eviction-answer\n```\n\n```\n/legal-clinic:draft asylum-declaration\n```\n\n---\n\n# Draft: First-Draft Document Generation\n\n## Purpose\n\nStudents spend enormous time on first drafts of documents where the educational value is in the analysis and strategy, not in formatting a caption or writing \"Dear Judge.\" This skill produces the first draft from case notes and practice-area templates so the student's time goes to the thinking.\n\n**Every draft is explicitly a starting point.** Not final work product. The student analyzes, revises, and the professor reviews before anything goes anywhere.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → practice areas, practice-area templates, jurisdiction (state + local court + any local rules ingested), supervision style.\n\nCase notes or intake summary for the facts.\n\n## Pedagogy check\n\nRead the supervisor guide for this practice area at the current project's documents. Check the `pedagogy_posture` setting:\n\n- **`guide` (default):** Produce the structure and the checklist. Ask the student to draft each section. Give feedback on their draft (register, reading level, required elements, what they missed). Offer to fill a section only when the student has tried once.\n- **`assist`:** Produce the work product. Flag items for student review. The student edits and learns by reviewing.\n- **`teach`:** Don't produce the work product. Ask the student to draft it. Give feedback. Ask leading questions when they're stuck. Only show a model paragraph after two attempts, and only the section they're stuck on. Track what they got right and wrong so the supervisor can see progress.\n\nIf no guide exists, use `guide`. If the guide exists but doesn't set a posture, use `guide`.\n\nWhatever the posture, the output always includes: \"**Pedagogy mode: [assist/guide/teach]** — set by your supervisor's guide. This means I [description of what the student did vs what the skill did].\"\n\n**Jurisdiction assumption.** The draft assumes the state, court, and local rules set in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Caption format, service requirements, page limits, filing windows, and substantive rules vary materially across jurisdictions and even between courts in the same state. If the matter is in a different court or a different state, confirm with your supervisor before relying on any format, deadline, or argument in the draft.\n\n## Workflow\n\n### Step 1: Which document?\n\nMatch the request to the clinic's template set (from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)). Common set by practice area:\n\n| Practice area | Documents |\n|---|---|\n| **Immigration** | I-589 asylum application narrative, client declaration, motion to change venue, motion to continue, FOIA request, country conditions summary |\n| **Housing** | Eviction answer, demand letter (repairs/deposit), motion to stay execution, discovery requests |\n| **Family** | Protective order petition, custody declaration, motion to modify, financial affidavit |\n| **Consumer** | Debt validation letter, FDCPA demand letter, answer to collection complaint, motion to vacate default |\n| **General litigation** | Motion template, notice of appearance, certificate of service |\n\nIf the requested document isn't in the template set: \"The clinic's templates don't include [X]. I can attempt a draft from general principles, but flag this heavily — it hasn't been tuned for your practice area or jurisdiction. Better to ask [Professor] if there's an existing template.\"\n\n### Step 2: Gather the facts\n\nRead the intake summary or case notes. For each fact the document needs: do we have it?\n\n| Document needs | Have? | Source |\n|---|---|---|\n| [fact] | ✓ / ✗ | [intake / client doc / need to get] |\n\nMissing required facts → don't guess. Mark them: `[FACT NEEDED: client's entry date — get from I-94 or ask client]`.\n\n### Step 3: Apply jurisdiction\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) jurisdiction:\n\n- **Caption format:** state and local court rules. If local rules were ingested at cold-start, use them. If not, use state default and flag: `[VERIFY CAPTION: local rules not loaded — confirm format against [Court]'s current rules]`\n- **Service requirements:** who gets served, how, by when per the court's rules\n- **Local quirks:** page limits, font requirements, standing orders. Apply what's ingested; flag what isn't.\n\n### Step 4: Draft\n\nUse the practice-area template. Fill what can be filled from facts. Leave placeholders explicit — never fill with plausible-sounding invention.\n\n**Everywhere the draft makes a legal assertion:** that assertion is a hypothesis the student verifies, not a conclusion the draft guarantees. Mark accordingly.\n\n### Step 5: Flag uncertainty\n\nThree kinds of flags, in-line:\n\n- `[FACT NEEDED: ...]` — the document needs a fact the case notes don't have\n- `[VERIFY: ...]` — a legal or factual assertion that needs checking before this is filed\n- `[UNCERTAIN: ...]` — the skill is genuinely unsure and says so rather than guessing\n\n### Step 6: Supervision routing\n\nFiling a document with a court or agency is a consequential action. The gate is the supervision workflow in `## Supervision style` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), reinforced by the Part 0 role check that confirms a licensed supervising attorney owns the clinic setup. Court filings always route through supervision before filing, regardless of the supervision-style choice.\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) supervision style:\n- **Formal queue:** draft goes to queue, student sees \"queued for [Professor]\"\n- **Configurable flags:** if this document type is a flag trigger (court filings usually are), output includes \"CHECK WITH [PROFESSOR] BEFORE FILING\"\n- **Lighter-touch:** standard safeguard label, no additional gate — but court filings still go to the professor before filing per the clinic's existing supervision structure\n\n## Output\n\n```markdown\n═══════════════════════════════════════════════════════════════════════\n AI-ASSISTED DRAFT — REQUIRES STUDENT ANALYSIS AND ATTORNEY REVIEW\n This is a starting point, not final work product.\n Every [VERIFY] and [FACT NEEDED] flag must be resolved before filing.\n═══════════════════════════════════════════════════════════════════════\n\n[The document — in the practice-area template format, jurisdiction-aware,\nwith flags inline]\n\n═══════════════════════════════════════════════════════════════════════\n\n## Student review checklist\n\nBefore showing this to [Professor]:\n\n- [ ] Read the whole thing. Does it say what you want it to say?\n- [ ] Every fact: is it accurate per the client's actual documents, not just the intake notes?\n- [ ] Every [VERIFY] flag: resolved with research or struck\n- [ ] Every [FACT NEEDED] flag: filled with verified information or the section removed\n- [ ] Legal theory: is this the right argument? Are there better ones? (That's your analysis, not the draft's.)\n- [ ] Jurisdiction: caption, service, format correct per current local rules\n- [ ] [Supervision step per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) style]\n\n## What this draft does NOT do\n\n- It does not decide strategy. The draft follows the most common approach for\n this document type — you decide if that's right for this client.\n- It does not verify its own legal assertions. Every legal conclusion above is\n a hypothesis until you research it.\n- It does not file itself. [Professor] reviews, you file per clinic procedure.\n\n---\n\n**Before this leaves the clinic.** This is a student draft for supervising-attorney review, not a final letter, filing, or form. Filing it with a court or agency, or sending it to a client or opposing party, has legal consequences for the client. A licensed supervising attorney reviews, edits, and signs off before it leaves the clinic. Strip the AI-assisted draft header only after that sign-off. Do not send or file this draft without supervisor approval.\n\n*ABA Formal Opinion 512 (2024): generative AI use requires competence,\nsupervision, and verification. This draft is designed to be supervised and\nverified — it is not designed to be trusted without that.*\n```\n\n## What this skill does NOT do\n\n- **Produce final work product.** First draft only. Student revises, professor reviews.\n- **Guess at missing facts.** Flags them for the student to get.\n- **Decide the legal theory.** Uses the common approach; the student decides if it's the right one for this case.\n- **Replace jurisdiction-specific research.** Applies ingested local rules; flags where rules weren't ingested or might have changed.", + }, + { + id: "builtin-cfl-clinic-memo", + title: "Memo", + practice: "Legal Clinic", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “memo” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /memo\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → practice areas, jurisdiction.\n2. Use the workflow below. Read intake summary / case notes.\n3. Frame issues as questions. Scaffold IRAC for each — Rule blocks are RESEARCH NEEDED, Application is STUDENT ANALYSIS prompts, Conclusion is blank.\n4. Strengths/weaknesses/open questions. Research gaps summary.\n5. Output with prominent \"the analysis is yours\" label.\n\n```\n/legal-clinic:memo\n```\n\n---\n\n# Memo: Internal Case Analysis\n\n## Purpose\n\nThe case analysis memo is where the student's thinking lives. This skill provides the IRAC scaffolding and flags the research gaps — the student fills in the analysis.\n\n**The analysis is the student's.** This skill structures; it doesn't conclude.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → practice areas, jurisdiction, supervision style.\nIntake summary and case notes for facts.\n\n## Pedagogy check\n\nRead the supervisor guide for this practice area at the current project's documents. Check the `pedagogy_posture` setting:\n\n- **`guide` (default):** Produce the IRAC structure and the research-gap list. Ask the student to draft each rule statement themselves from research, rather than giving them a framework. Give feedback on what they wrote. Offer to fill the framework rule for a section only when the student has tried once.\n- **`assist`:** Produce the memo scaffold and fill what can be filled. Flag items for student review. The student edits and learns by reviewing. (Note: this memo skill always leaves the `[STUDENT ANALYSIS]` and `[STUDENT CONCLUSION]` blocks blank by design — `assist` means the skill produces the IRAC scaffold and framework rule statement; it does not produce the application or the conclusion.)\n- **`teach`:** Don't produce the framework or the scaffold content. Ask the student to frame the issues, state the rules from their research, and do the application. Give feedback. Ask leading questions when they're stuck. Only show a model rule statement or a model application paragraph after two attempts, and only for the section they're stuck on. Track what they got right and wrong so the supervisor can see progress.\n\nIf no guide exists, use `guide`. If the guide exists but doesn't set a posture, use `guide`.\n\nWhatever the posture, the output always includes: \"**Pedagogy mode: [assist/guide/teach]** — set by your supervisor's guide. This means I [description of what the student did vs what the skill did].\"\n\n## Workflow\n\n### Step 1: Frame the issues\n\nFrom the intake summary and case notes: what are the legal questions this case presents?\n\nState each as a question. Not \"habitability\" — \"Can the client assert a habitability defense to the eviction based on the broken heater, and if so, does it offset the rent owed?\"\n\nIf there are multiple issues, each gets its own IRAC block.\n\n### Step 2: Scaffold the IRAC\n\nFor each issue:\n\n**Issue:** Stated as a question (from Step 1).\n\n**Rule:** This is a research gap, not a conclusion. State what the student needs to find:\n\n> `[RESEARCH NEEDED: [State] habitability doctrine — warranty of habitability\n> elements, what conditions qualify, remedies available including rent offset.\n> Start with: [State] landlord-tenant statute, then case law on heater/heat\n> specifically. See /research-start for a roadmap.]`\n\nIf the skill has high confidence in the general rule framework (e.g., \"most states recognize an implied warranty of habitability\"), state that as a framework starting point — **but explicitly mark it as unverified**:\n\n> *Framework (unverified — confirm for [State]):* Most jurisdictions recognize\n> an implied warranty of habitability requiring landlords to maintain\n> conditions fit for human occupation. Breach may give rise to rent withholding,\n> repair-and-deduct, or rent abatement.\n> `[VERIFY: [State]'s specific elements and remedies]`\n\n**Application:** This is where the student's analysis goes. Scaffold the structure, don't fill it:\n\n> `[STUDENT ANALYSIS: Apply the rule to the facts. Key facts to address:\n> - Heater broken since November — how long is \"unreasonable\"?\n> - Client notified landlord [when? how? documented?]\n> - Landlord's response or lack thereof\n> - [State]-specific: does client need to have given written notice?\n> deposited rent in escrow? other procedural prerequisites?]`\n\nList the facts that matter. Let the student do the applying.\n\n**Conclusion:** Explicitly blank:\n\n> `[STUDENT CONCLUSION: Based on your research and analysis above, what's the\n> likely outcome? How strong is this defense? What are the weaknesses?]`\n\n### Step 3: Identify strengths, weaknesses, open questions\n\nSeparate section, after the IRAC blocks:\n\n**Strengths (apparent from facts — student should test these):**\n- [Fact that seems helpful and why]\n\n**Weaknesses (apparent from facts — student should assess how serious):**\n- [Fact that seems harmful and why]\n- `[UNCERTAIN: whether [X] is actually a weakness — depends on [State] rule on [Y]]`\n\n**Open questions (things the memo can't answer without more info):**\n- Factual: [what we don't know from the client]\n- Legal: [what needs research]\n- Strategic: [judgment calls for the student/professor]\n\n## Output\n\n```markdown\n═══════════════════════════════════════════════════════════════════════\n AI-ASSISTED SCAFFOLD — THE ANALYSIS IS YOURS TO WRITE\n Every [RESEARCH NEEDED] and [STUDENT ANALYSIS] block is a prompt, not\n a placeholder to delete. The thinking happens when you fill them in.\n═══════════════════════════════════════════════════════════════════════\n\n# Case Analysis Memo: [Client] — [Matter]\n\n**Date:** [date] | **By:** [student] | **For:** [Professor]\n\n---\n\n## Bottom line\n\n[Take the case / Decline because X / Need more info on Y — next step is Z]\n\n---\n\n## Issues Presented\n\n1. [Issue as question]\n2. [Issue as question]\n\n---\n\n## Issue 1: [Issue]\n\n### Rule\n\n[Framework starting point with VERIFY flags, and RESEARCH NEEDED blocks]\n\n### Application\n\n[STUDENT ANALYSIS scaffold with the facts that matter]\n\n### Conclusion\n\n[STUDENT CONCLUSION — blank]\n\n---\n\n[repeat for each issue]\n\n---\n\n## Strengths\n\n[list with caveats]\n\n## Weaknesses\n\n[list with UNCERTAIN flags where applicable]\n\n## Open Questions\n\n**Factual:** [list]\n**Legal:** [list — these feed /research-start]\n**Strategic:** [list — these are for discussion with Professor]\n\n---\n\n## Research gaps summary\n\n[Every RESEARCH NEEDED block pulled out into one list, so the student can\nwork through them systematically — and can run /research-start on each]\n\n═══════════════════════════════════════════════════════════════════════\n\n## What this memo is NOT\n\nThis is a scaffold, not an analysis. The [STUDENT ANALYSIS] blocks are where\nthe educational value lives — filling them in is the work. A memo where those\nblocks are still empty is a memo that hasn't been written yet.\n\n---\n\n**Cite verification — required before use.** Any framework rules, cases, or statutes suggested above were generated by an AI model and have not been verified. Before relying on any citation — or including it in client work — run it through Westlaw, Fastcase, CourtListener, or your clinic's research platform for accuracy and current good-law status. Flag unverified citations to your supervisor.\n\n**Source attribution.** Tag every suggested citation in the scaffold with where it came from: `[Westlaw]`, `[CourtListener]`, `[Fastcase]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the supervising attorney or case file supplied. Citations tagged `verify` carry higher fabrication risk than tool-retrieved citations and should be checked first. Never strip or collapse the tags — they are the supervisor's fastest signal about which citations to verify.\n\n**No silent supplement.** If a query to a configured research tool returns few or no results for a rule the memo needs, say so and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / issue]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) leave `[RULE TO VERIFY]` and stop. Which would you like?\" The supervising attorney decides whether to accept lower-confidence sources.\n```\n\n## What this skill does NOT do\n\n- **Write the analysis.** It scaffolds the IRAC and flags the gaps. The student reasons through the application.\n- **Provide verified rules.** Every rule statement is explicitly unverified until the student researches it.\n- **Reach conclusions.** The C in IRAC is blank on purpose.\n- **Replace the conversation with the professor.** The Open Questions / Strategic section is the agenda for that conversation, not a substitute.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-clinic-research-start", + title: "Research Start", + practice: "Legal Clinic", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “research-start” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /research-start\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdiction, practice area.\n2. Use the workflow below.\n3. Frame the issue specifically. Build roadmap: statutory starting points (unverified), case law areas (not cases), secondary sources, search terms.\n4. If student has existing research uploaded: synthesize and identify gaps.\n5. Output with prominent \"leads not authorities\" header. Everything is a starting point the student verifies.\n\n```\n/legal-clinic:research-start \"habitability defense to nonpayment eviction in [State]\"\n```\n\n---\n\n# Research Start: Roadmap, Not Research\n\n## Purpose\n\nLegal research is essential to clinical education. But the initial phase — figuring out *what* to research, finding the right statute, understanding the framework — is often the most time-consuming and least educational part. Students spend hours finding the starting point before they can do the actual research.\n\nThis skill produces the starting point: statutes to check, case law areas to investigate, search terms for Westlaw and CourtListener. **None of it is verified. None of it is authoritative. All of it is a lead for the student to run down.**\n\n**This is a pedagogical safeguard, not just an ethical one.** Students still learn to research. They just start from a better place.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → jurisdiction (state), practice areas.\n\n## Workflow\n\n### Step 0: Seed documents first\n\n**Before building the roadmap, read the clinic's own seed documents.** The supervising attorney uploaded them at cold-start (handbook, filing guides, local court rules, intake forms, example case files, prior memos) — they are pre-vetted, jurisdiction-specific, and will beat any Westlaw query on the first 20 minutes of a student's research.\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Seed documents`. Identify any item whose purpose or filename matches the research area (e.g., \"Alameda UD filing guide\" for a UD habitability question; a redacted sample case file in the same practice area; a prior memo on the same issue).\n2. For each match, surface it as a **Seed documents to read first** block at the top of the roadmap output. Name the file, say why it matters for this specific question, and say what it likely covers vs. where outside research will still be needed.\n3. If no seed documents match the issue, say so plainly (\"No clinic seed documents match this issue — proceeding straight to primary sources\"). Don't fabricate a match.\n4. If the clinic has the `LIMITED DATA` flag set in `## Seed documents`, add a one-line note: \"Clinic has fewer than 10 seed docs; your professor's precedent bank is thin — lean harder on primary sources and flag what's missing for your supervisor.\"\n\nThe roadmap still covers statutes, case law areas, secondary sources, and search terms — seed docs are the first lead, not a replacement for the rest. But surface them above everything else so the student starts where their supervisor's precedent starts.\n\n### Step 1: Frame the issue\n\nWhat's the research question? Be specific. Not \"eviction defenses\" — \"habitability defense to nonpayment eviction in [State], specifically whether a broken heater qualifies and whether the tenant had to give written notice.\"\n\nIf the question is too broad, narrow it with the student: \"That's three research questions. Let's take them one at a time. Which first?\"\n\n### Step 2: Build the roadmap\n\n**Statutory starting points:**\nList statutes *likely* relevant. State explicitly these are likely, not confirmed.\n\n> **Likely relevant statutes** (UNVERIFIED — confirm currency and applicability):\n> - [State] Landlord-Tenant Act, likely at [State Code Title X] — look for \"warranty of habitability\" or \"repair and deduct\"\n> - Local housing code for [City/County] — may define specific conditions (heat, water) as required\n> - `[VERIFY each citation is current and correct — codes get renumbered]`\n\n**Case law areas to investigate:**\nNot cases — *areas*. The student finds the cases.\n\n> **Case law areas:**\n> - [State] Supreme Court or appellate decisions on implied warranty of habitability — look for the leading case establishing the doctrine\n> - Cases on what conditions qualify — heat specifically, if any\n> - Cases on procedural prerequisites — did tenant have to give notice? withhold rent? escrow?\n> - Cases on the remedy — offset against rent owed, or a separate damages claim?\n\n**Regulatory / administrative sources:**\nIf applicable (immigration especially).\n\n> **Administrative sources:**\n> - [Agency] regulations at [CFR cite area]\n> - Agency guidance or policy manuals — often more current than regs\n> - For immigration: USCIS Policy Manual, BIA precedent decisions\n\n**Secondary sources to orient:**\nWhere to get the framework before diving into primary.\n\n> **Secondary sources (for framework, not to cite):**\n> - [State] practice guide on landlord-tenant (check clinic library)\n> - Relevant CLE materials\n> - Law review notes on the specific issue if it's contested\n\n**Search terms:**\nFor Westlaw, or whatever the clinic uses.\n\n> **Search terms to try:**\n> - Westlaw: `\"warranty of habitability\" /s heat! & [State]`\n> - CourtListener: `implied warranty of habitability AND (heat OR heater) AND [State]`\n> - Refine based on what comes back — these are starting queries\n\n### Step 3: Flag what's uncertain\n\nIf the skill is unsure whether a source is relevant or current:\n\n> `[UNCERTAIN: whether [State] has a specific statute on this vs. common-law\n> doctrine only — the search will tell you]`\n\nUncertainty is stated, not hidden.\n\n> **No silent supplement.** This skill produces leads, not authoritative citations — by design, students run the citations down themselves. But if a query to a configured research tool (Westlaw, CourtListener) returns few or no results for a specific rule or case, say so and stop. Do NOT manufacture citations from web search or model knowledge to fill a thin result set without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) stop here and flag the gap for your supervisor. Which would you like?\" The supervising attorney decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Tag every suggested citation with where it came from: `[Westlaw]`, `[CourtListener]`, `[Fastcase]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations supplied by the supervising attorney or case file. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags — they tell the student which leads are raw research and which are model guesses to verify against a primary source.\n\n### Step 4: Synthesize uploaded research (if any)\n\nIf the student has already done some research and uploads it: read it, identify what's covered and what's missing.\n\n> **From your research so far:**\n> - You have: [summary of what's covered]\n> - Gap: [what the roadmap above suggests that you haven't found yet]\n> - `[VERIFY: the case you cited — [name] — run through a citator (verify it is good law) it, it may have been distinguished or limited]`\n\n## Output\n\n```markdown\n═══════════════════════════════════════════════════════════════════════\n RESEARCH ROADMAP — LEADS, NOT AUTHORITIES\n Nothing below is a verified citation. Every statute, every case area,\n every search term is a starting point for YOUR research. You verify\n currency, applicability, and accuracy. You find the actual cases.\n If something below turns out to be wrong or outdated, that's expected —\n this is a map of where to look, not a substitute for looking.\n═══════════════════════════════════════════════════════════════════════\n\n# Research Roadmap: [Issue]\n\n**Jurisdiction:** [State] | **Practice area:** [area]\n\n## Seed documents to read first\n\n[Per Step 0. List any clinic seed docs that match the issue with a one-line\n\"what this likely covers\" note. If none matched: \"No clinic seed documents\nmatch this issue — proceeding to primary sources.\"]\n\n## Statutory starting points (UNVERIFIED)\n\n[list with VERIFY flags]\n\n## Case law areas to investigate\n\n[areas, not cases]\n\n## Administrative / regulatory sources\n\n[if applicable]\n\n## Secondary sources (for framework, not citation)\n\n[list]\n\n## Search terms\n\n**Westlaw:** [queries]\n\n## Uncertainty flags\n\n[Everywhere the roadmap is genuinely unsure]\n\n---\n\n## What to do with this\n\n1. Start with a secondary source to get the framework\n2. Find and read the primary statutes — confirm the citations above are current\n3. Run the searches, find the leading cases\n4. run through a citator (verify it is good law) everything before relying on it\n5. Come back and run `/memo` to scaffold your analysis once you have the rule\n\n## What this roadmap does NOT do\n\n- **It does not give you citations you can use.** Every cite above is a lead\n to verify, not an authority to rely on.\n- **It does not do the research.** You do the research. This gets you to the\n starting line faster.\n- **It does not replace Westlaw.** Those have the actual cases. This\n tells you where to point them.\n\n---\n\n**Cite verification — required before use.** Citations above were generated by an AI model and have not been verified. Before relying on any case, statute, or rule — or including it in client work — run it through Westlaw, Fastcase, CourtListener, or your clinic's research platform for accuracy and current good-law status. Flag unverified citations to your supervisor.\n```\n\n## What this skill does NOT do\n\n- **Provide authoritative citations.** Explicitly, by design. The student verifies every cite before using it.\n- **Replace legal research.** Accelerates the \"where do I start\" phase; the research itself is still the student's.\n- **Guarantee the roadmap is complete.** It's a starting set of leads. The research may reveal sources the roadmap missed — that's fine, that's research.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-clinic-status", + title: "Status", + practice: "Legal Clinic", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “status” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /status\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → supervision style, plain-language standards, jurisdiction.\n2. Use the workflow below. Read case notes.\n3. Generate for the specified audience:\n - `client` — plain language, what happened/next/you do/reach us\n - `internal` — procedural posture, done since last check-in, upcoming, needs professor input, student's assessment\n - `court` — formal status report in caption format per local rules\n4. Supervision routing per audience (client-facing and court-ready usually flag).\n\n```\n/legal-clinic:status client\n```\n\n```\n/legal-clinic:status internal\n```\n\n```\n/legal-clinic:status court\n```\n\n---\n\n# Status: Audience-Aware Case Summaries\n\n## Purpose\n\nClinics generate enormous numbers of status updates — to clients, to professors, to co-counsel, to courts. Same case, same facts, completely different documents. This skill takes the case notes and produces the right summary for the right reader.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → supervision style, plain-language standards (for client-facing), jurisdiction.\nCase notes for facts.\n\n## Audience modes\n\n### Client-facing\n\n**Reader:** The client. Probably stressed. Possibly unfamiliar with legal process. Reading level per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) plain-language standards (default 6th grade).\n\n**Include:**\n- What's happened since they last heard from the clinic\n- What's happening next and when\n- What (if anything) they need to do\n- How to reach the clinic\n\n**Don't include:**\n- Legal analysis (they don't need to know the IRAC)\n- Weaknesses in their case (unless it's time to have that conversation — and that's a call for the professor, not a status update)\n- Jargon\n\n*Review label for the student (not for the client — strip before sending):*\n`[AI-ASSISTED DRAFT — requires student review and supervision step per plugin config]`\n\nCheck your jurisdiction's student practice rule for required law-student sign-off language; some jurisdictions require specific forms.\n\n```markdown\nDear [Client],\n\nI wanted to update you on your case.\n\n**What's happened:** [Plain English. \"We filed your answer with the court on\n[date]\" not \"The responsive pleading was submitted.\"]\n\n**What's next:** [What and when. \"The court scheduled a hearing for [date] at\n[time]. You need to be there.\" Or: \"We're waiting for the landlord's lawyer\nto respond. That could take a few weeks.\"]\n\n**What you need to do:** [Specific and clear. Or: \"Nothing right now — we'll\nlet you know when we need something from you.\"]\n\n**How to reach us:** [Clinic phone, hours, student name]\n\n[Student name]\nLaw Student, Certified Legal Intern\nUnder the supervision of [Supervising Attorney]\n[Clinic name]\n```\n\n**Before sending:** sending a client status update is a consequential action. The gate is the supervision workflow in `## Supervision style` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), reinforced by the Part 0 role check confirming a licensed supervising attorney owns the setup. Confirm the draft has been reviewed per the supervision protocol (queue / flag / lighter-touch) and all internal review labels (`[AI-ASSISTED DRAFT]`, `[VERIFY]`, etc.) have been removed from the client-facing copy.\n\n### Internal (for the professor)\n\n**Reader:** The supervising professor. Knows the law. Wants to know where the case stands and what the student needs from them.\n\n**Include:**\n- Procedural status (where in the life of the case)\n- What's been done since last check-in\n- What's coming up (deadlines, hearings)\n- Issues needing professor input\n- Student's assessment (how it's going, concerns)\n\n```markdown\n# Status: [Client] — [Matter] — [date]\n\n**Student:** [name] | **Procedural posture:** [pre-filing / answer filed /\ndiscovery / motion pending / etc.]\n\n## Since last check-in\n\n- [What's been done]\n\n## Upcoming\n\n| Date | What | Action needed by |\n|---|---|---|\n| [date] | [deadline/hearing] | [date] |\n\n## Needs professor input\n\n- [Question or decision point — specific]\n\n## Student's assessment\n\n[How it's going. Strengths, concerns, strategic questions. This is where the\nstudent's thinking shows.]\n\n---\n[AI-ASSISTED DRAFT — student should revise the assessment section especially;\nthat's your thinking, not a summary of notes]\n```\n\n### Court-ready\n\n**Reader:** A judge or clerk. Formal. Specific to what the court needs (often a status report ordered by the court, or a statement in advance of a status conference).\n\n**Include:**\n- Procedural history (briefly)\n- Current status of discovery/motions/settlement\n- What's outstanding\n- Proposed next steps or scheduling\n\n**Format:** Per local rules. Caption, signature block, certificate of service if filed.\n\n```markdown\n═══════════════════════════════════════════════════════════════════════\n AI-ASSISTED DRAFT — requires student analysis and attorney review\n Court filings ALWAYS require professor review before filing\n═══════════════════════════════════════════════════════════════════════\n\n[Caption per jurisdiction — VERIFY against current local rules]\n\nSTATUS REPORT\n\n[Party] respectfully submits this status report pursuant to [the court's\norder of [date] / local rule [X] / in advance of the status conference\nscheduled for [date]].\n\n1. Procedural history: [brief]\n\n2. Current status: [discovery status / motion status / settlement status]\n\n3. Outstanding matters: [what's pending]\n\n4. Proposed next steps: [scheduling, if the court wants input]\n\n[Signature block — student attorney under supervision of [Professor]]\n\n[Certificate of service if filing]\n\n---\n\n[VERIFY: caption format, local status report requirements, service\nrequirements — per current [Court] rules]\n```\n\n## Supervision routing\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n- Client-facing → usually a flag trigger (client communication)\n- Internal → no flag (it's going to the professor anyway)\n- Court-ready → always flagged if formal queue enabled (court filings)\n\n## What this skill does NOT do\n\n- **Decide what to tell the client.** Especially on bad news or case weaknesses — that's a conversation for the student and professor to have, then the student to have with the client. Status updates are status, not strategic advice.\n- **File anything with a court.** Drafts the document; professor reviews; filing per clinic procedure.\n- **Replace the student's assessment in internal status.** The \"student's assessment\" section is the student's thinking — the draft can scaffold it but can't write it.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-litigation-brief-section-drafter", + title: "Brief Section Drafter", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “brief-section-drafter” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /brief-section-drafter\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → case theory, house style.\n2. Follow the workflow and reference below.\n3. Draft in house format/tone/citation style. Consistent with theory.\n4. Output: draft section. Flag every place a fact or cite needs verification.\n\n---\n\n# Brief Section Drafter\n\n## Witness statements for England & Wales — PD 57AC\n\nIf the user's jurisdiction includes England & Wales and they're asking for a trial witness statement for the Business & Property Courts (or any CPR-governed proceeding), PD 57AC applies. The statement must be in the witness's own words, must not contain argument, must identify the documents the witness used to refresh their memory, and must carry the required confirmation of compliance and the legal representative's certificate.\n\n**Drafting a narrative \"as the witness\" from a chronology, document set, or your account of the case is exactly what PD 57AC was designed to prevent.** Courts are actively sanctioning AI-assisted witness statement drafting. If you ask me to do it, I won't.\n\nWhat I WILL do: prepare question prompts to elicit the witness's actual recollection; capture and organize what the witness says (their words, not mine); generate the list of documents they were shown; run a PD 57AC compliance checklist against a statement they've drafted; draft the solicitor's certificate of compliance. I help you get the witness's evidence into the statement. I don't write the evidence.\n\nFor US depositions, declarations, and affidavits: different rules, but the same discipline applies. A declaration in the declarant's voice that the declarant didn't write is a credibility problem at best.\n\n## Purpose\n\nA good brief section is consistent with the theory, cited to the record, written in house style, and checkable. This skill produces the first draft — emphasis on *draft*. Partner edits.\n\n## Written or oral?\n\nAsk before drafting: \"Is this for a written submission or oral argument?\" They are different crafts:\n\n- **Written:** thorough. Cover the points, develop the authority, anticipate the responses.\n- **Oral (rebuttal, closing, argument):** strategic. Pick the 3-4 points that matter most. Concede or ignore the weak ones. Lead with your strongest. A tribunal remembers the first two minutes and the last two. \"Too thorough\" for oral advocacy reads as unfocused. If you're responding to a multi-issue submission, tell the user which issues you'd press and which you'd let go — that's the draft of the strategy, not just the words.\n\n## Record fidelity — quotes and pinpoints\n\nTwo rules that govern every citation and every quotation in advocacy drafting. The canonical statement lives in the plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) shared guardrails; repeated here because this skill is the most common place the rule gets tested.\n\n**Verbatim quotes from the record must be verbatim.** Never put quotation marks around words attributed to opposing counsel, a witness, the court, or any record document unless you have the exact passage in front of you and can cite to it. A quote that's almost right is worse than a paraphrase — it misrepresents the record, it's sanctionable if filed, and it will be caught. When you want to characterize what someone said but can't find the exact words:\n\n- **Paraphrase without quotation marks**, attributing clearly: \"Opposing counsel argued that X `[verify against record — Tr. p. __]`.\"\n- **Mark the placeholder:** `[verify exact quote — record cite pending]`\n- **Never fill the gap.** An invented quote, even one word, is a fabrication. The reviewer note must flag every `[verify exact quote]` in the output.\n\nBefore citing any passage with quotation marks, have the source open. If you're working from memory or a summary, no quotation marks.\n\n**Pinpoint cites must support the whole proposition.** If the argument is \"opposing counsel said X, Y, and Z\" and you're citing one pinpoint, verify the pinpoint supports X AND Y AND Z. If it only supports Z, either (a) split the cite — \"said X (Tr. p. 10), Y (Tr. p. 12), and Z (Tr. p. 15)\" — or (b) narrow the proposition to what the pinpoint actually supports. A cite that supports part of a claim is how a tribunal catches you stretching. It's the single most common way a lawyer's credibility erodes in front of a court. This is the \"misgrounded citation\" failure mode: the cite exists, the passage exists, but the passage doesn't support the proposition as stated.\n\n## Candor about weak arguments\n\nWhen the law is against you, say so. When an argument is weak — the authority cuts the other way, the facts don't support it, the inference is a stretch — don't construct a shaky argument and present it as if it were solid. Flag it:\n\n> \"This point is weak — [authority] cuts the other way. Consider whether to press it (here's how you'd frame it), concede and pivot to [stronger point], or drop it. `[review — strategic call]`.\"\n\nAsserting a weak argument without flagging it erodes the lawyer's credibility with the tribunal and creates a candor problem (MR 3.1 — a lawyer must have a basis in law and fact). The draft should make the lawyer smarter, not confident about a bad position.\n\n## Citation extraction coverage\n\nWhen this draft is cite-checked — by you, by another skill, or by a reviewer running through what you produced — the check must be exhaustive, not selective:\n\n1. **First pass: extract.** Read the whole document and build a list of every citation — cases, statutes, regulations, record cites, secondary authority. Report the count: \"Found [N] citations.\"\n2. **Second pass: check.** Check each one against the source. Don't sample. Don't stop when you get tired.\n3. **Report coverage.** At the end: \"Checked [N] of [M] citations. [K] could not be retrieved — verify manually. [J] confirmed. [I] flagged as potential miscitations. [H] flagged as misgrounded (cite exists but doesn't support the proposition).\"\n4. **When source text is unavailable, say \"could not check,\" never \"confirmed.\"** A false positive (\"this cite is fine\" when you couldn't read the source) is worse than \"couldn't check this one.\"\n5. **The hardest errors to catch are partial support.** A cite that backs part of a claim but not all of it. Read the proposition the brief makes, read what the source actually holds, and compare element by element.\n\n## Echo vs repeat\n\nEcho key framings; don't lift sentences. Consistency with prior submissions is good — it reinforces your theory of the case and makes the record coherent. But there's a line between echoing and repeating.\n\n- **Echo:** use the same key terms, the same framing of the central issue, the same characterization of the other side's theory.\n- **Don't:** lift whole sentences, re-use distinctive phrasings so often the tribunal notices, or repeat the same argument verbatim without advancing it.\n\nA rebuttal that sounds like a re-read of the opening loses ground. The draft should advance the argument, not restate it.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → case theory, house style (citation format, structure, tone, length norms).\n\n**Conflicts gate — unbypassable.** Before drafting, check the current project's documents for the matter slug this skill is being invoked on. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace is set up. I won't draft substantive work product on a matter that hasn't been intaken — the conflicts check is the gate.\"\n\nDo not proceed on an unintaken matter. Intake is what runs conflicts, sets up `matter.md` / `history.md`, and writes the `_log.yaml` row this skill reads from. Skipping it produces work in an unmanaged location and bypasses the firm's conflicts discipline.\n\n## Workflow\n\n### Step 1: Which section?\n\n| Section | What it does | Inputs needed |\n|---|---|---|\n| Statement of facts | Tells the story, in our frame, cited to record | Chronology, key docs, depo cites |\n| Standard of review | Sets the bar the court applies | Procedural posture |\n| Argument | Makes the legal case | Issue, authorities, facts |\n| Conclusion | Asks for relief | What we want |\n\n### Step 2: Theory check\n\nBefore writing: what does this section need to accomplish for the theory?\n\n- Statement of facts: Frame the story so our theory is the natural reading.\n- Argument: Connect the law to the facts in a way that supports the theory.\n\nIf the section you're about to draft contradicts the theory — stop. Either the theory is wrong or the section approach is wrong. Flag it, don't paper over it.\n\n### Step 3: Draft in house style\n\n**Research the forum's local rules and the judge's standing orders for length, formatting, citation, and filing requirements; don't rely on preferences. Cite primary sources (local rule number, standing order section) in the drafting notes. Verify currency — local rules change.**\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- **Citation format:** Bluebook, ALWD, or local — match exactly. Signals, pincites, parentheticals per house practice, confirmed against the local rule.\n- **Structure:** How does this firm organize arguments? CRAC? Topic sentences first? Headings that argue vs. headings that describe?\n- **Tone:** Aggressive (\"Defendants' argument is meritless\") or measured (\"The evidence does not support Defendants' position\")? Match the seed brief.\n- **Length:** per the local rule / standing order — never relying on \"what this judge usually wants\" when the rule is checkable.\n\n### Step 4: Cite everything\n\nEvery fact → record cite (Bates, depo page:line, exhibit).\nEvery legal proposition → case cite with pincite.\n\n**Marker discipline — use liberally:**\n- `[VERIFY: specific factual assertion]` — anything not confirmed against the record\n- `[UNCERTAIN: specific legal proposition]` — anything not confirmed against current authority\n- `[CITE NEEDED: specific cite — fact/rule believed but cite not yet pinned]`\n\nA draft with unresolved markers is not final. The markers make the verification step explicit.\n\n**No silent supplement.** If a research query to the configured legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or firm platform) returns few or no results for an authority the draft needs, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [issue / holding]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) leave the `[CITE NEEDED]` marker and stop here. Which would you like?\" A partner decides whether to accept lower-confidence sources; the skill does not decide for them.\n\n**Source attribution.** Tag every citation in the draft with where it came from: `[Westlaw]`, `[CourtListener]`, `[Trellis]`, `[Descrybe]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the partner or senior associate supplied. Citations tagged `verify` carry higher fabrication risk than tool-retrieved citations and should be checked first. Never strip or collapse the tags — they are the reviewing attorney's fastest signal about which citations to Shepardize first before the brief is filed.\n\n### Step 5: Output\n\n**Before the brief is filed (the consequential act — this skill drafts, but the gate runs at the filing step regardless of who triggers it):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Filing a brief has legal consequences — it becomes the record, binds the client on arguments and facts asserted, and a Rule 11 / equivalent certification attaches to signature. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the section drafted, the theory tie-in, authorities relied on, open `[VERIFY]` / `[UNCERTAIN]` / `[CITE NEEDED]` markers unresolved, what could go wrong (factual misstatement, unsupported citation, argument outside the theory), what to ask the attorney before filing.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not treat the draft as filing-ready without an explicit yes. Drafting itself does not require the gate — filing does.\n\nThe section, in house style, with markers inline.\n\nPreface (not in the brief — a note to the reviewing attorney):\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Drafting Notes — [Section] — [date]\n\n**Theory tie-in:** [How this section supports the case theory]\n**Authorities relied on:** [list — all need Shepardizing]\n**Record cites to verify:** [N] flagged inline\n**Open questions for the partner:** [anything the draft assumes that should be confirmed]\n**Length:** [words/pages vs. house norm]\n\n---\n\n**Cite check before filing.** Citations in this draft were generated by an AI model and have not been verified against a primary source. Run every case, statute, and regulation through Westlaw, CourtListener, or your firm's research platform for accuracy, good-law status, and subsequent history. Fabricated or misquoted citations in filed briefs have resulted in Rule 11 sanctions.\n\n**Draft only — not a filing.** Filing this section initiates (or participates in) a proceeding and carries Rule 11 / Rule 3.3 exposure. A licensed attorney reviews, edits, and takes professional responsibility before it goes on the docket. Do not file unreviewed.\n```\n\n## Statement of facts specifics\n\nThe statement of facts is advocacy through selection and sequence, not argument.\n\n- Chronological unless there's a reason not to be\n- **Every fact in the statement of facts must cite to the record — a page and line reference, a docket entry, an exhibit.** \"Or conceded\" is not a substitute for a record cite. If the fact is established by a concession or stipulation, cite the stipulation document or the hearing transcript where the concession was made.\n- Frame through selection: which facts lead, which get one line, which get omitted (if not necessary and not helpful)\n- No argument. \"The contract unambiguously required X\" is argument. \"The contract stated 'X.'\" is fact.\n\n## Argument section specifics\n\n- Lead with the rule, not the facts (usually — house style may differ)\n- One argument per section. If it's really two arguments, it's two sections.\n- Address the other side's best counterargument. Don't hide from it — a brief that ignores the obvious counter is a brief the judge doesn't trust.\n- Parentheticals earn their space. If a parenthetical doesn't add something the cite alone doesn't, cut it.\n\n## What this skill does not do\n\n- Produce a final brief. It produces a draft. Every cite needs verification, every argument needs a partner's eyes.\n- Decide strategy. If there are two ways to argue the issue, flag both and let the partner choose.\n- File anything. Ever.", + }, + { + id: "builtin-cfl-litigation-chronology", + title: "Chronology", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “chronology” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /chronology\n\n1. Load the current project's documents → theory, pivot fact, key facts.\n2. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Document storage sources, default matter folder pattern.\n3. Follow the workflow and reference below.\n4. Identify sources in order: user-provided paths this session, default matter folder, declared sources from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n5. For readable sources: extract dated events. For unreachable sources: note in Gaps.\n6. De-dupe, merge with sources list per event.\n7. Tag significance (🔴/🟡/⚪) per matter theory.\n8. Write the current project's documents (or format variant per flag).\n9. If prior version exists: version number increments, diff summary presented to user.\n10. Confirm before finalizing: \"Here's what I built. Scan the 🔴 entries — anything I miscalled?\"\n\n---\n\n# Chronology\n\n## Disclosed-document use restrictions\n\nBefore working with a set of litigation documents, ask: \"Were any of these documents obtained through disclosure or discovery in legal proceedings?\" If yes:\n\n- **England & Wales (CPR 31.22):** Documents obtained through disclosure are subject to the implied undertaking — you may only use them for the purpose of the proceedings in which they were disclosed, unless the court grants permission, the disclosing party consents, or the document has been read in open court. Using them for a different matter, a different claim, or a commercial purpose without permission is a contempt.\n- **US:** Protective orders and Rule 26(c) may impose similar restrictions. Check the order.\n- **Other jurisdictions:** Similar restrictions commonly apply. Check the local rule.\n\nConfirm: \"This use is within the proceedings in which the documents were disclosed, or I have permission / consent, or the documents are now public.\" If not confirmed, flag it: \"⚠️ Disclosed documents may have use restrictions. Confirm this use is permitted before proceeding.\"\n\n## Purpose\n\nFacts happen in order. The chronology is the spine every narrative hangs on — the statement of facts in a brief, reserve memos, settlement memos, depo prep, witness prep. Building a chron by hand is slow; AI is good at structured extraction. The catch: garbage-in, garbage-out. This skill pulls from the sources the configuration declares and from whatever the user uploads.\n\n## Modes\n\nThis skill serves two practice settings. Pick a default from the user's `## Role` in the plugin's configuration your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile); the user can override per-run with a flag.\n\n- **`--matter` mode (default for in-house litigation counsel).** Matter-history-focused. Reads the matter's case theory and key facts from `matter.md`, pulls from declared document-storage sources (Google Drive, SharePoint, Gmail, iManage, CLM — whatever the `## Landscape` section of your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) declares), and treats `history.md` as the running internal log (decisions, holds, reserve memos — intentionally not in the chronology). Output is matter-centric: what happened across the dispute, tagged for advocacy use.\n- **`--documents` mode (default for firm associate / paralegal).** Production-document-focused. Reads the case theory from the configuration, then extracts from an eDiscovery export, a custodial file set, or a Bates-numbered production. Output is production-centric: what the documents show, with Bates citations, tagged per the case theory.\n\nBoth modes converge on the same output structure (timeline, 🔴/🟡/⚪ significance tags, gaps, SoF variant). The difference is the source profile and the significance frame.\n\nIf `## Role` is `solo` or `other`, default to `--matter` but mention both modes on the first run and let the user pick.\n\n## Side framing (significance tags)\n\nThe same event is significant in different ways depending on whether the practitioner is proving a claim or disproving it. Read `## Side` in the practice profile (and the per-matter posture if the matter overrides the default):\n\n- **Plaintiff (offensive framing)** — 🔴 marks events that *establish* elements of the claim (liability, causation, damages, notice), *close* gaps the defense will try to open, or *start* statute-of-limitations clocks in the plaintiff's favor. 🟡 marks events that support the claim but are subject to impeachment. ⚪ is background context.\n- **Defense (defensive framing)** — 🔴 marks events that *break* elements of the claim (failure of causation, notice, reliance), *open* statute-of-limitations or jurisdictional defenses, or *support* affirmative defenses (release, waiver, assumption of risk, comparative fault). 🟡 marks events that undermine the plaintiff's narrative. ⚪ is background.\n- **Both / varies** — ask the user per-chronology which side's framing to apply for significance tags. The underlying timeline is side-neutral; only the significance read changes.\n\nNote the applied framing at the top of the output: `Significance tags applied from [plaintiff / defense] perspective.` When producing a Statement of Facts variant, use the side default unless the user specifies otherwise.\n\n## Load context\n\nCommon:\n- Plugin configuration your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → case theory context (in-house: `## Landscape` for document sources; firm associate: `## Case theory` and `## Document review` for platform + custodians), `## Outputs` for the work-product header, `## Decision posture` for the privilege-flagging rule.\n- Prior `chronology.md` for this matter, if it exists.\n- Any files the user uploads or paths they provide in-session.\n\n`--matter` mode also reads:\n- the current project's documents → case theory, key facts, pivot fact (for significance tagging), key dates.\n- Default matter folder pattern from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → where docs for this slug live.\n\n`--documents` mode also reads:\n- eDiscovery platform metadata if a connector is available (Everlaw, Relativity, DISCO, Aurora) — by custodian + date range.\n- Bates-range manifest or production index if the user points at one.\n\n**Conflicts gate — unbypassable (`--matter` mode).** Before building the chronology, check the current project's documents for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace is set up. I won't build a chronology on a matter that hasn't been intaken — the conflicts check is the gate.\"\n\nDo not proceed on an unintaken matter. Intake is what runs conflicts and writes the `_log.yaml` row this skill reads from. `--documents` mode (running against an ad-hoc document set without a matter slug) is exempt from the gate, but its outputs should be treated as pre-matter research and not filed as if matter work product.\n\n## Workflow\n\n### Step 0: Privilege gate (runs first, every time)\n\nChronology work pulls from documents. Documents are often privileged (attorney-client, work product, common interest, joint defense) — in-house matter files often are by default; eDiscovery productions, especially rolling productions or common-interest productions, often contain privileged or unreviewed material. Extracting content from a privileged document into a chronology that later gets shared can *risk* waiver, depending on who receives it and under what doctrine (common-interest, joint-defense, Kovel, and work-product protections may apply). Waiver analysis is fact-specific — get counsel sign-off before distributing.\n\nThe skill will not extract until the user picks a privilege posture:\n\n> Before I extract: how have the sources been privilege-screened?\n>\n> - **A. All sources cleared** — you've already screened these. I extract without privilege flags. Output is discovery-ready posture; still marked work product.\n>\n> - **B. Mixed or not yet screened** — I extract and tag every entry with a `priv` flag: `ok` (sourced from clearly non-privileged material), `flag` (sourced from potentially privileged material — A/C, WP, common interest), or `review` (source unclear). Flagged entries are visually marked in the output, and the Statement-of-Facts variant filters them out by default.\n>\n> - **C. Abort — screen first** — pause the skill. Screen the sources. Return and re-run.\n\nRecord the choice in the chronology header as `privilege_posture: A-cleared | B-mixed | C-aborted`. If B or C, record the rationale briefly.\n\n**Why a gate and not just a warning:** a warning gets read once and forgotten. A gate forces the posture decision into the record, which means every chronology file carries its own provenance — anyone reading it later knows whether entries were derived from privilege-screened material.\n\n### Step 1: Identify document sources\n\n**`--matter` mode:**\n\n1. **User-provided paths** — anything dropped in this session (file paths, drive links, email exports).\n2. **Default matter folder** — from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)'s document-storage pattern, expanded for this slug (e.g., `G:/Legal/Matters/acme-v-us-2026`).\n3. **Declared sources** — the `Document storage` table in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), filtered to ones this matter might touch (e.g., Gmail archive for sender-side communications, SharePoint legal folder).\n4. **Ask** — if sources look thin, prompt: \"I can build from what I have, but the chronology will be incomplete. Anything else to point me at? Key emails, contracts, internal memos, production letters?\"\n\n**`--documents` mode:**\n\n1. **Production export / Bates set** — the user points at the production directory or a manifest; the skill reads by Bates range + date.\n2. **eDiscovery connector** — if an MCP connector is available (Everlaw, Relativity, DISCO, Aurora), pull by custodian + date range.\n3. **Custodial files** — if the user provides raw custodial mailboxes or drive exports, read those too.\n4. **Ask** — if coverage looks thin for a key custodian or date range, prompt.\n\n### Step 2: Pull + read\n\nFor each source with readable files:\n\n- **PDFs, emails (.eml), .docx, .txt** — read directly.\n- **Email archives (Gmail, Outlook)** — if an MCP connector is authenticated, query by date range + counterparty / key terms; otherwise the user exports relevant threads to a folder.\n- **eDiscovery platforms (Everlaw, Relativity, DISCO, Aurora)** — if connector is available, pull by custodian + date range; otherwise the user provides an export.\n\nIf the skill can't access a declared source, name it explicitly in the output's Gaps section rather than silently proceeding.\n\n**No silent supplement.** If source coverage for an era of the matter is thin — fewer documents than expected for a claimed time window, a custodian whose mailbox isn't accessible, a production that hasn't landed — report what was found and stop. Do NOT fill gaps from web search, public record search, or model knowledge about the matter without asking. Say: \"Sources returned [N] events for [period / custodian]. Coverage appears thin. Options: (1) point me at additional sources (Bates, folder, mailbox), (2) try a different MCP connector if configured, (3) search the web for public-record events in this window — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) stop here and note the gap. Which would you like?\" A lawyer decides whether to accept lower-confidence sources; the skill does not decide for them.\n\n**Source attribution.** Tag every chronology entry with where the event came from: the file path, Bates number, MCP connector, or declared document-storage source for events extracted from retrieved documents (already captured in the Sources column). For any event or date that cannot be traced to a retrieved document — e.g., a fact recalled from model training data, a public-record event found via web search — tag it inline: `[web search — verify]`, `[model knowledge — verify]`, or `[user provided]` where the user stated the fact in-session. Entries tagged `verify` carry higher fabrication risk than document-sourced entries and should be checked first. Never strip or collapse the tags — they are counsel's fastest signal about which entries to verify before pulling them into a brief or SoF.\n\n**Tagging reaches every section that states a legal conclusion, deadline, or computed date — not just timeline entries.** The timeline is sourced from documents. The Gaps section, the Key events section, the Theory tie lines, and any statement of limitations, tolling event, filing deadline, discovery cutoff, or privilege determination are legal analysis the skill writes from model knowledge unless sourced. Every such statement carries a provenance tag: `[computed from: ]`, `[model knowledge — verify]`, `[user provided]`, or a research-connector tag if retrieved in this session. A statute-of-limitations window with no tag defaults to `[model knowledge — verify]`. A \"key event\" line that characterizes a fact's legal significance is analysis and needs the tag. The rule is simple: if it's an assertion about the law, not an assertion about what a document says, it must carry the same provenance tag the timeline entries do. When no research connector is reachable and the skill is computing deadlines or citing rules, record it in the **Sources:** line of the reviewer note (see plugin your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`) — do not emit a standalone banner.\n\n### Step 3: Extract events\n\nFor each document, identify dated events:\n\n- **Email:** `[date] [sender] told [recipient] [subject/content]`\n- **Meeting:** `[date] [attendees] met about [topic]` (per calendar entry or notes)\n- **Decision:** `[date] [decision-maker] decided [what]` (per memorializing doc)\n- **Filing / pleading:** `[date] [party] filed [motion/complaint/response]`\n- **External event:** `[date] [thing happened]` (contract signed, product launched, regulator acted, event crossed a threshold)\n\nOne event per document usually. Occasionally zero (undated or no event established). Sometimes multiple (meeting summary covering several decisions).\n\n**Privilege flag per entry (only when privilege_posture == B-mixed). Three-state rule — never silently decide a subjective privilege test isn't met:**\n\n- `priv: ok` — source is **confidently** non-privileged (filings, regulatory correspondence, public docs, counterparty communications without our counsel). Used only when there's no plausible privilege theory.\n- `priv: flag` — source is confidently or likely privileged (communications with counsel, work-product memos, privileged drafts, joint-defense material). **Default for anything uncertain** — if the dominant-purpose call is close, or litigation contemplation is borderline, or the content is mixed, it goes here, not in `ok`.\n- `priv: review` — source unclear on its face, but the skill could not make the call at all (no sender/recipient metadata, unreadable, etc.).\n\nWhen `priv: flag` or `priv: review`, add `[SME VERIFY: privilege status]` inline so the counsel sees it during review. Under-flagging waives privilege (one-way door); over-flagging is corrected by counsel in review (two-way door). Prefer the recoverable error.\n\n### Step 4: De-dupe\n\nThe same event surfaces in multiple documents: a meeting is on three calendars and produces a summary email — that's **one event with four sources**, not four events. Merge. The merged entry cites all sources.\n\n### Step 5: Tag significance — per case theory\n\nRead the pivot fact and key facts from `matter.md` (`--matter` mode) or from the configuration's `## Case theory` section (`--documents` mode). Tag each event:\n\n- 🔴 **Key** — event is part of the pivot fact or a key fact for/against us\n- 🟡 **Relevant** — context, pattern evidence, supports a secondary argument\n- ⚪ **Background** — useful for completeness, not going in the brief\n\n**Discipline:** a chronology of 300 entries with 300 🔴 tags has no tags. Reserve 🔴 for events that would genuinely move a factfinder. If in doubt, 🟡.\n\n**Borderline tagging:** when an entry sits between 🔴 and 🟡 (or 🟡 and ⚪), tag at the lower significance and add `[SME VERIFY — borderline significance call]` inline. Counsel's judgment will override the skill's call. A chronology that confidently over-tags is less useful than one that surfaces its uncertainty.\n\n### Step 6: Write\n\nDefault output is the working chronology. Variants on request.\n\n## Output formats\n\n### Working chronology (default)\n\nLocation: the current project's documents. Complete, tagged, annotated. The reference doc counsel works from.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n> **Privilege inheritance.** This chronology is derived from matter documents that may be attorney-client-privileged, work-product-protected, common-interest / joint-defense material, or a mix. It inherits the sources' protection status. Distributing it beyond the privilege circle — to business stakeholders outside the engagement, to opposing counsel, to a regulator — can waive protection over both the chronology and the underlying sources. Store with privileged matter material, mark consistently with house privilege conventions, and make distribution decisions deliberately. The privilege-posture choice captured below is the provenance stamp for any later distribution call.\n\n# Chronology — [Matter Name]\n\n> Significance tags (🔴/🟡/⚪) and privilege flags (🔒) are first-pass reads requiring `[SME VERIFY]` before use in any external work product (briefs, SoF, board memo, outside counsel deliverable).\n\n**Matter:** [slug]\n**Mode:** matter | documents\n**Built:** [YYYY-MM-DD]\n**Sources:** [N] documents across [source types]\n**Entries:** [N] ([N] 🔴 / [N] 🟡 / [N] ⚪)\n**Pivot fact:** [one sentence]\n**Privilege posture:** A-cleared | B-mixed | C-aborted\n**Flagged entries:** [N] 🔒 *(only present when posture == B-mixed)*\n\n---\n\n## Timeline\n\n| Date | Event | Tag | 🔒 | Sources |\n|---|---|---|---|---|\n| [YYYY-MM-DD] | [what happened, one sentence] | 🔴/🟡/⚪ | [blank / 🔒-flag / 🔒-review] | [file paths or Bates] |\n\n---\n\n## Key events (🔴 only)\n\n[Pulled out, each with a line on why it matters to the theory.]\n\n### [date] — [event title]\n- What: [one line]\n- Theory tie: [why this matters]\n- Sources: [list]\n\n---\n\n## Gaps\n\n**Date ranges with no events:**\n[ranges — where are documents for this period?]\n\n**Expected but missing:**\n[events we'd expect to see documented but don't — e.g., \"contract amendments between 2024-06 and 2025-03 — not produced\"]\n\n**Unreadable sources:**\n[sources declared in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) but not accessible this run — e.g., \"Everlaw production — no MCP connector; export needed\"]\n\n---\n\n## Marker discipline\n\n- `[VERIFY: factual assertion — date, attendees, content]` — not yet confirmed against the underlying doc\n- `[UNCERTAIN: legal characterization — e.g., whether an event establishes a regulatory trigger]`\n- `[CITE NEEDED: Bates / exhibit / depo page:line]`\n- `[SME VERIFY: privilege status | borderline significance call]` — counsel judgment needed\n\n---\n\n## Version\n- v[N] built on [date] from [source summary]\n- v[N-1] built on [date] (prior, superseded)\n```\n\n### Statement-of-facts chronology (on request)\n\nFilter to 🔴 and relevant 🟡 only. Present as prose in chronological narrative order — the skeleton for a brief's fact section. Each paragraph is one event or tightly linked cluster, with record citations.\n\n**Privilege filter default:** when `privilege_posture == B-mixed`, 🔒-flagged and 🔒-review entries are **excluded** by default. The SoF variant is intended for eventual external use (briefs, disclosures, negotiating counterparty) — 🔒 entries don't belong there until counsel confirms privilege status. If the user wants 🔒 entries included anyway, require explicit `--include-flagged` acknowledgment; capture the acknowledgment in the output header as permanent record.\n\n### Witness-specific chronology (on request)\n\nFilter to events where a named witness is sender, recipient, attendee, or subject. Feeds witness prep and helps reconstruct what a witness knew when.\n\n## Incremental builds\n\nIf `chronology.md` exists:\n\n- Read prior version\n- Build new chronology from current sources\n- Diff: new events (since last build), modified entries (new sources added to existing events), removed entries (rare; note why)\n- Preserve the prior version number; write new version with `v[N+1]`\n- Output summary of what changed\n\n## Integration with matter.md / history.md\n\n**Intentionally separate** (in-house `--matter` mode). `history.md` is counsel's running log — decisions, updates, procedural milestones, internal strategy notes. `chronology.md` is the advocacy-facing timeline of facts. They overlap but don't merge:\n\n- A hold was issued → goes in history.md (internal action). Usually not in chronology (not a fact of the dispute).\n- The counterparty sent a breach notice on March 14 → goes in chronology.md (🟡 — establishes their knowledge). Also in history.md if the intake referenced it.\n- Our reserve recommendation memo was drafted → history.md only.\n\nWhen counsel wants history events in the chronology, they can paste them. The default is they stay separate.\n\n## What this skill does not do\n\n- **Resolve contradictions.** When two documents say different things about when an event happened, both entries go in with a flag. Resolution is counsel's call; may require witness interview or further discovery.\n- **Invent events not in the sources.** If it's not in the documents (and not in matter.md or the configuration as a captured fact), it's not in the chronology — but \"Gaps\" might call it out as missing.\n- **Guarantee completeness.** A chronology is only as good as the sources. If the eDiscovery production is ongoing and only 20% has landed, the chronology reflects that. Name the limitation.\n- **Decide privilege status for the user.** The Step 0 gate forces the posture choice; the per-entry `priv` flag captures first-pass classification. Actual privilege determinations are counsel's call per `[SME VERIFY]` flags.", + }, + { + id: "builtin-cfl-litigation-claim-chart", + title: "Claim Chart", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “claim-chart” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /claim-chart\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → role, work-product header, decision posture, document storage.\n2. If matter workspaces enabled, confirm or select the active matter; load `matter.md` (side, jurisdiction, phase, theory, pleadings).\n3. Follow the workflow and reference below.\n4. Mode selection:\n - `--patent` → patent claim chart. Require patent number and at least one asserted claim. Sub-modes: `--infringement`, `--invalidity`, `--review`.\n - `--civil` → civil element chart. Require the cause of action (or defense) and the side.\n - No flag → ask the user which.\n5. For civil mode: consult `references/element-templates.md` in the skill directory for the baseline element list. Confirm the controlling pattern instruction or statute with the user before mapping.\n6. For patent mode: parse asserted claims into elements, flag disputed terms for construction, apply any Markman order.\n7. Map elements against the target (accused product / prior art / evidence corpus / chart under review). Every cell pin-cited. Apply the apostrophe-prefix neutralization before writing any cell value starting with `=`, `+`, `-`, `@`, tab, or CR.\n8. Produce the gap list (civil) or needs-evidence list (patent) — the priority output.\n9. Write markdown, CSV (values + `_sources` companion), and Excel or Sheets per user preference. Work-product header on every output.\n10. Write to the matter's `claim-charts/` folder if a matter is active; otherwise the practice-level `claim-charts/` folder. Append a one-line entry to `history.md` if a matter is active.\n11. Return a summary readout: claim(s), target(s), jurisdiction, phase, element counts by state, the gap list, file paths, and the reminder that every cell is a lead.\n\n---\n\n# Claim Chart\n\n## Disclosed-document use restrictions\n\nBefore working with a set of litigation documents, ask: \"Were any of these documents obtained through disclosure or discovery in legal proceedings?\" If yes:\n\n- **England & Wales (CPR 31.22):** Documents obtained through disclosure are subject to the implied undertaking — you may only use them for the purpose of the proceedings in which they were disclosed, unless the court grants permission, the disclosing party consents, or the document has been read in open court. Using them for a different matter, a different claim, or a commercial purpose without permission is a contempt.\n- **US:** Protective orders and Rule 26(c) may impose similar restrictions. Check the order.\n- **Other jurisdictions:** Similar restrictions commonly apply. Check the local rule.\n\nConfirm: \"This use is within the proceedings in which the documents were disclosed, or I have permission / consent, or the documents are now public.\" If not confirmed, flag it: \"⚠️ Disclosed documents may have use restrictions. Confirm this use is permitted before proceeding.\"\n\n## A CHART IS A DRAFT, NOT A FINDING OR A CONTENTION\n\n**Put this at the top of every output. Do not drop it. Do not soften it.**\n\n> This chart is a draft for attorney analysis and verification, not a filed contention, an MSJ brief, an opening statement, or a legal opinion. Every mapping is a lead the attorney must verify against the source. The elements listed come from pattern jury instructions, the Restatement, or the claim language as parsed — the **controlling** authority in the user's jurisdiction (CACI / NYPJI / the circuit's pattern charge / the governing statute / a Markman order) may differ and always controls. Gap detection is a starting point for discovery or a motion; it is not a conclusion about the merits.\n\nUnder-flagging a gap is a one-way door — a complaint filed without plausibility on an element, an MSJ response served without evidence for a disputed element, or a case tried without proof of damages. Over-flagging is a two-way door — the attorney clears flags in review. The default is biased toward the two-way door.\n\n---\n\n## Matter context\n\nCheck `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` — especially the case theory, the pleading / complaint (for the elements actually alleged), the jurisdiction, any Markman order or stipulated constructions (patent mode), and the phase of the case. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → role, work-product header, decision posture, document storage, case-theory scaffolding\n- Active matter's `matter.md` — claims, defenses, side, jurisdiction, phase, theory\n- For civil mode: the complaint or counterclaim (for the actually-pleaded counts), any answer (for the actually-pleaded affirmative defenses), the relevant pattern jury instruction source, and the governing statute if statutory. Also the evidence corpus — deposition transcripts, declarations, produced documents, expert reports.\n- For patent mode: the patent, the asserted claims, the specification, prosecution history if available, the accused-product material or prior art reference, any Markman order or stipulated constructions.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) has `[PLACEHOLDER]` markers, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor risk calibration, landscape, and house style to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll run this tailored to YOUR practice.\n> - Say **\"provisional\"** and I'll run this against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" build the claim chart normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction, no practice-level playbook (work from the matter's pleadings and the elements of the claims as pleaded). Tag the reviewer note and every row of the chart with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your risk calibration, your landscape, your house style. 2 minutes.\"\n\n**Conflicts gate — unbypassable.** Before building a claim chart, check the current project's documents for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace is set up. I won't build a claim chart on a matter that hasn't been intaken — the conflicts check is the gate.\"\n\nDo not proceed on an unintaken matter. Intake is what runs conflicts and writes the `_log.yaml` row this skill reads from.\n\n---\n\n## Mode selection\n\nAsk at the top, before anything else:\n\n> Which kind of chart?\n>\n> 1. **Patent claim chart** — element-by-element mapping of claim limitations against an accused product (`--infringement`), prior art (`--invalidity`), or another party's chart (`--review`). For patent contentions, IPR petitions / responses, FTO charts.\n> 2. **Civil element chart** — elements of a cause of action (or affirmative defense) mapped against the evidence. For complaint plausibility checks, discovery planning, MSJ prep, order-of-proof outlines.\n\nPlus intake (common to both):\n\n- **Side.** Asserting or defending? (In civil mode this flips the burden; in patent mode it flips infringement/invalidity framing.)\n- **Jurisdiction / forum.** State and court — pattern instructions vary (CACI in California, NYPJI in New York, federal circuits' pattern charges, state-specific variations). In patent mode, Patent Local Rules vary (N.D. Cal., E.D. Tex., D. Del., ITC, PTAB). Flag which controls.\n- **Phase.** Pre-filing, pleadings, discovery, MSJ, trial prep, post-trial. The chart is the same; the framing of the output changes.\n- **Existing chart?** If `--review`, load it.\n\n---\n\n# MODE 1 — Patent claim chart\n\n## Sub-modes\n\n- `--infringement` — claim elements vs. accused product (PLR 3-1 infringement contentions, IPR/PGR response exhibits, complaint exhibits)\n- `--invalidity` — claim elements vs. prior art (PLR 3-3 invalidity contentions, IPR/PGR petition exhibits, §102/§103 defenses)\n- `--review` — audit a chart someone else produced\n\n## Additional patent-mode intake\n\n- **Patent number and asserted claims.** Which independent, which dependent. (Don't chart unasserted claims unless asked.)\n- **Priority date.** Establishes the §102 bar and the effective filing date for the AIA / pre-AIA regime.\n- **Existing constructions.** Markman order, stipulated constructions, constructions proposed in briefing.\n\n## Patent-mode workflow\n\n### Step 1: Parse the claims\n\nParse asserted independent claims into numbered elements. Handle:\n\n- **Preamble.** Note whether it's limiting — a question of claim construction (*Catalina Marketing Int'l, Inc. v. Coolsavings.com, Inc.*, 289 F.3d 801 (Fed. Cir. 2002)). Flag `preamble-limiting: unresolved` unless the construction order resolves it.\n- **Transitional phrase.** \"Comprising\" (open) / \"consisting of\" (closed) / \"consisting essentially of\" (semi-open). Affects whether additional unrecited elements defeat infringement.\n- **Elements** separated by commas / semicolons, numbered `[1a]`, `[1b]`, `[1c]`. Keep numbering stable — it's the chart's spine.\n- **Means-plus-function (§112(f))** — every \"means for [function]\" or non-structural functional term. Scope is the structure disclosed in the spec plus equivalents. Cite corresponding structure by col./line. If the spec fails to disclose structure, flag `indefinite-112f`.\n- **Markush groups, Jepson claims, product-by-process, method-step order dependencies** — flag with a note on unusual construction rules.\n- **Dependent claims** — reference parent; chart only the additional limitations. **Execute, don't gesture.** If asserted claims include dependents, produce the actual additional-limitation rows for each dependent in Step 4 — do not emit a note that dependents \"should be charted.\"\n- **Structural-term cognates — default to `construction-dependent`.** For each element that recites a structural noun with a common cognate in the prior art of the field, default the row's state to `literal-construction-dependent` (not `literal`) unless the spec expressly defines the term or an existing Markman order forecloses the ambiguity. These are the terms most commonly disputed at Markman — presuming a clean literal read under-flags the risk. Common cognate families to flag proactively:\n\n | Field | Cognate family (flag as `structural-term-cognate`) |\n |---|---|\n | Fasteners / anchors | barb / thread / projection / ridge / fin / tooth |\n | Fluidics / catheters | lumen / channel / bore / passage / conduit |\n | Mechanical housings | hub / boss / flange / collar / shoulder |\n | Fasteners / joints | socket / recess / pocket / cavity |\n | Electrical / electronic | contact / terminal / pad / lead |\n | Optical | lens / reflector / window / aperture |\n | Structural | wall / member / support / strut / rib |\n | Surfaces | surface / face / interface |\n\n This list is not exhaustive — if the claim recites a structural noun that could reasonably be read narrowly (pointed barb vs. any projection) or broadly (channel vs. any passage), flag `structural-term-cognate` in `_constructions` and default the row to `construction-dependent`. The attorney can demote it to `literal` after a Markman order or a definition in the spec forecloses the ambiguity.\n\nShow the parse to the user. Confirm before mapping. A wrong parse poisons every row below it.\n\n### Step 2: Claim construction check\n\nFlag disputed terms:\n\n- Coined terms or terms defined in the spec\n- Terms with prosecution history (amendments, arguments, disavowals — *Phillips v. AWH Corp.*, 415 F.3d 1303 (Fed. Cir. 2005); *Festo* estoppel)\n- Functional language (\"configured to\", \"adapted to\", \"operable to\")\n- Relative terms (\"substantially\", \"about\") — definiteness risk under *Nautilus, Inc. v. Biosig Instruments, Inc.*, 572 U.S. 898 (2014)\n- Computer-implemented terms — Alice / §101 exposure for invalidity\n\nFor each flagged term, state the construction(s) under which the mapping works and the construction(s) under which it fails. If a Markman order exists, apply it. If briefing is underway, chart under each side's proposed construction.\n\n### Step 3: Map\n\nFor each element, for each target:\n\n1. **Find evidence.** Accused product: documentation, manuals, data sheets, source code, teardowns, deposition testimony, expert reports. Prior art: column/line for US patents, paragraph for published apps, page/figure for NPL. For prior art, flag whether the reference qualifies (§102(a)(1), (a)(2), (b); AIA vs. pre-AIA cutoffs). If prior-art status isn't obvious, mark `prior-art-status: needs-evidence`.\n2. **Quote verbatim.** Character-for-character. No paraphrase. Cut at sentence boundaries and mark elision.\n3. **Characterize the mapping.**\n\n | Mapping | Meaning | Where |\n |---|---|---|\n | `literal` | Claim language reads on the accused feature / prior-art disclosure | Both |\n | `literal-construction-dependent` | Literal under X; fails under Y | Both |\n | `doe` | Equivalent (function-way-result or insubstantial differences) | Infringement only |\n | `anticipation` | Every element in a single reference, arranged as claimed (*Net MoneyIN, Inc. v. VeriSign, Inc.*, 545 F.3d 1359 (Fed. Cir. 2008)) | Invalidity only |\n | `obviousness-combination` | Secondary reference supplies the missing element; motivation to combine required under *KSR Int'l Co. v. Teleflex Inc.*, 550 U.S. 398 (2007) | Invalidity only |\n | `partial` | Some of the element is present | Both |\n | `not-found` | Element not present | Both |\n | `needs-evidence` | Can't tell from available material | Both |\n | `construction-dependent` | Turns on how a disputed term is construed | Both |\n\n4. **State per cell.** `mapped` / `mapped-doe` / `partial` / `not-found` / `needs-evidence` / `construction-dependent` / `anticipation` / `obviousness-combination`.\n5. **Flag open questions.** \"This maps if [X]. Need [teardown / source code / deposition / expert] to confirm.\"\n\n**No silent supplement.** Thin documentation means `needs-evidence`, not extrapolation from similar products.\n\n### Step 4: Dependent claims — execute, don't gesture\n\nFor each asserted dependent claim, produce an actual row (or set of rows) charting the additional limitation(s) against the target. The parent dependency is noted, and infringement / invalidity of the dependent requires the parent's. **Produce the rows, not a placeholder note that rows should be produced.**\n\nIf the user provided a list of asserted claims that includes dependents, the chart's output MUST contain rows for each of them. If the user gave only the independent claim and said \"chart the independents for now,\" fine — then the output doesn't chart dependents, but it surfaces the dropped ones explicitly (\"Asserted dependents [X, Y, Z] not charted in this run — request: rerun with `--include-dependents` or paste the dependent claim text\"). Do not silently skip dependents.\n\nA dependent-claim row format:\n\n```markdown\n| [#] | Element (verbatim) | Accused feature (or prior-art disclosure) | Evidence (pin-cited) | Mapping | State | Verified |\n|---|---|---|---|---|---|---|\n| 2 [add'l] | \"wherein the barb extends at an angle of 15° to 30° from the body axis\" | AnchorFast Mini barb angle 18° per [CM-AM-2026-03 Fig. 4 + §2.3] | [CM-AM-2026-03 §2.3] \"barb angle 18° ±2°\" | literal-construction-dependent | mapped | ☐ |\n```\n\n### Step 4.5: DOE supplements — execute, don't gesture\n\nFor every element charted as `literal` where the accused feature is structurally similar but not literally identical — or every element where the `literal` mapping turns on a contested construction — produce a **paired DOE candidacy row** (infringement mode). Do not footnote \"DOE analysis is separate\" without producing the actual DOE mapping.\n\nA DOE candidacy row adds a one-paragraph function-way-result sketch, flags prosecution history estoppel and dedication-to-the-public risks per element, and cites the evidence that would support the equivalent. If DOE is inapplicable (the element reads literally on the accused product beyond dispute), skip. If `literal` is construction-dependent and DOE would be the attorney's fallback under the narrower construction, produce the DOE row.\n\nFormat:\n\n```markdown\n| [#-DOE] | Element | Accused feature | Function-way-result | PH estoppel? | Dedication risk? | State |\n|---|---|---|---|---|---|---|\n| 1b-DOE | \"at least one barb\" | three-barb opposing-face array | function: resist withdrawal; way: mechanical engagement with cancellous bone; result: anchor remains seated under tensile load. | [needs-evidence: prosecution history] | [needs-evidence: disclosed-but-unclaimed alternatives in spec] | construction-dependent |\n```\n\nAs with dependents: if the skill can't produce the DOE rows for a reason (no accused-product evidence to ground function-way-result, no prosecution history available), say so explicitly and route to `needs-evidence`. Do not skip DOE silently.\n\n### Step 5: Indirect, divided, willfulness (infringement only)\n\nFlag, don't opine:\n\n- **Induced (§271(b))** — *Commil USA, LLC v. Cisco Systems, Inc.*, 575 U.S. 632 (2015); *Global-Tech Appliances, Inc. v. SEB S.A.*, 563 U.S. 754 (2011)\n- **Contributory (§271(c))** — component especially made for infringing use\n- **Divided / joint (§271(a))** — *Akamai Techs., Inc. v. Limelight Networks, Inc.*, 797 F.3d 1020 (Fed. Cir. 2015) (en banc) directs/controls test\n- **Willfulness** — *Halo Elecs., Inc. v. Pulse Elecs., Inc.*, 579 U.S. 93 (2016); treble damages under §284\n\n### Step 6: Invalidity thresholds (invalidity only)\n\nFor §102: every element in a single reference. Partial across references is §103.\n\nFor §103: primary reference + secondary reference(s) + documented motivation under *KSR*. Flag explicit teaching/suggestion/motivation, market or design-need motivation, reasonable expectation of success, and **secondary considerations** (*Graham v. John Deere Co.*, 383 U.S. 1 (1966)) — commercial success, long-felt need, failure of others, industry praise, copying.\n\nAlso flag:\n- **§101** — *Alice Corp. Pty. Ltd. v. CLS Bank Int'l*, 573 U.S. 208 (2014); *Mayo Collaborative Servs. v. Prometheus Labs., Inc.*, 566 U.S. 66 (2012)\n- **§112 ¶ 1** — written description, enablement (*Amgen Inc. v. Sanofi*, 598 U.S. 594 (2023))\n- **§112 ¶ 2** — definiteness (*Nautilus*, supra)\n- **§112 ¶ 6** — means-plus-function structure\n- **Unenforceability** — inequitable conduct, prosecution laches, assignor/licensee estoppel (attorney-only flags)\n\nInvalidity must be shown by clear and convincing evidence — *Microsoft Corp. v. i4i Ltd. P'ship*, 564 U.S. 91 (2011). Prima facie in a chart is not proof at trial.\n\n### Step 7 (review sub-mode): Audit\n\nFor each row: is the mapping supported? Is the pin cite accurate? Is the element fully accounted for? What's the strongest counter? What's the rebuttal opportunity? Output verdicts per row (`supported` / `weak` / `unsupported`) and the chart's vulnerabilities.\n\n## Patent-mode guardrails (in addition to shared guardrails)\n\n- **Rule 11 / Patent Local Rule.** Infringement and invalidity contentions require a reasonable inquiry and a non-frivolous basis. A chart out of this skill is a draft, not a contention.\n- **Claim construction candor.** Every construction-dependent row states the construction assumed and the construction under which the mapping fails.\n- **DOE candor.** A DOE mapping is not equivalent to a literal one. Flag prosecution history estoppel and dedication-to-the-public risks per element.\n- **Indirect is separate.** Don't fold induced / contributory into direct-infringement rows.\n- **Invalidity burden on the chart.** State the clear-and-convincing standard.\n\n---\n\n# MODE 2 — Civil element chart\n\nMap the elements of a cause of action (or affirmative defense) against the evidence. The killer outputs are (a) a chart that says what evidence goes with what element and (b) a gap list that tells the attorney what's missing.\n\n## Workflow\n\n### Step 1: Identify the claim(s)\n\n- What cause of action? (Or defense?) If multiple counts, chart each separately.\n- Which side? Plaintiff's prima facie case, defendant's affirmative defense, defendant's challenge to plaintiff's prima facie case (MSJ mode). Read `## Side` in the practice profile for the default — `plaintiff` defaults to mapping the prima facie case (proving the elements); `defense` defaults to mapping gaps and affirmative defenses (disproving or avoiding the elements). Confirm the posture matches this matter before starting.\n- Which jurisdiction? State and court. **Elements and pattern-instruction language vary by jurisdiction.** The template library is a baseline; the controlling pattern instruction or statute controls.\n- Which pleading? Load the complaint / counterclaim / answer so the chart tracks the counts actually pleaded, not a generic version.\n\n### Step 2: Load the elements\n\nThree paths:\n\n**(a) Template library.** Reference `references/element-templates.md` (in this skill's directory). Baseline elements for common causes of action and common affirmative defenses, with citations to the Restatement / pattern instructions and a jurisdiction caveat. Select the template that matches the pleaded count.\n\n**(b) Custom.** User defines elements, or pastes a jury instruction / statute / a count from the complaint to parse. Parse into numbered elements.\n\n**(c) Affirmative defenses.** Also support mapping defenses — statute of limitations, laches, estoppel, waiver, unclean hands, release, accord and satisfaction, failure to mitigate, comparative fault, contributory negligence, assumption of risk, etc. Defenses have their own elements the defendant must prove (or, for some, the plaintiff must negate once raised).\n\n**Jurisdiction-specific formulations — surface proactively.** If the practice profile's `## Company profile → Core jurisdictions` or the active matter's `matter.md` names **Delaware, New York, or California** (the three most-common commercial fora), surface the state-specific formulation proactively alongside the baseline — do not ask \"does your jurisdiction add/drop/reword\" first. The user shouldn't have to teach the skill the local rule; the skill should offer it and let the user choose.\n\nDivergences to surface without being asked (non-exhaustive — add to this list as patterns recur):\n\n| Cause of action / defense | Baseline (Restatement / pattern) | Jurisdiction-specific formulation |\n|---|---|---|\n| Breach of contract | 4 elements (contract, performance, breach, damages; CACI 303) | **DE:** 3 elements — contractual obligation, breach, damages (causation folded into breach) per *VLIW Tech., LLC v. Hewlett-Packard Co.*, 840 A.2d 606 (Del. 2003). **DE adds a 5th element** — no adequate remedy at law — when the claim seeks specific performance. |\n| Breach of contract — goods | Common-law breach elements | **If goods + U.C.C. Article 2 jurisdiction (all 50 states except LA):** load U.C.C. breach elements (conforming tender, acceptance / rejection / revocation, cure, cover, seller's remedies). Present both; let user pick. |\n| Breach of contract — multi-lot goods / installment contract | Common-law breach or U.C.C. § 2-711 (single-delivery breach framework) | **Installment contracts under U.C.C. § 2-612** — \"substantial impairment of the value of the installment\" replaces the perfect-tender rule; aggregate breach requires \"substantial impairment of the value of the whole contract.\" If the contract calls for goods to be delivered in separate lots (multiple shipments, deliveries), default to § 2-612 framing — it is the governing regime and the analysis is materially different from single-delivery breach. Flag for signer: \"This is drafted as an installment contract under § 2-612 — confirm that characterization matches the contract's delivery structure.\" |\n| Negligence | 4 elements (duty, breach, causation, damages; Restatement (Second) Torts § 281) | **CA:** follow CACI No. 400 formulation (negligence per se per CACI 418 when applicable). **NY:** PJI 2:10 formulation — slightly different language on proximate cause. |\n| Negligent misrepresentation | Restatement (Second) Torts § 552 — justifiable reliance, pecuniary loss | **NY:** requires **contemporaneous privity** or a relationship \"so close as to approach that of privity\" per *Credit Alliance Corp. v. Arthur Andersen & Co.*, 65 N.Y.2d 536 (1985). |\n| Fraud | 9 elements (often condensed to 5 — representation, materiality, knowledge of falsity, intent to induce, justifiable reliance, damages) | **DE:** 5 elements per *Stephenson v. Capano Dev.*, 462 A.2d 1069 (Del. 1983). **CA:** CACI 1900 formulation — 5 elements with reliance being \"justifiable.\" **NY:** requires pleading with particularity under CPLR 3016(b), and scienter is a distinct element. |\n| Breach of fiduciary duty | Restatement / common law — fiduciary duty, breach, damages | **DE:** the most-developed body of fiduciary-duty law (*Aronson v. Lewis*, *Cede & Co. v. Technicolor*, *In re Trados*) — default to the Delaware formulation for any DE-entity matter regardless of forum. |\n\nWhen a jurisdiction-specific formulation differs materially from the baseline, the chart opens with a one-line callout:\n\n> **Jurisdiction note:** You told me this is a [DE/NY/CA] matter. Here's how [jurisdiction]'s formulation differs from the baseline: [divergence]. The chart below uses the [jurisdiction] formulation. If that's wrong, say so and I'll reload.\n\nConfirm the element list with the user before mapping. If the user's jurisdiction isn't DE/NY/CA, ask: \"Does your jurisdiction's pattern instruction add / drop / reword any of these?\" If yes, use their version.\n\n### Step 3: Map\n\nFor each element:\n\n- **Evidence supporting** — what proves this element? Cite the source with a pin cite.\n - Deposition testimony — `[Doe Dep. 42:15–43:7]`\n - Declaration — `[Smith Decl. ¶ 12]`\n - Produced document — `[DEF00012345 at 3]`\n - Admission — `[Def.'s Resp. to RFA No. 5]`\n - Exhibit — `[Trial Ex. 14 at 2]`\n - Expert report — `[Jones Expert Rep. at 18]`\n - Discovery response — `[Pl.'s Resp. to Interrog. No. 8]`\n - Statute / case — for purely legal elements\n- **Verbatim quote** where the evidence is testimonial or documentary. No paraphrase.\n- **Evidence contradicting** — what cuts the other way? Cite it. This is the row's vulnerability.\n- **Strength** — `strong` / `moderate` / `weak` / `none`. Keep it simple. Over-calibrated strength scores are noise; `weak` and `none` are the rows that matter.\n- **State per cell** — `supported` / `partial` / `disputed` / `gap` / `needs-discovery`.\n\n### Step 4: Gap detection — the killer output\n\nAfter mapping, produce a gap list. This is the point of the chart.\n\n> **Elements with thin or no evidence:** [list]\n>\n> - If asserting (plaintiff): these defeat your complaint's plausibility (Iqbal/Twombly), your MSJ opposition, or your case at trial. Close them before the next motion.\n> - If defending: these are your MSJ targets and your directed-verdict motion. The plaintiff has to prove each element; a gap is a defense.\n> - If pre-discovery: these are your discovery priorities — the depositions, document requests, and interrogatories that turn a gap into `supported` or confirm `none`.\n\nGap detection is not a conclusion about the merits. It's a map of where the case is light.\n\n### Step 5: Phase-aware framing\n\nAsk the phase. Same chart; different framing on the output:\n\n- **Pre-filing / pleadings.** Does the complaint allege each element with plausibility (*Ashcroft v. Iqbal*, 556 U.S. 662 (2009); *Bell Atl. Corp. v. Twombly*, 550 U.S. 544 (2007))? Any element pleaded on information and belief without factual support is a 12(b)(6) target.\n- **Discovery.** For each `gap` or `needs-discovery` element, what discovery is needed? Which witnesses, which document custodians, which interrogatories, which RFAs.\n- **MSJ.** For each element, is there a genuine dispute of material fact? A `supported` cell for the movant with no contradicting evidence is summary-judgment ammunition; a `disputed` cell is MSJ-defeating.\n- **Trial.** Order of proof. Which witness proves element 1, which exhibit proves element 2, who authenticates, what's the foundation. The chart becomes the trial outline.\n\n### Step 6 (review sub-mode): Audit\n\nFor an opposing party's MSJ brief, a motion to dismiss, or outside counsel's draft: for each element, does their cited evidence actually prove it? Where is their chart thin? What's your strongest counter?\n\n## Civil-mode guardrails (in addition to shared guardrails)\n\n- **Jurisdiction.** The element list is a baseline. Always confirm the controlling pattern instruction (CACI, NYPJI, federal circuit pattern charge, etc.) or statute. State the source on the chart's `_elements` sheet.\n- **Pleaded counts only.** Chart what's actually pleaded. Don't add a count the complaint doesn't allege just because the facts might support it — that's a different analysis.\n- **Affirmative defenses.** If mapping defenses, note whether the burden is on the defendant (most) or whether raising the defense shifts a burden to the plaintiff.\n- **\"Gap\" ≠ \"case over.\"** A gap is a lead. Discovery, a declaration, or an expert report can close it. The chart shows where to dig.\n\n---\n\n# Shared chassis (both modes)\n\n## Output\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`.\n\n### Markdown table (always)\n\nOne table per claim / defense / patent-claim per target.\n\n**Patent mode example:**\n\n```markdown\n| [#] | Element (verbatim) | Accused feature | Evidence (pin-cited) | Mapping | State | Verified |\n|---|---|---|---|---|---|---|\n| 1a | \"a processor configured to...\" | SoC per datasheet | [Datasheet p. 7] \"...\" | literal-construction-dependent | mapped | ☐ |\n| 1b | \"means for [function]\" (§112(f)) | [alleged equiv.] | [source, file.c:124] \"...\" | needs-evidence | needs-evidence | ☐ |\n```\n\n**Civil mode example:**\n\n```markdown\n| [#] | Element | Evidence supporting (pin-cited) | Evidence contradicting | Strength | State | Verified |\n|---|---|---|---|---|---|---|\n| 1 | Existence of a contract | [Ex. 3, MSA § 1; Smith Dep. 22:4–14] | none | strong | supported | ☐ |\n| 2 | Plaintiff's performance | [Jones Decl. ¶¶ 4–9] | [Doe Dep. 101:3–11: \"they never delivered Phase 2\"] | moderate | disputed | ☐ |\n| 3 | Defendant's breach | — | [Doe Dep. 101:3–11] | none | gap | ☐ |\n| 4 | Causation | — | — | none | needs-discovery | ☐ |\n| 5 | Damages | [Expert Rep. at 18 — $2.4M lost profits] | [Def.'s Expert Rep. at 6 — critiques methodology] | moderate | disputed | ☐ |\n```\n\nFollow with:\n- **Defenses / thresholds** (patent mode: invalidity / indirect / willfulness flags; civil mode: affirmative-defense flags, Iqbal/Twombly flags pre-pleading)\n- **Gap list** (civil mode) / **needs-evidence list** (patent mode) — **the priority output**\n- **What cuts which way — summary** — strongest elements, weakest elements\n- **Conclusion line** — *\"This skill does not conclude.\"* Elements mapped/supported: [list]. Elements needing evidence / in a gap state: [list]. Elements construction-dependent (patent) / disputed (civil): [list]. Attorney judgment required.\n- **Citation verification** — every pin cite, case, column/line, deposition page:line must be verified against the source.\n\n### CSV (always)\n\nTwo files per chart:\n- `[chart-slug].csv` — values\n- `[chart-slug]_sources.csv` — verbatim quotes, pin cites, notes\n\n**CSV / spreadsheet cell safety.** Before writing any cell value, check the first character. If it is `=`, `+`, `-`, `@`, tab (`\\t`), or carriage return (`\\r`), prepend a single apostrophe (`'`) to neutralize Excel/Sheets formula interpretation. Verbatim evidence from adversarial sources (opposing counsel's contentions, competitor product manuals, third-party prior art, scraped web pages, deposition transcripts, discovery productions) can contain strings that a spreadsheet will execute as formulas (`=HYPERLINK(...)`, `=cmd|...!A1`, `+WEBSERVICE(...)`), turning the chart into a data-exfiltration or RCE vector when an attorney opens it. RFC 4180 quoting alone does not defeat this — the leading `=` is still interpreted. Apply the apostrophe prefix in CSV, XLSX, and Sheets outputs. Log cells where this was applied so the reviewer can see which quotes were neutralized.\n\n### Spreadsheet (Excel or Sheets)\n\nAsk which the team works in. Use the pattern from `corporate-legal`'s `tabular-review` skill — same cell-level citation model, same state-based color coding, same `Verified` column, same schema sheet:\n\n- One row per element (or element × target if comparing multiple targets)\n- Each evidence column paired with a hidden source column containing the verbatim quote and pin cite; cell comments (Excel) or notes (Sheets) surface the quote on hover\n- Color coding by state:\n - *Patent:* white = `mapped`, yellow = `construction-dependent` / `partial` / DOE, orange = `needs-evidence`, red = `not-found`\n - *Civil:* white = `supported`, yellow = `partial` / `disputed`, orange = `needs-discovery`, red = `gap`\n- `Verified` column per evidence column, blank by default — reviewer marks it\n- `_elements` sheet documenting the element source: pattern jury instruction (CACI No. X, NYPJI §Y, federal circuit pattern charge), statute (cite), Restatement section, or patent-claim parse. This is what makes the chart auditable — a reader can see where the elements came from.\n- `_gaps` sheet listing every `gap`, `needs-evidence`, or `needs-discovery` row with what's still needed\n- For patent mode only: `_claim-parse` sheet (element decomposition), `_constructions` sheet (disputed terms and assumed constructions)\n\nApply the apostrophe-prefix neutralization to every cell written into the spreadsheet.\n\nPrepend the work-product header as the top row. Alongside it, include:\n\n> This chart is derived from source documents that may be privileged, confidential, or both. It inherits the sources' privilege and confidentiality status — distribution beyond the privilege circle can waive privilege. Store with the matter's privileged files and make distribution decisions deliberately. Nothing in this chart has been filed or served; it is a draft for attorney review.\n\n### Filename and location\n\n- Patent infringement: `claim-chart-infringement-[patent#]-claim[#]-[target]-YYYY-MM-DD.{md,csv,xlsx}`\n- Patent invalidity: `claim-chart-invalidity-[patent#]-claim[#]-[ref]-YYYY-MM-DD.{md,csv,xlsx}`\n- Civil: `element-chart-[count-slug]-[side]-YYYY-MM-DD.{md,csv,xlsx}`\n- Review: `chart-review-[subject]-YYYY-MM-DD.{md,csv,xlsx}`\n\nIf matter workspaces enabled and a matter is active: the current project's documents. Otherwise: the current project's documents. Surface the path. Append a one-line entry to the matter's `history.md`.\n\n## Summary readout\n\nAfter the chart is written, give a one-screen readout:\n\n- Claim(s) / count(s) / patent claim(s), target(s), jurisdiction, phase\n- Elements charted · supported/mapped · partial · disputed · gap / needs-evidence · not-found\n- The gap list (civil) or needs-evidence list (patent) — **this is the priority list**\n- Where the output files are\n- Reminder: every cell is a lead. The chart is a draft, not a contention / brief / order of proof.\n\n## Non-lawyer gate\n\nIf `## Who's using this` Role is Non-lawyer:\n\n> This chart is a research draft, not a legal filing. Serving contentions, filing a brief, or relying on this for a merits opinion has Rule 11 and substantive legal consequences. An attorney in the relevant jurisdiction must review before this is used for any legal purpose.\n>\n> Here's a one-page brief to bring to an attorney:\n>\n> [Generate: claim / patent, side, jurisdiction, phase, elements, supported / gap / needs-discovery counts, the three most load-bearing open questions.]\n\nDeliver the chart alongside the brief.\n\n## Shared guardrails — checklist\n\n- **Citation verification.** Every pin cite (column/line, page, deposition page:line, Bates, ¶) is a claim about the source. The attorney verifies. The skill does not fabricate cites — if a cite cannot be produced, the cell is `needs-evidence` or `gap`.\n- **Source attribution.** Every verbatim quote has its source in the companion CSV and the spreadsheet's hidden source column. A quote without a source is not evidence.\n- **No silent supplement.** Thin evidence means `needs-evidence` / `gap`, not \"extrapolate.\" Do not fill from web search, training data, or \"how these cases usually go\" to close a gap.\n- **Matter workspace check.** Confirm the active matter before writing. Never write matter A's chart into matter B's folder.\n- **Decision posture.** When uncertain whether an element is met, flag; do not decide. `partial` tells the attorney what part is missing.\n- **Formula injection.** Every cell written to CSV / XLSX / Sheets is checked for leading `=`, `+`, `-`, `@`, `\\t`, `\\r` and prefixed with `'`. Default: neutralize-then-write.\n- **Elements are jurisdiction-specific.** The template library is a baseline. The controlling pattern instruction or statute controls.\n- **A chart is not a brief, a filing, or a contention.** Every output is a draft.\n\n---\n\n## Relationship to other skills\n\n- `ip-legal:infringement-triage` (patent mode) — the first-pass flag list. This skill is the full chart that comes next.\n- `ip-legal:fto-triage` — FTO uses the same mechanics from the potentially-accused posture. If evaluating own product vs. a third-party patent, route to FTO and use this skill's format.\n- `corporate-legal:tabular-review` — the underlying cell-level citation and verification-state pattern. A claim / element chart is a specialized tabular review.\n- `litigation-legal:chronology` — the chronology is the timeline; the element chart is the proof matrix. A chronology entry often becomes a cell's evidence cite.\n- `litigation-legal:deposition-prep` — a `needs-discovery` cell often becomes a depo topic. After a depo, new testimony fills cells.\n- `litigation-legal:brief-section-drafter` — an MSJ brief's fact section is often built directly off the supported rows of an element chart.\n\n---\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **It does not conclude.** Not infringement, not non-infringement, not liability, not non-liability. Ever.\n- **It does not decide claim construction** (patent) or **the controlling elements** (civil). It flags disputed terms / baseline elements and charts under stated assumptions.\n- **It does not meet the clear-and-convincing burden for invalidity** or **the preponderance at trial**. It produces a prima facie draft for attorney review.\n- **It does not substitute for expert analysis.** Source code review, teardowns, technical experts, damages experts are separate work products this chart routes to, not replaces.\n- **It does not serve, file, or sign anything.** Every output is a draft. An attorney serves and files.\n- **It does not extrapolate.** If the evidence isn't there, the cell is `needs-evidence` / `gap` — never a guess.", + }, + { + id: "builtin-cfl-litigation-demand-draft", + title: "Demand Draft", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “demand-draft” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /demand-draft\n\n1. Load the current project's documents. Refuse if missing or strategic block empty (for material demands).\n2. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → demand-letter practice, house style, seed-doc table.\n3. Follow the workflow and reference below.\n4. Run the pre-draft gate: privilege filter, admission risk, accord-and-satisfaction, FRE 408 posture, waiver scan, tone, factual accuracy. Do not proceed until each is engaged.\n5. Template select: seed doc if provided in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile); else soft template for the demand type.\n6. Draft in-chat for review. Iterate until user approves.\n7. Write the current project's documents using the docx skill.\n8. Write the current project's documents (post-send checklist).\n9. Assess materiality per heuristic; offer to create a matter. If yes: hand off to `matter-intake` with pre-populated fields.\n\n---\n\n# Demand Draft\n\n## Purpose\n\nTake a completed intake and produce a sendable draft. Most of the value is in refusing to draft until privilege, waiver, admission, and settlement-communication posture have been consciously addressed — the failure mode is a letter that waives privilege or constitutes an admission because no one paused to check.\n\n## Record fidelity — quotes and pinpoints\n\nDemand letters are advocacy, and every quoted line from a contract, an email, or a prior communication becomes an assertion the counterparty will test. Canonical statement in the plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) shared guardrails; repeated here.\n\n**Verbatim quotes must be verbatim.** Never put quotation marks around words attributed to the counterparty, their counsel, a witness, or any document unless you have the exact passage in front of you. When you want to characterize without the exact words:\n\n- **Paraphrase without quotation marks**, with a placeholder: \"Your [date] email stated X `[verify exact quote — email cite pending]`.\"\n- **Never fill the gap.** A misquoted contract provision in a demand letter is the fastest way to lose credibility with opposing counsel on the first round.\n- Every `[verify exact quote]` must be flagged in the reviewer note before the letter leaves.\n\n**Pinpoint cites must support the whole proposition.** If the demand asserts \"Section 4.2 requires payment within 30 days upon invoice receipt,\" the cited section must cover the obligation AND the trigger AND the window. If it only covers one, split the cite (e.g., \"Section 4.2 (payment obligation); Section 4.3 (30-day window)\") or narrow the proposition. A contract cite that backs part of the demand is how the counterparty replies with the full text and flips the posture.\n\n## Candor about weak arguments\n\nWhen the law or the record is against a point, don't dress it up as solid. When an argument in the demand is weak — the contract language is ambiguous, the authority cuts the other way, the damages theory is a stretch — flag it for the sender:\n\n> \"The [claim / theory] here is weak because [authority / fact]. Options: (a) press it and frame as `[alternative framing]`, (b) drop it and rely on [stronger claim], (c) keep it as a hook but hedge the language. `[review — strategic call]`.\"\n\nA demand letter that over-asserts gets a response that catalogs every overreach, shifts leverage, and burns the next round. The strongest demand letter is the one that concedes what's weak so the counterparty can't.\n\n## Echo vs repeat\n\nIf the matter has prior correspondence, echo the key terms — the same characterization of the breach, the same framing of the core obligation, the same name for the transaction. Don't lift whole sentences. A demand letter that reads like a copy-paste of the prior one signals that nothing has changed; the new letter should advance the posture (new facts, new deadline, new consequence), not restate it.\n\n> **External deliverable:** the drafted demand letter is sent to counterparty. Do NOT include a `PRIVILEGED & CONFIDENTIAL — ATTORNEY WORK PRODUCT — PREPARED AT THE DIRECTION OF COUNSEL` header on the outgoing letter. The post-send checklist and the intake file are internal work product and do carry the header.\n\n## Side context\n\nDrafting a demand letter is inherently an assertion — the sender is making a claim. Read `## Side` in the practice profile:\n\n- **Plaintiff / claimant** (default for this skill): demand-draft aligns with the posture. The letter is the claim. Tone, consequence language, and relief demanded all flow from the plaintiff-side playbook.\n- **Defense / respondent**: demand-drafts are less common from defense but do happen — a defense practitioner may send a counter-demand, a demand for contribution, or a demand letter in an unrelated matter. Confirm before drafting: \"You said defense is your default. Is this matter plaintiff-posture for you (you're asserting a claim), or is this a different posture?\"\n- **Both / varies**: ask per-draft which posture applies. The draft's tone and default signer may differ.\n\nFor in-house defense practitioners who receive demand letters more than they send them, route to `demand-received` instead — that skill handles the inbound-triage case.\n\n## Posture for this matter\n\nBefore the pre-draft gate, confirm the matter-level posture. Demand-letter tone and terms are case-by-case, not a practice default. Confirm with the user (reading the intake's `## Posture` section if present; asking if not):\n\n> **Posture for this matter.** Demand-letter tone and terms are case-by-case, not a practice default. Ask:\n> - **Tone:** measured / assertive / aggressive? (depends on the relationship, the amount, and whether litigation is likely)\n> - **Response window:** what's reasonable given the claim? (14 days is common for payment demands; 30 days for cure; 7 days for cease-and-desist — but the contract or protocol may set it)\n> - **Marking:** does this need a \"without prejudice\" or \"without prejudice save as to costs\" marking? (settlement communications do; assertions of claim often don't; jurisdiction matters — ask if unsure)\n> - **Signer:** you, the client, the GC, instructed solicitor/counsel?\n> Don't assume. Read the prior demand correspondence in the matter file if there is any — it establishes the register.\n\nThe answers drive tone verb choice, the consequence language, the `Without prejudice` header (or its absence), the signature block, and the compliance deadline. A posture that wasn't captured in intake gets captured here — do not fall back to a practice-level default.\n\n## Jurisdiction assumption\n\nThis draft assumes the jurisdiction identified in the intake and the forum's applicable settlement-communication rule (FRE 408 in federal, the state equivalent otherwise). Legal rules, deadlines, fee-shifting, and statutory hooks vary materially by jurisdiction. If the underlying facts touch a different forum, a different counterparty's home state, or a choice-of-law question, the draft may not apply as written — confirm before sending.\n\n## Load context\n\n- the current project's documents — required; refuse to proceed if missing\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Demand-letter practice (seed-doc paths, insurance-tender timing, materiality threshold for matter creation), house style (privilege markings, outside counsel directive format for tone reference). **Tone, compliance period, marking, and signer come from `## Posture for this matter` — they are matter-level, not practice-level.**\n- the current project's documents — to check for existing related matters (same counterparty) and offer cross-link\n\n### Strategic-block skipped handling\n\nIf the intake has `strategic_block: skipped` or `partial`, prompt the user before running the pre-draft gate:\n\n> The intake skipped [all / some] of the strategic block (leverage, BATNA, tone, privilege filters). Drafting now will produce a usable letter but the strategic sections will be generic and flagged with `[SME VERIFY]`.\n>\n> - **Complete strategic block now** — pause, return to `/demand-intake [slug] --resume-strategic`\n> - **Proceed anyway** — continue to pre-draft gate; downstream sections flagged\n\nIf \"proceed anyway,\" every section of the draft that depends on a skipped strategic question gets `[SME VERIFY: [specific question]]` inline.\n\n## Flags\n\n- `--skip-gate` → bypass the pre-draft checklist. Available but logged; use only when the checklist was run separately and documented.\n- `--version=N` → draft as `draft-vN.docx` (default: next version number)\n\n## The pre-draft gate\n\n**This runs before any drafting. If the user doesn't engage with it, stop.**\n\n```\nPRE-DRAFT CHECKLIST — [slug]\n\n1. Privilege filter\n Per intake privilege filters: [list]\n Confirm: none of these will appear in the draft? [y/n]\n\n2. Admission risk\n Per intake admission risk: [list]\n For each, is the phrasing controlled or removed? [y/n per item]\n\n3. Accord-and-satisfaction\n Per intake: [flagged risk, if any]\n Does the demand inadvertently satisfy or accept a separate claim? [y/n]\n\n4. Settlement-communication posture\n Research the settlement-communication protections applicable in the forum\n (FRE 408 in federal, the state equivalent otherwise). Note that protection\n attaches from conduct and context, not merely from labeling the communication.\n Intake says: [protected / not protected / case-by-case]\n Draft will [include / omit] settlement-communication markers, and will be\n structured so the substance — not just the label — supports the posture.\n Confirm.\n\n5. Privilege waiver scan\n Will any sentence in the draft reveal the substance of our internal legal analysis (not just the conclusion)? [y/n]\n If yes, rephrase before drafting.\n\n6. Tone posture\n Intake says: [relationship-preserving / measured / scorched-earth]\n This will drive verb choice, framing, and consequence language. Confirm.\n\n7. Factual accuracy\n Every fact in the draft must be verified. Not \"probably true\" — verified. List any facts that are not yet verified, and they will be flagged [VERIFY: ___] inline.\n```\n\nOnly proceed when the user has engaged with each item. A blank-acknowledged checklist is worse than no checklist.\n\n## Template selection\n\n### Step 1: Seed doc\n\nCheck your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Demand-letter practice → seed-doc table for the intake's demand type.\n\n- **Seed doc provided:** read it. Match structure, tone, signature block, privilege markings, typical section ordering. The seed doc is the template.\n- **No seed doc:** use the soft template below for the demand type.\n\n### Step 2: Soft templates (used only when no seed doc)\n\nEach is a skeleton — headings and expected content. Deviate when the facts require.\n\n**Payment demand skeleton:**\n1. Parties and relationship context (1 paragraph)\n2. Facts — the obligation and its source (contract § / invoice / order), dates\n3. The default — what's owed, when due, what happened (or didn't)\n4. Demand — specific amount, deadline, method of payment\n5. Consequences — referral to counsel, interest, fees, collections, litigation\n6. Preservation notice (if relevant)\n7. Signature block\n\n**Breach / cure notice skeleton:**\n1. Parties and agreement (identify the contract — effective date, parties)\n2. The obligation alleged breached — contract section, plain language\n3. The breach — specific facts, dates, evidence available\n4. Cure — what specifically would cure; cure period (from contract or reasonable)\n5. Consequences of failure to cure — termination, damages, specific remedies in the contract\n6. Preservation of rights\n7. Signature block\n\n**Cease & desist skeleton:**\n1. Parties and our rights (trademark/copyright/contract/common law — identify the right)\n2. The infringement / violation — specific acts, dates, evidence\n3. Demand — cease immediately, remove, account for past use, confirm compliance in writing\n4. Compliance deadline\n5. Consequences of non-compliance — litigation, injunctive relief, statutory damages if applicable, fees\n6. Preservation demand (documents, metadata, systems related to the alleged conduct)\n7. Signature block\n\n**Employment separation demand skeleton:**\n1. Parties and relationship context (ex-employee, dates of employment)\n2. The obligation — post-employment obligations breached (confidentiality, non-solicit, non-compete, IP assignment); cite the agreement\n3. The specific conduct alleged\n4. Demand — cease, return property/IP, confirm compliance, non-disparagement reinforcement if applicable\n5. Consequences — litigation, injunctive relief, fee-shifting if in the agreement\n6. Offer of informal resolution (if strategically appropriate)\n7. Preservation demand\n8. Signature block\n\n**Preservation demand skeleton:**\n1. Parties and context — what dispute is anticipated\n2. Scope — categories of documents, data, systems, communications\n3. Custodians — named individuals expected to have relevant material\n4. Date range\n5. Affirmative preservation obligation — suspend auto-delete, preserve metadata, preserve devices\n6. Consequences of spoliation — adverse inference, sanctions, fee-shifting\n7. Acknowledgment request\n8. Signature block\n\n## Drafting rules\n\n0. **Installment-contract default for multi-lot goods disputes.** For any breach-of-contract demand involving a multi-delivery goods contract under the U.C.C. (multiple shipments, lots, or deliveries over time), default to the installment-contract framework of **U.C.C. § 2-612** — \"substantial impairment of the value of the installment\" — rather than § 2-601's perfect-tender rule or § 2-711's single-delivery buyer's-remedies framework.\n\nPerfect tender under § 2-601 applies cleanly to single-delivery goods contracts. It does NOT transfer cleanly to installment contracts, where § 2-612 modifies the rule: a buyer can reject a nonconforming installment only when the nonconformity substantially impairs the value of that installment and cannot be cured; and can treat the whole contract as breached only when the nonconformity substantially impairs the value of the whole contract.\n\nWhen drafting the demand letter for a multi-lot goods breach:\n\n- Cite `[CITE: U.C.C. § 2-612 — installment contracts; substantial impairment of the installment]` as the primary framework, not § 2-601.\n- Cite § 2-711 and § 2-712 (cover) as remedies flowing from breach, but state the breach standard in § 2-612 terms.\n- Flag for the signer in a `[SIGNER NOTE:]` block above the draft: \"This letter is drafted under U.C.C. § 2-612 (installment contracts), not § 2-601 (perfect tender). The two have materially different breach standards. Confirm the contract's delivery structure supports installment-contract characterization before sending.\"\n- If the contract's delivery structure is unclear from the intake (e.g., the intake says \"three lots delivered\" but doesn't confirm whether the contract called for separate lot deliveries or a single shipment split for convenience), flag it `[VERIFY: is this an installment contract under § 2-612, or a single-delivery contract split into lots by shipping convenience?]` — do not silently assert § 2-612 applies.\n\nSingle-delivery breach: use § 2-601 perfect-tender framing. Installment: use § 2-612. Do not conflate them.\n\n1. **Specificity over adjectives.** \"On March 14, 2026, you sent X\" beats \"You repeatedly and improperly sent X.\" Adjectives are the draftsperson's tell that the facts are thin.\n\n2. **Facts traceable to sources.** Every factual assertion maps to a document, date, or witness. If not verifiable yet: `[VERIFY: specific claim]`.\n\n3. **Citations as placeholders.** `[CITE: statute/section/case]` wherever legal authority goes. Do not invent citations. If the user provided authorities in the intake, use them faithfully.\n\n4. **Consequence language matches tone posture.**\n - `relationship-preserving`: \"We hope to resolve this without further action.\"\n - `measured`: \"If not cured within [N] days, we will consider our options, including litigation.\"\n - `scorched-earth`: \"Failure to cure within [N] days will result in immediate legal action, including [specific relief].\"\n\n5. **Inline alternative phrasings.** Where tone could shift, the draft includes a compact alternative. Format:\n > *The attached invoice of $X remains unpaid.* [or more assertive: *You have failed to pay the attached invoice of $X, due [date].*]\n\n6. **No settlement discussion on the record unless intended.** If the intake flagged the communication as not carrying settlement-communication protection in the forum, the draft does not include any offer to compromise, any \"without prejudice\" framing, or any language that could be characterized as a settlement communication. Remember that protection attaches from conduct and context; labeling alone is not a cure.\n\n7. **Privilege markings per house style.** Apply your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) privilege conventions exactly.\n\n## Output\n\n### Primary: the current project's documents\n\nUse the `docx` skill to produce a letter-formatted .docx:\n- Letterhead / sender address block\n- Date\n- Recipient address block\n- Re: line (concise; does not reveal privileged strategy)\n- Salutation\n- Body (per template + drafting rules)\n- Closing\n- Signature block per intake\n\n### In-chat review\n\nShow the draft as readable plain text for the user to review and request edits. Iterate before writing the final .docx. Once approved, write to disk.\n\n### Send gate (closing note on the draft)\n\nAppend the following, set apart from the body, to the in-chat presentation and to any internal preview — it is a reviewer-facing note, not letter text, and is stripped before the letter goes out:\n\n> This is a draft demand letter for attorney review, not a letter ready to send. Sending it may constitute an attorney communication, create FRE 408 (or state-equivalent) implications, and start the clock on disputes, counterclaims, and statutes. A licensed attorney reviews, edits, and takes professional responsibility before sending. Do not send this draft unreviewed.\n\n### Citation verification\n\nEvery `[CITE:___]` placeholder — and any citation pulled from the intake or the seed doc — is unverified until a human runs it through a citator. Before sending, run a verification pass: check each case, statute, and regulation against a legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or your firm's platform) for accuracy, good law status, and subsequent history. Fabricated or misquoted citations in sent demand letters and filed documents have resulted in sanctions.\n\n**Source attribution.** Tag every citation in the draft with where it came from: `[Westlaw]`, `[CourtListener]`, `[Trellis]`, `[Descrybe]`, or the specific MCP tool name for citations retrieved via a legal research connector; `[web search — verify]` for citations surfaced by web search; `[model knowledge — verify]` for citations the model recalled from training data; `[user provided]` for citations supplied in the intake or seed doc. Citations tagged `verify` carry higher fabrication risk than tool-retrieved citations and should be checked first. Never strip or collapse the tags — they are the signer's fastest signal about which citations to verify before the letter goes out.\n\n**No silent supplement.** If a research query to the configured legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or firm platform) returns few or no results for an authority the draft needs, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [issue]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) leave the `[CITE:___]` placeholder and stop here. Which would you like?\" A lawyer decides whether to accept lower-confidence sources; the skill does not decide for them.\n\n### the current project's documents — the post-send checklist\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`. This header applies to the internal checklist file; the outgoing letter does NOT carry it.]\n\n# Post-Send Checklist — [slug]\n\n**Draft version sent:** [v1 / v2 / etc.]\n**Sent date:** [YYYY-MM-DD — filled in after send]\n**Signer:** [name]\n\n## Pre-send (before the letter goes out)\n\n- [ ] Final read-through by signer\n- [ ] Factual accuracy: all [VERIFY] flags resolved\n- [ ] Citations: all [CITE] placeholders filled and run through a citator (verify it is good law)d (if live law cited)\n- [ ] Privilege markings applied per house style — note: this is an external deliverable; do not include the `PRIVILEGED & CONFIDENTIAL — ATTORNEY WORK PRODUCT` header in the version sent to counterparty\n- [ ] Settlement-communication markers [present / absent] as intake specified, and substance aligns with posture\n- [ ] Internal copies cleared (per intake distribution list)\n- [ ] Insurance tender sent (if required per house practice)\n- [ ] Conflicts confirmed (if not yet cleared)\n\n**Before the letter is sent (the consequential act):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Sending this demand letter has legal consequences — it creates a record, can trigger statutes and counterclaims, and may waive privileges or constitute admissions. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: counterparty and dispute, the demand and deadline, tone posture, FRE 408 / settlement-communication status, privilege and admission risks flagged in the pre-draft gate, what could go wrong, what to ask the attorney before sending.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not mark as sent — do not execute the Send mechanics below — without an explicit yes.\n\n## Send mechanics\n\n- [ ] Delivery method executed: [certified / email / both]\n- [ ] Proof of delivery retained (certified receipt, email read-receipt, courier confirmation)\n- [ ] Copies sent per distribution list\n\n## After send\n\n- [ ] Compliance deadline calendared: [YYYY-MM-DD]\n- [ ] Escalation plan if no response: [next step + date]\n- [ ] Follow-up check-in calendared: [date — typically deadline + 2 business days]\n- [ ] Matter created in `_log.yaml`: [yes / no — see materiality below]\n\n## Materiality call\n\n**Heuristic says:** [material / immaterial]\n**Reason:** [demand type / exposure / counterparty type]\n**Your call:** [material → create matter] [immaterial → demand-letters record only]\n\nIf material: `the “Matter Intake” workflow` with `source: demand-letter` pre-populated from this intake.\n```\n\n### Matter auto-creation offer\n\nAfter drafting and writing the checklist, assess materiality per heuristic:\n\n- **Default yes if ANY of:**\n - Demand type is `cease-desist`, `breach-cure`, `employment-separation`, or `preservation`\n - Desired outcome $$ ≥ your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) medium-severity band\n - Counterparty is a customer, competitor, or frequent adversary per landscape\n- **Default no otherwise**\n\nPresent the call:\n> Materiality heuristic: [result]. [One-sentence reason.]\n> Create a tracked matter in the current project's documents? (default: [yes/no])\n\nIf user accepts: trigger `matter-intake` with fields pre-populated from the intake (counterparty, type, jurisdiction, `source: demand-letter`, initial theory, internal stakeholders). User reviews pre-filled fields and confirms.\n\nIf user declines: update intake `status: drafted` (later `sent` when user confirms). The record stays in the current project's documents only.\n\n## Versioning\n\nNever overwrite a draft that has been sent. If revising after send, `draft-v2.docx`. The sent-version history is itself the record of what the counterparty received.\n\n## What this skill does not do\n\n- **Send the letter.** Drafting only. The user sends.\n- **Research citations.** `[CITE:___]` placeholders stay as placeholders. If the user provided authorities in the intake, they're used; otherwise, blanks. Inventing cites is malpractice exposure.\n- **Bypass the pre-draft gate.** Even with `--skip-gate`, the skill notes in the draft file that the gate was skipped and why.\n- **Rewrite the intake.** If the intake is thin, send the user back to `demand-intake`. The draft is only as good as what it reads from.\n- **Decide materiality.** The heuristic offers a default; the user's call is the record.", + }, + { + id: "builtin-cfl-litigation-demand-intake", + title: "Demand Intake", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “demand-intake” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /demand-intake\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → demand-letter practice, landscape, risk calibration.\n2. Follow the workflow and reference below.\n3. Run the adaptive intake (core 8 always; strategic block if material or `--full`).\n4. Generate slug from title + counterparty + year-month.\n5. Write the current project's documents.\n6. Confirm with user: \"Intake saved. Run `the “Demand Draft” workflow [slug]` when ready.\"\n\n---\n\n# Demand Intake\n\n## Purpose\n\nThe drafting is downstream. The value is in the pre-writing — forcing the questions a careless letter skips. Leverage, BATNA, downside tolerance, privilege filters, the actual audience. A demand letter sent without thinking about those is worse than no letter.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Demand-letter practice (insurance-tender timing, materiality threshold for matter creation, any seed-doc templates), landscape (counterparty type, repeat-adversary patterns), risk calibration (to pre-estimate materiality), house style. **Tone, compliance period, marking, signer are NOT practice-level defaults — they are set per matter in the `## Posture for this matter` step below.**\n\n## Flags\n\n- `--full` → run the complete intake regardless of materiality heuristics (for counsel who wants thorough every time)\n\n## The intake\n\n### Posture for this matter (ask FIRST, before the core)\n\n> **Posture for this matter.** Demand-letter tone and terms are case-by-case, not a practice default. Ask:\n> - **Tone:** measured / assertive / aggressive? (depends on the relationship, the amount, and whether litigation is likely)\n> - **Response window:** what's reasonable given the claim? (14 days is common for payment demands; 30 days for cure; 7 days for cease-and-desist — but the contract or protocol may set it)\n> - **Marking:** does this need a \"without prejudice\" or \"without prejudice save as to costs\" marking? (settlement communications do; assertions of claim often don't; jurisdiction matters — ask if unsure)\n> - **Signer:** you, the client, the GC, instructed solicitor/counsel?\n> Don't assume. Read the prior demand correspondence in the matter file if there is any — it establishes the register.\n\nRecord the answers in the intake under a `## Posture` section before `## Parties`. These answers govern the rest of the intake and the downstream draft — do not fall back to a practice-level default if the user left any of them blank; ask again.\n\n### Core — always asked (8 questions)\n\n**1. Demand type**\n`payment | breach-cure | cease-desist | employment-separation | preservation | other`\n\n**2. Parties**\n- **Sender:** our company (and any specific entity if multi-entity)\n- **Recipient:** counterparty — name, entity, address\n- **Recipient audience:** who actually reads (GC? CEO? individual? in-house legal?)\n- **Relationship:** `customer | vendor | ex-employee | competitor | third-party | other`\n\n**3. Triggering event**\n- What happened and when (dates matter — statute-of-limitations, notice periods)\n- Evidence available (contracts, emails, records, witnesses)\n\n*Seed doc opportunity: \"If you can share the underlying contract, correspondence, or evidence, the draft will be materially sharper. Paths work.\"*\n\n**4. Legal / contractual basis**\n- Which provisions — specific contract sections if applicable\n- Governing law (jurisdiction, choice-of-law clause)\n- Statutes or rules relied on (placeholders OK — the draft will flag `[CITE:___]` anyway)\n\n**5. Desired outcome**\n- Specific asks. Not \"resolution\" — payment of $X by date Y; cessation of specific activity Z; cure within N days; return of specific property.\n- If multiple asks, order them (primary vs. fallback)\n\n**6. Deadlines**\n- External deadline driving this (SoL, ongoing harm window, business event)\n- Demand compliance deadline — how long we give the recipient. Use the response window captured in `## Posture for this matter` above; do not fall back to a practice-level default.\n\n**7. Prior outreach**\n- Has this been raised informally? When, by whom, in what form?\n- Any response so far?\n- Why is escalation to a demand letter happening now?\n\n**8. Distribution**\n- Delivery method (ask; no practice-level default)\n- Signer — captured in `## Posture for this matter` above\n- Copies — internal stakeholders, insurance carrier (if tendering pre-demand per practice-level tender-timing rule), counsel\n\n### Strategic — asked if material, or if `--full`\n\nMateriality heuristic: ask the strategic block if any of the following are true.\n\n- Demand type is `cease-desist`, `breach-cure`, `employment-separation`, or `preservation`\n- Desired outcome dollar value ≥ the medium-severity band from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) risk calibration\n- Counterparty is a customer, competitor, or frequent adversary per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) landscape\n- User ran with `--full`\n\n**Explicit skip option.** When the strategic block is triggered, the user can decline to answer it. Ask plainly:\n\n> This is a material demand by the heuristic. The strategic block (leverage, BATNA, tone, privilege filters) is where most of the pre-writing value lives. Skipping it produces a thinner draft.\n> - **Answer now** — walk the strategic block (5-7 min)\n> - **Answer partial** — walk the subset you feel prepared for\n> - **Skip** — proceed to draft with only the core block; I'll flag `strategic_block: skipped` in the intake\n\nIf the user chooses Skip, the intake file records it:\n\n```yaml\nstrategic_block: skipped # answered | partial | skipped\nskipped_reason: string | null # captured if user provided one\n```\n\nThe draft skill honors the skip — pre-draft gate runs regardless, but sections that depend on strategic-block answers get `[SME VERIFY: leverage/tone/privilege not captured in intake]` markers. The `/demand-draft` command also prompts a second time, asking whether the user wants to complete the strategic block before drafting.\n\n**9. Leverage and BATNA**\n- What gives us negotiating power (contractual rights, factual leverage, reputational, commercial)\n- What if they refuse — are we prepared to litigate? Go public? Accept a smaller outcome?\n- Their likely BATNA — what's their best alternative? (If they don't think we'll sue, the demand is weak.)\n\n**10. Downside tolerance**\n- Reputational exposure if this becomes public\n- Precedent risk — does this letter set a pattern that affects other matters?\n- Regulatory / disclosure implications (is this the kind of dispute that becomes a 10-Q item?)\n- Insurance implications — does sending without tendering waive coverage?\n\n**11. Tone posture**\n- Already captured in `## Posture for this matter` above. Here, probe the trade-off if the user chose a stronger tone than the facts seem to warrant, or a weaker tone than the facts seem to warrant.\n- Worth naming explicitly: aggressive tone burns the relationship. If you want to keep the business relationship but need to protect the legal position, `measured` is usually the right call.\n\n**12. Settlement-communication posture**\n- Research the settlement-communication protections applicable in the forum (FRE 408 in federal, the state equivalent otherwise). Is this letter a settlement communication that should be protected? Or an assertion of rights that shouldn't be?\n- If protected: the draft will include the settlement-communication marker and will be structured so the substance (a discussion of compromise) — not just the label — supports the posture.\n- Protection attaches from conduct and context, not merely from labeling. The marker is a belt-and-suspenders choice.\n\n**13. Privilege filters**\n- What's in our internal analysis that must NOT appear in the letter? (Facts we haven't verified, our doubts about our case, strategic reasoning, prior settlement discussions)\n- A single badly-worded sentence can waive privilege on related analysis. Be explicit about what stays out.\n\n**14. Admission and accord-and-satisfaction risk**\n- Anything in the letter that the counterparty could later characterize as an admission of fact or liability?\n- Does this demand risk inadvertently satisfying (or purporting to accept) a separate claim? (Accord-and-satisfaction: cashing a check marked \"payment in full\" can end a disputed debt.)\n\n## Writing the intake\n\n### Slug\n\n`[type]-[counterparty-short]-[yyyy-mm]`. Confirm uniqueness in the current project's documents.\n\n### the current project's documents\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# Demand Intake: [title]\n\n**Slug:** [slug]\n**Demand type:** [type]\n**Drafted by:** [counsel]\n**Opened:** [YYYY-MM-DD]\n**Status:** intake | ready-to-draft | drafted | sent | closed\n**Strategic block:** answered | partial | skipped\n**Skipped reason:** [if applicable]\n\n---\n\n## Posture\n\n- **Tone:** [measured / assertive / aggressive — with one-line rationale tied to the relationship and the amount]\n- **Response window:** [N days — tied to the claim / contract / protocol]\n- **Marking:** [none / without prejudice / without prejudice save as to costs / other — with rationale]\n- **Signer:** [name / role — you / client / GC / instructed counsel]\n\n*This is the per-matter posture captured at intake. The draft skill reads from here.*\n\n---\n\n## Parties\n\n- **Sender:** [our entity]\n- **Recipient:** [counterparty, entity, address]\n- **Recipient audience:** [who reads]\n- **Relationship:** [type]\n\n## Triggering event\n\n[What happened, when, evidence]\n\n## Legal / contractual basis\n\n[Provisions, governing law, statutes]\n\n## Desired outcome\n\n[Specific asks in priority order]\n\n## Deadlines\n\n- **External:** [SoL, ongoing harm window]\n- **Compliance:** [how long we give them]\n\n## Prior outreach\n\n[History, most recent first]\n\n## Distribution\n\n- **Delivery:** [method]\n- **Signer:** [name/role]\n- **Copies:** [list]\n\n---\n\n## Strategic (if applicable)\n\n### Leverage & BATNA\n\n[Our power, their likely response]\n\n### Downside tolerance\n\n[Reputational, precedent, regulatory, insurance]\n\n### Tone posture\n\n[relationship-preserving / measured / scorched-earth — with rationale]\n\n### Settlement-communication posture\n\n[Protected or not in the forum — with reasoning. Cite primary source per the applicable rule (FRE 408 or state equivalent).]\n\n### Privilege filters\n\n[What CANNOT appear in the draft]\n\n### Admission / accord-and-satisfaction risk\n\n[Specific risks flagged]\n\n---\n\n## Seed documents\n\n| Doc | Path |\n|---|---|\n| [underlying contract] | [path or \"not shared\"] |\n| [prior correspondence] | [path or \"not shared\"] |\n| [evidence] | [path or \"not shared\"] |\n\n---\n\n## Materiality assessment\n\n**Auto-heuristic says:** [material / immaterial — with reasoning]\n**User call:** [material / immaterial / TBD at post-send]\n```\n\n## Confirm before writing\n\nShow the user the draft intake. Flag anything thin:\n\n> Here's the intake. I notice [thin spots]. Before I save, anything to add?\n\n## Handoff to drafting\n\nEnd with:\n> Intake saved. When ready: `the “Demand Draft” workflow [slug]`\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- Draft the letter. That's `demand-draft` — the two steps are intentionally separate so counsel can pause for business input, outside counsel consult, or insurance tender before drafting.\n- Decide whether to send the letter. Some intake sessions end with \"actually, don't send — let's negotiate directly.\" That's a valid outcome; the intake record still has value.\n- Run the conflicts check. If the counterparty is a customer or known entity, flag that this should clear conflicts (per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)) before sending — but the check itself lives in the matter-intake workflow or outside this skill.", + }, + { + id: "builtin-cfl-litigation-demand-received", + title: "Demand Received", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “demand-received” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /demand-received\n\n1. Read the incoming document from provided path.\n2. Load the current project's documents for portfolio cross-check.\n3. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → risk calibration, landscape, demand-letter practice.\n4. Follow the workflow and reference below.\n5. Extract fields; cross-check portfolio; assess merit; present options with recommendation.\n6. Write the current project's documents. Copy or link incoming to the current project's documents.\n7. Hand off per user choice:\n - Create matter → `matter-intake` pre-populated\n - Respond with counter-demand → `demand-intake` pre-populated\n - Link to existing matter → update `related_matters` in log\n - Standalone → no further action\n\n---\n\n# Demand Received\n\n## Purpose\n\nInbound demand letters are the bread and butter of an in-house litigation practice. A small fraction need escalation; most can be handled with a structured response or a holding letter. The failure mode is treating them all alike. This skill triages, cross-checks the portfolio, and produces options.\n\n## Load context\n\n- The incoming document (user provides path or drops it in-session)\n- the current project's documents — scan for related matters (same counterparty, overlapping counterparties via entity relationships, or matter type + recent date)\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → risk calibration (for merit assessment), landscape (is the sender a frequent adversary?), demand-letter practice (house tone and response defaults)\n\n## Workflow\n\n### Step 1: Read the demand\n\nExtract from the incoming:\n\n- **Sender** — entity, signer, counsel (if signed by outside firm)\n- **Recipient** — which entity/person at our company\n- **Delivery** — certified, email, courier (matters for deadline calculation)\n- **Date received** vs. **date signed**\n- **Demand type** — payment, breach/cure, C&D, preservation, settlement, other\n- **Specific asks** — what they want, by when\n- **Facts alleged** — their version of what happened\n- **Legal basis** — statutes, contract provisions, theories they cite\n- **Threats** — what they say they'll do if we don't comply\n- **Settlement-communication framing** — research the settlement-communication protections applicable in the forum (FRE 408 in federal, the state equivalent otherwise). Note whether the demand is marked as a settlement communication, but remember: protection attaches from conduct and context, not merely from labeling. Capture both the label (if any) and a first-pass read of whether the substance is in fact a compromise discussion.\n\n### Step 2: Portfolio cross-check\n\nSearch `_log.yaml` for:\n\n- **Direct match** — matter with same counterparty (their slug matches the sender)\n- **Type match** — similar matter type with this counterparty in the past (closed matters count — they inform pattern)\n- **Subject overlap** — matters where the subject might be the same dispute (e.g., same contract, same product, same project)\n\nPresent findings:\n\n- If **direct match + active:** flag as almost certainly the same matter; recommend adding incoming to the existing matter, not opening a new one. Update `related_matters` if it's a tangent.\n- If **direct match + closed:** flag — counterparty is back. May be a new dispute (open new matter) or a resurrected one (reopen or amend). User decides.\n- If **type match:** note as precedent/context; probably distinct matter but inform the response strategy.\n- If **no match:** novel. Treat as fresh.\n\n### Step 3: Merit assessment\n\nNot a legal opinion — a structured read:\n\n- **Facts** — do the alleged facts align with what we know? Where's the disconnect?\n- **Legal basis** — are the cited provisions/statutes actually applicable? (Flag cites for user verification — do not attempt to validate law autonomously.)\n- **Strength on their side** — if they went to court tomorrow, what's their story?\n- **Strength on our side** — what are our likely defenses?\n- **Damages demanded vs. likely** — is the ask proportionate to what a court would award if they won?\n- **Leverage and pressure** — are they credibly prepared to sue? Do they have capacity? Are they a repeat-litigant adversary per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)?\n\nOutput a triage rating: **substantial merit / debatable / weak / frivolous**. Be blunt. The user is triaging, not writing the brief.\n\n### Step 4: Response options\n\nPresent 3-4 options with tradeoffs:\n\n**Option A — substantive response**\n- When: their demand has merit or is at least debatable; a reasoned reply protects the record\n- Tradeoff: commits us to a position in writing\n- Next step: `/demand-intake` with pre-populated fields for a counter-response letter\n\n**Option B — holding letter**\n- When: need time to investigate; don't want to concede anything or trigger their deadline math\n- Tradeoff: doesn't resolve anything; buys 2-4 weeks\n- Next step: short acknowledgment draft\n\n**Option C — settlement response**\n- When: early resolution is cheaper than litigation; willing to discuss without admitting\n- Tradeoff: settlement-communication posture required — research the applicable rule (FRE 408 or state equivalent) and structure the response so the substance, not just the label, qualifies as a compromise discussion. Must be careful not to waive claims.\n- Next step: `/demand-intake` with `type: settlement-response`\n\n**Option D — ignore + preserve**\n- When: demand is frivolous or the deadline doesn't create legal prejudice\n- Tradeoff: silence can be used against us in some contexts (e.g., account stated); legal hold still required\n- Next step: issue legal hold via `/legal-hold --issue` if not already; log the demand and move on\n\nRecommend one. Be specific about why.\n\n### Step 5: Deadline triage\n\n- **Their stated deadline** — note it, but it doesn't bind us\n- **Our internal deadline** — when we must decide (often: stated deadline minus 5 business days to draft + approve)\n- **Legal deadlines** — statute of limitations, contractual cure periods, procedural requirements\n\nFlag any legal deadlines that are tight. Calendar them.\n\n**No silent supplement.** If the inbound demand cites rules, cases, or statutes that require verification, and a research query to the configured legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or firm platform) returns few or no results for a given authority, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [cite / doctrine]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) leave the `[SME VERIFY]` flag and stop here. Which would you like?\" A lawyer decides whether to accept lower-confidence sources; the skill does not decide for them.\n\n**Source attribution.** Tag every citation carried into the triage — including the sender's cited authorities, our response-option rationales, and any research pulled for merit assessment — with where it came from: `[Westlaw]`, `[CourtListener]`, `[Trellis]`, `[Descrybe]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations supplied in the demand itself. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\n### Step 6: Write triage\n\nOutput: the current project's documents.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n> **Privilege inheritance.** This triage is derived from the inbound demand and from the portfolio log, and it records our first-pass merit read and response posture. Those internal analyses are attorney-client and/or work-product material. Distributing this triage beyond the privilege circle — including forwarding it to the business lead without marking, sharing with the counterparty, or attaching to an insurance tender without scrubbing — can waive protection over both this document and the reasoning inside it. Store with privileged matter material, mark consistently with house privilege conventions, and make distribution decisions deliberately.\n\n# Demand Received — Triage\n\n> **READ FOR TRIAGE, NOT OPINION.** This document is an intake scan and an options analysis — not a legal merit opinion. The `Triage rating` below is a structured read to support the counsel's decision on how to route the demand. It is not a recommendation on the merits and does not substitute for case-specific legal analysis. Every cited statute, rule, or case is flagged for SME verification; every merit call is the counsel's, not this skill's.\n\n**Slug:** [slug]\n**Received:** [YYYY-MM-DD]\n**Received by:** [entity / person]\n**Incoming file:** [path]\n\n---\n\n## The demand\n\n**Sender:** [entity, signer, counsel]\n**Demand type:** [type]\n**Specific asks:** [list]\n**Their stated deadline:** [date]\n**Settlement-communication framing:** [labeled / substantively / neither / ambiguous] — *protection turns on conduct and context, not the label; `[SME VERIFY]` against the forum's applicable rule*\n\n## Facts alleged\n\n[their version, in one paragraph]\n\n## Legal basis cited\n\n[citations — each inline-flagged with `[SME VERIFY: applicability / currency / jurisdiction]` — do not rely on any citation here without independent check]\n\n## Threats / next steps they state\n\n[list]\n\n---\n\n## Portfolio cross-check\n\n**Direct match:** [slug if exists, or \"none\"]\n**Type match / precedent:** [list or \"none\"]\n**Subject overlap:** [list or \"none\"]\n**Recommendation:** [new matter / add to existing / link via related_matters / standalone inbound]\n\n---\n\n## Merit assessment\n\n**Facts:** [alignment with our version; disconnects]\n**Legal basis:** [applicability, with flags]\n**Their case if litigated:** [one paragraph]\n**Our defenses:** [one paragraph]\n**Damages proportionality:** [assessment]\n**Credibility of threat:** [will they sue? capacity? repeat litigant?]\n\n**Triage rating:** [substantial / debatable / weak / frivolous] — *structured read for routing, not a merit opinion; `[SME VERIFY: counsel to confirm before relying on this]`*\n\n---\n\n## Response options\n\n### A. Substantive response\n[Rationale, tradeoffs, next step]\n\n### B. Holding letter\n[Rationale, tradeoffs, next step]\n\n### C. Settlement response\n[Rationale, tradeoffs, next step]\n\n### D. Ignore + preserve\n[Rationale, tradeoffs, next step]\n\n**Recommendation:** [A/B/C/D] — [two sentences why] — `[SME VERIFY: counsel to confirm before executing]`\n\n---\n\n## Deadlines\n\n- **Their stated deadline:** [date]\n- **Our internal decision deadline:** [date]\n- **Legal deadlines:** [SoL, cure periods, procedural — with dates]\n\n---\n\n## Immediate actions\n\n- [ ] Legal hold issued — [yes/no] — if no, run `/legal-hold [slug] --issue`\n- [ ] Matter created in log — [yes/no/TBD]\n- [ ] Counsel assigned — [who]\n- [ ] Insurance tendered — [yes/no/N-A]\n- [ ] Internal escalation (GC/CFO/business lead) — [who/when]\n```\n\n### Step 7: Hand off\n\nBased on recommendation and user confirmation:\n\n- Matter creation → hand off to `/matter-intake` with: counterparty, type, `source: demand-letter` (inbound), initial theory framed defensively, pre-populated.\n- Counter-response as outbound demand → hand off to `/demand-intake` with: counterparty, context from triage, desired outcome as the response.\n- Link to existing matter → update that matter's `related_matters` in `_log.yaml`; append event to its `history.md`.\n- Standalone → leave in the current project's documents; no portfolio change.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Validate cited law.** Flags cites for the user to run through a citator (verify it is good law) or check with outside counsel. Inventing legal analysis on inbound demands is malpractice exposure.\n- **Send a response.** Drafts are drafted in `demand-draft`; this skill stops at the triage decision.\n- **Decide merit definitively.** The rating is a read for triage; a formal merit opinion lives with outside counsel or more thorough analysis.\n- **Make the matter-creation call.** Surfaces the recommendation; user decides.", + }, + { + id: "builtin-cfl-litigation-deposition-prep", + title: "Deposition Prep", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “deposition-prep” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /deposition-prep\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → case theory, key facts.\n2. Follow the workflow and reference below.\n3. Pull docs authored by / mentioning witness from eDiscovery platform.\n4. Build outline: background, key docs, topics tied to theory, impeachment material.\n\n---\n\n# Deposition Prep\n\n## Witness statements for England & Wales — PD 57AC\n\nIf the user's jurisdiction includes England & Wales and they're asking for a trial witness statement for the Business & Property Courts (or any CPR-governed proceeding), PD 57AC applies. The statement must be in the witness's own words, must not contain argument, must identify the documents the witness used to refresh their memory, and must carry the required confirmation of compliance and the legal representative's certificate.\n\n**Drafting a narrative \"as the witness\" from a chronology, document set, or your account of the case is exactly what PD 57AC was designed to prevent.** Courts are actively sanctioning AI-assisted witness statement drafting. If you ask me to do it, I won't.\n\nWhat I WILL do: prepare question prompts to elicit the witness's actual recollection; capture and organize what the witness says (their words, not mine); generate the list of documents they were shown; run a PD 57AC compliance checklist against a statement they've drafted; draft the solicitor's certificate of compliance. I help you get the witness's evidence into the statement. I don't write the evidence.\n\nFor US depositions, declarations, and affidavits: different rules, but the same discipline applies. A declaration in the declarant's voice that the declarant didn't write is a credibility problem at best.\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nA depo outline is a map: background → lock in the good facts → confront with the bad ones → box in on the theory. This skill builds the map from the documents and the case theory.\n\n## Record fidelity — quotes and pinpoints\n\nTwo rules that govern every citation and every quotation pulled from the record into this outline. Canonical statement lives in the plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) shared guardrails; repeated here because an impeachment confrontation built on a misquoted prior statement or a misgrounded transcript cite collapses the impeachment.\n\n**Verbatim quotes from the record must be verbatim.** Never put quotation marks around words attributed to opposing counsel, the witness, another deponent, the court, or any record document unless you have the exact passage in front of you and can cite to it. When you want to characterize what someone said but can't find the exact words:\n\n- **Paraphrase without quotation marks**, attributing clearly: \"Witness previously testified that X `[verify against record — Tr. p. __]`.\"\n- **Mark the placeholder:** `[verify exact quote — record cite pending]`\n- **Never fill the gap.** An invented prior statement destroys the impeachment the moment the witness disavows it and the transcript doesn't back you up. Every `[verify exact quote]` must be flagged in the reviewer note.\n\n**Pinpoint cites must support the whole proposition.** If an impeachment point is \"the witness said X, Y, and Z on [date],\" verify the pinpoint cite supports X AND Y AND Z. If it only supports Z, split the cite — \"said X (Tr. p. 10), Y (Tr. p. 12), Z (Tr. p. 15)\" — or narrow the proposition. A cite that supports part of an impeachment is the failure mode where opposing counsel asks the witness to read more of the surrounding transcript and your confrontation falls apart.\n\n## Oral calibration\n\nA depo outline is read aloud in real time. That's oral advocacy, not written. It means:\n\n- Pick the 3-4 topics that actually matter. Don't try to cover everything — a 200-question outline on a 4-hour depo makes the lawyer skim, and skimming is how lines of questioning get lost mid-sequence.\n- Lead with your strongest confrontation. The witness is freshest at the start, and the transcript's opening pages are the ones a judge or jury is most likely to see.\n- For adverse witnesses: the tightest questions go in the tightest sequences. Everything else is scaffolding.\n- If you're preparing a rebuttal closing after the depo, the calibration is stricter still — the tribunal remembers the first two minutes and the last two.\n\n\"Too thorough\" for oral work reads as unfocused. If the outline is long because the record is deep, say so and flag where the lawyer should collapse.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → case theory (theory, pivot fact, key facts for/against), eDiscovery platform.\n\n**Conflicts gate — unbypassable.** Before building an outline, check the current project's documents for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace is set up. I won't build a deposition outline on a matter that hasn't been intaken — the conflicts check is the gate.\"\n\nDo not proceed on an unintaken matter. Intake is what runs conflicts and writes the `_log.yaml` row this skill reads from.\n\n## Workflow\n\n### Step 1: Who is this witness?\n\n- Name, role, relationship to the case\n- Why are we deposing them — what do we need from this witness?\n\nThe \"why\" connects to the theory. If the witness can establish the pivot fact, that's the centerpiece of the outline.\n\n### Step 1a: Witness posture — branch before drafting questions\n\nPrep structure differs by posture. Identify the witness posture before writing a single question:\n\n- **Adverse / hostile** — cross-examination style: closed, leading, one fact at a time. Build the box.\n- **Friendly / your own** — direct-examination style: open questions that let the witness tell the story. Closed leading questions with your own witness are usually improper and undercut credibility with the factfinder.\n- **Neutral third-party** — mix; often open to get the story, closed to pin specifics.\n- **Corporate representative (30(b)(6) or state equivalent)** — topic designation, binding-the-entity rules, and the witness's personal-knowledge vs. corporate-knowledge distinction all have distinct rules. Research the applicable deposition rule for the forum and the 30(b)(6) / state-equivalent procedure. Confirm: what topics were designated, who was produced, scope of binding testimony.\n\n**Research the applicable deposition rules for the forum and witness type** (FRCP 30 / state equivalent, local rules, judge's standing orders on depositions). Cite primary sources. Don't apply a one-size prep structure — the question form, the approach to documents, and the use of impeachment material all depend on posture.\n\n**No silent supplement.** If a research query to the configured legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or firm platform) returns few or no results for the forum's deposition rules or a cite you need for impeachment, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / authority]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) leave the `[UNCERTAIN]` marker and stop here. Which would you like?\" A lawyer decides whether to accept lower-confidence sources; the skill does not decide for them.\n\n**Source attribution.** Tag every rule reference, case cite, and authority in the outline with where it came from: `[Westlaw]`, `[CourtListener]`, `[Trellis]`, `[Descrybe]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the partner or senior associate supplied. Document citations (Bates, production numbers) retain their native source. Citations tagged `verify` carry higher fabrication risk and should be checked before the deposition. Never strip or collapse the tags.\n\n### Step 2: Pull their documents\n\nFrom the eDiscovery platform (Everlaw/Relativity/DISCO if connected):\n\n- Documents authored by witness\n- Documents sent to or from witness\n- Documents mentioning witness by name\n- Calendar entries and meeting notes with witness present\n\nOrganize by date. Flag the hot docs — the ones that matter most for the theory.\n\n### Step 3: Build topics\n\nEach topic is a thing you want to establish or explore. Organize around the theory:\n\n**Background (always first — lock in uncontroversial facts before the witness is defensive):**\n- Role, tenure, responsibilities\n- Reporting structure\n- How they interacted with the key players\n\n**Good facts (lock them in before confronting):**\n- Facts from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → key facts for us, that this witness can establish\n- Documents that support our theory, authored or received by this witness\n\n**Bad facts (confront with documents):**\n- Facts against us that this witness will be asked about anyway — get your version first\n- Documents that hurt — know how the witness will explain them\n\n**Impeachment (if hostile or if they contradict):**\n- Prior inconsistent statements (from docs, prior testimony, declarations)\n- Documents that contradict what you expect them to say\n\n**The pivot fact:**\n- The sequence of questions that establishes (or undermines) the fact the case turns on\n- This is the most carefully constructed section. Question form follows witness posture from Step 1a: tight closed leading on adverse, controlled open on friendly, mixed on neutral. Don't default to one pattern.\n\n### Step 4: Write the outline\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# Deposition Outline: [Witness Name]\n\n**Date:** [depo date]\n**Witness role:** [title, relationship to case]\n**Witness posture:** [adverse / friendly / neutral / 30(b)(6) or state equivalent] — drives question form\n**Applicable deposition rules:** [FRCP 30 / state rule / local rule / standing order — with pinpoint cites] `[UNCERTAIN — verify currency]`\n**Why we're taking this depo:** [one sentence — the goal]\n**Theory connection:** [how this witness fits the case theory]\n\n---\n\n## I. Background\n\n[Questions — closed, one fact each. Lock in the uncontroversial stuff.]\n\n## II. [Good fact topic]\n\n**Goal:** Establish [fact] for use at summary judgment / trial.\n\n**Documents:**\n- [Bates] — [description] — [why it matters]\n\n**Questions:**\n[The sequence. Each question closed. Build to the admission.]\n\n## III. [Bad fact topic]\n\n**Goal:** Get the witness's explanation of [bad fact] on our terms before they're prepped for trial.\n\n[Same structure]\n\n## IV. Impeachment material (use if needed)\n\n[Prior statements / documents to confront with, if the witness contradicts]\n\n## V. [Pivot fact sequence]\n\n**Goal:** [The thing the case turns on]\n\n[This is the tightest section. Every question is a yes/no. Every question establishes one fact. Build the box.]\n\n---\n\n## Exhibit list\n\n| # | Bates | Description | Used in section |\n|---|---|---|---|\n\n## Marker discipline\n\nUse inline while building and reviewing:\n- `[VERIFY: factual assertion]` — any fact not confirmed against the record\n- `[UNCERTAIN: legal proposition]` — any legal point (rule, deadline, scope-of-questioning limit) not confirmed against current authority\n- `[CITE NEEDED: specific cite]` — record or authority cite pending\n\n## Notes for the attorney\n\n- [Anything the outline doesn't capture — witness demeanor notes, strategic calls to make in the moment]\n\n---\n\n**Privileged / work-product material.** This outline is built from case materials and work product and inherits their protection status. Keep it in the privileged-materials folder, mark it appropriately, and make any distribution decision (co-counsel, client, experts) deliberately — distribution outside the privilege circle can waive protection.\n\n**Cite check any authority relied on.** Rule citations (FRCP 30, state equivalents, local rules, standing orders) and any case law pulled into the outline were generated by an AI model. Verify each against Westlaw, CourtListener, or your research platform — confirm currency and scope before using at the deposition. Source tags on each citation (e.g., `[Westlaw]`, `[web search — verify]`) show where the cite came from; `verify` tags carry higher fabrication risk and should be checked first.\n```\n\n## What this skill does not do\n\n- Take the deposition. The outline is a map; the attorney drives.\n- Predict what the witness will say. It prepares for likely answers, but witnesses surprise.\n- Decide what to ask on the fly. Follow-ups are the attorney's judgment in the room.", + }, + { + id: "builtin-cfl-litigation-legal-hold", + title: "Legal Hold", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “legal-hold” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /legal-hold\n\n1. If `--status` (no slug): read `_log.yaml`, produce portfolio-wide hold report.\n2. Otherwise: load the current project's documents + log row.\n3. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → privilege markings, hold template pointer, escalation norms.\n4. Follow the workflow and reference below.\n5. Route by flag:\n - `--issue`: capture scope, custodians, date range, systems. Draft `legal-hold-v1.docx`. Update `legal_hold` fields. Append history entry. Set `next_refresh` (default +6mo).\n - `--refresh`: capture scope/custodian changes. Draft next version. Update `last_refresh` + `next_refresh`. Flag departed custodians.\n - `--release`: capture release date, retention instruction. Draft release notice. Set `released:` field.\n6. Confirm before writing. Show the user the draft notice and the log diff.\n\n---\n\n# Legal Hold\n\n## Purpose\n\nA legal hold is the most mechanical high-stakes document in-house counsel writes. The notice itself is templated. The failure modes are operational: issued too late, scoped too narrowly, never refreshed, never released. This skill owns all four phases: **issue → refresh → (release) → track**.\n\nThe portfolio already flags missing holds; this skill writes them.\n\n## Jurisdiction assumption\n\nPreservation duties vary materially by forum. Federal common law (via Zubulake / Residential Funding / Rule 37(e)) differs from state practice; states differ from each other on trigger timing, scope, sanctions, and spoliation remedies; regulatory preservation obligations overlay civil rules in some matters (SEC Rule 17a-4, HIPAA, etc.). The trigger, scope, and sanctions exposure cited in the draft are a starting-point read for the forum named in the matter — confirm with counsel before issuing, refreshing, or releasing.\n\n## Load context\n\n- the current project's documents — log row (legal_hold fields + status)\n- the current project's documents — matter context (counterparty, facts, key custodians from internal_owners)\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — house style for litigation hold template pointer, privilege marking, escalation norms\n\n**Conflicts gate — unbypassable.** Before issuing, refreshing, or releasing a hold, check `_log.yaml` for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace is set up. I won't issue, refresh, or release a legal hold on a matter that hasn't been intaken — the conflicts check is the gate, and a hold issued against an unmanaged matter has no `_log.yaml` row to track `last_refresh` / `next_refresh` / `released` against.\"\n\nDo not proceed on an unintaken matter. Intake is what runs conflicts and writes the `_log.yaml` row the `--refresh` / `--release` / `--status` flags operate against.\n\n## Modes\n\nThe command takes a flag: `--issue | --refresh | --release | --status`. Default (no flag) → prompt.\n\n### `--issue` — first issuance\n\nRequired when `legal_hold.issued == false` and the matter is active or reasonably anticipated.\n\n**Before issuing the hold to custodians (the consequential act):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Issuing a legal hold has legal consequences — the scope, custodian list, and timing create the preservation record the company will be judged on if spoliation is argued later. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the matter and trigger, the proposed scope and custodians, the forum-specific preservation rule researched, known spoliation exposure, what could go wrong (too broad / too narrow), what to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not send the notice without an explicit yes. Drafting and scoping do not require the gate — issuance does.\n\n**Research the applicable preservation rule before issuing.** Identify the jurisdiction and the source of the preservation duty (common law, rule of civil procedure, regulatory preservation obligation, contractual). Confirm the currently operative trigger standard (when the duty attaches), scope standard (what must be preserved), and sanctions exposure (spoliation doctrine for the forum). Cite primary sources. Note that federal and state law can differ materially on trigger timing, scope, and remedy — flag the forum you're relying on. If uncertain, say so and get outside-counsel sign-off before issuing.\n\n> **External deliverable:** the notice below is sent to custodians. Do NOT include a `PRIVILEGED & CONFIDENTIAL — ATTORNEY WORK PRODUCT — PREPARED AT THE DIRECTION OF COUNSEL` header on the outgoing notice; use the attorney-client marking in the template. Confirm the correct marking for your jurisdiction and matter.\n\n**Inputs:**\n1. **Scope** — categories of documents, data, communications. Start specific: contracts with counterparty, all communications referencing [project/subject], related financial records, calendar entries. `[SME VERIFY — scope too broad = operational burden; too narrow = spoliation risk]`\n2. **Custodians** — named individuals likely to hold responsive material. Pull suggestions from matter.md internal_owners and from common roles (business lead, HR partner if employment, CISO if data). `[SME VERIFY — the custodian list is the difference between defensible preservation and a gap argument]`\n3. **Date range** — when to start preserving from (usually: triggering event or earlier), through the present + ongoing.\n4. **Systems** — email, Slack/Teams, file shares, devices (including BYOD if applicable), Jira/Asana, CRM, legacy systems.\n5. **Urgency** — if litigation already served or demand received with threat of suit, this goes out today.\n6. **Effective date** — date of the hold.\n\n**Draft the notice** to each custodian, using the house template in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) if one is configured; otherwise the default template below.\n\n**Default hold notice template:**\n\n```\n[PRIVILEGED & CONFIDENTIAL — ATTORNEY-CLIENT COMMUNICATION]\n\nDATE: [effective date]\nTO: [custodian name]\nFROM: [signer — per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) default]\nRE: LITIGATION HOLD NOTICE — [matter short name]\n\nYou are receiving this notice because [company] has determined that [one-\nsentence description of the dispute / investigation, avoiding prejudicial\ndetail]. The law requires preservation of documents and communications\npotentially relevant to this matter.\n\nEFFECTIVE IMMEDIATELY, you must preserve:\n\n1. All documents, emails, text messages, Slack/Teams messages, and other\n communications relating to [scope bullet 1].\n2. [scope bullet 2]\n3. [scope bullet 3]\n...\n\nThis preservation obligation applies to:\n- Email (including sent, archived, deleted folders)\n- Slack/Teams/messaging platforms\n- Shared drives and cloud storage\n- Personal devices used for company business (BYOD)\n- Paper documents\n- Voicemails\n- Calendar entries and meeting notes\n\nDO NOT:\n- Delete, modify, destroy, or dispose of any potentially responsive material\n- Auto-delete or \"Inbox Zero\" any email or messaging\n\nCoordinate with [legal contact] before sharing this notice with direct reports\nor IT.\n\nDirect questions about this notice or your preservation obligations to [legal\ncontact]. You may continue to discuss the underlying business subject matter\nwith colleagues as needed for your work, but do not discuss this legal notice,\nthe litigation, or legal strategy.\n\nIF YOU ARE UNSURE whether something is covered, ERR ON THE SIDE OF PRESERVING.\n\nPlease acknowledge receipt of this notice by [reply / link / form] within\nthree business days. If you have questions, contact [signer email].\n\nThis notice remains in effect until you receive written notice of its\nrelease. You may be asked to reaffirm compliance at periodic intervals.\n\n[Signer signature block]\n```\n\n**Send gate (closing note on the draft):** Append to the in-chat preview of the notice — stripped before the notice goes to custodians:\n\n> This is a draft legal hold notice for attorney review, not a notice ready to issue. Issuing a hold triggers preservation obligations the company will be judged on in any later spoliation argument, and the notice itself may be discoverable. A licensed attorney reviews, approves, and issues. Do not distribute this draft unreviewed.\n\n**Writes:**\n- the current project's documents via the `docx` skill\n- Appends to the current project's documents:\n ```\n ## [YYYY-MM-DD] — Legal hold issued\n\n Hold issued to [N] custodians: [list].\n Scope: [one-line summary].\n Next refresh: [YYYY-MM-DD (default issued + 6 months)].\n ```\n- Updates `_log.yaml` row:\n ```yaml\n legal_hold:\n issued: true\n issued_date: [YYYY-MM-DD]\n scope: \"[one-line summary]\"\n custodians: [list]\n last_refresh: [YYYY-MM-DD] # same as issued_date on first issuance\n next_refresh: [YYYY-MM-DD] # default: issued_date + 6 months\n released: null\n ```\n\n### `--refresh` — periodic reaffirmation\n\nRefresh cadence: default 6 months; adjustable per matter. When `next_refresh < today` (or user invokes manually), the skill drafts a refresh notice.\n\n**Inputs:**\n1. Any **scope changes** since last refresh (new topics surfaced in discovery, new custodians, new systems).\n2. Any **custodians to add or remove** (departures need special handling — see below).\n3. Re-confirmation language.\n\n**Refresh notice template:** similar to issuance; opens with \"This is a reaffirmation of the legal hold originally issued [date].\" Lists current scope (amended if needed). Requests re-acknowledgment.\n\n**Departed custodians:** if a custodian has left the company since last refresh, the skill flags this as a preservation action item — the departing employee's files and email archive need to be preserved at IT level, not just via notice to the individual. Records this in history.md as a separate entry requiring action.\n\n**Writes:**\n- the current project's documents (next version number)\n- `history.md` entry\n- `_log.yaml`: updates `last_refresh` and `next_refresh` fields; modifies `custodians` list if changed\n\n### `--release` — close the hold\n\nUsually at matter close. Confirm the matter is truly over (not on appeal, not likely to reopen, statute of limitations passed on related claims).\n\n**Before releasing the hold (the consequential act — preservation obligations resume normal retention):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Releasing a legal hold has legal consequences — once released, custodians may begin deleting material. Release at the wrong time creates spoliation exposure. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the matter status, why release is proposed now, related-claim / appeal / SOL exposure, custodian impact, what could go wrong, what to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not send the release notice without an explicit yes.\n\n**Inputs:**\n1. Confirmation of release authority (usually the signer or GC).\n2. Release date.\n3. Retention instruction — what happens to the material that was under hold? (Return to normal retention? Continue preserving for defined period? Transfer to archive?)\n\n**Release notice template:** one paragraph, formal. \"The litigation hold issued [date] regarding [matter] is released effective [date]. Normal retention resumes.\"\n\n**Writes:**\n- the current project's documents\n- `history.md` entry\n- `_log.yaml`: sets `released: [YYYY-MM-DD]`\n\n### `--status` — report across the portfolio\n\nRead `_log.yaml`. Produce a report:\n\n```markdown\n# Legal Hold Status — [today]\n\n## Active holds\n\n| Matter | Issued | Last refresh | Next refresh | Custodians | Status |\n|---|---|---|---|---|---|\n| [slug] | [date] | [date] | [date] | [N] | [ok / ⚠️ refresh due / ❌ overdue] |\n\n## ⚠️ Attention\n\n- **Refresh overdue:** [list slugs where next_refresh < today]\n- **Refresh due within 30 days:** [list]\n- **Matters active without hold issued:** [list — high/critical risk first]\n- **Matters closed with hold still active:** [list — consider release]\n\n## Recently released\n\n[last 5 released holds with dates]\n```\n\nThis is a separate command invocation (`/legal-hold --status` with no slug) OR invoked by `/portfolio-status` as a section in the portfolio rollup.\n\n## Integration with portfolio-status\n\nThe `portfolio-status` skill already flags \"Hold not issued on active litigation.\" This skill is what resolves those flags. Worth cross-referencing in the briefing when a matter is opened: if `legal_hold.issued == false`, `/matter-intake` closes by offering to run `/legal-hold --issue`.\n\n## What this skill does not do\n\n- **Enforce preservation.** It issues the notice; IT/custodians preserve. The skill flags when a custodian leaves (so IT can preserve at system level) but doesn't reach into systems.\n- **Make scope calls alone.** The skill proposes scope from matter context; the user confirms. Scope too broad = operational burden. Scope too narrow = spoliation risk. User's judgment.\n- **Auto-refresh without review.** Even when `next_refresh` comes up, the user reviews scope changes before the refresh notice goes out.\n- **Send the notice.** Drafts .docx; user sends via email per house convention. (Future integration: Gmail/O365 MCP could send directly after user review.)", + }, + { + id: "builtin-cfl-litigation-matter-briefing", + title: "Matter Briefing", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “matter-briefing” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /matter-briefing\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → risk calibration + relevant stakeholders.\n2. Follow the workflow and reference below.\n3. Read the current project's documents + the current project's documents + log row from `_log.yaml`.\n4. Produce briefing: current posture, what's changed since last update, next deadline, open questions, risk re-assessment check (\"does the `risk:` field still reflect reality?\").\n5. Flag staleness: if `last_updated` > 30 days, say so.\n\n---\n\n# Matter Briefing\n\n## Purpose\n\nGive the counsel a clean read on one matter in the time it takes to walk to a conference room. Current posture, what's changed, what's next, what's worth reconsidering.\n\n## Load context\n\n- the current project's documents — structured row\n- the current project's documents — narrative intake\n- the current project's documents — event log\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — risk calibration (so \"risk: high\" means something specific, not generic)\n\n**Conflicts gate — unbypassable.** Before briefing, check `_log.yaml` for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace is set up. I won't build a briefing on a matter that hasn't been intaken — the conflicts check is the gate.\"\n\n## Input\n\nSlug (required). If ambiguous or missing, ask the user to pick from a list of active matters.\n\n## The briefing\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# [Matter Name] — Briefing as of [today]\n\n**Status:** [status / stage]\n**Risk:** [rating] ([severity] × [likelihood])\n**Materiality:** [category]\n**Outside counsel:** [firm — lead]\n**Last updated:** [date] [flag ⚠️ STALE if >30d]\n**Conflicts:** [status — flag ⚠️ if `pending` or `not-run`]\n\n---\n\n## One-paragraph summary\n\n[Current posture. What are we doing and why. Name the pivot fact if one is captured.]\n\n## What's changed recently\n\n[Last 3-5 entries from history.md, most recent first. If history is thin, say so.]\n\n## What's next\n\n- **Immediate deadline:** [next_deadline + what it is]\n- **Upcoming milestones:** [anything dated in matter.md or recent history]\n- **Decisions pending:** [open questions flagged in matter.md]\n\n## Exposure\n\n[Range + any change since intake. If reserved, current reserve + whether recalibration is overdue.]\n\n## Internal owners\n\n[Who's looped in; whether anyone should be looped in and isn't]\n\n## Risk re-assessment check\n\n*A prompt, not an answer.*\n\n- Does `risk: [rating]` still feel right, or has the case moved?\n- Does `materiality: [category]` still match? (New facts might push toward reserve or disclosure.)\n- Any new stakeholder the matter needs (e.g., CISO becomes relevant after a discovery development)?\n\n## Open questions\n\n[From matter.md and anything unresolved in history]\n\n## For the conversation\n\n[If user specified a purpose — \"brief me before the call with outside counsel\" — tailor the final section: questions to ask, decisions to get, updates to extract. If no purpose given, omit this section.]\n```\n\n## Staleness\n\nIf `last_updated > 30 days ago`: flag at the top AND suggest running `the “Matter Update” workflow [slug]` after the meeting to capture whatever's discussed.\n\n## Tone\n\nThis is not marketing. Say what's known; flag what's not. If a matter has thin history and was just opened, the briefing is short — and that's correct. Don't pad.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- Predict outcomes. Risk rating is a captured judgment, not a forecast.\n- Recommend strategy. Surfaces questions; the counsel answers them.\n- Re-triage. If the user wants to re-triage, that's an `/matter-update` with field changes — this skill reads, doesn't write.", + }, + { + id: "builtin-cfl-litigation-matter-close", + title: "Matter Close", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “matter-close” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /matter-close\n\n1. Follow the workflow and reference below.\n2. Confirm slug and current status.\n3. Capture outcome: resolution type (settled, dismissed, judgment for/against, withdrawn, consolidated), date, final exposure/cost, lessons.\n4. Update `_log.yaml`: `status: closed`, add `closed: YYYY-MM-DD` and `outcome:` fields.\n5. Append final entry to the current project's documents.\n6. Matter stays in `_log.yaml` and the current project's documents — not deleted. `/portfolio-status` filters it from active rollups.\n\n---\n\n# Matter Close\n\n## Purpose\n\nMatters end. The outcome is the single most valuable data point the portfolio generates — it calibrates the risk framework for future matters. Closing a matter captures the outcome structurally so the record is useful, not just archived.\n\n## Load context\n\n- the current project's documents — find the row\n- the current project's documents — reference (intake context)\n- the current project's documents — append target\n\n**Conflicts gate — unbypassable.** Before closing, check `_log.yaml` for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Nothing to close — either the slug is wrong or the matter was never intaken through `the “Matter Intake” workflow`. Check the slug first; if it genuinely was never intaken, there's no row to update and no file structure to close.\"\n\n## Input\n\nSlug (required).\n\n## The close\n\n### 1. Resolution type\n\n- `settled` — with counterparty, dollar amount, structural terms\n- `dismissed` — with or without prejudice, by what mechanism\n- `judgment-for-us` — at what stage, appeal exposure\n- `judgment-against-us` — at what stage, appeal status, exposure crystallized\n- `withdrawn` — by counterparty, circumstances\n- `consolidated` — merged into another matter (provide slug of parent)\n- `other` — with explanation\n\n### 2. Resolution date\n\nThe date the matter actually ended (settlement executed, order issued, dismissal filed).\n\n### 3. Final exposure\n\n- Actual cost to company (settlement amount + fees + injunctive/structural cost)\n- vs. initial exposure range at intake (did we call it?)\n- Reserve accuracy (if reserved): booked vs. actual\n\n### 4. Lessons\n\nTwo or three sentences. What did we get right? What did we misjudge? Anything the intake should have flagged earlier?\n\nThis is the part future counsel will reread. Be honest. \"Misjudged likelihood — plaintiff firm was more aggressive than expected\" is worth more than \"resolved favorably.\"\n\n### 5. Seed doc prompt\n\nSettlement agreement, final order, dismissal — path if available. Not required.\n\n## Writing\n\n**Before closing the matter (the consequential act — the matter is archived and active tracking ends):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Closing a matter has legal consequences — it ends active tracking, may affect any associated legal hold (run `/legal-hold --release` separately if appropriate), and establishes the final record the company relies on. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the matter, resolution type and terms, final exposure vs. initial, reserve accuracy, related matters or appeals still live, what could go wrong with premature closure, what to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not write the close fields or append the close entry without an explicit yes.\n\n### Update the current project's documents\n\n```yaml\nstatus: closed\nclosed: [YYYY-MM-DD]\noutcome: [resolution-type]\nfinal_cost: [dollar amount]\nlast_updated: [today] # close is the last touch; record it\n```\n\nRetain all existing fields. Do not delete the row.\n\n### Append final entry to the current project's documents\n\n```markdown\n## [YYYY-MM-DD] — Matter closed: [resolution-type]\n\n**Resolution:** [narrative — what happened, on what terms]\n**Final cost:** [amount + structural terms if any]\n**vs. initial exposure:** [compare to matter.md intake range]\n**Reserve accuracy:** [if applicable]\n\n**Lessons:**\n[2-3 sentences — honest retrospective]\n\n**Related doc:** [settlement agreement / final order / etc., if provided]\n```\n\n### Touch the current project's documents\n\nAdd a closing block at the end (don't modify earlier sections — they're the historical intake):\n\n```markdown\n---\n\n## Closed [YYYY-MM-DD]\n\n[Resolution summary in one paragraph. Pointer to the final history entry for detail.]\n```\n\n## Confirm\n\nShow the user the full close entry and the yaml changes before writing.\n\n## What this skill does not do\n\n- Delete matters. Closed matters stay in `_log.yaml` and on disk — they're the training set for the portfolio's judgment.\n- Re-open. If a closed matter comes back (appeal, related litigation), open a new matter that references the closed one in `matter.md`.\n- Summarize lessons the user didn't say. If the user skips the lessons section, leave it empty rather than invent.", + }, + { + id: "builtin-cfl-litigation-matter-intake", + title: "Matter Intake", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “matter-intake” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /matter-intake\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → risk calibration (for triage), landscape (for context, conflicts method), stakeholders (for who to loop in).\n2. Follow the workflow and reference below.\n3. Run the uniform intake: identification, conflicts check, source, risk triage, materiality, outside counsel, internal owners, legal hold, key dates, initial posture.\n4. Generate slug from matter name (lowercase, hyphens, year).\n5. Create the current project's documents — full narrative intake.\n6. Create the current project's documents — seeded with the intake as the first entry.\n7. Append structured row to the current project's documents.\n8. Confirm with the user: \"Here's the row I'll write — any edits?\"\n\n---\n\n# Matter Intake\n\n## Purpose\n\nEvery new matter goes through the same intake so the portfolio stays comparable. Uniform rows in `_log.yaml` let the status skill roll up. Narrative in `matter.md` captures what the row can't. History file seeded here becomes the event record.\n\n## Load context\n\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — risk calibration (triage thresholds, materiality, settlement ladder), landscape (stakeholders, outside counsel bench).\n- the current project's documents — to confirm slug uniqueness.\n\n## The intake\n\n### 1. Identification\n\n- Matter name (as commonly referenced, e.g., \"Acme v. Us 2026\")\n- Counterparty\n- Matter type: `contract | employment | ip | regulatory | investigation | product | other`\n- Our role: `plaintiff | defendant | claimant | respondent | investigated`\n - If the practice profile's `## Side` is `plaintiff`, `defense`, or a \"both — default X\" variant, pre-fill the role from that default and confirm. If `## Side` is `varies by matter`, ask cold. Never silently assume a posture the practice profile hasn't set.\n - The role drives downstream skills: plaintiff-posture matters route risk triage to case value / contingency economics; defense-posture matters route to exposure / reserves / insurance tender.\n- Jurisdiction (court, arbitration forum, or regulatory body)\n\n### 2. Conflicts check\n\nBefore going further, run the conflicts step per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Conflicts clearance.\n\n- **Status:** `cleared | pending | not-run | waived`\n- **Method:** match what your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) declares (`corporate-legal | outside-counsel | system-check | informal | other`). If the declared method is `informal`, say so — the record still captures that a counsel's-judgment check was the basis.\n- **Cleared by:** name / team / firm\n- **Cleared date:** YYYY-MM-DD\n- **Checked against:** brief list of the specific names/entities run (counterparty, known affiliates, adverse counsel if known, key witnesses). Thin is fine; \"no\" is not.\n- **Notes:** anything flagged but cleared (e.g., \"Smith on our board sat on counterparty's board 2019–2021 — cleared as non-overlapping to this matter\").\n\nBehavior by status:\n\n- `cleared` → proceed.\n- `pending` → proceed with intake; flag prominently in `matter.md` and in the log row that conflicts are outstanding; surface again on every `/matter-update` and in `/portfolio-status` until resolved.\n- `waived` → rare; requires a conflict-waiver rationale (writing the waiver is outside this skill — capture that one exists, who signed it, and where it lives).\n- `not-run` → **STOP. This is a gate.** The skill will not create `matter.md`, `history.md`, or a `_log.yaml` entry until the conflicts posture is resolved. Three acceptable paths:\n\n **Path 1 — Run conflicts now.** Pause this intake. Clear per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) Conflicts clearance. Return with `status: cleared` or `status: waived` with rationale.\n\n **Path 2 — Mark pending with owner + due date.** Allowed only when your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) Conflicts clearance declares parallel-intake acceptable. Capture: who is running conflicts, when they're expected to return, what entities they're checking. Intake proceeds; matter row carries `conflicts.status: pending`; `/portfolio-status` flags it every run; `/matter-update` re-prompts until resolved.\n\n **Path 3 — Bypass with documented rationale.** Only if the user explicitly acknowledges the bypass. Record in `conflicts.override`:\n\n ```yaml\n conflicts:\n status: not-run # preserved as-is\n override:\n by: [user name]\n date: [YYYY-MM-DD]\n rationale: [why conflicts were bypassed — permanent record; does not auto-expire]\n ```\n\n This field is visible in every `/portfolio-status`, every `/matter` briefing, and every `/matter-update` until removed. It is never removed by the skill — only by explicit user edit to `_log.yaml` after conflicts are actually cleared.\n\n **Do not proceed silently.** \"I'll do it later\" is not an acceptable response. One of Path 1/2/3 must be chosen, and the choice is captured in the record.\n\nThis step is not about the skill deciding whether a conflict exists — that's the user's/firm's judgment. It's about making sure the check happened and the record reflects it.\n\n### 3. Source\n\nHow did this arrive?\n- `demand-letter | complaint-served | subpoena | regulator-inquiry | internal-report | pre-suit-threat`\n- *Seed doc opportunity:* \"If you have the initiating document (complaint, demand, subpoena), attach or share the path. It sharpens the intake.\"\n\n### 4. Risk triage — against house calibration\n\n- Severity: high | medium | low (reference the your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) severity bands)\n- Likelihood: high | medium | low (reference the your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) likelihood bands)\n- Resulting risk rating (per the matrix): high | medium | low | critical\n- Damages exposure range (best estimate)\n- Non-monetary exposure (injunction? consent decree? publicity? precedent?)\n\nIf the risk calibration in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) is thin, don't fake precision. Use the user's gut and note the thinness.\n\n### 5. Materiality\n\nAgainst the house thresholds in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n- `reserved | disclosed | monitored | none`\n- If `reserved`: reserve amount and whether finance has been notified\n- If `disclosed`: filing and footnote location\n\n### 6. Outside counsel\n\n- Firm\n- Lead partner\n- **Lead partner email** (used by `/oc-status` to draft status requests)\n- Engagement letter status: `signed | pending | none`\n- Budget authorization: amount and approver\n- *Seed doc opportunity:* \"Engagement letter path, if signed.\"\n\nIf risk is medium or higher and no outside counsel is assigned — flag it.\n\n### 7. Internal owners\n\nFrom your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) landscape — which internal stakeholders are involved?\n- Business lead\n- HR partner (if employment)\n- Comms contact (if reputational risk)\n- CISO (if data or cyber)\n- Other\n\n### 8. Legal hold\n\n- Issued? If yes: date, scope, custodians (list of names).\n- Next refresh date (default: six months from issuance; adjust per matter).\n- If no and this is active litigation or reasonably anticipated: flag urgently; offer to run `the “Legal Hold” workflow [slug] --issue` after intake completes.\n- *Seed doc opportunity:* \"Hold notice, if issued.\"\n\n### 9. Key dates\n\n- Response deadline (answer, objection, opposition)\n- Next hearing / conference\n- Statute of limitations cutoff (if applicable)\n- Any regulatory deadlines\n\n### 10. Initial posture\n\nOne-paragraph theory:\n- What's our story?\n- What's theirs?\n- What's the pivot fact?\n- Initial posture: `fight | settle | investigate | wait`\n\n## Writing the outputs\n\n### Slug\n\nLowercase, hyphens, year at the end. Examples: `acme-v-us-2026`, `employment-smith-2026`, `ftc-inquiry-2026`.\n\nConfirm slug is unique in `_log.yaml` before writing.\n\n### the current project's documents\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# [Matter Name]\n\n**Slug:** [slug]\n**Opened:** [YYYY-MM-DD]\n**Our role:** [plaintiff/defendant/etc.]\n**Status:** [status]\n\n---\n\n## Identification\n\n[counterparty, jurisdiction, matter type, source]\n\n## Conflicts\n\n**Status:** [cleared / pending / not-run / waived]\n**Method:** [corporate-legal / outside-counsel / system-check / informal / other]\n**Cleared by:** [name]\n**Cleared date:** [YYYY-MM-DD]\n**Checked against:** [entities run]\n**Notes:** [any flags cleared, waiver reference if applicable]\n\n## Risk triage\n\n**Severity:** [band] — [why, with reference to house severity definitions]\n**Likelihood:** [band] — [why]\n**Risk rating:** [high/medium/low/critical]\n**Exposure:** [dollar range + non-monetary]\n\n## Materiality\n\n[reserved/disclosed/monitored/none — with reserve amount, disclosure location, or reasoning if \"none\"]\n\n## Outside counsel\n\n[firm, lead, engagement status, budget]\n\n## Internal owners\n\n[stakeholders and why each is involved]\n\n## Legal hold\n\n[status, date, scope]\n\n## Key dates\n\n[list]\n\n## Initial theory\n\n[one paragraph: our story, their story, pivot fact, initial posture] `[SME VERIFY — theory at intake is a working hypothesis; confirm with outside counsel before any filing or material communication that assumes this framing]`\n\n## Open questions\n\n[anything not yet known that matters — e.g., \"insurance tender pending\", \"unclear whether we have coverage for X\"]\n\n---\n\n## Seed documents\n\n| Doc | Path / pointer |\n|---|---|\n| [e.g., complaint] | [path or \"not yet shared\"] |\n```\n\n### the current project's documents\n\nSeed the history file with the intake as entry zero:\n\n```markdown\n# History: [Matter Name]\n\nAppend-only event log. Most recent at top.\n\n---\n\n## [YYYY-MM-DD] — Matter opened\n\n[Source, who brought it in, initial triage summary, outside counsel assigned, legal hold issued yes/no.]\n```\n\n### Append to the current project's documents\n\nAdd a row per the schema. Example:\n\n```yaml\n- id: acme-v-us-2026\n name: \"Acme Corp v. Company\"\n type: contract\n role: defendant\n counterparty: \"Acme Corp\"\n jurisdiction: \"N.D. Cal.\"\n # status is derived from source:\n # source: pre-suit-threat | demand-letter → status: threatened\n # source: complaint-served | subpoena | regulator-inquiry → status: active\n # source: internal-report → status: threatened (default) or active if formal process has started\n status: active\n stage: pleadings\n source: complaint-served\n outside_counsel:\n firm: \"Wilson Sonsini\"\n lead: \"J. Reyes\"\n email: \"jreyes@wsgr.example.com\"\n engagement: signed\n conflicts:\n status: cleared\n method: corporate-legal\n cleared_by: \"K. Patel\"\n cleared_date: 2026-04-20\n override: # populated only on Path 3 bypass\n by: null\n date: null\n rationale: null\n risk: high\n materiality: reserved\n exposure_range: \"$2M–$5M\"\n internal_owners:\n business_lead: \"Jane Smith\"\n hr_partner: null\n comms_contact: null\n legal_hold:\n issued: true\n issued_date: 2026-02-15\n scope: \"Sales org 2023–2026\"\n custodians: [\"Jane Smith\", \"R. Chen\", \"T. Patel\"]\n last_refresh: 2026-02-15\n next_refresh: 2026-08-15\n released: null\n related_matters: []\n opened: 2026-04-20\n next_deadline: 2026-05-15\n last_updated: 2026-04-20\n path: matters/acme-v-us-2026/\n```\n\n## Confirm before writing\n\nShow the user the row and the matter.md content:\n\n> Here's what I'll write. Flag anything wrong or thin before I commit.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Run the conflicts check itself.** It records the result, status, method, and the entities checked. The actual clearance happens in whatever system (or judgment) the house practice profile declares. If the user says \"cleared,\" the skill takes that at face value and captures the metadata.\n- Decide the initial theory. It captures what the user says; it doesn't invent one.\n- Issue the legal hold. Flags it if missing. User issues it.", + }, + { + id: "builtin-cfl-litigation-matter-update", + title: "Matter Update", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “matter-update” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /matter-update\n\n1. Follow the workflow and reference below.\n2. Confirm slug exists in the current project's documents and `_log.yaml`.\n3. Prompt for event type, date (default today), summary, and any log field updates (risk change, status change, next deadline shift, materiality reclassification).\n4. Append dated entry to the current project's documents.\n5. Update `_log.yaml` — set `last_updated` to today, apply any field updates.\n6. Confirm.\n\n---\n\n# Matter Update\n\n## Purpose\n\nThe portfolio only stays useful if it stays current. This skill makes logging an update cheap — two minutes of structured capture, no freeform drift.\n\n## Load context\n\n- the current project's documents — find the row\n- the current project's documents — append target\n- the current project's documents — reference (don't rewrite)\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — risk calibration (if re-assessing risk)\n\n**Conflicts gate — unbypassable.** Before logging an update, check `_log.yaml` for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace exists. I won't append history to an unmanaged matter — the conflicts check is the gate, and there's no `history.md` to append to until the matter is intaken.\"\n\n## Input\n\nSlug (required). If not provided, ask — with a short list of recently updated matters to pick from.\n\n## The update\n\n### 1. Event type\n\nOffer categories:\n\n- **Procedural** — motion filed/received, order issued, hearing held, deadline set\n- **Discovery** — production made/received, depositions taken, subpoena served\n- **Substantive** — new facts, key document surfaced, ruling on merits\n- **Strategy** — posture shift, settlement offer made/received, authority update\n- **Risk re-assessment** — severity or likelihood changed\n- **Stakeholder** — new person looped in, outside counsel change\n- **Administrative** — engagement letter executed, budget adjusted, hold refreshed\n\nOr freeform if none fits.\n\n### 2. Date\n\nDefault today. Accept an override (e.g., capturing an event from last week).\n\n### 3. Summary\n\nOne-paragraph narrative. What happened, what it means, any immediate implication.\n\n### 4. Log field changes\n\nWalk through potentially affected fields:\n\n- `status:` — has the stage shifted (e.g., pleadings → fact discovery)?\n- `stage:` — substage update\n- `risk:` — reassessment required?\n- `materiality:` — any change (new facts might trigger reserve or disclosure)?\n- `exposure_range:` — revise if new information\n- `next_deadline:` — new upcoming date, if any\n- `outside_counsel:` — change?\n- `internal_owners:` — anyone new or removed?\n- `legal_hold:` — refreshed, expanded, released?\n\nOnly prompt for fields likely affected by the event type. Procedural updates usually touch `stage` and `next_deadline` only; a settlement offer might touch `materiality`, `exposure_range`, `status`.\n\n### 4pre. Settlement-acceptance gate\n\nIf the Strategy update is a **settlement acceptance** (the company is accepting a settlement offer, executing a settlement agreement, or authorizing acceptance in principle — not merely logging an offer made or received): Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Accepting a settlement has legal consequences — it resolves claims, typically requires a release, and can affect insurance, tax, and related matters. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the matter, proposed settlement terms (dollar, structural, release scope, confidentiality, non-disparagement), exposure at stake, authority ladder status (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) settlement authority), what could go wrong, what to ask the attorney before accepting.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not log the acceptance or flip materiality on acceptance basis without an explicit yes. Logging offers or counters does not require the gate — acceptance does.\n\n### 4a. Materiality trigger — explicit prompt\n\nCertain event types force a materiality re-check. When the event type is in this list, **always prompt** — don't let the user move on without an explicit answer:\n\n| Event type | Materiality trigger prompt |\n|---|---|\n| Substantive (new facts, key document, merits ruling) | \"This event is substantive. Does it push `materiality`? Current: `[current]`. Options: `reserved / disclosed / monitored / none`. Change?\" |\n| Strategy (posture shift, settlement offer made or received) | \"Settlement activity often triggers materiality reclassification. Current: `[current]`. If the offer, counter, or acceptance moves exposure or shifts from contested to probable-and-estimable, reclassify.\" |\n| Risk re-assessment (severity or likelihood changed) | \"Risk moved. Materiality should track. Current: `[current]`. Reclassify?\" |\n| Regulatory / enforcement development | \"Regulator action (subpoena, CID, enforcement notice) usually triggers disclosure analysis. Current: `[current]`. Change?\" |\n\nAcceptable answers include `no change` — but `no change` must be explicit, not implied by silence. Capture in the history entry:\n\n```markdown\n**Materiality check:** [no change / changed from X to Y]\n**Reasoning:** [one sentence]\n```\n\nIf materiality moves to `reserved` or `disclosed`, and the matter did not previously carry a reserve or disclosure, flag the event as requiring finance / audit-committee notification per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) materiality thresholds.\n\n### 5. Seed doc prompt (optional)\n\nIf the update references a document (order, filing, correspondence), ask if there's a path to link. Not pushy.\n\n## Writing\n\n### Append to the current project's documents\n\nMost recent at top, directly under the `---` that follows the header.\n\n```markdown\n## [YYYY-MM-DD] — [Event type]: [short title]\n\n[Paragraph summary.]\n\n**Fields changed:**\n- [field]: [old → new]\n- [field]: [old → new]\n\n**Related doc:** [path, if provided]\n```\n\nIf no fields changed, omit the \"Fields changed\" block.\n\n### Update the current project's documents\n\n- Apply any field changes.\n- Set `last_updated: [today]` (or the event date if the user overrode — the log tracks when the record was last touched).\n\n## Confirm\n\nShow the user the history entry and the yaml diff before writing:\n\n> Here's what I'll append and update. Good to commit?\n\n## What this skill does not do\n\n- Edit past history entries. Corrections are new entries that reference and correct prior ones.\n- Silently change the log. Every field change is shown to the user before write.\n- Decide whether a new development warrants reserve/disclosure. It surfaces the question (\"this might push materiality — want to reclassify?\"), the user answers.", + }, + { + id: "builtin-cfl-litigation-oc-status", + title: "Oc Status", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “oc-status” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /oc-status\n\nTo run weekly, set a recurring reminder to invoke `the “Oc Status” workflow`. Automated scheduling requires a scheduled-tasks integration, which is not bundled.\n\n1. Load the current project's documents, filter per default rules (or per flags).\n2. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → outside counsel directive style, signer defaults, budget posture.\n3. Follow the workflow and reference below.\n4. For each matter in scope: read `matter.md` + `history.md`, draft per-matter email.\n5. Write markdown to the current project's documents.\n6. If Gmail MCP authenticated: create Gmail drafts. Else: markdown-only, note in summary.\n7. Write the current project's documents — what ran, what was skipped and why.\n\n---\n\n# OC Status\n\n## Purpose\n\nWriting the same status-request email to outside counsel every week across 5–15 matters is mechanical cognitive tax. The content is consistent per matter (status, decisions pending, budget check). The audience is consistent (OC lead partner). The tone is consistent (per house outside-counsel-directive style). A scheduled task drafts all of them; counsel reviews and sends.\n\n## Load context\n\n- the current project's documents — the filtering and field source\n- the current project's documents — matter context (current posture, open questions)\n- the current project's documents — recent events to inform what to ask about\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → outside counsel directive style, signer name/email, budget posture\n\n## Filtering — which matters?\n\nDefault filter:\n\n- `status != closed`\n- `outside_counsel.firm != null` AND `outside_counsel.lead != null`\n- Either: last update more than 10 days old (time for something to have happened) OR has a `next_deadline` within 21 days\n\nSkip matters that just had a status update in the last 10 days (no need to re-ping) and matters where `outside_counsel.email` is null (email addresses needed for Gmail draft; still produce markdown).\n\nFlags:\n- `--all` → draft for every active matter regardless of recency\n- `--slug=[slug]` → draft for one matter only (ad-hoc request)\n- `--no-gmail` → skip Gmail draft creation even if MCP is available\n\n## Per-matter email draft\n\nEach email has the same skeleton; content is matter-specific.\n\n**Subject:** per house convention (from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) outside counsel directive style; fallback: `[Matter: [matter name]] — Weekly status update`)\n\n**Body skeleton:**\n\n```\n[lead partner first name],\n\n[One sentence opener — natural, matches house tone.]\n\nChecking in on [matter name]. A few items:\n\n1. **Status since [date of last update captured in history.md]** — what's moved, what's pending? Any filings, hearings, correspondence, or calls since we last touched base?\n\n2. **Upcoming deadlines** — I show [next_deadline from log + any deadlines in matter.md]. Confirm coverage plan and any dates we should add.\n\n3. **Decisions pending** — [pull open questions from matter.md that require OC input; if none, omit this numbered item and renumber]\n\n4. **Budget** — [monthly / quarterly / on-request per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) budget posture]. Where are we against [budget authorization from matter.md]? Any variance to flag?\n\n[If material and relevant: 5. Specific ask — e.g., \"Please send me the latest draft of the motion to dismiss before [date]\" — drawn from matter.md open questions.]\n\n[Signoff — name, role, contact. From your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) signer default for OC directives.]\n```\n\nAdapt tone per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) outside counsel directive style — some shops are \"dear counsel\" formal; others are first-name-and-bullets. Match.\n\n## Output\n\n### Markdown drafts\n\nWrite to: the current project's documents\n\nEach file is one email, formatted as:\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# [Matter name] — OC status request — [YYYY-MM-DD]\n\n**To:** [outside_counsel.email from log] ([outside_counsel.lead], [outside_counsel.firm])\n**From:** [signer name / email from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n**Subject:** [subject line]\n\n> The work-product header above applies to this internal record. The outgoing email body below goes to outside counsel on a retained matter, which is itself a privileged communication — apply the house privilege marking (your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) privilege conventions) at the top of the email sent, typically `Privileged & Confidential — Attorney-Client Communication / Attorney Work Product`, not this internal work-product header.\n\n---\n\n[body per skeleton]\n```\n\n### Send gate (closing note on every draft)\n\nAppend the following to each markdown draft, immediately below the body and above the run metadata — strip before sending:\n\n> This is a draft status email for attorney review before sending to outside counsel. Check for privileged content you did not intend to share outside the engagement circle, factual accuracy, tone, and budget posture. Do not send unreviewed — even routine weekly check-ins can surface theory, strategy, or concessions the sender didn't mean to put in writing.\n\n### Gmail drafts (if MCP available)\n\nIf the Gmail draft-creation MCP is authenticated:\n\n- Create a draft in the user's Gmail per matter with `to`, `from`, `subject`, `body` populated\n- The draft sits in Drafts folder; user reviews and sends Monday morning\n- If Gmail MCP is NOT available or fails: fall back to markdown-only and tell the user\n\n### Run summary\n\nAfter processing all matters, write the current project's documents:\n\n```markdown\n# OC Status Run — [YYYY-MM-DD]\n\n**Matters processed:** [N]\n**Drafts created:** [N]\n**Gmail drafts:** [created / skipped — reason]\n\n## Drafted for\n\n| Matter | OC lead | Last updated | Reason for inclusion |\n|---|---|---|---|\n| [slug] | [lead] | [date] | [stale / upcoming deadline / --all / --slug] |\n\n## Skipped\n\n| Matter | Reason |\n|---|---|\n| [slug] | recent update (last touched [date]) |\n| [slug] | no OC email in log — update with `/matter-update [slug]` |\n\n## Anomalies\n\n- Matters without outside counsel assigned: [list — if any are high/critical risk, flagged]\n- Matters with outside counsel but no email in log: [list]\n```\n\n## Scheduling\n\nThis skill is designed to run weekly. Automated scheduling requires a scheduled-tasks integration that is not bundled with the plugin. To run weekly, set a recurring reminder to invoke `the “Oc Status” workflow` — e.g., Monday morning on your calendar.\n\nAd-hoc: `/oc-status` any time. `/oc-status --slug=foo` for a single matter.\n\n## What this skill does not do\n\n- **Send the emails.** Drafts only. Counsel reviews and sends.\n- **Generate content it doesn't have.** If `matter.md` is thin, the email is short and asks broad-status questions. The skill doesn't invent specific questions from nothing.\n- **Retry failures.** If Gmail draft creation fails mid-run, the skill logs the failure and continues with markdown. User can retry after fixing auth.\n- **Rewrite history.md.** Reads it for context; doesn't modify. (If OC's response surfaces new events, use `/matter-update [slug]` to log them.)\n- **Enforce a minimum template.** If the house tone is \"one line, first name, done,\" the draft honors that and skips the bulleted structure. Match your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).", + }, + { + id: "builtin-cfl-litigation-portfolio-status", + title: "Portfolio Status", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “portfolio-status” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /portfolio-status\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → risk calibration (defines how to read the `risk:` field).\n2. Follow the workflow and reference below.\n3. Parse the current project's documents. Filter closed matters by default (include with `--all`).\n4. Produce rollup: risk distribution, deadlines in next 14/30/60 days, matters with no update in >30 days, materiality totals, stage distribution.\n5. Flag anomalies — everything marked critical, overdue next_deadline, matters without outside counsel assigned where risk is medium or high.\n\n---\n\n# Portfolio Status\n\n## Purpose\n\nOne read that answers: what do I own right now, what needs attention, and what's slipping? Output is scannable — designed for a counsel who has three minutes before their next call.\n\n## Load context\n\n- the current project's documents — source of truth\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — risk calibration (to interpret risk/materiality fields correctly)\n\n## Flags & filters\n\nDefault: active matters only (exclude `status: closed`).\n\nFlags:\n- `--all` — include closed\n- `--risk=high` (or `critical` / `medium` / `low`) — filter by risk band\n- `--stale` — only matters with `last_updated` > 30 days\n- `--type=employment` — filter by matter type\n- `--owner=[name]` — filter by business/HR/comms owner\n\n## The rollup\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# Portfolio Status — [today]\n\n**Active matters:** [N]\n**Closed (ytd):** [N] *(shown only with --all)*\n\n---\n\n## By risk\n\n| Risk | Count | Matters |\n|---|---|---|\n| Critical | [N] | [slugs] |\n| High | [N] | [slugs] |\n| Medium | [N] | [count only — expand with `--risk=medium`] |\n| Low | [N] | [count only] |\n\n## Upcoming deadlines\n\n| Within | Matters |\n|---|---|\n| 14 days | [slug — deadline — brief] |\n| 15–30 days | [...] |\n| 31–60 days | [...] |\n\n*Overdue `next_deadline` flagged separately below.*\n\n## Materiality\n\n| Category | Count | Total exposure (midpoint) |\n|---|---|---|\n| Reserved | [N] | [$X] |\n| Disclosed | [N] | [$X] |\n| Monitored | [N] | — |\n| None | [N] | — |\n\n## By stage\n\n[table: pleadings / discovery / dispositive motions / trial prep / settlement / appeal]\n\n---\n\n## ⚠️ Anomalies & flags\n\n- **Overdue deadlines:** [list slugs where next_deadline has passed]\n- **Stale (>30d no update):** [list]\n- **Conflicts unresolved:** [list slugs with `conflicts.status in [pending, not-run]`]\n- **Conflicts bypassed (override active):** [list slugs where `conflicts.override.by` is populated — permanent flag until manually cleared]\n- **High/critical risk without outside counsel:** [list]\n- **Reserved without last_updated in >60d:** [list] — reserve recalibration likely overdue\n- **Hold not issued on active litigation:** [list]\n- **Missing fields:** [slug → field]\n\n---\n\n## Closing advice\n\n[One or two sentences on what to look at first, if anything stands out. Not boilerplate — only if something truly stands out.]\n```\n\n## Anomaly rules\n\nThese are the checks that make the skill useful rather than decorative:\n\n1. **Overdue deadline:** `next_deadline < today` and `status != closed`\n2. **Stale:** `last_updated < today - 30d` and `status != closed`\n3. **Conflicts unresolved:** `conflicts.status in [pending, not-run]` and `status != closed`\n3b. **Conflicts override active:** `conflicts.override.by != null` (never auto-clears)\n4. **High-risk uncovered:** `risk in [high, critical]` and `outside_counsel.firm == null`\n5. **Stale reserve:** `materiality == reserved` and `last_updated < today - 60d`\n6. **Hold gap:** `status in [threatened, active, discovery, trial, appeal]` and `legal_hold.issued == false` — preservation duty attaches at reasonable anticipation, so `threatened` matters are in scope.\n7. **Missing fields:** any required field null — `risk`, `materiality`, `status`, `opened`, `conflicts.status`\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\nIf the portfolio has more than ~10 matters, or any time the user asks: offer the dashboard (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs → Dashboard offer for data-heavy outputs`). Shape the offer for this output — counts by risk tier, a timeline of upcoming deadlines, and a sortable matter ledger with status, conflicts check, and last-touched date.\n\n## What this skill does not do\n\n- Make decisions. It surfaces what needs attention; the user decides priority.\n- Pretend precision it doesn't have. Exposure midpoints are rough and should be labeled so.\n- Replace a real MMS. This is a working-memory rollup, not a system of record.", + }, + { + id: "builtin-cfl-litigation-privilege-log-review", + title: "Privilege Log Review", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “privilege-log-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /privilege-log-review\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → review protocol, priv log format.\n2. Follow the workflow and reference below.\n3. For each entry: obvious priv / obvious not priv / needs attorney review. Flag reasons.\n4. Output: reviewed log with flags. Attorney reviews all flags before production.\n\n---\n\n# Privilege Log Review\n\n## Disclosed-document use restrictions\n\nBefore working with a set of litigation documents, ask: \"Were any of these documents obtained through disclosure or discovery in legal proceedings?\" If yes:\n\n- **England & Wales (CPR 31.22):** Documents obtained through disclosure are subject to the implied undertaking — you may only use them for the purpose of the proceedings in which they were disclosed, unless the court grants permission, the disclosing party consents, or the document has been read in open court. Using them for a different matter, a different claim, or a commercial purpose without permission is a contempt.\n- **US:** Protective orders and Rule 26(c) may impose similar restrictions. Check the order.\n- **Other jurisdictions:** Similar restrictions commonly apply. Check the local rule.\n\nConfirm: \"This use is within the proceedings in which the documents were disclosed, or I have permission / consent, or the documents are now public.\" If not confirmed, flag it: \"⚠️ Disclosed documents may have use restrictions. Confirm this use is permitted before proceeding.\"\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). For litigation-legal the default is `Enabled: ✓` — every case gets its own matter workspace. If `Enabled` is `✗` (you turned it off because you work one case at a time), skip the rest of this paragraph and use practice-level context. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nA privilege log has three kinds of entries: obviously privileged, obviously not, and the ones that need thought. This skill sorts the first two kinds so the attorney's time goes entirely to the third.\n\n**This is first pass. Attorney reviews every flag. No exceptions.**\n\n## Record fidelity — pinpoints and citation coverage\n\nWhen this skill cites a rule, local variant, or authority for a privilege call (FRCP 26(b)(5)(A), state rule, local rule, case on waiver scope, case on dominant purpose), two rules apply.\n\n**Pinpoint cites must support the whole proposition.** If the review cites one rule or case to support a multi-part proposition — \"the log must describe each document and withhold only materials prepared in anticipation of litigation\" — verify the pinpoint covers every element. If it only covers one, split the cite or narrow the proposition. A cite that backs part of a privilege position gets the position rejected when opposing counsel reads the cite and points out it doesn't reach the contested element. This is the \"misgrounded citation\" failure mode: the cite exists, the passage exists, but it doesn't support the proposition as stated.\n\n**Extract all citations before checking any.** When this review cites authority — or when a separate citation-check is requested on the log, a related brief, or the supporting motion:\n\n1. **First pass: extract.** Read the document and build a list of every citation (rules, cases, statutes, local orders, record cites). Report the count: \"Found [N] citations.\"\n2. **Second pass: check.** Check each against the source. Don't sample. Don't stop at the first five.\n3. **Report coverage.** \"Checked [N] of [M] citations. [K] could not be retrieved — verify manually. [J] confirmed. [I] flagged as potential miscitations. [H] flagged as misgrounded (cite exists but doesn't support the proposition).\"\n4. **When source text is unavailable, say \"could not check,\" never \"confirmed.\"** A false positive is worse than a \"couldn't check\" — it lets a bad cite through.\n5. **The hardest errors are partial support.** Read the proposition, read the source, compare element by element.\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → privilege log format, review protocol.\n\n**Conflicts gate — unbypassable.** Before reviewing a privilege log, check the current project's documents for the matter slug. If the matter is not in `_log.yaml`, refuse and route:\n\n> \"I don't see [matter slug] in the matter log. Run `the “Matter Intake” workflow` first so the conflicts check runs and the matter workspace is set up. I won't review a privilege log on a matter that hasn't been intaken — the conflicts check is the gate, and a privilege log review is work product that needs to live in the matter file.\"\n\n**Jurisdiction matters.** Privilege scope (A/C and work product), waiver doctrine, and log-form requirements vary materially across federal circuits and state courts. This review applies the rules for the forum specified in config. If the matter involves a different forum, a transferred case, multi-jurisdictional production, or a choice-of-law question on privilege, the calls here may not transfer — re-run against the controlling forum.\n\n## Step 0: Research the forum's privilege-log rules\n\n**Before reviewing entries, research the forum's privilege-log requirements (FRCP 26(b)(5)(A) or state equivalent), any local rule variant, and the judge's standing orders. Identify the required fields, the level of description, and any category-log or metadata-log accommodations. Cite primary sources.**\n\n**No silent supplement.** If a research query to the configured legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or firm platform) returns few or no results for the forum's rule, waiver doctrine, or local variant, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / doctrine]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) leave the `[UNCERTAIN]` marker and stop here. Which would you like?\" A lawyer decides whether to accept lower-confidence sources; the skill does not decide for them.\n\n**Source attribution.** Tag every rule reference and authority in the review output with where it came from: `[Westlaw]`, `[CourtListener]`, `[Trellis]`, `[Descrybe]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the reviewing attorney supplied. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags — they are the reviewing attorney's signal about which authorities to re-confirm before service.\n\n**Waiver doctrine differs by privilege type:**\n\n- **Attorney-client privilege waiver** is often broad: subject-matter waiver can sweep in related communications on the same topic.\n- **Work-product waiver** is narrower: courts typically distinguish opinion work product (stronger protection) from fact work product. Waiver of fact work product doesn't automatically waive opinion work product.\n\nConfirm the forum's waiver doctrine for each privilege claimed before recommending production of anything. `[UNCERTAIN]` flags stay on waiver calls until counsel confirms.\n\n## The calls\n\n**Three-state rule. The skill never silently decides a subjective threshold isn't met.** On any uncertain call — dominant purpose unclear, litigation contemplation borderline, mixed legal/business content, ambiguous third-party presence — the skill keeps the privilege designation on and adds a ⚠️ flag for the attorney. Under-marking waives privilege (one-way door); over-marking is corrected by the attorney in review (two-way door). Prefer the recoverable error.\n\n**In-house counsel privilege is jurisdiction-specific and contested.** Before classifying any communication with in-house counsel as privileged, check the jurisdiction:\n\n- **US:** In-house counsel communications are generally privileged when made for the purpose of obtaining or providing legal advice, and the attorney is acting in a legal (not business) capacity. The legal-vs-business distinction is fact-specific and contested.\n- **EU (competition / DG COMP proceedings):** Under *Akzo Nobel Chemicals v. Commission* (C-550/07 P), communications with in-house counsel are NOT privileged in EU competition proceedings. The CJEU held privilege applies only to communications with independent external lawyers. If the matter involves EU competition or state aid, in-house counsel documents are compellable.\n- **Germany (Syndikusanwalt):** The German Syndikusanwalt has a hybrid status. Privilege depends on the capacity in which the lawyer was acting and whether the communication is in the \"advocate\" or \"employee\" role. Post-2016 registration rules changed the analysis.\n- **UK:** In-house counsel privilege generally recognized, but the \"dominant purpose\" test applies, and the legal-vs-commercial advice distinction is scrutinized.\n- **France, Belgium, some other EU:** In-house lawyers may not be members of the bar, and their communications may have no privilege at all.\n\n**Never classify an in-house counsel communication as \"confidently privileged\" without stating which privilege regime applies.** If the matter involves non-US jurisdictions, especially EU competition or any EU regulator: \"Documents from in-house counsel may have NO privilege in [jurisdiction]. Under *Akzo Nobel*, in-house communications are compellable in EU competition proceedings. Flag for review by a [jurisdiction] litigation specialist before asserting privilege.\"\n\nThe ✅ \"confidently privileged, no flag\" tier below is the one designed to bypass attorney review. That's exactly where the *Akzo Nobel* risk lives. When the jurisdiction is non-US or the matter touches EU regulators, there is no ✅ tier for in-house communications — everything goes to 🟡 \"flag for attorney review with jurisdiction note.\"\n\n### Confidently privileged (✅) — keep designation, no flag\n\n- Communication between client and outside counsel seeking/providing legal advice, no third parties copied\n- Communication between client and in-house counsel, clearly legal (not business) advice, no third parties\n- Work product created in anticipation of litigation, by or for counsel\n- Communications within the control group about legal strategy\n\n### Uncertain — keep designation AND flag (✅ + ⚠️)\n\nThe default for anything that isn't confidently in ✅ or ❌. The skill does not withhold a privilege designation on its own assessment of a subjective test. Examples:\n\n- **In-house counsel doing both legal and business** — was this communication legal advice or business advice? The dominant-purpose call is the attorney's, not the skill's.\n- **Third party present** — is the third party within the privilege (common interest, agent) or does their presence waive? Keep the designation; flag for attorney.\n- **Mixed purpose documents** — part legal, part business. Partial redaction? Full withhold? Produce? Keep the designation; flag for attorney to decide the treatment.\n- **Attachments** — analyze separately and keep each attachment's designation unless confidently ❌; flag the ones where privilege turns on a subjective call.\n- **Pre-litigation work product** — \"reasonable contemplation of litigation\" is fact-specific; keep the designation; flag.\n- **Waiver risk** — later-share history is ambiguous; keep the designation; flag the waiver question.\n\nEach flag records the specific open question and the evidence cutting each way, so the attorney can decide without re-reading the document cold.\n\n### Confidently not privileged (❌) — recommend remove, but note the assessment\n\nOnly for the unambiguous cases. The output still records the assessment rationale so the attorney can spot-check; it does not remove the designation from the log on its own.\n\n- No attorney involved anywhere\n- Business advice with a lawyer CC'd (CC'ing legal doesn't make it privileged)\n- Underlying facts (facts aren't privileged — communications *about* facts can be)\n- Third party copied who's clearly outside privilege (breaks confidentiality)\n- Attachments that are independently non-privileged (the email might be privileged; the attached spreadsheet of sales numbers is not)\n\nIf any of these is *close* — the third party might be an agent, the lawyer's CC might actually be on a legal request — it's uncertain, not ❌. Route it to the uncertain bucket and flag.\n\n## Workflow\n\n### Step 1: Format check\n\nDoes the log have what it needs?\n\n| Field | Present? |\n|---|---|\n| Date | |\n| Author | |\n| Recipients (all — TO, CC, BCC) | |\n| Document type | |\n| Privilege claimed (A/C, WP, both) | |\n| Description (enough to assess without revealing privileged content) | |\n\nMissing fields → flag for completion before substantive review.\n\n### Step 2: Entry-by-entry\n\nFor each entry:\n\n```\nEntry [N] ([Bates]): [✅ Priv | ✅ Priv + ⚠️ Flag | ❌ Not priv (assessed)]\n[If ✅ (no flag): one-line reason]\n[If ✅ + ⚠️: keep designation; the specific question the attorney needs to answer; evidence cutting each way]\n[If ❌: one-line reason — but the designation stays on the log until the attorney removes it]\n```\n\n**Never produce an entry that silently strips a privilege designation based on the skill's own subjective call.** A ❌ is a recommendation logged alongside the flag; the attorney acts on it.\n\n### Step 3: Pattern flags\n\nAcross the log:\n\n- Same issue repeating? (E.g., same third party on 50 entries — one decision resolves 50 flags)\n- Over-designation pattern? (If everything's designated without differentiation, surface it for the attorney — but the call to narrow the log is the attorney's, not the skill's. Under-designation waives; over-designation is correctable.)\n- Under-description? (Descriptions so vague a court would order in camera review)\n\n## Output\n\n**Before the privilege log is served on the opposing party (the consequential act — this includes serving the log AND designating documents withheld or produced under a protective-order designation such as Confidential / Highly Confidential / AEO):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Submitting a privilege log and designating documents in discovery both have legal consequences — over-designation risks sanctions and loss of credibility; under-designation risks waiver; a misdesignated production may be unrecallable. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the matter, log entry counts, the ⚠️ flags and close calls, pattern observations (over-designation, vague descriptions), waiver-doctrine posture by privilege type, what could go wrong on service or designation, what to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not treat the log as service-ready without an explicit yes. First-pass review, sorting, and flagging do not require the gate — service and designation do.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Privilege Log Review: [Matter] — [date]\n\n**Applicable rule:** [FRCP 26(b)(5)(A) / state rule / local rule / standing order — pinpoint cites] `[UNCERTAIN — verify currency]`\n**Entries reviewed:** [N]\n**Results:** [N] ✅ confident priv / [N] ✅+⚠️ priv kept & flagged / [N] ❌ recommend remove (attorney confirms)\n\n### ✅ + ⚠️ Flagged — designation kept, attorney decides\n\n| Entry | Bates | Issue | Evidence for priv | Evidence against | Question |\n|---|---|---|---|---|---|\n| [N] | [range] | [what's subjective] | [one line] | [one line] | [the specific call to make] |\n\n### ❌ Recommend remove designation (attorney confirms before stripping)\n\n| Entry | Bates | Reason |\n|---|---|---|\n\n*Recorded, not executed. The skill does not remove privilege designations from the log — the attorney does, after reviewing the rationale.*\n\n### ✅ Privileged (no action)\n\n[Count. List available on request.]\n\n### Pattern observations\n\n[Repeating issues, over-designation, description problems]\n\n### Marker discipline\n\n- `[VERIFY: factual assertion about document/custodian/date]`\n- `[UNCERTAIN: close privilege call / waiver scope / doctrine question]`\n- `[CITE NEEDED: rule, local variant, or authority supporting a call]`\n\n---\n\n**Attorney must review all ⚠️ and ❌ before any action.**\n\n**Privileged source material.** This review reads entries and underlying documents that are, by definition, privilege-candidate material. The review output inherits that status — keep it with privileged materials, mark it appropriately, and don't circulate outside the privilege circle. Distributing it can itself waive protection.\n```\n\n## What this skill emphatically does not do\n\n- Make close calls. ⚠️ means \"a human decides.\" On any subjective test (dominant purpose, reasonable contemplation, common-interest scope, waiver by later sharing) the skill keeps the privilege designation on and flags.\n- Strip a privilege designation from the log based on its own assessment. ❌ is a *recommendation* recorded for the attorney, not an action taken against the log.\n- Produce or withhold documents. It advises; attorney decides; attorney acts.\n- Guarantee correctness on ✅ calls. The attorney is responsible for the log. This is a first pass.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-litigation-subpoena-triage", + title: "Subpoena Triage", + practice: "Litigation", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “subpoena-triage” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /subpoena-triage\n\n1. Read the subpoena from provided path.\n2. Classify (third-party-docs / third-party-depo / party / CID / grand-jury).\n3. If grand jury → stop, escalate per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Otherwise continue.\n4. Load the current project's documents for cross-check. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → landscape, privilege conventions, escalation norms.\n5. Follow the workflow and reference below.\n6. Extract key fields, analyze scope/burden/privilege, produce objections framework + compliance plan + deadline calendar.\n7. Write the current project's documents. Copy or link subpoena to the current project's documents.\n8. Hand off: `/legal-hold --issue` if hold not in place; `/matter-intake` if materiality warrants; `/matter-briefing [slug]` if party subpoena in existing matter.\n\n---\n\n# Subpoena Triage\n\n## Purpose\n\nSubpoenas arrive with deadlines. The failure modes: missing the deadline, over-producing (privilege waiver, burden we should have objected to), under-producing (contempt exposure), or missing a motion-to-quash window. This skill classifies, analyzes, and produces a compliance plan with objections framework.\n\n## Jurisdiction assumption\n\nThe rule cited in Step 0 is the operative one for this subpoena in this forum. Subpoena practice varies materially: federal (FRCP 45) vs. state equivalents, state-to-state variants, local rules, court-specific standing orders, and the subpoena type (trial, deposition, document production) all change objection deadlines, place-of-compliance limits, privilege-log requirements, and cost-shifting. Every rule output here is a starting-point heuristic — confirm currency and the local variant before asserting in writing.\n\n## Side context\n\nThis skill is inherently defensive — a subpoena has been served on the recipient and the posture is respond/object/comply. Read `## Side` in the practice profile. If the user's default side is **plaintiff**, note that receiving a subpoena is common for plaintiffs too (witness subpoenas, third-party requests directed at the plaintiff's own records) but the framing here is always \"subpoena served on us, how do we respond.\" If the user is **defense** (typical), the framing aligns with the default. If the matter has a different posture than the default (e.g., defense practitioner receiving a subpoena in a matter where they're pro se for a family member), prompt the user to confirm posture before proceeding.\n\n## Load context\n\n- The subpoena document (user provides path or drops it in-session)\n- the current project's documents — for related matter lookup and legal hold status\n- your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → landscape (regulators we deal with), house privilege conventions, escalation norms\n\n## Workflow\n\n### Step 0: Research the applicable rule\n\n**Before analyzing this subpoena, research the applicable rule of civil procedure for the forum (FRCP 45 for federal, the state equivalent otherwise) and the subpoena type (trial, deposition, document production). Identify: place-of-compliance limits, objection deadlines (these often run from the EARLIER of the compliance date or a fixed number of days after service), privilege-log requirements, and who bears costs. Cite with pinpoint references. Verify currency — rules and local variants change. Flag grand-jury subpoenas for immediate criminal-counsel escalation.**\n\n**No silent supplement.** If a research query to the configured legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or firm platform) returns few or no results for the forum's rule, variant, or pinpoint, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [rule / forum / variant]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) stop here. Which would you like?\" A lawyer decides whether to accept lower-confidence sources; the skill does not decide for them.\n\n**Source attribution.** Tag every rule reference, case, statute, and regulation in the triage output with where it came from: `[Westlaw]`, `[CourtListener]`, `[Trellis]`, `[Descrybe]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for citations from web search; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the user supplied (e.g., from the subpoena or prior matter work). Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags — they are counsel's fastest signal about which citations to verify before asserting in objections or filings.\n\n### Step 1: Classify\n\nSubpoenas come in flavors with different rules; confirm the specifics against the rule you just researched:\n\n- **Third-party document subpoena (civil)** — we're not a party to the litigation; someone wants our documents. Usual objection categories: relevance, burden, privilege, place-of-compliance / geographic reach.\n- **Third-party deposition subpoena** — someone wants an employee to testify. Scope, relevance, burden; possible motion to quash; witness prep required.\n- **Party subpoena** — we ARE a party; this is discovery in a litigation we're tracking. Treat as discovery, not inbound — it should map to an existing matter.\n- **Regulatory civil investigative demand (CID)** — FTC, SEC, DOJ, state AG. Different rules, different posture; often more deferential but also more consequential.\n- **Grand jury subpoena** — criminal. Escalate immediately to criminal counsel; different skill path (outside this skill's scope — flag for escalation).\n\n### Step 2: Extract key fields\n\n- **Issuing authority** — court (which), agency (which), counsel (if civil)\n- **Issuing party** — who requested (if civil)\n- **Case / matter caption** — the litigation we're being asked about\n- **Document categories sought** — numbered list\n- **Testimony topics** (if depo) — Rule 30(b)(6) designations\n- **Deadline for response/objection** — date served + computing the response window per applicable rule\n- **Production date** — date by which documents must be produced\n- **Geographic scope** — custodians, locations, systems implicated\n- **Custodian of record designation** — who at the company is the witness/signatory\n\n### Step 3: Portfolio cross-check\n\n- **Party subpoena → related to existing matter:** verify the caption matches a matter in `_log.yaml`. If yes, route to that matter's workflow; this triage is informational.\n- **Third-party subpoena → caption we don't recognize:** capture the parties; log as standalone inbound.\n- **Multiple subpoenas from same case:** flag coordinated issuance; a single response strategy may apply.\n\n### Step 4: Analyze scope, burden, privilege\n\n**Scope / relevance**\n- Do the categories map to actual documents we plausibly have?\n- Is any category a fishing expedition (overbroad, untethered to claims/defenses of the underlying case)?\n- Place of compliance / geographic reach — apply the researched rule; limits differ by subpoena type (trial vs. document vs. deposition).\n\n**Burden**\n- Custodians implicated, systems searched, time period\n- Estimated volume (rough: small / medium / large / extreme)\n- Cost — third-party responders may have cost-shifting available; check the researched rule.\n\n**Privilege**\n- Attorney-client or work product likely implicated? (Almost always yes for anything legal-related; often yes for communications involving in-house or outside counsel.)\n- Other privileges — trade secret, HIPAA (if applicable), state privilege, common interest\n- Privilege log will be required — flag the format per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)\n\n**Other objection grounds**\n- Confidentiality — protective order needed?\n- Duplicative — do they already have this from another party?\n- Not possessed — we don't have what they're asking for (document with specificity)\n- Improperly served — check the researched rule's service requirements\n\n### Step 5: Objections framework\n\nDraft a structured objections outline — not the final objections letter, but the outline of what objections apply and why. The user (often with outside counsel) finalizes.\n\nEach objection:\n- Legal basis — cite the pinpoint from the rule researched in Step 0\n- Specific application to this subpoena (which categories, which custodians)\n- Strength (strong / reasonable / weak)\n\n### Step 6: Compliance plan\n\nEven when objecting, we often produce some of what's requested. Plan:\n\n- **Scope of likely production** — after objections, what we'd produce\n- **Custodians to search** — names and systems\n- **Date range**\n- **Review protocol** — who reviews for privilege (us, outside counsel, contract reviewers)\n- **Production format** — per the subpoena or per negotiated protocol (TIFF+load file, native, PDF)\n- **Privilege log requirements** — format, fields\n\n### Step 7: Deadlines\n\nUse the deadlines identified in the Step 0 research. Note that objection deadlines often run from the EARLIER of the compliance date or a fixed number of days after service — do not default to a single number without checking the applicable rule and local variant.\n\n- **Response deadline** — per researched rule; note if user needs more time (meet-and-confer to extend is standard)\n- **Objection deadline** — per researched rule (federal / state rule + any local variant)\n- **Production date** — if no objections succeed\n- **Motion to quash window** — if pursuing that path, timing is critical\n\nCalendar all of them. Immediate action item.\n\n### Step 8: Write triage\n\nOutput: the current project's documents.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n# Subpoena Triage\n\n> **NOT A SUBSTITUTE FOR OUTSIDE COUNSEL.** This is a structured classification and scoping read to support fast decisions on deadlines, holds, and engagement. Every rule reference is a starting-point heuristic; jurisdiction-specific analysis, objections finalization, motions practice, and merit calls on privilege require licensed counsel familiar with the forum. Engage outside counsel for any subpoena above routine third-party document scope.\n\n**Slug:** [slug]\n**Served:** [YYYY-MM-DD]\n**Served on:** [entity / registered agent]\n**Incoming file:** [path]\n**Classification:** [third-party-docs / third-party-depo / party / CID / grand-jury]\n\n---\n\n## Key fields\n\n- **Issuing authority:** [court/agency]\n- **Issuing party:** [name]\n- **Case caption:** [caption]\n- **Response deadline:** [date]\n- **Production date:** [date]\n- **Motion-to-quash window:** [date range]\n\n## Categories sought (summary)\n\n[numbered list, concise]\n\n## Custodians / systems likely implicated\n\n[list]\n\n---\n\n## Portfolio cross-check\n\n**Related matter:** [slug or \"none\"]\n**If party subpoena:** [routed to existing matter or new matter?]\n**If third-party:** [standalone inbound]\n\n---\n\n## Scope & burden analysis\n\n**Scope:** [relevance assessment by category]\n**Burden estimate:** [small / medium / large / extreme — with reasoning]\n**Geographic reach issues:** [any]\n\n## Privilege analysis\n\n*Privilege scoping is a first-pass read; final call is counsel's, not this skill's.*\n\n**Attorney-client / work product likely implicated:** [yes/no + which categories] `[SME VERIFY]`\n**Other privileges:** [trade secret, HIPAA, state, common interest] `[SME VERIFY]`\n**Privilege log format required:** [per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)]\n\n---\n\n## Objections framework\n\n*Every row below requires `[SME VERIFY]` before asserting in writing — jurisdiction, rule currency, waiver risk.*\n\n| Objection | Legal basis | Applies to | Strength | SME verified? |\n|---|---|---|---|---|\n| Relevance | [rule] | [categories] | [strong/reasonable/weak] | [ ] |\n| Burden | [rule] | [categories] | | [ ] |\n| Privilege | A/C, WP | [all producing docs] | strong (always) | [ ] |\n| Duplicative | [rule/doctrine] | [if applicable] | | [ ] |\n| [other] | | | | [ ] |\n\n---\n\n## Compliance plan (if responding)\n\n- **Scope of likely production:** [after objections]\n- **Custodians / systems:** [list]\n- **Date range:** [range]\n- **Review protocol:** [who, how]\n- **Production format:** [format]\n- **Privilege log:** [format, est. entries]\n\n---\n\n## Deadlines (calendar these)\n\n*All deadlines below come from the Step 0 rule research. `[SME VERIFY]` confirms the rule, variant, and computation for this forum and this subpoena type — state variants and local rules differ.*\n\n- **Response deadline:** [date] `[SME VERIFY]`\n- **Objection deadline:** [date] — cite: [rule + pinpoint] `[SME VERIFY]`\n- **Meet-and-confer by:** [date] (typically before objection deadline) `[SME VERIFY]`\n- **Production date:** [date]\n\n---\n\n## Immediate actions\n\n- [ ] Legal hold issued — [yes/no] — if no, run `/legal-hold [slug] --issue` with subpoena scope\n- [ ] Outside counsel engaged — [yes/who/TBD]\n- [ ] Meet-and-confer scheduled — [date]\n- [ ] Matter created in log — [yes/no/TBD — usually yes for anything above the smallest third-party docs subpoena]\n- [ ] Insurance / cost-shifting analysis — [if burden is large]\n- [ ] Internal escalation — [who]\n\n---\n\n## Recommendation\n\n[Two paragraphs: what to do. Objection posture. Production posture. Whether outside counsel handles objections or we do. Whether to move to quash.]\n\n---\n\n## Citation verification\n\nEvery rule reference, case, statute, and regulation in this triage — including the Step 0 research citations, objection bases, and the privilege-log format pointer — is AI-generated and unverified. Before relying on any cite (especially in objections, a motion to quash, or correspondence with the issuing party), run a verification pass against a legal research tool (Westlaw, CourtListener, Trellis, Descrybe, or your firm's platform) for accuracy, good law status, and local variants. Fabricated or misquoted citations in filed documents have resulted in sanctions. Source tags on each citation (e.g., `[Westlaw]`, `[web search — verify]`) show where it came from; `verify` tags carry higher fabrication risk and should be checked first.\n```\n\n### Step 9: Hand off\n\n**Before responding to the subpoena (serving objections, producing documents, appearing for deposition, or filing a motion to quash — any substantive response to the issuing party or court):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Responding to a subpoena has legal consequences — missing a deadline risks contempt, over-producing waives privilege, under-producing risks sanctions. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: the subpoena type, issuing authority, deadlines, scope of what's sought, objections framework and strength, privilege and burden issues, proposed response posture, what could go wrong, what to ask the attorney.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes. Triage, scoping, and internal calendaring do not require the gate — the response to the issuing authority does.\n\n- If classified as **grand jury subpoena** → stop, flag for escalation per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), do not proceed with standard triage.\n- If classified as **CID**: flag that regulator-specific norms apply; recommend outside regulatory counsel.\n- Otherwise: offer to create a matter (usually yes — subpoenas are almost always material enough to track).\n- If a legal hold isn't issued with subpoena scope, hand off to `/legal-hold --issue` immediately.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- **Draft the final objections letter.** Produces the framework; the letter is drafted by user + outside counsel (future: a dedicated objections-draft skill).\n- **Move to quash.** Surfaces the option; the motion is legal work that requires jurisdiction-specific analysis.\n- **Validate rules across jurisdictions.** The Step 0 research produces the operative rule for this subpoena; the skill doesn't independently confirm currency or local variants. Flag for counsel verification before acting.\n- **Handle grand jury subpoenas.** Escalates. This is outside the triage scope.", + }, + { + id: "builtin-cfl-privacy-dpa-review", + title: "DPA Review", + practice: "Privacy & Data Protection", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “dpa-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /dpa-review\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → DPA playbook. If placeholders, stop and prompt setup.\n2. Get the DPA. Determine direction: are we processor (customer's DPA) or controller (vendor's)? Ask if ambiguous.\n3. Run the workflow below — term-by-term against the appropriate playbook row.\n4. Run privacy policy consistency check.\n5. Output: review memo with redlines. Save per house style.\n\n```\nthe “DPA Review” workflow customer-dpa.pdf\n```\n\n---\n\n# DPA Review\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nDPAs come in two flavors and the review is nearly opposite for each. When a customer sends their DPA, we're defending our operational flexibility. When we send one to a vendor, we're protecting our (and our customers') data. Both reviews read from the same your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) playbook but from opposite rows.\n\n## First: which direction?\n\nBefore anything else, establish:\n\n- **We are the processor** → customer is sending us their DPA → read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → \"When we are the processor\" table\n- **We are the controller** → we're sending a DPA to a vendor (or reviewing theirs) → read \"When we are the controller\" table\n\nIf unclear, ask. Getting this wrong inverts every recommendation.\n\n## Jurisdiction assumption\n\nThis review assumes the jurisdictional scope specified in your configuration. Privacy rules, response deadlines, and lawful bases vary materially by jurisdiction (GDPR vs. state consumer privacy laws vs. sectoral). If the controller, processor, or data subjects are in a different jurisdiction than configured, this review may not apply as written.\n\n## Load prior context on this counterparty / activity\n\nBefore reviewing, check the outputs folder for prior work on this counterparty or processing activity. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` for the outputs folder path. Scan for:\n\n- **Prior `use-case-triage` results** for the same counterparty / processing activity — the triage produces a risk rating and conditions that this DPA review should honor or explicitly depart from.\n- **Prior `pia-generation` outputs** covering this counterparty / processing activity — the PIA may have flagged risk mitigations the DPA needs to implement.\n- **Prior `dpa-review` outputs** for the same counterparty — earlier DPA reviews set expectations about what was acceptable, what was flagged, and what was settled. A fresh review that silently contradicts the earlier one erodes trust in the work product.\n\nIf a prior output is found, cite it in the review:\n\n> \"Prior triage ([date]) rated this [risk level] and conditioned approval on [X]. This DPA review is consistent with that finding.\" — or —\n> \"Prior triage ([date]) rated this [risk level]. This DPA review departs from that finding because [reason — new facts, different scope, contract term that changed the picture].\"\n\n**Carry severity from the upstream output as a floor** per the cross-skill severity floor rule in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Shared guardrails`. A processing activity the triage rated 🔴 cannot be quietly downgraded to 🟢 in the DPA review; any demotion is stated and explained.\n\nIf no prior output is found (new counterparty / new activity), say so explicitly in the review — \"No prior triage or PIA on this counterparty in outputs folder\" — so the reviewing attorney knows the check ran.\n\n## Load the playbook\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## DPA playbook`. Also read `## Privacy policy commitments` — the DPA can't contradict what the privacy policy promises.\n\n## Federal sectoral overlay (ask first, before the term-by-term walk)\n\nBefore walking the term-by-term review, answer: **does the data flowing through this DPA include any federally-regulated category?** GDPR and state consumer-privacy law supply one floor; federal sectoral law often supplies another that does not appear in the generic DPA playbook. A DPA that is GDPR-complete can still be GLBA-blind, HIPAA-blind, or COPPA-blind, and a fintech / healthtech / edtech / kidtech counterparty will notice.\n\n> **Activity-based federal overlays — ask first:**\n>\n> Does this processing touch:\n> - **Financial account data or \"nonpublic personal information\" about consumers** (GLBA / Reg P)? If yes, the DPA needs: (a) an NPI-sharing restriction consistent with 15 U.S.C. § 6802(a)-(c) and Reg P (no sharing for marketing to non-affiliated third parties without opt-out / opt-in), (b) safeguards language aligned with the Safeguards Rule (16 C.F.R. Part 314), (c) incident notification that reaches FTC/OCC timing where applicable, (d) a clean carve-out so a CCPA § 1798.145(e) exemption doesn't accidentally waive GLBA-level obligations.\n> - **Protected health information held by a covered entity or business associate** (HIPAA Privacy / Security Rules)? If yes, the DPA needs: a Business Associate Agreement (BAA) layered with or integrated into the DPA per 45 C.F.R. § 164.504(e), breach notification timing aligned with HITECH (60 days to CE; CE 60 days to HHS; 500+ threshold for media), permitted-uses clause, subcontractor BAA flow-down. A commercial DPA without BAA flow-down for PHI is a defect.\n> - **Education records held by a school or a service provider acting for a school** (FERPA)? If yes, the DPA needs: a \"school official\" / directory-information framing consistent with 34 C.F.R. § 99.31, parental-consent flow-through, state student-privacy analog handling (NY Ed Law 2-d, CA SOPIPA, IL SOPPA).\n> - **Data from children under 13 collected by an operator of an online service directed to children or with actual knowledge** (COPPA)? If yes, the DPA needs: verifiable-parental-consent flow-through, retention limits, deletion-on-request machinery, prohibition on behavioral advertising absent VPC.\n> - **Another sectoral federal regime** (VPPA for video-viewing records, CPNI for carrier data, DPPA for DMV records, TCPA / Shaken-Stir for call/SMS, GLBA Reg S-P for broker-dealers, §5 FTC Act for unfair/deceptive practices around sensitive data)?\n>\n> If yes to any: the federal overlay usually supplies the controlling substantive restriction, not just an exemption from a state consumer privacy law. Research the currently-operative provision and cite it. A DPA that is \"exempt\" from CCPA under § 1798.145(e) because it is GLBA-covered is still subject to the GLBA restrictions — the CCPA exemption moves the governing framework, it doesn't eliminate it. Flag sectoral gaps in the deal-breakers list alongside GDPR / state-privacy gaps.\n\nIf no sectoral overlay applies, note that explicitly — \"no federally-regulated data categories identified; sectoral overlay n/a\" — so the reviewing attorney sees that the check happened, rather than wondering whether it was skipped.\n\n## The term-by-term review\n\n### Core terms (check every DPA)\n\nWalk every DPA through these terms, clause by clause. The *specific* numeric and substantive positions (notice periods, breach timelines, acceptable/unacceptable floors) come from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## DPA playbook`. The regulatory floors that any DPA has to clear come from primary law — **research the currently operative rule** for each applicable regime and cite primary sources before stating a floor.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for a regime's breach window, transfer-mechanism requirement, subprocessor-change rule, or any other floor, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / topic]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution tiering.** Tag every citation in the review — regulatory floors, SCC versions, adequacy decisions, regulator guidance, case law — with its source. For model-knowledge citations, use one of three tiers rather than a single blanket \"verify\" tag:\n>\n> - `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., GDPR Art. 28, Art. 33 72-hour breach notice, SCC Decision 2021/914 by number). Still verify before filing, but lower priority.\n> - `[verify]` — model-knowledge citations that are real but should be verified: specific implementing regulations, regulator guidance, case holdings, adequacy decisions, SCC modules and versions, UK Addendum / IDTA status, thresholds, effective dates.\n> - `[verify-pinpoint]` — pinpoint citations (specific subsection letters, clause numbers within SCCs, paragraph numbers, volume/page references) carry the highest fabrication risk and should ALWAYS be verified against a primary source.\n>\n> Tool-retrieved citations keep their source tag (`[Westlaw]`, `[Commission / regulator site]`, or the MCP tool name); web-search citations remain `[web search — verify]`; user-supplied citations remain `[user provided]`. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n\n| Term | Looking for | Playbook field | Common fights |\n|---|---|---|---|\n| **Roles** | Clear controller/processor designation; matches reality | — | Counterparty labels the relationship (e.g., \"joint controller\") in a way that doesn't match reality |\n| **Processing scope** | Limited to documented instructions; defined purposes | — | Open-ended scope expanders (\"and related purposes\") |\n| **Subprocessors** | Current list disclosed, change mechanism defined | Subprocessor changes | Blanket approval vs. veto vs. notice-only |\n| **Security measures** | Annex references specific controls or standards | Security standards | \"appropriate technical and organizational measures\" with no annex = empty promise |\n| **Breach notification** | Defined trigger (\"discovery\" vs \"confirmation\"), defined timeline | Breach notification | Timeline tightness; clock trigger; \"without undue delay\" is vague |\n| **Audit rights** | Method (report vs. on-site), frequency, notice, cost allocation | Audit rights | On-site audits on tight notice |\n| **International transfers** | Transfer mechanism identified, supplementary measures, transfer impact assessment reference | Transfers | Outdated or missing transfer mechanisms |\n| **Deletion/return** | Timeline post-termination, certification, backup carveout | Deletion on termination | \"Commercially reasonable\" deletion = ??? |\n| **Liability** | Within MSA cap or separate; carveouts | Liability for data | Uncapped data breach liability = existential |\n\n### When we're the processor: defensive review\n\nCustomer DPAs try to push operational burden onto us. For each clause below, compare the customer's ask to the playbook. Where the customer's ask is outside the playbook, push back to the team's standard position (from the config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)) and be ready to fall back to the acceptable position.\n\n| Clause | Risk | Research / playbook lookup |\n|---|---|---|\n| Subprocessor approval right (veto) | Can't add infrastructure without customer-by-customer approval | Apply playbook position on subprocessor changes |\n| On-site audit on short notice | Unworkable at scale | Apply playbook position on audit rights |\n| Aggressive breach notification window | Often demands notice before we know what happened | Research the regulatory floor for each applicable regime (cite primary sources); compare to playbook position |\n| Hard data residency (single country/DC) | May not match architecture | Apply playbook position on data location; confirm what we can actually commit to |\n| Processor liability uncapped | Bet-the-company | Apply playbook position on liability for data |\n| Customer may issue binding \"instructions\" | Open-ended operational control | Define instructions as \"documented in the Agreement or agreed in writing\" |\n| Deletion on very short timeline | Backup and log retention makes this impossible | Apply playbook position on deletion on termination; document backup rotation carveout |\n\n### When we're the controller: protective review\n\nVendor DPAs try to give us nothing. For each clause below, compare to the controller-side playbook.\n\n| Clause | Gap | Research / playbook lookup |\n|---|---|---|\n| No subprocessor list | Don't know who touches our data | Require published current list + advance notice per playbook |\n| \"Industry standard security\" | Means nothing | Require annex with specific controls, or reference to a named standard (e.g., SOC 2, ISO 27001) |\n| No breach notification timeline | They tell us whenever | Research applicable regulatory floor; require playbook position |\n| No audit rights at all | Can't verify anything | Require at minimum an independent audit report per playbook |\n| Vendor can use data for \"service improvement\" | Potential training on our data | Strike; processing limited to providing the service to us |\n| No international transfer mechanism | No lawful transfer mechanism | **Research the currently operative transfer mechanism** for the corridor in question (origin/destination jurisdictions, applicable regime, any adequacy decision, any supplementary measures). Cite primary sources and verify currency. |\n| No deletion commitment | Data lives forever | Require playbook position on deletion + certification on request |\n\n## Consistency check: privacy policy\n\nThe DPA you sign can't promise something the privacy policy doesn't cover, and vice versa.\n\n- If the DPA commits to processing only for purposes X, Y, Z — does the privacy policy list those purposes?\n- If the privacy policy says \"we never sell data\" — does any DPA clause look like a sale under CCPA?\n- If the privacy policy names specific subprocessor categories — does the DPA subprocessor list match?\n\nFlag mismatches. They're usually the privacy policy being stale, not the DPA being wrong, but someone needs to fix one of them.\n\n## Redline granularity\n\n**Edit at the smallest possible granularity.** A redline is a negotiation artifact, not a rewrite. Wholesale clause replacement signals \"we threw out your drafting\" — it's aggressive, it forces the counterparty to re-read the whole clause, and it discards the parts of their drafting that were fine. Surgical redlines — strike a word, insert a phrase, restructure a subclause — signal \"we have specific asks\" and are faster to read, understand, and accept.\n\nDefault to the smallest edit that achieves the playbook position:\n- Replace a **word** before a phrase. (\"twelve (12)\" → \"twenty-four (24)\")\n- Replace a **phrase** before a sentence. (\"paid by the Buyer\" → \"paid and payable by the Buyer\")\n- Restructure a **subclause** before replacing the sentence. (Add \"(a)\" and \"(b)\" to split a compound condition.)\n- Replace a **sentence** before replacing the clause.\n- Only replace a **whole clause** when the counterparty's version is so far from your position that surgical edits would be harder to read than a fresh draft — and when you do, say so in the transmittal: \"We've replaced §8.2 rather than marking it up because the changes were extensive. Happy to walk you through the delta.\"\n\nWhen in doubt, smaller. A client who receives a surgical redline trusts that you read carefully. A client who receives a wholesale replacement wonders whether you read at all.\n\n## Output\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n# DPA Review: [Counterparty]\n\n**Direction:** [We are processor / We are controller]\n**Reviewed:** [date]\n**Attached to:** [MSA / standalone]\n\n---\n\n## Bottom line\n\n[Two sentences. Can we sign? What has to change?]\n\n**Issues:** [N]🟢 [N]🟡 [N]🟠 [N]🔴\n\n---\n\n## Term-by-term\n\n[For each core term, use a standard deviation-memo format: what the\ncounterparty's DPA says, what our playbook says, the gap, the risk, and the\nproposed redline language. Keep each term to a short self-contained block so a\nreviewer can skim.]\n\n---\n\n## Privacy policy consistency\n\n[🟢 Consistent | 🟡 Flags: list]\n\n---\n\n## Recommended redlines\n\n[Consolidated — ready to send back]\n\n---\n\n## If they won't move\n\n[For each issue: the fallback from the config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), or escalation routing if no\nfallback exists]\n```\n\n## International transfers note\n\nIf the DPA contemplates cross-border data transfers, **research the currently operative transfer mechanism requirements** for the applicable corridor(s). For each origin/destination pair, identify: the applicable regime, whether any adequacy decision is in force, which transfer mechanism is required or available (e.g., Standard Contractual Clauses and their applicable version/module, UK Addendum or IDTA, BCRs, derogations), whether a transfer impact assessment or equivalent is required, and what supplementary measures may be needed. Cite primary sources (regulation, Commission decision, regulator guidance, controlling case law) with pinpoint cites and verify currency — adequacy decisions, SCC versions, and required supplementary measures change through new Commission decisions, court rulings, and regulator guidance. Flag uncertainty for attorney verification.\n\nIf a transfer mechanism is missing and there is an international transfer, that is a 🔴 — there is no lawful transfer mechanism.\n\n## Gate: signing a DPA\n\nReviewing a DPA is research. *Signing* it — or instructing someone to countersign on our behalf — is the consequential act.\n\n**Before proceeding to sign or countersign a DPA (including returning an executed version, consenting to automatic execution on a counterparty platform, or instructing a signatory to execute):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Signing a DPA is a legal act — it binds the company to specific data-protection obligations that flow to regulators and data subjects. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: counterparty, direction (we are processor / controller), the terms that deviate from the playbook and how they were resolved, any open fallback decisions, and the three things to ask the attorney before executing.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't draft a DPA from scratch. If the answer is \"use our template,\" pull the template from the seed docs path in the config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n- It doesn't do the Transfer Impact Assessment itself — it flags when one is needed.\n- It doesn't decide whether to accept terms outside the fallbacks. It routes those per the escalation table.", + }, + { + id: "builtin-cfl-privacy-dsar-response", + title: "DSAR Response", + practice: "Privacy & Data Protection", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “dsar-response” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /dsar-response\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → DSAR process (systems list, verification method, SLA).\n2. Run the workflow below.\n3. Classify request type. Check escalation triggers — if any fire, route before proceeding.\n4. Walk through: verify identity → walk systems list → exemption analysis → draft.\n5. Output response draft. Do NOT send — human reviews and sends.\n6. Log the DSAR per house process.\n\n**Before pasting the request:** the request will contain the data subject's PII. Confirm your session and output storage meet your data-handling requirements. Redact anything you don't need (ID attachments, unrelated email threads). Do not store the subject's name in filenames.\n\n```\nthe “DSAR Response” workflow\n[paste the request email]\n```\n\n---\n\n# DSAR Response Drafting\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nA DSAR has a deadline (set by the applicable regime), a process (verify, locate, assess exemptions, respond), and a bunch of places it can go wrong. This skill walks through each step and drafts the response.\n\n## Jurisdiction assumption\n\nThis analysis assumes the jurisdictional scope specified in your configuration. Privacy rules, response deadlines, and lawful bases vary materially by jurisdiction (GDPR vs. state consumer privacy laws vs. sectoral). If the data subject, processing activity, or controller is in a different jurisdiction than configured, this analysis may not apply as written.\n\n## Load the process\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## DSAR process`. That section has:\n- The systems list (every place user data lives)\n- Identity verification method\n- Response SLA\n- Who handles routine vs. who gets escalated\n\nIf the systems list is empty or stale, flag it — can't do a complete DSAR without knowing where to look.\n\n## Workflow\n\n### Step 1: Classify the request\n\nIdentify which right the data subject is invoking. Common categories:\n\n- **Access** — copy of their data + information about processing\n- **Deletion / erasure** — remove their data (subject to exemptions)\n- **Portability** — their data in machine-readable format\n- **Correction / rectification** — fix inaccurate data\n- **Objection** — stop a particular processing (often marketing)\n- **Restriction** — pause processing pending a dispute\n- **Opt-out of sale/share / automated decision-making** — regime-specific rights\n\n**Research the applicable rule before proceeding.** For each invoked right, identify the jurisdiction(s) whose law applies (GDPR, UK GDPR, CCPA/CPRA, other US state privacy laws, sectoral regimes). Cite the controlling statute or regulation with pinpoint references — the specific article/section, the scope of the right, any carve-outs. Note effective dates; data subject rights are amended frequently (new state laws each legislative session). Flag uncertainty and escalate for attorney verification rather than stating a rule you haven't confirmed.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for the jurisdiction's rights, exemptions, or deadlines, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / right]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution tiering.** Tag every citation with its source. For model-knowledge citations, use one of three tiers rather than a single blanket \"verify\" tag:\n>\n> - `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., GDPR Art. 33, CCPA § 1798.100, FTC Act § 5, 45-day CCPA response window under § 1798.130(a)(2) as a concept). Still verify before filing, but lower priority.\n> - `[verify]` — model-knowledge citations that are real but should be verified: specific implementing regulations, agency guidance, case holdings, thresholds, effective dates, post-2023 amendments.\n> - `[verify-pinpoint]` — pinpoint citations (specific subsection letters, volume/page numbers, paragraph numbers, regulatory subpart references) carry the highest fabrication risk and should ALWAYS be verified against a primary source.\n>\n> Tool-retrieved citations keep their source tag (`[Westlaw]`, `[issuing authority site]`, or the MCP tool name); web-search citations remain `[web search — verify]`; user-supplied citations remain `[user provided]`. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n\nSome requests are combinations — \"delete my account and send me my data first\" is deletion + portability. Handle as two linked requests.\n\n### Step 2: Verify identity\n\nPer the method in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Common approaches:\n\n- **Logged-in verification:** Request came from within an authenticated session → identity confirmed\n- **Email match:** Request came from an email on file → usually sufficient for low-risk requests\n- **Additional verification:** For high-value accounts or deletion requests → challenge question, phone verification, ID document\n\n**Calibrate to risk.** Over-verifying turns the DSAR process into a barrier (bad look with regulators). Under-verifying risks handing someone else's data to a fraudster.\n\nIf identity can't be verified:\n\n```markdown\nWe were unable to verify that this request came from the individual whose data\nis at issue. To proceed, please [verification step]. We cannot provide personal\ndata in response to a request we cannot verify.\n```\n\nThis pauses the clock (arguably) but don't sit on it — respond to say you need verification within a few days, not on day 29.\n\n### Step 3: Locate the data\n\nWalk the systems list from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). For each system:\n\n| System | Queried? | Data found? | What |\n|---|---|---|---|\n| Production database | | | |\n| Analytics (e.g., Mixpanel, Amplitude) | | | |\n| Support tickets (e.g., Zendesk) | | | |\n| CRM (e.g., Salesforce, HubSpot) | | | |\n| Email marketing (e.g., Marketo) | | | |\n| Logs | | | |\n| Backups | | | (note: usually exempt from deletion — see below) |\n| Third-party processors | | | (they may need to be notified for deletion) |\n\nFor a B2B processor: the \"data subject\" is usually *your customer's* end user. Check whether this is actually your customer's DSAR to handle, not yours. Many processor DPAs say \"forward DSARs to the controller.\"\n\n### Step 4: Exemption analysis\n\nNot everything gets produced or deleted. **Research the applicable rule before proceeding.** For each item, identify every exemption that plausibly applies under the regime in scope (e.g., third-party privacy, privilege, trade secret, security, legal obligation to retain, establishment/defense of legal claims, transactional necessity, backup rotation accommodations, freedom of expression). Cite the controlling statute, regulation, or case with a pinpoint cite. Exemption scope varies by jurisdiction and regime — verify currency and flag uncertainty.\n\n**Don't narrow the list on a subjective call.** The skill proposes exemptions where a good-faith basis exists and flags the uncertain ones; the attorney narrows the list before the response goes out. Dropping an exemption that later turns out to apply is costly — once material is disclosed, the exemption is functionally gone. Over-asserting a plausible exemption is correctable by the attorney in review. Prefer the recoverable error.\n\nEvery proposed exemption carries an explicit note: **\"proposed — requires attorney review before asserting. Regulators scrutinize blanket exemption claims, so the attorney narrows this list; the skill does not.\"**\n\nCommon recurring questions to work through:\n\n- Does the record contain data about *other* people that needs to be redacted before production?\n- Is there a specific legal retention obligation that blocks deletion? Cite it.\n- Is there an active litigation hold covering this individual's data?\n- Are there backup rotation or technical-feasibility accommodations that need to be documented (not used as a general excuse)?\n\n**Document every exemption claimed.** If a regulator asks why you didn't delete something, \"we had a legal obligation\" needs a citation.\n\n### Step 5: Draft the response — TWO LETTERS\n\n> **Research-connector pre-flight.** Before emitting either letter or the internal exemption analysis, check whether a legal research connector is reachable for this session — Westlaw, an EUR-Lex / regulator-site connector, or any firm-configured research MCP. Collect this into the reviewer note per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` — the reviewer note sits on the INTERNAL exemption-analysis and cover memo, NOT on the outward-facing DSAR letters to the data subject. If no connector returns results in Step 1 (right classification), Step 4 (exemption analysis), or the Deadline management research step (or none is configured at run time), record it in the **Sources:** line of the internal reviewer note — e.g., `not connected — cites from training knowledge; claimed exemptions, response deadlines, and extension mechanisms are especially fabrication-prone, verify before asserting any exemption to a data subject or regulator`. Per-citation `[model knowledge — verify]` tags remain inline. Do not emit a standalone banner above the output.\n\nMost regimes expect (or require) a prompt acknowledgment separate from the substantive response. Produce both; do not collapse them into one letter that waits until the 45-day deadline to go out.\n\n- **Step 5a — Acknowledgment letter.** Sent within days of receipt (target: same-day to 3–5 days, always well inside the regime's statutory window). Confirms receipt, states what the controller understands the request to be, states the response clock and the target date, asks for any identity-verification material still outstanding. Does NOT contain the substantive disclosure. A prompt acknowledgment is the first regulator-visible signal that the DSAR process is working; it also reduces the risk of a duplicate request or an early complaint.\n- **Step 5b — Substantive response letter.** The actual disclosure, deletion confirmation, or portability export. Goes out by the statutory deadline (or the internal SLA if tighter). Only after identity verification is complete and the Step 3 / Step 4 data location + exemption analysis is done.\n\n**Before proceeding to send either letter to the data subject:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Sending a DSAR response has legal consequences — the content, the exemptions claimed, and the omissions are all reviewable by a regulator, and misstatements become enforcement exposure. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: data subject, right invoked, applicable regime(s), what was located across the systems list, what is being withheld and under which exemption, identity verification posture, response deadline, and the three things to ask the attorney before the letter goes out.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes.\n\n> **Note:** Both DSAR letters are externally-facing deliverables sent to the data subject. Do **not** include the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` on either letter. Internal notes, logs, and exemption analyses that accompany the letters are attorney work product — keep those separate and prepend the work-product header per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (which differs by user role — see `## Who's using this`).\n\n> **Before sending either letter:** This is a draft for attorney review, not a response to send. Sending commits the controller to a position, may waive exemptions, and may start a regulator's clock. A licensed attorney reviews, edits, and approves before either letter goes to the data subject. Do not send unreviewed.\n\n#### Step 5a — Acknowledgment letter template\n\n```markdown\nSubject: We received your privacy request — [Company] — [date]\n\nDear [Name],\n\nWe received your [access / deletion / portability / correction] request on [date received].\n\n**Your request, as we understand it:** [one-sentence restatement — e.g., \"a copy of all personal data we hold associated with your account, along with the categories of third parties with whom we share it, and deletion of your account after we provide the copy.\"]\n\n**What happens next:**\n- Our target date for the substantive response is [date — no later than the regime's statutory deadline; use internal SLA if tighter]. [If identity verification is outstanding: \"We need [specific verification step] before we can proceed — see below.\"]\n- If we need more time because the request is complex or we receive other requests from you at the same time, we will tell you before the initial deadline and explain why. [If the regime allows an extension, cite the controlling provision.]\n- No fee applies to this request. [Or: the fee applies only if the regime permits it and the request is manifestly unfounded or excessive — cite the provision.]\n\n[If identity verification is outstanding:]\n**To verify your identity,** please [specific verification step — e.g., reply to this email from the address on file with the last 4 digits of the payment method we have on file]. This does not pause our deadline; we continue to work in parallel.\n\nIf you have questions, contact [privacy contact].\n\n[Sender]\n```\n\n**Clock-start rule.** The response clock starts on receipt of the request, not on completion of identity verification — unless the applicable regime says otherwise. Do not tacitly toll the clock on verification. If a regime has a different trigger, cite it; do not assume.\n\n#### Step 5b — Substantive response letter templates\n\n**Access request response:**\n\n```markdown\nSubject: Your Data Access Request — [Company] — [date]\n\nWe received your request on [date] for a copy of the personal data we hold about you.\n\n**What we found:**\n\nWe hold the following categories of personal data associated with [identifier]:\n\n| Category | Source | Purpose | Retained until |\n|---|---|---|---|\n| [Account info: name, email] | You, at signup | Account management | Account deletion |\n| [Usage data] | Our service | Analytics, product improvement | [period] |\n| [Support correspondence] | You | Customer support | [period] |\n\n**Your data is attached** in [format]. [Secure delivery note — password-protected\narchive, secure link with expiry, etc.]\n\n**Third parties:** We share data with the following processors: [list or link to\nsubprocessor page].\n\n**Your other rights:** You may also request [deletion / correction / portability].\nTo do so, [method].\n\n**Data we did not include:**\n- [Category] — [exemption and reason, e.g., \"internal security logs — disclosure\n would compromise security measures\"]\n- [Data about other individuals has been redacted from support correspondence]\n\nIf you have questions about this response, contact [privacy contact].\n```\n\n**Deletion request response:**\n\n```markdown\nSubject: Your Deletion Request — [Company] — [date]\n\nWe received your request on [date] to delete the personal data we hold about you.\n\n**What we deleted:**\n\n| Category | System | Deleted on |\n|---|---|---|\n| [Account and profile] | Production | [date] |\n| [Analytics events] | [Amplitude/etc.] | [date] |\n| [etc.] | | |\n\n**What we retained and why:**\n\n| Category | Reason | Retained until |\n|---|---|---|\n| [Transaction records] | Legal obligation (tax record retention, [cite law]) | [date] |\n| [Backup snapshots] | Will be deleted on next rotation | [date] |\n\n**Third-party processors:** We have instructed [list] to delete your data from\ntheir systems.\n\nYour account is now closed. If you have questions, contact [privacy contact].\n```\n\n### Step 6: Log it\n\nDSARs get audited. Record:\n- Date received\n- Date identity verified\n- Date responded\n- What was produced/deleted\n- Exemptions claimed and basis\n- Who handled it\n\nIf your team uses a DSAR tracking tool, create the record there. If not, a log file works.\n\n## Escalation triggers\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Escalation table, escalate when:\n\n- Requester is (or might be) a plaintiff, opposing counsel, or journalist\n- Request scope is unusual (\"all data including internal communications about me\")\n- There's a litigation hold on this individual's data (deletion request + lit hold = conflict, lawyer decides)\n- Requester is disputing a previous DSAR response\n- Any regulator is cc'd or mentioned\n\n## Deadline management\n\n**Two-letter rule.** Every DSAR produces an acknowledgment letter (prompt — target same-day to 3–5 days after receipt) AND a substantive response letter (by the statutory deadline). Most regimes either require or expect a prompt acknowledgment separate from the substantive response; a single combined letter sent on day 45 is a process failure even if it is substantively correct.\n\n**Research the currently operative response deadline for the specific right invoked and the applicable jurisdictions.** Check whether an extension mechanism exists, how much extra time it buys, and what notice the data subject must receive to invoke it. Identify when the clock starts (receipt vs. verification vs. some other trigger — default rule is receipt; verify per regime). Cite the controlling statute or regulation with pinpoint references. Note effective dates — data protection response timelines are amended frequently and new state laws introduce their own clocks.\n\nIf your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## DSAR process` records an internal SLA that is tighter than the legal deadline, use the internal SLA and note the legal backstop.\n\nIf you're going to need an extension, send the \"we need more time\" notice well before the first deadline. Day-of extensions look bad.\n\n## What this skill does not do\n\n- It doesn't query systems directly. It walks you through the checklist; a human (or a connected tool) does the actual queries.\n- It doesn't make exemption calls on close cases. It flags them for a lawyer.\n- It doesn't send the response. Draft, review, human sends.", + }, + { + id: "builtin-cfl-privacy-pia-generation", + title: "PIA Generation", + practice: "Privacy & Data Protection", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “pia-generation” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /pia-generation\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → PIA house style (trigger, structure, depth, sign-off).\n2. Run the workflow below.\n3. Check: is a PIA actually needed? (House trigger + research the mandatory-assessment triggers for each applicable regime — cite primary sources, verify currency.)\n4. Intake: ask the product-team questions. Can pull from PRD if provided.\n5. Write PIA in house format. Include privacy policy consistency check.\n6. Output with conditions list and named owners. Route for sign-off.\n\n```\nthe “PIA Generation” workflow \"Location sharing feature\"\n```\n\n```\nthe “PIA Generation” workflow\nPRD: [Drive link]\n```\n\n---\n\n# PIA Generation\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nA PIA is a conversation with the product team, captured. It asks: what data, why, how long, who sees it, what could go wrong. This skill structures that conversation and writes the output in this team's format — the one learned from the seed PIA during cold-start.\n\n## Jurisdiction assumption\n\nThis assessment assumes the jurisdictional scope specified in your configuration. Privacy rules, assessment triggers, and lawful bases vary materially by jurisdiction (GDPR vs. state consumer privacy laws vs. sectoral). If the processing activity, controller, or affected data subjects fall under a different jurisdiction, this analysis may not apply as written.\n\n## Load prior context on this feature / activity\n\nBefore writing a new PIA, check the outputs folder for prior work on the same feature, processing activity, or counterparty. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Outputs` for the path. Scan for:\n\n- **Prior `use-case-triage` results** covering this activity — the triage's risk rating, mandatory conditions, and called-out concerns are the entry point for the PIA.\n- **Prior `pia-generation` outputs** for the same or an overlapping activity — a superseding PIA should reconcile (what changed, what carried over). A PIA that silently produces different conclusions than a prior PIA on the same activity is a contradiction a reviewing attorney cannot see.\n- **Prior `dpa-review` outputs** for vendors in scope — the DPA review's findings inform the PIA's analysis of subprocessor / cross-border / retention risk.\n\nIf a prior output is found, cite it in the PIA:\n\n> \"Prior triage ([date]) rated this [risk level] and required [conditions]. This PIA builds on that finding — [which conditions are satisfied, which remain, which are re-scoped].\"\n\nIf a prior PIA exists:\n> \"This PIA supersedes the [date] PIA because [reason — scope change, new data category, vendor change, regulatory change]. Conclusions carried over: [X]. Conclusions revised: [Y, because Z].\"\n\n**Carry severity from upstream as a floor** per the cross-skill severity floor rule in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Shared guardrails`. A use-case-triage that rated the activity high-risk cannot become a PIA that concludes low-risk without stating why and what changed.\n\nIf no prior output is found, say so explicitly — \"No prior triage or PIA on this activity in outputs folder; this is a cold start\" — so the reviewing attorney knows the check ran and didn't find anything to reconcile.\n\n## Load house style\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## PIA house style`. That has:\n- What triggers a PIA here (may not match regulatory DPIA triggers — some teams PIA everything, some only high-risk)\n- The structure template extracted from the seed PIA\n- Typical depth\n- Who signs off\n\nIf the seed PIA structure is in the config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), **use it**. The point is that this PIA looks like the other PIAs this team produces, not like a generic one.\n\n## Step 0: Is a PIA needed?\n\nCheck the trigger criteria in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). That is the team's house answer.\n\nIn addition, **research the currently operative mandatory-assessment triggers** for each regime in the regulatory footprint (GDPR/UK GDPR DPIA triggers, CCPA/CPRA risk-assessment triggers, other US state data-protection assessment triggers, sectoral regimes). Cite the controlling statute, regulation, or regulator guidance with pinpoint references. Verify currency — assessment thresholds and definitions shift through new state laws, rulemaking, and enforcement guidance. Flag uncertainty rather than guess.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for a regime's DPIA / risk-assessment triggers or lawful-basis rules, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / question]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against a primary source before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Tag every citation in the PIA with where it came from: `[Westlaw]`, `[regulator site]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations the user supplied. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags.\n\nBeyond statutory mandates, treat these as **strong indicators** that a PIA is worth doing even if not strictly mandatory (research whether any of them independently triggers a mandatory assessment under the applicable regime):\n\n- New technology or novel use of existing tech\n- Children's data\n- Combining datasets that weren't collected together\n- Data that could enable discrimination\n- Processing that users wouldn't expect\n\nIf no statutory trigger applies and the house trigger also isn't met → \"Doesn't look like this needs a PIA. Here's a one-paragraph note for the file explaining why, in case anyone asks.\"\n\n## The intake\n\nBefore writing anything, get answers to these from the product team. Conversational is fine — this isn't a form to send them.\n\n### What and why\n\n- What's the feature/product/change?\n- What problem does it solve for users?\n- What personal data does it touch? Be specific — \"user data\" is not an answer. Which fields?\n- Is any of it new collection, or is it all data you already have?\n- What's the processing — storage, analysis, sharing, automated decisions?\n\n### Legal basis / regime-specific checks\n\nFor each applicable regime, **research the currently operative framework** for the question below and cite primary sources:\n\n- Under regimes that require an identified lawful basis for processing (e.g., GDPR, UK GDPR), identify the basis for each purpose (contract / legitimate interest / consent / legal obligation / vital interests / public task / other). Research the specific requirements and any balancing-test or consent-standard expectations; cite controlling authority.\n- Under regimes that regulate disclosures (e.g., CCPA/CPRA and other US state privacy laws), check whether any flow looks like a \"sale,\" \"share,\" or other regulated disclosure under the currently operative statutory definitions. Third-party advertising is a recurring trap — research whether it falls within the regulated category for the applicable regime.\n- Under sectoral regimes (HIPAA, GLBA, COPPA, FERPA, etc.), research any regime-specific basis or disclosure rules.\n\nVerify currency; statutory definitions and bases are amended often. Flag uncertainty for attorney verification.\n\n### Who and where\n\n- Who inside the company can see this data? Engineers? Support? Analysts?\n- Any third parties? Vendors, partners, analytics?\n- Where is it stored? Which region? New infrastructure or existing?\n- How long is it kept? Is there a deletion schedule or does it live forever?\n\n### What could go wrong\n\n- If this data leaked, what's the harm to the person?\n- Could this data be used to discriminate, even accidentally?\n- Would users be surprised this is happening? (The \"creepy test\" — not a legal standard but a useful one.)\n- Is there an opt-out? Should there be?\n\n## Writing the PIA\n\n**Use the seed PIA structure from the config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).** If none was captured, use this default. Prepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n# Privacy Impact Assessment: [Feature/Product Name]\n\n**Prepared by:** [name] | **Date:** [date] | **Status:** DRAFT / APPROVED\n**Product owner:** [name] | **Privacy reviewer:** [name]\n\n---\n\n## Executive summary\n\n[Two sentences: what this is, whether it's okay. E.g., \"Feature X collects\nlocation data to provide Y. Processing is consistent with existing privacy\npolicy commitments and uses consent as lawful basis. Two mitigations\nrecommended below; no blockers identified.\"]\n\n**Overall risk:** [Reviewer to set: 🟢 Low / 🟡 Medium / 🟠 High / 🔴 Very high]\n\n---\n\n## 1. Description of processing\n\n**What:** [the feature, in plain English]\n**Data categories:** [specific fields — not \"user data\"]\n**Data subjects:** [customers / end users / employees / etc.]\n**Purpose:** [why — tie to user benefit]\n**New collection?** [yes — these fields are new / no — reusing existing data]\n\n---\n\n## 2. Lawful basis\n\n| Purpose | Basis | Notes |\n|---|---|---|\n| [purpose 1] | [Contract / LI / Consent / etc.] | [if LI: balancing test summary; if consent: how obtained] |\n\n---\n\n## 3. Data flow\n\n**Collection:** [how/where data enters]\n**Storage:** [system, region, encryption]\n**Access:** [who, via what controls]\n**Sharing:** [third parties, purpose, governed by which DPA]\n**Retention:** [how long, deletion mechanism]\n\n---\n\n## 4. Privacy policy consistency\n\n| Policy commitment | Consistent? | Notes |\n|---|---|---|\n| [commitment from config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) privacy policy section] | 🟢 / 🟡 | |\n\n[If any 🟡: policy update needed before launch, or processing needs to change]\n\n---\n\n## 5. Risks and mitigations\n\n| # | Risk | Likelihood | Impact | Mitigation | Status | Owner |\n|---|---|---|---|---|---|---|\n| 1 | [specific risk, tied to the design — not \"data breach\" generically] | L/M/H | L/M/H | [specific control] | Done / Planned / Gap | [name] |\n\n**Residual risk after mitigations:** [assessment]\n\n---\n\n## 6. Data subject rights\n\n| Right | Can be exercised? | How |\n|---|---|---|\n| Access | | |\n| Deletion | | |\n| Correction | | |\n| Portability | | |\n| Objection | | |\n\n---\n\n## 7. Recommendation\n\n[APPROVED / APPROVED WITH CONDITIONS / CHANGES REQUIRED / NOT APPROVED]\n\n**Conditions (if any):**\n- [ ] [specific thing that has to happen before launch]\n\n**Sign-off:** [name, date]\n```\n\n## Risk quality standards\n\nRisks in a PIA should be **specific and tied to the design**, not generic. Bad risks pad the document and train readers to skim.\n\n| Bad risk | Why bad | Better |\n|---|---|---|\n| \"Data breach\" | Applies to everything; says nothing | \"Location history accessible by support staff via the admin panel without audit logging — a malicious insider could track a user undetected\" |\n| \"Non-compliance with GDPR\" | Circular — the PIA is supposed to *assess* compliance | Name the specific article and the gap |\n| \"Users might not like it\" | Vague | \"Users who opted out of marketing may still receive this because the opt-out flag isn't checked in this flow\" |\n\nAim for 2-5 real risks, not 15 padded ones.\n\n## Privacy policy diff\n\nEvery PIA should cross-check against the privacy policy commitments in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). The common drift:\n\n- Policy says \"we collect X, Y, Z\" — new feature collects W. Policy needs updating, or stop collecting W.\n- Policy says \"we don't sell data\" — new feature shares with an ad partner. That might be a CCPA sale.\n- Policy says retention is \"as long as your account is active\" — new feature keeps data post-deletion.\n\nFlag every mismatch. One of them has to change before launch.\n\n## Handoff\n\n- **To product team:** Conditions list with owners and deadlines. Not \"improve security\" — \"add audit logging to the admin panel's location lookup, owner: [eng lead], before launch.\"\n- **To reg-gap-analysis skill:** If the PIA uncovered a policy inconsistency, that skill tracks the policy update.\n- **To the sign-off process:** Per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → who approves PIAs.\n\n## Gate: submitting a DPIA to a regulator\n\nProducing an internal PIA is research and documentation. *Submitting a DPIA to a supervisory authority* — or voluntarily disclosing one to a regulator in response to an inquiry — is the consequential act.\n\n**Before proceeding to submit a DPIA (or any equivalent impact assessment) to a regulator, supervisory authority, or enforcement body:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n\n> Submitting to a regulator has legal consequences — the document becomes part of the supervisory record and any material omission or error becomes enforcement exposure. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> [Generate a 1-page summary: regime and regulator, why a submission is being made (mandatory trigger or voluntary), the risks identified, residual risk after mitigations, any flagged uncertainty, and the three things to ask the attorney before filing.]\n>\n> If you need to find a licensed attorney, solicitor, barrister, or other authorised legal professional in your jurisdiction: your professional regulator's referral service is the fastest starting point (state bar in the US, SRA/Bar Standards Board in England & Wales, Law Society in Scotland/NI/Ireland/Canada/Australia, or your jurisdiction's equivalent).\n\nDo not proceed past this gate without an explicit yes.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't approve the processing. A human signs the PIA.\n- It doesn't write a DPIA for a supervisory authority — that's a more formal document with specific regulatory requirements. This is the internal assessment.\n- It doesn't design the mitigation. It describes what needs mitigating; engineering designs the fix.", + }, + { + id: "builtin-cfl-privacy-reg-gap-analysis", + title: "Reg Gap Analysis", + practice: "Privacy & Data Protection", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “reg-gap-analysis” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /reg-gap-analysis\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → privacy policy commitments, regulatory footprint, DSAR systems.\n2. Run the workflow below.\n3. Scope: does the regulation apply? (jurisdiction, thresholds, sector)\n4. Extract requirements → diff against current state → gap list.\n5. Remediation plan with owners, dates, prioritization.\n6. Save dated doc. Even \"no gaps\" gets documented.\n\n```\nthe “Reg Gap Analysis” workflow \"Colorado Privacy Act\"\n```\n\n```\nthe “Reg Gap Analysis” workflow\n[paste guidance / reg text]\n```\n\n---\n\n# Regulation-to-Policy Gap Analysis\n\n## Purpose\n\nA state passes a new privacy law. The ICO issues new guidance. The CPPA finalizes regulations. Something moves — and now you need to know what, if anything, you have to change.\n\nThis skill diffs the new requirement against what you currently do (per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Privacy policy commitments + the practices documented in PIAs) and produces a gap list with a remediation plan.\n\n## Load current state\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n- `## Privacy policy commitments` — what you've publicly promised\n- `## Regulatory footprint` — what already applies\n- `## DSAR process` → systems list — what you actually do operationally\n\nIf the regulation doesn't apply to you (wrong jurisdiction, below threshold, different sector), the gap analysis is one line: \"Doesn't apply. Here's why: [reason]. No action needed.\"\n\n## Workflow\n\n### Step 1: Scope the regulation\n\nBefore diffing, answer:\n\n- **Does it apply?** Jurisdiction (do you have data subjects there?), threshold (revenue, user count, data volume), sector carve-outs\n- **When?** Effective date, enforcement date (often later), any phase-in\n- **What's actually new?** Many \"new\" state privacy laws are 90% CCPA with tweaks. Identify the delta from what you already comply with, not the full text.\n\n### Step 2: Extract requirements\n\nRead the regulation (or summary/guidance). List every substantive requirement as a discrete item:\n\n| # | Requirement | Citation | Category |\n|---|---|---|---|\n| 1 | [requirement as stated] | [section] | [Notice / Rights / Security / Vendor / Other] |\n\n**Categories:**\n- **Notice** — what you have to tell users (privacy policy content)\n- **Rights** — what users can ask for (DSAR-adjacent)\n- **Security** — technical/organizational measures\n- **Vendor** — what you have to flow down to processors\n- **Consent** — opt-in/opt-out mechanics\n- **Governance** — DPO, impact assessments, record-keeping\n\n### Step 3: Diff against current state\n\nFor each requirement:\n\n```markdown\n### [Requirement #N]: [short name]\n\n**Regulation says:** [requirement, quoted or paraphrased]\n\n**We currently:** [what the config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) / privacy policy / practice shows]\n\n**Gap:** [None | Partial | Full]\n\n**If partial/full gap — what's missing:** [specific]\n\n**Effort to close:** [Policy update only | Product change | Vendor renegotiation |\nNew process]\n\n**Risk of non-compliance:** [regulatory penalty range, enforcement likelihood,\nreputational]\n```\n\n### Step 4: Prioritize\n\nNot every gap is equal. Sort by:\n\n1. **Hard deadline with teeth** — effective date + active enforcement + real penalties\n2. **Effort-to-impact ratio** — policy language update is cheap; product rebuild is not\n3. **What you've already half-done** — if you're 80% there for GDPR, the state law delta may be small\n\n### Step 5: Remediation plan\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n> **Research-connector pre-flight.** Before emitting the remediation plan, check whether a legal research connector is reachable for this session — Westlaw, an EUR-Lex / regulator-site connector, or any firm-configured research MCP. Collect this into the reviewer note per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`: if no connector returns results in Step 2 or the Common regulation categories research step (or none is configured at run time), record it in the **Sources:** line of the reviewer note — e.g., `not connected — cites from training knowledge; the highest-fabrication items in privacy gap analyses are new state-law effective dates, enforcement-begins dates, and article/section pinpoints — spot-check those first`. Per-citation `[model knowledge — verify]` tags remain inline. Do not emit a standalone banner above the output.\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n## Remediation Plan: [Regulation name]\n\n**Effective date:** [date]\n**Enforcement begins:** [date]\n\n### Must-do before enforcement\n\n| Gap | Fix | Owner | Due | Status |\n|---|---|---|---|---|\n| [gap] | [specific fix] | [name] | [date] | [ ] |\n\n### Should-do (lower risk, not blocking)\n\n[same table]\n\n### Already compliant\n\n[list of requirements where gap = None — useful for the \"we're mostly fine\" message]\n\n### Accepted gaps (risk-accepted, not fixing)\n\n[if any — with documented rationale and who accepted the risk]\n```\n\n## Common regulation categories\n\nWhen scoping the delta, it helps to place the new regulation into a rough category and then research the specifics:\n\n- **Baseline data-protection / privacy law** — broad coverage of a jurisdiction's personal data practices\n- **Sector-specific overlay** — health, finance, children, education, employment, etc.\n- **AI-specific regime** — transparency, impact assessments, or governance for automated decision-making\n- **Data broker / ad-tech regime** — registration, opt-out, deletion mechanisms\n- **Breach-notification regime** — standalone or embedded in a broader law\n- **Cross-border transfer regime** — adequacy, mechanism, and assessment requirements\n\nFor each category relevant to the new regulation, **research the currently operative requirements** before drafting the gap analysis. Cite primary sources. Verify currency — new state laws come online each legislative session, and regulators issue interpretive guidance that shifts what \"compliance\" means for a given control. Flag uncertainty for attorney verification rather than assert a rule you haven't confirmed.\n\n> **No silent supplement.** If a research query to the configured legal research tool (Westlaw, regulator databases, or firm platform) returns few or no results for a regulation, guidance document, or enforcement action, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / topic]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against the issuing authority before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution tiering.** Tag every citation in the gap analysis with its source. For model-knowledge citations, use one of three tiers rather than a single blanket \"verify\" tag:\n>\n> - `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., GDPR Art. 33, CCPA § 1798.100, FTC Act § 5). Still verify before filing, but lower priority.\n> - `[verify]` — model-knowledge citations that are real but should be verified: specific implementing regulations, agency guidance, case holdings, thresholds, effective dates, newly enacted state statutes.\n> - `[verify-pinpoint]` — pinpoint citations (specific subsection letters, volume/page numbers, paragraph numbers, regulatory subpart references) carry the highest fabrication risk and should ALWAYS be verified against a primary source.\n>\n> Tool-retrieved citations keep their source tag (`[Westlaw]`, `[issuing authority site]`, or the MCP tool name); web-search citations remain `[web search — verify]`; user-supplied citations remain `[user provided]`. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n\n## Integration with other skills\n\n**From PIA generation:** PIAs flag privacy policy inconsistencies → those feed here as known gaps.\n\n**To the regulatory-legal plugin (if installed):** This skill is the manual version. The monitor plugin watches feeds and triggers this analysis automatically when something changes.\n\n## Output\n\nSave as a dated markdown doc. The remediation plan table becomes a tracker — update status as items close.\n\nIf the gap analysis concludes \"no gaps, we're compliant,\" still write the doc — it's useful evidence later that you looked.\n\n**Close with a citation-verification note:**\n\n> Citations in this output were generated by an AI model and have not been verified against a primary source. Before relying on any regulation, statute, guidance, or enforcement action, check it against a legal research tool (Westlaw, your firm's research platform, or the issuing authority's website) for accuracy and current status. AI-generated citations are sometimes fabricated or misquoted. Source tags on each citation (e.g., `[web search — verify]`) show where it came from; `verify` tags carry higher fabrication risk and should be checked first.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't interpret ambiguous regulatory language authoritatively. When the reg is unclear, say so: \"Section X could be read as [A] or [B]. [A] is the conservative read. Suggest outside counsel if this is material.\"\n- It doesn't track regulatory changes proactively. It runs when you point it at a change. For proactive monitoring, see the regulatory-legal plugin.\n- It doesn't implement fixes. It plans them.", + }, + { + id: "builtin-cfl-privacy-use-case-triage", + title: "Use Case Triage", + practice: "Privacy & Data Protection", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “use-case-triage” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /use-case-triage\n\n1. Read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). Confirm privacy practice is configured — if not, stop and direct to setup.\n2. Run the workflow below. Clarify the activity if vague.\n3. House trigger check → mandatory DPIA check (if GDPR in footprint) → privacy policy conflict check.\n4. Output: classification (PROCEED / PIA REQUIRED / DPIA MANDATORY / STOP), reasoning, conditions table if required, cross-plugin handoffs.\n5. Offer to continue into PIA generation if assessment is required.\n\n```\nthe “Use Case Triage” workflow \"New feature that uses behavioral data to personalize content recommendations\"\n```\n\n---\n\n# Privacy Use Case Triage\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nAnswer the question that comes up before anyone runs a PIA: \"does this thing even\nneed one?\" And if it does, what kind, and what's blocking the way?\n\nPrivacy triage is faster than PIA generation but upstream of it. It doesn't write\nthe assessment — it determines whether one is needed and on what terms. The PIA\ngeneration skill does the deep work.\n\nThe output is one of four classifications:\n- **PROCEED** — No PIA needed. Standard safeguards apply.\n- **PIA REQUIRED** — Assessment needed before or alongside deployment.\n- **DPIA MANDATORY** — A regime-mandated data protection impact assessment is\n required (research the applicable regime's trigger and cite primary sources).\n Harder bar, DPO/GC involvement likely.\n- **STOP** — Processing activity conflicts with the privacy policy or has no\n lawful basis as described. Needs redesign before proceeding.\n\n## Jurisdiction assumption\n\nThis triage assumes the jurisdictional scope specified in your configuration. Privacy rules, assessment triggers, and lawful bases vary materially by jurisdiction (GDPR vs. state consumer privacy laws vs. sectoral). If the processing activity, controller, or affected data subjects fall under a different jurisdiction, this classification may not apply as written.\n\n## Read the config first\n\nBefore triaging, always read your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). The PIA trigger criteria, regulatory\nfootprint, and privacy policy commitments there are authoritative. Generic privacy\nlaw reasoning is not a substitute for what this company has actually committed to.\n\nIf the file is missing or contains `[PLACEHOLDER]`, surface this bounce:\n\n> I notice you haven't configured your practice profile yet — that's how I tailor the PIA trigger criteria, regulatory footprint, and privacy policy commitments to your practice.\n>\n> **Two choices:**\n> - Run `configure your Practice Profile (Account → Practice Profile)` (2 minutes) to configure your profile, then I'll triage tailored to YOUR practice.\n> - Say **\"provisional\"** and I'll triage against generic defaults — US jurisdiction, middle risk appetite, lawyer role, no playbook — and tag every output `[PROVISIONAL — configure your profile for tailored output]` so you can see what I do before committing.\n\n### Provisional mode\n\nIf the user says \"provisional,\" run triage normally using these generic defaults: middle risk appetite, lawyer role, US jurisdiction (CCPA + common federal sectoral baselines), no playbook (classify from general privacy-law principles rather than matching to configured commitments). Tag the reviewer note and every finding block with `[PROVISIONAL]`. At the end of the output, append:\n\n> \"That was a generic run against default assumptions. Run `configure your Practice Profile (Account → Practice Profile)` to get output calibrated to YOUR practice — your regulatory footprint, your privacy policy commitments, your risk appetite. 2 minutes.\"\n\n---\n\n## Triage process\n\n### Step 1: Understand the activity\n\nIf the description is vague, ask before classifying. Get specific on:\n\n- What data is being collected or processed? Which categories?\n- Who are the data subjects — customers, employees, third parties?\n- What's the purpose? What problem is this solving?\n- Is this new data collection, or repurposing data you already have?\n- Is a third-party vendor involved? New vendor or existing?\n- Is any automated decision-making involved — does the output affect anyone?\n- What's the deployment context — internal only, customer-facing, public?\n\n\"New feature\" and \"data processing activity\" are not enough to triage accurately.\n\n---\n\n### Step 2: Check house triggers\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## PIA house style` → Trigger criteria. Apply them.\n\nIf the house trigger is met → at minimum **PIA REQUIRED**.\n\nIf house trigger is not met, continue to Step 3 before concluding PROCEED. Some\nactivities need a PIA regardless of internal policy.\n\n---\n\n### Step 3: Mandatory assessment check\n\n**Before researching regime-specific triggers, ask the activity-based federal overlay question first.** If the processing touches a federally-regulated data category, the federal overlay is usually the controlling framework, not state privacy law, and the triage needs to surface that early rather than as an afterthought.\n\n> **Activity-based federal overlays — ask first:**\n>\n> Does this processing touch:\n> - **Financial account data or \"nonpublic personal information\" about consumers** (GLBA / Reg P — applies to financial institutions and their non-affiliated third parties; imposes substantive restrictions on sharing NPI for marketing, separate from and on top of any state privacy-law exemption)?\n> - **Protected health information held by a covered entity or business associate** (HIPAA Privacy / Security Rules — substantive restrictions on use and disclosure, breach notification at 500+ records, BAA required for any vendor)?\n> - **Education records held by a school or a service provider acting for a school** (FERPA — consent requirements for disclosure, directory-information carve-outs)?\n> - **Data from children under 13 collected by an operator of an online service directed to children or with actual knowledge** (COPPA — parental consent, notice, deletion rights, strict limits on retention and sharing)?\n> - **Another sectoral federal regime** (e.g., VPPA for video-viewing records, CPNI for carrier data, DPPA for DMV records, TCPA for SMS/call consent)?\n>\n> If yes to any: the federal overlay usually supplies the controlling substantive restriction, not just an exemption from a state consumer privacy law. Research and cite the specific provision before continuing. An activity that is \"exempt\" from CCPA under § 1798.145(e) because it is GLBA-covered is still subject to the GLBA restrictions (e.g., § 6802(a)-(c) on NPI sharing) — the CCPA exemption does not make the activity lawful; it just moves the governing framework to GLBA.\n\nFor each regime in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Regulatory footprint`, **research the currently operative mandatory privacy/data-protection assessment triggers**. Cite controlling statute, regulation, or regulator guidance with pinpoint references. Note effective dates — national and state regulators publish and update trigger lists regularly; do not rely on a static checklist. Flag uncertainty for attorney verification rather than guess.\n\nIf **any** applicable regime's mandatory trigger is met → **DPIA MANDATORY** (or the equivalent regime-specific mandate), regardless of house trigger.\n\n**Strong indicators (not necessarily mandatory but do one anyway):**\n- New technology or novel use of existing technology\n- Children's data\n- Combining datasets that weren't collected together\n- Data that could enable discrimination\n- Processing users would not expect\n- Lookalike audiences, cross-context behavioral advertising, or other tracking-based ad-tech activity (recurring question for consumer-facing companies; surfaces policy-commitment conflicts and federal sectoral overlays reliably)\n\nOne or more strong indicators with no researched mandatory trigger → escalate to **PIA REQUIRED**\n(not DPIA mandatory, but flag in the output).\n\n---\n\n### Step 4: Privacy policy conflict check\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Privacy policy commitments`. Check the proposed activity\nagainst every stated commitment.\n\n**Common conflicts to catch:**\n- Policy says \"we collect X, Y, Z\" — this activity collects W. Policy update\n needed before launch, or stop collecting W.\n- Policy says \"we don't sell or share data with third parties\" — this activity\n passes data to a vendor for their own purposes. Research whether the flow falls\n within a regulated \"sale,\" \"share,\" or other disclosure category under each\n applicable regime.\n- Policy states retention limits — this activity retains data longer.\n- Policy says \"we use data only for [purpose]\" — this activity uses it for a new\n purpose without fresh consent or legitimate interest assessment.\n- Policy specifies user rights offered — this activity creates a new data category\n the rights process wasn't built for.\n\nIf a direct conflict exists → **STOP**. Not \"proceed with caution\" — the policy\nconflict has to be resolved (policy update or activity redesign) before this\nproceeds.\n\n---\n\n### Step 5: Classification and output\n\n---\n\n### Bottom line\n[PIA required / Mandatory DPIA required / Proceed — one-sentence why]\n\n---\n\n**ACTIVITY:** [State the processing activity as you understand it]\n\n**CLASSIFICATION:** [PROCEED / PIA REQUIRED / DPIA MANDATORY / STOP]\n\n**House trigger met?** [Yes / No]\n**GDPR mandatory DPIA trigger?** [Yes — [trigger] / No / N/A (GDPR not in footprint)]\n**Privacy policy conflict?** [None / Yes — [specific conflict]]\n\n**Reasoning:**\n[1-3 sentences. For PROCEED: what makes it safe under current policy. For PIA/DPIA:\nwhat creates the obligation. For STOP: which specific policy commitment or principle\nis in conflict.]\n\n---\n\n*If PIA REQUIRED or DPIA MANDATORY — conditions before proceeding:*\n\n| Requirement | Owner | Done? |\n|---|---|---|\n| [e.g., Privacy Impact Assessment — full DPIA format] | [Privacy counsel] | ☐ |\n| [e.g., Legitimate interest assessment (if LI basis)] | [Privacy counsel] | ☐ |\n| [e.g., DPO consultation (DPIA mandatory track)] | [DPO] | ☐ |\n| [e.g., Vendor DPA in place] | [Privacy / Legal] | ☐ |\n| [e.g., Privacy policy update before launch] | [Privacy counsel] | ☐ |\n| [e.g., Consent mechanism built and tested] | [Product] | ☐ |\n| [e.g., Data subject rights process covers new data category] | [Privacy / Product] | ☐ |\n\n**Lawful basis (if GDPR in footprint):** [Consent / Contract / Legitimate Interest /\nLegal Obligation — or \"unclear — needs determination in PIA\"]\n\n**Next step — offer to continue:**\n\nAfter presenting a PIA REQUIRED or DPIA MANDATORY result, always end with:\n\n> \"Want me to start the PIA now? I can run the intake questions and produce the\n> assessment document without you needing to run a separate command.\"\n\nIf they say yes, load the `pia-generation` skill and continue in the same\nconversation — pass the activity description and any triggers already identified.\n\nIf they say no, the triage result stands. The PIA can be run any time with:\n`the “PIA Generation” workflow [activity]`\n\n---\n\n*If STOP:*\n\n**Conflict:** [Specific privacy policy commitment or principle in conflict]\n\n**To proceed, one of these has to change:**\n- [Option A — redesign the activity so it doesn't create the conflict]\n- [Option B — update the privacy policy to cover this processing (requires review\n of whether the update is itself consistent with lawful basis)]\n\nDon't offer a path forward if there isn't one. If the processing simply can't be\nreconciled with stated commitments or lawful basis, say so.\n\n---\n\n### Step 6: Cross-plugin handoffs\n\n**AI governance handoff:** If the activity involves an AI system making or\ninfluencing decisions about individuals:\n\n> \"This activity involves AI decision-making. An AI impact assessment is likely\n> required in addition to a PIA. Use `the “AIA Generation” workflow [activity]`\n> to run that in parallel — they're not substitutes.\"\n\n**Product counsel handoff:** If this is a new product feature or launch:\n\n> \"If this is part of a product launch, loop in product counsel.\n> Use `the “Launch Review” workflow` — it will detect the privacy component\n> and route to this plugin.\"\n\nOnly flag handoffs that are actually relevant. Don't append both as boilerplate.\n\n---\n\n## Batch triage\n\nIf the user presents a feature list, roadmap, or backlog — summary table first,\nthen expand each non-PROCEED entry:\n\n| # | Activity | Classification | Key condition / blocker |\n|---|---|---|---|\n| 1 | [activity] | 🟢 Proceed | — |\n| 2 | [activity] | 🟡 PIA required | Lawful-basis assessment needed; vendor DPA not in place |\n| 3 | [activity] | 🟠 DPIA mandatory | Large-scale special category data |\n| 4 | [activity] | 🔴 Stop | Privacy policy conflict — purpose limitation |\n\n---\n\n## Edge cases and failure modes\n\n**\"It's anonymized\" doesn't automatically mean PROCEED.**\nAsk how it's anonymized and whether re-identification is realistically possible\ngiven the data set. Pseudonymized data is still personal data under GDPR.\n\n**\"We already do something similar\" isn't a triage.**\nExisting processing that was never assessed doesn't grandfather new processing.\nIf the new activity is materially different in scale, purpose, or data category,\ntriage it fresh.\n\n**\"Just a pilot\" doesn't skip triage.**\nA pilot that touches real user or employee data is subject to the same triggers.\nApply the same classification; if a PIA is required, the pilot should have one.\n\n**\"The vendor handles all the privacy.\"**\nVendor handles the infrastructure. You're still the controller determining the\npurposes. If personal data flows to the vendor, a DPA is required and triage still\napplies to the purpose.\n\n**Inferred data and derived attributes count.**\nIf the activity generates inferred data about individuals (e.g., a behavioral score,\na predicted preference), treat the inferred attribute as personal data for triage\npurposes. Don't let \"we're just computing a score\" obscure what the score represents.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-product-feature-risk-assessment", + title: "Feature Risk Assessment", + practice: "Product", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “feature-risk-assessment” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Feature Risk Assessment\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nThe launch review is broad. This is deep. When a single issue needs more than a table row — a novel AI feature, a children's product, something a regulator is actively looking at — this skill produces a standalone assessment.\n\nNot every launch needs one. Most don't. This is for the 10% where \"PIA done, shipped\" isn't the right level of scrutiny.\n\n## When to run this\n\n- Launch review found a pattern that's **not in the calibration table** (novel)\n- Launch review found something in the **\"usually blocks\"** category\n- GC or leadership asked \"what's the risk here\" and wants more than a one-liner\n- The feature is in an area with **active regulatory attention** (AI, children, biometric, health)\n- Someone outside legal is worried and a structured answer would help\n\nIf none of the above, the launch review is enough. Don't generate paperwork for its own sake.\n\n## Structure\n\n### 1. What we're assessing\n\nOne paragraph. What the feature does, what's new about it, why it got escalated to a full assessment.\n\n### 2. The risks\n\nFor each distinct risk (aim for 2-5, not 15):\n\n```markdown\n### Risk [N]: [Short name]\n\n**Scenario:** [What would have to happen for this to go wrong. Be specific —\nnot \"data breach\" but \"the recommendation algo surfaces a user's sensitive\ncategory interest to someone who shouldn't see it because X.\"]\n\n**Who gets hurt:** [Users? The company? A third party? Specific.]\n\n**How likely:** [Low / Medium / High — with a reason. \"Low — would require\nboth X and Y to fail simultaneously.\" Not just a vibes rating.]\n\n**How bad if it happens:** [Low / Medium / High — with a reason. \"High —\nregulatory fine + class action exposure + press\" vs. \"Low — one angry\ntweet, no actual harm.\"]\n\n**Existing mitigations:** [What already reduces the likelihood or impact]\n\n**Gap:** [What's missing, if anything]\n\n**Residual risk:** [After existing mitigations — is this acceptable or does\nit need more?]\n```\n\n### 3. Regulatory landscape (if relevant)\n\nOnly include if a regulator is actively interested in this space. If so:\n\n- Which regulator, what they've said/done recently\n- How this feature would look to them\n- Whether we'd rather they hear about it from us or from a headline\n\n### 4. Precedent (if any)\n\nHas another company done something similar? What happened?\n\n- If nothing bad happened → useful, not dispositive\n- If something bad happened → what was different about their situation, does it apply here\n\nDon't overweight precedent. Regulators change priorities; one company getting away with something doesn't mean the next one will.\n\n### 5. Options\n\nPresent 2-3 realistic paths:\n\n```markdown\n| Option | Description | Risk reduction | Cost |\n|---|---|---|---|\n| A: Ship as designed | [current plan] | None | None |\n| B: Ship with [mitigation] | [change] | [how much] | [eng effort, timeline, UX] |\n| C: Don't ship [component] | [scope cut] | [how much] | [product impact] |\n```\n\n### 6. Recommendation\n\nPick one. Explain why. Acknowledge what you're trading off.\n\n```markdown\n**Recommended: Option [X]**\n\n[Why. What risk remains. Why that's acceptable. Who accepts it.]\n\n**If the answer is \"not my call\":** [Who decides, what they need to know]\n```\n\n## Calibration check\n\nBefore finalizing, check against your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Risk calibration:\n\n- Is this risk assessment calibrated to *this company*, or is it generic?\n- A risk that's \"High\" at a company under a consent decree might be \"Medium\" at one that isn't\n- The assessment should reflect the actual regulatory posture, litigation history, and risk appetite captured in the practice profile\n\n## Handoffs\n\n- **To AI governance:** If the deep-dive was triggered by an AI feature — which\n it often is — run `the “AIA Generation” workflow [feature]` in parallel or\n immediately after. The feature risk assessment frames the decision; the AIA\n documents the AI system specifically in the format AI governance needs. They're\n not duplicates: the FRA is a product-legal decision doc; the AIA is the\n governance record.\n- **To privacy:** If the feature involves new data collection or processing,\n run `the “PIA Generation” workflow [feature]`. The FRA's risk section\n will likely overlap with the PIA's — flag that overlap so work isn't duplicated,\n but both docs need to exist.\n- **To AI governance vendor review:** If the feature uses a new AI vendor,\n run `the “Vendor Ai Review” workflow [vendor agreement]` if not already done\n during the launch review.\n\n## Output format\n\nStandalone doc, 2-4 pages. Prepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\nNot a slide deck, not a memo to file — a decision document someone reads and then decides.\n\nSave where your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Launch review process says review docs go. If the doc is going to be shared with anyone outside the privileged loop (e.g., posted to a broadly-shared ticket), drop the work-product header only for that externally-facing copy and keep the privileged original in the matter file.\n\n## Citation check\n\nIf the assessment cites cases, statutes, regulations, or enforcement actions — in the Regulatory landscape or Precedent sections especially — those citations were generated by an AI model and have not been verified against a primary source. Before the decision document goes to a decisionmaker, verify each citation against a legal research tool (Westlaw, CourtListener, or your firm's research platform) for accuracy, good law status, and current enforcement posture. A risk assessment built on a fabricated enforcement action is worse than no assessment.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for the regime or precedent the assessment needs, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / precedent]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against the issuing authority before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution.** Tag every citation in the Regulatory landscape and Precedent sections with where it came from: `[Westlaw]`, `[CourtListener]`, `[regulator site]`, or the MCP tool name for citations retrieved from a legal research connector; `[web search — verify]` for web-search citations; `[model knowledge — verify]` for citations recalled from training data; `[user provided]` for citations from the feature team. Citations tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags — the decisionmaker needs to see which citations to verify first.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't assess every feature. Most features get a launch review and that's it.\n- It doesn't make the decision. It frames the decision. Someone with authority picks an option.\n- It doesn't do quantitative risk modeling. If the company has a formal risk framework with numbers, use that — this is qualitative.", + }, + { + id: "builtin-cfl-product-is-this-a-problem", + title: "Is This A Problem", + practice: "Product", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “is-this-a-problem” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /is-this-a-problem\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Risk calibration.\n2. Apply the triage workflow below.\n3. Pattern-match. Check for common traps.\n4. Answer in one minute: ✅ Fine / ⚠️ Needs a look / 🛑 Hold. One sentence why.\n5. If ⚠️ or 🛑: name the next step.\n\n```\nthe “Is This A Problem” workflow \"Can we use customer logos on the pricing page?\"\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nMost \"quick legal question\" Slacks are one of three things: (a) not a problem, say so fast, (b) a real thing that needs a real look, route it, (c) a thing that looks fine but has a trap, catch the trap. This skill sorts in under a minute using the calibration table.\n\nThe goal is speed. The PM asked at 4:47pm. They want an answer, not a memo.\n\n## Load calibration\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Risk calibration`. The whole point of this skill is pattern-matching against that table.\n\n## The triage\n\n### Match against calibration\n\nDoes the question match a pattern in the calibration table?\n\n**Matches \"usually FYI\":**\n→ Say so. One line. \"You're fine — [pattern]. Ship it.\"\n\n**Matches \"usually requires work\":**\n→ Name the work. \"Needs a [PIA / vendor review / claims check]. Takes [timeline from table]. Want me to start it?\"\n\n**Matches \"usually blocks\":**\n→ Stop them. \"Hold on — [pattern]. This needs a real look before anyone commits to a date. Let's talk.\"\n\n**Doesn't match anything:**\n→ Say that too. \"This doesn't pattern-match to anything I've seen here. Needs a human look — [your name] or me tomorrow?\"\n\n### The trap check\n\nSome questions are fine on the surface but have a twist. Recognize the fact pattern, ask the catch question, then research the applicable doctrine for the specific fact pattern before concluding whether it's a problem or not.\n\n| Question sounds like | Why it might not be simple | Catch it by asking |\n|---|---|---|\n| \"Can we add [vendor] to the integration?\" | Vendor touches a new data category — flag as potentially implicating privacy and vendor-risk regimes and route for research | \"What data flows to them?\" |\n| \"Can we A/B test the pricing page?\" | Differential pricing by segment can implicate consumer-protection and anti-discrimination regimes — flag and route for research | \"Are both arms seeing the same price for the same thing? How are users assigned to arms?\" |\n| \"Can we auto-enroll users in the new feature?\" | Default-on behavior for users who previously opted out can implicate consent and consumer-protection rules — flag and route for research | \"Does this respect existing preferences?\" |\n| \"Can we use customer logos on the site?\" | Logo use is a separate permission from the contract relationship — flag as potentially implicating publicity / endorsement rules and the customer's own contract terms | \"What does the contract say about publicity? Do we have written permission?\" |\n| \"Can we train on this data?\" | Usage rights for the original collection purpose may not extend to training — flag and research the notice/consent the users were given at collection | \"What did we tell users when we collected it? What jurisdictions are the users in?\" |\n| \"It's just an internal tool\" | Internal tools still process personal data — flag as potentially implicating privacy regimes and route for research | \"Whose data does it touch? Employees, customers, third parties?\" |\n| \"We already do something similar\" | \"Similar\" is doing a lot of work — the delta is where the issue usually is | \"Similar how? What's actually different?\" |\n| \"Can we use [AI vendor / LLM] for this?\" | Vendor AI terms may permit training on inputs; use case may need an AIA — flag and route to `the “Use Case Triage” workflow` | \"Is there an AI addendum? What data goes into the model?\" |\n| \"Can we add AI to this feature?\" | May be a new use case not in the registry; may trigger AIA requirement — flag and route to `the “Use Case Triage” workflow` | \"What does the AI do — assistive or automated? Who does it act on?\" |\n| \"The model just decides automatically\" | Automated decision-making without human review is regulated in some jurisdictions — flag and research the applicable rules for the affected users' jurisdictions | \"Who's affected? Is there a human in the loop? Where are the affected users?\" |\n| \"It's AI-generated content\" | Output IP and disclosure duties vary by jurisdiction and vendor terms — flag and route for research | \"What's the content type? Does the vendor's ToS address output ownership? Who is the audience?\" |\n| \"We're just fine-tuning on our data\" | Training data rights, output IP, and vendor obligations all change — flag and route to `the “Vendor Ai Review” workflow` | \"What's in the training data? Is any of it customer or employee data?\" |\n\nIf a trap might be present, ask the one question before answering. One question, not a checklist. When the answer suggests a real issue, flag for research and route — don't pattern-match to a legal conclusion from the question alone.\n\n## Output format\n\n**For Slack (the common case):**\n\nSlack triage replies are internal legal advice. If the reply is being pasted into a ticket, document, or channel that's broadly shared with non-legal, prepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`):\n\n```\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n```\n\nFor an in-the-flow Slack DM reply to the PM, the short form is:\n\n```\n[✅ Fine | ⚠️ Needs a look | 🛑 Hold]\n\n[One sentence: the call and why.]\n\n[If ⚠️: what the look involves, how long]\n[If 🛑: who to talk to, when]\n```\n\n**Examples:**\n\n```\n✅ Fine — adding an analytics event is an FYI here as long as it's covered by\nthe existing privacy policy categories. This one is.\n```\n\n```\n⚠️ Needs a PIA — new data collection for [category]. Usually takes a day.\nWant me to kick it off?\n```\n\n```\n🛑 Hold — \"train on customer data\" triggers a bunch of things. What did the\ncustomer agreement say about data use? Let's pull it before anyone promises\nthis to the customer.\n```\n\n```\n⚠️ Needs an AI governance triage — adding an LLM to this workflow means we need\nto check the use case against the registry and confirm an AIA is done before it\nships. Takes a day. Want me to run `the “Use Case Triage” workflow` now?\n```\n\n## When to NOT use this skill\n\n- The question is actually complex (multiple issues, novel area) → route to launch-review or feature-risk-assessment\n- The question is \"can you review this PRD\" → that's launch-review, not triage\n- You're not sure → say \"I'm not sure, let me look properly\" — a wrong fast answer is worse than a slow right one\n\n## Tone\n\nFast, direct, helpful. The PM is not asking for a lecture. If it's fine, say \"fine\" — don't list the seven things you checked. If it's not fine, say what's not fine and what to do about it.\n\nYou are the lawyer people want to ask, not the one they route around.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.", + }, + { + id: "builtin-cfl-product-launch-review", + title: "Launch Review", + practice: "Product", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “launch-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /launch-review\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → framework + calibration. Stop if placeholders.\n2. Get PRD + related docs. If tracker connected, pull ticket and comments.\n3. Walk every framework category using the workflow below.\n4. Calibrate each finding against the table. Novel = flag explicitly.\n5. Output review memo in house format. Post summary to ticket if connected.\n6. Hand off: marketing-claims-review if substantial marketing; feature-risk-assessment if a finding needs depth.\n\n```\nthe “Launch Review” workflow PROJ-1234\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Destination check\n\nBefore producing output, check where it's going. If the user has named a destination (a channel, a distribution list, a counterparty, \"everyone\"), ask whether it's inside the privilege circle. Public channels, company-wide lists, counterparty/opposing counsel, vendors, and clients (for work product) waive the protection. When the destination looks outside the circle, flag it and offer (a) the privileged version for legal only, (b) a sanitized version for the broader channel, or (c) both — don't silently apply a privileged header and then help paste it somewhere the header won't protect it. See the canonical `## Shared guardrails → Destination check` in this plugin's your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n\n## Purpose\n\nRead the PRD, check every category in this team's framework, calibrate against what actually blocks here (per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile)), and output a review in house format. Goal: a PM reads it and knows exactly what has to happen before they ship.\n\n## Load calibration\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n- `## Review framework` — the categories to check\n- `## Risk calibration` — what blocks vs. what's FYI *at this company*\n- `## Launch review process` — output format\n- `## Escalation` — when to route up\n\nThe calibration table is the difference between this skill and a generic checklist. If the table says \"new data collection → PIA, ships in 1-2 days,\" don't write \"this might require a full DPIA and regulatory consultation.\" Match the team's actual practice.\n\n## Workflow\n\n### Step 1: Get the inputs\n\n- **PRD** — from file, Drive, or the launch tracker ticket\n- **Spec/design doc** — if separate\n- **Marketing plan** — if there is one (hands off to marketing-claims-review if substantial)\n- **Launch date** — for urgency calibration\n- **Launch tracker ticket** — if connected, pull it for context and comments\n\nIf Jira/Linear MCP is connected, pull the ticket history — often there's context in earlier comments that the PRD doesn't capture.\n\n### Step 2: Understand what's launching\n\nBefore the checklist, answer in plain English:\n\n- What does this thing do?\n- Who uses it — existing users, new users, a new segment?\n- What's new vs. what's an extension of something already reviewed?\n- Any new data, new vendors, new claims, new jurisdictions?\n\n**AI detection — run before the framework walk.** Check whether this launch uses\nAI in any form: a third-party model, an internally built model, an AI-powered\nvendor feature, automated scoring or classification, generative content,\nrecommendations, predictions. Look for this even if the PRD doesn't label it\n\"AI\" — words like \"intelligent\", \"automated\", \"personalized\", \"generated\",\n\"suggested\" are tells.\n\nIf AI component detected → flag it, then run `the “Use Case Triage” workflow [feature]`\nalongside the framework walk. Category 8 below handles the detail; this flag\nensures it's never skipped even if the PRD is vague.\n\n### Step 3: Walk the framework\n\nFor each category in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Review framework. If the team doesn't have one, use the 8-category default below. The categories are stable framing concepts; within each category, research the regulatory regimes applicable to the product's sector, audience, and jurisdictions before calibrating severity. What blocks in one jurisdiction or sector may be routine in another — your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) captures the team's calibration.\n\n| # | Category | Key question | Auto-skip if |\n|---|---|---|---|\n| 1 | **Contractual commitments** | Does this conflict with any customer-facing promise (ToS, SLA, marketing)? | No customer-facing changes |\n| 2 | **Privacy** | New data collection, new purpose, new sharing? | No data changes |\n| 3 | **Security** | New attack surface, new data at rest, new access patterns? | UI-only, no backend change |\n| 4 | **IP** | Third-party code/content? Open-source license check? Outputs that could infringe? | No new dependencies, no user-generated content |\n| 5 | **Third-party** | New vendor, partner, or integration? | No new external parties |\n| 6 | **Regulatory** | Does this touch a regulated sector, audience, or jurisdiction? Research the applicable regimes. | Same users, same sectors, same jurisdictions as existing product |\n\n> **No silent supplement.** If a research query to the configured legal research tool (Westlaw, CourtListener, regulator sites, or firm platform) returns few or no results for a regime, enforcement precedent, or regulator guidance, report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [regime / topic]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against the issuing authority before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution tiering.** Tag every citation in the review with its source. For model-knowledge citations, use one of three tiers rather than a single blanket \"verify\" tag:\n>\n> - `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., FTC Act § 5, GDPR Art. 33, CCPA § 1798.100). Still verify before relying on it to clear a launch, but lower priority.\n> - `[verify]` — model-knowledge citations that are real but should be verified: specific implementing regulations, agency guidance, enforcement actions, case holdings, thresholds, effective dates, post-2023 amendments.\n> - `[verify-pinpoint]` — pinpoint citations (specific subsection letters, volume/page numbers, paragraph numbers) carry the highest fabrication risk and should ALWAYS be verified against a primary source.\n>\n> Tool-retrieved citations keep their source tag (`[Westlaw]`, `[CourtListener]`, `[regulator site]`, or the MCP tool name); web-search citations remain `[web search — verify]`; user-supplied citations (from the PRD or seed materials) remain `[user provided]`. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n>\n> `[platform policy — verify against live docs]` — platform rules (Apple App Store Review Guidelines, Google Play policies, Meta / Snap / TikTok creator rules, ESRB / PEGI descriptors, card-network rules, app-store in-app-purchase policies) cited without fetching the live page. Never use `[settled]` for a platform policy — these change without notice and the model's snapshot is almost always stale. If the launch hinges on a platform rule, fetch the current policy page in-session before relying on it.\n| 7 | **Marketing claims** | Any claims that need substantiation? | No marketing component |\n| 8 | **AI governance** | Does this use AI in any form? Is the use case in the registry? AIA done? Vendor AI terms reviewed? | No AI component detected in Step 2 |\n\n**For each category, output:**\n\n```markdown\n### [N]. [Category]\n\n**Checked:** [what you looked at]\n**Finding:** [Clear | Needs work | Blocker | Skipped]\n**Detail:** [what the issue is, if any — specific to the PRD, not generic]\n**Calibration:** [per the config your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — this is usually an FYI / usually needs X / usually blocks]\n**Action:** [what has to happen, who owns it, by when]\n```\n\n**Auto-skip honestly.** If a category doesn't apply, say so with a one-line reason. Don't pad.\n\n**Sector hints.** The 8-category framework above is enterprise-SaaS-shaped. If the launch involves any of the sectors below, add the overlay: ask the overlay question alongside the base-framework question for each affected category, and surface the sector-specific regime before calibrating severity. A launch that checks all 8 boxes but misses a sector regime still ships with a hole.\n\n| Sector | Overlay regimes to surface |\n|---|---|\n| **Children / minors** | COPPA (US — operators of services directed to children under 13 or with actual knowledge), CA AADC / state age-appropriate design codes, platform age ratings (ESRB, PEGI), addictive-design scrutiny (NY Safe for Kids Act, CA SB 976 and analogs), FTC endorsement guides for kid-directed influencers |\n| **Gaming / loot boxes / in-game currency** | Loot-box odds disclosure (CA AB 2476-style, Chinese / Korean / Belgian / Dutch regimes), ESRB / PEGI descriptors (In-Game Purchases, Loot Boxes, Real Gambling), state gambling law (games-of-chance vs. games-of-skill lines, sweepstakes promotions law), FTC dark-patterns guidance, platform-store policies (Apple, Google, console) |\n| **Financial / fintech** | GLBA (NPI, Safeguards Rule, Reg P), state money transmission licensing (MTLs across ~50 states + DC), CFPB UDAAP, state UDAP, bank-partner sponsorship requirements and \"true lender\" exposure, Reg E / Reg Z where applicable, FINRA if brokerage |\n| **Health** | HIPAA (if CE or BA), FDA SaMD / clinical decision support / general wellness exemption, state health-privacy (WA MHMDA, NV SB 370, CT HIPAA-analog), FTC Health Breach Notification Rule for non-HIPAA entities |\n| **Education** | FERPA (if school or school-acting service provider), state student-privacy (NY Ed Law 2-d, IL SOPPA, CA SOPIPA + AB 1584), COPPA if K-12 data under 13 |\n| **Employment / HR tech** | Title VII, EEOC guidance on AI in hiring, ADA, state AI-hiring laws (IL AIVIA, NYC Local Law 144, CA / CO / UT / NJ analogs under consideration or enacted), state biometric laws (IL BIPA, TX / WA analogs) for video-interview and keystroke products, FCRA for background / verification products |\n| **Government / public sector** | FedRAMP (Low / Moderate / High), FAR / DFARS, CMMC where applicable, state-level equivalents (StateRAMP), CJIS for law-enforcement data, IRS Publication 1075 for tax data, StateRAMP and state procurement rules |\n| **Consumer / retail / marketing** | FTC Act § 5, Made-in-USA rule, Green Guides, CAN-SPAM, TCPA (with TCPA-Shaken/Stir for calls), state auto-renewal (ROSCA, CA ARL, NY GBL § 527-a [consumer] or GOL § 5-903 [B2B services] — verify which applies), state sweepstakes/promotions law |\n\nIf a sector hint fires and no dedicated category in the base framework covers it, insert it as a category (e.g., \"6a. Sector overlay — children / COPPA + CA AADC\"). Don't let it disappear into category 6 Regulatory as an afterthought; the sector regime often supplies the controlling floor, not a footnote.\n\n### Step 4: Calibrate severity\n\nFor each finding, check against the calibration table in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile):\n\n- If it matches a \"usually FYI\" pattern → note it, don't block\n- If it matches \"usually requires work\" → specify the work, estimate timeline from the table\n- If it matches \"usually blocks\" → flag prominently, route per escalation table\n- If it's **novel** (not in the table) → say so explicitly: \"This doesn't match any pattern in the calibration — needs a human call\"\n\n### Step 5: Assemble the review\n\nFormat per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Launch review process → output format. Prepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`). If no house format is specified:\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n# Launch Review: [Feature name]\n\n**Reviewed:** [date] | **Launch date:** [date] | **Reviewer:** [name]\n**PRD:** [link] | **Ticket:** [link if connected]\n\n---\n\n## Bottom line\n\n[One paragraph: can this ship? What has to happen first?]\n\n**Call:** [Clear to ship | Ship with conditions | Blocked pending X | Needs escalation]\n\n> **Before emitting a \"Clear to ship\" or \"Ship with conditions\" call:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n>\n> > Clearing a launch is a legal act — once the product ships, the company is committed to the legal posture documented here. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n> >\n> > [Generate a 1-page summary: the launch, the findings by category, any open questions, the residual risk after conditions, and the three things to ask the attorney before the launch goes out.]\n> >\n> > If you need to find a lawyer: your professional regulator's referral service is the fastest starting point (state bar in the US; SRA/Bar Standards Board in England & Wales; Law Society in Scotland/NI/Ireland/Canada/Australia; or your jurisdiction's equivalent).\n>\n> Do not proceed past this gate to a \"Clear to ship\" or \"Ship with conditions\" call without an explicit yes. \"Blocked pending X\" and \"Needs escalation\" do not require the gate — those are review calls, not clearances.\n\n---\n\n## Findings by category\n\n[All the category blocks from Step 3 — skip-noted categories at the bottom]\n\n---\n\n## Action items\n\n| # | Item | Owner | Due | Blocking? |\n|---|---|---|---|---|\n| 1 | [specific] | [PM/eng/legal] | [date] | Yes/No |\n\n---\n\n## Escalations\n\n[If any — who, why, drafted per escalation skill]\n\n---\n\n## Notes for next time\n\n[If this launch surfaced a pattern that should update the calibration table]\n\n---\n\n## Citation check\n\nAny cases, statutes, regulations, or enforcement actions referenced in this review were generated by an AI model and have not been verified against a primary source. Before relying on a citation in a launch decision, verify it against a legal research tool (Westlaw, CourtListener, or your firm's research platform) for accuracy, good law status, and current enforcement posture. Fabricated or misquoted citations in launch reviews can steer the business wrong. Source tags on each citation (e.g., `[Westlaw]`, `[web search — verify]`) show where it came from; `verify` tags carry higher fabrication risk and should be checked first.\n```\n\n### Step 6: Produce BOTH outputs — the privileged memo AND the redacted ticket comment\n\n⚠️ **Privilege warning:** Posting the full privileged memo to a Jira/Linear ticket that is widely shared with engineering, PM, and other non-legal roles may waive privilege. Don't paste the full memo into a broadly-shared ticket.\n\n**Both of the following are REQUIRED outputs of this skill.** Neither is optional. Print them in the order below, with a clear divider between them so the user cannot miss the redacted block.\n\n**Output 1 — Privileged launch review memo.** The full analysis assembled in Step 5: work-product header, bottom line, findings by category with risk rationale, action items, escalations, notes for next time, citation check. This is internal legal work product. Keep it in your matter file (Drive, DMS, or wherever your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) says review docs go). Distribute only to people inside the privilege circle.\n\n**Output 2 — Redacted ticket-comment block — SAFE TO POST TO TRACKER.** After the memo, with a clear `---` divider and the header `## SAFE TO POST TO TRACKER (non-privileged)`, produce a short comment block containing ONLY:\n\n- **Launch status:** green / yellow / red (i.e., Clear to ship / Ship with conditions / Blocked pending X / Needs escalation)\n- **Conditions as action items:** each condition is a bullet, written as an instruction to the PM/eng (\"add PIA link to ticket before ship\", \"remove 'most accurate' language from homepage copy\"). No legal reasoning.\n- **Deadline per condition.**\n- **Owner per condition.**\n\nThe redacted block contains NO work-product / privilege header, NO risk rationale, NO internal legal discussion, NO regulatory citations, NO escalation notes. If a condition's phrasing would leak the underlying legal theory (\"retaliation risk\"), rewrite it as the action (\"route to GC before term date\").\n\nExample divider and block:\n\n```markdown\n---\n\n## SAFE TO POST TO TRACKER (non-privileged)\n\n**Launch status:** Blocked pending conditions below.\n\n**Conditions:**\n- [ ] Attach completed PIA to ticket — Owner: [PM] — Due: [date]\n- [ ] Remove \"most accurate on the market\" copy from homepage draft — Owner: [Marketing] — Due: [date]\n- [ ] Confirm with GC before changing retention window — Owner: [PM] — Due: [date]\n```\n\nPaste Output 2 (and only Output 2) to the tracker. Link Output 1 only to the people inside the privilege circle who need to read the full analysis.\n\n## Handoffs\n\n- **To marketing-claims-review:** If there's a substantial marketing component, hand off the claims section.\n- **To feature-risk-assessment:** If a finding is complex enough to need its own doc (e.g., novel AI feature, children's product), spawn a deeper assessment.\n- **To privacy:** If the launch touches personal data, run `the “Use Case Triage” workflow [feature]`. If triage returns PIA REQUIRED or DPIA MANDATORY, run `the “PIA Generation” workflow [feature]`. Don't just note \"PIA needed\" — trigger it.\n- **To AI governance:** If an AI component was detected in Step 2, run `the “Use Case Triage” workflow [feature]`. If triage returns CONDITIONAL, run `the “AIA Generation” workflow [feature]`. If a new AI vendor is involved, run `the “Vendor Ai Review” workflow [vendor agreement]`.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't replace a conversation with the PM. Often the PRD is wrong or out of date — the review surfaces questions, a human asks them.\n- It doesn't approve the launch. It informs the approval.\n- It doesn't retroactively calibrate. If this launch turns out fine (or badly) in a way that should update the calibration table, a human updates your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).", + }, + { + id: "builtin-cfl-product-marketing-claims-review", + title: "Marketing Claims Review", + practice: "Product", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “marketing-claims-review” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /marketing-claims-review\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → Marketing claims standards.\n2. Apply the claim taxonomy and review workflow below.\n3. Extract every claim. Classify: puffery / factual / comparative / implied / absolute.\n4. For each non-puffery claim: substantiation check, suggested fix.\n5. Output: claim-by-claim with calls, suggested revision if short enough.\n\n```\nthe “Marketing Claims Review” workflow\n[paste landing page copy]\n```\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nMarketing wants to say the product is the best. Legal needs it to be true, or at least not provably false. This skill finds the claims that will get a demand letter from a competitor or an inquiry from a regulator, and suggests how to keep the energy while fixing the exposure.\n\n## Load standards\n\nRead your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → `## Marketing claims`:\n- Comparative claims policy (allowed with substantiation / discouraged / never)\n- Substantiation standard (what's required before a claim ships)\n- Common rejected claims (learn from history)\n\n## Research the applicable standards before clearing copy\n\nResearch the currently operative advertising and substantiation standards for the applicable jurisdictions and media (for example, FTC, NAD, state UDAP regimes, sector regulators for healthcare / financial / children's products, and platform-specific policies). Identify what substantiation the *specific claim* requires — who measured it, when, sample size, apples-to-apples basis — not just whether *some* substantiation exists on file. Flag implied claims and comparative claims for heightened scrutiny. Verify currency: endorsement and review guides have been updated recently and continue to evolve. Cite primary sources with pinpoint references. If you cannot verify the current standard, flag for attorney verification — do not state a rule you haven't confirmed.\n\n> **Only cite the standards that apply to the specific claims under review.** A blanket list of every FTC guideline, NAD practice note, or sector rule makes the load-bearing ones invisible. Do not cite the Endorsement Guides (16 CFR Part 255) unless the copy contains an endorsement, testimonial, or influencer content. Do not cite disclosure-overlay rules unless a claim in the asset triggers the overlay. Do not cite a sector regulator unless the copy targets or implicates that sector. A standard earns its place in the output by mapping to a specific quoted claim; otherwise drop it.\n\n> **No silent supplement.** If a research query to the configured legal research tool returns few or no results for the applicable standard (FTC rule, NAD decision, state UDAP, sector rule, platform policy), report what was found and stop. Do NOT fill the gap from web search or model knowledge without asking. Say: \"The search returned [N] results from [tool]. Coverage appears thin for [standard / jurisdiction]. Options: (1) broaden the search query, (2) try a different research tool, (3) search the web — results will be tagged `[web search — verify]` and should be checked against the issuing authority before relying, or (4) flag as unverified and stop. Which would you like?\" A lawyer decides whether to accept lower-confidence sources.\n>\n> **Source attribution tiering.** Tag every citation with its source. For model-knowledge citations, use one of three tiers rather than a single blanket \"verify\" tag:\n>\n> - `[settled]` — stable, well-known statutory and regulatory references unlikely to have changed (e.g., FTC Act § 5, Lanham Act § 43(a) as a concept). Still verify before approving copy, but lower priority.\n> - `[verify]` — model-knowledge citations that are real but should be verified: specific FTC enforcement actions, NAD decisions, state UDAP statutes, sector-specific rules, platform policies, case holdings, thresholds, effective dates, recent updates (the Endorsement Guides and disclosure rules update frequently).\n> - `[verify-pinpoint]` — pinpoint citations (specific subsection letters, CFR subpart references, case paragraph numbers) carry the highest fabrication risk and should ALWAYS be verified against a primary source.\n>\n> Tool-retrieved citations keep their source tag (`[Westlaw]`, `[CourtListener]`, `[FTC site]`, `[NAD]`, `[platform policy]`, or the MCP tool name); web-search citations remain `[web search — verify]`; user-supplied citations (from substantiation files) remain `[user provided]`. The tiering surfaces the real verification work — a reader who verifies everything verifies nothing. Never strip or collapse the tags.\n\n## Claim taxonomy\n\nThe categories below are structural patterns the reviewer should be able to recognize. Whether a given phrase is actionable depends on the currently operative rule in the applicable jurisdiction, the specific substantiation available, and the audience — research that before concluding.\n\n### Vague / subjective claims\n\nSubjective assertions with no measurable content. Whether they are actionable depends on jurisdiction, context, and audience — research before concluding.\n\n| Example |\n|---|\n| \"The best way to manage your projects\" |\n| \"You'll love it\" |\n| \"Revolutionary\" |\n\n### Specific factual claims\n\nMeasurable, specific, a reasonable person might rely on it.\n\n| Example | Substantiation to look for |\n|---|---|\n| \"50% faster than [competitor]\" | Benchmark data, disclosed methodology, date |\n| \"Trusted by 10,000 companies\" | Actual count (not cumulative signups — *currently* trusted) |\n| \"Saves 5 hours per week\" | Study or customer data, disclosed sample |\n| \"Enterprise-grade security\" | What does that mean? SOC 2? Spell it out or it's a promise |\n| \"HIPAA compliant\" | BAA available, actually configured for it — this is a contractual promise |\n\n### Comparative claims (heightened scrutiny)\n\nNaming a competitor or implying one. Research the applicable rules for comparative advertising in the relevant jurisdictions and media before clearing.\n\n| Example | Fix pattern |\n|---|---|\n| \"Faster than Slack\" | Either name Slack with head-to-head data you can defend, or abstract to \"faster than legacy chat tools\" with substantiation |\n| \"The only platform that does X\" | False if anyone else does X — \"The first platform to...\" (if true) or drop \"only\" |\n| \"[Competitor] can't do this\" | Show your feature. Let the viewer compare. |\n\nPer your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) — if comparative claims are \"never,\" flag all of them. If \"allowed with substantiation,\" check for the substantiation.\n\n### Implied claims\n\nNot stated outright but a reasonable reader infers it. Research the treatment of implied claims under the applicable advertising regime — implied claims often carry the same substantiation burden as express ones.\n\n| Example | Implication | Fix |\n|---|---|---|\n| \"Finally, a secure alternative\" | Competitors are insecure | \"Finally, security you can verify\" |\n| Customer logos without context | These companies endorse us | \"Customers include...\" is fine; \"Trusted by...\" implies more |\n| \"Built for healthcare\" | HIPAA compliant | Clarify or qualify |\n\n### Absolute claims\n\nNo room for error. One counter-example makes them false. Research whether qualifications cure the issue in the applicable jurisdiction.\n\n| Example | Fix pattern |\n|---|---|\n| \"Never goes down\" | \"99.9% uptime\" (with SLA that defines it) |\n| \"100% accurate\" | A specific, substantiated percentage tied to a benchmark |\n| \"Guaranteed\" | Only if you actually offer a guarantee with terms — this creates warranty exposure |\n| \"Always\" / \"Every\" | \"Typically\" / \"Most\" |\n\n## The review\n\n### Step 1: Extract every claim\n\nRead the copy. List every sentence or phrase that asserts a fact, makes a comparison, or promises something. Ignore pure puffery in the list.\n\n### Step 2: Classify and check\n\nFor each claim:\n\n```markdown\n**Claim:** \"[exact quote]\"\n**Type:** [Specific factual | Comparative | Implied | Absolute]\n**Substantiation on file:** [Yes — link | No | Unknown]\n**Call:** [✅ Fine | ⚠️ Needs substantiation | ⚠️ Needs rewording | 🔴 Cut]\n**Suggested fix:** \"[alternative phrasing that keeps the energy]\"\n**Why:** [one line]\n```\n\n### Step 3: Check against the product\n\nDoes the product actually do what the copy says? Not a philosophical question — check the PRD or ask the PM.\n\nCommon drift: marketing copy written from an early spec, product changed, nobody updated the copy.\n\n### Step 4: Output\n\nPrepend the work-product header from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs` (it differs by user role — see `## Who's using this`).\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs]\n\n# Marketing Review: [Campaign/Asset name]\n\n**Reviewed:** [date]\n**Asset:** [landing page / email / ad / etc.]\n\n---\n\n## Summary\n\n[N] claims reviewed. [N]✅ [N]⚠️ [N]🔴\n\n**Ready to ship:** [Yes | With changes below | No — rewrite needed]\n\n> **Before emitting \"Ready to ship: Yes\" (i.e., approving a claim for external use / publication):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is Non-lawyer:\n>\n> > Approving a marketing claim for publication is a legal act — once published, substantiation gaps and comparative-claim exposure become enforcement or competitor-challenge risk. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n> >\n> > [Generate a 1-page summary: asset, claims approved, claim types (specific factual / comparative / implied / absolute), substantiation on file for each, any implied claims flagged, and the three things to ask the attorney before the copy goes live.]\n> >\n> > If you need to find a lawyer: your professional regulator's referral service is the fastest starting point (state bar in the US; SRA/Bar Standards Board in England & Wales; Law Society in Scotland/NI/Ireland/Canada/Australia; or your jurisdiction's equivalent).\n>\n> Do not proceed past this gate to \"Ready to ship: Yes\" without an explicit yes. \"With changes below\" and \"No — rewrite needed\" do not require the gate — those are review calls, not approvals.\n\n---\n\n## Claim-by-claim\n\n[All the claim blocks from Step 2, grouped: 🔴 first, then ⚠️, then ✅]\n\n---\n\n## Suggested revision\n\n[For short assets — under 50 words, or a tweet, headline, one-liner, tagline, short ad — the output in this block is the actual revised copy with the fixes applied inline, not a description of what changed. The reader should be able to copy-paste this block into the asset.\nFor longer assets (>50 words but <300 words), show the revised copy with fixes applied inline.\nFor longer assets (300+ words), summarize the changes as a bulleted diff (\"Strip Claim 1. Rewrite Claim 3 to drop 'any.' Soften Claim 4 for regulated-domain risk.\") rather than pasting the whole asset.\nA meta-description of changes is never an acceptable output for a short asset — when the asset is one line, the output should BE the revised one line.]\n\n---\n\n## Substantiation needed before ship\n\n| Claim | Need | From whom |\n|---|---|---|\n| [claim] | [data type] | [PM / data team / eng] |\n\n---\n\n## Citation check\n\nAny FTC rules, NAD decisions, state UDAP statutes, sector regulations, or platform policies cited in this review were generated by an AI model and have not been verified against a primary source. Before relying on a specific rule to clear or reject copy, verify it against a legal research tool (Westlaw, CourtListener, or your firm's research platform) for accuracy and current effective date — endorsement guides, platform rules, and state UDAP regimes all update frequently. Source tags on each citation (e.g., `[FTC site]`, `[web search — verify]`) show where it came from; `verify` tags carry higher fabrication risk and should be checked first.\n```\n\n## Disclosure overlays\n\nCopy that involves any of the fact patterns below sits inside an additional disclosure regime. Research the currently operative disclosure requirements in the applicable jurisdictions (including any platform policies and sector-specific rules) and verify currency — these regimes are updated frequently.\n\n- **Testimonials / reviews** — material connections between the speaker and the advertiser are typically disclosable; research the current form and placement rules\n- **Influencer content** — research the current tagging, clarity, and conspicuousness requirements for the channel and audience\n- **\"Results may vary\" / atypical results** — research whether a disclosure (and what form) is required when shown results aren't representative\n- **Free trial / auto-renewal / negative option** — research the current conspicuousness and consent requirements for auto-conversion terms\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- It doesn't write the marketing. It fixes what's wrong with it. The suggested rewrites keep the energy, but the marketer owns the voice.\n- It doesn't substantiate claims. It identifies which ones need it and who has the data.\n- It doesn't review design or imagery — words only. If an image implies a claim (competitor logo with a red X through it), flag it, but visual review is a human judgment.", + }, + { + id: "builtin-cfl-regulatory-comments", + title: "Comments", + practice: "Regulatory", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “comments” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /comments\n\n## Purpose\n\nNPRMs have deadlines. The decision to file a comment or not is an attorney\ncall — but the deadline disappearing without a logged decision is the risk.\nThis skill surfaces open comment periods and records decisions.\n\n## Load context\n\nthe current project's documents → all tracked NPRMs and their status.\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → default comment decision owner.\n\n## Default view — open comment periods\n\n```markdown\n## Comment Period Tracker — [date]\n\n### ⏰ Deadline in <14 days\n\n| ID | Regulation | Deadline | Days left | Decision | Owner |\n|---|---|---|---|---|---|\n| CMT-001 | [name] | [date] | [N] | Undecided | [owner] |\n\n### 🟡 Open (>14 days)\n\n[same table]\n\n### Recently decided\n\n| ID | Regulation | Decision | Rationale |\n|---|---|---|---|\n| CMT-002 | [name] | Not filing | [reason] |\n\n---\n\n**Total open:** [N] **Undecided with deadline <30 days:** [N]\n```\n\n## Log a decision\n\n```\nthe “Comments” workflow --decide CMT-001\nDecision: [filing / not-filing / waived]\nRationale: \"[brief — e.g., 'Rule doesn't apply to our model' or 'Filing comment on Section 3']\"\n```\n\nUpdates tracker. If decision is \"filing\": prompt for filing deadline reminder\n(comment deadline minus 5 business days for internal review).\n\n## Notifications\n\nOn first detection of an NPRM (populated by reg-feed-watcher): Slack DM to\ncomment decision owner if Slack MCP is configured and `owner_slack` is set.\n\nReminder at 14 days before deadline if decision is still \"undecided.\"\nReminder at 3 days before deadline if still undecided — elevated urgency.\n\n## Consequential-action gate (submit a regulatory comment / respond to a regulator)\n\n**Before logging a decision as \"filing\" — and always before producing a comment letter or regulator-response draft for submission:** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Submitting a comment or response to a regulator has legal consequences. It's a public statement of the company's position, it's on the record in the rulemaking or enforcement matter, and positions taken here bind the company and can be used against it in subsequent proceedings. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - The rulemaking or inquiry (regulator, docket, deadline)\n> - What the proposed comment/response says and on what sections\n> - Open questions and what's unresolved\n> - What could go wrong (adverse admissions, inconsistent prior positions, coordination-of-comment concerns with trade associations)\n> - What to ask the attorney (should we file at all; should we file jointly through a trade group; are there positions we should not take)\n>\n> If you need to find a lawyer: your professional regulator's referral service is the fastest starting point (state bar in the US; SRA/Bar Standards Board in England & Wales; Law Society in Scotland/NI/Ireland/Canada/Australia; or your jurisdiction's equivalent).\n\nDo not log a \"filing\" decision or produce a submission-ready draft past this gate without an explicit yes. Tracking views, deadline reminders, and \"not-filing / waived\" decisions do not require the gate.\n\n---\n\n## What this skill does not do\n\n- Draft the comment letter. That is a separate attorney task.\n- Make the filing decision. It tracks the decision; the attorney makes it.\n- Monitor post-comment activity. Once a decision is filed, this tracker's job\n is done — follow the rulemaking through `the “Reg Feed Watcher” workflow`.\n\n> The `comment-decision` `gap_type` semantics, the per-send Slack confirmation rule, and the comment-tracker.yaml schema live in the **gap-surfacer** reference skill — load it before doing substantive work.", + }, + { + id: "builtin-cfl-regulatory-gap-surfacer", + title: "Gap Surfacer", + practice: "Regulatory", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “gap-surfacer” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# Gap Surfacer\n\n> Owner notifications: on by default. To opt an owner out, leave `owner_slack` empty.\n\n## Per-send confirmation — no exceptions\n\nBefore sending ANY Slack message (assignment notice, overdue reminder, bulk notification, status report):\n\n1. Show the user exactly what you're about to send and to whom: \"I'm about to send this to [N] people: [preview].\"\n2. Wait for an explicit yes.\n3. If the message contains any citations, deadlines, or compliance conclusions, add: \"⚠️ The citations in this message are unverified — I'm not confirming they're current before sending. Do you want me to add a 'verify before acting' line?\"\n4. Never send without the confirm. Not on a cadence. Not in a batch. Not because it was sent yesterday.\n\nAuto-send without confirmation is the most irreversible action in this plugin, sending content this plugin's own footer says may be wrong, to people who have no way to check. That combination does not get to skip review.\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nGaps get found and then forgotten. This skill tracks them until they're closed\nand notifies the people responsible for closing them.\n\n## The tracker\n\nLives at the current project's documents:\n\n> **Note on comment-tracker.yaml:** the current project's documents is a sibling file owned by the comments skill. It is written to by reg-feed-watcher (which logs NPRMs automatically) and the comments skill (which tracks user-initiated comment decisions). This skill does not read or cross-reference it. If you modify the comment-tracker schema, update both actual consumers.\n\n```yaml\ngaps:\n - id: GAP-001\n requirement: \"[what the reg requires]\"\n regulation: \"[name + cite]\"\n policy_affected: \"[name or 'new policy needed']\"\n gap_type: \"partial\" # none | partial | full | new-policy | watch | comment-decision\n owner: \"[name from policy index]\"\n owner_slack: \"[Slack user ID or handle, if known]\"\n opened: 2026-03-01\n due: 2026-06-01 # reg effective date, internal deadline, or comment deadline\n status_verified: true # false if upstream policy-diff could not confirm the rule is in force; unverified items never hit 🔴 Overdue\n status: \"open\" # open | in-progress | closed | risk-accepted\n notified: false # set to true after assignment notification sent\n resolution: \"\" # filled on close\n```\n\n**Never classify a gap as Overdue on an unverified rule.** The 🔴 Overdue classification means \"we missed a binding deadline.\" If the rule's status is unverified (policy-diff set `status_verified: false`, or the rule is >12 months old / past its applicability date with no currency confirmation), the deadline may not be binding. Use 🟡 \"Review needed\" and note: \"If this rule is in force as published, this would be overdue by [N] days. Verify rule status before escalating.\" Route unverified-rule items to `watch`, not to the active overdue/due-soon buckets; the `watch` revisit cadence forces a rule-status check before the item can re-surface as a compliance gap.\n\n**`gap_type` semantics:**\n\n| Value | Meaning | Typical reminder cadence |\n|---|---|---|\n| `none` | Policy already covers the requirement. Logged for audit trail only. Should be rare — if most entries are `none`, the diff is probably running against the wrong policy. | No auto-reminder. |\n| `partial` | Policy addresses the topic but doesn't fully cover the new requirement. Needs an amendment. | 30 days before due. |\n| `full` | Policy contradicts or silently omits the new requirement. Needs a rewrite or new section. | 30 days before due. |\n| `new-policy` | No existing policy covers this. Policy needs to be drafted. | 30 days before due. |\n| `watch` | Forward-looking item — ANPR, RFI, proposed rule not yet final. No compliance obligation today; policy work waits for the final rule. `due:` is a revisit date (typically the NPRM expected date or a one-year horizon), not a compliance deadline. | No auto-reminder; re-evaluate when an NPRM drops or at the revisit date. |\n| `comment-decision` | Pre-rulemaking comment decision pending — ANPR or NPRM where the team is deciding whether to file a comment. `due:` is the comment deadline. | 21 days before due (tighter than compliance gaps because comment-drafting windows are short). |\n\nA `watch` or `comment-decision` entry is not a compliance gap — it's a tracking artifact for pre-rule items that the watch skill and comments skill produce. Surface them in the status report in their own bucket so counsel reading at 7am can tell at a glance which items are \"fix this before a regulator notices\" vs. \"keep an eye on this.\"\n\n## Modes\n\n### Mode 1: Ingest from policy-diff\n\nWhen policy-diff finds gaps, append them to gap-tracker.yaml. De-dupe — same\nrequirement + same policy = same gap, don't double-count.\n\n**After ingesting, notify the owner:**\n\nIf Slack MCP is available and `owner_slack` is set:\n\nSend a Slack DM to the gap owner — but only after the per-send confirmation at the top of this file. Preview the message to the user, wait for an explicit yes, then send:\n\n```\n📋 New compliance gap assigned to you\n\nGap: [GAP-ID] — [requirement, one sentence]\nRegulation: [name + link]\nPolicy affected: [policy name or \"new policy needed\"]\nDue: [reg effective date]\n\nView full gap tracker: the “Gaps” workflow\n```\n\nSet `notified: true` in the tracker entry after sending.\n\nIf Slack MCP is not available: note in the status report that owner notification\nwas not sent and flag for manual follow-up.\n\n### Mode 2: Status report\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Open Gaps — [date]\n\n### Bottom line\n\n[N gaps need action by [date] — top 3: X, Y, Z]\n\n### 🔴 Overdue\n\n| ID | Requirement | Policy | Owner | Due | Days over |\n|---|---|---|---|---|---|\n\n### 🟠 Due in <30 days\n\n[same]\n\n### 🟡 Open\n\n[same]\n\n### 👀 Watch items (forward-looking — pre-rule)\n\n[Pre-rule tracking — `watch` and `comment-decision` entries. These are not\ncompliance gaps. Surface separately so the overdue / due-soon bands contain\nonly real compliance deadlines.]\n\n| ID | Item | Type (ANPR/NPRM/RFI) | Comment deadline | Owner |\n|---|---|---|---|---|\n\n### In progress\n\n[same]\n\n### Recently closed\n\n[last 5, with resolution]\n\n---\n\n**Oldest open gap:** [ID], [N] days\n**Gaps by owner:** [breakdown]\n**Owner notifications sent:** [N] / [N total gaps]\n\n---\n\n**Next step for each open gap:** `the “Policy Redraft” workflow` produces a marked-up policy redraft with `[verify]` tags and a change summary. It's a proposal for the policy owner's review — not a direct edit to source documents.\n\n---\n\n**Verify citations before relying on them.** Regulation citations in this tracker were AI-generated upstream (by reg-feed-watcher and policy-diff) and have not been checked against a primary source. Before closing or risk-accepting a gap — or citing one in an attestation, board report, or regulator response — confirm the underlying rule against Westlaw, your firm's research platform, or the issuing authority's website. AI-generated regulatory citations are sometimes fabricated, misquoted, or stale. Source tags carried forward from upstream (e.g., `[Federal Register]`, `[web search — verify]`) show where each citation originated; `verify` tags carry higher fabrication risk and should be checked first. Never strip the tags when surfacing gaps.\n```\n\n## Config-dependent fallbacks\n\nThis skill reads gap-response owners and the escalation path from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). When a value it needs is empty or still `[PLACEHOLDER]`:\n\n- **Gap-response triager missing:** leave assignment open and append to the output: \"No triager is set in `## Gap response process`. Assign one with `configure your Practice Profile (Account → Practice Profile) --redo` or by editing your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) so new gaps get routed.\"\n- **Owner unknown for a newly-ingested gap (no owner in policy library):** log the gap with `owner: [unassigned]` and append: \"[N] gaps were ingested without an owner because the policy library doesn't name one for the affected policy. Fill in the Owner column in the policy library to route them.\"\n- **Escalation path missing for an overdue material gap:** still report it as overdue, and append: \"No escalation path is set for material overdue gaps. Configure it with `configure your Practice Profile (Account → Practice Profile) --redo` or by editing your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\"\n\nSay nothing about config when the values are populated.\n\n**Due-date reminder logic (runs during status report and scheduled agent):**\n\nReminder cadence is a function of `gap_type` — compliance gaps get a 30-day heads-up, comment-decision items get 21 days (tighter because the drafting window is shorter), watch items get no auto-reminder (re-evaluate when an NPRM drops).\n\nFor each gap with status \"open\" or \"in-progress\":\n- `partial`, `full`, `new-policy`, `none`: if due date is within 30 days and a reminder has not been sent in the last 7 days, PREVIEW a Slack DM (subject \"⏰ Reminder: compliance gap due in [N] days\") and wait for per-send confirm before sending.\n- `comment-decision`: if comment deadline is within 21 days and a reminder has not been sent in the last 7 days, PREVIEW a Slack DM (subject \"💬 Comment-decision deadline in [N] days\") and wait for per-send confirm before sending.\n- `watch`: no auto-reminder. Revisit when the tracker is reviewed or an NPRM is logged for the same regulation.\n- If due date has passed on a compliance gap: flag as overdue in the report and PREVIEW a Slack DM — wait for per-send confirm before sending.\n- If comment deadline has passed on a `comment-decision` item and no comment was filed: flag as overdue, PREVIEW a Slack DM (wait for per-send confirm), and ask the owner to update to `risk-accepted` (deliberate no-comment) or `closed` (comment filed) with a note.\n- Record reminder timestamps in the tracker to avoid repeat nags.\n- Batch reminders still require per-send confirm — previewing \"you're about to send 12 DMs\" and waiting for yes counts; silently firing a batch does not.\n\n### Consequential-action gate (certify compliance)\n\n**Before closing a gap as resolved, or producing any output that certifies compliance with a regulatory requirement (internal attestation, board report, audit response, regulator response):** Read `## Who's using this` in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If the Role is **Non-lawyer**:\n\n> Certifying compliance — or closing a gap as resolved — has legal consequences. The certification can be used against the company if it's later shown to be wrong, and premature closure leaves exposure unaddressed. Have you reviewed this with an attorney? If yes, proceed. If no, here's a brief to bring to them:\n>\n> - The gap (requirement, source, what the policy diff found)\n> - What the proposed resolution does and does not cover\n> - Any residual gap or ambiguity\n> - Open questions and what's unresolved\n> - What could go wrong (overbroad certification, unresolved residual obligation, inconsistent prior position)\n> - What to ask the attorney (is this truly closed; should we risk-accept with rationale instead; do we need outside-counsel concurrence)\n>\n> If you need to find a lawyer: your professional regulator's referral service is the fastest starting point (state bar in the US; SRA/Bar Standards Board in England & Wales; Law Society in Scotland/NI/Ireland/Canada/Australia; or your jurisdiction's equivalent).\n\nDo not mark a gap closed or produce a compliance certification past this gate without an explicit yes. Status reports and tracking views do not require the gate.\n\n### Mode 3: Close a gap\n\n```\nthe “Gaps” workflow --close GAP-001\nResolution: \"Policy updated v2.3, approved [date]\"\n```\n\nUpdates status to closed, records resolution and close date.\n\n### Mode 4: Risk-accept a gap\n\nSometimes the answer is \"we're not going to fix this.\" That's a valid decision\n— but it should be documented.\n\n```\nthe “Gaps” workflow --accept GAP-002\nRationale: \"Requirement applies only to [condition we don't meet]. Revisit if [trigger].\"\nAccepted by: [name with authority]\n```\n\nStatus → risk-accepted. Stays in the tracker (not deleted) but falls out of\nthe open-gaps report.\n\n## Integration: reg-change-monitor agent\n\nThe agent's digest includes the gap count and oldest-open-gap age. If anything\ngoes overdue, that goes at the top of the digest. The agent also runs the\ndue-date reminder check and sends any outstanding Slack notifications.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\nIf the tracker surfaced more than ~10 open gaps, or any time the user asks: offer the dashboard (see your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs → Dashboard offer for data-heavy outputs`). Shape the offer for this output — counts by severity, a timeline of gaps by due date, and a sortable grid with owner, status, and last-touched date.\n\n## What this skill does not do\n\n- Close gaps on its own. Closing requires the resolution note and the human\n action that the note describes.\n- Send Slack notifications if the Slack MCP is not configured. Falls back to\n flagging in the status report.\n- Send more than one reminder per 7-day period per gap. Nag once, not constantly.", + }, + { + id: "builtin-cfl-regulatory-gaps", + title: "Gaps", + practice: "Regulatory", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “gaps” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /gaps\n\n1. Read the gap tracker at the current project's documents.\n2. If `--close`: mark gap closed with resolution note.\n3. If `--accept`: record the risk-acceptance rationale and acceptor, status → risk-accepted.\n4. Otherwise: report open gaps by age and materiality.\n\n> Detailed tracker schema, status-report format, owner-notification logic (per-send confirmation, no exceptions), reminder cadence, the close/risk-accept modes, and the consequential-action gate live in the **gap-surfacer** reference skill — load it before doing substantive work.", + }, + { + id: "builtin-cfl-regulatory-policy-diff", + title: "Policy Diff", + practice: "Regulatory", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “policy-diff” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /policy-diff\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → policy library index.\n2. Use the workflow below.\n3. Extract requirements from the reg. Match to indexed policies.\n4. Output: per-requirement gap analysis, which policy needs updating.\n\n---\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nA reg changed. You have policies. This skill finds which policies the change touches and what the gap is between \"what the reg now requires\" and \"what the policy says.\"\n\n## Load context\n\nyour USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → policy library index (policies, locations, owners).\n\n## Scope integrity\n\nIf the user asks you to exclude a policy section, requirement, or category from the diff:\n\n1. Do it — the user owns the scope.\n2. But flag it, loudly and permanently: \"⚠️ SCOPE LIMITATION: Section [X] excluded at user request. This diff does not reflect the full policy. Gaps in the excluded area are NOT identified.\" Above the header, carried to every downstream artifact.\n3. Hand the flag to `gap-surfacer`: \"This diff was scope-limited. Do not represent it as a complete compliance picture.\" Include the scope-limitation banner verbatim on any gap tracker entry derived from this diff.\n4. Note what the exclusion means: \"Excluding vendor management means the diff will show 'no policy addresses vendor management' — which is worse than showing the gap.\"\n\nA compliance artifact built on an undisclosed scope exclusion looks like concealment in discovery. The flag is the difference between \"we scoped the review\" and \"we hid the problem.\"\n\n## Workflow\n\n### Step 0: Verify rule status before you diff\n\nBefore diffing a rule against policy, confirm the rule is actually in force. Red flags that the rule may not be in force:\n\n- The applicability/compliance date has passed by more than 30 days but you have no confirmation it wasn't delayed\n- The rule is more than 12 months old\n- The rule is a politically contentious final rule (major rulemakings are frequently challenged)\n\nWhen you see a red flag, check (via research MCP, web search if enabled, or the Federal Register docket) for: delays, stays, injunctions, rescission proposals, vacatur, or amendments. If you can check and the rule is confirmed in force, proceed. If you cannot verify (no tools connected), emit this banner ABOVE the header, before any content:\n\n> `⚠️ RULE STATUS UNVERIFIED — I could not confirm this rule is currently in force. Final rules are frequently stayed, enjoined, delayed, or rescinded after publication. Do not treat any compliance date below as binding until you confirm the rule's status at the Federal Register docket or with outside counsel.`\n\nTag every due date in the output: `[due date per published rule — status unverified]`.\n\nRule-status uncertainty travels downstream. When handing off a gap to `gap-surfacer`, mark the item `status_verified: false` so it never gets routed to an Overdue bucket on the strength of a published date alone.\n\n### Step 1: Extract the new requirements\n\n**No silent supplement.** If the regulatory change text is partial or ambiguous and the fuller rule isn't available from the indexed source, stop and ask. Do NOT fill the gap from web search or model knowledge without asking. Say: \"I have [what you have]. To extract requirements accurately I'd need [what's missing]. Options: (1) paste the full text, (2) point me at the primary source, (3) search the web for the rule — results will be tagged `[web search — verify]` and should be checked against the issuing authority before relying, or (4) stop here. Which would you like?\" A lawyer decides whether to accept lower-confidence sources; Claude does not decide for them.\n\n**Source attribution.** Tag every citation — the regulatory citation, any cross-references, any policy excerpts — with where it came from: `[]` for items retrieved from a primary source, policy library, or MCP; `[web search — verify]` for items pulled from web search; `[model knowledge — verify]` for items recalled from the model's training data; `[user provided]` for items pasted in by the user. Items tagged `verify` carry higher fabrication risk and should be checked first. Never strip or collapse the tags in the output.\n\nRead the regulatory change. List each discrete new or changed requirement:\n\n| # | Requirement | Effective | Citation |\n|---|---|---|---|\n| 1 | [what it requires] | [date] | [section] |\n\nBe specific. \"Enhanced disclosure requirements\" is not a requirement. \"Must disclose X in Y format at Z point in the flow\" is.\n\n### Step 2: Map to policies\n\nFor each requirement, which indexed policy is closest?\n\n- Direct hit: policy explicitly covers this topic\n- Indirect: policy covers a related topic, this is a new sub-issue\n- No match: no policy addresses this — gap is \"policy doesn't exist\"\n\n### Step 3: Diff\n\nFor each direct or indirect hit, read the policy and compare:\n\n```markdown\n### Requirement [N]: [name]\n\n**New rule requires:** [requirement]\n\n**Our policy ([name], last updated [date]) says:**\n> \"[relevant excerpt]\"\n\n**Gap:** [None — policy already covers this | Partial — policy addresses X but not Y | Full — policy contradicts or doesn't address]\n\n**Change needed:** [specific — \"add a paragraph on X\" not \"update the policy\"]\n\n**Policy owner:** [from index]\n```\n\n### Step 4: No-match gaps\n\nRequirements with no policy match get called out separately:\n\n```markdown\n### New policy needed\n\nRequirement [N]: [requirement]\n\nNo existing policy covers this. Options:\n- Draft new policy (suggested owner: [whoever owns the closest topic])\n- Add to existing [related policy] as a new section\n- Determine this doesn't need a policy (one-off compliance, not ongoing)\n```\n\n## Branches by regulatory input type\n\n### Pre-rule branch (ANPR / RFI)\n\nIf the regulatory input is an ANPR or RFI (no imposed requirements), do NOT run a full gap-closure diff. Instead, produce a **pre-positioning analysis**:\n\n- Name the policies that will likely need to change once a final rule issues (not today).\n- Flag whether any of the ANPR's issue areas intersect with the company's practice in a way that warrants a comment letter.\n- Note the comment deadline and the team's comment-decision owner from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile).\n- Do NOT produce per-requirement \"no gap\" rows for an ANPR — there are no requirements to diff against. Produce one paragraph naming the future exposure and the policies it would touch.\n\n### Negative-finding branch (final rule / NPRM diffed against a policy that isn't the right target)\n\nIf every requirement in the extracted list comes out as \"no gap against [the named policy],\" do NOT produce the full per-requirement analysis — compress to a single short paragraph:\n\n```markdown\n## Policy Diff: [Regulation name] — [Policy name]\n\n[REGULATION] doesn't appear to require a change to [POLICY NAME]. [POLICY NAME]\n§[X] already covers [Y]. The policies this regulation actually touches are\n[other-policy-1] and [other-policy-2] — rerun `the “Policy Diff” workflow` against those.\n\nReview on [next cycle — e.g., \"at the next annual policy review\"] or if\n[trigger — e.g., \"the rule is finalized or amended\"].\n```\n\nOne paragraph, one recommendation, routing note. Don't repeat the \"no gap\" finding for every requirement — the summary table handles that. A negative finding against the wrong target policy is a routing problem, not a compliance analysis.\n\n### Gap branch (final rule / NPRM with at least one gap against the target policy)\n\nFull per-requirement analysis as specified below. The detailed diff format is for diffs that actually find gaps.\n\n## Output\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n## Policy Diff: [Regulation name]\n\n**Regulation:** [name, link]\n**Effective:** [date]\n**Requirements extracted:** [N]\n\n### Bottom line\n\n[N gaps need action by [date] — top 3: X, Y, Z]\n\n### Summary\n\n| # | Requirement | Policy affected | Gap | Owner |\n|---|---|---|---|---|\n| 1 | [short] | [policy name or \"none\"] | None/Partial/Full | [name] |\n\n### Detailed diffs\n\n[Each requirement block from Step 3]\n\n### New policies needed\n\n[From Step 4, if any]\n\n### No-gap requirements\n\n[List — useful to know what's already covered]\n\n---\n\n**Verify citations before relying on them.** The regulatory citations and policy references above were AI-generated and have not been checked against a primary source. Before acting on any requirement here, confirm the rule against Westlaw, your firm's research platform, or the issuing authority's website — check accuracy, effective date, and current status. AI-generated regulatory citations are sometimes fabricated, misquoted, or stale. Source tags on each requirement (e.g., `[Federal Register]`, `[web search — verify]`) show where the citation came from; `verify` tags carry higher fabrication risk and should be checked first.\n```\n\n## Config-dependent fallbacks\n\nThis skill reads the policy library index from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). When the index is empty or still `[PLACEHOLDER]`:\n\n- **Policy library empty:** flag every requirement as \"no policy match\" by default and append to the output: \"The policy library in your configuration is empty, so every requirement is flagged as a new-policy gap. If you have policies that address these requirements, add them to the library with `configure your Practice Profile (Account → Practice Profile) --redo` or by editing your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile), then re-run the diff.\"\n- **Owner missing for a matched policy:** leave the Owner cell blank in the summary and append: \"Policy owners aren't set for [list]. Assign them with `configure your Practice Profile (Account → Practice Profile) --redo` or by editing the policy library in your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) so gap-surfacer can route.\"\n\nSay nothing about config when the library is populated and owners are set.\n\n## Handoff\n\nTo gap-surfacer: every Partial or Full gap becomes a tracked item with owner and deadline.\n\n## Close with the next-steps decision tree\n\nEnd with the next-steps decision tree per your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Outputs`. Customize the options to what this skill just produced — the five default branches (draft the X, escalate, get more facts, watch and wait, something else) are a starting point, not a lock-in. The tree is the output; the lawyer picks.\n\n## What this skill does not do\n\n- Draft the policy updates. It identifies what needs updating; policy-drafting (or a human) drafts.\n- Interpret ambiguous regulatory text definitively. If the reg could be read two ways, say so and flag for counsel.", + }, + { + id: "builtin-cfl-regulatory-policy-redraft", + title: "Policy Redraft", + practice: "Regulatory", + prompt_md: "> Adapted for Mike from the Anthropic “claude-for-legal” skill “policy-redraft” (Apache-2.0).\n> Work from the current project's documents — call list_documents, read_document, and fetch_documents to load them; do not assume external CLM, e-signature, or document-storage connectors exist. Produce any downloadable file with the generate_docx tool. Use your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) for the firm's playbook positions, escalation matrix, and house style; if a position you need is not there, ask the user rather than assuming a default. Every output is a draft for attorney review — not legal advice.\n\n# /policy-redraft\n\n1. Load your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) → policy library index + practice profile.\n2. Use the workflow below.\n3. Gather inputs: the gap (from `the “Gaps” workflow` output or described directly), the current approved policy text, the rule text.\n4. Verify the rule is current (per the policy-diff rule-status check). If you can't verify, emit the `⚠️ RULE STATUS UNVERIFIED` banner.\n5. Produce a marked-up redraft of the affected policy section(s) — smallest-possible edit, `[verify]` tags carried through, inline comments explaining WHY each change was made.\n6. Output a Policy Redraft Memo. Write it to a new file named `[policy-name]-proposed-redraft-[YYYY-MM-DD].md` — never write to the source policy document.\n7. Do NOT close the gap in the tracker. The gap closes when the redraft is applied AND approved, which is the policy owner's action.\n\n---\n\n> This skill produces a **proposal**, not an edit. It writes to a new file with a clearly-marked draft filename. It never writes over a source policy document, and it never closes a gap in the tracker — the gap closes when the redraft is applied AND approved by the policy owner.\n\n## Matter context\n\n**Matter context.** Check `## Matter workspaces` in the practice-level your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). If `Enabled` is `✗` (the default for in-house users), skip the rest of this paragraph — skills use practice-level context and the matter machinery is invisible. If enabled and there is no active matter, ask: \"Which matter is this for? Run `the “Matter Workspace” workflow switch ` or say `practice-level`.\" Load the active matter's `matter.md` for matter-specific context and overrides. Write outputs to the matter folder at the current project's documents. Never read another matter's files unless `Cross-matter context` is `on`.\n\n---\n\n## Purpose\n\nGap-surfacer finds the gap. Policy-diff names what needs to change. This skill takes the next step and produces a marked-up redraft of the affected policy section — small, specific, flagged — as a first draft for the policy owner's review.\n\n## Hard guardrails — read these first\n\nThese are the load-bearing rules. If any of them would be violated, stop and ask.\n\n1. **This is a PROPOSAL, not an edit.** Never write directly to a source policy document. The output goes to a new file at `[policy-name]-proposed-redraft-[YYYY-MM-DD].md`, or into the matter workspace. Not `[policy-name].md`.\n2. **Never close the gap in the tracker.** Gaps close when the redraft is APPLIED AND APPROVED — that is the policy owner's action, not yours. If the user says \"close the gap now that you've redrafted it,\" decline: \"I produce the proposal. The gap closes when you've reviewed, applied, and approved the change. When that's done, tell me and I'll update the tracker.\"\n3. **\"Apply this for me\" is not in scope.** If the user asks you to apply the redraft to the source policy: \"I don't apply policy changes — that's the policy owner's action after review and approval. I produce the proposal. When it's been reviewed and approved, tell me and I'll update the gap tracker.\"\n4. **Confirm the policy version before redrafting.** If the user gives you a file, ask: \"Is this the approved version of the policy, and is it the latest? A redraft against an outdated policy creates divergence.\" If they paste text, trust but flag in the reviewer note.\n5. **Smallest-possible edit.** Strike a word before a sentence, a sentence before a paragraph, a paragraph before a section. Only touch sections affected by the gap. Don't restyle the policy.\n6. **Carry `[verify]` tags through.** Any effective date, threshold, citation, or requirement that came from model knowledge or an unverified source gets tagged in the redraft itself, not just in the memo.\n\n## Step 1: Gather inputs\n\nThree inputs are required. If any is missing, ask — don't infer.\n\n### 1a. The gap\n\nOne of:\n- A `GAP-ID` from the gap tracker — load the entry from the current project's documents (or the matter-level equivalent).\n- A gap described in the user's message — capture the requirement, the regulation, and the affected policy.\n- A diff summary pasted from `the “Policy Diff” workflow` output.\n\n### 1b. The current policy text\n\nOne of:\n- A file path — read it, then ask: \"Is this the approved version of the policy, and is it the latest? A redraft against an outdated policy creates divergence.\" Note the answer in the reviewer note.\n- Pasted text — trust but flag in the reviewer note: \"Policy text was pasted directly; I assumed it was the current approved version. Confirm before applying.\"\n- Neither — ask for one. Do not guess at the policy text from the gap tracker or from web search.\n\n### 1c. The rule text\n\nOne of:\n- The diff output (already has the rule extracted and tagged).\n- A fetched regulation — note the source with a provenance tag.\n- Pasted rule text from the user — tag `[user provided]`.\n\nIf the rule text is partial or ambiguous, apply the **no silent supplement** rule from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile): offer the user the options (paste full text, point at primary source, web-search-with-verify-tag, or stop), and wait.\n\n## Step 2: Verify the rule is current\n\nUse the same rule-status check pattern as `policy-diff`. Red flags that the rule may not be in force:\n\n- The applicability/compliance date has passed by more than 30 days with no confirmation it wasn't delayed.\n- The rule is more than 12 months old.\n- The rule is a politically contentious final rule (major rulemakings are frequently challenged).\n\nWhen you see a red flag, check (via research MCP, web search if enabled, or the Federal Register docket) for: delays, stays, injunctions, rescission proposals, vacatur, or amendments. If you can verify the rule is in force, proceed. If you cannot verify:\n\n> `⚠️ RULE STATUS UNVERIFIED — I could not confirm this rule is currently in force. Final rules are frequently stayed, enjoined, delayed, or rescinded after publication. Do not apply this redraft until you confirm the rule's status at the Federal Register docket or with outside counsel.`\n\nEmit that banner above the work-product header. Tag every effective/compliance date in the redraft as `[effective date per published rule — status unverified]`.\n\n## Step 3: Produce the redraft\n\nA marked-up version of the affected policy section.\n\n### Redline granularity — smallest possible edit\n\n- Strike a word before a sentence.\n- Strike a sentence before a paragraph.\n- Strike a paragraph before a section.\n- Only touch sections affected by the gap. Don't restyle the whole policy.\n\n### Conventions\n\n- Struck text: `~~struck text~~`\n- Inserted text: **inserted text**\n- Each change carries an inline comment explaining WHY — the rule, the cite, the gap being closed:\n\n > `[Change: added biometric identifiers to the PII definition per COPPA 2025 amendments, 16 CFR 312.2 (effective Apr 22 2026) [verify]]`\n\n- Any effective date, threshold, citation, or requirement that came from model knowledge or an unverified source gets a `[verify]` tag inline — not just in the change summary.\n- Carry source tags through from the diff: `[Federal Register]`, `[web search — verify]`, `[model knowledge — verify]`, `[user provided]`. Don't strip them when moving from the diff to the redraft.\n\n### Scope discipline\n\nIf a section of the policy isn't affected by the gap, leave it alone. A redraft that touches sections outside the gap looks like the AI opined on things it wasn't asked to opine on, and makes the review harder.\n\nIf you see a second gap while redrafting — a provision that's clearly out of step with the rule but wasn't in the original gap — don't silently fix it. Flag it in the reviewer note: \"While redrafting for [GAP-ID], I noticed [other provision] appears to have a related issue with [requirement]. Not included in this redraft. Consider a follow-on gap.\"\n\n## Step 4: Output — Policy Redraft Memo\n\n```markdown\n[WORK-PRODUCT HEADER — per plugin config ## Outputs — differs by role; see `## Who's using this`]\n\n> **⚠️ Reviewer note**\n> - **Sources:** [Research connector: CourtListener ✓ verified | not connected — cites from training knowledge, verify before relying]\n> - **Read:** [sections of the policy reviewed; what wasn't read]\n> - **Flagged for your judgment:** [N items marked `[review]` inline | none]\n> - **Currency:** [rule status verified against [source], [date] | unverified — see banner above]\n> - **Before relying:** confirm this is the current approved version of the policy; verify rule status and effective date; get the policy owner's review; follow your policy-change approval process; update the gap tracker only when applied and approved.\n\n## Policy Redraft: [Policy name]\n\n**Gap:** [GAP-ID or short description]\n**Regulation:** [name, citation, effective date]\n**Policy:** [name, last-updated date]\n**Status:** PROPOSAL — not yet reviewed or approved\n\n### Bottom line\n\n[One sentence: what the gap is. One sentence: what the redraft does. One sentence: what needs review.]\n\n### Marked-up policy section(s)\n\n[The redlined text, with inline `[Change: ...]` comments. Only the affected sections.]\n\n### Change summary\n\n| # | Provision | Current | Proposed | Why | Verify |\n|---|---|---|---|---|---|\n| 1 | §2.1 PII definition | \"…names, addresses, SSNs…\" | \"…names, addresses, SSNs, biometric identifiers…\" | COPPA 2025 amendments expand PII to cover biometrics | [Federal Register] |\n| 2 | §4.3 Retention period | \"30 days\" | \"14 days\" | New rule imposes 14-day cap | `[verify — model knowledge]` |\n\n### Before applying — checklist\n\n- [ ] Confirm this is the current approved version of the policy being redrafted.\n- [ ] Verify the rule status and effective date (Federal Register docket, or outside counsel).\n- [ ] Get the policy owner's review.\n- [ ] Follow your policy-change approval process.\n- [ ] Update the gap tracker when applied and approved — not before.\n\n---\n\n**What next? Pick one and I'll help you build it out:**\n\n1. **Apply and get sign-off** — you review, circulate to the policy owner, walk it through your approval process. When approved, tell me and I'll mark the gap closed.\n2. **Get more info on [X]** — if a specific change needs more grounding (a cite verified, a threshold checked, a jurisdiction question resolved), tell me which one and I'll dig in.\n3. **Escalate to [owner / GC]** — if the redraft raises something above the policy-owner's authority, I'll draft a short escalation with the facts, the proposed change, and what decision is needed.\n4. **Watch and wait** — if the rule's status is uncertain or the policy owner is unavailable, I'll add a revisit note to the gap tracker.\n5. **Something else** — tell me what you'd do with it.\n```\n\n## Filename\n\nThe output file name makes clear it's a draft. Use:\n\n`[policy-name]-proposed-redraft-[YYYY-MM-DD].md`\n\nNot `[policy-name].md`. Not `[policy-name]-v2.md`. The word \"proposed-redraft\" and the date are load-bearing — they prevent the draft from being mistaken for the current version.\n\nWrite to the matter workspace if one is active; otherwise to the current working directory or a location the user names. Do not write to the policy library source directory.\n\n## Config-dependent fallbacks\n\nThis skill reads the policy library index and owners from your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile). When a value it needs is empty or still `[PLACEHOLDER]`:\n\n- **Policy owner missing:** still produce the redraft. Note in the reviewer note: \"No policy owner is set for [policy] in `## Policy library`. Assign one with `configure your Practice Profile (Account → Practice Profile) --redo` so the approval path is routable.\"\n- **Policy library empty and the gap doesn't name a specific policy:** stop and ask: \"I need the current policy text to redraft. Paste the text of the affected policy, or point me at the file.\"\n\nSay nothing about config when the values are populated.\n\n## Interactions with other skills\n\n- **Upstream inputs** come from `policy-diff` (per-requirement gap analysis) and `gap-surfacer` (the tracker). Carry their source tags and `[verify]` flags through.\n- **Gap tracker state:** this skill does NOT change the tracker. It doesn't mark the gap closed, doesn't mark it in-progress, doesn't touch `notified`. If you want a paper trail that a redraft exists, the policy owner or the user can update the gap entry with a resolution note when the redraft is applied and approved — see `the “Gaps” workflow --close`.\n- **Severity floor:** if the upstream gap is 🔴 or 🟠, the memo's Bottom line carries that severity. Silent demotion is a contradiction a reviewing lawyer cannot see. See your USER PRACTICE PROFILE (provided in the system prompt; the user maintains it in Account → Practice Profile) `## Cross-skill severity floor`.\n\n## Close with the next-steps decision tree\n\nIncluded in the output template above. Customize the options to what the redraft actually produced — if the rule status is unverified, option 2 (get more info) moves up; if the policy owner isn't set, option 3 (escalate) gets specific.\n\n## What this skill does not do\n\n- Apply the redraft to the source policy. That's the policy owner's action.\n- Close the gap in the tracker. Gaps close when the redraft is applied and approved.\n- Rewrite the whole policy. Smallest-possible edit to close the gap.\n- Produce multi-policy redrafts. One gap, one policy, one memo. A `:package` command for multi-policy fan-out is a future skill.\n- Produce the \"apply\" workflow. An `:apply` command with an approval gate is a future skill.", + }, +]; diff --git a/backend/src/lib/practiceAreas.ts b/backend/src/lib/practiceAreas.ts new file mode 100644 index 000000000..f173249af --- /dev/null +++ b/backend/src/lib/practiceAreas.ts @@ -0,0 +1,23 @@ +/** + * The fixed set of practice areas a user can keep a per-area practice profile + * for. These match the `practice` labels carried by the built-in / ported + * workflows, so the active workflow's area maps onto exactly one profile. + */ +export const PRACTICE_AREAS = [ + "AI Governance", + "Commercial Contracts", + "Corporate / M&A", + "Employment", + "General Transactions", + "Intellectual Property", + "Law Student", + "Legal Clinic", + "Litigation", + "Privacy & Data Protection", + "Product", + "Regulatory", +] as const; + +export type PracticeArea = (typeof PRACTICE_AREAS)[number]; + +export const PRACTICE_AREA_SET: ReadonlySet = new Set(PRACTICE_AREAS); diff --git a/backend/src/lib/userSettings.ts b/backend/src/lib/userSettings.ts index bfbeb0fd5..962f67924 100644 --- a/backend/src/lib/userSettings.ts +++ b/backend/src/lib/userSettings.ts @@ -7,6 +7,8 @@ import { type UserApiKeys, } from "./llm"; import { getUserApiKeys as getStoredUserApiKeys } from "./userApiKeys"; +import { BUILTIN_WORKFLOW_PRACTICE } from "./builtinWorkflows"; +import { buildPracticeProfileBlock } from "./chatTools"; export type UserModelSettings = { title_model: string; @@ -51,3 +53,75 @@ export async function getUserApiKeys( const client = db ?? createServerSupabase(); return getStoredUserApiKeys(userId, client); } + +export type PracticeProfiles = { + /** Always-injected general profile (firm positions, house style, …). */ + general: string | null; + /** Per-practice-area profiles, keyed by practice label. */ + byArea: Record; +}; + +/** + * The user's practice profiles: a general profile plus a per-area map. Injected + * into the assistant system prompt so workflows can rely on the user's + * configured positions instead of assuming defaults. + */ +export async function getUserPracticeProfiles( + userId: string, + db?: ReturnType, +): Promise { + const client = db ?? createServerSupabase(); + const { data } = await client + .from("user_profiles") + .select("practice_profile, practice_profiles") + .eq("user_id", userId) + .maybeSingle(); + const general = (data?.practice_profile as string | null) ?? null; + const rawByArea = (data?.practice_profiles ?? {}) as Record; + const byArea: Record = {}; + for (const [area, value] of Object.entries(rawByArea)) { + if (typeof value === "string" && value.trim()) byArea[area] = value; + } + return { general: general && general.trim() ? general : null, byArea }; +} + +/** + * Resolve a workflow id to its practice area — checking the in-memory built-in + * catalogue first, then falling back to the workflows table for user-created + * workflows. Returns null when unknown. + */ +export async function resolveWorkflowPractice( + workflowId: string, + db?: ReturnType, +): Promise { + if (BUILTIN_WORKFLOW_PRACTICE.has(workflowId)) { + return BUILTIN_WORKFLOW_PRACTICE.get(workflowId) ?? null; + } + const client = db ?? createServerSupabase(); + const { data } = await client + .from("workflows") + .select("practice") + .eq("id", workflowId) + .maybeSingle(); + const practice = (data?.practice as string | null) ?? null; + return practice && practice.trim() ? practice : null; +} + +/** + * The system-prompt practice-profile block for a chat turn: the user's general + * profile plus the profile for the active workflow's practice area (resolved + * from `workflowId`). Shared by the chat, project-chat, and tabular routes. + * Returns an empty string when nothing is configured. + */ +export async function buildWorkflowPracticeBlock( + userId: string, + workflowId: string | null | undefined, + db?: ReturnType, +): Promise { + const client = db ?? createServerSupabase(); + const [profiles, area] = await Promise.all([ + getUserPracticeProfiles(userId, client), + workflowId ? resolveWorkflowPractice(workflowId, client) : null, + ]); + return buildPracticeProfileBlock(profiles, area); +} diff --git a/backend/src/routes/chat.ts b/backend/src/routes/chat.ts index 9a39e0a9b..c9ce6465c 100644 --- a/backend/src/routes/chat.ts +++ b/backend/src/routes/chat.ts @@ -11,7 +11,11 @@ import { type ChatMessage, } from "../lib/chatTools"; import { completeText } from "../lib/llm"; -import { getUserApiKeys, getUserModelSettings } from "../lib/userSettings"; +import { + getUserApiKeys, + getUserModelSettings, + buildWorkflowPracticeBlock, +} from "../lib/userSettings"; import { checkProjectAccess } from "../lib/access"; export const chatRouter = Router(); @@ -538,7 +542,11 @@ chatRouter.post("/", requireAuth, async (req, res) => { db, docIndex, ); - const apiMessages = buildMessages(enrichedMessages, docAvailability); + const apiMessages = buildMessages( + enrichedMessages, + docAvailability, + await buildWorkflowPracticeBlock(userId, lastUser?.workflow?.id, db), + ); const workflowStore = await buildWorkflowStore(userId, userEmail, db); diff --git a/backend/src/routes/projectChat.ts b/backend/src/routes/projectChat.ts index 5e2996152..57246341f 100644 --- a/backend/src/routes/projectChat.ts +++ b/backend/src/routes/projectChat.ts @@ -11,7 +11,10 @@ import { PROJECT_EXTRA_TOOLS, type ChatMessage, } from "../lib/chatTools"; -import { getUserApiKeys } from "../lib/userSettings"; +import { + getUserApiKeys, + buildWorkflowPracticeBlock, +} from "../lib/userSettings"; import { checkProjectAccess } from "../lib/access"; const PROJECT_SYSTEM_PROMPT_EXTRA = `PROJECT CONTEXT: @@ -136,10 +139,16 @@ projectChatRouter.post("/", requireAuth, async (req, res) => { systemPromptExtra += `\n\nUSER-ATTACHED DOCUMENTS FOR THIS TURN:\nThe user has attached the following document(s) directly to their latest message. Treat these as the primary focus of the request unless their message clearly says otherwise.\n${lines.join("\n")}`; } + const combinedSystemExtra = [ + systemPromptExtra, + await buildWorkflowPracticeBlock(userId, lastUser?.workflow?.id, db), + ] + .filter(Boolean) + .join("\n\n"); const apiMessages = buildMessages( messagesForLLM, docAvailability, - systemPromptExtra, + combinedSystemExtra, ); const workflowStore = await buildWorkflowStore(userId, userEmail, db); diff --git a/backend/src/routes/tabular.ts b/backend/src/routes/tabular.ts index 6cf649596..10946a8a2 100644 --- a/backend/src/routes/tabular.ts +++ b/backend/src/routes/tabular.ts @@ -17,7 +17,10 @@ import { type Provider, type UserApiKeys, } from "../lib/llm"; -import { getUserModelSettings } from "../lib/userSettings"; +import { + getUserModelSettings, + buildWorkflowPracticeBlock, +} from "../lib/userSettings"; import { checkProjectAccess, ensureReviewAccess, @@ -896,6 +899,12 @@ tabularRouter.post("/:reviewId/generate", requireAuth, async (req, res) => { const write = (line: string) => res.write(line); + const practiceProfileBlock = await buildWorkflowPracticeBlock( + userId, + review.workflow_id, + db, + ); + try { await Promise.all( docs.map(async (doc) => { @@ -973,6 +982,7 @@ tabularRouter.post("/:reviewId/generate", requireAuth, async (req, res) => { ); }, api_keys, + practiceProfileBlock, ); } catch (err) { console.error( @@ -1151,6 +1161,7 @@ function buildTabularMessages( messages: ChatMessage[], tabularStore: TabularCellStore, reviewTitle: string, + systemPromptExtra?: string, ): unknown[] { const docList = tabularStore.documents .map((d, i) => `- ROW:${i} "${d.filename}"`) @@ -1190,7 +1201,10 @@ Rules: - Do not fabricate cell content - Answer in clear, concise prose. You may use markdown formatting.`; - const formatted: unknown[] = [{ role: "system", content: systemContent }]; + const fullSystem = systemPromptExtra + ? `${systemContent}\n\n${systemPromptExtra.trim()}` + : systemContent; + const formatted: unknown[] = [{ role: "system", content: fullSystem }]; for (const msg of messages) { formatted.push({ role: msg.role, content: msg.content ?? "" }); } @@ -1331,6 +1345,7 @@ tabularRouter.post("/:reviewId/chat", requireAuth, async (req, res) => { messages, tabularStore, review.title || "Untitled Review", + await buildWorkflowPracticeBlock(userId, review.workflow_id, db), ); res.setHeader("Content-Type", "text/event-stream"); @@ -1618,6 +1633,7 @@ async function queryTabularAllColumns( columns: Column[], onResult: (columnIndex: number, result: CellResult) => Promise, apiKeys?: import("../lib/llm").UserApiKeys, + practiceProfile?: string, ): Promise { const columnsDesc = columns .map((col) => { @@ -1641,6 +1657,10 @@ Rules: - The "summary" and "reasoning" string VALUES may use markdown (bullets, bold, italics, etc.) — escape newlines as \\n inside the JSON string. This markdown is rendered in the UI. - Output ONLY the JSON lines themselves. Do NOT wrap the response in markdown code fences (e.g. \`\`\`json), and do not add any preamble or summary.`; + const systemWithProfile = practiceProfile?.trim() + ? `${SYSTEM}\n\n${practiceProfile.trim()}\n\nApply the practice profile above when deciding flags (green/yellow/red) and house style — e.g. flag terms that deviate from the firm's stated positions.` + : SYSTEM; + const USER = `Document: ${filename}\n\n${documentText.slice(0, 120_000)}\n\n---\nColumns to extract:\n${columnsDesc}`; let contentBuffer = ""; @@ -1676,7 +1696,7 @@ Rules: try { await streamChatWithTools({ model, - systemPrompt: SYSTEM, + systemPrompt: systemWithProfile, messages: [{ role: "user", content: USER }], tools: [], apiKeys, diff --git a/backend/src/routes/user.ts b/backend/src/routes/user.ts index 0df2021d6..4556e0450 100644 --- a/backend/src/routes/user.ts +++ b/backend/src/routes/user.ts @@ -2,6 +2,7 @@ import { Router } from "express"; import { requireAuth } from "../middleware/auth"; import { createServerSupabase } from "../lib/supabase"; import { DEFAULT_TABULAR_MODEL, resolveModel } from "../lib/llm"; +import { PRACTICE_AREA_SET } from "../lib/practiceAreas"; import { type ApiKeyStatus, getUserApiKeyStatus, @@ -14,6 +15,14 @@ export const userRouter = Router(); const MONTHLY_CREDIT_LIMIT = 999999; +// Single source of truth for the profile columns we select, so the three +// load paths below can't drift apart. +const PROFILE_COLUMNS = + "display_name, organisation, message_credits_used, credits_reset_date, tier, tabular_model, practice_profile, practice_profiles"; + +// Cap each practice profile so a runaway paste can't blow up the system prompt. +const MAX_PRACTICE_PROFILE_CHARS = 20000; + type UserProfileRow = { display_name: string | null; organisation: string | null; @@ -21,6 +30,8 @@ type UserProfileRow = { credits_reset_date: string; tier: string; tabular_model: string; + practice_profile: string | null; + practice_profiles: Record | null; }; function serializeProfile( @@ -36,10 +47,29 @@ function serializeProfile( creditsRemaining: Math.max(MONTHLY_CREDIT_LIMIT - creditsUsed, 0), tier: row.tier || "Free", tabularModel: resolveModel(row.tabular_model, DEFAULT_TABULAR_MODEL), + practiceProfile: row.practice_profile ?? null, + practiceProfiles: row.practice_profiles ?? {}, ...(apiKeyStatus ? { apiKeyStatus } : {}), }; } +// Shared type + length check for the free-text profile fields. Returns an error +// string, or null when the value is valid. +function validateProfileText( + label: string, + value: unknown, + allowNull: boolean, +): string | null { + if (allowNull && value === null) return null; + if (typeof value !== "string") { + return `${label} must be a string${allowNull ? " or null" : ""}`; + } + if (value.length > MAX_PRACTICE_PROFILE_CHARS) { + return `${label} must be ${MAX_PRACTICE_PROFILE_CHARS} characters or fewer`; + } + return null; +} + function validateProfilePayload(body: unknown): | { ok: true; @@ -47,6 +77,8 @@ function validateProfilePayload(body: unknown): display_name?: string | null; organisation?: string | null; tabular_model?: string; + practice_profile?: string | null; + practice_profiles?: Record; updated_at: string; }; } @@ -60,6 +92,8 @@ function validateProfilePayload(body: unknown): "displayName", "organisation", "tabularModel", + "practiceProfile", + "practiceProfiles", ]); const invalidField = Object.keys(raw).find((key) => !allowedFields.has(key)); if (invalidField) { @@ -70,6 +104,8 @@ function validateProfilePayload(body: unknown): display_name?: string | null; organisation?: string | null; tabular_model?: string; + practice_profile?: string | null; + practice_profiles?: Record; updated_at: string; } = { updated_at: new Date().toISOString() }; @@ -98,6 +134,37 @@ function validateProfilePayload(body: unknown): update.tabular_model = resolved; } + if ("practiceProfile" in raw) { + const err = validateProfileText("practiceProfile", raw.practiceProfile, true); + if (err) return { ok: false, detail: err }; + update.practice_profile = + (raw.practiceProfile as string | null)?.trim() || null; + } + + if ("practiceProfiles" in raw) { + const value = raw.practiceProfiles; + if (!value || typeof value !== "object" || Array.isArray(value)) { + return { ok: false, detail: "practiceProfiles must be an object" }; + } + const cleaned: Record = {}; + for (const [area, content] of Object.entries( + value as Record, + )) { + if (!PRACTICE_AREA_SET.has(area)) { + return { ok: false, detail: `Unknown practice area: ${area}` }; + } + const err = validateProfileText( + `practiceProfiles["${area}"]`, + content, + false, + ); + if (err) return { ok: false, detail: err }; + // Drop blanks so the map only stores areas the user actually filled in. + if ((content as string).trim()) cleaned[area] = content as string; + } + update.practice_profiles = cleaned; + } + return { ok: true, update }; } @@ -121,9 +188,7 @@ async function loadProfile( ) { let { data, error } = await db .from("user_profiles") - .select( - "display_name, organisation, message_credits_used, credits_reset_date, tier, tabular_model", - ) + .select(PROFILE_COLUMNS) .eq("user_id", userId) .maybeSingle(); @@ -138,9 +203,7 @@ async function loadProfile( const created = await db .from("user_profiles") - .select( - "display_name, organisation, message_credits_used, credits_reset_date, tier, tabular_model", - ) + .select(PROFILE_COLUMNS) .eq("user_id", userId) .single(); if (created.error) return { data: null, error: created.error }; diff --git a/backend/test/helpers/supabaseMock.ts b/backend/test/helpers/supabaseMock.ts new file mode 100644 index 000000000..701c090f5 --- /dev/null +++ b/backend/test/helpers/supabaseMock.ts @@ -0,0 +1,91 @@ +import { vi } from "vitest"; + +export type SupabaseResult = { data: unknown; error: unknown }; + +export interface SupabaseMockControl { + /** The object returned by the mocked `createServerSupabase()`. */ + db: Record; + /** Queue one `{ data, error }` to be returned by the next awaited query. */ + queue: (result: SupabaseResult) => SupabaseMockControl; + /** Queue several results, consumed in order. */ + queueMany: (results: SupabaseResult[]) => SupabaseMockControl; + /** Result returned once the queue is exhausted (defaults to `{data:null,error:null}`). */ + setDefault: (result: SupabaseResult) => void; + /** Mock for `db.auth.admin.deleteUser`. */ + authDeleteUser: ReturnType; + /** Table names passed to every `from()` call, in order. */ + fromCalls: string[]; + /** Every chain method invoked, in order, for assertions. */ + calls: Array<{ table: string; method: string; args: unknown[] }>; +} + +// The Supabase JS client exposes a fluent, chainable query builder whose calls +// (`from().select().eq().maybeSingle()`) only resolve when awaited. We emulate +// that with a builder where every chain/terminal method returns the same +// thenable object, and awaiting it dequeues the next configured result. Route +// handlers issue their DB calls sequentially, so a simple FIFO queue lines up +// results with the order the handler asks for them. +const CHAIN_METHODS = [ + "select", "insert", "update", "upsert", "delete", "eq", "neq", "gt", "gte", + "lt", "lte", "in", "is", "or", "and", "not", "contains", "containedBy", + "filter", "match", "like", "ilike", "order", "limit", "range", "onConflict", + "returns", "overlaps", "textSearch", "throwOnError", +]; +const TERMINAL_METHODS = ["single", "maybeSingle", "csv", "geojson"]; + +export function createSupabaseMock(): SupabaseMockControl { + const results: SupabaseResult[] = []; + let defaultResult: SupabaseResult = { data: null, error: null }; + const fromCalls: string[] = []; + const calls: SupabaseMockControl["calls"] = []; + + const next = (): SupabaseResult => + results.length ? results.shift()! : defaultResult; + + function makeBuilder(table: string): Record { + const builder: Record = { + then: (onF: ((v: SupabaseResult) => unknown) | null, onR?: ((e: unknown) => unknown) | null) => + Promise.resolve(next()).then(onF, onR), + catch: (onR: ((e: unknown) => unknown) | null) => + Promise.resolve(next()).catch(onR), + finally: (onF: (() => void) | null) => + Promise.resolve(next()).finally(onF ?? undefined), + }; + for (const m of [...CHAIN_METHODS, ...TERMINAL_METHODS]) { + builder[m] = (...args: unknown[]) => { + calls.push({ table, method: m, args }); + return builder; + }; + } + return builder; + } + + const authDeleteUser = vi.fn(async () => ({ data: { user: null }, error: null })); + + const db: Record = { + from: (table: string) => { + fromCalls.push(table); + return makeBuilder(table); + }, + auth: { admin: { deleteUser: authDeleteUser } }, + }; + + const control: SupabaseMockControl = { + db, + queue(result) { + results.push(result); + return control; + }, + queueMany(items) { + results.push(...items); + return control; + }, + setDefault(result) { + defaultResult = result; + }, + authDeleteUser, + fromCalls, + calls, + }; + return control; +} diff --git a/backend/test/lib/portedWorkflows.test.ts b/backend/test/lib/portedWorkflows.test.ts new file mode 100644 index 000000000..5883fe1db --- /dev/null +++ b/backend/test/lib/portedWorkflows.test.ts @@ -0,0 +1,70 @@ +import { describe, it, expect } from "vitest"; +import { + BUILTIN_WORKFLOWS, + BUILTIN_WORKFLOW_PRACTICE, +} from "../../src/lib/builtinWorkflows"; +import { PORTED_LEGAL_WORKFLOWS } from "../../src/lib/portedLegalWorkflows"; +import { PRACTICE_AREA_SET } from "../../src/lib/practiceAreas"; + +describe("ported claude-for-legal workflows", () => { + it("spans multiple practice areas, all in the canonical set", () => { + const areas = new Set(PORTED_LEGAL_WORKFLOWS.map((w) => w.practice)); + expect(areas.size).toBeGreaterThanOrEqual(8); + for (const area of areas) expect(PRACTICE_AREA_SET.has(area)).toBe(true); + }); + + it("maps each workflow id to its practice area", () => { + expect(BUILTIN_WORKFLOW_PRACTICE.get("builtin-cfl-commercial-review")).toBe( + "Commercial Contracts", + ); + expect( + BUILTIN_WORKFLOW_PRACTICE.get("builtin-cfl-litigation-claim-chart"), + ).toBe("Litigation"); + }); + + it("includes the promoted commercial review playbooks", () => { + const ids = new Set(PORTED_LEGAL_WORKFLOWS.map((w) => w.id)); + for (const id of [ + "builtin-cfl-commercial-review", + "builtin-cfl-commercial-nda-review", + "builtin-cfl-commercial-vendor-agreement-review", + "builtin-cfl-commercial-saas-msa-review", + ]) { + expect(ids.has(id)).toBe(true); + } + }); + + it("drops plugin-runtime / config-management skills", () => { + const joined = PORTED_LEGAL_WORKFLOWS.map((w) => w.id).join(","); + for (const dropped of [ + "cold-start-interview", + "customize", + "matter-workspace", + "renewal-tracker", + "review-proposals", + ]) { + expect(joined).not.toContain(dropped); + } + }); + + it("adapts each body to Mike's Practice Profile + guardrail and drops upstream paths", () => { + for (const wf of PORTED_LEGAL_WORKFLOWS) { + expect(wf.prompt_md).toContain("USER PRACTICE PROFILE"); + expect(wf.prompt_md).toContain("draft for attorney review"); + // Upstream CLAUDE.md practice-profile paths must be rewritten away. + expect(wf.prompt_md).not.toContain(".claude/plugins/config"); + expect(wf.prompt_md).not.toContain("CLAUDE.md"); + } + }); + + it("merges ported workflows into the injectable BUILTIN_WORKFLOWS", () => { + const ids = new Set(BUILTIN_WORKFLOWS.map((w) => w.id)); + // hand-written ones still present + expect(ids.has("builtin-cp-checklist")).toBe(true); + // ported ones now injectable via read_workflow + expect(ids.has("builtin-cfl-commercial-review")).toBe(true); + expect(BUILTIN_WORKFLOWS.length).toBeGreaterThanOrEqual( + PORTED_LEGAL_WORKFLOWS.length + 3, + ); + }); +}); diff --git a/backend/test/lib/practiceProfile.test.ts b/backend/test/lib/practiceProfile.test.ts new file mode 100644 index 000000000..0efb4ec38 --- /dev/null +++ b/backend/test/lib/practiceProfile.test.ts @@ -0,0 +1,85 @@ +import { describe, it, expect, vi } from "vitest"; +import { formatPracticeProfile } from "../../src/lib/chatTools"; + +describe("formatPracticeProfile", () => { + it("returns an empty string when there is no profile", () => { + expect(formatPracticeProfile(null)).toBe(""); + expect(formatPracticeProfile(undefined)).toBe(""); + expect(formatPracticeProfile(" ")).toBe(""); + }); + + it("wraps the profile in a labelled, authoritative system block", () => { + const out = formatPracticeProfile("We cap liability at 12 months of fees."); + expect(out).toContain("USER PRACTICE PROFILE:"); + expect(out).toContain("authoritative"); + // The verbatim profile text is preserved. + expect(out).toContain("We cap liability at 12 months of fees."); + // Tells the model to ask rather than invent missing values. + expect(out).toMatch(/ask the user/i); + }); +}); + +describe("buildPracticeProfileBlock", () => { + it("injects only the general profile when no area matches", async () => { + const { buildPracticeProfileBlock } = await import( + "../../src/lib/chatTools" + ); + const out = buildPracticeProfileBlock( + { general: "Firm-wide rules.", byArea: { Litigation: "Lit rules." } }, + null, + ); + expect(out).toContain("USER PRACTICE PROFILE:"); + expect(out).toContain("Firm-wide rules."); + expect(out).not.toContain("Lit rules."); + }); + + it("appends the active area's profile, labelled, alongside the general one", async () => { + const { buildPracticeProfileBlock } = await import( + "../../src/lib/chatTools" + ); + const out = buildPracticeProfileBlock( + { general: "Firm-wide rules.", byArea: { Litigation: "Lit rules." } }, + "Litigation", + ); + expect(out).toContain("USER PRACTICE PROFILE:"); + expect(out).toContain("USER PRACTICE PROFILE — Litigation:"); + expect(out).toContain("Firm-wide rules."); + expect(out).toContain("Lit rules."); + }); + + it("returns empty when nothing is configured", async () => { + const { buildPracticeProfileBlock } = await import( + "../../src/lib/chatTools" + ); + expect(buildPracticeProfileBlock({ general: null, byArea: {} }, "Litigation")).toBe( + "", + ); + }); +}); + +describe("getUserPracticeProfiles", () => { + it("returns the general profile and a cleaned per-area map", async () => { + const mod = await import("../../src/lib/userSettings"); + const db = { + from: () => ({ + select: () => ({ + eq: () => ({ + maybeSingle: async () => ({ + data: { + practice_profile: " general ", + practice_profiles: { + Litigation: "lit", + Employment: " ", // blank -> dropped + }, + }, + error: null, + }), + }), + }), + }), + } as never; + const profiles = await mod.getUserPracticeProfiles("u", db); + expect(profiles.general).toBe(" general "); + expect(profiles.byArea).toEqual({ Litigation: "lit" }); + }); +}); diff --git a/backend/test/routes/chat.test.ts b/backend/test/routes/chat.test.ts new file mode 100644 index 000000000..76eabe4be --- /dev/null +++ b/backend/test/routes/chat.test.ts @@ -0,0 +1,195 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) + return void res.status(401).json({ detail: "unauthorized" }); + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); +vi.mock("../../src/lib/chatTools", () => ({ + buildDocContext: vi.fn(async () => ({ docIndex: {}, docStore: new Map() })), + buildProjectDocContext: vi.fn(async () => ({ + docIndex: {}, + docStore: new Map(), + folderPaths: new Map(), + })), + buildMessages: vi.fn(() => []), + enrichWithPriorEvents: vi.fn(async (m: unknown) => m), + buildWorkflowStore: vi.fn(async () => new Map()), + extractAnnotations: vi.fn(() => []), + runLLMStream: vi.fn(async ({ write }: { write: (s: string) => void }) => { + write(`data: ${JSON.stringify({ type: "text", text: "hi" })}\n\n`); + return { fullText: "hi", events: [{ type: "text", text: "hi" }] }; + }), + PROJECT_EXTRA_TOOLS: [], +})); +vi.mock("../../src/lib/llm", () => ({ + completeText: vi.fn(async () => "Generated Title"), + resolveModel: (id: string, fb: string) => id || fb, + DEFAULT_TABULAR_MODEL: "gemini-3-flash-preview", + streamChatWithTools: vi.fn(), +})); +vi.mock("../../src/lib/userSettings", () => ({ + getUserModelSettings: vi.fn(async () => ({ title_model: "m", api_keys: {} })), + getUserApiKeys: vi.fn(async () => ({})), + buildWorkflowPracticeBlock: vi.fn(async () => ""), +})); + +import { createApp } from "../../src/index"; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + mock = createSupabaseMock(); + sb.current = mock.db; + app = createApp(); +}); + +describe("auth gate", () => { + it("returns 401 without auth", async () => { + auth.userId = null; + expect((await request(app).get("/chat")).status).toBe(401); + }); +}); + +describe("GET /chat", () => { + it("lists accessible chats", async () => { + mock.queueMany([ + { data: [{ id: "p1" }], error: null }, + { data: [{ id: "c1", title: "Hi" }], error: null }, + ]); + const res = await request(app).get("/chat"); + expect(res.status).toBe(200); + expect(res.body).toEqual([{ id: "c1", title: "Hi" }]); + }); + + it("returns 500 when the projects lookup fails", async () => { + mock.queue({ data: null, error: { message: "boom" } }); + const res = await request(app).get("/chat"); + expect(res.status).toBe(500); + expect(res.body).toEqual({ detail: "boom" }); + }); +}); + +describe("POST /chat/create", () => { + it("creates a chat and returns its id", async () => { + mock.queue({ data: { id: "new-chat" }, error: null }); + const res = await request(app).post("/chat/create").send({}); + expect(res.status).toBe(200); + expect(res.body).toEqual({ id: "new-chat" }); + }); + + it("rejects an empty-string project_id with 400", async () => { + const res = await request(app) + .post("/chat/create") + .send({ project_id: "" }); + expect(res.status).toBe(400); + }); +}); + +describe("GET /chat/:chatId", () => { + it("returns 404 when the chat is not accessible", async () => { + mock.queue({ data: null, error: null }); + expect((await request(app).get("/chat/c1")).status).toBe(404); + }); + + it("returns the chat with hydrated messages", async () => { + mock.queueMany([ + { + data: { id: "c1", user_id: "user-1", title: "t", project_id: null }, + error: null, + }, + { data: [{ id: "m1", content: "hello", annotations: null }], error: null }, + ]); + const res = await request(app).get("/chat/c1"); + expect(res.status).toBe(200); + expect(res.body.chat.id).toBe("c1"); + expect(res.body.messages).toHaveLength(1); + }); +}); + +describe("PATCH /chat/:chatId", () => { + it("rejects an empty title with 400", async () => { + const res = await request(app).patch("/chat/c1").send({ title: " " }); + expect(res.status).toBe(400); + }); + + it("renames a chat", async () => { + mock.queue({ data: { id: "c1", title: "New" }, error: null }); + const res = await request(app).patch("/chat/c1").send({ title: "New" }); + expect(res.status).toBe(200); + expect(res.body).toEqual({ id: "c1", title: "New" }); + }); + + it("returns 404 when the chat is missing", async () => { + mock.queue({ data: null, error: null }); + const res = await request(app).patch("/chat/c1").send({ title: "New" }); + expect(res.status).toBe(404); + }); +}); + +describe("DELETE /chat/:chatId", () => { + it("deletes and returns 204", async () => { + const res = await request(app).delete("/chat/c1"); + expect(res.status).toBe(204); + }); +}); + +describe("POST /chat/:chatId/generate-title", () => { + it("rejects a missing message with 400", async () => { + const res = await request(app) + .post("/chat/c1/generate-title") + .send({}); + expect(res.status).toBe(400); + }); + + it("generates and persists a title", async () => { + mock.queue({ + data: { id: "c1", user_id: "user-1", project_id: null, title: null }, + error: null, + }); + const res = await request(app) + .post("/chat/c1/generate-title") + .send({ message: "What are the indemnity terms?" }); + expect(res.status).toBe(200); + expect(res.body).toEqual({ title: "Generated Title" }); + }); +}); + +describe("POST /chat (streaming)", () => { + it("rejects a missing messages array with 400", async () => { + const res = await request(app).post("/chat").send({}); + expect(res.status).toBe(400); + }); + + it("streams an SSE response for a new chat", async () => { + mock.queue({ data: { id: "chat-1", title: null }, error: null }); + const res = await request(app) + .post("/chat") + .send({ messages: [{ role: "user", content: "hi" }] }); + expect(res.status).toBe(200); + expect(res.headers["content-type"]).toMatch(/text\/event-stream/); + expect(res.text).toContain('"type":"chat_id"'); + expect(res.text).toContain('"text":"hi"'); + }); +}); diff --git a/backend/test/routes/documents.test.ts b/backend/test/routes/documents.test.ts new file mode 100644 index 000000000..c00566655 --- /dev/null +++ b/backend/test/routes/documents.test.ts @@ -0,0 +1,146 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) + return void res.status(401).json({ detail: "unauthorized" }); + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); +vi.mock("../../src/lib/storage", () => ({ + uploadFile: vi.fn(async () => {}), + downloadFile: vi.fn(async () => new TextEncoder().encode("bytes").buffer), + deleteFile: vi.fn(async () => {}), + getSignedUrl: vi.fn(async () => "https://signed.example/x"), + buildContentDisposition: (type: string, filename: string) => + `${type}; filename="${filename}"`, + storageKey: (...p: string[]) => `key/${p.join("/")}`, + versionStorageKey: (...p: string[]) => `vkey/${p.join("/")}`, +})); +vi.mock("../../src/lib/convert", () => ({ + docxToPdf: vi.fn(async () => Buffer.from("pdf-bytes")), + convertedPdfKey: (userId: string, docId: string) => `pdf/${userId}/${docId}`, +})); +vi.mock("../../src/lib/documentVersions", () => ({ + attachLatestVersionNumbers: vi.fn(async () => {}), + attachActiveVersionPaths: vi.fn(async () => {}), + loadActiveVersion: vi.fn(async () => null), +})); + +import { createApp } from "../../src/index"; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + mock = createSupabaseMock(); + sb.current = mock.db; + app = createApp(); +}); + +describe("auth gate", () => { + it("returns 401 without auth", async () => { + auth.userId = null; + expect((await request(app).get("/single-documents")).status).toBe(401); + }); +}); + +describe("GET /single-documents", () => { + it("lists the user's standalone documents", async () => { + mock.queue({ data: [], error: null }); + const res = await request(app).get("/single-documents"); + expect(res.status).toBe(200); + expect(res.body).toEqual([]); + }); + + it("returns 500 on query error", async () => { + mock.queue({ data: null, error: { message: "boom" } }); + const res = await request(app).get("/single-documents"); + expect(res.status).toBe(500); + }); +}); + +describe("DELETE /single-documents/:documentId", () => { + it("returns 404 when the document is missing", async () => { + mock.queue({ data: null, error: null }); + expect((await request(app).delete("/single-documents/d1")).status).toBe( + 404, + ); + }); + + it("deletes the document and its version bytes", async () => { + mock.queueMany([ + { data: { id: "d1" }, error: null }, // doc lookup + { + data: [{ storage_path: "a", pdf_storage_path: "b" }], + error: null, + }, // versions + // documents.delete -> default + ]); + const res = await request(app).delete("/single-documents/d1"); + expect(res.status).toBe(204); + }); +}); + +describe("GET /single-documents/:documentId/display", () => { + it("returns 404 when the document is not found", async () => { + mock.queue({ data: null, error: null }); + const res = await request(app).get("/single-documents/d1/display"); + expect(res.status).toBe(404); + }); +}); + +describe("POST /single-documents (upload)", () => { + it("rejects a request with no file", async () => { + const res = await request(app).post("/single-documents"); + expect(res.status).toBe(400); + expect(res.body).toEqual({ detail: "file is required" }); + }); + + it("rejects an unsupported file type", async () => { + const res = await request(app) + .post("/single-documents") + .attach("file", Buffer.from("hello"), { + filename: "notes.txt", + contentType: "text/plain", + }); + expect(res.status).toBe(400); + expect(res.body.detail).toMatch(/Unsupported file type/); + }); + + it("uploads a docx and returns the created document", async () => { + mock.queueMany([ + { data: { id: "d1" }, error: null }, // insert documents + { data: { id: "v1" }, error: null }, // insert document_versions + { data: null, error: null }, // update documents + { data: { id: "d1", filename: "contract.docx" }, error: null }, // re-select + ]); + const res = await request(app) + .post("/single-documents") + .attach("file", Buffer.from("PKdocxbytes"), { + filename: "contract.docx", + contentType: + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + }); + expect(res.status).toBe(201); + expect(res.body).toMatchObject({ id: "d1", filename: "contract.docx" }); + }); +}); diff --git a/backend/test/routes/downloads.test.ts b/backend/test/routes/downloads.test.ts new file mode 100644 index 000000000..7192ea529 --- /dev/null +++ b/backend/test/routes/downloads.test.ts @@ -0,0 +1,101 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) + return void res.status(401).json({ detail: "unauthorized" }); + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); +// Only the network-touching storage helper is mocked; buildContentDisposition +// keeps a faithful-enough implementation so the header assertion is meaningful. +vi.mock("../../src/lib/storage", () => ({ + downloadFile: vi.fn(async () => new TextEncoder().encode("PKfilebytes").buffer), + buildContentDisposition: (type: string, filename: string) => + `${type}; filename="${filename}"`, +})); + +import { createApp } from "../../src/index"; +// Real signer/verifier — exercises the token round-trip against the test secret. +import { signDownload } from "../../src/lib/downloadTokens"; +import { downloadFile } from "../../src/lib/storage"; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + mock = createSupabaseMock(); + sb.current = mock.db; + app = createApp(); +}); + +describe("GET /download/:token", () => { + it("returns 401 without auth", async () => { + auth.userId = null; + const token = signDownload("docs/file.docx", "file.docx"); + expect((await request(app).get(`/download/${token}`)).status).toBe(401); + }); + + it("returns 404 for an invalid token", async () => { + const res = await request(app).get("/download/not-a-valid-token"); + expect(res.status).toBe(404); + expect(res.body).toEqual({ detail: "Invalid link" }); + }); + + it("returns 404 when the caller lacks access", async () => { + mock.queueMany([ + { data: { id: "v1", document_id: "d1" }, error: null }, + // Document owned by someone else, no project -> ensureDocAccess fails. + { data: { id: "d1", user_id: "other", project_id: null }, error: null }, + ]); + const token = signDownload("docs/file.docx", "file.docx"); + const res = await request(app).get(`/download/${token}`); + expect(res.status).toBe(404); + }); + + it("streams the file with the right content type for the owner", async () => { + mock.queueMany([ + { data: { id: "v1", document_id: "d1" }, error: null }, + { data: { id: "d1", user_id: "user-1", project_id: null }, error: null }, + ]); + const token = signDownload("docs/file.docx", "file.docx"); + const res = await request(app).get(`/download/${token}`); + expect(res.status).toBe(200); + expect(res.headers["content-type"]).toBe( + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + ); + expect(res.headers["content-disposition"]).toBe( + 'attachment; filename="file.docx"', + ); + expect(downloadFile).toHaveBeenCalledWith("docs/file.docx"); + }); + + it("maps .pdf to the pdf content type", async () => { + mock.queueMany([ + { data: { id: "v1", document_id: "d1" }, error: null }, + { data: { id: "d1", user_id: "user-1", project_id: null }, error: null }, + ]); + const token = signDownload("docs/file.pdf", "file.pdf"); + const res = await request(app).get(`/download/${token}`); + expect(res.status).toBe(200); + expect(res.headers["content-type"]).toBe("application/pdf"); + }); +}); diff --git a/backend/test/routes/health.test.ts b/backend/test/routes/health.test.ts new file mode 100644 index 000000000..0004f50d8 --- /dev/null +++ b/backend/test/routes/health.test.ts @@ -0,0 +1,11 @@ +import { describe, it, expect } from "vitest"; +import request from "supertest"; +import { createApp } from "../../src/index"; + +describe("GET /health", () => { + it("returns ok without auth", async () => { + const res = await request(createApp()).get("/health"); + expect(res.status).toBe(200); + expect(res.body).toEqual({ ok: true }); + }); +}); diff --git a/backend/test/routes/projectChat.test.ts b/backend/test/routes/projectChat.test.ts new file mode 100644 index 000000000..66d9a5147 --- /dev/null +++ b/backend/test/routes/projectChat.test.ts @@ -0,0 +1,104 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) + return void res.status(401).json({ detail: "unauthorized" }); + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); +vi.mock("../../src/lib/chatTools", () => ({ + buildDocContext: vi.fn(async () => ({ docIndex: {}, docStore: new Map() })), + buildProjectDocContext: vi.fn(async () => ({ + docIndex: {}, + docStore: new Map(), + folderPaths: new Map(), + })), + buildMessages: vi.fn(() => []), + enrichWithPriorEvents: vi.fn(async (m: unknown) => m), + buildWorkflowStore: vi.fn(async () => new Map()), + extractAnnotations: vi.fn(() => []), + runLLMStream: vi.fn(async ({ write }: { write: (s: string) => void }) => { + write(`data: ${JSON.stringify({ type: "text", text: "yo" })}\n\n`); + return { fullText: "yo", events: [{ type: "text", text: "yo" }] }; + }), + PROJECT_EXTRA_TOOLS: [], +})); +vi.mock("../../src/lib/userSettings", () => ({ + getUserModelSettings: vi.fn(async () => ({ title_model: "m", api_keys: {} })), + getUserApiKeys: vi.fn(async () => ({})), + buildWorkflowPracticeBlock: vi.fn(async () => ""), +})); + +import { createApp } from "../../src/index"; +import { runLLMStream } from "../../src/lib/chatTools"; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + mock = createSupabaseMock(); + sb.current = mock.db; + app = createApp(); +}); + +describe("POST /projects/:projectId/chat", () => { + it("returns 401 without auth", async () => { + auth.userId = null; + const res = await request(app) + .post("/projects/p1/chat") + .send({ messages: [{ role: "user", content: "hi" }] }); + expect(res.status).toBe(401); + }); + + it("returns 404 when the project is not accessible", async () => { + mock.queue({ data: null, error: null }); // checkProjectAccess -> no project + const res = await request(app) + .post("/projects/p1/chat") + .send({ messages: [{ role: "user", content: "hi" }] }); + expect(res.status).toBe(404); + expect(res.body).toEqual({ detail: "Project not found" }); + }); + + it("streams an SSE response and runs the LLM stream", async () => { + mock.queueMany([ + // checkProjectAccess -> owned project + { + data: { id: "p1", user_id: "user-1", shared_with: null }, + error: null, + }, + // insert new chat + { data: { id: "chat-1", title: null }, error: null }, + ]); + const res = await request(app) + .post("/projects/p1/chat") + .send({ messages: [{ role: "user", content: "hi" }] }); + expect(res.status).toBe(200); + expect(res.headers["content-type"]).toMatch(/text\/event-stream/); + expect(res.text).toContain('"type":"chat_id"'); + expect(res.text).toContain('"text":"yo"'); + expect(runLLMStream).toHaveBeenCalledOnce(); + const arg = vi.mocked(runLLMStream).mock.calls[0][0] as { + projectId: string; + }; + expect(arg.projectId).toBe("p1"); + }); +}); diff --git a/backend/test/routes/projects.test.ts b/backend/test/routes/projects.test.ts new file mode 100644 index 000000000..25e6d2d17 --- /dev/null +++ b/backend/test/routes/projects.test.ts @@ -0,0 +1,153 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) + return void res.status(401).json({ detail: "unauthorized" }); + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); + +import { createApp } from "../../src/index"; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + auth.userEmail = "user@example.com"; + mock = createSupabaseMock(); + sb.current = mock.db; + app = createApp(); +}); + +describe("auth gate", () => { + it("returns 401 without auth", async () => { + auth.userId = null; + expect((await request(app).get("/projects")).status).toBe(401); + }); +}); + +describe("GET /projects", () => { + it("returns owned projects with computed counts", async () => { + mock.queueMany([ + { + data: [ + { id: "p1", user_id: "user-1", name: "P", created_at: "2024-01-01" }, + ], + error: null, + }, + { data: [], error: null }, // shared projects + // remaining count queries fall through to the default {data:null} -> 0 + ]); + const res = await request(app).get("/projects"); + expect(res.status).toBe(200); + expect(res.body).toHaveLength(1); + expect(res.body[0]).toMatchObject({ + id: "p1", + is_owner: true, + document_count: 0, + chat_count: 0, + review_count: 0, + }); + }); + + it("returns 500 when the owned-projects query fails", async () => { + mock.queue({ data: null, error: { message: "boom" } }); + const res = await request(app).get("/projects"); + expect(res.status).toBe(500); + expect(res.body).toEqual({ detail: "boom" }); + }); +}); + +describe("POST /projects", () => { + it("rejects a missing name with 400", async () => { + const res = await request(app).post("/projects").send({ name: " " }); + expect(res.status).toBe(400); + }); + + it("rejects sharing with yourself", async () => { + const res = await request(app) + .post("/projects") + .send({ name: "P", shared_with: ["user@example.com"] }); + expect(res.status).toBe(400); + expect(res.body.detail).toMatch(/cannot share a project with yourself/i); + }); + + it("creates a project", async () => { + mock.queue({ + data: { id: "p1", name: "P", user_id: "user-1", shared_with: [] }, + error: null, + }); + const res = await request(app) + .post("/projects") + .send({ name: "P", shared_with: ["friend@example.com"] }); + expect(res.status).toBe(201); + expect(res.body).toMatchObject({ id: "p1", documents: [] }); + const insert = mock.calls.find((c) => c.method === "insert"); + expect(insert?.args[0]).toMatchObject({ + name: "P", + shared_with: ["friend@example.com"], + }); + }); +}); + +describe("DELETE /projects/:projectId", () => { + it("deletes and returns 204", async () => { + expect((await request(app).delete("/projects/p1")).status).toBe(204); + }); + + it("returns 500 on delete error", async () => { + mock.queue({ data: null, error: { message: "nope" } }); + const res = await request(app).delete("/projects/p1"); + expect(res.status).toBe(500); + }); +}); + +describe("POST /projects/:projectId/folders", () => { + it("rejects a missing name with 400", async () => { + const res = await request(app) + .post("/projects/p1/folders") + .send({ name: "" }); + expect(res.status).toBe(400); + }); + + it("returns 404 when the project is not accessible", async () => { + mock.queue({ data: null, error: null }); // checkProjectAccess + const res = await request(app) + .post("/projects/p1/folders") + .send({ name: "Contracts" }); + expect(res.status).toBe(404); + }); + + it("creates a folder", async () => { + mock.queueMany([ + // checkProjectAccess -> owned project + { data: { id: "p1", user_id: "user-1", shared_with: null }, error: null }, + // insert folder + { data: { id: "f1", name: "Contracts" }, error: null }, + ]); + const res = await request(app) + .post("/projects/p1/folders") + .send({ name: "Contracts" }); + expect(res.status).toBe(201); + expect(res.body).toEqual({ id: "f1", name: "Contracts" }); + }); +}); diff --git a/backend/test/routes/tabular.test.ts b/backend/test/routes/tabular.test.ts new file mode 100644 index 000000000..6c9de1c24 --- /dev/null +++ b/backend/test/routes/tabular.test.ts @@ -0,0 +1,200 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) + return void res.status(401).json({ detail: "unauthorized" }); + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); +vi.mock("../../src/lib/chatTools", () => ({ + runLLMStream: vi.fn( + async ({ + write, + apiMessages, + }: { + write: (s: string) => void; + apiMessages: { role: string; content: string }[]; + }) => { + void apiMessages; + write(`data: ${JSON.stringify({ type: "text", text: "t" })}\n\n`); + return { fullText: "t", events: [{ type: "text", text: "t" }] }; + }, + ), + TABULAR_TOOLS: [], +})); +vi.mock("../../src/lib/llm", () => ({ + completeText: vi.fn(async () => "Title"), + streamChatWithTools: vi.fn(), + providerForModel: (model: string) => + model.startsWith("claude") + ? "claude" + : model.startsWith("gpt") + ? "openai" + : "gemini", + resolveModel: (id: string, fb: string) => id || fb, + DEFAULT_TABULAR_MODEL: "gemini-3-flash-preview", +})); +vi.mock("../../src/lib/userSettings", () => ({ + getUserModelSettings: vi.fn(async () => ({ + tabular_model: "gemini-3-flash-preview", + api_keys: {}, + })), + getUserApiKeys: vi.fn(async () => ({})), + buildWorkflowPracticeBlock: vi.fn( + async () => "PRACTICE_BLOCK(House style: surgical redlines.)", + ), +})); + +import { createApp } from "../../src/index"; +import { runLLMStream } from "../../src/lib/chatTools"; +import { getUserModelSettings } from "../../src/lib/userSettings"; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + mock = createSupabaseMock(); + sb.current = mock.db; + app = createApp(); +}); + +describe("auth gate", () => { + it("returns 401 without auth", async () => { + auth.userId = null; + expect((await request(app).get("/tabular-review")).status).toBe(401); + }); +}); + +describe("GET /tabular-review", () => { + it("returns an empty list when the user has no reviews", async () => { + // listAccessibleProjectIds (own, shared), then own/sharedDirect reviews. + mock.queueMany([ + { data: [], error: null }, + { data: [], error: null }, + { data: [], error: null }, + { data: [], error: null }, + ]); + const res = await request(app).get("/tabular-review"); + expect(res.status).toBe(200); + expect(res.body).toEqual([]); + }); + + it("returns 500 when the own-reviews query fails", async () => { + mock.queueMany([ + { data: [], error: null }, + { data: [], error: null }, + { data: null, error: { message: "boom" } }, + ]); + const res = await request(app).get("/tabular-review"); + expect(res.status).toBe(500); + }); +}); + +describe("POST /tabular-review", () => { + it("creates a review", async () => { + mock.queue({ data: { id: "r1", title: "T" }, error: null }); + const res = await request(app) + .post("/tabular-review") + .send({ title: "T", columns_config: [] }); + expect(res.status).toBe(201); + expect(res.body).toEqual({ id: "r1", title: "T" }); + }); +}); + +describe("DELETE /tabular-review/:reviewId", () => { + it("deletes and returns 204", async () => { + expect((await request(app).delete("/tabular-review/r1")).status).toBe(204); + }); +}); + +describe("POST /tabular-review/:reviewId/chat", () => { + it("rejects when there is no user message", async () => { + const res = await request(app) + .post("/tabular-review/r1/chat") + .send({ messages: [{ role: "assistant", content: "hi" }] }); + expect(res.status).toBe(400); + }); + + it("returns 404 when the review is missing", async () => { + mock.queue({ data: null, error: null }); + const res = await request(app) + .post("/tabular-review/r1/chat") + .send({ messages: [{ role: "user", content: "summarize" }] }); + expect(res.status).toBe(404); + }); + + it("injects the practice profile into the tabular system prompt", async () => { + // Model has a key, so we pass the 422 gate and reach the LLM call. + vi.mocked(getUserModelSettings).mockResolvedValueOnce({ + tabular_model: "gemini-3-flash-preview", + api_keys: { gemini: "key" }, + title_model: "gemini-3-flash-lite-preview", + } as never); + mock.queueMany([ + // review lookup (owned, no workflow) + { + data: { + id: "r1", + user_id: "user-1", + columns_config: [], + workflow_id: null, + title: "R", + }, + error: null, + }, + { data: [], error: null }, // cells + { data: { id: "tc1", title: null }, error: null }, // create chat + ]); + const res = await request(app) + .post("/tabular-review/r1/chat") + .send({ messages: [{ role: "user", content: "summarize" }] }); + expect(res.status).toBe(200); + expect(runLLMStream).toHaveBeenCalledOnce(); + const arg = vi.mocked(runLLMStream).mock.calls[0][0] as { + apiMessages: { role: string; content: string }[]; + }; + const system = arg.apiMessages.find((m) => m.role === "system"); + expect(system?.content).toContain( + "PRACTICE_BLOCK(House style: surgical redlines.)", + ); + }); + + it("returns 422 when the model's API key is missing", async () => { + mock.queueMany([ + // review lookup (owned) + { + data: { id: "r1", user_id: "user-1", columns_config: [] }, + error: null, + }, + // cells lookup + { data: [], error: null }, + ]); + const res = await request(app) + .post("/tabular-review/r1/chat") + .send({ messages: [{ role: "user", content: "summarize" }] }); + expect(res.status).toBe(422); + expect(res.body).toMatchObject({ + code: "missing_api_key", + provider: "gemini", + }); + }); +}); diff --git a/backend/test/routes/user.test.ts b/backend/test/routes/user.test.ts new file mode 100644 index 000000000..6fb1f2e3a --- /dev/null +++ b/backend/test/routes/user.test.ts @@ -0,0 +1,285 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +// --- Mocked auth + Supabase + userApiKeys ------------------------------------ +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); + +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) { + res + .status(401) + .json({ detail: "Missing or invalid Authorization header" }); + return; + } + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); + +vi.mock("../../src/lib/userApiKeys", () => ({ + getUserApiKeyStatus: vi.fn(async () => ({ + claude: false, + gemini: false, + openai: false, + })), + hasEnvApiKey: vi.fn(() => false), + normalizeApiKeyProvider: vi.fn((v: string) => + ["claude", "gemini", "openai"].includes(v) ? v : null, + ), + saveUserApiKey: vi.fn(async () => {}), +})); + +import { createApp } from "../../src/index"; +import { + getUserApiKeyStatus, + hasEnvApiKey, + normalizeApiKeyProvider, + saveUserApiKey, +} from "../../src/lib/userApiKeys"; + +const profileRow = { + display_name: "Ada", + organisation: "Analytical Engines", + message_credits_used: 5, + // Far-future reset date avoids the credit-reset branch (which would issue + // an extra UPDATE...SELECT round-trip). + credits_reset_date: "2999-01-01T00:00:00.000Z", + tier: "Pro", + tabular_model: "gemini-3-flash-preview", + practice_profile: "Our firm prefers English law and a 12-month liability cap.", + practice_profiles: { Litigation: "We never waive privilege." }, +}; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + auth.userEmail = "user@example.com"; + mock = createSupabaseMock(); + sb.current = mock.db; + vi.mocked(getUserApiKeyStatus).mockResolvedValue({ + claude: false, + gemini: false, + openai: false, + }); + vi.mocked(hasEnvApiKey).mockReturnValue(false); + vi.mocked(normalizeApiKeyProvider).mockImplementation((v: string) => + ["claude", "gemini", "openai"].includes(v) + ? (v as "claude" | "gemini" | "openai") + : null, + ); + vi.mocked(saveUserApiKey).mockResolvedValue(undefined); + app = createApp(); +}); + +describe("auth gate", () => { + it("rejects unauthenticated requests with 401", async () => { + auth.userId = null; + const res = await request(app).get("/user/profile"); + expect(res.status).toBe(401); + }); +}); + +describe("POST /user/profile", () => { + it("ensures a profile row and returns ok", async () => { + const res = await request(app).post("/user/profile"); + expect(res.status).toBe(200); + expect(res.body).toEqual({ ok: true }); + expect(mock.fromCalls).toContain("user_profiles"); + }); + + it("returns 500 when the upsert fails", async () => { + mock.queue({ data: null, error: { message: "db down" } }); + const res = await request(app).post("/user/profile"); + expect(res.status).toBe(500); + expect(res.body).toEqual({ detail: "db down" }); + }); +}); + +describe("GET /user/profile", () => { + it("serializes the profile and attaches api-key status", async () => { + mock.queue({ data: profileRow, error: null }); + const res = await request(app).get("/user/profile"); + expect(res.status).toBe(200); + expect(res.body).toMatchObject({ + displayName: "Ada", + organisation: "Analytical Engines", + messageCreditsUsed: 5, + tier: "Pro", + tabularModel: "gemini-3-flash-preview", + practiceProfile: + "Our firm prefers English law and a 12-month liability cap.", + apiKeyStatus: { claude: false, gemini: false, openai: false }, + }); + }); + + it("returns 500 when the profile load fails", async () => { + mock.queue({ data: null, error: { message: "read error" } }); + const res = await request(app).get("/user/profile"); + expect(res.status).toBe(500); + expect(res.body).toEqual({ detail: "read error" }); + }); +}); + +describe("PATCH /user/profile", () => { + it("validates and persists allowed fields", async () => { + // ensureProfileRow upsert, update, then loadProfile select. + mock.queueMany([ + { data: null, error: null }, + { data: null, error: null }, + { data: profileRow, error: null }, + ]); + const res = await request(app) + .patch("/user/profile") + .send({ displayName: "Grace", organisation: "Navy" }); + expect(res.status).toBe(200); + expect(res.body.displayName).toBe("Ada"); + const update = mock.calls.find((c) => c.method === "update"); + expect(update?.args[0]).toMatchObject({ + display_name: "Grace", + organisation: "Navy", + }); + }); + + it("rejects unsupported fields with 400", async () => { + const res = await request(app) + .patch("/user/profile") + .send({ isAdmin: true }); + expect(res.status).toBe(400); + expect(res.body.detail).toMatch(/Unsupported profile field/); + }); + + it("rejects an unknown tabularModel with 400", async () => { + const res = await request(app) + .patch("/user/profile") + .send({ tabularModel: "not-a-real-model" }); + expect(res.status).toBe(400); + expect(res.body.detail).toMatch(/Unsupported tabularModel/); + }); + + it("persists the practice profile", async () => { + mock.queueMany([ + { data: null, error: null }, // ensureProfileRow + { data: null, error: null }, // update + { data: profileRow, error: null }, // loadProfile + ]); + const res = await request(app) + .patch("/user/profile") + .send({ practiceProfile: "We escalate any uncapped indemnity to the GC." }); + expect(res.status).toBe(200); + const update = mock.calls.find((c) => c.method === "update"); + expect(update?.args[0]).toMatchObject({ + practice_profile: "We escalate any uncapped indemnity to the GC.", + }); + }); + + it("rejects a non-string practice profile with 400", async () => { + const res = await request(app) + .patch("/user/profile") + .send({ practiceProfile: 42 }); + expect(res.status).toBe(400); + }); + + it("rejects an oversized practice profile with 400", async () => { + const res = await request(app) + .patch("/user/profile") + .send({ practiceProfile: "x".repeat(20001) }); + expect(res.status).toBe(400); + expect(res.body.detail).toMatch(/characters or fewer/); + }); + + it("persists per-area practice profiles", async () => { + mock.queueMany([ + { data: null, error: null }, // ensureProfileRow + { data: null, error: null }, // update + { data: profileRow, error: null }, // loadProfile + ]); + const res = await request(app) + .patch("/user/profile") + .send({ + practiceProfiles: { + Litigation: "We never waive privilege.", + Employment: " ", // blank -> dropped + }, + }); + expect(res.status).toBe(200); + const update = mock.calls.find((c) => c.method === "update"); + expect(update?.args[0]).toMatchObject({ + practice_profiles: { Litigation: "We never waive privilege." }, + }); + expect(update?.args[0].practice_profiles).not.toHaveProperty("Employment"); + }); + + it("rejects an unknown practice area with 400", async () => { + const res = await request(app) + .patch("/user/profile") + .send({ practiceProfiles: { "Made Up Area": "x" } }); + expect(res.status).toBe(400); + expect(res.body.detail).toMatch(/Unknown practice area/); + }); +}); + +describe("PUT /user/api-keys/:provider", () => { + it("returns 400 for an unsupported provider", async () => { + const res = await request(app) + .put("/user/api-keys/bogus") + .send({ api_key: "x" }); + expect(res.status).toBe(400); + expect(res.body).toEqual({ detail: "Unsupported provider" }); + }); + + it("returns 409 when the provider is configured by the environment", async () => { + vi.mocked(hasEnvApiKey).mockReturnValue(true); + const res = await request(app) + .put("/user/api-keys/openai") + .send({ api_key: "sk-test" }); + expect(res.status).toBe(409); + }); + + it("saves a user-supplied key and returns the updated status", async () => { + const res = await request(app) + .put("/user/api-keys/claude") + .send({ api_key: "sk-test" }); + expect(res.status).toBe(200); + expect(saveUserApiKey).toHaveBeenCalledWith( + "user-1", + "claude", + "sk-test", + expect.anything(), + ); + }); +}); + +describe("DELETE /user/account", () => { + it("deletes the auth user and returns 204", async () => { + const res = await request(app).delete("/user/account"); + expect(res.status).toBe(204); + expect(mock.authDeleteUser).toHaveBeenCalledWith("user-1"); + }); + + it("returns 500 when deletion fails", async () => { + mock.authDeleteUser.mockResolvedValueOnce({ + data: { user: null }, + error: { message: "cannot delete" }, + } as never); + const res = await request(app).delete("/user/account"); + expect(res.status).toBe(500); + expect(res.body).toEqual({ detail: "cannot delete" }); + }); +}); diff --git a/backend/test/routes/workflows.test.ts b/backend/test/routes/workflows.test.ts new file mode 100644 index 000000000..1a3eec8d1 --- /dev/null +++ b/backend/test/routes/workflows.test.ts @@ -0,0 +1,139 @@ +import { describe, it, expect, beforeEach, vi } from "vitest"; +import request from "supertest"; +import { + createSupabaseMock, + type SupabaseMockControl, +} from "../helpers/supabaseMock"; + +const auth = vi.hoisted(() => ({ + userId: "user-1" as string | null, + userEmail: "user@example.com", +})); +const sb = vi.hoisted(() => ({ current: null as unknown })); + +vi.mock("../../src/lib/supabase", () => ({ + createServerSupabase: () => sb.current, +})); +vi.mock("../../src/middleware/auth", () => ({ + requireAuth: (req: unknown, res: any, next: () => void) => { + if (!auth.userId) + return void res.status(401).json({ detail: "unauthorized" }); + res.locals.userId = auth.userId; + res.locals.userEmail = auth.userEmail; + res.locals.token = "test-token"; + next(); + }, +})); + +import { createApp } from "../../src/index"; + +let app: ReturnType; +let mock: SupabaseMockControl; + +beforeEach(() => { + auth.userId = "user-1"; + mock = createSupabaseMock(); + sb.current = mock.db; + app = createApp(); +}); + +describe("auth gate", () => { + it("returns 401 without auth", async () => { + auth.userId = null; + expect((await request(app).get("/workflows")).status).toBe(401); + }); +}); + +describe("GET /workflows", () => { + it("returns own workflows flagged as owned", async () => { + mock.queueMany([ + { + data: [{ id: "w1", user_id: "user-1", is_system: false, title: "X" }], + error: null, + }, + { data: [], error: null }, // workflow_shares + ]); + const res = await request(app).get("/workflows"); + expect(res.status).toBe(200); + expect(res.body).toHaveLength(1); + expect(res.body[0]).toMatchObject({ + id: "w1", + allow_edit: true, + is_owner: true, + }); + }); + + it("returns 500 when the own-workflows query fails", async () => { + mock.queue({ data: null, error: { message: "boom" } }); + expect((await request(app).get("/workflows")).status).toBe(500); + }); +}); + +describe("POST /workflows", () => { + it("rejects a missing title with 400", async () => { + const res = await request(app) + .post("/workflows") + .send({ type: "assistant" }); + expect(res.status).toBe(400); + }); + + it("rejects an invalid type with 400", async () => { + const res = await request(app) + .post("/workflows") + .send({ title: "T", type: "bogus" }); + expect(res.status).toBe(400); + }); + + it("creates a workflow", async () => { + mock.queue({ data: { id: "w1", title: "T" }, error: null }); + const res = await request(app) + .post("/workflows") + .send({ title: "T", type: "assistant" }); + expect(res.status).toBe(201); + expect(res.body).toEqual({ id: "w1", title: "T" }); + }); +}); + +describe("DELETE /workflows/:workflowId", () => { + it("deletes and returns 204", async () => { + expect((await request(app).delete("/workflows/w1")).status).toBe(204); + }); +}); + +describe("GET /workflows/:workflowId", () => { + it("returns 404 when not accessible", async () => { + mock.queue({ data: null, error: null }); + expect((await request(app).get("/workflows/w1")).status).toBe(404); + }); + + it("returns the workflow for its owner", async () => { + mock.queue({ + data: { id: "w1", user_id: "user-1", is_system: false, title: "X" }, + error: null, + }); + const res = await request(app).get("/workflows/w1"); + expect(res.status).toBe(200); + expect(res.body).toMatchObject({ id: "w1", is_owner: true }); + }); +}); + +describe("hidden workflows", () => { + it("lists hidden workflow ids", async () => { + mock.queue({ data: [{ workflow_id: "w9" }], error: null }); + const res = await request(app).get("/workflows/hidden"); + expect(res.status).toBe(200); + expect(res.body).toEqual(["w9"]); + }); + + it("rejects hiding without a workflow_id", async () => { + const res = await request(app).post("/workflows/hidden").send({}); + expect(res.status).toBe(400); + }); + + it("hides a workflow", async () => { + const res = await request(app) + .post("/workflows/hidden") + .send({ workflow_id: "w1" }); + expect(res.status).toBe(204); + }); +}); diff --git a/backend/test/setup.ts b/backend/test/setup.ts new file mode 100644 index 000000000..f2d134749 --- /dev/null +++ b/backend/test/setup.ts @@ -0,0 +1,12 @@ +// Global test bootstrap. Runs before every test file. +// +// Several modules read these at import time (createServerSupabase throws when +// they are absent, the auth middleware short-circuits to 500, downloadTokens +// throws without a signing secret). We use throwaway values because Supabase, +// storage and the LLM clients are all mocked in the route suites — nothing in +// the tests makes a real network call. +process.env.NODE_ENV = "test"; +process.env.SUPABASE_URL ??= "http://localhost:54321"; +process.env.SUPABASE_SECRET_KEY ??= "test-service-role-key"; +process.env.DOWNLOAD_SIGNING_SECRET ??= "test-download-signing-secret"; +process.env.FRONTEND_URL ??= "http://localhost:3000"; diff --git a/backend/vitest.config.ts b/backend/vitest.config.ts new file mode 100644 index 000000000..2c3354033 --- /dev/null +++ b/backend/vitest.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + globals: true, + environment: "node", + setupFiles: ["./test/setup.ts"], + include: ["test/**/*.test.ts"], + // Each test file gets a fresh module registry so vi.mock state and the + // per-test Supabase mock never leak between route suites. + isolate: true, + // Clear call history between tests but keep mock implementations defined + // in vi.mock factories (restoreMocks would wipe those). + clearMocks: true, + }, +}); diff --git a/frontend/src/app/(pages)/account/page.tsx b/frontend/src/app/(pages)/account/page.tsx index 1c18aa4d5..864560698 100644 --- a/frontend/src/app/(pages)/account/page.tsx +++ b/frontend/src/app/(pages)/account/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useMemo } from "react"; import { useRouter } from "next/navigation"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; @@ -8,17 +8,32 @@ import { LogOut, Check } from "lucide-react"; import { useAuth } from "@/contexts/AuthContext"; import { useUserProfile } from "@/contexts/UserProfileContext"; import { deleteAccount } from "@/app/lib/mikeApi"; +import { PRACTICE_AREAS } from "@/app/lib/practiceAreas"; export default function AccountPage() { const router = useRouter(); const { user, signOut } = useAuth(); - const { profile, updateDisplayName, updateOrganisation } = useUserProfile(); + const { + profile, + updateDisplayName, + updateOrganisation, + updatePracticeProfile, + updatePracticeProfiles, + } = useUserProfile(); const [displayName, setDisplayName] = useState(""); const [isSavingName, setIsSavingName] = useState(false); const [saved, setSaved] = useState(false); const [organisation, setOrganisation] = useState(""); const [isSavingOrg, setIsSavingOrg] = useState(false); const [orgSaved, setOrgSaved] = useState(false); + const [practiceProfile, setPracticeProfile] = useState(""); + const [isSavingPractice, setIsSavingPractice] = useState(false); + const [practiceSaved, setPracticeSaved] = useState(false); + const [areaProfiles, setAreaProfiles] = useState>( + {}, + ); + const [isSavingAreas, setIsSavingAreas] = useState(false); + const [areasSaved, setAreasSaved] = useState(false); const [deleteConfirm, setDeleteConfirm] = useState(false); const [isDeleting, setIsDeleting] = useState(false); @@ -29,6 +44,8 @@ export default function AccountPage() { if (profile?.organisation) { setOrganisation(profile.organisation); } + setPracticeProfile(profile?.practiceProfile ?? ""); + setAreaProfiles(profile?.practiceProfiles ?? {}); }, [profile]); const handleLogout = async () => { @@ -49,31 +66,63 @@ export default function AccountPage() { } }; - const handleSaveDisplayName = async () => { - setIsSavingName(true); - const success = await updateDisplayName(displayName.trim()); - setIsSavingName(false); - + // Shared save flow: toggle the saving flag, run the update, then flash + // "Saved" for 2s (or alert on failure). `label` keeps the error specific. + const runSave = async ( + label: string, + doUpdate: () => Promise, + setSaving: (b: boolean) => void, + setSavedFlag: (b: boolean) => void, + ) => { + setSaving(true); + const success = await doUpdate(); + setSaving(false); if (success) { - setSaved(true); - setTimeout(() => setSaved(false), 2000); + setSavedFlag(true); + setTimeout(() => setSavedFlag(false), 2000); } else { - alert("Failed to update display name. Please try again."); + alert(`Failed to update ${label}. Please try again.`); } }; - const handleSaveOrganisation = async () => { - setIsSavingOrg(true); - const success = await updateOrganisation(organisation.trim()); - setIsSavingOrg(false); + const handleSaveDisplayName = () => + runSave( + "display name", + () => updateDisplayName(displayName.trim()), + setIsSavingName, + setSaved, + ); + const handleSaveOrganisation = () => + runSave( + "organisation", + () => updateOrganisation(organisation.trim()), + setIsSavingOrg, + setOrgSaved, + ); + const handleSavePracticeProfile = () => + runSave( + "practice profile", + () => updatePracticeProfile(practiceProfile), + setIsSavingPractice, + setPracticeSaved, + ); + const handleSaveAreaProfiles = () => + runSave( + "area profiles", + () => updatePracticeProfiles(areaProfiles), + setIsSavingAreas, + setAreasSaved, + ); - if (success) { - setOrgSaved(true); - setTimeout(() => setOrgSaved(false), 2000); - } else { - alert("Failed to update organisation. Please try again."); - } - }; + const areasDirty = useMemo( + () => + PRACTICE_AREAS.some( + (area) => + (areaProfiles[area] ?? "").trim() !== + (profile?.practiceProfiles?.[area] ?? "").trim(), + ), + [areaProfiles, profile], + ); if (!user) return null; @@ -163,6 +212,126 @@ export default function AccountPage() { + {/* Practice Profile */} +
+
+

+ Practice Profile +

+
+

+ A plain-English playbook the assistant reads on every chat: + your firm's positions, house style, escalation rules, + preferred governing law, and review preferences. Workflows + use these instead of assuming defaults; anything you leave + out, the assistant will ask about. +

+