|
11 | 11 | entry_hashes: [content_hash, ...] # pointer to untracked entries/<hash>/ |
12 | 12 | result_cache: [relpath, ...] # pointer to untracked result cache |
13 | 13 | compute_cache: [relpath, ...] # pointer to untracked compute cache |
14 | | -
|
15 | | -The catalog git repo tracks only ``catalog.yaml`` + the two alias files. The |
| 14 | + alias_map: {alias: latest_hash} # mirror of artifacts/alias_state/aliases.json |
| 15 | + alias_history: {alias: [hash, ...]} # mirror of artifacts/alias_state/alias_history.json |
| 16 | +
|
| 17 | +The catalog git repo tracks only ``catalog.yaml``. tallyman's alias bookkeeping |
| 18 | +(``aliases.json``/``alias_history.json``) lives outside the repo, under |
| 19 | +``artifacts/alias_state/`` — committing it inside made xorq's |
| 20 | +``assert_consistency`` reject the repo and every ``xorq catalog add`` after the |
| 21 | +first silently no-op (#48). Its content is mirrored into ``catalog.yaml`` above |
| 22 | +so ``reset_to`` still rolls alias state back (git no longer can). The |
16 | 23 | heavy artifacts (entries/, the caches) are content-addressed, additive, and |
17 | 24 | untracked — ``git reset`` can't roll them back, so ``reset_to`` reconciles them |
18 | 25 | to the recorded pointer lists: evictions retire to the bullpen (not deleted), |
|
40 | 47 |
|
41 | 48 | import yaml |
42 | 49 |
|
| 50 | +from tallyman_core import aliases as al |
43 | 51 | from tallyman_core import charts, notebook |
44 | 52 | from tallyman_core import display_configs as dc |
45 | 53 | from tallyman_core import post_processing as pp |
|
60 | 68 |
|
61 | 69 | # git-level identity flags, so commits work without a global git config. |
62 | 70 | _GIT_ID = ["-c", "user.email=tallyman@local", "-c", "user.name=tallyman"] |
63 | | -_TRACKED = ("catalog.yaml", "aliases.json", "alias_history.json") |
| 71 | +# Only catalog.yaml is git-tracked in the catalog repo. The alias bookkeeping |
| 72 | +# files moved out to artifacts/alias_state/ (#48) — tracking them here made |
| 73 | +# xorq's assert_consistency reject the repo. |
| 74 | +_TRACKED = ("catalog.yaml",) |
64 | 75 | _STEP_RE = re.compile(r"^step-(\d+)$") |
65 | 76 | # Refs and labels are operator input that ends up as git arguments. A plain |
66 | 77 | # tag-shaped name only: no leading dash (option injection), no revision |
@@ -96,6 +107,8 @@ def read_tallyman_state(project: str) -> dict: |
96 | 107 | "entry_hashes": raw.get("entry_hashes", []), |
97 | 108 | "result_cache": raw.get("result_cache", []), |
98 | 109 | "compute_cache": raw.get("compute_cache", []), |
| 110 | + "alias_map": raw.get("alias_map", {}), |
| 111 | + "alias_history": raw.get("alias_history", {}), |
99 | 112 | } |
100 | 113 |
|
101 | 114 |
|
@@ -154,6 +167,8 @@ def capture_tallyman_state(project: str) -> dict: |
154 | 167 | "entry_hashes": sorted(c.name for c in ed.iterdir() if c.is_dir()) if ed.exists() else [], |
155 | 168 | "result_cache": _list_cache_files(result_cache_dir(project)), |
156 | 169 | "compute_cache": _list_cache_files(compute_cache_dir(project)), |
| 170 | + "alias_map": al.load_aliases(project), |
| 171 | + "alias_history": al.load_history(project), |
157 | 172 | } |
158 | 173 | write_tallyman_state(project, **state) |
159 | 174 | return state |
@@ -223,6 +238,8 @@ def materialize(project: str) -> None: |
223 | 238 | _materialize_display_configs(project, raw["display_configs"]) |
224 | 239 | if "notebook" in raw: |
225 | 240 | _materialize_notebook(project, raw["notebook"] or {"cells": []}) |
| 241 | + if "alias_map" in raw: |
| 242 | + al.write_state(project, raw["alias_map"] or {}, raw.get("alias_history") or {}) |
226 | 243 |
|
227 | 244 |
|
228 | 245 | # --------------------------------------------------------------------------- |
|
0 commit comments