{"results":[{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"id":"deployment-secrets-are-manual","text":"In FTL2 deployments (e.g., ftl2-stargate), secrets such as Google OAuth credentials are entered interactively at startup and are not handled by the deployment automation.","truth_value":"OUT","justification_count":0,"dependent_count":0,"challenges":[],"last_reviewed":null,"review_result":null},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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},{"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}],"count":24,"limit":20,"offset":0}