diff --git a/README.md b/README.md index 9cab63c9..5ca6cc18 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,16 @@ python3 scripts/first_oracle_packet_assistant.py --front shadbala --format markd 该助手不会生成或猜测 JHora/PyJHora 真值,只会列出当前 packet 还缺哪些字段、可用外部来源、apply 命令和 validator 命令。 +如需先看三条硬闭环 front 的统一排序入口,而不是分别运行三个助手: + +```bash +python3 scripts/oracle_packet_assistant_index.py \ + --format markdown \ + --output docs/benchmark/first_oracle_packet_assistant_index.md +``` + +该索引会固定列出 `dasha`、`tajika_sahams`、`shadbala` 三条 front 的首包 case、缺失字段数、operator card 与推荐执行顺序,方便直接判断当前最短闭环路径。 + Shadbala 外部绝对值闭环使用独立状态板,专门追踪七曜的六分量与总 Rupa: ```bash diff --git a/docs/benchmark/first_oracle_packet_assistant_index.json b/docs/benchmark/first_oracle_packet_assistant_index.json new file mode 100644 index 00000000..79d3559c --- /dev/null +++ b/docs/benchmark/first_oracle_packet_assistant_index.json @@ -0,0 +1,71 @@ +{ + "scope": "first_oracle_packet_assistant_index", + "schema_version": 1, + "generated_at": "2026-06-26T11:10:58.996169+00:00", + "summary": { + "front_count": 3, + "all_ready_to_apply": false + }, + "fronts": { + "dasha": { + "case_id": "template_steve_jobs_dasha_lahiri", + "capture_id": "external_template_steve_jobs_dasha_lahiri", + "operator_card": "docs/benchmark/dasha_steve_jobs_first_packet_operator_card.md", + "packet_template": "references/oracle/evidence_packet_templates/dasha_steve_jobs_lahiri_first_packet_only.json", + "missing_field_count": 6, + "ready_to_apply": false, + "apply_command": "python3 scripts/oracle_collection_queue.py --oracle-file references/oracle/dasha_shadbala_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/dasha_steve_jobs_lahiri_first_packet_only.json --format json" + }, + "tajika_sahams": { + "case_id": "template_steve_jobs_varshaphala_1984_lahiri", + "capture_id": "external_template_steve_jobs_varshaphala_1984_lahiri", + "operator_card": "docs/benchmark/tajika_steve_jobs_1984_first_packet_operator_card.md", + "packet_template": "references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json", + "missing_field_count": 15, + "ready_to_apply": false, + "apply_command": "python3 scripts/tajika_annual_oracle_queue.py --oracle-file references/oracle/tajika_annual_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json --format json" + }, + "shadbala": { + "case_id": "template_redacted_place_shadbala_raman", + "capture_id": "external_template_redacted_place_shadbala_raman", + "operator_card": "docs/benchmark/shadbala_redacted_place_raman_first_packet_operator_card.md", + "packet_template": "references/oracle/evidence_packet_templates/shadbala_redacted_place_raman_first_packet.json", + "missing_field_count": 55, + "ready_to_apply": false, + "apply_command": "python3 scripts/oracle_collection_queue.py --oracle-file references/oracle/dasha_shadbala_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/shadbala_redacted_place_raman_first_packet.json --format json" + } + }, + "recommended_order": [ + { + "front": "dasha", + "case_id": "template_steve_jobs_dasha_lahiri", + "capture_id": "external_template_steve_jobs_dasha_lahiri", + "operator_card": "docs/benchmark/dasha_steve_jobs_first_packet_operator_card.md", + "packet_template": "references/oracle/evidence_packet_templates/dasha_steve_jobs_lahiri_first_packet_only.json", + "missing_field_count": 6, + "ready_to_apply": false, + "apply_command": "python3 scripts/oracle_collection_queue.py --oracle-file references/oracle/dasha_shadbala_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/dasha_steve_jobs_lahiri_first_packet_only.json --format json" + }, + { + "front": "tajika_sahams", + "case_id": "template_steve_jobs_varshaphala_1984_lahiri", + "capture_id": "external_template_steve_jobs_varshaphala_1984_lahiri", + "operator_card": "docs/benchmark/tajika_steve_jobs_1984_first_packet_operator_card.md", + "packet_template": "references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json", + "missing_field_count": 15, + "ready_to_apply": false, + "apply_command": "python3 scripts/tajika_annual_oracle_queue.py --oracle-file references/oracle/tajika_annual_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json --format json" + }, + { + "front": "shadbala", + "case_id": "template_redacted_place_shadbala_raman", + "capture_id": "external_template_redacted_place_shadbala_raman", + "operator_card": "docs/benchmark/shadbala_redacted_place_raman_first_packet_operator_card.md", + "packet_template": "references/oracle/evidence_packet_templates/shadbala_redacted_place_raman_first_packet.json", + "missing_field_count": 55, + "ready_to_apply": false, + "apply_command": "python3 scripts/oracle_collection_queue.py --oracle-file references/oracle/dasha_shadbala_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/shadbala_redacted_place_raman_first_packet.json --format json" + } + ], + "boundary": "This index aggregates packet assistants only. It does not create oracle values, does not validate packets by itself, and does not change oracle files." +} \ No newline at end of file diff --git a/docs/benchmark/first_oracle_packet_assistant_index.md b/docs/benchmark/first_oracle_packet_assistant_index.md new file mode 100644 index 00000000..efe71e2e --- /dev/null +++ b/docs/benchmark/first_oracle_packet_assistant_index.md @@ -0,0 +1,47 @@ +# First Oracle Packet Assistant Index + +Generated: `2026-06-26T11:10:59.664177+00:00` + +## Fronts + +| front | case_id | missing fields | ready_to_apply | +|---|---|---:|---| +| `dasha` | `template_steve_jobs_dasha_lahiri` | 6 | `false` | +| `tajika_sahams` | `template_steve_jobs_varshaphala_1984_lahiri` | 15 | `false` | +| `shadbala` | `template_redacted_place_shadbala_raman` | 55 | `false` | + +## Recommended Order + +### dasha + +- case_id: `template_steve_jobs_dasha_lahiri` +- missing_field_count: `6` +- operator_card: `docs/benchmark/dasha_steve_jobs_first_packet_operator_card.md` + +```bash +python3 scripts/oracle_collection_queue.py --oracle-file references/oracle/dasha_shadbala_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/dasha_steve_jobs_lahiri_first_packet_only.json --format json +``` + +### tajika_sahams + +- case_id: `template_steve_jobs_varshaphala_1984_lahiri` +- missing_field_count: `15` +- operator_card: `docs/benchmark/tajika_steve_jobs_1984_first_packet_operator_card.md` + +```bash +python3 scripts/tajika_annual_oracle_queue.py --oracle-file references/oracle/tajika_annual_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/tajika_steve_jobs_1984_first_packet.json --format json +``` + +### shadbala + +- case_id: `template_redacted_place_shadbala_raman` +- missing_field_count: `55` +- operator_card: `docs/benchmark/shadbala_redacted_place_raman_first_packet_operator_card.md` + +```bash +python3 scripts/oracle_collection_queue.py --oracle-file references/oracle/dasha_shadbala_oracle_cases.json --apply-packet references/oracle/evidence_packet_templates/shadbala_redacted_place_raman_first_packet.json --format json +``` + +## Boundary + +This index aggregates packet assistants only. It does not create oracle values, does not validate packets by itself, and does not change oracle files. diff --git a/scripts/oracle_packet_assistant_index.py b/scripts/oracle_packet_assistant_index.py new file mode 100644 index 00000000..23076ee7 --- /dev/null +++ b/scripts/oracle_packet_assistant_index.py @@ -0,0 +1,124 @@ +#!/usr/bin/env python3 +"""Aggregate the first-oracle packet assistants into one index.""" + +from __future__ import annotations + +import argparse +import json +import subprocess +import sys +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +PYTHON = sys.executable +FRONTS = ["dasha", "tajika_sahams", "shadbala"] + + +def _run_json(command: list[str]) -> dict[str, Any]: + completed = subprocess.run( + command, + cwd=ROOT, + text=True, + capture_output=True, + timeout=90, + check=False, + ) + if completed.returncode != 0: + raise RuntimeError(completed.stderr.strip() or completed.stdout.strip()) + return json.loads(completed.stdout) + + +def build_index() -> dict[str, Any]: + fronts: dict[str, Any] = {} + for front in FRONTS: + report = _run_json([PYTHON, "scripts/first_oracle_packet_assistant.py", "--front", front, "--format", "json"]) + fronts[front] = { + "case_id": report["case_id"], + "capture_id": report["capture_id"], + "operator_card": report["operator_card"], + "packet_template": report["packet_template"], + "missing_field_count": len(report["missing_fields"]), + "ready_to_apply": report["ready_to_apply"], + "apply_command": report["apply_command"], + } + recommended_order = sorted( + [{"front": front, **fronts[front]} for front in FRONTS], + key=lambda item: item["missing_field_count"], + ) + return { + "scope": "first_oracle_packet_assistant_index", + "schema_version": 1, + "generated_at": datetime.now(timezone.utc).isoformat(), + "summary": { + "front_count": len(FRONTS), + "all_ready_to_apply": all(fronts[front]["ready_to_apply"] for front in FRONTS), + }, + "fronts": fronts, + "recommended_order": recommended_order, + "boundary": ( + "This index aggregates packet assistants only. It does not create oracle values, " + "does not validate packets by itself, and does not change oracle files." + ), + } + + +def render_markdown(report: dict[str, Any]) -> str: + lines = [ + "# First Oracle Packet Assistant Index", + "", + f"Generated: `{report['generated_at']}`", + "", + "## Fronts", + "", + "| front | case_id | missing fields | ready_to_apply |", + "|---|---|---:|---|", + ] + for front in FRONTS: + row = report["fronts"][front] + lines.append( + f"| `{front}` | `{row['case_id']}` | {row['missing_field_count']} | `{str(row['ready_to_apply']).lower()}` |" + ) + lines.extend(["", "## Recommended Order", ""]) + for item in report["recommended_order"]: + lines.extend( + [ + f"### {item['front']}", + "", + f"- case_id: `{item['case_id']}`", + f"- missing_field_count: `{item['missing_field_count']}`", + f"- operator_card: `{item['operator_card']}`", + "", + "```bash", + item["apply_command"], + "```", + "", + ] + ) + lines.extend(["## Boundary", "", report["boundary"], ""]) + return "\n".join(lines) + + +def parse_args(argv: list[str] | None = None) -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Aggregate first-oracle packet assistants") + parser.add_argument("--format", choices=["json", "markdown"], default="json") + parser.add_argument("--output", help="Optional output path") + return parser.parse_args(argv) + + +def main(argv: list[str] | None = None) -> int: + args = parse_args(argv) + report = build_index() + text = json.dumps(report, ensure_ascii=False, indent=2) if args.format == "json" else render_markdown(report) + if args.output: + output = Path(args.output) + output.parent.mkdir(parents=True, exist_ok=True) + output.write_text(text, encoding="utf-8") + print(text) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_oracle_packet_assistant_index.py b/tests/test_oracle_packet_assistant_index.py new file mode 100644 index 00000000..9c46cf3d --- /dev/null +++ b/tests/test_oracle_packet_assistant_index.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +"""Tests for the unified first-oracle packet assistant index.""" + +from __future__ import annotations + +import json +import subprocess +import sys +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] + + +def run_index(*args: str) -> subprocess.CompletedProcess[str]: + return subprocess.run( + [ + sys.executable, + "scripts/oracle_packet_assistant_index.py", + *args, + ], + cwd=ROOT, + text=True, + capture_output=True, + timeout=90, + check=False, + ) + + +def test_oracle_packet_assistant_index_aggregates_three_fronts() -> None: + completed = run_index("--format", "json") + + assert completed.returncode == 0, completed.stderr or completed.stdout + report = json.loads(completed.stdout) + assert report["scope"] == "first_oracle_packet_assistant_index" + assert report["schema_version"] == 1 + assert report["summary"]["front_count"] == 3 + assert report["summary"]["all_ready_to_apply"] is False + assert report["fronts"]["dasha"]["missing_field_count"] == 6 + assert report["fronts"]["tajika_sahams"]["missing_field_count"] == 15 + assert report["fronts"]["shadbala"]["missing_field_count"] == 55 + assert report["recommended_order"][0]["front"] == "dasha" + assert report["recommended_order"][1]["front"] == "tajika_sahams" + assert report["recommended_order"][2]["front"] == "shadbala" + + +def test_oracle_packet_assistant_index_markdown_can_be_written(tmp_path: Path) -> None: + output = tmp_path / "assistant_index.md" + completed = run_index("--format", "markdown", "--output", str(output)) + + assert completed.returncode == 0, completed.stderr or completed.stdout + assert output.exists() + markdown = output.read_text(encoding="utf-8") + assert "# First Oracle Packet Assistant Index" in markdown + assert "dasha" in markdown + assert "tajika_sahams" in markdown + assert "shadbala" in markdown + assert "6" in markdown + assert "15" in markdown + assert "55" in markdown