1
00:00:00,300 --> 00:00:03,440
Thanks to Jellypod for helping make this
daily show a reality.

2
00:00:04,220 --> 00:00:08,119
Today's topic is a small protocol change
that matters if you build on the Codex

3
00:00:08,260 --> 00:00:14,480
app-server: PR 59601, which adds command
output deferral to thread item listings.

4
00:00:15,220 --> 00:00:21,180
It was merged November 5th, and it lands
in the 0.167 and 0.168 alpha line.

5
00:00:21,580 --> 00:00:24,640
One caveat up front: it's experimental, so
don't expect it in stable.

6
00:00:25,398 --> 00:00:26,418
Some context.

7
00:00:27,198 --> 00:00:32,238
Codex 0.166.0 is still the stable release
on npm.

8
00:00:32,898 --> 00:00:36,938
The 0.167 line shipped alphas but never
got a stable release,

9
00:00:37,598 --> 00:00:44,278
and on November 4th the npm alpha tag
moved to 0.168.0-alpha.1.

10
00:00:44,898 --> 00:00:47,238
So this feature lives in preview
territory.

11
00:00:48,618 --> 00:00:51,658
The GitHub release entries for those
alphas are one-line titles,

12
00:00:51,838 --> 00:00:53,938
so the details come from the PR itself.

13
00:00:55,002 --> 00:00:55,742
What changed.

14
00:00:56,342 --> 00:01:02,042
The endpoint is thread/items/list in the
app-server JSON-RPC interface.

15
00:01:02,661 --> 00:01:07,862
There's a new parameter, deferOutput, and
you pass it as an object: commandExecution

16
00:01:07,982 --> 00:01:08,542
set to true.

17
00:01:09,222 --> 00:01:11,662
You send it while querying a specific
turnId.

18
00:01:12,342 --> 00:01:16,162
And because it's experimental, your client
has to opt in during the initialize

19
00:01:16,222 --> 00:01:20,342
handshake, with
capabilities.experimentalApi set to true.

20
00:01:20,702 --> 00:01:23,102
Without that, the server rejects
experimental fields.

21
00:01:23,882 --> 00:01:24,962
Now the behavior.

22
00:01:25,722 --> 00:01:30,402
For a completed command, the server
suppresses the raw output only if three things

23
00:01:30,442 --> 00:01:30,802
are true.

24
00:01:31,522 --> 00:01:33,282
It has a recorded completion time.

25
00:01:33,902 --> 00:01:35,342
It has an exit code of zero.

26
00:01:35,982 --> 00:01:38,122
And it has non-empty saved output.

27
00:01:39,022 --> 00:01:43,562
When all three hold, the item comes back
with outputDeferred set to true,

28
00:01:44,062 --> 00:01:46,942
and item.aggregatedOutput set to null.

29
00:01:47,833 --> 00:01:48,653
Why care?

30
00:01:49,273 --> 00:01:53,193
Think about what thread/items/list does in
a real client.

31
00:01:53,933 --> 00:01:57,833
You call it to render a turn: a timeline,
a summary, a progress view.

32
00:01:58,353 --> 00:02:01,833
If that turn ran a big test suite, a
build, or a noisy linter,

33
00:02:02,293 --> 00:02:06,713
you were pulling megabytes of stdout and
stderr just to draw a list of steps.

34
00:02:07,973 --> 00:02:12,373
That means bigger payloads, latency
spikes, and memory pressure in IDE extensions,

35
00:02:12,573 --> 00:02:14,633
CI runners, and custom web frontends.

36
00:02:15,333 --> 00:02:18,293
With deferral, you render the lightweight
timeline instantly,

37
00:02:18,533 --> 00:02:21,573
and move the heavy bytes only when
somebody clicks View Output,

38
00:02:22,013 --> 00:02:23,833
or when an agent needs to inspect a step.

39
00:02:24,508 --> 00:02:25,228
How do you use it?

40
00:02:25,908 --> 00:02:29,228
First, initialize with the experimental
capability on.

41
00:02:29,868 --> 00:02:34,748
In your initialize params, clientInfo as
usual, then capabilities with

42
00:02:34,808 --> 00:02:36,828
experimentalApi true.

43
00:02:37,488 --> 00:02:38,848
Then send initialized.

44
00:02:39,908 --> 00:02:46,228
Next, call thread/items/list with your
turnId and deferOutput set to

45
00:02:46,288 --> 00:02:48,128
commandExecution true.

46
00:02:48,968 --> 00:02:53,288
Items that qualify come back with the null
output and the outputDeferred flag.

47
00:02:54,008 --> 00:03:00,068
When your UI needs the text, call
thread/items/read with that same turnId and the

48
00:03:00,148 --> 00:03:02,708
specific itemId, and you get the full
item.

49
00:03:03,405 --> 00:03:05,605
The Rust SDK side deserves attention.

50
00:03:06,185 --> 00:03:10,085
Conversion from ThreadItemEntry to
ThreadItem is now fallible.

51
00:03:10,625 --> 00:03:11,345
That's deliberate.

52
00:03:12,045 --> 00:03:16,645
Typed consumers have to explicitly detect
deferred output, instead of silently

53
00:03:16,725 --> 00:03:18,705
treating an incomplete item as complete.

54
00:03:19,805 --> 00:03:23,905
So if you're a Rust consumer, expect to
handle a Result where you used to have a

55
00:03:23,965 --> 00:03:26,225
plain conversion, with TryFrom semantics.

56
00:03:27,045 --> 00:03:30,265
A compile error now beats a quietly empty
build log later.

57
00:03:30,925 --> 00:03:31,745
Caveats.

58
00:03:32,725 --> 00:03:33,725
One, scope.

59
00:03:34,265 --> 00:03:37,365
Deferral only applies when you target a
single turnId.

60
00:03:37,825 --> 00:03:41,125
Listings that span multiple turns still
return full output,

61
00:03:41,525 --> 00:03:44,205
and so does the default call when you
don't pass the parameter.

62
00:03:45,165 --> 00:03:46,345
Two, eligibility.

63
00:03:46,925 --> 00:03:51,985
A command with a nonzero exit code is
never deferred, so failure diagnostics stay

64
00:03:52,045 --> 00:03:53,065
immediately available.

65
00:03:53,765 --> 00:03:57,125
That means a noisy failing build still
sends its whole log,

66
00:03:57,625 --> 00:04:00,025
so don't assume payloads shrink across the
board.

67
00:04:01,045 --> 00:04:06,465
Three, your own code: anything that reads
aggregatedOutput must now handle null.

68
00:04:07,195 --> 00:04:09,135
A few smaller items from the past week.

69
00:04:09,935 --> 00:04:14,255
PR 59233 fixes Windows sandbox ACL
handling.

70
00:04:14,875 --> 00:04:19,715
It runs resolve_for_enforcement when
building restricted token and elevated sandbox

71
00:04:19,795 --> 00:04:25,735
overrides, keeps read-only carveouts at
volume roots, and expands deny-read ACL

72
00:04:25,775 --> 00:04:27,635
targets to prevent unintended leaks.

73
00:04:28,615 --> 00:04:34,595
PR 59677 removes the legacy
summarize_sandbox_policy helper in favor of

74
00:04:34,635 --> 00:04:38,035
summarize_permission_profile, which
matters if you call that internally.

75
00:04:38,455 --> 00:04:44,095
And PR 59512 modernizes the Python SDK
build, requiring uv_build at least

76
00:04:44,395 --> 00:04:50,555
0.13.0 and below 0.14, with lockfiles
refreshed to 0.13.6.

77
00:04:51,258 --> 00:04:55,978
On the wider ecosystem, OpenAI announced
on November 4th that it's acquiring Pierre

78
00:04:56,078 --> 00:04:59,998
Computer Company, the makers of Code
Storage, Trees, and Diffs,

79
00:05:00,198 --> 00:05:03,158
aimed at Git and source control
infrastructure for coding agents.

80
00:05:03,738 --> 00:05:07,238
That's the announcement; what it means for
Codex is not yet spelled out.

81
00:05:07,958 --> 00:05:08,658
That's the update.

82
00:05:09,078 --> 00:05:13,818
If you run an app-server client, try
deferOutput on a preview build and see how much

83
00:05:13,858 --> 00:05:15,058
your turn listings shrink.

