Commit Graph

61 Commits

Author SHA1 Message Date
Paul O'Reilly
7800503348 fix(review-loop-run): CR-10 — scope exits only on headings shallower-or-equal to start depth (8c865eb4-7fd1-4a8d-b51d-04d020ba41c0) 2026-09-17 00:06:00 +12:00
Paul O'Reilly
b915dcc753 test(review-loop-run): ungate CR-7/8/9 tests — implementation merged (bug 5352fe72)
Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
2026-09-16 15:25:18 +12:00
Paul O'Reilly
e291f25880 Merge branch 'main' into mm/cr789 2026-09-16 15:23:51 +12:00
Paul O'Reilly
7d43d29da1 fix(review-loop-run): review r1 — drop vestigial nocasematch pair; document CR-8 label exception
Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
2026-09-16 15:23:51 +12:00
Paul O'Reilly
8127cd3b46 spec(review-loop-run): CR-8 label-parenthetical exception ((C1)-style) — reconciles pre-existing list-style test
Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
2026-09-16 15:23:51 +12:00
Paul O'Reilly
61e4c53b9f fix(review-loop-run): counts parses annotated cells, declaration-only lines, suspect derived zero (5352fe72-242f-4fef-85a0-b7851a1110e5) 2026-09-16 15:13:25 +12:00
Paul O'Reilly
131486e0ff test(review-loop-run): CR-7/8/9 handles + fixtures, gated behind CR789_IMPL_READY (bug 5352fe72)
Default run: 40 passed + SKIP. CR789_IMPL_READY=1: 10 red until implementation.

Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
2026-09-16 14:51:04 +12:00
Paul O'Reilly
01ae924292 spec(review-loop-run): CR-7/8/9 — annotated table cells, declaration-only prose lines, suspect derived zero (bug 5352fe72)
Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
2026-09-16 14:35:03 +12:00
Paul O'Reilly
b340e2cd5c fix(review-loop-run): counts parses count-by-severity block with scope + format branches (2026-09-13 fix, 40/40 tests)
Was live via ~/sbin symlink but never committed. Baseline for bug 5352fe72.

Claude-Session: https://claude.ai/code/session_01G3SkMRBRWXyiGuMGs8WVas
2026-09-16 14:27:52 +12:00
Paul O'Reilly
636b8b2401 feat: review-loop-run — detached MiniMax review launcher for /review-loop artefacts
launch (per-kind prompt templates: verify/plan/spec/tests/code; best-practice +
gotcha reading sets; setsid nohup launcher; round N+1 feeds back round N),
status, counts (exit 4 on CRITICAL/HIGH). Spec + 29 dryrun tests.

Claude-Session: https://claude.ai/code/session_018LRh1S2bHJYhEgrMu3UJx8
2026-09-13 17:20:36 +12:00
Paul O'Reilly
f50561ea78 feat(mm-worktree-task): run from any planner-backed repo — cp_cli dir + context resolution (--context, MM_WORKTREE_TASK_CP_*), empty-docs guard, tests + spec
cp_cli lives in agent-runtimes; previously every planner call ran 'python3 -m lib.cp_cli' from the current repo with no --context, so the script only worked inside agent-runtimes. The context now resolves from ~/.cpconfig by matching project_id to the repo directory name. Verified live from hatchmate (item + parent + documents fetched via the hatchmate context).

Claude-Session: https://claude.ai/code/session_01JgJbWzVJioVznVTFyQFEfx
2026-09-11 16:27:08 +12:00
Paul O'Reilly
9488335713 feat: review-minimax-run + ci-triage-minimax-run MiniMax offload wrappers
First-pass branch review and CI failure triage in MiniMax M3 sub-sessions.
Both materialise inputs themselves (no Bash in the sub-session), gate
results strictly, retry once, and follow the explore-minimax 0/1/2/3 exit
contract. Specs with RM-n/CT-n IDs; offline tests via fake seams (36
assertions). Verified live: planted-issue branch -> 5 confirmed findings,
clean branch -> NO FINDINGS, failed gac-scratch run -> correct step +
honest low confidence.

Claude-Session: https://claude.ai/code/session_01Ku87DDWwbJkTx6SuV3sQDc
2026-09-11 13:48:09 +12:00
Paul O'Reilly
abed9e7c25 feat: explore-minimax-run — read-only MiniMax exploration wrapper + mode guidance
Hardened wrapper for delegating broad codebase exploration to MiniMax M3:
per-root --add-dir scoping, secrets-root refusal, enforced read-only via
--disallowedTools (profile defaults to acceptEdits), JSON .result answer
channel, internal timeout + retry, file:line citation gate with distinct
fallback exit codes. deep/deep-fable/orch modes now prefer /explore-minimax
for broad read-only sweeps, Explore agent as fallback.

Claude-Session: https://claude.ai/code/session_01Ku87DDWwbJkTx6SuV3sQDc
2026-09-11 11:33:38 +12:00
Paul O'Reilly
0ceb49044a chore: track ask-minimax-run, bg-model-call, wait-for-version, auto-draft (+spec/data) — were untracked
Claude-Session: https://claude.ai/code/session_015nXvGNNNixJPFwZKZHNyha
2026-09-11 06:15:14 +12:00
Paul O'Reilly
9a6d7135c5 feat: add mm-worktree-task — launch MiniMax worktree implementation sub-sessions
Wraps ask-minimax-run to run a MiniMax M3 implementation sub-session in an
isolated git worktree, with the prompt assembled from a planner work item
(cp_cli item + documents + parent/siblings). Supports --dryrun, --collect,
and --upload, per the pattern used for the 2026-09-10 seven-worktree batch
(see agent-runtimes memory/gotchas-minimax.md).

Claude-Session: https://claude.ai/code/session_015nXvGNNNixJPFwZKZHNyha
2026-09-10 22:57:55 +12:00
Paul O'Reilly
aa8883dbc5 future: mm-worktree-task (MiniMax implementation subagent in worktrees) 2026-09-10 14:46:39 +12:00
Paul O'Reilly
f21506af19 Add git-identity: switch git author identity from a saved menu
Identities live in ~/.git-identities (alias|Name|email). Interactive
menu to select, add, or remove identities; direct mode via alias
argument; --global/-g scope flag (defaults to local inside a repo,
global fallback outside); --list/--current helpers. Full --dryrun
support and a 27-assertion test suite driven through dryrun.
GIT_IDENTITIES_FILE env override for testability.
2026-08-18 20:20:45 +12:00
Paul O'Reilly
56c621713d idle-draft: fill all free worker slots, not one per completion
try_submit() returned after a single submission and was only called at
startup and once per completion, capping real concurrency at 1 task
regardless of the parallel setting — the ThreadPoolExecutor pool was
sized but never filled. Loop until every free slot is filled or no
eligible candidate remains, per spec §10 (wording sharpened to make the
whole-pool semantics explicit). No stub-claude harness exists yet to
test dispatch concurrency end-to-end; verified live against the real
queue (36 candidates, parallel=20).

Claude-Session: https://claude.ai/code/session_01Lgv4Qn82boNFC1jn8QXSNw
2026-08-03 07:29:52 +12:00
Paul O'Reilly
bdd10cbbc1 idle-draft: add sample_override config flag to bypass cold-start throttle
Optional config key (default false). When true, research candidates are
offered even at max_unreviewed_research_per_dossier; research_sampled
bookkeeping, mark sampled, and status flags are unchanged so unsampled
items stay visible for later human verification.

Claude-Session: https://claude.ai/code/session_01Lgv4Qn82boNFC1jn8QXSNw
2026-08-03 07:26:41 +12:00
Paul O'Reilly
29618f4319 idle-draft: stop committing state file with machine commits
idle-draft.state.json is now gitignored in the target repo; explicitly
git add-ing an ignored path errors, which broke every success commit.
The state file is still written atomically — just no longer tracked.

Claude-Session: https://claude.ai/code/session_01Lgv4Qn82boNFC1jn8QXSNw
2026-08-02 23:38:29 +12:00
Paul O'Reilly
18b25191a3 Session log: idle-draft pipeline tooling build
Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 22:32:34 +12:00
Paul O'Reilly
ca8b538d34 idle-draft: per-work-type and per-provider model/effort settings
--effort/--model on child argv; provider entries accept object form
{provider, model, effort}; precedence entry > work-type > profile.
Effort levels validated against the CLI's enumerated set.

Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 22:16:34 +12:00
Paul O'Reilly
ec25f02f01 idle-draft: clear attempts on success so forced redos start fresh
Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 21:54:53 +12:00
Paul O'Reilly
1f008eebcb idle-draft: process-group child termination, unique tmp paths, stale sweep
Lock-contention test added; children die with the dispatcher (SIGTERM/
SIGINT handlers + atexit); tmp files are per-invocation (.tmp.<pid>) so
a SIGKILL-orphaned child can never collide with a new instance.

Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 21:52:17 +12:00
Paul O'Reilly
75add58246 idle-draft: per-work-type allowed_tools; research must web-search for stories
Research and topic_ideas runs get --allowedTools WebSearch,WebFetch;
research template mandates >=1 web search for related stories with
full-URL + access-date citations under the dossier's status labels.

Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 21:32:35 +12:00
Paul O'Reilly
cd5be1cf92 idle-draft: strip :line-range suffixes before citation existence check
First pilot rejected valid citations like SPEC.md:1-80 — the form the
research template itself mandates. 5 new test cases (83 total).

Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 21:27:53 +12:00
Paul O'Reilly
6c4bf449aa idle-draft: idle-subscription dispatcher for the writing pipeline
Elapsed-paced gates, bounded-parallel event-driven dispatch, filesystem-
derived stages with thin human-gate state, citation validation with
quarantine, credential parity check, prompt templates as data.
Per IDLE-DRAFT-PLAN.md in writing/oreillyconsulting.

Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 21:18:02 +12:00
Paul O'Reilly
f78d292f05 score-paragraphs: port GOES paragraph scorer as general-purpose script
Required --style, --json machine-readable output, mandatory --dryrun.
Engine unchanged; known limitation documented: already-scored paragraphs
are never re-examined (present in the original).

Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 21:18:02 +12:00
Paul O'Reilly
52eb484ef7 agent-subscriptions: add window_seconds and elapsed_pct to JSON output
Elapsed is null when a window has no reset timestamp (MiniMax v1 fallback)
so pacing consumers fail closed; negative reset_in_seconds clamps to 0.

Claude-Session: https://claude.ai/code/session_01YQDoWNM7XPPii28khFWoMc
2026-08-02 21:18:02 +12:00
Paul O'Reilly
448091ecf4 feat(claude-tmux): spawn detached tmux Claude Code session with Remote Control
New script that launches Claude Code (via claude-profile) inside a detached
tmux session with --remote-control enabled, in a project's directory, named
after the project (Title-cased, auto-incrementing #N on collision). Lets a
session be started for later attach over VPN or control from the Claude app.

Spec-first per repo conventions: specs/claude-tmux.spec.md, script, and
tests/test-claude-tmux.sh (18 dryrun assertions, all passing).

Claude-Session: https://claude.ai/code/session_014oa7T7z1h5n34vu8vX9zGT
2026-07-25 16:29:46 +12:00
Paul O'Reilly
0476c00e81 fix: update MiniMax Anthropic-compat base URL to api.minimaxi.chat
MiniMax moved their Anthropic-compatible API from api.minimax.io to
api.minimaxi.chat. The old endpoint returns 404; the new one returns 200.
Key is unchanged and still valid. Native api.minimax.io endpoints (e.g.
subscription check) are unaffected.

Claude-Session: https://claude.ai/code/session_01XtWRazqRbMnMRa4iV3zbVx
2026-07-17 19:25:08 +12:00
Paul O'Reilly
a63f5a0f80 reflect-logs: distill session logs into topic memory (2026-07 sweep) 2026-07-02 16:05:43 +12:00
Paul O'Reilly
b76e56f750 fix(claude-profile): use --append-system-prompt-file to avoid ARG_MAX on large projects
Passing combined context inline as a CLI arg hits Linux ARG_MAX (~2 MB)
when project CONTEXT.md or MEMORY.md are large. Three changes:

1. Write combined_context to a mktemp file and pass via
   --append-system-prompt-file instead of the inline --append-system-prompt arg.

2. Drop exec in favour of a subprocess call so the EXIT trap fires
   after claude exits, properly resetting the WezTerm theme and cleaning
   up the temp file. (With exec, bash is replaced immediately and traps
   never fire on success — WezTerm reset was silently broken.)

3. Warn when context exceeds 150 KB and show context size (in KB) on
   the launch line and in dryrun output, so oversized CONTEXT.md files
   are visible before they become a crash.
2026-06-22 10:17:31 +12:00
Paul O'Reilly
864960cbbb claude-profile modes: add deep-fable, orch pre-flight gate, ask-minimax re-point
deep-fable.md (new):
- driver: fable (claude-fable-5), same plan-first/spec-first discipline as deep
- escalates_to: opus — Opus named workflows remain available
- status line: [Fable→Opus] deep-fable · <project>: <task> | N% ctx
- on context wipe mentions "Deep Work (Fable)"

deep.md:
- Gnarly-bug consult: bg-model-call -> /ask-minimax skill with Opus fallback
- Async policy: replace bg-model-call bullet with /ask-minimax + Opus-subagent-fallback
- Workflow stance: add SSH key pre-flight check before git push

quick.md:
- Workflow stance: add SSH key pre-flight check before git push

hybrid.md:
- Async policy: replace bg-model-call reference with /ask-minimax + Opus-subagent-fallback

orch.md:
- New section "Pre-flight gate (before the autoloop)" placed before Auto-fire
- Auto-fire step 1 rewritten: run pre-flight gate first, then /loop 2m /orchestrate
- Escalation triggers: add stuck-queue row (5 iterations no change -> stop, report)
- Out of scope: add "Run the autoloop without the pre-flight gate"

context/claude-profile-modes.md:
- Status line: 47 assertions; driver table updated; 6 mode files noted
- Remaining follow-ups: bg-model-call replaced by /ask-minimax; deep-fable noted
2026-06-12 21:34:20 +12:00
Paul O'Reilly
16586541ea claude-profile: bump opus to 4.8, add fable driver
- driver_model_id(): opus -> claude-opus-4-8, opus-1m -> claude-opus-4-8[1m]
- driver_model_id(): add fable -> claude-fable-5
- error message updated: Valid: haiku sonnet opus opus-1m fable
- spec: driver->model table updated (opus 4.8, fable added); frontmatter
  driver enum includes fable; note that opus-1m retained for [1m] convention
- tests: add Test 13 (deep-fable dryrun asserting claude-fable-5);
  add Test 14 (unknown driver exits 1) — 47 assertions total
  Note: deep-fable mode file lands in the next commit
2026-06-12 21:33:58 +12:00
Paul O'Reilly
9e13b7f096 claude-profile: remove provider-yaml system, embed model config in profiles
Provider selection phase removed; Anthropic driver→model_id is now
hardcoded in the script and non-Anthropic profiles supply provider.env
(MODEL_ID, ANTHROPIC_BASE_URL, ANTHROPIC_API_KEY_FILE).

Test suite baseline changes 58 → 41 assertions: the 17 dropped
assertions covered the removed provider-yaml selection phase, not
retained behaviour.

Includes refactor-derived memory: decisions (provider architecture,
driver enforcement via --model), bash gotchas (read -rp under set -e,
never eval user config), process lessons.
2026-06-12 21:26:07 +12:00
Paul O'Reilly
c0a2110ee6 fix(agent-subscriptions): handle MiniMax API v2 response shape
MiniMax changed from category_remains[text_generation] with count fields
to model_remains[general] with remaining_percent fields. Now tries v2
first (100 - remaining_percent), falls back to v1 count-based calculation.
2026-06-03 20:49:20 +12:00
Paul O'Reilly
b0130bf06b feat(agent-subscriptions): add script to show AI provider subscription usage
Probes Anthropic OAuth and MiniMax subscription usage and displays
percentage consumed for 5-hour and 7-day windows with colour-coded output.
Ported probe logic from agent-runtimes/scripts/ralph_code.
2026-06-03 20:43:24 +12:00
Paul O'Reilly
4cd9757abc feat(claude-profile): warn when non-Anthropic provider used with OAuth profile
Add a warning when ANTHROPIC_BASE_URL would be set but the active profile's
.credentials.json would override ANTHROPIC_API_KEY with subscription OAuth,
routing requests to Anthropic instead of the intended provider.

Fixes the MiniMax routing issue: use --profile minimax (~/.claude-minimax/,
no stored credentials) for non-Anthropic providers.

Update presets example to use profile: minimax for quick-minimax preset.
63 tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 18:33:39 +12:00
Paul O'Reilly
ff6228e7ad fix(minimax-provider): correct model name, auth var, and tier overrides
- model_id: MiniMax-M2.7 (was claude-sonnet-4-20250514)
- api_key_env: ANTHROPIC_API_KEY (was ANTHROPIC_AUTH_TOKEN — wrong for interactive CC)
- Add ANTHROPIC_MODEL + all four tier vars (SMALL_FAST, SONNET, OPUS, HAIKU) pointing to
  MiniMax-M2.7 to prevent fallback to Anthropic models on sub-agent calls
- Add API_TIMEOUT_MS=3000000 (50 min) for long-running operations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 18:28:48 +12:00
Paul O'Reilly
a11051e0a8 feat(claude-profile): add provider selection (model + endpoint + credentials)
Introduces provider files (`data/claude-profile/providers/*.yaml`) that
bundle model ID, API base URL, API key source, and extra env vars. Phase 2.5
(provider selection) added between mode selection and launch, with a default
derived from the mode's driver field so existing Anthropic usage is unchanged.

Ships 5 providers: anthropic-haiku/sonnet/opus/opus-1m and minimax-sonnet.
MiniMax token decrypted from agent-runtimes SOPS env, stored at
~/.claude-secrets/minimax-auth-token. Adding new providers = one YAML file,
no script changes.

58 dryrun tests passing (up from 37).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 18:16:22 +12:00
Paul O'Reilly
5a1b4b14bc Add wait-for-release: poll a Gitea repo's releases until a glob matches
Polls /api/v1/repos/<owner>/<repo>/releases and matches each tag_name
against a shell-style glob (e.g. v1.2.3.*). Default 600s timeout, 5s
interval, both overridable. Exits 0 with the matched tag on stdout,
1 on timeout, 2 on usage error, 3 on terminal API error (401/403/404).
Intended to run in the background of a Claude Code session while CI
produces the release.

Includes spec and 42-assertion test using a PATH-shadowed mock curl.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 20:06:24 +12:00
Paul O'Reilly
cde811fa0e Add semver-ci: commit-driven semantic versioning for Gitea Actions
Computes MAJOR.MINOR.PATCH.BUILD from NEW_MAJOR/NEW_MINOR/NEW_PATCH
whole-line tokens in commit messages since the last release tag.
Non-main branches get a BRANCH-SHORTSHA suffix and never release.
Maintains VERSION.md, writes $GITHUB_OUTPUT, and optionally creates
a Gitea release via API.

Includes spec, 67-assertion test, usage guide (docs/semver-ci.md),
and a drop-in Gitea Actions workflow template.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 19:30:44 +12:00
Paul O'Reilly
340c40392a End-of-session: statusline + session-start integration, docs update
- context: claude-profile-modes updated to reflect current state (statusline
  and session-start auto-select done; next step is real launch test)
- FUTURE.md: remove two completed items (status-line, CLAUDE.md picker)
- README: add missing scripts (check-skills, gen-secret, mp3-to-mp4,
  split-wezterm, sync-repos) to scripts table
- session log 2026-04-12.003747.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 00:40:17 +12:00
Paul O'Reilly
143b32597e Add claude-profile engagement mode picker with statusline and session-start integration
- claude-profile: phase 1-3 picker (profile, mode, launch) with preset support,
  dryrun, WezTerm theming, and --append-system-prompt mode body injection
- 5 mode files (chat/quick/deep/hybrid/orch) with YAML frontmatter + prose body;
  new escalates_to field drives statusline →Opus arrow for deep and hybrid
- statusline.sh reads CLAUDE_CONFIG_DIR/active-mode.env to show
  [Sonnet→Opus] deep · topic format when launched via claude-profile
- Root CLAUDE.md session-start: auto-selects project from cwd or CLAUDE_PROJECT
  in active-mode.env, skipping the interactive picker when context is clear
- Spec, tests (37 assertions, 9 test files, all passing), context docs, and
  preset example included

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 00:36:38 +12:00
Paul O'Reilly
765f32b4fa Add mp3-to-mp4: convert MP3 to MP4 with static title card
Uses ffmpeg to generate an H.264/AAC video from an MP3 file with a
centred title overlay. Supports optional background image (title at
bottom) or solid colour (title centred). Includes spec, dryrun support,
and 10 tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 18:34:50 +12:00
Paul O'Reilly
529e49fe98 Add reflected memory files and update git-status-report
Adds gotchas-wezterm and updates gotchas-bash from recent reflections.
Prunes old reflected log. Updates MEMORY.md index.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:38:00 +13:00
Paul O'Reilly
c470867039 Remove URL-unsafe characters from gen-secret charset
Remove ^, +, ~, :, @ from the allowed charset. The ^ character breaks
SQLAlchemy DATABASE_URL parsing, + becomes space in URL query strings,
: and @ are URL delimiters. The remaining charset (A-Za-z0-9._-) is
safe in URLs, database connection strings, YAML, JSON, and shell
without any encoding.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:29:08 +13:00
Paul O'Reilly
8bd4c7253b Add gen-secret: generate bash/YAML/JSON-safe random strings
Outputs cryptographically random strings using only characters safe
for unquoted use in bash, YAML, and JSON: [A-Za-z0-9._+\-:@^~]

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:32:55 +13:00
Paul O'Reilly
161c633b42 Add split-wezterm: split WezTerm pane into a rows x cols grid
Splits the current pane into evenly-sized grid using wezterm cli
split-pane. Supports optional command per pane, dryrun mode, and
auto-detects native or Flatpak WezTerm CLI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-23 12:33:04 +13:00