From ff5a290b8c119d46ce6f0f70cc524574fc6c94ba Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 02:39:14 +0200 Subject: [PATCH 01/16] feat(wiki): add full in-app wiki browser and llms index --- App.tsx | 4 +- components/Header.tsx | 3 +- pages/WikiBrowser.tsx | 399 ++++++++++++++++++++++++++++++++++++++++++ public/wiki/llms.txt | 43 +++++ 4 files changed, 447 insertions(+), 2 deletions(-) create mode 100644 pages/WikiBrowser.tsx create mode 100644 public/wiki/llms.txt diff --git a/App.tsx b/App.tsx index aad20db..327140d 100644 --- a/App.tsx +++ b/App.tsx @@ -6,6 +6,7 @@ import { FeedSetup } from './pages/FeedSetup'; import { SkillsCatalog } from './pages/SkillsCatalog'; import { SkillDetail } from './pages/SkillDetail'; import { AdvisoryDetail } from './pages/AdvisoryDetail'; +import { WikiBrowser } from './pages/WikiBrowser'; const App: React.FC = () => { return ( @@ -17,10 +18,11 @@ const App: React.FC = () => { } /> } /> } /> + } /> ); }; -export default App; \ No newline at end of file +export default App; diff --git a/components/Header.tsx b/components/Header.tsx index 11b589e..fe130d3 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { NavLink } from 'react-router-dom'; -import { Menu, X, Terminal, Layers, Rss, Home, Github } from 'lucide-react'; +import { Menu, X, Terminal, Layers, Rss, Home, Github, BookOpenText } from 'lucide-react'; export const Header: React.FC = () => { const [isOpen, setIsOpen] = useState(false); @@ -9,6 +9,7 @@ export const Header: React.FC = () => { { label: 'Home', path: '/', icon: Home }, { label: 'Skills', path: '/skills', icon: Layers }, { label: 'Security Feed', path: '/feed', icon: Rss }, + { label: 'Wiki', path: '/wiki', icon: BookOpenText }, ]; const baseLink = diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx new file mode 100644 index 0000000..f0b0dd2 --- /dev/null +++ b/pages/WikiBrowser.tsx @@ -0,0 +1,399 @@ +import React, { useMemo } from 'react'; +import { BookOpenText, ExternalLink, FileText } from 'lucide-react'; +import { Link, useParams } from 'react-router-dom'; +import Markdown from 'react-markdown'; +import remarkGfm from 'remark-gfm'; +import { Footer } from '../components/Footer'; + +interface WikiDoc { + filePath: string; + slug: string; + title: string; + content: string; +} + +const stripFrontmatter = (content: string): string => { + const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/; + return content.replace(frontmatterRegex, ''); +}; + +const normalizePath = (path: string): string => { + const clean = path.replace(/\\/g, '/'); + const parts: string[] = []; + for (const part of clean.split('/')) { + if (!part || part === '.') continue; + if (part === '..') { + if (parts.length > 0) parts.pop(); + continue; + } + parts.push(part); + } + return parts.join('/'); +}; + +const dirname = (path: string): string => { + const idx = path.lastIndexOf('/'); + return idx === -1 ? '' : path.slice(0, idx); +}; + +const resolveFromFile = (currentFilePath: string, targetPath: string): string => { + if (!targetPath) return currentFilePath; + if (targetPath.startsWith('/')) return normalizePath(targetPath.slice(1)); + const baseDir = dirname(currentFilePath); + const joined = baseDir ? `${baseDir}/${targetPath}` : targetPath; + return normalizePath(joined); +}; + +const splitHash = (href: string): { path: string; hash: string } => { + const idx = href.indexOf('#'); + if (idx === -1) return { path: href, hash: '' }; + return { path: href.slice(0, idx), hash: href.slice(idx) }; +}; + +const toWikiRelativePath = (globPath: string): string => + globPath.replace(/^\.\.\/wiki\//, '').replace(/\\/g, '/'); + +const fallbackTitleFromFilePath = (filePath: string): string => { + const filename = filePath.split('/').pop() ?? filePath; + const stem = filename.replace(/\.md$/i, ''); + return stem + .split(/[-_]/) + .filter(Boolean) + .map((part) => { + if (part.toUpperCase() === part && part.length > 1) return part; + return part.charAt(0).toUpperCase() + part.slice(1); + }) + .join(' '); +}; + +const extractTitle = (markdownContent: string, filePath: string): string => { + const cleaned = stripFrontmatter(markdownContent).trim(); + const match = cleaned.match(/^#\s+(.+)$/m); + return match?.[1]?.trim() || fallbackTitleFromFilePath(filePath); +}; + +const isExternalHref = (href: string): boolean => + /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(href) || href.startsWith('//'); + +const markdownModules = import.meta.glob('../wiki/**/*.md', { + eager: true, + query: '?raw', + import: 'default', +}) as Record; + +const assetModules = import.meta.glob('../wiki/**/*.{png,jpg,jpeg,gif,svg,webp,avif}', { + eager: true, + import: 'default', +}) as Record; + +const wikiDocs: WikiDoc[] = Object.entries(markdownModules) + .map(([globPath, content]) => { + const filePath = toWikiRelativePath(globPath); + return { + filePath, + slug: filePath.replace(/\.md$/i, ''), + title: extractTitle(content, filePath), + content: stripFrontmatter(content).trim(), + }; + }) + .sort((a, b) => { + const aIndex = a.slug.toLowerCase() === 'index'; + const bIndex = b.slug.toLowerCase() === 'index'; + if (aIndex && !bIndex) return -1; + if (!aIndex && bIndex) return 1; + + const aModule = a.filePath.startsWith('modules/'); + const bModule = b.filePath.startsWith('modules/'); + if (aModule !== bModule) return aModule ? 1 : -1; + + return a.title.localeCompare(b.title, 'en', { sensitivity: 'base' }); + }); + +const wikiDocBySlug = new Map( + wikiDocs.map((doc) => [doc.slug.toLowerCase(), doc]), +); + +const wikiDocByFilePath = new Map( + wikiDocs.map((doc) => [doc.filePath.toLowerCase(), doc]), +); + +const wikiAssetByPath = new Map( + Object.entries(assetModules).map(([globPath, assetUrl]) => [ + toWikiRelativePath(globPath).toLowerCase(), + assetUrl, + ]), +); + +const defaultDoc = wikiDocBySlug.get('index') ?? wikiDocs[0] ?? null; + +const toWikiRoute = (slug: string): string => + slug.toLowerCase() === 'index' ? '/wiki' : `/wiki/${slug}`; + +const toGroupName = (filePath: string): string => { + if (!filePath.includes('/')) return 'Core'; + if (filePath.startsWith('modules/')) return 'Modules'; + const [firstSegment] = filePath.split('/'); + return fallbackTitleFromFilePath(firstSegment); +}; + +export const WikiBrowser: React.FC = () => { + const params = useParams<{ '*': string }>(); + const wildcard = params['*'] ?? ''; + const requested = decodeURIComponent(wildcard.replace(/^\/+|\/+$/g, '')); + const requestedSlug = requested || 'INDEX'; + + const selectedDoc = wikiDocBySlug.get(requestedSlug.toLowerCase()) ?? defaultDoc; + const notFound = requested.length > 0 && !wikiDocBySlug.has(requestedSlug.toLowerCase()); + + const groupedDocs = useMemo(() => { + const map = new Map(); + for (const doc of wikiDocs) { + const group = toGroupName(doc.filePath); + const existing = map.get(group) ?? []; + existing.push(doc); + map.set(group, existing); + } + + const preferredOrder = ['Core', 'Modules']; + return Array.from(map.entries()) + .sort(([a], [b]) => { + const idxA = preferredOrder.indexOf(a); + const idxB = preferredOrder.indexOf(b); + if (idxA !== -1 || idxB !== -1) { + if (idxA === -1) return 1; + if (idxB === -1) return -1; + return idxA - idxB; + } + return a.localeCompare(b, 'en', { sensitivity: 'base' }); + }) + .map(([name, docs]) => ({ + name, + docs: docs.sort((a, b) => + a.title.localeCompare(b.title, 'en', { sensitivity: 'base' }), + ), + })); + }, []); + + if (!selectedDoc) { + return ( +
+ +

Wiki unavailable

+

No markdown files were found in the wiki source.

+
+ ); + } + + const activeSlug = selectedDoc.slug.toLowerCase(); + + const resolveWikiRouteFromHref = (href: string): string | null => { + if (!href || isExternalHref(href) || href.startsWith('mailto:') || href.startsWith('tel:')) { + return null; + } + const { path } = splitHash(href); + if (!path || !path.toLowerCase().endsWith('.md')) return null; + + const resolvedFilePath = resolveFromFile(selectedDoc.filePath, path).toLowerCase(); + const targetDoc = wikiDocByFilePath.get(resolvedFilePath); + if (!targetDoc) return null; + return toWikiRoute(targetDoc.slug); + }; + + const resolveAssetUrl = (srcOrHref: string): string | null => { + if (!srcOrHref || isExternalHref(srcOrHref) || srcOrHref.startsWith('/')) return null; + const { path } = splitHash(srcOrHref); + if (!path) return null; + const resolvedAssetPath = resolveFromFile(selectedDoc.filePath, path).toLowerCase(); + return wikiAssetByPath.get(resolvedAssetPath) ?? null; + }; + + return ( +
+
+

+ + Wiki +

+

+ Full repository wiki rendered from markdown in wiki/. + This is the same source synced to GitHub Wiki. +

+ +
+ +
+ + +
+ {notFound && ( +
+ Wiki page not found for {requested}. Showing {selectedDoc.title} instead. +
+ )} + + ( +

+ {children} +

+ ), + h2: ({ children }) => ( +

{children}

+ ), + h3: ({ children }) => ( +

{children}

+ ), + p: ({ children }) => ( +

{children}

+ ), + a: ({ href, children }) => { + if (!href) return {children}; + + const wikiRoute = resolveWikiRouteFromHref(href); + if (wikiRoute) { + return ( + + {children} + + ); + } + + const assetHref = resolveAssetUrl(href); + const finalHref = assetHref ?? href; + const external = isExternalHref(finalHref); + + return ( + + {children} + + ); + }, + img: ({ src, alt }) => { + const resolvedSrc = src ? resolveAssetUrl(src) : null; + const finalSrc = resolvedSrc ?? src ?? ''; + return ( + {alt + ); + }, + ul: ({ children }) => ( +
    + {children} +
+ ), + ol: ({ children }) => ( +
    + {children} +
+ ), + li: ({ children }) =>
  • {children}
  • , + blockquote: ({ children }) => ( +
    + {children} +
    + ), + code: ({ className, children }) => { + const isInline = !className; + if (isInline) { + return ( + + {children} + + ); + } + return {children}; + }, + pre: ({ children }) => ( +
    +                  {children}
    +                
    + ), + table: ({ children }) => ( +
    + + {children} +
    +
    + ), + thead: ({ children }) => ( + {children} + ), + tr: ({ children }) => ( + {children} + ), + th: ({ children }) => ( + {children} + ), + td: ({ children }) => {children}, + hr: () =>
    , + strong: ({ children }) => ( + {children} + ), + em: ({ children }) => {children}, + }} + > + {selectedDoc.content} +
    +
    +
    + +
    +
    + ); +}; diff --git a/public/wiki/llms.txt b/public/wiki/llms.txt new file mode 100644 index 0000000..7987e10 --- /dev/null +++ b/public/wiki/llms.txt @@ -0,0 +1,43 @@ +# ClawSec Wiki (LLMs) + +Machine-readable index for ClawSec wiki documentation. + +Website wiki root: https://clawsec.prompt.security/#/wiki +GitHub wiki mirror: https://github.com/prompt-security/clawsec/wiki +Canonical source of truth: https://github.com/prompt-security/clawsec/tree/main/wiki + +## Website Wiki Pages +- INDEX: https://clawsec.prompt.security/#/wiki +- Overview: https://clawsec.prompt.security/#/wiki/overview +- Architecture: https://clawsec.prompt.security/#/wiki/architecture +- Dependencies: https://clawsec.prompt.security/#/wiki/dependencies +- Data Flow: https://clawsec.prompt.security/#/wiki/data-flow +- Configuration: https://clawsec.prompt.security/#/wiki/configuration +- Testing: https://clawsec.prompt.security/#/wiki/testing +- Workflow: https://clawsec.prompt.security/#/wiki/workflow +- Security: https://clawsec.prompt.security/#/wiki/security +- Glossary: https://clawsec.prompt.security/#/wiki/glossary +- Generation Metadata: https://clawsec.prompt.security/#/wiki/GENERATION +- Frontend Web App: https://clawsec.prompt.security/#/wiki/modules/frontend-web +- ClawSec Suite Core: https://clawsec.prompt.security/#/wiki/modules/clawsec-suite +- NanoClaw Integration: https://clawsec.prompt.security/#/wiki/modules/nanoclaw-integration +- Automation and Release Pipelines: https://clawsec.prompt.security/#/wiki/modules/automation-release +- Local Validation and Packaging Tools: https://clawsec.prompt.security/#/wiki/modules/local-tooling + +## Raw Markdown Sources +- INDEX: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/INDEX.md +- Overview: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/overview.md +- Architecture: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/architecture.md +- Dependencies: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/dependencies.md +- Data Flow: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/data-flow.md +- Configuration: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/configuration.md +- Testing: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/testing.md +- Workflow: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/workflow.md +- Security: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/security.md +- Glossary: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/glossary.md +- Generation Metadata: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/GENERATION.md +- Frontend Web App: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/frontend-web.md +- ClawSec Suite Core: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/clawsec-suite.md +- NanoClaw Integration: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/nanoclaw-integration.md +- Automation and Release Pipelines: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/automation-release.md +- Local Validation and Packaging Tools: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/local-tooling.md From 1c45339438381237838ee9e01dd445ff5d80b250 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:03:45 +0200 Subject: [PATCH 02/16] feat(wiki): auto-generate per-page llms exports --- package.json | 3 + pages/WikiBrowser.tsx | 14 +- public/wiki/llms.txt | 56 +++--- public/wiki/llms/architecture.txt | 140 +++++++++++++++ public/wiki/llms/configuration.txt | 99 +++++++++++ public/wiki/llms/data-flow.txt | 109 ++++++++++++ public/wiki/llms/dependencies.txt | 112 ++++++++++++ public/wiki/llms/generation.txt | 37 ++++ public/wiki/llms/glossary.txt | 68 ++++++++ public/wiki/llms/index.txt | 54 ++++++ .../wiki/llms/modules/automation-release.txt | 103 +++++++++++ public/wiki/llms/modules/clawsec-suite.txt | 107 ++++++++++++ public/wiki/llms/modules/frontend-web.txt | 109 ++++++++++++ public/wiki/llms/modules/local-tooling.txt | 95 +++++++++++ .../llms/modules/nanoclaw-integration.txt | 108 ++++++++++++ public/wiki/llms/overview.txt | 113 +++++++++++++ public/wiki/llms/security.txt | 85 ++++++++++ public/wiki/llms/testing.txt | 84 +++++++++ public/wiki/llms/workflow.txt | 85 ++++++++++ scripts/generate-wiki-llms.mjs | 160 ++++++++++++++++++ 20 files changed, 1702 insertions(+), 39 deletions(-) create mode 100644 public/wiki/llms/architecture.txt create mode 100644 public/wiki/llms/configuration.txt create mode 100644 public/wiki/llms/data-flow.txt create mode 100644 public/wiki/llms/dependencies.txt create mode 100644 public/wiki/llms/generation.txt create mode 100644 public/wiki/llms/glossary.txt create mode 100644 public/wiki/llms/index.txt create mode 100644 public/wiki/llms/modules/automation-release.txt create mode 100644 public/wiki/llms/modules/clawsec-suite.txt create mode 100644 public/wiki/llms/modules/frontend-web.txt create mode 100644 public/wiki/llms/modules/local-tooling.txt create mode 100644 public/wiki/llms/modules/nanoclaw-integration.txt create mode 100644 public/wiki/llms/overview.txt create mode 100644 public/wiki/llms/security.txt create mode 100644 public/wiki/llms/testing.txt create mode 100644 public/wiki/llms/workflow.txt create mode 100644 scripts/generate-wiki-llms.mjs diff --git a/package.json b/package.json index 8e39ca1..4ecac6c 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,10 @@ "version": "0.0.0", "type": "module", "scripts": { + "gen:wiki-llms": "node scripts/generate-wiki-llms.mjs", + "predev": "npm run gen:wiki-llms", "dev": "vite", + "prebuild": "npm run gen:wiki-llms", "build": "vite build", "preview": "vite preview" }, diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index f0b0dd2..c7bb652 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -185,6 +185,7 @@ export const WikiBrowser: React.FC = () => { } const activeSlug = selectedDoc.slug.toLowerCase(); + const pageLlmsPath = `/wiki/llms/${activeSlug}.txt`; const resolveWikiRouteFromHref = (href: string): string | null => { if (!href || isExternalHref(href) || href.startsWith('mailto:') || href.startsWith('tel:')) { @@ -220,13 +221,22 @@ export const WikiBrowser: React.FC = () => {

    - llms.txt + Page llms.txt + + + + Wiki llms.txt Index B["Feed Workflows\n(poll/community)"] + B --> C["advisories/feed.json + signatures"] + C --> D["Deploy Workflow Mirrors to public/"] + D --> E["React UI (catalog/feed pages)"] + C --> F["clawsec-suite hook + installers"] + F --> G["Agent advisory alerts / gated install"] +``` + +![Prompt Line Motif](assets/architecture_img_01_prompt-line.svg) + +## Interfaces and Contracts +| Interface | Contract Form | Validation | +| --- | --- | --- | +| Skill metadata | `skills/*/skill.json` | Validated by Python utility + CI version-parity checks. | +| Advisory feed | JSON + Ed25519 detached signature | Verified by `feed.mjs` and NanoClaw signature utilities. | +| Checksums manifest | `checksums.json` (+ optional `.sig`) | Parsed and hash-matched before trusting payloads. | +| Hook event interface | `HookEvent` (`type`, `action`, `messages`) | Runtime handler only processes selected event names. | +| Workflow release naming | Tag pattern `-vX.Y.Z` | Parsed in release/deploy workflows to discover skills. | + +## Key Parameters +| Parameter | Default | Effect | +| --- | --- | --- | +| `CLAWSEC_FEED_URL` | `https://clawsec.prompt.security/advisories/feed.json` | Remote advisory source for suite scripts/hooks. | +| `CLAWSEC_ALLOW_UNSIGNED_FEED` | `0` | Enables temporary unsigned fallback compatibility. | +| `CLAWSEC_VERIFY_CHECKSUM_MANIFEST` | `1` | Requires checksum manifest verification where available. | +| `CLAWSEC_HOOK_INTERVAL_SECONDS` | `300` | Scan throttling window for advisory hook. | +| `CLAWSEC_SKILLS_INDEX_TIMEOUT_MS` | `5000` | Remote skill index fetch timeout for catalog discovery. | +| `PROMPTSEC_GIT_PULL` | `0` | Optional auto-pull before watchdog audit runs. | + +## Error Handling and Reliability +- Feed fetching is fail-closed for invalid signatures and malformed manifests. +- Remote fetch failures gracefully fall back to local signed feeds. +- Hook state uses atomic file writes with strict mode where supported. +- UI pages detect HTML fallbacks served as JSON and avoid rendering corrupted data. +- Workflow steps enforce key-fingerprint consistency to avoid split-key drift. + +## Example Snippets +```tsx +// Route topology in the web app + + } /> + } /> + } /> + } /> + } /> + +``` + +```ts +// Guarded feed loading contract in advisory hook +const remoteFeed = await loadRemoteFeed(feedUrl, { + signatureUrl: feedSignatureUrl, + checksumsUrl: feedChecksumsUrl, + checksumsSignatureUrl: feedChecksumsSignatureUrl, + publicKeyPem, + checksumsPublicKeyPem: publicKeyPem, + allowUnsigned, + verifyChecksumManifest, +}); +``` + +## Runtime and Deployment +| Runtime Surface | Execution Model | Output | +| --- | --- | --- | +| Vite app (`npm run dev`) | Local frontend server | Interactive web app for feed/skills. | +| GitHub CI | Multi-OS matrix + dedicated jobs | Lint/type/build/security and test confidence. | +| Skill release workflow | Tag-driven | Release assets, signed checksums, optional ClawHub publish. | +| Pages deploy workflow | Triggered by CI/Release success | Static site + mirrored advisories/releases. | +| Runtime hooks | OpenClaw event hooks / NanoClaw IPC | Advisory alerts, gating decisions, integrity checks. | + +## Scaling Notes +- Advisory volume scales with keyword set in NVD polling; dedupe and post-filtering control noise. +- Deploy workflow processes release lists and keeps newest skill versions in index output. +- Module boundaries by skill folder allow adding new security capabilities without changing frontend structure. +- Signature verification paths remain lightweight because payload sizes (feed/manifests) are small. + +## Source References +- App.tsx +- pages/SkillsCatalog.tsx +- pages/FeedSetup.tsx +- pages/AdvisoryDetail.tsx +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/clawsec-suite/scripts/discover_skill_catalog.mjs +- skills/clawsec-nanoclaw/lib/advisories.ts +- skills/clawsec-nanoclaw/lib/signatures.ts +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/deploy-pages.yml +- .github/workflows/skill-release.yml diff --git a/public/wiki/llms/configuration.txt b/public/wiki/llms/configuration.txt new file mode 100644 index 0000000..0720f74 --- /dev/null +++ b/public/wiki/llms/configuration.txt @@ -0,0 +1,99 @@ +# ClawSec Wiki · Configuration + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/configuration +- LLM export: https://clawsec.prompt.security/wiki/llms/configuration.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/configuration.md + +## Markdown + +# Configuration + +## Scope +- Configuration spans frontend build settings, runtime feed paths, workflow triggers, and skill metadata contracts. +- Most runtime-sensitive controls are environment variables prefixed with `CLAWSEC_` or `OPENCLAW_`. +- Path normalization is security-sensitive and intentionally rejects unresolved home-token literals. + +## Core Runtime Variables +| Variable | Default | Used By | +| --- | --- | --- | +| `CLAWSEC_FEED_URL` | Hosted advisory URL | Suite hook and guarded installer feed loading. | +| `CLAWSEC_FEED_SIG_URL` | `.sig` | Detached signature source. | +| `CLAWSEC_FEED_CHECKSUMS_URL` | `checksums.json` near feed URL | Optional checksum-manifest source. | +| `CLAWSEC_FEED_PUBLIC_KEY` | Suite-local PEM file | Feed signature verification. | +| `CLAWSEC_ALLOW_UNSIGNED_FEED` | `0` | Temporary migration bypass flag. | +| `CLAWSEC_VERIFY_CHECKSUM_MANIFEST` | `1` | Enables checksum-manifest verification. | +| `CLAWSEC_HOOK_INTERVAL_SECONDS` | `300` | Advisory hook scan throttle. | + +## Path Resolution Rules +| Rule | Behavior | Enforcement Location | +| --- | --- | --- | +| `~` expansion | Resolved to detected home directory | Shared path utility functions in suite/watchdog scripts. | +| `$HOME` / `${HOME}` expansion | Resolved when unescaped | Same utilities. | +| Windows home tokens | `%USERPROFILE%`, `$env:USERPROFILE` normalized | Same utilities. | +| Escaped tokens (`\$HOME`) | Rejected with explicit error | Prevents accidental literal directory creation. | +| Invalid explicit path | Can fallback to default path with warning | `resolveConfiguredPath` helpers. | + +## Frontend and Build Configuration +- `vite.config.ts` defines port (`3000`), host (`0.0.0.0`), and path alias (`@`). +- `index.html` provides Tailwind runtime config, custom fonts, and base color tokens. +- `tsconfig.json` uses bundler module resolution, `noEmit`, and JSX runtime configuration. +- `eslint.config.js` applies TS, React, hooks, and script-specific lint rules. + +## Skill Metadata Configuration +| Field Group | Location | Function | +| --- | --- | --- | +| Core skill identity | `skills/*/skill.json` | Name/version/author/license/description metadata. | +| SBOM file list | `skill.json -> sbom.files` | Declares release-required artifacts. | +| Platform metadata | `openclaw` or `nanoclaw` blocks | CLI requirements, triggers, platform capability hints. | +| Suite catalog metadata | `skills/clawsec-suite/skill.json -> catalog` | Integrated/default/consent behavior for suite members. | + +## Workflow Configuration +- Schedule configuration exists in workflow `cron` entries (`poll-nvd-cves`, `codeql`, `scorecard`). +- Release workflow expects tag naming pattern `-v`. +- Deployment workflow is triggered by successful CI/release `workflow_run` events and manual dispatch. +- Composite signing action requires private key inputs and verifies signatures immediately after signing. + +## Example Snippets +```bash +# run guarded install with explicit local signed feed paths +CLAWSEC_LOCAL_FEED="$HOME/.openclaw/skills/clawsec-suite/advisories/feed.json" \ +CLAWSEC_LOCAL_FEED_SIG="$HOME/.openclaw/skills/clawsec-suite/advisories/feed.json.sig" \ +CLAWSEC_FEED_PUBLIC_KEY="$HOME/.openclaw/skills/clawsec-suite/advisories/feed-signing-public.pem" \ +node skills/clawsec-suite/scripts/guarded_skill_install.mjs --skill clawtributor --dry-run +``` + +```json +{ + "name": "example-skill", + "version": "1.2.3", + "sbom": { + "files": [ + { "path": "SKILL.md", "required": true, "description": "Install docs" } + ] + } +} +``` + +## Operational Notes +- Keep signing keys outside the repository and inject via GitHub Secrets only. +- Prefer absolute paths or unescaped home expressions in local environment variable overrides. +- Treat unsigned feed mode as temporary migration support, not normal operation. +- Re-run release-link validation when editing `SKILL.md` URLs to avoid broken artifact references. + +## Source References +- vite.config.ts +- index.html +- tsconfig.json +- eslint.config.js +- skills/clawsec-suite/skill.json +- skills/clawsec-nanoclaw/skill.json +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/utils.mjs +- skills/openclaw-audit-watchdog/scripts/load_suppression_config.mjs +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- scripts/validate-release-links.sh +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/skill-release.yml +- .github/actions/sign-and-verify/action.yml diff --git a/public/wiki/llms/data-flow.txt b/public/wiki/llms/data-flow.txt new file mode 100644 index 0000000..ce2c648 --- /dev/null +++ b/public/wiki/llms/data-flow.txt @@ -0,0 +1,109 @@ +# ClawSec Wiki · Data Flow + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/data-flow +- LLM export: https://clawsec.prompt.security/wiki/llms/data-flow.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/data-flow.md + +## Markdown + +# Data Flow + +## Primary Flows +- `Advisory ingestion`: NVD/community inputs are transformed into a normalized advisory feed, signed, then mirrored for clients. +- `Skill catalog publication`: release assets are discovered and converted into `public/skills/index.json` plus per-skill docs/checksums. +- `Runtime enforcement`: suite and nanoclaw consumers load advisory data, match against skills, and emit alerts or confirmation gates. +- This page appears under the `Guides` section in `INDEX.md`. + +## Step-by-Step +1. Feed producer workflow/script fetches source data (`NVD API` or issue payload). +2. JSON transform logic normalizes severity/type/affected fields and deduplicates by advisory ID. +3. Signature/checksum steps generate detached signatures and checksum manifests. +4. Deploy workflow mirrors signed artifacts under `public/` and `public/releases/latest/download/`. +5. UI and runtime consumers fetch feed/index files and validate format/signatures before use. +6. Matchers compare `affected` specifiers to skill names/versions and emit alerts or enforce confirmation. + +## Inputs and Outputs +Inputs/outputs are summarized in the table below. + +| Type | Name | Location | Description | +| --- | --- | --- | --- | +| Input | CVE payloads | `services.nvd.nist.gov/rest/json/cves/2.0` | Source vulnerabilities filtered by ClawSec keywords. | +| Input | Community advisory issue | `.github/workflows/community-advisory.yml` event payload | Maintainer-approved issue transformed into advisory record. | +| Input | Skill release assets | GitHub Releases API + assets | Used to build web catalog and mirror downloads. | +| Input | Local config/env | `OPENCLAW_AUDIT_CONFIG`, `CLAWSEC_*` vars | Controls feed pathing, suppression, and verification behavior. | +| Output | Advisory feed | `advisories/feed.json` | Canonical repository feed. | +| Output | Advisory signature | `advisories/feed.json.sig` | Detached signature for feed authenticity. | +| Output | Skill catalog index | `public/skills/index.json` | Runtime web catalog used by `/skills` pages. | +| Output | Release checksums/signatures | `release-assets/checksums.json(.sig)` | Integrity manifest for release consumers. | +| Output | Hook state | `~/.openclaw/clawsec-suite-feed-state.json` | Tracks scan timing and notified matches. | + +## Data Structures +| Structure | Key Fields | Purpose | +| --- | --- | --- | +| Advisory feed record | `id`, `severity`, `type`, `affected[]`, `published` | Unit of risk data used by UI and installers. | +| Skill metadata record | `id`, `name`, `version`, `emoji`, `tag` | Catalog row for web browsing and install commands. | +| Checksums manifest | `schema_version`, `algorithm`, `files` | Maps file names to expected digests. | +| Advisory state | `known_advisories`, `last_hook_scan`, `notified_matches` | Prevents repeated alerts and throttles scans. | +| Suppression config | `enabledFor[]`, `suppressions[]` | Targeted skip list by `checkId` + `skill`. | + +## Diagrams +```mermaid +flowchart LR + A["NVD + Issue Inputs"] --> B["Transform + Deduplicate"] + B --> C["advisories/feed.json"] + C --> D["Sign + checksums"] + D --> E["public/advisories + releases/latest"] + E --> F["Web UI fetch"] + E --> G["Suite/NanoClaw verification"] + G --> H["Match skills + emit alerts/gates"] +``` + +## State and Storage +| Store | Path/Scope | Write Path | +| --- | --- | --- | +| Canonical advisories | `advisories/` | NVD + community workflows and local populate script. | +| Embedded advisory copies | `skills/clawsec-feed/advisories/` and `skills/clawsec-suite/advisories/` | Sync/packaging processes and release workflow. | +| Public mirrors | `public/advisories/`, `public/releases/` | Deploy workflow. | +| Runtime state | `~/.openclaw/clawsec-suite-feed-state.json` | Advisory hook state persistence. | +| NanoClaw cache | `/workspace/project/data/clawsec-advisory-cache.json` | Host-side advisory cache manager. | +| Integrity state | `/workspace/project/data/soul-guardian/` (NanoClaw) | Integrity monitor baseline/audit storage. | + +## Example Snippets +```bash +# Local feed flow (NVD fetch -> transform -> sync) +./scripts/populate-local-feed.sh --days 120 +jq '.updated, (.advisories | length)' advisories/feed.json +``` + +```bash +# Runtime guarded install uses signed feed paths +CLAWSEC_LOCAL_FEED=~/.openclaw/skills/clawsec-suite/advisories/feed.json \ +CLAWSEC_FEED_PUBLIC_KEY=~/.openclaw/skills/clawsec-suite/advisories/feed-signing-public.pem \ +node skills/clawsec-suite/scripts/guarded_skill_install.mjs --skill test-skill --dry-run +``` + +## Failure Modes +- NVD rate limits (`403/429`) can delay feed refresh and require retries/backoff. +- Missing or invalid detached signatures cause feed rejection in fail-closed mode. +- HTML fallback responses for JSON endpoints can produce false positives unless explicitly filtered. +- Path-token misconfiguration (`\$HOME`) can break local fallback path resolution. +- Mismatched public key fingerprints in workflows trigger hard CI failure. + +## Source References +- advisories/feed.json +- advisories/feed.json.sig +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/deploy-pages.yml +- .github/workflows/skill-release.yml +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/state.ts +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/matching.ts +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/clawsec-nanoclaw/lib/advisories.ts +- skills/clawsec-nanoclaw/host-services/advisory-cache.ts diff --git a/public/wiki/llms/dependencies.txt b/public/wiki/llms/dependencies.txt new file mode 100644 index 0000000..ca37837 --- /dev/null +++ b/public/wiki/llms/dependencies.txt @@ -0,0 +1,112 @@ +# ClawSec Wiki · Dependencies + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/dependencies +- LLM export: https://clawsec.prompt.security/wiki/llms/dependencies.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/dependencies.md + +## Markdown + +# Dependencies + +## Build and Runtime +| Layer | Primary Dependencies | Why It Exists | +| --- | --- | --- | +| Frontend runtime | `react`, `react-dom`, `react-router-dom`, `lucide-react` | UI rendering, routing, iconography. | +| Markdown rendering | `react-markdown`, `remark-gfm` | Render skill docs/readmes in detail pages. | +| Build tooling | `vite`, `@vitejs/plugin-react`, `typescript` | Fast TS/TSX bundling and production builds. | +| Python utilities | stdlib + `ruff`/`bandit` policy from `pyproject.toml` | Validate/package skills and run static checks. | +| Shell automation | `bash`, `jq`, `curl`, `openssl`, `sha256sum`/`shasum` | Feed polling, signing, checksum generation, release checks. | + +## Dependency Details +| Package | Version Constraint | Scope | +| --- | --- | --- | +| `react` / `react-dom` | `^19.2.4` | Frontend runtime | +| `react-router-dom` | `^7.13.1` | Frontend routing | +| `lucide-react` | `^0.575.0` | UI icon set | +| `vite` | `^7.3.1` | Dev server + build | +| `typescript` | `~5.8.2` | Type checking | +| `eslint` | `^9.39.2` | JS/TS linting | +| `@typescript-eslint/*` | `^8.55.0` / `^8.56.0` | TS lint parser/rules | +| `fast-check` | `^4.5.3` | Property/fuzz style tests | + +| Override | Pinned Version | Rationale | +| --- | --- | --- | +| `ajv` | `6.14.0` | Security and compatibility stabilization. | +| `balanced-match` | `4.0.3` | Transitive vulnerability control. | +| `brace-expansion` | `5.0.2` | Transitive dependency hardening. | +| `minimatch` | `10.2.1` | Deterministic dependency behavior. | + +## External Services +| Service | Used By | Function | +| --- | --- | --- | +| NVD API (`services.nvd.nist.gov`) | `poll-nvd-cves` workflow + local feed script | Pull CVEs by keyword/date window. | +| GitHub API | Deploy/release workflows | Discover releases, download assets, publish outputs. | +| GitHub Pages | Deploy workflow | Serve static site and mirrored artifacts. | +| ClawHub CLI/registry | Install scripts + optional publish jobs | Install and publish skills. | +| Optional local SMTP/sendmail | `openclaw-audit-watchdog` scripts | Deliver audit reports by email. | + +## Development Tools +| Tool | Invocation | Coverage | +| --- | --- | --- | +| ESLint | `npx eslint . --ext .ts,.tsx,.js,.jsx,.mjs --max-warnings 0` | Frontend and script linting. | +| TypeScript | `npx tsc --noEmit` | Compile-time TS contract checks. | +| Ruff | `ruff check utils/` | Python style and bug pattern checks. | +| Bandit | `bandit -r utils/ -ll` | Python security checks. | +| Trivy | Workflow + optional local run | FS/config vulnerability scans. | +| Gitleaks | Workflow + optional local run | Secret leak detection. | + +## Example Snippets +```json +{ + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^19.2.4", + "react-router-dom": "^7.13.1" + } +} +``` + +```toml +[tool.ruff] +target-version = "py310" +line-length = 120 + +[tool.bandit] +exclude_dirs = ["__pycache__", ".venv"] +skips = ["B101"] +``` + +## Compatibility Notes +- Local scripts account for macOS vs Linux differences in `date` and `stat` usage. +- Some workflows/scripts require OpenSSL features used with Ed25519 and `pkeyutl -rawin`. +- Windows support is strongest for Node-based tooling; POSIX shell paths may require WSL/Git Bash. +- Feed consumers include compatibility bypasses for migration phases, but signed mode is the intended steady state. + +## Versioning Notes +- Skill release tags follow `-v` and are parsed by CI/deploy automation. +- PR validation enforces version parity between `skill.json` and `SKILL.md` frontmatter for bumped skills. +- The public skills index keeps latest discovered version per skill for UI display. +- Signed artifact manifests (`checksums.json`) are versioned per release and include file hashes and URLs. + +## Source References +- package.json +- package-lock.json +- pyproject.toml +- eslint.config.js +- tsconfig.json +- scripts/prepare-to-push.sh +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- .github/workflows/ci.yml +- .github/workflows/codeql.yml +- .github/workflows/scorecard.yml +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/deploy-pages.yml +- .github/workflows/skill-release.yml diff --git a/public/wiki/llms/generation.txt b/public/wiki/llms/generation.txt new file mode 100644 index 0000000..e55df2c --- /dev/null +++ b/public/wiki/llms/generation.txt @@ -0,0 +1,37 @@ +# ClawSec Wiki · Wiki Generation Metadata + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/generation +- LLM export: https://clawsec.prompt.security/wiki/llms/generation.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/GENERATION.md + +## Markdown + +# Wiki Generation Metadata + +- Commit hash: `448aed326192d38812cb508820f967cb74e77ae9` +- Branch name: `main` +- Generation timestamp (local): `2026-02-25T20:59:57+0200` +- Generation mode: `initial` +- Output language: `English` +- Assets copied into `wiki/assets/`: + - `overview_img_01_prompt-security-logo.png` (from `img/Black+Color.png`) + - `overview_img_02_clawsec-mascot.png` (from `public/img/mascot.png`) + - `architecture_img_01_prompt-line.svg` (from `public/img/prompt_line.svg`) + +## Notes +- This is a first-time generation (`wiki/` did not exist before this run). +- Index sections were generated from repository structure and created wiki pages. +- Future updates should preserve existing headings and append `Update Notes` sections when making deltas. + +## Source References +- README.md +- package.json +- AGENTS.md +- wiki/overview.md +- wiki/architecture.md +- wiki/dependencies.md +- wiki/data-flow.md +- wiki/glossary.md diff --git a/public/wiki/llms/glossary.txt b/public/wiki/llms/glossary.txt new file mode 100644 index 0000000..aa00e04 --- /dev/null +++ b/public/wiki/llms/glossary.txt @@ -0,0 +1,68 @@ +# ClawSec Wiki · Glossary + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/glossary +- LLM export: https://clawsec.prompt.security/wiki/llms/glossary.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/glossary.md + +## Markdown + +# Glossary + +## Terms +| Term | Definition | +| --- | --- | +| Advisory Feed | JSON document (`feed.json`) containing security advisories for skills/platforms. | +| Affected Specifier | Skill selector such as `skill@1.2.3`, wildcard, or range used in matching logic. | +| Guarded Install | Two-step installer behavior that requires explicit confirmation when advisories match. | +| SBOM Files | Skill-declared artifact list in `skill.json` used for packaging and validation. | +| Detached Signature | Base64 signature file (`.sig`) stored separately from signed payload. | +| Checksum Manifest | File hash map (`checksums.json`) used to verify payload integrity. | + +## Skill Packaging Terms +| Term | Definition | +| --- | --- | +| Skill Tag | Git tag formatted as `-v` used by release automation. | +| Release Assets | Files attached to GitHub release (zip, `skill.json`, checksums, signatures). | +| Catalog Index | `public/skills/index.json`, generated list consumed by web catalog. | +| Embedded Components | Capability bundle from one skill included in another (for example feed embedded in suite). | + +## Advisory and Security Terms +| Term | Definition | +| --- | --- | +| Fail-Closed Verification | Reject payload if signature or checksum validation fails. | +| Unsigned Compatibility Mode | Temporary bypass path enabled via `CLAWSEC_ALLOW_UNSIGNED_FEED=1`. | +| Suppression Rule | Config entry matching `checkId` and `skill` to suppress known/accepted findings. | +| Key Fingerprint | SHA-256 digest of DER-encoded public key used for key consistency checks. | + +## Runtime and Platform Terms +| Term | Definition | +| --- | --- | +| OpenClaw Hook | Runtime event handler (`clawsec-advisory-guardian`) that checks advisories. | +| NanoClaw IPC | Host/container task exchange for advisory refresh, signature verification, integrity checks. | +| Integrity Baseline | Stored approved hashes/snapshots for protected files. | +| Hash-Chained Audit Log | Append-only audit log where each entry depends on prior hash. | + +## CI/CD Terms +| Term | Definition | +| --- | --- | +| Poll NVD CVEs Workflow | Scheduled workflow that fetches and transforms NVD CVEs into advisories. | +| Community Advisory Workflow | Issue-label-triggered workflow that publishes approved community advisories. | +| Skill Release Workflow | Tag-triggered packaging/signing/publishing pipeline for skills. | +| Deploy Pages Workflow | Workflow that builds site assets and mirrors release/advisory artifacts. | + +## Source References +- types.ts +- skills/clawsec-suite/skill.json +- skills/clawsec-nanoclaw/skill.json +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/suppression.mjs +- skills/clawsec-nanoclaw/guardian/integrity-monitor.ts +- scripts/populate-local-feed.sh +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/skill-release.yml +- .github/workflows/deploy-pages.yml diff --git a/public/wiki/llms/index.txt b/public/wiki/llms/index.txt new file mode 100644 index 0000000..c9acc82 --- /dev/null +++ b/public/wiki/llms/index.txt @@ -0,0 +1,54 @@ +# ClawSec Wiki · Wiki Index + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki +- LLM export: https://clawsec.prompt.security/wiki/llms/index.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/INDEX.md + +## Markdown + +# Wiki Index + +## Summary +- Purpose: Document ClawSec as a combined web catalog, signed advisory channel, and multi-skill security distribution system. +- Tech stack: React 19 + Vite + TypeScript frontend, Node/ESM scripts, Python utilities, Bash automation, GitHub Actions pipelines. +- Entry points: `index.tsx`, `App.tsx`, `scripts/prepare-to-push.sh`, `scripts/populate-local-feed.sh`, `scripts/populate-local-skills.sh`, workflow files under `.github/workflows/`. +- Where to start: Read [Overview](overview.md), then [Architecture](architecture.md), then module pages for the area you are editing. +- How to navigate: Use Guides for cross-cutting concerns, Modules for implementation boundaries, and Source References at the end of each page to jump into code. + +## Start Here +- [Overview](overview.md) +- [Architecture](architecture.md) + +## Guides +- [Dependencies](dependencies.md) +- [Data Flow](data-flow.md) +- [Configuration](configuration.md) +- [Testing](testing.md) +- [Workflow](workflow.md) +- [Security](security.md) + +## Modules +- [Frontend Web App](modules/frontend-web.md) +- [ClawSec Suite Core](modules/clawsec-suite.md) +- [NanoClaw Integration](modules/nanoclaw-integration.md) +- [Automation and Release Pipelines](modules/automation-release.md) +- [Local Validation and Packaging Tools](modules/local-tooling.md) + +## Glossary +- [Glossary](glossary.md) + +## Generation Metadata +- [Generation Metadata](GENERATION.md) + +## Source References +- README.md +- App.tsx +- package.json +- scripts/prepare-to-push.sh +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- skills/clawsec-suite/skill.json +- .github/workflows/ci.yml diff --git a/public/wiki/llms/modules/automation-release.txt b/public/wiki/llms/modules/automation-release.txt new file mode 100644 index 0000000..a913425 --- /dev/null +++ b/public/wiki/llms/modules/automation-release.txt @@ -0,0 +1,103 @@ +# ClawSec Wiki · Module: Automation and Release Pipelines + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/modules/automation-release +- LLM export: https://clawsec.prompt.security/wiki/llms/modules/automation-release.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/automation-release.md + +## Markdown + +# Module: Automation and Release Pipelines + +## Responsibilities +- Enforce repository quality/security checks before merge and deployment. +- Generate and maintain advisory feed updates from automated and community sources. +- Package, sign, and publish skill release artifacts from tag events. +- Build and deploy static website outputs and mirrored release/advisory assets. + +## Key Files +- `.github/workflows/ci.yml`: lint/type/build/security/test matrix. +- `.github/workflows/poll-nvd-cves.yml`: daily NVD advisory ingestion. +- `.github/workflows/community-advisory.yml`: issue-label-driven advisory publishing. +- `.github/workflows/skill-release.yml`: release validation, packaging, signing, and publishing. +- `.github/workflows/deploy-pages.yml`: site build + asset mirroring to GitHub Pages. +- `.github/actions/sign-and-verify/action.yml`: shared Ed25519 sign/verify composite action. +- `scripts/prepare-to-push.sh`: local CI-like quality gate. +- `scripts/release-skill.sh`: manual helper for version bump + tag workflow. + +## Public Interfaces +| Interface | Trigger | Outcome | +| --- | --- | --- | +| CI workflow | Push/PR on `main` | Fails fast on lint/type/build/test/security regressions. | +| NVD poll workflow | Cron + dispatch | Updates advisory feed with deduped, normalized CVEs. | +| Community advisory workflow | Issue labeled `advisory-approved` | Opens PR adding signed advisory records. | +| Skill release workflow | Tag `-v*` | Creates GitHub release assets and signatures. | +| Deploy pages workflow | Successful CI/release run | Publishes site + mirrored artifacts to Pages. | + +## Inputs and Outputs +Inputs/outputs are summarized in the table below. + +| Type | Name | Location | Description | +| --- | --- | --- | --- | +| Input | Git refs/events | GitHub Actions event payloads | Determines which workflow path runs. | +| Input | Skill metadata/SBOM | `skills/*/skill.json` | Drives release asset assembly and validation. | +| Input | NVD API data | External API responses | Source CVEs for advisory feed generation. | +| Input | Signing secrets | GitHub Secrets | Private key material for signing artifacts. | +| Output | Signed advisories | `advisories/feed.json(.sig)` + mirrored public files | Consumable signed feed channel. | +| Output | Skill release assets | `release-assets/*` and GitHub release attachments | Installable and verifiable skill artifacts. | +| Output | Website build | `dist/` deployment artifact | Public web frontend and mirrors. | + +## Configuration +| Config Point | Location | Notes | +| --- | --- | --- | +| Workflow schedules | `poll-nvd-cves.yml`, `codeql.yml`, `scorecard.yml` | Daily/weekly security automation cadence. | +| Concurrency groups | Workflow `concurrency` blocks | Prevents destructive overlap in key pipelines. | +| Signing key checks | `scripts/ci/verify_signing_key_consistency.sh` | Ensures docs and canonical PEM files align. | +| Local pre-push gating | `scripts/prepare-to-push.sh` | Mirrors CI checks with optional auto-fix. | + +## Example Snippets +```yaml +# skill release trigger pattern +on: + push: + tags: + - '*-v[0-9]*.[0-9]*.[0-9]*' +``` + +```bash +# local all-in-one pre-push gate +./scripts/prepare-to-push.sh +# optional auto-fix +./scripts/prepare-to-push.sh --fix +``` + +## Edge Cases +- NVD API rate limiting (`403`/`429`) is handled with retry/backoff and can fail workflow on persistent errors. +- Release pipeline blocks on version mismatch between `skill.json` and `SKILL.md` frontmatter. +- Key fingerprint drift between canonical PEM files and docs hard-fails signing-related workflows. +- Deploy workflow intentionally allows unsigned legacy checksums for backward compatibility in some branches. +- Manual helper script has safety checks but includes destructive rollback logic in error branches; use carefully. + +## Tests +| Validation Layer | Location | +| --- | --- | +| Workflow execution tests | CI jobs in `.github/workflows/ci.yml` | +| Skill-level unit/property tests | `skills/*/test/*.test.mjs` invoked by CI | +| Local deterministic checks | `scripts/prepare-to-push.sh` | +| Release link checks | `scripts/validate-release-links.sh` | + +## Source References +- .github/workflows/ci.yml +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/skill-release.yml +- .github/workflows/deploy-pages.yml +- .github/workflows/codeql.yml +- .github/workflows/scorecard.yml +- .github/actions/sign-and-verify/action.yml +- scripts/prepare-to-push.sh +- scripts/release-skill.sh +- scripts/validate-release-links.sh +- scripts/ci/verify_signing_key_consistency.sh diff --git a/public/wiki/llms/modules/clawsec-suite.txt b/public/wiki/llms/modules/clawsec-suite.txt new file mode 100644 index 0000000..4017695 --- /dev/null +++ b/public/wiki/llms/modules/clawsec-suite.txt @@ -0,0 +1,107 @@ +# ClawSec Wiki · Module: ClawSec Suite Core + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/modules/clawsec-suite +- LLM export: https://clawsec.prompt.security/wiki/llms/modules/clawsec-suite.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/clawsec-suite.md + +## Markdown + +# Module: ClawSec Suite Core + +## Responsibilities +- Act as the main skill-of-skills security bundle for OpenClaw-style agents. +- Verify advisory feed authenticity (Ed25519 signatures and optional checksum manifests). +- Detect advisory matches against installed skills and emit actionable runtime alerts. +- Enforce two-step confirmation for risky skill installations. + +## Key Files +- `skills/clawsec-suite/skill.json`: suite metadata, embedded components, catalog defaults. +- `skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts`: runtime event handler. +- `skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs`: signed feed loading/parsing. +- `skills/clawsec-suite/hooks/.../lib/matching.ts`: advisory-to-skill matching logic. +- `skills/clawsec-suite/hooks/.../lib/state.ts`: scan state persistence. +- `skills/clawsec-suite/hooks/.../lib/suppression.mjs`: allowlist-based suppression loader. +- `skills/clawsec-suite/scripts/guarded_skill_install.mjs`: advisory-gated installer wrapper. +- `skills/clawsec-suite/scripts/discover_skill_catalog.mjs`: remote/fallback catalog discovery. + +## Public Interfaces +| Interface | Consumer | Behavior | +| --- | --- | --- | +| Hook handler default export | OpenClaw hook runtime | Handles `agent:bootstrap` and `command:new` events. | +| `guarded_skill_install.mjs` CLI | Operators/automation | Blocks on advisory matches unless `--confirm-advisory`. | +| `discover_skill_catalog.mjs` CLI | Suite docs/automation | Lists installable skills with fallback metadata. | +| `feed.mjs` functions | Suite scripts and tests | Feed load, signature verification, checksum manifest checks. | +| Exit code contract | External wrappers | `42` indicates explicit second confirmation required. | + +## Inputs and Outputs +Inputs/outputs are summarized in the table below. + +| Type | Name | Location | Description | +| --- | --- | --- | --- | +| Input | Advisory feed + signatures | Remote URLs or local `advisories/` files | Risk intelligence source for hook and installer. | +| Input | Installed skill metadata | Skill directories under install root | Matcher compares installed versions to advisory affected specs. | +| Input | Suppression config | `OPENCLAW_AUDIT_CONFIG` or default config paths | Selective suppression by check and skill name. | +| Output | Runtime alert messages | Hook event `messages[]` | Advisories and recommended user actions. | +| Output | Persistent state | `~/.openclaw/clawsec-suite-feed-state.json` | De-dup alerts, track scan windows. | +| Output | CLI gating exit codes | Installer process status | Ensures deliberate user confirmation on risk. | + +## Configuration +| Variable | Default | Module Effect | +| --- | --- | --- | +| `CLAWSEC_FEED_URL` | Hosted advisory URL | Chooses primary remote feed endpoint. | +| `CLAWSEC_LOCAL_FEED*` vars | Suite-local advisories directory | Configures local signed fallback artifacts. | +| `CLAWSEC_FEED_PUBLIC_KEY` | `advisories/feed-signing-public.pem` | Verification key path. | +| `CLAWSEC_ALLOW_UNSIGNED_FEED` | `0` | Enables temporary migration bypass mode. | +| `CLAWSEC_VERIFY_CHECKSUM_MANIFEST` | `1` | Enables checksum manifest verification layer. | +| `CLAWSEC_HOOK_INTERVAL_SECONDS` | `300` | Controls event-driven scan throttling. | + +## Example Snippets +```ts +// hook only handles selected events +function shouldHandleEvent(event: HookEvent): boolean { + const eventName = toEventName(event); + return eventName === 'agent:bootstrap' || eventName === 'command:new'; +} +``` + +```js +// guarded installer confirmation contract +if (matches.length > 0 && !args.confirmAdvisory) { + process.stdout.write('Re-run with --confirm-advisory to proceed.\n'); + process.exit(EXIT_CONFIRM_REQUIRED); // 42 +} +``` + +## Edge Cases +- Missing/malformed feed signatures force remote rejection and local fallback attempts. +- Ambiguous checksum manifest basename collisions are treated as errors. +- Unknown skill versions are treated conservatively in version matching logic. +- Suppression is disabled unless config includes the pipeline sentinel (`enabledFor`). +- Invalid environment path tokens are rejected to avoid accidental literal path usage. + +## Tests +| Test File | Focus | +| --- | --- | +| `skills/clawsec-suite/test/feed_verification.test.mjs` | Signature/checksum verification and fail-closed behavior. | +| `skills/clawsec-suite/test/guarded_install.test.mjs` | Confirmation gating and match semantics. | +| `skills/clawsec-suite/test/path_resolution.test.mjs` | Home/path expansion and invalid token handling. | +| `skills/clawsec-suite/test/advisory_suppression.test.mjs` | Suppression config parsing and matching. | +| `skills/clawsec-suite/test/skill_catalog_discovery.test.mjs` | Remote index and fallback merge behavior. | + +## Source References +- skills/clawsec-suite/skill.json +- skills/clawsec-suite/SKILL.md +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/matching.ts +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/state.ts +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/suppression.mjs +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/version.mjs +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/clawsec-suite/scripts/discover_skill_catalog.mjs +- skills/clawsec-suite/test/feed_verification.test.mjs +- skills/clawsec-suite/test/guarded_install.test.mjs +- skills/clawsec-suite/test/path_resolution.test.mjs diff --git a/public/wiki/llms/modules/frontend-web.txt b/public/wiki/llms/modules/frontend-web.txt new file mode 100644 index 0000000..ffacaa6 --- /dev/null +++ b/public/wiki/llms/modules/frontend-web.txt @@ -0,0 +1,109 @@ +# ClawSec Wiki · Module: Frontend Web App + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/modules/frontend-web +- LLM export: https://clawsec.prompt.security/wiki/llms/modules/frontend-web.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/frontend-web.md + +## Markdown + +# Module: Frontend Web App + +## Responsibilities +- Render the ClawSec website for home, skills catalog/detail, and advisory feed/detail experiences. +- Provide resilient JSON fetch behavior that handles SPA HTML fallback cases. +- Display install commands, checksums, and advisory metadata in a browser-focused UX. + +## Key Files +- `index.tsx`: React bootstrap and root mount. +- `App.tsx`: Router map and page entry wiring. +- `pages/Home.tsx`: Landing page, install card, animated platform/file labels. +- `pages/SkillsCatalog.tsx`: Catalog fetch/filter state machine and empty-state handling. +- `pages/SkillDetail.tsx`: Loads `skill.json`, checksums, README/SKILL docs with markdown renderer. +- `pages/FeedSetup.tsx`: Advisory listing UI with pagination. +- `pages/AdvisoryDetail.tsx`: Advisory deep-dive view and source links. +- `components/Layout.tsx` + `components/Header.tsx`: Shared shell and nav behavior. + +## Public Interfaces +- Browser routes: + - `/` + - `/skills` + - `/skills/:skillId` + - `/feed` + - `/feed/:advisoryId` +- Static fetch targets: + - `/skills/index.json` + - `/skills//skill.json` + - `/skills//checksums.json` + - `/advisories/feed.json` +- Display contracts: + - `SkillMetadata`, `SkillJson`, `SkillChecksums`, `AdvisoryFeed`, `Advisory` from `types.ts`. + +## Inputs and Outputs +Inputs/outputs are summarized in the table below. + +| Type | Name | Location | Description | +| --- | --- | --- | --- | +| Input | Skills index JSON | `/skills/index.json` | List of published skills and metadata. | +| Input | Skill payload files | `/skills//skill.json`, markdown docs, `checksums.json` | Detail-page content and integrity table. | +| Input | Advisory feed JSON | `/advisories/feed.json` or remote URL fallback | Advisory list/detail content. | +| Output | Route-specific UI states | Browser view state | Loading, empty, error, and populated experiences. | +| Output | Copy-to-clipboard commands | Clipboard API | Install and checksum snippets copied for users. | + +## Configuration +- Build/runtime config comes from: + - `vite.config.ts` (port, host, path alias) + - `index.html` Tailwind config + custom fonts/colors + - `constants.ts` (`ADVISORY_FEED_URL`, `LOCAL_FEED_PATH`) +- Runtime behavior assumptions: + - JSON responses may be empty or HTML fallback and must be validated. + - Advisory list pagination uses `ITEMS_PER_PAGE = 9`. + +## Example Snippets +```tsx +// Catalog fetch logic guards against HTML fallback responses +const contentType = response.headers.get('content-type') ?? ''; +const raw = await response.text(); +if (!raw.trim() || contentType.includes('text/html') || isProbablyHtmlDocument(raw)) { + setSkills([]); + setFilteredSkills([]); + return; +} +``` + +```tsx +// Route map defined in App.tsx +} /> +} /> +``` + +## Edge Cases +- Missing `skills/index.json` returns empty catalog instead of hard failure. +- Some environments return `index.html` for missing JSON paths with status `200`; code defends against this. +- Skill detail tolerates missing/malformed checksums and missing markdown docs. +- Advisory detail handles absent optional fields (`cvss_score`, `reporter`, `references`). + +## Tests +| Test Type | Location | Notes | +| --- | --- | --- | +| Type/lint/build checks | `scripts/prepare-to-push.sh` + CI | Frontend confidence comes from static checks and build success. | +| App-wide CI gates | `.github/workflows/ci.yml` | Multi-OS TypeScript/ESLint/build checks. | +| Manual smoke checks | `npm run dev` | Validate route rendering and fetch paths during development. | + +## Source References +- index.tsx +- App.tsx +- pages/Home.tsx +- pages/SkillsCatalog.tsx +- pages/SkillDetail.tsx +- pages/FeedSetup.tsx +- pages/AdvisoryDetail.tsx +- pages/Checksums.tsx +- components/Layout.tsx +- components/Header.tsx +- constants.ts +- types.ts +- vite.config.ts +- index.html diff --git a/public/wiki/llms/modules/local-tooling.txt b/public/wiki/llms/modules/local-tooling.txt new file mode 100644 index 0000000..54b6dff --- /dev/null +++ b/public/wiki/llms/modules/local-tooling.txt @@ -0,0 +1,95 @@ +# ClawSec Wiki · Module: Local Validation and Packaging Tools + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/modules/local-tooling +- LLM export: https://clawsec.prompt.security/wiki/llms/modules/local-tooling.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/local-tooling.md + +## Markdown + +# Module: Local Validation and Packaging Tools + +## Responsibilities +- Validate skill directory metadata/schema and SBOM file presence before release. +- Generate per-skill checksums manifests for local testing or packaging. +- Provide local data bootstrap scripts that mirror CI behavior for advisories and skills. +- Offer release-link and signing-key consistency checks for maintainers. + +## Key Files +- `utils/validate_skill.py`: schema and file existence checks for a skill directory. +- `utils/package_skill.py`: checksum manifest generator with skill pre-validation. +- `scripts/populate-local-skills.sh`: generates local catalog and checksums under `public/skills/`. +- `scripts/populate-local-feed.sh`: pulls NVD data and updates feed copies. +- `scripts/validate-release-links.sh`: verifies docs reference releasable assets. +- `scripts/ci/verify_signing_key_consistency.sh`: verifies key fingerprints across docs/files. + +## Public Interfaces +| Tool | Interface | Primary Output | +| --- | --- | --- | +| `validate_skill.py` | `python utils/validate_skill.py ` | Exit code + validation summary with warnings/errors. | +| `package_skill.py` | `python utils/package_skill.py [out-dir]` | `checksums.json` artifact for skill files. | +| `populate-local-skills.sh` | shell CLI | `public/skills/index.json` and per-skill files/checksums. | +| `populate-local-feed.sh` | shell CLI flags `--days`, `--force` | Updated advisory feeds in repo/skill/public paths. | +| `validate-release-links.sh` | shell CLI optional skill arg | Release-link validation report. | + +## Inputs and Outputs +Inputs/outputs are summarized in the table below. + +| Type | Name | Location | Description | +| --- | --- | --- | --- | +| Input | Skill metadata and SBOM | `skills//skill.json` | Enumerates required files and release artifacts. | +| Input | Existing feed state | `advisories/feed.json` | Determines incremental NVD polling start date. | +| Input | Environment tools | `jq`, `curl`, `openssl`, Python runtime | Required execution dependencies. | +| Output | Validation diagnostics | stdout/stderr + exit code | Signals readiness for release/CI. | +| Output | Checksums manifests | `checksums.json` | Integrity data for skill artifacts. | +| Output | Local mirrors | `public/skills/*`, `public/advisories/feed.json` | Makes local web preview match CI outputs. | + +## Configuration +| Setting | Location | Purpose | +| --- | --- | --- | +| Ruff/Bandit policy | `pyproject.toml` | Python lint/security baseline. | +| CLI flags (`--days`, `--force`) | `populate-local-feed.sh` | Controls window and overwrite semantics. | +| `OPENCLAW_AUDIT_CONFIG` | suppression loaders in scripts | Chooses suppression config path. | +| `CLAWSEC_*` env vars | installer/hook scripts | Path and verification behavior tuning. | + +## Example Snippets +```bash +# validate and package a skill locally +python utils/validate_skill.py skills/clawsec-feed +python utils/package_skill.py skills/clawsec-feed ./dist +``` + +```bash +# refresh local UI data to mirror CI-generated artifacts +./scripts/populate-local-skills.sh +./scripts/populate-local-feed.sh --days 120 +``` + +## Edge Cases +- Validation allows warnings (for example missing optional files) while still returning success when required fields/files are present. +- NVD poll script handles macOS/Linux differences in `date` and `stat` utilities. +- Release-link validation can detect doc references to files missing from SBOM-derived release assets. +- Path expansion guards reject unexpanded home-token literals to avoid misdirected filesystem writes. + +## Tests +| Test/Check | Scope | +| --- | --- | +| `ruff check utils/` | Python style and correctness checks. | +| `bandit -r utils/ -ll` | Python security issue scan. | +| `scripts/prepare-to-push.sh` | Combined local gate across TS/Python/shell/security checks. | +| Skill-local tests | `skills/*/test/*.test.mjs` (targeted invocation) | + +## Source References +- utils/validate_skill.py +- utils/package_skill.py +- pyproject.toml +- scripts/populate-local-skills.sh +- scripts/populate-local-feed.sh +- scripts/prepare-to-push.sh +- scripts/validate-release-links.sh +- scripts/ci/verify_signing_key_consistency.sh +- skills/openclaw-audit-watchdog/scripts/load_suppression_config.mjs +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/clawsec-suite/scripts/discover_skill_catalog.mjs diff --git a/public/wiki/llms/modules/nanoclaw-integration.txt b/public/wiki/llms/modules/nanoclaw-integration.txt new file mode 100644 index 0000000..ebdfd5c --- /dev/null +++ b/public/wiki/llms/modules/nanoclaw-integration.txt @@ -0,0 +1,108 @@ +# ClawSec Wiki · Module: NanoClaw Integration + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/modules/nanoclaw-integration +- LLM export: https://clawsec.prompt.security/wiki/llms/modules/nanoclaw-integration.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/nanoclaw-integration.md + +## Markdown + +# Module: NanoClaw Integration + +## Responsibilities +- Port ClawSec advisory/signature logic into NanoClaw host+container architecture. +- Provide MCP tools that expose advisory checks, signature verification, and integrity monitoring. +- Maintain host-side cached advisory state with TLS/signature enforcement and IPC-triggered refresh. +- Protect critical NanoClaw files with baseline drift detection and hash-chained audit trails. + +## Key Files +- `skills/clawsec-nanoclaw/skill.json`: NanoClaw package contract and MCP tool registry. +- `skills/clawsec-nanoclaw/lib/signatures.ts`: secure fetch and Ed25519 verification primitives. +- `skills/clawsec-nanoclaw/lib/advisories.ts`: feed load and advisory matching helpers. +- `skills/clawsec-nanoclaw/host-services/advisory-cache.ts`: host cache manager. +- `skills/clawsec-nanoclaw/host-services/ipc-handlers.ts`: IPC request dispatch for advisory/signature tasks. +- `skills/clawsec-nanoclaw/host-services/skill-signature-handler.ts`: package signature verification service. +- `skills/clawsec-nanoclaw/guardian/integrity-monitor.ts`: baseline/diff/restore/audit engine. +- `skills/clawsec-nanoclaw/mcp-tools/*.ts`: container-side tool definitions. + +## Public Interfaces +| Interface | Context | Notes | +| --- | --- | --- | +| `clawsec_check_advisories` | MCP tool | Lists advisories affecting installed skills. | +| `clawsec_check_skill_safety` | MCP tool | Returns install recommendation for a specific skill. | +| `clawsec_verify_skill_package` | MCP tool | Verifies detached package signature through host IPC. | +| `clawsec_check_integrity` | MCP tool | Runs integrity check, optional auto-restore for critical targets. | +| IPC task `verify_skill_signature` | Host service | Returns structured verification response with error codes. | +| IPC task `refresh_advisory_cache` | Host service | Refreshes signed advisory cache on demand. | + +## Inputs and Outputs +Inputs/outputs are summarized in the table below. + +| Type | Name | Location | Description | +| --- | --- | --- | --- | +| Input | Signed advisory feed | `https://clawsec.prompt.security/advisories/feed.json(.sig)` | Threat intelligence source for cache refresh. | +| Input | Package + signature files | Host filesystem paths | Pre-install package authenticity checks. | +| Input | Integrity policy | `guardian/policy.json` | Per-path mode and priority controls. | +| Output | Advisory cache | `/workspace/project/data/clawsec-advisory-cache.json` | Host-managed verified advisory data. | +| Output | Verification results | `/workspace/ipc/clawsec_results/*.json` | IPC response payload for tool calls. | +| Output | Integrity state | `.../soul-guardian/` | Baselines, snapshots, patches, quarantine, audit logs. | + +## Configuration +| Setting | Default | Effect | +| --- | --- | --- | +| Feed URL | Hosted ClawSec advisory endpoint | Primary remote source for advisory cache manager. | +| Cache TTL | `5 minutes` | Controls staleness threshold before requiring refresh. | +| Fetch timeout | `10 seconds` | Limits host network wait time. | +| Allowed domains | `clawsec.prompt.security`, `prompt.security`, `raw.githubusercontent.com`, `github.com` | Restricts remote fetch targets. | +| Integrity policy modes | `restore`, `alert`, `ignore` | Controls automatic restoration and alert-only behavior. | + +## Example Snippets +```ts +// host-side signature verification dispatch +const result = await deps.signatureVerifier.verify({ + packagePath, + signaturePath, + publicKeyPem, + allowUnsigned: allowUnsigned || false, +}); +``` + +```ts +// integrity monitor drift handling +if (baseline.mode === 'restore' && autoRestore) { + // quarantine modified file, restore approved snapshot, append audit event +} +``` + +## Edge Cases +- Disallowed domains or non-HTTPS URLs are blocked by security policy wrappers. +- Missing signature files can be tolerated only when `allowUnsigned` is explicitly set. +- IPC result waits can timeout, causing conservative block recommendations. +- Integrity engine refuses symlink operations to reduce path-redirection attacks. +- Audit-chain validation can detect tampering or corruption in historical records. + +## Tests +| Test Scope | File/Path | Notes | +| --- | --- | --- | +| Type contracts | `skills/clawsec-nanoclaw/lib/types.ts` | Defines tool/IPC DB payload contracts. | +| Operational docs | `docs/SKILL_SIGNING.md`, `docs/INTEGRITY.md` | Describes verification/integrity usage patterns. | +| Cross-module behavior | Reuses suite verification patterns | Signature/checksum primitives ported from suite logic. | + +## Source References +- skills/clawsec-nanoclaw/skill.json +- skills/clawsec-nanoclaw/lib/types.ts +- skills/clawsec-nanoclaw/lib/signatures.ts +- skills/clawsec-nanoclaw/lib/advisories.ts +- skills/clawsec-nanoclaw/host-services/advisory-cache.ts +- skills/clawsec-nanoclaw/host-services/ipc-handlers.ts +- skills/clawsec-nanoclaw/host-services/skill-signature-handler.ts +- skills/clawsec-nanoclaw/host-services/integrity-handler.ts +- skills/clawsec-nanoclaw/guardian/integrity-monitor.ts +- skills/clawsec-nanoclaw/guardian/policy.json +- skills/clawsec-nanoclaw/mcp-tools/advisory-tools.ts +- skills/clawsec-nanoclaw/mcp-tools/signature-verification.ts +- skills/clawsec-nanoclaw/mcp-tools/integrity-tools.ts +- skills/clawsec-nanoclaw/docs/SKILL_SIGNING.md +- skills/clawsec-nanoclaw/docs/INTEGRITY.md diff --git a/public/wiki/llms/overview.txt b/public/wiki/llms/overview.txt new file mode 100644 index 0000000..dfb474d --- /dev/null +++ b/public/wiki/llms/overview.txt @@ -0,0 +1,113 @@ +# ClawSec Wiki · Overview + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/overview +- LLM export: https://clawsec.prompt.security/wiki/llms/overview.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/overview.md + +## Markdown + +# Overview + +## Purpose +- ClawSec is a security-focused repository that combines a public web catalog with installable security skills for OpenClaw and NanoClaw environments. +- The codebase supports three delivery paths at once: static website publishing, signed advisory distribution, and per-skill GitHub release packaging. +- Primary users are agent operators, skill developers, and maintainers running CI-based security automation. + +![Prompt Security Logo](assets/overview_img_01_prompt-security-logo.png) +![ClawSec Mascot](assets/overview_img_02_clawsec-mascot.png) + +## Repo Layout +| Path | Role | Notes | +| --- | --- | --- | +| `pages/`, `components/`, `App.tsx`, `index.tsx` | Vite + React UI | Skill catalog, advisory feed, and detail pages. | +| `skills/` | Security skill packages | Each skill has `skill.json`, `SKILL.md`, optional scripts/tests/docs. | +| `advisories/` | Repository advisory channel | Signed `feed.json` + `feed.json.sig` and key material. | +| `scripts/` | Local automation | Populate feed/skills, pre-push checks, release helpers. | +| `.github/workflows/` | CI/CD pipelines | CI, releases, NVD polling, community advisory ingestion, pages deploy. | +| `utils/` | Python utilities | Skill validation and checksum packaging helpers. | +| `public/` | Published static assets | Site media, mirrored advisories, and generated skill artifacts. | +| `docs/` | Operational docs | Signing runbooks, migration plans, compatibility and verification guides. | + +## Entry Points +| Entry | Type | Purpose | +| --- | --- | --- | +| `index.tsx` | Frontend bootstrap | Mounts React app into `#root`. | +| `App.tsx` | Frontend router | Defines route map for home, skills, and feed pages. | +| `scripts/prepare-to-push.sh` | Dev workflow | Runs lint/type/build/security checks before push. | +| `scripts/populate-local-feed.sh` | Data bootstrap | Pulls CVEs from NVD and updates local advisory feeds. | +| `scripts/populate-local-skills.sh` | Data bootstrap | Builds `public/skills/index.json` and per-skill checksums. | +| `.github/workflows/skill-release.yml` | Release entry | Handles tag-based skill packaging/signing/release. | +| `.github/workflows/poll-nvd-cves.yml` | Scheduled feed updates | Polls NVD and updates advisories. | + +## Key Artifacts +| Artifact | Produced By | Consumed By | +| --- | --- | --- | +| `advisories/feed.json` | NVD poll + community advisory workflows | Web UI, clawsec-suite hook, installers. | +| `advisories/feed.json.sig` | Signing workflow steps | Signature verification in suite/nanoclaw tooling. | +| `public/skills/index.json` | Deploy workflow / local populate script | `pages/SkillsCatalog.tsx` and `pages/SkillDetail.tsx`. | +| `public/checksums.json` + `public/checksums.sig` | Deploy workflow | Client-side integrity verification flows. | +| `release-assets/checksums.json` | Skill release workflow | Release consumers verifying zip integrity. | +| `skills/*/skill.json` | Skill authors | Site catalog generation, validators, and release pipelines. | + +## Key Workflows +- Local web development: `npm install` then `npm run dev`. +- Local security data preview: run `./scripts/populate-local-skills.sh` and `./scripts/populate-local-feed.sh` before loading `/skills` and `/feed` pages. +- Pre-push quality gate: run `./scripts/prepare-to-push.sh` (optionally `--fix`). +- Skill lifecycle: edit `skills//`, validate with `python utils/validate_skill.py`, then tag `-vX.Y.Z` to trigger release workflow. +- Advisory lifecycle: scheduled NVD poll and issue-label-based community ingestion both merge into the same signed feed. + +## Example Snippets +```bash +# local UI + locally populated data +npm install +./scripts/populate-local-skills.sh +./scripts/populate-local-feed.sh --days 120 +npm run dev +``` + +```bash +# canonical TypeScript quality checks used by CI +npx eslint . --ext .ts,.tsx,.js,.jsx,.mjs --max-warnings 0 +npx tsc --noEmit +npm run build +``` + +## Where to Start +- Read `README.md` for product positioning and install paths. +- Open `App.tsx` and `pages/` to understand user-facing behavior. +- Open `skills/clawsec-suite/skill.json` to understand the suite contract and embedded components. +- Review `.github/workflows/ci.yml`, `.github/workflows/skill-release.yml`, and `.github/workflows/deploy-pages.yml` for production behavior. + +## How to Navigate +- UI behavior is centered in `pages/`; visual wrappers sit in `components/`. +- Skill-specific logic is isolated by folder under `skills/`; each folder includes its own scripts/tests/docs. +- Feed handling appears in three layers: repository feed files, workflow updates, and runtime consumers (`clawsec-suite`/`clawsec-nanoclaw`). +- Operational quality gates live in `scripts/` and workflow YAML files. +- For generation traces and update baselines, start from `wiki/GENERATION.md` and then branch into module pages. + +## Common Pitfalls +- Using literal home tokens (for example `\$HOME`) in config path env vars can trigger path validation failures. +- Fetching JSON from SPA routes can return HTML with status 200; pages guard for this and treat it as empty-state. +- Unsigned feed bypass mode (`CLAWSEC_ALLOW_UNSIGNED_FEED=1`) exists for migration compatibility and should not be used in steady state. +- Skill release automation expects version parity between `skill.json` and `SKILL.md` frontmatter. +- Some scripts are POSIX shell oriented; Windows users should prefer PowerShell equivalents or WSL. + +## Source References +- README.md +- package.json +- App.tsx +- index.tsx +- pages/Home.tsx +- pages/SkillsCatalog.tsx +- pages/SkillDetail.tsx +- pages/FeedSetup.tsx +- scripts/prepare-to-push.sh +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- skills/clawsec-suite/skill.json +- .github/workflows/ci.yml +- .github/workflows/skill-release.yml +- .github/workflows/deploy-pages.yml diff --git a/public/wiki/llms/security.txt b/public/wiki/llms/security.txt new file mode 100644 index 0000000..2415537 --- /dev/null +++ b/public/wiki/llms/security.txt @@ -0,0 +1,85 @@ +# ClawSec Wiki · Security + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/security +- LLM export: https://clawsec.prompt.security/wiki/llms/security.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/security.md + +## Markdown + +# Security + +## Security Model Overview +- ClawSec secures both content distribution (signed artifacts) and runtime behavior (advisory gating, integrity monitoring). +- Trust anchors are pinned public keys committed in repo and verified against workflow-generated outputs. +- Runtime consumers default to verification-first behavior with explicit migration bypass flags. + +## Cryptographic Controls +| Control | Mechanism | Location | +| --- | --- | --- | +| Feed authenticity | Ed25519 detached signatures (`feed.json.sig`) | Advisory workflows + consumer verification libs. | +| Artifact integrity | SHA-256 checksum manifests (`checksums.json`) | Skill release and pages deploy workflows. | +| Key consistency | Fingerprint comparison across docs + canonical PEMs | `scripts/ci/verify_signing_key_consistency.sh`. | +| Signature verification action | Composite sign+verify action in CI | `.github/actions/sign-and-verify/action.yml`. | + +## Runtime Enforcement Controls +| Control | Component | Effect | +| --- | --- | --- | +| Advisory hook gating | `clawsec-advisory-guardian` | Alerts and cautious guidance based on matched advisories. | +| Double-confirmation installer | `guarded_skill_install.mjs` | Exit `42` until explicit confirmation for matched advisories. | +| Reputation extension | `clawsec-clawhub-checker` | Additional risk scoring before install. | +| NanoClaw signature gate | `skill-signature-handler.ts` + MCP tool | Blocks tampered/unsigned package installs by policy. | +| Integrity baseline monitor | `soul-guardian` + NanoClaw integrity monitor | Drift detection, quarantine, restore, auditable history. | + +## Supply-Chain and CI Controls +- CI runs Trivy, npm audit, gitleaks, CodeQL, and Scorecard workflows. +- Release workflows validate SBOM file existence before packaging. +- Deploy workflow verifies generated signing key fingerprint against canonical key material. +- Release docs include manual verification commands for downstream consumers. + +## Incident and Rotation Playbooks +- `docs/SECURITY-SIGNING.md` defines key generation, custody, rotation, and incident phases. +- `docs/MIGRATION-SIGNED-FEED.md` defines staged enforcement and rollback levels. +- Rollback paths prioritize preserving signed publishing where possible and time-boxing any bypass. + +## Example Snippets +```bash +# verify canonical public key fingerprint +openssl pkey -pubin -in clawsec-signing-public.pem -outform DER | shasum -a 256 +``` + +```bash +# run repo key-consistency guardrail used in CI +./scripts/ci/verify_signing_key_consistency.sh +``` + +## Known Security Tradeoffs +- Unsigned compatibility mode can reduce assurance and should be disabled once migration completes. +- Some deploy paths tolerate unsigned legacy checksum assets for backward compatibility. +- Reputation checks rely on external tooling output and may include heuristic false positives/negatives. +- Local scripts inherit environment trust; compromised local shells can still subvert operator workflows. + +## Hardening Opportunities +- Remove unsigned compatibility flags after migration stabilization. +- Expand deterministic checksum/signature verification for all mirrored release files. +- Add explicit tests for workflow-level signature failure scenarios. +- Increase runtime telemetry for advisory fetch/verification failures to simplify incident triage. + +## Source References +- SECURITY.md +- docs/SECURITY-SIGNING.md +- docs/MIGRATION-SIGNED-FEED.md +- scripts/ci/verify_signing_key_consistency.sh +- .github/actions/sign-and-verify/action.yml +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/skill-release.yml +- .github/workflows/deploy-pages.yml +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/clawsec-clawhub-checker/scripts/enhanced_guarded_install.mjs +- skills/soul-guardian/scripts/soul_guardian.py +- skills/clawsec-nanoclaw/host-services/skill-signature-handler.ts +- skills/clawsec-nanoclaw/guardian/integrity-monitor.ts diff --git a/public/wiki/llms/testing.txt b/public/wiki/llms/testing.txt new file mode 100644 index 0000000..ee18d7d --- /dev/null +++ b/public/wiki/llms/testing.txt @@ -0,0 +1,84 @@ +# ClawSec Wiki · Testing + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/testing +- LLM export: https://clawsec.prompt.security/wiki/llms/testing.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/testing.md + +## Markdown + +# Testing + +## Testing Strategy +- The repository uses layered verification rather than a single root `npm test` command. +- Core confidence comes from lint/type/build gates plus skill-local Node test suites. +- Python and shell tooling are validated through dedicated lint/security checks. +- Workflow pipelines run the same command classes used in local pre-push automation. + +## Verification Layers +| Layer | Commands | Scope | +| --- | --- | --- | +| Frontend/static checks | ESLint + `tsc --noEmit` + `npm run build` | TS/TSX correctness and build viability. | +| Skill unit tests | `node skills//test/*.test.mjs` | Signature, matching, suppression, installer contracts. | +| Python quality | `ruff check utils/`, `bandit -r utils/ -ll` | Utility correctness and security patterns. | +| Shell/script quality | ShellCheck + manual script smoke runs | Script hygiene and command robustness. | +| CI security scans | Trivy, npm audit, gitleaks, CodeQL, Scorecard | Dependency, config, and supply-chain security posture. | + +## Skill Test Matrix +| Skill | Test Files | Primary Focus | +| --- | --- | --- | +| `clawsec-suite` | `feed_verification`, `guarded_install`, `path_resolution`, fuzz tests | Signature checks, advisory gating, path safety, matching robustness. | +| `openclaw-audit-watchdog` | suppression config and render tests | Config parsing, suppression behavior, report formatting. | +| `clawsec-clawhub-checker` | `reputation_check.test.mjs` | Input validation and reputation gating behavior. | + +## CI Workflow Coverage +| Workflow | Trigger | Key Assertions | +| --- | --- | --- | +| `ci.yml` | PR/push to `main` | Lint/type/build, Python checks, security scans, skill tests. | +| `codeql.yml` | PR/push/schedule | JS/TS static security analysis. | +| `scorecard.yml` | schedule/push | Supply-chain posture reporting and SARIF upload. | +| `skill-release.yml` | tags + PRs | Version parity and release artifact verification. | + +## Local Testing Commands +```bash +# baseline frontend + config checks +npx eslint . --ext .ts,.tsx,.js,.jsx,.mjs --max-warnings 0 +npx tsc --noEmit +npm run build +``` + +```bash +# representative skill tests +node skills/clawsec-suite/test/feed_verification.test.mjs +node skills/clawsec-suite/test/guarded_install.test.mjs +node skills/openclaw-audit-watchdog/test/suppression_config.test.mjs +``` + +## Failure Patterns to Watch +- Signature/test fixtures can fail from key/payload mismatch when expected files are regenerated inconsistently. +- Path-resolution tests intentionally fail on escaped home tokens; this behavior is expected and security-relevant. +- Local scripts relying on `openclaw` or `clawhub` binaries may fail in environments where those CLIs are absent. +- Deploy/release logic can pass locally while failing in CI if signing secrets or workflow permissions differ. + +## Suggested Test Order +1. Run `./scripts/prepare-to-push.sh` for a full local gate. +2. Run directly impacted skill-local tests. +3. For feed/signing changes, run suite verification tests first (`feed_verification`, `guarded_install`). +4. For workflow or release changes, also run `scripts/validate-release-links.sh` and key consistency script. + +## Source References +- AGENTS.md +- scripts/prepare-to-push.sh +- scripts/validate-release-links.sh +- .github/workflows/ci.yml +- .github/workflows/codeql.yml +- .github/workflows/scorecard.yml +- .github/workflows/skill-release.yml +- skills/clawsec-suite/test/feed_verification.test.mjs +- skills/clawsec-suite/test/guarded_install.test.mjs +- skills/clawsec-suite/test/path_resolution.test.mjs +- skills/openclaw-audit-watchdog/test/suppression_config.test.mjs +- skills/clawsec-clawhub-checker/test/reputation_check.test.mjs +- docs/PLATFORM_VERIFICATION.md diff --git a/public/wiki/llms/workflow.txt b/public/wiki/llms/workflow.txt new file mode 100644 index 0000000..6b79c5f --- /dev/null +++ b/public/wiki/llms/workflow.txt @@ -0,0 +1,85 @@ +# ClawSec Wiki · Workflow + +LLM-ready export for a single wiki page. + +## Canonical +- Wiki page: https://clawsec.prompt.security/#/wiki/workflow +- LLM export: https://clawsec.prompt.security/wiki/llms/workflow.txt +- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/workflow.md + +## Markdown + +# Workflow + +## End-to-End Lifecycle +- Development starts with local coding + local data population for realistic UI preview. +- PR CI validates quality/security and skill test suites. +- Tag-driven release workflow packages and signs skill artifacts. +- Pages deploy workflow mirrors release/advisory artifacts and publishes the static site. +- Scheduled workflows continuously enrich advisory feed and supply-chain visibility. + +## Primary Workflow Map +| Workflow | Trigger | Main Steps | +| --- | --- | --- | +| CI | PR/push to `main` | Lint, typecheck, build, Python checks, security scans, skill tests. | +| Poll NVD CVEs | Daily cron + manual dispatch | Fetch CVEs, transform/dedupe, update feed, sign artifacts, PR changes. | +| Process Community Advisory | Issue label `advisory-approved` | Parse issue form, create advisory, sign feed, open PR, comment issue. | +| Skill Release | Tag `-v*` | Validate versions, package SBOM files, sign checksums, publish release. | +| Deploy Pages | Successful CI/Release or manual dispatch | Discover releases, mirror assets, sign public advisories/checksums, deploy site. | + +## Local Operator Workflow +| Step | Command | Outcome | +| --- | --- | --- | +| Install deps | `npm install` | Ready local environment. | +| Populate local catalog | `./scripts/populate-local-skills.sh` | `public/skills/index.json` and file checksums. | +| Populate local feed | `./scripts/populate-local-feed.sh --days 120` | Updated local advisory feed copy. | +| Run local gate | `./scripts/prepare-to-push.sh` | CI-like pass/fail signal. | +| Start dev UI | `npm run dev` | Browser preview at local Vite endpoint. | + +## Release Workflow Details +- Version bump and docs parity are enforced for PR/tag paths. +- Skill packaging includes SBOM-declared files and integrity manifests. +- `checksums.json` is signed and immediately verified in workflow execution. +- Optional publish-to-ClawHub job runs after successful GitHub release when configured. +- Older releases within same major line can be superseded/deleted by automation. + +## Advisory Workflow Details +- NVD workflow determines incremental window from previous feed `updated` timestamp. +- Transform phase maps CVE metrics to severity/type and normalizes affected targets. +- Community advisory workflow creates deterministic IDs (`CLAW-YYYY-NNNN`) from issue metadata. +- Both advisory workflows update skill feed copies and signature companions. + +## Example Snippets +```bash +# manual release prep for a skill +./scripts/release-skill.sh clawsec-feed 0.0.5 +# then push tag if running in release branch mode +``` + +```yaml +# pages deploy depends on successful upstream workflow run +on: + workflow_run: + workflows: ["CI", "Skill Release"] + types: [completed] +``` + +## Operational Risks +- Workflow permissions and secret scope misconfiguration can block signing/publishing. +- NVD/API transient failures may delay advisory freshness. +- Invalid tag naming or version mismatches halt release automation. +- Local scripts and CI can diverge if operator machine lacks expected binaries (`jq`, `openssl`, `clawhub`). + +## Source References +- scripts/release-skill.sh +- scripts/prepare-to-push.sh +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- .github/workflows/ci.yml +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/skill-release.yml +- .github/workflows/deploy-pages.yml +- .github/workflows/codeql.yml +- .github/workflows/scorecard.yml +- .github/actions/sign-and-verify/action.yml diff --git a/scripts/generate-wiki-llms.mjs b/scripts/generate-wiki-llms.mjs new file mode 100644 index 0000000..c479690 --- /dev/null +++ b/scripts/generate-wiki-llms.mjs @@ -0,0 +1,160 @@ +#!/usr/bin/env node + +import { promises as fs } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const REPO_ROOT = path.resolve(__dirname, '..'); +const WIKI_ROOT = path.join(REPO_ROOT, 'wiki'); +const PUBLIC_WIKI_ROOT = path.join(REPO_ROOT, 'public', 'wiki'); +const LLM_PAGES_ROOT = path.join(PUBLIC_WIKI_ROOT, 'llms'); +const LLM_INDEX_FILE = path.join(PUBLIC_WIKI_ROOT, 'llms.txt'); + +const WEBSITE_BASE = 'https://clawsec.prompt.security'; +const REPO_BASE = 'https://github.com/prompt-security/clawsec'; +const RAW_BASE = 'https://raw.githubusercontent.com/prompt-security/clawsec/main'; + +const FRONTMATTER_REGEX = /^---\s*\n[\s\S]*?\n---\s*\n/; + +const toPosix = (inputPath) => inputPath.split(path.sep).join('/'); + +const fallbackTitleFromPath = (filePath) => { + const filename = filePath.split('/').pop() ?? filePath; + const stem = filename.replace(/\.md$/i, ''); + return stem + .split(/[-_]/) + .filter(Boolean) + .map((part) => { + if (part.toUpperCase() === part && part.length > 1) return part; + return part.charAt(0).toUpperCase() + part.slice(1); + }) + .join(' '); +}; + +const stripFrontmatter = (content) => content.replace(FRONTMATTER_REGEX, ''); + +const extractTitle = (content, filePath) => { + const cleaned = stripFrontmatter(content).trim(); + const match = cleaned.match(/^#\s+(.+)$/m); + return match?.[1]?.trim() || fallbackTitleFromPath(filePath); +}; + +const toWebsiteRoute = (slug) => (slug === 'index' ? '/wiki' : `/wiki/${slug}`); + +const toLlmsPageUrl = (slug) => `${WEBSITE_BASE}/wiki/llms/${slug}.txt`; + +const walkMarkdownFiles = async (dir) => { + const entries = await fs.readdir(dir, { withFileTypes: true }); + const files = []; + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + const nested = await walkMarkdownFiles(fullPath); + files.push(...nested); + continue; + } + if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) { + files.push(fullPath); + } + } + + return files; +}; + +const sortDocs = (a, b) => { + if (a.slug === 'index' && b.slug !== 'index') return -1; + if (a.slug !== 'index' && b.slug === 'index') return 1; + return a.slug.localeCompare(b.slug, 'en', { sensitivity: 'base' }); +}; + +const buildPageBody = (doc) => { + const pageRoute = toWebsiteRoute(doc.slug); + const pageUrl = `${WEBSITE_BASE}/#${pageRoute}`; + const sourceUrl = `${RAW_BASE}/wiki/${doc.relativePath}`; + const llmsUrl = toLlmsPageUrl(doc.slug); + + return [ + `# ClawSec Wiki · ${doc.title}`, + '', + 'LLM-ready export for a single wiki page.', + '', + '## Canonical', + `- Wiki page: ${pageUrl}`, + `- LLM export: ${llmsUrl}`, + `- Source markdown: ${sourceUrl}`, + '', + '## Markdown', + '', + doc.content.trim(), + '', + ].join('\n'); +}; + +const buildIndexBody = (docs) => { + const lines = [ + '# ClawSec Wiki llms.txt', + '', + 'LLM-readable index for wiki pages. A generated `.txt` export exists for each page.', + '', + `Website wiki root: ${WEBSITE_BASE}/#/wiki`, + `GitHub wiki mirror: ${REPO_BASE}/wiki`, + `Canonical source of truth: ${REPO_BASE}/tree/main/wiki`, + '', + '## Generated Page Exports', + ]; + + for (const doc of docs) { + const pageRoute = toWebsiteRoute(doc.slug); + const pageUrl = `${WEBSITE_BASE}/#${pageRoute}`; + const llmsUrl = toLlmsPageUrl(doc.slug); + lines.push(`- ${doc.title}: ${llmsUrl} (page: ${pageUrl})`); + } + + return `${lines.join('\n')}\n`; +}; + +const main = async () => { + try { + const wikiStat = await fs.stat(WIKI_ROOT).catch(() => null); + if (!wikiStat || !wikiStat.isDirectory()) { + throw new Error('wiki/ directory not found.'); + } + + const markdownFiles = await walkMarkdownFiles(WIKI_ROOT); + const docs = []; + + for (const fullPath of markdownFiles) { + const relativePath = toPosix(path.relative(WIKI_ROOT, fullPath)); + const slug = relativePath.replace(/\.md$/i, '').toLowerCase(); + const rawContent = await fs.readFile(fullPath, 'utf8'); + const content = stripFrontmatter(rawContent); + const title = extractTitle(rawContent, relativePath); + docs.push({ relativePath, slug, title, content }); + } + + docs.sort(sortDocs); + + await fs.mkdir(PUBLIC_WIKI_ROOT, { recursive: true }); + await fs.rm(LLM_PAGES_ROOT, { recursive: true, force: true }); + await fs.mkdir(LLM_PAGES_ROOT, { recursive: true }); + + for (const doc of docs) { + const outputFile = path.join(LLM_PAGES_ROOT, `${doc.slug}.txt`); + await fs.mkdir(path.dirname(outputFile), { recursive: true }); + await fs.writeFile(outputFile, buildPageBody(doc), 'utf8'); + } + + await fs.writeFile(LLM_INDEX_FILE, buildIndexBody(docs), 'utf8'); + + // Keep logs short for CI readability. + console.log(`Generated ${docs.length} wiki llms page exports and /wiki/llms.txt`); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + console.error(`Failed to generate wiki llms exports: ${message}`); + process.exit(1); + } +}; + +await main(); From 0d06f9553d4ac9116dc61248bb5281e721665095 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:05:40 +0200 Subject: [PATCH 03/16] vuln package --- package-lock.json | 380 +++++++++++++++++++++++++++++++++------------- 1 file changed, 278 insertions(+), 102 deletions(-) diff --git a/package-lock.json b/package-lock.json index 161aec6..dae8d7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -953,154 +953,329 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.57.1", - "integrity": "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "android" + ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.57.1", - "integrity": "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "android" + ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.57.1", - "integrity": "sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "darwin" + ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.57.1", - "integrity": "sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "darwin" + ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.57.1", - "integrity": "sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "freebsd" + ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.57.1", - "integrity": "sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "freebsd" + ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.57.1", - "integrity": "sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.57.1", - "integrity": "sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.57.1", - "integrity": "sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.57.1", - "integrity": "sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.57.1", - "integrity": "sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.57.1", - "integrity": "sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.57.1", - "integrity": "sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.57.1", - "integrity": "sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.57.1", - "integrity": "sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.57.1", - "integrity": "sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.57.1", - "integrity": "sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.57.1", - "integrity": "sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.57.1", - "integrity": "sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "linux" + ] }, "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.57.1", - "integrity": "sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "openbsd" + ] }, "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.57.1", - "integrity": "sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "openharmony" + ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.57.1", - "integrity": "sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.57.1", - "integrity": "sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.57.1", - "integrity": "sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.57.1", - "integrity": "sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "optional": true, + "os": [ + "win32" + ] }, "node_modules/@types/babel__core": { "version": "7.20.5", @@ -5049,8 +5224,9 @@ } }, "node_modules/rollup": { - "version": "4.57.1", - "integrity": "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==", + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "dependencies": { "@types/estree": "1.0.8" @@ -5063,31 +5239,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.57.1", - "@rollup/rollup-android-arm64": "4.57.1", - "@rollup/rollup-darwin-arm64": "4.57.1", - "@rollup/rollup-darwin-x64": "4.57.1", - "@rollup/rollup-freebsd-arm64": "4.57.1", - "@rollup/rollup-freebsd-x64": "4.57.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", - "@rollup/rollup-linux-arm-musleabihf": "4.57.1", - "@rollup/rollup-linux-arm64-gnu": "4.57.1", - "@rollup/rollup-linux-arm64-musl": "4.57.1", - "@rollup/rollup-linux-loong64-gnu": "4.57.1", - "@rollup/rollup-linux-loong64-musl": "4.57.1", - "@rollup/rollup-linux-ppc64-gnu": "4.57.1", - "@rollup/rollup-linux-ppc64-musl": "4.57.1", - "@rollup/rollup-linux-riscv64-gnu": "4.57.1", - "@rollup/rollup-linux-riscv64-musl": "4.57.1", - "@rollup/rollup-linux-s390x-gnu": "4.57.1", - "@rollup/rollup-linux-x64-gnu": "4.57.1", - "@rollup/rollup-linux-x64-musl": "4.57.1", - "@rollup/rollup-openbsd-x64": "4.57.1", - "@rollup/rollup-openharmony-arm64": "4.57.1", - "@rollup/rollup-win32-arm64-msvc": "4.57.1", - "@rollup/rollup-win32-ia32-msvc": "4.57.1", - "@rollup/rollup-win32-x64-gnu": "4.57.1", - "@rollup/rollup-win32-x64-msvc": "4.57.1", + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" } }, From 3b775cd891cd6a7d9a9f431995e8d5f3c47f8cf0 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:07:30 +0200 Subject: [PATCH 04/16] fix(wiki): guard malformed route decoding --- pages/WikiBrowser.tsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index c7bb652..2c2bb15 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -139,11 +139,22 @@ const toGroupName = (filePath: string): string => { export const WikiBrowser: React.FC = () => { const params = useParams<{ '*': string }>(); const wildcard = params['*'] ?? ''; - const requested = decodeURIComponent(wildcard.replace(/^\/+|\/+$/g, '')); + const normalizedWildcard = wildcard.replace(/^\/+|\/+$/g, ''); + let requested = ''; + let decodeFailed = false; + try { + requested = decodeURIComponent(normalizedWildcard); + } catch (error) { + decodeFailed = normalizedWildcard.length > 0; + console.warn('Failed to decode wiki route segment', { wildcard, error }); + requested = ''; + } const requestedSlug = requested || 'INDEX'; const selectedDoc = wikiDocBySlug.get(requestedSlug.toLowerCase()) ?? defaultDoc; - const notFound = requested.length > 0 && !wikiDocBySlug.has(requestedSlug.toLowerCase()); + const notFound = + (decodeFailed && normalizedWildcard.length > 0) || + (requested.length > 0 && !wikiDocBySlug.has(requestedSlug.toLowerCase())); const groupedDocs = useMemo(() => { const map = new Map(); From 087bf3456e9367aa5e4df6d625ec3a02e4267157 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:08:34 +0200 Subject: [PATCH 05/16] fix(wiki): preserve markdown anchor fragments across page links --- pages/WikiBrowser.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index 2c2bb15..f614eef 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -202,13 +202,13 @@ export const WikiBrowser: React.FC = () => { if (!href || isExternalHref(href) || href.startsWith('mailto:') || href.startsWith('tel:')) { return null; } - const { path } = splitHash(href); + const { path, hash } = splitHash(href); if (!path || !path.toLowerCase().endsWith('.md')) return null; const resolvedFilePath = resolveFromFile(selectedDoc.filePath, path).toLowerCase(); const targetDoc = wikiDocByFilePath.get(resolvedFilePath); if (!targetDoc) return null; - return toWikiRoute(targetDoc.slug); + return `${toWikiRoute(targetDoc.slug)}${hash}`; }; const resolveAssetUrl = (srcOrHref: string): string | null => { From e81af3bc15d51c4fa4c7cbb57c49f724c03be3d3 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:10:44 +0200 Subject: [PATCH 06/16] refactor(markdown): share default render components --- pages/SkillDetail.tsx | 98 +--------------------- pages/WikiBrowser.tsx | 155 +++++++++++------------------------ utils/markdownComponents.tsx | 99 ++++++++++++++++++++++ 3 files changed, 147 insertions(+), 205 deletions(-) create mode 100644 utils/markdownComponents.tsx diff --git a/pages/SkillDetail.tsx b/pages/SkillDetail.tsx index 103000c..b7a1c00 100644 --- a/pages/SkillDetail.tsx +++ b/pages/SkillDetail.tsx @@ -5,6 +5,7 @@ import Markdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { Footer } from '../components/Footer'; import type { SkillJson, SkillChecksums } from '../types'; +import { defaultMarkdownComponents } from '../utils/markdownComponents'; // Strip YAML frontmatter from markdown content const stripFrontmatter = (content: string): string => { @@ -320,102 +321,7 @@ export const SkillDetail: React.FC = () => {
    ( -

    - {children} -

    - ), - h2: ({ children }) => ( -

    {children}

    - ), - h3: ({ children }) => ( -

    {children}

    - ), - h4: ({ children }) => ( -

    {children}

    - ), - p: ({ children }) => ( -

    {children}

    - ), - a: ({ href, children }) => ( -
    - {children} - - ), - ul: ({ children }) => ( -
      - {children} -
    - ), - ol: ({ children }) => ( -
      - {children} -
    - ), - li: ({ children }) => ( -
  • {children}
  • - ), - blockquote: ({ children }) => ( -
    - {children} -
    - ), - code: ({ className, children }) => { - const isInline = !className; - if (isInline) { - return ( - - {children} - - ); - } - return ( - {children} - ); - }, - pre: ({ children }) => ( -
    -                    {children}
    -                  
    - ), - table: ({ children }) => ( -
    - - {children} -
    -
    - ), - thead: ({ children }) => ( - - {children} - - ), - tbody: ({ children }) => {children}, - tr: ({ children }) => ( - {children} - ), - th: ({ children }) => ( - - {children} - - ), - td: ({ children }) => ( - {children} - ), - hr: () =>
    , - strong: ({ children }) => ( - {children} - ), - em: ({ children }) => ( - {children} - ), - }} + components={defaultMarkdownComponents} > {stripFrontmatter(doc.content)} diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index f614eef..dd9189f 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -2,8 +2,10 @@ import React, { useMemo } from 'react'; import { BookOpenText, ExternalLink, FileText } from 'lucide-react'; import { Link, useParams } from 'react-router-dom'; import Markdown from 'react-markdown'; +import type { Components } from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { Footer } from '../components/Footer'; +import { defaultMarkdownComponents } from '../utils/markdownComponents'; interface WikiDoc { filePath: string; @@ -219,6 +221,49 @@ export const WikiBrowser: React.FC = () => { return wikiAssetByPath.get(resolvedAssetPath) ?? null; }; + const wikiMarkdownComponents: Components = { + ...defaultMarkdownComponents, + a: ({ href, children }) => { + if (!href) return {children}; + + const wikiRoute = resolveWikiRouteFromHref(href); + if (wikiRoute) { + return ( + + {children} + + ); + } + + const assetHref = resolveAssetUrl(href); + const finalHref = assetHref ?? href; + const external = isExternalHref(finalHref); + + return ( + + {children} + + ); + }, + img: ({ src, alt }) => { + const resolvedSrc = src ? resolveAssetUrl(src) : null; + const finalSrc = resolvedSrc ?? src ?? ''; + return ( + {alt + ); + }, + }; + return (
    @@ -299,115 +344,7 @@ export const WikiBrowser: React.FC = () => { ( -

    - {children} -

    - ), - h2: ({ children }) => ( -

    {children}

    - ), - h3: ({ children }) => ( -

    {children}

    - ), - p: ({ children }) => ( -

    {children}

    - ), - a: ({ href, children }) => { - if (!href) return {children}; - - const wikiRoute = resolveWikiRouteFromHref(href); - if (wikiRoute) { - return ( - - {children} - - ); - } - - const assetHref = resolveAssetUrl(href); - const finalHref = assetHref ?? href; - const external = isExternalHref(finalHref); - - return ( - - {children} - - ); - }, - img: ({ src, alt }) => { - const resolvedSrc = src ? resolveAssetUrl(src) : null; - const finalSrc = resolvedSrc ?? src ?? ''; - return ( - {alt - ); - }, - ul: ({ children }) => ( -
      - {children} -
    - ), - ol: ({ children }) => ( -
      - {children} -
    - ), - li: ({ children }) =>
  • {children}
  • , - blockquote: ({ children }) => ( -
    - {children} -
    - ), - code: ({ className, children }) => { - const isInline = !className; - if (isInline) { - return ( - - {children} - - ); - } - return {children}; - }, - pre: ({ children }) => ( -
    -                  {children}
    -                
    - ), - table: ({ children }) => ( -
    - - {children} -
    -
    - ), - thead: ({ children }) => ( - {children} - ), - tr: ({ children }) => ( - {children} - ), - th: ({ children }) => ( - {children} - ), - td: ({ children }) => {children}, - hr: () =>
    , - strong: ({ children }) => ( - {children} - ), - em: ({ children }) => {children}, - }} + components={wikiMarkdownComponents} > {selectedDoc.content}
    diff --git a/utils/markdownComponents.tsx b/utils/markdownComponents.tsx new file mode 100644 index 0000000..a0b4618 --- /dev/null +++ b/utils/markdownComponents.tsx @@ -0,0 +1,99 @@ +import React from 'react'; +import type { Components } from 'react-markdown'; + +export const defaultMarkdownComponents: Components = { + h1: ({ children }) => ( +

    + {children} +

    + ), + h2: ({ children }) => ( +

    {children}

    + ), + h3: ({ children }) => ( +

    {children}

    + ), + h4: ({ children }) => ( +

    {children}

    + ), + p: ({ children }) => ( +

    {children}

    + ), + a: ({ href, children }) => ( + + {children} + + ), + ul: ({ children }) => ( +
      + {children} +
    + ), + ol: ({ children }) => ( +
      + {children} +
    + ), + li: ({ children }) => ( +
  • {children}
  • + ), + blockquote: ({ children }) => ( +
    + {children} +
    + ), + code: ({ className, children }) => { + const isInline = !className; + if (isInline) { + return ( + + {children} + + ); + } + return ( + {children} + ); + }, + pre: ({ children }) => ( +
    +      {children}
    +    
    + ), + table: ({ children }) => ( +
    + + {children} +
    +
    + ), + thead: ({ children }) => ( + + {children} + + ), + tbody: ({ children }) => {children}, + tr: ({ children }) => ( + {children} + ), + th: ({ children }) => ( + + {children} + + ), + td: ({ children }) => ( + {children} + ), + hr: () =>
    , + strong: ({ children }) => ( + {children} + ), + em: ({ children }) => ( + {children} + ), +}; From 85f48db2909ed1c83fae60e7f9c306b554f8d530 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:11:49 +0200 Subject: [PATCH 07/16] fix(wiki): block unsafe markdown link schemes --- pages/WikiBrowser.tsx | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index dd9189f..0aeb7a9 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -77,6 +77,19 @@ const extractTitle = (markdownContent: string, filePath: string): string => { const isExternalHref = (href: string): boolean => /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(href) || href.startsWith('//'); +const ALLOWED_LINK_SCHEMES = new Set(['http:', 'https:', 'mailto:', 'tel:']); + +const sanitizeHref = (href: string): string | null => { + const trimmed = href.trim(); + if (!trimmed) return null; + if (trimmed.startsWith('//')) return null; + + const schemeMatch = trimmed.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:)/); + if (!schemeMatch) return trimmed; + + return ALLOWED_LINK_SCHEMES.has(schemeMatch[1].toLowerCase()) ? trimmed : null; +}; + const markdownModules = import.meta.glob('../wiki/**/*.md', { eager: true, query: '?raw', @@ -237,11 +250,15 @@ export const WikiBrowser: React.FC = () => { const assetHref = resolveAssetUrl(href); const finalHref = assetHref ?? href; - const external = isExternalHref(finalHref); + const safeHref = sanitizeHref(finalHref); + if (!safeHref) { + return {children}; + } + const external = isExternalHref(safeHref); return ( Date: Thu, 26 Feb 2026 09:13:17 +0200 Subject: [PATCH 08/16] fix(wiki): block unsafe markdown image schemes --- pages/WikiBrowser.tsx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index 0aeb7a9..b1df081 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -78,6 +78,7 @@ const isExternalHref = (href: string): boolean => /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(href) || href.startsWith('//'); const ALLOWED_LINK_SCHEMES = new Set(['http:', 'https:', 'mailto:', 'tel:']); +const ALLOWED_IMAGE_SCHEMES = new Set(['http:', 'https:']); const sanitizeHref = (href: string): string | null => { const trimmed = href.trim(); @@ -90,6 +91,17 @@ const sanitizeHref = (href: string): string | null => { return ALLOWED_LINK_SCHEMES.has(schemeMatch[1].toLowerCase()) ? trimmed : null; }; +const sanitizeImageSrc = (src: string): string | null => { + const trimmed = src.trim(); + if (!trimmed) return null; + if (trimmed.startsWith('//')) return null; + + const schemeMatch = trimmed.match(/^([a-zA-Z][a-zA-Z0-9+.-]*:)/); + if (!schemeMatch) return trimmed; + + return ALLOWED_IMAGE_SCHEMES.has(schemeMatch[1].toLowerCase()) ? trimmed : null; +}; + const markdownModules = import.meta.glob('../wiki/**/*.md', { eager: true, query: '?raw', @@ -269,7 +281,10 @@ export const WikiBrowser: React.FC = () => { }, img: ({ src, alt }) => { const resolvedSrc = src ? resolveAssetUrl(src) : null; - const finalSrc = resolvedSrc ?? src ?? ''; + const finalSrc = resolvedSrc ?? (src ? sanitizeImageSrc(src) : null); + if (!finalSrc) { + return [image blocked]; + } return ( Date: Thu, 26 Feb 2026 09:24:11 +0200 Subject: [PATCH 09/16] docs(wiki): migrate root docs into wiki pages --- README.md | 8 ++++++-- skills/clawsec-nanoclaw/README.md | 2 +- wiki/GENERATION.md | 17 ++++++++++------ wiki/INDEX.md | 12 ++++++++++- .../compatibility-report.md | 20 ++++++++++++++++--- .../migration-signed-feed.md | 11 +++++++++- wiki/overview.md | 5 ++++- .../platform-verification.md | 11 ++++++++++ .../remediation-plan.md | 12 +++++++++++ .../security-signing-runbook.md | 13 ++++++++++++ wiki/security.md | 11 ++++++---- wiki/testing.md | 5 ++++- 12 files changed, 107 insertions(+), 20 deletions(-) rename docs/COMPATIBILITY_REPORT.md => wiki/compatibility-report.md (86%) rename docs/MIGRATION-SIGNED-FEED.md => wiki/migration-signed-feed.md (93%) rename docs/PLATFORM_VERIFICATION.md => wiki/platform-verification.md (87%) rename docs/REMEDIATION_PLAN.md => wiki/remediation-plan.md (86%) rename docs/SECURITY-SIGNING.md => wiki/security-signing-runbook.md (94%) diff --git a/README.md b/README.md index 91ef21b..28b5341 100644 --- a/README.md +++ b/README.md @@ -313,8 +313,8 @@ Each skill release includes: ### Signing Operations Documentation For feed/release signing rollout and operations guidance: -- [`docs/SECURITY-SIGNING.md`](docs/SECURITY-SIGNING.md) - key generation, GitHub secrets, rotation/revocation, incident response -- [`docs/MIGRATION-SIGNED-FEED.md`](docs/MIGRATION-SIGNED-FEED.md) - phased migration from unsigned feed, enforcement gates, rollback plan +- [`wiki/security-signing-runbook.md`](wiki/security-signing-runbook.md) - key generation, GitHub secrets, rotation/revocation, incident response +- [`wiki/migration-signed-feed.md`](wiki/migration-signed-feed.md) - phased migration from unsigned feed, enforcement gates, rollback plan --- @@ -375,6 +375,9 @@ npm run dev # Populate advisory feed with real NVD CVE data ./scripts/populate-local-feed.sh --days 120 + +# Generate wiki llms exports from wiki/ (for local preview) +./scripts/populate-local-wiki.sh ``` ### Build @@ -395,6 +398,7 @@ npm run build ├── scripts/ │ ├── populate-local-feed.sh # Local CVE feed populator │ ├── populate-local-skills.sh # Local skills catalog populator +│ ├── populate-local-wiki.sh # Local wiki llms export populator │ └── release-skill.sh # Manual skill release helper ├── skills/ │ ├── clawsec-suite/ # 📦 Suite installer (skill-of-skills) diff --git a/skills/clawsec-nanoclaw/README.md b/skills/clawsec-nanoclaw/README.md index abd4080..bd1b2e2 100644 --- a/skills/clawsec-nanoclaw/README.md +++ b/skills/clawsec-nanoclaw/README.md @@ -142,7 +142,7 @@ Planned features for future releases: - [Skill Documentation](skills/clawsec-nanoclaw/SKILL.md) - Features and architecture - [Installation Guide](skills/clawsec-nanoclaw/INSTALL.md) - Detailed setup instructions - [ClawSec Main README](README.md) - Overall ClawSec documentation -- [Security & Signing](../../docs/SECURITY-SIGNING.md) - Signature verification details +- [Security & Signing](../../wiki/security-signing-runbook.md) - Signature verification details ## Support diff --git a/wiki/GENERATION.md b/wiki/GENERATION.md index b164c52..fb37ba5 100644 --- a/wiki/GENERATION.md +++ b/wiki/GENERATION.md @@ -1,9 +1,9 @@ # Wiki Generation Metadata -- Commit hash: `448aed326192d38812cb508820f967cb74e77ae9` -- Branch name: `main` -- Generation timestamp (local): `2026-02-25T20:59:57+0200` -- Generation mode: `initial` +- Commit hash: `d5aadfbee15b48ebb4872dfb838e4df88c611d56` +- Branch name: `codex/wiki-tab-ui` +- Generation timestamp (local): `2026-02-26T09:16:02+0200` +- Generation mode: `update` - Output language: `English` - Assets copied into `wiki/assets/`: - `overview_img_01_prompt-security-logo.png` (from `img/Black+Color.png`) @@ -11,8 +11,8 @@ - `architecture_img_01_prompt-line.svg` (from `public/img/prompt_line.svg`) ## Notes -- This is a first-time generation (`wiki/` did not exist before this run). -- Index sections were generated from repository structure and created wiki pages. +- Migrated root documentation pages from `docs/` into dedicated `wiki/` operation pages. +- Updated index and cross-links to use `wiki/` as the documentation source of truth. - Future updates should preserve existing headings and append `Update Notes` sections when making deltas. ## Source References @@ -24,3 +24,8 @@ - wiki/dependencies.md - wiki/data-flow.md - wiki/glossary.md +- wiki/security-signing-runbook.md +- wiki/migration-signed-feed.md +- wiki/platform-verification.md +- wiki/remediation-plan.md +- wiki/compatibility-report.md diff --git a/wiki/INDEX.md b/wiki/INDEX.md index 7a59ed7..78be0fa 100644 --- a/wiki/INDEX.md +++ b/wiki/INDEX.md @@ -5,7 +5,7 @@ - Tech stack: React 19 + Vite + TypeScript frontend, Node/ESM scripts, Python utilities, Bash automation, GitHub Actions pipelines. - Entry points: `index.tsx`, `App.tsx`, `scripts/prepare-to-push.sh`, `scripts/populate-local-feed.sh`, `scripts/populate-local-skills.sh`, workflow files under `.github/workflows/`. - Where to start: Read [Overview](overview.md), then [Architecture](architecture.md), then module pages for the area you are editing. -- How to navigate: Use Guides for cross-cutting concerns, Modules for implementation boundaries, and Source References at the end of each page to jump into code. +- How to navigate: Use Guides for cross-cutting concerns, Operations for runbooks and migration plans, Modules for implementation boundaries, and Source References at the end of each page to jump into code. ## Start Here - [Overview](overview.md) @@ -19,6 +19,13 @@ - [Workflow](workflow.md) - [Security](security.md) +## Operations +- [Security Signing Runbook](security-signing-runbook.md) +- [Signed Feed Migration Plan](migration-signed-feed.md) +- [Platform Verification Checklist](platform-verification.md) +- [Cross-Platform Remediation Plan](remediation-plan.md) +- [Cross-Platform Compatibility Report](compatibility-report.md) + ## Modules - [Frontend Web App](modules/frontend-web.md) - [ClawSec Suite Core](modules/clawsec-suite.md) @@ -32,6 +39,9 @@ ## Generation Metadata - [Generation Metadata](GENERATION.md) +## Update Notes +- 2026-02-26: Added Operations pages and updated navigation guidance after migrating root docs into wiki pages. + ## Source References - README.md - App.tsx diff --git a/docs/COMPATIBILITY_REPORT.md b/wiki/compatibility-report.md similarity index 86% rename from docs/COMPATIBILITY_REPORT.md rename to wiki/compatibility-report.md index e35cd6b..458ee85 100644 --- a/docs/COMPATIBILITY_REPORT.md +++ b/wiki/compatibility-report.md @@ -34,7 +34,7 @@ This could produce paths like `~/.openclaw/workspace/$HOME/...`. | CP-006 | High | Windows | Multiple SKILL docs and shell scripts | Install/maintenance flow is still heavily POSIX-shell based. | Add PowerShell equivalents or Node wrappers for critical flows. | Open | | CP-007 | Medium | Linux/macOS/Windows | `skills/soul-guardian/scripts/soul_guardian.py` | `Path(...).expanduser()` handles `~` but not `$HOME`/`%USERPROFILE%`. | Add explicit env-token expansion + validation for `--state-dir`. | Open | | CP-008 | Medium | Windows | `scripts/release-skill.sh`, `scripts/populate-local-*.sh` | GNU/BSD shell toolchain assumptions block native Windows usage. | Provide cross-platform Node/Python replacements or PowerShell equivalents. | Open | -| CP-009 | Low | Windows | docs + scripts using `chmod 600/644` | POSIX permission semantics are partial/non-portable on Windows. | Document best-effort behavior and Windows ACL alternatives. | Open | +| CP-009 | Low | Windows | documentation + scripts using `chmod 600/644` | POSIX permission semantics are partial/non-portable on Windows. | Document best-effort behavior and Windows ACL alternatives. | Open | | CP-010 | Low | macOS/Windows | CI non-Node jobs | Shell/Python/security scan jobs remain Ubuntu-only. | Add scoped matrix or dedicated non-Linux smoke jobs where practical. | Open | --- @@ -54,7 +54,7 @@ This could produce paths like `~/.openclaw/workspace/$HOME/...`. ## Permissions / Filesystem Semantics - Confirmed many scripts rely on POSIX permission commands. - Existing `state.ts` already handles `chmod` failures on unsupported filesystems. -- Open: docs still mostly assume POSIX permissions. +- Open: documentation still mostly assumes POSIX permissions. ## Line Endings - Fixed by adding `.gitattributes` with LF rules for scripts and key text/config files. @@ -62,7 +62,7 @@ This could produce paths like `~/.openclaw/workspace/$HOME/...`. ## Runtime Dependencies - Node scripts generally portable. - Python utilities are portable. -- OpenSSL usage in docs/workflows remains shell/toolchain dependent. +- OpenSSL usage in documentation/workflows remains shell/toolchain dependent. ## CI / Automation - Fixed: TS/lint/build matrix now runs on Linux/macOS/Windows. @@ -95,3 +95,17 @@ This could produce paths like `~/.openclaw/workspace/$HOME/...`. - `sh` (where scripts are invoked through Node entrypoints): same path behavior in Node layer. - Windows PowerShell: `%USERPROFILE%` / `$env:USERPROFILE` expansion and path normalization validated in Node tests. +## Source References +- .gitattributes +- .github/workflows/ci.yml +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/suppression.mjs +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/openclaw-audit-watchdog/scripts/setup_cron.mjs +- skills/openclaw-audit-watchdog/scripts/load_suppression_config.mjs +- skills/soul-guardian/scripts/soul_guardian.py +- scripts/release-skill.sh +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- wiki/remediation-plan.md +- wiki/platform-verification.md diff --git a/docs/MIGRATION-SIGNED-FEED.md b/wiki/migration-signed-feed.md similarity index 93% rename from docs/MIGRATION-SIGNED-FEED.md rename to wiki/migration-signed-feed.md index feeb108..26e1455 100644 --- a/docs/MIGRATION-SIGNED-FEED.md +++ b/wiki/migration-signed-feed.md @@ -37,7 +37,7 @@ Deliverables: - signing keys generated and fingerprints recorded - GitHub secrets created - public key(s) added in repo -- runbooks approved (`SECURITY-SIGNING.md`, this file) +- runbooks approved (`security-signing-runbook.md`, this file) Exit criteria: - key fingerprints verified by reviewer @@ -165,3 +165,12 @@ Go only if all are true: - consumer verification path tested for remote + local fallback - rollback owner is assigned and reachable - key rotation procedure has been dry-run at least once + +## Source References +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/deploy-pages.yml +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- advisories/feed.json +- wiki/security-signing-runbook.md diff --git a/wiki/overview.md b/wiki/overview.md index 72fbdf3..5393fe2 100644 --- a/wiki/overview.md +++ b/wiki/overview.md @@ -18,7 +18,7 @@ | `.github/workflows/` | CI/CD pipelines | CI, releases, NVD polling, community advisory ingestion, pages deploy. | | `utils/` | Python utilities | Skill validation and checksum packaging helpers. | | `public/` | Published static assets | Site media, mirrored advisories, and generated skill artifacts. | -| `docs/` | Operational docs | Signing runbooks, migration plans, compatibility and verification guides. | +| `wiki/` | Documentation hub | Architecture, operations runbooks, compatibility, and verification guides. | ## Entry Points | Entry | Type | Purpose | @@ -84,6 +84,9 @@ npm run build - Skill release automation expects version parity between `skill.json` and `SKILL.md` frontmatter. - Some scripts are POSIX shell oriented; Windows users should prefer PowerShell equivalents or WSL. +## Update Notes +- 2026-02-26: Updated repo layout to point operational documentation at `wiki/` instead of the removed root `docs/` directory. + ## Source References - README.md - package.json diff --git a/docs/PLATFORM_VERIFICATION.md b/wiki/platform-verification.md similarity index 87% rename from docs/PLATFORM_VERIFICATION.md rename to wiki/platform-verification.md index 748906c..6e8d14d 100644 --- a/docs/PLATFORM_VERIFICATION.md +++ b/wiki/platform-verification.md @@ -85,3 +85,14 @@ Use this checklist to validate portability and path-handling behavior after chan 4. Confirm no `$HOME` segment directory was created under working directories. Expected outcome: **no directories containing literal `$HOME` are created by supported setup scripts.** + +## Source References +- .gitattributes +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- skills/clawsec-suite/test/path_resolution.test.mjs +- skills/clawsec-suite/test/guarded_install.test.mjs +- skills/clawsec-suite/test/advisory_suppression.test.mjs +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/openclaw-audit-watchdog/scripts/load_suppression_config.mjs +- skills/openclaw-audit-watchdog/test/suppression_config.test.mjs diff --git a/docs/REMEDIATION_PLAN.md b/wiki/remediation-plan.md similarity index 86% rename from docs/REMEDIATION_PLAN.md rename to wiki/remediation-plan.md index e2af965..8d59b40 100644 --- a/docs/REMEDIATION_PLAN.md +++ b/wiki/remediation-plan.md @@ -71,3 +71,15 @@ - path token validation now enforced - how to correct invalid quoted env values - where PowerShell examples live + +## Source References +- .gitattributes +- .github/workflows/ci.yml +- scripts/populate-local-feed.sh +- scripts/populate-local-skills.sh +- scripts/release-skill.sh +- skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts +- skills/clawsec-suite/scripts/guarded_skill_install.mjs +- skills/openclaw-audit-watchdog/scripts/load_suppression_config.mjs +- wiki/platform-verification.md +- wiki/compatibility-report.md diff --git a/docs/SECURITY-SIGNING.md b/wiki/security-signing-runbook.md similarity index 94% rename from docs/SECURITY-SIGNING.md rename to wiki/security-signing-runbook.md index a775e17..4ad8f47 100644 --- a/docs/SECURITY-SIGNING.md +++ b/wiki/security-signing-runbook.md @@ -213,3 +213,16 @@ Before requiring signatures in all clients: - deploy pipeline mirrors signature companions - one rollback drill and one key rotation drill completed successfully - incident response on-call owner identified and documented + +## Source References +- advisories/feed.json +- advisories/feed.json.sig +- advisories/feed-signing-public.pem +- clawsec-signing-public.pem +- .github/actions/sign-and-verify/action.yml +- .github/workflows/poll-nvd-cves.yml +- .github/workflows/community-advisory.yml +- .github/workflows/deploy-pages.yml +- .github/workflows/skill-release.yml +- scripts/ci/verify_signing_key_consistency.sh +- wiki/migration-signed-feed.md diff --git a/wiki/security.md b/wiki/security.md index 5d788ed..36d0f39 100644 --- a/wiki/security.md +++ b/wiki/security.md @@ -29,8 +29,8 @@ - Release docs include manual verification commands for downstream consumers. ## Incident and Rotation Playbooks -- `docs/SECURITY-SIGNING.md` defines key generation, custody, rotation, and incident phases. -- `docs/MIGRATION-SIGNED-FEED.md` defines staged enforcement and rollback levels. +- `wiki/security-signing-runbook.md` defines key generation, custody, rotation, and incident phases. +- `wiki/migration-signed-feed.md` defines staged enforcement and rollback levels. - Rollback paths prioritize preserving signed publishing where possible and time-boxing any bypass. ## Example Snippets @@ -56,10 +56,13 @@ openssl pkey -pubin -in clawsec-signing-public.pem -outform DER | shasum -a 256 - Add explicit tests for workflow-level signature failure scenarios. - Increase runtime telemetry for advisory fetch/verification failures to simplify incident triage. +## Update Notes +- 2026-02-26: Repointed signing and migration references from root `docs/` files to dedicated `wiki/` operations pages. + ## Source References - SECURITY.md -- docs/SECURITY-SIGNING.md -- docs/MIGRATION-SIGNED-FEED.md +- wiki/security-signing-runbook.md +- wiki/migration-signed-feed.md - scripts/ci/verify_signing_key_consistency.sh - .github/actions/sign-and-verify/action.yml - .github/workflows/poll-nvd-cves.yml diff --git a/wiki/testing.md b/wiki/testing.md index a326463..7833040 100644 --- a/wiki/testing.md +++ b/wiki/testing.md @@ -57,6 +57,9 @@ node skills/openclaw-audit-watchdog/test/suppression_config.test.mjs 3. For feed/signing changes, run suite verification tests first (`feed_verification`, `guarded_install`). 4. For workflow or release changes, also run `scripts/validate-release-links.sh` and key consistency script. +## Update Notes +- 2026-02-26: Updated source references to the migrated `wiki/platform-verification.md` checklist. + ## Source References - AGENTS.md - scripts/prepare-to-push.sh @@ -70,4 +73,4 @@ node skills/openclaw-audit-watchdog/test/suppression_config.test.mjs - skills/clawsec-suite/test/path_resolution.test.mjs - skills/openclaw-audit-watchdog/test/suppression_config.test.mjs - skills/clawsec-clawhub-checker/test/reputation_check.test.mjs -- docs/PLATFORM_VERIFICATION.md +- wiki/platform-verification.md From 645220dc9b7cfa1e0188bf42b2c6c8a290e16f30 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:24:19 +0200 Subject: [PATCH 10/16] chore(wiki): de-track generated llms exports --- .gitignore | 2 ++ package.json | 1 + public/wiki/llms.txt | 5 +++++ public/wiki/llms/generation.txt | 17 +++++++++++------ public/wiki/llms/index.txt | 12 +++++++++++- public/wiki/llms/overview.txt | 5 ++++- public/wiki/llms/security.txt | 11 +++++++---- public/wiki/llms/testing.txt | 5 ++++- scripts/populate-local-wiki.sh | 32 ++++++++++++++++++++++++++++++++ 9 files changed, 77 insertions(+), 13 deletions(-) create mode 100755 scripts/populate-local-wiki.sh diff --git a/.gitignore b/.gitignore index 30934d4..158bb94 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,8 @@ dist-ssr # Derived public assets (copied during build) public/advisories public/skills +public/wiki/llms.txt +public/wiki/llms/ # Python bytecode __pycache__/ diff --git a/package.json b/package.json index 4ecac6c..8f06c9e 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "type": "module", "scripts": { "gen:wiki-llms": "node scripts/generate-wiki-llms.mjs", + "populate-local-wiki": "./scripts/populate-local-wiki.sh", "predev": "npm run gen:wiki-llms", "dev": "vite", "prebuild": "npm run gen:wiki-llms", diff --git a/public/wiki/llms.txt b/public/wiki/llms.txt index 368bacb..21a042c 100644 --- a/public/wiki/llms.txt +++ b/public/wiki/llms.txt @@ -9,17 +9,22 @@ Canonical source of truth: https://github.com/prompt-security/clawsec/tree/main/ ## Generated Page Exports - Wiki Index: https://clawsec.prompt.security/wiki/llms/index.txt (page: https://clawsec.prompt.security/#/wiki) - Architecture: https://clawsec.prompt.security/wiki/llms/architecture.txt (page: https://clawsec.prompt.security/#/wiki/architecture) +- Cross-Platform Compatibility Report: https://clawsec.prompt.security/wiki/llms/compatibility-report.txt (page: https://clawsec.prompt.security/#/wiki/compatibility-report) - Configuration: https://clawsec.prompt.security/wiki/llms/configuration.txt (page: https://clawsec.prompt.security/#/wiki/configuration) - Data Flow: https://clawsec.prompt.security/wiki/llms/data-flow.txt (page: https://clawsec.prompt.security/#/wiki/data-flow) - Dependencies: https://clawsec.prompt.security/wiki/llms/dependencies.txt (page: https://clawsec.prompt.security/#/wiki/dependencies) - Wiki Generation Metadata: https://clawsec.prompt.security/wiki/llms/generation.txt (page: https://clawsec.prompt.security/#/wiki/generation) - Glossary: https://clawsec.prompt.security/wiki/llms/glossary.txt (page: https://clawsec.prompt.security/#/wiki/glossary) +- Migration Plan: Unsigned Feed → Signed Feed: https://clawsec.prompt.security/wiki/llms/migration-signed-feed.txt (page: https://clawsec.prompt.security/#/wiki/migration-signed-feed) - Module: Automation and Release Pipelines: https://clawsec.prompt.security/wiki/llms/modules/automation-release.txt (page: https://clawsec.prompt.security/#/wiki/modules/automation-release) - Module: ClawSec Suite Core: https://clawsec.prompt.security/wiki/llms/modules/clawsec-suite.txt (page: https://clawsec.prompt.security/#/wiki/modules/clawsec-suite) - Module: Frontend Web App: https://clawsec.prompt.security/wiki/llms/modules/frontend-web.txt (page: https://clawsec.prompt.security/#/wiki/modules/frontend-web) - Module: Local Validation and Packaging Tools: https://clawsec.prompt.security/wiki/llms/modules/local-tooling.txt (page: https://clawsec.prompt.security/#/wiki/modules/local-tooling) - Module: NanoClaw Integration: https://clawsec.prompt.security/wiki/llms/modules/nanoclaw-integration.txt (page: https://clawsec.prompt.security/#/wiki/modules/nanoclaw-integration) - Overview: https://clawsec.prompt.security/wiki/llms/overview.txt (page: https://clawsec.prompt.security/#/wiki/overview) +- Platform Verification Checklist: https://clawsec.prompt.security/wiki/llms/platform-verification.txt (page: https://clawsec.prompt.security/#/wiki/platform-verification) +- Cross-Platform Remediation Plan: https://clawsec.prompt.security/wiki/llms/remediation-plan.txt (page: https://clawsec.prompt.security/#/wiki/remediation-plan) - Security: https://clawsec.prompt.security/wiki/llms/security.txt (page: https://clawsec.prompt.security/#/wiki/security) +- ClawSec Signing Operations Runbook: https://clawsec.prompt.security/wiki/llms/security-signing-runbook.txt (page: https://clawsec.prompt.security/#/wiki/security-signing-runbook) - Testing: https://clawsec.prompt.security/wiki/llms/testing.txt (page: https://clawsec.prompt.security/#/wiki/testing) - Workflow: https://clawsec.prompt.security/wiki/llms/workflow.txt (page: https://clawsec.prompt.security/#/wiki/workflow) diff --git a/public/wiki/llms/generation.txt b/public/wiki/llms/generation.txt index e55df2c..edd8729 100644 --- a/public/wiki/llms/generation.txt +++ b/public/wiki/llms/generation.txt @@ -11,10 +11,10 @@ LLM-ready export for a single wiki page. # Wiki Generation Metadata -- Commit hash: `448aed326192d38812cb508820f967cb74e77ae9` -- Branch name: `main` -- Generation timestamp (local): `2026-02-25T20:59:57+0200` -- Generation mode: `initial` +- Commit hash: `d5aadfbee15b48ebb4872dfb838e4df88c611d56` +- Branch name: `codex/wiki-tab-ui` +- Generation timestamp (local): `2026-02-26T09:16:02+0200` +- Generation mode: `update` - Output language: `English` - Assets copied into `wiki/assets/`: - `overview_img_01_prompt-security-logo.png` (from `img/Black+Color.png`) @@ -22,8 +22,8 @@ LLM-ready export for a single wiki page. - `architecture_img_01_prompt-line.svg` (from `public/img/prompt_line.svg`) ## Notes -- This is a first-time generation (`wiki/` did not exist before this run). -- Index sections were generated from repository structure and created wiki pages. +- Migrated root documentation pages from `docs/` into dedicated `wiki/` operation pages. +- Updated index and cross-links to use `wiki/` as the documentation source of truth. - Future updates should preserve existing headings and append `Update Notes` sections when making deltas. ## Source References @@ -35,3 +35,8 @@ LLM-ready export for a single wiki page. - wiki/dependencies.md - wiki/data-flow.md - wiki/glossary.md +- wiki/security-signing-runbook.md +- wiki/migration-signed-feed.md +- wiki/platform-verification.md +- wiki/remediation-plan.md +- wiki/compatibility-report.md diff --git a/public/wiki/llms/index.txt b/public/wiki/llms/index.txt index c9acc82..348df36 100644 --- a/public/wiki/llms/index.txt +++ b/public/wiki/llms/index.txt @@ -16,7 +16,7 @@ LLM-ready export for a single wiki page. - Tech stack: React 19 + Vite + TypeScript frontend, Node/ESM scripts, Python utilities, Bash automation, GitHub Actions pipelines. - Entry points: `index.tsx`, `App.tsx`, `scripts/prepare-to-push.sh`, `scripts/populate-local-feed.sh`, `scripts/populate-local-skills.sh`, workflow files under `.github/workflows/`. - Where to start: Read [Overview](overview.md), then [Architecture](architecture.md), then module pages for the area you are editing. -- How to navigate: Use Guides for cross-cutting concerns, Modules for implementation boundaries, and Source References at the end of each page to jump into code. +- How to navigate: Use Guides for cross-cutting concerns, Operations for runbooks and migration plans, Modules for implementation boundaries, and Source References at the end of each page to jump into code. ## Start Here - [Overview](overview.md) @@ -30,6 +30,13 @@ LLM-ready export for a single wiki page. - [Workflow](workflow.md) - [Security](security.md) +## Operations +- [Security Signing Runbook](security-signing-runbook.md) +- [Signed Feed Migration Plan](migration-signed-feed.md) +- [Platform Verification Checklist](platform-verification.md) +- [Cross-Platform Remediation Plan](remediation-plan.md) +- [Cross-Platform Compatibility Report](compatibility-report.md) + ## Modules - [Frontend Web App](modules/frontend-web.md) - [ClawSec Suite Core](modules/clawsec-suite.md) @@ -43,6 +50,9 @@ LLM-ready export for a single wiki page. ## Generation Metadata - [Generation Metadata](GENERATION.md) +## Update Notes +- 2026-02-26: Added Operations pages and updated navigation guidance after migrating root docs into wiki pages. + ## Source References - README.md - App.tsx diff --git a/public/wiki/llms/overview.txt b/public/wiki/llms/overview.txt index dfb474d..1f7f256 100644 --- a/public/wiki/llms/overview.txt +++ b/public/wiki/llms/overview.txt @@ -29,7 +29,7 @@ LLM-ready export for a single wiki page. | `.github/workflows/` | CI/CD pipelines | CI, releases, NVD polling, community advisory ingestion, pages deploy. | | `utils/` | Python utilities | Skill validation and checksum packaging helpers. | | `public/` | Published static assets | Site media, mirrored advisories, and generated skill artifacts. | -| `docs/` | Operational docs | Signing runbooks, migration plans, compatibility and verification guides. | +| `wiki/` | Documentation hub | Architecture, operations runbooks, compatibility, and verification guides. | ## Entry Points | Entry | Type | Purpose | @@ -95,6 +95,9 @@ npm run build - Skill release automation expects version parity between `skill.json` and `SKILL.md` frontmatter. - Some scripts are POSIX shell oriented; Windows users should prefer PowerShell equivalents or WSL. +## Update Notes +- 2026-02-26: Updated repo layout to point operational documentation at `wiki/` instead of the removed root `docs/` directory. + ## Source References - README.md - package.json diff --git a/public/wiki/llms/security.txt b/public/wiki/llms/security.txt index 2415537..0dbb297 100644 --- a/public/wiki/llms/security.txt +++ b/public/wiki/llms/security.txt @@ -40,8 +40,8 @@ LLM-ready export for a single wiki page. - Release docs include manual verification commands for downstream consumers. ## Incident and Rotation Playbooks -- `docs/SECURITY-SIGNING.md` defines key generation, custody, rotation, and incident phases. -- `docs/MIGRATION-SIGNED-FEED.md` defines staged enforcement and rollback levels. +- `wiki/security-signing-runbook.md` defines key generation, custody, rotation, and incident phases. +- `wiki/migration-signed-feed.md` defines staged enforcement and rollback levels. - Rollback paths prioritize preserving signed publishing where possible and time-boxing any bypass. ## Example Snippets @@ -67,10 +67,13 @@ openssl pkey -pubin -in clawsec-signing-public.pem -outform DER | shasum -a 256 - Add explicit tests for workflow-level signature failure scenarios. - Increase runtime telemetry for advisory fetch/verification failures to simplify incident triage. +## Update Notes +- 2026-02-26: Repointed signing and migration references from root `docs/` files to dedicated `wiki/` operations pages. + ## Source References - SECURITY.md -- docs/SECURITY-SIGNING.md -- docs/MIGRATION-SIGNED-FEED.md +- wiki/security-signing-runbook.md +- wiki/migration-signed-feed.md - scripts/ci/verify_signing_key_consistency.sh - .github/actions/sign-and-verify/action.yml - .github/workflows/poll-nvd-cves.yml diff --git a/public/wiki/llms/testing.txt b/public/wiki/llms/testing.txt index ee18d7d..6f600e1 100644 --- a/public/wiki/llms/testing.txt +++ b/public/wiki/llms/testing.txt @@ -68,6 +68,9 @@ node skills/openclaw-audit-watchdog/test/suppression_config.test.mjs 3. For feed/signing changes, run suite verification tests first (`feed_verification`, `guarded_install`). 4. For workflow or release changes, also run `scripts/validate-release-links.sh` and key consistency script. +## Update Notes +- 2026-02-26: Updated source references to the migrated `wiki/platform-verification.md` checklist. + ## Source References - AGENTS.md - scripts/prepare-to-push.sh @@ -81,4 +84,4 @@ node skills/openclaw-audit-watchdog/test/suppression_config.test.mjs - skills/clawsec-suite/test/path_resolution.test.mjs - skills/openclaw-audit-watchdog/test/suppression_config.test.mjs - skills/clawsec-clawhub-checker/test/reputation_check.test.mjs -- docs/PLATFORM_VERIFICATION.md +- wiki/platform-verification.md diff --git a/scripts/populate-local-wiki.sh b/scripts/populate-local-wiki.sh new file mode 100755 index 0000000..d6fd0ba --- /dev/null +++ b/scripts/populate-local-wiki.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# populate-local-wiki.sh +# Generates wiki-derived public assets for local preview and CI parity. +# +# Usage: ./scripts/populate-local-wiki.sh + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" + +WIKI_DIR="$PROJECT_ROOT/wiki" +PUBLIC_WIKI_DIR="$PROJECT_ROOT/public/wiki" +LLMS_DIR="$PUBLIC_WIKI_DIR/llms" + +if [ ! -d "$WIKI_DIR" ]; then + echo "Error: wiki directory not found at $WIKI_DIR" + exit 1 +fi + +echo "=== ClawSec Local Wiki Populator ===" +echo "Project root: $PROJECT_ROOT" + +node "$PROJECT_ROOT/scripts/generate-wiki-llms.mjs" + +PAGE_COUNT=0 +if [ -d "$LLMS_DIR" ]; then + PAGE_COUNT=$(find "$LLMS_DIR" -type f -name '*.txt' | wc -l | tr -d ' ') +fi + +echo "Wiki llms index: $PUBLIC_WIKI_DIR/llms.txt" +echo "Wiki llms pages: $PAGE_COUNT files under $LLMS_DIR" From 819838777983b2ee6e03758914af329d566918dd Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:26:54 +0200 Subject: [PATCH 11/16] chore(wiki): ignore generated public wiki artifacts --- .gitignore | 3 +- public/wiki/llms.txt | 30 ---- public/wiki/llms/architecture.txt | 140 ------------------ public/wiki/llms/configuration.txt | 99 ------------- public/wiki/llms/data-flow.txt | 109 -------------- public/wiki/llms/dependencies.txt | 112 -------------- public/wiki/llms/generation.txt | 42 ------ public/wiki/llms/glossary.txt | 68 --------- public/wiki/llms/index.txt | 64 -------- .../wiki/llms/modules/automation-release.txt | 103 ------------- public/wiki/llms/modules/clawsec-suite.txt | 107 ------------- public/wiki/llms/modules/frontend-web.txt | 109 -------------- public/wiki/llms/modules/local-tooling.txt | 95 ------------ .../llms/modules/nanoclaw-integration.txt | 108 -------------- public/wiki/llms/overview.txt | 116 --------------- public/wiki/llms/security.txt | 88 ----------- public/wiki/llms/testing.txt | 87 ----------- public/wiki/llms/workflow.txt | 85 ----------- 18 files changed, 1 insertion(+), 1564 deletions(-) delete mode 100644 public/wiki/llms.txt delete mode 100644 public/wiki/llms/architecture.txt delete mode 100644 public/wiki/llms/configuration.txt delete mode 100644 public/wiki/llms/data-flow.txt delete mode 100644 public/wiki/llms/dependencies.txt delete mode 100644 public/wiki/llms/generation.txt delete mode 100644 public/wiki/llms/glossary.txt delete mode 100644 public/wiki/llms/index.txt delete mode 100644 public/wiki/llms/modules/automation-release.txt delete mode 100644 public/wiki/llms/modules/clawsec-suite.txt delete mode 100644 public/wiki/llms/modules/frontend-web.txt delete mode 100644 public/wiki/llms/modules/local-tooling.txt delete mode 100644 public/wiki/llms/modules/nanoclaw-integration.txt delete mode 100644 public/wiki/llms/overview.txt delete mode 100644 public/wiki/llms/security.txt delete mode 100644 public/wiki/llms/testing.txt delete mode 100644 public/wiki/llms/workflow.txt diff --git a/.gitignore b/.gitignore index 158bb94..8faf088 100644 --- a/.gitignore +++ b/.gitignore @@ -24,8 +24,7 @@ dist-ssr # Derived public assets (copied during build) public/advisories public/skills -public/wiki/llms.txt -public/wiki/llms/ +public/wiki/ # Python bytecode __pycache__/ diff --git a/public/wiki/llms.txt b/public/wiki/llms.txt deleted file mode 100644 index 21a042c..0000000 --- a/public/wiki/llms.txt +++ /dev/null @@ -1,30 +0,0 @@ -# ClawSec Wiki llms.txt - -LLM-readable index for wiki pages. A generated `.txt` export exists for each page. - -Website wiki root: https://clawsec.prompt.security/#/wiki -GitHub wiki mirror: https://github.com/prompt-security/clawsec/wiki -Canonical source of truth: https://github.com/prompt-security/clawsec/tree/main/wiki - -## Generated Page Exports -- Wiki Index: https://clawsec.prompt.security/wiki/llms/index.txt (page: https://clawsec.prompt.security/#/wiki) -- Architecture: https://clawsec.prompt.security/wiki/llms/architecture.txt (page: https://clawsec.prompt.security/#/wiki/architecture) -- Cross-Platform Compatibility Report: https://clawsec.prompt.security/wiki/llms/compatibility-report.txt (page: https://clawsec.prompt.security/#/wiki/compatibility-report) -- Configuration: https://clawsec.prompt.security/wiki/llms/configuration.txt (page: https://clawsec.prompt.security/#/wiki/configuration) -- Data Flow: https://clawsec.prompt.security/wiki/llms/data-flow.txt (page: https://clawsec.prompt.security/#/wiki/data-flow) -- Dependencies: https://clawsec.prompt.security/wiki/llms/dependencies.txt (page: https://clawsec.prompt.security/#/wiki/dependencies) -- Wiki Generation Metadata: https://clawsec.prompt.security/wiki/llms/generation.txt (page: https://clawsec.prompt.security/#/wiki/generation) -- Glossary: https://clawsec.prompt.security/wiki/llms/glossary.txt (page: https://clawsec.prompt.security/#/wiki/glossary) -- Migration Plan: Unsigned Feed → Signed Feed: https://clawsec.prompt.security/wiki/llms/migration-signed-feed.txt (page: https://clawsec.prompt.security/#/wiki/migration-signed-feed) -- Module: Automation and Release Pipelines: https://clawsec.prompt.security/wiki/llms/modules/automation-release.txt (page: https://clawsec.prompt.security/#/wiki/modules/automation-release) -- Module: ClawSec Suite Core: https://clawsec.prompt.security/wiki/llms/modules/clawsec-suite.txt (page: https://clawsec.prompt.security/#/wiki/modules/clawsec-suite) -- Module: Frontend Web App: https://clawsec.prompt.security/wiki/llms/modules/frontend-web.txt (page: https://clawsec.prompt.security/#/wiki/modules/frontend-web) -- Module: Local Validation and Packaging Tools: https://clawsec.prompt.security/wiki/llms/modules/local-tooling.txt (page: https://clawsec.prompt.security/#/wiki/modules/local-tooling) -- Module: NanoClaw Integration: https://clawsec.prompt.security/wiki/llms/modules/nanoclaw-integration.txt (page: https://clawsec.prompt.security/#/wiki/modules/nanoclaw-integration) -- Overview: https://clawsec.prompt.security/wiki/llms/overview.txt (page: https://clawsec.prompt.security/#/wiki/overview) -- Platform Verification Checklist: https://clawsec.prompt.security/wiki/llms/platform-verification.txt (page: https://clawsec.prompt.security/#/wiki/platform-verification) -- Cross-Platform Remediation Plan: https://clawsec.prompt.security/wiki/llms/remediation-plan.txt (page: https://clawsec.prompt.security/#/wiki/remediation-plan) -- Security: https://clawsec.prompt.security/wiki/llms/security.txt (page: https://clawsec.prompt.security/#/wiki/security) -- ClawSec Signing Operations Runbook: https://clawsec.prompt.security/wiki/llms/security-signing-runbook.txt (page: https://clawsec.prompt.security/#/wiki/security-signing-runbook) -- Testing: https://clawsec.prompt.security/wiki/llms/testing.txt (page: https://clawsec.prompt.security/#/wiki/testing) -- Workflow: https://clawsec.prompt.security/wiki/llms/workflow.txt (page: https://clawsec.prompt.security/#/wiki/workflow) diff --git a/public/wiki/llms/architecture.txt b/public/wiki/llms/architecture.txt deleted file mode 100644 index 752de15..0000000 --- a/public/wiki/llms/architecture.txt +++ /dev/null @@ -1,140 +0,0 @@ -# ClawSec Wiki · Architecture - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/architecture -- LLM export: https://clawsec.prompt.security/wiki/llms/architecture.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/architecture.md - -## Markdown - -# Architecture - -## System Context -- This page appears under the `Start Here` section in `INDEX.md`. -- ClawSec sits between upstream intelligence sources (NVD + community issues), GitHub automation, and runtime agent environments. -- The repository publishes both static site content and signed artifacts that runtime skills verify before using. -- External actor groups: - - GitHub Actions runners executing CI, release, and feed workflows. - - OpenClaw/NanoClaw agents consuming skills, advisories, and verification scripts. - - Repository maintainers approving advisory issues and merging release/tag changes. - -## Components -| Component | Location | Responsibility | -| --- | --- | --- | -| Web UI | `App.tsx`, `pages/`, `components/` | Renders skills catalog and advisory detail experiences. | -| Advisory Feed Core | `advisories/feed.json*`, `skills/clawsec-suite/.../feed.mjs` | Stores, verifies, and parses advisories with detached signatures/checksums. | -| Skill Packages | `skills/*/` | Distributes installable security capabilities with SBOM metadata. | -| Local Automation Scripts | `scripts/*.sh` | Build local mirrors, pre-push checks, and manual release helpers. | -| CI/CD Workflows | `.github/workflows/*.yml` | Linting, tests, NVD polling, release packaging, and Pages deploy. | -| Python Utility Layer | `utils/*.py` | Skill metadata validation and checksum generation. | - -## Key Flows -- Skill catalog flow: - 1. Release/tag workflows publish skill assets. - 2. Deploy workflow discovers release assets and builds `public/skills/index.json`. - 3. UI fetches `public/skills/index.json` and skill docs for `/skills` pages. -- Advisory feed flow: - 1. `poll-nvd-cves.yml` and `community-advisory.yml` update `advisories/feed.json`. - 2. Feed is signed and mirrored to public paths. - 3. Runtime hooks/scripts load remote feed and fallback to local signed copies. -- Guarded install flow: - 1. Installer requests target skill + version. - 2. Advisory matcher checks affected specifiers and severity/risk hints. - 3. Exit code 42 enforces second confirmation when advisories match. - -## Diagrams -```mermaid -flowchart TD - A["NVD + Community Inputs"] --> B["Feed Workflows\n(poll/community)"] - B --> C["advisories/feed.json + signatures"] - C --> D["Deploy Workflow Mirrors to public/"] - D --> E["React UI (catalog/feed pages)"] - C --> F["clawsec-suite hook + installers"] - F --> G["Agent advisory alerts / gated install"] -``` - -![Prompt Line Motif](assets/architecture_img_01_prompt-line.svg) - -## Interfaces and Contracts -| Interface | Contract Form | Validation | -| --- | --- | --- | -| Skill metadata | `skills/*/skill.json` | Validated by Python utility + CI version-parity checks. | -| Advisory feed | JSON + Ed25519 detached signature | Verified by `feed.mjs` and NanoClaw signature utilities. | -| Checksums manifest | `checksums.json` (+ optional `.sig`) | Parsed and hash-matched before trusting payloads. | -| Hook event interface | `HookEvent` (`type`, `action`, `messages`) | Runtime handler only processes selected event names. | -| Workflow release naming | Tag pattern `-vX.Y.Z` | Parsed in release/deploy workflows to discover skills. | - -## Key Parameters -| Parameter | Default | Effect | -| --- | --- | --- | -| `CLAWSEC_FEED_URL` | `https://clawsec.prompt.security/advisories/feed.json` | Remote advisory source for suite scripts/hooks. | -| `CLAWSEC_ALLOW_UNSIGNED_FEED` | `0` | Enables temporary unsigned fallback compatibility. | -| `CLAWSEC_VERIFY_CHECKSUM_MANIFEST` | `1` | Requires checksum manifest verification where available. | -| `CLAWSEC_HOOK_INTERVAL_SECONDS` | `300` | Scan throttling window for advisory hook. | -| `CLAWSEC_SKILLS_INDEX_TIMEOUT_MS` | `5000` | Remote skill index fetch timeout for catalog discovery. | -| `PROMPTSEC_GIT_PULL` | `0` | Optional auto-pull before watchdog audit runs. | - -## Error Handling and Reliability -- Feed fetching is fail-closed for invalid signatures and malformed manifests. -- Remote fetch failures gracefully fall back to local signed feeds. -- Hook state uses atomic file writes with strict mode where supported. -- UI pages detect HTML fallbacks served as JSON and avoid rendering corrupted data. -- Workflow steps enforce key-fingerprint consistency to avoid split-key drift. - -## Example Snippets -```tsx -// Route topology in the web app - - } /> - } /> - } /> - } /> - } /> - -``` - -```ts -// Guarded feed loading contract in advisory hook -const remoteFeed = await loadRemoteFeed(feedUrl, { - signatureUrl: feedSignatureUrl, - checksumsUrl: feedChecksumsUrl, - checksumsSignatureUrl: feedChecksumsSignatureUrl, - publicKeyPem, - checksumsPublicKeyPem: publicKeyPem, - allowUnsigned, - verifyChecksumManifest, -}); -``` - -## Runtime and Deployment -| Runtime Surface | Execution Model | Output | -| --- | --- | --- | -| Vite app (`npm run dev`) | Local frontend server | Interactive web app for feed/skills. | -| GitHub CI | Multi-OS matrix + dedicated jobs | Lint/type/build/security and test confidence. | -| Skill release workflow | Tag-driven | Release assets, signed checksums, optional ClawHub publish. | -| Pages deploy workflow | Triggered by CI/Release success | Static site + mirrored advisories/releases. | -| Runtime hooks | OpenClaw event hooks / NanoClaw IPC | Advisory alerts, gating decisions, integrity checks. | - -## Scaling Notes -- Advisory volume scales with keyword set in NVD polling; dedupe and post-filtering control noise. -- Deploy workflow processes release lists and keeps newest skill versions in index output. -- Module boundaries by skill folder allow adding new security capabilities without changing frontend structure. -- Signature verification paths remain lightweight because payload sizes (feed/manifests) are small. - -## Source References -- App.tsx -- pages/SkillsCatalog.tsx -- pages/FeedSetup.tsx -- pages/AdvisoryDetail.tsx -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs -- skills/clawsec-suite/scripts/guarded_skill_install.mjs -- skills/clawsec-suite/scripts/discover_skill_catalog.mjs -- skills/clawsec-nanoclaw/lib/advisories.ts -- skills/clawsec-nanoclaw/lib/signatures.ts -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/community-advisory.yml -- .github/workflows/deploy-pages.yml -- .github/workflows/skill-release.yml diff --git a/public/wiki/llms/configuration.txt b/public/wiki/llms/configuration.txt deleted file mode 100644 index 0720f74..0000000 --- a/public/wiki/llms/configuration.txt +++ /dev/null @@ -1,99 +0,0 @@ -# ClawSec Wiki · Configuration - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/configuration -- LLM export: https://clawsec.prompt.security/wiki/llms/configuration.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/configuration.md - -## Markdown - -# Configuration - -## Scope -- Configuration spans frontend build settings, runtime feed paths, workflow triggers, and skill metadata contracts. -- Most runtime-sensitive controls are environment variables prefixed with `CLAWSEC_` or `OPENCLAW_`. -- Path normalization is security-sensitive and intentionally rejects unresolved home-token literals. - -## Core Runtime Variables -| Variable | Default | Used By | -| --- | --- | --- | -| `CLAWSEC_FEED_URL` | Hosted advisory URL | Suite hook and guarded installer feed loading. | -| `CLAWSEC_FEED_SIG_URL` | `.sig` | Detached signature source. | -| `CLAWSEC_FEED_CHECKSUMS_URL` | `checksums.json` near feed URL | Optional checksum-manifest source. | -| `CLAWSEC_FEED_PUBLIC_KEY` | Suite-local PEM file | Feed signature verification. | -| `CLAWSEC_ALLOW_UNSIGNED_FEED` | `0` | Temporary migration bypass flag. | -| `CLAWSEC_VERIFY_CHECKSUM_MANIFEST` | `1` | Enables checksum-manifest verification. | -| `CLAWSEC_HOOK_INTERVAL_SECONDS` | `300` | Advisory hook scan throttle. | - -## Path Resolution Rules -| Rule | Behavior | Enforcement Location | -| --- | --- | --- | -| `~` expansion | Resolved to detected home directory | Shared path utility functions in suite/watchdog scripts. | -| `$HOME` / `${HOME}` expansion | Resolved when unescaped | Same utilities. | -| Windows home tokens | `%USERPROFILE%`, `$env:USERPROFILE` normalized | Same utilities. | -| Escaped tokens (`\$HOME`) | Rejected with explicit error | Prevents accidental literal directory creation. | -| Invalid explicit path | Can fallback to default path with warning | `resolveConfiguredPath` helpers. | - -## Frontend and Build Configuration -- `vite.config.ts` defines port (`3000`), host (`0.0.0.0`), and path alias (`@`). -- `index.html` provides Tailwind runtime config, custom fonts, and base color tokens. -- `tsconfig.json` uses bundler module resolution, `noEmit`, and JSX runtime configuration. -- `eslint.config.js` applies TS, React, hooks, and script-specific lint rules. - -## Skill Metadata Configuration -| Field Group | Location | Function | -| --- | --- | --- | -| Core skill identity | `skills/*/skill.json` | Name/version/author/license/description metadata. | -| SBOM file list | `skill.json -> sbom.files` | Declares release-required artifacts. | -| Platform metadata | `openclaw` or `nanoclaw` blocks | CLI requirements, triggers, platform capability hints. | -| Suite catalog metadata | `skills/clawsec-suite/skill.json -> catalog` | Integrated/default/consent behavior for suite members. | - -## Workflow Configuration -- Schedule configuration exists in workflow `cron` entries (`poll-nvd-cves`, `codeql`, `scorecard`). -- Release workflow expects tag naming pattern `-v`. -- Deployment workflow is triggered by successful CI/release `workflow_run` events and manual dispatch. -- Composite signing action requires private key inputs and verifies signatures immediately after signing. - -## Example Snippets -```bash -# run guarded install with explicit local signed feed paths -CLAWSEC_LOCAL_FEED="$HOME/.openclaw/skills/clawsec-suite/advisories/feed.json" \ -CLAWSEC_LOCAL_FEED_SIG="$HOME/.openclaw/skills/clawsec-suite/advisories/feed.json.sig" \ -CLAWSEC_FEED_PUBLIC_KEY="$HOME/.openclaw/skills/clawsec-suite/advisories/feed-signing-public.pem" \ -node skills/clawsec-suite/scripts/guarded_skill_install.mjs --skill clawtributor --dry-run -``` - -```json -{ - "name": "example-skill", - "version": "1.2.3", - "sbom": { - "files": [ - { "path": "SKILL.md", "required": true, "description": "Install docs" } - ] - } -} -``` - -## Operational Notes -- Keep signing keys outside the repository and inject via GitHub Secrets only. -- Prefer absolute paths or unescaped home expressions in local environment variable overrides. -- Treat unsigned feed mode as temporary migration support, not normal operation. -- Re-run release-link validation when editing `SKILL.md` URLs to avoid broken artifact references. - -## Source References -- vite.config.ts -- index.html -- tsconfig.json -- eslint.config.js -- skills/clawsec-suite/skill.json -- skills/clawsec-nanoclaw/skill.json -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/utils.mjs -- skills/openclaw-audit-watchdog/scripts/load_suppression_config.mjs -- skills/clawsec-suite/scripts/guarded_skill_install.mjs -- scripts/validate-release-links.sh -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/skill-release.yml -- .github/actions/sign-and-verify/action.yml diff --git a/public/wiki/llms/data-flow.txt b/public/wiki/llms/data-flow.txt deleted file mode 100644 index ce2c648..0000000 --- a/public/wiki/llms/data-flow.txt +++ /dev/null @@ -1,109 +0,0 @@ -# ClawSec Wiki · Data Flow - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/data-flow -- LLM export: https://clawsec.prompt.security/wiki/llms/data-flow.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/data-flow.md - -## Markdown - -# Data Flow - -## Primary Flows -- `Advisory ingestion`: NVD/community inputs are transformed into a normalized advisory feed, signed, then mirrored for clients. -- `Skill catalog publication`: release assets are discovered and converted into `public/skills/index.json` plus per-skill docs/checksums. -- `Runtime enforcement`: suite and nanoclaw consumers load advisory data, match against skills, and emit alerts or confirmation gates. -- This page appears under the `Guides` section in `INDEX.md`. - -## Step-by-Step -1. Feed producer workflow/script fetches source data (`NVD API` or issue payload). -2. JSON transform logic normalizes severity/type/affected fields and deduplicates by advisory ID. -3. Signature/checksum steps generate detached signatures and checksum manifests. -4. Deploy workflow mirrors signed artifacts under `public/` and `public/releases/latest/download/`. -5. UI and runtime consumers fetch feed/index files and validate format/signatures before use. -6. Matchers compare `affected` specifiers to skill names/versions and emit alerts or enforce confirmation. - -## Inputs and Outputs -Inputs/outputs are summarized in the table below. - -| Type | Name | Location | Description | -| --- | --- | --- | --- | -| Input | CVE payloads | `services.nvd.nist.gov/rest/json/cves/2.0` | Source vulnerabilities filtered by ClawSec keywords. | -| Input | Community advisory issue | `.github/workflows/community-advisory.yml` event payload | Maintainer-approved issue transformed into advisory record. | -| Input | Skill release assets | GitHub Releases API + assets | Used to build web catalog and mirror downloads. | -| Input | Local config/env | `OPENCLAW_AUDIT_CONFIG`, `CLAWSEC_*` vars | Controls feed pathing, suppression, and verification behavior. | -| Output | Advisory feed | `advisories/feed.json` | Canonical repository feed. | -| Output | Advisory signature | `advisories/feed.json.sig` | Detached signature for feed authenticity. | -| Output | Skill catalog index | `public/skills/index.json` | Runtime web catalog used by `/skills` pages. | -| Output | Release checksums/signatures | `release-assets/checksums.json(.sig)` | Integrity manifest for release consumers. | -| Output | Hook state | `~/.openclaw/clawsec-suite-feed-state.json` | Tracks scan timing and notified matches. | - -## Data Structures -| Structure | Key Fields | Purpose | -| --- | --- | --- | -| Advisory feed record | `id`, `severity`, `type`, `affected[]`, `published` | Unit of risk data used by UI and installers. | -| Skill metadata record | `id`, `name`, `version`, `emoji`, `tag` | Catalog row for web browsing and install commands. | -| Checksums manifest | `schema_version`, `algorithm`, `files` | Maps file names to expected digests. | -| Advisory state | `known_advisories`, `last_hook_scan`, `notified_matches` | Prevents repeated alerts and throttles scans. | -| Suppression config | `enabledFor[]`, `suppressions[]` | Targeted skip list by `checkId` + `skill`. | - -## Diagrams -```mermaid -flowchart LR - A["NVD + Issue Inputs"] --> B["Transform + Deduplicate"] - B --> C["advisories/feed.json"] - C --> D["Sign + checksums"] - D --> E["public/advisories + releases/latest"] - E --> F["Web UI fetch"] - E --> G["Suite/NanoClaw verification"] - G --> H["Match skills + emit alerts/gates"] -``` - -## State and Storage -| Store | Path/Scope | Write Path | -| --- | --- | --- | -| Canonical advisories | `advisories/` | NVD + community workflows and local populate script. | -| Embedded advisory copies | `skills/clawsec-feed/advisories/` and `skills/clawsec-suite/advisories/` | Sync/packaging processes and release workflow. | -| Public mirrors | `public/advisories/`, `public/releases/` | Deploy workflow. | -| Runtime state | `~/.openclaw/clawsec-suite-feed-state.json` | Advisory hook state persistence. | -| NanoClaw cache | `/workspace/project/data/clawsec-advisory-cache.json` | Host-side advisory cache manager. | -| Integrity state | `/workspace/project/data/soul-guardian/` (NanoClaw) | Integrity monitor baseline/audit storage. | - -## Example Snippets -```bash -# Local feed flow (NVD fetch -> transform -> sync) -./scripts/populate-local-feed.sh --days 120 -jq '.updated, (.advisories | length)' advisories/feed.json -``` - -```bash -# Runtime guarded install uses signed feed paths -CLAWSEC_LOCAL_FEED=~/.openclaw/skills/clawsec-suite/advisories/feed.json \ -CLAWSEC_FEED_PUBLIC_KEY=~/.openclaw/skills/clawsec-suite/advisories/feed-signing-public.pem \ -node skills/clawsec-suite/scripts/guarded_skill_install.mjs --skill test-skill --dry-run -``` - -## Failure Modes -- NVD rate limits (`403/429`) can delay feed refresh and require retries/backoff. -- Missing or invalid detached signatures cause feed rejection in fail-closed mode. -- HTML fallback responses for JSON endpoints can produce false positives unless explicitly filtered. -- Path-token misconfiguration (`\$HOME`) can break local fallback path resolution. -- Mismatched public key fingerprints in workflows trigger hard CI failure. - -## Source References -- advisories/feed.json -- advisories/feed.json.sig -- scripts/populate-local-feed.sh -- scripts/populate-local-skills.sh -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/community-advisory.yml -- .github/workflows/deploy-pages.yml -- .github/workflows/skill-release.yml -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/state.ts -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/matching.ts -- skills/clawsec-suite/scripts/guarded_skill_install.mjs -- skills/clawsec-nanoclaw/lib/advisories.ts -- skills/clawsec-nanoclaw/host-services/advisory-cache.ts diff --git a/public/wiki/llms/dependencies.txt b/public/wiki/llms/dependencies.txt deleted file mode 100644 index ca37837..0000000 --- a/public/wiki/llms/dependencies.txt +++ /dev/null @@ -1,112 +0,0 @@ -# ClawSec Wiki · Dependencies - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/dependencies -- LLM export: https://clawsec.prompt.security/wiki/llms/dependencies.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/dependencies.md - -## Markdown - -# Dependencies - -## Build and Runtime -| Layer | Primary Dependencies | Why It Exists | -| --- | --- | --- | -| Frontend runtime | `react`, `react-dom`, `react-router-dom`, `lucide-react` | UI rendering, routing, iconography. | -| Markdown rendering | `react-markdown`, `remark-gfm` | Render skill docs/readmes in detail pages. | -| Build tooling | `vite`, `@vitejs/plugin-react`, `typescript` | Fast TS/TSX bundling and production builds. | -| Python utilities | stdlib + `ruff`/`bandit` policy from `pyproject.toml` | Validate/package skills and run static checks. | -| Shell automation | `bash`, `jq`, `curl`, `openssl`, `sha256sum`/`shasum` | Feed polling, signing, checksum generation, release checks. | - -## Dependency Details -| Package | Version Constraint | Scope | -| --- | --- | --- | -| `react` / `react-dom` | `^19.2.4` | Frontend runtime | -| `react-router-dom` | `^7.13.1` | Frontend routing | -| `lucide-react` | `^0.575.0` | UI icon set | -| `vite` | `^7.3.1` | Dev server + build | -| `typescript` | `~5.8.2` | Type checking | -| `eslint` | `^9.39.2` | JS/TS linting | -| `@typescript-eslint/*` | `^8.55.0` / `^8.56.0` | TS lint parser/rules | -| `fast-check` | `^4.5.3` | Property/fuzz style tests | - -| Override | Pinned Version | Rationale | -| --- | --- | --- | -| `ajv` | `6.14.0` | Security and compatibility stabilization. | -| `balanced-match` | `4.0.3` | Transitive vulnerability control. | -| `brace-expansion` | `5.0.2` | Transitive dependency hardening. | -| `minimatch` | `10.2.1` | Deterministic dependency behavior. | - -## External Services -| Service | Used By | Function | -| --- | --- | --- | -| NVD API (`services.nvd.nist.gov`) | `poll-nvd-cves` workflow + local feed script | Pull CVEs by keyword/date window. | -| GitHub API | Deploy/release workflows | Discover releases, download assets, publish outputs. | -| GitHub Pages | Deploy workflow | Serve static site and mirrored artifacts. | -| ClawHub CLI/registry | Install scripts + optional publish jobs | Install and publish skills. | -| Optional local SMTP/sendmail | `openclaw-audit-watchdog` scripts | Deliver audit reports by email. | - -## Development Tools -| Tool | Invocation | Coverage | -| --- | --- | --- | -| ESLint | `npx eslint . --ext .ts,.tsx,.js,.jsx,.mjs --max-warnings 0` | Frontend and script linting. | -| TypeScript | `npx tsc --noEmit` | Compile-time TS contract checks. | -| Ruff | `ruff check utils/` | Python style and bug pattern checks. | -| Bandit | `bandit -r utils/ -ll` | Python security checks. | -| Trivy | Workflow + optional local run | FS/config vulnerability scans. | -| Gitleaks | Workflow + optional local run | Secret leak detection. | - -## Example Snippets -```json -{ - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "dependencies": { - "react": "^19.2.4", - "react-router-dom": "^7.13.1" - } -} -``` - -```toml -[tool.ruff] -target-version = "py310" -line-length = 120 - -[tool.bandit] -exclude_dirs = ["__pycache__", ".venv"] -skips = ["B101"] -``` - -## Compatibility Notes -- Local scripts account for macOS vs Linux differences in `date` and `stat` usage. -- Some workflows/scripts require OpenSSL features used with Ed25519 and `pkeyutl -rawin`. -- Windows support is strongest for Node-based tooling; POSIX shell paths may require WSL/Git Bash. -- Feed consumers include compatibility bypasses for migration phases, but signed mode is the intended steady state. - -## Versioning Notes -- Skill release tags follow `-v` and are parsed by CI/deploy automation. -- PR validation enforces version parity between `skill.json` and `SKILL.md` frontmatter for bumped skills. -- The public skills index keeps latest discovered version per skill for UI display. -- Signed artifact manifests (`checksums.json`) are versioned per release and include file hashes and URLs. - -## Source References -- package.json -- package-lock.json -- pyproject.toml -- eslint.config.js -- tsconfig.json -- scripts/prepare-to-push.sh -- scripts/populate-local-feed.sh -- scripts/populate-local-skills.sh -- .github/workflows/ci.yml -- .github/workflows/codeql.yml -- .github/workflows/scorecard.yml -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/deploy-pages.yml -- .github/workflows/skill-release.yml diff --git a/public/wiki/llms/generation.txt b/public/wiki/llms/generation.txt deleted file mode 100644 index edd8729..0000000 --- a/public/wiki/llms/generation.txt +++ /dev/null @@ -1,42 +0,0 @@ -# ClawSec Wiki · Wiki Generation Metadata - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/generation -- LLM export: https://clawsec.prompt.security/wiki/llms/generation.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/GENERATION.md - -## Markdown - -# Wiki Generation Metadata - -- Commit hash: `d5aadfbee15b48ebb4872dfb838e4df88c611d56` -- Branch name: `codex/wiki-tab-ui` -- Generation timestamp (local): `2026-02-26T09:16:02+0200` -- Generation mode: `update` -- Output language: `English` -- Assets copied into `wiki/assets/`: - - `overview_img_01_prompt-security-logo.png` (from `img/Black+Color.png`) - - `overview_img_02_clawsec-mascot.png` (from `public/img/mascot.png`) - - `architecture_img_01_prompt-line.svg` (from `public/img/prompt_line.svg`) - -## Notes -- Migrated root documentation pages from `docs/` into dedicated `wiki/` operation pages. -- Updated index and cross-links to use `wiki/` as the documentation source of truth. -- Future updates should preserve existing headings and append `Update Notes` sections when making deltas. - -## Source References -- README.md -- package.json -- AGENTS.md -- wiki/overview.md -- wiki/architecture.md -- wiki/dependencies.md -- wiki/data-flow.md -- wiki/glossary.md -- wiki/security-signing-runbook.md -- wiki/migration-signed-feed.md -- wiki/platform-verification.md -- wiki/remediation-plan.md -- wiki/compatibility-report.md diff --git a/public/wiki/llms/glossary.txt b/public/wiki/llms/glossary.txt deleted file mode 100644 index aa00e04..0000000 --- a/public/wiki/llms/glossary.txt +++ /dev/null @@ -1,68 +0,0 @@ -# ClawSec Wiki · Glossary - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/glossary -- LLM export: https://clawsec.prompt.security/wiki/llms/glossary.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/glossary.md - -## Markdown - -# Glossary - -## Terms -| Term | Definition | -| --- | --- | -| Advisory Feed | JSON document (`feed.json`) containing security advisories for skills/platforms. | -| Affected Specifier | Skill selector such as `skill@1.2.3`, wildcard, or range used in matching logic. | -| Guarded Install | Two-step installer behavior that requires explicit confirmation when advisories match. | -| SBOM Files | Skill-declared artifact list in `skill.json` used for packaging and validation. | -| Detached Signature | Base64 signature file (`.sig`) stored separately from signed payload. | -| Checksum Manifest | File hash map (`checksums.json`) used to verify payload integrity. | - -## Skill Packaging Terms -| Term | Definition | -| --- | --- | -| Skill Tag | Git tag formatted as `-v` used by release automation. | -| Release Assets | Files attached to GitHub release (zip, `skill.json`, checksums, signatures). | -| Catalog Index | `public/skills/index.json`, generated list consumed by web catalog. | -| Embedded Components | Capability bundle from one skill included in another (for example feed embedded in suite). | - -## Advisory and Security Terms -| Term | Definition | -| --- | --- | -| Fail-Closed Verification | Reject payload if signature or checksum validation fails. | -| Unsigned Compatibility Mode | Temporary bypass path enabled via `CLAWSEC_ALLOW_UNSIGNED_FEED=1`. | -| Suppression Rule | Config entry matching `checkId` and `skill` to suppress known/accepted findings. | -| Key Fingerprint | SHA-256 digest of DER-encoded public key used for key consistency checks. | - -## Runtime and Platform Terms -| Term | Definition | -| --- | --- | -| OpenClaw Hook | Runtime event handler (`clawsec-advisory-guardian`) that checks advisories. | -| NanoClaw IPC | Host/container task exchange for advisory refresh, signature verification, integrity checks. | -| Integrity Baseline | Stored approved hashes/snapshots for protected files. | -| Hash-Chained Audit Log | Append-only audit log where each entry depends on prior hash. | - -## CI/CD Terms -| Term | Definition | -| --- | --- | -| Poll NVD CVEs Workflow | Scheduled workflow that fetches and transforms NVD CVEs into advisories. | -| Community Advisory Workflow | Issue-label-triggered workflow that publishes approved community advisories. | -| Skill Release Workflow | Tag-triggered packaging/signing/publishing pipeline for skills. | -| Deploy Pages Workflow | Workflow that builds site assets and mirrors release/advisory artifacts. | - -## Source References -- types.ts -- skills/clawsec-suite/skill.json -- skills/clawsec-nanoclaw/skill.json -- skills/clawsec-suite/scripts/guarded_skill_install.mjs -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/suppression.mjs -- skills/clawsec-nanoclaw/guardian/integrity-monitor.ts -- scripts/populate-local-feed.sh -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/community-advisory.yml -- .github/workflows/skill-release.yml -- .github/workflows/deploy-pages.yml diff --git a/public/wiki/llms/index.txt b/public/wiki/llms/index.txt deleted file mode 100644 index 348df36..0000000 --- a/public/wiki/llms/index.txt +++ /dev/null @@ -1,64 +0,0 @@ -# ClawSec Wiki · Wiki Index - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki -- LLM export: https://clawsec.prompt.security/wiki/llms/index.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/INDEX.md - -## Markdown - -# Wiki Index - -## Summary -- Purpose: Document ClawSec as a combined web catalog, signed advisory channel, and multi-skill security distribution system. -- Tech stack: React 19 + Vite + TypeScript frontend, Node/ESM scripts, Python utilities, Bash automation, GitHub Actions pipelines. -- Entry points: `index.tsx`, `App.tsx`, `scripts/prepare-to-push.sh`, `scripts/populate-local-feed.sh`, `scripts/populate-local-skills.sh`, workflow files under `.github/workflows/`. -- Where to start: Read [Overview](overview.md), then [Architecture](architecture.md), then module pages for the area you are editing. -- How to navigate: Use Guides for cross-cutting concerns, Operations for runbooks and migration plans, Modules for implementation boundaries, and Source References at the end of each page to jump into code. - -## Start Here -- [Overview](overview.md) -- [Architecture](architecture.md) - -## Guides -- [Dependencies](dependencies.md) -- [Data Flow](data-flow.md) -- [Configuration](configuration.md) -- [Testing](testing.md) -- [Workflow](workflow.md) -- [Security](security.md) - -## Operations -- [Security Signing Runbook](security-signing-runbook.md) -- [Signed Feed Migration Plan](migration-signed-feed.md) -- [Platform Verification Checklist](platform-verification.md) -- [Cross-Platform Remediation Plan](remediation-plan.md) -- [Cross-Platform Compatibility Report](compatibility-report.md) - -## Modules -- [Frontend Web App](modules/frontend-web.md) -- [ClawSec Suite Core](modules/clawsec-suite.md) -- [NanoClaw Integration](modules/nanoclaw-integration.md) -- [Automation and Release Pipelines](modules/automation-release.md) -- [Local Validation and Packaging Tools](modules/local-tooling.md) - -## Glossary -- [Glossary](glossary.md) - -## Generation Metadata -- [Generation Metadata](GENERATION.md) - -## Update Notes -- 2026-02-26: Added Operations pages and updated navigation guidance after migrating root docs into wiki pages. - -## Source References -- README.md -- App.tsx -- package.json -- scripts/prepare-to-push.sh -- scripts/populate-local-feed.sh -- scripts/populate-local-skills.sh -- skills/clawsec-suite/skill.json -- .github/workflows/ci.yml diff --git a/public/wiki/llms/modules/automation-release.txt b/public/wiki/llms/modules/automation-release.txt deleted file mode 100644 index a913425..0000000 --- a/public/wiki/llms/modules/automation-release.txt +++ /dev/null @@ -1,103 +0,0 @@ -# ClawSec Wiki · Module: Automation and Release Pipelines - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/modules/automation-release -- LLM export: https://clawsec.prompt.security/wiki/llms/modules/automation-release.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/automation-release.md - -## Markdown - -# Module: Automation and Release Pipelines - -## Responsibilities -- Enforce repository quality/security checks before merge and deployment. -- Generate and maintain advisory feed updates from automated and community sources. -- Package, sign, and publish skill release artifacts from tag events. -- Build and deploy static website outputs and mirrored release/advisory assets. - -## Key Files -- `.github/workflows/ci.yml`: lint/type/build/security/test matrix. -- `.github/workflows/poll-nvd-cves.yml`: daily NVD advisory ingestion. -- `.github/workflows/community-advisory.yml`: issue-label-driven advisory publishing. -- `.github/workflows/skill-release.yml`: release validation, packaging, signing, and publishing. -- `.github/workflows/deploy-pages.yml`: site build + asset mirroring to GitHub Pages. -- `.github/actions/sign-and-verify/action.yml`: shared Ed25519 sign/verify composite action. -- `scripts/prepare-to-push.sh`: local CI-like quality gate. -- `scripts/release-skill.sh`: manual helper for version bump + tag workflow. - -## Public Interfaces -| Interface | Trigger | Outcome | -| --- | --- | --- | -| CI workflow | Push/PR on `main` | Fails fast on lint/type/build/test/security regressions. | -| NVD poll workflow | Cron + dispatch | Updates advisory feed with deduped, normalized CVEs. | -| Community advisory workflow | Issue labeled `advisory-approved` | Opens PR adding signed advisory records. | -| Skill release workflow | Tag `-v*` | Creates GitHub release assets and signatures. | -| Deploy pages workflow | Successful CI/release run | Publishes site + mirrored artifacts to Pages. | - -## Inputs and Outputs -Inputs/outputs are summarized in the table below. - -| Type | Name | Location | Description | -| --- | --- | --- | --- | -| Input | Git refs/events | GitHub Actions event payloads | Determines which workflow path runs. | -| Input | Skill metadata/SBOM | `skills/*/skill.json` | Drives release asset assembly and validation. | -| Input | NVD API data | External API responses | Source CVEs for advisory feed generation. | -| Input | Signing secrets | GitHub Secrets | Private key material for signing artifacts. | -| Output | Signed advisories | `advisories/feed.json(.sig)` + mirrored public files | Consumable signed feed channel. | -| Output | Skill release assets | `release-assets/*` and GitHub release attachments | Installable and verifiable skill artifacts. | -| Output | Website build | `dist/` deployment artifact | Public web frontend and mirrors. | - -## Configuration -| Config Point | Location | Notes | -| --- | --- | --- | -| Workflow schedules | `poll-nvd-cves.yml`, `codeql.yml`, `scorecard.yml` | Daily/weekly security automation cadence. | -| Concurrency groups | Workflow `concurrency` blocks | Prevents destructive overlap in key pipelines. | -| Signing key checks | `scripts/ci/verify_signing_key_consistency.sh` | Ensures docs and canonical PEM files align. | -| Local pre-push gating | `scripts/prepare-to-push.sh` | Mirrors CI checks with optional auto-fix. | - -## Example Snippets -```yaml -# skill release trigger pattern -on: - push: - tags: - - '*-v[0-9]*.[0-9]*.[0-9]*' -``` - -```bash -# local all-in-one pre-push gate -./scripts/prepare-to-push.sh -# optional auto-fix -./scripts/prepare-to-push.sh --fix -``` - -## Edge Cases -- NVD API rate limiting (`403`/`429`) is handled with retry/backoff and can fail workflow on persistent errors. -- Release pipeline blocks on version mismatch between `skill.json` and `SKILL.md` frontmatter. -- Key fingerprint drift between canonical PEM files and docs hard-fails signing-related workflows. -- Deploy workflow intentionally allows unsigned legacy checksums for backward compatibility in some branches. -- Manual helper script has safety checks but includes destructive rollback logic in error branches; use carefully. - -## Tests -| Validation Layer | Location | -| --- | --- | -| Workflow execution tests | CI jobs in `.github/workflows/ci.yml` | -| Skill-level unit/property tests | `skills/*/test/*.test.mjs` invoked by CI | -| Local deterministic checks | `scripts/prepare-to-push.sh` | -| Release link checks | `scripts/validate-release-links.sh` | - -## Source References -- .github/workflows/ci.yml -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/community-advisory.yml -- .github/workflows/skill-release.yml -- .github/workflows/deploy-pages.yml -- .github/workflows/codeql.yml -- .github/workflows/scorecard.yml -- .github/actions/sign-and-verify/action.yml -- scripts/prepare-to-push.sh -- scripts/release-skill.sh -- scripts/validate-release-links.sh -- scripts/ci/verify_signing_key_consistency.sh diff --git a/public/wiki/llms/modules/clawsec-suite.txt b/public/wiki/llms/modules/clawsec-suite.txt deleted file mode 100644 index 4017695..0000000 --- a/public/wiki/llms/modules/clawsec-suite.txt +++ /dev/null @@ -1,107 +0,0 @@ -# ClawSec Wiki · Module: ClawSec Suite Core - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/modules/clawsec-suite -- LLM export: https://clawsec.prompt.security/wiki/llms/modules/clawsec-suite.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/clawsec-suite.md - -## Markdown - -# Module: ClawSec Suite Core - -## Responsibilities -- Act as the main skill-of-skills security bundle for OpenClaw-style agents. -- Verify advisory feed authenticity (Ed25519 signatures and optional checksum manifests). -- Detect advisory matches against installed skills and emit actionable runtime alerts. -- Enforce two-step confirmation for risky skill installations. - -## Key Files -- `skills/clawsec-suite/skill.json`: suite metadata, embedded components, catalog defaults. -- `skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts`: runtime event handler. -- `skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs`: signed feed loading/parsing. -- `skills/clawsec-suite/hooks/.../lib/matching.ts`: advisory-to-skill matching logic. -- `skills/clawsec-suite/hooks/.../lib/state.ts`: scan state persistence. -- `skills/clawsec-suite/hooks/.../lib/suppression.mjs`: allowlist-based suppression loader. -- `skills/clawsec-suite/scripts/guarded_skill_install.mjs`: advisory-gated installer wrapper. -- `skills/clawsec-suite/scripts/discover_skill_catalog.mjs`: remote/fallback catalog discovery. - -## Public Interfaces -| Interface | Consumer | Behavior | -| --- | --- | --- | -| Hook handler default export | OpenClaw hook runtime | Handles `agent:bootstrap` and `command:new` events. | -| `guarded_skill_install.mjs` CLI | Operators/automation | Blocks on advisory matches unless `--confirm-advisory`. | -| `discover_skill_catalog.mjs` CLI | Suite docs/automation | Lists installable skills with fallback metadata. | -| `feed.mjs` functions | Suite scripts and tests | Feed load, signature verification, checksum manifest checks. | -| Exit code contract | External wrappers | `42` indicates explicit second confirmation required. | - -## Inputs and Outputs -Inputs/outputs are summarized in the table below. - -| Type | Name | Location | Description | -| --- | --- | --- | --- | -| Input | Advisory feed + signatures | Remote URLs or local `advisories/` files | Risk intelligence source for hook and installer. | -| Input | Installed skill metadata | Skill directories under install root | Matcher compares installed versions to advisory affected specs. | -| Input | Suppression config | `OPENCLAW_AUDIT_CONFIG` or default config paths | Selective suppression by check and skill name. | -| Output | Runtime alert messages | Hook event `messages[]` | Advisories and recommended user actions. | -| Output | Persistent state | `~/.openclaw/clawsec-suite-feed-state.json` | De-dup alerts, track scan windows. | -| Output | CLI gating exit codes | Installer process status | Ensures deliberate user confirmation on risk. | - -## Configuration -| Variable | Default | Module Effect | -| --- | --- | --- | -| `CLAWSEC_FEED_URL` | Hosted advisory URL | Chooses primary remote feed endpoint. | -| `CLAWSEC_LOCAL_FEED*` vars | Suite-local advisories directory | Configures local signed fallback artifacts. | -| `CLAWSEC_FEED_PUBLIC_KEY` | `advisories/feed-signing-public.pem` | Verification key path. | -| `CLAWSEC_ALLOW_UNSIGNED_FEED` | `0` | Enables temporary migration bypass mode. | -| `CLAWSEC_VERIFY_CHECKSUM_MANIFEST` | `1` | Enables checksum manifest verification layer. | -| `CLAWSEC_HOOK_INTERVAL_SECONDS` | `300` | Controls event-driven scan throttling. | - -## Example Snippets -```ts -// hook only handles selected events -function shouldHandleEvent(event: HookEvent): boolean { - const eventName = toEventName(event); - return eventName === 'agent:bootstrap' || eventName === 'command:new'; -} -``` - -```js -// guarded installer confirmation contract -if (matches.length > 0 && !args.confirmAdvisory) { - process.stdout.write('Re-run with --confirm-advisory to proceed.\n'); - process.exit(EXIT_CONFIRM_REQUIRED); // 42 -} -``` - -## Edge Cases -- Missing/malformed feed signatures force remote rejection and local fallback attempts. -- Ambiguous checksum manifest basename collisions are treated as errors. -- Unknown skill versions are treated conservatively in version matching logic. -- Suppression is disabled unless config includes the pipeline sentinel (`enabledFor`). -- Invalid environment path tokens are rejected to avoid accidental literal path usage. - -## Tests -| Test File | Focus | -| --- | --- | -| `skills/clawsec-suite/test/feed_verification.test.mjs` | Signature/checksum verification and fail-closed behavior. | -| `skills/clawsec-suite/test/guarded_install.test.mjs` | Confirmation gating and match semantics. | -| `skills/clawsec-suite/test/path_resolution.test.mjs` | Home/path expansion and invalid token handling. | -| `skills/clawsec-suite/test/advisory_suppression.test.mjs` | Suppression config parsing and matching. | -| `skills/clawsec-suite/test/skill_catalog_discovery.test.mjs` | Remote index and fallback merge behavior. | - -## Source References -- skills/clawsec-suite/skill.json -- skills/clawsec-suite/SKILL.md -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/handler.ts -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/matching.ts -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/state.ts -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/suppression.mjs -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/version.mjs -- skills/clawsec-suite/scripts/guarded_skill_install.mjs -- skills/clawsec-suite/scripts/discover_skill_catalog.mjs -- skills/clawsec-suite/test/feed_verification.test.mjs -- skills/clawsec-suite/test/guarded_install.test.mjs -- skills/clawsec-suite/test/path_resolution.test.mjs diff --git a/public/wiki/llms/modules/frontend-web.txt b/public/wiki/llms/modules/frontend-web.txt deleted file mode 100644 index ffacaa6..0000000 --- a/public/wiki/llms/modules/frontend-web.txt +++ /dev/null @@ -1,109 +0,0 @@ -# ClawSec Wiki · Module: Frontend Web App - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/modules/frontend-web -- LLM export: https://clawsec.prompt.security/wiki/llms/modules/frontend-web.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/frontend-web.md - -## Markdown - -# Module: Frontend Web App - -## Responsibilities -- Render the ClawSec website for home, skills catalog/detail, and advisory feed/detail experiences. -- Provide resilient JSON fetch behavior that handles SPA HTML fallback cases. -- Display install commands, checksums, and advisory metadata in a browser-focused UX. - -## Key Files -- `index.tsx`: React bootstrap and root mount. -- `App.tsx`: Router map and page entry wiring. -- `pages/Home.tsx`: Landing page, install card, animated platform/file labels. -- `pages/SkillsCatalog.tsx`: Catalog fetch/filter state machine and empty-state handling. -- `pages/SkillDetail.tsx`: Loads `skill.json`, checksums, README/SKILL docs with markdown renderer. -- `pages/FeedSetup.tsx`: Advisory listing UI with pagination. -- `pages/AdvisoryDetail.tsx`: Advisory deep-dive view and source links. -- `components/Layout.tsx` + `components/Header.tsx`: Shared shell and nav behavior. - -## Public Interfaces -- Browser routes: - - `/` - - `/skills` - - `/skills/:skillId` - - `/feed` - - `/feed/:advisoryId` -- Static fetch targets: - - `/skills/index.json` - - `/skills//skill.json` - - `/skills//checksums.json` - - `/advisories/feed.json` -- Display contracts: - - `SkillMetadata`, `SkillJson`, `SkillChecksums`, `AdvisoryFeed`, `Advisory` from `types.ts`. - -## Inputs and Outputs -Inputs/outputs are summarized in the table below. - -| Type | Name | Location | Description | -| --- | --- | --- | --- | -| Input | Skills index JSON | `/skills/index.json` | List of published skills and metadata. | -| Input | Skill payload files | `/skills//skill.json`, markdown docs, `checksums.json` | Detail-page content and integrity table. | -| Input | Advisory feed JSON | `/advisories/feed.json` or remote URL fallback | Advisory list/detail content. | -| Output | Route-specific UI states | Browser view state | Loading, empty, error, and populated experiences. | -| Output | Copy-to-clipboard commands | Clipboard API | Install and checksum snippets copied for users. | - -## Configuration -- Build/runtime config comes from: - - `vite.config.ts` (port, host, path alias) - - `index.html` Tailwind config + custom fonts/colors - - `constants.ts` (`ADVISORY_FEED_URL`, `LOCAL_FEED_PATH`) -- Runtime behavior assumptions: - - JSON responses may be empty or HTML fallback and must be validated. - - Advisory list pagination uses `ITEMS_PER_PAGE = 9`. - -## Example Snippets -```tsx -// Catalog fetch logic guards against HTML fallback responses -const contentType = response.headers.get('content-type') ?? ''; -const raw = await response.text(); -if (!raw.trim() || contentType.includes('text/html') || isProbablyHtmlDocument(raw)) { - setSkills([]); - setFilteredSkills([]); - return; -} -``` - -```tsx -// Route map defined in App.tsx -} /> -} /> -``` - -## Edge Cases -- Missing `skills/index.json` returns empty catalog instead of hard failure. -- Some environments return `index.html` for missing JSON paths with status `200`; code defends against this. -- Skill detail tolerates missing/malformed checksums and missing markdown docs. -- Advisory detail handles absent optional fields (`cvss_score`, `reporter`, `references`). - -## Tests -| Test Type | Location | Notes | -| --- | --- | --- | -| Type/lint/build checks | `scripts/prepare-to-push.sh` + CI | Frontend confidence comes from static checks and build success. | -| App-wide CI gates | `.github/workflows/ci.yml` | Multi-OS TypeScript/ESLint/build checks. | -| Manual smoke checks | `npm run dev` | Validate route rendering and fetch paths during development. | - -## Source References -- index.tsx -- App.tsx -- pages/Home.tsx -- pages/SkillsCatalog.tsx -- pages/SkillDetail.tsx -- pages/FeedSetup.tsx -- pages/AdvisoryDetail.tsx -- pages/Checksums.tsx -- components/Layout.tsx -- components/Header.tsx -- constants.ts -- types.ts -- vite.config.ts -- index.html diff --git a/public/wiki/llms/modules/local-tooling.txt b/public/wiki/llms/modules/local-tooling.txt deleted file mode 100644 index 54b6dff..0000000 --- a/public/wiki/llms/modules/local-tooling.txt +++ /dev/null @@ -1,95 +0,0 @@ -# ClawSec Wiki · Module: Local Validation and Packaging Tools - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/modules/local-tooling -- LLM export: https://clawsec.prompt.security/wiki/llms/modules/local-tooling.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/local-tooling.md - -## Markdown - -# Module: Local Validation and Packaging Tools - -## Responsibilities -- Validate skill directory metadata/schema and SBOM file presence before release. -- Generate per-skill checksums manifests for local testing or packaging. -- Provide local data bootstrap scripts that mirror CI behavior for advisories and skills. -- Offer release-link and signing-key consistency checks for maintainers. - -## Key Files -- `utils/validate_skill.py`: schema and file existence checks for a skill directory. -- `utils/package_skill.py`: checksum manifest generator with skill pre-validation. -- `scripts/populate-local-skills.sh`: generates local catalog and checksums under `public/skills/`. -- `scripts/populate-local-feed.sh`: pulls NVD data and updates feed copies. -- `scripts/validate-release-links.sh`: verifies docs reference releasable assets. -- `scripts/ci/verify_signing_key_consistency.sh`: verifies key fingerprints across docs/files. - -## Public Interfaces -| Tool | Interface | Primary Output | -| --- | --- | --- | -| `validate_skill.py` | `python utils/validate_skill.py ` | Exit code + validation summary with warnings/errors. | -| `package_skill.py` | `python utils/package_skill.py [out-dir]` | `checksums.json` artifact for skill files. | -| `populate-local-skills.sh` | shell CLI | `public/skills/index.json` and per-skill files/checksums. | -| `populate-local-feed.sh` | shell CLI flags `--days`, `--force` | Updated advisory feeds in repo/skill/public paths. | -| `validate-release-links.sh` | shell CLI optional skill arg | Release-link validation report. | - -## Inputs and Outputs -Inputs/outputs are summarized in the table below. - -| Type | Name | Location | Description | -| --- | --- | --- | --- | -| Input | Skill metadata and SBOM | `skills//skill.json` | Enumerates required files and release artifacts. | -| Input | Existing feed state | `advisories/feed.json` | Determines incremental NVD polling start date. | -| Input | Environment tools | `jq`, `curl`, `openssl`, Python runtime | Required execution dependencies. | -| Output | Validation diagnostics | stdout/stderr + exit code | Signals readiness for release/CI. | -| Output | Checksums manifests | `checksums.json` | Integrity data for skill artifacts. | -| Output | Local mirrors | `public/skills/*`, `public/advisories/feed.json` | Makes local web preview match CI outputs. | - -## Configuration -| Setting | Location | Purpose | -| --- | --- | --- | -| Ruff/Bandit policy | `pyproject.toml` | Python lint/security baseline. | -| CLI flags (`--days`, `--force`) | `populate-local-feed.sh` | Controls window and overwrite semantics. | -| `OPENCLAW_AUDIT_CONFIG` | suppression loaders in scripts | Chooses suppression config path. | -| `CLAWSEC_*` env vars | installer/hook scripts | Path and verification behavior tuning. | - -## Example Snippets -```bash -# validate and package a skill locally -python utils/validate_skill.py skills/clawsec-feed -python utils/package_skill.py skills/clawsec-feed ./dist -``` - -```bash -# refresh local UI data to mirror CI-generated artifacts -./scripts/populate-local-skills.sh -./scripts/populate-local-feed.sh --days 120 -``` - -## Edge Cases -- Validation allows warnings (for example missing optional files) while still returning success when required fields/files are present. -- NVD poll script handles macOS/Linux differences in `date` and `stat` utilities. -- Release-link validation can detect doc references to files missing from SBOM-derived release assets. -- Path expansion guards reject unexpanded home-token literals to avoid misdirected filesystem writes. - -## Tests -| Test/Check | Scope | -| --- | --- | -| `ruff check utils/` | Python style and correctness checks. | -| `bandit -r utils/ -ll` | Python security issue scan. | -| `scripts/prepare-to-push.sh` | Combined local gate across TS/Python/shell/security checks. | -| Skill-local tests | `skills/*/test/*.test.mjs` (targeted invocation) | - -## Source References -- utils/validate_skill.py -- utils/package_skill.py -- pyproject.toml -- scripts/populate-local-skills.sh -- scripts/populate-local-feed.sh -- scripts/prepare-to-push.sh -- scripts/validate-release-links.sh -- scripts/ci/verify_signing_key_consistency.sh -- skills/openclaw-audit-watchdog/scripts/load_suppression_config.mjs -- skills/clawsec-suite/scripts/guarded_skill_install.mjs -- skills/clawsec-suite/scripts/discover_skill_catalog.mjs diff --git a/public/wiki/llms/modules/nanoclaw-integration.txt b/public/wiki/llms/modules/nanoclaw-integration.txt deleted file mode 100644 index ebdfd5c..0000000 --- a/public/wiki/llms/modules/nanoclaw-integration.txt +++ /dev/null @@ -1,108 +0,0 @@ -# ClawSec Wiki · Module: NanoClaw Integration - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/modules/nanoclaw-integration -- LLM export: https://clawsec.prompt.security/wiki/llms/modules/nanoclaw-integration.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/modules/nanoclaw-integration.md - -## Markdown - -# Module: NanoClaw Integration - -## Responsibilities -- Port ClawSec advisory/signature logic into NanoClaw host+container architecture. -- Provide MCP tools that expose advisory checks, signature verification, and integrity monitoring. -- Maintain host-side cached advisory state with TLS/signature enforcement and IPC-triggered refresh. -- Protect critical NanoClaw files with baseline drift detection and hash-chained audit trails. - -## Key Files -- `skills/clawsec-nanoclaw/skill.json`: NanoClaw package contract and MCP tool registry. -- `skills/clawsec-nanoclaw/lib/signatures.ts`: secure fetch and Ed25519 verification primitives. -- `skills/clawsec-nanoclaw/lib/advisories.ts`: feed load and advisory matching helpers. -- `skills/clawsec-nanoclaw/host-services/advisory-cache.ts`: host cache manager. -- `skills/clawsec-nanoclaw/host-services/ipc-handlers.ts`: IPC request dispatch for advisory/signature tasks. -- `skills/clawsec-nanoclaw/host-services/skill-signature-handler.ts`: package signature verification service. -- `skills/clawsec-nanoclaw/guardian/integrity-monitor.ts`: baseline/diff/restore/audit engine. -- `skills/clawsec-nanoclaw/mcp-tools/*.ts`: container-side tool definitions. - -## Public Interfaces -| Interface | Context | Notes | -| --- | --- | --- | -| `clawsec_check_advisories` | MCP tool | Lists advisories affecting installed skills. | -| `clawsec_check_skill_safety` | MCP tool | Returns install recommendation for a specific skill. | -| `clawsec_verify_skill_package` | MCP tool | Verifies detached package signature through host IPC. | -| `clawsec_check_integrity` | MCP tool | Runs integrity check, optional auto-restore for critical targets. | -| IPC task `verify_skill_signature` | Host service | Returns structured verification response with error codes. | -| IPC task `refresh_advisory_cache` | Host service | Refreshes signed advisory cache on demand. | - -## Inputs and Outputs -Inputs/outputs are summarized in the table below. - -| Type | Name | Location | Description | -| --- | --- | --- | --- | -| Input | Signed advisory feed | `https://clawsec.prompt.security/advisories/feed.json(.sig)` | Threat intelligence source for cache refresh. | -| Input | Package + signature files | Host filesystem paths | Pre-install package authenticity checks. | -| Input | Integrity policy | `guardian/policy.json` | Per-path mode and priority controls. | -| Output | Advisory cache | `/workspace/project/data/clawsec-advisory-cache.json` | Host-managed verified advisory data. | -| Output | Verification results | `/workspace/ipc/clawsec_results/*.json` | IPC response payload for tool calls. | -| Output | Integrity state | `.../soul-guardian/` | Baselines, snapshots, patches, quarantine, audit logs. | - -## Configuration -| Setting | Default | Effect | -| --- | --- | --- | -| Feed URL | Hosted ClawSec advisory endpoint | Primary remote source for advisory cache manager. | -| Cache TTL | `5 minutes` | Controls staleness threshold before requiring refresh. | -| Fetch timeout | `10 seconds` | Limits host network wait time. | -| Allowed domains | `clawsec.prompt.security`, `prompt.security`, `raw.githubusercontent.com`, `github.com` | Restricts remote fetch targets. | -| Integrity policy modes | `restore`, `alert`, `ignore` | Controls automatic restoration and alert-only behavior. | - -## Example Snippets -```ts -// host-side signature verification dispatch -const result = await deps.signatureVerifier.verify({ - packagePath, - signaturePath, - publicKeyPem, - allowUnsigned: allowUnsigned || false, -}); -``` - -```ts -// integrity monitor drift handling -if (baseline.mode === 'restore' && autoRestore) { - // quarantine modified file, restore approved snapshot, append audit event -} -``` - -## Edge Cases -- Disallowed domains or non-HTTPS URLs are blocked by security policy wrappers. -- Missing signature files can be tolerated only when `allowUnsigned` is explicitly set. -- IPC result waits can timeout, causing conservative block recommendations. -- Integrity engine refuses symlink operations to reduce path-redirection attacks. -- Audit-chain validation can detect tampering or corruption in historical records. - -## Tests -| Test Scope | File/Path | Notes | -| --- | --- | --- | -| Type contracts | `skills/clawsec-nanoclaw/lib/types.ts` | Defines tool/IPC DB payload contracts. | -| Operational docs | `docs/SKILL_SIGNING.md`, `docs/INTEGRITY.md` | Describes verification/integrity usage patterns. | -| Cross-module behavior | Reuses suite verification patterns | Signature/checksum primitives ported from suite logic. | - -## Source References -- skills/clawsec-nanoclaw/skill.json -- skills/clawsec-nanoclaw/lib/types.ts -- skills/clawsec-nanoclaw/lib/signatures.ts -- skills/clawsec-nanoclaw/lib/advisories.ts -- skills/clawsec-nanoclaw/host-services/advisory-cache.ts -- skills/clawsec-nanoclaw/host-services/ipc-handlers.ts -- skills/clawsec-nanoclaw/host-services/skill-signature-handler.ts -- skills/clawsec-nanoclaw/host-services/integrity-handler.ts -- skills/clawsec-nanoclaw/guardian/integrity-monitor.ts -- skills/clawsec-nanoclaw/guardian/policy.json -- skills/clawsec-nanoclaw/mcp-tools/advisory-tools.ts -- skills/clawsec-nanoclaw/mcp-tools/signature-verification.ts -- skills/clawsec-nanoclaw/mcp-tools/integrity-tools.ts -- skills/clawsec-nanoclaw/docs/SKILL_SIGNING.md -- skills/clawsec-nanoclaw/docs/INTEGRITY.md diff --git a/public/wiki/llms/overview.txt b/public/wiki/llms/overview.txt deleted file mode 100644 index 1f7f256..0000000 --- a/public/wiki/llms/overview.txt +++ /dev/null @@ -1,116 +0,0 @@ -# ClawSec Wiki · Overview - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/overview -- LLM export: https://clawsec.prompt.security/wiki/llms/overview.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/overview.md - -## Markdown - -# Overview - -## Purpose -- ClawSec is a security-focused repository that combines a public web catalog with installable security skills for OpenClaw and NanoClaw environments. -- The codebase supports three delivery paths at once: static website publishing, signed advisory distribution, and per-skill GitHub release packaging. -- Primary users are agent operators, skill developers, and maintainers running CI-based security automation. - -![Prompt Security Logo](assets/overview_img_01_prompt-security-logo.png) -![ClawSec Mascot](assets/overview_img_02_clawsec-mascot.png) - -## Repo Layout -| Path | Role | Notes | -| --- | --- | --- | -| `pages/`, `components/`, `App.tsx`, `index.tsx` | Vite + React UI | Skill catalog, advisory feed, and detail pages. | -| `skills/` | Security skill packages | Each skill has `skill.json`, `SKILL.md`, optional scripts/tests/docs. | -| `advisories/` | Repository advisory channel | Signed `feed.json` + `feed.json.sig` and key material. | -| `scripts/` | Local automation | Populate feed/skills, pre-push checks, release helpers. | -| `.github/workflows/` | CI/CD pipelines | CI, releases, NVD polling, community advisory ingestion, pages deploy. | -| `utils/` | Python utilities | Skill validation and checksum packaging helpers. | -| `public/` | Published static assets | Site media, mirrored advisories, and generated skill artifacts. | -| `wiki/` | Documentation hub | Architecture, operations runbooks, compatibility, and verification guides. | - -## Entry Points -| Entry | Type | Purpose | -| --- | --- | --- | -| `index.tsx` | Frontend bootstrap | Mounts React app into `#root`. | -| `App.tsx` | Frontend router | Defines route map for home, skills, and feed pages. | -| `scripts/prepare-to-push.sh` | Dev workflow | Runs lint/type/build/security checks before push. | -| `scripts/populate-local-feed.sh` | Data bootstrap | Pulls CVEs from NVD and updates local advisory feeds. | -| `scripts/populate-local-skills.sh` | Data bootstrap | Builds `public/skills/index.json` and per-skill checksums. | -| `.github/workflows/skill-release.yml` | Release entry | Handles tag-based skill packaging/signing/release. | -| `.github/workflows/poll-nvd-cves.yml` | Scheduled feed updates | Polls NVD and updates advisories. | - -## Key Artifacts -| Artifact | Produced By | Consumed By | -| --- | --- | --- | -| `advisories/feed.json` | NVD poll + community advisory workflows | Web UI, clawsec-suite hook, installers. | -| `advisories/feed.json.sig` | Signing workflow steps | Signature verification in suite/nanoclaw tooling. | -| `public/skills/index.json` | Deploy workflow / local populate script | `pages/SkillsCatalog.tsx` and `pages/SkillDetail.tsx`. | -| `public/checksums.json` + `public/checksums.sig` | Deploy workflow | Client-side integrity verification flows. | -| `release-assets/checksums.json` | Skill release workflow | Release consumers verifying zip integrity. | -| `skills/*/skill.json` | Skill authors | Site catalog generation, validators, and release pipelines. | - -## Key Workflows -- Local web development: `npm install` then `npm run dev`. -- Local security data preview: run `./scripts/populate-local-skills.sh` and `./scripts/populate-local-feed.sh` before loading `/skills` and `/feed` pages. -- Pre-push quality gate: run `./scripts/prepare-to-push.sh` (optionally `--fix`). -- Skill lifecycle: edit `skills//`, validate with `python utils/validate_skill.py`, then tag `-vX.Y.Z` to trigger release workflow. -- Advisory lifecycle: scheduled NVD poll and issue-label-based community ingestion both merge into the same signed feed. - -## Example Snippets -```bash -# local UI + locally populated data -npm install -./scripts/populate-local-skills.sh -./scripts/populate-local-feed.sh --days 120 -npm run dev -``` - -```bash -# canonical TypeScript quality checks used by CI -npx eslint . --ext .ts,.tsx,.js,.jsx,.mjs --max-warnings 0 -npx tsc --noEmit -npm run build -``` - -## Where to Start -- Read `README.md` for product positioning and install paths. -- Open `App.tsx` and `pages/` to understand user-facing behavior. -- Open `skills/clawsec-suite/skill.json` to understand the suite contract and embedded components. -- Review `.github/workflows/ci.yml`, `.github/workflows/skill-release.yml`, and `.github/workflows/deploy-pages.yml` for production behavior. - -## How to Navigate -- UI behavior is centered in `pages/`; visual wrappers sit in `components/`. -- Skill-specific logic is isolated by folder under `skills/`; each folder includes its own scripts/tests/docs. -- Feed handling appears in three layers: repository feed files, workflow updates, and runtime consumers (`clawsec-suite`/`clawsec-nanoclaw`). -- Operational quality gates live in `scripts/` and workflow YAML files. -- For generation traces and update baselines, start from `wiki/GENERATION.md` and then branch into module pages. - -## Common Pitfalls -- Using literal home tokens (for example `\$HOME`) in config path env vars can trigger path validation failures. -- Fetching JSON from SPA routes can return HTML with status 200; pages guard for this and treat it as empty-state. -- Unsigned feed bypass mode (`CLAWSEC_ALLOW_UNSIGNED_FEED=1`) exists for migration compatibility and should not be used in steady state. -- Skill release automation expects version parity between `skill.json` and `SKILL.md` frontmatter. -- Some scripts are POSIX shell oriented; Windows users should prefer PowerShell equivalents or WSL. - -## Update Notes -- 2026-02-26: Updated repo layout to point operational documentation at `wiki/` instead of the removed root `docs/` directory. - -## Source References -- README.md -- package.json -- App.tsx -- index.tsx -- pages/Home.tsx -- pages/SkillsCatalog.tsx -- pages/SkillDetail.tsx -- pages/FeedSetup.tsx -- scripts/prepare-to-push.sh -- scripts/populate-local-feed.sh -- scripts/populate-local-skills.sh -- skills/clawsec-suite/skill.json -- .github/workflows/ci.yml -- .github/workflows/skill-release.yml -- .github/workflows/deploy-pages.yml diff --git a/public/wiki/llms/security.txt b/public/wiki/llms/security.txt deleted file mode 100644 index 0dbb297..0000000 --- a/public/wiki/llms/security.txt +++ /dev/null @@ -1,88 +0,0 @@ -# ClawSec Wiki · Security - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/security -- LLM export: https://clawsec.prompt.security/wiki/llms/security.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/security.md - -## Markdown - -# Security - -## Security Model Overview -- ClawSec secures both content distribution (signed artifacts) and runtime behavior (advisory gating, integrity monitoring). -- Trust anchors are pinned public keys committed in repo and verified against workflow-generated outputs. -- Runtime consumers default to verification-first behavior with explicit migration bypass flags. - -## Cryptographic Controls -| Control | Mechanism | Location | -| --- | --- | --- | -| Feed authenticity | Ed25519 detached signatures (`feed.json.sig`) | Advisory workflows + consumer verification libs. | -| Artifact integrity | SHA-256 checksum manifests (`checksums.json`) | Skill release and pages deploy workflows. | -| Key consistency | Fingerprint comparison across docs + canonical PEMs | `scripts/ci/verify_signing_key_consistency.sh`. | -| Signature verification action | Composite sign+verify action in CI | `.github/actions/sign-and-verify/action.yml`. | - -## Runtime Enforcement Controls -| Control | Component | Effect | -| --- | --- | --- | -| Advisory hook gating | `clawsec-advisory-guardian` | Alerts and cautious guidance based on matched advisories. | -| Double-confirmation installer | `guarded_skill_install.mjs` | Exit `42` until explicit confirmation for matched advisories. | -| Reputation extension | `clawsec-clawhub-checker` | Additional risk scoring before install. | -| NanoClaw signature gate | `skill-signature-handler.ts` + MCP tool | Blocks tampered/unsigned package installs by policy. | -| Integrity baseline monitor | `soul-guardian` + NanoClaw integrity monitor | Drift detection, quarantine, restore, auditable history. | - -## Supply-Chain and CI Controls -- CI runs Trivy, npm audit, gitleaks, CodeQL, and Scorecard workflows. -- Release workflows validate SBOM file existence before packaging. -- Deploy workflow verifies generated signing key fingerprint against canonical key material. -- Release docs include manual verification commands for downstream consumers. - -## Incident and Rotation Playbooks -- `wiki/security-signing-runbook.md` defines key generation, custody, rotation, and incident phases. -- `wiki/migration-signed-feed.md` defines staged enforcement and rollback levels. -- Rollback paths prioritize preserving signed publishing where possible and time-boxing any bypass. - -## Example Snippets -```bash -# verify canonical public key fingerprint -openssl pkey -pubin -in clawsec-signing-public.pem -outform DER | shasum -a 256 -``` - -```bash -# run repo key-consistency guardrail used in CI -./scripts/ci/verify_signing_key_consistency.sh -``` - -## Known Security Tradeoffs -- Unsigned compatibility mode can reduce assurance and should be disabled once migration completes. -- Some deploy paths tolerate unsigned legacy checksum assets for backward compatibility. -- Reputation checks rely on external tooling output and may include heuristic false positives/negatives. -- Local scripts inherit environment trust; compromised local shells can still subvert operator workflows. - -## Hardening Opportunities -- Remove unsigned compatibility flags after migration stabilization. -- Expand deterministic checksum/signature verification for all mirrored release files. -- Add explicit tests for workflow-level signature failure scenarios. -- Increase runtime telemetry for advisory fetch/verification failures to simplify incident triage. - -## Update Notes -- 2026-02-26: Repointed signing and migration references from root `docs/` files to dedicated `wiki/` operations pages. - -## Source References -- SECURITY.md -- wiki/security-signing-runbook.md -- wiki/migration-signed-feed.md -- scripts/ci/verify_signing_key_consistency.sh -- .github/actions/sign-and-verify/action.yml -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/community-advisory.yml -- .github/workflows/skill-release.yml -- .github/workflows/deploy-pages.yml -- skills/clawsec-suite/hooks/clawsec-advisory-guardian/lib/feed.mjs -- skills/clawsec-suite/scripts/guarded_skill_install.mjs -- skills/clawsec-clawhub-checker/scripts/enhanced_guarded_install.mjs -- skills/soul-guardian/scripts/soul_guardian.py -- skills/clawsec-nanoclaw/host-services/skill-signature-handler.ts -- skills/clawsec-nanoclaw/guardian/integrity-monitor.ts diff --git a/public/wiki/llms/testing.txt b/public/wiki/llms/testing.txt deleted file mode 100644 index 6f600e1..0000000 --- a/public/wiki/llms/testing.txt +++ /dev/null @@ -1,87 +0,0 @@ -# ClawSec Wiki · Testing - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/testing -- LLM export: https://clawsec.prompt.security/wiki/llms/testing.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/testing.md - -## Markdown - -# Testing - -## Testing Strategy -- The repository uses layered verification rather than a single root `npm test` command. -- Core confidence comes from lint/type/build gates plus skill-local Node test suites. -- Python and shell tooling are validated through dedicated lint/security checks. -- Workflow pipelines run the same command classes used in local pre-push automation. - -## Verification Layers -| Layer | Commands | Scope | -| --- | --- | --- | -| Frontend/static checks | ESLint + `tsc --noEmit` + `npm run build` | TS/TSX correctness and build viability. | -| Skill unit tests | `node skills//test/*.test.mjs` | Signature, matching, suppression, installer contracts. | -| Python quality | `ruff check utils/`, `bandit -r utils/ -ll` | Utility correctness and security patterns. | -| Shell/script quality | ShellCheck + manual script smoke runs | Script hygiene and command robustness. | -| CI security scans | Trivy, npm audit, gitleaks, CodeQL, Scorecard | Dependency, config, and supply-chain security posture. | - -## Skill Test Matrix -| Skill | Test Files | Primary Focus | -| --- | --- | --- | -| `clawsec-suite` | `feed_verification`, `guarded_install`, `path_resolution`, fuzz tests | Signature checks, advisory gating, path safety, matching robustness. | -| `openclaw-audit-watchdog` | suppression config and render tests | Config parsing, suppression behavior, report formatting. | -| `clawsec-clawhub-checker` | `reputation_check.test.mjs` | Input validation and reputation gating behavior. | - -## CI Workflow Coverage -| Workflow | Trigger | Key Assertions | -| --- | --- | --- | -| `ci.yml` | PR/push to `main` | Lint/type/build, Python checks, security scans, skill tests. | -| `codeql.yml` | PR/push/schedule | JS/TS static security analysis. | -| `scorecard.yml` | schedule/push | Supply-chain posture reporting and SARIF upload. | -| `skill-release.yml` | tags + PRs | Version parity and release artifact verification. | - -## Local Testing Commands -```bash -# baseline frontend + config checks -npx eslint . --ext .ts,.tsx,.js,.jsx,.mjs --max-warnings 0 -npx tsc --noEmit -npm run build -``` - -```bash -# representative skill tests -node skills/clawsec-suite/test/feed_verification.test.mjs -node skills/clawsec-suite/test/guarded_install.test.mjs -node skills/openclaw-audit-watchdog/test/suppression_config.test.mjs -``` - -## Failure Patterns to Watch -- Signature/test fixtures can fail from key/payload mismatch when expected files are regenerated inconsistently. -- Path-resolution tests intentionally fail on escaped home tokens; this behavior is expected and security-relevant. -- Local scripts relying on `openclaw` or `clawhub` binaries may fail in environments where those CLIs are absent. -- Deploy/release logic can pass locally while failing in CI if signing secrets or workflow permissions differ. - -## Suggested Test Order -1. Run `./scripts/prepare-to-push.sh` for a full local gate. -2. Run directly impacted skill-local tests. -3. For feed/signing changes, run suite verification tests first (`feed_verification`, `guarded_install`). -4. For workflow or release changes, also run `scripts/validate-release-links.sh` and key consistency script. - -## Update Notes -- 2026-02-26: Updated source references to the migrated `wiki/platform-verification.md` checklist. - -## Source References -- AGENTS.md -- scripts/prepare-to-push.sh -- scripts/validate-release-links.sh -- .github/workflows/ci.yml -- .github/workflows/codeql.yml -- .github/workflows/scorecard.yml -- .github/workflows/skill-release.yml -- skills/clawsec-suite/test/feed_verification.test.mjs -- skills/clawsec-suite/test/guarded_install.test.mjs -- skills/clawsec-suite/test/path_resolution.test.mjs -- skills/openclaw-audit-watchdog/test/suppression_config.test.mjs -- skills/clawsec-clawhub-checker/test/reputation_check.test.mjs -- wiki/platform-verification.md diff --git a/public/wiki/llms/workflow.txt b/public/wiki/llms/workflow.txt deleted file mode 100644 index 6b79c5f..0000000 --- a/public/wiki/llms/workflow.txt +++ /dev/null @@ -1,85 +0,0 @@ -# ClawSec Wiki · Workflow - -LLM-ready export for a single wiki page. - -## Canonical -- Wiki page: https://clawsec.prompt.security/#/wiki/workflow -- LLM export: https://clawsec.prompt.security/wiki/llms/workflow.txt -- Source markdown: https://raw.githubusercontent.com/prompt-security/clawsec/main/wiki/workflow.md - -## Markdown - -# Workflow - -## End-to-End Lifecycle -- Development starts with local coding + local data population for realistic UI preview. -- PR CI validates quality/security and skill test suites. -- Tag-driven release workflow packages and signs skill artifacts. -- Pages deploy workflow mirrors release/advisory artifacts and publishes the static site. -- Scheduled workflows continuously enrich advisory feed and supply-chain visibility. - -## Primary Workflow Map -| Workflow | Trigger | Main Steps | -| --- | --- | --- | -| CI | PR/push to `main` | Lint, typecheck, build, Python checks, security scans, skill tests. | -| Poll NVD CVEs | Daily cron + manual dispatch | Fetch CVEs, transform/dedupe, update feed, sign artifacts, PR changes. | -| Process Community Advisory | Issue label `advisory-approved` | Parse issue form, create advisory, sign feed, open PR, comment issue. | -| Skill Release | Tag `-v*` | Validate versions, package SBOM files, sign checksums, publish release. | -| Deploy Pages | Successful CI/Release or manual dispatch | Discover releases, mirror assets, sign public advisories/checksums, deploy site. | - -## Local Operator Workflow -| Step | Command | Outcome | -| --- | --- | --- | -| Install deps | `npm install` | Ready local environment. | -| Populate local catalog | `./scripts/populate-local-skills.sh` | `public/skills/index.json` and file checksums. | -| Populate local feed | `./scripts/populate-local-feed.sh --days 120` | Updated local advisory feed copy. | -| Run local gate | `./scripts/prepare-to-push.sh` | CI-like pass/fail signal. | -| Start dev UI | `npm run dev` | Browser preview at local Vite endpoint. | - -## Release Workflow Details -- Version bump and docs parity are enforced for PR/tag paths. -- Skill packaging includes SBOM-declared files and integrity manifests. -- `checksums.json` is signed and immediately verified in workflow execution. -- Optional publish-to-ClawHub job runs after successful GitHub release when configured. -- Older releases within same major line can be superseded/deleted by automation. - -## Advisory Workflow Details -- NVD workflow determines incremental window from previous feed `updated` timestamp. -- Transform phase maps CVE metrics to severity/type and normalizes affected targets. -- Community advisory workflow creates deterministic IDs (`CLAW-YYYY-NNNN`) from issue metadata. -- Both advisory workflows update skill feed copies and signature companions. - -## Example Snippets -```bash -# manual release prep for a skill -./scripts/release-skill.sh clawsec-feed 0.0.5 -# then push tag if running in release branch mode -``` - -```yaml -# pages deploy depends on successful upstream workflow run -on: - workflow_run: - workflows: ["CI", "Skill Release"] - types: [completed] -``` - -## Operational Risks -- Workflow permissions and secret scope misconfiguration can block signing/publishing. -- NVD/API transient failures may delay advisory freshness. -- Invalid tag naming or version mismatches halt release automation. -- Local scripts and CI can diverge if operator machine lacks expected binaries (`jq`, `openssl`, `clawhub`). - -## Source References -- scripts/release-skill.sh -- scripts/prepare-to-push.sh -- scripts/populate-local-feed.sh -- scripts/populate-local-skills.sh -- .github/workflows/ci.yml -- .github/workflows/poll-nvd-cves.yml -- .github/workflows/community-advisory.yml -- .github/workflows/skill-release.yml -- .github/workflows/deploy-pages.yml -- .github/workflows/codeql.yml -- .github/workflows/scorecard.yml -- .github/actions/sign-and-verify/action.yml From a717904f85d7fba65c493e5b37e107e2410c3a58 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:34:10 +0200 Subject: [PATCH 12/16] fix(wiki): align llms urls with per-page endpoint pattern --- pages/WikiBrowser.tsx | 24 ++++++++++++++---------- scripts/generate-wiki-llms.mjs | 25 +++++++++++++++---------- scripts/populate-local-wiki.sh | 7 +++---- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index b1df081..f239340 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -223,7 +223,9 @@ export const WikiBrowser: React.FC = () => { } const activeSlug = selectedDoc.slug.toLowerCase(); - const pageLlmsPath = `/wiki/llms/${activeSlug}.txt`; + const pageLlmsPath = + activeSlug === 'index' ? '/wiki/llms.txt' : `/wiki/${activeSlug}/llms.txt`; + const showWikiLlmsIndexLink = activeSlug !== 'index'; const resolveWikiRouteFromHref = (href: string): string | null => { if (!href || isExternalHref(href) || href.startsWith('mailto:') || href.startsWith('tel:')) { @@ -317,15 +319,17 @@ export const WikiBrowser: React.FC = () => { Page llms.txt - - - Wiki llms.txt Index - + {showWikiLlmsIndexLink && ( + + + Wiki llms.txt Index + + )} { return match?.[1]?.trim() || fallbackTitleFromPath(filePath); }; +const isIndexSlug = (slug) => slug.toLowerCase() === 'index'; + const toWebsiteRoute = (slug) => (slug === 'index' ? '/wiki' : `/wiki/${slug}`); -const toLlmsPageUrl = (slug) => `${WEBSITE_BASE}/wiki/llms/${slug}.txt`; +const toLlmsPagePath = (slug) => + isIndexSlug(slug) ? '/wiki/llms.txt' : `/wiki/${slug}/llms.txt`; + +const toLlmsPageUrl = (slug) => `${WEBSITE_BASE}${toLlmsPagePath(slug)}`; const walkMarkdownFiles = async (dir) => { const entries = await fs.readdir(dir, { withFileTypes: true }); @@ -96,7 +100,7 @@ const buildIndexBody = (docs) => { const lines = [ '# ClawSec Wiki llms.txt', '', - 'LLM-readable index for wiki pages. A generated `.txt` export exists for each page.', + 'LLM-readable index for wiki pages. Each page has a corresponding `/wiki//llms.txt` export.', '', `Website wiki root: ${WEBSITE_BASE}/#/wiki`, `GitHub wiki mirror: ${REPO_BASE}/wiki`, @@ -115,7 +119,7 @@ const buildIndexBody = (docs) => { return `${lines.join('\n')}\n`; }; -const main = async () => { + const main = async () => { try { const wikiStat = await fs.stat(WIKI_ROOT).catch(() => null); if (!wikiStat || !wikiStat.isDirectory()) { @@ -135,21 +139,22 @@ const main = async () => { } docs.sort(sortDocs); + const pageDocs = docs.filter((doc) => !isIndexSlug(doc.slug)); + // `public/wiki/` is fully generated; wipe stale output before regenerating. + await fs.rm(PUBLIC_WIKI_ROOT, { recursive: true, force: true }); await fs.mkdir(PUBLIC_WIKI_ROOT, { recursive: true }); - await fs.rm(LLM_PAGES_ROOT, { recursive: true, force: true }); - await fs.mkdir(LLM_PAGES_ROOT, { recursive: true }); - for (const doc of docs) { - const outputFile = path.join(LLM_PAGES_ROOT, `${doc.slug}.txt`); + for (const doc of pageDocs) { + const outputFile = path.join(PUBLIC_WIKI_ROOT, doc.slug, 'llms.txt'); await fs.mkdir(path.dirname(outputFile), { recursive: true }); await fs.writeFile(outputFile, buildPageBody(doc), 'utf8'); } - await fs.writeFile(LLM_INDEX_FILE, buildIndexBody(docs), 'utf8'); + await fs.writeFile(LLM_INDEX_FILE, buildIndexBody(pageDocs), 'utf8'); // Keep logs short for CI readability. - console.log(`Generated ${docs.length} wiki llms page exports and /wiki/llms.txt`); + console.log(`Generated ${pageDocs.length} page llms.txt exports and /wiki/llms.txt`); } catch (error) { const message = error instanceof Error ? error.message : String(error); console.error(`Failed to generate wiki llms exports: ${message}`); diff --git a/scripts/populate-local-wiki.sh b/scripts/populate-local-wiki.sh index d6fd0ba..be02b72 100755 --- a/scripts/populate-local-wiki.sh +++ b/scripts/populate-local-wiki.sh @@ -11,7 +11,6 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" WIKI_DIR="$PROJECT_ROOT/wiki" PUBLIC_WIKI_DIR="$PROJECT_ROOT/public/wiki" -LLMS_DIR="$PUBLIC_WIKI_DIR/llms" if [ ! -d "$WIKI_DIR" ]; then echo "Error: wiki directory not found at $WIKI_DIR" @@ -24,9 +23,9 @@ echo "Project root: $PROJECT_ROOT" node "$PROJECT_ROOT/scripts/generate-wiki-llms.mjs" PAGE_COUNT=0 -if [ -d "$LLMS_DIR" ]; then - PAGE_COUNT=$(find "$LLMS_DIR" -type f -name '*.txt' | wc -l | tr -d ' ') +if [ -d "$PUBLIC_WIKI_DIR" ]; then + PAGE_COUNT=$(find "$PUBLIC_WIKI_DIR" -type f -path '*/llms.txt' ! -path "$PUBLIC_WIKI_DIR/llms.txt" | wc -l | tr -d ' ') fi echo "Wiki llms index: $PUBLIC_WIKI_DIR/llms.txt" -echo "Wiki llms pages: $PAGE_COUNT files under $LLMS_DIR" +echo "Wiki llms pages: $PAGE_COUNT files under $PUBLIC_WIKI_DIR//llms.txt" From 5434085ab6a35fabeea53a8dfb40bc77a694c1b3 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:36:54 +0200 Subject: [PATCH 13/16] fix(wiki): derive llms index from wiki index page --- scripts/generate-wiki-llms.mjs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/generate-wiki-llms.mjs b/scripts/generate-wiki-llms.mjs index 5f54eac..1aed7db 100644 --- a/scripts/generate-wiki-llms.mjs +++ b/scripts/generate-wiki-llms.mjs @@ -96,11 +96,11 @@ const buildPageBody = (doc) => { ].join('\n'); }; -const buildIndexBody = (docs) => { +const buildFallbackIndexBody = (docs) => { const lines = [ '# ClawSec Wiki llms.txt', '', - 'LLM-readable index for wiki pages. Each page has a corresponding `/wiki//llms.txt` export.', + 'LLM-readable index for wiki pages.', '', `Website wiki root: ${WEBSITE_BASE}/#/wiki`, `GitHub wiki mirror: ${REPO_BASE}/wiki`, @@ -140,6 +140,7 @@ const buildIndexBody = (docs) => { docs.sort(sortDocs); const pageDocs = docs.filter((doc) => !isIndexSlug(doc.slug)); + const indexDoc = docs.find((doc) => isIndexSlug(doc.slug)); // `public/wiki/` is fully generated; wipe stale output before regenerating. await fs.rm(PUBLIC_WIKI_ROOT, { recursive: true, force: true }); @@ -151,7 +152,8 @@ const buildIndexBody = (docs) => { await fs.writeFile(outputFile, buildPageBody(doc), 'utf8'); } - await fs.writeFile(LLM_INDEX_FILE, buildIndexBody(pageDocs), 'utf8'); + const indexBody = indexDoc ? buildPageBody(indexDoc) : buildFallbackIndexBody(pageDocs); + await fs.writeFile(LLM_INDEX_FILE, indexBody, 'utf8'); // Keep logs short for CI readability. console.log(`Generated ${pageDocs.length} page llms.txt exports and /wiki/llms.txt`); From eb97e68e98c6244fb7ae10cccd10cf96783f5a27 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 09:55:18 +0200 Subject: [PATCH 14/16] refactor(markdown): share frontmatter and title helpers --- pages/SkillDetail.tsx | 7 +----- pages/WikiBrowser.tsx | 33 ++++++---------------------- scripts/generate-wiki-llms.mjs | 31 +++++--------------------- utils/markdownHelpers.mjs | 40 ++++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 57 deletions(-) create mode 100644 utils/markdownHelpers.mjs diff --git a/pages/SkillDetail.tsx b/pages/SkillDetail.tsx index b7a1c00..18b4fcd 100644 --- a/pages/SkillDetail.tsx +++ b/pages/SkillDetail.tsx @@ -6,12 +6,7 @@ import remarkGfm from 'remark-gfm'; import { Footer } from '../components/Footer'; import type { SkillJson, SkillChecksums } from '../types'; import { defaultMarkdownComponents } from '../utils/markdownComponents'; - -// Strip YAML frontmatter from markdown content -const stripFrontmatter = (content: string): string => { - const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/; - return content.replace(frontmatterRegex, ''); -}; +import { stripFrontmatter } from '../utils/markdownHelpers.mjs'; const isProbablyHtmlDocument = (text: string): boolean => { const start = text.trimStart().slice(0, 200).toLowerCase(); diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index f239340..6a10411 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -6,6 +6,11 @@ import type { Components } from 'react-markdown'; import remarkGfm from 'remark-gfm'; import { Footer } from '../components/Footer'; import { defaultMarkdownComponents } from '../utils/markdownComponents'; +import { + extractTitleFromMarkdown, + fallbackTitleFromPath, + stripFrontmatter, +} from '../utils/markdownHelpers.mjs'; interface WikiDoc { filePath: string; @@ -14,11 +19,6 @@ interface WikiDoc { content: string; } -const stripFrontmatter = (content: string): string => { - const frontmatterRegex = /^---\s*\n[\s\S]*?\n---\s*\n/; - return content.replace(frontmatterRegex, ''); -}; - const normalizePath = (path: string): string => { const clean = path.replace(/\\/g, '/'); const parts: string[] = []; @@ -55,25 +55,6 @@ const splitHash = (href: string): { path: string; hash: string } => { const toWikiRelativePath = (globPath: string): string => globPath.replace(/^\.\.\/wiki\//, '').replace(/\\/g, '/'); -const fallbackTitleFromFilePath = (filePath: string): string => { - const filename = filePath.split('/').pop() ?? filePath; - const stem = filename.replace(/\.md$/i, ''); - return stem - .split(/[-_]/) - .filter(Boolean) - .map((part) => { - if (part.toUpperCase() === part && part.length > 1) return part; - return part.charAt(0).toUpperCase() + part.slice(1); - }) - .join(' '); -}; - -const extractTitle = (markdownContent: string, filePath: string): string => { - const cleaned = stripFrontmatter(markdownContent).trim(); - const match = cleaned.match(/^#\s+(.+)$/m); - return match?.[1]?.trim() || fallbackTitleFromFilePath(filePath); -}; - const isExternalHref = (href: string): boolean => /^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(href) || href.startsWith('//'); @@ -119,7 +100,7 @@ const wikiDocs: WikiDoc[] = Object.entries(markdownModules) return { filePath, slug: filePath.replace(/\.md$/i, ''), - title: extractTitle(content, filePath), + title: extractTitleFromMarkdown(content, filePath), content: stripFrontmatter(content).trim(), }; }) @@ -160,7 +141,7 @@ const toGroupName = (filePath: string): string => { if (!filePath.includes('/')) return 'Core'; if (filePath.startsWith('modules/')) return 'Modules'; const [firstSegment] = filePath.split('/'); - return fallbackTitleFromFilePath(firstSegment); + return fallbackTitleFromPath(firstSegment); }; export const WikiBrowser: React.FC = () => { diff --git a/scripts/generate-wiki-llms.mjs b/scripts/generate-wiki-llms.mjs index 1aed7db..7dcf9c5 100644 --- a/scripts/generate-wiki-llms.mjs +++ b/scripts/generate-wiki-llms.mjs @@ -3,6 +3,10 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { + extractTitleFromMarkdown, + stripFrontmatter, +} from '../utils/markdownHelpers.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const REPO_ROOT = path.resolve(__dirname, '..'); @@ -14,31 +18,8 @@ const WEBSITE_BASE = 'https://clawsec.prompt.security'; const REPO_BASE = 'https://github.com/prompt-security/clawsec'; const RAW_BASE = 'https://raw.githubusercontent.com/prompt-security/clawsec/main'; -const FRONTMATTER_REGEX = /^---\s*\n[\s\S]*?\n---\s*\n/; - const toPosix = (inputPath) => inputPath.split(path.sep).join('/'); -const fallbackTitleFromPath = (filePath) => { - const filename = filePath.split('/').pop() ?? filePath; - const stem = filename.replace(/\.md$/i, ''); - return stem - .split(/[-_]/) - .filter(Boolean) - .map((part) => { - if (part.toUpperCase() === part && part.length > 1) return part; - return part.charAt(0).toUpperCase() + part.slice(1); - }) - .join(' '); -}; - -const stripFrontmatter = (content) => content.replace(FRONTMATTER_REGEX, ''); - -const extractTitle = (content, filePath) => { - const cleaned = stripFrontmatter(content).trim(); - const match = cleaned.match(/^#\s+(.+)$/m); - return match?.[1]?.trim() || fallbackTitleFromPath(filePath); -}; - const isIndexSlug = (slug) => slug.toLowerCase() === 'index'; const toWebsiteRoute = (slug) => (slug === 'index' ? '/wiki' : `/wiki/${slug}`); @@ -119,7 +100,7 @@ const buildFallbackIndexBody = (docs) => { return `${lines.join('\n')}\n`; }; - const main = async () => { +const main = async () => { try { const wikiStat = await fs.stat(WIKI_ROOT).catch(() => null); if (!wikiStat || !wikiStat.isDirectory()) { @@ -134,7 +115,7 @@ const buildFallbackIndexBody = (docs) => { const slug = relativePath.replace(/\.md$/i, '').toLowerCase(); const rawContent = await fs.readFile(fullPath, 'utf8'); const content = stripFrontmatter(rawContent); - const title = extractTitle(rawContent, relativePath); + const title = extractTitleFromMarkdown(rawContent, relativePath); docs.push({ relativePath, slug, title, content }); } diff --git a/utils/markdownHelpers.mjs b/utils/markdownHelpers.mjs new file mode 100644 index 0000000..ef9c785 --- /dev/null +++ b/utils/markdownHelpers.mjs @@ -0,0 +1,40 @@ +const FRONTMATTER_REGEX = /^---\s*\n[\s\S]*?\n---\s*\n/; + +/** + * Remove a leading YAML frontmatter block from markdown content. + * @param {string} content + * @returns {string} + */ +export const stripFrontmatter = (content) => + String(content ?? '').replace(FRONTMATTER_REGEX, ''); + +/** + * Build a readable fallback title from a markdown file path. + * @param {string} filePath + * @returns {string} + */ +export const fallbackTitleFromPath = (filePath) => { + const normalized = String(filePath ?? ''); + const filename = normalized.split('/').pop() ?? normalized; + const stem = filename.replace(/\.md$/i, ''); + return stem + .split(/[-_]/) + .filter(Boolean) + .map((part) => { + if (part.toUpperCase() === part && part.length > 1) return part; + return part.charAt(0).toUpperCase() + part.slice(1); + }) + .join(' '); +}; + +/** + * Extract the first H1 title from markdown; fall back to path-derived title. + * @param {string} content + * @param {string} filePath + * @returns {string} + */ +export const extractTitleFromMarkdown = (content, filePath) => { + const cleaned = stripFrontmatter(content).trim(); + const match = cleaned.match(/^#\s+(.+)$/m); + return match?.[1]?.trim() || fallbackTitleFromPath(filePath); +}; From 1e787c49a470a00247c0e4dba11da41ef00dc129 Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 10:22:25 +0200 Subject: [PATCH 15/16] refactor(wiki): share route and llms path mapping --- pages/WikiBrowser.tsx | 13 ++++++------ scripts/generate-wiki-llms.mjs | 23 +++++++++----------- utils/wikiPathHelpers.mjs | 38 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 utils/wikiPathHelpers.mjs diff --git a/pages/WikiBrowser.tsx b/pages/WikiBrowser.tsx index 6a10411..c410ab1 100644 --- a/pages/WikiBrowser.tsx +++ b/pages/WikiBrowser.tsx @@ -11,6 +11,11 @@ import { fallbackTitleFromPath, stripFrontmatter, } from '../utils/markdownHelpers.mjs'; +import { + isWikiIndexSlug, + toWikiLlmsPath, + toWikiRoute, +} from '../utils/wikiPathHelpers.mjs'; interface WikiDoc { filePath: string; @@ -134,9 +139,6 @@ const wikiAssetByPath = new Map( const defaultDoc = wikiDocBySlug.get('index') ?? wikiDocs[0] ?? null; -const toWikiRoute = (slug: string): string => - slug.toLowerCase() === 'index' ? '/wiki' : `/wiki/${slug}`; - const toGroupName = (filePath: string): string => { if (!filePath.includes('/')) return 'Core'; if (filePath.startsWith('modules/')) return 'Modules'; @@ -204,9 +206,8 @@ export const WikiBrowser: React.FC = () => { } const activeSlug = selectedDoc.slug.toLowerCase(); - const pageLlmsPath = - activeSlug === 'index' ? '/wiki/llms.txt' : `/wiki/${activeSlug}/llms.txt`; - const showWikiLlmsIndexLink = activeSlug !== 'index'; + const pageLlmsPath = toWikiLlmsPath(activeSlug); + const showWikiLlmsIndexLink = !isWikiIndexSlug(activeSlug); const resolveWikiRouteFromHref = (href: string): string | null => { if (!href || isExternalHref(href) || href.startsWith('mailto:') || href.startsWith('tel:')) { diff --git a/scripts/generate-wiki-llms.mjs b/scripts/generate-wiki-llms.mjs index 7dcf9c5..913c4f6 100644 --- a/scripts/generate-wiki-llms.mjs +++ b/scripts/generate-wiki-llms.mjs @@ -7,6 +7,11 @@ import { extractTitleFromMarkdown, stripFrontmatter, } from '../utils/markdownHelpers.mjs'; +import { + isWikiIndexSlug, + toWikiLlmsPath, + toWikiRoute, +} from '../utils/wikiPathHelpers.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const REPO_ROOT = path.resolve(__dirname, '..'); @@ -19,15 +24,7 @@ const REPO_BASE = 'https://github.com/prompt-security/clawsec'; const RAW_BASE = 'https://raw.githubusercontent.com/prompt-security/clawsec/main'; const toPosix = (inputPath) => inputPath.split(path.sep).join('/'); - -const isIndexSlug = (slug) => slug.toLowerCase() === 'index'; - -const toWebsiteRoute = (slug) => (slug === 'index' ? '/wiki' : `/wiki/${slug}`); - -const toLlmsPagePath = (slug) => - isIndexSlug(slug) ? '/wiki/llms.txt' : `/wiki/${slug}/llms.txt`; - -const toLlmsPageUrl = (slug) => `${WEBSITE_BASE}${toLlmsPagePath(slug)}`; +const toLlmsPageUrl = (slug) => `${WEBSITE_BASE}${toWikiLlmsPath(slug)}`; const walkMarkdownFiles = async (dir) => { const entries = await fs.readdir(dir, { withFileTypes: true }); @@ -55,7 +52,7 @@ const sortDocs = (a, b) => { }; const buildPageBody = (doc) => { - const pageRoute = toWebsiteRoute(doc.slug); + const pageRoute = toWikiRoute(doc.slug); const pageUrl = `${WEBSITE_BASE}/#${pageRoute}`; const sourceUrl = `${RAW_BASE}/wiki/${doc.relativePath}`; const llmsUrl = toLlmsPageUrl(doc.slug); @@ -91,7 +88,7 @@ const buildFallbackIndexBody = (docs) => { ]; for (const doc of docs) { - const pageRoute = toWebsiteRoute(doc.slug); + const pageRoute = toWikiRoute(doc.slug); const pageUrl = `${WEBSITE_BASE}/#${pageRoute}`; const llmsUrl = toLlmsPageUrl(doc.slug); lines.push(`- ${doc.title}: ${llmsUrl} (page: ${pageUrl})`); @@ -120,8 +117,8 @@ const main = async () => { } docs.sort(sortDocs); - const pageDocs = docs.filter((doc) => !isIndexSlug(doc.slug)); - const indexDoc = docs.find((doc) => isIndexSlug(doc.slug)); + const pageDocs = docs.filter((doc) => !isWikiIndexSlug(doc.slug)); + const indexDoc = docs.find((doc) => isWikiIndexSlug(doc.slug)); // `public/wiki/` is fully generated; wipe stale output before regenerating. await fs.rm(PUBLIC_WIKI_ROOT, { recursive: true, force: true }); diff --git a/utils/wikiPathHelpers.mjs b/utils/wikiPathHelpers.mjs new file mode 100644 index 0000000..ec87350 --- /dev/null +++ b/utils/wikiPathHelpers.mjs @@ -0,0 +1,38 @@ +/** + * Normalize a wiki slug for route/path construction. + * @param {string} slug + * @returns {string} + */ +const normalizeWikiSlug = (slug) => + String(slug ?? '') + .replace(/\\/g, '/') + .replace(/^\/+|\/+$/g, ''); + +/** + * Return whether a slug represents the wiki index page. + * @param {string} slug + * @returns {boolean} + */ +export const isWikiIndexSlug = (slug) => normalizeWikiSlug(slug).toLowerCase() === 'index'; + +/** + * Convert a wiki slug to app route path. + * @param {string} slug + * @returns {string} + */ +export const toWikiRoute = (slug) => { + const normalized = normalizeWikiSlug(slug); + if (!normalized || isWikiIndexSlug(normalized)) return '/wiki'; + return `/wiki/${normalized}`; +}; + +/** + * Convert a wiki slug to its llms.txt endpoint path. + * @param {string} slug + * @returns {string} + */ +export const toWikiLlmsPath = (slug) => { + const normalized = normalizeWikiSlug(slug); + if (!normalized || isWikiIndexSlug(normalized)) return '/wiki/llms.txt'; + return `/wiki/${normalized}/llms.txt`; +}; From c899970ba1369b13ed8534eeffaeaf92ecc4f01e Mon Sep 17 00:00:00 2001 From: David Abutbul Date: Thu, 26 Feb 2026 10:29:58 +0200 Subject: [PATCH 16/16] ci(pages): add pr verify workflow and tighten deploy triggers --- .github/workflows/deploy-pages.yml | 41 +++++++++-- .github/workflows/pages-verify.yml | 111 +++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/pages-verify.yml diff --git a/.github/workflows/deploy-pages.yml b/.github/workflows/deploy-pages.yml index 614c0f4..e024e11 100644 --- a/.github/workflows/deploy-pages.yml +++ b/.github/workflows/deploy-pages.yml @@ -4,7 +4,6 @@ on: workflow_run: workflows: ["CI", "Skill Release"] types: [completed] - # Note: No branch restriction - must trigger on both main branch CI runs AND tag-based Skill Releases workflow_dispatch: permissions: @@ -19,8 +18,25 @@ concurrency: jobs: build: runs-on: ubuntu-latest - # Only run if workflow_dispatch OR the triggering workflow succeeded - if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' + # Production build only: manual dispatch or trusted workflow_run sources. + # PR validation runs in .github/workflows/pages-verify.yml. + if: | + github.event_name == 'workflow_dispatch' || + ( + github.event_name == 'workflow_run' && + github.event.workflow_run.conclusion == 'success' && + ( + ( + github.event.workflow_run.name == 'CI' && + github.event.workflow_run.event == 'push' && + github.event.workflow_run.head_branch == 'main' + ) || + ( + github.event.workflow_run.name == 'Skill Release' && + github.event.workflow_run.event != 'pull_request' + ) + ) + ) steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -401,7 +417,24 @@ jobs: path: ./dist deploy: - # Deploy after build succeeds (CI or Skill Release must pass first, or manual dispatch) + # Deploy after a production build succeeds. + if: | + github.event_name == 'workflow_dispatch' || + ( + github.event_name == 'workflow_run' && + github.event.workflow_run.conclusion == 'success' && + ( + ( + github.event.workflow_run.name == 'CI' && + github.event.workflow_run.event == 'push' && + github.event.workflow_run.head_branch == 'main' + ) || + ( + github.event.workflow_run.name == 'Skill Release' && + github.event.workflow_run.event != 'pull_request' + ) + ) + ) environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} diff --git a/.github/workflows/pages-verify.yml b/.github/workflows/pages-verify.yml new file mode 100644 index 0000000..70f38e4 --- /dev/null +++ b/.github/workflows/pages-verify.yml @@ -0,0 +1,111 @@ +name: Pages Verify + +on: + pull_request: + branches: [main] + +permissions: + contents: read + +concurrency: + group: pages-verify-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + verify-pages-build: + name: Verify Pages Build (No Publish) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Verify signing key consistency (repo + docs) + run: ./scripts/ci/verify_signing_key_consistency.sh + + - name: Prepare advisory artifacts for pre-deploy checks + run: | + set -euo pipefail + mkdir -p public/advisories + cp advisories/feed.json public/advisories/feed.json + + - name: Generate advisory checksums manifest + run: | + set -euo pipefail + + FEED_FILE="public/advisories/feed.json" + FEED_SHA=$(sha256sum "$FEED_FILE" | awk '{print $1}') + FEED_SIZE=$(stat -c%s "$FEED_FILE" 2>/dev/null || stat -f%z "$FEED_FILE") + + jq -n \ + --arg schema_version "1" \ + --arg algorithm "sha256" \ + --arg version "1.1.0" \ + --arg generated "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ + --arg repo "${{ github.repository }}" \ + --arg sha "$FEED_SHA" \ + --argjson size "$FEED_SIZE" \ + '{ + schema_version: $schema_version, + algorithm: $algorithm, + version: $version, + generated_at: $generated, + repository: $repo, + files: { + "advisories/feed.json": { + sha256: $sha, + size: $size, + path: "advisories/feed.json", + url: "https://clawsec.prompt.security/advisories/feed.json" + } + } + }' > public/checksums.json + + - name: Generate ephemeral signing key for PR verification + id: test_key + run: | + set -euo pipefail + KEY_FILE=$(mktemp) + openssl genpkey -algorithm Ed25519 -out "$KEY_FILE" + { + echo "private_key<> "$GITHUB_OUTPUT" + rm -f "$KEY_FILE" + + - name: Sign advisory feed and verify + uses: ./.github/actions/sign-and-verify + with: + private_key: ${{ steps.test_key.outputs.private_key }} + input_file: public/advisories/feed.json + signature_file: public/advisories/feed.json.sig + public_key_output: public/signing-public.pem + + - name: Sign checksums and verify + uses: ./.github/actions/sign-and-verify + with: + private_key: ${{ steps.test_key.outputs.private_key }} + input_file: public/checksums.json + signature_file: public/checksums.sig + + - name: Setup Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build site + run: npm run build + env: + NODE_ENV: production + + - name: Sanity-check generated artifacts + run: | + set -euo pipefail + test -f dist/index.html + test -f public/advisories/feed.json.sig + test -f public/checksums.sig + test -f public/signing-public.pem