Skip to content

Sync v0.2.0: family closure, report workflow, and tmux dotted-path fix - #3

Open
LehengChen wants to merge 25 commits into
frenzymath:mainfrom
LehengChen:feat/family-closure-report-and-tmux-dotfix
Open

Sync v0.2.0: family closure, report workflow, and tmux dotted-path fix#3
LehengChen wants to merge 25 commits into
frenzymath:mainfrom
LehengChen:feat/family-closure-report-and-tmux-dotfix

Conversation

@LehengChen

Copy link
Copy Markdown
Collaborator

Brings the public repo up to the current v0.2.0 development state. Upstream main is still at the initial public snapshot, so this carries 23 commits across 64 files rather than a single feature.

What is in here

Family closure (from #2 by @Zihao-Liu-Leo, which this supersedes) — iteris family new/init/status/schedule/start/run/stop/export/pool: joint scheduling and a shared verified-fact pool for parallel sibling North-Star tracks, via an .iteris/FAMILY.json wrapper with max_concurrent control.

Report workflowiteris report new/draft/build/export/config/feedback/doctor/status plus the dashboard Reports UI: versioned LaTeX reports drafted from verified project evidence.

Fix: dotted project paths break tmux sessions. Reported by a user who found that a working directory could not contain a .. The cause is not path handling but tmux target syntax: tmux new-session -s iteris-2.15 silently STORES the session as iteris-2_15, because . is a pane separator. Every later -t iteris-2.15 was then parsed as pane 15 of session iteris-2 and failed with can't find pane: 15 — leaving a live worker that could not be attached, logged, messaged, or stopped.

This is general (any project directory containing a dot) and it lands squarely on family closure, whose documented use case is sibling ids 2.152.19. Fixed at two chokepoints: project.tmux_safe_name inside session_slug covers every generated name, and tmux.tmux_target covers names passed by hand via --session. Creation and lookup sites were changed together — normalizing only one side reproduces the original mismatch. Folding ./: to _ matches tmux's own behavior (it reports duplicate session for 2.15 when 2_15 exists), so no two names collapse that tmux kept apart.

Also: PATH pinning for interactive monitor sessions, and restoring the executable bit on scripts/deploy.sh that #2 dropped.

Testing

  • python -m pytest -q408 passed (8 new regression tests in tests/test_tmux_target_names.py)
  • Live tmux verification on an isolated socket (tmux -L) with a real 2.15 project: create, has-session, capture-pane, send-keys, kill-session all succeed; dot-free names keep their historical session names unchanged.
  • Family smoke test: a 3-sibling family (2.15/2.16/2.17) scaffolds correctly, family status reports all three, and schedule --dry-run respects max_concurrent=2.
  • Report smoke test: report new/draft work in a dotted project directory and with a dotted report id (report paths are filesystem-only and were never affected).

Note for reviewers

#1 was closed as superseded — it is the same feature from the same author in an earlier form, fully contained in #2. Original commit authorship from both contributors is preserved in the history.

Known nit, not fixed here

iteris family new --manifest expects sibling_id for each sibling, while the --sibling CLI spec uses id=. Passing id in a manifest silently yields sibling_id: null instead of erroring. Left for a follow-up since it is a validation gap, not a regression.

LehengChen and others added 24 commits June 18, 2026 10:32
Introduce iteris family for parallel sibling North-Star runs with shared verified-fact pool and max_concurrent scheduling, plus iteris report for LaTeX/PDF drafts from verified project evidence. Existing monitor, doctor, run, and evolve commands remain unchanged; family integrates via a thin CLI typer and lazy goal-prompt context.

Co-authored-by: Cursor <cursoragent@cursor.com>
Expose iteris family and iteris report in English and Chinese READMEs, user guide, and GUIDE_INDEX so open-source users can discover the new workflows.

Co-authored-by: Cursor <cursoragent@cursor.com>
…e-and-report

Add family closure scheduling and report workflow
Match the natural workflow order: generalize from one verified result first, then parallel sibling North-Star closure.

Co-authored-by: Cursor <cursoragent@cursor.com>
…workflow

Merges frenzymath#2 (Zihao-Liu-Leo). The report half of that PR is
already present in main via local development (identical tree), so this
merge effectively lands the family-closure feature: iteris family init/
status/schedule/export/pool, shared verified-fact pool, sibling markers,
and .iteris/FAMILY.json wrapper scheduling with max_concurrent.

Supersedes PR frenzymath#1, whose family files appear here in revised form.
PR frenzymath#2 dropped the mode bit (100755 -> 100644) as an unintended side effect.
…paths)

A project directory containing a dot produced a session Iteris could create
but never address again. `tmux new-session -s iteris-2.15` silently STORES
the session as `iteris-2_15`, because tmux target syntax reads `.` as a pane
separator. Every later `-t iteris-2.15` was then parsed as pane 15 of session
`iteris-2` and failed with `can't find pane: 15`, leaving a live worker that
could not be attached, logged, messaged, or stopped.

This is general, not incidental: it hits any project whose directory name
contains a dot, and lands squarely on family closure, whose documented use
case is sibling ids 2.15-2.19.

Fixed at two chokepoints:

- `project.tmux_safe_name` folds `.` and `:` to `_`, applied inside
  `session_slug` before the length check so the collision digest stays
  stable. Covers every Iteris-generated name.
- `tmux.tmux_target` applies the same fold at each tmux invocation, so a
  name passed by hand via `--session` is normalized too.

Folding matches tmux's own behavior: it reports `duplicate session` for
`2.15` when `2_15` exists, so no two names collapse that tmux kept apart.
Both helpers are idempotent, so layering them is safe. Creation and lookup
sites were changed together — normalizing only one side would have recreated
the original mismatch.

Verified end-to-end on an isolated tmux socket with a real `2.15` project:
create, has-session, capture-pane, send-keys, and kill-session all succeed.
Dot-free names keep their historical session names unchanged.
Interactive monitor sessions invoke Iteris again for read-only lookups and
user-approved project actions, but Codex tool shells may reset PATH and lose
a user-local Iteris installation. Pin the console-scripts directory the same
way worker and verification sessions already do.
A manifest written to match the documented `--sibling id=...` CLI spec
scaffolded successfully but stored `sibling_id: None`. The family looked
healthy — `family status` listed every sibling — yet each id-addressed
command failed far from the cause: `family start --sibling 2.15` reported
`unknown sibling id: 2.15`, because `sibling_by_id` matches on `sibling_id`.

`normalize_sibling_entries` now runs at both scaffolding entry points
(`perform_family_new` and `perform_family_init`) and:

- accepts `id` as an alias for `sibling_id`, matching what
  `parse_sibling_spec` already does for the CLI surface
- raises when neither spelling is present, instead of storing None
- coerces ids to str, so a bare numeric id in JSON still resolves
- rejects duplicate ids, which would have left the second sibling
  unreachable via `sibling_by_id`

Verified live: a manifest using `id` now yields an addressable sibling and
`family start --sibling 2.15` resolves it.
@LehengChen

Copy link
Copy Markdown
Collaborator Author

Pushed one more fix, replacing the "known nit" noted at the end of the description.

iteris family new --manifest silently dropped sibling ids. A manifest written to match the documented --sibling id=... CLI spec scaffolded successfully but stored sibling_id: None. The family then looked healthy — family status listed every sibling — while each id-addressed command failed far from the cause: family start --sibling 2.15 reported unknown sibling id: 2.15, because sibling_by_id matches on sibling_id.

normalize_sibling_entries now runs at both scaffolding entry points (perform_family_new and perform_family_init) and accepts id as an alias, raises when neither spelling is present, coerces ids to str so a bare numeric id in JSON still resolves, and rejects duplicate ids that would leave the second sibling unreachable.

Tests are now 416 passed (8 more in tests/test_family_sibling_ids.py). Verified live: a manifest using id yields an addressable sibling and family start --sibling 2.15 resolves it.

Two report tests asserted on literal substrings of rendered CLI output and
failed in CI while passing locally. CI enables color; a plain local run does
not, and Rich styles message fragments independently:

- `--source` is emitted as `\x1b[1;36m-\x1b[0m\x1b[1;36m-source\x1b[0m`, so
  the literal `--source` is absent from the output entirely.
- An exported path is split into a styled parent directory and filename, and
  may wrap between them.

Rich also hard-wraps inside error boxes and pads lines to the terminal width
with `│` borders, so where a phrase breaks depends on terminal width and on
the length of interpolated paths — CI's `tmp_path` is longer than a local one.

Adds a `plain` fixture in `tests/conftest.py` that strips ANSI escapes and box
borders and collapses whitespace, and uses it in both tests. The assertions
now check the message text, which is what they were meant to verify; the
product code was correct and is unchanged.

Verified 416 passed across four combinations: local and CI dependency
versions (typer 0.27 / click 8.4), each with color off and on. The colored
CI-dependency run reproduces the original failure before this change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants