Hard batch G0022-G0026: 5/5 accepted; budget floor, CDS checks, mutation check

- generator: budget floor (2x oracle activations, 3x calls), static checks for CDS
  $parameters and UNION annotation
- harness/mutation.py: deterministic mutants of the reference; hidden tests must fail
- G0022 revalidated with harness fixes: oracle 100, null 0
- results in docs/faz1-tasarim.md 11f

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-03 05:16:30 +02:00
parent 3570d7ef9b
commit 32f03fcad4
53 changed files with 2931 additions and 14 deletions

View File

@@ -49,8 +49,10 @@ Rules for the bundle:
- Method parameters need a complete type: "TYPE c LENGTH 4" is not allowed in a signature.
Declare a type first (TYPES ty_zone TYPE c LENGTH 4) and use it.
- Field names in tables and CDS views are not SQL reserved words (no HOURS, MODE, ORDER, DATE, COUNT ...).
- CDS: use "define view entity". Parameters have no default value. In a UNION, all branches have the same
key elements and element names. Hidden tests for a view with parameters pass all parameters.
- CDS: use "define view entity". Parameters have no default value. Use a parameter as
$parameters.p_name (not :p_name). In a UNION, all branches have the same
key elements and element names, and the view
has the annotation @Metadata.ignorePropagatedAnnotations: true. Hidden tests for a view with parameters pass all parameters.
- Legacy seed code (categories E, I) must activate on SAP_BASIS 816: do not mix old and new syntax in one
SQL statement (with new syntax, every host variable needs "@").
- The contract lists only the objects that the hidden tests call. Test classes are never in the contract.
@@ -178,6 +180,14 @@ def lint_files(b):
for f in re.findall(r"^\s*(?:key\s+)?(\w+)\s*:", src, re.I | re.M):
if f.upper() in RESERVED:
errs.append(f"{rel}: field name {f} is a reserved word; choose another name")
for rel, src in b.get("files", {}).items():
if rel.endswith(".asddls") and re.search(r"define\s+(root\s+)?view\s+entity", src, re.I):
if re.search(r"\bunion\b", src, re.I) and not re.search(r"@Metadata\.ignorePropagatedAnnotations\s*:\s*true",
src, re.I):
errs.append(f"{rel}: a view entity with UNION needs @Metadata.ignorePropagatedAnnotations: true")
for p in sorted(set(re.findall(r"[=<>(,]\s*:(\w+)|\bbetween\s+:(\w+)|\band\s+:(\w+)", src, re.I))):
name = next(x for x in p if x)
errs.append(f"{rel}: parameter :{name}; a view entity needs $parameters.{name}")
for k in ("seed", "reference"):
for o in t.get(k, []):
m = DDL_KIND.search(b.get("files", {}).get(o.get("file", ""), ""))
@@ -279,11 +289,23 @@ def dependency_order(objs, files):
return out
def floor_budget(task):
"""The model needs more calls than the oracle (reads, repairs). G0022: budget 12 activations,
reference alone 13. Minimum: 2 x oracle activations, 3 x oracle tool calls."""
ref = task.get("reference", [])
pushes = sum(bool(o.get("file")) + bool(o.get("testclasses_file")) for o in ref)
calls = len(ref) + pushes
bud = task.setdefault("budget", {})
bud["max_activations"] = max(int(bud.get("max_activations", 0)), 2 * pushes)
bud["max_tool_calls"] = max(int(bud.get("max_tool_calls", 0)), 3 * calls)
def write_bundle(b, task_dir, task_id):
os.makedirs(task_dir, exist_ok=True)
b["task"]["id"] = task_id
for k in ("seed", "reference"):
b["task"][k] = dependency_order(b["task"].get(k, []), b["files"])
floor_budget(b["task"])
json.dump(b["task"], open(os.path.join(task_dir, "task.json"), "w"), indent=2)
for rel, content in b["files"].items():
path = os.path.join(task_dir, rel)