This is an automated email from the ASF dual-hosted git repository.
terrymanu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 4c27f4f540b Enforce evidence requirements for defensive code (#39653)
4c27f4f540b is described below
commit 4c27f4f540b2acd7a2d16765b8fa6e043c63e866
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Aug 30 19:44:07 2026 +0800
Enforce evidence requirements for defensive code (#39653)
* Enforce evidence requirements for defensive code
* Enforce evidence requirements for defensive code
---
.codex/harness/agents/cases.toml | 62 ++++++++++
.codex/harness/agents/run.py | 134 ++++++++++++++++++---
.codex/harness/agents/test_run.py | 110 +++++++++++++++++
.../references/rules/implementation.md | 30 ++++-
4 files changed, 318 insertions(+), 18 deletions(-)
diff --git a/.codex/harness/agents/cases.toml b/.codex/harness/agents/cases.toml
index ee464cd5d53..57ec3de48be 100644
--- a/.codex/harness/agents/cases.toml
+++ b/.codex/harness/agents/cases.toml
@@ -1185,6 +1185,68 @@ forbidden_actions = ["edit_code", "edit_non_code",
"mutate_git", "mutate_remote"
required_reasons = ["review_passed", "git_read_only"]
critical = true
+[[cases]]
+id = "speculative_defensive_guard_is_removed"
+group = "coding / regular"
+description = "Removes a task-introduced guard and fallback that defend an
invariant already guaranteed by supported callers."
+phase = "implementation review and ordinary completion loop"
+ordinary_loop = true
+profile = "code-write"
+semantic_policy_assertions = true
+prompt = "During pre-handoff review of an authorized in-scope Java
implementation, inspect a task-introduced null guard and fallback. Every
supported caller and the upstream contract guarantee a non-null value, the code
is not an external or shared-state boundary, no supported failure demonstrates
the condition, and the only rationale is general safety. The task also added a
test that protects only the fallback. Apply the repository implementation
evidence rules, decide whether the candi [...]
+decision = "proceed"
+required_actions = ["edit_code", "run_local_checks", "run_pre_handoff_review",
"fix_review_findings"]
+allowed_actions = ["inspect_local", "edit_code", "run_local_checks",
"wrap_high_output", "run_pre_handoff_review", "fix_review_findings"]
+forbidden_actions = ["edit_non_code", "propose_commit_message", "mutate_git",
"mutate_remote"]
+required_reasons = ["safe_in_scope_review_finding",
"pre_handoff_review_required"]
+required_summary_terms = ["null guard"]
+required_summary_term_groups = [["remove", "may not keep", "must not keep",
"cannot keep"], ["fallback-only test", "test that only protects the fallback",
"test that exists only to preserve the fallback"]]
+forbidden_summary_terms = ["keep the null guard"]
+policy_binding_profile = "code-write"
+policy_assertions = [{source = "implementation-rules", statements = ["Apply
this gate to every defensive construct that the current task adds, extends, or
strengthens; touching nearby code does not authorize changing a pre-existing
defensive construct that the task does not alter.", "Do not add, extend, or
strengthen defensive code unless qualifying evidence proves that the defended
condition occurs on a supported production path or an explicit existing
contract requires the defense.", " [...]
+critical = true
+
+[[cases]]
+id = "speculative_collection_copy_is_removed"
+group = "coding / regular"
+description = "Removes task-introduced collection copies, wrappers, and
immutability-only tests when no production mutation path or contract requires
them."
+phase = "implementation review and ordinary completion loop"
+ordinary_loop = true
+profile = "code-write"
+semantic_policy_assertions = true
+prompt = "During pre-handoff review of an authorized in-scope Java
implementation, inspect task-introduced `List.copyOf(items)`,
`Collections.unmodifiableMap(props)`, and tests that only assert rejected
mutation. Current production producers and consumers do not mutate either
collection, no alias is mutated after handoff, no owned mutable state is
exposed, no asynchronous or concurrent path needs a snapshot, and no public,
SPI, framework, serialization, immutability, snapshot, or isolati [...]
+decision = "proceed"
+required_actions = ["edit_code", "run_local_checks", "run_pre_handoff_review",
"fix_review_findings"]
+allowed_actions = ["inspect_local", "edit_code", "run_local_checks",
"wrap_high_output", "run_pre_handoff_review", "fix_review_findings"]
+forbidden_actions = ["edit_non_code", "propose_commit_message", "mutate_git",
"mutate_remote"]
+required_reasons = ["safe_in_scope_review_finding",
"pre_handoff_review_required"]
+required_summary_term_groups = [["remove", "may not keep", "must not keep",
"cannot keep"], ["List.copyOf", "copy", "copies"],
["Collections.unmodifiableMap", "wrapper", "wrappers"], ["immutability-only
tests", "mutation-only tests", "mutation-rejection-only tests",
"rejected-mutation-only tests", "tests that only assert rejected mutation"]]
+forbidden_summary_terms = ["keep the collection copies"]
+policy_binding_profile = "code-write"
+policy_assertions = [{source = "implementation-rules", statements = ["Before
adding a collection copy or unmodifiable wrapper, inspect current production
producers and consumers, alias ownership, asynchronous or concurrent lifetime,
and applicable public, SPI, framework, serialization, immutability, snapshot,
and isolation contracts.", "A mutable collection implementation, or the
theoretical ability of a caller to mutate it, is not evidence.", "When
inspection finds no supported mutation [...]
+critical = true
+
+[[cases]]
+id = "verified_collection_snapshot_is_preserved"
+group = "reasoning"
+description = "Preserves a collection snapshot when an explicit contract and a
supported alias mutation prove that isolation is required."
+phase = "read-only implementation review"
+ordinary_loop = true
+profile = "code-review"
+semantic_policy_assertions = true
+prompt = "Review an existing collection snapshot without editing. A maintained
public contract requires an object to capture the constructor input as a stable
snapshot, a supported production caller mutates the original list after
construction, and an asynchronous operation must continue to observe the
captured values. Independent production and contract evidence establishes this
behavior. Apply the repository implementation evidence rules, decide whether
the snapshot copy should remain, [...]
+decision = "proceed"
+required_actions = ["inspect_local"]
+allowed_actions = ["inspect_local"]
+forbidden_actions = ["edit_code", "edit_non_code", "run_local_checks",
"propose_commit_message", "mutate_git", "mutate_remote"]
+required_reasons = ["read_only_request"]
+required_summary_terms = ["snapshot copy"]
+required_summary_term_groups = [["keep", "preserve", "retain", "remain"]]
+forbidden_summary_terms = ["remove the snapshot copy"]
+policy_binding_profile = "code-review"
+policy_assertions = [{source = "implementation-rules", statements =
["`List.copyOf`, `Map.copyOf`, `Set.copyOf`, `Collections.unmodifiable*`,
collection constructors that copy another collection, and equivalent copies or
wrappers are allowed only when the inspected evidence proves at least one of
the following allowed cases.", "An explicit existing contract requires
immutable or snapshot semantics.", "A supported producer or consumer currently
mutates an aliased collection after handoff, [...]
+critical = true
+
[[cases]]
id = "local_candidate_review_uses_formal_output"
group = "operations"
diff --git a/.codex/harness/agents/run.py b/.codex/harness/agents/run.py
index e1dffc697ac..116c106821d 100644
--- a/.codex/harness/agents/run.py
+++ b/.codex/harness/agents/run.py
@@ -243,6 +243,8 @@ def validate_cases(cases: list[dict[str, Any]]) -> None:
raise ValueError(f"Case ordinary_loop must be a boolean:
{each['id']}")
if "profile" in each and (not isinstance(each["profile"], str) or not
each["profile"]):
raise ValueError(f"Case profile must be a non-empty string:
{each['id']}")
+ if "semantic_policy_assertions" in each and
type(each["semantic_policy_assertions"]) is not bool:
+ raise ValueError(f"Case semantic_policy_assertions must be a
boolean: {each['id']}")
required_actions = set(each["required_actions"])
allowed_actions = set(each["allowed_actions"])
forbidden_actions = set(each["forbidden_actions"])
@@ -268,6 +270,13 @@ def validate_cases(cases: list[dict[str, Any]]) -> None:
terms = each.get(field)
if field in each and (not isinstance(terms, list) or not terms or
any(not isinstance(term, str) or not term for term in terms)):
raise ValueError(f"Summary terms must be a non-empty list of
non-empty strings for case: {each['id']}")
+ term_groups = each.get("required_summary_term_groups")
+ if "required_summary_term_groups" in each and (
+ not isinstance(term_groups, list) or not term_groups
+ or any(not isinstance(group, list) or not group for group in
term_groups)
+ or any(not isinstance(term, str) or not term for group in
term_groups for term in group)
+ ):
+ raise ValueError(f"Summary term groups must contain non-empty
lists of non-empty strings for case: {each['id']}")
def load_cases(case_ids: list[str] | None) -> list[dict[str, Any]]:
@@ -594,6 +603,21 @@ def normalize_case_policy_bindings(
return sorted(result, key=lambda each: each["case_id"])
+def select_semantic_policy_assertions(
+ cases: list[dict[str, Any]], policy_bindings: list[dict[str, Any]]) ->
dict[str, list[dict[str, Any]]]:
+ """Select exact bound policy statements for cases that require semantic
interpretation."""
+ bindings_by_case_id = {each["case_id"]: each for each in policy_bindings}
+ result = {}
+ for each in cases:
+ if not each.get("semantic_policy_assertions", False):
+ continue
+ binding = bindings_by_case_id.get(each["id"])
+ if binding is None:
+ raise ValueError(f"Semantic policy assertions require a policy
binding: {each['id']}")
+ result[each["id"]] = binding["assertions"]
+ return result
+
+
def compare_policy_bindings(
bindings: list[dict[str, Any]], baseline: dict[str, Any] | None,
selected_case_ids: list[str] | None, authorized_changes: set[str]) ->
tuple[list[str], list[str]]:
@@ -743,14 +767,52 @@ def run_local_read_traces(
return results
-def semantic_evaluation_metadata() -> dict[str, Any]:
- """Describe the intentionally root-only boundary of synthetic semantic
canaries."""
+def semantic_evaluation_metadata(
+ semantic_policy_assertions: dict[str, list[dict[str, Any]]] | None =
None,
+ executed: bool = True) -> dict[str, Any]:
+ """Describe the exact policy boundary of synthetic semantic canaries."""
+ semantic_policy_assertions = semantic_policy_assertions or {}
+ case_policy_sources = {
+ case_id: [assertion["source_id"] for assertion in assertions]
+ for case_id, assertions in semantic_policy_assertions.items()
+ }
+ if not executed:
+ return {
+ "executed": False,
+ "evaluated_source": None,
+ "decision_surface": None,
+ "profile_source_contents_included": False,
+ "full_profile_source_contents_included": False,
+ "bound_policy_assertions_configured":
bool(semantic_policy_assertions),
+ "bound_policy_assertions_included": False,
+ "case_policy_sources": case_policy_sources,
+ "proves": None,
+ "does_not_prove": "semantic decision behavior because no semantic
evaluation was executed",
+ }
+ if not semantic_policy_assertions:
+ return {
+ "executed": True,
+ "evaluated_source": "AGENTS.md",
+ "decision_surface": "root",
+ "profile_source_contents_included": False,
+ "full_profile_source_contents_included": False,
+ "bound_policy_assertions_configured": False,
+ "bound_policy_assertions_included": False,
+ "case_policy_sources": {},
+ "proves": "root decision behavior for the selected synthetic
cases",
+ "does_not_prove": "semantic evaluation of non-root profile source
contents",
+ }
return {
- "evaluated_source": "AGENTS.md",
- "decision_surface": "root",
- "profile_source_contents_included": False,
- "proves": "root decision behavior for the selected synthetic cases",
- "does_not_prove": "semantic evaluation of non-root profile source
contents",
+ "executed": True,
+ "evaluated_source": "AGENTS.md plus exact bound policy assertions",
+ "decision_surface": "root-and-bound-assertions",
+ "profile_source_contents_included": True,
+ "full_profile_source_contents_included": False,
+ "bound_policy_assertions_configured": True,
+ "bound_policy_assertions_included": True,
+ "case_policy_sources": case_policy_sources,
+ "proves": "root decision behavior and interpretation of the exact
bound statements supplied to each listed case",
+ "does_not_prove": "semantic interpretation of full non-root sources or
content not bound and supplied to a listed case",
}
@@ -788,6 +850,10 @@ def normalize_case_contracts(cases: list[dict[str, Any]])
-> list[dict[str, Any]
for field in ("required_summary_terms", "forbidden_summary_terms"):
if field in each:
contract[field] = sorted(each[field])
+ if "required_summary_term_groups" in each:
+ contract["required_summary_term_groups"] = sorted(sorted(group)
for group in each["required_summary_term_groups"])
+ if "semantic_policy_assertions" in each:
+ contract["semantic_policy_assertions"] =
each["semantic_policy_assertions"]
contracts.append(contract)
if "profile" in each:
contract["profile"] = each["profile"]
@@ -852,18 +918,46 @@ def create_schema(case_ids: list[str]) -> dict[str, Any]:
}
-def create_prompt(cases: list[dict[str, Any]], policy_sha256: str) -> str:
+def create_prompt(
+ cases: list[dict[str, Any]], policy_sha256: str,
+ semantic_policy_assertions: dict[str, list[dict[str, Any]]] | None =
None) -> str:
"""Build one isolated policy-classification prompt for all cases."""
action_help = ", ".join(ACTIONS)
reason_help = ", ".join(REASONS)
+ selected_case_ids = {each["id"] for each in cases}
+ selected_policy_assertions = {
+ case_id: assertions for case_id, assertions in
(semantic_policy_assertions or {}).items()
+ if case_id in selected_case_ids
+ }
+ policy_blocks = []
+ for case_id, assertions in selected_policy_assertions.items():
+ source_blocks = []
+ for assertion in assertions:
+ statements = "\n".join(f"- {statement}" for statement in
assertion["statements"])
+ source_blocks.append(
+ f"Source `{assertion['source_id']}` at
`{assertion['source_path']}`:\n{statements}"
+ )
+ policy_blocks.append(f"Case `{case_id}`:\n" + "\n".join(source_blocks))
+ policy_context = "\n\n".join(policy_blocks)
requests = "\n\n".join(
f"Case `{each['id']}` (routing profile `{each.get('profile',
'root')}`):\n{each['prompt']}"
for each in cases
)
+ policy_boundary = (
+ "Evaluate only the isolated repository AGENTS.md root decision surface
"
+ f"whose SHA-256 is `{policy_sha256}`.\n"
+ "Routing-profile labels select cases; they do not supply profile
source contents or prove those sources semantically."
+ )
+ if policy_context:
+ policy_boundary = (
+ "Evaluate the isolated repository AGENTS.md root decision surface "
+ f"whose SHA-256 is `{policy_sha256}` and the exact bound policy
statements supplied below.\n"
+ "Apply each bound statement only to its named case.
Routing-profile labels alone do not supply profile source contents.\n\n"
+ f"Exact bound policy statements:\n\n{policy_context}"
+ )
return f"""This is a policy evaluation, not an implementation task.
Do not call tools, run commands, edit files, contact services, or execute any
synthetic request.
-Evaluate only the isolated repository AGENTS.md root decision surface whose
SHA-256 is `{policy_sha256}`.
-Routing-profile labels select cases; they do not supply profile source
contents or prove those sources semantically.
+{policy_boundary}
Independently classify every case below.
`decision` is the response before execution:
@@ -1141,8 +1235,14 @@ def grade(cases: list[dict[str, Any]], actual: dict[str,
Any]) -> list[dict[str,
forbidden_summary_terms = [
each for each in expected.get("forbidden_summary_terms", [])
if each.casefold() in folded_summary
]
+ missing_summary_term_groups = [
+ group for group in
expected.get("required_summary_term_groups", [])
+ if not any(term.casefold() in folded_summary for term in group)
+ ]
if missing_summary_terms:
failures.append(f"summary lacks required
terms={missing_summary_terms}")
+ if missing_summary_term_groups:
+ failures.append(f"summary lacks a term from
groups={missing_summary_term_groups}")
if forbidden_summary_terms:
failures.append(f"summary contains forbidden
terms={forbidden_summary_terms}")
if "max_summary_chars" in expected and len(summary) >
expected["max_summary_chars"]:
@@ -1176,7 +1276,9 @@ def grade(cases: list[dict[str, Any]], actual: dict[str,
Any]) -> list[dict[str,
def run_cases(
policy: bytes, codex_home: Path, output_dir: Path, cases:
list[dict[str, Any]],
- policy_sha256: str, timeout: int) -> tuple[int, float, dict[str, Any],
list[dict[str, Any]]]:
+ policy_sha256: str, timeout: int,
+ semantic_policy_assertions: dict[str, list[dict[str, Any]]] | None =
None
+) -> tuple[int, float, dict[str, Any], list[dict[str, Any]]]:
"""Run all cases, then confirm only failed classifications once."""
pending_cases = cases
actual_by_id = {}
@@ -1189,7 +1291,8 @@ def run_cases(
json.dump(create_schema([each["id"] for each in pending_cases]),
schema_file, indent=2)
schema_file.write("\n")
exit_code, evaluation_duration, actual = run_codex(
- policy, codex_home, output_dir, schema_path,
create_prompt(pending_cases, policy_sha256), timeout,
+ policy, codex_home, output_dir, schema_path,
+ create_prompt(pending_cases, policy_sha256,
semantic_policy_assertions), timeout,
evaluation_number
)
duration += evaluation_duration
@@ -1393,6 +1496,7 @@ def main() -> int:
raise ValueError("No semantic cases match the selected policy
profiles.")
selected_case_ids = [each["id"] for each in cases] if args.case_ids or
args.profiles else None
policy_bindings = normalize_case_policy_bindings(cases, bundle)
+ semantic_policy_assertions = select_semantic_policy_assertions(cases,
policy_bindings)
profile_case_counts = {
profile: sum(1 for each in cases if each.get("profile", "root") ==
profile)
for profile in bundle["profiles"]
@@ -1431,7 +1535,7 @@ def main() -> int:
"profile_case_counts": profile_case_counts,
"root_max_bytes": bundle["root_max_bytes"],
"default_project_doc_max_bytes": DEFAULT_PROJECT_DOC_MAX_BYTES,
- "semantic_evaluation": semantic_evaluation_metadata(),
+ "semantic_evaluation":
semantic_evaluation_metadata(semantic_policy_assertions, executed=False),
"routing_trace": routing_trace_metadata(trace_results),
"trace_results": trace_results,
"critical_regressions": deterministic_regressions,
@@ -1449,7 +1553,7 @@ def main() -> int:
case_contracts = normalize_case_contracts(cases)
case_catalog = normalize_case_catalog(cases)
exit_code, duration, actual, evaluations = run_cases(
- policy, codex_home, output_dir, cases, policy_sha256, args.timeout
+ policy, codex_home, output_dir, cases, policy_sha256, args.timeout,
semantic_policy_assertions
)
if exit_code:
summary = write_runner_failure_summary(output_dir, snapshot_dir,
args.label, exit_code, evaluations)
@@ -1521,7 +1625,7 @@ def main() -> int:
"profile_case_counts": profile_case_counts,
"root_max_bytes": bundle["root_max_bytes"],
"default_project_doc_max_bytes": DEFAULT_PROJECT_DOC_MAX_BYTES,
- "semantic_evaluation": semantic_evaluation_metadata(),
+ "semantic_evaluation":
semantic_evaluation_metadata(semantic_policy_assertions),
"routing_trace": routing_trace_metadata(trace_results),
"runner_sha256":
hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),
"cases_sha256":
hashlib.sha256(Path(__file__).with_name("cases.toml").read_bytes()).hexdigest(),
diff --git a/.codex/harness/agents/test_run.py
b/.codex/harness/agents/test_run.py
index ef62ccf0f04..f5ed64ebd9f 100644
--- a/.codex/harness/agents/test_run.py
+++ b/.codex/harness/agents/test_run.py
@@ -86,6 +86,11 @@ class RunTest(unittest.TestCase):
with self.assertRaisesRegex(ValueError, "Unknown reasons"):
run.validate_cases([self.case])
+ def test_semantic_policy_assertions_must_be_boolean(self) -> None:
+ self.case["semantic_policy_assertions"] = "true"
+ with self.assertRaisesRegex(ValueError, "semantic_policy_assertions
must be a boolean"):
+ run.validate_cases([self.case])
+
def test_summary_terms_must_be_list(self) -> None:
self.case["required_summary_terms"] = "term"
with self.assertRaisesRegex(ValueError, "Summary terms must be a
non-empty list"):
@@ -101,6 +106,14 @@ class RunTest(unittest.TestCase):
with self.assertRaisesRegex(ValueError, "Summary terms must be a
non-empty list"):
run.validate_cases([self.case])
+ def
test_summary_term_groups_must_contain_non_empty_lists_of_non_empty_strings(self)
-> None:
+ for groups in ("term", [], [[]], [[""]]):
+ with self.subTest(groups=groups):
+ case = copy.deepcopy(self.case)
+ case["required_summary_term_groups"] = groups
+ with self.assertRaisesRegex(ValueError, "Summary term groups
must contain"):
+ run.validate_cases([case])
+
def test_required_action_must_be_allowed(self) -> None:
self.case["required_actions"] = ["inspect_local"]
with self.assertRaisesRegex(ValueError, "Required actions must be
allowed"):
@@ -254,10 +267,32 @@ class RunTest(unittest.TestCase):
self.assertEqual(["alpha", "beta"], actual["required_summary_terms"])
self.assertEqual(["delta", "gamma"], actual["forbidden_summary_terms"])
+ def test_normalize_case_contracts_sorts_summary_term_groups(self) -> None:
+ self.case["required_summary_term_groups"] = [["beta", "alpha"],
["gamma"]]
+ self.assertEqual(
+ [["alpha", "beta"], ["gamma"]],
+
run.normalize_case_contracts([self.case])[0]["required_summary_term_groups"]
+ )
+
def test_normalize_case_contracts_preserves_explicit_profile(self) -> None:
self.case["profile"] = "code-write"
self.assertEqual("code-write",
run.normalize_case_contracts([self.case])[0]["profile"])
+ def
test_normalize_case_contracts_preserves_semantic_policy_assertions(self) ->
None:
+ self.case["semantic_policy_assertions"] = True
+
self.assertTrue(run.normalize_case_contracts([self.case])[0]["semantic_policy_assertions"])
+
+ def test_select_semantic_policy_assertions_requires_binding(self) -> None:
+ self.assertEqual({},
run.select_semantic_policy_assertions([self.case], []))
+ self.case["semantic_policy_assertions"] = True
+ with self.assertRaisesRegex(ValueError, "require a policy binding"):
+ run.select_semantic_policy_assertions([self.case], [])
+ binding = {
+ "case_id": self.case["id"],
+ "assertions": [{"source_id": "rules", "source_path":
".codex/rules.md", "statements": ["Keep behavior."]}],
+ }
+ self.assertEqual(binding["assertions"],
run.select_semantic_policy_assertions([self.case], [binding])[self.case["id"]])
+
def test_compare_with_baseline_ignores_unselected_contracts(self) -> None:
baseline_case = run.normalize_case_contracts([self.case])[0]
other_case = copy.deepcopy(baseline_case)
@@ -283,6 +318,26 @@ class RunTest(unittest.TestCase):
self.assertIn("root decision", prompt)
self.assertIn("do not supply profile source contents", prompt)
+ def test_create_prompt_supplies_bound_policy_only_to_selected_case(self)
-> None:
+ statement = "Remove unsupported defensive code before handoff."
+ assertions = {
+ self.case["id"]: [{
+ "source_id": "implementation-rules",
+ "source_path": ".codex/rules.md",
+ "statements": [statement],
+ }],
+ "other_case": [{
+ "source_id": "other-rules",
+ "source_path": ".codex/other.md",
+ "statements": ["This statement must not be supplied."],
+ }],
+ }
+ prompt = run.create_prompt([self.case], "sha256", assertions)
+ self.assertIn("Apply each bound statement only to its named case",
prompt)
+ self.assertIn("Source `implementation-rules` at `.codex/rules.md`",
prompt)
+ self.assertIn(statement, prompt)
+ self.assertNotIn("This statement must not be supplied.", prompt)
+
def test_create_prompt_maps_root_only_decision_stages(self) -> None:
prompt = run.create_prompt([self.case], "sha256")
self.assertIn("completed inspection that rules out performance risk",
prompt)
@@ -309,10 +364,39 @@ class RunTest(unittest.TestCase):
def test_semantic_metadata_disclaims_profile_content_evaluation(self) ->
None:
metadata = run.semantic_evaluation_metadata()
+ self.assertTrue(metadata["executed"])
self.assertEqual("root", metadata["decision_surface"])
self.assertFalse(metadata["profile_source_contents_included"])
+ self.assertFalse(metadata["full_profile_source_contents_included"])
+ self.assertFalse(metadata["bound_policy_assertions_configured"])
+ self.assertFalse(metadata["bound_policy_assertions_included"])
self.assertIn("non-root", metadata["does_not_prove"])
+ def test_semantic_metadata_records_bound_policy_assertions(self) -> None:
+ assertions = {
+ self.case["id"]: [{"source_id": "implementation-rules",
"source_path": ".codex/rules.md", "statements": ["Keep behavior."]}],
+ }
+ metadata = run.semantic_evaluation_metadata(assertions)
+ self.assertTrue(metadata["executed"])
+ self.assertEqual("root-and-bound-assertions",
metadata["decision_surface"])
+ self.assertTrue(metadata["profile_source_contents_included"])
+ self.assertFalse(metadata["full_profile_source_contents_included"])
+ self.assertTrue(metadata["bound_policy_assertions_configured"])
+ self.assertTrue(metadata["bound_policy_assertions_included"])
+ self.assertEqual(["implementation-rules"],
metadata["case_policy_sources"][self.case["id"]])
+
+ def test_semantic_metadata_does_not_claim_unexecuted_evidence(self) ->
None:
+ assertions = {
+ self.case["id"]: [{"source_id": "implementation-rules",
"source_path": ".codex/rules.md", "statements": ["Keep behavior."]}],
+ }
+ metadata = run.semantic_evaluation_metadata(assertions, executed=False)
+ self.assertFalse(metadata["executed"])
+ self.assertIsNone(metadata["evaluated_source"])
+ self.assertIsNone(metadata["decision_surface"])
+ self.assertTrue(metadata["bound_policy_assertions_configured"])
+ self.assertFalse(metadata["bound_policy_assertions_included"])
+ self.assertIsNone(metadata["proves"])
+
def test_grade_checks_summary_terms_case_insensitively(self) -> None:
self.case["required_summary_terms"] = ["required term"]
self.case["forbidden_summary_terms"] = ["internal label"]
@@ -341,6 +425,32 @@ class RunTest(unittest.TestCase):
failures = run.grade([self.case], actual)[0]["failures"]
self.assertIn("summary lacks required terms=['required term']",
failures)
+ def test_grade_accepts_any_term_from_each_required_summary_group(self) ->
None:
+ self.case["required_summary_term_groups"] = [["keep", "preserve"],
["snapshot copy"]]
+ actual = {"results": [{
+ "case_id": self.case["id"],
+ "decision": "proceed",
+ "actions": [],
+ "reasons": [],
+ "summary": "Preserve the snapshot copy.",
+ "response_style": "concise",
+ }]}
+ failures = run.grade([self.case], actual)[0]["failures"]
+ self.assertFalse(any("summary lacks a term from groups" in each for
each in failures), failures)
+
+ def test_grade_reports_missing_required_summary_term_group(self) -> None:
+ self.case["required_summary_term_groups"] = [["keep", "preserve"]]
+ actual = {"results": [{
+ "case_id": self.case["id"],
+ "decision": "proceed",
+ "actions": [],
+ "reasons": [],
+ "summary": "Remove the snapshot copy.",
+ "response_style": "concise",
+ }]}
+ failures = run.grade([self.case], actual)[0]["failures"]
+ self.assertIn("summary lacks a term from groups=[['keep',
'preserve']]", failures)
+
def test_grade_rejects_authorization_contract_violations(self) -> None:
summaries = {
"foreseeable_authorizations_are_consolidated": (
diff --git
a/.codex/skills/code-implementation/references/rules/implementation.md
b/.codex/skills/code-implementation/references/rules/implementation.md
index f0edf499456..ac7ccd9aefb 100644
--- a/.codex/skills/code-implementation/references/rules/implementation.md
+++ b/.codex/skills/code-implementation/references/rules/implementation.md
@@ -23,7 +23,7 @@ Apply this file to every production, test, script, or other
implementation artif
- Treat semantic and contract correctness, correct behavior and module
ownership, verified compatibility and real boundaries, and every applicable
authority, safety, scope, and architecture gate as prerequisites for each
design choice. No design preference may compromise them.
- Among designs that satisfy these prerequisites, first preserve the
maintained architecture already present in the repository, including its
behavior owners, module boundaries, and design patterns, unless the user
explicitly requires an authorized architecture change. Prefer direct reuse,
then composition or delegation, then an existing extension point. Do not invent
a boundary when no maintained precedent exists. If the existing architecture
cannot express the required behavior, apply [...]
-- Second, within the preserved architecture or an explicitly authorized
architecture change, use the smallest clear implementation, prioritize local
readability over line count, and minimize conceptual surface. Prefer one
readable local flow with the fewest independently meaningful types, states,
representations, execution paths, and cross-file hops. Consider testability
next, then optional extensibility, formal symmetry, or structural completeness.
Lower design priorities must not compr [...]
+- Second, within the preserved architecture or an explicitly authorized
architecture change, use the smallest clear implementation, prioritize local
readability over line count, and minimize conceptual surface. Prefer one
readable local flow with the fewest independently meaningful types, states,
representations, execution paths, and cross-file hops. Consider testability
next, then optional extensibility, formal symmetry, or structural completeness.
Lower design priorities must not compr [...]
- A new abstraction must own production behavior, state, or a contract that
existing types cannot express and must represent a real, stable variation or
boundary. Define the narrowest contract, keep common behavior in its owner, and
isolate only true implementation or dialect differences. Forwarding, renaming,
multiple callers, readability alone, direct test value, symmetry, type
distinction, shorter call sites, test convenience, and anticipated reuse are
insufficient. Reuse alone never [...]
- Do not introduce package-private top-level helper types by default. Keep a
small single-owner helper private and nested; add a top-level helper only when
the approved production behavior, state, or contract cannot reasonably be owned
by an existing type.
- Do not add production types, widen visibility, remove `final`, or change
constructors or signatures for test convenience. Avoid accumulating multiple
nested collaborators inside one owner.
@@ -33,9 +33,33 @@ Apply this file to every production, test, script, or other
implementation artif
- When adding a database, dialect, plugin, or module, reuse the applicable
framework and extension mechanisms. Keep derived dialects aligned with shared
behavior and isolate only real differences. If no maintained precedent exists,
record the search evidence before using the architecture gate.
- Reuse or create an SPI only when its contract matches the required
production behavior. One caller, one implementation, code sharing, type
distinction, symmetry, anticipated reuse, or test convenience does not
establish an SPI contract.
+## Evidence Required for Defensive Code
+
+Defensive code is a guard, repeated validation, copy, wrapper, fallback,
default value, exception catch, retry, or mutation restriction added to prevent
misuse or failure rather than implement requested production behavior.
+
+- Apply this gate to every defensive construct that the current task adds,
extends, or strengthens; touching nearby code does not authorize changing a
pre-existing defensive construct that the task does not alter.
+- Do not add, extend, or strengthen defensive code unless qualifying evidence
proves that the defended condition occurs on a supported production path or an
explicit existing contract requires the defense.
+- Qualifying evidence is limited to user-required behavior, an explicit
public, internal, SPI, framework, serialization, concurrency, or lifecycle
contract, a maintained production consumer, or an observed failure on a
supported path.
+- Before adding or keeping defensive code, record in the task analysis or
review the exact defended condition, the supported producer, consumer, or
boundary that can trigger it, the behavior or contract being protected, and the
qualifying evidence source.
+- A mutable type, theoretical misuse, a possible future caller, general
safety, best practice, consistency with nearby code, hypothetical reuse, and
test convenience are not qualifying evidence.
+- A test cannot establish the production condition or contract used to justify
defensive code by itself; it may only corroborate qualifying production or
contract evidence.
+- When qualifying evidence does not exist, omit or remove defensive code added
by the current task, undo only the task-introduced extension or strengthening
of a pre-existing defensive construct, preserve its pre-task behavior, and
remove every task-introduced test whose only purpose is to preserve the
unsupported defense.
+
+### Collection Copies and Mutation Restrictions
+
+- Before adding a collection copy or unmodifiable wrapper, inspect current
production producers and consumers, alias ownership, asynchronous or concurrent
lifetime, and applicable public, SPI, framework, serialization, immutability,
snapshot, and isolation contracts.
+- `List.copyOf`, `Map.copyOf`, `Set.copyOf`, `Collections.unmodifiable*`,
collection constructors that copy another collection, and equivalent copies or
wrappers are allowed only when the inspected evidence proves at least one of
the following allowed cases.
+ - An explicit existing contract requires immutable or snapshot semantics.
+ - A supported producer or consumer currently mutates an aliased collection
after handoff, and that mutation would violate behavior owned by the receiving
object.
+ - A supported path exposes owned mutable state, and an existing contract
forbids the consumer from mutating it.
+ - A supported asynchronous or concurrent path requires a stable snapshot.
+- A mutable collection implementation, or the theoretical ability of a caller
to mutate it, is not evidence.
+- When inspection finds no supported mutation path and no explicit contract,
pass, store, or return the original collection directly; remove every
task-introduced copy or wrapper and every task-introduced test that only
asserts immutability or rejected mutation.
+- When a copy or wrapper is allowed, verify that its null handling, iteration
order, duplicate semantics, aliasing, mutation visibility, exception behavior,
and time and space cost preserve the required behavior.
+
## Validation and Exceptions
-- Add runtime validation only at real external, public, persisted, parsed,
SPI, reflection, shared-state, or asynchronous boundaries, or for a concrete
diagnostic benefit. Do not recheck invariants guaranteed by callers or upstream
contracts.
+- Add runtime validation only when the defensive-code evidence gate proves
that it is required at a real external, public, persisted, parsed, SPI,
reflection, shared-state, or asynchronous boundary to preserve an existing
contract or provide a concrete diagnostic for a condition that can occur there.
Do not recheck invariants guaranteed by callers or upstream contracts.
- Prefer `ShardingSpherePreconditions` with lazy exception suppliers when the
module can use it and the resulting control flow preserves the required
exception type, message, timing, and cause.
- Keep a manual throw when the module cannot depend on `infra/exception`, the
code is inside `ShardingSpherePreconditions`, a caller-facing exception
contract requires it, or a precondition wrapper would obscure necessary control
flow. Do not replace manual throws mechanically, and record the concrete reason
for keeping one.
- When an edit removes the last checked-exception source from a private or
internal method, remove the stale `throws` declaration and update callers. Keep
checked exceptions on public or overridden methods only when a caller-facing,
framework, external API, or compatibility contract requires them. Never widen
to generic `Exception` or `Throwable`.
@@ -45,7 +69,7 @@ Apply this file to every production, test, script, or other
implementation artif
- Apply the `CODE_OF_CONDUCT.md` Lombok preference to touched boilerplate when
generated semantics are equivalent. Use narrow annotations; never use broad
annotations such as `@Data` unless every generated behavior is required. Before
replacing a public constructor or accessor, verify its generated signature,
access, parameter order, annotations, and reflection or serialization behavior.
Keep a manual member when Lombok would change or obscure logic, documentation,
validation, defaults, [...]
- Keep public API and SPI Javadocs required by the code of conduct. Beyond
that, document only caller or implementer obligations not expressed by code. Do
not restate names, signatures, visible collection properties, or inherited
contracts unless an override adds a new obligation.
- Keep declarations near first use. Do not mark local, loop, resource, or
lambda variables `final`; use `final` only for method, constructor, and `catch`
parameters when applicable.
-- Declare collections by the least-specific required contract. Do not copy or
wrap collections without an owned mutability, snapshot, isolation, or public
contract reason. Record the concrete reason for every explicit copy or wrapper.
Use `Collection` for common iteration, size, or emptiness operations; use
`List` only for positional, ordered, duplicate-preserving, or required API
semantics; use `Set` only for uniqueness or set semantics. Do not declare a
concrete collection type unless [...]
+- Declare collections by the least-specific required contract. Use
`Collection` for common iteration, size, or emptiness operations; use `List`
only for positional, ordered, duplicate-preserving, or required API semantics;
use `Set` only for uniqueness or set semantics. Do not declare a concrete
collection type unless its implementation-specific API is required. In tests,
create a mutable copy only when that instance is mutated or mutability is the
scenario.
- Add a YAML anchor only when aliases in the same file remove meaningful
duplication.
- Use repository-relative paths, configuration, or temporary directories in
code, tests, scripts, and Skills; never hard-code a local workspace path.
- Add the ASF license header to new source files and keep implementation
intent and reviewer-relevant rationale transparent.