{"results":[{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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}],"count":142,"limit":20,"offset":0}