chore(cleanup): R-b R3 — profiles, phase signals and the effort dialog removed, one fixed path per command
The four profiles, the resolver, the profile validator and docs/profiles.md go; /trekbrief Phase 3.5 and the brief's phase_signals checks go (an older brief's key is ignored); MANIFEST_PROFILE_DRIFT and profile_used go. Every Profile, Composition rule, Sequencing gate and High-effort section leaves the commands. Decision 209: /trekresearch runs the full swarm with contrarian-researcher as wave 2 every run; /trekreview and the coordinator run all four passes with no high-effort normalization. Voyage agents are spawned with no model (their own model: opus applies); the two built-in spawns pass model "opus". --profile stays in the parser as a retired flag that swallows its value. §Model & effort moves to docs/architecture.md; the sequencing-gate eval case goes. Files removed: 44 (43 from the R3 list + tests/commands/trekreview.test.mjs, whose every test pinned removed text). Files edited: 43. Tests: 2467 (2466 pass / 0 fail / 1 skipped) before, 2309 (2309 pass / 0 fail / 0 skipped) after. Durable check: all three groups green, none pending. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
32621dcb63
commit
2a35d067d9
87 changed files with 225 additions and 4967 deletions
|
|
@ -9,7 +9,6 @@
|
|||
import { readFileSync, existsSync } from 'node:fs';
|
||||
import { parseDocument } from '../util/frontmatter.mjs';
|
||||
import { issue, ok, fail } from '../util/result.mjs';
|
||||
import { BASE_ALLOWED_MODELS } from './profile-validator.mjs';
|
||||
import { parseSuccessCriteria, runnableCheck, firstCommand } from '../verification/criteria-runner.mjs';
|
||||
import { isMain } from '../util/is-main.mjs';
|
||||
|
||||
|
|
@ -18,8 +17,6 @@ export const REVIEW_AS_BRIEF_REQUIRED_FRONTMATTER = ['type', 'task', 'slug', 'pr
|
|||
export const BRIEF_TYPE_VALUES = Object.freeze(['trekbrief', 'trekreview']);
|
||||
export const BRIEF_RESEARCH_STATUS_VALUES = ['pending', 'in_progress', 'complete', 'skipped'];
|
||||
export const BRIEF_BODY_SECTIONS = ['Intent', 'Goal', 'Success Criteria'];
|
||||
export const PHASE_SIGNAL_PHASES = Object.freeze(['research', 'plan', 'execute', 'review']);
|
||||
export const EFFORT_LEVELS = Object.freeze(['low', 'standard', 'high']);
|
||||
// v5.5 — framing: how this brief relates to prior operator intent (the first layer
|
||||
// of the framing-alignment defense). Required at brief_version ≥ 2.2.
|
||||
export const BRIEF_FRAMING_VALUES = Object.freeze(['preserve', 'refine', 'replace', 'new-direction']);
|
||||
|
|
@ -77,55 +74,6 @@ export function validateBriefContent(text, opts = {}) {
|
|||
}
|
||||
}
|
||||
|
||||
// v5.1 — phase_signals (additive optional field) + version-conditional sequencing gate.
|
||||
// Composition rule documented in each downstream command's "Composition rule (v5.1)" section.
|
||||
const hasSignals = 'phase_signals' in fm;
|
||||
const hasPartial = 'phase_signals_partial' in fm;
|
||||
if (hasSignals && hasPartial) {
|
||||
errors.push(issue(
|
||||
'BRIEF_SIGNALS_MUTUALLY_EXCLUSIVE',
|
||||
'phase_signals and phase_signals_partial are mutually exclusive — set exactly one',
|
||||
'Either commit per-phase signals OR record phase_signals_partial: true (force-stop).',
|
||||
));
|
||||
}
|
||||
if (hasSignals) {
|
||||
if (!Array.isArray(fm.phase_signals)) {
|
||||
errors.push(issue(
|
||||
'BRIEF_INVALID_PHASE_SIGNALS',
|
||||
'phase_signals must be a list of {phase, effort?, model?} entries',
|
||||
));
|
||||
} else {
|
||||
for (const entry of fm.phase_signals) {
|
||||
if (!entry || typeof entry !== 'object' || !('phase' in entry)) {
|
||||
errors.push(issue('BRIEF_INVALID_PHASE_SIGNALS', `phase_signals entry must include a "phase" key`));
|
||||
continue;
|
||||
}
|
||||
if (!PHASE_SIGNAL_PHASES.includes(entry.phase)) {
|
||||
errors.push(issue(
|
||||
'BRIEF_INVALID_PHASE_SIGNAL_PHASE',
|
||||
`phase_signals.phase "${entry.phase}" not in [${PHASE_SIGNAL_PHASES.join(', ')}]`,
|
||||
));
|
||||
}
|
||||
if ('effort' in entry && !EFFORT_LEVELS.includes(entry.effort)) {
|
||||
errors.push(issue(
|
||||
'BRIEF_INVALID_EFFORT',
|
||||
`phase_signals.effort "${entry.effort}" not in [${EFFORT_LEVELS.join(', ')}]`,
|
||||
));
|
||||
}
|
||||
if ('model' in entry && !BASE_ALLOWED_MODELS.includes(entry.model)) {
|
||||
errors.push(issue(
|
||||
'BRIEF_INVALID_MODEL',
|
||||
`phase_signals.model "${entry.model}" not in [${BASE_ALLOWED_MODELS.join(', ')}]`,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sequencing gate: brief_version ≥ 2.1 requires phase_signals OR phase_signals_partial.
|
||||
// Coerce to String so the gate fires regardless of whether YAML parsed the value as
|
||||
// a string ("2.1") or a number (2.1). v5.1.0 shipped with an unquoted-2.1 template
|
||||
// that silently bypassed this gate — fix locked in by quoting the template AND
|
||||
// accepting both shapes here as defense-in-depth (v5.1.1, finding 3c834097/df1435a2).
|
||||
// v5.5 — framing enum check fires on ANY version when the field is present but
|
||||
// malformed. The missing-framing BLOCKER below is version-gated (≥ 2.2).
|
||||
if ('framing' in fm && !BRIEF_FRAMING_VALUES.includes(fm.framing)) {
|
||||
|
|
@ -156,15 +104,7 @@ export function validateBriefContent(text, opts = {}) {
|
|||
if (vm) {
|
||||
const major = Number(vm[1]);
|
||||
const minor = Number(vm[2]);
|
||||
const atLeast21 = major > 2 || (major === 2 && minor >= 1);
|
||||
const atLeast22 = major > 2 || (major === 2 && minor >= 2);
|
||||
if (atLeast21 && !hasSignals && !hasPartial && fm.type !== 'trekreview') {
|
||||
errors.push(issue(
|
||||
'BRIEF_V51_MISSING_SIGNALS',
|
||||
'brief_version ≥ 2.1 requires phase_signals (or phase_signals_partial: true)',
|
||||
'Re-run /trekbrief — Phase 3.5 collects per-phase effort + model signals.',
|
||||
));
|
||||
}
|
||||
// v5.5 framing enforcement — gated at ≥ 2.2 (trekreview briefs are exempt).
|
||||
if (atLeast22 && fm.type !== 'trekreview') {
|
||||
if (!('framing' in fm)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue