c412f72605
test(voyage): add annotation roundtrip + rollback + source_annotations integration — v4.2 Step 7
...
Implements SC2/SC3/SC5b/SC7 + additive-field invariant for the v4.2
annotation pipeline:
Fixtures (tests/fixtures/annotation/):
- annotation-brief.md — brief-validator-clean fixture
- annotation-plan.md — plan-validator-clean (2 steps)
- annotation-review.md — review-validator-clean
- annotation-plan-large.md — 51 steps (SC3 scale fixture)
Integration tests:
- tests/integration/annotation-roundtrip.test.mjs — 7 cases:
SC2 byte-identical empty round-trip across brief/plan/review,
SC3 scale (51 steps + 100 anchors) round-trip,
SC7 parseAnchors(stripAnchors(addAnchors(...))) === [] per target.
- tests/integration/schema-rollback.test.mjs — 4 cases:
SC5b validator-FAIL -> revisionGuard rolls back byte-identical
(sha256 invariant) for brief/plan/review + cross-target sweep.
.local.bak deleted on rollback path (validator-PASS path tested
in lib/util/revision-guard tests).
- tests/lib/source-annotations.test.mjs — 6 cases mirroring
tests/lib/source-findings.test.mjs additive-field pattern: each
validator (brief/plan/review) accepts source_annotations as
additive-optional, parser extracts as array of dicts, entries
conform to documented shape, baseline forward-compat (artifacts
without source_annotations still validate).
Verify: node --test tests/integration/annotation-roundtrip.test.mjs
tests/integration/schema-rollback.test.mjs
tests/lib/source-annotations.test.mjs -> 17 pass / 0 fail.
Full npm test: 577 pass / 0 fail / 2 skipped (Docker).
Refs plan.md Step 7 + plan-critic M4 + plan-critic B4.
2026-05-09 15:13:27 +02:00
4fbc52bbb4
feat(voyage): add commands/trekrevise.md — 7th pipeline command + settings.json scope — v4.2 Step 6 [skip-docs]
...
Implements Phase 1-8 of /trekrevise (Handover 8 producer):
- Phase 1: parse mode + reject MULTI_ARTIFACT_NOT_SUPPORTED
- Phase 2: read source + check stale .local.bak
- Phase 3: parseAnchors + validateAnchorPlacement (no partial revisions)
- Phase 4: computeAnnotationDigest + non-additive detection
- Phase 5: revisionGuard orchestration (backup -> mutate -> validate -> rollback-on-fail)
- Phase 6: branch on outcome (applied / rolled-back / mutator-failed)
- Phase 7: optional review-gate (advisory, no auto-rollback)
- Phase 8: trekrevise-stats.jsonl + report
Frontmatter: name=trekrevise, model=opus, allowed-tools includes Read/Write/Edit/Bash/Grep/Glob.
Reuses lib/parsers/anchor-parser, lib/parsers/annotation-digest,
lib/util/markdown-write, lib/util/revision-guard, lib/validators/{brief,plan,review}.
settings.json: register new top-level scope trekrevise with
trekrevise-stats.jsonl tracking (mirrors trekplan/trekresearch shape).
Forward-pinning to keep doc-consistency invariants green:
- tests/lib/doc-consistency.test.mjs: known-scopes allowlist += trekrevise
- CLAUDE.md commands table: add /trekrevise row
Plan Step 13 owns the full README/CLAUDE.md/CHANGELOG content sync;
this commit is the implementation milestone, not the doc milestone.
Refs plan.md Step 6 + plan-critic M3.
2026-05-09 15:09:01 +02:00
dcf0c7ad02
feat(voyage): add markdown-write.mjs + revision-guard.mjs + forward-compat policy comments — v4.2 Step 1
...
- lib/util/markdown-write.mjs: serializeFrontmatter (subset matches frontmatter.mjs parser), atomicWriteMarkdown (single tmp+rename, body bytes verbatim), readAndUpdate (read+mutate+write).
- lib/util/revision-guard.mjs: revisionGuard(path, mutator, validator) — backup -> mutate -> validate -> restore-on-fail. Extracted from /trekrevise prompt so rollback can be unit-tested.
- 12 tests for markdown-write, including 6-key source_annotations round-trip + walk-all-fixtures regression.
- 6 tests for revision-guard: applied/rolled-back/mutator-failed/sha256 stability/pre-existing-bak abort.
- Forward-compat policy comments in 3 validators (brief/plan/review) — non-functional pin against future strict-key refactors.
Pass: 508/510 (was 490; +18 net from v4.2 Step 1, 2 skipped Docker)
2026-05-09 12:48:40 +02:00
f2f8246e01
docs(voyage): document v4.1 profiles + observability + doc-consistency-pinning
...
Step 22 of v4.1 — write top-level docs for the v4.1 feature surface.
Files updated:
CLAUDE.md — Commands tables: add --profile to all 6 modes
+ new ## Profile system + ## Observability sections
README.md — per-command Modes tables: add --profile row
+ new top-level ## Profile system + ## Observability
+ cross-link from ## Cost profile
CHANGELOG.md — new "## v4.1.0 — 2026-05-09" entry per Keep-a-Changelog 1.1.0
(Added / Changed / Fixed / Notes)
docs/profiles.md — NEW: 168-line decision tree, lookup precedence,
custom-profile authoring, drift detection,
cost-estimation table with disclaimer
tests/lib/doc-consistency.test.mjs — extend with 5 new pinning tests:
CLAUDE.md --profile + phase_models canonical name,
README.md --profile coverage (≥ 6 mentions),
CHANGELOG.md v4.1.0 entry, docs/profiles.md substantive
ROADMAP.md is gitignored per marketplace policy (sesjonsfiler) — local
edit applied for v4.1 DONE marker, not committed.
Plan-critic Blocker 2 split is honored: Step 21 pinned commands-only;
Step 22 writes the docs and pins them. doc-consistency.test.mjs is
green AFTER Step 22 (would have failed if Step 22 ran in same wave).
Tests: 487 pass + 2 skipped (Docker not installed).
2026-05-09 10:09:44 +02:00
e440ca858c
test(voyage): extend doc-consistency.test.mjs — pin --profile + phase_models on 6 commands SC #20
...
Step 21 of v4.1 — extend-in-place per Plan-critic Blocker 2 split:
commands-only assertions land here; CLAUDE.md / README.md pinning is
deferred to Step 22 (post-write).
Changes:
1. CLAUDE.md command coverage loop now spans all SIX pipeline commands
(added /trekcontinue — was 5 of 6 pre-v4.1 per HIGH risk-assessor).
2. New: every pipeline command-file (trekbrief/research/plan/execute/
review/continue.md) must document the --profile flag.
3. New: forbidden-alias check — no command-file may use the legacy
names model_per_phase / phase_to_model / profile_phase_models.
Canonical name is "phase_models" (locked in brief).
4. New: at least one command-file must mention "phase_models" by name
so the regression detects total removal of the canonical-name
reference.
Tests: 482 pass + 2 skipped (Docker not installed).
2026-05-09 10:03:43 +02:00
ef379bedf7
feat(voyage): add 5 additive profile fields to JSONL stats — SC #11
...
Step 8 av v4.1-execute (Wave 3, Session 4).
5 nye additive felter er nå dokumentert i hver kommandos prose-stats-blokk
(via Profile-seksjonen fra Step 7 — felles overflate per kommando):
- profile — string ('economy' | 'balanced' | 'premium' | <custom>)
- phase_models — object form {brief: 'sonnet', ..., continue: 'opus'}
- parallel_agents — number (snapshot av maksverdi som faktisk ble brukt)
- external_research_enabled — boolean
- profile_source — 'flag' | 'env' | 'default' | 'inheritance'
Patcher trekresearch.md med eksplisitt profile_source-mention + alle 5 felter
(de andre 5 commands hadde dette allerede via Step 7 Profile-seksjon).
SC #11 contract-test design (per brief):
(a) Fixture-records valideres som JSONL-contracts → tests/fixtures/stats-with-profile.jsonl
(5 simulerte stats-rader, én per kommando-overflate)
(b) Command-prose contains field-names → kompenserer for plan-critic Major 4
false-confidence (faktisk runtime-emission er LLM-prose-driven, ikke
testbart i node:test alene).
Tester (12 nye, baseline 445 → 457):
- Fixture parses som JSONL (5 records)
- Hver record har profile + profile_source
- profile_source-verdier i {flag, env, default, inheritance}
- Fikstur dekker alle 4 profile_source-verdier
- 6 commands × prose contains profile + profile_source
- trekplan.md prose contains phase_models + parallel_agents
- trekresearch.md prose contains external_research_enabled
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 09:40:21 +02:00
71fcf6065a
feat(voyage): document --profile flag in all 6 commands — SC #4 + arv-policy
...
Step 7 av v4.1-execute (Wave 3, Session 4).
Legg ny "## Profile (v4.1)"-seksjon i hver kommando-fil rett før "## Hard rules":
- trekbrief.md: --profile + VOYAGE_PROFILE + premium default
- trekresearch.md: + economy/balanced auto-disable external_research_enabled
- trekplan.md: + plan.md frontmatter recording for inheritance
- trekexecute.md: + 4-step resolution (flag > env > inheritance > default)
- trekreview.md: + opus-default for review-deepening
- trekcontinue.md: spesiell — INHERITANCE er default (ikke premium), --profile
overstyr emitter stderr-advarsel
Tester (13 nye, baseline 432 → 445):
- 6 commands × 2 (--profile + VOYAGE_PROFILE)
- trekcontinue.md "inheritance"-keyword
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 09:38:36 +02:00
f419121682
feat(voyage): add lib/profiles/resolver.mjs — locked interface SC #5-#9
...
Step 6 av v4.1-execute (Wave 2, Session 2).
Implementer locked interface contract fra brief Preferences:
- loadProfile(name, opts) → ProfileObject
Leser lib/profiles/<name>.yaml (built-in) eller custom fra
<cwd>/voyage-profiles/ > ~/.claude/voyage-profiles/. Throws Error med
cause: PROFILE_NOT_FOUND. Returnerer parsed object med phase_models
flattened til {brief: 'sonnet', research: 'opus', ...} (object form
for downstream JSON-stats).
- resolveProfile(argv, env) → {profile, profile_source}
Ordre: --profile flag > VOYAGE_PROFILE env > 'premium' default.
- resolveTrekcontinueProfile(planPath, argv, opts) → {profile, profile_source}
--profile flag wins ('flag'); ellers leser plan.md frontmatter
('inheritance'); v4.0-stil plan uten profile-felt → 'default' premium
(backward-compat). Flag overstyrer arv → console.error advisory.
- validateProfileFile(path) → Result
Tynn re-eksport av validateProfile fra profile-validator.mjs.
- findProfilePath(name, opts) → {path, attempted}
Lookup-helper. attempted-array brukes i error-melding for HIGH-risk-
mitigering (ENOENT-diagnose).
Tester (13 nye, baseline 387 → 400):
- SC #5 x4 (loadProfile economy/balanced/premium + PROFILE_NOT_FOUND)
- SC #6 (flag > env > default ordre)
- SC #7 (performance: 1000-iter < 50ms gjennomsnitt; faktisk ~0.055ms)
- SC #8 x2 (cwd > home precedence + error-msg attempted-paths)
- SC #9 x2 (inheritance + flag-override-advisory)
- Backward-compat x2 (v4.0 plan + non-existent plan)
- validateProfileFile re-export sanity
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 09:29:01 +02:00
ad2dc5759a
feat(voyage): add OPTIONAL_STRING_KEYS path to manifest-yaml — profile_used additive
...
Step 3 av v4.1-execute (Wave 1, Session 1).
Legg ny eksportert const OPTIONAL_STRING_KEYS = ['profile_used'] parallel
til eksisterende OPTIONAL_KEYS. Utvid parseManifest med ny dispatch-loop
etter OPTIONAL_BOOLEAN_KEYS. Returnerer MANIFEST_OPTIONAL_TYPE hvis
profile_used finnes men ikke er string.
Forskjell fra OPTIONAL_BOOLEAN_KEYS: absence == not-present (NOT defaulted
til false, unlike boolean). Downstream-konsumenter kan dermed skille mellom
unset og empty-string.
Tester (5 nye, baseline 372 → 377):
- OPTIONAL_STRING_KEYS export drift-pin
- profile_used: economy parses successfully (SC #10 forward-compat)
- profile_used: numeric rejected
- absence: field NOT in parsed (string-key semantics)
- profile_used + skip_commit_check + memory_write co-existence
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-09 09:23:32 +02:00
7a90d348ad
feat(voyage)!: marketplace handoff — rename plugins/ultraplan-local to plugins/voyage [skip-docs]
...
Session 5 of voyage-rebrand (V6). Operator-authorized cross-plugin scope.
- git mv plugins/ultraplan-local plugins/voyage (rename detected, history preserved)
- .claude-plugin/marketplace.json: voyage entry replaces ultraplan-local
- CLAUDE.md: voyage row in plugin list, voyage in design-system consumer list
- README.md: bulk rename ultra*-local commands -> trek* commands; ultraplan-local refs -> voyage; type discriminators (type: trekbrief/trekreview); session-title pattern (voyage:<command>:<slug>); v4.0.0 release-note paragraph
- plugins/voyage/.claude-plugin/plugin.json: homepage/repository URLs point to monorepo voyage path
- plugins/voyage/verify.sh: drop URL whitelist exception (no longer needed)
Closes voyage-rebrand. bash plugins/voyage/verify.sh PASS 7/7. npm test 361/361.
2026-05-05 15:37:52 +02:00