feat(voyage)!: rename type discriminators across validators + fixtures [skip-docs]

- brief-validator: BRIEF_TYPE_VALUES ['ultrabrief','ultrareview'] -> ['trekbrief','trekreview'] + dependent branches
- research-validator: 'ultraresearch-brief' -> 'trekresearch-brief'
- review-validator: 'ultrareview' -> 'trekreview'
- 3 templates frontmatter type:
- 4 synthetic fixtures: ultraplan-synthetic/ultrareview-synthetic -> trek* (frontmatter only; bodies untouched, Jaccard floor preserved)
- 2 trekreview fixtures: type: trekreview
- 6 validator-test fixtures + asserts
- agents/review-coordinator.md frontmatter example

Atomic: validator + fixtures committed together — partial state would cause vacuous
test passes or hard validator rejection.

Part of voyage-rebrand session 2 (W3.3 / Step 5).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-05-05 14:40:25 +02:00
commit 0508edff15
16 changed files with 28 additions and 28 deletions

View file

@ -134,7 +134,7 @@ Produce the full review.md content as your output. The
```yaml ```yaml
--- ---
type: ultrareview type: trekreview
review_version: "1.0" review_version: "1.0"
created: {YYYY-MM-DD} created: {YYYY-MM-DD}
task: "{from brief frontmatter}" task: "{from brief frontmatter}"

View file

@ -7,12 +7,12 @@ import { issue, ok, fail } from '../util/result.mjs';
export const BRIEF_REQUIRED_FRONTMATTER = ['type', 'brief_version', 'task', 'slug', 'research_topics', 'research_status']; export const BRIEF_REQUIRED_FRONTMATTER = ['type', 'brief_version', 'task', 'slug', 'research_topics', 'research_status'];
export const REVIEW_AS_BRIEF_REQUIRED_FRONTMATTER = ['type', 'task', 'slug', 'project_dir', 'findings']; export const REVIEW_AS_BRIEF_REQUIRED_FRONTMATTER = ['type', 'task', 'slug', 'project_dir', 'findings'];
export const BRIEF_TYPE_VALUES = Object.freeze(['ultrabrief', 'ultrareview']); export const BRIEF_TYPE_VALUES = Object.freeze(['trekbrief', 'trekreview']);
export const BRIEF_RESEARCH_STATUS_VALUES = ['pending', 'in_progress', 'complete', 'skipped']; export const BRIEF_RESEARCH_STATUS_VALUES = ['pending', 'in_progress', 'complete', 'skipped'];
export const BRIEF_BODY_SECTIONS = ['Intent', 'Goal', 'Success Criteria']; export const BRIEF_BODY_SECTIONS = ['Intent', 'Goal', 'Success Criteria'];
function getRequiredFields(type) { function getRequiredFields(type) {
return type === 'ultrareview' ? REVIEW_AS_BRIEF_REQUIRED_FRONTMATTER : BRIEF_REQUIRED_FRONTMATTER; return type === 'trekreview' ? REVIEW_AS_BRIEF_REQUIRED_FRONTMATTER : BRIEF_REQUIRED_FRONTMATTER;
} }
export function validateBriefContent(text, opts = {}) { export function validateBriefContent(text, opts = {}) {
@ -38,10 +38,10 @@ export function validateBriefContent(text, opts = {}) {
)); ));
} }
if (fm.type === 'ultrareview' && fm.findings !== undefined && !Array.isArray(fm.findings)) { if (fm.type === 'trekreview' && fm.findings !== undefined && !Array.isArray(fm.findings)) {
errors.push(issue( errors.push(issue(
'BRIEF_BAD_FINDINGS_TYPE', 'BRIEF_BAD_FINDINGS_TYPE',
'Field "findings" must be an array of finding-IDs for type:ultrareview', 'Field "findings" must be an array of finding-IDs for type:trekreview',
'Use block-style YAML: `findings:\\n - <id1>\\n - <id2>`', 'Use block-style YAML: `findings:\\n - <id1>\\n - <id2>`',
)); ));
} }

View file

@ -23,8 +23,8 @@ export function validateResearchContent(text, opts = {}) {
if (!(k in fm)) errors.push(issue('RESEARCH_MISSING_FIELD', `Required frontmatter field missing: ${k}`)); if (!(k in fm)) errors.push(issue('RESEARCH_MISSING_FIELD', `Required frontmatter field missing: ${k}`));
} }
if (fm.type !== undefined && fm.type !== 'ultraresearch-brief') { if (fm.type !== undefined && fm.type !== 'trekresearch-brief') {
errors.push(issue('RESEARCH_WRONG_TYPE', `frontmatter.type must be "ultraresearch-brief", got "${fm.type}"`)); errors.push(issue('RESEARCH_WRONG_TYPE', `frontmatter.type must be "trekresearch-brief", got "${fm.type}"`));
} }
if (fm.confidence !== undefined) { if (fm.confidence !== undefined) {

View file

@ -37,8 +37,8 @@ export function validateReviewContent(text, opts = {}) {
} }
} }
if (fm.type !== undefined && fm.type !== 'ultrareview') { if (fm.type !== undefined && fm.type !== 'trekreview') {
errors.push(issue('REVIEW_WRONG_TYPE', `frontmatter.type must be "ultrareview", got "${fm.type}"`)); errors.push(issue('REVIEW_WRONG_TYPE', `frontmatter.type must be "trekreview", got "${fm.type}"`));
} }
if (fm.findings !== undefined) { if (fm.findings !== undefined) {

View file

@ -1,5 +1,5 @@
--- ---
type: ultraresearch-brief type: trekresearch-brief
created: {YYYY-MM-DD} created: {YYYY-MM-DD}
question: "{research question}" question: "{research question}"
confidence: {0.0-1.0} confidence: {0.0-1.0}

View file

@ -1,5 +1,5 @@
--- ---
type: ultrabrief type: trekbrief
brief_version: 2.0 brief_version: 2.0
created: {YYYY-MM-DD} created: {YYYY-MM-DD}
task: "{one-line task description}" task: "{one-line task description}"

View file

@ -1,5 +1,5 @@
--- ---
type: ultrareview type: trekreview
review_version: "1.0" review_version: "1.0"
created: {YYYY-MM-DD} created: {YYYY-MM-DD}
task: "{Task description from brief.md}" task: "{Task description from brief.md}"

View file

@ -1,5 +1,5 @@
--- ---
type: ultrareview type: trekreview
review_version: "1.0" review_version: "1.0"
created: 2026-05-01 created: 2026-05-01
task: "Add JWT authentication with refresh-token rotation" task: "Add JWT authentication with refresh-token rotation"

View file

@ -1,5 +1,5 @@
--- ---
type: ultrareview type: trekreview
review_version: "1.0" review_version: "1.0"
created: 2026-05-01 created: 2026-05-01
task: "Add JWT authentication with refresh-token rotation" task: "Add JWT authentication with refresh-token rotation"

View file

@ -1,5 +1,5 @@
--- ---
type: ultraplan-synthetic type: trekplan-synthetic
plan_version: "1.7" plan_version: "1.7"
created: 2026-05-04 created: 2026-05-04
task: "Add --verbose flag to CLI" task: "Add --verbose flag to CLI"

View file

@ -1,5 +1,5 @@
--- ---
type: ultraplan-synthetic type: trekplan-synthetic
plan_version: "1.7" plan_version: "1.7"
created: 2026-05-04 created: 2026-05-04
task: "Add --verbose flag to CLI" task: "Add --verbose flag to CLI"

View file

@ -1,5 +1,5 @@
--- ---
type: ultrareview-synthetic type: trekreview-synthetic
review_version: "1.0" review_version: "1.0"
created: 2026-05-04 created: 2026-05-04
task: "Add JWT authentication with refresh-token rotation" task: "Add JWT authentication with refresh-token rotation"

View file

@ -1,5 +1,5 @@
--- ---
type: ultrareview-synthetic type: trekreview-synthetic
review_version: "1.0" review_version: "1.0"
created: 2026-05-04 created: 2026-05-04
task: "Add JWT authentication with refresh-token rotation" task: "Add JWT authentication with refresh-token rotation"

View file

@ -3,7 +3,7 @@ import { strict as assert } from 'node:assert';
import { validateBriefContent } from '../../lib/validators/brief-validator.mjs'; import { validateBriefContent } from '../../lib/validators/brief-validator.mjs';
const GOOD_BRIEF = `--- const GOOD_BRIEF = `---
type: ultrabrief type: trekbrief
brief_version: "2.0" brief_version: "2.0"
created: 2026-04-30 created: 2026-04-30
task: "Add JWT auth to API" task: "Add JWT auth to API"
@ -37,7 +37,7 @@ test('validateBrief — happy path', () => {
}); });
test('validateBrief — wrong type rejected', () => { test('validateBrief — wrong type rejected', () => {
const t = GOOD_BRIEF.replace('type: ultrabrief', 'type: notabrief'); const t = GOOD_BRIEF.replace('type: trekbrief', 'type: notabrief');
const r = validateBriefContent(t); const r = validateBriefContent(t);
assert.equal(r.valid, false); assert.equal(r.valid, false);
assert.ok(r.errors.find(e => e.code === 'BRIEF_WRONG_TYPE')); assert.ok(r.errors.find(e => e.code === 'BRIEF_WRONG_TYPE'));
@ -94,7 +94,7 @@ test('validateBrief — missing frontmatter is hard error', () => {
}); });
const REVIEW_AS_BRIEF = `--- const REVIEW_AS_BRIEF = `---
type: ultrareview type: trekreview
task: "Review delivered ultrareview-local v1.0" task: "Review delivered ultrareview-local v1.0"
slug: ultrareview-local slug: ultrareview-local
project_dir: .claude/projects/2026-05-01-ultrareview-local/ project_dir: .claude/projects/2026-05-01-ultrareview-local/
@ -144,11 +144,11 @@ test('validateBrief — ultrareview with findings as scalar (not array) rejected
}); });
test('validateBrief — wrong-type error message includes accepted set', () => { test('validateBrief — wrong-type error message includes accepted set', () => {
const t = REVIEW_AS_BRIEF.replace('type: ultrareview', 'type: somethingelse'); const t = REVIEW_AS_BRIEF.replace('type: trekreview', 'type: somethingelse');
const r = validateBriefContent(t); const r = validateBriefContent(t);
assert.equal(r.valid, false); assert.equal(r.valid, false);
const wrongType = r.errors.find(e => e.code === 'BRIEF_WRONG_TYPE'); const wrongType = r.errors.find(e => e.code === 'BRIEF_WRONG_TYPE');
assert.ok(wrongType); assert.ok(wrongType);
assert.ok(/ultrabrief/.test(wrongType.message)); assert.ok(/trekbrief/.test(wrongType.message));
assert.ok(/ultrareview/.test(wrongType.message)); assert.ok(/trekreview/.test(wrongType.message));
}); });

View file

@ -3,7 +3,7 @@ import { strict as assert } from 'node:assert';
import { validateResearchContent } from '../../lib/validators/research-validator.mjs'; import { validateResearchContent } from '../../lib/validators/research-validator.mjs';
const GOOD = `--- const GOOD = `---
type: ultraresearch-brief type: trekresearch-brief
created: 2026-04-30 created: 2026-04-30
question: "How to do X?" question: "How to do X?"
confidence: 0.8 confidence: 0.8
@ -25,7 +25,7 @@ test('validateResearch — happy path', () => {
}); });
test('validateResearch — wrong type', () => { test('validateResearch — wrong type', () => {
const t = GOOD.replace('type: ultraresearch-brief', 'type: random'); const t = GOOD.replace('type: trekresearch-brief', 'type: random');
const r = validateResearchContent(t); const r = validateResearchContent(t);
assert.equal(r.valid, false); assert.equal(r.valid, false);
assert.ok(r.errors.find(e => e.code === 'RESEARCH_WRONG_TYPE')); assert.ok(r.errors.find(e => e.code === 'RESEARCH_WRONG_TYPE'));

View file

@ -3,7 +3,7 @@ import { strict as assert } from 'node:assert';
import { validateReviewContent } from '../../lib/validators/review-validator.mjs'; import { validateReviewContent } from '../../lib/validators/review-validator.mjs';
const GOOD_REVIEW = `--- const GOOD_REVIEW = `---
type: ultrareview type: trekreview
review_version: "1.0" review_version: "1.0"
created: 2026-05-01 created: 2026-05-01
task: "Add JWT auth" task: "Add JWT auth"
@ -41,7 +41,7 @@ test('validateReview — happy path', () => {
}); });
test('validateReview — wrong type rejected (REVIEW_WRONG_TYPE)', () => { test('validateReview — wrong type rejected (REVIEW_WRONG_TYPE)', () => {
const t = GOOD_REVIEW.replace('type: ultrareview', 'type: ultrabrief'); const t = GOOD_REVIEW.replace('type: trekreview', 'type: trekbrief');
const r = validateReviewContent(t); const r = validateReviewContent(t);
assert.equal(r.valid, false); assert.equal(r.valid, false);
assert.ok(r.errors.find(e => e.code === 'REVIEW_WRONG_TYPE')); assert.ok(r.errors.find(e => e.code === 'REVIEW_WRONG_TYPE'));