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
50 changes: 23 additions & 27 deletions src/scripts/discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,10 @@ const CONTRACT_SCHEMA_VERSION = '1.0.0';
/* Three committed goals — a structured Spec-113 target + starting facts each.
No natural language: the target is an exact capability identity. */
const GOALS = [
{
id: 'coverage',
label: 'Score the uncertainty of a reporting period',
blurb: 'Target: uncertainty.score. Facts: a partial coverage state with two included and one pending reference.',
kind: 'chain',
target: { capability_id: 'uncertainty.score', capability_version: '1.1.0' },
candidate_refs: [
{ namespace: 'summary', id: 'summary.aggregate', versionRange: '1.1.0' },
{ namespace: 'uncertainty', id: 'uncertainty.score', versionRange: '1.1.0' },
],
starting_facts: {
coverage_state: 'partial',
period_key: '2026-08-17',
scope_id: 'golden-bc',
policy: { version: 'policy-1' },
},
},
{
id: 'price',
label: 'Price a small quote',
blurb: 'Target: core.calculate-price. Facts: one line item, a versioned pricing config.',
label: 'Price a quote',
blurb: 'One line item, two units at $50, a versioned pricing config with no discounts or tax — target core.calculate-price.',
kind: 'single',
target: { capability_id: 'core.calculate-price', capability_version: '1.2.0' },
candidate_refs: [
Expand All @@ -56,16 +39,29 @@ const GOALS = [
},
},
{
id: 'noplan',
label: 'A goal with no structural path',
blurb: 'Target: core.calculate-price. Facts: only a currency — nothing produces the line items or pricing config it needs.',
kind: 'none',
target: { capability_id: 'core.calculate-price', capability_version: '1.2.0' },
id: 'docapproval',
label: 'Review a document for approval',
blurb: 'From the document text alone the planner chains doc-approval.analyze (extract type, parties, amounts, a confidence) into doc-approval.recommend (approve or route, with a rationale).',
kind: 'chain',
target: { capability_id: 'doc-approval.recommend', capability_version: '1.4.0' },
candidate_refs: [
{ namespace: 'core', id: 'core.calculate-price', versionRange: '1.2.0' },
{ namespace: 'summary', id: 'summary.aggregate', versionRange: '1.1.0' },
{ namespace: 'doc-approval', id: 'doc-approval.analyze', versionRange: '1.4.0' },
{ namespace: 'doc-approval', id: 'doc-approval.recommend', versionRange: '1.4.0' },
],
starting_facts: {
document: 'INVOICE\nVendor: Acme Corp\nBill to: Globex Industries\nInvoice #: AC-20481\nTotal due: $4,200.00\nDue date: 2026-10-01\nTerms: Net 30',
},
},
{
id: 'luhn',
label: 'Check a card number',
blurb: 'Does a 16-digit number pass the Luhn checksum? Facts: one number string — target validation.validate-luhn.',
kind: 'single',
target: { capability_id: 'validation.validate-luhn', capability_version: '1.2.0' },
candidate_refs: [
{ namespace: 'validation', id: 'validation.validate-luhn', versionRange: '1.2.0' },
],
starting_facts: { currency: 'USD' },
starting_facts: { number: '4242424242424242' },
},
];

Expand Down
25 changes: 16 additions & 9 deletions tests/e2e/discover.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ test('goal 1 auto-plans on load, then review + execute for real against the live

// Auto-run to the review gate.
await expect(page.locator('#discover-badge')).toHaveText('Planned — review the mappings', { timeout: 45_000 });
await expect(page.locator('#discover-plan-target')).toHaveText('uncertainty.score@1.1.0');
await expect(page.locator('#discover-plan-target')).toHaveText('core.calculate-price@1.2.0');
await expect(page.locator('#discover-plan-mappings')).toContainText('unconfirmed');
await expect(page.locator('#discover-stats')).toContainText('namespaces');

Expand All @@ -16,19 +16,26 @@ test('goal 1 auto-plans on load, then review + execute for real against the live
await expect(page.locator('#discover-badge')).toHaveText('Executed — real, offline, governed', { timeout: 45_000 });
await expect(page.locator('#discover-result')).toHaveAttribute('data-outcome', 'executed');
await expect(page.locator('#discover-trace')).toContainText('terminal: succeeded');
await expect(page.locator('#discover-trace')).toContainText('uncertainty.score@1.1.0');
await expect(page.locator('#discover-trace')).toContainText('core.calculate-price@1.2.0');
await expect(page.locator('#discover-log')).toContainText('executed offline in your browser');
});

test('the no-structural-path goal returns "no plan" as a real outcome, not an error', async ({ page }) => {
test('a single-capability goal (card checksum) plans and executes for real', async ({ page }) => {
test.slow();
await page.goto('/discover.html');
await expect(page.locator('#discover-badge')).toHaveText('Planned — review the mappings', { timeout: 45_000 });

await page.locator('.discover-goal[data-goal="noplan"]').click();
await expect(page.locator('#discover-badge')).toHaveText('No plan — the goal has no structural path', { timeout: 45_000 });
await expect(page.locator('#discover-result')).toHaveAttribute('data-outcome', 'noplan');
await expect(page.locator('#discover-plan-mappings')).toContainText('No structural candidate');
await expect(page.locator('#discover-exec')).toBeHidden();
await expect(page.locator('#discover-log')).toContainText('0 candidates');
await page.locator('.discover-goal[data-goal="luhn"]').click();
await expect(page.locator('#discover-plan-target')).toHaveText('validation.validate-luhn@1.2.0', { timeout: 45_000 });
await expect(page.locator('#discover-badge')).toHaveText('Planned — review the mappings');

await page.locator('#discover-exec').click();
await expect(page.locator('#discover-badge')).toHaveText('Executed — real, offline, governed', { timeout: 45_000 });
await expect(page.locator('#discover-trace')).toContainText('terminal: succeeded');
await expect(page.locator('#discover-trace')).toContainText('validation.validate-luhn@1.2.0');
});

// The "Review a document for approval" goal (doc-approval.analyze -> doc-approval.recommend)
// plans today but only *executes* once doc-approval.analyze@1.4.0 / recommend@1.4.0 land
// on the live catalog with a pure_read risk class (traverse-framework/registry#424, #425).
// Add its plan+execute spec once those merge.
Loading