runops 2.4.0__tar.gz → 2.6.0__tar.gz
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.
- {runops-2.4.0 → runops-2.6.0}/PKG-INFO +6 -1
- {runops-2.4.0 → runops-2.6.0}/README.md +5 -0
- {runops-2.4.0 → runops-2.6.0}/SPEC.md +69 -12
- {runops-2.4.0 → runops-2.6.0}/docs/adapter.md +4 -2
- {runops-2.4.0 → runops-2.6.0}/docs/guide.md +48 -3
- {runops-2.4.0 → runops-2.6.0}/docs/reference.md +20 -6
- {runops-2.4.0 → runops-2.6.0}/pyproject.toml +1 -1
- {runops-2.4.0 → runops-2.6.0}/src/runops/__init__.py +1 -1
- {runops-2.4.0 → runops-2.6.0}/src/runops/cli.py +26 -2
- {runops-2.4.0 → runops-2.6.0}/src/runops/harness.py +15 -3
- {runops-2.4.0 → runops-2.6.0}/src/runops/manifest.py +8 -0
- runops-2.6.0/src/runops/ops/analysis.py +113 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/common.py +2 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/create.py +18 -4
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/notes.py +2 -0
- runops-2.6.0/src/runops/ops/progress.py +197 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/setup.py +3 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/skills.py +25 -14
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/sync.py +8 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/tidy.py +80 -3
- {runops-2.4.0 → runops-2.6.0}/src/runops/project.py +9 -3
- runops-2.6.0/src/runops/skills/runops-analyze/SKILL.md +40 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/skills/runops-check-status/SKILL.md +5 -2
- {runops-2.4.0 → runops-2.6.0}/src/runops/skills/runops-create-run/SKILL.md +1 -1
- {runops-2.4.0 → runops-2.6.0}/src/runops/skills/runops-reference/SKILL.md +5 -3
- {runops-2.4.0 → runops-2.6.0}/src/runops/skills/runops-tidy/SKILL.md +4 -0
- runops-2.6.0/tests/test_analysis_layout.py +311 -0
- runops-2.6.0/tests/test_progress.py +120 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_run_job.py +12 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_skills.py +10 -1
- {runops-2.4.0 → runops-2.6.0}/uv.lock +1 -1
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/check/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/improve-harness/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/agents/openai.yaml +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/examples/refactor-request.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/references/anti-patterns.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/references/api-compatibility.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/references/packaging-modernization.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/references/refactor-playbook.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/references/verification.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/scripts/api_surface_snapshot.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/scripts/import_smoke.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/scripts/inspect_python_package.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/python-package-refactor/scripts/refactor_quality_gate.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/release/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/simulator-adapter/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/spec-reviewer/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.agents/skills/sync-docs/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/agents/spec-reviewer.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/rules/architecture.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/rules/dev-workflow.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/rules/gotchas.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/settings.json +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/skills/check/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/skills/improve-harness/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/skills/python-package-refactor/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/skills/release/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/skills/simulator-adapter/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/skills/spec-reviewer/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.claude/skills/sync-docs/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.codex/README.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/.codex/agents/spec-reviewer.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/.codex/config.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/.codex/rules/runops.rules +0 -0
- {runops-2.4.0 → runops-2.6.0}/.dockerignore +0 -0
- {runops-2.4.0 → runops-2.6.0}/.gitattributes +0 -0
- {runops-2.4.0 → runops-2.6.0}/.github/assets/conversation-dark.svg +0 -0
- {runops-2.4.0 → runops-2.6.0}/.github/assets/conversation-light.svg +0 -0
- {runops-2.4.0 → runops-2.6.0}/.github/assets/hero-dark.svg +0 -0
- {runops-2.4.0 → runops-2.6.0}/.github/assets/hero-light.svg +0 -0
- {runops-2.4.0 → runops-2.6.0}/.github/assets/make_readme_art.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/.github/workflows/ci.yml +0 -0
- {runops-2.4.0 → runops-2.6.0}/.github/workflows/publish.yml +0 -0
- {runops-2.4.0 → runops-2.6.0}/.gitignore +0 -0
- {runops-2.4.0 → runops-2.6.0}/.harness/manifest.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/.pre-commit-config.yaml +0 -0
- {runops-2.4.0 → runops-2.6.0}/.vscode/settings.json +0 -0
- {runops-2.4.0 → runops-2.6.0}/AGENTS.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/CLAUDE.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/LICENSE +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/adapters/__init__.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/adapters/base.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/adapters/generic.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/adapters/registry.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/case.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/config.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/errors.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/jobgen.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/launchers.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/legacy_adapters/__init__.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/legacy_adapters/beach.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/legacy_adapters/emses.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/__init__.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/listing.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/migrate.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/ops/submit.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/runtime.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/skills/runops-maintain/SKILL.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/slurm.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/src/runops/util.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/__init__.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/conftest.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/.codex/rules/a.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/.runops/test-runs/T20260701-0001/receipt.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/.runops/work/beach-x-abc/bin/beach +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/AGENTS.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/CLAUDE.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/cases/beach/plane/beach.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/cases/beach/plane/case.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/cases/old/beach.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/cases/old/case.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/launchers.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/research/CURRENT.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runops.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runs/AGENTS.md +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runs/_archive/plane/R20260601-0001/manifest.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runs/plane/R20260701-0001--a/input/beach.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runs/plane/R20260701-0001--a/manifest.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runs/plane/R20260702-0001/manifest.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runs/scan/R20260701-0002/manifest.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/runs/scan/survey.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/simulators.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/fixtures/v1-project/site.toml +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/golden/mpi_standard.sh +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/golden/openmp_rsc.sh +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_adapters.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_archive_series.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_build.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_dev_harness.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_jobgen.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_legacy_adapters.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_lifecycle.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_manifest_config.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_migrate.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_mv_naming.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_project_scope.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_safety.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_scratch_tidy.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_setup_misc.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_sweep.py +0 -0
- {runops-2.4.0 → runops-2.6.0}/tests/test_sync_evidence.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: runops
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.0
|
|
4
4
|
Summary: Run ledger and Slurm job submission for HPC simulation projects
|
|
5
5
|
Project-URL: Homepage, https://github.com/Nkzono99/runops
|
|
6
6
|
Project-URL: Documentation, https://github.com/Nkzono99/runops/blob/main/docs/reference.md
|
|
@@ -76,6 +76,7 @@ runo init
|
|
|
76
76
|
| 資源を変えて作り直す | R20261015-0003 を 256 並列・72 時間で作り直して(case はそのまま) |
|
|
77
77
|
| 片付ける | 古い run を整理して。消すものと archive するものを先に見せて |
|
|
78
78
|
| 作り直した旧系列を片付ける | 旧系列は新系列で置き換えたので、対応を記録して archive して |
|
|
79
|
+
| 解析する | この系列の速度を比較して。図とスクリプト、調査メモを系列の `_analysis/` にまとめて |
|
|
79
80
|
| simulator を足す | パッチを当てた ~/BEACH-dev をビルドして、別の simulator として登録して |
|
|
80
81
|
| 更新する | runops と simulator を最新にして |
|
|
81
82
|
| v1 から移る | この project を runops v2 に移行して(`runo migrate-v1` を dry-run で確認してから) |
|
|
@@ -100,15 +101,19 @@ lunar-sheath/
|
|
|
100
101
|
│ │ │ ├── work/ Slurm のログと出力
|
|
101
102
|
│ │ │ └── analysis/
|
|
102
103
|
│ │ └── wc-phiz-scan/ sweep はまとめて 1 階層
|
|
104
|
+
│ │ └── _analysis/ 系列・sweep の比較調査(topic ごと)
|
|
103
105
|
│ ├── _scratch/ smoke / debug(期限付き)
|
|
104
106
|
│ └── _archive/ archive した run
|
|
105
107
|
├── LOG.md run をまたぐ結論と次の判断
|
|
106
108
|
├── notes/ 再利用する知見
|
|
109
|
+
├── analysis/ 複数系列にまたがる調査。共通コードは lib/
|
|
107
110
|
└── AGENTS.md, .agents/skills/, .claude/skills/
|
|
108
111
|
```
|
|
109
112
|
|
|
110
113
|
run は ID が変わらないので、directory を移動してもエージェントは見つけられます。
|
|
111
114
|
`work/` は Git の対象外で、`manifest.toml`、`input/`、`job.sh` は Git で追えます。
|
|
115
|
+
解析は依存する run の範囲で置き場所を選び、調査ごとに `README.md`、`scripts/`、`out/`、
|
|
116
|
+
`logs/` をまとめます。判断は `LOG.md` からリンクし、古い解析 job の log は整理候補になります。
|
|
112
117
|
|
|
113
118
|
## 対応 simulator
|
|
114
119
|
|
|
@@ -45,6 +45,7 @@ runo init
|
|
|
45
45
|
| 資源を変えて作り直す | R20261015-0003 を 256 並列・72 時間で作り直して(case はそのまま) |
|
|
46
46
|
| 片付ける | 古い run を整理して。消すものと archive するものを先に見せて |
|
|
47
47
|
| 作り直した旧系列を片付ける | 旧系列は新系列で置き換えたので、対応を記録して archive して |
|
|
48
|
+
| 解析する | この系列の速度を比較して。図とスクリプト、調査メモを系列の `_analysis/` にまとめて |
|
|
48
49
|
| simulator を足す | パッチを当てた ~/BEACH-dev をビルドして、別の simulator として登録して |
|
|
49
50
|
| 更新する | runops と simulator を最新にして |
|
|
50
51
|
| v1 から移る | この project を runops v2 に移行して(`runo migrate-v1` を dry-run で確認してから) |
|
|
@@ -69,15 +70,19 @@ lunar-sheath/
|
|
|
69
70
|
│ │ │ ├── work/ Slurm のログと出力
|
|
70
71
|
│ │ │ └── analysis/
|
|
71
72
|
│ │ └── wc-phiz-scan/ sweep はまとめて 1 階層
|
|
73
|
+
│ │ └── _analysis/ 系列・sweep の比較調査(topic ごと)
|
|
72
74
|
│ ├── _scratch/ smoke / debug(期限付き)
|
|
73
75
|
│ └── _archive/ archive した run
|
|
74
76
|
├── LOG.md run をまたぐ結論と次の判断
|
|
75
77
|
├── notes/ 再利用する知見
|
|
78
|
+
├── analysis/ 複数系列にまたがる調査。共通コードは lib/
|
|
76
79
|
└── AGENTS.md, .agents/skills/, .claude/skills/
|
|
77
80
|
```
|
|
78
81
|
|
|
79
82
|
run は ID が変わらないので、directory を移動してもエージェントは見つけられます。
|
|
80
83
|
`work/` は Git の対象外で、`manifest.toml`、`input/`、`job.sh` は Git で追えます。
|
|
84
|
+
解析は依存する run の範囲で置き場所を選び、調査ごとに `README.md`、`scripts/`、`out/`、
|
|
85
|
+
`logs/` をまとめます。判断は `LOG.md` からリンクし、古い解析 job の log は整理候補になります。
|
|
81
86
|
|
|
82
87
|
## 対応 simulator
|
|
83
88
|
|
|
@@ -119,12 +119,14 @@ v1 で運用した 2 つの project(`project_dust_release`: BEACH、run 120、
|
|
|
119
119
|
<run_id>--<label>/ # 単発 run
|
|
120
120
|
<sweep_label>/
|
|
121
121
|
<run_id>--<label>/ # sweep で生成された run
|
|
122
|
+
_analysis/<topic>/ # この group に依存する調査(§9.1)
|
|
122
123
|
_scratch/
|
|
123
124
|
<run_id>--<label>/ # scratch run
|
|
124
125
|
_archive/
|
|
125
126
|
<case_name>/... # archive された run(元の相対 path を保つ)
|
|
126
127
|
adapters/ # 任意。project ローカル adapter `<name>.py`(§8.1)
|
|
127
128
|
notes/ # 永続的な知見。1 topic 1 file。runops は管理しない(§9)
|
|
129
|
+
analysis/<topic>/ # 複数 group にまたがる調査。共通コードは analysis/lib/(§9.1)
|
|
128
130
|
LOG.md # project 全体の追記専用ログ(§9)
|
|
129
131
|
AGENTS.md # agent 向け入口(§10)
|
|
130
132
|
CLAUDE.md # `@AGENTS.md` のみ
|
|
@@ -147,7 +149,8 @@ v1 で運用した 2 つの project(`project_dust_release`: BEACH、run 120、
|
|
|
147
149
|
`runs/` 配下の任意の場所に移動してよい。runops は manifest の `run.id` で run を
|
|
148
150
|
見つける(§7.2)。
|
|
149
151
|
- 既定の配置先は `runs/<case_name>/`。`--dest` で上書きできる。`_` で始まる
|
|
150
|
-
directory(`_scratch`、`_archive`)は runops が予約する。
|
|
152
|
+
directory(`_scratch`、`_archive`、`_analysis`)は runops が予約する。
|
|
153
|
+
`_analysis` は group の調査用で、run の発見・作成先から除く。
|
|
151
154
|
- run directory の中(自身と子孫)には run を置けない。`--dest` が既存 run の中なら拒否し、
|
|
152
155
|
`delete` は中に別の run があれば拒否する(§7.2 の走査は manifest のある directory で止まる)。
|
|
153
156
|
- run id は `R<YYYYMMDD>-<NNNN>`。その日の既存 run と `.runops/last_run_id` の大きい方に 1 を足す。
|
|
@@ -160,7 +163,8 @@ v1 で運用した 2 つの project(`project_dust_release`: BEACH、run 120、
|
|
|
160
163
|
- `materials/`、`refs/`、`scripts/` などユーザーが置く directory は runops の関知外。
|
|
161
164
|
runops は `runs/`、`cases/`、`.runops/`、`.agents/skills/`、`.claude/skills/`、
|
|
162
165
|
`AGENTS.md`、`CLAUDE.md`、`runops.toml` 以外を作成・変更しない(`LOG.md`、`notes/`
|
|
163
|
-
は `init`
|
|
166
|
+
は `init` の雛形生成のみ)。例外として `tidy --apply --only analysis-logs` は
|
|
167
|
+
§7.5 の解析 log を削除できる。解析のスクリプト・結果・README は agent が書く。
|
|
164
168
|
|
|
165
169
|
---
|
|
166
170
|
|
|
@@ -460,6 +464,22 @@ created ──submit──▶ submitted ──(slurm)──▶ running ──▶
|
|
|
460
464
|
|
|
461
465
|
---
|
|
462
466
|
|
|
467
|
+
### 6.4 進捗
|
|
468
|
+
|
|
469
|
+
adapter が `progress(run_dir)` を持つとき、`sync` は running の run と、queue を離れた
|
|
470
|
+
直後の run について呼び、`{done, total, unit, start}` を受け取る。`done` は今の到達点、
|
|
471
|
+
`total` は目標(不明なら省略)、`unit` は数える単位(`batch`、`step` など)、`start` は
|
|
472
|
+
この attempt を始めた地点(resume した run の再開点。新規なら 0)。
|
|
473
|
+
|
|
474
|
+
- 観測は `submit/progress.<job_id>.jsonl` に `{at, done}` として追記する(attempt ごと、
|
|
475
|
+
上限 1000 件程度)。queue を離れたときの観測は終了時刻で記録し、終了後の待ち時間を速度に含めない。
|
|
476
|
+
- 要約を `[[job.attempts]].progress` に置く: `done`、`total`、`unit`、`start`、`fraction`、
|
|
477
|
+
`rate_recent_per_hour`(直近 10 分)、`rate_attempt_per_hour`(program 開始から。起点は
|
|
478
|
+
`start`)、`eta_hours`(running のみ)。program 開始時刻は job.sh が stdout に出す
|
|
479
|
+
`runops: start` 行から取り、`started_at` に入れる。
|
|
480
|
+
- `status` / `list` は要約だけを読む(file を開かない)。read-only command は観測を足さない。
|
|
481
|
+
- 解析は adapter が行い、runops は保存と表示だけを持つ(§1.2 #4)。
|
|
482
|
+
|
|
463
483
|
## 7. CLI
|
|
464
484
|
|
|
465
485
|
### 7.1 共通規則
|
|
@@ -487,7 +507,7 @@ created ──submit──▶ submitted ──(slurm)──▶ running ──▶
|
|
|
487
507
|
- `runs/` 配下(`_archive/` を含む)を再帰的に走査し `manifest.toml` を集める。
|
|
488
508
|
`.runops/index.toml` に `run_id -> run_dir` の cache を持ち、manifest が cache の
|
|
489
509
|
path に無ければ再走査して cache を更新する。cache は常に再生成可能で、
|
|
490
|
-
|
|
510
|
+
壊れていても動作に影響しない。`_analysis/` は走査せず、そこにある manifest は run と扱わない。
|
|
491
511
|
- 走査対象は `runs/` のみ。project 外や `runs/` 外の run は扱わない。
|
|
492
512
|
|
|
493
513
|
### 7.3 command 一覧
|
|
@@ -498,11 +518,11 @@ created ──submit──▶ submitted ──(slurm)──▶ running ──▶
|
|
|
498
518
|
| `runo doctor [--json]` | `runops.toml` の妥当性、adapter の import 可否、executable の存在、`sbatch` の有無、skill の鮮度を検査 |
|
|
499
519
|
| `runo update [--skills-only] [-y]` | adapter package を upgrade し、skill を再展開する |
|
|
500
520
|
| `runo build SIM [--force]` | `local_source` simulator を `.runops/build/` に build する(§4.1) |
|
|
501
|
-
| `runo context [--json]` | agent 向け現在地。project 名、simulator、active run 数、直近 run 5 件、scratch 期限切れ数、`LOG.md` 末尾 20
|
|
521
|
+
| `runo context [--json]` | agent 向け現在地。project 名、simulator、active run 数、直近 run 5 件、scratch 期限切れ数、`LOG.md` 末尾 20 行、現用 group の解析 topic 名(§9.1)。配置した runops skill が install 済みの runops より古ければ `runo update --skills-only` を促す warning |
|
|
502
522
|
| `runo case new NAME --simulator SIM [--from CASE]` | case をスキャフォールド。adapter の `case_template()` を展開 |
|
|
503
523
|
| `runo case list` | case 一覧 |
|
|
504
524
|
| `runo new CASE [--why TEXT] [--label L] [--set k=v]... [--job k=v]... [--tag T]... [--scratch] [--dest DIR] [--submit] [--created-by WHO] [--json]` | 単発 run を作る |
|
|
505
|
-
| `runo new --from RUN [--why] [--set k=v]... [--job k=v]... [--job-from-case] [--continue] [--submit]` | 既存 run の params と `[job]` から派生 run を作る(§5
|
|
525
|
+
| `runo new --from RUN [--why] [--set k=v]... [--job k=v]... [--job-from-case] [--continue] [--submit]` | 既存 run の params と `[job]` から派生 run を作る(§5)。置き場所の既定は元 run と同じ directory(元 run が archive / scratch なら `runs/<case>/`)。`--continue` は adapter が `extend_inputs()` を実装する場合のみ有効(§8.1) |
|
|
506
526
|
| `runo sweep CASE --set k=v1,v2,... [--set ...] [--names KEY=n1,n2,...]... [--job k=v]... [--label L] [--dest DIR] [--why TEXT] [--apply] [--submit] [--limit N] [--json]` | 直積の候補を表示する。`--apply` で生成。`--submit` は `--apply` と同時のみ有効 |
|
|
507
527
|
| `runo submit RUN... [--partition P] [--qos Q] [--afterok JOBID] [-y]` | job.sh を生成して sbatch。`created` 以外は拒否 |
|
|
508
528
|
| `runo submit --all [DIR] [-y]` | DIR 配下の `created` run をすべて投入。件数と概算 core-hours を表示して確認 |
|
|
@@ -536,7 +556,7 @@ created ──submit──▶ submitted ──(slurm)──▶ running ──▶
|
|
|
536
556
|
|
|
537
557
|
### 7.5 `tidy` の規則
|
|
538
558
|
|
|
539
|
-
`tidy` は候補を
|
|
559
|
+
`tidy` は候補を 6 種に分けて表示する。`--apply` はすべてを実行し、
|
|
540
560
|
`--apply --only KIND` で絞れる。
|
|
541
561
|
|
|
542
562
|
| kind | 条件 | 動作 |
|
|
@@ -546,8 +566,14 @@ created ──submit──▶ submitted ──(slurm)──▶ running ──▶
|
|
|
546
566
|
| `old-completed` | `completed` で `defaults.tidy_archive_days`(既定 90)日より古く、`pinned = false` | archive |
|
|
547
567
|
| `orphan-job` | `submitted`/`running` だが squeue/sacct に job が無い | sync(state 確定) |
|
|
548
568
|
| `unused-build` | `.runops/build/*` のうち、非 archived run の manifest から参照されないもの | delete |
|
|
569
|
+
| `analysis-logs` | §9.1 の解析 directory 配下の `logs/` にある `*.<jobid>.out/err`。組の最終更新が `tidy_failed_days` より古く、同じ log directory・job 名の最新の組ではない | log file のみ delete |
|
|
549
570
|
|
|
550
571
|
- `--older-than AGE`(例 `14d`)はその回だけ、上の 2 つの日数をどちらもこの値で置き換える。
|
|
572
|
+
- `analysis-logs` は project の `analysis/`、group の `_analysis/`、run の `analysis/`
|
|
573
|
+
(topic の下も含む)を対象にする。stdout/stderr は同じ job id の組として更新時刻を比較し、
|
|
574
|
+
最新の組は常に残す。同時刻なら job id が大きい組を最新とする。片方だけの log も同じ扱い。
|
|
575
|
+
archived / pinned / submitted / running run の解析と、symlink は対象外。
|
|
576
|
+
適用直前にも対象範囲・更新時刻・最新組を再確認し、条件が変われば削除せず止まる。
|
|
551
577
|
- `--purge-work RUN...` は指定 run の `work/` の中身を削除し `work_purged_at` を記録する。
|
|
552
578
|
adapter が `keep_patterns()` を返す場合、一致するファイルは残す。`completed` 以外は拒否。
|
|
553
579
|
adapter を読み込めない(残すファイルを判定できない)ときは何も消さずにエラーにする。
|
|
@@ -621,6 +647,7 @@ class SimulatorAdapter(ABC):
|
|
|
621
647
|
def agent_context_dir(self) -> Path | None: return None # §8.2
|
|
622
648
|
def configure(self, sim_config: dict) -> None: ... # runops.toml の [simulators.X] を受け取る
|
|
623
649
|
def job_prelude(self, run_dir: Path) -> list[str]: return [] # job.sh で実行直前に置く shell 行
|
|
650
|
+
def progress(self, run_dir: Path) -> dict | None: return None # §6.4。{done, total, unit, start}
|
|
624
651
|
```
|
|
625
652
|
|
|
626
653
|
- job.sh は run_dir へ `cd` してから実行する(v1 と同じ。v1 adapter の path 規約
|
|
@@ -675,8 +702,9 @@ runops は `init` と `update` で次を行う。
|
|
|
675
702
|
(例: `mpiemses3d-input-review`)。`runops-` で始まる名前は予約されており展開しない。
|
|
676
703
|
2. `references/` を `.agents/skills/<adapter>-references/` にコピーし、
|
|
677
704
|
`SKILL.md` が無ければ reference 一覧を列挙した `SKILL.md` を生成する。
|
|
678
|
-
|
|
679
|
-
`../<adapter>-references
|
|
705
|
+
`docs/` があれば同じく `.agents/skills/<adapter>-docs/` に置く。展開した skill の
|
|
706
|
+
`../../references/`、`../../docs/`(package 内の配置での参照)は `../<adapter>-references/`、
|
|
707
|
+
`../<adapter>-docs/` に書き換える。
|
|
680
708
|
3. 展開先には `.managed-by-runops` marker を置く。marker のある directory は
|
|
681
709
|
`update` 時に **無条件で上書き** する。marker の無い同名 directory は触らず warning。
|
|
682
710
|
4. `.runops/skills.lock` に adapter 名、package version、展開した directory、content hash を記録する。
|
|
@@ -692,7 +720,7 @@ runops は `init` と `update` で次を行う。
|
|
|
692
720
|
|
|
693
721
|
### 8.3 runops 自身の skill
|
|
694
722
|
|
|
695
|
-
runops は次の
|
|
723
|
+
runops は次の 6 skill だけを同梱し、simulator skill と同じ仕組みで展開する。
|
|
696
724
|
利用者が覚えるコマンドは `runo init` だけとし、それ以外(simulator の追加、更新、v1 移行を含む)は
|
|
697
725
|
エージェントへの依頼で行う。
|
|
698
726
|
各 SKILL.md は 60 行以内に収める。
|
|
@@ -702,6 +730,7 @@ runops は次の 5 skill だけを同梱し、simulator skill と同じ仕組み
|
|
|
702
730
|
| `runops-create-run` | `new` / `sweep` の使い方。`--why` を必ず書く、scratch の使い分け |
|
|
703
731
|
| `runops-check-status` | `sync` → `list` → `log` の順。失敗時の `retry` と `tidy --purge-work` |
|
|
704
732
|
| `runops-tidy` | `tidy` を定期的に実行する判断基準。pin の使い方 |
|
|
733
|
+
| `runops-analyze` | 依存する run の範囲で調査の置き場所を決め、script・結果・log・README をまとめる |
|
|
705
734
|
| `runops-reference` | command 一覧(§7.3 の表をそのまま載せる) |
|
|
706
735
|
| `runops-maintain` | simulator の追加、runops と simulator package の更新、`migrate-v1`、`doctor` の読み方 |
|
|
707
736
|
|
|
@@ -730,7 +759,7 @@ v1 の `emses` / `beach` adapter は次の順で runops 本体から出す。
|
|
|
730
759
|
見つかると使われなくなる(解決順 1 が優先)ので、ユーザーが消せばよい。
|
|
731
760
|
---
|
|
732
761
|
|
|
733
|
-
## 9.
|
|
762
|
+
## 9. ノートと解析
|
|
734
763
|
|
|
735
764
|
置き場所は 3 つに固定し、runops はどれも「管理」しない(schema、budget、rotation、
|
|
736
765
|
seal、index を持たない)。
|
|
@@ -748,10 +777,33 @@ seal、index を持たない)。
|
|
|
748
777
|
- 複数 run にまたがる結論と次の判断は `LOG.md` に日付付きで追記する
|
|
749
778
|
- 再利用する式・手法・環境の落とし穴は `notes/<topic>.md` に書く。既存 file があれば追記し、
|
|
750
779
|
似た topic の file を増やさない
|
|
751
|
-
-
|
|
780
|
+
- 調査の詳細は §9.1 の README にまとめ、LOG.md からリンクする
|
|
752
781
|
- v1 の `research/results/`、`.runops/insights/`、`research/archive/legacy/` は移行時に
|
|
753
782
|
`notes/legacy/` 配下へ **移動せず** そのまま残し、`notes/README.md` から path を案内する(§11)。
|
|
754
783
|
|
|
784
|
+
### 9.1 解析の置き場所
|
|
785
|
+
|
|
786
|
+
| 結果が依存する範囲 | 置き場所 |
|
|
787
|
+
|---|---|
|
|
788
|
+
| 1 run | `runs/.../<RUN>/analysis/`(必要なら `<topic>/`) |
|
|
789
|
+
| 1 group(同じ directory に並ぶ系列・sweep) | `runs/<group>/_analysis/<topic>/` |
|
|
790
|
+
| 複数 group・case または project 全体 | `analysis/<topic>/` |
|
|
791
|
+
| 共通コード | `analysis/lib/` |
|
|
792
|
+
|
|
793
|
+
- group は directory であり、新しい entity / ID / ledger を持たない。
|
|
794
|
+
- 調査 directory は `README.md`(問い・対象 run id・方法・結果・制約)、`scripts/`
|
|
795
|
+
(Python、sbatch)、`out/`(図・JSON・CSV)、`logs/`(job の stdout/stderr)からなる。
|
|
796
|
+
topic は内容で名付け、同じ問いは README に日付付きで追記する。
|
|
797
|
+
- `init` の `.gitignore` は `**/logs/`、`__pycache__/`、`.runops/analysis-env/` を含む。
|
|
798
|
+
既存 project のファイルは自動で再配置しない。
|
|
799
|
+
- `context` は現用 group の `_analysis/*/README.md` がある topic 名を表示し、
|
|
800
|
+
`--json` では `group_analysis` に project 相対の group path → topic 名一覧を返す。
|
|
801
|
+
README 本文や `out/`、simulator の `work/` は読まない。
|
|
802
|
+
- `archive DIR` が group 配下の全 run を移す場合、その group と配下の group の
|
|
803
|
+
`_analysis/` も同じ相対 path の `runs/_archive/` に移す。run が残る group の解析は残す。
|
|
804
|
+
確認表示に解析の移動先を含め、移動前に run と解析の全移動先を検査し、既存なら上書きしない。
|
|
805
|
+
`archive RUN...` / `--older-than` は group の解析を動かさず、`restore RUN` は run のみを戻す。
|
|
806
|
+
|
|
755
807
|
---
|
|
756
808
|
|
|
757
809
|
## 10. harness 生成
|
|
@@ -898,7 +950,7 @@ src/runops/
|
|
|
898
950
|
| 項目 | 目標 |
|
|
899
951
|
|---|---|
|
|
900
952
|
| `src/runops/` の行数(skill の md を除く) | 8,000 行以下 |
|
|
901
|
-
| CLI command 数(`case new` / `case list` を含む。同じ command の option 違いは数えない) | 25 以下。§7.3 の表の distinct command は
|
|
953
|
+
| CLI command 数(`case new` / `case list` を含む。同じ command の option 違いは数えない) | 25 以下。§7.3 の表の distinct command は 25 |
|
|
902
954
|
| ユーザーが編集する TOML | `runops.toml`、`case.toml` の 2 種 |
|
|
903
955
|
| runops が書く TOML | `manifest.toml`、`.runops/skills.lock`、`.runops/index.toml` の 3 種 |
|
|
904
956
|
| 依存 | `typer`、`rich`、`tomli-w`、`tomlkit`、`jinja2`、`packaging`(`mcp` を外す) |
|
|
@@ -936,6 +988,9 @@ src/runops/
|
|
|
936
988
|
9b. 同名 adapter が entry point と `adapters/X.py` の両方にあるとき entry point が優先される。
|
|
937
989
|
どちらも無く `generic` でもなければ exit code 2 で案内が出る。
|
|
938
990
|
10. `manifest.toml` の書き込み途中で例外が起きても元のファイルが壊れない。
|
|
991
|
+
11. 解析 log の tidy は最新組・新しい組・対象外ファイルを残し、確認後の更新も削除しない。
|
|
992
|
+
group の archive は全 run が対象のときだけ解析も移し、衝突時は何も動かさない。
|
|
993
|
+
context は調査の名前だけを読み、解析内の manifest を run と誤認しない。
|
|
939
994
|
|
|
940
995
|
### 13.3 ドキュメント
|
|
941
996
|
|
|
@@ -956,6 +1011,7 @@ v2 の文書は次の 4 ファイルだけにする。
|
|
|
956
1011
|
|
|
957
1012
|
| 項目 | 決定 | 理由 |
|
|
958
1013
|
|---|---|---|
|
|
1014
|
+
| 解析の配置 2.6.0(2026-10-23) | 依存する run の範囲に応じて run 内 `analysis/`、group の `_analysis/<topic>/`、project の `analysis/<topic>/` にまとめる。skill、log の tidy、group archive、context を対応させる(§9.1) | 報告・図・script・job log が分散・混在していた。group は既存の directory として扱い、新しい entity や command は足さない。既存ファイルの整理は移動一覧を提示してから行う |
|
|
959
1015
|
| job の cwd | run_dir(v1 と同じ)。Slurm log は `work/` | v1 adapter の path 規約と実 project の job.sh をそのまま使える |
|
|
960
1016
|
| adapter の追加 hook | `configure(sim_config)`、`job_prelude(run_dir)` | generic の `command` 取得と、EMSES の `rm -f *_0000.h5` など v1 の setup command を表す |
|
|
961
1017
|
| launcher `kind = "none"` | MPI launcher を使わず program を直接実行 | OpenMP のみの BEACH run 用 |
|
|
@@ -981,5 +1037,6 @@ v2 の文書は次の 4 ファイルだけにする。
|
|
|
981
1037
|
| 置き換えた系列の整理(2026-10-21) | `archive` が DIR(系列)を受け、`--superseded-by` で置き換え先を manifest に記録する。新しい command と tidy の種別は足さない。skill は新系列を作ったら旧系列の要否を確かめ、不要なら archive して現用系列・archive 先・件数を報告する | 修正版を作った後に旧系列が作業領域に残り、毎回ユーザーが整理を頼んでいた。`parent_run` だけでは比較用の派生と置き換えを区別できないので、置き換えは明示操作で記録する。旧 `archive` は 1 件ずつ検査していて、途中の running run で一部だけ移動していた(#113) |
|
|
982
1038
|
| 生成ハーネスの書き方(2026-10-21) | AGENTS.md の Rules を「作業の進め方」5 項目に絞り、各項目を「何をするか」と短い理由で書く。skill は手順に専念し、AGENTS.md の方針(manifest を手で編集しない等)を繰り返さない | #112・#113 で規則が増え、禁止形(never / do not)が並んでいた。現行の Claude の prompting 指針は、しないことより何をするかを、理由と共に書くことを勧め、強い禁止語は過剰反応を招くとしている |
|
|
983
1039
|
| 複数 run の mv / archive(2026-10-22) | 1 回の `run.lock` の下で全対象を読み直して検査し、通ってから移す。途中の filesystem error では移し終えた run id を示して止まる | `mv A B C --dest X` は 1 件ずつ検査して移していたので、途中の submitted run で一部だけ移動していた。archive は表示の後で lock を取り直していて、その間に再投入された run で同じことが起き得た |
|
|
1040
|
+
| 進捗と系列配置 2.5.0(2026-10-23) | adapter に任意の `progress()`、`sync` が時刻付き観測を保存し速度・残り時間を要約(§6.4)。`new --from` の既定置き場所を元 run と同じ directory に。agent context の `docs/` も展開 | 速度比較のために agent が時刻付き batch 観測を手で保存し、再開点や終了後の待ちを毎回補正していた(4 回)。継続世代が case 直下に並び、同じ計算の系列を見分けにくかった。skill が package の `docs/` を参照していたが展開されていなかった。進捗の解析は simulator 固有なので adapter が持ち、runops は保存と表示だけにする |
|
|
984
1041
|
| FEEDBACK 棚卸し 2.4.0(2026-10-23) | `--job k=v` と `new --from` の `[job]` 継承、created の archive / restore、archived scratch を期限削除しない、展開 skill の references 参照の書き換えと `doctor` のリンク検査、adapter warning への版の併記、生成 AGENTS.md に解析環境の置き場所 | hub の FEEDBACK で、資源変更のための case 編集(3 回)、置換済み draft を archive できず helper で迂回(2 回)、保管目的の archive が期限削除される、skill から reference に辿れない、新版の正規キーが誤記に見える、解析依存の置き場所が project ごとに違う、が記録された。いずれも既存 command の拡張で、command 数は増やさない |
|
|
985
1042
|
| 使い方ガイド | `docs/guide.md` を追加し、文書を 4 ファイルにする(§13.3) | README の依頼例の表と command 一覧の間を埋める、場面ごとの流れ(case と run の分け方、smoke から本計算、状態の決まり方、整理)の置き場所が無かった |
|
|
@@ -49,6 +49,7 @@ class Adapter:
|
|
|
49
49
|
| `keep_patterns() -> list[str]` | `tidy --purge-work` で残す glob |
|
|
50
50
|
| `extend_inputs(src_run, run_dir, params) -> list[str]` | `runo new --from RUN --continue` の restart 設定 |
|
|
51
51
|
| `agent_context_dir() -> Path | None` | 同梱 skill と reference の場所 |
|
|
52
|
+
| `progress(run_dir) -> dict | None` | 進捗 `{"done", "total", "unit", "start"}`。`runo sync` が時刻付きで保存し、速度と残り時間を出す |
|
|
52
53
|
|
|
53
54
|
`runtime` は `executable`、`package_version`、`exe_hash`、`git_commit`、`git_dirty`、
|
|
54
55
|
`env`、`resolver_mode`、`build_dir` を持ちます。
|
|
@@ -76,14 +77,15 @@ project の `adapters/mysim.py` に `Adapter` という名前で置けば使え
|
|
|
76
77
|
<dir>/
|
|
77
78
|
skills/<skill-name>/SKILL.md
|
|
78
79
|
references/*.md
|
|
80
|
+
docs/*.md # 任意。references と同じく展開する
|
|
79
81
|
```
|
|
80
82
|
|
|
81
83
|
`runo init` と `runo update` は `skills/*` を project の `.agents/skills/` と
|
|
82
84
|
`.claude/skills/` に同名でコピーし、`references/` を `<adapter>-references` として置きます。
|
|
83
85
|
skill 名は package 側で名前空間を付けてください(例: `mysim-input-review`)。
|
|
84
86
|
`runops-` で始まる名前は予約されています。skill から reference へは
|
|
85
|
-
`../<adapter>-references/X.md
|
|
86
|
-
`../../references/X.md` は展開時にこの形へ書き換えます。`runo doctor` は展開済み skill の
|
|
87
|
+
`../<adapter>-references/X.md`(`docs/` なら `../<adapter>-docs/X.md`)と書いてください。
|
|
88
|
+
package 内の配置どおりの `../../references/X.md`、`../../docs/X.md` は展開時にこの形へ書き換えます。`runo doctor` は展開済み skill の
|
|
87
89
|
相対リンク切れを報告します。展開した directory には
|
|
88
90
|
`.managed-by-runops` が置かれ、更新時に上書きされます。利用者が作った同名 directory は
|
|
89
91
|
上書きしません。
|
|
@@ -131,6 +131,11 @@ walltime は、同じ case・同じ資源で終わった run の実時間を元
|
|
|
131
131
|
`runo sync` は、active な run が何件あっても `squeue` と `sacct` を 1 回ずつしか呼びません。
|
|
132
132
|
エージェントには `squeue` を直接叩かせず、`runo sync` を使わせてください。
|
|
133
133
|
|
|
134
|
+
adapter が進捗に対応していれば(BEACH の batch、MPIEMSES3D の step)、`sync` のたびに時刻付きの
|
|
135
|
+
観測を残し、`runo list` / `status` に `62% 0.198 s/batch eta 3.1h` のように進み具合、直近 10 分の
|
|
136
|
+
速度、残り時間を出します。resume した run は再開点から数え、終わった run は終了時刻までで速度を出すので、
|
|
137
|
+
版を切り替えた前後の比較にそのまま使えます(`--json` の `progress`)。
|
|
138
|
+
|
|
134
139
|
### 状態の決まり方
|
|
135
140
|
|
|
136
141
|
run の状態は `created → submitted → running → completed | failed | cancelled` と進みます。
|
|
@@ -180,13 +185,14 @@ project の run だけが対象です。同じアカウントの別 project の
|
|
|
180
185
|
> R20261015-0003 の続きを 2 倍の step で。
|
|
181
186
|
|
|
182
187
|
`runo new --from RUN --continue` で、終わった run の出力から再開する run を作ります。
|
|
188
|
+
`--from` で作る run は元 run と同じ directory に置かれるので、同じ計算の継続は 1 つの directory に並びます。
|
|
183
189
|
再開の方法は simulator ごとに違い、adapter が対応している場合だけ使えます
|
|
184
190
|
(現在は MPIEMSES3D が対応し、`SNAPSHOT1` から再開します)。新しい run は元の run を `parent_run` として記録します。
|
|
185
191
|
|
|
186
192
|
前の job が終わるのを待って投入したいときは、「R20261016-0005 が成功したら投げて」と頼めば
|
|
187
193
|
`runo submit RUN --afterok <job_id>` になります。
|
|
188
194
|
|
|
189
|
-
## 6.
|
|
195
|
+
## 6. 解析して記録を残す
|
|
190
196
|
|
|
191
197
|
記録の置き場所は 3 つに決まっています。
|
|
192
198
|
|
|
@@ -196,10 +202,40 @@ project の run だけが対象です。同じアカウントの別 project の
|
|
|
196
202
|
| 複数の run をまたぐ結論と次の判断 | `LOG.md` に日付見出しで追記 | 今日の scan の結論を LOG にまとめて |
|
|
197
203
|
| 再利用する式、手法、落とし穴 | `notes/<topic>.md`(1 topic 1 file) | Debye 長の見積もり方を notes に残して |
|
|
198
204
|
|
|
199
|
-
エージェントはこれ以外の場所(`research/`、`analysis/*.md`、`runs/` の下など)にノートを作りません。
|
|
200
205
|
`notes/` に似た topic の file があれば、新しく作らずに追記します。
|
|
201
206
|
|
|
202
|
-
|
|
207
|
+
調査の詳細と図・スクリプトは、結果が依存する run の範囲に合わせてまとめます。
|
|
208
|
+
|
|
209
|
+
> この系列の速度を比較して。図とスクリプト、調査メモを系列の `_analysis/` にまとめて。
|
|
210
|
+
|
|
211
|
+
| 依存する範囲 | 置き場所 |
|
|
212
|
+
|---|---|
|
|
213
|
+
| 1 run | `<run_dir>/analysis/`(必要なら topic を切る) |
|
|
214
|
+
| 1 系列・sweep | `runs/<group>/_analysis/<topic>/` |
|
|
215
|
+
| 複数系列・case、project 全体 | `analysis/<topic>/` |
|
|
216
|
+
| 共通コードとそのテスト | `analysis/lib/` |
|
|
217
|
+
|
|
218
|
+
group は run が並ぶ directory です。登録や新しい ID は要りません。
|
|
219
|
+
topic は `speed-by-version` のように問いの内容で名付け、同じ問いをやり直すときは
|
|
220
|
+
同じ directory の結果を更新し、README に日付付きで追記します。
|
|
221
|
+
|
|
222
|
+
```text
|
|
223
|
+
<topic>/
|
|
224
|
+
README.md 問い・対象 run id と path・方法・結果・制約
|
|
225
|
+
scripts/ Python と sbatch
|
|
226
|
+
out/ 図、JSON、CSV、HTML
|
|
227
|
+
logs/ 解析 job の stdout/stderr(Git 管理外)
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
エージェントは `runops-analyze` skill を使い、調査の README と、そこへのリンクを含む
|
|
231
|
+
`LOG.md` の判断を更新します。`notes/` は run に依存しない知見に使います。
|
|
232
|
+
解析の追加依存は `.runops/analysis-env/` に置き、重い読み込みや作図はサイトの規則に従って
|
|
233
|
+
計算ノードで実行します。sbatch は調査 directory から投入し、事前に `logs/` を作って
|
|
234
|
+
`#SBATCH -o logs/%x.%j.out` と `#SBATCH -e logs/%x.%j.err` を指定します。
|
|
235
|
+
既存 project のファイルは自動で移動しません。整理を頼むと、移動前に一覧を提示します。
|
|
236
|
+
|
|
237
|
+
`runo context` は `LOG.md` の末尾、`notes/` の file 名、現用 group の
|
|
238
|
+
`_analysis/*/README.md` がある topic 名を表示します。エージェントは作業の始めに
|
|
203
239
|
これを読むので、前回の続きから話を始められます。
|
|
204
240
|
|
|
205
241
|
## 7. 整理する
|
|
@@ -215,6 +251,7 @@ run は消さなくても `runo list` が古いものを隠しますが、direct
|
|
|
215
251
|
| `expired-scratch` | 期限切れの scratch run(archive したものは除く) | 削除 |
|
|
216
252
|
| `stale-failed` | 30 日より古い failed / cancelled で、`why` もノートも無い | 削除 |
|
|
217
253
|
| `old-completed` | 90 日より古い completed | archive |
|
|
254
|
+
| `analysis-logs` | 30 日より古い解析 job の log(各 job 名の最新組は保持) | log のみ削除 |
|
|
218
255
|
| `orphan-job` | 投入済みなのに Slurm が知らない | `sync` で状態を確定 |
|
|
219
256
|
| `unused-build` | どの run も使っていない build cache | 削除 |
|
|
220
257
|
|
|
@@ -233,6 +270,14 @@ run id で引き続き見つかり、`runo restore` で戻せます。
|
|
|
233
270
|
記録され、理由はノートに残ります。比較用に派生しただけの run は置き換えとは扱わないので、
|
|
234
271
|
旧系列が不要かどうかは毎回確かめます。
|
|
235
272
|
|
|
273
|
+
directory 指定で group の全 run を archive すると、その `_analysis/` も同じ相対 path で
|
|
274
|
+
移動します。run が残る group の解析は元の場所に残り、移動先に既存の解析があれば、run を
|
|
275
|
+
動かす前に停止します。`archive RUN...` と `restore RUN` は run だけを移動します。
|
|
276
|
+
|
|
277
|
+
解析 log だけの整理は「古い解析 log を整理して」で `runo tidy --only analysis-logs` に
|
|
278
|
+
なります。各 `logs/` の `*.<jobid>.out/err` を組で比較し、job 名ごとに最新の組を残します。
|
|
279
|
+
片方が新しければ両方とも残し、README、script、結果は削除しません。
|
|
280
|
+
|
|
236
281
|
論文の図に使う run や基準にする run は pin しておくと、`list` に常に表示され、`tidy` や `delete`
|
|
237
282
|
の対象になりません。
|
|
238
283
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
## runops.toml
|
|
7
7
|
|
|
8
8
|
project root にあり、`runo` はここを上方向に探して project を特定します。
|
|
9
|
-
command はこの project の `runs/` 配下だけを扱い、別 project の run directory や
|
|
9
|
+
run を対象にする command はこの project の `runs/` 配下だけを扱い、別 project の run directory や
|
|
10
10
|
directory を path で渡すとエラーになります。run id は project ごとなので、同じ id が
|
|
11
11
|
別 project にあっても cwd の project の run を指します。
|
|
12
12
|
|
|
@@ -110,7 +110,7 @@ runops だけが書きます。手で編集しないでください。主な fie
|
|
|
110
110
|
| `[path]` | `run_dir`(project 相対)、`archived_from`、`archived_at` |
|
|
111
111
|
| `[origin]` | `case`、`sweep`、`parent_run`、`created_by`、`case_input_hash` |
|
|
112
112
|
| `[simulator]` | `name`、`adapter`、`adapter_source`、`adapter_version`、`executable`、`resolver_mode`、`package_version`、`exe_hash`、`git_commit`、`git_dirty`、`build_dir` |
|
|
113
|
-
| `[job]` | case の `[job]` に加え `job_id`、`attempt`、`submitted_at`、`finished_at`、`last_slurm_state`、`exit_code`、`[[job.attempts]]`(attempt ごとの `job_id`、`started_at`、`exit_code`、`exe_hash`、`elapsed`、`cancel --why` の `cancel_reason
|
|
113
|
+
| `[job]` | case の `[job]` に加え `job_id`、`attempt`、`submitted_at`、`finished_at`、`last_slurm_state`、`exit_code`、`[[job.attempts]]`(attempt ごとの `job_id`、`started_at`、`exit_code`、`exe_hash`、`elapsed`、`cancel --why` の `cancel_reason`、`runo sync` が付ける `progress`(§進捗)) |
|
|
114
114
|
| `[params]` | case の params に `--set` を適用した最終値 |
|
|
115
115
|
| `[variation]` | `changed_keys`、`job_changed_keys`(case の `[job]` と違う key) |
|
|
116
116
|
| `[identity]` | `input_hash` |
|
|
@@ -139,7 +139,9 @@ run id は削除後も再利用しません。`--dest` に既存 run の中は
|
|
|
139
139
|
## command
|
|
140
140
|
|
|
141
141
|
`list --json` と `status --json` は、walltime の根拠として `walltime`、最新 attempt の `elapsed`、
|
|
142
|
-
`walltime_used`(elapsed / walltime)、`slurm_state`
|
|
142
|
+
`walltime_used`(elapsed / walltime)、`slurm_state` も返します。adapter が `progress()` を持てば
|
|
143
|
+
`progress`(`done`、`total`、`unit`、`fraction`、`rate_recent_per_hour`、`rate_attempt_per_hour`、
|
|
144
|
+
`eta_hours`)も返し、表の `progress` 列に `62% 0.198 s/batch eta 3.1h` と出します。表では `TIMEOUT` などを
|
|
143
145
|
`failed (TIMEOUT)` と示します。
|
|
144
146
|
|
|
145
147
|
全 command は `--help` で option を確認できます。`RUN` には run id、run directory、
|
|
@@ -151,10 +153,10 @@ run id は削除後も再利用しません。`--dest` に既存 run の中は
|
|
|
151
153
|
| `runo doctor [--json]` | 設定、adapter の解決経路、executable、sbatch、skill の鮮度とリンク切れを点検 |
|
|
152
154
|
| `runo update [--skills-only] [-y]` | simulator package を更新し skill と AGENTS.md の管理 block を再生成 |
|
|
153
155
|
| `runo build SIM [--force]` | `local_source` の simulator を build |
|
|
154
|
-
| `runo context [--json]` | agent
|
|
156
|
+
| `runo context [--json]` | agent 向けの現在地と現用 group の解析 topic 名(JSON の `group_analysis` は group path → topic 名一覧) |
|
|
155
157
|
| `runo case new NAME [-s SIM] [--from CASE]` / `runo case list` | case の作成と一覧 |
|
|
156
158
|
| `runo new CASE [--why] [--label] [--set k=v]... [--job k=v]... [--tag] [--scratch] [--dest DIR] [--submit] [--json]` | run を 1 つ作る。`--job` はこの run の `[job]` の値 |
|
|
157
|
-
| `runo new --from RUN [--set k=v]... [--job k=v]... [--job-from-case] [--continue]` | 既存 run の params と `[job]` から派生(`--job-from-case` で `[job]` は case
|
|
159
|
+
| `runo new --from RUN [--set k=v]... [--job k=v]... [--job-from-case] [--continue]` | 既存 run の params と `[job]` から派生(`--job-from-case` で `[job]` は case から)。置き場所の既定は元 run と同じ directory。`--continue` は adapter の restart 対応が必要 |
|
|
158
160
|
| `runo sweep CASE --set k=v1,v2 ... [--names k=n1,n2...] [--job k=v]... [--label] [--dest DIR] [--limit N] [--apply] [--submit] [--json]` | 直積の候補表示。`--apply` で作成。`--names` は各値の短い label、`--dest` は sweep directory の親 |
|
|
159
161
|
| `runo submit RUN... [-p P] [--qos Q] [--afterok JOB]` / `runo submit --all [DIR] [-y]` | job.sh を生成して sbatch |
|
|
160
162
|
| `runo cancel RUN... [--why TEXT] [-y]` / `runo retry RUN [--submit] [-y]` | scancel(`--why` は note に残る)/ failed・cancelled を created に戻す(理由付きで cancel された run は確認を取る) |
|
|
@@ -171,7 +173,11 @@ run id は削除後も再利用しません。`--dest` に既存 run の中は
|
|
|
171
173
|
`list` は既定で active、created、直近 `list_since_days` 日、pinned の run を表示し、
|
|
172
174
|
scratch と archived は表示しません。
|
|
173
175
|
|
|
174
|
-
`
|
|
176
|
+
`archive DIR` が group 配下の全 run を移すときは、group の `_analysis/` も同じ相対 path で
|
|
177
|
+
移動します。run が残る group の解析は残し、移動先が存在すれば全 run の移動前に拒否します。
|
|
178
|
+
`archive RUN...` / `--older-than` と `restore RUN` は group の解析を移動しません。
|
|
179
|
+
|
|
180
|
+
`tidy` の候補は次の 6 種類です。
|
|
175
181
|
|
|
176
182
|
| kind | 条件 | 動作 |
|
|
177
183
|
|---|---|---|
|
|
@@ -180,9 +186,17 @@ scratch と archived は表示しません。
|
|
|
180
186
|
| `old-completed` | `tidy_archive_days`(既定 90)日より古い completed | archive |
|
|
181
187
|
| `orphan-job` | Slurm が知らない submitted / running | sync |
|
|
182
188
|
| `unused-build` | 非 archived run が参照しない `.runops/build/*` | delete |
|
|
189
|
+
| `analysis-logs` | `tidy_failed_days` より古い解析 log。各 log directory・job 名の最新組は保持 | log のみ delete |
|
|
183
190
|
|
|
184
191
|
日数は `runops.toml` の `[defaults]` で変えられます。`--older-than 14d` のように指定すると、
|
|
185
192
|
その回だけ両方の日数をその値で置き換えます。pinned の run は `tidy` と `delete` の対象になりません。
|
|
186
193
|
`--purge-work` は adapter を読み込めないと何も消さずにエラーにします。
|
|
187
194
|
|
|
195
|
+
`analysis-logs` は project の `analysis/`、group の `_analysis/`、run の `analysis/` 配下の
|
|
196
|
+
`logs/*.<jobid>.out/err`(topic の下も含む)に限定します。組の新しい方の更新時刻で年齢を判定し、
|
|
197
|
+
最新組を残します。同時刻なら job id が大きい組を最新とします。片方だけの log も同じ扱いです。
|
|
198
|
+
archived / pinned / submitted / running run の解析と symlink は対象外で、適用直前にも条件を
|
|
199
|
+
確認します。`--json` の解析 log 候補は `files`(削除する project 相対 path)と `cutoff`
|
|
200
|
+
(ISO 日時)も持ちます。確認後に条件が変われば削除せず、再度 tidy を実行するよう案内します。
|
|
201
|
+
|
|
188
202
|
exit code は 0 が成功、1 が実行時エラー(sbatch 失敗など)、2 が使い方や設定のエラーです。
|
|
@@ -263,6 +263,8 @@ def context(as_json: bool = typer.Option(False, "--json")) -> None:
|
|
|
263
263
|
)
|
|
264
264
|
if data["notes_files"]:
|
|
265
265
|
out.print("notes/: " + ", ".join(data["notes_files"]))
|
|
266
|
+
for group, topics in data["group_analysis"].items():
|
|
267
|
+
out.print(f"{group}/_analysis/: {', '.join(topics)}", markup=False)
|
|
266
268
|
if data["log_tail"]:
|
|
267
269
|
out.print("--- LOG.md (tail) ---")
|
|
268
270
|
out.print(data["log_tail"], markup=False)
|
|
@@ -592,9 +594,20 @@ def retry(
|
|
|
592
594
|
|
|
593
595
|
def _status_table(project: Project, manifests: list[Manifest]) -> Table:
|
|
594
596
|
from runops.ops.listing import relative_age
|
|
597
|
+
from runops.ops.progress import format_progress
|
|
595
598
|
|
|
596
599
|
table = Table(
|
|
597
|
-
"id",
|
|
600
|
+
"id",
|
|
601
|
+
"status",
|
|
602
|
+
"label",
|
|
603
|
+
"case",
|
|
604
|
+
"sweep",
|
|
605
|
+
"created",
|
|
606
|
+
"elapsed",
|
|
607
|
+
"progress",
|
|
608
|
+
"note",
|
|
609
|
+
"why",
|
|
610
|
+
box=None,
|
|
598
611
|
)
|
|
599
612
|
for m in manifests:
|
|
600
613
|
s = m.to_summary(project.root)
|
|
@@ -625,6 +638,7 @@ def _status_table(project: Project, manifests: list[Manifest]) -> Table:
|
|
|
625
638
|
s["sweep"],
|
|
626
639
|
relative_age(s["created_at"]),
|
|
627
640
|
elapsed,
|
|
641
|
+
format_progress(s["progress"]),
|
|
628
642
|
s["last_note"][:60],
|
|
629
643
|
s["why"][:60],
|
|
630
644
|
)
|
|
@@ -857,12 +871,22 @@ def archive(
|
|
|
857
871
|
if m.id in plan.superseded_by:
|
|
858
872
|
line += f" -> {', '.join(plan.superseded_by[m.id])}"
|
|
859
873
|
out.print(line)
|
|
874
|
+
for directory in plan.analysis_dirs:
|
|
875
|
+
dest = project.runs_dir / "_archive" / directory.relative_to(project.runs_dir)
|
|
876
|
+
out.print(f" analysis {project.rel(directory)} -> {project.rel(dest)}", markup=False)
|
|
860
877
|
_confirm(f"Archive {len(plan.targets)} runs?", yes)
|
|
861
878
|
archived = archive_runs(
|
|
862
|
-
project,
|
|
879
|
+
project,
|
|
880
|
+
plan.targets,
|
|
881
|
+
superseded_by=plan.superseded_by,
|
|
882
|
+
why=why,
|
|
883
|
+
by=_actor(),
|
|
884
|
+
analysis_dirs=plan.analysis_dirs,
|
|
863
885
|
)
|
|
864
886
|
for run_id, dst in archived:
|
|
865
887
|
out.print(f"archived {run_id} -> {project.rel(dst)}")
|
|
888
|
+
for directory in plan.analysis_dirs:
|
|
889
|
+
out.print(f"archived analysis {project.rel(directory)}", markup=False)
|
|
866
890
|
|
|
867
891
|
|
|
868
892
|
@app.command("mv")
|
|
@@ -12,7 +12,7 @@ END = "<!-- runops:end -->"
|
|
|
12
12
|
COMMANDS = """\
|
|
13
13
|
| command | effect |
|
|
14
14
|
|---|---|
|
|
15
|
-
| `runo context --json` |
|
|
15
|
+
| `runo context --json` | active runs, recent runs, group analysis topics, LOG.md tail |
|
|
16
16
|
| `runo case list` / `runo case new NAME --simulator SIM [--from CASE]` | list / scaffold cases |
|
|
17
17
|
| `runo new CASE --why TEXT [--set k=v]... [--job k=v]... [--scratch] [--submit]` | create one run |
|
|
18
18
|
| `runo new --from RUN --why TEXT [--set k=v]... [--job k=v]... [--continue]` | derive a run (keeps its params and [job]) |
|
|
@@ -23,7 +23,7 @@ COMMANDS = """\
|
|
|
23
23
|
| `runo cancel RUN [--why T]` / `runo retry RUN` | stop a job / reset failed or cancelled to created |
|
|
24
24
|
| `runo note RUN "text"` / `runo pin RUN --reason TEXT` | append an observation / protect a key run |
|
|
25
25
|
| `runo summarize RUN` | adapter summary into analysis/summary.json |
|
|
26
|
-
| `runo tidy` / `runo tidy --apply` | list / apply cleanup (
|
|
26
|
+
| `runo tidy` / `runo tidy --apply` | list / apply cleanup (runs, builds, old analysis logs) |
|
|
27
27
|
| `runo mv RUN... [--dest DIR] [--label L] --why TEXT` | rename / move runs, keeping ids and inputs |
|
|
28
28
|
| `runo archive RUN\\|DIR... [--superseded-by RUN\\|DIR --why T]` | move created or finished runs (or a series) to runs/_archive |
|
|
29
29
|
| `runo restore RUN` / `runo delete RUN` | move back / remove |
|
|
@@ -78,7 +78,7 @@ the project found from the current directory.
|
|
|
78
78
|
stopped. When a new series replaces an old one, ask whether the old one is still
|
|
79
79
|
needed and archive it with `--superseded-by`.
|
|
80
80
|
|
|
81
|
-
## Notes
|
|
81
|
+
## Notes and analysis
|
|
82
82
|
|
|
83
83
|
Notes live in three places, where `runo context` and the next session find them:
|
|
84
84
|
- one run: `runo note RUN "..."`;
|
|
@@ -86,6 +86,18 @@ Notes live in three places, where `runo context` and the next session find them:
|
|
|
86
86
|
- reusable knowledge (formulas, methods, pitfalls): `notes/<topic>.md`, extending the
|
|
87
87
|
existing file for a topic.
|
|
88
88
|
|
|
89
|
+
Place analysis by the runs its results depend on:
|
|
90
|
+
|
|
91
|
+
| Scope | Location |
|
|
92
|
+
|---|---|
|
|
93
|
+
| One run | `runs/.../<RUN>/analysis/` |
|
|
94
|
+
| One group (series or sweep directory) | `runs/<group>/_analysis/<topic>/` |
|
|
95
|
+
| Multiple groups or the project | `analysis/<topic>/`; shared code in `analysis/lib/` |
|
|
96
|
+
|
|
97
|
+
Keep each investigation's question, run ids, method, results and limits in its
|
|
98
|
+
`README.md`, with `scripts/`, `out/` and `logs/` beside it. Link it from `LOG.md`.
|
|
99
|
+
Use `runops-analyze` for this workflow; `runo context` lists group topics with a README.
|
|
100
|
+
|
|
89
101
|
Analysis tools the simulator package does not bring go in `.runops/analysis-env/`
|
|
90
102
|
(`uv venv .runops/analysis-env`), so `.venv` stays as `runo update` manages it. Run heavy
|
|
91
103
|
reading and plotting where the site allows compute jobs.
|
|
@@ -220,8 +220,16 @@ class Manifest:
|
|
|
220
220
|
"input_hash": str(self.section("identity").get("input_hash", "")),
|
|
221
221
|
# Walltime evidence for the next run: elapsed of the latest attempt.
|
|
222
222
|
**self.timing(),
|
|
223
|
+
"progress": self.progress,
|
|
223
224
|
}
|
|
224
225
|
|
|
226
|
+
@property
|
|
227
|
+
def progress(self) -> dict[str, Any] | None:
|
|
228
|
+
"""Progress of the latest attempt as `runo sync` last saw it (adapter ``progress()``)."""
|
|
229
|
+
attempts = self.job.get("attempts") or []
|
|
230
|
+
value = attempts[-1].get("progress") if attempts else None
|
|
231
|
+
return dict(value) if isinstance(value, dict) else None
|
|
232
|
+
|
|
225
233
|
def timing(self) -> dict[str, Any]:
|
|
226
234
|
"""Walltime, latest attempt elapsed, the fraction used, and the last Slurm state."""
|
|
227
235
|
walltime = str(self.job.get("walltime", ""))
|