From ef238338a9d2d1ff6b7b7662ebc95f20c7516f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E5=98=89=E8=BC=9D?= <49779818+ChesterHsu@users.noreply.github.com> Date: Fri, 24 Jul 2026 01:08:45 +0800 Subject: [PATCH] docs: organize Flow and Warroom product guides Signed-off-by: ChesterHsu <49779818+ChesterHsu@users.noreply.github.com> Flyto2-CLA: accepted --- .seo/keyword-matrix-2026-07-23.md | 38 +++++---- .vitepress/config.mts | 132 +++++++++++++++++++----------- flow/browser-automation.md | 34 ++++++++ flow/evidence-replay.md | 29 +++++++ flow/index.md | 27 ++++++ flow/mcp-builder.md | 63 ++++++++++++++ index.md | 39 ++++----- reference/docs-code.md | 120 +++++++++++++-------------- scripts/audit-seo-surface.mjs | 10 ++- scripts/seo-score.mjs | 10 +++ warroom/surfaces/pentest.md | 8 +- 11 files changed, 359 insertions(+), 151 deletions(-) create mode 100644 flow/browser-automation.md create mode 100644 flow/evidence-replay.md create mode 100644 flow/index.md create mode 100644 flow/mcp-builder.md diff --git a/.seo/keyword-matrix-2026-07-23.md b/.seo/keyword-matrix-2026-07-23.md index 47baede2..d9dae93b 100644 --- a/.seo/keyword-matrix-2026-07-23.md +++ b/.seo/keyword-matrix-2026-07-23.md @@ -22,20 +22,24 @@ sitemap coverage. | Intent | Keyword | Volume | SD | PD | CPC | Heat | Primary Docs Path | Related Landing | Related Blog | | --- | --- | ---: | ---: | ---: | ---: | --- | --- | --- | --- | | Core runtime | open source AI agent framework | 1600* | 6* | 3* | 7.05* | High | `/core/`, `/mcp/` | `https://flyto2.com/open-source/` | `https://blog.flyto2.com/posts/mcp-server-guide` | -| Core runtime | AI workflow automation | 1000 | 59 | 40 | 42.24 | High | `/core/`, `/guide/getting-started`, `/modules/` | `https://flyto2.com/` | `https://blog.flyto2.com/posts/ai-browser-automation-guide` | -| Modules | AI workflow automation tools | 480 | 50 | 11 | 33.65 | Medium | `/modules/`, `/modules/browser`, `/modules/ai-llm` | `https://flyto2.com/` | `https://blog.flyto2.com/posts/workflow-automation` | -| Warroom | attack surface management | 880 | 44 | 25 | 32.48 | High | `/warroom/surfaces/attack-surface` | `https://flyto2.com/attack-surface-management/` | `https://blog.flyto2.com/posts/attack-surface-management-guide` | -| Warroom | attack surface management tools | 390 | 46 | 14 | 43.46 | Medium | `/warroom/surfaces/attack-surface`, `/warroom/closed-loop` | `https://flyto2.com/attack-surface-management/` | `https://blog.flyto2.com/posts/attack-surface-management-guide` | -| Warroom | continuous threat exposure management | 260 | 39 | 32 | 171.87 | Medium | `/warroom/closed-loop`, `/warroom/` | `https://flyto2.com/ctem/` | `https://blog.flyto2.com/posts/what-is-ctem-continuous-threat-exposure-management` | -| Warroom | CTEM | 1600 | 37 | 46 | 45.83 | High | `/warroom/closed-loop`, `/warroom/` | `https://flyto2.com/ctem/` | `https://blog.flyto2.com/posts/what-is-ctem-continuous-threat-exposure-management` | +| Flow | AI workflow automation | 1000 | 59 | 40 | 42.24 | High | `/flow/`, `/guide/getting-started`, `/core/` | `https://flyto2.com/flow/` | `https://blog.flyto2.com/flow/` | +| Flow modules | AI workflow automation tools | 480 | 50 | 11 | 33.65 | Medium | `/flow/`, `/modules/`, `/modules/browser` | `https://flyto2.com/flow/` | `https://blog.flyto2.com/posts/workflow-automation` | +| Warroom | attack surface management | 880 | 44 | 25 | 32.48 | High | `/warroom/surfaces/attack-surface` | `https://flyto2.com/warroom/attack-surface-management/` | `https://blog.flyto2.com/security/` | +| Warroom | attack surface management tools | 390 | 46 | 14 | 43.46 | Medium | `/warroom/surfaces/attack-surface`, `/warroom/closed-loop` | `https://flyto2.com/warroom/attack-surface-management/` | `https://blog.flyto2.com/posts/attack-surface-management-guide` | +| Warroom | continuous threat exposure management | 260 | 39 | 32 | 171.87 | Medium | `/warroom/closed-loop`, `/warroom/` | `https://flyto2.com/warroom/ctem/` | `https://blog.flyto2.com/security/` | +| Warroom | CTEM | 1600 | 37 | 46 | 45.83 | High | `/warroom/closed-loop`, `/warroom/` | `https://flyto2.com/warroom/ctem/` | `https://blog.flyto2.com/posts/what-is-ctem-continuous-threat-exposure-management` | +| Warroom | CTEM platform | 40 | 30 | 33 | 30.54 | Low | `/warroom/`, `/warroom/closed-loop` | `https://flyto2.com/warroom/ctem/` | `https://blog.flyto2.com/security/` | +| Warroom | security validation platform | 20 | 24 | 34 | 0.00 | Low | `/warroom/surfaces/pentest` | `https://flyto2.com/warroom/security-validation/` | `https://blog.flyto2.com/security/` | | MCP security | MCP security | 880 | 40 | 48 | 20.08 | High | `/warroom/surfaces/mcp-security` | `https://flyto2.com/ai-security/` | `https://blog.flyto2.com/posts/mcp-security-risks-and-controls` | | MCP security | MCP security best practices | 110 | 31 | 53 | 36.26 | Medium | `/warroom/surfaces/mcp-security` | `https://flyto2.com/ai-security/` | `https://blog.flyto2.com/posts/mcp-security-risks-and-controls` | -| Warroom | continuous threat exposure management ctem | 110 | 40 | 14 | 45.24 | Medium | `/warroom/closed-loop` | `https://flyto2.com/ctem/` | `https://blog.flyto2.com/posts/what-is-ctem-continuous-threat-exposure-management` | -| EASM | external attack surface management tools | 110 | 37 | 11 | 135.21 | Medium | `/warroom/surfaces/attack-surface` | `https://flyto2.com/external-attack-surface-management/` | `https://blog.flyto2.com/posts/what-is-easm-external-attack-surface-management` | -| MCP | MCP server automation | 10 | 34 | 68 | 16.50 | Low | `/mcp/`, `/modules/mcp` | `https://flyto2.com/api-docs/` | `https://blog.flyto2.com/posts/mcp-server-guide` | +| Warroom | continuous threat exposure management ctem | 110 | 40 | 14 | 45.24 | Medium | `/warroom/closed-loop` | `https://flyto2.com/warroom/ctem/` | `https://blog.flyto2.com/posts/what-is-ctem-continuous-threat-exposure-management` | +| EASM | external attack surface management tools | 110 | 37 | 11 | 135.21 | Medium | `/warroom/surfaces/attack-surface` | `https://flyto2.com/warroom/attack-surface-management/` | `https://blog.flyto2.com/posts/what-is-easm-external-attack-surface-management` | +| MCP | MCP server automation | 10 | 34 | 68 | 16.50 | Low | `/flow/mcp-builder`, `/mcp/`, `/modules/mcp` | `https://flyto2.com/flow/mcp-builder/` | `https://blog.flyto2.com/posts/mcp-server-guide` | +| MCP | visual MCP builder | 0 | 12 | 1 | 0.00 | Emerging | `/flow/mcp-builder` | `https://flyto2.com/flow/mcp-builder/` | `https://blog.flyto2.com/flow/` | | MCP testing | MCP server automation testing | 10 | 25 | 64 | 0.00 | Low | `/mcp/`, `/modules/verify`, `/modules/testing` | `https://flyto2.com/api-docs/` | `https://blog.flyto2.com/posts/mcp-server-guide` | -| Browser automation | AI browser automation | 140 | 53 | 35 | 11.40 | Medium | `/modules/browser`, `/guide/getting-started` | `https://flyto2.com/cloud/` | `https://blog.flyto2.com/posts/ai-browser-automation-guide` | -| Browser automation | no code browser automation | 20 | 23 | 56 | 16.13 | Low | `/modules/browser`, `/guide/getting-started` | `https://flyto2.com/` | `https://blog.flyto2.com/posts/no-code-browser-automation` | +| Browser automation | AI browser automation | 140 | 53 | 35 | 11.40 | Medium | `/flow/browser-automation`, `/modules/browser` | `https://flyto2.com/flow/browser-automation/` | `https://blog.flyto2.com/posts/ai-browser-automation-guide` | +| Browser automation | no code browser automation | 20 | 23 | 56 | 16.13 | Low | `/flow/browser-automation`, `/modules/browser` | `https://flyto2.com/flow/browser-automation/` | `https://blog.flyto2.com/posts/no-code-browser-automation` | +| Browser automation | self-hosted browser automation | 0 | 30 | 1 | 0.00 | Emerging | `/flow/browser-automation` | `https://flyto2.com/flow/browser-automation/` | `https://blog.flyto2.com/flow/` | ## flyto-i18n Manifest Addendum @@ -54,17 +58,17 @@ These terms are now carried by `.seo/i18n-seo-manifest.json`, synced from | MCP server automation | MCP server automation testing | 10 | 25 | 64 | 0.00 | Route to `/mcp/`, `/modules/verify`, and testing docs. | | MCP server automation | MCP server automation agent | 0 | 4 | 1 | 0.00 | Emerging agent-tool intent routed to `/mcp/` and `/modules/mcp`. | | MCP native AI agent runtime | open source execution engine for AI agents | 0 | 0 | 0 | 0.00 | Emerging Flyto2-owned phrase routed to `/core/`, `/mcp/`, and `/modules/`. | -| No-code browser automation | no code browser automation tool | 0 | 4 | 1 | 0.00 | Route to `/modules/browser` and beginner workflow docs. | -| No-code browser automation | free no code browser automation | 0 | 4 | 1 | 0.00 | Route to `/modules/browser` plus landing/open-source pages. | -| CTEM explainers | what is continuous threat exposure management | 20 | 15 | 31 | 0.00 | Route to `/warroom/closed-loop` plus landing `/ctem/` and the CTEM explainer post. | +| No-code browser automation | no code browser automation tool | 0 | 4 | 1 | 0.00 | Route to `/flow/browser-automation` and the module reference. | +| No-code browser automation | free no code browser automation | 0 | 4 | 1 | 0.00 | Route to `/flow/browser-automation` with accurate source-available and open-source runtime boundaries. | +| CTEM explainers | what is continuous threat exposure management | 20 | 15 | 31 | 0.00 | Route to `/warroom/closed-loop`, landing `/warroom/ctem/`, and the CTEM explainer post. | ## Long-Tail Docs Routing | Docs task | Long-tail examples | Route behavior | | --- | --- | --- | -| Start a workflow | `how to build AI workflow automation`, `AI workflow automation tutorial`, `self-hosted workflow automation` | Start at `/guide/getting-started`, then move to `/core/` and `/modules/`. | -| Connect AI agents to tools | `MCP server automation`, `MCP automation tools`, `MCP tools for AI agents` | Route to `/mcp/` and `/modules/mcp`. | -| Automate browser work | `no code browser automation`, `automate website without code`, `record and replay browser automation` | Route to `/modules/browser` and beginner guide pages. | +| Start a workflow | `how to build AI workflow automation`, `AI workflow automation tutorial`, `self-hosted workflow automation` | Start at `/flow/`, then choose the product workflow or direct `/core/` runtime path. | +| Connect AI agents to tools | `MCP server automation`, `visual MCP builder`, `MCP tools for AI agents` | Route to `/flow/mcp-builder`, then `/mcp/` for transport details. | +| Automate browser work | `no code browser automation`, `self-hosted browser automation`, `record and replay browser automation` | Route to `/flow/browser-automation`, then `/modules/browser` for the runtime contract. | | Build CTEM workflows | `continuous threat exposure management ctem`, `CTEM framework`, `CTEM vs vulnerability management` | Route to `/warroom/closed-loop` and surface pages. | | Work with EASM data | `external attack surface management platform`, `outside-in discovery`, `asset attribution` | Route to `/warroom/surfaces/attack-surface`. | diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 161f1a46..17392142 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -12,7 +12,7 @@ const CORE_MODULE_COUNT = 452 const CORE_CATALOG_CATEGORY_COUNT = 84 const BUILT_IN_RECIPE_COUNT = 41 const CORE_RUNTIME_SUMMARY = `${CORE_MODULE_COUNT} registry-backed modules across ${CORE_CATALOG_CATEGORY_COUNT} catalog categories, ${BUILT_IN_RECIPE_COUNT} built-in recipes, MCP transports, evidence capture, and replayable YAML execution` -const SITE_DESCRIPTION = 'Technical docs for Flyto2 Core, an open-source AI agent framework for AI workflow automation, MCP server automation, no-code browser workflows, replay, and CTEM evidence.' +const SITE_DESCRIPTION = 'Technical documentation for Flyto2 Flow, Flyto2 Warroom, and the open-source flyto-core runtime, organized by product and implementation outcome.' const SEO_KEYWORDS = [ 'Flyto2 docs', 'AI workflow automation', @@ -39,6 +39,22 @@ const SEO_KEYWORDS = [ ...manifestKeywordTerms(), ] const PAGE_SEO: Record = { + flow: { + title: 'Flyto2 Flow Documentation', + description: 'Build local AI workflow automation with Flyto2 Flow, visual MCP tools, browser recording, execution evidence, replay, and the open-source flyto-core runtime.', + }, + 'flow/mcp-builder': { + title: 'Visual MCP Builder', + description: 'Use the Flyto2 visual MCP builder to turn a workflow into a typed tool with local Streamable HTTP, client setup, audit metadata, and operator controls.', + }, + 'flow/browser-automation': { + title: 'Self-Hosted Browser Automation', + description: 'Record, edit, run, and inspect self-hosted browser automation in Flyto2 Flow with visual steps, same-origin streaming, screenshots, assertions, and evidence.', + }, + 'flow/evidence-replay': { + title: 'Workflow Evidence and Replay', + description: 'Use Flyto2 workflow evidence and replay to inspect execution history, step outputs, screenshots, checkpoints, and reproduction limits.', + }, 'guide/what-is-flyto2': { title: 'Open Source AI Agent Framework', description: 'Learn how Flyto2 works as an open source AI agent framework for deterministic modules, MCP server automation, workflow replay, and evidence.', @@ -135,6 +151,10 @@ const PAGE_SEO: Record = { title: 'Continuous Threat Exposure Management', description: 'Use Flyto2 for continuous threat exposure management workflows that connect discovery, prioritization, validation, remediation, and evidence.', }, + 'warroom/surfaces/pentest': { + title: 'Security Validation and Pentest', + description: 'Use Flyto2 Warroom security validation to connect prioritized findings, pentest evidence, remediation status, and repeatable verification.', + }, 'warroom/surfaces/attack-surface': { title: 'Attack Surface Management', description: 'Use Flyto2 attack surface management docs to connect assets, repositories, scanner findings, CTEM prioritization, evidence, and remediation.', @@ -494,6 +514,7 @@ export default defineConfig({ const dateModified = pageData.lastUpdated ? new Date(pageData.lastUpdated).toISOString() : undefined + const isProductHub = canonicalPath === 'flow' || canonicalPath === 'warroom' pageData.frontmatter.head = [ ...(pageData.frontmatter.head || []), @@ -510,9 +531,9 @@ export default defineConfig({ breadcrumb: { '@id': `${canonicalUrl}#breadcrumb` }, }, { - '@type': 'TechArticle', + '@type': isProductHub ? 'CollectionPage' : 'TechArticle', '@id': `${canonicalUrl}#article`, - headline: title, + ...(isProductHub ? { name: title } : { headline: title }), description, url: canonicalUrl, dateModified, @@ -596,40 +617,42 @@ export default defineConfig({ ], }, { - text: 'Build', + text: 'Flow', items: [ - { text: 'Core Runtime', link: '/core/' }, - { text: 'MCP Server', link: '/mcp/' }, - { text: 'Modules Reference', link: '/modules/' }, - { text: 'Configuration', link: '/guide/configuration' }, + { text: 'Flow Overview', link: '/flow/' }, + { text: 'Visual MCP Builder', link: '/flow/mcp-builder' }, + { text: 'Browser Automation', link: '/flow/browser-automation' }, + { text: 'Evidence & Replay', link: '/flow/evidence-replay' }, ], }, { - text: 'Reference', + text: 'Warroom', items: [ - { text: 'flyto-ai', link: '/ai/' }, - { text: 'flyto-indexer', link: '/indexer/' }, - { text: 'flyto-blueprint', link: '/blueprint/' }, + { text: 'Warroom Overview', link: '/warroom/' }, + { text: 'CTEM Closed Loop', link: '/warroom/closed-loop' }, + { text: 'Attack Surface Management', link: '/warroom/surfaces/attack-surface' }, + { text: 'Security Validation', link: '/warroom/surfaces/pentest' }, ], }, { - text: 'Security', + text: 'Core & MCP', items: [ - { text: 'Warroom Overview', link: '/warroom/' }, - { text: 'Self-hosted CE', link: '/warroom/self-hosted-ce' }, - { text: 'Security Surfaces', link: '/warroom/surfaces/' }, - { text: 'BYO Integrations', link: '/warroom/byo-integration' }, - { text: 'Scoring Methodology', link: '/warroom/scoring-methodology' }, + { text: 'Core Runtime', link: '/core/' }, + { text: 'MCP Server', link: '/mcp/' }, + { text: 'Modules Reference', link: '/modules/' }, + { text: 'flyto-ai', link: '/ai/' }, + { text: 'flyto-indexer', link: '/indexer/' }, + { text: 'flyto-blueprint', link: '/blueprint/' }, ], }, { text: 'Resources', items: [ - { text: 'Product Lines', link: '/strategy/flyto2-product-lines' }, { text: 'Community', link: '/community/' }, - { text: 'Blog', link: 'https://blog.flyto2.com' }, - { text: 'Product Site', link: 'https://flyto2.com' }, - { text: 'Warroom CE on GitHub', link: 'https://github.com/flytohub/flyto-warroom' }, + { text: 'Flow Guides', link: 'https://blog.flyto2.com/flow/' }, + { text: 'Security Guides', link: 'https://blog.flyto2.com/security/' }, + { text: 'Flyto2 Product Site', link: 'https://flyto2.com' }, + { text: 'GitHub Organization', link: 'https://github.com/flytohub' }, ], }, ], @@ -682,6 +705,28 @@ export default defineConfig({ ], }, ], + '/flow/': [ + { + text: 'Flyto2 Flow', + collapsed: false, + items: [ + { text: 'Overview', link: '/flow/' }, + { text: 'Visual MCP Builder', link: '/flow/mcp-builder' }, + { text: 'Browser Automation', link: '/flow/browser-automation' }, + { text: 'Evidence & Replay', link: '/flow/evidence-replay' }, + ], + }, + { + text: 'Runtime References', + collapsed: true, + items: [ + { text: 'flyto-core', link: '/core/' }, + { text: 'MCP Transports', link: '/mcp/' }, + { text: 'Browser Modules', link: '/modules/browser' }, + { text: 'Configuration', link: '/guide/configuration' }, + ], + }, + ], '/core/': [ { text: 'Core Runtime', @@ -806,21 +851,21 @@ export default defineConfig({ text: 'Start Here', collapsed: false, items: [ - { text: 'Home', link: '/warroom/' }, - { text: 'Overview', link: '/warroom/overview' }, - { text: 'MSSP Overview', link: '/warroom/mssp-overview' }, - { text: 'War-Room Concept', link: '/warroom/war-room-concept' }, + { text: 'Warroom Overview', link: '/warroom/' }, { text: 'Getting Started', link: '/warroom/getting-started' }, { text: 'Self-hosted CE', link: '/warroom/self-hosted-ce' }, { text: 'Product Tour', link: '/warroom/product-tour' }, ], }, { - text: 'Products', - collapsed: true, + text: 'CTEM Operations', + collapsed: false, items: [ - { text: 'Flyto2 Code (VA/PT)', link: '/warroom/flyto-code' }, - { text: 'Flyto2 Domains (CTEM)', link: '/warroom/flyto-domains' }, + { text: 'Closed-Loop Verify', link: '/warroom/closed-loop' }, + { text: 'Attack Surface Management', link: '/warroom/surfaces/attack-surface' }, + { text: 'Security Validation', link: '/warroom/surfaces/pentest' }, + { text: 'Unified Scoring', link: '/warroom/surfaces/unified-scoring' }, + { text: 'Integrations', link: '/warroom/integrations' }, ], }, { @@ -828,42 +873,29 @@ export default defineConfig({ collapsed: true, items: [ { text: 'Overview', link: '/warroom/surfaces/' }, - { text: 'External Attack Surface', link: '/warroom/surfaces/attack-surface' }, { text: 'Code Intelligence', link: '/warroom/surfaces/code-intelligence' }, { text: 'MCP Security', link: '/warroom/surfaces/mcp-security' }, { text: 'Container & Cloud Identity', link: '/warroom/surfaces/container-cloud-identity' }, { text: 'Darkweb & Threat Intel', link: '/warroom/surfaces/darkweb-threat-intel' }, { text: 'Footprint & Attribution', link: '/warroom/surfaces/footprint-attribution' }, { text: 'Asset Map', link: '/warroom/surfaces/asset-map' }, - { text: 'Pentest', link: '/warroom/surfaces/pentest' }, { text: 'Red-Team Simulation', link: '/warroom/surfaces/red-team' }, - { text: 'Unified Scoring', link: '/warroom/surfaces/unified-scoring' }, ], }, { - text: 'Scoring & Events', + text: 'Advanced & Reference', collapsed: true, items: [ + { text: 'MSSP Overview', link: '/warroom/mssp-overview' }, + { text: 'War-Room Concept', link: '/warroom/war-room-concept' }, + { text: 'Flyto2 Code (VA/PT)', link: '/warroom/flyto-code' }, + { text: 'Flyto2 Domains (CTEM)', link: '/warroom/flyto-domains' }, + { text: 'BYO Integration', link: '/warroom/byo-integration' }, { text: 'Scoring Methodology', link: '/warroom/scoring-methodology' }, { text: 'Score Events', link: '/warroom/score-events' }, - ], - }, - { - text: 'Workflows', - collapsed: true, - items: [ - { text: 'Closed-Loop Verify', link: '/warroom/closed-loop' }, { text: 'Pulse', link: '/warroom/pulse' }, { text: 'Red Team', link: '/warroom/red-team' }, - ], - }, - { - text: 'Reference', - collapsed: true, - items: [ { text: 'API Reference', link: '/warroom/api' }, - { text: 'Integrations', link: '/warroom/integrations' }, - { text: 'BYO Integration', link: '/warroom/byo-integration' }, ], }, ], @@ -883,7 +915,7 @@ export default defineConfig({ }, footer: { - message: 'Released under the Apache 2.0 License.', + message: 'Product licenses vary by repository; flyto-core is Apache 2.0.', copyright: `Copyright 2025-${new Date().getFullYear()} Flyto2`, }, }, diff --git a/flow/browser-automation.md b/flow/browser-automation.md new file mode 100644 index 00000000..d5a4b4d4 --- /dev/null +++ b/flow/browser-automation.md @@ -0,0 +1,34 @@ +# Self-hosted browser automation + +Flyto2 Flow provides **self-hosted browser automation** that records interactions, converts them into editable workflow steps, runs them in the local workspace, and keeps screenshots and execution evidence beside the run. + +## Working loop + +1. Open the recorder and enter the target URL. +2. Interact with the browser while Flow captures supported actions. +3. Review selectors, values, waits, screenshots, and generated assertions. +4. Add API, file, data, approval, or notification steps in the visual editor. +5. Run the workflow and inspect each step before scheduling or publishing it. + +Recorded steps are a starting point, not a guarantee of long-term stability. Prefer selectors tied to accessible names or stable application identifiers, and test navigation, empty-state, timeout, and authentication failures. + +## Local browser surface + +The Flow UI uses a same-origin browser stream for the local workspace. Browser frames and input events stay within that workspace by default. Treat any remote browser exposure as privileged access and put it behind reviewed authentication and network controls. + +## Evidence to keep + +- The workflow revision that ran +- Inputs and non-secret environment references +- Step status and timing +- Screenshots around important state changes +- Assertions that explain why the run passed +- The failing selector, URL, and error when it did not + +Do not place passwords, session tokens, personal data, or private customer content in workflow examples, screenshots, logs, or issue reports. + +## Choose the right layer + +Use Flow when you want recording, visual editing, execution history, and operator review. Use the [browser module reference](/modules/browser) or [`flyto-core`](/core/) directly when the workflow is maintained as code or YAML. + +See the [Flow browser automation product page](https://flyto2.com/flow/browser-automation/) and [browser automation guides](https://blog.flyto2.com/flow/). diff --git a/flow/evidence-replay.md b/flow/evidence-replay.md new file mode 100644 index 00000000..74bd5930 --- /dev/null +++ b/flow/evidence-replay.md @@ -0,0 +1,29 @@ +# Workflow evidence and replay + +Flyto2 **workflow evidence and replay** stores local execution history and step evidence so an operator can inspect what happened, reproduce a run, and compare the result with the original. + +## Evidence and replay are different + +**Evidence** records the inputs, state transitions, outputs, screenshots, and errors associated with an execution. **Replay** uses recorded execution state to run the workflow or a selected step again. + +A successful replay shows that the workflow can reproduce an outcome under the current environment. It does not prove who authored the original workflow, guarantee that an external website is unchanged, or turn a schema fingerprint into a signature. + +## Investigation sequence + +1. Select the execution from local history. +2. Find the first failing or divergent step. +3. Review its inputs, output, error, screenshot, and upstream state. +4. Confirm that required secrets and external services are available. +5. Replay the smallest useful scope. +6. Compare the new evidence with the original before accepting the result. + +## Reliability practices + +- Version breaking workflow and MCP contract changes. +- Keep assertions close to the state they validate. +- Avoid relying on timing alone when a visible or API state can be checked. +- Preserve the original evidence before debugging changes. +- Record environmental limitations and external dependencies. +- Require an operator checkpoint before replaying irreversible actions. + +For the underlying runtime model, read [`flyto-core` evidence and replay](/core/evidence-replay). To publish a reviewed workflow to an agent, continue with the [Visual MCP Builder](/flow/mcp-builder). diff --git a/flow/index.md b/flow/index.md new file mode 100644 index 00000000..5f35d20c --- /dev/null +++ b/flow/index.md @@ -0,0 +1,27 @@ +# Flyto2 Flow + +Flyto2 Flow is a local-first visual workflow application for building repeatable automation, publishing selected workflows as MCP tools, and inspecting the evidence produced by each run. + +Use this section when you want the product workflow. Use the [`flyto-core` documentation](/core/) when you need the underlying Python runtime, YAML contract, module registry, or direct MCP transports. + +## Choose an implementation path + +| Goal | Documentation | +| --- | --- | +| Turn a visual workflow into an MCP tool | [Visual MCP Builder](/flow/mcp-builder) | +| Record and run browser work locally | [Browser Automation](/flow/browser-automation) | +| Inspect a run or reproduce a failed step | [Evidence and Replay](/flow/evidence-replay) | +| Use the runtime without the Flow UI | [flyto-core](/core/) | + +## Product boundary + +Flyto2 Flow is source-available under [PolyForm Shield 1.0.0](https://github.com/flytohub/flyto-flow/blob/main/LICENSE). The product uses the open-source [`flyto-core`](https://github.com/flytohub/flyto-core) runtime, which is licensed under Apache 2.0. + +The default local workspace does not require a Flyto2 account. That does not make an internet-exposed installation safe by itself. Keep local endpoints on loopback unless you have added reviewed authentication, TLS, network policy, rate limits, and operational monitoring. + +## Related resources + +- [Flyto2 Flow product overview](https://flyto2.com/flow/) +- [Flow engineering guides](https://blog.flyto2.com/flow/) +- [Source repository](https://github.com/flytohub/flyto-flow) +- [Getting started with the runtime](/guide/getting-started) diff --git a/flow/mcp-builder.md b/flow/mcp-builder.md new file mode 100644 index 00000000..ef5aad81 --- /dev/null +++ b/flow/mcp-builder.md @@ -0,0 +1,63 @@ +# Visual MCP builder + +Flyto2 Flow discovers saved workflows that contain an MCP trigger and exposes each one as a typed Model Context Protocol tool. The saved workflow remains the canonical source; the trigger defines the public tool name, description, and input schema. + +## Define the tool contract + +Add an MCP trigger to the workflow: + +```yaml +- id: mcp_trigger + module: flow.trigger + params: + trigger_type: mcp + tool_name: collect_release_notes + tool_description: Collect release notes for a repository + config: + input_fields: + - name: repository + type: string + description: Repository owner and name + required: true +``` + +The input fields become JSON Schema properties. Treat this trigger as a public API: changing the tool name, deleting a field, or making an optional field required can break agent prompts and connected clients. + +## Connect a local client + +With Flow running on `127.0.0.1:9000`, the Streamable HTTP endpoint is: + +```text +http://127.0.0.1:9000/api/mcp +``` + +Check discovery and setup metadata: + +```bash +curl --fail http://127.0.0.1:9000/api/mcp/status +``` + +MCP Studio also generates configuration for local stdio clients. The bridge requires an absolute backend working directory and refuses a non-loopback backend URL. + +## Access model + +- Loopback clients can use the local endpoint without a Flyto2 account. +- Non-loopback access fails closed unless `FLYTO_FLOW_MCP_TOKEN` is configured. +- Remote clients send `Authorization: Bearer `. +- Browser calls also enforce an origin check through `FLYTO_MCP_ALLOWED_ORIGINS`. + +An operator token is one guard, not a complete public deployment design. Add TLS, an authenticated reverse proxy, network policy, rate limits, rotation, and log review before exposing MCP remotely. + +## Audit behavior + +Generated tools include additive Flyto2 metadata for the source workflow, contract version, schema fingerprint, risk level, approval policy, and evidence references. The fingerprint identifies contract drift; it is not a digital signature and does not prove authorship. + +## Design checklist + +1. Give the tool one clear outcome and an action-oriented name. +2. Keep inputs typed and make only truly mandatory values required. +3. Keep the returned result compact; leave verbose diagnostics in evidence. +4. Put destructive, financial, publishing, or permission-changing steps behind an operator checkpoint. +5. Test failure and timeout paths as well as the successful call. + +Continue with [MCP transport reference](/mcp/) or [Flow evidence and replay](/flow/evidence-replay). diff --git a/index.md b/index.md index 3d5c53d4..74ab191a 100644 --- a/index.md +++ b/index.md @@ -3,32 +3,33 @@ layout: home hero: name: Flyto2 Docs - text: Build, replay, and validate real AI workflows - tagline: New here? Start with Flyto2 Core, connect deterministic tools through MCP, then add evidence-backed CTEM, pentest, red-team, and security workflows when you need them. + text: Documentation organized by product and outcome + tagline: Build local AI automation with Flyto2 Flow, run evidence-backed CTEM operations with Flyto2 Warroom, or integrate directly with the open-source flyto-core runtime. image: src: /logo.webp alt: Flyto2 actions: - theme: brand - text: Start Here - link: /guide/getting-started + text: Flyto2 Flow + link: /flow/ - theme: alt - text: Core Runtime - link: /core/ - - theme: alt - text: MCP - link: /mcp/ - - theme: alt - text: Warroom + text: Flyto2 Warroom link: /warroom/ + - theme: alt + text: flyto-core + link: /core/ features: - - title: Start Without Guessing - details: Install Flyto2, run the first workflow, and learn the basics before opening the full module reference. - - title: Open-Source AI Agent Framework - details: flyto-core documents 452 registry-backed modules, 84 catalog categories, 41 recipes, trace, evidence capture, and replayable YAML execution. - - title: MCP Server Automation - details: Configure Flyto2 as an MCP server so AI agents can call deterministic browser, file, API, data, AI, and verification tools. - - title: Evidence-Backed Security - details: Warroom docs connect CTEM, attack surface, code risk, dark web, pentest, red-team, scoring, reporting, and evidence into one operating picture. + - title: Flyto2 Flow + details: Build visual workflows, expose typed MCP tools, automate browsers locally, inspect evidence, and replay execution. + link: /flow/ + - title: Flyto2 Warroom + details: Connect CTEM, attack surface management, security validation, remediation, scoring, and evidence in one operating loop. + link: /warroom/ + - title: flyto-core + details: Use the Apache-2.0 runtime directly through 452 registry-backed modules, 84 catalog categories, 41 recipes, MCP transports, and replayable YAML. + link: /core/ + - title: MCP and modules + details: Configure MCP transports and browse the complete generated module catalog when you need the underlying implementation contract. + link: /mcp/ --- diff --git a/reference/docs-code.md b/reference/docs-code.md index 6dd44900..7a24ae02 100644 --- a/reference/docs-code.md +++ b/reference/docs-code.md @@ -4,21 +4,21 @@ Source map for every maintained function and configuration method in the Flyto2 Docs generators, audits, SEO gates, and VitePress configuration. -Inventory: **14 files**, **3792 lines**, and **156 declarations**. +Inventory: **14 files**, **3842 lines**, and **156 declarations**. ## `.vitepress/config.mts` | Kind | Signature | Responsibility | Source | |---|---|---|---| -| function | `toPublicPath(url: string)` | Implements `toPublicPath` in this documentation surface. | [`.vitepress/config.mts:180`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L180) | -| function | `isNonContentPath(relativePath: string)` | Implements `isNonContentPath` in this documentation surface. | [`.vitepress/config.mts:184`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L184) | -| function | `isNonContentPublicPath(publicPath: string)` | Implements `isNonContentPublicPath` in this documentation surface. | [`.vitepress/config.mts:191`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L191) | -| function | `titleFromSegment(segment: string)` | Implements `titleFromSegment` in this documentation surface. | [`.vitepress/config.mts:201`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L201) | -| function | `breadcrumbItems(canonicalPath: string, title: string)` | Implements `breadcrumbItems` in this documentation surface. | [`.vitepress/config.mts:209`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L209) | -| function | `modulesSidebar(prefix = '')` | Implements `modulesSidebar` in this documentation surface. | [`.vitepress/config.mts:232`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L232) | -| function | `localeModulesConfig(prefix: string)` | Implements `localeModulesConfig` in this documentation surface. | [`.vitepress/config.mts:344`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L344) | -| method | `transformItems(items)` | Implements `transformItems` in this documentation surface. | [`.vitepress/config.mts:404`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L404) | -| method | `transformPageData(pageData)` | Implements `transformPageData` in this documentation surface. | [`.vitepress/config.mts:459`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L459) | +| function | `toPublicPath(url: string)` | Implements `toPublicPath` in this documentation surface. | [`.vitepress/config.mts:200`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L200) | +| function | `isNonContentPath(relativePath: string)` | Implements `isNonContentPath` in this documentation surface. | [`.vitepress/config.mts:204`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L204) | +| function | `isNonContentPublicPath(publicPath: string)` | Implements `isNonContentPublicPath` in this documentation surface. | [`.vitepress/config.mts:211`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L211) | +| function | `titleFromSegment(segment: string)` | Implements `titleFromSegment` in this documentation surface. | [`.vitepress/config.mts:221`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L221) | +| function | `breadcrumbItems(canonicalPath: string, title: string)` | Implements `breadcrumbItems` in this documentation surface. | [`.vitepress/config.mts:229`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L229) | +| function | `modulesSidebar(prefix = '')` | Implements `modulesSidebar` in this documentation surface. | [`.vitepress/config.mts:252`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L252) | +| function | `localeModulesConfig(prefix: string)` | Implements `localeModulesConfig` in this documentation surface. | [`.vitepress/config.mts:364`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L364) | +| method | `transformItems(items)` | Implements `transformItems` in this documentation surface. | [`.vitepress/config.mts:424`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L424) | +| method | `transformPageData(pageData)` | Implements `transformPageData` in this documentation surface. | [`.vitepress/config.mts:479`](https://github.com/flytohub/flyto-docs/blob/main/.vitepress/config.mts#L479) | ## `.vitepress/seo-contract.ts` @@ -41,30 +41,30 @@ Inventory: **14 files**, **3792 lines**, and **156 declarations**. | Kind | Signature | Responsibility | Source | |---|---|---|---| -| function | `fail(message)` | Implements `fail` in this documentation surface. | [`scripts/audit-seo-surface.mjs:78`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L78) | -| function | `sha256(value)` | Implements `sha256` in this documentation surface. | [`scripts/audit-seo-surface.mjs:82`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L82) | -| function | `loadSeoContract()` | Implements `loadSeoContract` in this documentation surface. | [`scripts/audit-seo-surface.mjs:86`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L86) | -| function | `decodeHtml(value)` | Implements `decodeHtml` in this documentation surface. | [`scripts/audit-seo-surface.mjs:94`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L94) | -| function | `getTags(html, tagName)` | Implements `getTags` in this documentation surface. | [`scripts/audit-seo-surface.mjs:105`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L105) | -| function | `attrs(rawAttrs)` | Implements `attrs` in this documentation surface. | [`scripts/audit-seo-surface.mjs:109`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L109) | -| function | `findMeta(html, key, value)` | Implements `findMeta` in this documentation surface. | [`scripts/audit-seo-surface.mjs:117`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L117) | -| function | `findLink(html, rel, hrefLang = null)` | Implements `findLink` in this documentation surface. | [`scripts/audit-seo-surface.mjs:128`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L128) | -| function | `publicAssetPath(url)` | Implements `publicAssetPath` in this documentation surface. | [`scripts/audit-seo-surface.mjs:141`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L141) | -| function | `checkPublicAsset(label, metaLabel, url)` | Implements `checkPublicAsset` in this documentation surface. | [`scripts/audit-seo-surface.mjs:152`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L152) | -| function | `contractKeywordTerms()` | Implements `contractKeywordTerms` in this documentation surface. | [`scripts/audit-seo-surface.mjs:157`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L157) | -| function | `checkAlternateLinks(label, html, expectedHreflangs)` | Implements `checkAlternateLinks` in this documentation surface. | [`scripts/audit-seo-surface.mjs:164`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L164) | -| function | `titleFrom(html)` | Implements `titleFrom` in this documentation surface. | [`scripts/audit-seo-surface.mjs:172`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L172) | -| function | `checkLength(label, value, min, max)` | Implements `checkLength` in this documentation surface. | [`scripts/audit-seo-surface.mjs:177`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L177) | -| function | `sitemapLocVariants(url)` | Implements `sitemapLocVariants` in this documentation surface. | [`scripts/audit-seo-surface.mjs:183`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L183) | -| function | `checkBrandAndEmails(label, content)` | Implements `checkBrandAndEmails` in this documentation surface. | [`scripts/audit-seo-surface.mjs:187`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L187) | -| function | `checkPage(page)` | Implements `checkPage` in this documentation surface. | [`scripts/audit-seo-surface.mjs:195`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L195) | -| function | `checkLocalizedPage(page)` | Implements `checkLocalizedPage` in this documentation surface. | [`scripts/audit-seo-surface.mjs:236`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L236) | -| function | `checkSeoContract()` | Implements `checkSeoContract` in this documentation surface. | [`scripts/audit-seo-surface.mjs:254`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L254) | -| function | `checkDist()` | Implements `checkDist` in this documentation surface. | [`scripts/audit-seo-surface.mjs:290`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L290) | -| function | `checkSitemapRobotsLlms()` | Implements `checkSitemapRobotsLlms` in this documentation surface. | [`scripts/audit-seo-surface.mjs:307`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L307) | -| function | `checkDiscoveryFiles()` | Implements `checkDiscoveryFiles` in this documentation surface. | [`scripts/audit-seo-surface.mjs:341`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L341) | -| function | `newestKeywordMatrix()` | Implements `newestKeywordMatrix` in this documentation surface. | [`scripts/audit-seo-surface.mjs:370`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L370) | -| function | `checkKeywordMatrix()` | Implements `checkKeywordMatrix` in this documentation surface. | [`scripts/audit-seo-surface.mjs:382`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L382) | +| function | `fail(message)` | Implements `fail` in this documentation surface. | [`scripts/audit-seo-surface.mjs:83`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L83) | +| function | `sha256(value)` | Implements `sha256` in this documentation surface. | [`scripts/audit-seo-surface.mjs:87`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L87) | +| function | `loadSeoContract()` | Implements `loadSeoContract` in this documentation surface. | [`scripts/audit-seo-surface.mjs:91`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L91) | +| function | `decodeHtml(value)` | Implements `decodeHtml` in this documentation surface. | [`scripts/audit-seo-surface.mjs:99`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L99) | +| function | `getTags(html, tagName)` | Implements `getTags` in this documentation surface. | [`scripts/audit-seo-surface.mjs:110`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L110) | +| function | `attrs(rawAttrs)` | Implements `attrs` in this documentation surface. | [`scripts/audit-seo-surface.mjs:114`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L114) | +| function | `findMeta(html, key, value)` | Implements `findMeta` in this documentation surface. | [`scripts/audit-seo-surface.mjs:122`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L122) | +| function | `findLink(html, rel, hrefLang = null)` | Implements `findLink` in this documentation surface. | [`scripts/audit-seo-surface.mjs:133`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L133) | +| function | `publicAssetPath(url)` | Implements `publicAssetPath` in this documentation surface. | [`scripts/audit-seo-surface.mjs:146`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L146) | +| function | `checkPublicAsset(label, metaLabel, url)` | Implements `checkPublicAsset` in this documentation surface. | [`scripts/audit-seo-surface.mjs:157`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L157) | +| function | `contractKeywordTerms()` | Implements `contractKeywordTerms` in this documentation surface. | [`scripts/audit-seo-surface.mjs:162`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L162) | +| function | `checkAlternateLinks(label, html, expectedHreflangs)` | Implements `checkAlternateLinks` in this documentation surface. | [`scripts/audit-seo-surface.mjs:169`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L169) | +| function | `titleFrom(html)` | Implements `titleFrom` in this documentation surface. | [`scripts/audit-seo-surface.mjs:177`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L177) | +| function | `checkLength(label, value, min, max)` | Implements `checkLength` in this documentation surface. | [`scripts/audit-seo-surface.mjs:182`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L182) | +| function | `sitemapLocVariants(url)` | Implements `sitemapLocVariants` in this documentation surface. | [`scripts/audit-seo-surface.mjs:188`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L188) | +| function | `checkBrandAndEmails(label, content)` | Implements `checkBrandAndEmails` in this documentation surface. | [`scripts/audit-seo-surface.mjs:192`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L192) | +| function | `checkPage(page)` | Implements `checkPage` in this documentation surface. | [`scripts/audit-seo-surface.mjs:200`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L200) | +| function | `checkLocalizedPage(page)` | Implements `checkLocalizedPage` in this documentation surface. | [`scripts/audit-seo-surface.mjs:244`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L244) | +| function | `checkSeoContract()` | Implements `checkSeoContract` in this documentation surface. | [`scripts/audit-seo-surface.mjs:262`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L262) | +| function | `checkDist()` | Implements `checkDist` in this documentation surface. | [`scripts/audit-seo-surface.mjs:298`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L298) | +| function | `checkSitemapRobotsLlms()` | Implements `checkSitemapRobotsLlms` in this documentation surface. | [`scripts/audit-seo-surface.mjs:315`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L315) | +| function | `checkDiscoveryFiles()` | Implements `checkDiscoveryFiles` in this documentation surface. | [`scripts/audit-seo-surface.mjs:349`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L349) | +| function | `newestKeywordMatrix()` | Implements `newestKeywordMatrix` in this documentation surface. | [`scripts/audit-seo-surface.mjs:378`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L378) | +| function | `checkKeywordMatrix()` | Implements `checkKeywordMatrix` in this documentation surface. | [`scripts/audit-seo-surface.mjs:390`](https://github.com/flytohub/flyto-docs/blob/main/scripts/audit-seo-surface.mjs#L390) | ## `scripts/check-documentation.py` @@ -184,32 +184,32 @@ Inventory: **14 files**, **3792 lines**, and **156 declarations**. | Kind | Signature | Responsibility | Source | |---|---|---|---| -| function | `decodeHtml(value)` | Implements `decodeHtml` in this documentation surface. | [`scripts/seo-score.mjs:84`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L84) | -| function | `getTags(html, tagName)` | Implements `getTags` in this documentation surface. | [`scripts/seo-score.mjs:95`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L95) | -| function | `attrs(rawAttrs)` | Implements `attrs` in this documentation surface. | [`scripts/seo-score.mjs:99`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L99) | -| function | `findMeta(html, key, value)` | Implements `findMeta` in this documentation surface. | [`scripts/seo-score.mjs:107`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L107) | -| function | `findLink(html, rel, hrefLang = null)` | Implements `findLink` in this documentation surface. | [`scripts/seo-score.mjs:116`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L116) | -| function | `titleFrom(html)` | Implements `titleFrom` in this documentation surface. | [`scripts/seo-score.mjs:128`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L128) | -| function | `stripHtml(html)` | Implements `stripHtml` in this documentation surface. | [`scripts/seo-score.mjs:133`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L133) | -| function | `visibleText(html)` | Implements `visibleText` in this documentation surface. | [`scripts/seo-score.mjs:141`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L141) | -| function | `textFromTag(html, tagName)` | Implements `textFromTag` in this documentation surface. | [`scripts/seo-score.mjs:146`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L146) | -| function | `normalizeTerm(value)` | Implements `normalizeTerm` in this documentation surface. | [`scripts/seo-score.mjs:150`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L150) | -| function | `includesTerm(haystack, term)` | Implements `includesTerm` in this documentation surface. | [`scripts/seo-score.mjs:159`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L159) | -| function | `wordList(text)` | Implements `wordList` in this documentation surface. | [`scripts/seo-score.mjs:163`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L163) | -| function | `wordCount(text)` | Implements `wordCount` in this documentation surface. | [`scripts/seo-score.mjs:167`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L167) | -| function | `canonicalFor(route)` | Implements `canonicalFor` in this documentation surface. | [`scripts/seo-score.mjs:171`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L171) | -| function | `htmlPathFor(route)` | Implements `htmlPathFor` in this documentation surface. | [`scripts/seo-score.mjs:175`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L175) | -| function | `sitemapUrls()` | Implements `sitemapUrls` in this documentation surface. | [`scripts/seo-score.mjs:182`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L182) | -| function | `publicAssetExists(url)` | Implements `publicAssetExists` in this documentation surface. | [`scripts/seo-score.mjs:189`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L189) | -| function | `linkStats(html)` | Implements `linkStats` in this documentation surface. | [`scripts/seo-score.mjs:200`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L200) | -| function | `imageStats(html)` | Implements `imageStats` in this documentation surface. | [`scripts/seo-score.mjs:207`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L207) | -| function | `jsonLdTypes(html)` | Implements `jsonLdTypes` in this documentation surface. | [`scripts/seo-score.mjs:213`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L213) | -| function | `noBadEmails(html)` | Implements `noBadEmails` in this documentation surface. | [`scripts/seo-score.mjs:232`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L232) | -| function | `scoreItem(items, category, name, points, pass, recommendation, details = {})` | Implements `scoreItem` in this documentation surface. | [`scripts/seo-score.mjs:237`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L237) | -| function | `scoreRange(items, category, name, points, value, min, max, recommendation)` | Implements `scoreRange` in this documentation surface. | [`scripts/seo-score.mjs:241`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L241) | -| function | `scorePage(route, html, sitemap)` | Implements `scorePage` in this documentation surface. | [`scripts/seo-score.mjs:245`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L245) | -| function | `writeReports(report)` | Implements `writeReports` in this documentation surface. | [`scripts/seo-score.mjs:312`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L312) | -| function | `main()` | Implements `main` in this documentation surface. | [`scripts/seo-score.mjs:346`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L346) | +| function | `decodeHtml(value)` | Implements `decodeHtml` in this documentation surface. | [`scripts/seo-score.mjs:94`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L94) | +| function | `getTags(html, tagName)` | Implements `getTags` in this documentation surface. | [`scripts/seo-score.mjs:105`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L105) | +| function | `attrs(rawAttrs)` | Implements `attrs` in this documentation surface. | [`scripts/seo-score.mjs:109`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L109) | +| function | `findMeta(html, key, value)` | Implements `findMeta` in this documentation surface. | [`scripts/seo-score.mjs:117`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L117) | +| function | `findLink(html, rel, hrefLang = null)` | Implements `findLink` in this documentation surface. | [`scripts/seo-score.mjs:126`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L126) | +| function | `titleFrom(html)` | Implements `titleFrom` in this documentation surface. | [`scripts/seo-score.mjs:138`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L138) | +| function | `stripHtml(html)` | Implements `stripHtml` in this documentation surface. | [`scripts/seo-score.mjs:143`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L143) | +| function | `visibleText(html)` | Implements `visibleText` in this documentation surface. | [`scripts/seo-score.mjs:151`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L151) | +| function | `textFromTag(html, tagName)` | Implements `textFromTag` in this documentation surface. | [`scripts/seo-score.mjs:156`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L156) | +| function | `normalizeTerm(value)` | Implements `normalizeTerm` in this documentation surface. | [`scripts/seo-score.mjs:160`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L160) | +| function | `includesTerm(haystack, term)` | Implements `includesTerm` in this documentation surface. | [`scripts/seo-score.mjs:169`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L169) | +| function | `wordList(text)` | Implements `wordList` in this documentation surface. | [`scripts/seo-score.mjs:173`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L173) | +| function | `wordCount(text)` | Implements `wordCount` in this documentation surface. | [`scripts/seo-score.mjs:177`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L177) | +| function | `canonicalFor(route)` | Implements `canonicalFor` in this documentation surface. | [`scripts/seo-score.mjs:181`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L181) | +| function | `htmlPathFor(route)` | Implements `htmlPathFor` in this documentation surface. | [`scripts/seo-score.mjs:185`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L185) | +| function | `sitemapUrls()` | Implements `sitemapUrls` in this documentation surface. | [`scripts/seo-score.mjs:192`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L192) | +| function | `publicAssetExists(url)` | Implements `publicAssetExists` in this documentation surface. | [`scripts/seo-score.mjs:199`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L199) | +| function | `linkStats(html)` | Implements `linkStats` in this documentation surface. | [`scripts/seo-score.mjs:210`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L210) | +| function | `imageStats(html)` | Implements `imageStats` in this documentation surface. | [`scripts/seo-score.mjs:217`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L217) | +| function | `jsonLdTypes(html)` | Implements `jsonLdTypes` in this documentation surface. | [`scripts/seo-score.mjs:223`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L223) | +| function | `noBadEmails(html)` | Implements `noBadEmails` in this documentation surface. | [`scripts/seo-score.mjs:242`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L242) | +| function | `scoreItem(items, category, name, points, pass, recommendation, details = {})` | Implements `scoreItem` in this documentation surface. | [`scripts/seo-score.mjs:247`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L247) | +| function | `scoreRange(items, category, name, points, value, min, max, recommendation)` | Implements `scoreRange` in this documentation surface. | [`scripts/seo-score.mjs:251`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L251) | +| function | `scorePage(route, html, sitemap)` | Implements `scorePage` in this documentation surface. | [`scripts/seo-score.mjs:255`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L255) | +| function | `writeReports(report)` | Implements `writeReports` in this documentation surface. | [`scripts/seo-score.mjs:322`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L322) | +| function | `main()` | Implements `main` in this documentation surface. | [`scripts/seo-score.mjs:356`](https://github.com/flytohub/flyto-docs/blob/main/scripts/seo-score.mjs#L356) | ## `scripts/sync-core-reference.py` diff --git a/scripts/audit-seo-surface.mjs b/scripts/audit-seo-surface.mjs index 4ee689aa..8978e74c 100644 --- a/scripts/audit-seo-surface.mjs +++ b/scripts/audit-seo-surface.mjs @@ -21,6 +21,10 @@ const formattedCoreDeclarationCount = coreDeclarationCount.toLocaleString('en-US const checkedPages = [ { name: 'home', file: 'index.html', canonical: siteUrl, terms: ['AI workflow automation', 'MCP server automation'] }, + { name: 'flow', file: 'flow/index.html', canonical: `${siteUrl}/flow`, terms: ['Flyto2 Flow', 'visual workflow'], schemaType: 'CollectionPage' }, + { name: 'flow mcp builder', file: 'flow/mcp-builder.html', canonical: `${siteUrl}/flow/mcp-builder`, terms: ['Visual MCP builder', '/api/mcp'] }, + { name: 'flow browser automation', file: 'flow/browser-automation.html', canonical: `${siteUrl}/flow/browser-automation`, terms: ['browser automation', 'evidence'] }, + { name: 'flow evidence replay', file: 'flow/evidence-replay.html', canonical: `${siteUrl}/flow/evidence-replay`, terms: ['Evidence', 'Replay'] }, { name: 'core', file: 'core/index.html', canonical: `${siteUrl}/core`, terms: ['flyto-core', 'execution'] }, { name: 'core whitepaper', file: 'core/whitepaper.html', canonical: `${siteUrl}/core/whitepaper`, terms: ['module contract', 'security model'] }, { name: 'core reference', file: 'core/reference/index.html', canonical: `${siteUrl}/core/reference`, terms: ['Python declaration reference', 'HTTP route reference'] }, @@ -30,10 +34,11 @@ const checkedPages = [ { name: 'getting started', file: 'guide/getting-started.html', canonical: `${siteUrl}/guide/getting-started`, terms: ['workflow'] }, { name: 'installation', file: 'guide/installation.html', canonical: `${siteUrl}/guide/installation`, terms: ['install'] }, { name: 'community', file: 'community/index.html', canonical: `${siteUrl}/community`, terms: ['community', 'social syndication'] }, - { name: 'warroom', file: 'warroom/index.html', canonical: `${siteUrl}/warroom`, terms: ['Warroom'] }, + { name: 'warroom', file: 'warroom/index.html', canonical: `${siteUrl}/warroom`, terms: ['Warroom'], schemaType: 'CollectionPage' }, { name: 'self-hosted ce', file: 'warroom/self-hosted-ce.html', canonical: `${siteUrl}/warroom/self-hosted-ce`, terms: ['Warroom CE', 'Docker'] }, { name: 'closed loop', file: 'warroom/closed-loop.html', canonical: `${siteUrl}/warroom/closed-loop`, terms: ['evidence'] }, { name: 'attack surface docs', file: 'warroom/surfaces/attack-surface.html', canonical: `${siteUrl}/warroom/surfaces/attack-surface`, terms: ['attack surface'] }, + { name: 'security validation docs', file: 'warroom/surfaces/pentest.html', canonical: `${siteUrl}/warroom/surfaces/pentest`, terms: ['security validation', 'evidence'] }, ]; const checkedLocalizedPages = [ { name: 'zh-TW browser module', file: 'zh-TW/modules/browser.html', canonical: `${siteUrl}/zh-TW/modules/browser`, locale: 'zh-TW' }, @@ -227,6 +232,9 @@ function checkPage(page) { checkPublicAsset(page.name, 'og:image', ogImage); checkPublicAsset(page.name, 'twitter:image', twitterImage); if (!html.includes('application/ld+json')) fail(`${page.name} missing JSON-LD`); + if (page.schemaType && !html.includes(`"@type":"${page.schemaType}"`)) { + fail(`${page.name} missing ${page.schemaType} JSON-LD`); + } for (const term of page.terms) { if (!html.toLowerCase().includes(term.toLowerCase())) fail(`${page.name} missing docs intent term: ${term}`); } diff --git a/scripts/seo-score.mjs b/scripts/seo-score.mjs index 21db3c3e..ee65b334 100644 --- a/scripts/seo-score.mjs +++ b/scripts/seo-score.mjs @@ -15,6 +15,10 @@ const legacyBrandPattern = new RegExp(`\\b${['Fly', 'to'].join('')}\\b`); const routes = [ '', + 'flow', + 'flow/mcp-builder', + 'flow/browser-automation', + 'flow/evidence-replay', 'guide/what-is-flyto2', 'guide/getting-started', 'guide/installation', @@ -41,6 +45,7 @@ const routes = [ 'warroom/closed-loop', 'warroom/surfaces/attack-surface', 'warroom/surfaces/mcp-security', + 'warroom/surfaces/pentest', 'ai', 'indexer', 'blueprint', @@ -49,6 +54,10 @@ const routes = [ const focusByRoute = new Map([ ['', 'Flyto2 docs'], + ['flow', 'Flyto2 Flow'], + ['flow/mcp-builder', 'visual MCP builder'], + ['flow/browser-automation', 'self-hosted browser automation'], + ['flow/evidence-replay', 'workflow evidence and replay'], ['guide/what-is-flyto2', 'open source AI agent framework'], ['guide/getting-started', 'AI workflow automation'], ['guide/installation', 'install Flyto2'], @@ -75,6 +84,7 @@ const focusByRoute = new Map([ ['warroom/closed-loop', 'continuous threat exposure management'], ['warroom/surfaces/attack-surface', 'attack surface management'], ['warroom/surfaces/mcp-security', 'MCP security'], + ['warroom/surfaces/pentest', 'security validation'], ['ai', 'AI agent framework'], ['indexer', 'code intelligence'], ['blueprint', 'workflow blueprint'], diff --git a/warroom/surfaces/pentest.md b/warroom/surfaces/pentest.md index e1e305ec..c07e6874 100644 --- a/warroom/surfaces/pentest.md +++ b/warroom/surfaces/pentest.md @@ -1,13 +1,13 @@ --- -title: Pentest -description: "Surface-level technical deep dive on the pentest loop within code_redteam — /pentests with contract-only scoring (no legacy fallback), how a target is generated from footprint and the asset map, executed via the footprint-to-pentest-target and pentest-campaign-dryrun recipes, and how exploitation evidence feeds verdicts through verify.terminal. Honest: verified paths only, no fuzzy-matched fabricated links." +title: Security Validation and Pentest +description: "Technical reference for Flyto2 security validation and pentest workflows: scoped targets, evidence-backed execution, explicit verdicts, remediation context, and contract-only scoring." --- -# Pentest +# Security Validation and Pentest ![Pentest — the recon→pentest→red-team bridge: footprint targets promoted into DAST projects with evidence](/warroom/shots/pentest.jpeg) -The **pentest** surface is the "is it really exploitable?" half of the war-room. It is one of the nine [converged surfaces](/warroom/surfaces/), and it shares the `code_redteam` registry surface with [code intelligence](/warroom/surfaces/code-intelligence) and [red-team simulation](/warroom/surfaces/red-team) — a common `/pentests` + `/findings/${fingerprint}/verify` spine, three distinct closed loops. Code intelligence answers *what's wrong*; pentest answers *is it really exploitable*; red-team simulation answers *what happens when an adversary chains it*. +The **security validation and pentest** surface is the "is it really exploitable?" half of the war-room. It is one of the nine [converged surfaces](/warroom/surfaces/), and it shares the `code_redteam` registry surface with [code intelligence](/warroom/surfaces/code-intelligence) and [red-team simulation](/warroom/surfaces/red-team) — a common `/pentests` + `/findings/${fingerprint}/verify` spine, three distinct closed loops. Code intelligence answers *what's wrong*; pentest answers *is it really exploitable*; red-team simulation answers *what happens when an adversary chains it*. This page is the surface-level technical reference for the pentest loop: how a target is generated from footprint and asset-map data, executed through deterministic [flyto-core](/) recipes, and how the resulting evidence promotes a finding's confidence and feeds the score. For the verification mechanics it relies on — the L0→L1→L2 promotion rules, static vs dynamic modes, and the `verify.terminal` event contract — read [Closed-Loop Verify](/warroom/closed-loop) first.