Option (b)'s example had `[customcat]` before the `=`, while clause 5's formula-line
shape puts the category tag after the expression. It was the only copy of the slip.
The status header and the list under Q23 now say eight places, since three of the
eight bullets each hold two readings.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Copilot found two inconsistencies in the previous push:
- clause 5 said a WHERE/IS value is an item id while Q23 said it could be a formula id.
Clause 5 now states one rule, the id text of an ItemHandle, for an expression and a
filter value alike, and Q23 points to it instead of restating it;
- the status header still said three readings were flagged, where Q23 lists eight.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
The le4p fix said no number format is spelled as an axis keyword. That is false:
set-format stores its argument verbatim and the writer emits `format: <value>`, so
`:set-format none` writes `format: none`, which the axis-first order would read as
the axis line of a category `format`. Clause 5 now states one rule, as the ADR's own
reading: the writer pipe-quotes a format that would also match axis_line, and the new
arm's format_line unquotes it.
Also:
- answer 32 quotes the recorded comment whole, and the section says what its
quotations are and why authorship in the tracker does not settle them;
- the readings that are not user answers are flagged in place and listed under Q23;
- clause 11 step 2 lists ItemHandle;
- Q23 states how an expression refers to a formula target and that the target
position's pipe-quoting covers a `_Measure` display that looks like `Name(x)`.
Nothing is renumbered, and no earlier decision changes.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Clause 3 defines the canonical element with Seq, derives the (key, value)
projection for the record tier, and states bit identity over that part only.
Clause 11 names all three crates; the 2^19 note is past tense.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
The run_case_capture helper was being called in command substitution
(out=$(run_case_capture ...)), which runs it in a subshell. This caused
the ok/bad updates to the pass/fail counters to be discarded.
Fix by having the helper write output to a caller-provided file parameter,
then reading from that file in the caller. This keeps the helper in the
parent shell where counter updates are preserved.
Addresses Codex P2 review on commit ec30c8a7.
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
1. Shebang (Codex P2): scripts/agent-bootstrap.sh and .claude/hooks/session-start.sh
now use #!/usr/bin/env bash instead of #!/bin/bash, matching repo convention
enforced by checkers.sh.
2. Fail-closed bd pin (Codex P2): .claude/hooks/session-start.sh local path now
exits 2 with a warning when pinned or running version cannot be parsed,
instead of silently succeeding. An unparseable version is not a pass.
3. pr-reviews failure (Codex P2): scripts/pr-watch no longer uses '|| true' to
swallow pr-reviews failures. If pr-reviews fails (fetch error, malformed
response), pr-watch now exits 6 with a warning. Empty successful fetch
(no reviews) is still exit 0.
- Added exit 6 to usage text and skill documentation
- Added test case 'pr-reviews failure exits 6' using malformed JSON fixture
- All 57 pr-watch tests pass
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
Every GitHub write (PR, comment, review reply) must include an attribution line
identifying the AI agent. Posts go out under the repository owner's account, so
an unattributed post reads as the human's words.
Format: _Posted by <Agent Stack> (<model>)_
Examples:
- _Posted by Claude (Opus 4.5)_
- _Posted by Cursor Agent (claude-sonnet-5)_
AGENTS.md:
- Added 'GitHub Attribution (Hard Rule)' section in multi-stack docs
- Concrete format and examples
- Clarified that a thread is not 'answered' until the reply has attribution
.agents/skills/pr-watch/SKILL.md:
- Added 'GitHub Attribution (Hard Rule)' subsection
- Updated 'Answer substantive feedback with attribution' in obligations
- Cross-references AGENTS.md for full rule
context/cloud-agents.md:
- Added 'GitHub Attribution (Hard Rule)' section
- Same format and examples as AGENTS.md
This ensures any agent reading the shared docs (Cursor, Claude, etc.) knows to
attribute every GitHub write to the specific AI agent.
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
The pr-watch skill and script now cover reviews/comments, not just CI checks.
An agent reading only the pr-watch skill now knows to track both.
.agents/skills/pr-watch/SKILL.md:
- Reframed: 'watching a PR' means checks AND reviews
- Added 'Reviews and Comments' section with the three surfaces table
- Added 'Review Obligations' subsection (answer feedback, identity line, etc.)
- Documented --reviews (default) and --no-reviews flags
- Cross-references AGENTS.md for full workflow details
scripts/pr-watch:
- Added --reviews (default) and --no-reviews flags
- After exit 0 (green/mergeable), calls scripts/pr-reviews to show all
reviews and comments. Does not change exit code — answering is agent's job.
- Updated usage text to document the new behavior
- Composes with existing pr-reviews (fixture mode passes through)
scripts/pr-watch-test.sh:
- Added mk_reviews_empty() and mk_reviews_with_review() helpers
- Added review fixtures to all cases that exit 0 (pr-reviews needs them)
- Added tests: 'green with reviews shows review output' and
'--no-reviews skips review output'
- All 56 tests pass
AGENTS.md / context/cloud-agents.md:
- Updated cross-references to point to pr-watch skill as agent-facing recipe
- Simplified text now that pr-watch handles reviews automatically
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
Question 13 no longer says the user has not decided. Clause 2's
overflowing formula literal is a 309-plus digit string, since the formula
grammar has no exponent. The appendix states the second benchmark run's
agreement as measured (within 6%, within 2.7% above K = 2).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Multi-stack agents (especially Cursor cloud) may focus on pr-watch (CI checks
only) and miss review feedback. This makes the obligation explicit.
AGENTS.md - new 'PR Tracking: Checks AND Reviews' subsection:
- Fetch reviews AND comments (reviews are separate API surface)
- Codex/ChatGPT reviews arrive as reviews, not comments
- Use ./scripts/pr-reviews <n> to see all feedback together
- Answer substantive feedback with identity line before done/merge
- Re-check after push that reviews target current head SHA
- Don't wait indefinitely on Copilot/Codex (quota-limited)
- Points to existing wave essay for full workflow
context/cloud-agents.md - new 'PR Tracking' section:
- Brief summary of the obligation
- Points to pr-watch skill for CI, scripts/pr-reviews for reviews
- Cross-references AGENTS.md for full details
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
User ruling: agents must work inside nix develop (or direnv) for this repo.
Bare system cargo that fails edition2024 is a misconfigured session.
Changes:
1. scripts/agent-bootstrap.sh:
- Added section 0: seed nix flake inputs automatically
- Cargo warm now runs inside 'nix develop --command'
- Added --skip-nix-seed flag for environments that don't need it
- Updated environment notes to emphasize nix-first
2. .cursor/environment.json:
- Removed --skip-cargo-warm (full nix-backed warm now default)
3. AGENTS.md:
- Added 'Toolchain' row to multi-stack table (nix develop required)
- Added 'Toolchain Requirement' subsection with usage examples
- Updated local agents guidance to use 'direnv allow'
4. context/cloud-agents.md:
- Bootstrap now lists nix-seed as step 1
- 'What does not work' table updated: bare system cargo now listed as
failing; nix develop works after bootstrap
- Updated nix section to reflect automatic seeding
Previous soft gap: nix-seed was a manual footnote; now it runs in bootstrap.
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
This commit implements the download flow for SaveAs and ExportCsv per the
USER RULING on improvise-2mqz. The correct shape is:
- A request frame asks the host for BYTES
- ServerFrame returns the bytes (or Rejected)
- Browser triggers downloads via Blob + <a download>
Key changes:
Protocol layer (improvise-protocol):
- Add Request::DownloadDocument and Request::DownloadCsv variants
- Add ClientFrame::DownloadDocument and ClientFrame::DownloadCsv
- Add ServerFrame::DocumentBytes and ServerFrame::CsvBytes
- Add KeyOutcome::LocalThenRequest variant for operations that need
both local fold (mode change, buffer clear) AND a server request
- Update stranding() to unstrand SavePrompt and ExportPrompt modes
- Update keymap to use rebind() instead of commit() for commit-save
and commit-export (because LocalThenRequest can't be in a Sequence)
Host layer (improvise-command):
- Handle new ClientFrames in host.rs returning bytes or Rejected
- Add Rejection::ExportFailed variant for CSV export failures
- Update CommitSave and CommitExport to clear their buffers
- Make render_csv() public in improvise-io for host use
WASM client layer (improvise-wasm-client):
- Add PendingDownload type with filename, bytes, and kind
- Store pending downloads for JavaScript retrieval via take_pending_download()
Browser layer (web/app.js):
- Add triggerDownload() function using Blob + <a download>
- Poll for pending downloads after frame handling
This unstrands SavePrompt and ExportPrompt which were previously refused
by stranding() due to missing wire forms.
Refs: improvise-2mqz
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
Revision 9 put a FormulaId in a CellKey's item position while clause 2 typed that
position ItemId, a contradiction Codex found on PR #326. Clause 2, the formula-cell
key in clause 5 and clause 8's RecordHash now use clause 6's own ItemHandle.
Answer 22 keeps the id text unambiguous.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
- `Category`, `Item` and `View` each gain a private `display` that starts equal
to the key and changes only through `set_display` / `set_item_display`.
- `CategoryRow`, `TileEntry` and `ViewSummary` carry `display` beside their key
field. The key stays what commands are composed from.
- The category-panel headers, the tile bar and the view list paint the display
in the TUI and the browser. The active-view marker still compares keys.
- No production code sets a display yet, so behaviour is unchanged.
- This is the first slice of ADR 007 step 2. The grid, page bar, records labels,
item rows and CSV export are improvise-cq1q.12; messages and the view title
are improvise-cq1q.13.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Revision 6. The user decided question 10 (a) with a 320-bit decimal
partition, question 13 (b), question 14 `numtower`, and question 15 (a).
N1: the number language's gate is the finite results of f64::from_str,
which is #321's gate; nan, inf and 1e999 stay text at import as
improvise-jc95 decided, and reversing jc95 is the rejected alternative.
N2: entry tries the fraction arm before f64, so a typed value is as exact
as the same value computed.
Also: raw_value's restructuring cost is stated; stale text is corrected;
the ceiling is sized to K*127+256; the exact grouped read is measured
(0.67-1.9 ms at K = 32, about 50x the estimate), which adds question 16
on the value of K; and the last-bit miss condition is stated on the
terms, matching ADR 009 at 4973845f.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
- A miss against a typed total is bounded by the terms' rounding, about half
an ulp of each term, so it is last-bit relative to the largest term. It can
reach = only when the terms reach about 2^19. The large-term, small-total
case (1e15 + 0.10 - 1e15 reads 0.125) is added. The epsilon-free = shows
every miss.
- 5a: cell sequences are assigned at DataStore's mutation sites and carried in
each delta element, so a remove-then-set of one key within an effect moves
it to the end, as IndexMap does. The generator includes that case. The
record tier projects to (key, value).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Unifies coding-agent setup across Claude Code and Cursor so both stacks get:
- Pin-matched bd from flake.nix
- Fresh Dolt beads tracker sync (not stale JSONL export)
- Same skills via symlinks to .agents/skills/
Key changes:
1. scripts/agent-bootstrap.sh: stack-agnostic bootstrap that handles bd
installation, tracker sync, and optional cargo warming. Works for any
agent stack (Claude, Cursor, or manual).
2. .claude/hooks/session-start.sh: now a thin wrapper that calls the
shared bootstrap for cloud sessions, keeping only the local pin-check
inline.
3. .cursor/environment.json: configures Cursor cloud agents to run the
bootstrap via 'install'.
4. .cursor/skills/: symlinks to .agents/skills/* so Cursor agents
discover the same skills Claude has.
5. AGENTS.md: adds Multi-Stack Agent Support section; clarifies that
scripts/kb is the KB interface (Prolog MCP is not required and not
available in all stacks).
6. context/cloud-agents.md: updated for multi-stack support; added KB
section emphasizing scripts/kb over Prolog MCP.
The canonical skill source remains .agents/skills/. Both .claude/skills/
and .cursor/skills/ are symlinks to it, so there is one truth that both
stacks read.
Co-authored-by: Ed Langley <fiddlerwoaroof@users.noreply.github.com>
- Folds in the user's answers on improvise-m56i (items 2 and 6) and
improvise-hexb (item 2) as answers 30-32. The m56i readings (items 1, 3, 4
and 5) go in clause 5 as the formula line.
- Applies the planned text fixes: le4p, p003, the i0n7 remainder, hexb items 1,
3 and 4, 8vs2 item 4, the 8tk5 merge sentence, and PR #318's two slugify
readings.
- Asks one new question, Q23: how a formula line spells its target.
- Changes no earlier decision. As an amendment to an accepted ADR, it needs the
user's approval.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
- 5a: a per-cell store sequence. A record's order key is the minimum over its
live cells, carried in the snapshot, so deleting a leading cell re-emits the
record as eager's shift_remove reorders it. A delete-leading-cell regression
is added. Formulas with a non-_Measure target stay eager until 5a defines
their projection.
- A last-bit miss against a typed total is visible to = only above about 2^19,
because = is an absolute 1e-10. The table row and paragraph now match ADR 005.
- "not on the term count as such"; the numbering note says ADR 005 is on #320;
ExactSum's home defers to ADR 005 question 15; the chunk loop's cost is noted.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
Adds What the user decided, quoting each inline answer: three levels, option (d), exact comparison plus EQUAL(a, b, epsilon), #i, ADR 007's version literal, a string encoding on the wire and lexeme-read JSON import with no f64 round trip, accept version skew (improvise-szi8), exact MIN/MAX tie-break, n/d as text where inferred and a fraction where forced. Answers question 10 with widths (320 bits for decimals, ~2,100 for f64, none fixed for fractions). Review B2-B4: decimal partition exempt from the parallel accumulator, exact-read estimate at the bigint rate, num-bigint always a dependency, (d)'s bundle cost, one number language for gate and parse. D1's direct test is normative; question 13 states its one exception; homes for shortest-spelling and inexact display rounding; numtower may land with ExactSum alone.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
BLOCK D2: option (d)'s grouped sum keeps a parallel f64 accumulator per group and reads exactly only with at most K = 32 non-decimal groups, with its costs stated; rules for dropping zeroed groups and for decimal-denominator fractions. Should-fix: 1-based overflow counting (5th-6th, i64 3rd-4th), the independent interval check replaces the circular to_f64 one, may-overflow wording for checked_add, display beyond 38 places, CellValue stays 32 bytes, plain examples of changed formulas and the version-skew cost, the review's signed large-N figures. CSV measures parse their verbatim text with from_str_exact and keep scale; shortest spelling is for JSON only.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
At the user's direction the numbers become a problem-agnostic crate (clause 14, proposed name numtower) that improvise-core depends on; migration starts with it. New questions 13 (bound the stored result, unbounded intermediates), 14 (crate name) and 15 (where ExactSum lives). Answers review BLOCK D1: a terminating quotient is exact iff k = max(p, q) <= 28 and the mantissa fits; multiplying back with clause 4's detection is also sound.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze
ADR 005 measured with the exact rational of the stored f64s, rounded once,
not with ExactSum itself. The typed-total miss rate depends on how large
the total is relative to its terms, not on the values' magnitudes. Both of
ADR 005's distributions are cited.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VdfEGXA7aJ6ftMsCc9PJze