Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
8fa8db0
performance report
Jun 13, 2026
bb0db02
plans
Jun 13, 2026
b7b100a
improved readability
Jun 13, 2026
b01e692
improved quality
Jun 13, 2026
1fff056
Commit 0.1: Adversarial string generator module
Jun 13, 2026
713e2bf
Commit 0.2: Timing, scaling, and allocation harness
Jun 13, 2026
6413582
Commit 0.3: Hotspot registry and smoke coverage
Jun 13, 2026
7d12ffb
Commit 0.4: Opt-in scaling tests for registry entries
Jun 13, 2026
05996a2
Commit 0.5: Focused regex backtracking probes
Jun 13, 2026
7f85cdc
Commit 0.6: Decode/decompress amplification probes
Jun 13, 2026
bc23d1e
Commit 0.7: Container, formatting, and search probes
Jun 13, 2026
43fc6db
Commit 0.8: MILESTONE - aggregate report and Plan 1 thresholds
Jun 13, 2026
60e3407
constants
Jun 13, 2026
d9c9e64
Add realistic content families to perf tests
Jun 13, 2026
caebb36
updated
Jun 13, 2026
914d1f7
Harden mpq parsing with decimal traps and preserve unsafe numeric lit…
Jun 13, 2026
72d86fc
editing unsupported floats plan
Jun 13, 2026
fd5c642
editing unsupported floats
Jun 13, 2026
bf5b8b6
semi-patch
Jun 13, 2026
ef56364
done
Jun 13, 2026
c4bc1c9
update repo agent memory
Jun 13, 2026
98de80b
linted
Jun 13, 2026
694186c
fix allowed imports tracked line numbers
Jun 13, 2026
2223987
patch plan
Jun 13, 2026
a9e68fd
Plan 1 commits 1.1-1.5: inference safety constants, length-gate helpe…
Jun 13, 2026
3f78c88
Update agent.md: use .venv activation, emphasize make gate before eve…
Jun 13, 2026
17ff27e
Plan 1 commit 1.6: gate color inference with length check
Jun 13, 2026
15309df
Plan 1 commit 1.7: gate base64/zlib/gzip with syntax validation
Jun 13, 2026
e9489d3
Plan 1 commit 1.8: cap paint-time binary preview decode
Jun 13, 2026
1c9bbf5
feat(loading): add LoadCoordinator scaffold for open/reload (Commit 2.1)
Jun 13, 2026
bbc41f8
feat(loading): add delayed progress widget without Cancel (Commit 2.2)
Jun 13, 2026
0a235ad
feat(loading): add worker thread for file parsing (Commit 2.3)
Jun 13, 2026
ff5d69d
feat(loading): add progress reporting protocol (Commit 2.4)
Jun 13, 2026
8daf67c
feat(loading): add chunked cooperative model/tree builder (Commit 2.5)
Jun 13, 2026
8b2553c
feat(loading): add schema/validation progress stages (Commit 2.6)
Jun 13, 2026
44398f6
feat(loading): wire delayed widget to open/reload tasks (Commit 2.7)
Jun 13, 2026
ec99c38
feat(loading): add reload build-then-swap without cancellation (Commi…
Jun 13, 2026
14ab347
fix progress bar
Jun 13, 2026
5c72cc8
plan 2.5 - improve async progress bar
Jun 13, 2026
1caec38
loading: extend progress protocol with detail payload
Jun 13, 2026
fed34e7
loading: report builder processed counts with JSON pointer paths
Jun 13, 2026
a0d2bf2
loading: emit decode detail progress and harden with timeout guidance
Jun 13, 2026
5f726f7
loading: throttle detail label updates and forward detail events
Jun 13, 2026
f97afea
loading: stage UI bind, gate large-tree first paint, and swap prebuil…
Jun 13, 2026
663927b
plan 2.6 - improve async ui init
Jun 13, 2026
c653138
updated agent.md
Jun 13, 2026
50b0c5c
Plan 2.6: finalize post-build responsiveness after model build
Jun 13, 2026
838f337
small fixes
Jun 13, 2026
267f49b
patched plans
Jun 13, 2026
b7d9894
Plan 3.1: add cancellation token primitive and tests
Jun 13, 2026
c02bb9c
Plan 3.2: wire loading cancel button to task token
Jun 13, 2026
50d0ecd
Plan 3.3: cancel parse tasks and drop late worker results
Jun 13, 2026
468c0e3
Plan 3.4: cooperative cancel during chunked build
Jun 13, 2026
9202401
Plan 3.5: gate reload swap on cancellation token
Jun 13, 2026
929d7d5
Plan 3.6: add cancellation invariant regression suite
Jun 13, 2026
6561cfa
Plan 4.1: measure tab-close phase timings
Jun 13, 2026
595cc36
Plan 4.2: add close progress delay and dialog tests
Jun 13, 2026
8875fe0
Plan 4.3: add tab-close progress ownership and stages
Jun 13, 2026
38d9a25
Plan 4.4: make close save phase event-loop responsive
Jun 13, 2026
30ee24f
test(plan 4.5): extend tab close regressions for reopen cycles
Jun 13, 2026
8a9c975
docs(plans): mark plan 3 and plan 4 items completed
Jun 13, 2026
cdc6acf
fin
Jun 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .githooks/_check_tree_isolation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ set -euo pipefail

# Allowlisted lines: file:linenumber pairs that are permitted.
ALLOWLIST=(
"tree/item.py:28"
"tree/item.py:29"
"tree/item.py:30"
"tree/item.py:31"
)

is_allowlisted() {
Expand Down
64 changes: 64 additions & 0 deletions agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Agent Guide — Editable-Tree-Model-Example (compact)

_High-signal rules for AI agents. Keep this brief and actionable._
**Last updated:** 2026-06-13

## 1) First commands (always)

```bash
. .venv/bin/activate
timeout 1200 make gate
```

- Tools live in `.venv`.
- `make gate` is mandatory before every commit.

## 2) Mandatory delivery loop (do not skip steps)

For plan-based work, execute exactly this loop:

1. **Pick one next unchecked plan item** (single scope).
2. **Implement only that scope**.
3. **Run targeted tests** for touched files.
4. **Run full gate** (`timeout 1200 make gate`).
5. **Commit immediately** (message references plan item).
6. **Mark plan checkbox `[x]`** only after commit.
7. Repeat for the next item.

Hard rules:
- If tests/gate fail: go back to implementation; **no commit**.
- Do not batch multiple plan items into one commit unless plan explicitly says so.
- Do not stop at “green but uncommitted”.

## 3) Critical architecture facts (easy to miss)

1. **Undo edit path bypasses `JsonTreeItem.set_data()`**
- Real replay path: `DocumentMutationGateway` → undo command → `undo/diff.py:DiffApplier.apply()`.
- Type/value fixes often require changes in both item logic and `DiffApplier`.

2. **`mpq` whole numbers are inferred as FLOAT unless converted**
- Convert `mpq(n,1)` to `int` where integer semantics are required.

3. **UI uses proxy model**
- Map indices proxy↔source before touching tree items.

## 4) Isolation constraints (must hold)

- `editors/inline/*`, `editors/windowed/*` must not import `app/`, `documents/`, `tree/`.
- `editors/factory.py`, `editors/context.py` must not import `app/`, `documents/`.
- `tree/` must not import `app/`, `documents/`, `editors/`, `delegates/`, `state/`, `validation/`.
- No reflection (`getattr` / `hasattr` / `TYPE_CHECKING`) outside allowlist.

## 5) Minimal file map for common work

- Types/coercion: `tree/types.py`, `tree/item_coercion.py`
- Item/model behavior: `tree/item.py`, `tree/model.py`
- Undo replay: `undo/commands.py`, `undo/diff.py`
- Tab composition/lifecycle: `documents/composition/*`, `app/tab_lifecycle.py`, `app/main_window.py`
- Validation: `documents/controllers/validation.py`, `validation/*`

## 6) Testing quick rules

- Use `QT_QPA_PLATFORM=offscreen` for pytest.
- Prefer focused tests during development, then full gate.
- Add regression tests for every bug fix or plan checkpoint.
19 changes: 16 additions & 3 deletions ai-memory/repo-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

_This is a condensed index and architectural summary. LLM agents should refer to direct source files for implementation
details._
**Last updated:** 2026-06-01 (after tree-upward-imports refactor; added `core/`, `tree/codecs/`,
tree-isolation rule, and `check-tree-isolation` target).
**Last updated:** 2026-06-13 (after raw-numeric edit-flow fix; added DiffApplier RAW_FLOAT routing,
integer promotion for whole-number mpq edits, and `agent.md`).

## 1) High-level Purpose

Expand All @@ -25,7 +25,7 @@ Model".
| **Type System** | `tree/types.py` (Definitions), `tree/item_coercion.py` (Conversion) |
| **Editor Widgets** | `editors/factory.py` (dispatch), `editors/inline/`, `editors/windowed/` |
| **Delegates** | `delegates/value.py` (paint + createEditor → editors.factory), `delegates/formatting/` |
| **Undo System** | `undo/commands.py` (Operations), `undo/diff.py` (Surgical replay) |
| **Undo System** | `undo/commands.py` (Operations), `undo/diff.py` (Surgical replay + RAW_FLOAT routing) |
| **Structural Ops** | `tree_actions/` (Clipboard, DnD, Move, Sort, Anchors) |
| **Validation** | `validation/` (JSON-Schema), `app/validation_presenter.py` |
| **Theming** | `themes/`, `app/theme_controller.py` |
Expand All @@ -43,6 +43,15 @@ Model".
how data is handled. Don't scatter type logic in the UI.
- **Surgical Model Updates**: The `DiffApplier` (`undo/diff.py`) is used during Undo/Redo to emit minimal Qt signals.
This preserves UI state like selection and expansion that would be lost on a full model reset.
**Important**: `DiffApplier.apply()` bypasses `JsonTreeItem.set_data()` — special type handling (e.g., `RAW_FLOAT`
routing to `_set_raw_numeric_value`) must be added to `DiffApplier.apply()` explicitly.
- **Edit flow path**: Editor → `editors/factory.set_value_model_data()` → `DefaultEditContext.commit()` →
`DocumentMutationGateway.commit_set_data()` → `CommandDispatcher.push_edit_value()` → `_EditValueCmd` →
`DiffApplier.apply()` → `JsonTreeItem._apply_typed_value()` / `_set_raw_numeric_value()`.
- **Raw numeric values**: Unsupported numeric literals (overflow, underflow, non-finite) are preserved as
`RawNumericValue` (`core/raw_numeric.py`) with type `JsonType.RAW_FLOAT`. Edits go through
`JsonTreeItem._set_raw_numeric_value()` which handles: safe-parse → int/float conversion, unchanged → preserve,
regex-match → keep raw, regex-violate → reject. Whole-number mpq results are promoted to `int` for `INTEGER` type.
- **No external `data_store.*` reads** (Plan 20). External callers (`app/`, `undo/`, `tree_actions/`, `state/`) must
reach state through typed `JsonTab.*` properties. The pre-commit hook
`.githooks/_check_data_store_leaks.sh` enforces this for 17 retired attributes.
Expand Down Expand Up @@ -138,6 +147,7 @@ editors/
│ ├── mpq_spinbox/ QMpqSpinBox (spinbox.py + validator.py).
│ ├── datetime/ BetterDateTimeEditor + validator (enums/regex imported from core/).
│ ├── affix_composite.py AffixCompositeEditor (prefix/suffix + spinbox).
│ ├── raw_numeric_line.py RawNumericLineEdit + RawNumericValidator for RAW_FLOAT.
│ ├── secret_line.py _SecretLineEdit + _SecretEditorWatcher.
│ └── caps_safe_line.py _CapsLockSafeLineEdit + lock-key constants.
└── windowed/ Modal dialog editors (no app/documents/tree imports).
Expand All @@ -153,6 +163,9 @@ editors/
```
core/
├── __init__.py
├── raw_numeric.py RawNumericValue dataclass + narrow edit regex validator.
├── safe_mpq.py Safe mpq parsing (parse_mpq, safe_mpq_from_text, MpqParseResult).
├── frozen_value.py Legacy FrozenValue alias → RawNumericValue (compatibility).
└── datetime_parsing/ Pure datetime parsing (no Qt dependency).
├── __init__.py Re-exports DateTimeCategory, parse_datetime_text, etc.
├── enums.py DateTimeCategory enum.
Expand Down
12 changes: 8 additions & 4 deletions ai-memory/todo-n-fixme.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# TODO & FIXME

_Last updated: **2026-06-01** (post code-quality audit). Minor smells
and speculative wishlist entries were pruned; only actionable,
meaningful work remains. Format:
`- [ ] [scope] description — file:symbol`._
_Last updated: **2026-06-13** (post raw-numeric edit-flow fix). Added
completed entry for DiffApplier RAW_FLOAT routing and integer promotion.
Format: `- [ ] [scope] description — file:symbol`._

## High priority — architecture (audit §8)

Expand Down Expand Up @@ -42,6 +41,11 @@ meaningful work remains. Format:

## Low priority — hygiene & dead code (audit §6)

- [x] [bug] Fix raw numeric edit flow: `DiffApplier.apply()` now routes
`RAW_FLOAT` edits through `_set_raw_numeric_value()` instead of
bypassing it; whole-number mpq results are promoted to `int` for
`INTEGER` type (displaying "42" not "42.0").
— `undo/diff.py:apply`, `tree/item.py:_set_raw_numeric_value`
- [x] [hygiene] Remove deprecated shims `_closed_tabs_stack` /
`_MAX_CLOSED_TABS` and the no-op stubs `_setup_validation_dock` /
`_setup_schemas_menu` — tests and production code now call the
Expand Down
1 change: 1 addition & 0 deletions app/loading/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Loading coordination for file open and reload operations."""
Loading
Loading