tlamatini-self-modify-inclusion · git:20261004.76e603e · 2026-10-04 · sha256 8a4da02665748427
tlamatini-self-modify-inclusion git:20261004.76e603eA
Immutable. This exact content never changes and is served at /api/v1/blob/8a4da02665748427.
---
name: tlamatini-self-modify-inclusion
description: Sweep the whole codebase and keep the SELF-MODIFY source snapshot complete — so the TlamatiniSourceCode/ tree that a `--self-modify` build ships carries every source/build asset Tlamatini needs to read, modify, and REBUILD herself, with heavy media/secrets correctly omitted+redacted and omitted binaries listed in the restore manifest. Invoke whenever you add/rename a new agent, source file, top-level dir, dependency, build input, prompt/identity file, migration, static/template asset, or any rebuild input — and ALWAYS after a feature like Blenderer or the self-update capability lands. Owns copy_source_assets.py and audits it against five invariants with a runnable sweep that GENERATES a snapshot and proves a rebuild's inputs all survive. Sibling of tlamatini-self-update-inclusion (which guards the runnable release).
---
<!--
═══════════════════════════════════════════════════════════════════
✦ T L A M A T I N I ✦ — "one who knows"
Created by Angela López Mendoza · @angelahack1
Developer · Architect · Creator of Tlamatini
Tlamatini Author Banner — do not remove (Angela's name is kept in every build)
═══════════════════════════════════════════════════════════════════
-->
# Tlamatini — Self-Modify Inclusion Sweep
> **HEADLESS IS FORBIDDEN. VISIBLE FOREGROUND EXECUTION ONLY.** Every command, automated test, diagnostic, script, build, agent and browser must run in a visible foreground window on Angela's real desktop. Use forked CMD/PowerShell windows, `execute_forked_window: true`, and `headless: false`. Monitor live; if visibility cannot be confirmed, do not run. Read the [mandatory execution policy](../../../TestsVisiblesAndVisibleExecutionFromClaude2Codex.md).
> **Audience:** Claude Code working ON the Tlamatini codebase for **Angela**.
> **Goal:** guarantee the **source snapshot** a self-able-modify build ships
> (`TlamatiniSourceCode/`, generated by `copy_source_assets.py`) carries **everything a
> rebuild needs** — so a running Tlamatini can read → modify → **regenerate her own
> `Tlamatini.exe`** without missing the minimal thing — while staying lean (media/secrets
> out) and safe (no leaked keys).
This is the twin of `tlamatini-self-update-inclusion`. That one guards the **runnable
release** (what users download). **This one guards the SOURCE tree** Tlamatini carries
of herself. They overlap on one fact: a rebuild from the snapshot must be able to re-run
the *same* `build.py` — so **every input `build.py` consumes must survive the snapshot**.
### The acid test (the whole job in one sentence)
> Can `cd <install>/TlamatiniSourceCode && python build.py --self-modify` succeed using
> **only** the snapshot plus the documented restore steps? If yes, the snapshot is complete.
---
## Shared build inputs (2026-09-27)
The runtime build now copies loose files directly from
`build_runtime_assets.ROOT_SOURCES`; the sweep adds this inventory to its build
inputs, and `validate_snapshot_carriage()` compares each source against the
snapshot or its explicit restore mapping. This includes the shared
`chat_voice_settings.py` and Whisperer `chat_worker.py`. No second copy list is
needed when adding a helper. Run the snapshot sweep in a verified visible
foreground console, kept open afterward; `--keep` retains the generated tree
for inspection. If Git is forbidden, omit history comparisons elsewhere in this
skill and state that limitation; snapshot generation itself needs no Git.
## The file this skill owns
**`copy_source_assets.py`** (repo root) — generates the snapshot. The following rules decide what
ships:
| Knob | Controls |
|---|---|
| `EXCLUDED_DIR_NAMES` | directory names pruned everywhere (`.git`, `node_modules`, `build`, `dist`, `pools`, `staticfiles`, `Temp`, `Templates`, `agents_backup`, `updater`, `TlamatiniSourceCode`, …) |
| `KEEP_DIR_PATHS` | exact source-directory exceptions, including PDF.js's `build/` API/worker and Bootstrap/jQuery vendor `dist/`; other build outputs stay excluded |
| `EXCLUDED_EXTENSIONS` | file types dropped (`.pdf/.pptx/.png/.mp4/...`, binaries, generated state). **`.ico`/`.wav`/`.svg` are deliberately KEPT** (build-required) |
| `EXCLUDED_FILE_NAMES` | exact files dropped (`db.sqlite3`, `data.keys`, `settings.local.json`, `_version.py`, …) |
| `EXCLUDED_FILE_GLOBS` | patterns dropped (`*.version.txt`, `*_log.*`) |
| `RESTORE_FROM_INSTALL` | binaries the build NEEDS but the snapshot OMITS → restored from the install at rebuild (`jd-cli.jar`, `XAIHT-Tlamatini.mp4`). The rebuild's escape hatch. |
| `REQUIRED_SNAPSHOT_FILES` + `_wants_redaction()` | the completeness floor (raises if a critical file is missing) and the secret-redaction rules (config.json + agent config.yaml) |
It also writes `_SOURCE_SNAPSHOT_MANIFEST.json` (counts/restore list) and
`_REBUILD_INSTRUCTIONS.md` (the restore + rebuild runbook). The walk is **generic** — any
new `.py/.js/.css/.yaml/.pmt/...` ships automatically. The danger is the *exclusions*
wrongly dropping a rebuild input, an omitted binary missing from the restore manifest, a
new always-present capability file not in `REQUIRED_SNAPSHOT_FILES`, or a secret leaking.
---
## The FIVE invariants
### Invariant 1 — INCLUDE: every rebuild SOURCE input survives
Every file `build.py` reads to build (the build scripts, `requirements.txt`, all
`--add-data` source trees, `ROOT_SOURCES`, optional identity copies, `optional_dir_copies` sources,
`support_files`, the icon/wav/svg, every agent template, every `SKILL.md`, `prompt.pmt`,
`Tlamatini.md`, `agentic_skill.md`, `monitoring-prompt.pmt`) must appear in the snapshot —
**or** be in `RESTORE_FROM_INSTALL`. A source file dropped by an exclusion rule = a rebuild
that fails or degrades.
### Invariant 2 — OMIT-LEAN, but RESTORE what the build needs
Heavy media, dev trees, regenerable state and secrets stay out. Measure the actual
snapshot; do not impose an obsolete ~10 MB target or drop required vendor assets.
But **anything omitted that the build genuinely consumes must be in `RESTORE_FROM_INSTALL`**
(restored from the install) or covered by a regeneration step in `_REBUILD_INSTRUCTIONS.md`
(e.g. `collectstatic` for `staticfiles`). Optional inputs (the `images` gallery) may
degrade gracefully — decide per asset whether degradation is acceptable or it needs a
restore entry.
### Invariant 3 — REDACT: no live secret survives
`config.json` and every agent `config.yaml` are scrubbed to `<KEY goes here>` placeholders;
`data.keys` is excluded outright. The snapshot must contain **zero** live keys.
### Invariant 4 — COMPLETENESS: critical files are guaranteed, not incidental
`REQUIRED_SNAPSHOT_FILES` raises if a build-/run-critical source is missing. When you add a
**new always-present capability** (a new build script, a new identity file, a flagship new
agent), add its canonical file here so a future careless exclusion can't silently drop it.
### Invariant 5 — REBUILD COHERENCE: the manifest + instructions are true
`_SOURCE_SNAPSHOT_MANIFEST.json` and `_REBUILD_INSTRUCTIONS.md` exist, `errors == []`, and
the restore steps name real omitted binaries with correct install-relative sources.
---
## THE SWEEP — run this every time
### Step 0 — run the deterministic checker (does the heavy lifting)
```bash
python .claude/skills/tlamatini-self-modify-inclusion/scripts/sweep_self_modify.py
# add --keep to retain the unique Temp/_self_modify_sweep_<id> printed by the checker
```
It **actually generates** a snapshot into `Temp/` and verifies: it builds error-free with
all `REQUIRED_SNAPSHOT_FILES`; **every resolvable `build.py` input is carried or restorable**
(distinguishing source-drop FINDINGS from intentionally-omitted media/regenerable NOTES);
no live secret survives (re-running copy_source_assets' own redaction logic on the OUTPUT +
a config-file value scan); the restore manifest + instructions exist and name real binaries;
and no source-like extension is in the exclude set. Exit code = findings (0 == clean). Fix
every `[FINDING]`; read every `[note]` and confirm the degradation/regeneration is intended.
### Step 1 — diff since the last release and classify new paths
```bash
git diff --name-status "$(git describe --tags --abbrev=0 --match 'v[0-9]*')"..HEAD
# brand-new TOP-LEVEL repo entries — the highest risk for a wrongly-excluded rebuild input
git diff --name-status "$(git describe --tags --abbrev=0 --match 'v[0-9]*')"..HEAD \
| awk '$1=="A"{print $2}' | awk -F/ '{print $1}' | sort -u
```
For each new path ask the taxonomy question below. New `.py/.js/.css/.yaml/.pmt/SKILL.md`
inside already-walked trees auto-ship (note, no action). The risks are: a new **binary**
build input, a new **excluded** dir/ext/name that hides source, a new **secret-bearing
config file**, or a new **always-present** file that belongs in `REQUIRED_SNAPSHOT_FILES`.
### Step 2 — the judgment passes the script can't fully make
```bash
# (a) New binary build inputs the build reads (icons/fonts/wav/jar/etc.) that EXCLUDED_EXTENSIONS would drop
grep -nE "--add-data=|--icon|optional_dir_copies|copy_root_sources|support_files" build.py | grep -iE "\.(ico|wav|svg|png|jpg|ttf|otf|jar|dll|bin|dat)"
# (b) New config files that may carry secrets but AREN'T covered by _wants_redaction()
grep -rilE "api[_-]?key|token|secret|password|client_secret" Tlamatini --include=*.json --include=*.yaml --include=*.yml \
| grep -viE "/agents/.*/config.yaml$|agent/config.json$"
# (c) New dependency / runtime added (cross-check the self-update skill too)
git diff "$(git describe --tags --abbrev=0)"..HEAD -- requirements.txt
```
- (a) Any binary the build needs and the snapshot drops → add to `RESTORE_FROM_INSTALL`
(omit + restore) or to the KEEP exceptions (if small + truly source-required, like the
`.ico`/`.wav`/`.svg` already are).
- (b) Any NEW config file that can hold a live key → extend `_wants_redaction()` to scrub it
(and confirm Step 0's redaction check then covers it), or exclude it by name.
- (c) A new dep doesn't affect the snapshot directly (it ships `requirements.txt`), but the
rebuild `pip install`s it — make sure `requirements.txt` is current (the self-UPDATE skill
owns the *bundled* side).
**v1.48.14 External-MCP gate:** the snapshot must carry `agent/runtime_provisioner.py`,
`agent/external_mcp_defaults.py`, and the manager/build/secret-regeneration source, but must
not copy the downloaded `%LOCALAPPDATA%\Tlamatini\runtimes` tree or persistent Memory graph.
Treat `external_mcps.json` as gitignored user state: the snapshot resets it to an empty
`mcpServers`/`active` document; startup seeds defaults. The public build receives inactive
maintained defaults, never the keyed developer catalog. Verify
`REQUIRED_SNAPSHOT_FILES`, `_wants_redaction()`, and the generated rebuild instructions agree.
**v1.48.17 source-coherence gate:** the snapshot must carry Grepper's encoding-safe source,
`agent_verdict.py`, `services/agent_contracts.py`, Kuberneter, and their regression tests,
including `test_grepper_encodings.py`, `test_status_vocabulary.py`, and
`test_preserved_user_state.py`. The status vocabulary must remain defined once in
`agent_verdict.py`; do not copy its sets into a snapshot helper. Confirm the generated
snapshot preserves `returncode`/`success`/semantic-status fields and the updater's
`Uninstaller.exe` rule without copying local runtime state or keyed catalogs.
**v1.50.0 release source-coherence gate:** the snapshot must carry the complete
NetSpeed-Calculator source/config/wiring/tests and migrations 0195-0197, `sqlite_copy.py`
plus its WAL backup/swap tests, Googler's structured-dork and two-tier plain-HTTP-first resilience
source/config, `test_googler_dorks.py`, and the optional visible dork-hunt harness,
migration 0194's Deep Internet Research prompt, and the
`adding_external_mcp` skill tree. It must also carry the private-builder source that performs
contact synchronization, but it must never copy `contacts.json`, `contacts.private.json`, a
frozen-install contact book, or live External-MCP secrets. Derive current agent/tool/migration counts
from the generated snapshot rather than copying historical prose counts.
### PDF and update-helper carriage gate (2026-09-16)
Keep the complete `Tlamatini/agent/static/agent/vendor/pdfjs/` tree, including
`build/pdf.mjs`, `build/pdf.worker.mjs`, fonts, character maps, WASM decoders and
licenses. The global `build` directory exclusion requires the exact
`KEEP_DIR_PATHS` exception; file KEEP rules alone cannot defeat directory pruning.
PDF backend/frontend files, `pyinstaller_hooks/hook-pymupdf.py`, the vendoring
script and representative binary assets belong in `REQUIRED_SNAPSHOT_FILES`.
The snapshot must also include `agent/sqlite_copy.py`, `apply_update.ps1` and
`preserved_user_state.json`. The build carries the same SQLite helper as a
standalone install-root script for the external updater. Snapshot generation
errors and recorded copy failures must abort the build; never fall back to a
stale static source tree. Generated rebuild instructions must require an explicit
`TLAMATINI_VERSION`, since snapshots omit Git history and generated version files.
### Step 3 — fix every finding, re-run Step 0 until clean, eyeball the notes.
---
## Asset taxonomy — type → ship in snapshot? → action
| New asset | In snapshot by default? | Action |
|---|---|---|
| New `.py/.js/.css/.html/.yaml/.pmt/.proto/SKILL.md` (source) | ✅ auto (generic walk) | none |
| New **agent** (`agent/agents/<x>/` source + config.yaml) | ✅ auto; config.yaml auto-**redacted** | none (verify redaction in Step 0) |
| New **migration** (`.py`) | ✅ auto | none |
| New **build script / build input file** at repo root | ✅ if not excluded | add to `REQUIRED_SNAPSHOT_FILES` if always-present |
| New **small build-required binary** (`.ico/.wav/.svg`-class) | ✅ (those exts KEPT) | if a NEW binary ext, KEEP it (remove from excludes) or restore-map it |
| New **heavy binary** the build needs (`.jar/.mp4/large media`) | ❌ omitted | add to `RESTORE_FROM_INSTALL` (+ it lands in `_REBUILD_INSTRUCTIONS.md`) |
| New **optional media** (gallery image) | ❌ omitted | leave omitted if degradation OK; else restore-map |
| New **config file with secrets** | ✅ shipped — ⚠️ maybe UNREDACTED | extend `_wants_redaction()` or exclude by name |
| New **runtime-state / generated dir** | should be ❌ | add its name to `EXCLUDED_DIR_NAMES` |
| New **flagship capability file** (e.g. `self_update.py`, `Tlamatini.md`) | ✅ auto | add to `REQUIRED_SNAPSHOT_FILES` so it's guaranteed |
| New **operator toolkit tree** at the repo root (e.g. `security/` — the Blue-hat defender/whitelist `.ps1`, the `.bat` UAC launchers, `README.md`, its asset test) | ✅ auto (the generic walk carries `.py`/`.ps1`/`.bat`/`.md`) | nothing to add — but you MUST confirm its **runtime output** dir is excluded (next row) |
| New **runtime / evidence dir INSIDE a shipped tree** (e.g. `security/security_logs/`) | ❌ must be **EXCLUDED** | add the dir name to `EXCLUDED_DIRS` in `copy_source_assets.py`. It is state, not source — and here it is the operator's forensic evidence, which can contain their own usernames, IPs and command lines. It must never travel in a snapshot |
The single most dangerous omissions: a **source file hidden by an over-broad exclusion**
(Step 0 flags it as a source-drop FINDING) and a **new secret-bearing config that
`_wants_redaction()` doesn't cover** (Step 2b — the raw scan in Step 0 catches obvious key
shapes, but a novel config path needs the redaction rule extended).
---
## Where to make each fix (`copy_source_assets.py`)
- **A source file got excluded** → narrow the offending rule in `EXCLUDED_EXTENSIONS` /
`EXCLUDED_FILE_NAMES` / `EXCLUDED_FILE_GLOBS` / `EXCLUDED_DIR_NAMES`, or add a KEEP carve-out.
- **An omitted binary the build needs** → add `"snapshot/rel/path": "install/rel/source"` to
`RESTORE_FROM_INSTALL` (it auto-renders into `_REBUILD_INSTRUCTIONS.md`).
- **Guarantee a critical file** → add its snapshot-relative path to `REQUIRED_SNAPSHOT_FILES`.
- **A new secret-bearing config** → extend `_wants_redaction()` to return `'json'`/`'yaml'`
for it (and add the key suffix to `_SECRET_KEY_RE` if it's a novel secret-key name).
- **A new state/output dir leaking in** → add its name to `EXCLUDED_DIR_NAMES`.
---
## Done criteria (all must hold)
1. `sweep_self_modify.py` exits clean (no `[FINDING]`); every `[note]` is reviewed + intended.
2. Every new top-level repo path from the since-last-tag diff is classified and handled.
3. Snapshot generation completes error-free with every `REQUIRED_SNAPSHOT_FILES` entry; separately state whether an actual rebuild was run.
4. Every `build.py` SOURCE input is in the snapshot or in `RESTORE_FROM_INSTALL`.
5. Zero live secrets in the snapshot (redaction check + value scan pass).
6. The manifest + `_REBUILD_INSTRUCTIONS.md` are accurate; restore targets are real.
7. `python -m ruff check copy_source_assets.py` is clean.
8. (Ideal) you eyeballed a `--keep` snapshot and spot-confirmed the newest feature's source
files are physically present.
---
### Complete carrier/redaction gate (2026-09-16)
- `validate_snapshot_carriage()` checks EVERY source file in the shared runtime
`SOURCE_TREES` and `ROOT_SOURCES`, not just representative canaries. Each must
match source bytes (except intentionally sanitized configuration), or have an
explicit `RESTORE_FROM_INSTALL` mapping. Collected static is regenerated.
- Keep all tracked PDFer `agents/pdfer/_art/**` ornaments; they are small rendering
inputs, unlike the optional `agent/images/` gallery. Keep all local frontend
vendor files/fonts/licenses and exact vendor build/dist directory exceptions.
- Require installer/uninstaller, public/private wrappers, integrity helper,
External MCP defaults/provisioner, and both inclusion skills/checkers.
Keep the `.claude` and `.gemini` copies synchronized.
- Malformed JSON/YAML or unavailable PyYAML must abort redaction, not return raw
content. Parse YAML structures so block scalars/flow mappings/aliases cannot
bypass a line-based scrubber. Exceptions and audit reports must not print keys'
values, including token prefixes. Unknown new secret-bearing configs still
require human classification; shape scans do not prove universal secrecy.
- Custom destinations must be dedicated repository descendants. An existing
nonempty destination requires a snapshot manifest before replacement. Reject
linked source inputs. The emitted manifest omits developer absolute paths.
- The file-only checker creates a fresh unique scratch directory. A CLEAN result
proves its stated source guards, NOT a successful frozen rebuild. Honor any
no-tests/no-build restriction and do not silently expand this sweep.
## Companion references
- `tlamatini-self-update-inclusion` — the sibling skill guarding the **runnable release**
(`build.py` carriers + the update swap). Run BOTH after any feature: one proves users can
*receive* the feature, this one proves Tlamatini can *rebuild herself with* it.
- `docs/claude/architecture.md` → *Self-Knowledge & Self-Modification* and
`docs/claude/gotchas.md` → *Building & Packaging* for the `--self-modify` flag mechanics.
- `VERSIONING.md` — use Git tags in the repository; a Git-free snapshot requires an explicit `TLAMATINI_VERSION`.
### Prompt Flow Panel and menu snapshot gate (2026-09-25)
`REQUIRED_SNAPSHOT_FILES` guarantees the whole feature: the backend (`agent/prompt_flow_panel_consumer.py`, `agent/prompt_flow_panel_runtime.py`, `agent/services/prompt_flow_panel.py`, `agent/management/commands/check_prompt_flow_panel.py`), the page, its CSS, `prompt-flow-panel-model.js`, `prompt-flow-panel.js` and `acp-editor-tools.js`, the four `agent/test_prompt_flow_panel*.py` modules, the visible menu/panel scripts (`scripts/menu_reference_graph.mjs`, `menu_browser_checks.py`, `menu_live_checks.py`, `run_menu_state_checks.py`, `panel_search_title_visible.py`, `acp_editor_visible.py`, `prompt_flow_extension_visible.py`), `docs/prompting-flow-designer.md` and `docs/examples/prompting-kickoff.fpmt`. `scripts/menu_reference_graph.mjs` is not optional tooling: `agent/test_frontend_mutable_state.py` runs it for the scope-aware cross-file const-poison check.
`.fpmt` is a source/text extension — never add it to `EXCLUDED_EXTENSIONS`. The kept snapshot of 2026-09-25 physically contained `docs/examples/prompting-kickoff.fpmt` and no `.pmt` copy of it. The plain-text `prompt.pmt` / `monitoring-prompt.pmt` remain ordinary carried inputs.
⚠️ On 2026-09-25 `git diff` also showed `copy_source_assets.py` with a whole-file line-ending rewrite (543 changed lines, only 23 real). Review that before committing, so history records the real change rather than churn.
### Prompt Flow commentary/input refactor carriage (2026-10-03, source only)
New `.fpmt` documents are version 2: `user_input` is the existing runtime reply step with the supplied notched figure; `user_commentary` is a static speech-bubble annotation. Preserve version 1 migration, identifiers, connections, settings and cancellation behavior. Static notes have no ports/Start state and do not enter prompts, history or playback steps. Their full wrapped text and inline editors grow at the chosen width/font without internal scrollbars; saved height is a minimum. The compatible browser-draft key still ends in `.draft.v1.<user id>`.
The existing backend/template/static/guide/example carriers cover these changes. Keep the frontend and backend version/validation contracts synchronized, carry the updated kickoff example (seven operations plus one note), and verify source/collected-static byte parity. `scripts/prompt_flow_commentary_visible.py` travels through the generic source snapshot walk; do not claim it is explicitly required unless the live manifest lists it. The refactor passed 61 backend/packaging tests, nine foreground Chrome checkpoints and both inclusion sweeps, with no rebuilt executable/installer. A source sweep does not establish release delivery. Current cache suffix is `-prompt-commentary-input-1`; retain the timestamp/environment expression. See `docs/prompting-flow-designer.md` and `docs/changes/2026-10-03-prompt-commentary-input.md`.
Run checks only in a verified visible foreground console and explicitly headed Chrome. Stop the task-owned harness/browser/server when Angela asks; use its `Temp/prompt-commentary-visible/close.confirmed` marker and verify owned processes/listeners are gone. Do not stop unrelated user processes.
### Skill boundary, Context Governor and dossier snapshot gate (2026-09-26)
`REQUIRED_SNAPSHOT_FILES` also guarantees: `agent/context_governor.py` with `context_gauge.js` / `context_gauge.css`; `agent/skills/validation.py`, `agent/skills/redaction.py`, `scripts/skill_inventory.py` and `scripts/sync_assistant_skills.py`; `TestsVisiblesAndVisibleExecutionFromClaude2Codex.md` (every skill links to it) and `AGENTS.md`; and the six-file dossier generator (`agent/doc_generation/complete_project_docs.py` + `dossier_content.py`, `dossier_theme.py`, `dossier_pdf.py`, `dossier_pptx.py`, `dossier_verify.py`), which only works as a set. The generator reads Git (`git ls-files`, tags), so it runs from a repository clone, not from a Git-free snapshot. The shared `flow_canvas.css` / `flow-canvas-interactions.js` and the three newest visible scripts (`flow_canvas_mechanics_visible.py`, `prompt_flow_selection_visible.py`, `prompt_flow_connections_visible.py`) were already listed.
The 2026-09-25 line-ending warning about `copy_source_assets.py` is resolved: `ca66745` committed only its 28 real lines. It happens easily: `build.py` and `copy_source_assets.py` have MIXED line endings, and an editor that normalizes them rewrites the whole file. Check `git diff --stat` against `git diff --ignore-space-at-eol --stat` before committing.
### Compact mode snapshot gate (2026-10-01)
- `REQUIRED_SNAPSHOT_FILES` (`copy_source_assets.py`) names `context_fitter.py`, `model_capacity.js`, `model_capacity.css` and `chat_table_contrast.js`, so a self-rebuild keeps the fitter and its page pieces together.
- **2026-10-02 — the Compact mode SWITCH.** The list also names `agent/compact_mode.py`, its migration `0211_compact_state.py` and `compact_costs.js` (the per-row token prices in the Configure dialogs). The box is the toolbar's `#compact-mode-enabled`, owned by `model_capacity.js`; the old Compact badge and the ACPX lock are gone, so do not look for them. `build_runtime_assets.REQUIRED_STATIC` carries the same page pieces (`model_capacity.js` / `.css`, `compact_costs.js`) into the release.
### Self-modify switch snapshot gate (2026-10-03)
- **Who is self-able now.** `rag/config.self_modify_available()` decides. A SOURCE (dev) run of this checkout is ALWAYS self-able, folder or no folder — Angela: *"THE DEV MODE MUST ALWAYS BE LIKE --self-modify MODE"*. A FROZEN build is self-able only when `build.py --self-modify` bundled `TlamatiniSourceCode/` beside the exe. So the snapshot this skill owns is what makes a FROZEN build self-able; dev mode does not depend on it.
- **The switch.** A toolbar box **Self-modify** (`#self-modify-enabled`, right after Compact mode), owned by `self_modify_switch.js` and persisted in `CompactState.self_modify` (migration `0212_compact_state_self_modify.py`, ON by default). ON sends Tlamatini.md (≈28.9K tokens per request); OFF sends one honest line instead. A model that cannot hold it shows the box locked OFF (🔒). Where self-modify is not available, the box and its script are not rendered at all.
- **Carriage (verified 2026-10-03).** `REQUIRED_SNAPSHOT_FILES` names `Tlamatini/agent/migrations/0212_compact_state_self_modify.py` and `Tlamatini/agent/static/agent/js/self_modify_switch.js`, and `build_runtime_assets.REQUIRED_STATIC` names `agent/js/self_modify_switch.js`. A missing one makes `copy_source_assets.py` raise rather than produce a quietly-incomplete tree.
- ⚠️ Never run `build.py` just to check the frozen branch: it erases `Tlamatini/db.sqlite3` and wipes `dist/`. The frozen page is covered by `agent/test_self_modify_switch.py::FrozenPageTests`, which render the real chat page under a patched `sys.frozen`, with and without `--self-modify`.
### Central model settings runtime gate (2026-09-20)
The model registry must ship as compiled `agent.agents.model_settings` and as
portable `agents/model_settings.py`. Frozen services import compiled code and
resolve portable data with `get_agents_root()`, never a synthetic `__file__`
source path inside `_internal`. Require `check_agent_runtimes` in the frozen
archive and self-modify snapshot. The build executes this command before ZIP
creation: every template must prepare, reusable helpers and planner catalogs
must refresh, actual model loaders must resolve saved settings, and File-Creator
must write exact scratch bytes with the selected runtime Python. File-only
inclusion sweeps are not a substitute for this execution check.
The complete operational contract is `docs/model_configuration.md`; dated executed
checks are in `docs/model-configuration-verification.md`. Preserve saved global
values and explicit agent overrides during updates. Absent new keys use registry
fallbacks/defaults; existing choices must not be silently replaced. Document model
key changes, empty-value semantics, next-load/reconnect behavior and helper carriage
in README, BookOfTlamatini, self-knowledge, prompts and agent/MCP creation guides.
UTF-8/BOM loader checks must include Windows default-codepage execution. The current
gate checks 89 templates and 21 model loaders; derive future counts from source.