diff --git a/default/skills/alice-workspace/SKILL.md b/default/skills/alice-workspace/SKILL.md index 9bcf0817c..30acabca0 100644 --- a/default/skills/alice-workspace/SKILL.md +++ b/default/skills/alice-workspace/SKILL.md @@ -58,13 +58,17 @@ alice-workspace conversation ask --inbox-id \ # Recruit a fresh Session in a Harness default Workspace. alice-workspace conversation ask --harness autoquant \ --prompt 'Start a new quantitative research assignment.' + +alice-workspace conversation ask --harness prediction \ + --prompt 'Investigate this prediction-market contract relationship and return evidence.' ``` `--harness chat` follows the recent/default Chat desk policy and creates the stable starter Chat Workspace only when none exists. `--harness autoquant` requires the explicitly initialized AutoQuant default Workspace and never -creates or guesses one. Both launch a fresh product Session in the resolved -desk; use the returned `resumeId` for later continuation. +creates or guesses one. `--harness prediction` follows the same initialized- +default rule for the Auto Prediction desk. All three launch a fresh product +Session in the resolved desk; use the returned `resumeId` for later continuation. Prompts are ordinary coworker messages. Add `--reconstruct` only when the task explicitly requires a fresh worker to reconstruct missing historical intent. diff --git a/default/skills/delegate-prediction/SKILL.md b/default/skills/delegate-prediction/SKILL.md new file mode 100644 index 000000000..12969883c --- /dev/null +++ b/default/skills/delegate-prediction/SKILL.md @@ -0,0 +1,87 @@ +--- +name: delegate-prediction +description: > + Delegate prediction-market contract and evidence research from a general + Chat Workspace to the durable Auto Prediction desk. Use for cross-venue + settlement comparison, semantic relationship hypotheses, anonymous venue + evidence, deterministic replay, simulation, shadow qualification, or an + Auto Prediction follow-up. Do not use for general news commentary, broker + orders, live execution, or a question Chat can answer directly. +--- + +# Delegate prediction research to Auto Prediction + +Treat Auto Prediction as a specialist coworker, not a probability oracle or a +function call. OpenAlice owns conversation and routing. The Auto Prediction +Agent owns repository orientation, campaign selection, evidence retention, +semantic review, exact payout logic, simulation, and shadow-only qualification. + +## Bound the assignment + +Preserve the caller-owned parts of the question before dispatch: + +- the decision or research question the answer should support; +- named venues, contracts, outcomes, dates, and settlement language when known; +- the proposed relationship, or permission to search an open semantic neighborhood; +- available evidence with source and freshness, including known gaps; +- scope, time or model budget, and the requested handoff. + +Do not convert a quote directly into a world probability, assume differently +worded contracts settle identically, prescribe Auto Prediction's internal CLI +steps, or promise that a hypothesis will survive review. Negative evidence, +falsification, an unsupported venue, or a request for missing contract terms can +be a correct result. + +## Recruit the default desk + +Use the `alice-workspace` collaboration surface: + +```bash +alice-workspace conversation ask --harness prediction --await --prompt ' +Research question: +Decision this supports: +Caller-owned scope: +Available evidence: +Budget and stopping condition: +Expected handoff: answer in plain language; separate world proposition, venue settlement contract, and traded state; name every applicable campaign, finding, review, replay, simulation, or certificate id; give the absolute Workspace root and end with `Primary evidence directory: ` for the retained evidence; report counterexamples, freshness, assumptions, unsupported claims, and the exact no-live-trading boundary. +Ask before proceeding if a missing caller-owned fact would materially change the research. Do not create an artifact solely for transport. +' +``` + +Add `--await` when the current turn needs the answer. For longer delegation, +omit it, retain the returned `taskId`, and use `conversation await`, `read`, or +`collect` as described by the `alice-workspace` skill. There is no unsolicited +Agent-to-Agent completion notification bus. Add `--timeout-ms` only when the +caller chose a real execution watchdog for this assignment. + +If Auto Prediction is not initialized, report that boundary and direct the user +to initialize the Prediction desk. Do not silently substitute Chat research or +guess another Workspace. + +## Consume and continue + +1. Read the returned `assistantText` first. A useful answer may be a retained + hypothesis, falsification, venue boundary, campaign result, review state, or + shadow-only qualification; no single artifact type is mandatory. +2. Require an absolute Workspace root, the primary evidence directory when one + exists, applicable durable ids, evidence provenance and freshness, material + assumptions, counterexamples, and the no-live-trading boundary. +3. If the path or evidence identity is missing, continue the returned Session: + + ```bash + alice-workspace conversation ask --resume-id --await \ + --prompt 'Provide the absolute primary evidence directory and exact durable ids from the completed assignment. Do not rerun the research.' + ``` + +4. Use native Read/Search/Git capabilities on only the returned paths and named + artifacts. Use `alice-workspace peer path --id ` only when the + reported absolute root is unavailable. +5. Continue the same `resumeId` for substantive clarification. Do not recruit a + new Prediction Session and discard the context. +6. Present retained evidence separately from your judgment. A normal attended + reply already reaches the user; use Inbox only when durable human-facing + delivery or asynchronous notification was explicitly requested. + +Auto Prediction has no authority to place a live order, sign a transaction, +approve a token, request production-trading credentials, or move funds. Do not +reinterpret research or shadow evidence as permission to cross that boundary. diff --git a/default/skills/delegate-prediction/agents/openai.yaml b/default/skills/delegate-prediction/agents/openai.yaml new file mode 100644 index 000000000..d27af696d --- /dev/null +++ b/default/skills/delegate-prediction/agents/openai.yaml @@ -0,0 +1,4 @@ +interface: + display_name: "Auto Prediction Coworker" + short_description: "Delegate evidence research to Auto Prediction" + default_prompt: "Use $delegate-prediction to hand this prediction-market research assignment to the Auto Prediction desk." diff --git a/docs/conversation-provenance.md b/docs/conversation-provenance.md index e44187512..d78ebeacb 100644 --- a/docs/conversation-provenance.md +++ b/docs/conversation-provenance.md @@ -611,6 +611,7 @@ alice-workspace conversation ask --issue-id [--ws-id ] -- alice-workspace conversation ask --ws-id --prompt '' alice-workspace conversation ask --harness chat --prompt '' alice-workspace conversation ask --harness autoquant --prompt '' +alice-workspace conversation ask --harness prediction --prompt '' alice-workspace conversation ask --ws-id --prompt '' --reconstruct alice-workspace conversation await --task-id alice-workspace conversation collect --task-id --task-id @@ -629,10 +630,10 @@ alice-workspace issue ask --id --run-id --prompt ' { }) }) + it('gives stale guidance a recovery path when Prediction is not initialized', async () => { + const tool = conversationAskFactory.build(context({ + conversation: { + ask: vi.fn(async () => ({ + status: 'unavailable' as const, + resolution: { mode: 'unavailable' as const, reason: 'prediction-not-initialized' as const }, + })), + read: vi.fn(), + }, + })) + await expect(run(tool, { + prompt: 'Investigate this contract.', harness: 'prediction', + })).resolves.toMatchObject({ + ok: false, + next: expect.stringContaining('retry with --harness prediction'), + }) + }) + it('rejects ambiguous or missing addressing flags', async () => { const tool = conversationAskFactory.build(context({ conversation: { ask: vi.fn(), read: vi.fn() }, @@ -149,7 +167,10 @@ describe('conversation_ask', () => { })) }) - it('addresses a fresh Session through a Harness default', async () => { + it.each([ + ['autoquant', 'Start a new study.'], + ['prediction', 'Investigate this contract relationship.'], + ] as const)('addresses a fresh Session through the %s Harness default', async (harness, prompt) => { const ask = vi.fn(async () => ({ status: 'dispatched' as const, taskId: 'task-1', resumeId: 'resume-fresh', workspaceId: 'ws-aq', @@ -164,12 +185,17 @@ describe('conversation_ask', () => { conversation: { ask, read: vi.fn() }, })) - await run(tool, { prompt: 'Start a new study.', harness: 'autoquant' }) + await run(tool, { prompt, harness }) expect(ask).toHaveBeenCalledWith(expect.objectContaining({ - target: { kind: 'harness', harness: 'autoquant' }, + target: { kind: 'harness', harness }, })) }) + it('advertises Prediction alongside Chat and AutoQuant in live CLI help', () => { + const tool = conversationAskFactory.build(context()) + expect(tool.description).toContain('Chat, AutoQuant, or Prediction desk') + }) + it('passes reconstruction guidance only when explicitly requested', async () => { const ask = vi.fn(async () => ({ status: 'dispatched' as const, diff --git a/src/tool/conversation.ts b/src/tool/conversation.ts index 9fcbaa48f..13ef93e30 100644 --- a/src/tool/conversation.ts +++ b/src/tool/conversation.ts @@ -16,6 +16,16 @@ const MAX_TIMEOUT_MS = 2_147_478_647 const MAX_PROMPT_CHARS = 16_000 const AWAIT_POLL_MS = 250 +function unavailableRecovery(reason: string): string | undefined { + if (reason === 'prediction-not-initialized') { + return 'Open Prediction and initialize the Auto Prediction desk, then retry with --harness prediction.' + } + if (reason === 'autoquant-not-initialized') { + return 'Open Quant and initialize the AutoQuant desk, then retry with --harness autoquant.' + } + return undefined +} + export const conversationAskCommonShape = { prompt: z.string().trim().min(1).max(MAX_PROMPT_CHARS) .describe('Question for the responsible Session or reconstructing worker.'), @@ -101,10 +111,12 @@ export async function askWorkspaceConversation( ...(input.reconstruct ? { reconstruct: true } : {}), }) if (result.status === 'unavailable') { + const next = unavailableRecovery(result.resolution.reason) return { ok: false as const, status: result.status, resolution: { mode: result.resolution.mode, reason: result.resolution.reason }, + ...(next ? { next } : {}), } } const dispatched = { @@ -174,7 +186,7 @@ export const conversationAskFactory: WorkspaceToolFactory = { 'Use exactly one addressing form: resumeId for an exact Session; inboxId for the', 'sender of one delivery; issueId (optionally scoped by wsId) for Issue creation', 'provenance; wsId for a fresh worker in an exact desk; or harness for a fresh', - 'worker in the current default Chat/AutoQuant desk.', + 'worker in the current default Chat, AutoQuant, or Prediction desk.', '', 'Use --await when this turn needs the reply. Without it, the call returns a', 'short taskId immediately for delegated work or several concurrent questions;', diff --git a/src/workspaces/context-injector.spec.ts b/src/workspaces/context-injector.spec.ts index 6d3c28145..3149adda4 100644 --- a/src/workspaces/context-injector.spec.ts +++ b/src/workspaces/context-injector.spec.ts @@ -121,6 +121,21 @@ describe('injectWorkspaceContext — skills', () => { } }); + it('copies the Chat Auto Prediction delegation contract into both discovery paths', async () => { + await injectWorkspaceContext({ + template: makeTemplate({ bundledSkills: ['delegate-prediction'] }), + wsId: 'ws-chat', + dir, + }); + for (const root of ['.claude/skills', '.agents/skills']) { + const skill = await read(`${root}/delegate-prediction/SKILL.md`); + expect(skill).toContain('alice-workspace conversation ask --harness prediction'); + expect(skill).toContain('Primary evidence directory: '); + expect(skill).toContain('Do not rerun the research.'); + expect(skill).toContain('has no authority to place a live order'); + } + }); + it('injects the per-CLI playbooks (alice* + traderhub) for a tool-bearing template', async () => { await injectWorkspaceContext({ template: makeTemplate({ injectTools: true, bundledSkills: ['scan-value-chain'] }), @@ -146,6 +161,7 @@ describe('injectWorkspaceContext — skills', () => { expect(skill).toContain("Coding Agent's native Read/Search/Glob/Git capabilities"); expect(skill).toContain('alice-workspace conversation ask --inbox-id '); expect(skill).toContain('alice-workspace conversation ask --harness autoquant'); + expect(skill).toContain('alice-workspace conversation ask --harness prediction'); expect(skill).not.toContain('peer file-read'); }); diff --git a/src/workspaces/templates/auto-prediction/README.md b/src/workspaces/templates/auto-prediction/README.md index 2c5ab4375..0eda0e8d0 100644 --- a/src/workspaces/templates/auto-prediction/README.md +++ b/src/workspaces/templates/auto-prediction/README.md @@ -1,5 +1,5 @@ --- -version: 0.1.2 +version: 0.1.3 --- # Auto Prediction @@ -14,8 +14,9 @@ venue evidence, develops semantic hypotheses, runs the repository's checks, and maintains research artifacts and local Git history. Auto Prediction owns its SQLite state, campaigns, evidence model, internal workers, and Studio. -OpenAlice supplies native Agent Sessions, collaboration, Inbox, market-data -tools, Workspace lifecycle, and the managed Studio route around the desk. +OpenAlice supplies native Agent Sessions, peer discovery and conversation, +Inbox, market-data tools, Workspace lifecycle, and the managed Studio route +around the desk. OpenAlice supervises only the command declared by `harness.json`; Auto Prediction retains its complete Studio and control-plane ownership. diff --git a/src/workspaces/templates/auto-quant-v2/README.md b/src/workspaces/templates/auto-quant-v2/README.md index eed92e5a5..c46b5834b 100644 --- a/src/workspaces/templates/auto-quant-v2/README.md +++ b/src/workspaces/templates/auto-quant-v2/README.md @@ -1,5 +1,5 @@ --- -version: 1.1.5 +version: 1.1.6 --- # AutoQuant diff --git a/src/workspaces/templates/chat/README.md b/src/workspaces/templates/chat/README.md index 8cb57a556..e220707fd 100644 --- a/src/workspaces/templates/chat/README.md +++ b/src/workspaces/templates/chat/README.md @@ -1,5 +1,5 @@ --- -version: 1.8.5 +version: 1.8.6 --- # Chat @@ -23,7 +23,9 @@ community `opencli` CLI — it will ask before assuming you have it. When an Inbox result or Issue is hard to interpret, the workspace can ask its attributable product Session directly. It can also dispatch several peer questions concurrently, await them server-side, and synthesize the replies -without hand-written sleep loops or leaking runtime-native session ids. +without hand-written sleep loops or leaking runtime-native session ids. The +bundled delegation skills route governed research to the durable AutoQuant or +Auto Prediction desk without making Chat impersonate either specialist. Trading runs through the `alice-uta` CLI against your UTA accounts — orders go through the trading-as-git approval flow. Recurring/headless work runs through diff --git a/src/workspaces/templates/chat/template.json b/src/workspaces/templates/chat/template.json index 23be13636..acc71d978 100644 --- a/src/workspaces/templates/chat/template.json +++ b/src/workspaces/templates/chat/template.json @@ -6,5 +6,5 @@ "injectTools": true, "injectInstructions": true, "upgradeStrategy": "managed-context", - "bundledSkills": ["scan-value-chain", "build-thesis", "sector-rotation", "retrospective", "opencli-reader", "delegate-autoquant"] + "bundledSkills": ["scan-value-chain", "build-thesis", "sector-rotation", "retrospective", "opencli-reader", "delegate-autoquant", "delegate-prediction"] } diff --git a/src/workspaces/workspace-creation.e2e.spec.ts b/src/workspaces/workspace-creation.e2e.spec.ts index e90dbe258..4d06ce762 100644 --- a/src/workspaces/workspace-creation.e2e.spec.ts +++ b/src/workspaces/workspace-creation.e2e.spec.ts @@ -95,7 +95,7 @@ function chatMeta(): TemplateMeta { defaultAgents: ['claude', 'codex'], injectTools: true, injectInstructions: true, - bundledSkills: ['scan-value-chain', 'delegate-autoquant'], + bundledSkills: ['scan-value-chain', 'delegate-autoquant', 'delegate-prediction'], }; } @@ -127,6 +127,8 @@ describe('chat workspace create: bootstrap → inject → commit', () => { '.agents/skills/scan-value-chain/SKILL.md', '.claude/skills/delegate-autoquant/SKILL.md', '.agents/skills/delegate-autoquant/SKILL.md', + '.claude/skills/delegate-prediction/SKILL.md', + '.agents/skills/delegate-prediction/SKILL.md', // per-CLI playbooks injected for every tool-bearing template '.claude/skills/alice/SKILL.md', '.claude/skills/alice-analysis/SKILL.md',