Every write the merged PRs added now names a view, chosen deliberately:
- The keyboard commit names OpenedCell::view, captured when the editor
opened, as EditTarget does for the mouse (context/code/clients.md).
- RenameRecordCoordinate names no view. Its record must hold cells, so it
resolves in the store alone: NamedRecord::Stored, as does the rename
destination records_at_stake adds. named_records replaces cells_named as
the exhaustive list records_named is read off.
- #252/#265's non_item_refusal moves into Grids::unwritable. The strict view
lookup (a missing view is RecordGone) and the Grids memo are kept.
- Test fixtures name a view their document has: Default for host() and
host_on_a_fold(), the records view for the rename pair, and the viewing
client's own view in browser_round_trip.
Evidence files: both sides kept, every heading of both parents verified
present. Test names: the merge holds every test of both parents.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Conflicts:
- cmd/core.rs committable_cell_key: took main's form, which asks
`uneditable` (#277), and gave `uneditable` a declining NonItem arm.
That keeps this branch's refusal of a commit on a non-item cell.
- resolve.rs reopened_at (auto-merged, non-exhaustive after the merge):
a declining NonItem arm, the sentence `i` already says.
The #277 review asked for both arms to decline, never to open.
- tests/shipped_documents_load.rs: kept both, this branch's
every_record_a_shipped_document_projects_is_writable and main's git()
helper.
- context/test-evidence/{command,core}.md: both sides appended at EOF; kept
both, the branch's first.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
GIT_CONFIG_GLOBAL=/dev/null and GIT_CONFIG_NOSYSTEM=1 in run_git were
witnessed by a config excludesFile, which vwjj's -c
core.excludesFile=/dev/null outranks. So dropping either line passed
every test from vwjj onwards.
The hostile child's config, read as both GIT_CONFIG_GLOBAL and
GIT_CONFIG_SYSTEM, now also sets core.sharedRepository = nonsense.
Measured on git 2.55: git init and git add die on it, git ls-files
does not read it (so the walk, which does not null the user's config,
is unaffected), and run_git passes no -c for it. init.defaultObjectFormat
and init.defaultRefFormat were tried first; they only warn.
Dropping either env line is now red. Every other rival in the combined
test is unchanged, and there is still one child per test.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
tests/shipped_documents_load.rs re-ran itself in 18 child processes, one
per hostile setting, and each child spawns several gits. So the binary
took 2.1-3.3s against design-principles 7's 2s-per-binary tripwire.
The six per-setting tests (53zz x2, vwjj, pr3i, a0i3 and 2iws/vav0) are
now one test, a_hostile_git_environment_changes_nothing. It has two
children: the gzip shape test and every_shipped_document_loads. Each
carries every setting at once:
- the template dir;
- the global and system config (with trace2 targets);
- XDG_CONFIG_HOME;
- GIT_DIR and GIT_INDEX_FILE;
- the five pathspec and attribute settings;
- the six trace variables.
Afterwards the test asserts the outer index is still empty.
Each setting breaks the walk on its own, so a rival that drops one
defence leaves that setting live, and the child fails. Every rival that
was red against the per-setting tests is red against the combined one.
The rivals that were green before are green now:
- ICASE;
- the trace2 names under the 0 override;
- the GIT_CONFIG_GLOBAL and NOSYSTEM nulls, whose excludes witness vwjj's
-c override masks. That last pair is filed as improvise-3j70.
Measured on an Apple M4 Max, three workspace runs each: this binary went
from 2.10-3.31s (load 37-39) to 0.57-0.91s (load 30-33). It is now
below the next-largest binary in every run.
The evidence sections keep their reasoning, under prose headings.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
The review of #276 found that an exact list of the three names the test
set passed it. The child now sets all six variables that write to their
target on git 2.55: GIT_TRACE, _SETUP, _PERFORMANCE, 2, 2_EVENT and
2_PERF. An exact three-name list leaves GIT_TRACE_SETUP behind and
fails.
vav0: a trace2.*Target in user config is not an environment variable,
so removal cannot reach it, and the walk's git does not null the user's
config. untraced_git now also sets GIT_TRACE2, GIT_TRACE2_EVENT and
GIT_TRACE2_PERF to 0, which outranks the config. The child adds a
GIT_CONFIG_GLOBAL whose [trace2] section sends all three targets to
/dev/stdout.
Rivals, each of which fails:
- no strip;
- the exact three names;
- the prefix minus GIT_TRACE, minus _SETUP, or minus _PERFORMANCE;
- no 0 override.
The evidence entry moves from the web_demo_model section to the
shipped_documents_load one.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
GIT_TRACE, GIT_TRACE2_EVENT and GIT_TRACE_PERFORMANCE are process-wide,
so --local-env-vars lists none of them. Pointed at /dev/stdout, git
wrote trace lines into the ls-files -z output, and the walk read them
as paths. git() now builds on untraced_git(), which removes every
variable starting with GIT_TRACE: a prefix, because the family is
open-ended. The rev-parse --local-env-vars call goes through it too,
since its stdout is parsed as well.
the_walk_ignores_a_git_trace_sent_to_stdout reruns the gzip shape test
and every_shipped_document_loads in children with all three set to
/dev/stdout. It failed at #269's head. Rivals, each of which fails it:
- no strip;
- the exact name only;
- keep GIT_TRACE_PERFORMANCE;
- keep GIT_TRACE2_EVENT.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
GIT_LITERAL/GLOB/NOGLOB/ICASE_PATHSPECS and GIT_ATTR_SOURCE are
process-wide, so --local-env-vars names none of them. Remove them in
git() beside the local-vars loop.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
improvise-pr3i, found reviewing #255. git init copies GIT_TEMPLATE_DIR
into the new .git. That variable is not in --local-env-vars, and it
bypasses config, so a template whose info/exclude holds *.gz still broke
a_gzipped_document_is_walked at git add. scratch_repo now runs
`git init -q --template=`, which copies no template at all, including a
distribution's compiled-in default. Stripping the variable would still
copy that default.
Also: rerun_with_env's callers print the child's stderr as well as its
stdout (told), because the child's panic goes to stderr.
Stacked on #255 (fix/vwjj-default-excludes).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
improvise-vwjj, found reviewing #248. GIT_CONFIG_GLOBAL=/dev/null empties
the config files. It does not stop git falling back to
$XDG_CONFIG_HOME/git/ignore (or ~/.config/git/ignore) when
core.excludesFile is unset, and git/attributes has the same kind of
default. So a *.gz line in the user's default ignore file still failed
a_gzipped_document_is_walked.
run_git now passes -c core.excludesFile=/dev/null and
-c core.attributesFile=/dev/null. A -c argument outranks every config
file and every default path.
The new test re-runs the gzip shape test under an XDG_CONFIG_HOME whose
git/ignore holds *.gz, and again with a git/attributes line that breaks
git add. Each half was red on its own.
Stacked on #248 (fix/53zz-scratch-repo-env).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
improvise-53zz. The scratch-repo shape tests inherited the caller's git
environment. A hook in a linked worktree exports GIT_DIR (and
GIT_INDEX_FILE), which override -C, so `git -C <scratch> add` staged the
scratch files into the outer checkout's index. The user's global
excludesFile applied too, so a `*.gz` line there broke the gzip test.
One helper, git(root), now removes every name that
`git rev-parse --local-env-vars` prints. run_git also sets
GIT_CONFIG_GLOBAL=/dev/null and GIT_CONFIG_NOSYSTEM=1.
Two new tests re-run a shape test in a child process of this binary with
the variables set. Both were red before the fix. Five rivals are recorded
in context/test-evidence/tui.md.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
grid_frame_agreement.rs is the strongest test in the last wave and its
comments were the record of six injected faults; all of it is now in
context/test-evidence/tui.md, keyed by test name.
THE_MEMBERSHIP_CORRECT_SPANS and its assert_ne! are UNTOUCHED. Its comment
now says what it is — a deliberately wrong constant and a live tripwire —
and points at the derivation rather than carrying it.
shipped_documents_load.rs keeps its two load-bearing claims in the file
(directory walk, full-name match) because both sit directly over the code
that would otherwise be "simplified" back into the bug.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Self-review of improvise-odbc's own guard. The walk filtered on
`Path::extension() == "improv"`, and `extension()` of `demo.improv.gz` is
`gz` — so a gzipped shipped document would have been skipped silently, which
is exactly the "exercised by nothing" hole the test exists to close, put back
one line inside the fix for it.
Matched on the full name instead. Proved both arms: a valid `.improv.gz`
dropped into `examples/` passes, and a truncated one fails. (The truncation
also exercises the `with_context` added two commits ago, from the other side.)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
improvise-odbc named two readings of the parse failure at
`- JORDAN MARTINEZ` and said to decide by asking whether improvise can
WRITE that line today. It cannot: `item_list`'s `name` is
`pipe_quoted | bare_name`, `bare_name` is `[A-Za-z_][A-Za-z0-9_-]*`, and
`quote_name` mirrors it character for character, so a spaced item name is
emitted `|JORDAN MARTINEZ|`. So the reader and the writer agree and the
round-trip property is not incomplete — the file was stale.
It was stale by hand, not by drift. c48a5cd migrated it to v2025-04-09 by
editing it in place: the `Date` items were pipe-quoted and the `Entity`
ones were not, and every line of its `## Data` section names a category
`Measure` where the file declares `_Measure`. It has not been loadable
since April, and nothing loaded it, so nothing said so. Deleted rather
than regenerated: there is no generator for it — it is hand-written fake
bank data — so "regenerating" would mean inventing a canonical form and
checking in 1200 lines whose only property is that they parse, which the
generator-driven proptests already establish over a far wider input space.
What is kept is the evidence and the gap the incident actually exposed:
- `an_item_name_the_item_line_cannot_carry_round_trips` puts the file's own
item names through `format_md`/`parse_md` and asserts the spaced ones come
back quoted and the bare-legal one stays bare.
- `a_bare_item_name_with_a_space_is_rejected` asserts the reader really does
refuse the unquoted line, with the quoted form parsing as the precondition.
Without it the first test would be consistent with the reader accepting
both spellings, which is not what happened.
- `tests/shipped_documents_load.rs` closes "a sample document exercised by
nothing": it walks the two directories `.gitignore` un-ignores and loads
every `.improv` in them. A directory walk, not a list of names, because a
list is a second place to remember. Proved discriminating by dropping the
offending line into `examples/` and watching it fail.
Unrelated, reported not fixed: `foo.improv` in the repo root has no version
line at all and is equally unloadable.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>