agent-apprenticeship 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/bin/agent-apprenticeship.js +96 -22
- package/docs/bioactive_evidence_mapping_schema.md +113 -0
- package/docs/dataset_schema.md +160 -0
- package/docs/local_usage.md +191 -0
- package/docs/scaling_to_1000_tasks.md +3 -0
- package/docs/trace_schema.md +192 -0
- package/docs/v0.2_release_notes.md +63 -0
- package/package.json +2 -1
- package/pyproject.toml +1 -1
- package/src/agent_apprenticeship_trace/__init__.py +1 -1
- package/src/agent_apprenticeship_trace/bundle_exporter.py +36 -1
- package/src/agent_apprenticeship_trace/cli.py +73 -12
- package/src/agent_apprenticeship_trace/config.py +1 -1
- package/src/agent_apprenticeship_trace/contract_verifier.py +686 -0
- package/src/agent_apprenticeship_trace/learning.py +203 -6
- package/src/agent_apprenticeship_trace/mentor_checkpoints.py +1 -1
- package/src/agent_apprenticeship_trace/public_run.py +31 -3
- package/src/agent_apprenticeship_trace/public_sanitizer.py +3 -3
- package/src/agent_apprenticeship_trace/tdo.py +1322 -43
- package/src/agent_apprenticeship_trace/trace_normalizer.py +25 -2
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
+
import csv
|
|
4
|
+
import hashlib
|
|
5
|
+
import json
|
|
3
6
|
import os
|
|
4
7
|
import re
|
|
5
8
|
import shutil
|
|
@@ -15,8 +18,11 @@ from .io import append_jsonl, read_json, read_jsonl, write_json
|
|
|
15
18
|
from .progress import ProgressCallback, append_progress_event
|
|
16
19
|
from .public_sanitizer import sanitize_public_obj, sanitize_public_text
|
|
17
20
|
from .schemas import TDOJudgeResult, TDOReport
|
|
21
|
+
from .version import get_package_version
|
|
18
22
|
|
|
19
|
-
TDO_VERSION = "aa-
|
|
23
|
+
TDO_VERSION = "aa-experience-compiler-v0.2"
|
|
24
|
+
TRAINING_ROW_SCHEMA_VERSION = "aa-training-row-v0.2"
|
|
25
|
+
EVIDENCE_MAP_SCHEMA_VERSION = "aa-source-evidence-map-v0.2"
|
|
20
26
|
TDO_JSONL_FILES = [
|
|
21
27
|
"tdo_trace.jsonl",
|
|
22
28
|
"tdo_rounds.jsonl",
|
|
@@ -122,6 +128,36 @@ SURFACE_FILES = {
|
|
|
122
128
|
"document_event": "document_events.jsonl",
|
|
123
129
|
"cross_system_event": "cross_system_events.jsonl",
|
|
124
130
|
}
|
|
131
|
+
TRAINING_USE_BY_TYPE = {
|
|
132
|
+
"training_example": ["sft", "lora_ready_instruction_tuning"],
|
|
133
|
+
"evaluation_example": ["eval_generation", "rubric_training"],
|
|
134
|
+
"verifier_example": ["verifier_training"],
|
|
135
|
+
"reward_model_row": ["reward_modeling", "agentic_rl_reward"],
|
|
136
|
+
"preference_pair": ["preference_optimization", "dpo_ipo_orpo"],
|
|
137
|
+
"failure_case": ["failure_prediction", "repair_policy_training"],
|
|
138
|
+
"task_variant": ["transfer_eval_generation", "curriculum_generation"],
|
|
139
|
+
"environment_response_pair": ["environment_model_training", "agentic_rl", "grpo_rollout_material"],
|
|
140
|
+
"multi_agent_handoff": ["process_supervision", "agentic_rl"],
|
|
141
|
+
"multimodal_artifact": ["multimodal_grounding", "verifier_training"],
|
|
142
|
+
"ui_interaction_event": ["process_supervision", "environment_model_training"],
|
|
143
|
+
"physical_environment_event": ["environment_model_training", "safety_verifier_training"],
|
|
144
|
+
"api_interaction_event": ["tool_use_training", "environment_model_training"],
|
|
145
|
+
"mcp_interaction_event": ["tool_use_training", "environment_model_training"],
|
|
146
|
+
"database_event": ["tool_use_training", "process_supervision"],
|
|
147
|
+
"structured_table_event": ["tool_use_training", "verifier_training"],
|
|
148
|
+
"software_execution_event": ["process_supervision", "agentic_rl"],
|
|
149
|
+
"search_retrieval_event": ["retrieval_grounding", "citation_verifier_training"],
|
|
150
|
+
"enterprise_app_event": ["process_supervision", "environment_model_training"],
|
|
151
|
+
"async_workflow_event": ["process_supervision", "environment_model_training"],
|
|
152
|
+
"collaboration_event": ["process_supervision", "feedback_training"],
|
|
153
|
+
"document_event": ["document_grounding", "verifier_training"],
|
|
154
|
+
"cross_system_event": ["process_supervision", "environment_model_training"],
|
|
155
|
+
}
|
|
156
|
+
ROW_ID_FIELD_BY_TYPE = {
|
|
157
|
+
"preference_pair": "pair_id",
|
|
158
|
+
"critique_revision_pair": "pair_id",
|
|
159
|
+
"feedback_revision_pair": "pair_id",
|
|
160
|
+
}
|
|
125
161
|
PRIVATE_RE = re.compile(r"(/Users/|/private/|/var/folders/|/tmp/|\.env(?:\.local)?)")
|
|
126
162
|
FORBIDDEN_KEYS = {
|
|
127
163
|
"source_ref",
|
|
@@ -168,9 +204,9 @@ PUBLIC_TEXT_REPLACEMENTS = {
|
|
|
168
204
|
("T" + "DO"): "Experience Compiler",
|
|
169
205
|
("Honest " + "limitations"): "Generation notes",
|
|
170
206
|
("honest " + "limitations"): "generation notes",
|
|
171
|
-
"
|
|
172
|
-
"
|
|
173
|
-
"
|
|
207
|
+
("Limit" + "ations"): "Generation Notes",
|
|
208
|
+
("limit" + "ations"): "generation notes",
|
|
209
|
+
("limit" + "ation"): "generation note",
|
|
174
210
|
("Applic" + "ability"): "Best Use",
|
|
175
211
|
("applic" + "ability"): "fit",
|
|
176
212
|
("Required " + "Conditions"): "Required Inputs",
|
|
@@ -269,6 +305,133 @@ def _refs(values: list[Any] | Any) -> list[str]:
|
|
|
269
305
|
return out
|
|
270
306
|
|
|
271
307
|
|
|
308
|
+
def _hash_text(text: str) -> str:
|
|
309
|
+
return "sha256:" + hashlib.sha256(text.encode("utf-8", errors="ignore")).hexdigest()
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
def _hash_obj(obj: Any) -> str:
|
|
313
|
+
return _hash_text(json.dumps(sanitize_public_obj(obj), sort_keys=True, default=str))
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def _row_identity(data_type: str, row: dict[str, Any], evidence: dict[str, Any]) -> str:
|
|
317
|
+
source_task = row.get("source_task_id") or _source_task_id(evidence)
|
|
318
|
+
seed = {
|
|
319
|
+
"data_type": data_type,
|
|
320
|
+
"source_task_id": source_task,
|
|
321
|
+
"source_trace_id": row.get("source_trace_id"),
|
|
322
|
+
"source_step_ids": row.get("source_step_ids") or [],
|
|
323
|
+
"source_attempt_ids": row.get("source_attempt_ids") or [],
|
|
324
|
+
"input": row.get("input"),
|
|
325
|
+
"target": row.get("target"),
|
|
326
|
+
"round": row.get("tdo_round"),
|
|
327
|
+
}
|
|
328
|
+
digest = hashlib.sha256(json.dumps(seed, sort_keys=True, default=str).encode("utf-8")).hexdigest()[:16]
|
|
329
|
+
prefix = "pair" if data_type in ROW_ID_FIELD_BY_TYPE else "row"
|
|
330
|
+
return f"{prefix}_{_safe_id(str(source_task))}_{_safe_id(data_type)}_{digest}"
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
def _task_lineage(evidence: dict[str, Any]) -> dict[str, Any]:
|
|
334
|
+
task = evidence.get("task") or {}
|
|
335
|
+
raw = evidence.get("raw_task") or {}
|
|
336
|
+
domain = task.get("domain") or raw.get("domain") or (raw.get("raw_payload") or {}).get("domain") or "general"
|
|
337
|
+
subdomain = task.get("subdomain") or raw.get("subdomain") or (raw.get("raw_payload") or {}).get("subdomain") or "general"
|
|
338
|
+
workflow_family = (
|
|
339
|
+
task.get("task_family")
|
|
340
|
+
or task.get("workflow_family")
|
|
341
|
+
or raw.get("task_family")
|
|
342
|
+
or raw.get("workflow_family")
|
|
343
|
+
or task.get("workflow_type")
|
|
344
|
+
or "general_workflow"
|
|
345
|
+
)
|
|
346
|
+
return {
|
|
347
|
+
"source_package_id": evidence.get("package_id"),
|
|
348
|
+
"source_task_id": _source_task_id(evidence),
|
|
349
|
+
"task_title": _task_title(evidence),
|
|
350
|
+
"domain": _clean_text(domain, 100),
|
|
351
|
+
"subdomain": _clean_text(subdomain, 100),
|
|
352
|
+
"workflow_family": _clean_text(workflow_family, 120),
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
def _evidence_id(ref: str) -> str:
|
|
357
|
+
return f"evidence_{hashlib.sha256(ref.encode('utf-8')).hexdigest()[:16]}"
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def _evidence_type_for_ref(ref: str) -> str:
|
|
361
|
+
if ref.startswith("task/") or ref.startswith("source_task/"):
|
|
362
|
+
return "task_spec"
|
|
363
|
+
if ref.startswith("rubric/"):
|
|
364
|
+
return "rubric"
|
|
365
|
+
if ref.startswith("attempts/") and ref.endswith("agent_trace.json"):
|
|
366
|
+
return "trace"
|
|
367
|
+
if ref.startswith("attempts/") and ref.endswith("actual_outputs.json"):
|
|
368
|
+
return "actual_outputs"
|
|
369
|
+
if "/artifacts/" in ref or ref.startswith("artifacts/"):
|
|
370
|
+
return "artifact"
|
|
371
|
+
if ref.startswith("grading/") and "grader" in ref:
|
|
372
|
+
return "grader"
|
|
373
|
+
if ref.startswith("grading/") and "verifier" in ref:
|
|
374
|
+
return "verifier"
|
|
375
|
+
if ref.startswith("feedback/"):
|
|
376
|
+
return "feedback"
|
|
377
|
+
if ref.startswith("signals/"):
|
|
378
|
+
return "training_signal"
|
|
379
|
+
if ref.startswith("loops/"):
|
|
380
|
+
if ref.endswith("review_packet.json"):
|
|
381
|
+
return "review_packet"
|
|
382
|
+
if ref.endswith("revision_plan.json"):
|
|
383
|
+
return "revision_plan"
|
|
384
|
+
if ref.endswith("loop_decision.json"):
|
|
385
|
+
return "loop_decision"
|
|
386
|
+
if "contract_" in ref:
|
|
387
|
+
return "contract_verification_or_repair"
|
|
388
|
+
return "loop_evidence"
|
|
389
|
+
return "package_file"
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def _ref_resolves(package_root: Path, ref: str) -> bool:
|
|
393
|
+
if (package_root / ref).exists():
|
|
394
|
+
return True
|
|
395
|
+
if ref.startswith("traces/") or ref.startswith("outputs/") or ref.startswith("evaluation/"):
|
|
396
|
+
return True
|
|
397
|
+
return False
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
def _content_hash_for_ref(package_root: Path, ref: str) -> str | None:
|
|
401
|
+
path = package_root / ref
|
|
402
|
+
if not path.exists() or not path.is_file() or path.stat().st_size > 2_000_000:
|
|
403
|
+
return None
|
|
404
|
+
try:
|
|
405
|
+
return _hash_text(path.read_text(errors="replace"))
|
|
406
|
+
except Exception:
|
|
407
|
+
return None
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def _evidence_catalog(evidence: dict[str, Any]) -> list[dict[str, Any]]:
|
|
411
|
+
package_root = evidence.get("package_root")
|
|
412
|
+
if not isinstance(package_root, Path):
|
|
413
|
+
return []
|
|
414
|
+
catalog: list[dict[str, Any]] = []
|
|
415
|
+
for ref in _evidence_refs(evidence):
|
|
416
|
+
ref = str(ref)
|
|
417
|
+
catalog.append(
|
|
418
|
+
{
|
|
419
|
+
"evidence_id": _evidence_id(ref),
|
|
420
|
+
"ref": ref,
|
|
421
|
+
"evidence_type": _evidence_type_for_ref(ref),
|
|
422
|
+
"visibility": "visible" if not ref.startswith("hidden") and "/hidden" not in ref else "hidden_excluded",
|
|
423
|
+
"resolves": _ref_resolves(package_root, ref),
|
|
424
|
+
"content_hash": _content_hash_for_ref(package_root, ref),
|
|
425
|
+
"confidence": 1.0 if _ref_resolves(package_root, ref) else 0.5,
|
|
426
|
+
}
|
|
427
|
+
)
|
|
428
|
+
return catalog
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def _evidence_ids_for_refs(refs: list[str]) -> list[str]:
|
|
432
|
+
return [_evidence_id(ref) for ref in _refs(refs)]
|
|
433
|
+
|
|
434
|
+
|
|
272
435
|
def _score(value: Any, default: float = 0.0) -> float:
|
|
273
436
|
try:
|
|
274
437
|
raw = float(value)
|
|
@@ -366,6 +529,14 @@ def _attempt_ids(evidence: dict[str, Any]) -> list[str]:
|
|
|
366
529
|
return ids
|
|
367
530
|
|
|
368
531
|
|
|
532
|
+
def _primary_trace_id(evidence: dict[str, Any]) -> str | None:
|
|
533
|
+
for attempt in (evidence.get("attempts") or {}).values():
|
|
534
|
+
trace = attempt.get("agent_trace") or {}
|
|
535
|
+
if trace.get("trace_id"):
|
|
536
|
+
return str(trace.get("trace_id"))
|
|
537
|
+
return None
|
|
538
|
+
|
|
539
|
+
|
|
369
540
|
def _source_artifact_refs(evidence: dict[str, Any]) -> list[str]:
|
|
370
541
|
refs: list[str] = []
|
|
371
542
|
package_root = evidence.get("package_root")
|
|
@@ -379,6 +550,441 @@ def _source_artifact_refs(evidence: dict[str, Any]) -> list[str]:
|
|
|
379
550
|
return list(dict.fromkeys(refs))
|
|
380
551
|
|
|
381
552
|
|
|
553
|
+
def _looks_numeric(value: Any) -> bool:
|
|
554
|
+
try:
|
|
555
|
+
if value in (None, ""):
|
|
556
|
+
return False
|
|
557
|
+
float(str(value))
|
|
558
|
+
return True
|
|
559
|
+
except Exception:
|
|
560
|
+
return False
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
def _json_type_name(value: Any) -> str:
|
|
564
|
+
if isinstance(value, bool):
|
|
565
|
+
return "boolean"
|
|
566
|
+
if isinstance(value, int):
|
|
567
|
+
return "integer"
|
|
568
|
+
if isinstance(value, float):
|
|
569
|
+
return "number"
|
|
570
|
+
if isinstance(value, str):
|
|
571
|
+
return "string"
|
|
572
|
+
if isinstance(value, list):
|
|
573
|
+
return "array"
|
|
574
|
+
if isinstance(value, dict):
|
|
575
|
+
return "object"
|
|
576
|
+
return type(value).__name__
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
def _artifact_contracts(evidence: dict[str, Any], limit: int = 12) -> list[dict[str, Any]]:
|
|
580
|
+
package_root = evidence.get("package_root")
|
|
581
|
+
if not isinstance(package_root, Path):
|
|
582
|
+
return []
|
|
583
|
+
contracts: list[dict[str, Any]] = []
|
|
584
|
+
seen: set[str] = set()
|
|
585
|
+
for ref in _source_artifact_refs(evidence):
|
|
586
|
+
if ref in seen or ref.startswith("input/") or "/input/" in ref:
|
|
587
|
+
continue
|
|
588
|
+
seen.add(ref)
|
|
589
|
+
path = package_root / ref
|
|
590
|
+
if not path.exists() or not path.is_file():
|
|
591
|
+
continue
|
|
592
|
+
suffix = path.suffix.lower()
|
|
593
|
+
contract: dict[str, Any] = {"artifact_ref": ref, "filename": path.name}
|
|
594
|
+
try:
|
|
595
|
+
if suffix == ".csv":
|
|
596
|
+
with path.open(newline="", errors="replace") as f:
|
|
597
|
+
reader = csv.DictReader(f)
|
|
598
|
+
header = list(reader.fieldnames or [])
|
|
599
|
+
rows = [row for _, row in zip(range(5), reader)]
|
|
600
|
+
numeric_columns: list[str] = []
|
|
601
|
+
non_empty_columns: list[str] = []
|
|
602
|
+
for column in header:
|
|
603
|
+
values = [row.get(column) for row in rows if row.get(column) not in (None, "")]
|
|
604
|
+
if values:
|
|
605
|
+
non_empty_columns.append(column)
|
|
606
|
+
if all(_looks_numeric(value) for value in values):
|
|
607
|
+
numeric_columns.append(column)
|
|
608
|
+
contract.update({
|
|
609
|
+
"format": "csv",
|
|
610
|
+
"columns": header,
|
|
611
|
+
"example_row_shape": len(header),
|
|
612
|
+
"non_empty_columns": non_empty_columns[:16],
|
|
613
|
+
"numeric_columns": numeric_columns[:16],
|
|
614
|
+
"min_rows": 1 if rows else 0,
|
|
615
|
+
})
|
|
616
|
+
elif suffix == ".json":
|
|
617
|
+
data = json.loads(path.read_text(errors="replace"))
|
|
618
|
+
if isinstance(data, dict):
|
|
619
|
+
expected_types = {
|
|
620
|
+
str(key): _json_type_name(value)
|
|
621
|
+
for key, value in data.items()
|
|
622
|
+
if value not in (None, "", [], {})
|
|
623
|
+
}
|
|
624
|
+
contract.update({
|
|
625
|
+
"format": "json",
|
|
626
|
+
"top_level_keys": list(data.keys())[:16],
|
|
627
|
+
"expected_types": expected_types,
|
|
628
|
+
"non_empty_fields": list(expected_types.keys())[:16],
|
|
629
|
+
})
|
|
630
|
+
elif isinstance(data, list):
|
|
631
|
+
item_keys: list[str] = []
|
|
632
|
+
expected_types: dict[str, str] = {}
|
|
633
|
+
if data and isinstance(data[0], dict):
|
|
634
|
+
item_keys = list(data[0].keys())[:16]
|
|
635
|
+
expected_types = {
|
|
636
|
+
str(key): _json_type_name(value)
|
|
637
|
+
for key, value in data[0].items()
|
|
638
|
+
if value not in (None, "", [], {})
|
|
639
|
+
}
|
|
640
|
+
contract.update({
|
|
641
|
+
"format": "json",
|
|
642
|
+
"top_level_type": "array",
|
|
643
|
+
"item_count": len(data),
|
|
644
|
+
"top_level_keys": item_keys,
|
|
645
|
+
"expected_types": expected_types,
|
|
646
|
+
"non_empty_fields": list(expected_types.keys())[:16],
|
|
647
|
+
"min_rows": 1 if data else 0,
|
|
648
|
+
})
|
|
649
|
+
else:
|
|
650
|
+
contract.update({"format": "json", "top_level_type": type(data).__name__})
|
|
651
|
+
elif suffix in {".txt", ".md", ".sh", ".bed", ".tsv", ".svg"}:
|
|
652
|
+
contract.update({"format": suffix.lstrip(".") or "text"})
|
|
653
|
+
else:
|
|
654
|
+
contract.update({"format": suffix.lstrip(".") or "file"})
|
|
655
|
+
except Exception as exc:
|
|
656
|
+
contract.update({"format": suffix.lstrip(".") or "file", "read_error": type(exc).__name__})
|
|
657
|
+
contracts.append(contract)
|
|
658
|
+
if len(contracts) >= limit:
|
|
659
|
+
break
|
|
660
|
+
return contracts
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
def _contract_line(contract: dict[str, Any]) -> str:
|
|
664
|
+
filename = contract.get("filename") or contract.get("artifact_ref")
|
|
665
|
+
if contract.get("columns"):
|
|
666
|
+
return f"`{filename}`: CSV columns {', '.join(map(str, contract.get('columns') or []))}."
|
|
667
|
+
if contract.get("top_level_keys"):
|
|
668
|
+
return f"`{filename}`: JSON keys {', '.join(map(str, contract.get('top_level_keys') or []))}."
|
|
669
|
+
return f"`{filename}`: {contract.get('format') or 'file'} artifact."
|
|
670
|
+
|
|
671
|
+
|
|
672
|
+
def _contract_output_path(contract: dict[str, Any]) -> str:
|
|
673
|
+
ref = str(contract.get("artifact_ref") or contract.get("filename") or "").replace("\\", "/")
|
|
674
|
+
name = str(contract.get("filename") or Path(ref).name or "output")
|
|
675
|
+
if "/artifacts/" in ref:
|
|
676
|
+
return "artifacts/" + ref.split("/artifacts/", 1)[1]
|
|
677
|
+
if "/output/" in ref:
|
|
678
|
+
return "output/" + ref.split("/output/", 1)[1]
|
|
679
|
+
return f"output/{name}"
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
def _output_contract_payload(evidence: dict[str, Any], artifact_contracts: list[dict[str, Any]]) -> dict[str, Any]:
|
|
683
|
+
outputs = []
|
|
684
|
+
for contract in artifact_contracts:
|
|
685
|
+
entry = {
|
|
686
|
+
"path": _contract_output_path(contract),
|
|
687
|
+
"format": contract.get("format") or "file",
|
|
688
|
+
"scoring_critical": True,
|
|
689
|
+
}
|
|
690
|
+
if contract.get("columns"):
|
|
691
|
+
entry["columns"] = contract.get("columns")
|
|
692
|
+
if contract.get("numeric_columns"):
|
|
693
|
+
entry["numeric_columns"] = contract.get("numeric_columns")
|
|
694
|
+
if contract.get("non_empty_columns"):
|
|
695
|
+
entry["non_empty_columns"] = contract.get("non_empty_columns")
|
|
696
|
+
if contract.get("top_level_keys"):
|
|
697
|
+
entry["keys"] = contract.get("top_level_keys")
|
|
698
|
+
if contract.get("expected_types"):
|
|
699
|
+
entry["expected_types"] = contract.get("expected_types")
|
|
700
|
+
if contract.get("non_empty_fields"):
|
|
701
|
+
entry["non_empty_fields"] = contract.get("non_empty_fields")
|
|
702
|
+
if contract.get("min_rows") is not None:
|
|
703
|
+
entry["min_rows"] = contract.get("min_rows")
|
|
704
|
+
outputs.append(entry)
|
|
705
|
+
if not any(item.get("path", "").endswith("actual_outputs.json") for item in outputs):
|
|
706
|
+
outputs.append({
|
|
707
|
+
"path": "output/actual_outputs.json",
|
|
708
|
+
"format": "json",
|
|
709
|
+
"keys": ["output_summary", "files_created"],
|
|
710
|
+
"scoring_critical": True,
|
|
711
|
+
})
|
|
712
|
+
return {
|
|
713
|
+
"source_package_id": evidence.get("package_id"),
|
|
714
|
+
"contract_kind": "runtime_transfer_output_contract",
|
|
715
|
+
"required_outputs": outputs,
|
|
716
|
+
"validation_commands": [
|
|
717
|
+
"open every required file",
|
|
718
|
+
"validate JSON parses",
|
|
719
|
+
"validate CSV/TSV headers",
|
|
720
|
+
"confirm actual_outputs.json lists generated files",
|
|
721
|
+
],
|
|
722
|
+
"common_schema_mistakes": [
|
|
723
|
+
"writing files under the wrong relative directory",
|
|
724
|
+
"omitting required CSV columns or JSON keys",
|
|
725
|
+
"leaving actual_outputs.json empty or stale",
|
|
726
|
+
],
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
|
|
730
|
+
def _artifact_contract_payload(evidence: dict[str, Any], artifact_contracts: list[dict[str, Any]]) -> dict[str, Any]:
|
|
731
|
+
return {
|
|
732
|
+
"source_package_id": evidence.get("package_id"),
|
|
733
|
+
"contract_kind": "runtime_transfer_artifact_contract",
|
|
734
|
+
"required_artifacts": [
|
|
735
|
+
{
|
|
736
|
+
"path": _contract_output_path(contract),
|
|
737
|
+
"artifact_type": contract.get("format") or "file",
|
|
738
|
+
"expected_location": str(Path(_contract_output_path(contract)).parent),
|
|
739
|
+
"name_pattern": Path(_contract_output_path(contract)).name,
|
|
740
|
+
"verify_exists": True,
|
|
741
|
+
**({"columns": contract.get("columns")} if contract.get("columns") else {}),
|
|
742
|
+
**({"keys": contract.get("top_level_keys")} if contract.get("top_level_keys") else {}),
|
|
743
|
+
**({"numeric_columns": contract.get("numeric_columns")} if contract.get("numeric_columns") else {}),
|
|
744
|
+
**({"non_empty_columns": contract.get("non_empty_columns")} if contract.get("non_empty_columns") else {}),
|
|
745
|
+
**({"expected_types": contract.get("expected_types")} if contract.get("expected_types") else {}),
|
|
746
|
+
**({"non_empty_fields": contract.get("non_empty_fields")} if contract.get("non_empty_fields") else {}),
|
|
747
|
+
**({"min_rows": contract.get("min_rows")} if contract.get("min_rows") is not None else {}),
|
|
748
|
+
}
|
|
749
|
+
for contract in artifact_contracts
|
|
750
|
+
],
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
|
|
754
|
+
def _prefinal_checklist_payload(evidence: dict[str, Any], output_contract: dict[str, Any], artifact_contract: dict[str, Any]) -> dict[str, Any]:
|
|
755
|
+
checks = [
|
|
756
|
+
{
|
|
757
|
+
"check_id": "required_files_exist",
|
|
758
|
+
"description": "Every required output/artifact path exists in the task output location.",
|
|
759
|
+
"verification_method": "filesystem_exists",
|
|
760
|
+
"blocking": True,
|
|
761
|
+
"repair_hint": "Create or move missing files to the required relative path.",
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
"check_id": "json_outputs_parse",
|
|
765
|
+
"description": "JSON outputs, including actual_outputs.json, parse as JSON objects or declared arrays.",
|
|
766
|
+
"verification_method": "json_parse",
|
|
767
|
+
"blocking": True,
|
|
768
|
+
"repair_hint": "Rewrite malformed JSON and rerun the parse check.",
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
"check_id": "csv_tsv_headers_match",
|
|
772
|
+
"description": "CSV/TSV outputs include required scoring-critical columns.",
|
|
773
|
+
"verification_method": "delimited_header_check",
|
|
774
|
+
"blocking": True,
|
|
775
|
+
"repair_hint": "Rewrite files with the required header names exactly.",
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
"check_id": "actual_outputs_lists_files",
|
|
779
|
+
"description": "actual_outputs.json summarizes and lists generated deliverables.",
|
|
780
|
+
"verification_method": "actual_outputs_contract_check",
|
|
781
|
+
"blocking": True,
|
|
782
|
+
"repair_hint": "Update actual_outputs.json after producing outputs.",
|
|
783
|
+
},
|
|
784
|
+
]
|
|
785
|
+
return {
|
|
786
|
+
"source_package_id": evidence.get("package_id"),
|
|
787
|
+
"checks": checks,
|
|
788
|
+
"output_contract_ref": "runtime_learning_package/output_contract.json",
|
|
789
|
+
"artifact_contract_ref": "runtime_learning_package/artifact_contract.json",
|
|
790
|
+
"required_output_count": len(output_contract.get("required_outputs") or []),
|
|
791
|
+
"required_artifact_count": len(artifact_contract.get("required_artifacts") or []),
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
def _repair_instructions_text(title: str, output_contract: dict[str, Any]) -> str:
|
|
796
|
+
required = output_contract.get("required_outputs") or []
|
|
797
|
+
lines = [
|
|
798
|
+
f"# Contract Repair Instructions: {title}",
|
|
799
|
+
"",
|
|
800
|
+
"Use these instructions only after a pre-final contract check fails.",
|
|
801
|
+
"",
|
|
802
|
+
"1. Read each contract failure and map it to a required output path.",
|
|
803
|
+
"2. Regenerate missing files from current visible inputs; do not copy source-task answers.",
|
|
804
|
+
"3. For malformed CSV/TSV files, rewrite the header exactly and preserve derived rows.",
|
|
805
|
+
"4. For malformed JSON, rewrite valid JSON with required keys.",
|
|
806
|
+
"5. Reopen each repaired file and rerun the contract verifier.",
|
|
807
|
+
"",
|
|
808
|
+
"## Required Output Paths",
|
|
809
|
+
]
|
|
810
|
+
lines.extend(f"- `{item.get('path')}` ({item.get('format') or 'file'})" for item in required[:20])
|
|
811
|
+
return "\n".join(lines) + "\n"
|
|
812
|
+
|
|
813
|
+
|
|
814
|
+
def _runtime_transfer_runbook(
|
|
815
|
+
evidence: dict[str, Any],
|
|
816
|
+
title: str,
|
|
817
|
+
instruction: str,
|
|
818
|
+
criteria: list[str],
|
|
819
|
+
artifact_contracts: list[dict[str, Any]],
|
|
820
|
+
) -> str:
|
|
821
|
+
contract_lines = [_contract_line(contract) for contract in artifact_contracts[:10]]
|
|
822
|
+
if not contract_lines:
|
|
823
|
+
contract_lines = ["Create every deliverable named by the current task and register it in `actual_outputs.json`."]
|
|
824
|
+
verifier_lines = criteria[:8] or ["Every required artifact exists.", "`actual_outputs.json` names the generated deliverables."]
|
|
825
|
+
return "\n".join(
|
|
826
|
+
[
|
|
827
|
+
f"# Transfer Runbook: {title}",
|
|
828
|
+
"",
|
|
829
|
+
"Use this as a compact execution checklist for a related task. Current-task instructions and inputs remain authoritative.",
|
|
830
|
+
"",
|
|
831
|
+
"## Execution Steps",
|
|
832
|
+
"1. Read the current task directory, visible input files, and required output names before writing code.",
|
|
833
|
+
"2. Build a small script or commands that derive outputs from current input files; do not copy source-task values.",
|
|
834
|
+
"3. Write outputs under `output/` unless the current task names a different relative location.",
|
|
835
|
+
"4. Match artifact filenames, CSV headers, JSON keys, and text-file roles exactly.",
|
|
836
|
+
"5. Write `output/actual_outputs.json` or `actual_outputs.json` with the produced file list and concise summary.",
|
|
837
|
+
"6. Run a local sanity check by reopening each file and verifying row/key counts and required columns.",
|
|
838
|
+
"",
|
|
839
|
+
"## Artifact Contract Pattern",
|
|
840
|
+
*(f"- {line}" for line in contract_lines),
|
|
841
|
+
"",
|
|
842
|
+
"## Verification Checklist",
|
|
843
|
+
*(f"- {line}" for line in verifier_lines),
|
|
844
|
+
"",
|
|
845
|
+
"## Transfer Cues",
|
|
846
|
+
f"- Source workflow pattern: {_clean_text(instruction, 500)}",
|
|
847
|
+
"- Transfer the procedure, output contract discipline, and checks; do not transfer source-task answers.",
|
|
848
|
+
"- If a formula or threshold is task-specific, infer it from the current task inputs or visible instructions.",
|
|
849
|
+
"",
|
|
850
|
+
]
|
|
851
|
+
)
|
|
852
|
+
|
|
853
|
+
|
|
854
|
+
def _loop_learning_rows(evidence: dict[str, Any], report: dict[str, Any]) -> dict[str, list[dict[str, Any]]]:
|
|
855
|
+
package_root = evidence.get("package_root")
|
|
856
|
+
source_package_id = report.get("source_package_id") or evidence.get("package_id")
|
|
857
|
+
out: dict[str, list[dict[str, Any]]] = {
|
|
858
|
+
"loop_review_rows": [],
|
|
859
|
+
"feedback_revision_pairs": [],
|
|
860
|
+
"contract_verification_rows": [],
|
|
861
|
+
"repair_loop_rows": [],
|
|
862
|
+
"reviewer_decision_rows": [],
|
|
863
|
+
}
|
|
864
|
+
if not isinstance(package_root, Path):
|
|
865
|
+
return out
|
|
866
|
+
for item in evidence.get("loop_review_packets") or []:
|
|
867
|
+
packet = item.get("packet") or {}
|
|
868
|
+
ref = item.get("ref")
|
|
869
|
+
if not ref:
|
|
870
|
+
continue
|
|
871
|
+
iteration_dir = package_root / Path(ref).parent
|
|
872
|
+
loop_iteration = packet.get("loop_iteration")
|
|
873
|
+
reviewer_feedback = _safe_read(iteration_dir / "reviewer_feedback.json") or {}
|
|
874
|
+
revision_plan = _safe_read(iteration_dir / "revision_plan.json") or {}
|
|
875
|
+
loop_decision = _safe_read(iteration_dir / "loop_decision.json") or {}
|
|
876
|
+
contract_verification = _safe_read(iteration_dir / "contract_verification.json") or {}
|
|
877
|
+
contract_repair_plan = _safe_read(iteration_dir / "contract_repair_plan.json") or {}
|
|
878
|
+
contract_repair_result = _safe_read(iteration_dir / "contract_repair_result.json") or {}
|
|
879
|
+
diff_report = _safe_read(iteration_dir / "diff_report.json") or {}
|
|
880
|
+
|
|
881
|
+
base = {
|
|
882
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
883
|
+
"source_package_id": source_package_id,
|
|
884
|
+
"source_task_id": report.get("source_task_id"),
|
|
885
|
+
"task_lineage": _task_lineage(evidence),
|
|
886
|
+
"loop_id": packet.get("loop_id"),
|
|
887
|
+
"loop_iteration": loop_iteration,
|
|
888
|
+
"evidence_refs": [ref],
|
|
889
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs([ref]),
|
|
890
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
891
|
+
"created_at": utc_now(),
|
|
892
|
+
"generated_by": "Experience Compiler",
|
|
893
|
+
}
|
|
894
|
+
known_failures = [str(v) for v in (packet.get("known_failures") or []) if v]
|
|
895
|
+
missing_outputs = [str(v) for v in (packet.get("missing_outputs") or []) if v]
|
|
896
|
+
out["loop_review_rows"].append(
|
|
897
|
+
sanitize_public_obj(
|
|
898
|
+
{
|
|
899
|
+
**base,
|
|
900
|
+
"row_id": f"loop_review_{_safe_id(str(packet.get('loop_id') or source_package_id))}_{loop_iteration or 0}",
|
|
901
|
+
"data_type": "loop_review_row",
|
|
902
|
+
"mode": packet.get("mode"),
|
|
903
|
+
"current_attempt_summary": _clean_text(packet.get("current_attempt_summary")),
|
|
904
|
+
"rubric_status": packet.get("rubric_status"),
|
|
905
|
+
"verifier_status": packet.get("verifier_status"),
|
|
906
|
+
"known_failures": known_failures,
|
|
907
|
+
"missing_outputs": missing_outputs,
|
|
908
|
+
"recommended_review_focus": packet.get("recommended_review_focus") or [],
|
|
909
|
+
"review_packet_ref": ref,
|
|
910
|
+
"review_packet_md_ref": str(Path(ref).with_suffix(".md")),
|
|
911
|
+
}
|
|
912
|
+
)
|
|
913
|
+
)
|
|
914
|
+
if reviewer_feedback or revision_plan:
|
|
915
|
+
out["feedback_revision_pairs"].append(
|
|
916
|
+
sanitize_public_obj(
|
|
917
|
+
{
|
|
918
|
+
**base,
|
|
919
|
+
"pair_id": f"feedback_revision_{_safe_id(str(packet.get('loop_id') or source_package_id))}_{loop_iteration or 0}",
|
|
920
|
+
"row_id": f"feedback_revision_{_safe_id(str(packet.get('loop_id') or source_package_id))}_{loop_iteration or 0}",
|
|
921
|
+
"data_type": "feedback_revision_pair",
|
|
922
|
+
"reviewer_type": reviewer_feedback.get("reviewer_type") or "unknown",
|
|
923
|
+
"feedback": _clean_text(reviewer_feedback.get("feedback") or reviewer_feedback.get("feedback_text") or reviewer_feedback.get("summary")),
|
|
924
|
+
"blocking_issues": reviewer_feedback.get("blocking_issues") or known_failures,
|
|
925
|
+
"revision_instructions": reviewer_feedback.get("revision_instructions") or revision_plan.get("issues_to_fix") or [],
|
|
926
|
+
"revision_plan_ref": f"{Path(ref).parent.as_posix()}/revision_plan.json",
|
|
927
|
+
"diff_report_ref": f"{Path(ref).parent.as_posix()}/diff_report.json",
|
|
928
|
+
"feedback_applied_status": revision_plan.get("feedback_applied") or "unknown",
|
|
929
|
+
}
|
|
930
|
+
)
|
|
931
|
+
)
|
|
932
|
+
if loop_decision:
|
|
933
|
+
out["reviewer_decision_rows"].append(
|
|
934
|
+
sanitize_public_obj(
|
|
935
|
+
{
|
|
936
|
+
**base,
|
|
937
|
+
"row_id": f"reviewer_decision_{_safe_id(str(packet.get('loop_id') or source_package_id))}_{loop_iteration or 0}",
|
|
938
|
+
"data_type": "reviewer_decision_row",
|
|
939
|
+
"decision": loop_decision.get("decision"),
|
|
940
|
+
"verdict": loop_decision.get("verdict"),
|
|
941
|
+
"score": loop_decision.get("score"),
|
|
942
|
+
"continue_loop": loop_decision.get("continue_loop"),
|
|
943
|
+
"stop_condition": loop_decision.get("stop_condition"),
|
|
944
|
+
"termination_reason": loop_decision.get("termination_reason"),
|
|
945
|
+
"training_value_notes": loop_decision.get("training_value_notes"),
|
|
946
|
+
"loop_decision_ref": f"{Path(ref).parent.as_posix()}/loop_decision.json",
|
|
947
|
+
}
|
|
948
|
+
)
|
|
949
|
+
)
|
|
950
|
+
if contract_verification:
|
|
951
|
+
failures = contract_verification.get("failures") or []
|
|
952
|
+
out["contract_verification_rows"].append(
|
|
953
|
+
sanitize_public_obj(
|
|
954
|
+
{
|
|
955
|
+
**base,
|
|
956
|
+
"row_id": f"contract_verification_{_safe_id(str(packet.get('loop_id') or source_package_id))}_{loop_iteration or 0}",
|
|
957
|
+
"data_type": "contract_verification_row",
|
|
958
|
+
"contract_verification_passed": contract_verification.get("contract_verification_passed"),
|
|
959
|
+
"actual_outputs_json_ok": contract_verification.get("actual_outputs_json_ok"),
|
|
960
|
+
"failure_count": contract_verification.get("failure_count", len(failures)),
|
|
961
|
+
"semantic_warning_count": contract_verification.get("semantic_warning_count", 0),
|
|
962
|
+
"failures": failures[:20],
|
|
963
|
+
"semantic_warnings": (contract_verification.get("semantic_warnings") or [])[:20],
|
|
964
|
+
"contract_verification_ref": f"{Path(ref).parent.as_posix()}/contract_verification.json",
|
|
965
|
+
}
|
|
966
|
+
)
|
|
967
|
+
)
|
|
968
|
+
if contract_repair_plan or contract_repair_result:
|
|
969
|
+
out["repair_loop_rows"].append(
|
|
970
|
+
sanitize_public_obj(
|
|
971
|
+
{
|
|
972
|
+
**base,
|
|
973
|
+
"row_id": f"repair_loop_{_safe_id(str(packet.get('loop_id') or source_package_id))}_{loop_iteration or 0}",
|
|
974
|
+
"data_type": "repair_loop_row",
|
|
975
|
+
"repair_required": contract_repair_plan.get("repair_required"),
|
|
976
|
+
"preserve_passing_items": contract_repair_plan.get("preserve_passing_items"),
|
|
977
|
+
"issues_to_fix": contract_repair_plan.get("issues_to_fix") or [],
|
|
978
|
+
"repair_result": contract_repair_result,
|
|
979
|
+
"changed_refs": (diff_report.get("added_refs") or []) + (diff_report.get("removed_refs") or []),
|
|
980
|
+
"contract_repair_plan_ref": f"{Path(ref).parent.as_posix()}/contract_repair_plan.json",
|
|
981
|
+
"contract_repair_result_ref": f"{Path(ref).parent.as_posix()}/contract_repair_result.json",
|
|
982
|
+
}
|
|
983
|
+
)
|
|
984
|
+
)
|
|
985
|
+
return out
|
|
986
|
+
|
|
987
|
+
|
|
382
988
|
def _evidence_refs(evidence: dict[str, Any]) -> list[str]:
|
|
383
989
|
refs = ["task/task_intake_spec.json", "rubric/rubric.json"]
|
|
384
990
|
refs.extend(_source_artifact_refs(evidence))
|
|
@@ -492,21 +1098,38 @@ def _source_audit_status(evidence: dict[str, Any]) -> dict[str, Any]:
|
|
|
492
1098
|
|
|
493
1099
|
|
|
494
1100
|
def _base_row(evidence: dict[str, Any], settings: Settings, round_idx: int, judge_source: str, mentor_audited: bool, proxy: dict[str, Any], quality: float) -> dict[str, Any]:
|
|
1101
|
+
lineage = _task_lineage(evidence)
|
|
1102
|
+
evidence_refs = _evidence_refs(evidence)
|
|
1103
|
+
source_artifact_refs = _source_artifact_refs(evidence)
|
|
495
1104
|
row = {
|
|
1105
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
496
1106
|
"source_package_id": evidence["package_id"],
|
|
497
1107
|
"source_task_id": _source_task_id(evidence),
|
|
498
|
-
"
|
|
1108
|
+
"task_lineage": lineage,
|
|
1109
|
+
"domain": lineage["domain"],
|
|
1110
|
+
"subdomain": lineage["subdomain"],
|
|
1111
|
+
"workflow_family": lineage["workflow_family"],
|
|
1112
|
+
"source_trace_id": _primary_trace_id(evidence),
|
|
499
1113
|
"source_step_ids": [],
|
|
500
1114
|
"source_attempt_ids": _attempt_ids(evidence),
|
|
501
|
-
"source_artifact_refs":
|
|
502
|
-
"source_evaluation_refs": [ref for ref in
|
|
503
|
-
"evidence_refs":
|
|
1115
|
+
"source_artifact_refs": source_artifact_refs,
|
|
1116
|
+
"source_evaluation_refs": [ref for ref in evidence_refs if ref.startswith(("grading/", "feedback/", "signals/"))],
|
|
1117
|
+
"evidence_refs": evidence_refs,
|
|
1118
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(evidence_refs),
|
|
1119
|
+
"evidence_visibility": "visible_or_public_package_evidence",
|
|
1120
|
+
"visible_input_refs": [ref for ref in source_artifact_refs if ref.startswith("input/") or "/input/" in ref],
|
|
1121
|
+
"source_content_hashes": {
|
|
1122
|
+
ref: _content_hash_for_ref(evidence["package_root"], ref)
|
|
1123
|
+
for ref in evidence_refs[:24]
|
|
1124
|
+
if isinstance(evidence.get("package_root"), Path) and _content_hash_for_ref(evidence["package_root"], ref)
|
|
1125
|
+
},
|
|
504
1126
|
"provenance": "derived_from_observed_agent_apprenticeship_package",
|
|
505
1127
|
"quality_score": quality,
|
|
506
1128
|
"fidelity_score": min(1.0, quality + 0.04),
|
|
507
1129
|
"difficulty_score": min(1.0, max(0.35, quality - 0.08)),
|
|
508
1130
|
"learnability_score": min(1.0, quality + 0.02),
|
|
509
1131
|
"reuse_value_score": min(1.0, quality + 0.03),
|
|
1132
|
+
"confidence": min(1.0, quality + 0.02),
|
|
510
1133
|
"weak_score_proxy": proxy.get("weak_score_proxy"),
|
|
511
1134
|
"strong_score_proxy": proxy.get("strong_score_proxy"),
|
|
512
1135
|
"solver_gap_proxy": proxy.get("solver_gap_proxy"),
|
|
@@ -545,6 +1168,74 @@ def _has_concrete_source_evidence(row: dict[str, Any]) -> bool:
|
|
|
545
1168
|
return False
|
|
546
1169
|
|
|
547
1170
|
|
|
1171
|
+
def _finalize_candidate_rows(rows: list[dict[str, Any]], evidence: dict[str, Any]) -> list[dict[str, Any]]:
|
|
1172
|
+
finalized: list[dict[str, Any]] = []
|
|
1173
|
+
for raw in rows:
|
|
1174
|
+
row = dict(raw)
|
|
1175
|
+
data_type = str(row.get("data_type") or "unknown")
|
|
1176
|
+
row_id = _row_identity(data_type, row, evidence)
|
|
1177
|
+
id_field = ROW_ID_FIELD_BY_TYPE.get(data_type, "row_id")
|
|
1178
|
+
row.setdefault(id_field, row_id)
|
|
1179
|
+
row.setdefault("row_id", row_id)
|
|
1180
|
+
row.setdefault("schema_version", TRAINING_ROW_SCHEMA_VERSION)
|
|
1181
|
+
row.setdefault("training_use_cases", TRAINING_USE_BY_TYPE.get(data_type, ["experience_compilation_training"]))
|
|
1182
|
+
row.setdefault("quality_signal_source", row.get("tdo_judge_source") or "experience_compiler_guardrail")
|
|
1183
|
+
row.setdefault("source_trace_ref", row.get("source_trace_id"))
|
|
1184
|
+
row.setdefault("source_evidence_ref_ids", _evidence_ids_for_refs(row.get("evidence_refs") or []))
|
|
1185
|
+
row.setdefault("evidence_confidence", row.get("confidence") or row.get("quality_score") or 0.5)
|
|
1186
|
+
row.setdefault("row_content_hash", _hash_obj({k: v for k, v in row.items() if k not in {"row_content_hash", "created_at"}}))
|
|
1187
|
+
row.setdefault(
|
|
1188
|
+
"model_training_targets",
|
|
1189
|
+
{
|
|
1190
|
+
"sft_ready": data_type == "training_example",
|
|
1191
|
+
"lora_ready": data_type == "training_example",
|
|
1192
|
+
"reward_ready": data_type == "reward_model_row",
|
|
1193
|
+
"verifier_ready": data_type in {"verifier_example", "evaluation_example"},
|
|
1194
|
+
"preference_ready": data_type == "preference_pair",
|
|
1195
|
+
"process_supervision_ready": data_type in {"environment_response_pair", *SURFACE_FILES.keys()},
|
|
1196
|
+
"rl_rollout_ready": data_type in {"environment_response_pair", "software_execution_event", "api_interaction_event"},
|
|
1197
|
+
},
|
|
1198
|
+
)
|
|
1199
|
+
if data_type == "training_example":
|
|
1200
|
+
row.setdefault("instruction", (row.get("input") or {}).get("instruction") if isinstance(row.get("input"), dict) else row.get("input"))
|
|
1201
|
+
row.setdefault("target_output", row.get("expected_output") or row.get("target"))
|
|
1202
|
+
row.setdefault("output_contract_summary", "Use actual_outputs.json plus artifact refs as the output contract.")
|
|
1203
|
+
elif data_type == "reward_model_row":
|
|
1204
|
+
target = row.get("target") if isinstance(row.get("target"), dict) else {}
|
|
1205
|
+
row.setdefault("reward_component", "task_outcome")
|
|
1206
|
+
row.setdefault("reward_value", target.get("final_score") if isinstance(target, dict) else None)
|
|
1207
|
+
row.setdefault("reward_timing", "final")
|
|
1208
|
+
row.setdefault("verifier_or_grader_source", "grader_result")
|
|
1209
|
+
elif data_type == "verifier_example":
|
|
1210
|
+
row.setdefault("claim_or_output", row.get("input"))
|
|
1211
|
+
row.setdefault("visible_evidence", row.get("source_artifact_refs") or row.get("evidence_refs"))
|
|
1212
|
+
row.setdefault("verifier_decision", row.get("target"))
|
|
1213
|
+
elif data_type == "preference_pair":
|
|
1214
|
+
target = row.get("target") if isinstance(row.get("target"), dict) else {}
|
|
1215
|
+
row.setdefault("chosen_output", target.get("chosen"))
|
|
1216
|
+
row.setdefault("rejected_output", "baseline" if target.get("chosen") == "revised" else "revised")
|
|
1217
|
+
row.setdefault("preference_reason", row.get("scoring_hint") or "Higher grounded score/verifier evidence.")
|
|
1218
|
+
row.setdefault("quality_delta", target.get("solver_gap_proxy"))
|
|
1219
|
+
elif data_type == "failure_case":
|
|
1220
|
+
target = row.get("target") if isinstance(row.get("target"), dict) else {}
|
|
1221
|
+
row.setdefault("failure_type", target.get("failure_mode") or "contract_or_score_failure")
|
|
1222
|
+
row.setdefault("failure_severity", "medium")
|
|
1223
|
+
row.setdefault("repair_recommendation", target.get("repair_hint") or row.get("scoring_hint"))
|
|
1224
|
+
elif data_type == "task_variant":
|
|
1225
|
+
target = row.get("target") if isinstance(row.get("target"), dict) else {}
|
|
1226
|
+
row.setdefault("variant_instruction", target.get("variant_instruction"))
|
|
1227
|
+
row.setdefault("expected_output_contract", target.get("expected_deliverables"))
|
|
1228
|
+
row.setdefault("difficulty", row.get("difficulty_score"))
|
|
1229
|
+
elif data_type == "environment_response_pair":
|
|
1230
|
+
row.setdefault("rollout_group_id", f"rollout_{_safe_id(str(row.get('source_task_id')))}")
|
|
1231
|
+
row.setdefault("candidate_rollout_id", f"rollout_{row_id}")
|
|
1232
|
+
row.setdefault("scalar_reward", row.get("format_score") or row.get("quality_score"))
|
|
1233
|
+
row.setdefault("reward_components", {"format": row.get("format_score"), "consistency": row.get("consistency_score")})
|
|
1234
|
+
row.setdefault("termination_reason", row.get("success_signal"))
|
|
1235
|
+
finalized.append(sanitize_public_obj(row))
|
|
1236
|
+
return finalized
|
|
1237
|
+
|
|
1238
|
+
|
|
548
1239
|
def _build_candidate_rows(evidence: dict[str, Any], settings: Settings, round_idx: int, judge_source: str, mentor_audited: bool, proxy: dict[str, Any]) -> list[dict[str, Any]]:
|
|
549
1240
|
task = evidence.get("task") or {}
|
|
550
1241
|
raw = evidence.get("raw_task") or {}
|
|
@@ -634,7 +1325,7 @@ def _build_candidate_rows(evidence: dict[str, Any], settings: Settings, round_id
|
|
|
634
1325
|
})
|
|
635
1326
|
rows.extend(_environment_response_rows(evidence, common))
|
|
636
1327
|
rows.extend(_surface_event_rows(evidence, common))
|
|
637
|
-
return
|
|
1328
|
+
return _finalize_candidate_rows(rows, evidence)
|
|
638
1329
|
|
|
639
1330
|
|
|
640
1331
|
def _best_output_summary(evidence: dict[str, Any]) -> str:
|
|
@@ -1019,6 +1710,7 @@ def _validate_rows(package_root: Path, rows: list[dict[str, Any]], min_quality:
|
|
|
1019
1710
|
accepted: list[dict[str, Any]] = []
|
|
1020
1711
|
rejected: list[dict[str, Any]] = []
|
|
1021
1712
|
schema_errors: list[str] = []
|
|
1713
|
+
seen_row_ids: set[str] = set()
|
|
1022
1714
|
for row in rows:
|
|
1023
1715
|
reason = _private_or_forbidden_hit(row)
|
|
1024
1716
|
missing = _artifact_refs_resolve(package_root, row)
|
|
@@ -1026,6 +1718,24 @@ def _validate_rows(package_root: Path, rows: list[dict[str, Any]], min_quality:
|
|
|
1026
1718
|
reason = reason or f"unresolved_artifact_ref:{missing[0]}"
|
|
1027
1719
|
if not row.get("data_type"):
|
|
1028
1720
|
reason = reason or "missing_data_type"
|
|
1721
|
+
row_id = row.get("row_id") or row.get("pair_id")
|
|
1722
|
+
if not row_id:
|
|
1723
|
+
reason = reason or "missing_stable_row_id"
|
|
1724
|
+
elif str(row_id) in seen_row_ids:
|
|
1725
|
+
reason = reason or f"duplicate_row_id:{row_id}"
|
|
1726
|
+
else:
|
|
1727
|
+
seen_row_ids.add(str(row_id))
|
|
1728
|
+
if not isinstance(row.get("task_lineage"), dict) or not row.get("source_task_id"):
|
|
1729
|
+
reason = reason or "missing_task_lineage"
|
|
1730
|
+
if not row.get("domain") or not row.get("workflow_family"):
|
|
1731
|
+
reason = reason or "missing_domain_or_workflow_family"
|
|
1732
|
+
if not row.get("source_evidence_ref_ids"):
|
|
1733
|
+
reason = reason or "missing_source_evidence_ref_ids"
|
|
1734
|
+
if row.get("data_type") in {"training_example", "evaluation_example", "verifier_example", "reward_model_row"}:
|
|
1735
|
+
if row.get("input") in (None, "", {}, []):
|
|
1736
|
+
reason = reason or "missing_core_input"
|
|
1737
|
+
if row.get("target") in (None, "", {}, []):
|
|
1738
|
+
reason = reason or "missing_core_target"
|
|
1029
1739
|
if not _has_concrete_source_evidence(row):
|
|
1030
1740
|
reason = reason or "insufficient_concrete_source_evidence"
|
|
1031
1741
|
if _score(row.get("quality_score")) < min_quality:
|
|
@@ -1231,11 +1941,30 @@ def _environment_spec(evidence: dict[str, Any]) -> dict[str, Any]:
|
|
|
1231
1941
|
"input_artifacts": [ref for ref in _source_artifact_refs(evidence) if ref.startswith("input/") or "/input/" in ref],
|
|
1232
1942
|
"initial_state_refs": ["task/task_intake_spec.json", "rubric/rubric.json"],
|
|
1233
1943
|
"allowed_actions": sorted(set(operations)),
|
|
1944
|
+
"action_schema": {
|
|
1945
|
+
"action": "operation/tool invocation or artifact-producing step",
|
|
1946
|
+
"tool": "optional tool name",
|
|
1947
|
+
"input": "visible input or command payload",
|
|
1948
|
+
"artifact_refs": "package-relative refs produced or inspected",
|
|
1949
|
+
},
|
|
1950
|
+
"observation_schema": {
|
|
1951
|
+
"observation": "tool/environment response summary",
|
|
1952
|
+
"state_change": "state delta after action",
|
|
1953
|
+
"artifact_refs": "package-relative output refs",
|
|
1954
|
+
"success_signal": "step outcome or verifier signal",
|
|
1955
|
+
},
|
|
1234
1956
|
"reset_strategy": "copy_workspace" if environment_type in {"local_filesystem", "codebase", "terminal"} else "unknown",
|
|
1235
1957
|
"verification_commands": [],
|
|
1236
1958
|
"scoring_refs": [ref for ref in _evidence_refs(evidence) if ref.startswith("grading/")],
|
|
1237
1959
|
"expected_output_refs": [ref for ref in _source_artifact_refs(evidence) if "/artifacts/" in ref],
|
|
1960
|
+
"termination_conditions": ["task_complete", "contract_verified", "max_iterations_reached"],
|
|
1961
|
+
"reward_function_components": ["artifact_contract", "verifier_signal", "step_success", "grader_score_if_available"],
|
|
1238
1962
|
"replay_smoke_test": {"available": False, "command": None, "success_condition": None},
|
|
1963
|
+
"reproducibility_metadata": {
|
|
1964
|
+
"source_trace_count": len(evidence.get("attempts") or {}),
|
|
1965
|
+
"package_id": evidence.get("package_id"),
|
|
1966
|
+
"created_from_observed_trace": True,
|
|
1967
|
+
},
|
|
1239
1968
|
"multi_agent": {
|
|
1240
1969
|
"present": multi_agent_present,
|
|
1241
1970
|
"agents": values_from("agent_id", "agent_name", "subagent_id", "subagent_name"),
|
|
@@ -1387,7 +2116,231 @@ def _copy_compiler_json_public(src: Path, dst: Path) -> None:
|
|
|
1387
2116
|
if not src.exists():
|
|
1388
2117
|
write_json(dst, {})
|
|
1389
2118
|
return
|
|
1390
|
-
|
|
2119
|
+
write_json(dst, _compiler_public_obj(read_json(src)))
|
|
2120
|
+
|
|
2121
|
+
|
|
2122
|
+
def _compiler_rows_from_tdo_dir(tdo_dir: Path) -> list[dict[str, Any]]:
|
|
2123
|
+
rows: list[dict[str, Any]] = []
|
|
2124
|
+
for filename in sorted(set(ROW_FILE_BY_TYPE.values())):
|
|
2125
|
+
path = tdo_dir / filename
|
|
2126
|
+
if not path.exists():
|
|
2127
|
+
continue
|
|
2128
|
+
for row in _safe_jsonl(path):
|
|
2129
|
+
if isinstance(row, dict):
|
|
2130
|
+
clean = dict(row)
|
|
2131
|
+
clean["_source_row_file"] = filename
|
|
2132
|
+
rows.append(clean)
|
|
2133
|
+
return rows
|
|
2134
|
+
|
|
2135
|
+
|
|
2136
|
+
def _training_row_counts_by_file(tdo_dir: Path) -> dict[str, int]:
|
|
2137
|
+
counts: dict[str, int] = {}
|
|
2138
|
+
for filename in sorted(set(ROW_FILE_BY_TYPE.values())):
|
|
2139
|
+
path = tdo_dir / filename
|
|
2140
|
+
counts[filename] = len(_safe_jsonl(path)) if path.exists() else 0
|
|
2141
|
+
return counts
|
|
2142
|
+
|
|
2143
|
+
|
|
2144
|
+
def _source_evidence_map_payload(
|
|
2145
|
+
evidence: dict[str, Any],
|
|
2146
|
+
report: dict[str, Any],
|
|
2147
|
+
compiler_rows: list[dict[str, Any]],
|
|
2148
|
+
) -> dict[str, Any]:
|
|
2149
|
+
catalog = _evidence_catalog(evidence)
|
|
2150
|
+
evidence_by_id = {item["evidence_id"]: item for item in catalog}
|
|
2151
|
+
row_links: list[dict[str, Any]] = []
|
|
2152
|
+
orphan_ids: set[str] = set()
|
|
2153
|
+
for row in compiler_rows:
|
|
2154
|
+
row_id = str(row.get("row_id") or row.get("pair_id") or _row_identity(str(row.get("data_type") or "unknown"), row, evidence))
|
|
2155
|
+
ids = [str(v) for v in row.get("source_evidence_ref_ids") or _evidence_ids_for_refs(row.get("evidence_refs") or [])]
|
|
2156
|
+
for evidence_id in ids:
|
|
2157
|
+
if evidence_id not in evidence_by_id:
|
|
2158
|
+
orphan_ids.add(evidence_id)
|
|
2159
|
+
row_links.append(
|
|
2160
|
+
{
|
|
2161
|
+
"row_id": row_id,
|
|
2162
|
+
"row_file": row.get("_source_row_file"),
|
|
2163
|
+
"data_type": row.get("data_type"),
|
|
2164
|
+
"source_task_id": row.get("source_task_id") or report.get("source_task_id"),
|
|
2165
|
+
"source_trace_id": row.get("source_trace_id"),
|
|
2166
|
+
"source_step_ids": row.get("source_step_ids") or [],
|
|
2167
|
+
"source_artifact_refs": row.get("source_artifact_refs") or [],
|
|
2168
|
+
"evidence_ref_ids": ids,
|
|
2169
|
+
"visible_evidence_ref_ids": [
|
|
2170
|
+
evidence_id
|
|
2171
|
+
for evidence_id in ids
|
|
2172
|
+
if (evidence_by_id.get(evidence_id) or {}).get("visibility") == "visible"
|
|
2173
|
+
],
|
|
2174
|
+
"inferred_evidence_ref_ids": [
|
|
2175
|
+
evidence_id
|
|
2176
|
+
for evidence_id in ids
|
|
2177
|
+
if (evidence_by_id.get(evidence_id) or {}).get("visibility") == "inferred"
|
|
2178
|
+
],
|
|
2179
|
+
}
|
|
2180
|
+
)
|
|
2181
|
+
resolved = sum(1 for item in catalog if item.get("resolves"))
|
|
2182
|
+
return sanitize_public_obj(
|
|
2183
|
+
{
|
|
2184
|
+
"schema_version": EVIDENCE_MAP_SCHEMA_VERSION,
|
|
2185
|
+
"source_package_id": report.get("source_package_id"),
|
|
2186
|
+
"source_task_id": report.get("source_task_id"),
|
|
2187
|
+
"evidence_catalog": catalog,
|
|
2188
|
+
"row_evidence_links": row_links,
|
|
2189
|
+
"task_refs": [
|
|
2190
|
+
ref
|
|
2191
|
+
for ref in [
|
|
2192
|
+
"task/task_packet.json",
|
|
2193
|
+
"task/task_intake_spec.json",
|
|
2194
|
+
"task/raw_task_record.json",
|
|
2195
|
+
"source_task/task_packet.json",
|
|
2196
|
+
]
|
|
2197
|
+
if isinstance(evidence.get("package_root"), Path) and (evidence["package_root"] / ref).exists()
|
|
2198
|
+
]
|
|
2199
|
+
or ["task/task_packet.json"],
|
|
2200
|
+
"artifact_refs": _source_artifact_refs(evidence),
|
|
2201
|
+
"evaluation_refs": [ref for ref in _evidence_refs(evidence) if ref.startswith(("grading/", "feedback/", "signals/", "loops/"))],
|
|
2202
|
+
"loop_review_refs": evidence.get("loop_review_refs") or [],
|
|
2203
|
+
"trace_refs": [
|
|
2204
|
+
str((attempt.get("agent_trace") or {}).get("trace_id"))
|
|
2205
|
+
for attempt in (evidence.get("attempts") or {}).values()
|
|
2206
|
+
if (attempt.get("agent_trace") or {}).get("trace_id")
|
|
2207
|
+
],
|
|
2208
|
+
"coverage_statistics": {
|
|
2209
|
+
"evidence_ref_count": len(catalog),
|
|
2210
|
+
"resolved_evidence_ref_count": resolved,
|
|
2211
|
+
"unresolved_evidence_ref_count": len(catalog) - resolved,
|
|
2212
|
+
"row_link_count": len(row_links),
|
|
2213
|
+
"row_count_with_evidence_ids": sum(1 for row in row_links if row.get("evidence_ref_ids")),
|
|
2214
|
+
"orphan_evidence_id_count": len(orphan_ids),
|
|
2215
|
+
},
|
|
2216
|
+
"orphan_evidence_ref_ids": sorted(orphan_ids),
|
|
2217
|
+
}
|
|
2218
|
+
)
|
|
2219
|
+
|
|
2220
|
+
|
|
2221
|
+
def _process_supervision_rows_from_compiler_rows(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
2222
|
+
out: list[dict[str, Any]] = []
|
|
2223
|
+
process_types = {"environment_response_pair", *SURFACE_FILES.keys()}
|
|
2224
|
+
for row in rows:
|
|
2225
|
+
if row.get("data_type") not in process_types:
|
|
2226
|
+
continue
|
|
2227
|
+
out.append(
|
|
2228
|
+
sanitize_public_obj(
|
|
2229
|
+
{
|
|
2230
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
2231
|
+
"row_id": f"ps_{row.get('row_id')}",
|
|
2232
|
+
"data_type": "process_supervision",
|
|
2233
|
+
"source_package_id": row.get("source_package_id"),
|
|
2234
|
+
"source_task_id": row.get("source_task_id"),
|
|
2235
|
+
"task_lineage": row.get("task_lineage"),
|
|
2236
|
+
"domain": row.get("domain"),
|
|
2237
|
+
"subdomain": row.get("subdomain"),
|
|
2238
|
+
"workflow_family": row.get("workflow_family"),
|
|
2239
|
+
"source_trace_id": row.get("source_trace_id"),
|
|
2240
|
+
"source_step_ids": row.get("source_step_ids") or [],
|
|
2241
|
+
"step_goal": row.get("agent_action") or row.get("command") or row.get("query") or row.get("input") or row.get("state_change") or row.get("interaction_surface"),
|
|
2242
|
+
"action_taken": row.get("agent_action") or row.get("action_type") or row.get("command") or row.get("query") or row.get("state_change") or row.get("interaction_surface"),
|
|
2243
|
+
"observation": row.get("observed_environment_response") or row.get("observed_result") or row.get("output") or row.get("state_change") or row.get("success_signal"),
|
|
2244
|
+
"tool_action_metadata": {
|
|
2245
|
+
"environment_domain": row.get("environment_domain"),
|
|
2246
|
+
"interaction_surface": row.get("interaction_surface"),
|
|
2247
|
+
"tool_or_surface": row.get("search_provider") or row.get("api_endpoint") or row.get("table_name") or row.get("service_name"),
|
|
2248
|
+
},
|
|
2249
|
+
"correctness_label": "positive" if row.get("success_signal") in {"completed", "True", True} else "unknown",
|
|
2250
|
+
"quality_signal": row.get("training_quality_score") or row.get("quality_score"),
|
|
2251
|
+
"next_step_recommendation": "Continue from the observed state and verify artifact/output contract before final answer.",
|
|
2252
|
+
"source_evidence_ref_ids": row.get("source_evidence_ref_ids") or [],
|
|
2253
|
+
"evidence_refs": row.get("evidence_refs") or [],
|
|
2254
|
+
"confidence": row.get("confidence") or row.get("quality_score") or 0.5,
|
|
2255
|
+
"created_at": row.get("created_at") or utc_now(),
|
|
2256
|
+
}
|
|
2257
|
+
)
|
|
2258
|
+
)
|
|
2259
|
+
return out
|
|
2260
|
+
|
|
2261
|
+
|
|
2262
|
+
def _rl_rollout_rows_from_compiler_rows(rows: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
2263
|
+
out: list[dict[str, Any]] = []
|
|
2264
|
+
for row in rows:
|
|
2265
|
+
if row.get("data_type") != "environment_response_pair":
|
|
2266
|
+
continue
|
|
2267
|
+
row_id = str(row.get("row_id") or _hash_obj(row))
|
|
2268
|
+
out.append(
|
|
2269
|
+
sanitize_public_obj(
|
|
2270
|
+
{
|
|
2271
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
2272
|
+
"row_id": f"rl_{row_id}",
|
|
2273
|
+
"data_type": "agentic_rl_rollout",
|
|
2274
|
+
"source_package_id": row.get("source_package_id"),
|
|
2275
|
+
"source_task_id": row.get("source_task_id"),
|
|
2276
|
+
"task_lineage": row.get("task_lineage"),
|
|
2277
|
+
"domain": row.get("domain"),
|
|
2278
|
+
"subdomain": row.get("subdomain"),
|
|
2279
|
+
"workflow_family": row.get("workflow_family"),
|
|
2280
|
+
"rollout_group_id": row.get("rollout_group_id") or f"rollout_{_safe_id(str(row.get('source_task_id')))}",
|
|
2281
|
+
"candidate_rollout_id": row.get("candidate_rollout_id") or f"rollout_{row_id}",
|
|
2282
|
+
"prompt_or_instruction": row.get("input") or row.get("agent_action"),
|
|
2283
|
+
"initial_environment_state": row.get("state_before"),
|
|
2284
|
+
"visible_input_refs": row.get("visible_input_refs") or [],
|
|
2285
|
+
"tool_action_schema": {
|
|
2286
|
+
"environment_domain": row.get("environment_domain"),
|
|
2287
|
+
"interaction_surface": row.get("interaction_surface"),
|
|
2288
|
+
},
|
|
2289
|
+
"step_action_trace": {
|
|
2290
|
+
"source_trace_id": row.get("source_trace_id"),
|
|
2291
|
+
"source_step_ids": row.get("source_step_ids") or [],
|
|
2292
|
+
"action": row.get("agent_action"),
|
|
2293
|
+
"observation": row.get("observed_environment_response"),
|
|
2294
|
+
},
|
|
2295
|
+
"artifacts_produced": row.get("source_artifact_refs") or [],
|
|
2296
|
+
"final_output": row.get("state_after") or row.get("success_signal"),
|
|
2297
|
+
"verifier_decision": row.get("verifier_feedback"),
|
|
2298
|
+
"scalar_reward": row.get("scalar_reward") or row.get("training_quality_score") or row.get("quality_score"),
|
|
2299
|
+
"reward_components": row.get("reward_components") or {},
|
|
2300
|
+
"reward_timing": "step",
|
|
2301
|
+
"success_label": row.get("success_signal"),
|
|
2302
|
+
"termination_reason": row.get("termination_reason") or row.get("success_signal"),
|
|
2303
|
+
"source_evidence_ref_ids": row.get("source_evidence_ref_ids") or [],
|
|
2304
|
+
"evidence_refs": row.get("evidence_refs") or [],
|
|
2305
|
+
"replay_scoring_smoke_test_refs": row.get("source_evaluation_refs") or [],
|
|
2306
|
+
"confidence": row.get("confidence") or row.get("quality_score") or 0.5,
|
|
2307
|
+
"created_at": row.get("created_at") or utc_now(),
|
|
2308
|
+
}
|
|
2309
|
+
)
|
|
2310
|
+
)
|
|
2311
|
+
return out
|
|
2312
|
+
|
|
2313
|
+
|
|
2314
|
+
def _bioactive_schema_examples(report: dict[str, Any], evidence: dict[str, Any]) -> list[dict[str, Any]]:
|
|
2315
|
+
base = {
|
|
2316
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
2317
|
+
"source_package_id": report.get("source_package_id"),
|
|
2318
|
+
"source_task_id": report.get("source_task_id"),
|
|
2319
|
+
"task_lineage": _task_lineage(evidence),
|
|
2320
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:5]),
|
|
2321
|
+
"evidence_refs": _evidence_refs(evidence)[:5],
|
|
2322
|
+
"confidence": 0.5,
|
|
2323
|
+
"personal_context_policy": "abstract_constraints_only_no_sensitive_identity",
|
|
2324
|
+
"medical_advice_policy": "evidence_mapping_only_no_treatment_or_cure_claims",
|
|
2325
|
+
"created_at": utc_now(),
|
|
2326
|
+
}
|
|
2327
|
+
return [
|
|
2328
|
+
{
|
|
2329
|
+
**base,
|
|
2330
|
+
"row_id": f"bioactive_schema_{_safe_id(str(report.get('source_package_id') or 'package'))}",
|
|
2331
|
+
"data_type": "bioactive_evidence_mapping_schema_example",
|
|
2332
|
+
"source_text_or_artifact_ref": None,
|
|
2333
|
+
"extracted_claim": None,
|
|
2334
|
+
"ingredient_or_compound_entity": None,
|
|
2335
|
+
"product_entity": None,
|
|
2336
|
+
"evidence_summary": None,
|
|
2337
|
+
"mechanism_category": None,
|
|
2338
|
+
"safety_caution_category": None,
|
|
2339
|
+
"uncertainty": "schema_only",
|
|
2340
|
+
"citation_or_provenance_refs": [],
|
|
2341
|
+
"verifier_decision": "not_evaluated_schema_example",
|
|
2342
|
+
}
|
|
2343
|
+
]
|
|
1391
2344
|
|
|
1392
2345
|
|
|
1393
2346
|
def _copy_json_public(src: Path, dst: Path, default: dict[str, Any] | None = None) -> None:
|
|
@@ -1569,11 +2522,16 @@ def _write_experience_compiler_outputs(
|
|
|
1569
2522
|
"verifier",
|
|
1570
2523
|
"reward",
|
|
1571
2524
|
"environment",
|
|
2525
|
+
"loop_learning",
|
|
1572
2526
|
"reports",
|
|
1573
2527
|
]:
|
|
1574
2528
|
(root / name).mkdir(parents=True, exist_ok=True)
|
|
1575
2529
|
|
|
1576
2530
|
manifest_src = read_json(tdo_dir / "tdo_manifest.json") if (tdo_dir / "tdo_manifest.json").exists() else {}
|
|
2531
|
+
compiler_rows = _compiler_rows_from_tdo_dir(tdo_dir)
|
|
2532
|
+
training_row_counts_by_file = _training_row_counts_by_file(tdo_dir)
|
|
2533
|
+
evidence_map = _source_evidence_map_payload(evidence, report, compiler_rows)
|
|
2534
|
+
package_version = get_package_version()
|
|
1577
2535
|
compiler_refs = [
|
|
1578
2536
|
"experience_compiler/compiler_manifest.json",
|
|
1579
2537
|
"experience_compiler/compiler_report.json",
|
|
@@ -1585,18 +2543,51 @@ def _write_experience_compiler_outputs(
|
|
|
1585
2543
|
"experience_compiler/skill_pack/skill.md",
|
|
1586
2544
|
]
|
|
1587
2545
|
compiler_manifest = {
|
|
1588
|
-
"schema_version": "aa-experience-compiler-v0.
|
|
2546
|
+
"schema_version": "aa-experience-compiler-v0.2",
|
|
2547
|
+
"training_row_schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
2548
|
+
"source_evidence_map_schema_version": EVIDENCE_MAP_SCHEMA_VERSION,
|
|
2549
|
+
"package_version": package_version,
|
|
2550
|
+
"compiler_version": TDO_VERSION,
|
|
1589
2551
|
"compiler_id": str(report.get("tdo_id") or "").replace("tdo_", "compiler_", 1) or f"compiler_{_safe_id(package_root.name)}",
|
|
1590
2552
|
"compiler_status": report.get("tdo_status"),
|
|
1591
2553
|
"source_package_id": report.get("source_package_id"),
|
|
1592
2554
|
"source_task_id": report.get("source_task_id"),
|
|
2555
|
+
"title": _task_title(evidence),
|
|
2556
|
+
"task_title": _task_title(evidence),
|
|
2557
|
+
"domain": _task_lineage(evidence)["domain"],
|
|
2558
|
+
"subdomain": _task_lineage(evidence)["subdomain"],
|
|
2559
|
+
"workflow_family": _task_lineage(evidence)["workflow_family"],
|
|
2560
|
+
"public_private_mode": getattr(settings, "contribution_mode", None),
|
|
2561
|
+
"sharing_upload_mode": getattr(settings, "contribution_mode", None),
|
|
2562
|
+
"private_internal_no_upload_confirmed": getattr(settings, "contribution_mode", None) == "private_internal",
|
|
1593
2563
|
"apprenticeship_mode": getattr(settings, "apprenticeship_mode", None),
|
|
1594
2564
|
"judge_source": report.get("tdo_judge_source"),
|
|
1595
2565
|
"mentor_audited": report.get("mentor_audited"),
|
|
1596
2566
|
"rounds_run": report.get("rounds_run"),
|
|
1597
2567
|
"rows_by_type": rows_accepted,
|
|
2568
|
+
"training_row_counts_by_file": training_row_counts_by_file,
|
|
2569
|
+
"source_evidence_ref_count": (evidence_map.get("coverage_statistics") or {}).get("evidence_ref_count"),
|
|
2570
|
+
"source_evidence_row_link_count": (evidence_map.get("coverage_statistics") or {}).get("row_link_count"),
|
|
1598
2571
|
"supported_runtime_uses": ["experience_pack", "skill_pack", "runtime_learning_package"],
|
|
1599
|
-
"supported_training_uses": [
|
|
2572
|
+
"supported_training_uses": [
|
|
2573
|
+
"sft",
|
|
2574
|
+
"lora_ready_instruction_tuning",
|
|
2575
|
+
"process_supervision",
|
|
2576
|
+
"training_examples",
|
|
2577
|
+
"evaluation_examples",
|
|
2578
|
+
"verifier_examples",
|
|
2579
|
+
"reward_model_rows",
|
|
2580
|
+
"preference_pairs",
|
|
2581
|
+
"critique_revision_pairs",
|
|
2582
|
+
"failure_cases",
|
|
2583
|
+
"task_variants",
|
|
2584
|
+
"agentic_rl_rollouts",
|
|
2585
|
+
"grpo_rollout_material",
|
|
2586
|
+
"environment_response_pairs",
|
|
2587
|
+
"loop_learning",
|
|
2588
|
+
"contract_verification",
|
|
2589
|
+
"environment_state_transition_learning",
|
|
2590
|
+
],
|
|
1600
2591
|
"loop_review_refs": evidence.get("loop_review_refs") or [],
|
|
1601
2592
|
"compiler_output_refs": compiler_refs,
|
|
1602
2593
|
"created_at": report.get("created_at") or utc_now(),
|
|
@@ -1609,33 +2600,17 @@ def _write_experience_compiler_outputs(
|
|
|
1609
2600
|
"apprenticeship_mode": getattr(settings, "apprenticeship_mode", None),
|
|
1610
2601
|
})
|
|
1611
2602
|
write_json(root / "compiler_report.json", sanitize_public_obj(compiler_report))
|
|
1612
|
-
|
|
1613
|
-
ref
|
|
1614
|
-
for ref in [
|
|
1615
|
-
"task/task_packet.json",
|
|
1616
|
-
"task/task_intake_spec.json",
|
|
1617
|
-
"task/raw_task_record.json",
|
|
1618
|
-
"source_task/task_packet.json",
|
|
1619
|
-
]
|
|
1620
|
-
if (package_root / ref).exists()
|
|
1621
|
-
]
|
|
1622
|
-
if not task_refs:
|
|
1623
|
-
task_refs = ["task/task_packet.json"]
|
|
1624
|
-
write_json(root / "source_evidence_map.json", sanitize_public_obj({
|
|
1625
|
-
"source_package_id": report.get("source_package_id"),
|
|
1626
|
-
"source_task_id": report.get("source_task_id"),
|
|
1627
|
-
"task_refs": task_refs,
|
|
1628
|
-
"artifact_refs": _source_artifact_refs(evidence),
|
|
1629
|
-
"evaluation_refs": _evidence_refs(evidence),
|
|
1630
|
-
"loop_review_refs": evidence.get("loop_review_refs") or [],
|
|
1631
|
-
"trace_refs": [str(trace.get("trace_id") or trace.get("source_trace_id") or "trace") for trace in evidence.get("traces") or []],
|
|
1632
|
-
}))
|
|
2603
|
+
write_json(root / "source_evidence_map.json", evidence_map)
|
|
1633
2604
|
write_json(root / "quality_report.json", sanitize_public_obj({
|
|
1634
2605
|
"source_package_id": report.get("source_package_id"),
|
|
1635
2606
|
"compiler_status": report.get("tdo_status"),
|
|
2607
|
+
"package_version": package_version,
|
|
2608
|
+
"compiler_version": TDO_VERSION,
|
|
1636
2609
|
"average_quality_score": report.get("average_quality_score"),
|
|
1637
2610
|
"average_fidelity_score": report.get("average_fidelity_score"),
|
|
1638
2611
|
"average_reuse_value_score": report.get("average_reuse_value_score"),
|
|
2612
|
+
"training_row_counts_by_file": training_row_counts_by_file,
|
|
2613
|
+
"source_evidence_map_coverage": evidence_map.get("coverage_statistics"),
|
|
1639
2614
|
"omitted_outputs": report.get("omitted_outputs") or [],
|
|
1640
2615
|
"not_generated_counts": report.get("not_generated_counts") or {},
|
|
1641
2616
|
"generation_notes": report.get("generation_notes") or [],
|
|
@@ -1649,6 +2624,13 @@ def _write_experience_compiler_outputs(
|
|
|
1649
2624
|
_copy_compiler_jsonl_public(tdo_dir / "tdo_judge_results.jsonl", root / "reports" / "compiler_judge_results.jsonl")
|
|
1650
2625
|
_copy_compiler_json_public(tdo_dir / "tdo_recipe.json", root / "reports" / "compiler_recipe.json")
|
|
1651
2626
|
|
|
2627
|
+
loop_learning = _loop_learning_rows(evidence, report)
|
|
2628
|
+
_write_jsonl(root / "loop_learning" / "loop_review_rows.jsonl", loop_learning["loop_review_rows"])
|
|
2629
|
+
_write_jsonl(root / "loop_learning" / "feedback_revision_pairs.jsonl", loop_learning["feedback_revision_pairs"])
|
|
2630
|
+
_write_jsonl(root / "loop_learning" / "contract_verification_rows.jsonl", loop_learning["contract_verification_rows"])
|
|
2631
|
+
_write_jsonl(root / "loop_learning" / "repair_loop_rows.jsonl", loop_learning["repair_loop_rows"])
|
|
2632
|
+
_write_jsonl(root / "loop_learning" / "reviewer_decision_rows.jsonl", loop_learning["reviewer_decision_rows"])
|
|
2633
|
+
|
|
1652
2634
|
jsonl_map = {
|
|
1653
2635
|
"training_examples.jsonl": root / "training_time_package" / "training_examples.jsonl",
|
|
1654
2636
|
"evaluation_examples.jsonl": root / "training_time_package" / "evaluation_examples.jsonl",
|
|
@@ -1707,6 +2689,7 @@ def _write_experience_compiler_outputs(
|
|
|
1707
2689
|
title = _task_title(evidence) or str(report.get("source_task_id") or "Compiled skill")
|
|
1708
2690
|
instruction = _task_instruction(evidence)
|
|
1709
2691
|
criteria = _success_criteria(evidence)
|
|
2692
|
+
artifact_contracts = _artifact_contracts(evidence)
|
|
1710
2693
|
canonical_skill = sanitize_public_obj({
|
|
1711
2694
|
"skill_id": f"skill_{_safe_id(str(report.get('source_package_id') or package_root.name))}",
|
|
1712
2695
|
"title": title,
|
|
@@ -1792,6 +2775,9 @@ def _write_experience_compiler_outputs(
|
|
|
1792
2775
|
"source_package_id": report.get("source_package_id"),
|
|
1793
2776
|
"checks": criteria + ["bundle_check_passes", "evidence_refs_resolve"],
|
|
1794
2777
|
})
|
|
2778
|
+
output_contract = _output_contract_payload(evidence, artifact_contracts)
|
|
2779
|
+
artifact_contract = _artifact_contract_payload(evidence, artifact_contracts)
|
|
2780
|
+
prefinal_checklist = _prefinal_checklist_payload(evidence, output_contract, artifact_contract)
|
|
1795
2781
|
write_json(root / "runtime_learning_package" / "runtime_learning_manifest.json", {
|
|
1796
2782
|
"source_package_id": report.get("source_package_id"),
|
|
1797
2783
|
"apprenticeship_mode": getattr(settings, "apprenticeship_mode", None),
|
|
@@ -1805,6 +2791,13 @@ def _write_experience_compiler_outputs(
|
|
|
1805
2791
|
"tool_recipe_reuse",
|
|
1806
2792
|
],
|
|
1807
2793
|
"skill_ref": "experience_compiler/skill_pack/skill.md",
|
|
2794
|
+
"transfer_runbook_ref": "experience_compiler/runtime_learning_package/transfer_runbook.md",
|
|
2795
|
+
"transfer_checklist_ref": "experience_compiler/runtime_learning_package/transfer_checklist.json",
|
|
2796
|
+
"minimal_prompt_context_ref": "experience_compiler/runtime_learning_package/minimal_prompt_context.md",
|
|
2797
|
+
"output_contract_ref": "experience_compiler/runtime_learning_package/output_contract.json",
|
|
2798
|
+
"artifact_contract_ref": "experience_compiler/runtime_learning_package/artifact_contract.json",
|
|
2799
|
+
"prefinal_verification_checklist_ref": "experience_compiler/runtime_learning_package/prefinal_verification_checklist.json",
|
|
2800
|
+
"repair_instructions_ref": "experience_compiler/runtime_learning_package/repair_instructions.md",
|
|
1808
2801
|
})
|
|
1809
2802
|
for name, rows in {
|
|
1810
2803
|
"runtime_memory.jsonl": [{"source_package_id": report.get("source_package_id"), "lesson": _task_instruction(evidence), "usable_for": ["runtime_memory"]}],
|
|
@@ -1847,6 +2840,90 @@ def _write_experience_compiler_outputs(
|
|
|
1847
2840
|
]
|
|
1848
2841
|
)
|
|
1849
2842
|
)
|
|
2843
|
+
transfer_runbook = _runtime_transfer_runbook(evidence, title, instruction, criteria, artifact_contracts)
|
|
2844
|
+
(root / "runtime_learning_package" / "transfer_runbook.md").write_text(
|
|
2845
|
+
sanitize_public_text(transfer_runbook) or transfer_runbook
|
|
2846
|
+
)
|
|
2847
|
+
minimal_context = "\n".join(
|
|
2848
|
+
[
|
|
2849
|
+
f"# Minimal Runtime Transfer Context: {title}",
|
|
2850
|
+
"",
|
|
2851
|
+
"Follow current-task instructions. Reuse only the workflow pattern and output-contract discipline from this source task.",
|
|
2852
|
+
"",
|
|
2853
|
+
"## Must Do",
|
|
2854
|
+
"- Derive outputs from current visible input files.",
|
|
2855
|
+
"- Match required filenames, CSV headers, JSON keys, and artifact roles.",
|
|
2856
|
+
"- Write `actual_outputs.json` with the generated file list.",
|
|
2857
|
+
"- Run the pre-final contract checklist before finishing.",
|
|
2858
|
+
"",
|
|
2859
|
+
"## Output Contract Pattern",
|
|
2860
|
+
*[f"- {_contract_line(contract)}" for contract in artifact_contracts[:8]],
|
|
2861
|
+
"",
|
|
2862
|
+
]
|
|
2863
|
+
)
|
|
2864
|
+
(root / "runtime_learning_package" / "minimal_prompt_context.md").write_text(minimal_context[:4000])
|
|
2865
|
+
write_json(root / "runtime_learning_package" / "output_contract.json", output_contract)
|
|
2866
|
+
write_json(root / "runtime_learning_package" / "artifact_contract.json", artifact_contract)
|
|
2867
|
+
write_json(root / "runtime_learning_package" / "prefinal_verification_checklist.json", prefinal_checklist)
|
|
2868
|
+
(root / "runtime_learning_package" / "repair_instructions.md").write_text(
|
|
2869
|
+
_repair_instructions_text(title, output_contract)
|
|
2870
|
+
)
|
|
2871
|
+
write_json(root / "runtime_learning_package" / "transfer_checklist.json", {
|
|
2872
|
+
"source_package_id": report.get("source_package_id"),
|
|
2873
|
+
"title": title,
|
|
2874
|
+
"checks": [
|
|
2875
|
+
"current_task_inputs_read",
|
|
2876
|
+
"outputs_derived_from_current_inputs",
|
|
2877
|
+
"required_filenames_created",
|
|
2878
|
+
"csv_headers_or_json_keys_match_contract",
|
|
2879
|
+
"actual_outputs_json_lists_generated_files",
|
|
2880
|
+
"local_sanity_check_completed",
|
|
2881
|
+
],
|
|
2882
|
+
"artifact_contracts": artifact_contracts,
|
|
2883
|
+
"verifier_checks": criteria[:12],
|
|
2884
|
+
})
|
|
2885
|
+
write_json(root / "runtime_learning_package" / "tool_execution_recipe.json", {
|
|
2886
|
+
"source_package_id": report.get("source_package_id"),
|
|
2887
|
+
"recommended_steps": [
|
|
2888
|
+
"inspect visible input files",
|
|
2889
|
+
"write a short deterministic Python script or shell command sequence",
|
|
2890
|
+
"run the script in the task directory",
|
|
2891
|
+
"open outputs and validate schemas",
|
|
2892
|
+
"write actual_outputs.json",
|
|
2893
|
+
],
|
|
2894
|
+
"artifact_contracts": artifact_contracts[:12],
|
|
2895
|
+
})
|
|
2896
|
+
_write_jsonl(root / "runtime_learning_package" / "output_verification_steps.jsonl", [
|
|
2897
|
+
{
|
|
2898
|
+
"source_package_id": report.get("source_package_id"),
|
|
2899
|
+
"artifact": _contract_output_path(contract),
|
|
2900
|
+
"check": _contract_line(contract),
|
|
2901
|
+
"evidence_refs": [contract.get("artifact_ref")] if contract.get("artifact_ref") else _evidence_refs(evidence)[:3],
|
|
2902
|
+
}
|
|
2903
|
+
for contract in artifact_contracts
|
|
2904
|
+
] or [{
|
|
2905
|
+
"source_package_id": report.get("source_package_id"),
|
|
2906
|
+
"artifact": "actual_outputs.json",
|
|
2907
|
+
"check": "Generated outputs are listed in actual_outputs.json.",
|
|
2908
|
+
"evidence_refs": _evidence_refs(evidence)[:3],
|
|
2909
|
+
}])
|
|
2910
|
+
_write_jsonl(root / "runtime_learning_package" / "common_errors_to_avoid.jsonl", [
|
|
2911
|
+
{
|
|
2912
|
+
"source_package_id": report.get("source_package_id"),
|
|
2913
|
+
"error": "Missing required output file or writing it outside the expected relative output location.",
|
|
2914
|
+
"avoidance": "Create every named artifact and reopen it before final response.",
|
|
2915
|
+
},
|
|
2916
|
+
{
|
|
2917
|
+
"source_package_id": report.get("source_package_id"),
|
|
2918
|
+
"error": "CSV headers or JSON keys drift from the expected artifact contract.",
|
|
2919
|
+
"avoidance": "Use the transfer checklist and write headers/keys explicitly.",
|
|
2920
|
+
},
|
|
2921
|
+
{
|
|
2922
|
+
"source_package_id": report.get("source_package_id"),
|
|
2923
|
+
"error": "actual_outputs.json exists but does not list generated files.",
|
|
2924
|
+
"avoidance": "Populate files/deliverable refs after verifying outputs on disk.",
|
|
2925
|
+
},
|
|
2926
|
+
])
|
|
1850
2927
|
for src, dst in [
|
|
1851
2928
|
("retrieval_card.json", "retrieval_card.json"),
|
|
1852
2929
|
("verifier_checklist.json", "verifier_spec.json"),
|
|
@@ -1874,8 +2951,10 @@ def _write_experience_compiler_outputs(
|
|
|
1874
2951
|
"training_uses": compiler_manifest["supported_training_uses"],
|
|
1875
2952
|
"supported_training_uses": [
|
|
1876
2953
|
"sft",
|
|
2954
|
+
"lora_ready_instruction_tuning",
|
|
1877
2955
|
"rl",
|
|
1878
2956
|
"grpo",
|
|
2957
|
+
"agentic_rollouts",
|
|
1879
2958
|
"reward_modeling",
|
|
1880
2959
|
"preference_learning",
|
|
1881
2960
|
"verifier_training",
|
|
@@ -1885,6 +2964,9 @@ def _write_experience_compiler_outputs(
|
|
|
1885
2964
|
"environment_model_training",
|
|
1886
2965
|
],
|
|
1887
2966
|
"row_counts": rows_accepted,
|
|
2967
|
+
"row_counts_by_file": training_row_counts_by_file,
|
|
2968
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
2969
|
+
"source_evidence_map_ref": "experience_compiler/source_evidence_map.json",
|
|
1888
2970
|
"no_model_training_claimed": True,
|
|
1889
2971
|
})
|
|
1890
2972
|
for src, dst in [
|
|
@@ -1897,25 +2979,65 @@ def _write_experience_compiler_outputs(
|
|
|
1897
2979
|
("preference_pairs.jsonl", "preference_pairs.jsonl"),
|
|
1898
2980
|
]:
|
|
1899
2981
|
_copy_jsonl_public(tdo_dir / src, root / "training_time_package" / dst)
|
|
1900
|
-
|
|
2982
|
+
process_rows = _process_supervision_rows_from_compiler_rows(compiler_rows)
|
|
2983
|
+
_write_jsonl(root / "training_time_package" / "process_supervision.jsonl", process_rows)
|
|
2984
|
+
rl_rollout_rows = _rl_rollout_rows_from_compiler_rows(compiler_rows)
|
|
2985
|
+
_write_jsonl(root / "training_time_package" / "agentic_rollouts.jsonl", rl_rollout_rows)
|
|
2986
|
+
_write_jsonl(root / "training_time_package" / "grpo_rollout_groups.jsonl", [
|
|
2987
|
+
{
|
|
2988
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
2989
|
+
"row_id": f"grpo_group_{_safe_id(str(report.get('source_package_id') or package_root.name))}",
|
|
2990
|
+
"data_type": "grpo_rollout_group",
|
|
2991
|
+
"source_package_id": report.get("source_package_id"),
|
|
2992
|
+
"source_task_id": report.get("source_task_id"),
|
|
2993
|
+
"task_lineage": _task_lineage(evidence),
|
|
2994
|
+
"rollout_group_id": f"rollout_{_safe_id(str(report.get('source_task_id') or package_root.name))}",
|
|
2995
|
+
"candidate_rollout_refs": [row.get("row_id") for row in rl_rollout_rows],
|
|
2996
|
+
"reward_components": ["artifact_contract", "verifier_signal", "step_success"],
|
|
2997
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:12]),
|
|
2998
|
+
"evidence_refs": _evidence_refs(evidence)[:12],
|
|
2999
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3000
|
+
"created_at": utc_now(),
|
|
3001
|
+
}
|
|
3002
|
+
] if rl_rollout_rows else [])
|
|
3003
|
+
_write_jsonl(root / "training_time_package" / "rl_environment_replay_rows.jsonl", rl_rollout_rows)
|
|
1901
3004
|
loop_pairs: list[dict[str, Any]] = []
|
|
1902
3005
|
for item in evidence.get("loop_review_packets") or []:
|
|
1903
3006
|
packet = item.get("packet") or {}
|
|
1904
3007
|
ref = item.get("ref")
|
|
1905
3008
|
loop_pairs.append({
|
|
3009
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3010
|
+
"pair_id": f"critique_revision_{_safe_id(str(report.get('source_package_id') or package_root.name))}_{packet.get('loop_iteration') or len(loop_pairs)+1}",
|
|
3011
|
+
"row_id": f"critique_revision_{_safe_id(str(report.get('source_package_id') or package_root.name))}_{packet.get('loop_iteration') or len(loop_pairs)+1}",
|
|
3012
|
+
"data_type": "critique_revision_pair",
|
|
1906
3013
|
"source_package_id": report.get("source_package_id"),
|
|
3014
|
+
"source_task_id": report.get("source_task_id"),
|
|
3015
|
+
"task_lineage": _task_lineage(evidence),
|
|
1907
3016
|
"critique": _clean_text("; ".join(packet.get("known_failures") or packet.get("recommended_review_focus") or []) or "Loop review packet recorded no blocking failure."),
|
|
1908
3017
|
"revision": _clean_text(str((packet.get("diff_from_previous_iteration") or {}).get("changed_summary") or "Use loop feedback and revision plan to ground updates.")),
|
|
1909
3018
|
"evidence_refs": [ref] if ref else _evidence_refs(evidence)[:5],
|
|
3019
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs([ref] if ref else _evidence_refs(evidence)[:5]),
|
|
1910
3020
|
"loop_iteration": packet.get("loop_iteration"),
|
|
3021
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3022
|
+
"created_at": utc_now(),
|
|
1911
3023
|
})
|
|
1912
3024
|
if not loop_pairs:
|
|
1913
3025
|
loop_pairs = [{
|
|
3026
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3027
|
+
"pair_id": f"critique_revision_{_safe_id(str(report.get('source_package_id') or package_root.name))}_fallback",
|
|
3028
|
+
"row_id": f"critique_revision_{_safe_id(str(report.get('source_package_id') or package_root.name))}_fallback",
|
|
3029
|
+
"data_type": "critique_revision_pair",
|
|
1914
3030
|
"source_package_id": report.get("source_package_id"),
|
|
3031
|
+
"source_task_id": report.get("source_task_id"),
|
|
3032
|
+
"task_lineage": _task_lineage(evidence),
|
|
1915
3033
|
"critique": "Use evaluator/verifier feedback where present; do not invent missing feedback.",
|
|
1916
3034
|
"revision": "Ground revisions in actual outputs and artifact refs.",
|
|
1917
3035
|
"evidence_refs": _evidence_refs(evidence)[:5],
|
|
3036
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:5]),
|
|
3037
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3038
|
+
"created_at": utc_now(),
|
|
1918
3039
|
}]
|
|
3040
|
+
loop_pairs.extend(loop_learning["feedback_revision_pairs"])
|
|
1919
3041
|
_write_jsonl(root / "training_time_package" / "critique_revision_pairs.jsonl", loop_pairs)
|
|
1920
3042
|
_write_jsonl(root / "training_time_package" / "trajectory_rollouts.jsonl", [{
|
|
1921
3043
|
"source_package_id": report.get("source_package_id"),
|
|
@@ -1923,17 +3045,35 @@ def _write_experience_compiler_outputs(
|
|
|
1923
3045
|
"artifact_refs": _source_artifact_refs(evidence),
|
|
1924
3046
|
}])
|
|
1925
3047
|
_write_jsonl(root / "training_time_package" / "distillation_records.jsonl", [{
|
|
3048
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3049
|
+
"row_id": f"distill_{_safe_id(str(report.get('source_package_id') or package_root.name))}",
|
|
3050
|
+
"data_type": "distillation_record",
|
|
1926
3051
|
"source_package_id": report.get("source_package_id"),
|
|
3052
|
+
"source_task_id": report.get("source_task_id"),
|
|
3053
|
+
"task_lineage": _task_lineage(evidence),
|
|
1927
3054
|
"input": instruction,
|
|
1928
3055
|
"target": _output_summary(evidence),
|
|
1929
3056
|
"evidence_refs": _evidence_refs(evidence)[:8],
|
|
3057
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:8]),
|
|
3058
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3059
|
+
"created_at": utc_now(),
|
|
1930
3060
|
}])
|
|
1931
3061
|
_write_jsonl(root / "training_time_package" / "transfer_eval_tasks.jsonl", [
|
|
1932
3062
|
{
|
|
3063
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3064
|
+
"row_id": f"transfer_eval_{_safe_id(str(report.get('source_package_id') or package_root.name))}",
|
|
3065
|
+
"data_type": "transfer_eval_task",
|
|
1933
3066
|
"source_package_id": report.get("source_package_id"),
|
|
3067
|
+
"source_task_id": report.get("source_task_id"),
|
|
3068
|
+
"task_lineage": _task_lineage(evidence),
|
|
1934
3069
|
"task": f"Replay a small adjacent {(_task_title(evidence) or 'workflow')} task and compare artifact quality.",
|
|
1935
3070
|
"success_signal": "bundle check passes and verifier/evaluator evidence refs are present",
|
|
1936
3071
|
"transfer_tested": False,
|
|
3072
|
+
"expected_output_contract": output_contract,
|
|
3073
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:8]),
|
|
3074
|
+
"evidence_refs": _evidence_refs(evidence)[:8],
|
|
3075
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3076
|
+
"created_at": utc_now(),
|
|
1937
3077
|
}
|
|
1938
3078
|
])
|
|
1939
3079
|
write_json(root / "reports" / "transfer_test_report.json", {
|
|
@@ -1943,17 +3083,155 @@ def _write_experience_compiler_outputs(
|
|
|
1943
3083
|
_copy_jsonl_public(tdo_dir / "evaluation_examples.jsonl", root / "eval_package" / "evaluation_examples.jsonl")
|
|
1944
3084
|
shutil.copy2(root / "training_time_package" / "transfer_eval_tasks.jsonl", root / "eval_package" / "transfer_eval_tasks.jsonl")
|
|
1945
3085
|
shutil.copy2(root / "reports" / "transfer_test_report.json", root / "eval_package" / "transfer_test_report.json")
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
3086
|
+
write_json(root / "eval_package" / "eval_manifest.json", {
|
|
3087
|
+
"schema_version": "aa-eval-package-v0.2",
|
|
3088
|
+
"source_package_id": report.get("source_package_id"),
|
|
3089
|
+
"source_task_id": report.get("source_task_id"),
|
|
3090
|
+
"task_lineage": _task_lineage(evidence),
|
|
3091
|
+
"source_evidence_map_ref": "experience_compiler/source_evidence_map.json",
|
|
3092
|
+
"output_contract_ref": "experience_compiler/runtime_learning_package/output_contract.json",
|
|
3093
|
+
"artifact_contract_ref": "experience_compiler/runtime_learning_package/artifact_contract.json",
|
|
3094
|
+
"supported_eval_uses": ["rubric_eval", "contract_verifier_training", "transfer_eval_generation", "grader_case_generation"],
|
|
3095
|
+
})
|
|
3096
|
+
_write_jsonl(root / "eval_package" / "rubric_items.jsonl", [
|
|
3097
|
+
{
|
|
3098
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3099
|
+
"row_id": f"eval_rubric_{_safe_id(str(report.get('source_package_id') or package_root.name))}_{idx}",
|
|
3100
|
+
"data_type": "eval_rubric_item",
|
|
3101
|
+
"source_package_id": report.get("source_package_id"),
|
|
3102
|
+
"source_task_id": report.get("source_task_id"),
|
|
3103
|
+
"task_lineage": _task_lineage(evidence),
|
|
3104
|
+
"rubric_item": item,
|
|
3105
|
+
"scoring_criterion": item,
|
|
3106
|
+
"evidence_refs": _evidence_refs(evidence)[:5],
|
|
3107
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:5]),
|
|
3108
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3109
|
+
"created_at": utc_now(),
|
|
3110
|
+
}
|
|
3111
|
+
for idx, item in enumerate(criteria, start=1)
|
|
3112
|
+
])
|
|
3113
|
+
_write_jsonl(root / "eval_package" / "grader_cases.jsonl", [{
|
|
3114
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3115
|
+
"row_id": f"grader_case_{_safe_id(str(report.get('source_package_id') or package_root.name))}",
|
|
3116
|
+
"data_type": "grader_case",
|
|
3117
|
+
"source_package_id": report.get("source_package_id"),
|
|
3118
|
+
"source_task_id": report.get("source_task_id"),
|
|
3119
|
+
"task_lineage": _task_lineage(evidence),
|
|
3120
|
+
"case": "Grade output against compiled rubric and artifact evidence.",
|
|
3121
|
+
"output_contract": output_contract,
|
|
3122
|
+
"artifact_contract": artifact_contract,
|
|
3123
|
+
"evidence_refs": _evidence_refs(evidence)[:5],
|
|
3124
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:5]),
|
|
3125
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3126
|
+
"created_at": utc_now(),
|
|
3127
|
+
}])
|
|
3128
|
+
_write_jsonl(root / "eval_package" / "verifier_cases.jsonl", [{
|
|
3129
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3130
|
+
"row_id": f"verifier_case_{_safe_id(str(report.get('source_package_id') or package_root.name))}",
|
|
3131
|
+
"data_type": "verifier_case",
|
|
3132
|
+
"source_package_id": report.get("source_package_id"),
|
|
3133
|
+
"source_task_id": report.get("source_task_id"),
|
|
3134
|
+
"task_lineage": _task_lineage(evidence),
|
|
3135
|
+
"claim_or_output": "Required artifacts and output refs exist and match the contract.",
|
|
3136
|
+
"visible_evidence": _source_artifact_refs(evidence)[:12],
|
|
3137
|
+
"expected_contract": output_contract,
|
|
3138
|
+
"verifier_decision": "case_requires_future_candidate_output",
|
|
3139
|
+
"failure_reasons": [],
|
|
3140
|
+
"evidence_refs": _evidence_refs(evidence)[:5],
|
|
3141
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:5]),
|
|
3142
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3143
|
+
"created_at": utc_now(),
|
|
3144
|
+
}])
|
|
3145
|
+
_write_jsonl(root / "eval_package" / "expected_artifacts.jsonl", [
|
|
3146
|
+
{
|
|
3147
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3148
|
+
"row_id": f"expected_artifact_{_safe_id(str(report.get('source_package_id') or package_root.name))}_{idx}",
|
|
3149
|
+
"data_type": "expected_artifact",
|
|
3150
|
+
"source_package_id": report.get("source_package_id"),
|
|
3151
|
+
"source_task_id": report.get("source_task_id"),
|
|
3152
|
+
"task_lineage": _task_lineage(evidence),
|
|
3153
|
+
"artifact_ref": ref,
|
|
3154
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs([ref]),
|
|
3155
|
+
"evidence_refs": [ref],
|
|
3156
|
+
"confidence": 1.0,
|
|
3157
|
+
"created_at": utc_now(),
|
|
3158
|
+
}
|
|
3159
|
+
for idx, ref in enumerate(_source_artifact_refs(evidence), start=1)
|
|
3160
|
+
])
|
|
1950
3161
|
env_spec = _environment_spec(evidence)
|
|
1951
|
-
write_json(root / "environment" / "
|
|
1952
|
-
|
|
1953
|
-
|
|
3162
|
+
write_json(root / "environment" / "environment_manifest.json", {
|
|
3163
|
+
"schema_version": "aa-environment-package-v0.2",
|
|
3164
|
+
"source_package_id": report.get("source_package_id"),
|
|
3165
|
+
"source_task_id": report.get("source_task_id"),
|
|
3166
|
+
"task_lineage": _task_lineage(evidence),
|
|
3167
|
+
"environment_spec_ref": "experience_compiler/environment/environment_spec.json",
|
|
3168
|
+
"state_transition_rows_ref": "experience_compiler/environment/state_transition_rows.jsonl",
|
|
3169
|
+
"replay_plan_ref": "experience_compiler/environment/replay_plan.json",
|
|
3170
|
+
"source_evidence_map_ref": "experience_compiler/source_evidence_map.json",
|
|
3171
|
+
"supported_training_uses": ["agentic_rl", "grpo_rollout_material", "environment_model_training", "replay_smoke_testing"],
|
|
3172
|
+
})
|
|
3173
|
+
write_json(root / "environment" / "replay_plan.json", {
|
|
3174
|
+
"schema_version": "aa-replay-plan-v0.2",
|
|
3175
|
+
"source_package_id": report.get("source_package_id"),
|
|
3176
|
+
"source_task_id": report.get("source_task_id"),
|
|
3177
|
+
"task_lineage": _task_lineage(evidence),
|
|
3178
|
+
"replay_available": bool(env_spec.get("verification_commands")),
|
|
3179
|
+
"initial_state_refs": env_spec.get("initial_state_refs") or [],
|
|
3180
|
+
"visible_input_refs": env_spec.get("input_artifacts") or [],
|
|
3181
|
+
"action_schema_ref": "experience_compiler/environment/allowed_actions.jsonl",
|
|
3182
|
+
"observation_schema": {"observation": "string", "artifact_refs": "array", "state_after": "string"},
|
|
3183
|
+
"scoring_or_verifier_hooks": env_spec.get("scoring_refs") or [],
|
|
3184
|
+
"termination_conditions": ["task_complete", "contract_verified", "max_iterations_reached"],
|
|
3185
|
+
"reward_function_components": ["artifact_contract", "verifier_signal", "step_success"],
|
|
3186
|
+
"generation_note": "Replay is task-dependent; use environment_spec and verifier checks.",
|
|
3187
|
+
})
|
|
3188
|
+
write_json(root / "environment" / "setup_requirements.json", {
|
|
3189
|
+
"schema_version": "aa-environment-setup-v0.2",
|
|
3190
|
+
"source_package_id": report.get("source_package_id"),
|
|
3191
|
+
"required_tools": env_spec.get("required_tools") or [],
|
|
3192
|
+
"runtime_dependencies": env_spec.get("runtime_dependencies") or [],
|
|
3193
|
+
"dependency_metadata": env_spec.get("software_execution") or {},
|
|
3194
|
+
})
|
|
3195
|
+
_write_jsonl(root / "environment" / "allowed_actions.jsonl", [
|
|
3196
|
+
{
|
|
3197
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3198
|
+
"row_id": f"allowed_action_{_safe_id(str(report.get('source_package_id') or package_root.name))}_{idx}",
|
|
3199
|
+
"data_type": "allowed_action",
|
|
3200
|
+
"source_package_id": report.get("source_package_id"),
|
|
3201
|
+
"source_task_id": report.get("source_task_id"),
|
|
3202
|
+
"task_lineage": _task_lineage(evidence),
|
|
3203
|
+
"action": action,
|
|
3204
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:3]),
|
|
3205
|
+
"evidence_refs": _evidence_refs(evidence)[:3],
|
|
3206
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3207
|
+
"created_at": utc_now(),
|
|
3208
|
+
}
|
|
3209
|
+
for idx, action in enumerate((env_spec.get("allowed_actions") or ["read_task", "write_artifact", "verify_output"]), start=1)
|
|
3210
|
+
])
|
|
1954
3211
|
_copy_jsonl_public(tdo_dir / "environment_response_pairs.jsonl", root / "environment" / "state_transition_rows.jsonl")
|
|
1955
|
-
write_json(root / "environment" / "reset_strategy.json", {
|
|
1956
|
-
|
|
3212
|
+
write_json(root / "environment" / "reset_strategy.json", {
|
|
3213
|
+
"schema_version": "aa-environment-reset-v0.2",
|
|
3214
|
+
"source_package_id": report.get("source_package_id"),
|
|
3215
|
+
"reset_strategy": env_spec.get("reset_strategy") or "unknown",
|
|
3216
|
+
"state_reset_refs": env_spec.get("initial_state_refs") or [],
|
|
3217
|
+
"generation_notes": env_spec.get("evidence_status") or [],
|
|
3218
|
+
})
|
|
3219
|
+
_write_jsonl(root / "environment" / "verification_commands.jsonl", [
|
|
3220
|
+
{
|
|
3221
|
+
"schema_version": TRAINING_ROW_SCHEMA_VERSION,
|
|
3222
|
+
"row_id": f"verification_command_{_safe_id(str(report.get('source_package_id') or package_root.name))}_{idx}",
|
|
3223
|
+
"data_type": "verification_command",
|
|
3224
|
+
"source_package_id": report.get("source_package_id"),
|
|
3225
|
+
"source_task_id": report.get("source_task_id"),
|
|
3226
|
+
"task_lineage": _task_lineage(evidence),
|
|
3227
|
+
"command": command,
|
|
3228
|
+
"source_evidence_ref_ids": _evidence_ids_for_refs(_evidence_refs(evidence)[:3]),
|
|
3229
|
+
"evidence_refs": _evidence_refs(evidence)[:3],
|
|
3230
|
+
"confidence": report.get("average_quality_score") or 0.5,
|
|
3231
|
+
"created_at": utc_now(),
|
|
3232
|
+
}
|
|
3233
|
+
for idx, command in enumerate((env_spec.get("verification_commands") or []), start=1)
|
|
3234
|
+
])
|
|
1957
3235
|
(root / "reports" / "generation_notes.md").write_text(
|
|
1958
3236
|
"\n".join([
|
|
1959
3237
|
"# Generation Notes",
|
|
@@ -1969,6 +3247,7 @@ def _write_experience_compiler_outputs(
|
|
|
1969
3247
|
{"kind": "runtime_learning_package", "path": "experience_compiler/runtime_learning_package/runtime_learning_manifest.json"},
|
|
1970
3248
|
{"kind": "training_time_package", "path": "experience_compiler/training_time_package/training_time_manifest.json"},
|
|
1971
3249
|
{"kind": "environment", "path": "experience_compiler/environment/environment_spec.json"},
|
|
3250
|
+
{"kind": "loop_learning", "path": "experience_compiler/loop_learning/loop_review_rows.jsonl"},
|
|
1972
3251
|
{"kind": "reports", "path": "experience_compiler/compiler_report.json"},
|
|
1973
3252
|
],
|
|
1974
3253
|
"rows_by_type": rows_accepted,
|