{"nodes":[{"id":"add-host-creates-attribute-accessible-hosts","text":"After `ftl.add_host(hostname=\"web01\", ...)`, the host is immediately addressable as `ftl.web01` for attribute-style host-scoped module calls (e.g., `ftl.web01.apt(...)`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/add-host-creates-attribute-accessible-hosts.json"},{"id":"add-host-disable-host-key-checking","text":"The `disable_host_key_checking=True` parameter on `ftl.add_host()` skips SSH host key verification, essential for newly provisioned cloud VMs whose keys are unknown.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/add-host-disable-host-key-checking.json"},{"id":"add-host-dynamic-registration","text":"`ftl.add_host(name, ansible_host=, ansible_user=, groups=[])` dynamically registers a host at runtime.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/add-host-dynamic-registration.json"},{"id":"add-host-groups-parameter","text":"`ftl.add_host()` accepts a `groups` parameter to assign the dynamically registered host to inventory groups.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/add-host-groups-parameter.json"},{"id":"add-host-persists-immediately","text":"`add_host()` persists to the state file immediately (not deferred to context exit).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/add-host-persists-immediately.json"},{"id":"add-host-registers-dynamic-hosts-at-runtime","text":"`ftl.add_host(hostname, ansible_host, groups=[], **kwargs)` registers hosts at runtime; extra kwargs become custom host variables.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/add-host-registers-dynamic-hosts-at-runtime.json"},{"id":"add-host-registers-hosts-dynamically","text":"Hosts are registered dynamically via `ftl.add_host(hostname=..., ansible_host=ip, ansible_user=..., ansible_become=True)` — this is how scripts add hosts discovered at runtime (e.g., after provisioning a Linode).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/add-host-registers-hosts-dynamically.json"},{"id":"ai-loop-action-ordering-matters","text":"Sequential ordering in AI-loop action functions matters — for example, a user must be created before files can be owned by that user — and this is the author's responsibility, not automatically handled.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-action-ordering-matters.json"},{"id":"ai-loop-autonomous-remediation-system","text":"The AI loop combines resilient observation (shell guards, error suppression, fail-open semantics) with a self-healing contract (observe → condition → action) that supports convergence toward desired state. Together, these mechanisms enable autonomous remediation without requiring human intervention for observed drift.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-autonomous-remediation-system.json"},{"id":"ai-loop-condition-skip-on-missing-state","text":"AI-loop rule conditions can return `False` when prerequisite state is missing (e.g., IP not yet provisioned), causing the rule to silently skip rather than fail — this handles ordering between dependent rules.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-condition-skip-on-missing-state.json"},{"id":"ai-loop-declarative-goal-string","text":"The `ftl2-ai-loop` takes a declarative goal string as input and reconciles toward it using workspace rules.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-declarative-goal-string.json"},{"id":"ai-loop-host-accessor-syntax","text":"AI-loop action functions use the `ftl[\"hostname\"].module()` accessor pattern with `await` for sequential module calls (e.g., `await ftl[\"stargate\"].user(name=\"admin\")`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-host-accessor-syntax.json"},{"id":"ai-loop-incremental-flag","text":"The `--incremental` flag on `ftl2-ai-loop` enables incremental reconciliation rather than full re-deployment.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-incremental-flag.json"},{"id":"ai-loop-modules-are-idempotent","text":"Module calls in AI-loop actions (user, file, copy, lineinfile, service) are idempotent — safe to re-run even if the condition gate fails to prevent unnecessary executions.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-modules-are-idempotent.json"},{"id":"ai-loop-observe-condition-action-pattern","text":"FTL2 AI-loop rules follow an observe → condition → action pattern: the loop runs `observe` to gather state, calls `condition(state)` to decide whether to act, and calls `action(ftl)` if the condition returns True.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-observe-condition-action-pattern.json"},{"id":"ai-loop-observe-list-structure","text":"AI-loop observe blocks are lists of dicts with `name`, `module`, `params`, and `host` keys that run commands on target hosts to gather state.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-observe-list-structure.json"},{"id":"ai-loop-observe-resilience","text":"AI-loop observe steps are resilient by design: shell commands use `|| true` to suppress non-zero exits, `2>&1` captures all output, and failed observations are treated as drift triggers rather than errors.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-observe-resilience.json"},{"id":"ai-loop-rule-three-phase-contract","text":"FTL2 AI-loop rules follow a three-phase contract: `observe` (gather state), `condition(state)` (check for drift), and `action(ftl)` (remediate) — the reconciliation loop calls these in order automatically.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-rule-three-phase-contract.json"},{"id":"ai-loop-rules-not-called-directly","text":"AI-loop rules are not called directly by user code — they are discovered and executed by the FTL2 AI reconciliation loop automatically.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-rules-not-called-directly.json"},{"id":"ai-loop-self-healing-contract","text":"AI-loop rules implement a complete self-healing contract: observation failures trigger action (fail-open), guard clauses defer when prerequisites are missing, and actions apply full convergence regardless of which specific check detected drift.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-self-healing-contract.json"},{"id":"ai-loop-state-inventory-generated-at-runtime","text":"State and inventory files in ftl2-deployments workspaces are not pre-created — they are generated at runtime by the AI loop.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-state-inventory-generated-at-runtime.json"},{"id":"ai-loop-typed-function-contract","text":"AI-loop rules define a typed function contract across their three phases: observe is a declarative list of module dicts with name/module/params/host keys, condition receives a structured state dict keyed by observation name, and action receives the full FTL2 runtime with host accessors and module methods.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-typed-function-contract.json"},{"id":"ai-loop-workspace-four-components","text":"Each ftl2-deployments workspace has four key components: `desired_state.txt` (declarative intent), `rules/` (AI loop constraints), `.env` (secrets/config), and runtime-generated state/inventory.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-loop-workspace-four-components.json"},{"id":"ai-reconciliation-loop-pattern","text":"The AI reconciliation loop follows the pattern: observe → decide → act → verify; cost converges toward zero as deterministic rules replace AI reasoning.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ai-reconciliation-loop-pattern.json"},{"id":"ansible-collection-install-requires-collections-path","text":"Installing Ansible collections into the venv requires setting `ANSIBLE_COLLECTIONS_PATH` to the venv's site-packages directory (e.g., `.venv/lib/python3.14/site-packages`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ansible-collection-install-requires-collections-path.json"},{"id":"ansible-drops-hosts-25-ftl2-handles","text":"Ansible drops hosts as \"unreachable\" at 25+ hosts; FTL2's persistent gate connections handle them without issues.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ansible-drops-hosts-25-ftl2-handles.json"},{"id":"ansible-familiarity-across-layers","text":"FTL2 preserves Ansible familiarity at every interaction layer: CLI flags mirror `-m -i -a`, variable precedence follows group < host < argument ordering, inventory groups map directly to Ansible groups, and modules support both short names and FQCNs.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ansible-familiarity-across-layers.json"},{"id":"ansible-gradual-migration-path","text":"FTL2 enables gradual Ansible migration without workflow disruption: familiar CLI/inventory/FQCN patterns reduce learning curve while the universal module system (four addressing syntaxes, dual native/bundled execution modes) lets teams run existing Ansible collections alongside faster FTL2 natives incrementally.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ansible-gradual-migration-path.json"},{"id":"ansible-migration-production-ready","text":"Ansible teams migrating to FTL2 retain familiar patterns while immediately gaining production-grade deployment capabilities: gradual migration preserves CLI, inventory, FQCN, and variable precedence patterns, while state-driven reliability and security-first lifecycle provide enterprise-grade re-runnability and hardening from day one.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ansible-migration-production-ready.json"},{"id":"ansible-to-ftl2-conversion-mappings","text":"The Ansible-to-FTL2 converter maps: `with_items` to `for` loops, `when` to `if` statements, `handlers` to explicit service restarts, `roles` to function calls, `hosts` to group proxies, `vars` to Python variables.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ansible-to-ftl2-conversion-mappings.json"},{"id":"auditable-resilient-reexecution","text":"Every re-execution in FTL2 is both safe and auditable: state-driven idempotency prevents resource duplication and enables crash recovery, while event streaming and policy audit trails capture exactly what happened in each run — failed re-runs leave evidence, successful ones prove convergence.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/auditable-resilient-reexecution.json"},{"id":"authorized-key-module-fqcn","text":"SSH public keys are deployed via `ftl.host.ansible.posix.authorized_key()` using the full FQCN pattern, supporting user/key/state parameters.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/authorized-key-module-fqcn.json"},{"id":"auto-install-deps-parameter","text":"The `automation()` context manager accepts `auto_install_deps=True` to automatically install required Ansible collections if they are missing.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/auto-install-deps-parameter.json"},{"id":"automation-complete-developer-experience","text":"The AutomationContext serves as a unified entry point (async context manager) that combines module access through four addressing syntaxes (dot, bracket, FQCN, proxy) with configurable error semantics (continue-on-error or fail-fast with introspectable exceptions), providing a cohesive developer interface for FTL2 automation.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-complete-developer-experience.json"},{"id":"automation-context-accepts-check-mode","text":"`automation(check_mode=True)` enables dry-run mode that previews changes without applying them; output is annotated with `[CHECK MODE]`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-accepts-check-mode.json"},{"id":"automation-context-default-print-summary-true","text":"`automation()` defaults to `print_summary=True` and `print_errors=True`, printing a per-host task summary with error details when the async context manager exits.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-default-print-summary-true.json"},{"id":"automation-context-is-primary-user-class","text":"`AutomationContext` is the primary user-facing class in FTL2's automation framework, providing the `async with automation() as ftl:` pattern.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-is-primary-user-class.json"},{"id":"automation-context-manager-async-with","text":"The `automation()` context manager is the entry point for all FTL2 remote operations, used with `async with`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-manager-async-with.json"},{"id":"automation-context-manager-entry-point","text":"`async with automation() as ftl:` is the entry point for all FTL2 automation scripts, providing module access, inventory, secrets, and result tracking.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-manager-entry-point.json"},{"id":"automation-context-manager-pattern","text":"FTL2 scripts use `async with automation(state_file=..., secret_bindings=...) as ftl:` as the core entry point — this context manager sets up inventory, state, and secrets.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-manager-pattern.json"},{"id":"automation-context-unified-api","text":"AutomationContext is the primary user-facing class for FTL2 automation, providing an async context manager entry point, module access via attributes, secret binding and access, categorized result tracking (changed/ok/failed), and dual error handling modes (continue-on-error or fail-fast).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-unified-api.json"},{"id":"automation-context-usable-as-object-or-context-manager","text":"`AutomationContext` can be used both as a regular object (`ctx = AutomationContext(...)`) and as an async context manager (`async with AutomationContext(...) as ftl`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-context-usable-as-object-or-context-manager.json"},{"id":"automation-default-fail-fast-false","text":"FTL2's default behavior is `fail_fast=False` — a failing task does not halt subsequent tasks in the same automation context.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-default-fail-fast-false.json"},{"id":"automation-default-target-localhost","text":"When no inventory is specified, `automation()` defaults to targeting `localhost`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-default-target-localhost.json"},{"id":"automation-error-has-result-attribute","text":"`AutomationError` has `message` (str) and `result` (the failed `ExecuteResult`) attributes, enabling granular error inspection per host and module.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-error-has-result-attribute.json"},{"id":"automation-factory-wraps-automation-context","text":"The `automation()` function is an async context manager factory that wraps `AutomationContext` — all real logic lives in `AutomationContext`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-factory-wraps-automation-context.json"},{"id":"automation-fail-fast-raises-automationerror","text":"`automation(fail_fast=True)` raises `AutomationError` on first module failure; the exception has `.result.module` to identify the failing module.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-fail-fast-raises-automationerror.json"},{"id":"automation-fqcn-via-namespace-proxy-chaining","text":"FQCN modules use `NamespaceProxy` chaining: `ftl.amazon.aws.ec2_instance(...)` chains `NamespaceProxy(\"amazon\")` → `.aws` → `NamespaceProxy(\"amazon.aws\")` → `.ec2_instance()` executes `\"amazon.aws.ec2_instance\"`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-fqcn-via-namespace-proxy-chaining.json"},{"id":"automation-inventory-parameter","text":"The `inventory` parameter on `automation()` loads a YAML inventory file for host/group definitions, used alongside `add_host()` for hybrid static+dynamic inventory.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-inventory-parameter.json"},{"id":"automation-module-restriction-raises-attributeerror","text":"`automation(modules=[\"file\", \"copy\"])` restricts which modules can be called; accessing a disallowed module raises `AttributeError`, not a runtime module error.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-module-restriction-raises-attributeerror.json"},{"id":"automation-modules-as-attributes","text":"Modules are called as attributes on the automation context: `await ftl.module_name(param=value)` — no string lookups or dictionaries needed.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-modules-as-attributes.json"},{"id":"automation-modules-parameter-restricts-available","text":"`automation(modules=[\"file\", \"copy\"])` restricts which modules are available; calling an unlisted module raises `AttributeError`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-modules-parameter-restricts-available.json"},{"id":"automation-quiet-parameter","text":"`automation(quiet=True)` suppresses all console output during execution. Combined with `fail_fast=True`, this is the standard pattern for programmatic/embedded usage (TUI, watchdog, CI).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-quiet-parameter.json"},{"id":"automation-results-categorized-changed-ok-failed","text":"Task results in the automation context are categorized as `changed`, `ok`, or `failed`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-results-categorized-changed-ok-failed.json"},{"id":"automation-secrets-binding-parameter","text":"`automation(secrets=[\"KEY_NAME\", ...])` binds secrets for access via `ftl.secrets[\"KEY_NAME\"]` within module calls.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-secrets-binding-parameter.json"},{"id":"automation-secrets-key-error-semantics","text":"Accessing a secret not in the requested list raises `KeyError: not requested`; a requested but unset environment variable raises `KeyError: not set in environment` — two distinct error cases.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-secrets-key-error-semantics.json"},{"id":"automation-secrets-never-exposed-in-repr","text":"`ftl.secrets` values are never exposed in `print()` or `repr()` — this is a security feature of the secrets proxy.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-secrets-never-exposed-in-repr.json"},{"id":"automation-verbose-parameter-enables-debug","text":"`automation(verbose=True)` enables verbose/debug output for the automation session.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/automation-verbose-parameter-enables-debug.json"},{"id":"autonomous-error-resilient-operations","text":"AI-loop operations are resilient at every layer: coordinated cross-rule self-healing recovers from drift via observe/condition/action with state-file-mediated communication, while dual error modes (continue-on-error for collection, fail-fast for halt) capture structured errors alongside state persistence for crash recovery.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/autonomous-error-resilient-operations.json"},{"id":"autonomous-self-healing-infrastructure-apps","text":"FTL2 enables autonomous self-healing infrastructure applications: durable AI-loop remediation (observe/condition/action with fail-open, persistent state for crash recovery) operates within a full application framework (long-lived daemons, real-time monitoring via htop, event/gate/SSH pipeline).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/autonomous-self-healing-infrastructure-apps.json"},{"id":"azure-credentials-use-four-env-vars","text":"Azure authentication uses a service principal configured via four environment variables: `AZURE_CLIENT_ID`, `AZURE_SECRET`, `AZURE_SUBSCRIPTION_ID`, and `AZURE_TENANT`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/azure-credentials-use-four-env-vars.json"},{"id":"azure-state-file-name","text":"The Azure examples use `.ftl2-state-azure.json` as the state file for tracking provisioned resources.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/azure-state-file-name.json"},{"id":"backup-and-state-operational-durability","text":"FTL2 achieves operational durability through complementary persistence mechanisms: the state file tracks resource identity and enables crash recovery (control plane), while the backup subsystem preserves file contents before destructive changes (data plane) — together they protect both what exists and what it contains.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backup-and-state-operational-durability.json"},{"id":"backup-comprehensive-subsystem","text":"FTL2's backup subsystem is comprehensive and safe by default: automatic backups are enabled for destructive operations, two-phase protocol (discover paths, then create backups) ensures correctness, two storage modes (adjacent and central) provide deployment flexibility, consistent naming convention enables discovery, and fail-safe semantics abort operations rather than proceeding without a backup.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backup-comprehensive-subsystem.json"},{"id":"backup-failsafe-aborts-on-failure","text":"If backup creation fails, FTL2 aborts the destructive operation rather than proceeding without a backup (fail-safe behavior).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backup-failsafe-aborts-on-failure.json"},{"id":"backup-naming-convention","text":"FTL2 backup files are named `{original_path}.ftl2-backup-{YYYYMMDD}-{HHMMSS}`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backup-naming-convention.json"},{"id":"backup-paths-by-game-type","text":"Backup discovery uses game-type-specific paths: `~/data/minecraft/backups/` for Minecraft/NeoForge and `~/data/terraria/backups/` for Terraria, sorted newest-first by mtime.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backup-paths-by-game-type.json"},{"id":"backup-two-phase-protocol","text":"FTL2 backups use a two-phase protocol: Phase 1 discovers paths needing backup (`_ftl2_discover_backups: true`), Phase 2 executes with `_ftl2_backups_created` metadata attached.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backup-two-phase-protocol.json"},{"id":"backup-two-storage-modes","text":"FTL2 backups support two storage modes: adjacent (default, next to original file) and central (configured via `backup.central_dir` or `--backup-dir`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backup-two-storage-modes.json"},{"id":"backups-enabled-by-default","text":"FTL2 automatic backups are enabled by default for destructive module operations; use `--no-backup` to disable them.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/backups-enabled-by-default.json"},{"id":"become-copy-uses-temp-then-sudo-mv","text":"When privilege escalation is active, `copy` SFTPs files to `/tmp/.ftl2_copy_*` then uses `sudo mv` to place them at the destination.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/become-copy-uses-temp-then-sudo-mv.json"},{"id":"become-user-for-unprivileged-ops","text":"FTL2 supports `become_user` parameter on module calls to run operations as a specific unprivileged user rather than root — e.g., `become_user=SERVICE_USER` for `uv` installs.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/become-user-for-unprivileged-ops.json"},{"id":"bracket-notation-for-dashed-hostnames","text":"Bracket notation `ftl[\"hostname\"]` supports host names with dashes that cannot be used with dot-access syntax.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/bracket-notation-for-dashed-hostnames.json"},{"id":"builtin-modules-in-process-collection-subprocess","text":"FTL2 builtin modules (file, copy, shell, command, service, dnf) run in-process as native implementations; collection modules fall back to subprocess execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/builtin-modules-in-process-collection-subprocess.json"},{"id":"bundle-content-hashing-deduplication","text":"`build_bundle()` produces bundles with `info.content_hash`; `stage_bundle_remote()` uses this hash for deduplication — skipping re-upload if the hash matches what's already staged.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/bundle-content-hashing-deduplication.json"},{"id":"bundled-ansible-modules-can-emit-ftl2-events","text":"Bundled Ansible modules running inside FTL2 can import `ftl2.events` and emit events using `emit_progress()`, `emit_log()`, `emit_data()` — this is an FTL2-specific extension, not standard Ansible.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/bundled-ansible-modules-can-emit-ftl2-events.json"},{"id":"caddy-rule-idempotent-action","text":"The Caddy rule's action phase is idempotent: `copy` overwrites the Caddyfile, `firewalld` with `state=\"enabled\"` is a no-op if already enabled, and `service` with `state=\"started\"` is a no-op if already running.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/caddy-rule-idempotent-action.json"},{"id":"catbeez-arcade-app-binds-localhost-only","text":"The catbeez-arcade application binds to 127.0.0.1:8000 (localhost only) and is not directly accessible from the internet.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-arcade-app-binds-localhost-only.json"},{"id":"catbeez-arcade-caddy-reverse-proxy-to-8000","text":"Catbeez-arcade deployments use Caddy as a reverse proxy, terminating TLS on :443 and forwarding to the application on localhost:8000.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-arcade-caddy-reverse-proxy-to-8000.json"},{"id":"catbeez-arcade-dns-only-not-proxied","text":"Catbeez-arcade Cloudflare DNS records are set to DNS-only (not proxied), so TLS is handled by Caddy/Let's Encrypt rather than Cloudflare.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-arcade-dns-only-not-proxied.json"},{"id":"catbeez-arcade-manual-secret-injection","text":"Catbeez-arcade secrets (OAuth credentials, secret key, allowed emails) are entered interactively at startup rather than stored in automation or config files.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-arcade-manual-secret-injection.json"},{"id":"catbeez-arcade-port-80-required-for-acme","text":"Firewall port 80 must be opened for Let's Encrypt ACME challenges even though traffic is served on port 443.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-arcade-port-80-required-for-acme.json"},{"id":"catbeez-arcade-private-linode-image-37121878","text":"Catbeez-arcade uses a private Linode image `private/37121878` (Fedora 43 with Caddy pre-installed) to skip base configuration during provisioning.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-arcade-private-linode-image-37121878.json"},{"id":"catbeez-complete-deployment-pattern","text":"Catbeez demonstrates an FTL2 deployment pattern that combines three production concerns: layered security (localhost binding, Caddy TLS, firewalld drop zone, SSH source-IP restriction, SELinux), DNS-to-TLS automation (Cloudflare DNS-only records enabling Caddy ACME challenges), and hot-reload publishing (HTML5/WASM asset upload with dynamic discovery, no restart required) — illustrating how these concerns compose in a web application hosting scenario.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-complete-deployment-pattern.json"},{"id":"catbeez-dev-cloudflare-dns-automated","text":"The catbeez dev deployment automates DNS via `community.general.cloudflare_dns` module, unlike the prod deployment which uses manual Namecheap DNS.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-dev-cloudflare-dns-automated.json"},{"id":"catbeez-firewalld-drop-zone","text":"Catbeez deployments use firewalld's `drop` zone, which silently discards all uninvited traffic, with explicit allowances for HTTP, HTTPS, and restricted SSH.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-firewalld-drop-zone.json"},{"id":"catbeez-game-files-are-html-js-wasm","text":"Catbeez game assets consist of three file types: `.html`, `.js`, and `.wasm` — these are browser-based HTML5/WASM games.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-game-files-are-html-js-wasm.json"},{"id":"catbeez-hot-reload-publishing","text":"Catbeez game publishing is a hot-reload pipeline: HTML5/WASM game assets are uploaded to the games directory, and the server discovers new files dynamically without restart, with the same publish script supporting both dev and prod environments via flag selection.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-hot-reload-publishing.json"},{"id":"catbeez-layered-security","text":"Catbeez deployments implement layered security: application binds localhost-only, Caddy terminates TLS and reverse-proxies, firewalld drop zone silently discards uninvited traffic, SSH is restricted to a source IP range, and SELinux enforces network connect policy.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-layered-security.json"},{"id":"catbeez-prod-become-user-for-service-account","text":"The catbeez production deployment uses `become_user='catbeez'` to run application installation as the service user rather than as root.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-prod-become-user-for-service-account.json"},{"id":"catbeez-prod-game-files-uploaded-individually","text":"Game files are uploaded individually (3 files per game × 9 games = 27 copy calls) rather than as an archive.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-prod-game-files-uploaded-individually.json"},{"id":"catbeez-prod-manual-dns-at-namecheap","text":"The catbeez production deployment requires manual DNS A record creation at Namecheap — DNS is not automated in the prod deploy script.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-prod-manual-dns-at-namecheap.json"},{"id":"catbeez-prod-ssh-restricted-to-source-ip","text":"The catbeez production deployment restricts SSH access to `136.56.0.0/16` via firewalld; HTTP/HTTPS are open to all.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-prod-ssh-restricted-to-source-ip.json"},{"id":"catbeez-publish-games-dev-prod-environments","text":"`publish-games.py` supports dev and prod environments: dev uses `state.json` and hostname `arcade`; prod (via `--prod` flag) uses `state-prod.json` and hostname `catbeez-prod`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-publish-games-dev-prod-environments.json"},{"id":"catbeez-publish-games-no-restart-needed","text":"The catbeez-arcade server discovers new game files dynamically — publishing games is purely a file upload to `/home/catbeez/games/` with no application restart required.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-publish-games-no-restart-needed.json"},{"id":"catbeez-publish-games-requires-existing-state-file","text":"The publish-games script reads an existing state file to extract host connection info — the state file must already exist from a prior provisioning run.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-publish-games-requires-existing-state-file.json"},{"id":"catbeez-selinux-httpd-can-network-connect","text":"Catbeez deployments set the `httpd_can_network_connect` SELinux boolean so Caddy can reverse-proxy to localhost:8000 under SELinux enforcing mode.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/catbeez-selinux-httpd-can-network-connect.json"},{"id":"check-mode-enabled-via-check-mode-true","text":"`automation(check_mode=True)` enables dry-run mode where operations report what would change without executing.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/check-mode-enabled-via-check-mode-true.json"},{"id":"check-mode-not-all-modules-support","text":"Not all modules fully support check mode — some may still create files or execute commands despite check mode being enabled.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/check-mode-not-all-modules-support.json"},{"id":"check-mode-results-still-accumulate","text":"`ftl.results` collects results from all operations even in check mode, enabling post-run analysis.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/check-mode-results-still-accumulate.json"},{"id":"check-mode-validate-then-execute-pattern","text":"The recommended workflow for critical operations is validate-then-execute: run check mode first, inspect for failures, then execute for real only if validation passes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/check-mode-validate-then-execute-pattern.json"},{"id":"cli-rich-targeting-ansible-familiar","text":"The FTL2 CLI provides Ansible-familiar syntax with rich targeting capabilities: the `-m -i -a` flag pattern mirrors Ansible, shlex parsing handles quoted arguments correctly, the --limit flag supports group names, host names, glob patterns, and `!` exclusion, and three run modes (normal, check, teardown) cover the full lifecycle.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cli-rich-targeting-ansible-familiar.json"},{"id":"cloud-to-configured-host-pipeline","text":"FTL2 supports a provision-then-configure workflow within a single run: `add_host()` dynamically registers a newly created host with connection parameters and group assignment, and a two-phase bootstrap pattern (root → admin re-registration) can harden access before applying configuration. State persistence across these steps supports crash recovery and re-runs.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloud-to-configured-host-pipeline.json"},{"id":"cloudflare-caddy-tls-deployment-pattern","text":"FTL2 deployments use a consistent Cloudflare+Caddy TLS pattern: Cloudflare DNS records are set to DNS-only (not proxied) so Caddy can perform Let's Encrypt ACME challenges on port 80 and terminate TLS directly, avoiding certificate conflicts between Cloudflare and the origin server.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-caddy-tls-deployment-pattern.json"},{"id":"cloudflare-dns-module-fqcn","text":"The Cloudflare DNS module is accessed via `ftl.community.general.cloudflare_dns()` with parameters: `zone`, `record`, `type`, `value`, `proxied`, `state`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-dns-module-fqcn.json"},{"id":"cloudflare-dns-only-for-caddy-acme","text":"When using Caddy for automatic TLS via Let's Encrypt, Cloudflare DNS must be set to DNS-only mode (not proxied) so Caddy can perform its own ACME HTTP-01 challenge on port 80.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-dns-only-for-caddy-acme.json"},{"id":"cloudflare-dns-records-ttl-300-not-proxied","text":"Cloudflare DNS records are created with TTL 300 seconds and `proxied: False` (DNS-only), and these settings are hardcoded, not configurable via parameters.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-dns-records-ttl-300-not-proxied.json"},{"id":"cloudflare-module-stdlib-only","text":"The Cloudflare DNS module uses only Python stdlib (`urllib.request`) with no external HTTP dependencies and no FTL2 framework imports.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-module-stdlib-only.json"},{"id":"cloudflare-update-dns-idempotent","text":"The `update_dns_record` function is idempotent: it creates the record if missing, updates it if the IP changed, and skips the API call entirely if the record already matches.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-update-dns-idempotent.json"},{"id":"cloudflare-update-dns-record-single-entry-point","text":"The `update_dns_record` function is the single public entry point for Cloudflare DNS management in ftl2-servercraft.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-update-dns-record-single-entry-point.json"},{"id":"cloudflare-zone-lookup-last-two-domain-parts","text":"Zone lookup extracts the root domain from the hostname by taking the last two domain parts (e.g., `world1.servercraft2.com` → `servercraft2.com`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/cloudflare-zone-lookup-last-two-domain-parts.json"},{"id":"command-execution-dual-governance","text":"Command execution in FTL2 is governed at two independent levels: the policy engine enforces pre-execution access control (deny rules matching module, host, environment, and parameters with first-match semantics), while the command/shell distinction controls injection exposure at runtime (command runs without shell interpretation, shell enables pipes but triggers the same policy deny as command and raw).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/command-execution-dual-governance.json"},{"id":"command-execution-security-model","text":"FTL2's command execution model balances power with safety: `command` runs without shell interpretation (injection-safe), `shell` enables pipes and redirects (more powerful), `creates` provides idempotency for both, and the policy engine treats command/shell/raw as equivalent — denying any one blocks all three to prevent circumvention.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/command-execution-security-model.json"},{"id":"community-modules-called-on-ftl-directly","text":"Community modules are called on the `ftl` object directly (not on a host) — e.g., `ftl.community.general.linode_v4(...)`, `ftl.community.general.cloudflare_dns(...)` — because they target external APIs, not a specific managed host.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/community-modules-called-on-ftl-directly.json"},{"id":"compiled-deps-cannot-bundle-in-gate-pyz","text":"Compiled dependencies (C extensions like psutil) cannot be bundled in the gate `.pyz` package; they must be pre-installed on the remote host via `dnf`/`apt`. Pure-Python deps go in the `.pyz` bundle.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/compiled-deps-cannot-bundle-in-gate-pyz.json"},{"id":"complete-developer-to-production-continuity","text":"FTL2 provides continuity from development to production: the same automation() context manager, module addressing, and error handling API used during development also drives production deployments — production scripts add parameters like state_file, fail_fast, and secret_bindings but use the same core API surface, with no separate deployment-specific interface required.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/complete-developer-to-production-continuity.json"},{"id":"complete-execution-feedback-pipeline","text":"FTL2 provides a three-tier execution feedback pipeline: consistent result objects (success, changed, output, error) provide synchronous control-flow data, configurable display modes (errors-only through verbose timing) shape human-readable output, and parallel event streaming (progress, log, status) delivers structured data for programmatic observability.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/complete-execution-feedback-pipeline.json"},{"id":"complete-failure-capture-and-recovery","text":"FTL2 combines structured error handling with execution feedback and state persistence to support failure recovery: dual error modes (continue-on-error and fail-fast) capture structured error information, a three-tier feedback pipeline (result objects, display modes, event streaming) provides both control-flow data and programmatic observability, and state persistence allows subsequent runs to resume from where a failure occurred rather than starting over.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/complete-failure-capture-and-recovery.json"},{"id":"complete-targeting-to-execution-pipeline","text":"FTL2 provides a unified pipeline from host selection to module execution: the CLI's rich pattern-based targeting (groups, globs, exclusions) feeds into flexible multi-format inventory resolution, which feeds into four module addressing syntaxes — creating a seamless path from \"which hosts\" to \"what action.\"","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/complete-targeting-to-execution-pipeline.json"},{"id":"comprehensive-crash-resilience","text":"FTL2 achieves comprehensive crash resilience through three independent mechanisms: persistent state files enable re-run recovery from any interruption, automatic backups protect filesystem changes with fail-safe abort, and dual error modes capture failures without halting — every failure path leads to a recoverable state.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/comprehensive-crash-resilience.json"},{"id":"comprehensive-operational-observability","text":"FTL2 provides comprehensive operational observability across automation and infrastructure: the event streaming subsystem captures structured module execution data (progress/log/status events always in results), while ftl2-htop delivers real-time system metrics (CPU, memory, network) via SSH-gate-psutil pipeline — together covering both application-level task tracking and system-level resource monitoring.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/comprehensive-operational-observability.json"},{"id":"comprehensive-security-credentials-to-edge","text":"FTL2 provides layered security from credential storage to network edge: the secrets management spectrum (env bindings, Vault integration, lazy evaluation, defense-in-depth practices like redaction and never-logging) complements a layered deployment security model (two-phase bootstrap, firewalld drop zone, SELinux, SSH restriction, Cloudflare DNS-only, Caddy TLS termination), supporting credential protection across storage, transit, and serving layers.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/comprehensive-security-credentials-to-edge.json"},{"id":"config-paths-support-tilde-expansion","text":"The `state_path`, `inventory_path`, and `config_dir_path` properties all call `expanduser()`, so `~` is valid in configuration values.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/config-paths-support-tilde-expansion.json"},{"id":"coordinated-cross-rule-self-healing","text":"AI-loop rules achieve coordinated multi-rule self-healing: the three-phase contract (observe/condition/action with fail-open and guard clauses) operates on shared persistent state, enabling rules to read each other's outputs, defer when prerequisites are missing, and converge toward a complex desired state that no single rule could reach alone.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/coordinated-cross-rule-self-healing.json"},{"id":"copy-fan-out-uses-asyncio-gather","text":"The native `copy` module uses `asyncio.gather` to transfer files to all hosts in a group concurrently.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/copy-fan-out-uses-asyncio-gather.json"},{"id":"crash-and-error-resilient-autonomy","text":"FTL2 combines crash recovery and error-resilient AI-loop operations to support autonomous recovery from many failure scenarios without manual intervention: three independent crash recovery mechanisms (persistent state files for re-run recovery, automatic backups with fail-safe abort, and dual error modes for failure capture) complement the AI-loop's self-healing capabilities (observe/condition/action with state-file-mediated coordination and structured error collection), providing multiple recovery paths for both unplanned crashes and runtime errors.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/crash-and-error-resilient-autonomy.json"},{"id":"crash-resilient-autonomous-remediation","text":"The AI loop achieves durable autonomous remediation: self-healing observation/condition/action with fail-open semantics feeds into persistent state that survives process crashes, enabling the reconciliation loop to resume convergence from where it left off rather than starting over.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/crash-resilient-autonomous-remediation.json"},{"id":"crash-resilient-error-management","text":"FTL2 provides crash-resilient error management: dual error modes (continue-on-error for collection, fail-fast for immediate halt) capture structured error information, while state persistence ensures that after any failure — whether collected or raised — the next run can resume from persisted state rather than starting over.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/crash-resilient-error-management.json"},{"id":"declarative-resource-planning-topological-sort","text":"Declarative resource planning uses topological sort for parallel execution waves and reverse order for teardown.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/declarative-resource-planning-topological-sort.json"},{"id":"default-error-behavior-continue-on-error","text":"FTL2's default behavior is continue-on-error: all operations execute regardless of individual failures, with errors collected and inspectable after the run.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/default-error-behavior-continue-on-error.json"},{"id":"default-output-shows-errors-only","text":"Default output mode shows nothing for successful operations — only errors surface.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/default-output-shows-errors-only.json"},{"id":"default-state-file-is-ftl2-state-json","text":"The default state file path is `.ftl2-state.json`; it enables crash recovery by persisting dynamically added hosts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/default-state-file-is-ftl2-state-json.json"},{"id":"defense-in-depth-bootstrap-to-edge","text":"FTL2 deployments achieve defense-in-depth from host bootstrap to network edge: two-phase registration hardens host access before content deployment, layered security (firewalld drop zone, SELinux, SSH restriction) protects the host perimeter, and Cloudflare DNS-only + Caddy TLS secures the network edge with Let's Encrypt ACME.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/defense-in-depth-bootstrap-to-edge.json"},{"id":"deployment-credentials-integrated-security","text":"Credentials are integrated into the security-first deployment lifecycle: defense-in-depth prevents exposure at every surface (bindings, repr, logs) while security-first ordering ensures secrets only flow through hardened, bootstrapped channels — the two-phase registration hardens access before any credentials are injected.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/deployment-credentials-integrated-security.json"},{"id":"deployment-incremental-verification-pattern","text":"FTL2 deployments follow an incremental verification pattern: each layer (DNS, TLS, services) is confirmed working before proceeding to the next.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/deployment-incremental-verification-pattern.json"},{"id":"deployment-security-first-lifecycle","text":"FTL2 production deployments can follow a security-first lifecycle from bootstrap to runtime: two-phase host registration hardens access before content deployment, and runtime protection layers (such as localhost binding, reverse proxy TLS termination, firewalld drop zone, SELinux booleans, and SSH IP restrictions) provide defense-in-depth at network boundaries, as demonstrated in the Catbeez deployment pattern.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/deployment-security-first-lifecycle.json"},{"id":"desired-state-markdown-scripts-disposable","text":"In the desired-state-as-markdown model, scripts are disposable and regenerated — the state file is ground truth, not the scripts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/desired-state-markdown-scripts-disposable.json"},{"id":"developer-to-autonomous-operations-continuum","text":"FTL2 bridges the complete spectrum from developer onboarding to autonomous production operations: zero-setup scripts with familiar APIs and full observability enable rapid development, which seamlessly transitions to autonomous self-healing production through the same unified API surface — the identical async context manager, module addressing, and state management work at every stage of the journey.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/developer-to-autonomous-operations-continuum.json"},{"id":"direct-module-calls-local-only-run-on-for-remote","text":"Direct module calls (`ftl.file(...)`) execute locally and return a dict; `ftl.run_on()` is required for remote/multi-host execution and returns a list of result objects with `.host`, `.success`, `.changed`, `.output`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/direct-module-calls-local-only-run-on-for-remote.json"},{"id":"diverse-application-hosting-platform","text":"FTL2 serves as a hosting platform for diverse application types: long-lived daemon contexts with event/gate/SSH infrastructure support game server lifecycle management (servercraft with watchdog, TUI, backup), while the same provisioning pipeline supports hot-reload web applications (catbeez arcade) where publishing is purely file upload with no restart.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/diverse-application-hosting-platform.json"},{"id":"dual-audience-minimal-barrier-onboarding","text":"FTL2 minimizes learning investment for both new and migrating users simultaneously: newcomers start immediately with PEP 723 single-file scripts that self-bootstrap via uv run with no project scaffolding, while Ansible users recognize CLI flags (`-m -i -a`), variable precedence (group < host < argument), inventory groups, and FQCN module naming.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/dual-audience-minimal-barrier-onboarding.json"},{"id":"dual-onramp-unified-production","text":"FTL2 offers two complementary onramps to production-grade automation: greenfield developers can start with zero-setup PEP 723 scripts and progress to optimized cloud execution without intermediate tooling, while Ansible teams can migrate gradually by retaining familiar patterns (CLI, inventory, FQCN, variable precedence) and immediately gaining state-driven reliability and security-first lifecycle features. Both paths lead to production-capable deployments, though the specific observability and security characteristics available depend on which features each path exercises.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/dual-onramp-unified-production.json"},{"id":"dynamic-host-complete-lifecycle","text":"`ftl.add_host()` provides a complete dynamic host lifecycle: runtime registration with connection parameters and group assignment, immediate state persistence, and instant attribute-style addressing (`ftl.hostname`) — enabling provisioning scripts to create infrastructure and configure it in a single run.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/dynamic-host-complete-lifecycle.json"},{"id":"dynamic-hosts-full-security-lifecycle","text":"FTL2's unified inventory model means dynamically provisioned hosts can receive the same security treatment as static infrastructure: add_host registration integrates runtime-discovered hosts into the same addressing model where security-first lifecycle patterns — such as two-phase bootstrap, security-before-content ordering, and layered network hardening — can be applied consistently, rather than requiring separate or reduced security workflows for dynamic hosts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/dynamic-hosts-full-security-lifecycle.json"},{"id":"edge-to-application-security-perimeter","text":"FTL2 deployments can implement a layered edge-to-application security perimeter. In observed patterns, Cloudflare DNS-only mode delegates TLS to Caddy (enabling Let's Encrypt ACME), Caddy terminates HTTPS and reverse-proxies to a localhost-only application, firewalld's drop zone silently discards uninvited traffic, SSH is restricted to source IP ranges, and SELinux enforces network connect policies. This pattern has been documented in catbeez deployments and the Cloudflare+Caddy TLS approach is used consistently across FTL2 deployments.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/edge-to-application-security-perimeter.json"},{"id":"end-to-end-remote-execution-optimization","text":"FTL2 optimizes remote execution end-to-end from connection to result: the SSH layer pools and reuses connections via asyncssh for async non-blocking I/O, while the gate layer pre-builds modules into cached zipapps that communicate via length-prefixed JSON — eliminating overhead at both the transport and module delivery layers.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/end-to-end-remote-execution-optimization.json"},{"id":"error-handling-dual-mode","text":"FTL2 provides two error handling modes: continue-on-error (default) collects all failures in ftl.errors for post-run analysis, while fail-fast raises AutomationError on first failure with module identification via the .result attribute.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/error-handling-dual-mode.json"},{"id":"event-callbacks-are-synchronous","text":"Event callbacks passed via `on_event` fire synchronously during execution — the callback is a plain function, not a coroutine.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/event-callbacks-are-synchronous.json"},{"id":"event-driven-application-architecture","text":"FTL2 supports event-driven application architectures: the complete event streaming subsystem (three event types, always-captured results, structured callbacks) combined with the listen/gather concurrency pattern enables long-running applications to react to infrastructure events in real-time alongside application logic.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/event-driven-application-architecture.json"},{"id":"event-handlers-registered-via-proxy-on","text":"Event handlers are registered via `proxy.on(event_type, handler)`; both sync and async handlers are supported, and multiple handlers per event type are allowed.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/event-handlers-registered-via-proxy-on.json"},{"id":"event-progress-display-requires-rich","text":"`EventProgressDisplay` requires the Rich library; `SimpleEventDisplay` has no Rich dependency.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/event-progress-display-requires-rich.json"},{"id":"event-streaming-complete-subsystem","text":"FTL2 provides an event streaming subsystem with three event types (progress, log, data) for structured observability. Events are always captured in results regardless of callback registration. Structured dict payloads with fields like event, module, host, success, changed, duration, and timestamp enable programmatic consumption. Handler registration via proxy.on() supports both sync and async handlers, with multiple handlers per event type.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/event-streaming-complete-subsystem.json"},{"id":"event-streaming-three-event-types","text":"FTL2's event streaming system has three event types: `progress` (percent/bytes tracking), `log` (leveled messages: info/warning/error), and `data` (raw stdout/stderr streams).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/event-streaming-three-event-types.json"},{"id":"event-system-observability-and-control","text":"FTL2's event streaming serves dual purposes that reinforce each other: operational observability (structured module events captured in results plus ftl2-htop real-time monitoring) AND application-level event-driven control (ftl.listen() with asyncio.gather for concurrent event processing), using the same three event types for both.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/event-system-observability-and-control.json"},{"id":"events-always-captured-in-result","text":"Events are always captured in `result.events` regardless of whether an `event_callback` is registered — callbacks are optional.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/events-always-captured-in-result.json"},{"id":"events-are-json-on-stderr","text":"Modules emit events as JSON objects to stderr, one per line. Stdout is reserved for the final result JSON — events on stdout would corrupt the result.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/events-are-json-on-stderr.json"},{"id":"execution-dual-mode-architecture","text":"FTL2 provides a dual-mode execution architecture: native in-process modules for speed and Ansible-compatible bundled modules for ecosystem breadth, with the same API surface for both.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/execution-dual-mode-architecture.json"},{"id":"execution-secured-and-instrumented-end-to-end","text":"Every FTL2 module execution from CLI target selection through result delivery is both secured and fully instrumented: rich pattern-based targeting feeds through policy enforcement, credential injection, and privilege escalation controls, while structured events, consistent result contracts, and flexible output modes provide complete execution telemetry.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/execution-secured-and-instrumented-end-to-end.json"},{"id":"fail-fast-false-collects-errors-default","text":"By default (`fail_fast=False`), errors are collected in `ftl.errors` and execution continues; `fail_fast=True` raises `AutomationError` on first failure.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fail-fast-false-collects-errors-default.json"},{"id":"fail-fast-raises-automation-error","text":"`automation(fail_fast=True)` raises `AutomationError` immediately on the first module failure, stopping all subsequent operations.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fail-fast-raises-automation-error.json"},{"id":"failed-observe-triggers-action","text":"When an AI-loop rule's observe call itself fails (e.g., API error), the condition returns `True`, treating observation failure as \"needs fix\" — a defensive pattern.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/failed-observe-triggers-action.json"},{"id":"fast-resilient-fleet-execution","text":"FTL2 fleet operations are simultaneously fast and resilient: SSH connection pooling with async I/O and gate caching minimize per-host overhead, default parallelism bounds execution to the slowest host, and failure isolation ensures fleet execution continues and collects structured errors even when individual hosts fail.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fast-resilient-fleet-execution.json"},{"id":"file-module-state-touch-absent","text":"The FTL2 `file` module uses `state=touch` to create files and `state=absent` to remove them.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/file-module-state-touch-absent.json"},{"id":"firewalld-module-available","text":"FTL2 provides access to the `ansible.posix.firewalld` module for managing firewall rules (services, ports, zones) via the FQCN pattern.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/firewalld-module-available.json"},{"id":"fqcn-chains-through-host-proxy","text":"FQCN module names chain through the host-scoped proxy — e.g., `ftl.webservers.ansible.builtin.command(cmd=...)` works correctly.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fqcn-chains-through-host-proxy.json"},{"id":"fqcn-module-names-supported","text":"FTL2 supports Ansible-style fully qualified collection names (FQCN) for modules, e.g., `ftl.local.ansible.builtin.ping()`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fqcn-module-names-supported.json"},{"id":"fqcn-modules-require-ansible-collection-installed","text":"FQCN modules (e.g., `amazon.aws.ec2_instance`) require the corresponding Ansible collection to be installed to function.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fqcn-modules-require-ansible-collection-installed.json"},{"id":"frictionless-full-ecosystem-experience","text":"Developers get a frictionless full-ecosystem experience: zero-setup PEP 723/uv scripts eliminate project scaffolding while the dual-mode architecture provides native speed and Ansible ecosystem breadth, all accessed through a unified async context manager with four addressing syntaxes and dual error handling.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/frictionless-full-ecosystem-experience.json"},{"id":"ftl-ansible-compat-requires-packages","text":"Ansible module compatibility in FTL2 requires the `ftl_builtin_modules` and `ftl_module_utils` packages to be installed.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-ansible-compat-requires-packages.json"},{"id":"ftl-ansible-module-stdlib-shadowing","text":"Some Ansible modules (e.g., `tempfile.py`) shadow Python standard library modules, causing failures outside the full Ansible runtime — this is a known limitation.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-ansible-module-stdlib-shadowing.json"},{"id":"ftl-bundle-system-packages-with-deps","text":"`build_bundle_from_fqcn` packages an Ansible module with its dependencies into a transferable bundle with `fqcn`, `content_hash`, `size`, and `dependency_count` attributes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-bundle-system-packages-with-deps.json"},{"id":"ftl-command-creates-parameter-idempotency","text":"The `creates` parameter on `ftl_command` skips execution if the specified file already exists, providing idempotency for command execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-command-creates-parameter-idempotency.json"},{"id":"ftl-command-vs-shell-distinction","text":"`ftl_command` runs commands directly without shell interpretation; `ftl_shell` runs through a shell and supports pipes (`|`) and environment variable expansion (`$HOME`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-command-vs-shell-distinction.json"},{"id":"ftl-copy-backup-preserves-previous","text":"`ftl_copy` with `backup=True` preserves the previous version of the destination file before overwriting.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-copy-backup-preserves-previous.json"},{"id":"ftl-eight-builtin-modules","text":"FTL2 has eight built-in native modules: `file`, `copy`, `template`, `command`, `shell`, `uri`, `get_url`, and `pip`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-eight-builtin-modules.json"},{"id":"ftl-errors-captured-not-raised","text":"FTL2 module errors don't raise exceptions — they are captured in result objects with `success=False` and an `error` message.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-errors-captured-not-raised.json"},{"id":"ftl-execute-batch-concurrent-speedup","text":"`execute_batch` provides near-linear speedup over sequential `execute()` calls by running tasks concurrently via asyncio.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-execute-batch-concurrent-speedup.json"},{"id":"ftl-execute-batch-tuple-format","text":"`execute_batch` accepts tasks as a list of `(module_name, params_dict, host_or_none)` tuples.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-execute-batch-tuple-format.json"},{"id":"ftl-execute-local-fqcn-function","text":"`execute_local_fqcn(fqcn, params_dict)` executes an Ansible module locally by its fully-qualified collection name, returning an `ExecutionResult`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-execute-local-fqcn-function.json"},{"id":"ftl-execution-result-fields","text":"`ExecutionResult` has four fields: `success` (bool), `output` (dict), `error` (str|None), and `changed` (bool).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-execution-result-fields.json"},{"id":"ftl-executor-api-recommended","text":"The Executor API (`execute`/`run`/`execute_on_hosts`) is the recommended API for FTL2 module execution, not direct function calls.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-executor-api-recommended.json"},{"id":"ftl-executor-result-attributes","text":"The Executor API returns result objects with `.success`, `.changed`, and `.output` attributes, while raw `ftl_*` functions return plain dicts with a `changed` key.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-executor-result-attributes.json"},{"id":"ftl-failed-and-errors-properties","text":"`ftl.failed` is a bool indicating if any operation failed; `ftl.errors` returns a list of failed `ExecuteResult` objects; `ftl.error_messages` returns just the error strings.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-failed-and-errors-properties.json"},{"id":"ftl-fetch-module-remote-to-local","text":"The `fetch` module copies files FROM remote hosts TO the control machine — the reverse of `copy`. Used for downloading backups and logs.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-fetch-module-remote-to-local.json"},{"id":"ftl-get-url-module","text":"The `get_url` module downloads files from URLs to remote hosts, used for fetching server JARs, installers, and other artifacts during provisioning.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-get-url-module.json"},{"id":"ftl-host-module-call-syntax","text":"Modules are called on hosts via `ftl[\"hostname\"].module_name(params...)` syntax — e.g., `ftl[\"arcade\"].shell(cmd=\"...\")`, `ftl[\"arcade\"].copy(src=..., dest=...)`, `ftl[\"arcade\"].file(path=..., state=\"directory\")`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-host-module-call-syntax.json"},{"id":"ftl-listen-blocks-requires-asyncio-gather","text":"`ftl.listen()` blocks and dispatches events; it must run concurrently with application logic via `asyncio.gather(ftl.listen(), app_coroutine())`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-listen-blocks-requires-asyncio-gather.json"},{"id":"ftl-local-for-api-cloud-modules","text":"`ftl.local` is used for API/cloud modules (equivalent to Ansible's `connection: local`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-local-for-api-cloud-modules.json"},{"id":"ftl-local-slack-notification-pattern","text":"FTL2 applications use `ftl.local.community.general.slack()` for sending Slack notifications from the control machine, wrapped in try/except to prevent notification failures from aborting infrastructure operations.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-local-slack-notification-pattern.json"},{"id":"ftl-localhost-abstraction","text":"`LocalHost(name=...)` creates a local execution target that enables the same API pattern used for remote hosts (`execute_on_hosts`) to work locally.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-localhost-abstraction.json"},{"id":"ftl-module-short-name-mapping","text":"The `execute()` and `run()` functions accept short module names (e.g., `'file'`, `'command'`) which map internally to the corresponding `ftl_file`/`ftl_command` functions.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-module-short-name-mapping.json"},{"id":"ftl-modules-in-process-execution","text":"FTL modules run as native Python functions inside the same process, eliminating subprocess overhead (fork/exec per task).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-modules-in-process-execution.json"},{"id":"ftl-modules-sent-by-name-ansible-as-bundles","text":"FTL modules are sent to the gate by name (gate already has them); Ansible modules are sent as bundles.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-modules-sent-by-name-ansible-as-bundles.json"},{"id":"ftl-modules-speedup-by-type","text":"FTL modules achieve ~330x speedup for file operations, ~84x for HTTP/uri operations, and ~7x for command execution compared to subprocess-based execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-modules-speedup-by-type.json"},{"id":"ftl-modules-track-changed-status","text":"FTL2 modules track idempotency via `changed` status — operations like touching an existing file or copying identical content return `changed=False`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-modules-track-changed-status.json"},{"id":"ftl-object-first-arg-to-script-functions","text":"The `ftl` object is passed as the first argument to all script interface functions — it is the primary handle for FTL2 automation operations within an application.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-object-first-arg-to-script-functions.json"},{"id":"ftl-remote-ssh-falls-back-to-ansible-bundling","text":"Remote execution via SSHHost falls back to Ansible module bundling when using the Executor — it does not run FTL functions in-process on the remote side.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-remote-ssh-falls-back-to-ansible-bundling.json"},{"id":"ftl-resolve-fqcn-maps-to-filesystem","text":"`resolve_fqcn` maps dotted Ansible FQCN strings (e.g., `ansible.builtin.command`) to filesystem paths via `find_ansible_builtin_path()`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-resolve-fqcn-maps-to-filesystem.json"},{"id":"ftl-results-success-and-changed-attributes","text":"`ftl.results` provides a list of module results, each with `.success` and `.changed` attributes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-results-success-and-changed-attributes.json"},{"id":"ftl-results-tracks-all-executions","text":"The automation context tracks all module executions in `ftl.results` — each entry has `.success`, `.changed`, and `.module` attributes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-results-tracks-all-executions.json"},{"id":"ftl-swap-module","text":"FTL2 provides a `swap` module for configuring swap space on remote hosts — used in game server provisioning where memory-intensive Java processes need swap.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-swap-module.json"},{"id":"ftl-two-api-surfaces","text":"FTL2 provides two API surfaces: direct synchronous function calls (`ftl_file()`, `ftl_command()`, etc.) and the async Executor API (`execute`, `run`, `execute_on_hosts`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl-two-api-surfaces.json"},{"id":"ftl2-add-host-bridges-provision-and-config","text":"`ftl.add_host()` registers a dynamically created server as an inventory host mid-run with connection parameters (`ansible_host`, `ansible_user`, group membership), enabling provisioning and configuration in the same script.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-add-host-bridges-provision-and-config.json"},{"id":"ftl2-ai-loop-action-receives-ftl-runtime","text":"The AI-loop `action(ftl)` function receives the FTL2 runtime, providing host accessors and module methods to perform remediation.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-action-receives-ftl-runtime.json"},{"id":"ftl2-ai-loop-condition-receives-state-dict","text":"The AI-loop `condition(state)` function receives observed state as a dict keyed by observation step name, where each value contains fields like `stdout`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-condition-receives-state-dict.json"},{"id":"ftl2-ai-loop-failed-observation-triggers-action","text":"In AI-loop rules, if an observe step fails (e.g., API error), the condition function can treat the failure as drift and return `True`, triggering the action to re-establish the resource.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-failed-observation-triggers-action.json"},{"id":"ftl2-ai-loop-full-convergence-on-any-drift","text":"AI-loop action functions apply all fixes (e.g., config, firewall, service) regardless of which specific condition check failed — a full convergence approach rather than targeted remediation.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-full-convergence-on-any-drift.json"},{"id":"ftl2-ai-loop-guard-clause-defers-to-prerequisites","text":"AI-loop condition functions can implement guard clauses that return `False` when prerequisite state doesn't exist yet, deferring to other rules that establish that state first.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-guard-clause-defers-to-prerequisites.json"},{"id":"ftl2-ai-loop-observe-condition-action-pattern","text":"FTL2 AI-loop rules follow a three-part observe/condition/action pattern: observe gathers current state, condition returns True if drift is detected, action converges to desired state.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-observe-condition-action-pattern.json"},{"id":"ftl2-ai-loop-observe-uses-shell-module","text":"AI-loop observe steps can use the `shell` (or `command`) module with `cmd` and `host` parameters to run arbitrary commands for state gathering.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-observe-uses-shell-module.json"},{"id":"ftl2-ai-loop-rules-auto-generated","text":"AI-loop rules can be auto-generated by the `ftl2-ai-loop` system, though they may contain artifacts like duplicate observe blocks.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-rules-auto-generated.json"},{"id":"ftl2-ai-loop-state-file-cross-rule-communication","text":"AI-loop rules can read state populated by other rules via `state._state_file.resources`, enabling cross-rule data flow (e.g., DNS rule reads IP from Linode provisioning rule's state).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-ai-loop-state-file-cross-rule-communication.json"},{"id":"ftl2-application-framework-beyond-automation","text":"FTL2 serves as a full application framework beyond one-shot automation: long-lived daemon contexts support persistent services, the event/gate/SSH pipeline enables real-time TUIs, and persistent state orchestrates multi-run workflows — demonstrated by servercraft (game lifecycle manager with watchdog and TUI dashboard) and ftl2-htop (real-time infrastructure monitoring).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-application-framework-beyond-automation.json"},{"id":"ftl2-apps-pep723-inline-metadata","text":"FTL2 applications can be single-file scripts using PEP 723 inline script metadata for dependency declarations, runnable via `uv run` with no virtualenv setup.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-apps-pep723-inline-metadata.json"},{"id":"ftl2-auto-install-deps-option","text":"The `automation()` context manager accepts `auto_install_deps=True` to automatically install missing Ansible collections at runtime.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-auto-install-deps-option.json"},{"id":"ftl2-automation-context-manager-pattern","text":"The core FTL2 usage pattern is the `automation()` async context manager, which accepts parameters like `state_file` and `secret_bindings`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-automation-context-manager-pattern.json"},{"id":"ftl2-builtin-groups-all-ungrouped","text":"FTL2 inventory always has two built-in groups: `all` (every host) and `ungrouped` (hosts not in any explicit group).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-builtin-groups-all-ungrouped.json"},{"id":"ftl2-calls-ansible-modules-in-process","text":"FTL2 calls Ansible modules in-process rather than as subprocesses — a core architectural difference from Ansible.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-calls-ansible-modules-in-process.json"},{"id":"ftl2-check-mode-skips-post-provision","text":"When `check_mode=True`, FTL2 scripts should skip post-provision configuration (SSH wait, package install, service setup) since resources don't actually exist in dry-run mode.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-check-mode-skips-post-provision.json"},{"id":"ftl2-cli-flag-pattern","text":"The FTL2 CLI uses the flag pattern `-m <module> -i <inventory> -a \"<args>\"`, mirroring Ansible's CLI syntax.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-cli-flag-pattern.json"},{"id":"ftl2-cli-uses-shlex-parsing","text":"The FTL2 CLI uses Python's `shlex` module for proper shell-style argument parsing, handling quoted strings like `cmd='echo hello'`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-cli-uses-shlex-parsing.json"},{"id":"ftl2-cloudflare-dns-proxied-false-for-caddy-tls","text":"When using Caddy for TLS termination, Cloudflare DNS records must be set with `proxied=False` to avoid certificate conflicts between Caddy and Cloudflare's proxy.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-cloudflare-dns-proxied-false-for-caddy-tls.json"},{"id":"ftl2-community-modules-fqcn-accessor","text":"Community modules are called via the `ftl.community.general.*()` accessor pattern using FQCN-style naming.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-community-modules-fqcn-accessor.json"},{"id":"ftl2-complete-production-platform","text":"FTL2 is a complete production platform: high performance without sacrificing ergonomics (async context manager, flexible addressing, dual error modes) combines with reliable and secure deployments (state-driven crash recovery, security-first lifecycle, two-phase bootstrap).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-complete-production-platform.json"},{"id":"ftl2-destroy-cleans-up-state-file","text":"The destroy script deletes the state file after a successful destroy or when the instance is already gone.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-destroy-cleans-up-state-file.json"},{"id":"ftl2-destroy-looks-up-by-label-not-id","text":"The Linode destroy script finds instances by matching the label against all instances from `GET /linode/instances`, not by stored instance ID.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-destroy-looks-up-by-label-not-id.json"},{"id":"ftl2-destroy-processes-first-resource-only","text":"The destroy script uses `next(iter(resources.values()))` and only processes the first resource in the state file, ignoring any others.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-destroy-processes-first-resource-only.json"},{"id":"ftl2-error-checking-failed-and-errors","text":"Error checking in FTL2 uses `ftl.failed` (boolean flag) and `ftl.errors` (structured error objects with `.module` and `.error` fields) — not exceptions by default.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-error-checking-failed-and-errors.json"},{"id":"ftl2-execution-time-equals-slowest-host","text":"In multi-host execution, total execution time approximates the slowest host rather than the sum of all hosts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-execution-time-equals-slowest-host.json"},{"id":"ftl2-failed-property-on-context","text":"`ftl.failed` is a property on the automation context that indicates whether any module call failed during the session, not a per-call return value.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-failed-property-on-context.json"},{"id":"ftl2-failure-isolation-continues-remaining","text":"When some hosts fail during multi-host execution, FTL2 continues executing on the remaining hosts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-failure-isolation-continues-remaining.json"},{"id":"ftl2-five-built-in-modules","text":"FTL2 ships five built-in modules: `ping` (connectivity), `setup` (fact gathering), `shell` (command execution), `file` (file/directory management), and `copy` (file copying), located in `src/ftl2/modules/`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-five-built-in-modules.json"},{"id":"ftl2-full-performance-stack","text":"FTL2's speed advantage derives from three independent optimization sources: in-process native module execution (up to 250x per-call speedup for native modules), gate-based remote delivery (pre-built zipapps cached on remote hosts, JSON-only parameter protocol), and default parallel host targeting (asyncio.gather fan-out, total time bounded by slowest host).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-full-performance-stack.json"},{"id":"ftl2-fully-zero-config-deployment","text":"FTL2 scripts achieve fully zero-configuration deployment: inline PEP 723 metadata declares dependencies and uv run bootstraps everything.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-fully-zero-config-deployment.json"},{"id":"ftl2-gate-zipapp-built-once-shared","text":"The gate zipapp is built once and uploaded to all targeted hosts, not rebuilt per host.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-gate-zipapp-built-once-shared.json"},{"id":"ftl2-gcp-auth-env-vars","text":"GCP authentication in FTL2 uses three environment variables: `GCP_PROJECT` (project ID), `GCP_AUTH_KIND` (auth type, e.g., `serviceaccount`), and `GCP_SERVICE_ACCOUNT_FILE` (path to service account JSON key).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-gcp-auth-env-vars.json"},{"id":"ftl2-hcloud-token-via-secret-bindings","text":"`HCLOUD_TOKEN` is injected into Hetzner modules via secret bindings (e.g., `{\"hetzner.hcloud.*\": {\"api_token\": \"HCLOUD_TOKEN\"}}`), ensuring the token is never logged or visible in scripts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-hcloud-token-via-secret-bindings.json"},{"id":"ftl2-hetzner-collection-install-via-ansible-galaxy","text":"The Hetzner Cloud collection is installed via `ansible-galaxy collection install hetzner.hcloud`, not pip.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-hetzner-collection-install-via-ansible-galaxy.json"},{"id":"ftl2-hetzner-state-file-name","text":"The Hetzner state file is named `.ftl2-state-hetzner.json`, following a `.ftl2-state-<provider>.json` naming pattern.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-hetzner-state-file-name.json"},{"id":"ftl2-host-groups-are-ansible-inventory-groups","text":"Host groups in FTL2 correspond to Ansible inventory groups and determine which hosts receive module calls.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-host-groups-are-ansible-inventory-groups.json"},{"id":"ftl2-host-reregistration-for-bootstrap","text":"During initial provisioning, a host can be registered first as `root` for user creation, then re-registered as a non-root user with `ansible_become=True` to bootstrap sudo access.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-host-reregistration-for-bootstrap.json"},{"id":"ftl2-hosts-addressed-by-name-modules-are-async","text":"Hosts are addressed by name via `ftl[\"hostname\"]` and modules are called as async methods (e.g., `.copy()`, `.shell()`, `.service()`, `.file()`, `.user()`, `.wait_for()`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-hosts-addressed-by-name-modules-are-async.json"},{"id":"ftl2-htop-data-flow-pipeline","text":"ftl2-htop data flow: SSH connection → gate process → SystemMonitor (psutil) → SystemMetrics events → SSH channel → TUI rendering.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-data-flow-pipeline.json"},{"id":"ftl2-htop-debug-prints-raw-events","text":"The `--debug` flag in ftl2-htop bypasses the TUI and prints raw gate events to stderr, useful for understanding the event protocol.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-debug-prints-raw-events.json"},{"id":"ftl2-htop-group-filtering-matches-standard","text":"Group filtering via `-g` in ftl2-htop works the same way as in standard FTL2 task execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-group-filtering-matches-standard.json"},{"id":"ftl2-htop-inventory-resolution-priority","text":"Inventory resolution priority in ftl2-htop: positional hosts → `--inventory` → `--state` → fallback to `\"localhost,\"`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-inventory-resolution-priority.json"},{"id":"ftl2-htop-multi-output-mode","text":"ftl2-htop supports four distinct output modes for different use cases: native Textual TUI for terminal monitoring, textual-serve for browser-based access, WebSocket broadcasting for custom dashboards and integrations, and debug mode for raw event inspection during development.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-multi-output-mode.json"},{"id":"ftl2-htop-only-remote-dep-psutil","text":"ftl2-htop requires only `python3-psutil` installed on remote hosts; FTL2's gate handles everything else via SSH.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-only-remote-dep-psutil.json"},{"id":"ftl2-htop-real-time-monitoring-stack","text":"ftl2-htop is a complete real-time infrastructure monitoring stack: SSH→gate→psutil data pipeline, dual-thread architecture (Textual UI + FTL2 daemon), 30-sample sparkline history, group-based host filtering, and browser accessibility via textual-serve — all reusing standard FTL2 inventory and gate subsystems.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-real-time-monitoring-stack.json"},{"id":"ftl2-htop-sparkline-30-sample-history","text":"ftl2-htop maintains a 30-sample rolling history per host for CPU, memory, and network rates, rendered as Unicode sparkline characters (`▁▂▃▄▅▆▇█`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-sparkline-30-sample-history.json"},{"id":"ftl2-htop-textual-serve-compatible","text":"The Textual TUI mode (`--tui` flag) is compatible with `textual-serve` for browser-based rendering.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-textual-serve-compatible.json"},{"id":"ftl2-htop-tui-dual-thread-architecture","text":"The Textual TUI mode uses a dual-thread architecture: Textual event loop on the main thread, FTL2 automation on a daemon thread with its own asyncio event loop; cross-thread updates use `call_from_thread`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-tui-dual-thread-architecture.json"},{"id":"ftl2-htop-websocket-broadcast-support","text":"ftl2-htop supports WebSocket broadcasting via `--ws-port`; it pushes the full metrics store as JSON to all connected clients every 2 seconds.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-htop-websocket-broadcast-support.json"},{"id":"ftl2-install-from-github-via-pip","text":"FTL2 applications are installed using `pip install \"package @ git+https://github.com/...\"` URLs to install directly from GitHub repositories.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-install-from-github-via-pip.json"},{"id":"ftl2-inventory-connection-parameters","text":"FTL2 inventory uses `ansible_host`, `ansible_port`, `ansible_user`, `ansible_connection`, and `ansible_python_interpreter` as host connection parameters.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-inventory-connection-parameters.json"},{"id":"ftl2-inventory-groups-flattened","text":"FTL2 uses flattened (not nested) group structures in its inventory system.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-inventory-groups-flattened.json"},{"id":"ftl2-limit-flag-patterns","text":"The `--limit` flag supports specific groups, individual hosts, glob patterns (`web*`), exclusion patterns (`!db*`), and comma-separated lists.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-limit-flag-patterns.json"},{"id":"ftl2-limit-flag-supports-patterns-and-exclusion","text":"The `--limit` flag supports group names, host names, glob patterns (e.g., `web*`), and exclusion with `!` prefix (e.g., `!databases`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-limit-flag-supports-patterns-and-exclusion.json"},{"id":"ftl2-linode-v4-idempotent-with-state-present","text":"The `community.general.linode_v4` module with `state: present` is idempotent — if the instance already exists and matches the spec, it returns the existing instance without changes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-linode-v4-idempotent-with-state-present.json"},{"id":"ftl2-modules-250x-faster-in-process","text":"FTL modules execute as in-process Python, claimed to be 250x faster than subprocess execution used by traditional module invocation.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-modules-250x-faster-in-process.json"},{"id":"ftl2-modules-run-in-process-not-subprocess","text":"FTL2 native modules run in-process rather than via subprocess execution, claimed to be 250x faster than subprocess-based execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-modules-run-in-process-not-subprocess.json"},{"id":"ftl2-no-ansible-prefix-in-inventory-vars","text":"FTL2 inventory variables do NOT use the `ansible_` prefix — use `ssh_private_key_file` instead of `ansible_ssh_private_key_file`. Only fields starting with `ansible_` are treated as direct host attributes; other variables go into a `vars` dict.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-no-ansible-prefix-in-inventory-vars.json"},{"id":"ftl2-observe-or-true-prevents-failure-reporting","text":"AI-loop observe steps append `|| true` to shell commands to prevent non-zero exit codes from being reported as observation failures, allowing the condition function to interpret missing state gracefully.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-observe-or-true-prevents-failure-reporting.json"},{"id":"ftl2-parallel-execution-by-default","text":"FTL2 executes modules concurrently across all targeted hosts by default, with no flag needed to enable parallelism.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-parallel-execution-by-default.json"},{"id":"ftl2-performance-and-ergonomics-unified","text":"FTL2's performance optimizations and developer ergonomics features are complementary aspects of the same system: the three-tier execution stack (in-process, gate, parallel) provides the performance foundation, while the async context manager, flexible module addressing, and dual error modes provide the usability layer. Because both operate within the same architecture, users can benefit from performance optimizations without needing to adopt a different API or workflow for speed-sensitive tasks.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-performance-and-ergonomics-unified.json"},{"id":"ftl2-pip-git-url-installs-in-action","text":"FTL2 action functions can install Python packages from GitHub repositories using pip's `git+https://` URL syntax via the `.shell()` module.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-pip-git-url-installs-in-action.json"},{"id":"ftl2-requires-python-311-plus","text":"FTL2 requires Python 3.11 or higher.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-requires-python-311-plus.json"},{"id":"ftl2-results-and-errors-collections","text":"`ftl.results` collects all operation outcomes from a session; `ftl.errors` provides error introspection with module name and error message.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-results-and-errors-collections.json"},{"id":"ftl2-scripts-run-with-uv","text":"FTL2 example scripts are run with `uv run python` — FTL2 uses `uv` as its Python runner.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-scripts-run-with-uv.json"},{"id":"ftl2-secret-bindings-map-fqcn-to-env-vars","text":"FTL2's `secret_bindings` parameter maps module FQCNs to environment variable names, auto-injecting secrets into specific modules at runtime.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-secret-bindings-map-fqcn-to-env-vars.json"},{"id":"ftl2-secret-bindings-map-modules-to-env-vars","text":"FTL2 secret bindings map module FQCN names to environment variable names (e.g., `{\"community.general.linode_v4\": {\"access_token\": \"LINODE_TOKEN\"}}`) for automatic secret injection.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-secret-bindings-map-modules-to-env-vars.json"},{"id":"ftl2-secret-bindings-wildcard-namespace","text":"Secret bindings support wildcard namespace patterns (e.g., `\"google.cloud.*\"`) to inject environment variables as parameters to all modules in that namespace, avoiding repetition per call.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-secret-bindings-wildcard-namespace.json"},{"id":"ftl2-security-before-content-ordering","text":"FTL2 deployments apply security hardening (firewall, SSH lockdown, SELinux, crypto policies, fail2ban) before any application content is deployed, so failed hardening prevents app exposure.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-security-before-content-ordering.json"},{"id":"ftl2-self-sufficient-production-platform","text":"FTL2 is a self-sufficient production infrastructure platform: autonomous self-healing (AI-loop remediation with persistent state and crash recovery) operates within a complete production framework (high-performance execution, ergonomic API, secure reliable deployments), enabling infrastructure that converges toward desired state without human intervention.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-self-sufficient-production-platform.json"},{"id":"ftl2-shell-guards-for-idempotency","text":"FTL2 deployment scripts use shell guards like `which uv || (install uv)` and `grep -qF ... || echo ...` to make shell commands safe to re-run, though heavy shell use reduces idempotency guarantees compared to dedicated modules.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-shell-guards-for-idempotency.json"},{"id":"ftl2-short-names-vs-fqcn","text":"Builtin modules use short names (`file`, `copy`, `shell`); collection modules use fully qualified collection names (e.g., `community.general.linode_v4`, `ansible.posix.firewalld`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-short-names-vs-fqcn.json"},{"id":"ftl2-speed-2-21x-over-ansible","text":"FTL2 achieves 2-21x speedup over ansible-playbook, depending on workload and module mix.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-speed-2-21x-over-ansible.json"},{"id":"ftl2-speed-compound-advantage","text":"FTL2's 2-21x speed advantage derives from three independent sources: in-process module execution (up to 250x per-call for native modules), default parallel host targeting, and gate pre-building that eliminates per-task bundling overhead.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-speed-compound-advantage.json"},{"id":"ftl2-speedup-3-21x-over-ansible","text":"FTL2 achieves 2-21x speedup over Ansible; API workloads show the largest gains (up to ~21x at 25 hosts).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-speedup-3-21x-over-ansible.json"},{"id":"ftl2-state-absent-deletes-resources","text":"FTL2 modules use `state=\"absent\"` to delete resources — the same module handles both creation and removal.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-state-absent-deletes-resources.json"},{"id":"ftl2-state-add-remove-api","text":"`ftl.state.add()` persists resource metadata to the state file and `ftl.state.remove()` cleans it up, enabling idempotent re-runs and cross-run resource tracking.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-state-add-remove-api.json"},{"id":"ftl2-state-api-add-remove","text":"FTL2's state API provides `ftl.state.add(key, dict)` to persist resource metadata and `ftl.state.remove(key)` to remove it on teardown.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-state-api-add-remove.json"},{"id":"ftl2-state-file-enables-crash-recovery","text":"The `state_file` parameter on `automation()` persists run state to a JSON file for crash recovery.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-state-file-enables-crash-recovery.json"},{"id":"ftl2-supports-long-lived-daemon-contexts","text":"FTL2 can run in long-lived application contexts such as a watchdog daemon, not just one-shot scripts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-supports-long-lived-daemon-contexts.json"},{"id":"ftl2-teardown-reverse-dependency-order","text":"Resource teardown must follow reverse dependency order (e.g., instances before networks); FTL2 does not automate this ordering — the user must sequence deletions manually.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-teardown-reverse-dependency-order.json"},{"id":"ftl2-telemetry-env-var-off","text":"Setting `FTL2_TELEMETRY=off` disables Segment telemetry on FTL2 startup.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-telemetry-env-var-off.json"},{"id":"ftl2-three-run-modes-check-teardown","text":"FTL2 cloud provisioning scripts support three run modes: normal (provision), `--check` (dry run), and `--teardown` (destroy resources).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-three-run-modes-check-teardown.json"},{"id":"ftl2-two-phase-host-registration","text":"FTL2 deployments use a two-phase host registration pattern: connect first as `root` to bootstrap an `admin` user, then re-register the same hostname with `ansible_user='admin'` and `ansible_become=True` for privileged operations.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-two-phase-host-registration.json"},{"id":"ftl2-uv-run-for-ftl-module-scripts","text":"FTL module Python scripts are executed via `uv run python <script>.py`, not through the `ftl2` CLI.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-uv-run-for-ftl-module-scripts.json"},{"id":"ftl2-uv-run-inline-dependencies","text":"FTL2 deployment scripts use `uv run` with PEP 723 inline dependency declarations, requiring no separate install step or virtualenv setup.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-uv-run-inline-dependencies.json"},{"id":"ftl2-uv-run-shebang-pep723-inline-deps","text":"FTL2 deployment scripts can use `uv run` as their shebang with inline PEP 723 script dependencies, requiring no virtualenv setup.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-uv-run-shebang-pep723-inline-deps.json"},{"id":"ftl2-variable-precedence-order","text":"Variable precedence in FTL2 follows group vars < host vars < module arguments (`-a` flag), with last wins semantics.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-variable-precedence-order.json"},{"id":"ftl2-wait-for-ssh-method","text":"`ftl.wait_for_ssh()` blocks until a newly provisioned server accepts SSH connections before attempting configuration, used in the provision-then-configure pattern.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-wait-for-ssh-method.json"},{"id":"ftl2-wait-for-ssh-readiness-gate","text":"The `wait_for` module can block until a TCP port (e.g., SSH on port 22) is reachable with a configurable timeout, acting as a readiness gate for downstream rules.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ftl2-wait-for-ssh-readiness-gate.json"},{"id":"fully-autonomous-cloud-lifecycle","text":"FTL2 manages the complete cloud lifecycle autonomously from initial provisioning through ongoing remediation: state-driven idempotent provisioning creates and configures hosts, persistent state enables crash recovery, and the AI reconciliation loop continuously observes and heals drift — all without human intervention.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fully-autonomous-cloud-lifecycle.json"},{"id":"fully-secure-single-file-cloud-deployments","text":"FTL2 achieves fully secure single-file cloud deployments: PEP 723 scripts self-bootstrap dependencies and provide idempotent provisioning with state persistence, while comprehensive security from credential bindings to network edge ensures every deployment surface is protected — all from a single script file.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/fully-secure-single-file-cloud-deployments.json"},{"id":"gate-cache-location-dot-ftl","text":"The gate cache location is `~/.ftl` per user.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-cache-location-dot-ftl.json"},{"id":"gate-creates-backups-not-module","text":"The gate's `BackupManager` creates backups, not individual modules — modules only declare backup capability via docstring metadata (`Backup-Capable`, `Backup-Paths`, `Backup-Trigger`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-creates-backups-not-module.json"},{"id":"gate-dependencies-parameter","text":"The `gate_dependencies` parameter on `automation()` specifies additional Python packages to bundle into the gate zipapp alongside the modules — needed when modules import libraries not in the Ansible collection (e.g., `httpx`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-dependencies-parameter.json"},{"id":"gate-message-format-json-tuples","text":"The gate event protocol uses JSON tuples as its message format (e.g., `[\"CommandName\", {params}]`), sent as length-prefixed messages over SSH channels.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-message-format-json-tuples.json"},{"id":"gate-modules-auto-records-then-reads","text":"Using `gate_modules=\"auto\"` records module usage on the first run to `.ftl2-modules.txt` and reads from that file on subsequent runs.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-modules-auto-records-then-reads.json"},{"id":"gate-modules-prebuild-once-json-params","text":"Gate modules are pre-built once into a gate package; subsequent tasks send only JSON parameters over SSH, eliminating per-task module upload overhead.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-modules-prebuild-once-json-params.json"},{"id":"gate-protocol-length-prefixed-json","text":"The FTL2 gate protocol uses length-prefixed JSON for communication between the local controller and the remote gate process.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-protocol-length-prefixed-json.json"},{"id":"gate-remote-optimization-pipeline","text":"The gate subsystem is a complete remote execution optimization pipeline: modules are pre-built once into a zipapp, uploaded and cached on remote hosts, then subsequent tasks send only JSON parameters over a length-prefixed protocol.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-remote-optimization-pipeline.json"},{"id":"gate-subsystem-enabled-via-parameter","text":"The gate subsystem is enabled by passing `gate_subsystem=True` to the `automation()` context manager; gate processes persist for the lifetime of the `async with automation()` block.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-subsystem-enabled-via-parameter.json"},{"id":"gate-zipapp-mechanism","text":"FTL2's gate mechanism packages each module into a Python zipapp (.pyz), uploads it to `/tmp/` on the remote host, executes it with the remote Python interpreter, and reads results back via length-prefixed JSON protocol.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gate-zipapp-mechanism.json"},{"id":"gates-cached-by-content-hash","text":"FTL2 gate zipapps are cached on the remote host by content hash — once uploaded to `/tmp/`, a gate is reused on subsequent runs without re-uploading.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gates-cached-by-content-hash.json"},{"id":"gcp-python-dependencies","text":"GCP automation requires three Python packages: `google-auth`, `google-cloud-compute`, and `google-api-python-client`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gcp-python-dependencies.json"},{"id":"gcp-state-file-name","text":"The GCP provisioning example uses `.ftl2-gcp-state.json` as the state file for idempotent re-runs.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gcp-state-file-name.json"},{"id":"gcp-two-auth-methods","text":"GCP authentication in FTL2 supports two methods via `GCP_AUTH_KIND`: `serviceaccount` (with `GCP_SERVICE_ACCOUNT_FILE`) and `application` (via `gcloud auth application-default login`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/gcp-two-auth-methods.json"},{"id":"getattr-ftl-group-returns-hostscopedproxy","text":"`getattr(ftl, group_name)` returns a `HostScopedProxy` that targets all hosts in that group, not a list of hosts. Also works for individual hosts (e.g., `ftl.webserver`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/getattr-ftl-group-returns-hostscopedproxy.json"},{"id":"governed-fault-tolerant-execution","text":"Every FTL2 execution is simultaneously governed and fault-tolerant: security enforcement, credential injection, and structured telemetry instrument every module call end-to-end, while three independent crash recovery mechanisms and dual error modes ensure no failure — planned or unplanned — goes unrecoverable.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/governed-fault-tolerant-execution.json"},{"id":"grace-period-poll-interval-per-server","text":"Grace period and poll interval are per-server configuration in servers.yml, not global settings.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/grace-period-poll-interval-per-server.json"},{"id":"group-accessor-syntax","text":"When hosts are added with `groups=[\"minecraft\"]`, all modules for that group are accessible via `ftl.minecraft.module()` — the group name becomes a proxy attribute on the automation context.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/group-accessor-syntax.json"},{"id":"hetzner-server-type-prefixes","text":"Hetzner Cloud server type prefixes: `cx` = shared Intel/AMD, `cax` = shared ARM/Ampere, `cpx` = dedicated AMD, `ccx` = dedicated high-memory AMD.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/hetzner-server-type-prefixes.json"},{"id":"hetzner-six-datacenter-locations","text":"Hetzner Cloud has six datacenter locations: `nbg1`, `fsn1`, `hel1` (EU), `ash` (US East), `hil` (US West), `sin` (APAC).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/hetzner-six-datacenter-locations.json"},{"id":"high-performance-targeting-pipeline","text":"The complete FTL2 pipeline from CLI host selection through module execution is performance-optimized at every layer: rich pattern-based targeting (groups, globs, exclusions) feeds into the three-tier performance stack (in-process native execution, gate-cached remote delivery, default parallelism), delivering 2-21x speedup across the entire targeting-to-result path.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/high-performance-targeting-pipeline.json"},{"id":"host-dash-to-underscore-attribute-access","text":"Host names containing dashes (e.g., `db-primary`) are accessed as Python attributes with underscores (`ftl.db_primary`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/host-dash-to-underscore-attribute-access.json"},{"id":"host-module-name-collision-disambiguation","text":"If a host or group name shadows a module name, a `UserWarning` is emitted at init and the module is accessible via `ftl.module.<name>()`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/host-module-name-collision-disambiguation.json"},{"id":"host-scoped-execution-syntax","text":"Host-scoped execution uses attribute access: `ftl.webservers.service(name=\"nginx\", state=\"restarted\")` targets a specific host or group.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/host-scoped-execution-syntax.json"},{"id":"host-scoped-proxy-syntax-targets-hosts-and-groups","text":"`ftl.<name>.module()` proxy syntax targets a host or group by name — e.g., `ftl.web01.command(...)` targets host web01, `ftl.webservers.command(...)` fans out to all hosts in the webservers group.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/host-scoped-proxy-syntax-targets-hosts-and-groups.json"},{"id":"host-targeted-module-calls-bracket-syntax","text":"After registering a host with `ftl.add_host()`, modules can be called against that specific host using bracket syntax: `ftl[hostname].module(...)`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/host-targeted-module-calls-bracket-syntax.json"},{"id":"hosts-lookup-always-returns-list","text":"`ftl.hosts[\"name\"]` always returns a list of Host objects, whether looking up a host name or a group name.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/hosts-lookup-always-returns-list.json"},{"id":"idempotency-multi-layer-strategy","text":"FTL2 achieves idempotency through multiple complementary mechanisms: shell guards (`which X || install X`), the `creates` parameter for file-producing commands, inherently idempotent AI-loop module calls, and Cloudflare DNS create-or-skip logic.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/idempotency-multi-layer-strategy.json"},{"id":"idempotent-cloud-provisioning-pipeline","text":"Cloud provisioning is idempotent end-to-end: state persistence enables safe re-runs with crash recovery, multi-layer idempotency (shell guards, creates parameter, module-level) prevents duplicate resources, and the full lifecycle from cloud API through add_host() to two-phase bootstrap can be interrupted and resumed at any point.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/idempotent-cloud-provisioning-pipeline.json"},{"id":"in-process-execution-3-17x-speedup","text":"FTL2 achieves 3-17x speedup over `ansible-playbook` by running modules as Python functions in-process rather than as subprocesses.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/in-process-execution-3-17x-speedup.json"},{"id":"inventory-driven-dynamic-infrastructure","text":"FTL2's inventory system seamlessly spans static and dynamic infrastructure: multi-format inventory (YAML, JSON, executable, dict) provides static host definitions while add_host's complete lifecycle (runtime registration, immediate state persistence, attribute access, group assignment) dynamically extends it mid-run — supporting traditional fleet management and cloud provisioning within the same scripts and addressing model.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/inventory-driven-dynamic-infrastructure.json"},{"id":"inventory-flexible-multi-format","text":"FTL2 inventory is flexible and multi-source: auto-detects three formats (executable scripts, JSON, YAML), accepts Python dicts programmatically, uses Ansible-compatible connection parameters (ansible_host, ansible_user, etc.), provides built-in `all`/`ungrouped` groups, and uses a flat (non-nested) group hierarchy.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/inventory-flexible-multi-format.json"},{"id":"inventory-from-yaml-or-dict","text":"Inventory can be loaded from a YAML file path (`automation(inventory=\"/path/to/inventory.yml\")`) or from a Python dict passed to `AutomationContext(inventory={...})`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/inventory-from-yaml-or-dict.json"},{"id":"linode-v4-module-idempotent","text":"The `community.general.linode_v4` module with `state: present` is idempotent — if the instance already exists and matches the spec, it returns the existing instance without changes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/linode-v4-module-idempotent.json"},{"id":"load-config-returns-empty-dict-if-missing","text":"The `load_config` function returns an empty dict if the config file doesn't exist, rather than raising an error.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/load-config-returns-empty-dict-if-missing.json"},{"id":"load-inventory-three-formats","text":"`load_inventory()` auto-detects three inventory formats: executable scripts, JSON (Ansible `--list` format), and YAML.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/load-inventory-three-formats.json"},{"id":"local-execution-cloud-api-optimized","text":"FTL2's local execution path bypasses SSH and gate overhead entirely, using direct subprocess/pathlib operations — making it the natural high-performance path for cloud API modules that call external services rather than remote hosts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/local-execution-cloud-api-optimized.json"},{"id":"local-execution-uses-ansible-connection-local","text":"FTL2 local execution is triggered by setting `ansible_connection: local` in inventory, which uses `LocalModuleRunner` instead of `RemoteModuleRunner`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/local-execution-uses-ansible-connection-local.json"},{"id":"local-remote-execution-continuum","text":"FTL2 optimizes execution across the entire local-to-remote continuum: local operations bypass SSH and gate overhead entirely using direct subprocess/pathlib for cloud API calls, while remote execution uses SSH connection pooling, gate-cached zipapps, and length-prefixed JSON protocol — with the same modules and API working identically in both modes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/local-remote-execution-continuum.json"},{"id":"localhost-uses-direct-local-operations","text":"All native modules detect `local`/`localhost` targets and use direct local operations (subprocess, pathlib) instead of SSH/SFTP.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/localhost-uses-direct-local-operations.json"},{"id":"module-addressing-flexibility","text":"FTL2 supports four complementary module addressing syntaxes: dot-access for simple names, bracket notation for dashed hostnames, FQCN chains for collection modules, and host-scoped proxy for targeted execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-addressing-flexibility.json"},{"id":"module-call-pattern-group-dot-module","text":"FTL2 module calls follow the attribute-chain pattern `ftl.<inventory_group>.<module_name>(param=value)`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-call-pattern-group-dot-module.json"},{"id":"module-calls-proxied-through-module-proxy","text":"Module calls like `ftl.file(...)` are proxied through `ModuleProxy`, which resolves module names at runtime via attribute access.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-calls-proxied-through-module-proxy.json"},{"id":"module-discovery-api-two-functions","text":"The planned Module Discovery API has two functions: `ftl.list_modules(category=None)` for browsing by category and `ftl.describe(module_name)` for detailed parameter info.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-discovery-api-two-functions.json"},{"id":"module-execution-triple-security-layer","text":"Every FTL2 module execution passes through three independent security layers: policy enforcement denies unauthorized operations before execution begins, secret bindings auto-inject credentials without code or log exposure, and privilege escalation stages files through safe temp paths with per-user sudoers drop-in files — composing into defense-in-depth at the individual module call level.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-execution-triple-security-layer.json"},{"id":"module-restriction-raises-attribute-error","text":"Passing `modules=[\"file\", \"copy\"]` to `automation()` restricts available modules; calling any other module raises `AttributeError`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-restriction-raises-attribute-error.json"},{"id":"module-result-contract-consistency","text":"Every FTL2 module execution returns a consistent result contract — success, changed, output, and error fields — regardless of whether the module ran locally or remotely, natively or via Ansible compatibility, through direct calls or the Executor API.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-result-contract-consistency.json"},{"id":"module-results-expose-output-dict","text":"Module call results expose an `.output` dict containing provider-specific data (e.g., `selfLink`, `networkInterfaces`) that can be used to chain resource dependencies.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-results-expose-output-dict.json"},{"id":"module-universal-addressing-and-execution","text":"FTL2 provides a universal module system: four addressing syntaxes (dot-access, bracket notation, FQCN chains, host-scoped proxy) cover every naming and targeting pattern, while the dual-mode architecture (native in-process + Ansible-compatible bundled) executes any module transparently with the same local/remote API surface.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/module-universal-addressing-and-execution.json"},{"id":"modules-are-callable-context-attributes","text":"Modules are callable attributes on the automation context object, accessible via `ftl.module_name()` or dynamically via `getattr(ftl, module_name)`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/modules-are-callable-context-attributes.json"},{"id":"multi-cloud-credential-unification","text":"FTL2 unifies multi-cloud authentication through a consistent env-var and secret-bindings pattern: GCP uses three env vars with two auth methods, Azure uses four service principal vars, Hetzner injects tokens via wildcard secret bindings, and all resolve credentials at module call time without source code exposure.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/multi-cloud-credential-unification.json"},{"id":"multi-cloud-fully-automated","text":"Multi-cloud operations are fully automated from provisioning through ongoing management: unified credential patterns across GCP, Azure, Hetzner, and Linode combine with provider-specific state isolation and idempotent end-to-end cloud provisioning for completely unattended multi-cloud deployments.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/multi-cloud-fully-automated.json"},{"id":"multi-cloud-isolated-operations","text":"FTL2 enables multi-cloud operations with clean isolation between providers: provider-specific state files (`.ftl2-state-<provider>.json`) prevent cross-cloud resource conflicts, while the unified env-var and secret-bindings pattern provides consistent credential management across GCP, Azure, Hetzner, and Linode.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/multi-cloud-isolated-operations.json"},{"id":"multi-host-progress-uses-make-callback","text":"Multi-host progress tracking uses `display.make_callback(host_name)` to create per-host callbacks — not `display.handle_event` directly.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/multi-host-progress-uses-make-callback.json"},{"id":"namespace-proxy-enables-fqcn-dot-notation","text":"Accessing an unknown attribute on the automation context returns a `NamespaceProxy` that builds a dotted FQCN path; calling the final proxy executes the module via `context.execute()`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/namespace-proxy-enables-fqcn-dot-notation.json"},{"id":"namespaced-modules-use-dot-access","text":"Fully qualified collection names are accessed via dot notation: `ftl.community.general.slack(channel=\"#deploy\", msg=\"Done!\")`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/namespaced-modules-use-dot-access.json"},{"id":"native-ftl-modules-250x-faster","text":"Native FTL modules run in-process and are 250x faster than Ansible's subprocess-based execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/native-ftl-modules-250x-faster.json"},{"id":"native-shadowed-modules-list","text":"FTL2 has six native shadowed modules that replace Ansible equivalents: `wait_for_ssh`, `ping`, `copy`, `template`, `fetch`, and `shell`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/native-shadowed-modules-list.json"},{"id":"no-gate-in-local-execution","text":"Gate modules are NOT used in local execution — gates are a remote execution optimization only.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/no-gate-in-local-execution.json"},{"id":"observable-autonomous-remediation","text":"AI-loop autonomous remediation is fully observable: observe/condition/action cycles emit structured events (progress, log, status) that are always captured in results regardless of display mode, enabling operators to monitor, debug, and audit self-healing operations without interfering with autonomous execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/observable-autonomous-remediation.json"},{"id":"observable-resilient-application-platform","text":"FTL2 infrastructure applications achieve both resilience and full observability simultaneously: servercraft demonstrates safe re-provisioning via idempotent cloud operations while every watchdog and AI-loop self-healing cycle emits structured events — autonomous operation without sacrificing operational insight.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/observable-resilient-application-platform.json"},{"id":"observable-safe-autonomous-operations","text":"Autonomous infrastructure operations are both safe and fully observable: intelligent lifecycle management (warmup delays, consecutive-failure thresholds, player-join grace period resets) operates alongside structured event emission for every observe/condition/action cycle — operators can verify autonomous decisions without intervening.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/observable-safe-autonomous-operations.json"},{"id":"observe-block-uses-module-dicts","text":"The `observe` block in AI-loop rules is a list of dictionaries with `name`, `module`, `params`, and `host` keys — each entry runs a module call to gather state.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/observe-block-uses-module-dicts.json"},{"id":"observe-error-suppression-pattern","text":"AI-loop rule observe blocks use `|| true` and `2>&1` to prevent observation failures from crashing the reconciliation loop.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/observe-error-suppression-pattern.json"},{"id":"on-event-callback-receives-structured-dicts","text":"`automation(on_event=callback)` receives structured event dicts with fields: `event`, `module`, `host`, `success`, `changed`, `duration` (float seconds), and `timestamp`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/on-event-callback-receives-structured-dicts.json"},{"id":"output-mode-flexibility-spectrum","text":"FTL2 provides a complete spectrum of output verbosity: default shows only errors with a per-host task summary, verbose adds per-operation execution timing, and quiet with event callbacks enables structured machine-readable capture for production use — covering interactive development through production monitoring without code changes, only parameter changes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/output-mode-flexibility-spectrum.json"},{"id":"parallel-execution-model","text":"FTL2 executes modules concurrently across all targeted hosts by default with no explicit parallelism configuration required, so total execution time approximates the slowest host rather than the sum of all hosts. asyncio.gather is one mechanism used for concurrent fan-out (e.g., in the copy module), and execute_batch provides near-linear speedup over sequential execute() calls via asyncio.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/parallel-execution-model.json"},{"id":"pep723-zero-setup-scripts","text":"FTL2 enables a zero-setup single-file deployment model: PEP 723 inline metadata declares dependencies, uv run self-bootstraps them via shebang, and no virtualenv, requirements.txt, or install step is needed.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/pep723-zero-setup-scripts.json"},{"id":"ping-module-returns-changed-false","text":"The FTL2 `ping` module returns `{\"changed\": false, \"ping\": \"pong\"}`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ping-module-returns-changed-false.json"},{"id":"ping-returns-ping-pong","text":"`ping()` returns `{'ping': 'pong'}` on success.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ping-returns-ping-pong.json"},{"id":"ping-tests-full-execution-pipeline","text":"`ping()` tests the full execution pipeline in order: TCP → SSH → Gate setup → Command execution → Response round-trip. A successful ping guarantees module execution will work.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ping-tests-full-execution-pipeline.json"},{"id":"ping-tests-full-gate-pipeline","text":"FTL2's `ping()` tests the entire gate execution pipeline (TCP → SSH → gate → command → response), unlike Ansible's ping which only tests the connection plugin.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ping-tests-full-gate-pipeline.json"},{"id":"policy-audit-crash-safe-jsonlines","text":"Policy audit events are appended as JSON lines immediately after evaluation, making the audit trail crash-safe.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/policy-audit-crash-safe-jsonlines.json"},{"id":"policy-enforcement-before-every-execution","text":"Policy enforcement runs before every module execution; denied actions raise `PolicyDeniedError`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/policy-enforcement-before-every-execution.json"},{"id":"policy-enforcement-complete-access-control","text":"FTL2's policy engine provides complete pre-execution access control: enforcement runs before every module call with first-match-deny semantics, rules match on module/environment/host/parameter fields for granular control, and shell/command/raw modules are treated as policy-equivalent to prevent bypass through alternative command execution paths.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/policy-enforcement-complete-access-control.json"},{"id":"policy-engine-planned-composition-and-validation","text":"Planned policy engine improvements include rule short-circuiting (not just deny), policy validation on load, policy composition from multiple files/directories, and policy summary in audit logs.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/policy-engine-planned-composition-and-validation.json"},{"id":"policy-first-matching-deny-wins","text":"The policy engine uses first-match semantics — the first matching deny rule raises `PolicyDeniedError`, not the most specific rule.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/policy-first-matching-deny-wins.json"},{"id":"policy-rules-match-fields","text":"Policy rules match on `module`, `environment`, `host`, and `param.*` fields; a `PolicyDeniedError` is raised when a rule blocks an action.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/policy-rules-match-fields.json"},{"id":"polymorphic-resilient-game-servers","text":"Each game server type in servercraft gets both custom lifecycle behavior through the 8-function script interface (provision, start, verify, backup, restore, stop, get_player_count, reconfigure) and unified resilience monitoring through the watchdog's warmup/threshold/grace-period chain — the polymorphism handles game-specific differences while the watchdog provides game-agnostic operational safety.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/polymorphic-resilient-game-servers.json"},{"id":"port-80-required-for-acme-challenge","text":"Port 80 must be open on the host even when serving only HTTPS, because Let's Encrypt's HTTP-01 ACME challenge requires it.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/port-80-required-for-acme-challenge.json"},{"id":"privilege-escalation-safe-and-flexible","text":"FTL2 privilege escalation is both safe and flexible: copy operations stage through /tmp with sudo mv to avoid permission races, become_user enables running as specific unprivileged users (not just root), and sudoers configuration uses /etc/sudoers.d/ drop-in files rather than editing /etc/sudoers directly.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/privilege-escalation-safe-and-flexible.json"},{"id":"production-deployment-reliable-and-secure","text":"FTL2 production deployments are simultaneously reliable and secure: state persistence enables idempotent re-runs and crash recovery while the security-first bootstrap ensures every run (including re-runs) maintains the hardened posture — security is never a one-time setup that drifts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/production-deployment-reliable-and-secure.json"},{"id":"production-deployments-fully-hands-off","text":"Production FTL2 deployments are fully hands-off from bootstrap to serving: zero-setup scripts self-bootstrap dependencies via uv run, DNS records are automated via Cloudflare modules, and TLS is auto-provisioned via Caddy's Let's Encrypt integration — the entire deployment lifecycle requires no manual intervention.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/production-deployments-fully-hands-off.json"},{"id":"provider-specific-state-file-convention","text":"FTL2 examples use provider-specific state file names — `.ftl2-state-hetzner.json` for Hetzner, `.ftl2-state-azure.json` for Azure, and `.ftl2-gcp-state.json` for GCP — alongside the default `.ftl2-state.json`. The Hetzner and Azure names follow a `.ftl2-state-<provider>.json` pattern, though GCP's `.ftl2-gcp-state.json` deviates from it. This suggests provider-specific state files can coexist, which could support multi-cloud deployments maintaining independent state per provider.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/provider-specific-state-file-convention.json"},{"id":"provisioning-exception-slack-notify-reraise","text":"Production provisioning functions wrap the entire operation in try/except, send a Slack failure notification on error, then re-raise — ensuring the caller still sees the failure while operators get immediate alerts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/provisioning-exception-slack-notify-reraise.json"},{"id":"provisioning-idempotent-supports-reconfigure","text":"FTL2 provisioning is idempotent enough to support \"Reconfigure\" (re-run on existing server) as a distinct operation from initial \"Launch\".","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/provisioning-idempotent-supports-reconfigure.json"},{"id":"provisioning-through-monitoring-lifecycle","text":"FTL2 manages the complete host lifecycle from cloud API call through ongoing real-time monitoring: local execution provisions VMs via cloud API, add_host dynamically registers them with two-phase bootstrap, and the htop monitoring stack (SSH→gate→psutil with sparklines and WebSocket broadcast) provides continuous operational visibility over the provisioned fleet.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/provisioning-through-monitoring-lifecycle.json"},{"id":"provisioning-to-optimized-execution","text":"FTL2 provides a complete pipeline from cloud provisioning to optimized execution: VMs are provisioned via cloud API, dynamically registered with add_host(), bootstrapped through two-phase registration, then managed through connection-pooled asyncssh with gate-optimized module delivery (pre-built zipapps, length-prefixed JSON, content-hash caching).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/provisioning-to-optimized-execution.json"},{"id":"quiet-plus-events-recommended-for-production","text":"`quiet=True` combined with `on_event` (silent execution with structured event capture) is the recommended pattern for production scripts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/quiet-plus-events-recommended-for-production.json"},{"id":"readiness-gated-secure-bootstrap","text":"FTL2 host provisioning is safe from first connection: SSH readiness gating (wait_for_ssh with configurable timeout and wait_for TCP port checks) ensures the host is reachable before two-phase bootstrap (root → admin re-registration → security hardening → content deployment) begins.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/readiness-gated-secure-bootstrap.json"},{"id":"remote-execution-uses-asyncssh","text":"FTL2 remote execution uses the `asyncssh` library for SSH connections, triggered by `ansible_connection: ssh` in inventory.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/remote-execution-uses-asyncssh.json"},{"id":"replay-is-positional","text":"Replay matching is positional — action N in the current run matches action N in the replay log; successful replayed actions are skipped with cached output.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/replay-is-positional.json"},{"id":"resilient-parallel-fleet-operations","text":"FTL2 fleet operations are resilient under partial failure: parallel execution across all hosts continues on remaining hosts when some fail, with dual error modes providing flexible failure policy — continue-on-error collects all failures for fleet-wide analysis, while fail-fast halts on critical operations.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/resilient-parallel-fleet-operations.json"},{"id":"result-normalization-helper-pattern","text":"FTL2 module results can be dicts, lists (multi-host), or objects with `.output`/`.success` attributes. Production apps use a `_result_dict()` helper to normalize these into plain dicts for reliable field access.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/result-normalization-helper-pattern.json"},{"id":"run-on-still-supported-alongside-proxy","text":"`ftl.run_on(target, module, **kwargs)` is the older explicit targeting API and remains supported alongside the newer proxy syntax.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/run-on-still-supported-alongside-proxy.json"},{"id":"run-on-target-accepts-string-or-host-list","text":"`ftl.run_on()` accepts a group name string, host name string, or list of Host objects as its target parameter.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/run-on-target-accepts-string-or-host-list.json"},{"id":"run-streaming-returns-4-tuple","text":"`SSHHost.run_streaming()` returns a 4-tuple `(stdout, stderr, rc, events)`, extending the standard `run()` 3-tuple with parsed events.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/run-streaming-returns-4-tuple.json"},{"id":"safe-intelligent-autonomous-lifecycle","text":"Servercraft achieves safe AND intelligent autonomous lifecycle management: intelligent watchdog behavior (10-minute warmup, 3-consecutive-failure threshold, grace-period reset on player join, context-sensitive teardown) safely re-invokes infrastructure operations because FTL2's multi-layer idempotency prevents duplicate resources or repeated destructive side effects on each re-execution cycle.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/safe-intelligent-autonomous-lifecycle.json"},{"id":"safe-parallel-idempotent-operations","text":"FTL2 safely scales concurrent operations across large fleets: multi-layer idempotency (shell guards, creates parameter, state-driven re-runs) combined with default parallel execution across all hosts ensures re-runs never create duplicate resources even when targeting dozens of hosts simultaneously.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/safe-parallel-idempotent-operations.json"},{"id":"safe-recoverable-resource-lifecycle","text":"FTL2 resource lifecycle completion is both orderly and recoverable: state-managed teardown uses label lookup and reverse dependency ordering for clean multi-resource removal with state file cleanup, while the backup subsystem ensures destructive operations are recoverable via the two-phase protocol (discover then backup) with fail-safe abort on backup failure.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/safe-recoverable-resource-lifecycle.json"},{"id":"same-api-dev-and-production","text":"FTL2 uses the same `automation()` context manager, module addressing, and error handling API for both development scripts and production deployments — there is no separate deployment-specific interface.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/same-api-dev-and-production.json"},{"id":"same-modules-local-and-remote","text":"The same FTL2 modules work identically in both local and remote execution modes — only the connection type and runner change.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/same-modules-local-and-remote.json"},{"id":"script-field-selects-python-module","text":"The `script` field in servers.yml selects which Python module under `scripts/` handles that server type (e.g., `script: neoforge` loads `scripts/neoforge.py`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/script-field-selects-python-module.json"},{"id":"script-interface-eight-functions","text":"The ftl2-servercraft script interface defines exactly 8 functions: `provision`, `start_server`, `verify_server`, `restore_world`, `backup_world`, `get_player_count`, `save_and_stop`, `destroy`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/script-interface-eight-functions.json"},{"id":"secret-bindings-env-vars-without-vault","text":"The `secret_bindings` parameter of `automation()` maps environment variables to module parameters without requiring Vault integration.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secret-bindings-env-vars-without-vault.json"},{"id":"secret-bindings-map-env-to-modules","text":"FTL2 `secret_bindings` map environment variable names to module parameters — e.g., `LINODE_TOKEN` maps to `community.general.linode_v4`'s `access_token`, so credentials are injected automatically without appearing in rule code.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secret-bindings-map-env-to-modules.json"},{"id":"secret-bindings-map-module-patterns-to-env-vars","text":"Secret binding keys are module names or glob patterns (e.g., `amazon.aws.*`); values are dicts mapping parameter names to environment variable names.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secret-bindings-map-module-patterns-to-env-vars.json"},{"id":"secret-bindings-passed-to-automation-constructor","text":"Secret bindings are passed as the `secret_bindings` parameter to the `automation()` context manager at initialization time.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secret-bindings-passed-to-automation-constructor.json"},{"id":"secret-bindings-prevent-credential-leakage","text":"Secret bindings ensure credentials are never visible in code or logs, critical for AI agent safety.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secret-bindings-prevent-credential-leakage.json"},{"id":"secret-bindings-resolve-env-vars-at-call-time","text":"Secret bindings resolve environment variables at module call time and inject them into parameters — the script source never contains or sees actual secret values.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secret-bindings-resolve-env-vars-at-call-time.json"},{"id":"secret-defense-in-depth","text":"FTL2 implements defense-in-depth for credentials: bindings auto-inject secrets without source code exposure, repr/str always redact values, secrets are never logged, and resolution happens at call time so variables never appear in scripts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secret-defense-in-depth.json"},{"id":"secrets-access-raises-keyerror-if-missing","text":"`ftl.secrets[\"KEY\"]` raises `KeyError` if the environment variable wasn't set or wasn't in the declared secrets list.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-access-raises-keyerror-if-missing.json"},{"id":"secrets-complete-management-spectrum","text":"FTL2 covers the full secrets management spectrum: environment variable bindings for simple deployments, HashiCorp Vault integration with grouped reads for enterprise key rotation, and defense-in-depth (redaction, never-logged, lazy evaluation) at every tier — teams can start simple and scale to Vault without changing their security posture.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-complete-management-spectrum.json"},{"id":"secrets-declared-as-env-var-names","text":"Secrets are declared as a list of environment variable names via `automation(secrets=[\"KEY1\", \"KEY2\"])` and sourced from the process environment.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-declared-as-env-var-names.json"},{"id":"secrets-fallback-ftl-secrets-key","text":"For modules not covered by secret bindings, `ftl.secrets[\"KEY\"]` is still available as a fallback mechanism for accessing secrets.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-fallback-ftl-secrets-key.json"},{"id":"secrets-get-provides-default-fallback","text":"`ftl.secrets.get(\"KEY\", default)` retrieves a secret with a fallback value if the key is missing.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-get-provides-default-fallback.json"},{"id":"secrets-lazy-evaluation","text":"FTL2 secrets use lazy evaluation: missing env vars don't fail at context creation, errors surface only on access, and get() provides default fallbacks — enabling flexible secret management without upfront validation failures.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-lazy-evaluation.json"},{"id":"secrets-loaded-keys-vs-keys","text":"`ftl.secrets.keys()` lists all requested secret names, while `ftl.secrets.loaded_keys()` lists only secrets actually found in the environment.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-loaded-keys-vs-keys.json"},{"id":"secrets-missing-env-vars-dont-fail-at-creation","text":"Missing environment variables for declared secrets don't cause failure at context creation — the error surfaces on access (or returns a default via `.get()`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-missing-env-vars-dont-fail-at-creation.json"},{"id":"secrets-never-logged","text":"Secrets are never logged — `SecretsProxy` provides safe `__repr__`/`__str__`, and secret bindings use fnmatch patterns to auto-inject secrets with pre-injection params sent to audit trails.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-never-logged.json"},{"id":"secrets-secure-and-ergonomic","text":"FTL2's secrets system achieves both strong security and developer ergonomics: defense-in-depth prevents credential leakage at every surface (bindings, repr, logs), while lazy evaluation avoids premature failures and provides graceful error semantics on access.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-secure-and-ergonomic.json"},{"id":"secrets-str-repr-redact-values","text":"`str()` and `repr()` on the secrets object redact actual values, preventing accidental exposure in logs or tracebacks.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secrets-str-repr-redact-values.json"},{"id":"secure-auditable-deployment-lifecycle","text":"FTL2 production deployments are simultaneously auditable and credential-safe: every re-execution is tracked through event streaming and state-driven idempotency while defense-in-depth ensures credentials never appear in audit trails, logs, or repr output — full traceability without security exposure.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secure-auditable-deployment-lifecycle.json"},{"id":"secure-autonomous-operations-governance","text":"Autonomous FTL2 operations run within a complete governance framework: self-healing AI-loop remediation with safe lifecycle management (warmup delays, failure thresholds, player-aware teardown) operates under comprehensive credential security from storage to network edge, with full observability at every layer.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secure-autonomous-operations-governance.json"},{"id":"secure-observable-dynamic-cloud-pipeline","text":"Dynamically provisioned cloud hosts receive full security AND observability from first connection: two-phase bootstrap hardens access before content deployment, every module call passes through triple security enforcement (policy, credentials, privilege escalation), and all operations emit structured events for audit.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secure-observable-dynamic-cloud-pipeline.json"},{"id":"secure-observable-execution-pipeline","text":"Every FTL2 module execution is both secured and observable: calls pass through policy enforcement, credential injection, and privilege escalation controls while simultaneously emitting structured events — creating an audit trail where every secured operation has a corresponding observable record.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secure-observable-execution-pipeline.json"},{"id":"secure-self-sufficient-production-platform","text":"FTL2 is a secure, self-sufficient production platform: autonomous self-healing with full observability operates within comprehensive security from credential storage to network edge, making it capable of sustained autonomous operation without manual security intervention.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secure-self-sufficient-production-platform.json"},{"id":"secure-targeting-to-execution-pipeline","text":"The complete host selection through module execution pipeline is secured end-to-end: CLI targeting (groups, globs, exclusions) feeds into multi-format inventory resolution, then every resolved module call passes through policy enforcement, credential injection, and privilege escalation before execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/secure-targeting-to-execution-pipeline.json"},{"id":"self-healing-with-full-visibility","text":"AI-loop autonomous remediation is fully visible without manual monitoring: each observe/condition/action cycle within the error-resilient framework emits structured events through the observability stack, meaning self-healing actions are event-tracked, their failures are captured, and their convergence can be verified by external systems.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/self-healing-with-full-visibility.json"},{"id":"server-name-is-state-dict-resource-key","text":"The server's `name` field is used as the resource key in the FTL2 state dict when reading `.ftl2-state.json`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/server-name-is-state-dict-resource-key.json"},{"id":"serverconfig-default-grace-period-1800","text":"The default `grace_period` for ServerConfig is 1800 seconds (30 minutes) before idle shutdown.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/serverconfig-default-grace-period-1800.json"},{"id":"serverconfig-default-poll-interval-30","text":"The default `poll_interval` for ServerConfig is 30 seconds for watchdog polling frequency.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/serverconfig-default-poll-interval-30.json"},{"id":"servercraft-automation-context-params","text":"Every servercraft infrastructure command creates an FTL2 `automation()` context with `fail_fast=True`, `auto_install_deps=True`, and `secret_bindings` mapping module FQCNs to Vault secret names (`LINODE_TOKEN`, `LINODE_ROOT_PASS`, `SLACK_TOKEN`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-automation-context-params.json"},{"id":"servercraft-config-default-servers-yml","text":"All servercraft commands accept `--config path/to/servers.yml` with the default being `servers.yml`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-config-default-servers-yml.json"},{"id":"servercraft-default-subcommand-is-tui","text":"Running `ftl2-servercraft` with no subcommand launches the TUI dashboard (equivalent to `ftl2-servercraft tui`).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-default-subcommand-is-tui.json"},{"id":"servercraft-game-server-polymorphism","text":"Servercraft implements game server polymorphism: the `script` field in servers.yml selects a Python module implementing the 8-function script interface, with game-specific variations (NeoForge: 7-step provision, 30s backup poll, \"minecraft\" tmux session; Terraria: 5s backup wait, port 7777, \"terraria\" host group, regex-based player count) all conforming to the same lifecycle contract.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-game-server-polymorphism.json"},{"id":"servercraft-gate-modules-on-launch","text":"The `launch` and `reconfigure` commands use `gate_modules=\"auto\"` with `gate_dependencies=[\"httpx\"]` to pre-build modules for remote execution performance.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-gate-modules-on-launch.json"},{"id":"servercraft-get-player-count-returns-none-when-down","text":"`get_player_count()` returns `None` when the tmux session is down (server not running), `0` when running but no players matched, or the parsed player count as an integer.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-get-player-count-returns-none-when-down.json"},{"id":"servercraft-intelligent-lifecycle-management","text":"Servercraft implements intelligent lifecycle management: automated watchdog paths (warmup grace, consecutive-failure threshold, player-join reset) and manual stop paths adapt teardown behavior based on operational context — watchdog aborts on backup failure to preserve data, while manual stop continues past backup failure because the user explicitly chose to shut down.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-intelligent-lifecycle-management.json"},{"id":"servercraft-is-minecraft-lifecycle-manager","text":"ftl2-servercraft is a Minecraft server lifecycle manager built on FTL2, providing CLI subcommands to provision, start, stop, back up, verify, and monitor game servers on Linode infrastructure.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-is-minecraft-lifecycle-manager.json"},{"id":"servercraft-launch-lifecycle-sequence","text":"The `launch` subcommand runs the full lifecycle: provision → optionally restore from backup → start → verify. Verification failure raises `RuntimeError` and exits with code 1.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-launch-lifecycle-sequence.json"},{"id":"servercraft-neoforge-backup-polls-30s","text":"The NeoForge `backup_world()` sends `save-all` and polls the server log for up to 30 seconds waiting for \"Saved the game\" confirmation before archiving. Proceeds with a warning if confirmation never appears.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-neoforge-backup-polls-30s.json"},{"id":"servercraft-neoforge-provision-seven-steps","text":"The NeoForge `provision()` function orchestrates seven sequential steps (infrastructure, minecraft install, utilities, security, swap, ownership, DDNS) plus an optional NeoForge install, each idempotent via `ftl.state` checks.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-neoforge-provision-seven-steps.json"},{"id":"servercraft-neoforge-tmux-session-name","text":"The NeoForge Minecraft server script uses the tmux session name constant `TMUX_SESSION = \"minecraft\"`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-neoforge-tmux-session-name.json"},{"id":"servercraft-neoforge-uses-ftl-add-host","text":"The NeoForge script uses `ftl.add_host()` to dynamically register the provisioned server into the `minecraft` group for subsequent module execution.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-neoforge-uses-ftl-add-host.json"},{"id":"servercraft-resilient-on-idempotent-infrastructure","text":"Servercraft game servers achieve infrastructure-level resilience: watchdog-triggered re-provisioning and reconfiguration are safe because the cloud provisioning pipeline is idempotent end-to-end (state persistence, create-guards, DNS idempotency), and the polymorphic script interface ensures each game type handles its own recovery sequence correctly.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-resilient-on-idempotent-infrastructure.json"},{"id":"servercraft-result-dict-helper","text":"The Terraria script includes a `_result_dict()` helper that normalizes FTL2 action results (which can be dicts, lists, or objects with `.output`) into plain dicts for extracting `stdout`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-result-dict-helper.json"},{"id":"servercraft-slack-failures-silently-swallowed","text":"In the servercraft provisioning scripts, Slack notification failures are silently swallowed via double-wrapped try/except blocks to prevent notification errors from aborting infrastructure operations.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-slack-failures-silently-swallowed.json"},{"id":"servercraft-ssh-bootstrap-pattern","text":"Servercraft provisioning scripts use an SSH bootstrap pattern: initially connect as `root`, create an admin user, harden SSH (disable password auth, IPv4-only), then re-register the host with the admin user.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-ssh-bootstrap-pattern.json"},{"id":"servercraft-stop-does-not-abort-on-backup-failure","text":"The `stop` subcommand performs save → backup → Slack notification → destroy, where backup and Slack failures are caught and logged but do not abort the destroy step.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-stop-does-not-abort-on-backup-failure.json"},{"id":"servercraft-teardown-context-sensitivity","text":"Servercraft teardown behavior is context-sensitive: the manual `stop` subcommand continues past backup failure (user explicitly chose to stop), while watchdog-initiated teardown aborts on backup failure (automated safety demands a higher bar).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-teardown-context-sensitivity.json"},{"id":"servercraft-terraria-backup-waits-5s","text":"The Terraria `backup_world()` sends `save` to the console and waits 5 seconds before fetching the `.wld` file, compared to the NeoForge script which polls for 30 seconds.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-terraria-backup-waits-5s.json"},{"id":"servercraft-terraria-default-port-7777","text":"The Terraria provisioning script opens TCP port 7777 (Terraria default) via firewalld.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-terraria-default-port-7777.json"},{"id":"servercraft-terraria-host-group-name","text":"The Terraria script registers provisioned servers into the `terraria` host group (vs. `minecraft` for NeoForge), using `ftl.add_host()`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-terraria-host-group-name.json"},{"id":"servercraft-terraria-player-count-regex","text":"The Terraria script reads player count by capturing the tmux pane output and regex-matching `N players? connected`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-terraria-player-count-regex.json"},{"id":"servercraft-terraria-tmux-session-name","text":"The Terraria server script uses the tmux session name constant `TMUX_SESSION = \"terraria\"`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-terraria-tmux-session-name.json"},{"id":"servercraft-tmux-based-server-management","text":"Game servers in ftl2-servercraft run in tmux sessions on remote hosts; all monitoring and control happens through tmux commands executed via FTL2 shell modules.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-tmux-based-server-management.json"},{"id":"servercraft-tui-built-on-textual","text":"The servercraft TUI dashboard is built on the Textual framework (with Rich for text styling), using Screen, ModalScreen, DataTable, RichLog, Header, Button, and Label widgets.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-tui-built-on-textual.json"},{"id":"servercraft-tui-daemon-threads-with-own-event-loops","text":"All FTL2 operations in the TUI run in daemon threads with their own asyncio event loops, keeping the UI responsive while infrastructure operations execute.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-tui-daemon-threads-with-own-event-loops.json"},{"id":"servercraft-tui-detects-existing-state-on-startup","text":"The TUI runs `_check_existing_state()` on startup to read FTL2 state files and detect already-provisioned servers, so the dashboard reflects reality on restart.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-tui-detects-existing-state-on-startup.json"},{"id":"servercraft-tui-refreshes-every-2s","text":"The TUI dashboard refreshes every 2 seconds by reading shared `runtime_state` from a timer callback.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-tui-refreshes-every-2s.json"},{"id":"servercraft-tui-shared-state-no-locking","text":"The TUI uses module-level `runtime_state` dict of `ServerState` dataclasses as shared mutable state between background threads and the UI, with no locking — relying on the GIL and simple attribute writes.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-tui-shared-state-no-locking.json"},{"id":"servercraft-verify-exit-code-2-for-missing-tmux","text":"The `verify` subcommand exits with code 2 if the tmux session is not found (distinct from code 1 for errors).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-verify-exit-code-2-for-missing-tmux.json"},{"id":"servercraft-watchdog-3-consecutive-failures-teardown","text":"Three consecutive unreachable player count polls triggers an emergency backup + teardown sequence.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-watchdog-3-consecutive-failures-teardown.json"},{"id":"servercraft-watchdog-600s-warmup","text":"The watchdog module sleeps 600 seconds (10 minutes) before its first player count poll, allowing the game server time to finish starting.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-watchdog-600s-warmup.json"},{"id":"servercraft-watchdog-backup-failure-aborts-teardown","text":"If backup fails during watchdog-initiated teardown, the teardown is aborted and the server status is set to `error`, preventing data loss.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-watchdog-backup-failure-aborts-teardown.json"},{"id":"servercraft-watchdog-grace-period-resets-on-player-join","text":"If a player joins during the watchdog grace period (countdown to teardown), the empty-since timer resets completely, canceling the pending teardown.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-watchdog-grace-period-resets-on-player-join.json"},{"id":"servercraft-watchdog-resilience-chain","text":"The servercraft watchdog implements a complete resilience chain: 10-minute warmup avoids false positives on slow starts, 3-consecutive-failure threshold absorbs transient errors, grace period resets on player join, and backup failure aborts teardown to prevent data loss.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-watchdog-resilience-chain.json"},{"id":"servercraft-watchdog-three-exit-conditions","text":"The watchdog loop exits on one of three conditions: (1) grace period expires and server is torn down, (2) 3 consecutive unreachable polls trigger teardown, or (3) `state.watchdog_active` is set to `False` externally by the user.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/servercraft-watchdog-three-exit-conditions.json"},{"id":"shell-command-raw-policy-equivalent","text":"`shell`, `command`, and `raw` modules are treated as policy-equivalent by FTL2's policy engine — denying one blocks all three, including FQCN variants.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/shell-command-raw-policy-equivalent.json"},{"id":"shell-module-not-backup-capable","text":"The FTL2 shell module declares `Backup-Capable: No` because its effects are unpredictable.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/shell-module-not-backup-capable.json"},{"id":"shell-module-returns-changed-true","text":"The FTL2 `shell` module returns `{\"changed\": true, \"stdout\": \"...\", \"stderr\": \"...\", \"rc\": 0}` — it always reports `changed: true`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/shell-module-returns-changed-true.json"},{"id":"single-file-idempotent-cloud-deployments","text":"FTL2 enables idempotent cloud deployments from single-file scripts: PEP 723 scripts with integrated credential management (secret bindings, defense-in-depth) orchestrate a complete idempotent provisioning pipeline (state persistence, crash recovery, shell guards, creates parameter) requiring no project structure, virtualenvs, or separate configuration files.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/single-file-idempotent-cloud-deployments.json"},{"id":"single-file-secure-deployment-scripts","text":"FTL2 enables complete deployment scripts in a single file with integrated credential management: PEP 723 inline metadata self-bootstraps dependencies via uv run, while secret bindings auto-inject credentials without source code exposure, redact values in logs, and lazy-evaluate at call time.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/single-file-secure-deployment-scripts.json"},{"id":"ssh-connection-efficient-reuse","text":"FTL2's SSH layer is designed for connection efficiency: the connection pool reuses connections to identical hosts, `asyncssh` provides async non-blocking I/O, `ssh_run_on_hosts` parallelizes across hosts, and the gate protocol sends only JSON parameters over established connections — eliminating per-task connection overhead.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ssh-connection-efficient-reuse.json"},{"id":"ssh-connection-pool-reuses-connections","text":"`SSHConnectionPool.get()` reuses connections to the same host — calling `get()` with identical config returns the same `SSHHost` object.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ssh-connection-pool-reuses-connections.json"},{"id":"ssh-imports-from-ftl2-ssh","text":"The SSH user-facing API (`SSHHost`, `SSHConnectionPool`, `ssh_run`, `ssh_run_on_hosts`) is imported from `ftl2.ssh`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ssh-imports-from-ftl2-ssh.json"},{"id":"ssh-readiness-gate-complete","text":"FTL2 provides comprehensive SSH readiness gating: `wait_for_ssh()` blocks with configurable timeout and delay until SSH is available, `wait_for` module checks arbitrary TCP ports as a generic readiness gate, and both serve as blocking preconditions before configuration commands are sent.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ssh-readiness-gate-complete.json"},{"id":"ssh-run-on-hosts-parallel","text":"`ssh_run_on_hosts()` runs commands on multiple hosts in parallel and returns a list of `(hostname, stdout, stderr, rc)` tuples.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/ssh-run-on-hosts-parallel.json"},{"id":"sshhost-is-async-context-manager","text":"`SSHHost` is used as an async context manager (`async with host:`) which handles connect/disconnect automatically.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/sshhost-is-async-context-manager.json"},{"id":"sshhost-run-returns-3-tuple","text":"`SSHHost.run()` returns a 3-tuple `(stdout, stderr, rc)` and does not raise an exception on non-zero return code — the caller must check `rc`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/sshhost-run-returns-3-tuple.json"},{"id":"state-driven-reliable-rerunability","text":"FTL2 achieves reliable re-runnability through persistent state orchestration combined with multi-layer idempotency: the state file persists between runs, enables crash recovery, and shares context across AI-loop rules, while shell guards, `creates` parameters, and module-level idempotency ensure repeated execution converges without side effects.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/state-driven-reliable-rerunability.json"},{"id":"state-file-cross-rule-sharing","text":"AI-loop rules share state via the FTL2 state file — e.g., a provisioning rule writes `resources.arcade.ipv4` and a DNS rule reads it via `state[\"_state_file\"][\"resources\"][\"arcade\"][\"ipv4\"]`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/state-file-cross-rule-sharing.json"},{"id":"state-file-format-and-api","text":"FTL2's state file is `.ftl2-state.json`; existence is checked with `ftl.state.has(\"name\")`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/state-file-format-and-api.json"},{"id":"state-file-orchestration-backbone","text":"The FTL2 state file serves as the orchestration backbone: it persists between runs, enables crash recovery, shares state across AI-loop rules, and provides the resource lookup key for multi-script workflows.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/state-file-orchestration-backbone.json"},{"id":"state-file-persists-between-runs","text":"The FTL2 state file (e.g., `state.json`) persists host IPs and connection info between separate script runs — `redeploy` reads it to recover the Linode IP without re-querying the API.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/state-file-persists-between-runs.json"},{"id":"state-has-get-read-api","text":"`ftl.state.has(key)` checks if a resource exists in the state file and `ftl.state.get(key)` retrieves its metadata dict. Used to skip provisioning on re-runs and to look up IPs for re-registration.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/state-has-get-read-api.json"},{"id":"state-managed-resource-teardown","text":"FTL2 resource teardown is state-managed and orderly: destroy operations look up resources by label (not ID), state files are cleaned up after successful destroy, modules use `state=absent` for removal, and teardown must follow reverse dependency order (instances before networks).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/state-managed-resource-teardown.json"},{"id":"streaming-executor-default-timeout-300","text":"All streaming executor functions (`execute_local_streaming`, `execute_remote_streaming`, `execute_remote_with_staging_streaming`) have a default timeout of 300 seconds.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/streaming-executor-default-timeout-300.json"},{"id":"structured-results-adaptive-presentation","text":"FTL2's consistent result contract complements its flexible output modes: every module returns success/changed/output/error fields regardless of execution context, while a separate output verbosity spectrum — from errors-only default through verbose per-operation timing to quiet structured event capture — allows tuning presentation for development through production use via parameter changes alone.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/structured-results-adaptive-presentation.json"},{"id":"sudoers-drop-in-pattern","text":"FTL2 deployment rules use `/etc/sudoers.d/<username>` drop-in files rather than editing `/etc/sudoers` directly for granting sudo access.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/sudoers-drop-in-pattern.json"},{"id":"template-renders-locally-via-jinja2","text":"Templates are rendered locally via Jinja2 with variables passed as `**kwargs`, then transferred to the remote host via the `copy()` method.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/template-renders-locally-via-jinja2.json"},{"id":"terraform-provider-grpc-bridge-python-to-go","text":"Terraform provider integration in FTL2 requires a gRPC protocol bridge from Python to Go because FTL2 is Python and Terraform providers are Go.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/terraform-provider-grpc-bridge-python-to-go.json"},{"id":"terraform-provider-state-maps-to-ftl2-state-json","text":"State from Terraform providers maps to the same `.ftl2-state.json` format used by native FTL2 state tracking.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/terraform-provider-state-maps-to-ftl2-state-json.json"},{"id":"textual-serve-wraps-tui-for-web","text":"The `textual serve -c \"<command>\" --port <port>` command wraps a Textual TUI application for web browser access.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/textual-serve-wraps-tui-for-web.json"},{"id":"two-phase-bootstrap-lifecycle","text":"FTL2's two-phase host registration is a complete bootstrap lifecycle: connect as root, create admin user, re-register as the unprivileged admin, then apply security hardening before any application content.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/two-phase-bootstrap-lifecycle.json"},{"id":"two-phase-host-registration-bootstrap","text":"For bootstrapping fresh VMs, a two-phase host registration pattern is used: first register as `root` for initial user creation, then re-register as the unprivileged user with `ansible_become=True` for all subsequent operations.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/two-phase-host-registration-bootstrap.json"},{"id":"uniform-governance-static-and-dynamic-infrastructure","text":"Both pre-existing and dynamically provisioned infrastructure can receive strong security governance and auditability through FTL2's mechanisms: static deployments use state-driven idempotent re-execution with event tracking, while dynamically provisioned hosts receive two-phase bootstrap hardening — and both pass through the same policy, credential, and privilege escalation enforcement layers with structured event emission for audit.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/uniform-governance-static-and-dynamic-infrastructure.json"},{"id":"universal-modules-at-peak-performance","text":"FTL2's universal module system supports multiple addressing patterns (dot-access, bracket notation, FQCN chains, host-scoped proxy) that resolve to modules executable through either native in-process or Ansible-compatible bundled modes. These modules can benefit from FTL2's three-tier optimization stack (in-process native execution, gate-cached remote delivery, default parallel host targeting), though the antecedents do not establish that all addressing patterns achieve identical performance characteristics across all tiers.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/universal-modules-at-peak-performance.json"},{"id":"uv-run-inline-script-metadata","text":"FTL2 deployment scripts use `uv run` with PEP 723 inline script metadata to self-bootstrap dependencies (FTL2, linode-api4) — no separate virtual environment setup is needed.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/uv-run-inline-script-metadata.json"},{"id":"validated-dynamic-cloud-provisioning","text":"Cloud provisioning is validation-gated end-to-end: after VM creation via cloud API and dynamic host registration via add_host, SSH readiness gating verifies the host is actually reachable before two-phase bootstrap and configuration begin, preventing wasted operations against unreachable hosts.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/validated-dynamic-cloud-provisioning.json"},{"id":"vault-complete-integration-requirements","text":"Vault integration involves a three-part setup: the `hvac` optional dependency (`pip install ftl2[vault]`), two environment variables (`VAULT_ADDR` and `VAULT_TOKEN`), and secret reads that are grouped by path to minimize API calls — a layered configuration where each part addresses a different concern (library availability, connection credentials, and API efficiency).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/vault-complete-integration-requirements.json"},{"id":"vault-reads-grouped-by-path","text":"Vault reads are grouped by path to minimize API calls when multiple secrets share the same Vault path.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/vault-reads-grouped-by-path.json"},{"id":"vault-requires-addr-and-token-env-vars","text":"Vault integration requires `VAULT_ADDR` and `VAULT_TOKEN` environment variables.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/vault-requires-addr-and-token-env-vars.json"},{"id":"vault-requires-extra-and-env-vars","text":"Vault integration requires `pip install ftl2[vault]` and the `VAULT_ADDR` and `VAULT_TOKEN` environment variables to be set.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/vault-requires-extra-and-env-vars.json"},{"id":"vault-requires-hvac-optional-extra","text":"Vault integration requires installing the optional `hvac` dependency via `pip install ftl2[vault]`.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/vault-requires-hvac-optional-extra.json"},{"id":"verbose-flag-triple-v","text":"The `-vvv` flag enables verbose logging in FTL2 for troubleshooting remote execution issues.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/verbose-flag-triple-v.json"},{"id":"verbose-shows-operations-with-timing","text":"`automation(verbose=True)` shows every operation with execution timing.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/verbose-shows-operations-with-timing.json"},{"id":"verify-server-returns-bool-player-count-returns-int-or-none","text":"In the script interface, `verify_server` returns `bool` and `get_player_count` returns `int | None` where None indicates server unreachable (distinct from zero players).","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/verify-server-returns-bool-player-count-returns-int-or-none.json"},{"id":"wait-for-module-ssh-gate","text":"FTL2 provides a `wait_for` module (called as `ftl.wait_for(host=..., port=22, timeout=300)`) that blocks until a TCP port is reachable — used to gate downstream rules on SSH readiness after provisioning.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/wait-for-module-ssh-gate.json"},{"id":"wait-for-ssh-polls-until-available","text":"`ftl.<host>.wait_for_ssh(timeout=120, delay=10)` polls until SSH is available on a host, with `timeout` in seconds and `delay` between retries.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/wait-for-ssh-polls-until-available.json"},{"id":"watchdog-long-running-automation-context","text":"FTL2 automation contexts can be held open for hours in watchdog/monitoring loops. The context manages SSH connections and state for the lifetime of the `async with` block.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/watchdog-long-running-automation-context.json"},{"id":"watchdog-safe-reexecution","text":"Servercraft's watchdog safely re-invokes infrastructure operations because FTL2's multi-layer idempotency ensures re-execution never creates duplicate state: shell guards skip completed installs, the creates parameter skips existing files, and module-level idempotency handles the rest — so watchdog-triggered re-provisioning after consecutive failures is always safe.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/watchdog-safe-reexecution.json"},{"id":"zero-setup-full-ecosystem-scripts","text":"FTL2 enables zero-setup scripts that access the full module ecosystem: PEP 723 inline metadata with uv run eliminates project scaffolding, while dual-mode execution provides both native fast-path modules and Ansible collection compatibility in the same script.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/zero-setup-full-ecosystem-scripts.json"},{"id":"zero-to-autonomous-production-journey","text":"FTL2 supports a developer journey from zero-setup scripting to production execution with autonomous remediation capabilities: frictionless onboarding (PEP 723/uv, dual-mode modules) flows into an optimized cloud-to-execution pipeline, while AI-loop remediation with structured observability enables self-healing actions that are event-tracked and verifiable — reducing the need for platform switches between prototyping and production.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/zero-to-autonomous-production-journey.json"},{"id":"zero-to-production-developer-journey","text":"FTL2 delivers a complete developer journey from zero-setup to production execution: frictionless onboarding (PEP 723/uv scripts, dual-mode module ecosystem) flows into an optimized cloud-to-execution pipeline (provision, add_host, gate optimization, parallel execution), enabling developers to go from a single file to running infrastructure with no scaffolding or intermediate tooling.","truth_value":"IN","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null,"url":"/public/ftl2-automation-expert/belief/zero-to-production-developer-journey.json"}],"count":512}