Stabilize final gate before release checkpoint

Resolve the G012 evidence gate by fixing permission-mode regressions, platform-sensitive tests, and the clippy surface that blocked an all-targets verification run.

Constraint: G012 final gate required docs, board, full workspace tests, and clippy -D warnings evidence before checkpointing.

Rejected: documenting the worker-2 gate failure as an accepted gap | the failing tests and lints were locally reproducible and fixable.

Confidence: high

Scope-risk: moderate

Directive: Preserve read-only permission requirements for read/glob/grep tools; write/edit remain workspace-write or danger-full-access when outside the workspace.

Tested: python3 .github/scripts/check_doc_source_of_truth.py; python3 .github/scripts/check_release_readiness.py; python3 scripts/validate_cc2_board.py --board .omx/cc2/board.json; python3 .omx/cc2/validate_issue_parity_intake.py .omx/cc2/issue-parity-intake.json; cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo check --manifest-path rust/Cargo.toml --workspace; cargo test --manifest-path rust/Cargo.toml --workspace -- --nocapture; cargo clippy --manifest-path rust/Cargo.toml --workspace --all-targets -- -D warnings

Not-tested: live network provider smoke tests and remote PR/issue mutations.
This commit is contained in:
bellman
2026-05-15 13:34:57 +09:00
parent 33df16b6dd
commit 04c2abb412
11 changed files with 45 additions and 18 deletions

View File

@@ -1214,7 +1214,7 @@ fn execute_tool_with_enforcer(
}
"read_file" => {
let file_input: ReadFileInput = from_value(input)?;
let required_mode = classify_file_path_permission(&file_input.path, false);
let required_mode = classify_read_path_permission(&file_input.path, false);
maybe_enforce_permission_check_with_mode(enforcer, name, input, required_mode)?;
run_read_file(file_input)
}
@@ -2219,6 +2219,14 @@ fn classify_file_path_permission(path: &str, allow_missing: bool) -> PermissionM
}
}
fn classify_read_path_permission(path: &str, allow_missing: bool) -> PermissionMode {
if path_within_current_workspace(path, allow_missing) {
PermissionMode::ReadOnly
} else {
PermissionMode::DangerFullAccess
}
}
fn classify_glob_permission(input: &GlobSearchInputValue) -> PermissionMode {
let base_allowed = input
.path
@@ -2226,7 +2234,7 @@ fn classify_glob_permission(input: &GlobSearchInputValue) -> PermissionMode {
.is_none_or(|path| path_within_current_workspace(path, false));
let pattern_allowed = path_within_current_workspace(&input.pattern, true);
if base_allowed && pattern_allowed {
PermissionMode::WorkspaceWrite
PermissionMode::ReadOnly
} else {
PermissionMode::DangerFullAccess
}
@@ -2238,7 +2246,7 @@ fn classify_grep_permission(input: &GrepSearchInput) -> PermissionMode {
.as_deref()
.is_none_or(|path| path_within_current_workspace(path, false))
{
PermissionMode::WorkspaceWrite
PermissionMode::ReadOnly
} else {
PermissionMode::DangerFullAccess
}
@@ -7126,7 +7134,7 @@ mod tests {
.expect_err("write tool should be denied before dispatch");
// then
assert!(error.contains("requires workspace-write permission"));
assert!(error.contains("requires 'workspace-write' permission"));
}
#[test]
@@ -7151,7 +7159,7 @@ mod tests {
// then
assert!(error
.to_string()
.contains("requires workspace-write permission"));
.contains("requires 'workspace-write' permission"));
}
#[test]
@@ -9926,7 +9934,7 @@ printf 'pwsh:%s' "$1"
)
.expect_err("write_file should be denied in read-only mode");
assert!(
err.contains("current mode is read-only"),
err.contains("current mode is 'read-only'"),
"should cite active mode: {err}"
);
}
@@ -9941,7 +9949,7 @@ printf 'pwsh:%s' "$1"
)
.expect_err("edit_file should be denied in read-only mode");
assert!(
err.contains("current mode is read-only"),
err.contains("current mode is 'read-only'"),
"should cite active mode: {err}"
);
}