feat(voyage)!: bulk content rewrite ultra -> voyage/trek prose [skip-docs]

Sed-pipeline (16 patterns, longest-match-first) sweeper residuelle ultra*-treff
i prose, command-narrativ, agent-prompts, hook-kommentarer, doc-prosa.

Pipeline-utvidelser fra V4-prompten:
- BSD-syntax [[:<:]]ultra[[:>:]] istedenfor \bultra\b (BSD sed mangler \b)
- 6 compound-patterns for ultraplan/ultraexecute/ultraresearch/ultrabrief/
  ultrareview/ultracontinue uten -local-suffiks
- ultra*-stats glob -> trek*-stats glob
- Linje-eksklusjon redusert til ultra-cc-architect (Q8); session-state-
  eksklusjonen var over-protektiv
- File-eksklusjon utvidet til settings.json, package.json, plugin.json,
  hele .claude/-treet (gitignored + V5-territorium)

Q8-undantak holdt: architecture-discovery.mjs + project-discovery.mjs urort.
Filnavn-konvensjon holdt: .session-state.local.json + *.local.* preservert.

Manuell narrative-fix: tests/lib/agent-frontmatter.test.mjs linje 10
mangled "/ultra*-local" til "/voyage*-local" (ingen slik kommando finnes);
korrigert til "/trek*".

Residualer utenfor scope (V5 handterer): package.json + .claude-plugin/
plugin.json (Step 12-14 versjons-bump). .claude/* er gitignored
spec-historikk med tilsiktet BEFORE/AFTER-narrativ.

Part of voyage-rebrand session 3 (Wave 4 / Step 10).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-05 15:08:20 +02:00
commit 14ecda886c
81 changed files with 672 additions and 672 deletions

View file

@ -7,7 +7,7 @@
// MUST include the `Agent` tool in their tools allowlist (they spawn the swarm).
//
// When this test fails, fix the agent file — do NOT relax the assertion to
// hide drift. The contract is what /ultra*-local commands rely on for
// hide drift. The contract is what /trek* commands rely on for
// disciplined model selection + tool scoping.
import { test } from 'node:test';

View file

@ -2,66 +2,66 @@ import { test } from 'node:test';
import { strict as assert } from 'node:assert';
import { parseArgs } from '../../lib/parsers/arg-parser.mjs';
test('ultrabrief — empty args', () => {
test('trekbrief — empty args', () => {
const r = parseArgs('', 'trekbrief');
assert.equal(r.command, 'trekbrief');
assert.deepEqual(r.flags, {});
});
test('ultrabrief — --quick boolean', () => {
test('trekbrief — --quick boolean', () => {
const r = parseArgs('--quick', 'trekbrief');
assert.equal(r.flags['--quick'], true);
});
test('ultraresearch — --project value capture', () => {
test('trekresearch — --project value capture', () => {
const r = parseArgs('--project .claude/projects/2026-04-30-foo', 'trekresearch');
assert.equal(r.flags['--project'], '.claude/projects/2026-04-30-foo');
});
test('ultraresearch — --quick --local combined', () => {
test('trekresearch — --quick --local combined', () => {
const r = parseArgs('--quick --local', 'trekresearch');
assert.equal(r.flags['--quick'], true);
assert.equal(r.flags['--local'], true);
});
test('ultraplan — --research multi-value', () => {
test('trekplan — --research multi-value', () => {
const r = parseArgs('--research a.md b.md c.md', 'trekplan');
assert.deepEqual(r.flags['--research'], ['a.md', 'b.md', 'c.md']);
});
test('ultraplan — --research multi stops at next flag', () => {
test('trekplan — --research multi stops at next flag', () => {
const r = parseArgs('--research a.md b.md --project /x', 'trekplan');
assert.deepEqual(r.flags['--research'], ['a.md', 'b.md']);
assert.equal(r.flags['--project'], '/x');
});
test('ultraplan — --brief required-value flag', () => {
test('trekplan — --brief required-value flag', () => {
const r = parseArgs('--brief brief.md', 'trekplan');
assert.equal(r.flags['--brief'], 'brief.md');
});
test('ultraplan — missing value for --brief produces error', () => {
test('trekplan — missing value for --brief produces error', () => {
const r = parseArgs('--brief --quick', 'trekplan');
assert.ok(r.errors.find(e => e.code === 'ARG_MISSING_VALUE'));
});
test('ultraplan — --decompose value flag', () => {
test('trekplan — --decompose value flag', () => {
const r = parseArgs('--decompose plan.md', 'trekplan');
assert.equal(r.flags['--decompose'], 'plan.md');
});
test('ultraexecute — --resume + --project', () => {
test('trekexecute — --resume + --project', () => {
const r = parseArgs('--resume --project /tmp/p', 'trekexecute');
assert.equal(r.flags['--resume'], true);
assert.equal(r.flags['--project'], '/tmp/p');
});
test('ultraexecute — --step N value', () => {
test('trekexecute — --step N value', () => {
const r = parseArgs('--step 3', 'trekexecute');
assert.equal(r.flags['--step'], '3');
});
test('ultraexecute — unknown flag goes to unknown[]', () => {
test('trekexecute — unknown flag goes to unknown[]', () => {
const r = parseArgs('--mystery foo', 'trekexecute');
assert.ok(r.unknown.includes('--mystery'));
});
@ -76,28 +76,28 @@ test('unknown command reported as error', () => {
assert.ok(r.errors.find(e => e.code === 'ARG_UNKNOWN_COMMAND'));
});
test('ultrareview — --project value capture', () => {
test('trekreview — --project value capture', () => {
const r = parseArgs('--project .claude/projects/2026-05-01-foo', 'trekreview');
assert.equal(r.flags['--project'], '.claude/projects/2026-05-01-foo');
});
test('ultrareview — --since <ref> value', () => {
test('trekreview — --since <ref> value', () => {
const r = parseArgs('--since HEAD~5', 'trekreview');
assert.equal(r.flags['--since'], 'HEAD~5');
});
test('ultrareview — --quick + --validate combined', () => {
test('trekreview — --quick + --validate combined', () => {
const r = parseArgs('--quick --validate', 'trekreview');
assert.equal(r.flags['--quick'], true);
assert.equal(r.flags['--validate'], true);
});
test('ultrareview — unknown flag goes to unknown[]', () => {
test('trekreview — unknown flag goes to unknown[]', () => {
const r = parseArgs('--mystery foo', 'trekreview');
assert.ok(r.unknown.includes('--mystery'));
});
test('ultracontinue — empty args produce no flags and no positional', () => {
test('trekcontinue — empty args produce no flags and no positional', () => {
const r = parseArgs('', 'trekcontinue');
assert.equal(r.command, 'trekcontinue');
assert.deepEqual(r.flags, {});
@ -105,35 +105,35 @@ test('ultracontinue — empty args produce no flags and no positional', () => {
assert.deepEqual(r.errors, []);
});
test('ultracontinue — --help boolean flag', () => {
test('trekcontinue — --help boolean flag', () => {
const r = parseArgs('--help', 'trekcontinue');
assert.equal(r.flags['--help'], true);
});
test('ultracontinue — -h treated as positional (no alias resolution)', () => {
test('trekcontinue — -h treated as positional (no alias resolution)', () => {
const r = parseArgs('-h', 'trekcontinue');
assert.deepEqual(r.positional, ['-h']);
assert.deepEqual(r.errors, []);
assert.equal(r.flags['--help'], undefined);
});
test('ultracontinue — --cleanup boolean flag', () => {
test('trekcontinue — --cleanup boolean flag', () => {
const r = parseArgs('--cleanup', 'trekcontinue');
assert.equal(r.flags['--cleanup'], true);
});
test('ultracontinue — --cleanup --confirm both flags', () => {
test('trekcontinue — --cleanup --confirm both flags', () => {
const r = parseArgs('--cleanup --confirm', 'trekcontinue');
assert.equal(r.flags['--cleanup'], true);
assert.equal(r.flags['--confirm'], true);
});
test('ultracontinue — positional project dir captured', () => {
test('trekcontinue — positional project dir captured', () => {
const r = parseArgs('.claude/projects/2026-05-04-foo', 'trekcontinue');
assert.deepEqual(r.positional, ['.claude/projects/2026-05-04-foo']);
});
test('ultracontinue — .md positional accepted by parser (rejection is command-level)', () => {
test('trekcontinue — .md positional accepted by parser (rejection is command-level)', () => {
const r = parseArgs('NEXT-SESSION-PROMPT.local.md', 'trekcontinue');
assert.deepEqual(r.positional, ['NEXT-SESSION-PROMPT.local.md']);
assert.deepEqual(r.errors, []);

View file

@ -27,9 +27,9 @@ test('splitFrontmatter — no frontmatter', () => {
});
test('parseFrontmatter — string scalars', () => {
const r = parseFrontmatter('type: ultrabrief\nslug: jwt-auth\n');
const r = parseFrontmatter('type: trekbrief\nslug: jwt-auth\n');
assert.equal(r.valid, true);
assert.equal(r.parsed.type, 'ultrabrief');
assert.equal(r.parsed.type, 'trekbrief');
assert.equal(r.parsed.slug, 'jwt-auth');
});
@ -60,10 +60,10 @@ test('parseFrontmatter — rejects nested dict', () => {
});
test('parseDocument — full pipeline', () => {
const text = '---\ntype: ultrabrief\nresearch_topics: 2\n---\n\n# Body\n\ncontent\n';
const text = '---\ntype: trekbrief\nresearch_topics: 2\n---\n\n# Body\n\ncontent\n';
const r = parseDocument(text);
assert.equal(r.valid, true);
assert.equal(r.parsed.frontmatter.type, 'ultrabrief');
assert.equal(r.parsed.frontmatter.type, 'trekbrief');
assert.match(r.parsed.body, /content/);
});

View file

@ -9,7 +9,7 @@ import {
} from '../../lib/parsers/project-discovery.mjs';
function setupProject(structure) {
const root = mkdtempSync(join(tmpdir(), 'ultraplan-disc-'));
const root = mkdtempSync(join(tmpdir(), 'trekplan-disc-'));
for (const [path, content] of Object.entries(structure)) {
const full = join(root, path);
mkdirSync(join(full, '..'), { recursive: true });

View file

@ -1,7 +1,7 @@
// tests/lib/source-findings.test.mjs
// SC3(b) structural test for Handover 6.
//
// The brief requires `plan.md` produced from a `type: ultrareview` brief to
// The brief requires `plan.md` produced from a `type: trekreview` brief to
// contain `source_findings: [<id>, ...]` in its frontmatter. Without an
// automated test, SC3(b) is unverified.
//