mirror of
https://github.com/instructkr/claw-code.git
synced 2026-05-18 21:41:26 +08:00
omx(team): merge worker-3
This commit is contained in:
@@ -63,12 +63,27 @@ fn validate_lane_events(value: Option<&Value>, path: &str, errors: &mut Vec<G004
|
|||||||
let mut previous_seq = None;
|
let mut previous_seq = None;
|
||||||
for (index, event) in events.iter().enumerate() {
|
for (index, event) in events.iter().enumerate() {
|
||||||
let base = format!("{path}/{index}");
|
let base = format!("{path}/{index}");
|
||||||
require_non_empty_string(event, &format!("{base}/event"), errors);
|
require_non_empty_string_at(event, "/event", &format!("{base}/event"), errors);
|
||||||
require_non_empty_string(event, &format!("{base}/status"), errors);
|
require_non_empty_string_at(event, "/status", &format!("{base}/status"), errors);
|
||||||
require_non_empty_string(event, &format!("{base}/emittedAt"), errors);
|
require_non_empty_string_at(event, "/emittedAt", &format!("{base}/emittedAt"), errors);
|
||||||
require_non_empty_string(event, &format!("{base}/metadata/provenance"), errors);
|
require_non_empty_string_at(
|
||||||
require_non_empty_string(event, &format!("{base}/metadata/emitterIdentity"), errors);
|
event,
|
||||||
require_non_empty_string(event, &format!("{base}/metadata/environmentLabel"), errors);
|
"/metadata/provenance",
|
||||||
|
&format!("{base}/metadata/provenance"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
require_non_empty_string_at(
|
||||||
|
event,
|
||||||
|
"/metadata/emitterIdentity",
|
||||||
|
&format!("{base}/metadata/emitterIdentity"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
require_non_empty_string_at(
|
||||||
|
event,
|
||||||
|
"/metadata/environmentLabel",
|
||||||
|
&format!("{base}/metadata/environmentLabel"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
|
||||||
match get_path(event, "/metadata/seq").and_then(Value::as_u64) {
|
match get_path(event, "/metadata/seq").and_then(Value::as_u64) {
|
||||||
Some(seq) => {
|
Some(seq) => {
|
||||||
@@ -89,7 +104,12 @@ fn validate_lane_events(value: Option<&Value>, path: &str, errors: &mut Vec<G004
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is_terminal_event_value(event.get("event")) {
|
if is_terminal_event_value(event.get("event")) {
|
||||||
require_non_empty_string(event, &format!("{base}/metadata/eventFingerprint"), errors);
|
require_non_empty_string_at(
|
||||||
|
event,
|
||||||
|
"/metadata/eventFingerprint",
|
||||||
|
&format!("{base}/metadata/eventFingerprint"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,16 +121,32 @@ fn validate_reports(value: Option<&Value>, path: &str, errors: &mut Vec<G004Conf
|
|||||||
|
|
||||||
for (index, report) in reports.iter().enumerate() {
|
for (index, report) in reports.iter().enumerate() {
|
||||||
let base = format!("{path}/{index}");
|
let base = format!("{path}/{index}");
|
||||||
require_string_eq(
|
require_string_eq_at(
|
||||||
report,
|
report,
|
||||||
|
"/schemaVersion",
|
||||||
&format!("{base}/schemaVersion"),
|
&format!("{base}/schemaVersion"),
|
||||||
REPORT_SCHEMA_VERSION,
|
REPORT_SCHEMA_VERSION,
|
||||||
errors,
|
errors,
|
||||||
);
|
);
|
||||||
require_non_empty_string(report, &format!("{base}/reportId"), errors);
|
require_non_empty_string_at(report, "/reportId", &format!("{base}/reportId"), errors);
|
||||||
require_non_empty_string(report, &format!("{base}/identity/contentHash"), errors);
|
require_non_empty_string_at(
|
||||||
require_non_empty_string(report, &format!("{base}/projection/provenance"), errors);
|
report,
|
||||||
require_non_empty_string(report, &format!("{base}/redaction/provenance"), errors);
|
"/identity/contentHash",
|
||||||
|
&format!("{base}/identity/contentHash"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
require_non_empty_string_at(
|
||||||
|
report,
|
||||||
|
"/projection/provenance",
|
||||||
|
&format!("{base}/projection/provenance"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
require_non_empty_string_at(
|
||||||
|
report,
|
||||||
|
"/redaction/provenance",
|
||||||
|
&format!("{base}/redaction/provenance"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
non_empty_array(
|
non_empty_array(
|
||||||
get_path(report, "/consumerCapabilities"),
|
get_path(report, "/consumerCapabilities"),
|
||||||
&format!("{base}/consumerCapabilities"),
|
&format!("{base}/consumerCapabilities"),
|
||||||
@@ -136,19 +172,21 @@ fn validate_findings(value: Option<&Value>, path: &str, errors: &mut Vec<G004Con
|
|||||||
|
|
||||||
for (index, finding) in findings.iter().enumerate() {
|
for (index, finding) in findings.iter().enumerate() {
|
||||||
let base = format!("{path}/{index}");
|
let base = format!("{path}/{index}");
|
||||||
require_one_of(
|
require_one_of_at(
|
||||||
finding,
|
finding,
|
||||||
|
"/kind",
|
||||||
&format!("{base}/kind"),
|
&format!("{base}/kind"),
|
||||||
&["fact", "hypothesis", "negative_evidence"],
|
&["fact", "hypothesis", "negative_evidence"],
|
||||||
errors,
|
errors,
|
||||||
);
|
);
|
||||||
require_one_of(
|
require_one_of_at(
|
||||||
finding,
|
finding,
|
||||||
|
"/confidence",
|
||||||
&format!("{base}/confidence"),
|
&format!("{base}/confidence"),
|
||||||
&["low", "medium", "high"],
|
&["low", "medium", "high"],
|
||||||
errors,
|
errors,
|
||||||
);
|
);
|
||||||
require_non_empty_string(finding, &format!("{base}/statement"), errors);
|
require_non_empty_string_at(finding, "/statement", &format!("{base}/statement"), errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,10 +201,25 @@ fn validate_field_deltas(
|
|||||||
|
|
||||||
for (index, delta) in deltas.iter().enumerate() {
|
for (index, delta) in deltas.iter().enumerate() {
|
||||||
let base = format!("{path}/{index}");
|
let base = format!("{path}/{index}");
|
||||||
require_non_empty_string(delta, &format!("{base}/field"), errors);
|
require_non_empty_string_at(delta, "/field", &format!("{base}/field"), errors);
|
||||||
require_non_empty_string(delta, &format!("{base}/previousHash"), errors);
|
require_non_empty_string_at(
|
||||||
require_non_empty_string(delta, &format!("{base}/currentHash"), errors);
|
delta,
|
||||||
require_non_empty_string(delta, &format!("{base}/attribution"), errors);
|
"/previousHash",
|
||||||
|
&format!("{base}/previousHash"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
require_non_empty_string_at(
|
||||||
|
delta,
|
||||||
|
"/currentHash",
|
||||||
|
&format!("{base}/currentHash"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
|
require_non_empty_string_at(
|
||||||
|
delta,
|
||||||
|
"/attribution",
|
||||||
|
&format!("{base}/attribution"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,12 +234,17 @@ fn validate_approval_tokens(
|
|||||||
|
|
||||||
for (index, token) in tokens.iter().enumerate() {
|
for (index, token) in tokens.iter().enumerate() {
|
||||||
let base = format!("{path}/{index}");
|
let base = format!("{path}/{index}");
|
||||||
require_non_empty_string(token, &format!("{base}/tokenId"), errors);
|
require_non_empty_string_at(token, "/tokenId", &format!("{base}/tokenId"), errors);
|
||||||
require_non_empty_string(token, &format!("{base}/owner"), errors);
|
require_non_empty_string_at(token, "/owner", &format!("{base}/owner"), errors);
|
||||||
require_non_empty_string(token, &format!("{base}/scope"), errors);
|
require_non_empty_string_at(token, "/scope", &format!("{base}/scope"), errors);
|
||||||
require_non_empty_string(token, &format!("{base}/issuedAt"), errors);
|
require_non_empty_string_at(token, "/issuedAt", &format!("{base}/issuedAt"), errors);
|
||||||
require_bool_true(token, &format!("{base}/oneTimeUse"), errors);
|
require_bool_true_at(token, "/oneTimeUse", &format!("{base}/oneTimeUse"), errors);
|
||||||
require_non_empty_string(token, &format!("{base}/replayPreventionNonce"), errors);
|
require_non_empty_string_at(
|
||||||
|
token,
|
||||||
|
"/replayPreventionNonce",
|
||||||
|
&format!("{base}/replayPreventionNonce"),
|
||||||
|
errors,
|
||||||
|
);
|
||||||
validate_delegation_chain(
|
validate_delegation_chain(
|
||||||
get_path(token, "/delegationChain"),
|
get_path(token, "/delegationChain"),
|
||||||
&format!("{base}/delegationChain"),
|
&format!("{base}/delegationChain"),
|
||||||
@@ -206,10 +264,10 @@ fn validate_delegation_chain(
|
|||||||
|
|
||||||
for (index, hop) in chain.iter().enumerate() {
|
for (index, hop) in chain.iter().enumerate() {
|
||||||
let base = format!("{path}/{index}");
|
let base = format!("{path}/{index}");
|
||||||
require_non_empty_string(hop, &format!("{base}/from"), errors);
|
require_non_empty_string_at(hop, "/from", &format!("{base}/from"), errors);
|
||||||
require_non_empty_string(hop, &format!("{base}/to"), errors);
|
require_non_empty_string_at(hop, "/to", &format!("{base}/to"), errors);
|
||||||
require_non_empty_string(hop, &format!("{base}/action"), errors);
|
require_non_empty_string_at(hop, "/action", &format!("{base}/action"), errors);
|
||||||
require_non_empty_string(hop, &format!("{base}/at"), errors);
|
require_non_empty_string_at(hop, "/at", &format!("{base}/at"), errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,55 +298,79 @@ fn require_string_eq(
|
|||||||
expected: &str,
|
expected: &str,
|
||||||
errors: &mut Vec<G004ConformanceError>,
|
errors: &mut Vec<G004ConformanceError>,
|
||||||
) {
|
) {
|
||||||
match get_path(root, path).and_then(Value::as_str) {
|
require_string_eq_at(root, path, path, expected, errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn require_string_eq_at(
|
||||||
|
root: &Value,
|
||||||
|
pointer: &str,
|
||||||
|
error_path: &str,
|
||||||
|
expected: &str,
|
||||||
|
errors: &mut Vec<G004ConformanceError>,
|
||||||
|
) {
|
||||||
|
match get_path(root, pointer).and_then(Value::as_str) {
|
||||||
Some(actual) if actual == expected => {}
|
Some(actual) if actual == expected => {}
|
||||||
Some(actual) => errors.push(G004ConformanceError::new(
|
Some(actual) => errors.push(G004ConformanceError::new(
|
||||||
path,
|
error_path,
|
||||||
format!("expected '{expected}', got '{actual}'"),
|
format!("expected '{expected}', got '{actual}'"),
|
||||||
)),
|
)),
|
||||||
None => errors.push(G004ConformanceError::new(
|
None => errors.push(G004ConformanceError::new(
|
||||||
path,
|
error_path,
|
||||||
"required string field missing",
|
"required string field missing",
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn require_non_empty_string(root: &Value, path: &str, errors: &mut Vec<G004ConformanceError>) {
|
fn require_non_empty_string_at(
|
||||||
match get_path(root, path).and_then(Value::as_str) {
|
|
||||||
Some(value) if !value.trim().is_empty() => {}
|
|
||||||
Some(_) => errors.push(G004ConformanceError::new(path, "string must not be empty")),
|
|
||||||
None => errors.push(G004ConformanceError::new(
|
|
||||||
path,
|
|
||||||
"required string field missing",
|
|
||||||
)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn require_one_of(
|
|
||||||
root: &Value,
|
root: &Value,
|
||||||
path: &str,
|
pointer: &str,
|
||||||
|
error_path: &str,
|
||||||
|
errors: &mut Vec<G004ConformanceError>,
|
||||||
|
) {
|
||||||
|
match get_path(root, pointer).and_then(Value::as_str) {
|
||||||
|
Some(value) if !value.trim().is_empty() => {}
|
||||||
|
Some(_) => errors.push(G004ConformanceError::new(
|
||||||
|
error_path,
|
||||||
|
"string must not be empty",
|
||||||
|
)),
|
||||||
|
None => errors.push(G004ConformanceError::new(
|
||||||
|
error_path,
|
||||||
|
"required string field missing",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn require_one_of_at(
|
||||||
|
root: &Value,
|
||||||
|
pointer: &str,
|
||||||
|
error_path: &str,
|
||||||
allowed: &[&str],
|
allowed: &[&str],
|
||||||
errors: &mut Vec<G004ConformanceError>,
|
errors: &mut Vec<G004ConformanceError>,
|
||||||
) {
|
) {
|
||||||
match get_path(root, path).and_then(Value::as_str) {
|
match get_path(root, pointer).and_then(Value::as_str) {
|
||||||
Some(value) if allowed.contains(&value) => {}
|
Some(value) if allowed.contains(&value) => {}
|
||||||
Some(value) => errors.push(G004ConformanceError::new(
|
Some(value) => errors.push(G004ConformanceError::new(
|
||||||
path,
|
error_path,
|
||||||
format!("'{value}' is not one of {}", allowed.join(", ")),
|
format!("'{value}' is not one of {}", allowed.join(", ")),
|
||||||
)),
|
)),
|
||||||
None => errors.push(G004ConformanceError::new(
|
None => errors.push(G004ConformanceError::new(
|
||||||
path,
|
error_path,
|
||||||
"required string field missing",
|
"required string field missing",
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn require_bool_true(root: &Value, path: &str, errors: &mut Vec<G004ConformanceError>) {
|
fn require_bool_true_at(
|
||||||
match get_path(root, path).and_then(Value::as_bool) {
|
root: &Value,
|
||||||
|
pointer: &str,
|
||||||
|
error_path: &str,
|
||||||
|
errors: &mut Vec<G004ConformanceError>,
|
||||||
|
) {
|
||||||
|
match get_path(root, pointer).and_then(Value::as_bool) {
|
||||||
Some(true) => {}
|
Some(true) => {}
|
||||||
Some(false) => errors.push(G004ConformanceError::new(path, "must be true")),
|
Some(false) => errors.push(G004ConformanceError::new(error_path, "must be true")),
|
||||||
None => errors.push(G004ConformanceError::new(
|
None => errors.push(G004ConformanceError::new(
|
||||||
path,
|
error_path,
|
||||||
"required boolean field missing",
|
"required boolean field missing",
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user