OverviewFilesCommitsIssuesDocsReleasesPeers

P2P-Hiverelay / test / unit / vnext-program-state.test.js

75 lines · javascript ref:
import test from 'brittle'
import fs from 'node:fs'
import { validateVnextProgramState } from '../../scripts/check-vnext-program-state.mjs'

const canonical = JSON.parse(fs.readFileSync(new URL('../../docs/vnext/program-state.json', import.meta.url), 'utf8'))

test('vNext program state validates the canonical release train without approving pending decisions', (t) => {
  const result = validateVnextProgramState(structuredClone(canonical))
  t.is(result.schema, 'hiverelay-vnext-program-state-v1')
  t.is(result.profiles, 5)
  t.alike(result.pendingDecisions, [])
  t.alike(result.passedGates, [])
  t.alike(result.activeTracks, ['T00', 'T01', 'T01B', 'T02', 'T03', 'T04', 'T05'])
})

test('vNext program state rejects recommendation-as-authorization drift', (t) => {
  const state = structuredClone(canonical)
  // The drift rule guards PENDING decisions (a recommendation can never become
  // a selection without an owner action) — D-1 is decided in the canonical
  // ledger, so put it back into a pending state to exercise the guard.
  state.decisions[0].status = 'pending-owner'
  state.decisions[0].selected = state.decisions[0].recommendation
  t.exception(() => validateVnextProgramState(state), /pending decision D-1 cannot encode a selection/)
})

test('vNext program state keeps owner, deadline, rationale, and affected boundaries explicit', (t) => {
  const unsafeOwner = structuredClone(canonical)
  unsafeOwner.decisions[0].owner = '../anyone'
  t.exception(() => validateVnextProgramState(unsafeOwner), /decision D-1 owner is invalid/)

  const badDeadline = structuredClone(canonical)
  badDeadline.decisions[0].deadline = '2026-02-30'
  t.exception(() => validateVnextProgramState(badDeadline), /decision D-1 deadline is invalid/)

  const resolvedWithoutDeadline = structuredClone(canonical)
  Object.assign(resolvedWithoutDeadline.decisions[0], {
    status: 'approved',
    selected: 'approve-direct-g2s-canary',
    rationale: 'The owner accepted the bounded G2-S invitation canary and its disclosed residuals.',
    evidence: ['decisions/D-1.signed.json']
  })
  t.exception(() => validateVnextProgramState(resolvedWithoutDeadline), /requires its decision deadline/)

  const missingBoundary = structuredClone(canonical)
  missingBoundary.decisions[0].affectedProfiles = []
  t.exception(() => validateVnextProgramState(missingBoundary), /affectedProfiles are invalid/)
})

test('vNext program state rejects evidence-free completion and promotion', (t) => {
  const gate = structuredClone(canonical)
  gate.gates[0].status = 'passed'
  gate.gates[0].evidence = []
  t.exception(() => validateVnextProgramState(gate), /passed gate PG-0 requires evidence/)

  const track = structuredClone(canonical)
  track.tracks[0].status = 'completed'
  track.tracks[0].handoffs = []
  t.exception(() => validateVnextProgramState(track), /completed track T00 requires a handoff/)
})

test('vNext program state rejects missing ids, unsafe evidence, and baseline drift', (t) => {
  const missing = structuredClone(canonical)
  missing.gates.pop()
  t.exception(() => validateVnextProgramState(missing), /gates must contain exactly/)

  const unsafe = structuredClone(canonical)
  unsafe.gates[0].evidence.push('../invented.json')
  t.exception(() => validateVnextProgramState(unsafe), /unsafe reference/)

  const drift = structuredClone(canonical)
  drift.releaseTrain.artifactBaseline.commit = 'a'.repeat(40)
  drift.releaseTrain.artifactBaseline.tag = 'v0.24.2'
  t.exception(() => validateVnextProgramState(drift), /artifact baseline tag/)
})