Skip to content

Commit fa2a2f0

Browse files
authored
Use released DotSlash package for argument-comment lint (#15199)
## Why The argument-comment lint now has a packaged DotSlash artifact from [#15198](#15198), so the normal repo lint path should use that released payload instead of rebuilding the lint from source every time. That keeps `just clippy` and CI aligned with the shipped artifact while preserving a separate source-build path for people actively hacking on the lint crate. The current alpha package also exposed two integration wrinkles that the repo-side prebuilt wrapper needs to smooth over: - the bundled Dylint library filename includes the host triple, for example `@nightly-2025-09-18-aarch64-apple-darwin`, and Dylint derives `RUSTUP_TOOLCHAIN` from that filename - on Windows, Dylint's driver path also expects `RUSTUP_HOME` to be present in the environment Without those adjustments, the prebuilt CI jobs fail during `cargo metadata` or driver setup. This change makes the checked-in prebuilt wrapper normalize the packaged library name to the plain `nightly-2025-09-18` channel before invoking `cargo-dylint`, and it teaches both the wrapper and the packaged runner source to infer `RUSTUP_HOME` from `rustup show home` when the environment does not already provide it. After the prebuilt Windows lint job started running successfully, it also surfaced a handful of existing anonymous literal callsites in `windows-sandbox-rs`. This PR now annotates those callsites so the new cross-platform lint job is green on the current tree. ## What Changed - checked in the current `tools/argument-comment-lint/argument-comment-lint` DotSlash manifest - kept `tools/argument-comment-lint/run.sh` as the source-build wrapper for lint development - added `tools/argument-comment-lint/run-prebuilt-linter.sh` as the normal enforcement path, using the checked-in DotSlash package and bundled `cargo-dylint` - updated `just clippy` and `just argument-comment-lint` to use the prebuilt wrapper - split `.github/workflows/rust-ci.yml` so source-package checks live in a dedicated `argument_comment_lint_package` job, while the released lint runs in an `argument_comment_lint_prebuilt` matrix on Linux, macOS, and Windows - kept the pinned `nightly-2025-09-18` toolchain install in the prebuilt CI matrix, since the prebuilt package still relies on rustup-provided toolchain components - updated `tools/argument-comment-lint/run-prebuilt-linter.sh` to normalize host-qualified nightly library filenames, keep the `rustup` shim directory ahead of direct toolchain `cargo` binaries, and export `RUSTUP_HOME` when needed for Windows Dylint driver setup - updated `tools/argument-comment-lint/src/bin/argument-comment-lint.rs` so future published DotSlash artifacts apply the same nightly-filename normalization and `RUSTUP_HOME` inference internally - fixed the remaining Windows lint violations in `codex-rs/windows-sandbox-rs` by adding the required `/*param*/` comments at the reported callsites - documented the checked-in DotSlash file, wrapper split, archive layout, nightly prerequisite, and Windows `RUSTUP_HOME` requirement in `tools/argument-comment-lint/README.md`
1 parent 96a8671 commit fa2a2f0

29 files changed

Lines changed: 718 additions & 153 deletions

File tree

.github/workflows/rust-ci.yml

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,13 @@ jobs:
9191
- name: cargo shear
9292
run: cargo shear
9393

94-
argument_comment_lint:
95-
name: Argument comment lint
94+
argument_comment_lint_package:
95+
name: Argument comment lint package
9696
runs-on: ubuntu-24.04
9797
needs: changed
98-
if: ${{ needs.changed.outputs.argument_comment_lint == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }}
98+
if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' || github.event_name == 'push' }}
9999
steps:
100100
- uses: actions/checkout@v6
101-
- name: Install Linux sandbox build dependencies
102-
run: |
103-
sudo DEBIAN_FRONTEND=noninteractive apt-get update
104-
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
105101
- uses: dtolnay/rust-toolchain@1.93.0
106102
with:
107103
toolchain: nightly-2025-09-18
@@ -120,14 +116,46 @@ jobs:
120116
- name: Install cargo-dylint tooling
121117
if: ${{ steps.cargo_dylint_cache.outputs.cache-hit != 'true' }}
122118
run: cargo install --locked cargo-dylint dylint-link
119+
- name: Check source wrapper syntax
120+
run: bash -n tools/argument-comment-lint/run.sh
123121
- name: Test argument comment lint package
124-
if: ${{ needs.changed.outputs.argument_comment_lint_package == 'true' || github.event_name == 'push' }}
125122
working-directory: tools/argument-comment-lint
126123
run: cargo test
127-
- name: Run argument comment lint on codex-rs
124+
125+
argument_comment_lint_prebuilt:
126+
name: Argument comment lint - ${{ matrix.name }}
127+
runs-on: ${{ matrix.runs_on || matrix.runner }}
128+
needs: changed
129+
if: ${{ needs.changed.outputs.argument_comment_lint == 'true' || needs.changed.outputs.workflows == 'true' || github.event_name == 'push' }}
130+
strategy:
131+
fail-fast: false
132+
matrix:
133+
include:
134+
- name: Linux
135+
runner: ubuntu-24.04
136+
- name: macOS
137+
runner: macos-15-xlarge
138+
- name: Windows
139+
runner: windows-x64
140+
runs_on:
141+
group: codex-runners
142+
labels: codex-windows-x64
143+
steps:
144+
- uses: actions/checkout@v6
145+
- name: Install Linux sandbox build dependencies
146+
if: ${{ runner.os == 'Linux' }}
147+
shell: bash
128148
run: |
129-
bash -n tools/argument-comment-lint/run.sh
130-
./tools/argument-comment-lint/run.sh
149+
sudo DEBIAN_FRONTEND=noninteractive apt-get update
150+
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends pkg-config libcap-dev
151+
- uses: dtolnay/rust-toolchain@1.93.0
152+
with:
153+
toolchain: nightly-2025-09-18
154+
components: llvm-tools-preview, rustc-dev, rust-src
155+
- uses: facebook/install-dotslash@v2
156+
- name: Run argument comment lint on codex-rs
157+
shell: bash
158+
run: ./tools/argument-comment-lint/run-prebuilt-linter.sh
131159

132160
# --- CI to validate on different os/targets --------------------------------
133161
lint_build:
@@ -708,14 +736,23 @@ jobs:
708736
results:
709737
name: CI results (required)
710738
needs:
711-
[changed, general, cargo_shear, argument_comment_lint, lint_build, tests]
739+
[
740+
changed,
741+
general,
742+
cargo_shear,
743+
argument_comment_lint_package,
744+
argument_comment_lint_prebuilt,
745+
lint_build,
746+
tests,
747+
]
712748
if: always()
713749
runs-on: ubuntu-24.04
714750
steps:
715751
- name: Summarize
716752
shell: bash
717753
run: |
718-
echo "arglint: ${{ needs.argument_comment_lint.result }}"
754+
echo "argpkg : ${{ needs.argument_comment_lint_package.result }}"
755+
echo "arglint: ${{ needs.argument_comment_lint_prebuilt.result }}"
719756
echo "general: ${{ needs.general.result }}"
720757
echo "shear : ${{ needs.cargo_shear.result }}"
721758
echo "lint : ${{ needs.lint_build.result }}"
@@ -728,8 +765,12 @@ jobs:
728765
exit 0
729766
fi
730767
768+
if [[ '${{ needs.changed.outputs.argument_comment_lint_package }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then
769+
[[ '${{ needs.argument_comment_lint_package.result }}' == 'success' ]] || { echo 'argument_comment_lint_package failed'; exit 1; }
770+
fi
771+
731772
if [[ '${{ needs.changed.outputs.argument_comment_lint }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then
732-
[[ '${{ needs.argument_comment_lint.result }}' == 'success' ]] || { echo 'argument_comment_lint failed'; exit 1; }
773+
[[ '${{ needs.argument_comment_lint_prebuilt.result }}' == 'success' ]] || { echo 'argument_comment_lint_prebuilt failed'; exit 1; }
733774
fi
734775
735776
if [[ '${{ needs.changed.outputs.codex }}' == 'true' || '${{ needs.changed.outputs.workflows }}' == 'true' || '${{ github.event_name }}' == 'push' ]]; then

AGENTS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ Run `just fmt` (in `codex-rs` directory) automatically after you have finished m
4848

4949
Before finalizing a large change to `codex-rs`, run `just fix -p <project>` (in `codex-rs` directory) to fix any linter issues in the code. Prefer scoping with `-p` to avoid slow workspace‑wide Clippy builds; only run `just fix` without `-p` if you changed shared crates. Do not re-run tests after running `fix` or `fmt`.
5050

51+
Also run `just argument-comment-lint` to ensure the codebase is clean of comment lint errors.
52+
5153
## TUI style conventions
5254

5355
See `codex-rs/tui/styles.md`.

codex-rs/cli/src/debug_sandbox.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ async fn run_command_under_sandbox(
170170
command_vec,
171171
&cwd_clone,
172172
env_map,
173-
None,
173+
/*timeout_ms*/ None,
174174
config.permissions.windows_sandbox_private_desktop,
175175
)
176176
} else {
@@ -181,7 +181,7 @@ async fn run_command_under_sandbox(
181181
command_vec,
182182
&cwd_clone,
183183
env_map,
184-
None,
184+
/*timeout_ms*/ None,
185185
config.permissions.windows_sandbox_private_desktop,
186186
)
187187
}
@@ -251,15 +251,15 @@ async fn run_command_under_sandbox(
251251
&config.permissions.file_system_sandbox_policy,
252252
config.permissions.network_sandbox_policy,
253253
sandbox_policy_cwd.as_path(),
254-
false,
254+
/*enforce_managed_network*/ false,
255255
network.as_ref(),
256-
None,
256+
/*extensions*/ None,
257257
);
258258
let network_policy = config.permissions.network_sandbox_policy;
259259
spawn_debug_sandbox_child(
260260
PathBuf::from("/usr/bin/sandbox-exec"),
261261
args,
262-
None,
262+
/*arg0*/ None,
263263
cwd,
264264
network_policy,
265265
env,

codex-rs/core/src/exec.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ fn record_windows_sandbox_spawn_failure(
422422
if let Some(metrics) = codex_otel::metrics::global() {
423423
let _ = metrics.counter(
424424
"codex.windows_sandbox.createprocessasuserw_failed",
425-
1,
425+
/*inc*/ 1,
426426
&[
427427
("error_code", error_code.as_str()),
428428
("path_kind", path_kind),

codex-rs/core/src/windows_sandbox.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ pub fn run_elevated_setup(
185185
command_cwd,
186186
env_map,
187187
codex_home,
188-
None,
189-
None,
188+
/*read_roots_override*/ None,
189+
/*write_roots_override*/ None,
190190
)
191191
}
192192

@@ -421,7 +421,11 @@ fn emit_windows_sandbox_setup_failure_metrics(
421421
if let Some(message) = message_tag.as_deref() {
422422
failure_tags.push(("message", message));
423423
}
424-
let _ = metrics.counter(elevated_setup_failure_metric_name(_err), 1, &failure_tags);
424+
let _ = metrics.counter(
425+
elevated_setup_failure_metric_name(_err),
426+
/*inc*/ 1,
427+
&failure_tags,
428+
);
425429
}
426430
} else {
427431
let _ = metrics.counter(

codex-rs/tui/src/app.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,7 +2901,7 @@ impl App {
29012901
Ok(()) => {
29022902
session_telemetry.counter(
29032903
"codex.windows_sandbox.elevated_setup_success",
2904-
1,
2904+
/*inc*/ 1,
29052905
&[],
29062906
);
29072907
AppEvent::EnableWindowsSandboxForAgentMode {
@@ -2931,7 +2931,7 @@ impl App {
29312931
codex_core::windows_sandbox::elevated_setup_failure_metric_name(
29322932
&err,
29332933
),
2934-
1,
2934+
/*inc*/ 1,
29352935
&tags,
29362936
);
29372937
tracing::error!(
@@ -2972,7 +2972,7 @@ impl App {
29722972
) {
29732973
session_telemetry.counter(
29742974
"codex.windows_sandbox.legacy_setup_preflight_failed",
2975-
1,
2975+
/*inc*/ 1,
29762976
&[],
29772977
);
29782978
tracing::warn!(
@@ -2997,7 +2997,7 @@ impl App {
29972997
self.chat_widget
29982998
.add_to_history(history_cell::new_info_event(
29992999
format!("Granting sandbox read access to {path} ..."),
3000-
None,
3000+
/*hint*/ None,
30013001
));
30023002

30033003
let policy = self.config.permissions.sandbox_policy.get().clone();
@@ -3072,11 +3072,13 @@ impl App {
30723072
match builder.apply().await {
30733073
Ok(()) => {
30743074
if elevated_enabled {
3075-
self.config.set_windows_sandbox_enabled(false);
3076-
self.config.set_windows_elevated_sandbox_enabled(true);
3075+
self.config.set_windows_sandbox_enabled(/*value*/ false);
3076+
self.config
3077+
.set_windows_elevated_sandbox_enabled(/*value*/ true);
30773078
} else {
3078-
self.config.set_windows_sandbox_enabled(true);
3079-
self.config.set_windows_elevated_sandbox_enabled(false);
3079+
self.config.set_windows_sandbox_enabled(/*value*/ true);
3080+
self.config
3081+
.set_windows_elevated_sandbox_enabled(/*value*/ false);
30803082
}
30813083
self.chat_widget.set_windows_sandbox_mode(
30823084
self.config.permissions.windows_sandbox_mode,
@@ -6454,7 +6456,7 @@ guardian_approval = true
64546456
make_header(true),
64556457
Arc::new(crate::history_cell::new_info_event(
64566458
"startup tip that used to replay".to_string(),
6457-
None,
6459+
/*hint*/ None,
64586460
)) as Arc<dyn HistoryCell>,
64596461
user_cell("Tell me a long story about a town with a dark lighthouse."),
64606462
agent_cell(story_part_one),

codex-rs/tui/src/chatwidget.rs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4536,7 +4536,7 @@ impl ChatWidget {
45364536

45374537
self.session_telemetry.counter(
45384538
"codex.windows_sandbox.setup_elevated_sandbox_command",
4539-
1,
4539+
/*inc*/ 1,
45404540
&[],
45414541
);
45424542
self.app_event_tx
@@ -7525,8 +7525,11 @@ impl ChatWidget {
75257525
return;
75267526
}
75277527

7528-
self.session_telemetry
7529-
.counter("codex.windows_sandbox.elevated_prompt_shown", 1, &[]);
7528+
self.session_telemetry.counter(
7529+
"codex.windows_sandbox.elevated_prompt_shown",
7530+
/*inc*/ 1,
7531+
&[],
7532+
);
75307533

75317534
let mut header = ColumnRenderable::new();
75327535
header.push(*Box::new(
@@ -7545,7 +7548,11 @@ impl ChatWidget {
75457548
name: "Set up default sandbox (requires Administrator permissions)".to_string(),
75467549
description: None,
75477550
actions: vec![Box::new(move |tx| {
7548-
accept_otel.counter("codex.windows_sandbox.elevated_prompt_accept", 1, &[]);
7551+
accept_otel.counter(
7552+
"codex.windows_sandbox.elevated_prompt_accept",
7553+
/*inc*/ 1,
7554+
&[],
7555+
);
75497556
tx.send(AppEvent::BeginWindowsSandboxElevatedSetup {
75507557
preset: preset.clone(),
75517558
});
@@ -7557,7 +7564,11 @@ impl ChatWidget {
75577564
name: "Use non-admin sandbox (higher risk if prompt injected)".to_string(),
75587565
description: None,
75597566
actions: vec![Box::new(move |tx| {
7560-
legacy_otel.counter("codex.windows_sandbox.elevated_prompt_use_legacy", 1, &[]);
7567+
legacy_otel.counter(
7568+
"codex.windows_sandbox.elevated_prompt_use_legacy",
7569+
/*inc*/ 1,
7570+
&[],
7571+
);
75617572
tx.send(AppEvent::BeginWindowsSandboxLegacySetup {
75627573
preset: legacy_preset.clone(),
75637574
});
@@ -7569,7 +7580,11 @@ impl ChatWidget {
75697580
name: "Quit".to_string(),
75707581
description: None,
75717582
actions: vec![Box::new(move |tx| {
7572-
quit_otel.counter("codex.windows_sandbox.elevated_prompt_quit", 1, &[]);
7583+
quit_otel.counter(
7584+
"codex.windows_sandbox.elevated_prompt_quit",
7585+
/*inc*/ 1,
7586+
&[],
7587+
);
75737588
tx.send(AppEvent::Exit(ExitMode::ShutdownFirst));
75747589
})],
75757590
dismiss_on_select: true,
@@ -7619,7 +7634,11 @@ impl ChatWidget {
76197634
let otel = self.session_telemetry.clone();
76207635
let preset = elevated_preset;
76217636
move |tx| {
7622-
otel.counter("codex.windows_sandbox.fallback_retry_elevated", 1, &[]);
7637+
otel.counter(
7638+
"codex.windows_sandbox.fallback_retry_elevated",
7639+
/*inc*/ 1,
7640+
&[],
7641+
);
76237642
tx.send(AppEvent::BeginWindowsSandboxElevatedSetup {
76247643
preset: preset.clone(),
76257644
});
@@ -7635,7 +7654,11 @@ impl ChatWidget {
76357654
let otel = self.session_telemetry.clone();
76367655
let preset = legacy_preset;
76377656
move |tx| {
7638-
otel.counter("codex.windows_sandbox.fallback_use_legacy", 1, &[]);
7657+
otel.counter(
7658+
"codex.windows_sandbox.fallback_use_legacy",
7659+
/*inc*/ 1,
7660+
&[],
7661+
);
76397662
tx.send(AppEvent::BeginWindowsSandboxLegacySetup {
76407663
preset: preset.clone(),
76417664
});
@@ -7648,7 +7671,11 @@ impl ChatWidget {
76487671
name: "Quit".to_string(),
76497672
description: None,
76507673
actions: vec![Box::new(move |tx| {
7651-
quit_otel.counter("codex.windows_sandbox.fallback_prompt_quit", 1, &[]);
7674+
quit_otel.counter(
7675+
"codex.windows_sandbox.fallback_prompt_quit",
7676+
/*inc*/ 1,
7677+
&[],
7678+
);
76527679
tx.send(AppEvent::Exit(ExitMode::ShutdownFirst));
76537680
})],
76547681
dismiss_on_select: true,
@@ -7688,11 +7715,12 @@ impl ChatWidget {
76887715
// While elevated sandbox setup runs, prevent typing so the user doesn't
76897716
// accidentally queue messages that will run under an unexpected mode.
76907717
self.bottom_pane.set_composer_input_enabled(
7691-
false,
7718+
/*enabled*/ false,
76927719
Some("Input disabled until setup completes.".to_string()),
76937720
);
76947721
self.bottom_pane.ensure_status_indicator();
7695-
self.bottom_pane.set_interrupt_hint_visible(false);
7722+
self.bottom_pane
7723+
.set_interrupt_hint_visible(/*visible*/ false);
76967724
self.set_status(
76977725
"Setting up sandbox...".to_string(),
76987726
Some("Hang tight, this may take a few minutes".to_string()),
@@ -7708,7 +7736,8 @@ impl ChatWidget {
77087736

77097737
#[cfg(target_os = "windows")]
77107738
pub(crate) fn clear_windows_sandbox_setup_status(&mut self) {
7711-
self.bottom_pane.set_composer_input_enabled(true, None);
7739+
self.bottom_pane
7740+
.set_composer_input_enabled(/*enabled*/ true, /*placeholder*/ None);
77127741
self.bottom_pane.hide_status_indicator();
77137742
self.request_redraw();
77147743
}

codex-rs/tui/src/chatwidget/tests.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -979,8 +979,10 @@ async fn enter_with_only_remote_images_does_not_submit_when_input_disabled() {
979979

980980
let remote_url = "https://example.com/remote-only.png".to_string();
981981
chat.set_remote_image_urls(vec![remote_url.clone()]);
982-
chat.bottom_pane
983-
.set_composer_input_enabled(false, Some("Input disabled for test.".to_string()));
982+
chat.bottom_pane.set_composer_input_enabled(
983+
/*enabled*/ false,
984+
Some("Input disabled for test.".to_string()),
985+
);
984986

985987
chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
986988

0 commit comments

Comments
 (0)