{"record":{"id":"038ae0bcad96a5f4","repo":"ruvnet/ruflo","slug":"approval-issuance-requires-an-authenticated-human","errorCode":null,"errorMessage":"approval issuance requires an authenticated human identity adapter; the local TTY is not an identity credential","messagePattern":"approval issuance requires an authenticated human identity adapter; the local TTY is not an identity credential","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/commands/policy.ts","lineNumber":89,"sourceCode":"        });\n      }\n      if (operation === 'evaluate') {\n        return print(await evaluatePolicyRequest(argJson<PolicyRequest>(args[1], 'evaluate'), root));\n      }\n      if (operation === 'rule' && args[1] === 'add') {\n        requireInteractiveAdministrator();\n        const rule = argJson<PolicyRule>(args[2], 'rule add');\n        await upsertPolicyRule(rule, root);\n        return print({ success: true, ruleId: rule.id });\n      }\n      if (operation === 'budget' && args[1] === 'set') {\n        requireInteractiveAdministrator();\n        const budget = argJson<BudgetLimit>(args[2], 'budget set');\n        await setPolicyBudget(budget, root);\n        return print({ success: true, budgetId: budget.id });\n      }\n      if (operation === 'approve') {\n        throw new Error(\n          'approval issuance requires an authenticated human identity adapter; '\n          + 'the local TTY is not an identity credential',\n        );\n      }\n      if (operation === 'revoke') {\n        requireInteractiveAdministrator();\n        if (!args[1]) throw new Error('revoke requires an approval id');\n        return print({ success: await revokePolicyApproval(args[1], root), approvalId: args[1] });\n      }\n      if (operation === 'audit') {\n        const state = loadPolicyState(root);\n        return print({ receipts: state.receipts });\n      }\n      if (operation === 'verify') return print(await verifyPolicyLedger(root));\n      throw new Error(`unknown policy operation: ${operation}`);\n    } catch (error) {\n      const message = error instanceof Error ? error.message : String(error);\n      output.printError(message);","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/ruvnet/ruflo/blob/6b01dc5a687b26b3e218f796de45ec51f8fa9e8c/v3/@claude-flow/cli/src/commands/policy.ts#L71-L107","documentation":"The `policy approve` operation ALWAYS throws this — it is intentionally unimplemented. Per ADR-324, approval issuance requires a genuine authenticated human identity (an identity adapter), and a local TTY does not constitute an identity credential. The CLI deliberately refuses to mint approvals from a terminal to prevent privilege escalation via whoever happens to be at the keyboard.","triggerScenarios":"Calling `ruflo policy approve <anything>` from any context. The branch is unconditional; it throws before any argument parsing for the approve subcommand.","commonSituations":"Operators expecting a manual override command, scripts trying to pre-approve an action, or assuming approval is symmetric with revoke (which IS supported interactively).","solutions":["Do not call `policy approve` from the CLI — it is unsupported by design.","Obtain approvals through the authenticated identity adapter path referenced in ADR-324 (e.g. an external identity provider / policy service), not the local terminal.","If you only need to remove an existing approval, use `policy revoke <id>` from an interactive terminal instead."],"exampleFix":"// before\nruflo policy approve action-123\n// after — approvals are issued via the identity adapter, not the CLI\n# revoke (the supported interactive inverse) works:\nruflo policy revoke approval-abc","handlingStrategy":"validation","validationCode":"// The approve operation is intentionally unsupported. Block it in your dispatcher.\nconst UNSUPPORTED_POLICY_OPS = new Set(['approve']);\nfunction dispatchPolicy(op: string): void {\n  if (UNSUPPORTED_POLICY_OPS.has(op)) {\n    throw new Error(`policy '${op}' is unsupported from the CLI; use the identity adapter (ADR-324)`);\n  }\n}","typeGuard":"const isCliSupportedPolicyOp = (op: string): boolean =>\n  !['approve'].includes(op) &&\n  ['init','migrate','status','rule','budget','revoke','audit','verify'].includes(op);","tryCatchPattern":"// No retry — this branch throws unconditionally. Treat as a programming error.\nif (op === 'approve') {\n  throw new Error('do not call policy approve from the CLI; route through the identity adapter');\n}","preventionTips":["Never call `policy approve` — by design it always fails.","Issue approvals only through the authenticated identity adapter path.","Use `policy revoke` for the interactive inverse."],"tags":["cli","security","policy","auth","adr-324"],"backgroundTag":null,"analyzedSha":"6b01dc5a687b26b3e218f796de45ec51f8fa9e8c","analyzedAt":"2026-08-12T13:20:50.148Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}