Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions test/ci/datetime-template.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,13 @@ describe('current datetime template contract', () => {
});

it('tells agents to substitute the literal datetime in command examples', () => {
// These strings live in spawn-reference.md after PR #1035 moved spawn templates there.
expect(spawnReference).toContain('<literal CURRENT_DATETIME value from your prompt>');
expect(spawnReference).toContain('Substitute the actual CURRENT_DATETIME value');
// These substitution strings live in coordinator-owned spawn templates. PR #1035
// moved spawn-template details to on-demand reference files, but the Full Spawn
// Template block still lives in squad.agent.md alongside spawn-reference.md and
// after-agent-reference.md. Check across all coordinator-owned templates so the
// assertion is robust to future relocations within that set.
expect(allCoordinatorTemplates).toContain('<literal CURRENT_DATETIME value from your prompt>');
expect(allCoordinatorTemplates).toContain('Substitute the actual CURRENT_DATETIME value');
});

it('keeps Scribe from writing placeholder datetime headings', () => {
Expand Down
38 changes: 29 additions & 9 deletions test/ci/scribe-template.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
* - HARD GATE enforcement is documented (decisions archival ceiling)
* - Decision inbox merge is a numbered step
* - Deduplication is a numbered step
* - A commit step is present
* - A persistence-verification step is present (runtime state backend writes
* are verified via state tools; Scribe never commits mutable squad state)
* - "Never speak to the user." is the final numbered step (Scribe stays invisible)
* - Commit step precedes the "never speak" step
* - Persistence-verification step precedes the "never speak" step
*
* Canonical source: .squad-templates/scribe-charter.md
*
Expand All @@ -18,6 +19,12 @@
* PRE-CHECK / GIT COMMIT section labels (bold headers), which no longer
* exist in the new prose-based charter structure. HEALTH REPORT and the
* archival size thresholds (20KB / 50KB) are still present and tested below.
*
* The runtime-state-backend migration removed the explicit "git commit" step:
* mutable squad state is now persisted through `squad_state_*` tools, and the
* charter explicitly forbids Scribe from committing, switching branches, or
* pushing note refs. The persistence-verification step (squad_state_health +
* state re-reads) replaces the old commit step and is what we now assert.
*/

import { describe, it, expect } from 'vitest';
Expand Down Expand Up @@ -76,10 +83,20 @@ describe('Scribe charter — task structure and HARD GATE enforcement', () => {
expect(hasStep, 'Deduplication must appear on a numbered step line').toBe(true);
});

it('commit step is present', () => {
it('persistence-verification step is present', () => {
const numberedLines = taskBlock.split('\n').filter(l => l.trim().match(/^\d+\./));
const hasStep = numberedLines.some(l => l.includes('Commit'));
expect(hasStep, 'Commit must appear on a numbered step line').toBe(true);
const hasStep = numberedLines.some(l => l.includes('Verify persistence'));
expect(
hasStep,
'Persistence-verification step (runtime state backend) must appear on a numbered step line',
).toBe(true);
});

it('charter forbids Scribe from committing mutable squad state', () => {
expect(
content,
'Charter must explicitly forbid committing/pushing/branch-switching for mutable state',
).toMatch(/Never commit[^.]*mutable squad state/);
});

it('HARD GATE enforcement is documented in the charter', () => {
Expand Down Expand Up @@ -109,11 +126,14 @@ describe('Scribe charter — task structure and HARD GATE enforcement', () => {
).toContain('Never speak to the user');
});

it('commit step precedes "Never speak to the user."', () => {
const commitIndex = taskBlock.indexOf('Commit');
it('persistence-verification step precedes "Never speak to the user."', () => {
const verifyIndex = taskBlock.indexOf('Verify persistence');
const neverSpeakIndex = taskBlock.indexOf('Never speak to the user.');
expect(commitIndex, 'Commit step not found in task block').toBeGreaterThan(-1);
expect(verifyIndex, 'Persistence-verification step not found in task block').toBeGreaterThan(-1);
expect(neverSpeakIndex, '"Never speak to the user." not found in task block').toBeGreaterThan(-1);
expect(commitIndex, 'Commit must precede "Never speak to the user."').toBeLessThan(neverSpeakIndex);
expect(
verifyIndex,
'Persistence-verification step must precede "Never speak to the user."',
).toBeLessThan(neverSpeakIndex);
});
});
Loading