feat: advance local-first workspace checklist
- add admin access-policy UI and local access control surfaces - add local markdown conflict resolution UI and smoke coverage - add ACP local agent changed-files audit scaffold and read-only write guard - document current P0-P2 checklist progress and verification evidence
This commit is contained in:
@@ -707,6 +707,14 @@ pub(crate) fn ensure_write_contract(
|
||||
)
|
||||
.with_context(context));
|
||||
}
|
||||
if input.ai_access_scope_is_read_only() {
|
||||
return Err(WebError::new(
|
||||
axum::http::StatusCode::FORBIDDEN,
|
||||
"mnote_tool_ai_scope_write_forbidden",
|
||||
"当前 AI scope 是只读权限,禁止执行写入型 mnote tool",
|
||||
)
|
||||
.with_context(context));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1490,6 +1498,44 @@ fn build_insert_block(block_id: &str, value: &Value) -> Value {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn ensure_write_contract_rejects_read_only_ai_scope() {
|
||||
let context = RequestContext::from_http_parts(
|
||||
&axum::http::Method::POST,
|
||||
&"/api/hermes/tools".parse().expect("uri"),
|
||||
&axum::http::HeaderMap::new(),
|
||||
);
|
||||
let input = ToolCallInput {
|
||||
tool_name: "mnote.block.replace".into(),
|
||||
workspace_id: Some("ws_1".into()),
|
||||
document_id: Some("doc_1".into()),
|
||||
source_kind: Some("local_folder".into()),
|
||||
root_uri: Some("file:///tmp/mnote-readonly".into()),
|
||||
actor_id: Some("user_1".into()),
|
||||
profile: None,
|
||||
session_id: Some("sess_1".into()),
|
||||
run_id: Some("run_1".into()),
|
||||
tool_call_id: Some("tool_1".into()),
|
||||
trace_id: Some("trace_1".into()),
|
||||
idempotency_key: Some("idem_1".into()),
|
||||
dry_run: Some(false),
|
||||
capability_scope: None,
|
||||
args: Some(json!({
|
||||
"aiAccessScope": {
|
||||
"permissionLevel": "read_only",
|
||||
"allowedRoots": ["file:///tmp/mnote-readonly"]
|
||||
}
|
||||
})),
|
||||
};
|
||||
|
||||
let error = ensure_write_contract(&context, &input).expect_err("read only rejected");
|
||||
assert_eq!(error.status(), axum::http::StatusCode::FORBIDDEN);
|
||||
assert_eq!(
|
||||
error.message(),
|
||||
"当前 AI scope 是只读权限,禁止执行写入型 mnote tool"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn content_to_text_reads_projection_content_nodes() {
|
||||
let value = json!([
|
||||
|
||||
Reference in New Issue
Block a user