Step 11 of v3.4.1 plan. Adds the lifecycle subsection to Handover 7
documenting:
- Producer/consumer arbeidsdeling (executor + helper write; ultracontinue
reads; pre-compact-flush refreshes only)
- Stale-file principle: status==='completed' state files SHOULD be
removed via /ultracontinue-local --cleanup --confirm (operator-invoked,
no auto-cleanup, no force flag)
- Frontmatter contract for NEXT-SESSION-PROMPT.local.md: producers MUST
write produced_by + produced_at (ISO-8601); files without frontmatter
are tolerated (warning, not error) for backwards compatibility
- Idempotency: --cleanup --confirm is safe to re-run; partial state
reported but never auto-recovered
Adds 3 doc-consistency pins:
- next-session-prompt-validator CLI shim
- Handover 7 § Lifecycle subsection present
- Handover 7 § Lifecycle names --cleanup + produced_by contract
358 -> 361 tests, all green.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 10 of v3.4.1 plan.
commands/ultracontinue-local.md:
- New Phase 0.5 between Phase 0 and Phase 1 — terminal cleanup mode
triggered by parsed flags['--cleanup'] === true. Requires explicit
positional[0] (no "clean all"), no template placeholders in the Bash
invocation. Passes through to cleanupProject via inline ESM. Cleanup
never falls through to Phase 1/2/3/4.
- Phase 0 usage block updated to document --cleanup and --cleanup
--confirm forms alongside the legacy <project-dir> form.
tests/commands/ultracontinue.test.mjs:
- Test (Bug 4 prose) — Phase 0.5 header present, references
cleanupProject and flags['--cleanup'], appears between Phase 0 and
Phase 1 in document order, usage mentions --cleanup --confirm.
- Test (f-1) dry-run on completed project lists candidates without
deleting; both files still on disk.
- Test (f-2 + f-3) confirm-mode deletes both files; subsequent
invocation on the already-cleaned dir signals CLEANUP_NO_STATE_FILE
(deterministic terminal state, idempotent for operators).
Tests 355 -> 358 (+3).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 9 of v3.4.1 plan.
lib/util/cleanup.mjs (new):
- cleanupProject(projectDir, {dryRun, confirm}) reads
.session-state.local.json via validateSessionState; refuses unless the
parsed status is strictly equal to 'completed' (per risk-assessor
Critical 2 — no soft-match on similar statuses).
- Default dryRun: true; refuses dryRun: false without explicit
confirm: true (CLEANUP_REQUIRES_CONFIRM).
- Removes .session-state.local.json + NEXT-SESSION-PROMPT.local.md
candidates; ENOENT counts as "already absent" so the function is
idempotent.
- No CLI shim — invoked from /ultracontinue --cleanup via inline ESM
(Step 10 wires this in).
tests/lib/cleanup.test.mjs (new):
- 7 cases: dry-run lists candidates without deleting; confirm-mode
deletes both files; idempotent re-run signals CLEANUP_NO_STATE_FILE
after fully cleaned; refuses on status: in_progress
(CLEANUP_NOT_COMPLETED); refuses dryRun: false without confirm
(CLEANUP_REQUIRES_CONFIRM); defaults to dry-run; missing state file
returns CLEANUP_NO_STATE_FILE.
Internal scaffolding consumed by Step 10 (Phase 0.5 wire-up). User-facing
docs land with Step 14.
Tests 348 -> 355 (+7).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 8 of v3.4.1 plan.
commands/ultracontinue-local.md:
- New Phase 1.5 between Phase 1 and Phase 2 — runs the
next-session-prompt-validator in --consistency mode when both candidates
exist (plugin-root + project-dir). Refuses on producer mismatch with
fresh candidates, downgrades stale candidate to a warning, downgrades
>24h wall-clock drift to a soft warning.
- Anti-substitution rule applies — paths emitted as concrete tokens, not
template placeholders.
lib/validators/next-session-prompt-validator.mjs:
- Sharpen NEXT_SESSION_PROMPT_PRODUCER_MISMATCH error message to include
the literal "produced_by" field name so consumers (and operators) can
trace the disagreement back to the YAML key.
tests/commands/ultracontinue.test.mjs:
- Test (Bug 3 prose) — Phase 1.5 header present, references validator,
appears between Phase 1 and Phase 2 in document order.
- Test (Bug 3 e) — tmp project dir with state file + two prompt files
with mismatched producers, both fresh relative to state.updated_at;
CLI consistency mode exits non-zero, JSON stdout surfaces
NEXT_SESSION_PROMPT_PRODUCER_MISMATCH with both paths and the
"produced_by" token in the message.
Tests 346 -> 348 (+2).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 6 of v3.4.1 plan. Adds the validator quartet
(Content/Object/Consistency/CLI) for NEXT-SESSION-PROMPT.local.md
frontmatter (produced_by, produced_at). State-anchored staleness check
is the primary refusal; 24h wall-clock drift downgraded to soft warning
to avoid false positives on weekend pauses.
Internal scaffolding consumed by Step 8 (Phase 1.5 wire-up). User-facing
docs land with Step 14 (CHANGELOG + README + version bump).
Tests 335 -> 346 (+11): 9 unit + 2 CLI shim cases.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 4 of v3.4.1 hot-fix plan. Two new tests in
tests/commands/ultracontinue.test.mjs:
(d-1) ALLOW-resolved-path — runHook + pre-bash-executor sanity check
that a concrete validator invocation (no template placeholders)
is not blocked by the marketplace bash-guard.
(d-2) NO-PLACEHOLDER — Pattern D structure assertion that Phase 2
contains neither {state-file-path} nor any other
{lowercase-template} curly-brace placeholder, and that the
Phase 2 prose explicitly documents the deterministic Read
tool flow.
(d-1) passes today (the planned bash form is allowed). (d-2) fails
intentionally on current Phase 2 — Step 5 fix turns it green.
Step 2 of v3.4.1 hot-fix plan. Establishes tests/commands/
directory and adds Pattern D structure tests against
commands/ultracontinue-local.md prose:
(a) Phase 1 must document Date.parse(updated_at) numeric sort
(b) Phase 0 must NOT use substring "contains --help" dispatch;
must reference parsed flags or positional[0]
(c) Phase 1 must reference auto-discovery as empty-args fallback
(d) Phase 1 must emit SC-2 diagnostic strings for .md positional arg
Tests (a), (b), (d) fail intentionally on current prose; Step 3
fix turns them green. Test (c) passes already (current Phase 1
prose says "non-empty" which matches the regex assertion).
Step 1 of v3.4.1 hot-fix plan (project 2026-05-04-v3.3.1-ultracontinue-fixes).
Adds ultracontinue entry to FLAG_SCHEMA covering boolean flags --help,
--cleanup, --confirm, --dry-run with no valued flags. The -h short form
is intentionally not aliased: it appears as positional[0] === '-h' and
the command prose dispatches usage on either condition.
7 new tests in tests/lib/arg-parser.test.mjs verify empty args, --help,
-h positional, --cleanup, --cleanup --confirm, project-dir positional,
and .md positional (parser-level accept; command-level reject).
Pins existing BLOCK rules in the two pre-* executor hooks so a future
silent weakening of BLOCK_RULES surfaces as test failures instead of
slipping through code review.
50 new tests covering both hooks plus allow-list pins (lib/, tests/,
docs/, ls, git, npm) and fail-open on malformed input. Reuses
tests/helpers/hook-helper.mjs child-process spawner.
[skip-docs]
Adds 6 files in tests/synthetic/ exercising the determinism pipeline at the
SC7 brief floor (Jaccard >= 0.833). Plan fixture pair: 40 step titles each
with 38 shared (Jaccard 0.905). Review fixture pair: 30 finding-IDs each
with 28 shared (Jaccard 0.875). Reuses lib/parsers/jaccard.mjs +
lib/parsers/finding-id.mjs.
The new pair coexists with tests/lib/review-determinism.test.mjs which
holds the older SC4 (0.70) floor against tests/fixtures/ultrareview/.
The lower floor protects pipeline regressions; the higher floor anchors
the speedup brief's determinism aspiration.
[skip-docs]
New hooks/scripts/post-compact-flush.mjs (PostCompact event, CC v2.1.105+):
auto-discovers <cwd>/.claude/projects/*/.session-state.local.json (most
recently modified), validates it via session-state-validator, emits
additionalContext via stdout so the post-compact assistant turn has
Handover 7 resume context loaded immediately.
Read-only — never writes. Always exits 0; never blocks compaction. Uses
only node:fs sync APIs available since Node 12 (no glob dependency).
Companion to the existing pre-compact-flush.mjs:
- PreCompact: refresh progress.json + .session-state.local.json
- PostCompact: re-inject .session-state.local.json into context
Wired in hooks/hooks.json under a new PostCompact matcher block.
Both files staged via /tmp/claude-* and copied into hooks/* via Bash to
respect the llm-security plugin path-guard (which blocks direct Write to
hooks/scripts/*.mjs and hooks*.json).
Test: tests/hooks/post-compact-flush.test.mjs (4 tests) covers no-state,
malformed-state, valid-state, and multi-project mtime selection.
Wire the main-merge-gate lifecycle event into commands/ultraexecute-local.md
Phase 8. Three event variants emitted via lib/stats/event-emit.mjs (S8):
- main-merge-gate fired at the gate boundary
- main-merge-approved fired on operator confirm
- main-merge-declined fired on operator decline (run recorded as partial)
The gate ALWAYS pauses regardless of gates_mode — it is the one always-on
boundary that --gates does not toggle. On decline, --resume re-enters at
the gate, and the wave session branches survive on the remote thanks to
Hard Rule 19's push-before-cleanup. Recovery surface is documented inline.
Pin in tests/lib/main-merge-gate.test.mjs locks the always-on prose, the
event names, and the recovery-surface contract.
Single autonomy-control surface (--gates) added to ultrabrief, ultraresearch,
ultraplan, and ultraexecute. When present, sets gates_mode = true and
re-enables approval pauses at every phase boundary + every wave for
high-stakes runs. When absent (default in auto), the chain runs continuously
to the main-merge gate (which always pauses regardless of --gates — that
boundary is the one always-on safety stop).
ultrabrief: pause after auto-mode confirmation; emit brief-approved event
ultraresearch: pause after each topic completes
ultraplan: pause after Phases 5, 7, 9
ultraexecute: pause after each wave's worktrees finish, before merge-back,
AND before the main-merge gate (MAIN_MERGE_GATE)
All four commands invoke the autonomy-gate state machine via the CLI shim
node lib/util/autonomy-gate.mjs (built in S8). Test pin in
tests/lib/gates-flag-coverage.test.mjs locks the contract.
Also wires the brief-approved stats emission into ultrabrief Phase 5 auto
path (was the SC4 wiring requirement from plan-v2 Step 11).
Bring the launch template (used by /ultraplan-local --decompose) into
contract-parity with the Phase 2.6 wave executor hardenings shipped in the
previous commit:
- GIT_OPTIONAL_LOCKS=0 exported once at the top
- MAX_TURNS / MAX_BUDGET_USD env-overridable (default 50 / 5)
- Absolute SHARED_CONTEXT_FILE built from brief + architecture
- SAFETY_PREAMBLE prepended to every per-session prompt (GH #36071 +
GH #52272 clarifications)
- Per-child --max-turns + --max-budget-usd + --append-system-prompt-file
- push-before-cleanup before merge AND in the cleanup_worktrees trap
- Three new template rules (16, 17, 18, 19) document the contract for
session-decomposer
Pin in tests/lib/doc-consistency.test.mjs locks all required substrings
against future regressions.
Strengthen single-message reinforcement for plan-critic + scope-guardian
parallel dispatch in commands/ultraplan-local.md Phase 9 and mirror in
agents/planning-orchestrator.md Phase 6. Reviewers now write structured JSON
to /tmp/{plan-critic,scope-guardian}-out.json which is merged via the
lib/review/plan-review-dedup.mjs CLI shim from S8.
The merged set lets us revise the plan once for duplicate findings instead
of twice. Source: research/05 R1 + R2.
Pin in tests/lib/doc-consistency.test.mjs locks both files against
single-message + dedup-helper regressions.
Inline STEP_HEADING_REGEX, FORBIDDEN_HEADING_REGEX, the canonical step+manifest
example, and the post-write plan-validator self-check directly into Phase 8 of
commands/ultraplan-local.md. This eliminates the dependency on Opus 4.7
implicitly loading agents/planning-orchestrator.md — the format contract now
travels with the command file itself.
Source: research/04 D5 + plan-v2 Step 7. Pin in tests/lib/doc-consistency.test.mjs
locks the substrings so future edits cannot silently regress the seal.
Pin the contract from plan-v2 Steps 1-3: every agents/*.md must declare
model: (opus|sonnet|haiku) AND (tools: or disallowedTools:). Orchestrators
(planning/research/review) must be opus and include the Agent tool;
non-orchestrators must not include Agent (no recursive swarming).
23 agents in scope; 5 pinning tests.
[skip-docs]
Three changes in one commit:
1. NEW lib/util/atomic-write.mjs — exports atomicWriteJson(path, obj),
the canonical tmp+rename pattern. Reused by pre-compact-flush.mjs and
(in subsequent steps) by the new session-state writer.
2. NEW tests/lib/atomic-write.test.mjs — 4 unit tests covering
round-trip, no-orphan-tmp, overwrite-atomic, pretty-print formatting.
3. REFACTOR hooks/scripts/pre-compact-flush.mjs — replace the inline
atomicWrite() with the imported atomicWriteJson(). Also fixes a
pre-existing syntax error (leading whitespace + stray --resume token
outside the comment block) that silently broke the hook from v3.1.0
onward — PreCompact runtime is fail-open and swallowed the error.
File reformatted with standard zero-indent JS.
163 → 167 tests, 0 fail.
Step 2 of /ultracontinue v3.3.0 (project 2026-05-01-ultracontinue).
Synthetic plan.md fixture with source_findings: block-style YAML list of 3
40-char hex IDs in frontmatter, plus minimal plan structure (Title +
Implementation Plan + 1 Step + Manifest). 3 tests verify:
1. plan-validator accepts a plan with source_findings (additive optional field)
2. frontmatter parser extracts source_findings as array of strings
3. each ID matches the 40-char lowercase hex format from finding-id.mjs
Closes the SC3(b) gap flagged by adversarial review (scope-guardian Gap 2).
LLM-level behavior (planner emitting source_findings) remains non-testable
without live invocation; this covers the structural contract.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
3 integration tests using the run-A/run-B fixtures:
- Jaccard(A, B) ≥ 0.70 (SC4 brief threshold)
- IDs match 40-char hex shape (lib/parsers/finding-id.mjs format)
- no duplicate IDs within a single run
Tests the Jaccard PIPELINE; real-LLM determinism deferred to v1.1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
review-run-A.md (5 findings) and review-run-B.md (6 findings, A ⊂ B) form a
known-Jaccard fixture pair: |A ∩ B| = 5, |A ∪ B| = 6, Jaccard = 5/6 = 0.833,
above the SC4 threshold of 0.70. IDs are real 40-char SHA1s computed via
lib/parsers/finding-id.mjs from realistic (file, line, rule_key) triplets.
Both fixtures pass review-validator --strict (frontmatter + body sections +
findings shape). Real-LLM determinism measurement deferred to v1.1.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Modify "all four pipeline commands" → "all five" (adds /ultrareview-local).
Add 3 new pins: Handover 6 section in HANDOVER-CONTRACTS.md,
review-validator CLI shim, rule-catalogue 12-key size invariant.
11/11 doc-consistency tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Step 1 of v2.0 plan. Hard cut from commands/ to skills/ per Anthropic
recommendation for new plugins. Frontmatter sets disable-model-invocation:
true and pins model: claude-sonnet-4-6. Docs (README, CLAUDE.md, root
README) deferred to Step 9 per plan.
- package.json med node:test runner og scripts (test, simulate), zero deps
- settings.json: fjern vestigial exploration- og agentTeam-blokker (verifisert leset av ingen kode via grep)
- docs/: commit subagent-delegation-audit.md og ultraexecute-v2-observations-from-config-audit-v4.md (begge real arkitektur-notater)
- docs/: arkiver ultra-suite-brief_2.md som _archive- (var paste fra annet plugin-arbeid, irrelevant her)
- tests/helpers/hook-helper.mjs kopiert fra llm-security m/ provenance-kommentar
Forberedelse for Spor 1 (lib/-moduler), Spor 2 (HANDOVER-CONTRACTS + PreCompact-hook), Spor 3 (bug-fixes + CC-features).
Plan: ~/.claude/plans/det-neste-vi-gj-r-eventual-adleman.md
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Extract `/ultra-cc-architect-local` and `/ultra-skill-author-local` plus all 7
supporting agents, the `cc-architect-catalog` skill (13 files), the
`ngram-overlap.mjs` IP-hygiene script, and the skill-factory test fixtures
from `ultraplan-local` v2.4.0 into a new `ultra-cc-architect` plugin v0.1.0.
Why: ultraplan-local had drifted into containing two distinct domains — a
universal planning pipeline (brief → research → plan → execute) and a
Claude-Code-specific architecture phase. Keeping them together forced users
to inherit an unfinished CC-feature catalog (~11 seeds) when they only
wanted the planning pipeline, and locked the catalog and the pipeline into
the same release cadence. The architect was already optional and decoupled
at the code level — only one filesystem touchpoint remained
(auto-discovery of `architecture/overview.md`), which already handles
absence gracefully.
Plugin manifests:
- ultraplan-local: 2.4.0 → 3.0.0 (description + keywords updated)
- ultra-cc-architect: new at 0.1.0 (pre-release; catalog is thin, Fase 2/3
of skill-factory unbuilt, decision-layer empty, fallback list still
needed)
What stays in ultraplan-local: brief/research/plan/execute commands, all
19 planning agents, security hooks, plan auto-discovery of
`architecture/overview.md` (filesystem-level contract, not code-level).
What moved (28 files via git mv, R100 — full history preserved):
- 2 commands, 8 agents, 1 skill catalog (13 files), 2 scripts, 8 fixtures
Documentation updates: plugin CLAUDE.md and README.md for both plugins,
root README.md (added ultra-cc-architect section, updated ultraplan-local
section), root CLAUDE.md (added ultra-cc-architect to repo-struktur),
marketplace.json (registered ultra-cc-architect), ultraplan-local
CHANGELOG.md (v3.0.0 entry with migration guidance).
Test verification: ngram-overlap.test.mjs passes 23/23 from new location.
Memory updated: feedback_no_architect_until_v3.md now points at the new
plugin and reframes the threshold around catalog maturity rather than an
ultraplan-local milestone.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
skill-drafter now reads {catalog_root}/<slug>.md before writing its
draft and prepends a warning block to its confirmation output when
an existing skill would be overwritten during manual `mv` promotion.
The draft is still written to .drafts/<slug>.md — the check is a
hint, not a block.
Closes v2.3.0 dogfood finding (post_dogfood_findings[0]): the
drafter produced .drafts/hooks-pattern.md when an approved
hooks-pattern.md seed already existed, giving no signal that `mv`
during promotion would silently overwrite the seed. v2.3.1
introduced the qualified-slug mechanism to resolve such collisions;
v2.3.2 surfaces them at the right moment — before promotion.
Changes:
- agents/skill-drafter.md — new Step 2 between slug computation and
source reading. Reads {catalog_root}/<slug>.md, inspects
review_status, derives a kebab-case qualifier from the concept
handle (or source basename fallback). Subsequent steps renumbered
3→7. Output format gains Collision: field and optional warning
block. New Hard Rule.
- tests/fixtures/skill-drafter/slug-collision-expected.md — reference
fixture documenting expected confirmation shape across four
scenarios (no collision, approved collision, soft pending
collision, collision with no good qualifier). Skill-drafter is
prompt-driven; fixture anchors shape for human verification and
downstream parsers.
- CHANGELOG [2.3.2], plugin.json 2.3.1→2.3.2, README badge, plugin
CLAUDE.md slug-convention Collision-hint bullet, marketplace root
README summary, marketplace root CLAUDE.md plugin table.
Non-breaking. No frontmatter/drafts-layout/tool-scope/regex changes.
Existing pipelines see one extra field and an optional warning —
both purely additive.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>