Skip to content
Merged
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
1 change: 1 addition & 0 deletions docs/LESSON.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@
- The reference repo also reports that `requestReviewsByLogin` can succeed (returning `clientMutationId: null`) while the resulting `reviewRequests` collection stays empty, treated as an API-side regression. Workaround: request Copilot review manually from the PR sidebar Reviewers menu. **Do not silently skip review** — record the blocker in `docs/PROGRESS.md` instead.
- Bun + TypeScript ESM + strict + `noUncheckedIndexedAccess` is the chosen baseline. Some libraries still ship CJS-only types; pin a `tsconfig.json` per-package when a CJS dep forces module interop relaxation, never relax it globally.
- For Bun workspaces, the root `package.json` uses `"workspaces": ["packages/*", "packs/*"]`. `bun install` from root installs all workspaces. `bun --filter <name> <script>` runs a script in a single workspace. `bunx -p <pkg> <bin>` runs a binary from a specific package version.
- **Live admin e2e against local API needs CORS + chain-order normalization.** When the admin Vite dev server (`:5173`) targets a separate local API origin, the test bridge must emit `Access-Control-Allow-*` headers or the UI silently falls back to mock mode. Also, `MemoryStore.listAuditEvents()` returns newest-first; the AuditChainViewer verify flow expects chronological chain order. For live smoke stability, normalize `/api/audit` response to ascending `seq` before feeding the viewer.

## v1.5 — Admin design integration lessons (2026-05-18)

Expand Down
2 changes: 2 additions & 0 deletions docs/PROGRESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

## 2026-05-20

- **v1.x roadmap closure completed.** Added a dedicated ecosystem Playwright smoke (`packages/admin/test/e2e/ecosystem-live.e2e.ts`) with a single-command stack bootstrap (`scripts/ecosystem-stack.mjs`) that boots `examples/bun-api`, runs a real `aqa run --profile smoke`, serves live `/api/*` from `@aqa/server.makeApi` + `MemoryStore`, and drives the admin against that live backend (`VITE_AQA_SERVER_URL`). The test asserts `finding_emitted` is visible from live `/api/audit` data and that chain verification returns `CHAIN OK`. Command: `bun run e2e:ecosystem`.
- **Docs/progress alignment closed for v1.x.** The previous "in progress/deferred" notes for the v1.6→v1.8 follow-ups are now materially closed in code and release artifacts (`v1.8.2` published). Historical bullets below remain as timeline context; current operational status is: no open PRs, no open issues, ecosystem smoke present and green.
- **v1.8.2 slice closed — CLI smoke now runs a real HTTP end-to-end path.** `scripts/e2e-cli.mjs` no longer stops at version/help/doctor/validate only: it now boots a local HTTP `/healthz` target, seeds a schema-valid local smoke pack/profile, executes `aqa run --profile smoke` with the real HTTP probe runner, and asserts run artifacts are emitted under `.aqa/runs/<run-id>/` (`events.jsonl` non-empty, `findings.jsonl` present). This closes the old “CLI smoke is command-only” gap and makes CI catch integration regressions earlier.
- **v1.8.1 slice closed — audit-chain canonical reconciliation.** Aligned `@aqa/compliance.verifyEventChain` with `@aqa/runner.EventChainWriter`: hash recomputation now excludes `prev_hash` from canonical body (matches writer), and first-record `prev_hash: null` is now treated as canonical instead of expecting all-zero literal in the field. Updated compliance tests and removed stale divergence note in `@aqa/kit` run smoke tests.
- **v1.x docs closure in progress — README/docs refresh pass started.** Removed stale preview/stub wording from README, added the new **How you use it** section after the 7-word model, updated quick-start flow to the current shipped commands (including admin panel boot), and aligned `PACK-AUTHORING.md` with the real HTTP probe runner now shipped in v1.8 (`aqa run` uses `project.sut.base_url` for `http` probes).
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"build": "node scripts/run-workspace-script.mjs build",
"clean": "node scripts/run-workspace-script.mjs clean",
"e2e": "node scripts/run-tool.mjs playwright test",
"e2e:ecosystem": "bun --filter @aqa/admin test:e2e:ecosystem",
"e2e:install": "node scripts/run-tool.mjs playwright install --with-deps chromium",
"docs:linkcheck": "node scripts/run-tool.mjs markdown-link-check '**/*.md' --quiet",
"prepare": "node -e \"\""
Expand Down
1 change: 1 addition & 0 deletions packages/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"preview": "vite preview",
"test": "node -e \"console.log('[@aqa/admin] no unit tests; e2e suite under test:e2e (Playwright).')\"",
"test:e2e": "playwright test --reporter=line",
"test:e2e:ecosystem": "playwright test -c playwright.ecosystem.config.ts --reporter=line",
"test:e2e:headed": "playwright test --headed",
"test:install-browsers": "playwright install --with-deps chromium",
"clean": "node --input-type=module -e \"import { rmSync } from 'node:fs'; for (const p of ['dist','.tsbuildinfo','node_modules/.vite','playwright-report','test-results']) { try { rmSync(p, { recursive: true, force: true }); } catch {} }\""
Expand Down
1 change: 1 addition & 0 deletions packages/admin/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default defineConfig({
// monorepo's bun-test runner doesn't try to execute these — bun's
// built-in glob picks up `*.{test,spec}.ts`.
testMatch: ['**/*.e2e.ts'],
testIgnore: ['**/ecosystem-live.e2e.ts'],
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
Expand Down
26 changes: 26 additions & 0 deletions packages/admin/playwright.ecosystem.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
testDir: './test/e2e',
testMatch: ['**/ecosystem-live.e2e.ts'],
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
workers: 2,
reporter: process.env.CI ? [['line'], ['html', { open: 'never' }]] : 'list',
use: {
baseURL: 'http://127.0.0.1:5174',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [{ name: 'chromium', use: { ...devices['Desktop Chrome'] } }],
webServer: {
command: 'node scripts/ecosystem-stack.mjs',
cwd: '../..',
url: 'http://127.0.0.1:5174',
reuseExistingServer: false,
timeout: 180_000,
stdout: 'pipe',
},
});
22 changes: 22 additions & 0 deletions packages/admin/test/e2e/ecosystem-live.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { expect, test } from '@playwright/test';
import type { Page } from '@playwright/test';

function nav(page: Page, label: string) {
const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return page.locator('.nav-item', { hasText: new RegExp(`^${escaped}`, 'i') }).first();
}

test('ecosystem live: finding_emitted is visible in live audit and chain verifies', async ({
page,
}) => {
await page.goto('/');
await nav(page, 'Audit log').click();
await expect(page.locator('.page-title, h1').first()).toContainText(/Audit/i);
await expect(page.getByText(/Event timeline/i)).toBeVisible({ timeout: 15_000 });
await expect(page.getByText(/finding_emitted/i)).toBeVisible({ timeout: 15_000 });
await page
.getByRole('button', { name: /^Verify( chain)?$/i })
.first()
.click();
await expect(page.getByRole('heading', { name: /CHAIN OK/i })).toBeVisible({ timeout: 15_000 });
});
Loading
Loading