A virtual jailed shell environment for Go apps backed by an io/fs#FS.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

docs(sleep): document 1-hour cap as kefka sandbox invariant

Adds doc comment explaining that maxSleep = time.Hour is a
deliberate sandbox invariant, deviating from POSIX/GNU's
2147483647-second requirement. Cross-references the
conformance audit so future contributors don't "fix" it.

Adds tests asserting GNU-compatible behavior: sleep 0,
sleep abc diagnostic, fractional 1.5, multi-operand sum.

Retains GNU extensions: fractional seconds, m/h/d
suffixes, multiple-operand summing.

Refs: docs/posix2018/CONFORMANCE.md
Assisted-by: Claude Opus 4.7 via Claude Code
Signed-off-by: Xe Iaso <me@xeiaso.net>

+68
+10
command/internal/sleep/sleep.go
··· 16 16 17 17 type Impl struct{} 18 18 19 + // maxSleep caps every sleep invocation at one hour. This is a kefka 20 + // sandbox invariant: kefka runs untrusted scripts inside short-lived 21 + // agent sessions, so a script that calls `sleep 99999999` (or `sleep 1y` 22 + // equivalent) must not be able to wedge the harness for hours or days. 23 + // 24 + // GNU coreutils and POSIX both allow much larger durations (POSIX 25 + // RATIONALE requires implementations to accept up to ~68 years), so 26 + // this is a deliberate deviation. See docs/posix2018/CONFORMANCE.md 27 + // "### `sleep`" for the design rationale. Do not remove without 28 + // updating that document. 19 29 const maxSleep = time.Hour 20 30 21 31 var durationRe = regexp.MustCompile(`^(\d+\.?\d*)(s|m|h|d)?$`)
+58
command/internal/sleep/sleep_test.go
··· 148 148 } 149 149 } 150 150 151 + func TestSleepZeroReturnsImmediately(t *testing.T) { 152 + start := time.Now() 153 + stdout, stderr, err := run(t, context.Background(), []string{"0"}) 154 + elapsed := time.Since(start) 155 + 156 + if err != nil { 157 + t.Fatalf("unexpected error: %v; stderr=%q", err, stderr) 158 + } 159 + if stdout != "" { 160 + t.Errorf("expected empty stdout, got %q", stdout) 161 + } 162 + if stderr != "" { 163 + t.Errorf("expected empty stderr, got %q", stderr) 164 + } 165 + if elapsed > 100*time.Millisecond { 166 + t.Errorf("sleep 0 took %v, expected immediate return", elapsed) 167 + } 168 + } 169 + 170 + func TestSleepAlphaFails(t *testing.T) { 171 + stdout, stderr, err := run(t, context.Background(), []string{"abc"}) 172 + if err == nil { 173 + t.Fatalf("expected error, got nil; stdout=%q stderr=%q", stdout, stderr) 174 + } 175 + if !strings.Contains(stderr, "invalid time interval 'abc'") { 176 + t.Errorf("stderr = %q, want diagnostic for 'abc'", stderr) 177 + } 178 + } 179 + 180 + func TestSleepFractionalAccepted(t *testing.T) { 181 + // 1.5 is a GNU compatibility extension over POSIX (which says 182 + // "non-negative decimal integer"). Verify parseDuration accepts it 183 + // without actually waiting 1.5 seconds. 184 + d, ok := parseDuration("1.5") 185 + if !ok { 186 + t.Fatalf("parseDuration(\"1.5\") returned !ok") 187 + } 188 + if want := 1500 * time.Millisecond; d != want { 189 + t.Errorf("parseDuration(\"1.5\") = %v, want %v", d, want) 190 + } 191 + } 192 + 193 + func TestMultipleOperandsSum(t *testing.T) { 194 + // Avoid actually sleeping 6 seconds by validating the parse path 195 + // directly; Exec's loop is a trivial fold over parseDuration. 196 + var total time.Duration 197 + for _, arg := range []string{"1", "2", "3"} { 198 + d, ok := parseDuration(arg) 199 + if !ok { 200 + t.Fatalf("parseDuration(%q) returned !ok", arg) 201 + } 202 + total += d 203 + } 204 + if want := 6 * time.Second; total != want { 205 + t.Errorf("sum = %v, want %v", total, want) 206 + } 207 + } 208 + 151 209 func TestCancelAlreadyDone(t *testing.T) { 152 210 ctx, cancel := context.WithCancel(context.Background()) 153 211 cancel()