From e18ab818df6d686b588d161745e4e94c2f1f04ee Mon Sep 17 00:00:00 2001 From: Tombar Date: Fri, 17 Jul 2026 21:24:29 -0300 Subject: [PATCH 1/6] fix(explain): resolve live mode chain instead of hardcoding enabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit explain now resolves the live mode the same way the hook does (env, pane-mode files, config), so its verdict matches what the hook would actually decide. Previously it hardcoded "enabled", so a disabled pane or FAILSAFE_MODE=disabled was invisible to explain — contradicting the docs' claim that explain shows what the hook would do. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TiYGMkQeeiUQ6vWVqJaaQc --- cmd/failsafe/main.go | 8 +++++++- cmd/failsafe/main_test.go | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/cmd/failsafe/main.go b/cmd/failsafe/main.go index e0a7edc..a6ae540 100644 --- a/cmd/failsafe/main.go +++ b/cmd/failsafe/main.go @@ -42,10 +42,16 @@ func run(args []string, stdin io.Reader, stdout, stderr io.Writer) int { return subcommand.MCP(stdin, stdout, stderr) case "explain": cwd, _ := os.Getwd() + // Resolve the live mode the same way the hook does, so explain's + // verdict matches what the hook would actually decide. + liveMode, _, err := subcommand.ModeChainFromConfig(cfg, os.Getenv("HOME")).Resolve(subcommand.EnvFromOS()) + if err != nil { + liveMode = "enabled" // fail-safe: an unresolvable mode never weakens the verdict + } return subcommand.Explain(args[2:], stdout, subcommand.ExplainOptions{ Home: os.Getenv("HOME"), CWD: cwd, - Mode: "enabled", // chain default is always hardcoded; no mode.default config key + Mode: liveMode, }) case "test": if len(args) < 3 { diff --git a/cmd/failsafe/main_test.go b/cmd/failsafe/main_test.go index 1ce0cfe..f4d363f 100644 --- a/cmd/failsafe/main_test.go +++ b/cmd/failsafe/main_test.go @@ -43,3 +43,20 @@ func TestRun_Report(t *testing.T) { t.Errorf("report did not include the logged kubectl decision:\n%s", stdout.String()) } } + +// Regression: explain must resolve the live mode chain (env, pane files, …), +// not assume "enabled". A disabled pane must be reflected in explain's verdict, +// or the docs claim "explain shows what the hook would do" is false. +func TestRun_ExplainResolvesLiveMode(t *testing.T) { + t.Setenv("HOME", t.TempDir()) // isolate pane/config state + t.Setenv("FAILSAFE_MODE", "disabled") + + var stdout, stderr bytes.Buffer + code := run([]string{"failsafe", "explain", "kubectl delete ns payments"}, nil, &stdout, &stderr) + if code != 0 && code != 1 { // 0=allow, 1=block are both valid exits; 2=usage error is not + t.Fatalf("exit code = %d; stderr=%s", code, stderr.String()) + } + if !strings.Contains(stdout.String(), "Mode: disabled") { + t.Errorf("explain ignored FAILSAFE_MODE=disabled:\n%s", stdout.String()) + } +} From 783346e6c707034cf45043d7d26bb1966bf86c8b Mon Sep 17 00:00:00 2001 From: Tombar Date: Fri, 17 Jul 2026 22:15:44 -0300 Subject: [PATCH 2/6] docs(demos): live hotkey + inside-Claude recordings; per-keystroke typing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rewrite scripts/record-docs.sh (v2): - Human-visible typing: every command is typed one glyph at a time via a new type_line helper (TYPE_DELAY, default 0.05s; 0 = instant), replacing the atomic `virtui exec` in the step loop with type_line + `virtui wait`. Casts now read like someone at a keyboard, not text teleporting in. - --render and --claude parse in any order. - New tmux-hotkey scenario: the Ctrl+Alt+T per-pane toggle flipping the guard enabled<->disabled live — the same command BLOCKs, then (after the chord, sent as `press Escape Ctrl+T` through the tmux root key table) ALLOWs when re-run from shell history, then BLOCKs again, with the status bar following. The tmux config is materialised from docs/toggle/tmux.md's own fenced blocks (via test/docs/lib/extract.sh) so it can't drift. - New opt-in --claude scenario (record_claude_hook): failsafe blocking a kubectl delete inside Claude Code, then the hotkey flipping the guard without leaving the Claude TUI. Runs with the REAL home (Claude auth is Keychain/~/.claude), isolates writes via FAILSAFE_LOG -> throwaway file, and removes only the pane-mode file its toggle creates. Degrades gracefully (skips if claude/tmux absent; a flaky turn warns and the other casts are unaffected). Recorded + rendered: explain-block, mode-toggle, audit, tmux-hotkey (.cast + .svg). Per-char typing verified (one output event per glyph); tmux-hotkey verified to contain Decision: BLOCK, Decision: ALLOW, and the `sudo` status flip. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TiYGMkQeeiUQ6vWVqJaaQc --- docs/assets/casts/audit.cast | 87 +++++--- docs/assets/casts/audit.svg | 2 +- docs/assets/casts/explain-block.cast | 264 +++++++++++++++++++++--- docs/assets/casts/explain-block.svg | 2 +- docs/assets/casts/mode-toggle.cast | 249 +++++++++++++++++++---- docs/assets/casts/mode-toggle.svg | 2 +- docs/assets/casts/tmux-hotkey.cast | 170 ++++++++++++++++ docs/assets/casts/tmux-hotkey.svg | 1 + scripts/record-docs.sh | 288 +++++++++++++++++++++++++-- 9 files changed, 943 insertions(+), 122 deletions(-) create mode 100644 docs/assets/casts/tmux-hotkey.cast create mode 100644 docs/assets/casts/tmux-hotkey.svg diff --git a/docs/assets/casts/audit.cast b/docs/assets/casts/audit.cast index e0c871b..c2122d0 100644 --- a/docs/assets/casts/audit.cast +++ b/docs/assets/casts/audit.cast @@ -1,29 +1,58 @@ -{"version":2,"width":92,"height":22,"timestamp":1784331898} -[0.005935, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] -[0.006175, "o", "\u001b[?1034h"] -[0.006191, "o", "bash-3.2$ "] -[0.013003, "i", "export PS1='$ '; cd \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/project\"; clear\r"] -[0.013056, "o", "e"] -[0.013092, "o", "xport PS1='$ '; "] -[0.013099, "o", "cd"] -[0.013206, "o", " \"/var/folders/12/mydd4m455zn9t"] -[0.013214, "o", "__"] -[0.013315, "o", "48syck4940000gn/T//fa"] -[0.013368, "o", "ilsafe-do \rcs-"] -[0.013432, "o", "home/project\"; clear\r\n"] -[0.015773, "o", "\u001b[3J\u001b[H\u001b[2J"] -[0.016056, "o", "$ "] -[0.543033, "i", "failsafe audit\r"] -[0.543163, "o", "f"] -[0.543232, "o", "ailsafe audit\r\n"] -[0.557055, "o", "Policy layers in effect at /var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/project:\r\n\r\n [bundled]\r\n"] -[0.557309, "o", " bundled/aws.rego — 2 block rule(s)\r\n"] -[0.557386, "o", " bundled/failsafe.rego — 2 block rule(s)\r\n"] -[0.557536, "o", " bundled/git.rego — 0 block rule(s)\r\n"] -[0.557630, "o", " bundled/helm.rego — 2 block rule(s)\r\n"] -[0.557722, "o", " bundled/kubectl.rego — 1 block rule(s)\r\n"] -[0.557803, "o", " bundled/terraform.rego — 2 block rule(s)\r\n\r\n9 block rules total, 0 allow_override.\r\n"] -[0.558949, "o", "$ "] -[2.585943, "i", "exit\r"] -[2.586019, "o", "ex"] -[2.586093, "o", "it\r\nexit\r\n"] +{"version":2,"width":92,"height":22,"timestamp":1784334849} +[0.005793, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] +[0.006007, "o", "\u001b[?1034h"] +[0.006020, "o", "bash-3.2$ "] +[0.011097, "i", "export PS1='$ '; cd \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/project\"; clear\r"] +[0.011128, "o", "e"] +[0.011165, "o", "xport PS1='$ '; cd "] +[0.011213, "o", "\"/var/folders/12/my"] +[0.011260, "o", "dd4m455zn9t__4"] +[0.011267, "o", "8s"] +[0.011343, "o", "yck4940000gn/T//fai"] +[0.011386, "o", "lsafe-do \rcs-ho"] +[0.011428, "o", "me/project\"; clea"] +[0.011469, "o", "r\r\n"] +[0.013415, "o", "\u001b[3J\u001b[H\u001b[2J"] +[0.013650, "o", "$ "] +[0.536898, "i", "f"] +[0.537003, "o", "f"] +[0.612068, "i", "a"] +[0.612155, "o", "a"] +[0.683702, "i", "i"] +[0.683783, "o", "i"] +[0.748184, "i", "l"] +[0.748229, "o", "l"] +[0.815811, "i", "s"] +[0.815869, "o", "s"] +[0.884732, "i", "a"] +[0.884803, "o", "a"] +[0.951374, "i", "f"] +[0.951433, "o", "f"] +[1.025238, "i", "e"] +[1.025380, "o", "e"] +[1.090788, "i", " "] +[1.090838, "o", " "] +[1.159001, "i", "a"] +[1.159063, "o", "a"] +[1.226645, "i", "u"] +[1.226720, "o", "u"] +[1.296252, "i", "d"] +[1.296308, "o", "d"] +[1.367866, "i", "i"] +[1.367924, "o", "i"] +[1.437083, "i", "t"] +[1.437144, "o", "t"] +[1.507146, "i", "\r"] +[1.507203, "o", "\r\n"] +[1.516153, "o", "Policy layers in effect at /var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/project:\r\n\r\n [bundled]\r\n"] +[1.516374, "o", " bundled/aws.rego — 2 block rule(s)\r\n"] +[1.516422, "o", " bundled/failsafe.rego — 2 block rule(s)\r\n"] +[1.516444, "o", " bundled/git.rego — 0 block rule(s)\r\n"] +[1.516514, "o", " bundled/helm.rego — 2 block rule(s)\r\n"] +[1.516592, "o", " bundled/kubectl.rego — 1 block rule(s)\r\n"] +[1.516675, "o", " bundled/terraform.rego — 2 block rule(s)\r\n\r\n9 block rules total, 0 allow_override.\r\n"] +[1.517401, "o", "$ "] +[3.536809, "i", "exit\r"] +[3.536926, "o", "e"] +[3.536943, "o", "xit\r\n"] +[3.536986, "o", "exit\r\n"] diff --git a/docs/assets/casts/audit.svg b/docs/assets/casts/audit.svg index 9455ff9..e8218eb 100644 --- a/docs/assets/casts/audit.svg +++ b/docs/assets/casts/audit.svg @@ -1 +1 @@ -Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-do$$failsafeauditPolicylayersineffectat/var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/project:[bundled]bundled/aws.rego2blockrule(s)bundled/failsafe.rego2blockrule(s)bundled/git.rego0blockrule(s)bundled/helm.rego2blockrule(s)bundled/kubectl.rego1blockrule(s)bundled/terraform.rego2blockrule(s)9blockrulestotal,0allow_override.bash-3.2$bash-3.2$ebash-3.2$exportPS1='$';bash-3.2$exportPS1='$';cdbash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9tbash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//facs-cs-home/project";clear$f$ex$exitexit \ No newline at end of file +Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-do$$failsafe$failsafeauditPolicylayersineffectat/var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/project:[bundled]bundled/aws.rego2blockrule(s)bundled/failsafe.rego2blockrule(s)bundled/git.rego0blockrule(s)bundled/helm.rego2blockrule(s)bundled/kubectl.rego1blockrule(s)bundled/terraform.rego2blockrule(s)9blockrulestotal,0allow_override.$exitbash-3.2$bash-3.2$ebash-3.2$exportPS1='$';cdbash-3.2$exportPS1='$';cd"/var/folders/12/mybash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__4bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48sbash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//faics-hocs-home/project";cleacs-home/project";clear$f$fa$fai$fail$fails$failsa$failsaf$failsafea$failsafeau$failsafeaud$failsafeaudi$eexit \ No newline at end of file diff --git a/docs/assets/casts/explain-block.cast b/docs/assets/casts/explain-block.cast index 04aa745..73760b7 100644 --- a/docs/assets/casts/explain-block.cast +++ b/docs/assets/casts/explain-block.cast @@ -1,33 +1,231 @@ -{"version":2,"width":92,"height":22,"timestamp":1784331884} -[0.007669, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] -[0.010914, "o", "\u001b[?1034h"] -[0.011090, "o", "bash-3.2$ "] -[0.016704, "i", "export PS1='$ '; cd \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/project\"; clear\r"] -[0.016757, "o", "e"] -[0.016839, "o", "xport PS1='$ '; cd \"/var/fol"] -[0.016850, "o", "de"] -[0.016962, "o", "rs/12/mydd4m455zn9t__48sy"] -[0.017024, "o", "ck4940000gn/"] -[0.017032, "o", "T"] -[0.017127, "o", "//failsafe-do \rcs-hom"] -[0.017198, "o", "e/project\"; clear\r\n"] -[0.021285, "o", "\u001b[3J\u001b[H\u001b[2J"] -[0.021574, "o", "$ "] -[0.544513, "i", "failsafe explain \"kubectl --context arn:aws:eks:us-east-1:123456789012:cluster/prod delete ns payments\"\r"] -[0.544583, "o", "f"] -[0.544639, "o", "ailsafe explain \"k"] -[0.544713, "o", "ubectl --context "] -[0.544726, "o", "ar"] -[0.544847, "o", "n:aws:eks:us-east-1:"] -[0.544859, "o", "12"] -[0.544984, "o", "3456789012:cluste"] -[0.545062, "o", "r/prod de"] -[0.545137, "o", "lete \r ns pa"] -[0.545211, "o", "yments\"\r\n"] -[0.848167, "o", "── call 1: kubectl ──\r\nVerb: delete\r\nFlags:\r\n"] -[0.848216, "o", " context = arn:aws:eks:us-east-1:123456789012:cluster/prod\r\nPositional: ns payments\r\nEffective cwd: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/project\r\nMode: enabled\r\nPolicy chain (6 modules at this cwd):\r\n [bundled] bundled/aws.rego\r\n [bundled] bundled/failsafe.rego\r\n [bundled] bundled/git.rego\r\n [bundled] bundled/helm.rego\r\n [bundled] bundled/kubectl.rego\r\n [bundled] bundled/terraform.rego\r\nDecision: BLOCK\r\nReason : kubectl delete blocked while failsafe is enabled\r\n"] -[0.849408, "o", "$ "] -[2.882566, "i", "exit\r"] -[2.882745, "o", "e"] -[2.882788, "o", "xit\r\n"] -[2.882877, "o", "exit\r\n"] +{"version":2,"width":92,"height":22,"timestamp":1784334823} +[0.004300, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] +[0.004605, "o", "\u001b[?1034hbash-3.2$ "] +[0.008887, "i", "export PS1='$ '; cd \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/project\"; clear\r"] +[0.008944, "o", "e"] +[0.008984, "o", "xport PS1='$ '; cd \"/var/f"] +[0.008993, "o", "olde"] +[0.009079, "o", "rs/12/mydd4m455zn9t__48syck494000"] +[0.009084, "o", "0"] +[0.009086, "o", "g"] +[0.009089, "o", "n"] +[0.009151, "o", "/T//failsafe-do \rcs-hom"] +[0.009185, "o", "e/project\"; clea"] +[0.009218, "o", "r\r\n"] +[0.011101, "o", "\u001b[3J\u001b[H\u001b[2J"] +[0.011305, "o", "$ "] +[0.524566, "i", "f"] +[0.524653, "o", "f"] +[0.591133, "i", "a"] +[0.591185, "o", "a"] +[0.656933, "i", "i"] +[0.656977, "o", "i"] +[0.722965, "i", "l"] +[0.723013, "o", "l"] +[0.790270, "i", "s"] +[0.790322, "o", "s"] +[0.856334, "i", "a"] +[0.856379, "o", "a"] +[0.923842, "i", "f"] +[0.923894, "o", "f"] +[0.991235, "i", "e"] +[0.991287, "o", "e"] +[1.059449, "i", " "] +[1.059506, "o", " "] +[1.127136, "i", "e"] +[1.127196, "o", "e"] +[1.193988, "i", "x"] +[1.194055, "o", "x"] +[1.262359, "i", "p"] +[1.262430, "o", "p"] +[1.326483, "i", "l"] +[1.326541, "o", "l"] +[1.389784, "i", "a"] +[1.389837, "o", "a"] +[1.454047, "i", "i"] +[1.454088, "o", "i"] +[1.519117, "i", "n"] +[1.519183, "o", "n"] +[1.583495, "i", " "] +[1.583541, "o", " "] +[1.652557, "i", "\""] +[1.652629, "o", "\""] +[1.716813, "i", "k"] +[1.716867, "o", "k"] +[1.784570, "i", "u"] +[1.784624, "o", "u"] +[1.851673, "i", "b"] +[1.851730, "o", "b"] +[1.918567, "i", "e"] +[1.918627, "o", "e"] +[1.985452, "i", "c"] +[1.985498, "o", "c"] +[2.052410, "i", "t"] +[2.052458, "o", "t"] +[2.122370, "i", "l"] +[2.122432, "o", "l"] +[2.195485, "i", " "] +[2.195563, "o", " "] +[2.264328, "i", "-"] +[2.264417, "o", "-"] +[2.331462, "i", "-"] +[2.331506, "o", "-"] +[2.399034, "i", "c"] +[2.399087, "o", "c"] +[2.467399, "i", "o"] +[2.467456, "o", "o"] +[2.537710, "i", "n"] +[2.537804, "o", "n"] +[2.605700, "i", "t"] +[2.605770, "o", "t"] +[2.672689, "i", "e"] +[2.672768, "o", "e"] +[2.739452, "i", "x"] +[2.739503, "o", "x"] +[2.803879, "i", "t"] +[2.803934, "o", "t"] +[2.869406, "i", " "] +[2.869495, "o", " "] +[2.935837, "i", "a"] +[2.935885, "o", "a"] +[2.997366, "i", "r"] +[2.997416, "o", "r"] +[3.061840, "i", "n"] +[3.061893, "o", "n"] +[3.129341, "i", ":"] +[3.129401, "o", ":"] +[3.193124, "i", "a"] +[3.193181, "o", "a"] +[3.261219, "i", "w"] +[3.261268, "o", "w"] +[3.327434, "i", "s"] +[3.327482, "o", "s"] +[3.393364, "i", ":"] +[3.393411, "o", ":"] +[3.461350, "i", "e"] +[3.461409, "o", "e"] +[3.532832, "i", "k"] +[3.532901, "o", "k"] +[3.606090, "i", "s"] +[3.606175, "o", "s"] +[3.679299, "i", ":"] +[3.679369, "o", ":"] +[3.747239, "i", "u"] +[3.747334, "o", "u"] +[3.814713, "i", "s"] +[3.814752, "o", "s"] +[3.880518, "i", "-"] +[3.880563, "o", "-"] +[3.947592, "i", "e"] +[3.947646, "o", "e"] +[4.017352, "i", "a"] +[4.017422, "o", "a"] +[4.089702, "i", "s"] +[4.089797, "o", "s"] +[4.161091, "i", "t"] +[4.161155, "o", "t"] +[4.228802, "i", "-"] +[4.228885, "o", "-"] +[4.293712, "i", "1"] +[4.293764, "o", "1"] +[4.359526, "i", ":"] +[4.359571, "o", ":"] +[4.425429, "i", "1"] +[4.425486, "o", "1"] +[4.491568, "i", "2"] +[4.491625, "o", "2"] +[4.558319, "i", "3"] +[4.558377, "o", "3"] +[4.625343, "i", "4"] +[4.625400, "o", "4"] +[4.694108, "i", "5"] +[4.694167, "o", "5"] +[4.759564, "i", "6"] +[4.759628, "o", "6"] +[4.826793, "i", "7"] +[4.826856, "o", "7"] +[4.893609, "i", "8"] +[4.893661, "o", "8"] +[4.960664, "i", "9"] +[4.960722, "o", "9"] +[5.028871, "i", "0"] +[5.028926, "o", "0"] +[5.092111, "i", "1"] +[5.092171, "o", "1"] +[5.160811, "i", "2"] +[5.160867, "o", "2"] +[5.228150, "i", ":"] +[5.228215, "o", ":"] +[5.293785, "i", "c"] +[5.293837, "o", "c"] +[5.360933, "i", "l"] +[5.360987, "o", "l"] +[5.428940, "i", "u"] +[5.428997, "o", "u"] +[5.497721, "i", "s"] +[5.497793, "o", "s"] +[5.569537, "i", "t"] +[5.569617, "o", "t"] +[5.642320, "i", "e"] +[5.642397, "o", "e"] +[5.709363, "i", "r"] +[5.709454, "o", "r"] +[5.780519, "i", "/"] +[5.780602, "o", "/"] +[5.846083, "i", "p"] +[5.846127, "o", "p"] +[5.913533, "i", "r"] +[5.913647, "o", "r"] +[5.982615, "i", "o"] +[5.982689, "o", "o"] +[6.049044, "i", "d"] +[6.049102, "o", "d"] +[6.115504, "i", " "] +[6.115558, "o", " "] +[6.184849, "i", "d"] +[6.184899, "o", "d"] +[6.248980, "i", "e"] +[6.249038, "o", "e"] +[6.315944, "i", "l"] +[6.316003, "o", "l"] +[6.383705, "i", "e"] +[6.383810, "o", "e"] +[6.449221, "i", "t"] +[6.449295, "o", "t"] +[6.512343, "i", "e"] +[6.512405, "o", "e \r"] +[6.575826, "i", " "] +[6.575866, "o", " "] +[6.640099, "i", "n"] +[6.640141, "o", "n"] +[6.704344, "i", "s"] +[6.704387, "o", "s"] +[6.771080, "i", " "] +[6.771125, "o", " "] +[6.838123, "i", "p"] +[6.838198, "o", "p"] +[6.902998, "i", "a"] +[6.903051, "o", "a"] +[6.967990, "i", "y"] +[6.968050, "o", "y"] +[7.030989, "i", "m"] +[7.031029, "o", "m"] +[7.094314, "i", "e"] +[7.094368, "o", "e"] +[7.157317, "i", "n"] +[7.157362, "o", "n"] +[7.222577, "i", "t"] +[7.222625, "o", "t"] +[7.288976, "i", "s"] +[7.289036, "o", "s"] +[7.352101, "i", "\""] +[7.352148, "o", "\""] +[7.413834, "i", "\r"] +[7.413885, "o", "\r\n"] +[7.703114, "o", "── call 1: kubectl ──\r\nVerb: delete\r\nFlags:\r\n"] +[7.703163, "o", " context = arn:aws:eks:us-east-1:123456789012:cluster/prod\r\nPositional: ns payments\r\nEffective cwd: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/project\r\nMode: enabled\r\nPolicy chain (6 modules at this cwd):\r\n [bundled] bundled/aws.rego\r\n [bundled] bundled/failsafe.rego\r\n [bundled] bundled/git.rego\r\n [bundled] bundled/helm.rego\r\n [bundled] bundled/kubectl.rego\r\n [bundled] bundled/terraform.rego\r\nDecision: BLOCK\r\nReason : kubectl delete blocked while failsafe is enabled\r\n"] +[7.703842, "o", "$ "] +[9.727401, "i", "exit\r"] +[9.727520, "o", "e"] +[9.727581, "o", "xit\r\n"] +[9.727634, "o", "exit\r\n"] diff --git a/docs/assets/casts/explain-block.svg b/docs/assets/casts/explain-block.svg index 5caab03..8241dac 100644 --- a/docs/assets/casts/explain-block.svg +++ b/docs/assets/casts/explain-block.svg @@ -1 +1 @@ -Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-do$$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/proddeletenspayments"──call1:kubectl──Verb:deleteFlags:context=arn:aws:eks:us-east-1:123456789012:cluster/prodPositional:nspaymentsEffectivecwd:/var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/projectMode:enabledPolicychain(6modulesatthiscwd):[bundled]bundled/aws.rego[bundled]bundled/failsafe.rego[bundled]bundled/git.rego[bundled]bundled/helm.rego[bundled]bundled/kubectl.rego[bundled]bundled/terraform.regoDecision:BLOCKReason:kubectldeleteblockedwhilefailsafeisenabled$exitbash-3.2$bash-3.2$ebash-3.2$exportPS1='$';cd"/var/folbash-3.2$exportPS1='$';cd"/var/foldebash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48sybash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/Tcs-homcs-home/project";clear$f$failsafeexplain"k$failsafeexplain"kubectl--context$failsafeexplain"kubectl--contextar$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:12$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluste$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/proddenspa$eexit \ No newline at end of file +Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-do$$failsafe$failsafeexplain$failsafeexplain"kubectl$failsafeexplain"kubectl--context$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/prod$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/proddeletensnspayments"──call1:kubectl──Verb:deleteFlags:context=arn:aws:eks:us-east-1:123456789012:cluster/prodPositional:nspaymentsEffectivecwd:/var/folders/12/mydd4m455zn9t__48syck4940000gn/T/failsafe-docs-home/projectMode:enabledPolicychain(6modulesatthiscwd):[bundled]bundled/aws.rego[bundled]bundled/failsafe.rego[bundled]bundled/git.rego[bundled]bundled/helm.rego[bundled]bundled/kubectl.rego[bundled]bundled/terraform.regoDecision:BLOCKReason:kubectldeleteblockedwhilefailsafeisenabled$exitbash-3.2$bash-3.2$ebash-3.2$exportPS1='$';cd"/var/fbash-3.2$exportPS1='$';cd"/var/foldebash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck494000bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gbash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gncs-homcs-home/project";cleacs-home/project";clear$f$fa$fai$fail$fails$failsa$failsaf$failsafee$failsafeex$failsafeexp$failsafeexpl$failsafeexpla$failsafeexplai$failsafeexplain"$failsafeexplain"k$failsafeexplain"ku$failsafeexplain"kub$failsafeexplain"kube$failsafeexplain"kubec$failsafeexplain"kubect$failsafeexplain"kubectl-$failsafeexplain"kubectl--$failsafeexplain"kubectl--c$failsafeexplain"kubectl--co$failsafeexplain"kubectl--con$failsafeexplain"kubectl--cont$failsafeexplain"kubectl--conte$failsafeexplain"kubectl--contex$failsafeexplain"kubectl--contexta$failsafeexplain"kubectl--contextar$failsafeexplain"kubectl--contextarn$failsafeexplain"kubectl--contextarn:$failsafeexplain"kubectl--contextarn:a$failsafeexplain"kubectl--contextarn:aw$failsafeexplain"kubectl--contextarn:aws$failsafeexplain"kubectl--contextarn:aws:$failsafeexplain"kubectl--contextarn:aws:e$failsafeexplain"kubectl--contextarn:aws:ek$failsafeexplain"kubectl--contextarn:aws:eks$failsafeexplain"kubectl--contextarn:aws:eks:$failsafeexplain"kubectl--contextarn:aws:eks:u$failsafeexplain"kubectl--contextarn:aws:eks:us$failsafeexplain"kubectl--contextarn:aws:eks:us-$failsafeexplain"kubectl--contextarn:aws:eks:us-e$failsafeexplain"kubectl--contextarn:aws:eks:us-ea$failsafeexplain"kubectl--contextarn:aws:eks:us-eas$failsafeexplain"kubectl--contextarn:aws:eks:us-east$failsafeexplain"kubectl--contextarn:aws:eks:us-east-$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:1$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:12$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:1234$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:12345$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:1234567$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:12345678$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:1234567890$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:12345678901$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:c$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cl$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:clu$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:clus$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:clust$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluste$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/p$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/pr$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/pro$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/prodd$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/prodde$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/proddel$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/proddele$failsafeexplain"kubectl--contextarn:aws:eks:us-east-1:123456789012:cluster/proddeletnnspnspanspaynspaymnspaymenspaymennspaymentnspayments$eexit \ No newline at end of file diff --git a/docs/assets/casts/mode-toggle.cast b/docs/assets/casts/mode-toggle.cast index 76a3cb8..e447205 100644 --- a/docs/assets/casts/mode-toggle.cast +++ b/docs/assets/casts/mode-toggle.cast @@ -1,43 +1,206 @@ -{"version":2,"width":92,"height":22,"timestamp":1784331888} -[0.005927, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] -[0.006178, "o", "\u001b[?1034h"] -[0.006212, "o", "bash-3.2$ "] -[0.014081, "i", "export PS1='$ '; cd \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/project\"; clear\r"] -[0.014288, "o", "e"] -[0.014310, "o", "xport PS1='$"] -[0.014358, "o", " '; cd \"/var/folde"] -[0.014367, "o", "rs/"] -[0.014445, "o", "12/mydd4m455zn9t__48sy"] -[0.014452, "o", "ck"] -[0.014535, "o", "4940000gn/T//failsa"] -[0.014578, "o", "fe-do \rcs-home/"] -[0.014585, "o", "pr"] -[0.014589, "o", "oj"] -[0.014664, "o", "ect\"; clear\r\n"] -[0.016854, "o", "\u001b[3J\u001b[H\u001b[2J"] -[0.017117, "o", "$ "] -[0.539295, "i", "failsafe mode get\r"] -[0.539375, "o", "f"] -[0.539437, "o", "ailsafe mode get\r\n"] -[0.550818, "o", "enabled\t(default; no source resolved)\r\n"] -[0.551704, "o", "$ "] -[2.583063, "i", "failsafe mode set disabled\r"] -[2.583205, "o", "f"] -[2.583281, "o", "ailsafe mode set disabled\r\n"] -[2.598676, "o", "disabled\t(file: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)\r\n"] -[2.599698, "o", "$ "] -[4.614719, "i", "failsafe mode get\r"] -[4.614865, "o", "f"] -[4.614953, "o", "ailsafe mode get\r\n"] -[4.629334, "o", "disabled\t(file: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)\r\n"] -[4.630511, "o", "$ "] -[7.160456, "i", "failsafe mode set enabled\r"] -[7.160543, "o", "f"] -[7.160604, "o", "ailsafe mode set e"] -[7.160689, "o", "nabled\r\n"] -[7.171934, "o", "enabled\t(file: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)\r\n"] -[7.172671, "o", "$ "] -[9.711063, "i", "exit\r"] -[9.711225, "o", "e"] -[9.711286, "o", "xit\r\n"] -[9.711402, "o", "exit\r\n"] +{"version":2,"width":92,"height":22,"timestamp":1784334833} +[0.004162, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] +[0.004318, "o", "\u001b[?1034h"] +[0.004333, "o", "bash-3.2$ "] +[0.009875, "i", "export PS1='$ '; cd \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/project\"; clear\r"] +[0.009920, "o", "e"] +[0.009950, "o", "xport PS1='$ '; c"] +[0.009995, "o", "d \"/var/folders/12/"] +[0.010042, "o", "mydd4m455zn9t__4"] +[0.010085, "o", "8syck4940000g"] +[0.010091, "o", "n"] +[0.010164, "o", "/T//failsafe-do \rcs-home"] +[0.010202, "o", "/project\"; clear"] +[0.010207, "o", "\r\n"] +[0.012249, "o", "\u001b[3J\u001b[H\u001b[2J"] +[0.012475, "o", "$ "] +[0.526209, "i", "f"] +[0.526296, "o", "f"] +[0.592558, "i", "a"] +[0.592641, "o", "a"] +[0.658105, "i", "i"] +[0.658153, "o", "i"] +[0.724168, "i", "l"] +[0.724223, "o", "l"] +[0.789577, "i", "s"] +[0.789634, "o", "s"] +[0.855260, "i", "a"] +[0.855314, "o", "a"] +[0.922138, "i", "f"] +[0.922206, "o", "f"] +[0.988933, "i", "e"] +[0.988987, "o", "e"] +[1.053316, "i", " "] +[1.053420, "o", " "] +[1.121810, "i", "m"] +[1.121878, "o", "m"] +[1.188858, "i", "o"] +[1.188922, "o", "o"] +[1.255934, "i", "d"] +[1.255992, "o", "d"] +[1.325474, "i", "e"] +[1.325555, "o", "e"] +[1.391403, "i", " "] +[1.391456, "o", " "] +[1.458447, "i", "g"] +[1.458499, "o", "g"] +[1.525156, "i", "e"] +[1.525207, "o", "e"] +[1.591756, "i", "t"] +[1.591810, "o", "t"] +[1.658382, "i", "\r"] +[1.658438, "o", "\r\n"] +[1.666953, "o", "enabled\t(default; no source resolved)\r\n"] +[1.667733, "o", "$ "] +[3.685959, "i", "f"] +[3.686031, "o", "f"] +[3.755600, "i", "a"] +[3.755668, "o", "a"] +[3.827533, "i", "i"] +[3.827606, "o", "i"] +[3.899667, "i", "l"] +[3.899764, "o", "l"] +[3.973322, "i", "s"] +[3.973384, "o", "s"] +[4.043884, "i", "a"] +[4.043966, "o", "a"] +[4.110717, "i", "f"] +[4.110759, "o", "f"] +[4.177252, "i", "e"] +[4.177299, "o", "e"] +[4.240126, "i", " "] +[4.240180, "o", " "] +[4.305944, "i", "m"] +[4.306012, "o", "m"] +[4.373124, "i", "o"] +[4.373186, "o", "o"] +[4.439670, "i", "d"] +[4.439725, "o", "d"] +[4.503856, "i", "e"] +[4.503917, "o", "e"] +[4.571240, "i", " "] +[4.571315, "o", " "] +[4.639508, "i", "s"] +[4.639558, "o", "s"] +[4.707252, "i", "e"] +[4.707309, "o", "e"] +[4.777386, "i", "t"] +[4.777470, "o", "t"] +[4.845633, "i", " "] +[4.845698, "o", " "] +[4.911548, "i", "d"] +[4.911590, "o", "d"] +[4.977796, "i", "i"] +[4.977848, "o", "i"] +[5.045858, "i", "s"] +[5.045931, "o", "s"] +[5.114947, "i", "a"] +[5.115010, "o", "a"] +[5.183756, "i", "b"] +[5.183822, "o", "b"] +[5.252126, "i", "l"] +[5.252182, "o", "l"] +[5.320527, "i", "e"] +[5.320577, "o", "e"] +[5.388325, "i", "d"] +[5.388390, "o", "d"] +[5.453116, "i", "\r"] +[5.453165, "o", "\r\n"] +[5.461886, "o", "disabled\t(file: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)\r\n"] +[5.462535, "o", "$ "] +[7.476508, "i", "f"] +[7.476576, "o", "f"] +[7.540666, "i", "a"] +[7.540724, "o", "a"] +[7.604941, "i", "i"] +[7.605006, "o", "i"] +[7.671109, "i", "l"] +[7.671161, "o", "l"] +[7.738290, "i", "s"] +[7.738343, "o", "s"] +[7.804500, "i", "a"] +[7.804550, "o", "a"] +[7.871701, "i", "f"] +[7.871748, "o", "f"] +[7.935776, "i", "e"] +[7.935824, "o", "e"] +[8.003051, "i", " "] +[8.003149, "o", " "] +[8.069881, "i", "m"] +[8.069950, "o", "m"] +[8.137047, "i", "o"] +[8.137101, "o", "o"] +[8.202301, "i", "d"] +[8.202354, "o", "d"] +[8.269111, "i", "e"] +[8.269161, "o", "e"] +[8.338715, "i", " "] +[8.338779, "o", " "] +[8.409166, "i", "g"] +[8.409240, "o", "g"] +[8.473000, "i", "e"] +[8.473175, "o", "e"] +[8.536607, "i", "t"] +[8.536657, "o", "t"] +[8.596941, "i", "\r"] +[8.596980, "o", "\r\n"] +[8.602675, "o", "disabled\t(file: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)\r\n"] +[8.603223, "o", "$ "] +[11.122598, "i", "f"] +[11.122682, "o", "f"] +[11.189778, "i", "a"] +[11.189839, "o", "a"] +[11.255421, "i", "i"] +[11.255477, "o", "i"] +[11.321706, "i", "l"] +[11.321794, "o", "l"] +[11.388673, "i", "s"] +[11.388732, "o", "s"] +[11.455424, "i", "a"] +[11.455476, "o", "a"] +[11.522638, "i", "f"] +[11.522697, "o", "f"] +[11.588859, "i", "e"] +[11.588916, "o", "e"] +[11.655246, "i", " "] +[11.655302, "o", " "] +[11.721647, "i", "m"] +[11.721701, "o", "m"] +[11.787780, "i", "o"] +[11.787840, "o", "o"] +[11.853935, "i", "d"] +[11.853995, "o", "d"] +[11.915354, "i", "e"] +[11.915407, "o", "e"] +[11.981377, "i", " "] +[11.981433, "o", " "] +[12.047459, "i", "s"] +[12.047519, "o", "s"] +[12.114324, "i", "e"] +[12.114378, "o", "e"] +[12.179634, "i", "t"] +[12.179686, "o", "t"] +[12.243328, "i", " "] +[12.243374, "o", " "] +[12.309349, "i", "e"] +[12.309409, "o", "e"] +[12.376090, "i", "n"] +[12.376138, "o", "n"] +[12.442520, "i", "a"] +[12.442582, "o", "a"] +[12.509806, "i", "b"] +[12.509865, "o", "b"] +[12.576685, "i", "l"] +[12.576738, "o", "l"] +[12.643696, "i", "e"] +[12.643752, "o", "e"] +[12.710067, "i", "d"] +[12.710121, "o", "d"] +[12.779593, "i", "\r"] +[12.779666, "o", "\r\n"] +[12.788138, "o", "enabled\t(file: /var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)\r\n"] +[12.788755, "o", "$ "] +[15.316550, "i", "exit\r"] +[15.316645, "o", "e"] +[15.316690, "o", "xit\r\n"] +[15.316750, "o", "exit\r\n"] diff --git a/docs/assets/casts/mode-toggle.svg b/docs/assets/casts/mode-toggle.svg index 22dbb04..0e6d4d8 100644 --- a/docs/assets/casts/mode-toggle.svg +++ b/docs/assets/casts/mode-toggle.svg @@ -1 +1 @@ -Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-do$$f$failsafemodegetenabled(default;nosourceresolved)$failsafemodesetdisableddisabled(file:/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)$failsafemodesetenabledenabled(file:/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)$exitbash-3.2$bash-3.2$ebash-3.2$exportPS1='$bash-3.2$exportPS1='$';cd"/var/foldebash-3.2$exportPS1='$';cd"/var/folders/bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48sybash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syckbash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsacs-home/cs-home/prcs-home/projcs-home/project";clear$failsafemodesete$eexit \ No newline at end of file +Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/project";clear$$f$fa$fai$fail$fails$failsa$failsaf$failsafe$failsafem$failsafemo$failsafemod$failsafemode$failsafemodeg$failsafemodege$failsafemodegetenabled(default;nosourceresolved)$failsafemodes$failsafemodese$failsafemodeset$failsafemodesetdisableddisabled(file:/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)$failsafemodesetenabledenabled(file:/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.claude/pane-mode/w0t1p0:E03E0B4D-6630-49D4-96E2-ADCE77DB2402)$exitbash-3.2$bash-3.2$ebash-3.2$exportPS1='$';cbash-3.2$exportPS1='$';cd"/var/folders/12/bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__4bash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gbash-3.2$exportPS1='$';cd"/var/folders/12/mydd4m455zn9t__48syck4940000gncs-home$failsafemodesetd$failsafemodesetdi$failsafemodesetdis$failsafemodesetdisa$failsafemodesetdisab$failsafemodesetdisabl$failsafemodesetdisable$failsafemodesete$failsafemodeseten$failsafemodesetena$failsafemodesetenab$failsafemodesetenabl$failsafemodesetenable$eexit \ No newline at end of file diff --git a/docs/assets/casts/tmux-hotkey.cast b/docs/assets/casts/tmux-hotkey.cast new file mode 100644 index 0000000..1d6388e --- /dev/null +++ b/docs/assets/casts/tmux-hotkey.cast @@ -0,0 +1,170 @@ +{"version":2,"width":92,"height":22,"timestamp":1784334853} +[0.003044, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\n"] +[0.003082, "o", "For more details, please visit https://support.apple.com/kb/HT208050.\r\n"] +[0.003157, "o", "\u001b[?1034h"] +[0.003163, "o", "bash-3.2$ "] +[0.007264, "i", "export PS1='$ '; clear\r"] +[0.007330, "o", "e"] +[0.007343, "o", "xport PS1="] +[0.007349, "o", "'$ '"] +[0.007399, "o", "; clear\r\n"] +[0.008792, "o", "\u001b[3J\u001b[H\u001b[2J"] +[0.008963, "o", "$ "] +[0.518436, "i", "tmux -L failsafe-demo -f \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf\" new-session\r"] +[0.518507, "o", "t"] +[0.518524, "o", "mux -L fail"] +[0.518532, "o", "safe"] +[0.518606, "o", "-demo -f \"/var/folders/12/mydd4"] +[0.518648, "o", "m455zn9t__48s"] +[0.518657, "o", "yck"] +[0.518723, "o", "4940000gn/T//fail"] +[0.518771, "o", "safe-docs"] +[0.518806, "o", "- \rhome/.dem"] +[0.518813, "o", "o-t"] +[0.518877, "o", "mux.conf\" new-session\r\n"] +[0.531887, "o", "\u001b[?1049h\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b[?2031h\u001b[?996n\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[c\u001b[\u003ec\u001b[\u003eq\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H"] +[0.532389, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"] +[0.532511, "o", "\u001b[18t\u001b[14t\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[1;1H"] +[0.532715, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"] +[0.538118, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] +[0.539900, "o", "$ "] +[0.718062, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:zsh* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[5;3H"] +[1.534681, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[5;3H"] +[2.058148, "i", "f"] +[2.058718, "o", "f"] +[2.135230, "i", "a"] +[2.135573, "o", "a"] +[2.205995, "i", "i"] +[2.206123, "o", "i"] +[2.276351, "i", "l"] +[2.276488, "o", "l"] +[2.347755, "i", "s"] +[2.347971, "o", "s"] +[2.410002, "i", "a"] +[2.410103, "o", "a"] +[2.475944, "i", "f"] +[2.476089, "o", "f"] +[2.542293, "i", "e"] +[2.542518, "o", "e"] +[2.609615, "i", " "] +[2.609752, "o", " "] +[2.676070, "i", "e"] +[2.676227, "o", "e"] +[2.738592, "i", "x"] +[2.738713, "o", "x"] +[2.805144, "i", "p"] +[2.805274, "o", "p"] +[2.868617, "i", "l"] +[2.868753, "o", "l"] +[2.936658, "i", "a"] +[2.936785, "o", "a"] +[3.004700, "i", "i"] +[3.004846, "o", "i"] +[3.072414, "i", "n"] +[3.072592, "o", "n"] +[3.142482, "i", " "] +[3.142679, "o", " "] +[3.204807, "i", "\""] +[3.204962, "o", "\""] +[3.271405, "i", "k"] +[3.271565, "o", "k"] +[3.337986, "i", "u"] +[3.338167, "o", "u"] +[3.406895, "i", "b"] +[3.407068, "o", "b"] +[3.482644, "i", "e"] +[3.482830, "o", "e"] +[3.557363, "i", "c"] +[3.558175, "o", "c"] +[3.629246, "i", "t"] +[3.629468, "o", "t"] +[3.700380, "i", "l"] +[3.700538, "o", "l"] +[3.771809, "i", " "] +[3.772075, "o", " "] +[3.842462, "i", "d"] +[3.842614, "o", "d"] +[3.918519, "i", "e"] +[3.918706, "o", "e"] +[3.994695, "i", "l"] +[3.994949, "o", "l"] +[4.070459, "i", "e"] +[4.070697, "o", "e"] +[4.144472, "i", "t"] +[4.144660, "o", "t"] +[4.223702, "i", "e"] +[4.223945, "o", "e"] +[4.295253, "i", " "] +[4.295402, "o", " "] +[4.363054, "i", "n"] +[4.363226, "o", "n"] +[4.433167, "i", "s"] +[4.433364, "o", "s"] +[4.508889, "i", " "] +[4.509193, "o", " "] +[4.582862, "i", "p"] +[4.583191, "o", "p"] +[4.655139, "i", "a"] +[4.655392, "o", "a"] +[4.730062, "i", "y"] +[4.730367, "o", "y"] +[4.796433, "i", "m"] +[4.796593, "o", "m"] +[4.869050, "i", "e"] +[4.869271, "o", "e"] +[4.945714, "i", "n"] +[4.946275, "o", "n"] +[5.021439, "i", "t"] +[5.021737, "o", "t"] +[5.094404, "i", "s"] +[5.094591, "o", "s"] +[5.168949, "i", "\""] +[5.169135, "o", "\""] +[5.245139, "i", "\r"] +[5.245303, "o", "\r\n"] +[5.258074, "o", "failsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\r\n"] +[5.263014, "o", "── call 1: kubectl ──\u001b[1;21r\u001b[21;1H\n\u001b[9dVerb: delete\r\nPositional: ns payments\r\nEffective cwd: /Users/tombar/Code/failsafe\r\nMode: enabled\r\nPolicy chain (7 modules at this cwd):\r\n [bundled] bundled/aws.rego\r\n [bundled] bundled/failsafe.rego\r\n [bundled] bundled/git.rego\r\n [bundled] bundled/helm.rego\r\n [bundled] bundled/kubectl.rego\r\n [bundled] bundled/terraform.rego\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[5.263088, "o", "\u001b[1;21r\u001b[1;1H\u001b[2S\u001b[19dDecision: BLOCK\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] +[5.264024, "o", "$ "] +[5.531418, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[21;3H"] +[5.531972, "o", "\u001b[?25l\u001b[HFor more details, please visit https://support.apple.com/kb/HT208050.\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m"] +[5.532028, "o", "\u001b[?12l\u001b[?25h\u001b[21;3H"] +[7.295931, "i", "\u001b"] +[7.296029, "i", "\u0014"] +[7.501634, "o", "\u001b[?25l\u001b[30m\u001b[43m\r\n🔒 failsafe: enabled → disabled \u001b(B\u001b[m\u001b[21;3H"] +[8.254252, "o", "\u001b[HFor more details, please visit https://support.apple.com/kb/HT208050.\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[21;3"] +[8.254552, "o", "H\u001b[?12l\u001b[?25h"] +[8.281499, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] +[10.305724, "i", "\u001b[A"] +[10.306104, "o", "failsafe explain \"kubectl delete ns payments\""] +[10.321253, "i", "\r"] +[10.321544, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[10.321621, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[10.331621, "o", "\u001b[1;21r\u001b[1;1H\u001b[3S\u001b[18dfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[10.331714, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[10.335859, "o", "── call 1: kubectl ──\u001b[1;21r\u001b[1;1H\u001b[15S\u001b[6BVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[10.335923, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[10.337128, "o", "$ "] +[12.369880, "i", "\u001b"] +[12.369970, "i", "\u0014"] +[12.395665, "o", "\u001b[?25l\u001b[30m\u001b[43m\r\n🔒 failsafe: disabled → enabled \u001b(B\u001b[m\u001b[21;3H"] +[13.148491, "o", "\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 21:34 \u001b(B\u001b[m\u001b[21;3H\u001b[?12l\u001b[?25h"] +[13.180116, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] +[14.430278, "i", "e"] +[14.430812, "o", "e"] +[14.511713, "i", "x"] +[14.511988, "o", "x"] +[14.584892, "i", "i"] +[14.585125, "o", "i"] +[14.651248, "i", "t"] +[14.651371, "o", "t"] +[14.709667, "i", "\r"] +[14.709786, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] +[14.709826, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[Aexit\r\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] +[14.710687, "o", "\u001b[1;22r"] +[14.710695, "o", "\u001b(B\u001b[m\u001b[?1l\u001b\u003e\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[?2031l"] +[14.710766, "o", "[exited]\r\n"] +[14.711044, "o", "$ "] +[14.715971, "i", "exit\r"] +[14.716003, "o", "exit\r\n"] +[14.716024, "o", "exit\r\n"] diff --git a/docs/assets/casts/tmux-hotkey.svg b/docs/assets/casts/tmux-hotkey.svg new file mode 100644 index 0000000..8d80178 --- /dev/null +++ b/docs/assets/casts/tmux-hotkey.svg @@ -0,0 +1 @@ +Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.$$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf"new-session[0] 0:zsh* | 21:34[0] 0:bash*🔒 on| 21:34$failsafe$failsafeexplain$failsafeexplain"kubectl$failsafeexplain"kubectldelete$failsafeexplain"kubectldeletens$failsafeexplain"kubectldeletenspayments"failsafe:repo/Users/tombar/Code/failsafeshipsallow_overriderulesbutisuntrusted;overridesignored.Run`failsafetrust.`toenable.(file:/Users/tombar/Code/failsafe/.failsafe.rego)──call1:kubectl──Verb:deletePositional:nspaymentsEffectivecwd:/Users/tombar/Code/failsafeMode:enabledPolicychain(7modulesatthiscwd):[bundled]bundled/aws.rego[bundled]bundled/failsafe.rego[bundled]bundled/git.rego[bundled]bundled/helm.rego[bundled]bundled/kubectl.rego[bundled]bundled/terraform.rego[repo]/Users/tombar/Code/failsafe/.failsafe.rego[untrusted]Decision:BLOCKReason:kubectldeleteblockedwhilefailsafeisenabled[0] 0:bash*🔓 sudo| 21:34Mode:disabledDecision:ALLOW$exitexit[exited]bash-3.2$bash-3.2$ebash-3.2$exportPS1=bash-3.2$exportPS1='$'bash-3.2$exportPS1='$';clear$t$tmux-Lfail$tmux-Lfailsafe$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48s$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//fail$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docshome/.demhome/.demo-t[0] 0:zsh*🔒 on| 21:34$f$fa$fai$fail$fails$failsa$failsaf$failsafee$failsafeex$failsafeexp$failsafeexpl$failsafeexpla$failsafeexplai$failsafeexplain"$failsafeexplain"k$failsafeexplain"ku$failsafeexplain"kub$failsafeexplain"kube$failsafeexplain"kubec$failsafeexplain"kubect$failsafeexplain"kubectld$failsafeexplain"kubectlde$failsafeexplain"kubectldel$failsafeexplain"kubectldele$failsafeexplain"kubectldelet$failsafeexplain"kubectldeleten$failsafeexplain"kubectldeletensp$failsafeexplain"kubectldeletenspa$failsafeexplain"kubectldeletenspay$failsafeexplain"kubectldeletenspaym$failsafeexplain"kubectldeletenspayme$failsafeexplain"kubectldeletenspaymen$failsafeexplain"kubectldeletenspayment$failsafeexplain"kubectldeletenspayments🔒 failsafe: enabled → disabled🔒 failsafe: disabled → enabled$e$ex$exi \ No newline at end of file diff --git a/scripts/record-docs.sh b/scripts/record-docs.sh index a9af27c..a9c350e 100755 --- a/scripts/record-docs.sh +++ b/scripts/record-docs.sh @@ -11,26 +11,41 @@ # produces the demo recordings that *show* them running, from the same commands, # so the two never drift. # -# It is deliberately scoped to the HEADLESS CLI surface (explain / mode / audit / -# report). The GUI terminal-integration surfaces (WezTerm toasts & tab-title, -# iTerm2's Python keybinding) are NOT recordable headlessly and stay manual — -# see docs/demos/README.md, same honest split as test/docs/REPORT.md. +# It covers the HEADLESS CLI surface (explain / mode / audit / report) AND two +# live, keystroke-driven demos: +# - tmux-hotkey : the Ctrl+Alt+T per-pane toggle flipping enabled↔disabled +# live, re-running the same command to BLOCK then ALLOW. +# - claude-hook-block: failsafe blocking a kubectl delete *inside Claude Code*, +# then the same hotkey flipping the guard without leaving +# the Claude TUI. (opt-in: --claude; uses the REAL home so +# Claude's Keychain/~/.claude auth works, spends a few +# tokens — see record_claude_hook for the safety notes.) +# +# The tmux configs for the live demos are materialised FROM docs/toggle/tmux.md's +# own fenced blocks (via test/docs/lib/extract.sh), so the recording can't drift +# from the documented setup either. # # Requirements (all optional — missing tools downgrade gracefully, never fail): # - virtui https://github.com/honeybadge-labs/virtui (the recorder) # - agg https://github.com/asciinema/agg (.cast -> .gif) [optional render] # - svg-term npm i -g svg-term-cli (.cast -> .svg) [optional render] +# - tmux (the two live demos) +# - claude Claude Code CLI (--claude demo only) # # Usage: -# scripts/record-docs.sh # record all scenarios into docs/assets/casts/ -# scripts/record-docs.sh --render # also render .cast -> .svg/.gif if a renderer is present -# COLS=100 ROWS=24 scripts/record-docs.sh +# scripts/record-docs.sh # record headless + tmux-hotkey demos +# scripts/record-docs.sh --render # also render .cast -> .svg/.gif +# scripts/record-docs.sh --claude # additionally record the inside-Claude demo +# scripts/record-docs.sh --claude --render # both, in any order +# COLS=100 ROWS=24 TYPE_DELAY=0 scripts/record-docs.sh set -euo pipefail # ── Resolve paths ──────────────────────────────────────────────────────────── SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" OUT_DIR="${OUT_DIR:-$REPO_ROOT/docs/assets/casts}" +EXTRACT="$REPO_ROOT/test/docs/lib/extract.sh" +TMUX_DOC="$REPO_ROOT/docs/toggle/tmux.md" COLS="${COLS:-92}" ROWS="${ROWS:-22}" # Pause (seconds) held AFTER each command's output, so playback lingers on the @@ -38,8 +53,23 @@ ROWS="${ROWS:-22}" # wall-clock time, so a host-side idle gap becomes a visible pause baked into the # cast (re-rendering can't add it — it must be recorded). STEP_PAUSE=0 = fast. STEP_PAUSE="${STEP_PAUSE:-2}" +# Per-character delay (seconds) for the human-visible typing effect. Every command +# is typed one glyph at a time via `virtui type` with this gap between glyphs, so +# playback shows a person typing, not text teleporting in. TYPE_DELAY=0 = instant. +# NOTE: this bakes real wall-clock timing into the cast, so casts (and their SVGs) +# differ byte-for-byte on every re-record even when behaviour is identical. +TYPE_DELAY="${TYPE_DELAY:-0.05}" + +# ── Arg parsing: --render and --claude, in any order ───────────────────────── RENDER=0 -[[ "${1:-}" == "--render" ]] && RENDER=1 +CLAUDE=0 +for arg in "$@"; do + case "$arg" in + --render) RENDER=1 ;; + --claude) CLAUDE=1 ;; + *) printf 'record-docs.sh: unknown arg %q (ignored)\n' "$arg" >&2 ;; + esac +done mkdir -p "$OUT_DIR" @@ -57,12 +87,17 @@ log "building failsafe -> $BINDIR/failsafe" ( cd "$REPO_ROOT" && go build -o "$BINDIR/failsafe" ./cmd/failsafe ) export PATH="$BINDIR:$PATH" +# ── Capture the REAL home BEFORE sandboxing ────────────────────────────────── +# The inside-Claude demo (record_claude_hook) needs it: Claude Code authenticates +# against the macOS Keychain and ~/.claude, which a throwaway HOME would break. +REAL_HOME="$HOME" + # ── Sandbox HOME so demos never touch the real ~/.config/failsafe ──────────── # failsafe resolves all of its state from $HOME (policy.rego, trusted-repos.yaml, # decisions.jsonl, pane-mode files). A throwaway HOME keeps demos side-effect # free, mirroring helpers.bash in the doc-validation harness. The path is FIXED # (not mktemp-random) so the cwd printed by `explain` is readable and identical -# on every re-record — committed SVGs then diff only when behaviour changes. +# on every re-record. SANDBOX_HOME="${TMPDIR:-/tmp}/failsafe-docs-home" rm -rf "$SANDBOX_HOME" export HOME="$SANDBOX_HOME" @@ -73,6 +108,8 @@ unset FAILSAFE_MODE FAILSAFE_LOG 2>/dev/null || true DAEMON_STARTED=0 cleanup() { [[ "$DAEMON_STARTED" == 1 ]] && virtui daemon stop >/dev/null 2>&1 || true + tmux -L failsafe-demo kill-server >/dev/null 2>&1 || true + tmux -L failsafe-claude-demo kill-server >/dev/null 2>&1 || true rm -rf "$BINDIR" "$SANDBOX_HOME" } trap cleanup EXIT @@ -80,9 +117,24 @@ trap cleanup EXIT log "starting virtui daemon" virtui daemon start >/dev/null 2>&1 && DAEMON_STARTED=1 || warn "daemon may already be running" +# ── type_line SID TEXT ─────────────────────────────────────────────────────── +# Type TEXT one character at a time (human-visible), then press Enter. This is +# the whole reason the casts read like someone at a keyboard rather than a script +# pasting. Single chars — including space, ", -, / — go through `virtui type` +# verbatim (verified). TYPE_DELAY=0 makes it instant. +type_line() { + local sid="$1" text="$2" i ch + for (( i = 0; i < ${#text}; i++ )); do + ch="${text:i:1}" + virtui type "$sid" "$ch" >/dev/null + [[ "$TYPE_DELAY" == 0 ]] || sleep "$TYPE_DELAY" + done + virtui press "$sid" Enter >/dev/null +} + # ── record_scenario NAME -- "cmd|wait-for-text" ["cmd|wait" …] ─────────────── -# Spawns a recorded bash session, normalises the prompt, runs each step typing -# the command and waiting for the given screen text, then exits to flush the cast. +# Spawns a recorded bash session, normalises the prompt, types each command +# char-by-char and waits for the given screen text, then exits to flush the cast. record_scenario() { local name="$1"; shift [[ "$1" == "--" ]] && shift @@ -96,17 +148,19 @@ record_scenario() { | sed -n 's/^session_id: //p')" [[ -n "$sid" ]] || { warn "could not start session for $name"; return 1; } - # Quiet, deterministic prompt; start from the sandbox project dir. + # Quiet, deterministic prompt; start from the sandbox project dir. (Setup, not + # part of the visible story — kept as an instant exec, not char-by-char.) virtui exec "$sid" "export PS1='\$ '; cd \"$HOME/project\"; clear" --wait-stable >/dev/null local step cmd want for step in "$@"; do cmd="${step%%|*}" want="${step#*|}" + type_line "$sid" "$cmd" if [[ "$want" == "$step" || -z "$want" ]]; then - virtui exec "$sid" "$cmd" --wait-stable >/dev/null + virtui wait "$sid" --stable >/dev/null else - virtui exec "$sid" "$cmd" --wait "$want" >/dev/null + virtui wait "$sid" --text "$want" >/dev/null fi sleep "$STEP_PAUSE" # linger on this command's output before the next one done @@ -115,6 +169,44 @@ record_scenario() { virtui kill "$sid" >/dev/null 2>&1 || true # finalize/flush the recording } +# ── build_tmux_config CFGDIR CONF ──────────────────────────────────────────── +# Materialise the documented tmux integration into CFGDIR + CONF, straight from +# docs/toggle/tmux.md's fenced blocks so the demo can't drift from the docs. +# - toggle + status helper scripts -> CFGDIR/{tmux-toggle,tmux-status}.sh (+x) +# - CONF = the doc's key-binding block + status block, with the doc's literal +# ~/.config/failsafe paths rewritten to CFGDIR (so a temp CFGDIR works), plus +# demo-only overrides: +# status-interval 1 — snappier status flip on toggle (doc ships 2) +# default-command — force a clean `$ ` bash prompt in the pane (macOS's +# default login shell would otherwise pollute it) +build_tmux_config() { + local cfgdir="$1" conf="$2" + mkdir -p "$cfgdir" + "$EXTRACT" "$TMUX_DOC" bash 1 "The toggle helper" > "$cfgdir/tmux-toggle.sh" + "$EXTRACT" "$TMUX_DOC" bash 1 "Status indicator" > "$cfgdir/tmux-status.sh" + chmod +x "$cfgdir/tmux-toggle.sh" "$cfgdir/tmux-status.sh" + + { + "$EXTRACT" "$TMUX_DOC" tmux 1 "The key binding" + "$EXTRACT" "$TMUX_DOC" tmux 1 "Status indicator" + printf '\n# --- demo-only overrides ---\n' + printf 'set -g status-interval 1\n' + printf 'set -g display-time 900\n' + # Keycast wrapper (demo polish only): the doc's C-M-t binding is materialised + # ABOVE, then this later binding for the SAME key wins. It flashes a "key was + # pressed" caption, then runs the doc's toggle script by its exact path — the + # toggle path is byte-identical to the doc; the wrapper only ADDS the on-screen + # key caption. The same real chord (press Escape Ctrl+T) still fires it through + # tmux's root key table, so the keystroke is genuine, not faked. + printf "bind -n C-M-t run-shell \"tmux display-message '⌨ Ctrl+Alt+T'; sleep 0.7; %s/tmux-toggle.sh '#{pane_id}'\"\n" "$cfgdir" + printf "set -g default-command \"env PS1='\$ ' BASH_SILENCE_DEPRECATION_WARNING=1 bash --norc\"\n" + } > "$conf" + + # Rewrite the doc's ~/.config/failsafe reference to the real CFGDIR (absolute), + # so a throwaway CFGDIR resolves and there's no ~ / chain ambiguity. + sed -i '' "s#~/.config/failsafe#$cfgdir#g" "$conf" +} + # ── Scenarios — the headless CLI demos ─────────────────────────────────────── # Each scenario maps to a doc page. Keep the commands identical to the snippets # the doc-validation harness checks, so the recording and the prose can't drift. @@ -136,6 +228,174 @@ record_scenario "mode-toggle" -- \ record_scenario "audit" -- \ "failsafe audit|block rule" +# ── record_tmux_hotkey — the live per-pane toggle demo ─────────────────────── +# Ctrl+Alt+T flips the focused pane enabled↔disabled *live*: the same command +# BLOCKs, then (after the chord) ALLOWs, then BLOCKs again — with the status bar +# following along. Uses the sandbox HOME like the headless scenarios. +record_tmux_hotkey() { + command -v tmux >/dev/null 2>&1 || { warn "tmux not found — skipping tmux-hotkey demo"; return 0; } + local name="tmux-hotkey" cast="$OUT_DIR/tmux-hotkey.cast" + local cfgdir="$HOME/.config/failsafe" conf="$HOME/.demo-tmux.conf" + log "recording $name -> $cast" + + build_tmux_config "$cfgdir" "$conf" + tmux -L failsafe-demo kill-server >/dev/null 2>&1 || true # no zombie server + + local sid + sid="$(virtui run --record --record-path "$cast" --cols "$COLS" --rows "$ROWS" bash \ + | sed -n 's/^session_id: //p')" + [[ -n "$sid" ]] || { warn "could not start session for $name"; return 1; } + + virtui exec "$sid" "export PS1='\$ '; clear" --wait-stable >/dev/null + # Launch tmux on a private socket with the materialised config (setup, exec'd). + virtui exec "$sid" "tmux -L failsafe-demo -f \"$conf\" new-session" --wait-stable >/dev/null + virtui wait "$sid" --stable >/dev/null + + # BLOCK: guard is enabled by default. + type_line "$sid" 'failsafe explain "kubectl delete ns payments"' + virtui wait "$sid" --text "Decision: BLOCK" >/dev/null + sleep "$STEP_PAUSE" + + # Chord → disabled. Status flips 🔒 on → 🔓 sudo. Wait on the ASCII "sudo" + # (the emoji cells render unpredictably; the word is stable). + virtui press "$sid" Escape Ctrl+T >/dev/null + virtui wait "$sid" --text "sudo" >/dev/null + sleep "$STEP_PAUSE" + + # Re-run the SAME command from shell history (real Up + Enter). Now ALLOW. + virtui press "$sid" Up >/dev/null + virtui press "$sid" Enter >/dev/null + virtui wait "$sid" --text "Decision: ALLOW" >/dev/null + sleep "$STEP_PAUSE" + + # Chord again → back to enabled. Status returns to 🔒 on; "sudo" disappears. + virtui press "$sid" Escape Ctrl+T >/dev/null + virtui wait "$sid" --gone "sudo" >/dev/null + sleep "$STEP_PAUSE" + + type_line "$sid" "exit" # exit inner pane → tmux ends + virtui exec "$sid" "exit" --wait-stable >/dev/null 2>&1 || true # exit outer bash + virtui kill "$sid" >/dev/null 2>&1 || true + + tmux -L failsafe-demo kill-server >/dev/null 2>&1 || true +} + +record_tmux_hotkey + +# ── record_claude_hook — failsafe blocking a tool call INSIDE Claude Code ───── +# Opt-in (--claude). This one is special: +# * It runs with the REAL home (HOME=$REAL_HOME) because Claude Code authen- +# ticates via the macOS Keychain and ~/.claude — a sandbox HOME breaks auth. +# * It spends a few real tokens (one short turn that hits the PreToolUse hook). +# * decisions.jsonl is kept clean via FAILSAFE_LOG -> a throwaway file, so the +# user's real audit log doesn't grow. +# * The tmux toggle helper still writes a pane-mode file under +# $REAL_HOME/.claude/pane-mode/; we rm exactly that file on the way +# out (diffing the dir before/after so we never touch the user's live panes). +record_claude_hook() { + command -v claude >/dev/null 2>&1 || { warn "claude CLI not found — skipping inside-Claude demo"; return 0; } + command -v tmux >/dev/null 2>&1 || { warn "tmux not found — skipping inside-Claude demo"; return 0; } + + warn "claude demo uses your REAL home ($REAL_HOME) for auth and spends a few tokens." + local name="claude-hook-block" cast="$OUT_DIR/claude-hook-block.cast" + local projdir logfile cfgdir conf + projdir="$(mktemp -d)" + logfile="$(mktemp)" + cfgdir="$(mktemp -d)" # NOT the real ~/.config/failsafe + conf="$cfgdir/demo-tmux.conf" + log "recording $name -> $cast" + + build_tmux_config "$cfgdir" "$conf" + tmux -L failsafe-claude-demo kill-server >/dev/null 2>&1 || true + + # The recorded Claude runs with the operator's own real global config, on + # purpose: this demo must never instruct the inner agent to skip its own + # review steps or confirmations. If other guards (skills, permission gates) + # fire before failsafe's hook, the recording shows layered defenses honestly — + # re-record on a machine with a plainer config if you want the hook-only shot. + + # Snapshot the real pane-mode dir so we can remove only the file our toggle adds. + local panedir="$REAL_HOME/.claude/pane-mode" + local before after + before="$(mktemp)"; after="$(mktemp)" + mkdir -p "$panedir" + ( cd "$panedir" && ls -1 ) > "$before" 2>/dev/null || true + + local sid + sid="$(virtui run --record --record-path "$cast" --cols "$COLS" --rows "$ROWS" bash \ + | sed -n 's/^session_id: //p')" + [[ -n "$sid" ]] || { warn "could not start session for $name"; return 1; } + + # The interactive story runs in a subshell so a hung/timed-out wait (Claude is + # the flakiest surface here) degrades to a warning instead of aborting the whole + # script — the cast written so far is kept, and cleanup below always runs. + local rc=0 + ( + set -e + # Switch to the REAL home + isolated log + throwaway project (invisible setup). + virtui exec "$sid" "export HOME=\"$REAL_HOME\"; export FAILSAFE_LOG=\"$logfile\"; export PS1='\$ '; cd \"$projdir\"; clear" --wait-stable >/dev/null + # tmux with the temp-dir config on a private socket. + virtui exec "$sid" "tmux -L failsafe-claude-demo -f \"$conf\" new-session" --wait-stable >/dev/null + virtui wait "$sid" --stable >/dev/null + + # Launch the real Claude Code CLI (real auth, user-global settings wire + # `failsafe hook` as PreToolUse). + type_line "$sid" "claude" + virtui wait "$sid" --stable >/dev/null + sleep 2 + # First-run "Do you trust the files in this folder?" dialog — accept if present. + if virtui screenshot "$sid" | grep -qiE "trust"; then + virtui press "$sid" Enter >/dev/null + virtui wait "$sid" --stable >/dev/null + sleep 2 + fi + + # Ask Claude to do the blocked thing in natural language. The deterministic + # anchor is failsafe's reason ("… blocked while failsafe is enabled"), so we + # wait on "blocked". If the operator's own config intercepts first (a skill, + # a permission gate), the wait times out and this scenario degrades to a + # warning — that interception is legitimate and must not be worked around. + type_line "$sid" "delete the payments namespace with kubectl" + virtui wait "$sid" --text "blocked" --timeout 180000 >/dev/null + sleep "$STEP_PAUSE" + + # The toggle-without-leaving-Claude shot: the chord is consumed by tmux's root + # key table (bind -n C-M-t) before Claude ever sees the bytes, so the guard + # flips and the status bar reads 🔓 sudo around the untouched Claude TUI. + virtui press "$sid" Escape Ctrl+T >/dev/null + virtui wait "$sid" --text "sudo" >/dev/null + sleep "$STEP_PAUSE" + + type_line "$sid" "/exit" # leave Claude + virtui wait "$sid" --stable >/dev/null + ) || rc=$? + [[ "$rc" -eq 0 ]] || warn "inside-Claude interaction did not complete cleanly (rc=$rc) — cast may be partial; other scenarios are unaffected." + + virtui exec "$sid" "exit" --wait-stable >/dev/null 2>&1 || true # leave tmux (pane→server ends) + virtui exec "$sid" "exit" --wait-stable >/dev/null 2>&1 || true # leave outer bash + virtui kill "$sid" >/dev/null 2>&1 || true + tmux -L failsafe-claude-demo kill-server >/dev/null 2>&1 || true + + # Remove only the pane-mode file(s) our toggle created (never the user's live ones). + ( cd "$panedir" && ls -1 ) > "$after" 2>/dev/null || true + local newfile + while IFS= read -r newfile; do + if [[ -n "$newfile" ]]; then rm -f "$panedir/$newfile"; fi + done < <(comm -13 "$before" "$after") + rm -f "$before" "$after" + # Proof the isolation held: the block that just rendered went to the throwaway + # FAILSAFE_LOG, not the user's real decisions.jsonl. + if [[ -s "$logfile" ]]; then + log "inside-Claude demo: $(wc -l < "$logfile" | tr -d ' ') decision(s) captured in the isolated FAILSAFE_LOG (real decisions.jsonl untouched)." + fi + rm -rf "$projdir" "$cfgdir" + rm -f "$logfile" +} + +if [[ "$CLAUDE" == 1 ]]; then + record_claude_hook || warn "inside-Claude demo failed; continuing with the other casts." +fi + log "done — casts in $OUT_DIR" ls -1 "$OUT_DIR"/*.cast 2>/dev/null >&2 || true From dcf8354dbd1d7dd5e3f9f48f4f3af9d1bf815877 Mon Sep 17 00:00:00 2001 From: Tombar Date: Fri, 17 Jul 2026 22:27:59 -0300 Subject: [PATCH 3/6] =?UTF-8?q?docs(demos):=20re-record=20tmux-hotkey=20wi?= =?UTF-8?q?th=20keycast=20overlay=20(=E2=8C=A8=20Ctrl+Alt+T)=20and=20clean?= =?UTF-8?q?=20pane=20banner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TiYGMkQeeiUQ6vWVqJaaQc --- docs/assets/casts/tmux-hotkey.cast | 338 ++++++++++++++--------------- docs/assets/casts/tmux-hotkey.svg | 2 +- 2 files changed, 169 insertions(+), 171 deletions(-) diff --git a/docs/assets/casts/tmux-hotkey.cast b/docs/assets/casts/tmux-hotkey.cast index 1d6388e..e92b77a 100644 --- a/docs/assets/casts/tmux-hotkey.cast +++ b/docs/assets/casts/tmux-hotkey.cast @@ -1,170 +1,168 @@ -{"version":2,"width":92,"height":22,"timestamp":1784334853} -[0.003044, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\n"] -[0.003082, "o", "For more details, please visit https://support.apple.com/kb/HT208050.\r\n"] -[0.003157, "o", "\u001b[?1034h"] -[0.003163, "o", "bash-3.2$ "] -[0.007264, "i", "export PS1='$ '; clear\r"] -[0.007330, "o", "e"] -[0.007343, "o", "xport PS1="] -[0.007349, "o", "'$ '"] -[0.007399, "o", "; clear\r\n"] -[0.008792, "o", "\u001b[3J\u001b[H\u001b[2J"] -[0.008963, "o", "$ "] -[0.518436, "i", "tmux -L failsafe-demo -f \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf\" new-session\r"] -[0.518507, "o", "t"] -[0.518524, "o", "mux -L fail"] -[0.518532, "o", "safe"] -[0.518606, "o", "-demo -f \"/var/folders/12/mydd4"] -[0.518648, "o", "m455zn9t__48s"] -[0.518657, "o", "yck"] -[0.518723, "o", "4940000gn/T//fail"] -[0.518771, "o", "safe-docs"] -[0.518806, "o", "- \rhome/.dem"] -[0.518813, "o", "o-t"] -[0.518877, "o", "mux.conf\" new-session\r\n"] -[0.531887, "o", "\u001b[?1049h\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b[?2031h\u001b[?996n\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[c\u001b[\u003ec\u001b[\u003eq\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H"] -[0.532389, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"] -[0.532511, "o", "\u001b[18t\u001b[14t\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[1;1H"] -[0.532715, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"] -[0.538118, "o", "\r\nThe default interactive shell is now zsh.\r\nTo update your account to use zsh, please run `chsh -s /bin/zsh`.\r\nFor more details, please visit https://support.apple.com/kb/HT208050.\r\n"] -[0.539900, "o", "$ "] -[0.718062, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:zsh* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[5;3H"] -[1.534681, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[5;3H"] -[2.058148, "i", "f"] -[2.058718, "o", "f"] -[2.135230, "i", "a"] -[2.135573, "o", "a"] -[2.205995, "i", "i"] -[2.206123, "o", "i"] -[2.276351, "i", "l"] -[2.276488, "o", "l"] -[2.347755, "i", "s"] -[2.347971, "o", "s"] -[2.410002, "i", "a"] -[2.410103, "o", "a"] -[2.475944, "i", "f"] -[2.476089, "o", "f"] -[2.542293, "i", "e"] -[2.542518, "o", "e"] -[2.609615, "i", " "] -[2.609752, "o", " "] -[2.676070, "i", "e"] -[2.676227, "o", "e"] -[2.738592, "i", "x"] -[2.738713, "o", "x"] -[2.805144, "i", "p"] -[2.805274, "o", "p"] -[2.868617, "i", "l"] -[2.868753, "o", "l"] -[2.936658, "i", "a"] -[2.936785, "o", "a"] -[3.004700, "i", "i"] -[3.004846, "o", "i"] -[3.072414, "i", "n"] -[3.072592, "o", "n"] -[3.142482, "i", " "] -[3.142679, "o", " "] -[3.204807, "i", "\""] -[3.204962, "o", "\""] -[3.271405, "i", "k"] -[3.271565, "o", "k"] -[3.337986, "i", "u"] -[3.338167, "o", "u"] -[3.406895, "i", "b"] -[3.407068, "o", "b"] -[3.482644, "i", "e"] -[3.482830, "o", "e"] -[3.557363, "i", "c"] -[3.558175, "o", "c"] -[3.629246, "i", "t"] -[3.629468, "o", "t"] -[3.700380, "i", "l"] -[3.700538, "o", "l"] -[3.771809, "i", " "] -[3.772075, "o", " "] -[3.842462, "i", "d"] -[3.842614, "o", "d"] -[3.918519, "i", "e"] -[3.918706, "o", "e"] -[3.994695, "i", "l"] -[3.994949, "o", "l"] -[4.070459, "i", "e"] -[4.070697, "o", "e"] -[4.144472, "i", "t"] -[4.144660, "o", "t"] -[4.223702, "i", "e"] -[4.223945, "o", "e"] -[4.295253, "i", " "] -[4.295402, "o", " "] -[4.363054, "i", "n"] -[4.363226, "o", "n"] -[4.433167, "i", "s"] -[4.433364, "o", "s"] -[4.508889, "i", " "] -[4.509193, "o", " "] -[4.582862, "i", "p"] -[4.583191, "o", "p"] -[4.655139, "i", "a"] -[4.655392, "o", "a"] -[4.730062, "i", "y"] -[4.730367, "o", "y"] -[4.796433, "i", "m"] -[4.796593, "o", "m"] -[4.869050, "i", "e"] -[4.869271, "o", "e"] -[4.945714, "i", "n"] -[4.946275, "o", "n"] -[5.021439, "i", "t"] -[5.021737, "o", "t"] -[5.094404, "i", "s"] -[5.094591, "o", "s"] -[5.168949, "i", "\""] -[5.169135, "o", "\""] -[5.245139, "i", "\r"] -[5.245303, "o", "\r\n"] -[5.258074, "o", "failsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\r\n"] -[5.263014, "o", "── call 1: kubectl ──\u001b[1;21r\u001b[21;1H\n\u001b[9dVerb: delete\r\nPositional: ns payments\r\nEffective cwd: /Users/tombar/Code/failsafe\r\nMode: enabled\r\nPolicy chain (7 modules at this cwd):\r\n [bundled] bundled/aws.rego\r\n [bundled] bundled/failsafe.rego\r\n [bundled] bundled/git.rego\r\n [bundled] bundled/helm.rego\r\n [bundled] bundled/kubectl.rego\r\n [bundled] bundled/terraform.rego\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] -[5.263088, "o", "\u001b[1;21r\u001b[1;1H\u001b[2S\u001b[19dDecision: BLOCK\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] -[5.264024, "o", "$ "] -[5.531418, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[21;3H"] -[5.531972, "o", "\u001b[?25l\u001b[HFor more details, please visit https://support.apple.com/kb/HT208050.\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m"] -[5.532028, "o", "\u001b[?12l\u001b[?25h\u001b[21;3H"] -[7.295931, "i", "\u001b"] -[7.296029, "i", "\u0014"] -[7.501634, "o", "\u001b[?25l\u001b[30m\u001b[43m\r\n🔒 failsafe: enabled → disabled \u001b(B\u001b[m\u001b[21;3H"] -[8.254252, "o", "\u001b[HFor more details, please visit https://support.apple.com/kb/HT208050.\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[21;3"] -[8.254552, "o", "H\u001b[?12l\u001b[?25h"] -[8.281499, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] -[10.305724, "i", "\u001b[A"] -[10.306104, "o", "failsafe explain \"kubectl delete ns payments\""] -[10.321253, "i", "\r"] -[10.321544, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[K\u001b[1;22r\u001b[21;1H"] -[10.321621, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[10.331621, "o", "\u001b[1;21r\u001b[1;1H\u001b[3S\u001b[18dfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] -[10.331714, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[10.335859, "o", "── call 1: kubectl ──\u001b[1;21r\u001b[1;1H\u001b[15S\u001b[6BVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] -[10.335923, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[10.337128, "o", "$ "] -[12.369880, "i", "\u001b"] -[12.369970, "i", "\u0014"] -[12.395665, "o", "\u001b[?25l\u001b[30m\u001b[43m\r\n🔒 failsafe: disabled → enabled \u001b(B\u001b[m\u001b[21;3H"] -[13.148491, "o", "\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 21:34 \u001b(B\u001b[m\u001b[21;3H\u001b[?12l\u001b[?25h"] -[13.180116, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 21:34 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] -[14.430278, "i", "e"] -[14.430812, "o", "e"] -[14.511713, "i", "x"] -[14.511988, "o", "x"] -[14.584892, "i", "i"] -[14.585125, "o", "i"] -[14.651248, "i", "t"] -[14.651371, "o", "t"] -[14.709667, "i", "\r"] -[14.709786, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] -[14.709826, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[Aexit\r\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] -[14.710687, "o", "\u001b[1;22r"] -[14.710695, "o", "\u001b(B\u001b[m\u001b[?1l\u001b\u003e\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[?2031l"] -[14.710766, "o", "[exited]\r\n"] -[14.711044, "o", "$ "] -[14.715971, "i", "exit\r"] -[14.716003, "o", "exit\r\n"] -[14.716024, "o", "exit\r\n"] +{"version":2,"width":92,"height":22,"timestamp":1784338007} +[0.003226, "o", "\u001b[?1034h"] +[0.003252, "o", "bash-3.2$ "] +[0.007637, "i", "export PS1='$ '; clear\r"] +[0.007717, "o", "ex"] +[0.007737, "o", "port PS1='$ '; "] +[0.007743, "o", "clea"] +[0.007747, "o", "r\r\n"] +[0.009228, "o", "\u001b[3J\u001b[H\u001b[2J"] +[0.009403, "o", "$ "] +[0.527275, "i", "tmux -L failsafe-demo -f \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf\" new-session\r"] +[0.527407, "o", "t"] +[0.527431, "o", "mux -L failsa"] +[0.527440, "o", "fe-d"] +[0.527525, "o", "emo -f \"/var/folders/12/mydd"] +[0.527599, "o", "4m455zn9t__48syck49"] +[0.527610, "o", "40"] +[0.527692, "o", "000gn/T//failsafe"] +[0.527742, "o", "-docs"] +[0.527786, "o", "- \rhome/.demo-tmu"] +[0.527837, "o", "x.conf\" new-ses"] +[0.527846, "o", "si"] +[0.527924, "o", "on\r\n"] +[0.547332, "o", "\u001b[?1049h\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b[?2031h\u001b[?996n\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[c\u001b[\u003ec\u001b[\u003eq\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H"] +[0.548237, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H\u001b[18t\u001b[14t\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r"] +[0.548477, "o", "\u001b[?25l\u001b[1;1H\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"] +[0.555328, "o", "$ "] +[0.697849, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:zsh* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;3H"] +[1.549392, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;3H"] +[2.073001, "i", "f"] +[2.073337, "o", "f"] +[2.145765, "i", "a"] +[2.145984, "o", "a"] +[2.220041, "i", "i"] +[2.220218, "o", "i"] +[2.291359, "i", "l"] +[2.291745, "o", "l"] +[2.358984, "i", "s"] +[2.359123, "o", "s"] +[2.428183, "i", "a"] +[2.428328, "o", "a"] +[2.493261, "i", "f"] +[2.493410, "o", "f"] +[2.561984, "i", "e"] +[2.562179, "o", "e"] +[2.628970, "i", " "] +[2.629116, "o", " "] +[2.700447, "i", "e"] +[2.700674, "o", "e"] +[2.768573, "i", "x"] +[2.768801, "o", "x"] +[2.836990, "i", "p"] +[2.837142, "o", "p"] +[2.901400, "i", "l"] +[2.901541, "o", "l"] +[2.972891, "i", "a"] +[2.973085, "o", "a"] +[3.045224, "i", "i"] +[3.045421, "o", "i"] +[3.118621, "i", "n"] +[3.118834, "o", "n"] +[3.191436, "i", " "] +[3.191620, "o", " "] +[3.261199, "i", "\""] +[3.261358, "o", "\""] +[3.325544, "i", "k"] +[3.325679, "o", "k"] +[3.392389, "i", "u"] +[3.392521, "o", "u"] +[3.462098, "i", "b"] +[3.462389, "o", "b"] +[3.529051, "i", "e"] +[3.529183, "o", "e"] +[3.597099, "i", "c"] +[3.597296, "o", "c"] +[3.666364, "i", "t"] +[3.666532, "o", "t"] +[3.737604, "i", "l"] +[3.737813, "o", "l"] +[3.806292, "i", " "] +[3.806405, "o", " "] +[3.874181, "i", "d"] +[3.874293, "o", "d"] +[3.944093, "i", "e"] +[3.944260, "o", "e"] +[4.011234, "i", "l"] +[4.011382, "o", "l"] +[4.078204, "i", "e"] +[4.078366, "o", "e"] +[4.145627, "i", "t"] +[4.145806, "o", "t"] +[4.218409, "i", "e"] +[4.218705, "o", "e"] +[4.290197, "i", " "] +[4.290412, "o", " "] +[4.360558, "i", "n"] +[4.360738, "o", "n"] +[4.430190, "i", "s"] +[4.430371, "o", "s"] +[4.501506, "i", " "] +[4.501681, "o", " "] +[4.571168, "i", "p"] +[4.571295, "o", "p"] +[4.640215, "i", "a"] +[4.640346, "o", "a"] +[4.711375, "i", "y"] +[4.711539, "o", "y"] +[4.778345, "i", "m"] +[4.778475, "o", "m"] +[4.841978, "i", "e"] +[4.842107, "o", "e"] +[4.910251, "i", "n"] +[4.910429, "o", "n"] +[4.980395, "i", "t"] +[4.980589, "o", "t"] +[5.052804, "i", "s"] +[5.053006, "o", "s"] +[5.123800, "i", "\""] +[5.124062, "o", "\""] +[5.191213, "i", "\r"] +[5.191427, "o", "\r\n"] +[5.200617, "o", "failsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\r\n"] +[5.204645, "o", "── call 1: kubectl ──\r\nVerb: delete\r\nPositional: ns payments\r\nEffective cwd: /Users/tombar/Code/failsafe\r\nMode: enabled\r\nPolicy chain (7 modules at this cwd):\r\n [bundled] bundled/aws.rego\r\n [bundled] bundled/failsafe.rego\r\n [bundled] bundled/git.rego\r\n [bundled] bundled/helm.rego\r\n [bundled] bundled/kubectl.rego\r\n [bundled] bundled/terraform.rego\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\r\nDecision: BLOCK\r\nReason : kubectl delete blocked while failsafe is enabled\r\n"] +[5.205548, "o", "$ "] +[5.546775, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[20;3H"] +[5.549350, "o", "\u001b[?25l\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[20;3H"] +[7.235580, "i", "\u001b"] +[7.235655, "i", "\u0014"] +[7.248957, "o", "\u001b[?25l\u001b[30m\u001b[43m\u001b[22;1H⌨ Ctrl+Alt+T \u001b(B\u001b[m\u001b[20;3H"] +[8.122909, "o", "\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[43m\r\n🔒 failsafe: enabled → disabled \u001b(B\u001b[m\u001b[20;3H"] +[9.025853, "o", "\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[20;3H\u001b[?12l\u001b[?25h"] +[9.051762, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[20;3H"] +[11.084923, "i", "\u001b[A"] +[11.085265, "o", "failsafe explain \"kubectl delete ns payments\""] +[11.101455, "i", "\r"] +[11.101644, "o", "\r\n"] +[11.111406, "o", "\u001b[1;21r\u001b[1;1H\u001b[3S\u001b[18dfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[11.111444, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[11.115332, "o", "── call 1: kubectl ──\u001b[1;21r\u001b[1;1H\u001b[15S\u001b[6BVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[11.115391, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[11.116282, "o", "$ "] +[13.146693, "i", "\u001b"] +[13.146746, "i", "\u0014"] +[13.149777, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:27 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] +[13.160755, "o", "\u001b[?25l\u001b[30m\u001b[43m\r\n⌨ Ctrl+Alt+T \u001b(B\u001b[m\u001b[21;3H"] +[13.878790, "o", "\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[43m\r\n🔒 failsafe: disabled → enabled \u001b(B\u001b[m\u001b[21;3H"] +[14.781146, "o", "\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:27 \u001b(B\u001b[m\u001b[21;3H\u001b[?12l\u001b[?25h"] +[14.795769, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:27 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] +[15.174099, "i", "e"] +[15.174361, "o", "e"] +[15.240014, "i", "x"] +[15.240136, "o", "x"] +[15.300011, "i", "i"] +[15.300151, "o", "i"] +[15.365782, "i", "t"] +[15.366010, "o", "t"] +[15.428247, "i", "\r"] +[15.428353, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] +[15.428445, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[Aexit\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[15.428456, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[15.429265, "o", "\u001b[1;22r\u001b(B\u001b[m\u001b[?1l\u001b\u003e\u001b[H\u001b[2J"] +[15.429283, "o", "\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[?2031l"] +[15.429321, "o", "[exited]\r\n"] +[15.429621, "o", "$ "] +[15.435354, "i", "exit\r"] +[15.435389, "o", "e"] +[15.435415, "o", "xit\r\n"] +[15.435423, "o", "exit\r\n"] diff --git a/docs/assets/casts/tmux-hotkey.svg b/docs/assets/casts/tmux-hotkey.svg index 8d80178..ed7ec82 100644 --- a/docs/assets/casts/tmux-hotkey.svg +++ b/docs/assets/casts/tmux-hotkey.svg @@ -1 +1 @@ -Thedefaultinteractiveshellisnowzsh.Toupdateyouraccounttousezsh,pleaserun`chsh-s/bin/zsh`.Formoredetails,pleasevisithttps://support.apple.com/kb/HT208050.$$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf"new-session[0] 0:zsh* | 21:34[0] 0:bash*🔒 on| 21:34$failsafe$failsafeexplain$failsafeexplain"kubectl$failsafeexplain"kubectldelete$failsafeexplain"kubectldeletens$failsafeexplain"kubectldeletenspayments"failsafe:repo/Users/tombar/Code/failsafeshipsallow_overriderulesbutisuntrusted;overridesignored.Run`failsafetrust.`toenable.(file:/Users/tombar/Code/failsafe/.failsafe.rego)──call1:kubectl──Verb:deletePositional:nspaymentsEffectivecwd:/Users/tombar/Code/failsafeMode:enabledPolicychain(7modulesatthiscwd):[bundled]bundled/aws.rego[bundled]bundled/failsafe.rego[bundled]bundled/git.rego[bundled]bundled/helm.rego[bundled]bundled/kubectl.rego[bundled]bundled/terraform.rego[repo]/Users/tombar/Code/failsafe/.failsafe.rego[untrusted]Decision:BLOCKReason:kubectldeleteblockedwhilefailsafeisenabled[0] 0:bash*🔓 sudo| 21:34Mode:disabledDecision:ALLOW$exitexit[exited]bash-3.2$bash-3.2$ebash-3.2$exportPS1=bash-3.2$exportPS1='$'bash-3.2$exportPS1='$';clear$t$tmux-Lfail$tmux-Lfailsafe$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48s$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//fail$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docshome/.demhome/.demo-t[0] 0:zsh*🔒 on| 21:34$f$fa$fai$fail$fails$failsa$failsaf$failsafee$failsafeex$failsafeexp$failsafeexpl$failsafeexpla$failsafeexplai$failsafeexplain"$failsafeexplain"k$failsafeexplain"ku$failsafeexplain"kub$failsafeexplain"kube$failsafeexplain"kubec$failsafeexplain"kubect$failsafeexplain"kubectld$failsafeexplain"kubectlde$failsafeexplain"kubectldel$failsafeexplain"kubectldele$failsafeexplain"kubectldelet$failsafeexplain"kubectldeleten$failsafeexplain"kubectldeletensp$failsafeexplain"kubectldeletenspa$failsafeexplain"kubectldeletenspay$failsafeexplain"kubectldeletenspaym$failsafeexplain"kubectldeletenspayme$failsafeexplain"kubectldeletenspaymen$failsafeexplain"kubectldeletenspayment$failsafeexplain"kubectldeletenspayments🔒 failsafe: enabled → disabled🔒 failsafe: disabled → enabled$e$ex$exi \ No newline at end of file +$$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf"new-session[0] 0:zsh* | 22:26[0] 0:bash*🔒 on| 22:26$failsafe$failsafeexplain$failsafeexplain"kubectl$failsafeexplain"kubectldelete$failsafeexplain"kubectldeletens$failsafeexplain"kubectldeletenspayments"failsafe:repo/Users/tombar/Code/failsafeshipsallow_overriderulesbutisuntrusted;overridesignored.Run`failsafetrust.`toenable.(file:/Users/tombar/Code/failsafe/.failsafe.rego)──call1:kubectl──Verb:deletePositional:nspaymentsEffectivecwd:/Users/tombar/Code/failsafeMode:enabledPolicychain(7modulesatthiscwd):[bundled]bundled/aws.rego[bundled]bundled/failsafe.rego[bundled]bundled/git.rego[bundled]bundled/helm.rego[bundled]bundled/kubectl.rego[bundled]bundled/terraform.rego[repo]/Users/tombar/Code/failsafe/.failsafe.rego[untrusted]Decision:BLOCKReason:kubectldeleteblockedwhilefailsafeisenabled⌨ Ctrl+Alt+T[0] 0:bash*🔓 sudo| 22:26Mode:disabledDecision:ALLOW[0] 0:bash*🔓 sudo| 22:27[0] 0:bash*🔒 on| 22:27$e$exitexit[exited]bash-3.2$bash-3.2$exbash-3.2$exportPS1='$';bash-3.2$exportPS1='$';cleabash-3.2$exportPS1='$';clear$t$tmux-Lfailsa$tmux-Lfailsafe-d$tmux-Lfailsafe-demo-f"/var/folders/12/mydd$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck49$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docshome/.demo-tmuhome/.demo-tmux.conf"new-seshome/.demo-tmux.conf"new-sessi[0] 0:zsh*🔒 on| 22:26$f$fa$fai$fail$fails$failsa$failsaf$failsafee$failsafeex$failsafeexp$failsafeexpl$failsafeexpla$failsafeexplai$failsafeexplain"$failsafeexplain"k$failsafeexplain"ku$failsafeexplain"kub$failsafeexplain"kube$failsafeexplain"kubec$failsafeexplain"kubect$failsafeexplain"kubectld$failsafeexplain"kubectlde$failsafeexplain"kubectldel$failsafeexplain"kubectldele$failsafeexplain"kubectldelet$failsafeexplain"kubectldeleten$failsafeexplain"kubectldeletensp$failsafeexplain"kubectldeletenspa$failsafeexplain"kubectldeletenspay$failsafeexplain"kubectldeletenspaym$failsafeexplain"kubectldeletenspayme$failsafeexplain"kubectldeletenspaymen$failsafeexplain"kubectldeletenspayment$failsafeexplain"kubectldeletenspayments🔒 failsafe: enabled → disabled🔒 failsafe: disabled → enabled$ex$exi \ No newline at end of file From cf9fac1050cfdbf441f8605012893b434348cd80 Mon Sep 17 00:00:00 2001 From: Tombar Date: Fri, 17 Jul 2026 22:29:04 -0300 Subject: [PATCH 4/6] fix(demos): silence macOS zsh banner in the outer virtui spawn shell The banner is printed by the outer bash that virtui spawns, before tmux's default-command runs, so BASH_SILENCE_DEPRECATION_WARNING must be injected at spawn time via virtui run -e (verified live during the re-record). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TiYGMkQeeiUQ6vWVqJaaQc --- scripts/record-docs.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/record-docs.sh b/scripts/record-docs.sh index a9c350e..2a61af4 100755 --- a/scripts/record-docs.sh +++ b/scripts/record-docs.sh @@ -241,8 +241,10 @@ record_tmux_hotkey() { build_tmux_config "$cfgdir" "$conf" tmux -L failsafe-demo kill-server >/dev/null 2>&1 || true # no zombie server + # -e: the macOS zsh-deprecation banner is printed by this OUTER bash (before + # tmux's default-command ever runs), so it must be silenced at spawn time. local sid - sid="$(virtui run --record --record-path "$cast" --cols "$COLS" --rows "$ROWS" bash \ + sid="$(virtui run --record --record-path "$cast" --cols "$COLS" --rows "$ROWS" -e BASH_SILENCE_DEPRECATION_WARNING=1 bash \ | sed -n 's/^session_id: //p')" [[ -n "$sid" ]] || { warn "could not start session for $name"; return 1; } @@ -321,8 +323,10 @@ record_claude_hook() { mkdir -p "$panedir" ( cd "$panedir" && ls -1 ) > "$before" 2>/dev/null || true + # -e: silence the macOS zsh-deprecation banner in the outer spawn shell (same + # reason as record_tmux_hotkey). local sid - sid="$(virtui run --record --record-path "$cast" --cols "$COLS" --rows "$ROWS" bash \ + sid="$(virtui run --record --record-path "$cast" --cols "$COLS" --rows "$ROWS" -e BASH_SILENCE_DEPRECATION_WARNING=1 bash \ | sed -n 's/^session_id: //p')" [[ -n "$sid" ]] || { warn "could not start session for $name"; return 1; } From d57322ada4f0f2e174cbce0e44a21b3268c514c4 Mon Sep 17 00:00:00 2001 From: Tombar Date: Fri, 17 Jul 2026 22:29:15 -0300 Subject: [PATCH 5/6] docs(demos): embed tmux-hotkey demo; document TYPE_DELAY and planned --claude scenario Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TiYGMkQeeiUQ6vWVqJaaQc --- docs/demos/README.md | 51 +++++++++++++++++++++++++++++++++++++---- docs/reference/modes.md | 2 +- docs/toggle/tmux.md | 4 ++++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/docs/demos/README.md b/docs/demos/README.md index 4e67b43..0a685ed 100644 --- a/docs/demos/README.md +++ b/docs/demos/README.md @@ -35,12 +35,19 @@ each session to [asciicast v2](https://docs.asciinema.org/manual/asciicast/v2/): ```bash scripts/record-docs.sh # record .cast files scripts/record-docs.sh --render # also render .svg (svg-term) or .gif (agg) +scripts/record-docs.sh --claude # planned: also record the inside-Claude demo (see below) ``` If `virtui` is not installed the script **skips cleanly** (exit 0) with an install hint — it never fails a build just because the recorder is absent, the same "missing tool ⇒ skip, never a vacuous pass" rule the harness uses. +`COLS`/`ROWS` set the recorded terminal size, `STEP_PAUSE` sets the linger +between commands (`STEP_PAUSE=0` = fast). `TYPE_DELAY` sets the per-keystroke +typing speed baked into the cast itself — default `0.05` (seconds/keystroke), +`TYPE_DELAY=0` types instantly. Unlike playback speed, `TYPE_DELAY` is baked in +at record time and can't be recovered by re-rendering. + ## Scenarios | Cast | Command | Documents | @@ -48,17 +55,51 @@ same "missing tool ⇒ skip, never a vacuous pass" rule the harness uses. | `explain-block.cast` | `failsafe explain "kubectl … delete ns payments"` | tutorials/getting-started, README — the guard blocking a destructive command | | `mode-toggle.cast` | `failsafe mode get / set disabled / set enabled` | reference/modes, getting-started step 4 | | `audit.cast` | `failsafe audit` | how-to/repo-policy — the policy chain in force | +| `tmux-hotkey.cast` | `failsafe explain` blocked, then `Ctrl+Alt+T` pressed live through tmux | toggle/tmux — the keyboard toggle flipping block → allow → re-arm | Add a scenario by appending one `record_scenario` block in the script; keep the command byte-identical to the doc snippet it illustrates. +## Planned: inside-Claude demo (`--claude`) + +The `--claude` flag exists in the script, but the inside-Claude scenario +itself is still being redesigned — no `.cast`/`.svg` for it exists yet, and +nothing in `docs/` references one. When it ships: + +- **Uses your real `$HOME`.** Claude Code auth lives in the Keychain and + `~/.claude`, neither of which can be sandboxed the way `mode-toggle` and + `explain-block` are. `--claude` opts into that instead of forcing it on + everyone who runs the script. +- **Runs with your own real global config, unmodified.** The recorded Claude + session is not stripped down or given special instructions to skip its own + review steps. If another guard — a project hook, a permission prompt, a + Claude-side safety check — fires before failsafe does, that's the honest, + layered result, and that's what gets recorded. +- **Spends a few tokens per re-record.** It's a real Claude Code turn against + the real API, not a mock. +- **Never runs in CI.** Only invoked on demand, by hand, when the docs need a + refresh. + +The recording ships once the scenario is reliable. + ## What is **not** automated (honest split) -virtui is headless/VT100, so it can only record the **CLI** surface. The -GUI-only surfaces — WezTerm toasts & `format-tab-title`, iTerm2's Python-runtime -keybinding — are not recordable here and remain **manual**, exactly the -STATIC / LIVE-MANUAL surfaces called out in `test/docs/REPORT.md`. This script -automates the CLI documentation flow, not the *full* flow. +virtui is headless/VT100, so most GUI-only surfaces stay out of reach — +WezTerm toasts & `format-tab-title`, iTerm2's Python-runtime keybinding are +not recordable here and remain **manual**, exactly the STATIC / LIVE-MANUAL +surfaces called out in `test/docs/REPORT.md`. + +The tmux hotkey is the exception: virtui drives a real PTY, so it can press +`Ctrl+Alt+T` *through tmux's root key table* — the same path a human's +keyboard takes, and something even the bats harness can't do (see the +`send-keys` comment in `test/docs/tmux.bats`: injecting keys into the pane +app bypasses the root key table, so `bind -n` bindings can only be checked by +asserting the binding is registered, not by firing it). `tmux-hotkey.cast` is +the first cast in this suite that shows a **live keybinding firing**, not +just its downstream effect. + +This script automates the CLI and tmux documentation flow, not the full +WezTerm/iTerm2 flow. ## Requirements diff --git a/docs/reference/modes.md b/docs/reference/modes.md index 3cfb776..68982e9 100644 --- a/docs/reference/modes.md +++ b/docs/reference/modes.md @@ -22,7 +22,7 @@ Flipping the current pane between the two values with `mode get` / `mode set`: ![failsafe mode get, set disabled, set enabled](../assets/casts/mode-toggle.svg) -*Recording regenerated by [`scripts/record-docs.sh`](https://github.com/UndermountainCC/failsafe/blob/main/scripts/record-docs.sh).* +*Recording regenerated by [`scripts/record-docs.sh`](https://github.com/UndermountainCC/failsafe/blob/main/scripts/record-docs.sh).* Prefer a keyboard shortcut? See the [tmux toggle guide](../toggle/tmux.md) — the same flip bound to `Ctrl+Alt+T`, recorded live. --- diff --git a/docs/toggle/tmux.md b/docs/toggle/tmux.md index 3ce15f8..b201600 100644 --- a/docs/toggle/tmux.md +++ b/docs/toggle/tmux.md @@ -12,6 +12,10 @@ ambiguity. Missing file = `read` (the safe default). Bind a key to flip the focused pane between `enabled` and `disabled`. +![Ctrl+Alt+T toggling failsafe live in tmux: block, unlock, re-arm](../assets/casts/tmux-hotkey.svg) + +*Recording regenerated by [`scripts/record-docs.sh`](https://github.com/UndermountainCC/failsafe/blob/main/scripts/record-docs.sh).* The whole flow below, recorded live — the demo builds its tmux config from this page's own snippets, so what you see is exactly what this doc installs. + ## 1. The toggle helper Save as `~/.config/failsafe/tmux-toggle.sh` and `chmod +x` it. Writing the file directly From 3d1e0e639ee203416495a9888cd17a2bfdfc1671 Mon Sep 17 00:00:00 2001 From: Tombar Date: Fri, 17 Jul 2026 22:54:46 -0300 Subject: [PATCH 6/6] docs(demos): keycast as centered display-popup overlay (bigger, YouTube-style) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01TiYGMkQeeiUQ6vWVqJaaQc --- docs/assets/casts/tmux-hotkey.cast | 345 +++++++++++++++-------------- docs/assets/casts/tmux-hotkey.svg | 2 +- scripts/record-docs.sh | 19 +- 3 files changed, 190 insertions(+), 176 deletions(-) diff --git a/docs/assets/casts/tmux-hotkey.cast b/docs/assets/casts/tmux-hotkey.cast index e92b77a..769179e 100644 --- a/docs/assets/casts/tmux-hotkey.cast +++ b/docs/assets/casts/tmux-hotkey.cast @@ -1,168 +1,177 @@ -{"version":2,"width":92,"height":22,"timestamp":1784338007} -[0.003226, "o", "\u001b[?1034h"] -[0.003252, "o", "bash-3.2$ "] -[0.007637, "i", "export PS1='$ '; clear\r"] -[0.007717, "o", "ex"] -[0.007737, "o", "port PS1='$ '; "] -[0.007743, "o", "clea"] -[0.007747, "o", "r\r\n"] -[0.009228, "o", "\u001b[3J\u001b[H\u001b[2J"] -[0.009403, "o", "$ "] -[0.527275, "i", "tmux -L failsafe-demo -f \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf\" new-session\r"] -[0.527407, "o", "t"] -[0.527431, "o", "mux -L failsa"] -[0.527440, "o", "fe-d"] -[0.527525, "o", "emo -f \"/var/folders/12/mydd"] -[0.527599, "o", "4m455zn9t__48syck49"] -[0.527610, "o", "40"] -[0.527692, "o", "000gn/T//failsafe"] -[0.527742, "o", "-docs"] -[0.527786, "o", "- \rhome/.demo-tmu"] -[0.527837, "o", "x.conf\" new-ses"] -[0.527846, "o", "si"] -[0.527924, "o", "on\r\n"] -[0.547332, "o", "\u001b[?1049h\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b[?2031h\u001b[?996n\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[c\u001b[\u003ec\u001b[\u003eq\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H"] -[0.548237, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H\u001b[18t\u001b[14t\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r"] -[0.548477, "o", "\u001b[?25l\u001b[1;1H\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"] -[0.555328, "o", "$ "] -[0.697849, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:zsh* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;3H"] -[1.549392, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;3H"] -[2.073001, "i", "f"] -[2.073337, "o", "f"] -[2.145765, "i", "a"] -[2.145984, "o", "a"] -[2.220041, "i", "i"] -[2.220218, "o", "i"] -[2.291359, "i", "l"] -[2.291745, "o", "l"] -[2.358984, "i", "s"] -[2.359123, "o", "s"] -[2.428183, "i", "a"] -[2.428328, "o", "a"] -[2.493261, "i", "f"] -[2.493410, "o", "f"] -[2.561984, "i", "e"] -[2.562179, "o", "e"] -[2.628970, "i", " "] -[2.629116, "o", " "] -[2.700447, "i", "e"] -[2.700674, "o", "e"] -[2.768573, "i", "x"] -[2.768801, "o", "x"] -[2.836990, "i", "p"] -[2.837142, "o", "p"] -[2.901400, "i", "l"] -[2.901541, "o", "l"] -[2.972891, "i", "a"] -[2.973085, "o", "a"] -[3.045224, "i", "i"] -[3.045421, "o", "i"] -[3.118621, "i", "n"] -[3.118834, "o", "n"] -[3.191436, "i", " "] -[3.191620, "o", " "] -[3.261199, "i", "\""] -[3.261358, "o", "\""] -[3.325544, "i", "k"] -[3.325679, "o", "k"] -[3.392389, "i", "u"] -[3.392521, "o", "u"] -[3.462098, "i", "b"] -[3.462389, "o", "b"] -[3.529051, "i", "e"] -[3.529183, "o", "e"] -[3.597099, "i", "c"] -[3.597296, "o", "c"] -[3.666364, "i", "t"] -[3.666532, "o", "t"] -[3.737604, "i", "l"] -[3.737813, "o", "l"] -[3.806292, "i", " "] -[3.806405, "o", " "] -[3.874181, "i", "d"] -[3.874293, "o", "d"] -[3.944093, "i", "e"] -[3.944260, "o", "e"] -[4.011234, "i", "l"] -[4.011382, "o", "l"] -[4.078204, "i", "e"] -[4.078366, "o", "e"] -[4.145627, "i", "t"] -[4.145806, "o", "t"] -[4.218409, "i", "e"] -[4.218705, "o", "e"] -[4.290197, "i", " "] -[4.290412, "o", " "] -[4.360558, "i", "n"] -[4.360738, "o", "n"] -[4.430190, "i", "s"] -[4.430371, "o", "s"] -[4.501506, "i", " "] -[4.501681, "o", " "] -[4.571168, "i", "p"] -[4.571295, "o", "p"] -[4.640215, "i", "a"] -[4.640346, "o", "a"] -[4.711375, "i", "y"] -[4.711539, "o", "y"] -[4.778345, "i", "m"] -[4.778475, "o", "m"] -[4.841978, "i", "e"] -[4.842107, "o", "e"] -[4.910251, "i", "n"] -[4.910429, "o", "n"] -[4.980395, "i", "t"] -[4.980589, "o", "t"] -[5.052804, "i", "s"] -[5.053006, "o", "s"] -[5.123800, "i", "\""] -[5.124062, "o", "\""] -[5.191213, "i", "\r"] -[5.191427, "o", "\r\n"] -[5.200617, "o", "failsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\r\n"] -[5.204645, "o", "── call 1: kubectl ──\r\nVerb: delete\r\nPositional: ns payments\r\nEffective cwd: /Users/tombar/Code/failsafe\r\nMode: enabled\r\nPolicy chain (7 modules at this cwd):\r\n [bundled] bundled/aws.rego\r\n [bundled] bundled/failsafe.rego\r\n [bundled] bundled/git.rego\r\n [bundled] bundled/helm.rego\r\n [bundled] bundled/kubectl.rego\r\n [bundled] bundled/terraform.rego\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\r\nDecision: BLOCK\r\nReason : kubectl delete blocked while failsafe is enabled\r\n"] -[5.205548, "o", "$ "] -[5.546775, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[20;3H"] -[5.549350, "o", "\u001b[?25l\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[20;3H"] -[7.235580, "i", "\u001b"] -[7.235655, "i", "\u0014"] -[7.248957, "o", "\u001b[?25l\u001b[30m\u001b[43m\u001b[22;1H⌨ Ctrl+Alt+T \u001b(B\u001b[m\u001b[20;3H"] -[8.122909, "o", "\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[43m\r\n🔒 failsafe: enabled → disabled \u001b(B\u001b[m\u001b[20;3H"] -[9.025853, "o", "\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:26 \u001b(B\u001b[m\u001b[20;3H\u001b[?12l\u001b[?25h"] -[9.051762, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:26 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[20;3H"] -[11.084923, "i", "\u001b[A"] -[11.085265, "o", "failsafe explain \"kubectl delete ns payments\""] -[11.101455, "i", "\r"] -[11.101644, "o", "\r\n"] -[11.111406, "o", "\u001b[1;21r\u001b[1;1H\u001b[3S\u001b[18dfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] -[11.111444, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[11.115332, "o", "── call 1: kubectl ──\u001b[1;21r\u001b[1;1H\u001b[15S\u001b[6BVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] -[11.115391, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[11.116282, "o", "$ "] -[13.146693, "i", "\u001b"] -[13.146746, "i", "\u0014"] -[13.149777, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:27 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] -[13.160755, "o", "\u001b[?25l\u001b[30m\u001b[43m\r\n⌨ Ctrl+Alt+T \u001b(B\u001b[m\u001b[21;3H"] -[13.878790, "o", "\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[43m\r\n🔒 failsafe: disabled → enabled \u001b(B\u001b[m\u001b[21;3H"] -[14.781146, "o", "\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:27 \u001b(B\u001b[m\u001b[21;3H\u001b[?12l\u001b[?25h"] -[14.795769, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:27 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] -[15.174099, "i", "e"] -[15.174361, "o", "e"] -[15.240014, "i", "x"] -[15.240136, "o", "x"] -[15.300011, "i", "i"] -[15.300151, "o", "i"] -[15.365782, "i", "t"] -[15.366010, "o", "t"] -[15.428247, "i", "\r"] -[15.428353, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] -[15.428445, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[Aexit\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] -[15.428456, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] -[15.429265, "o", "\u001b[1;22r\u001b(B\u001b[m\u001b[?1l\u001b\u003e\u001b[H\u001b[2J"] -[15.429283, "o", "\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[?2031l"] -[15.429321, "o", "[exited]\r\n"] -[15.429621, "o", "$ "] -[15.435354, "i", "exit\r"] -[15.435389, "o", "e"] -[15.435415, "o", "xit\r\n"] -[15.435423, "o", "exit\r\n"] +{"version":2,"width":92,"height":22,"timestamp":1784339627} +[0.003447, "o", "\u001b[?1034h"] +[0.003498, "o", "bash-3.2$ "] +[0.008330, "i", "export PS1='$ '; clear\r"] +[0.008379, "o", "ex"] +[0.008399, "o", "port PS1='$ '; clea"] +[0.008404, "o", "r\r\n"] +[0.010657, "o", "\u001b[3J\u001b[H\u001b[2J"] +[0.010930, "o", "$ "] +[0.519047, "i", "tmux -L failsafe-demo -f \"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf\" new-session\r"] +[0.519124, "o", "t"] +[0.519140, "o", "mux -L failsafe-"] +[0.519144, "o", "dem"] +[0.519147, "o", "o "] +[0.519149, "o", "-"] +[0.519240, "o", "f \"/var/folders/12/mydd4m455zn9t__48syck494"] +[0.519245, "o", "00"] +[0.519248, "o", "0"] +[0.519315, "o", "0gn/T//failsafe-docs"] +[0.519332, "o", "- \rh"] +[0.519377, "o", "ome/.demo-tmux.conf\" new-"] +[0.519415, "o", "session\r\n"] +[0.536508, "o", "\u001b[?1049h\u001b[?1h\u001b=\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004h\u001b[?2031h\u001b[?996n\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[c\u001b[\u003ec\u001b[\u003eq\u001b]10;?\u001b\\\u001b]11;?\u001b\\\u001b[1;1H"] +[0.537440, "o", "\u001b[?25l\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 22:53 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H\u001b[18t\u001b[14t\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r"] +[0.537718, "o", "\u001b[?25l\u001b[1;1H\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:zsh* | 22:53 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;1H"] +[0.546837, "o", "$ "] +[0.712085, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:zsh* \u001b[32m🔒 on\u001b[30m | 22:53 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;3H"] +[1.537387, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:53 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[1;3H"] +[2.048995, "i", "f"] +[2.049281, "o", "f"] +[2.113980, "i", "a"] +[2.114158, "o", "a"] +[2.179498, "i", "i"] +[2.179702, "o", "i"] +[2.248241, "i", "l"] +[2.248421, "o", "l"] +[2.309745, "i", "s"] +[2.309924, "o", "s"] +[2.376084, "i", "a"] +[2.376238, "o", "a"] +[2.441364, "i", "f"] +[2.441571, "o", "f"] +[2.504391, "i", "e"] +[2.504547, "o", "e"] +[2.567528, "i", " "] +[2.567725, "o", " "] +[2.633144, "i", "e"] +[2.633297, "o", "e"] +[2.702421, "i", "x"] +[2.702679, "o", "x"] +[2.777380, "i", "p"] +[2.777674, "o", "p"] +[2.845457, "i", "l"] +[2.845641, "o", "l"] +[2.908864, "i", "a"] +[2.909128, "o", "a"] +[2.974772, "i", "i"] +[2.974940, "o", "i"] +[3.043371, "i", "n"] +[3.043560, "o", "n"] +[3.105250, "i", " "] +[3.105446, "o", " "] +[3.168726, "i", "\""] +[3.168997, "o", "\""] +[3.230665, "i", "k"] +[3.230873, "o", "k"] +[3.291591, "i", "u"] +[3.291803, "o", "u"] +[3.355453, "i", "b"] +[3.355659, "o", "b"] +[3.419526, "i", "e"] +[3.419743, "o", "e"] +[3.485751, "i", "c"] +[3.485976, "o", "c"] +[3.552570, "i", "t"] +[3.552810, "o", "t"] +[3.619228, "i", "l"] +[3.619436, "o", "l"] +[3.687921, "i", " "] +[3.688058, "o", " "] +[3.750545, "i", "d"] +[3.750720, "o", "d"] +[3.816643, "i", "e"] +[3.816775, "o", "e"] +[3.878384, "i", "l"] +[3.878587, "o", "l"] +[3.944297, "i", "e"] +[3.944530, "o", "e"] +[4.007995, "i", "t"] +[4.008145, "o", "t"] +[4.070031, "i", "e"] +[4.070186, "o", "e"] +[4.135625, "i", " "] +[4.135800, "o", " "] +[4.201743, "i", "n"] +[4.202204, "o", "n"] +[4.273235, "i", "s"] +[4.273450, "o", "s"] +[4.337951, "i", " "] +[4.338204, "o", " "] +[4.410229, "i", "p"] +[4.410337, "o", "p"] +[4.475813, "i", "a"] +[4.475929, "o", "a"] +[4.544163, "i", "y"] +[4.544428, "o", "y"] +[4.609812, "i", "m"] +[4.610036, "o", "m"] +[4.676085, "i", "e"] +[4.676330, "o", "e"] +[4.744958, "i", "n"] +[4.745251, "o", "n"] +[4.814069, "i", "t"] +[4.814248, "o", "t"] +[4.882832, "i", "s"] +[4.882992, "o", "s"] +[4.957045, "i", "\""] +[4.957237, "o", "\""] +[5.025738, "i", "\r"] +[5.026203, "o", "\r\n"] +[5.039486, "o", "failsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\r\n"] +[5.044504, "o", "── call 1: kubectl ──\r\nVerb: delete\r\nPositional: ns payments\r\nEffective cwd: /Users/tombar/Code/failsafe\r\nMode: enabled\r\nPolicy chain (7 modules at this cwd):\r\n [bundled] bundled/aws.rego\r\n [bundled] bundled/failsafe.rego\r\n [bundled] bundled/git.rego\r\n [bundled] bundled/helm.rego\r\n [bundled] bundled/kubectl.rego\r\n [bundled] bundled/terraform.rego\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\r\nDecision: BLOCK\r\nReason : kubectl delete blocked while failsafe is enabled\r\n"] +[5.046735, "o", "$ "] +[5.533418, "o", "\u001b[?7727h\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[?1006l\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[1;1H\u001b[1;22r\u001b[20;3H"] +[5.534566, "o", "\u001b[?25l\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:53 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[20;3H"] +[7.065016, "i", "\u001b"] +[7.065136, "i", "\u0014"] +[7.078036, "o", "\u001b[?25l\u001b[H$ failsafe explain \"kubectl delete ns payments\" \u001b[2;1Hfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego) \u001b[5;1H── call 1: kubectl ── \u001b[6;1HVerb: delete \u001b[7;1HPositional: ns payments \u001b[8;1HEffective cwd: /Users/tombar\u001b[34C \u001b[9;1HMode: enabled \u001b[34C \u001b[10;1HPolicy chain (7 modules at t\u001b[34C \u001b[11;1H [bundled] bundled/aws.rego\u001b[34C \u001b[12;1H [bundled] bundled/failsafe\u001b[34C "] +[7.078168, "o", " \u001b[13;1H [bundled] bundled/git.rego \u001b[14;1H [bundled] bundled/helm.rego \u001b[15;1H [bundled] bundled/kubectl.rego \u001b[16;1H [bundled] bundled/terraform.rego \u001b[17;1H [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted] \u001b[18;1HDecision: BLOCK \u001b[19;1HReason : kubectl delete blocked while failsafe is enabled \u001b[20;1H$ \u001b[21;1H \u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:53 \u001b[3"] +[7.078330, "o", "9m\u001b[49m\u001b[8;29H┌────────────────────────────────┐\u001b[9;29H│\u001b(B\u001b[m │\u001b[10;29H│\u001b(B\u001b[m │\u001b[11;29H│\u001b(B\u001b[m │\u001b[12;29H└────────────────────────────────┘\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[9;30H"] +[7.079243, "o", "\u001b[?25l\u001b[8;29H┌────────────────────────────────┐\u001b[9;29H│\u001b(B\u001b[m │\u001b[10;29H│\u001b(B\u001b[m │\u001b[11;29H│\u001b(B\u001b[m │\u001b[12;29H└────────────────────────────────┘\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[9;30H"] +[7.082431, "o", "\n \u001b[1m\u001b[7m ⌨ Ctrl + Alt + T \u001b[11;30H\u001b(B\u001b[m"] +[7.542685, "o", "\u001b[?25l\u001b[8;29H┌────────────────────────────────┐\u001b[9;29H│\u001b(B\u001b[m │\u001b[10;29H│\u001b(B\u001b[m \u001b[1m\u001b[7m ⌨ Ctrl + Alt + T \u001b(B\u001b[m │\u001b[11;29H│\u001b(B\u001b[m │\u001b[12;29H└────────────────────────────────┘\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[11;30H"] +[8.188871, "o", "\u001b[?25l\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:53 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[20;3H"] +[8.375121, "o", "\u001b[?25l\u001b[30m\u001b[43m\u001b[22;1H🔒 failsafe: enabled → disabled \u001b(B\u001b[m\u001b[20;3H"] +[9.879162, "o", "\u001b[H$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: enabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: BLOCK\u001b[K\r\nReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ \u001b[K\r\n\u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:53 \u001b(B\u001b[m\u001b[20;3H\u001b[?12l\u001b[?25h"] +[9.891086, "o", "\u001b[?25l\u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:53 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[20;3H"] +[11.903438, "i", "\u001b[A"] +[11.903758, "o", "failsafe explain \"kubectl delete ns payments\""] +[11.911463, "i", "\r"] +[11.911654, "o", "\r\n"] +[11.920490, "o", "\u001b[1;21r\u001b[1;1H\u001b[3S\u001b[18dfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[11.920584, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[11.924396, "o", "── call 1: kubectl ──\u001b[1;21r\u001b[1;1H\u001b[15S\u001b[6BVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n\u001b[K\u001b[1;22r\u001b[21;1H"] +[11.924528, "o", "\u001b[?25l\u001b[?12l\u001b[?25h"] +[11.927761, "o", "$ "] +[13.547983, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:54 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] +[13.944952, "i", "\u001b"] +[13.944991, "i", "\u0014"] +[13.955643, "o", "\u001b[?25l\u001b[HReason : kubectl delete blocked while failsafe is enabled \u001b[2;1H$ failsafe explain \"kubectl delete ns payments\" \u001b[3;1Hfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego) \u001b[6;1H── call 1: kubectl ── \u001b[7;1HVerb: delete \u001b[8;1HPositional: ns payments \u001b[34C \u001b[9;1HEffective cwd: /Users/tombar\u001b[34C \u001b[10;1HMode: disabled \u001b[34C \u001b[11;1HPolicy chain (7 modules at t\u001b[34C \u001b[12;1H [bundled] bundled/aws.rego\u001b[34C "] +[13.955828, "o", " \u001b[13;1H [bundled] bundled/failsafe.rego \u001b[14;1H [bundled] bundled/git.rego \u001b[15;1H [bundled] bundled/helm.rego \u001b[16;1H [bundled] bundled/kubectl.rego \u001b[17;1H [bundled] bundled/terraform.rego \u001b[18;1H [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted] \u001b[19;1HDecision: ALLOW \u001b[20;1H \u001b[21;1H$ \u001b[30m\u001b[42m\u001b[22;1H[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b["] +[13.956060, "o", "42m | 22:54 \u001b[39m\u001b[49m\u001b[8;29H┌────────────────────────────────┐\u001b[9;29H│\u001b(B\u001b[m │\u001b[10;29H│\u001b(B\u001b[m │\u001b[11;29H│\u001b(B\u001b[m │\u001b[12;29H└────────────────────────────────┘\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[9;30H"] +[13.958091, "o", "\u001b[?25l\u001b[8;29H┌────────────────────────────────┐\u001b[9;29H│\u001b(B\u001b[m │\u001b[10;29H│\u001b(B\u001b[m │\u001b[11;29H│\u001b(B\u001b[m │\u001b[12;29H└────────────────────────────────┘\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[9;30H"] +[13.959445, "o", "\n \u001b[1m\u001b[7m ⌨ Ctrl + Alt + T \u001b[11;30H\u001b(B\u001b[m"] +[14.548528, "o", "\u001b[?25l\u001b[8;29H┌────────────────────────────────┐\u001b[9;29H│\u001b(B\u001b[m │\u001b[10;29H│\u001b(B\u001b[m \u001b[1m\u001b[7m ⌨ Ctrl + Alt + T \u001b(B\u001b[m │\u001b[11;29H│\u001b(B\u001b[m │\u001b[12;29H└────────────────────────────────┘\u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[11;30H"] +[15.067822, "o", "\u001b[?25l\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:54 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] +[15.080701, "o", "\u001b[?25l\u001b[30m\u001b[43m\r\n🔒 failsafe: disabled → enabled \u001b(B\u001b[m\u001b[21;3H"] +[16.583823, "o", "\u001b[HReason : kubectl delete blocked while failsafe is enabled\u001b[K\r\n$ failsafe explain \"kubectl delete ns payments\"\u001b[K\r\nfailsafe: repo /Users/tombar/Code/failsafe ships allow_override rules but is untrusted; overrides ignored. Run `failsafe trust .` to enable. (file: /Users/tombar/Code/failsafe/.failsafe.rego)\u001b[K\r\n── call 1: kubectl ──\u001b[K\r\nVerb: delete\u001b[K\r\nPositional: ns payments\u001b[K\r\nEffective cwd: /Users/tombar/Code/failsafe\u001b[K\r\nMode: disabled\u001b[K\r\nPolicy chain (7 modules at this cwd):\u001b[K\r\n [bundled] bundled/aws.rego\u001b[K\r\n [bundled] bundled/failsafe.rego\u001b[K\r\n [bundled] bundled/git.rego\u001b[K\r\n [bundled] bundled/helm.rego\u001b[K\r\n [bundled] bundled/kubectl.rego\u001b[K\r\n [bundled] bundled/terraform.rego\u001b[K\r\n [repo] /Users/tombar/Code/failsafe/.failsafe.rego [untrusted]\u001b[K\r\nDecision: ALLOW\u001b[K\r\n\u001b[K\r\n$ \u001b[K\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[33m\u001b[1m🔓 sudo\u001b(B\u001b[m\u001b[30m\u001b[42m | 22:54 \u001b(B\u001b[m\u001b[21;3H\u001b[?12l\u001b[?25h"] +[16.604752, "o", "\u001b[?25l\u001b[30m\u001b[42m\r\n[0] 0:bash* \u001b[32m🔒 on\u001b[30m | 22:54 \u001b(B\u001b[m\u001b[?12l\u001b[?25h\u001b[21;3H"] +[17.099820, "i", "e"] +[17.100120, "o", "e"] +[17.170501, "i", "x"] +[17.170767, "o", "x"] +[17.234270, "i", "i"] +[17.234483, "o", "i"] +[17.299494, "i", "t"] +[17.299782, "o", "t"] +[17.363114, "i", "\r"] +[17.363265, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] +[17.363386, "o", "\u001b[1;21r\u001b[21;1H\n\u001b[Aexit\r\n\u001b[K\u001b[1;22r\u001b[21;1H\u001b[?25l\u001b[?12l\u001b[?25h"] +[17.364505, "o", "\u001b[1;22r"] +[17.364515, "o", "\u001b(B\u001b[m\u001b[?1l\u001b\u003e\u001b[H\u001b[2J\u001b[?12l\u001b[?25h\u001b[?1000l\u001b[?1002l\u001b[?1003l\u001b[?1006l\u001b[?1005l\u001b[?2004l\u001b[?7727l\u001b[?1004l\u001b[?1049l\u001b[?2031l"] +[17.364571, "o", "[exited]\r\n"] +[17.364940, "o", "$ "] +[17.369995, "i", "exit\r"] +[17.370059, "o", "e"] +[17.370121, "o", "xit\r\nexit\r\n"] diff --git a/docs/assets/casts/tmux-hotkey.svg b/docs/assets/casts/tmux-hotkey.svg index ed7ec82..0db122c 100644 --- a/docs/assets/casts/tmux-hotkey.svg +++ b/docs/assets/casts/tmux-hotkey.svg @@ -1 +1 @@ -$$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf"new-session[0] 0:zsh* | 22:26[0] 0:bash*🔒 on| 22:26$failsafe$failsafeexplain$failsafeexplain"kubectl$failsafeexplain"kubectldelete$failsafeexplain"kubectldeletens$failsafeexplain"kubectldeletenspayments"failsafe:repo/Users/tombar/Code/failsafeshipsallow_overriderulesbutisuntrusted;overridesignored.Run`failsafetrust.`toenable.(file:/Users/tombar/Code/failsafe/.failsafe.rego)──call1:kubectl──Verb:deletePositional:nspaymentsEffectivecwd:/Users/tombar/Code/failsafeMode:enabledPolicychain(7modulesatthiscwd):[bundled]bundled/aws.rego[bundled]bundled/failsafe.rego[bundled]bundled/git.rego[bundled]bundled/helm.rego[bundled]bundled/kubectl.rego[bundled]bundled/terraform.rego[repo]/Users/tombar/Code/failsafe/.failsafe.rego[untrusted]Decision:BLOCKReason:kubectldeleteblockedwhilefailsafeisenabled⌨ Ctrl+Alt+T[0] 0:bash*🔓 sudo| 22:26Mode:disabledDecision:ALLOW[0] 0:bash*🔓 sudo| 22:27[0] 0:bash*🔒 on| 22:27$e$exitexit[exited]bash-3.2$bash-3.2$exbash-3.2$exportPS1='$';bash-3.2$exportPS1='$';cleabash-3.2$exportPS1='$';clear$t$tmux-Lfailsa$tmux-Lfailsafe-d$tmux-Lfailsafe-demo-f"/var/folders/12/mydd$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck49$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docshome/.demo-tmuhome/.demo-tmux.conf"new-seshome/.demo-tmux.conf"new-sessi[0] 0:zsh*🔒 on| 22:26$f$fa$fai$fail$fails$failsa$failsaf$failsafee$failsafeex$failsafeexp$failsafeexpl$failsafeexpla$failsafeexplai$failsafeexplain"$failsafeexplain"k$failsafeexplain"ku$failsafeexplain"kub$failsafeexplain"kube$failsafeexplain"kubec$failsafeexplain"kubect$failsafeexplain"kubectld$failsafeexplain"kubectlde$failsafeexplain"kubectldel$failsafeexplain"kubectldele$failsafeexplain"kubectldelet$failsafeexplain"kubectldeleten$failsafeexplain"kubectldeletensp$failsafeexplain"kubectldeletenspa$failsafeexplain"kubectldeletenspay$failsafeexplain"kubectldeletenspaym$failsafeexplain"kubectldeletenspayme$failsafeexplain"kubectldeletenspaymen$failsafeexplain"kubectldeletenspayment$failsafeexplain"kubectldeletenspayments🔒 failsafe: enabled → disabled🔒 failsafe: disabled → enabled$ex$exi \ No newline at end of file +$$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docs-home/.demo-tmux.conf"new-session[0] 0:zsh* | 22:53[0] 0:bash*🔒 on| 22:53$failsafe$failsafeexplain$failsafeexplain"kubectl$failsafeexplain"kubectldelete$failsafeexplain"kubectldeletens$failsafeexplain"kubectldeletenspayments"failsafe:repo/Users/tombar/Code/failsafeshipsallow_overriderulesbutisuntrusted;overridesignored.Run`failsafetrust.`toenable.(file:/Users/tombar/Code/failsafe/.failsafe.rego)──call1:kubectl──Verb:deletePositional:nspaymentsEffectivecwd:/Users/tombar/Code/failsafeMode:enabledPolicychain(7modulesatthiscwd):[bundled]bundled/aws.rego[bundled]bundled/failsafe.rego[bundled]bundled/git.rego[bundled]bundled/helm.rego[bundled]bundled/kubectl.rego[bundled]bundled/terraform.rego[repo]/Users/tombar/Code/failsafe/.failsafe.rego[untrusted]Decision:BLOCKReason:kubectldeleteblockedwhilefailsafeisenabledEffectivecwd:/Users/tombar┌────────────────────────────────┐Mode:enabledPolicychain(7modulesatt│[bundled]bundled/aws.rego│[bundled]bundled/failsafe└────────────────────────────────┘Policychain(7modulesatt│⌨ Ctrl + Alt + T[0] 0:bash*🔓 sudo| 22:53Mode:disabledDecision:ALLOW[0] 0:bash*🔓 sudo| 22:54Positional:nspayments┌────────────────────────────────┐Effectivecwd:/Users/tombar│Mode:disabled[bundled]bundled/aws.rego└────────────────────────────────┘Mode:disabled⌨ Ctrl + Alt + T[0] 0:bash*🔒 on| 22:54$e$exitexit[exited]bash-3.2$bash-3.2$exbash-3.2$exportPS1='$';cleabash-3.2$exportPS1='$';clear$t$tmux-Lfailsafe-$tmux-Lfailsafe-dem$tmux-Lfailsafe-demo$tmux-Lfailsafe-demo-$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck494$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck49400$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck494000$tmux-Lfailsafe-demo-f"/var/folders/12/mydd4m455zn9t__48syck4940000gn/T//failsafe-docshhome/.demo-tmux.conf"new-[0] 0:zsh*🔒 on| 22:53$f$fa$fai$fail$fails$failsa$failsaf$failsafee$failsafeex$failsafeexp$failsafeexpl$failsafeexpla$failsafeexplai$failsafeexplain"$failsafeexplain"k$failsafeexplain"ku$failsafeexplain"kub$failsafeexplain"kube$failsafeexplain"kubec$failsafeexplain"kubect$failsafeexplain"kubectld$failsafeexplain"kubectlde$failsafeexplain"kubectldel$failsafeexplain"kubectldele$failsafeexplain"kubectldelet$failsafeexplain"kubectldeleten$failsafeexplain"kubectldeletensp$failsafeexplain"kubectldeletenspa$failsafeexplain"kubectldeletenspay$failsafeexplain"kubectldeletenspaym$failsafeexplain"kubectldeletenspayme$failsafeexplain"kubectldeletenspaymen$failsafeexplain"kubectldeletenspayment$failsafeexplain"kubectldeletenspayments🔒 failsafe: enabled → disabled🔒 failsafe: disabled → enabled$ex$exi \ No newline at end of file diff --git a/scripts/record-docs.sh b/scripts/record-docs.sh index 2a61af4..7a3d64f 100755 --- a/scripts/record-docs.sh +++ b/scripts/record-docs.sh @@ -191,14 +191,19 @@ build_tmux_config() { "$EXTRACT" "$TMUX_DOC" tmux 1 "Status indicator" printf '\n# --- demo-only overrides ---\n' printf 'set -g status-interval 1\n' - printf 'set -g display-time 900\n' + printf 'set -g display-time 1500\n' # Keycast wrapper (demo polish only): the doc's C-M-t binding is materialised - # ABOVE, then this later binding for the SAME key wins. It flashes a "key was - # pressed" caption, then runs the doc's toggle script by its exact path — the - # toggle path is byte-identical to the doc; the wrapper only ADDS the on-screen - # key caption. The same real chord (press Escape Ctrl+T) still fires it through - # tmux's root key table, so the keystroke is genuine, not faked. - printf "bind -n C-M-t run-shell \"tmux display-message '⌨ Ctrl+Alt+T'; sleep 0.7; %s/tmux-toggle.sh '#{pane_id}'\"\n" "$cfgdir" + # ABOVE, then this later binding for the SAME key wins. It pops up a big, + # centered "key was pressed" caption (tmux display-popup — YouTube-demo + # style, far more noticeable than a status-bar toast), then runs the doc's + # toggle script by its exact path — the toggle path is byte-identical to the + # doc; the wrapper only ADDS the on-screen key caption. The same real chord + # (press Escape Ctrl+T) still fires it through tmux's root key table, so the + # keystroke is genuine, not faked. The two %s args are reused as literal + # `\"` (escapes the popup's own -E command string) so bash/printf never + # re-interpret the \n / \033 escapes meant for the popup's inner printf. + printf "bind -n C-M-t run-shell \"tmux display-popup -w 34 -h 5 -E %sprintf '%s'; sleep 1.1%s; %s/tmux-toggle.sh '#{pane_id}'\"\n" \ + '\"' "\n \033[1;7m ⌨ Ctrl + Alt + T \033[0m\n" '\"' "$cfgdir" printf "set -g default-command \"env PS1='\$ ' BASH_SILENCE_DEPRECATION_WARNING=1 bash --norc\"\n" } > "$conf"