From 469c63fb951397055c8ae416ed34d00d93767a34 Mon Sep 17 00:00:00 2001 From: Croissant Le Doux Date: Wed, 8 Jul 2026 23:07:21 -0400 Subject: [PATCH] test: verify record_directive end-to-end + label the ledger in the activity line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pm-state repo now exists, so the last unverified path is proven: Reginald records a directive to the real ledger. - chat panel: the "consulted" activity line names record_directive as "the directive ledger" (matching query_project → the project, propose_change → the labels). - live-directive e2e (gated): a directive typed in chat → Reginald logs it and says "recorded", consulting the directive ledger. Verified live against gemma-4-26b + the commitea-pm-state repo: "freeze scope for beta, pilots come first" appended to directives/log.jsonl as {kind: scope, quote: , status: accepted} — logged, never claimed applied. Reginald is now complete and every tool is verified end-to-end. Co-Authored-By: Claude Opus 4.8 (1M context) --- apps/desktop/e2e/live-directive.spec.ts | 32 +++++++++++++++++++ .../src/components/shell/chat-panel.tsx | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 apps/desktop/e2e/live-directive.spec.ts diff --git a/apps/desktop/e2e/live-directive.spec.ts b/apps/desktop/e2e/live-directive.spec.ts new file mode 100644 index 0000000..ba74bb0 --- /dev/null +++ b/apps/desktop/e2e/live-directive.spec.ts @@ -0,0 +1,32 @@ +import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' + +import { _electron as electron, expect, test } from '@playwright/test' + +const here = dirname(fileURLToPath(import.meta.url)) +const MAIN = join(here, '..', 'out', 'main', 'index.js') + +// Opt-in (GITEA_LIVE=1 + COMMITEA_MODEL_LIVE=1 + a local model + the commitea-pm-state +// repo). Reginald records a standing directive; it's appended to the real pm-state +// ledger. The append is idempotent-ish (a fresh line each run); this only reads back +// that a directive was consulted, and leaves the ledger intact. +test.describe('live record_directive', () => { + test('logs a standing directive to the pm-state ledger', async () => { + test.skip(!process.env.GITEA_LIVE || !process.env.COMMITEA_MODEL_LIVE, 'live model test — opt-in') + test.setTimeout(300_000) + const app = await electron.launch({ args: [MAIN], env: { ...process.env } }) + const win = await app.firstWindow() + await win.waitForLoadState('domcontentloaded') + await expect(win.getByText(/· local$/)).toBeVisible({ timeout: 20000 }) + + const composer = win.getByPlaceholder(/Tell me what to do/) + await composer.fill('Record a standing directive: freeze scope for beta, pilots come first.') + await composer.press('Enter') + + // the agent logged it to the ledger (record_directive), not applied a change + await expect(win.getByText(/consulted the directive ledger/)).toBeVisible({ timeout: 240_000 }) + await win.screenshot({ path: join(here, '.artifacts', 'screens', 'live-directive.png'), fullPage: true, animations: 'disabled' }) + + await app.close() + }) +}) diff --git a/apps/desktop/src/renderer/src/components/shell/chat-panel.tsx b/apps/desktop/src/renderer/src/components/shell/chat-panel.tsx index f50737f..ca4bd6e 100644 --- a/apps/desktop/src/renderer/src/components/shell/chat-panel.tsx +++ b/apps/desktop/src/renderer/src/components/shell/chat-panel.tsx @@ -101,7 +101,7 @@ export function ChatPanel({ onOpenDirectives, offline, onApplyChange }: ChatPane {thinking ?
considering…
: null} {!thinking && steps.length ? (
- consulted {Array.from(new Set(steps.map((s) => s.replace('query_project', 'the project').replace('propose_change', 'the labels')))).join(', ')} + consulted {Array.from(new Set(steps.map((s) => s.replace('query_project', 'the project').replace('propose_change', 'the labels').replace('record_directive', 'the directive ledger')))).join(', ')}
) : null} {proposals.map((p) => (