@exaudeus/workrail 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/application/services/enhanced-loop-validator.js +3 -3
- package/dist/application/services/step-output-decoder.d.ts +6 -0
- package/dist/application/services/step-output-decoder.js +49 -0
- package/dist/application/services/validation-engine.d.ts +9 -0
- package/dist/application/services/validation-engine.js +142 -18
- package/dist/application/services/workflow-interpreter.d.ts +1 -1
- package/dist/application/services/workflow-interpreter.js +147 -81
- package/dist/application/services/workflow-service.d.ts +2 -0
- package/dist/application/services/workflow-service.js +3 -3
- package/dist/application/use-cases/validate-step-output.d.ts +2 -0
- package/dist/config/feature-flags.js +1 -1
- package/dist/di/container.js +88 -0
- package/dist/di/tokens.d.ts +16 -0
- package/dist/di/tokens.js +16 -0
- package/dist/domain/execution/state.d.ts +6 -6
- package/dist/domain/workflow-id-policy.d.ts +17 -0
- package/dist/domain/workflow-id-policy.js +57 -0
- package/dist/infrastructure/storage/enhanced-multi-source-workflow-storage.js +33 -6
- package/dist/infrastructure/storage/file-workflow-storage.js +3 -1
- package/dist/infrastructure/storage/schema-validating-workflow-storage.js +13 -8
- package/dist/manifest.json +329 -161
- package/dist/mcp/error-mapper.d.ts +3 -8
- package/dist/mcp/error-mapper.js +41 -19
- package/dist/mcp/handlers/session.js +25 -11
- package/dist/mcp/handlers/v2-execution-helpers.d.ts +99 -0
- package/dist/mcp/handlers/v2-execution-helpers.js +249 -0
- package/dist/mcp/handlers/v2-execution.d.ts +4 -0
- package/dist/mcp/handlers/v2-execution.js +1044 -0
- package/dist/mcp/handlers/v2-workflow.js +21 -16
- package/dist/mcp/handlers/workflow.js +21 -12
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +4 -1
- package/dist/mcp/output-schemas.d.ts +411 -4
- package/dist/mcp/output-schemas.js +57 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +96 -65
- package/dist/mcp/tool-descriptions.js +32 -15
- package/dist/mcp/tools.js +26 -14
- package/dist/mcp/types/tool-description-types.d.ts +1 -1
- package/dist/mcp/types/tool-description-types.js +7 -5
- package/dist/mcp/types.d.ts +40 -3
- package/dist/mcp/types.js +32 -3
- package/dist/mcp/v2/tool-registry.js +16 -1
- package/dist/mcp/v2/tools.d.ts +45 -0
- package/dist/mcp/v2/tools.js +21 -1
- package/dist/mcp/validation/workflow-next-prevalidate.d.ts +2 -3
- package/dist/mcp/validation/workflow-next-prevalidate.js +38 -27
- package/dist/v2/durable-core/constants.d.ts +15 -0
- package/dist/v2/durable-core/constants.js +18 -0
- package/dist/v2/durable-core/domain/ack-advance-append-plan.d.ts +32 -0
- package/dist/v2/durable-core/domain/ack-advance-append-plan.js +95 -0
- package/dist/v2/durable-core/domain/loop-runtime.d.ts +50 -0
- package/dist/v2/durable-core/domain/loop-runtime.js +95 -0
- package/dist/v2/durable-core/domain/notes-markdown.d.ts +4 -0
- package/dist/v2/durable-core/domain/notes-markdown.js +46 -0
- package/dist/v2/durable-core/domain/outputs.d.ts +12 -0
- package/dist/v2/durable-core/domain/outputs.js +18 -0
- package/dist/v2/durable-core/ids/index.d.ts +2 -0
- package/dist/v2/durable-core/ids/index.js +4 -0
- package/dist/v2/durable-core/schemas/compiled-workflow/index.d.ts +100 -6
- package/dist/v2/durable-core/schemas/compiled-workflow/index.js +18 -3
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +113 -113
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.js +11 -10
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +7129 -0
- package/dist/v2/durable-core/schemas/export-bundle/index.js +82 -0
- package/dist/v2/durable-core/schemas/lib/decision-trace-ref.d.ts +80 -0
- package/dist/v2/durable-core/schemas/lib/decision-trace-ref.js +38 -0
- package/dist/v2/durable-core/schemas/lib/dedupe-key.d.ts +8 -0
- package/dist/v2/durable-core/schemas/lib/dedupe-key.js +28 -0
- package/dist/v2/durable-core/schemas/lib/utf8-bounded-string.d.ts +6 -0
- package/dist/v2/durable-core/schemas/lib/utf8-bounded-string.js +12 -0
- package/dist/v2/durable-core/schemas/session/events.d.ts +238 -62
- package/dist/v2/durable-core/schemas/session/events.js +74 -29
- package/dist/v2/durable-core/schemas/session/manifest.d.ts +3 -3
- package/dist/v2/durable-core/schemas/session/manifest.js +6 -1
- package/dist/v2/durable-core/schemas/session/preferences.d.ts +5 -0
- package/dist/v2/durable-core/schemas/session/preferences.js +6 -0
- package/dist/v2/durable-core/schemas/session/session-health.d.ts +3 -0
- package/dist/v2/durable-core/tokens/index.d.ts +2 -1
- package/dist/v2/durable-core/tokens/index.js +4 -4
- package/dist/v2/durable-core/tokens/payloads.d.ts +4 -4
- package/dist/v2/durable-core/tokens/token-codec.d.ts +3 -2
- package/dist/v2/durable-core/tokens/token-codec.js +12 -6
- package/dist/v2/durable-core/tokens/token-signer.d.ts +3 -2
- package/dist/v2/durable-core/tokens/token-signer.js +8 -9
- package/dist/v2/infra/local/base64url/index.d.ts +5 -0
- package/dist/v2/infra/local/base64url/index.js +48 -0
- package/dist/v2/infra/local/fs/index.js +8 -4
- package/dist/v2/infra/local/keyring/index.d.ts +5 -1
- package/dist/v2/infra/local/keyring/index.js +41 -32
- package/dist/v2/infra/local/pinned-workflow-store/index.d.ts +6 -4
- package/dist/v2/infra/local/pinned-workflow-store/index.js +50 -62
- package/dist/v2/infra/local/random-entropy/index.d.ts +4 -0
- package/dist/v2/infra/local/random-entropy/index.js +10 -0
- package/dist/v2/infra/local/session-lock/index.d.ts +3 -1
- package/dist/v2/infra/local/session-lock/index.js +5 -4
- package/dist/v2/infra/local/session-store/index.d.ts +0 -1
- package/dist/v2/infra/local/session-store/index.js +372 -282
- package/dist/v2/infra/local/snapshot-store/index.js +20 -25
- package/dist/v2/infra/local/time-clock/index.d.ts +5 -0
- package/dist/v2/infra/local/time-clock/index.js +12 -0
- package/dist/v2/infra/local/utf8/index.d.ts +5 -0
- package/dist/v2/infra/local/utf8/index.js +12 -0
- package/dist/v2/ports/base64url.port.d.ts +12 -0
- package/dist/v2/ports/base64url.port.js +2 -0
- package/dist/v2/ports/pinned-workflow-store.port.d.ts +3 -3
- package/dist/v2/ports/random-entropy.port.d.ts +3 -0
- package/dist/v2/ports/random-entropy.port.js +2 -0
- package/dist/v2/ports/session-event-log-store.port.d.ts +1 -1
- package/dist/v2/ports/session-lock.port.d.ts +1 -1
- package/dist/v2/ports/time-clock.port.d.ts +4 -0
- package/dist/v2/ports/time-clock.port.js +2 -0
- package/dist/v2/ports/utf8.port.d.ts +3 -0
- package/dist/v2/ports/utf8.port.js +2 -0
- package/dist/v2/projections/node-outputs.js +28 -11
- package/dist/v2/projections/preferences.d.ts +1 -2
- package/dist/v2/projections/preferences.js +11 -4
- package/dist/v2/projections/run-dag.js +40 -28
- package/dist/v2/projections/run-status-signals.d.ts +1 -2
- package/dist/v2/read-only/v1-to-v2-shim.d.ts +6 -1
- package/dist/v2/read-only/v1-to-v2-shim.js +16 -4
- package/dist/v2/usecases/execution-session-gate.d.ts +3 -2
- package/dist/v2/usecases/execution-session-gate.js +81 -85
- package/package.json +4 -1
- package/spec/workflow.schema.json +2 -2
- package/workflows/coding-task-workflow-agentic.json +498 -78
- package/workflows/design-thinking-workflow-autonomous.agentic.json +1 -1
- package/workflows/design-thinking-workflow.json +1 -1
- package/workflows/relocation-workflow-us.json +430 -0
- package/dist/v2/durable-core/tokens/base64url.d.ts +0 -7
- package/dist/v2/durable-core/tokens/base64url.js +0 -16
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"id": "phase-3-ideation-loop",
|
|
111
111
|
"type": "loop",
|
|
112
112
|
"title": "Phase 3: Ideation (4 Rounds)",
|
|
113
|
-
"loop": { "type": "for", "count": 4, "maxIterations":
|
|
113
|
+
"loop": { "type": "for", "count": 4, "maxIterations": 5, "iterationVar": "ideationRound" },
|
|
114
114
|
"body": [
|
|
115
115
|
{
|
|
116
116
|
"id": "ideation-round-1",
|
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "relocation-workflow-us",
|
|
3
|
+
"name": "Relocation Decision Workflow (US v1 — AreaSpec • Custom Areas • Dossier • Evidence • Ranking)",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"description": "A bias-resistant, evidence-driven relocation workflow for the United States. Helps users discover what they care about, generate a broad candidate pool (including optional custom areas), screen it with strict caps, deep-dive shortlisted areas, and produce a master dossier plus per-location profile docs with a transparent, explainable weighted ranking.",
|
|
6
|
+
"preconditions": [
|
|
7
|
+
"User is considering relocation within the United States (v1 scope).",
|
|
8
|
+
"Agent can research the web and/or use user-provided sources.",
|
|
9
|
+
"Agent can write files to maintain a durable paper trail (or paste canonical artifacts if file writing is unavailable)."
|
|
10
|
+
],
|
|
11
|
+
"clarificationPrompts": [
|
|
12
|
+
"Are you relocating within the US only (this v1 workflow), or do you want an international-capable version?",
|
|
13
|
+
"What is your expected timeline to move (0-3 months, 3-12 months, 12+ months)?",
|
|
14
|
+
"What is your household situation (single, couple, family with kids, multi-generational, etc.) and which constraints matter most?",
|
|
15
|
+
"Do you need to consider a specific job market / visa / employer location constraint (even within the US)?",
|
|
16
|
+
"What is your rough budget range (housing, total monthly burn) and are you buying or renting?"
|
|
17
|
+
],
|
|
18
|
+
"metaGuidance": [
|
|
19
|
+
"MISSION: Help the user pick where to move by systematically discovering preferences, researching candidates, and producing an evidence-backed, explainable ranking.",
|
|
20
|
+
"ANTI-ANCHORING: Do not deep-dive a single favorite city early. Generate a broad pool first, then screen, then shortlist, then deep dive.",
|
|
21
|
+
"PAPER TRAIL: Maintain a master dossier and per-location profile docs. Every key claim must be sourced and graded (High/Medium/Low).",
|
|
22
|
+
"DATA VARIANCE: If a metric is unavailable or inconsistent, record it as Unknown and apply the explicit missing-data policy (never silently assume).",
|
|
23
|
+
"BOUNDARIES (CRITICAL): Prevent boundary drift by representing every candidate as an AreaSpec (what exactly the 'area' is). Never switch boundaries mid-run without logging it.",
|
|
24
|
+
"CUSTOM AREAS: v1 supports custom areas via a single custom boundary mode: radius (center + radiusMiles). More precise custom modes can be added later.",
|
|
25
|
+
"SCREENING MUST SCALE: First-pass screening must be intentionally thin (dealbreakers + top criteria only) with strict time/source/claim caps. Deep dives are where detail lives.",
|
|
26
|
+
"BRANCHING: Keep this workflow generic via lightweight modules (kids/schools, commute, transit, climate risk, etc.) rather than rigid personas.",
|
|
27
|
+
"OUTPUT SHAPE: One master dossier + one profile doc per shortlisted candidate. Keep formatting consistent to enable side-by-side comparison.",
|
|
28
|
+
"QUALITY GATES: Require user confirmation at criteria lock-in, shortlist selection, and final ranking."
|
|
29
|
+
],
|
|
30
|
+
"functionDefinitions": [
|
|
31
|
+
{
|
|
32
|
+
"name": "writeOrPasteArtifact",
|
|
33
|
+
"definition": "When a step requires a durable artifact, attempt to write/update the file(s). If file writing is unavailable, output the full pasteable content in chat and treat that as canonical."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "captureCheckpoint",
|
|
37
|
+
"definition": "Append a 'Machine State Checkpoint' entry to `RELOCATION_DOSSIER.md` that is BOTH human-meaningful and machine-resumable.\n\nRequired fields:\n- timestamp (ISO)\n- lastCompletedStepId\n- missingDataPolicy\n- weights summary (top 3 criteria + weights)\n- candidatePoolCount, nonObviousCandidateCount, shortlistCount\n- unresolved unknowns summary (1–3 bullets)\n\nDeterministic resume payload (non-optional):\n- Paste the raw `response.state` object from the latest `workflow_next` call\n- Paste the raw `response.next.stepInstanceId` object from the latest `workflow_next` call\n\nRules:\n- Keep the last 3 checkpoints only (delete older)\n- Do not stringify the JSON objects (paste as objects)\n- If you cannot write the file: paste the full updated section in chat and treat it as canonical."
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"name": "trackClaim",
|
|
41
|
+
"definition": "For each important statement about a location (cost, taxes, schools, crime, climate, job market, etc.), record: claim, source (URL or citation), retrievedAt (date), and confidenceGrade (High/Medium/Low). If unsure, grade Low."
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "areaSpec",
|
|
45
|
+
"definition": "Represent the exact boundary of a candidate deterministically using an AreaSpec.\n\nAreaSpec fields (v1):\n- areaId: stable slug for the run (derive from candidateType + displayName + stateCodes; keep consistent)\n- displayName: human-friendly\n- candidateType: metro|city|county|custom\n- region: freeform (e.g., \"New England\", \"Mid-Atlantic\", \"Southeast\")\n- stateCodes: string[] (required)\n\nBoundary definition (by candidateType):\n- metro: { metroName: string, states: string[], definitionSource: string }\n- city: { cityName: string, stateCode: string }\n- county: { countyName: string, stateCode: string, fips?: string }\n- custom (v1 mode): { mode: \"radius\", center: { place: string, stateCode: string }, radiusMiles: number }\n\nRule: No candidate may enter candidatePool without an AreaSpec."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "normalizeCandidate",
|
|
49
|
+
"definition": "Represent each candidate consistently using: { areaId, name, region, candidateType (metro/city/county/custom), areaSpec, whyIncluded, dealbreakersPassed, unknowns, notes }.\n\n- name should match areaSpec.displayName\n- areaId must be stable (do not change mid-run)\n- unknowns is a short list of unresolved questions (strings)"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "defineNonObvious",
|
|
53
|
+
"definition": "A candidate is 'non-obvious' if:\n- It is NOT in `userTopOfMind`, AND\n- It is NOT in the top-N most populous US metros list used for this run (N default 20).\n\nCustom/city/county candidates: if the candidate's displayName contains or is anchored to a top-N metro/city name, treat it as obvious.\n\nRecord the top-N list source and N in the dossier."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "missingDataPolicy",
|
|
57
|
+
"definition": "Explicitly choose how Unknown affects scoring: neutral, penalize, or followup_required. Apply consistently across all candidates and explain the choice in the dossier."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"name": "antiAnchoringGate",
|
|
61
|
+
"definition": "Do not proceed to deep dives unless candidatePoolCount >= minCandidatePool AND nonObviousCandidateCount >= minNonObviousCandidates. If not met, expand the pool first."
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
"steps": [
|
|
65
|
+
{
|
|
66
|
+
"id": "phase-0-scope-and-artifacts",
|
|
67
|
+
"title": "Phase 0: Scope, Modules, and Paper-Trail Artifacts",
|
|
68
|
+
"prompt": "Establish scope, modules, and artifact structure.\n\n1) Confirm v1 scope: US-only relocation.\n2) Capture top-of-mind list (optional): ask the user for `userTopOfMind` (0–10 areas).\n3) Determine user context and activate lightweight modules (select all that apply):\n - kids/schools\n - commute\n - transit\n - climate risk\n - healthcare access\n - career/job market\n - outdoors\n - nightlife/arts\n - safety\n - taxes\n - diversity/community\n - disability accessibility\n\n4) Define primary search granularity for this run (set `candidateType`):\n - Default: metro\n - Optional: city, county, custom\n\n5) Custom areas (v1):\n - Set `customAreaMode = radius`\n - Custom AreaSpec format: center (place+stateCode) + radiusMiles\n\n6) Initialize artifacts (write-or-paste):\n - Master dossier: `RELOCATION_DOSSIER.md`\n - Profiles directory: `relocation-profiles/`\n - Profile naming: `relocation-profiles/<candidate-slug>.md`\n\nIn the dossier, create these sections:\n- User Context & Modules\n- Boundary & Definitions\n- Aggregation & Comparability Policy\n- Preferences (Draft)\n- Constraints & Dealbreakers\n- Missing Data Policy\n- Sources Strategy\n- Candidate Pool (Breadth)\n- Screened Candidates\n- Screening Claims Ledger\n- Shortlist\n- Profiles Index\n- Comparison & Ranking\n- Machine State Checkpoints\n- Decision Log (append-only)\n\n**Set context variables (required):**\n- activeModules: string[]\n- candidateType: metro|city|county|custom\n- customAreaMode: radius\n- userTopOfMind: string[] (empty array allowed)\n\nOutput (in chat):\n- activeModules\n- candidateType\n- customAreaMode\n- userTopOfMind\n- Artifact paths created\n\nThen ask user to confirm modules + candidateType before proceeding.",
|
|
69
|
+
"agentRole": "You are a relocation workflow coordinator. Create structure first, then proceed systematically.",
|
|
70
|
+
"validationCriteria": [
|
|
71
|
+
{
|
|
72
|
+
"type": "contains",
|
|
73
|
+
"value": "activeModules",
|
|
74
|
+
"message": "Must set activeModules"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"type": "contains",
|
|
78
|
+
"value": "candidateType",
|
|
79
|
+
"message": "Must set candidateType"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"type": "contains",
|
|
83
|
+
"value": "customAreaMode",
|
|
84
|
+
"message": "Must set customAreaMode"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"type": "contains",
|
|
88
|
+
"value": "userTopOfMind",
|
|
89
|
+
"message": "Must set userTopOfMind (can be empty)"
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
"requireConfirmation": true
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"id": "phase-0b-area-model-and-boundary-rules",
|
|
96
|
+
"title": "Phase 0b: Area Model & Boundary Rules (Prevent Boundary Drift)",
|
|
97
|
+
"prompt": "Lock in how candidates are defined so research and scoring are comparable.\n\n1) Define and record the AreaSpec model (use the `areaSpec()` definition).\n2) Confirm custom boundary mode (v1): `customAreaMode = radius`.\n3) Define deterministic Area ID rules (record in dossier):\n - areaId = <candidateType>-<slug(displayName)>-<sortedStateCodes>\n - Example: metro-raleigh-durham-nc\n4) Define boundary resolution rules:\n - For metro: explicitly treat as the metro area (not just the city). Record the metro definition source.\n - For city/county: record state code, and FIPS if found.\n - For custom radius: record center + radiusMiles; do not silently expand.\n\nUpdate `RELOCATION_DOSSIER.md`:\n- Boundary & Definitions (AreaSpec rules + areaId rules)\n- Aggregation & Comparability Policy (v1):\n - Prefer narrative + explicit Unknowns over false precision\n - For custom areas, allow proxy/aggregate only if clearly labeled; otherwise Unknown\n\n**Set context variables (required):**\n- areaIdRule: <string>\n\nOutput (in chat):\n- areaIdRule\n- Confirmation request: proceed with these boundary rules?",
|
|
98
|
+
"agentRole": "You are a boundary discipline enforcer. Make area definitions explicit and stable.",
|
|
99
|
+
"validationCriteria": [
|
|
100
|
+
{ "type": "contains", "value": "areaIdRule", "message": "Must set areaIdRule" },
|
|
101
|
+
{ "type": "regex", "pattern": "customAreaMode:\\s*radius", "message": "customAreaMode must be radius for v1" }
|
|
102
|
+
],
|
|
103
|
+
"requireConfirmation": true
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "phase-1-preference-discovery",
|
|
107
|
+
"title": "Phase 1: Preference Discovery (Draft) + Calibration Setup",
|
|
108
|
+
"prompt": "Discover what the user cares about before searching.\n\n1) Gather constraints:\n- Hard constraints (must-have): geography constraints, climate constraints, max budget, job constraints, family constraints, health constraints.\n- Anti-goals (explicit non-goals).\n- Timeline.\n\n2) Draft preferences as:\n- Dealbreakers\n- Strong preferences\n- Mild preferences\n\n3) Create an initial weight model (draft) across the activated modules:\n- Pick top 6–10 criteria.\n- Assign weights (sum to 100).\n\n**Required output format (exact keys):**\n- weights: [{ criterion: string, weight: number }]\n- weightsCount: <number>\n- weightsSumCheck: 100\n\n4) Update `RELOCATION_DOSSIER.md`:\n- Fill Preferences (Draft)\n- Fill Constraints & Dealbreakers\n- Add initial Weight Model (Draft)\n\nKeep it generic: prefer questions about tradeoffs (e.g., \"Would you trade smaller home for better walkability?\").\n\nOutput: Draft preferences + a short list of open questions (max 5).",
|
|
109
|
+
"agentRole": "You are a facilitator eliciting preferences through tradeoffs and constraints.",
|
|
110
|
+
"validationCriteria": [
|
|
111
|
+
{
|
|
112
|
+
"type": "contains",
|
|
113
|
+
"value": "weights:",
|
|
114
|
+
"message": "Must output weights array"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"type": "regex",
|
|
118
|
+
"pattern": "weightsCount:\\s*(6|7|8|9|10)",
|
|
119
|
+
"message": "weightsCount must be 6–10"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"type": "regex",
|
|
123
|
+
"pattern": "weightsSumCheck:\\s*100",
|
|
124
|
+
"message": "weightsSumCheck must be 100"
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"requireConfirmation": false
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "phase-1b-calibration-deck",
|
|
131
|
+
"title": "Phase 1b: Preference Calibration Deck (Anti-Anchoring)",
|
|
132
|
+
"prompt": "Generate a calibration deck of 8–12 diverse US location archetypes (not specific cities yet). Examples: dense transit metro, college town, mountain small city, coastal mid-size, sunbelt suburb, rust-belt revival city, DC-adjacent, etc.\n\nFor each archetype:\n- 2–3 sentences describing lifestyle and typical tradeoffs\n- Who it fits / who it frustrates\n- What it implies about the weight model\n\nAsk user to:\n- Rank top 3 and bottom 3 archetypes\n- Name 1–2 surprises (\"I didn't expect to like...\")\n\nThen update `RELOCATION_DOSSIER.md`:\n- Add Calibration Findings (what changed in preferences)\n- Revise the Weight Model accordingly\n\n**Required output format (exact keys):**\n- calibrationTop3: [string, string, string]\n- calibrationBottom3: [string, string, string]\n- weightsDeltaSummary: [1–5 bullets]\n- weights: [{ criterion: string, weight: number }]\n\nOutput: Updated weight model and what changed because of calibration.",
|
|
133
|
+
"agentRole": "You are an anti-anchoring specialist. Use diversity to reveal latent preferences.",
|
|
134
|
+
"validationCriteria": [
|
|
135
|
+
{
|
|
136
|
+
"type": "contains",
|
|
137
|
+
"value": "calibrationTop3",
|
|
138
|
+
"message": "Must output calibrationTop3"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"type": "contains",
|
|
142
|
+
"value": "calibrationBottom3",
|
|
143
|
+
"message": "Must output calibrationBottom3"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"type": "contains",
|
|
147
|
+
"value": "weightsDeltaSummary",
|
|
148
|
+
"message": "Must output weightsDeltaSummary"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"type": "contains",
|
|
152
|
+
"value": "weights:",
|
|
153
|
+
"message": "Must output updated weights array"
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"requireConfirmation": true
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"id": "phase-2-policy-and-gates",
|
|
160
|
+
"title": "Phase 2: Missing-Data Policy + Gates (Lock-In)",
|
|
161
|
+
"prompt": "Lock in the decision mechanics before researching candidates.\n\n1) Choose a Missing Data Policy (must be explicit) and record it as `missingDataPolicy`:\n- neutral\n- penalize\n- followup_required\n\n2) Define anti-anchoring gate parameters:\n- minCandidatePool (default 20)\n- minNonObviousCandidates (default 6)\n\n3) Define shortlist range:\n- shortlistMin (default 8)\n- shortlistMax (default 12)\n\n4) Define screening caps (to keep Phase 4 scalable):\n- screeningTopCriteriaCount (default 3) // screen only dealbreakers + top N weighted criteria\n- screeningMaxClaimsPerCandidate (default 3)\n- screeningMaxSourcesPerClaim (default 1)\n- screeningTimeboxMinutesPerCandidate (default 5)\n\n5) Define screening batching (to avoid huge loop iteration limits):\n- screeningBatchSize (default 10)\n\n6) Update `RELOCATION_DOSSIER.md`:\n- Missing Data Policy\n- Anti-Anchoring Gate\n- Shortlist Size Target\n- Screening Caps\n- Screening Batching\n\n**Required output format (exact keys):**\n- missingDataPolicy: neutral|penalize|followup_required\n- minCandidatePool: <number>\n- minNonObviousCandidates: <number>\n- shortlistMin: <number>\n- shortlistMax: <number>\n- screeningTopCriteriaCount: <number>\n- screeningMaxClaimsPerCandidate: <number>\n- screeningTimeboxMinutesPerCandidate: <number>\n- screeningBatchSize: <number>\n- shortlistRangeCheck: ok\n\nAsk user to confirm these policies before proceeding.",
|
|
162
|
+
"agentRole": "You are a decision systems designer. Make ambiguity explicit and policy-driven.",
|
|
163
|
+
"validationCriteria": [
|
|
164
|
+
{
|
|
165
|
+
"type": "regex",
|
|
166
|
+
"pattern": "missingDataPolicy:\\s*(neutral|penalize|followup_required)",
|
|
167
|
+
"message": "missingDataPolicy must be one of neutral|penalize|followup_required"
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"type": "contains",
|
|
171
|
+
"value": "minCandidatePool",
|
|
172
|
+
"message": "Must set minCandidatePool"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
"type": "contains",
|
|
176
|
+
"value": "minNonObviousCandidates",
|
|
177
|
+
"message": "Must set minNonObviousCandidates"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"type": "contains",
|
|
181
|
+
"value": "shortlistMin",
|
|
182
|
+
"message": "Must set shortlistMin"
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"type": "contains",
|
|
186
|
+
"value": "shortlistMax",
|
|
187
|
+
"message": "Must set shortlistMax"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"type": "contains",
|
|
191
|
+
"value": "screeningTopCriteriaCount",
|
|
192
|
+
"message": "Must set screeningTopCriteriaCount"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"type": "contains",
|
|
196
|
+
"value": "screeningMaxClaimsPerCandidate",
|
|
197
|
+
"message": "Must set screeningMaxClaimsPerCandidate"
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"type": "contains",
|
|
201
|
+
"value": "screeningTimeboxMinutesPerCandidate",
|
|
202
|
+
"message": "Must set screeningTimeboxMinutesPerCandidate"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"type": "contains",
|
|
206
|
+
"value": "screeningBatchSize",
|
|
207
|
+
"message": "Must set screeningBatchSize"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
"type": "regex",
|
|
211
|
+
"pattern": "shortlistRangeCheck:\\s*ok",
|
|
212
|
+
"message": "Must confirm shortlistMin <= shortlistMax"
|
|
213
|
+
}
|
|
214
|
+
],
|
|
215
|
+
"requireConfirmation": true
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
"id": "phase-2b-checkpoint",
|
|
219
|
+
"title": "Phase 2b: Checkpoint (Resumability)",
|
|
220
|
+
"prompt": "Run captureCheckpoint() and append a Machine State Checkpoint entry to `RELOCATION_DOSSIER.md`.\n\nRequired:\n- record lastCompletedStepId = phase-2-policy-and-gates\n- include the raw `response.state` and `response.next.stepInstanceId` objects from the latest `workflow_next` call",
|
|
221
|
+
"agentRole": "You are maintaining resumability. Capture enough state to resume deterministically.",
|
|
222
|
+
"requireConfirmation": false
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"id": "phase-3-breadth-search",
|
|
226
|
+
"title": "Phase 3: Breadth Search (Generate Candidate Pool)",
|
|
227
|
+
"prompt": "Generate a broad candidate pool of US areas that plausibly fit the user's constraints.\n\nBefore generating candidates, update `RELOCATION_DOSSIER.md` with a required section:\n- `## Sources Strategy`\n - Housing: Zillow (if available) + at least one alternative\n - Taxes: state revenue sites / reputable summaries\n - Climate normals: NOAA\n - Climate risk: FEMA flood maps + local/state sources where applicable\n - Employment: BLS / state labor stats (if module active)\n - Transit/commute: local transit agencies / reputable summaries (if module active)\n\nRules:\n- Use the Weight Model + Dealbreakers.\n- Generate at least `minCandidatePool` candidates.\n- Ensure at least `minNonObviousCandidates` candidates qualify per defineNonObvious().\n- Every candidate MUST have an AreaSpec.\n- For each candidate, use normalizeCandidate() and record why included.\n- Record the top-N populous metros list used for defineNonObvious() (N default 20) with a source.\n- Include a mix: some candidates the user likely knows + some non-obvious candidates.\n- Optional: include a small number of custom radius candidates if they are plausible and well-defined.\n\n**Set context variables (required):**\n- candidatePool: normalized candidates array\n- candidatePoolCount: number\n- nonObviousCandidateCount: number\n- nonObviousDefinitionUsed: { topN: number, source: string }\n\nUpdate `RELOCATION_DOSSIER.md`:\n- Candidate Pool (Breadth): table with candidate name, candidateType, region, why included, early risks/unknowns\n- Decision Log entry: how the pool was constructed\n\n**Required output format (exact keys):**\n- candidatePoolCount: <number>\n- nonObviousCandidateCount: <number>\n- nonObviousDefinitionUsed: <summary>",
|
|
228
|
+
"agentRole": "You are a researcher generating a diverse, constraint-respecting candidate pool.",
|
|
229
|
+
"validationCriteria": [
|
|
230
|
+
{
|
|
231
|
+
"type": "contains",
|
|
232
|
+
"value": "candidatePool",
|
|
233
|
+
"message": "Must set candidatePool"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
"type": "contains",
|
|
237
|
+
"value": "candidatePoolCount",
|
|
238
|
+
"message": "Must set candidatePoolCount"
|
|
239
|
+
},
|
|
240
|
+
{
|
|
241
|
+
"type": "contains",
|
|
242
|
+
"value": "nonObviousCandidateCount",
|
|
243
|
+
"message": "Must set nonObviousCandidateCount"
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"type": "contains",
|
|
247
|
+
"value": "nonObviousDefinitionUsed",
|
|
248
|
+
"message": "Must record nonObviousDefinitionUsed"
|
|
249
|
+
}
|
|
250
|
+
],
|
|
251
|
+
"requireConfirmation": false
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"id": "phase-3b-anti-anchoring-gate-check",
|
|
255
|
+
"title": "Phase 3b: Anti-Anchoring Gate Check",
|
|
256
|
+
"prompt": "Run antiAnchoringGate() deterministically using these comparisons:\n- candidatePoolCount >= minCandidatePool\n- nonObviousCandidateCount >= minNonObviousCandidates\n\nIf the gate fails:\n- Expand the pool until it passes (diversify; avoid adding only obvious metros).\n- Recompute candidatePoolCount and nonObviousCandidateCount.\n\nIf the gate passes:\n- Proceed.\n\n**Required output format (exact keys):**\n- antiAnchoringGate: pass|fail\n- gateFailureReason: <string or empty>\n- poolExpansionCount: <number>\n\nUpdate `RELOCATION_DOSSIER.md` with gate status and any expansions performed.",
|
|
257
|
+
"agentRole": "You enforce anti-anchoring and minimum diversity requirements.",
|
|
258
|
+
"validationCriteria": [
|
|
259
|
+
{
|
|
260
|
+
"type": "regex",
|
|
261
|
+
"pattern": "antiAnchoringGate:\\s*(pass|fail)",
|
|
262
|
+
"message": "Must output antiAnchoringGate: pass|fail"
|
|
263
|
+
}
|
|
264
|
+
],
|
|
265
|
+
"requireConfirmation": false
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"id": "phase-3c-build-screening-batches",
|
|
269
|
+
"title": "Phase 3c: Build Screening Batches (Chunking)",
|
|
270
|
+
"prompt": "Prepare chunked screening to avoid excessively large loop iteration limits.\n\nGoal: build `screeningBatches` from `candidatePool` using `screeningBatchSize`.\n\nRules:\n- Preserve candidate order from `candidatePool`.\n- Each batch has at most `screeningBatchSize` candidates.\n- Each batch must be represented deterministically as:\n - { batchId, startIndex, endIndexExclusive, candidates }\n - where candidates is the list of normalized candidates (or their names/areaIds), in order.\n\n**Set context variables (required):**\n- screeningBatches: array\n- screeningBatchesCount: number\n\nUpdate `RELOCATION_DOSSIER.md`:\n- Add a short note under \"Screened Candidates\" explaining batching (batch size + number of batches).\n\n**Required output format (exact keys):**\n- screeningBatchSize: <number>\n- screeningBatchesCount: <number>\n- screeningBatches: <present>\n\nThen proceed to Phase 4.",
|
|
271
|
+
"agentRole": "You are preparing chunked execution. Keep the screening loop bounded and resumable.",
|
|
272
|
+
"validationCriteria": [
|
|
273
|
+
{ "type": "contains", "value": "screeningBatches:", "message": "Must output screeningBatches" },
|
|
274
|
+
{ "type": "contains", "value": "screeningBatchesCount", "message": "Must output screeningBatchesCount" },
|
|
275
|
+
{ "type": "contains", "value": "screeningBatchSize", "message": "Must output screeningBatchSize" }
|
|
276
|
+
],
|
|
277
|
+
"requireConfirmation": false
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"id": "phase-4-screening-loop",
|
|
281
|
+
"type": "loop",
|
|
282
|
+
"title": "Phase 4: First-Pass Screening (Fast, High-Signal)",
|
|
283
|
+
"loop": {
|
|
284
|
+
"type": "forEach",
|
|
285
|
+
"items": "screeningBatches",
|
|
286
|
+
"itemVar": "batch",
|
|
287
|
+
"indexVar": "batchIndex",
|
|
288
|
+
"maxIterations": 30
|
|
289
|
+
},
|
|
290
|
+
"body": [
|
|
291
|
+
{
|
|
292
|
+
"id": "phase-4a-screen-batch",
|
|
293
|
+
"title": "Screen Batch {{batchIndex}}",
|
|
294
|
+
"prompt": "Perform a fast, high-signal screening pass for the current batch.\n\nBatch format (from Phase 3c):\n- batch: { batchId, startIndex, endIndexExclusive, candidates }\n\n**Non-negotiable caps (from Phase 2):**\n- For EACH candidate in batch.candidates:\n - Screen only: dealbreakers + top `screeningTopCriteriaCount` weighted criteria\n - Max `screeningMaxClaimsPerCandidate` claims recorded for this candidate in screening\n - Prefer 1 source per claim (screeningMaxSourcesPerClaim); otherwise mark Unknown\n - Stay within `screeningTimeboxMinutesPerCandidate` minutes PER candidate\n\nInstructions:\n1) Iterate through `batch.candidates` sequentially (do not skip).\n2) For each candidate, produce a `screenResult` (Pass/Fail/Maybe) and update:\n - `RELOCATION_DOSSIER.md` Screened Candidates table\n - `RELOCATION_DOSSIER.md` Screening Claims Ledger (capped)\n - `screenResults` context map\n3) After the batch completes, write a short batch summary into the dossier (one paragraph):\n - batchId, screened count, pass/fail/maybe counts, any repeated unknown categories\n\nMaintain `screenResults` in context as a map:\n- screenResults: { [candidateName: string]: \"Pass\"|\"Fail\"|\"Maybe\" }\n\n**Required output format (exact keys):**\n- batchId: <string>\n- batchScreenedCount: <number>\n- batchPassCount: <number>\n- batchFailCount: <number>\n- batchMaybeCount: <number>",
|
|
295
|
+
"agentRole": "You are doing triage-level screening in batches to keep the workflow scalable and resumable.",
|
|
296
|
+
"validationCriteria": [
|
|
297
|
+
{
|
|
298
|
+
"type": "contains",
|
|
299
|
+
"value": "batchId",
|
|
300
|
+
"message": "Must output batchId"
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
"type": "contains",
|
|
304
|
+
"value": "batchScreenedCount",
|
|
305
|
+
"message": "Must output batchScreenedCount"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"type": "contains",
|
|
309
|
+
"value": "batchPassCount",
|
|
310
|
+
"message": "Must output batchPassCount"
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"type": "contains",
|
|
314
|
+
"value": "batchFailCount",
|
|
315
|
+
"message": "Must output batchFailCount"
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
"type": "contains",
|
|
319
|
+
"value": "batchMaybeCount",
|
|
320
|
+
"message": "Must output batchMaybeCount"
|
|
321
|
+
}
|
|
322
|
+
],
|
|
323
|
+
"requireConfirmation": false
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"id": "phase-4b-select-shortlist",
|
|
329
|
+
"title": "Phase 4b: Select Shortlist for Deep Dives",
|
|
330
|
+
"prompt": "Select a shortlist for deep dives.\n\nRules:\n- Target shortlist size: within shortlistMin..shortlistMax.\n- Must include at least 3 candidates outside the user's `userTopOfMind` list (if provided).\n- If too many Pass/Maybe, prefer diversity across archetypes.\n\n**Set context variables (required):**\n- shortlist: normalized candidates array\n- shortlistCount: number\n- shortlistNonTopOfMindCount: number\n\n**Required output format (exact keys):**\n- shortlistCount: <number>\n- shortlistNonTopOfMindCount: <number>\n- shortlistRangeCheck: ok\n\nUpdate `RELOCATION_DOSSIER.md`:\n- Shortlist section with rationale per shortlisted candidate\n- Profiles Index (planned profile files)\n\nAsk user to confirm the shortlist before deep dives.",
|
|
331
|
+
"agentRole": "You are a curator optimizing for diversity, fit, and decision usefulness.",
|
|
332
|
+
"validationCriteria": [
|
|
333
|
+
{
|
|
334
|
+
"type": "contains",
|
|
335
|
+
"value": "shortlist",
|
|
336
|
+
"message": "Must set shortlist"
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"type": "contains",
|
|
340
|
+
"value": "shortlistCount",
|
|
341
|
+
"message": "Must set shortlistCount"
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
"type": "contains",
|
|
345
|
+
"value": "shortlistNonTopOfMindCount",
|
|
346
|
+
"message": "Must set shortlistNonTopOfMindCount"
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"type": "regex",
|
|
350
|
+
"pattern": "shortlistRangeCheck:\\s*ok",
|
|
351
|
+
"message": "Must confirm shortlistMin <= shortlistCount <= shortlistMax"
|
|
352
|
+
}
|
|
353
|
+
],
|
|
354
|
+
"requireConfirmation": true
|
|
355
|
+
},
|
|
356
|
+
{
|
|
357
|
+
"id": "phase-4c-checkpoint",
|
|
358
|
+
"title": "Phase 4c: Checkpoint (After Shortlist Confirmation)",
|
|
359
|
+
"prompt": "Run captureCheckpoint() and append a Machine State Checkpoint entry to `RELOCATION_DOSSIER.md`.\n\nRequired:\n- record lastCompletedStepId = phase-4b-select-shortlist\n- include the raw `response.state` and `response.next.stepInstanceId` objects from the latest `workflow_next` call",
|
|
360
|
+
"agentRole": "You are maintaining resumability. Capture enough state to resume deterministically.",
|
|
361
|
+
"requireConfirmation": false
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
"id": "phase-5-profile-deep-dive-loop",
|
|
365
|
+
"type": "loop",
|
|
366
|
+
"title": "Phase 5: Deep Dives (Per-Candidate Profiles)",
|
|
367
|
+
"loop": {
|
|
368
|
+
"type": "forEach",
|
|
369
|
+
"items": "shortlist",
|
|
370
|
+
"itemVar": "shortCandidate",
|
|
371
|
+
"indexVar": "shortIndex",
|
|
372
|
+
"maxIterations": 50
|
|
373
|
+
},
|
|
374
|
+
"body": [
|
|
375
|
+
{
|
|
376
|
+
"id": "phase-5a-write-profile",
|
|
377
|
+
"title": "Profile Deep Dive: {{shortCandidate.name}}",
|
|
378
|
+
"prompt": "Create/update the per-candidate profile doc at `relocation-profiles/<candidate-slug>.md`.\n\nRequired: include boundary explicitly at the top:\n- CandidateType\n- AreaSpec (exact boundary)\n\nModule-driven rule (required):\n- Include a section ONLY if its module is active in `activeModules`.\n- If a module is inactive, omit the section (do not include placeholders).\n\nProfile template (must follow):\n- Summary (who it fits / who it doesn't)\n- Housing (rent/buy ranges, inventory notes, neighborhood variation)\n- Cost of living (beyond housing)\n- Taxes (income/property/sales; major gotchas)\n- Safety (high-level + neighborhood variance; avoid false precision)\n- Schools/childcare (module: kids/schools)\n- Commute/transit (modules: commute, transit)\n- Healthcare access (module: healthcare access)\n- Climate & climate risk (module: climate risk)\n- Job market (module: career/job market)\n- Lifestyle (modules: outdoors, nightlife/arts, diversity/community)\n- Pros / Cons (evidence-backed)\n\n**Required headings (non-optional):**\n- ## Unknowns & follow-ups\n- ## Claims & Sources\n\nClaims & Sources ledger requirements:\n- Every key claim uses trackClaim() fields: claim, source, retrievedAt, confidenceGrade.\n- If a claim is proxy/aggregate (especially for custom areas), label it as such.\n\nAlso update `RELOCATION_DOSSIER.md`:\n- Add a short entry for this candidate (1 paragraph) linking to the profile and summarizing differentiators.\n\nWrite-or-paste applies.",
|
|
379
|
+
"agentRole": "You are a meticulous researcher producing consistent, evidence-backed location profiles.",
|
|
380
|
+
"validationCriteria": [
|
|
381
|
+
{
|
|
382
|
+
"type": "contains",
|
|
383
|
+
"value": "## Claims & Sources",
|
|
384
|
+
"message": "Profile must include '## Claims & Sources'"
|
|
385
|
+
},
|
|
386
|
+
{
|
|
387
|
+
"type": "contains",
|
|
388
|
+
"value": "## Unknowns & follow-ups",
|
|
389
|
+
"message": "Profile must include '## Unknowns & follow-ups'"
|
|
390
|
+
}
|
|
391
|
+
],
|
|
392
|
+
"requireConfirmation": false
|
|
393
|
+
}
|
|
394
|
+
]
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
"id": "phase-6-compare-and-rank",
|
|
398
|
+
"title": "Phase 6: Comparison & Explainable Ranking",
|
|
399
|
+
"prompt": "Produce the final comparison and ranking.\n\n1) Build a comparison matrix in `RELOCATION_DOSSIER.md`:\n- Rows: shortlisted candidates\n- Columns: the weighted criteria\n- Include Unknown markers explicitly\n\n2) Deterministic scoring model (required):\n- For each criterion, assign a normalized subscore:\n - Strong fit = 1.0\n - Mixed/conditional fit = 0.5\n - Weak fit = 0.0\n - Unknown = depends on missingDataPolicy\n- Missing data handling (must be explicit and consistent):\n - missingDataPolicy=neutral → Unknown subscore = 0.5\n - missingDataPolicy=penalize → Unknown subscore = 0.25\n - missingDataPolicy=followup_required → Unknown subscore = 0.5 AND candidate is ineligible for top 3 if it has Unknown on any criterion with weight >= 15\n\nScore formula:\n- totalScore = Σ (weight_i * subscore_i)\n\n3) For each candidate, add an explainable narrative:\n- \"Ranks #k because it wins on X/Y and loses on Z. Biggest tradeoff: ...\"\n\n4) Produce final ranked list (top to bottom) with confidence notes and key caveats.\n\n5) Re-weight gate (bounded):\n- Ask user to confirm if ranking is directionally correct.\n- If not, allow ONE re-weight of `weights` and re-run scoring.\n- Output `reweightUsed: true|false`.\n\n**Required output format (exact keys):**\n- ranking: [{ name: string, totalScore: number, rank: number }]\n- unknownsImpactSummary: <string>\n- reweightUsed: true|false\n\nUpdate Decision Log with any weight changes and rationale.",
|
|
400
|
+
"agentRole": "You are an analyst producing an explainable, evidence-backed ranking with explicit tradeoffs.",
|
|
401
|
+
"validationCriteria": [
|
|
402
|
+
{
|
|
403
|
+
"type": "contains",
|
|
404
|
+
"value": "ranking:",
|
|
405
|
+
"message": "Must output ranking list"
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"type": "contains",
|
|
409
|
+
"value": "reweightUsed",
|
|
410
|
+
"message": "Must output reweightUsed"
|
|
411
|
+
}
|
|
412
|
+
],
|
|
413
|
+
"requireConfirmation": true
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"id": "phase-6b-checkpoint",
|
|
417
|
+
"title": "Phase 6b: Checkpoint (After Ranking)",
|
|
418
|
+
"prompt": "Run captureCheckpoint() and append a Machine State Checkpoint entry to `RELOCATION_DOSSIER.md`.\n\nRequired:\n- record lastCompletedStepId = phase-6-compare-and-rank\n- include the raw `response.state` and `response.next.stepInstanceId` objects from the latest `workflow_next` call",
|
|
419
|
+
"agentRole": "You are maintaining resumability. Capture enough state to resume deterministically.",
|
|
420
|
+
"requireConfirmation": false
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
"id": "phase-7-next-steps",
|
|
424
|
+
"title": "Phase 7: Next Steps (Validation in the Real World)",
|
|
425
|
+
"prompt": "Create a practical next-steps plan.\n\nInclude:\n- Suggested visit plan for top 2–4 candidates (what to validate in person)\n- Open questions per candidate (from Unknowns)\n- What would change your mind (pivot triggers)\n- Optional: recommended neighborhoods to investigate further (if you have enough evidence; otherwise mark Unknown)\n\nUpdate `RELOCATION_DOSSIER.md` with Next Steps and Pivot Triggers.\n\nOutput: concise next-steps checklist.",
|
|
426
|
+
"agentRole": "You are a pragmatic planner. Translate analysis into actionable validation steps.",
|
|
427
|
+
"requireConfirmation": false
|
|
428
|
+
}
|
|
429
|
+
]
|
|
430
|
+
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Result } from 'neverthrow';
|
|
2
|
-
export type Base64UrlError = {
|
|
3
|
-
readonly code: 'BASE64URL_INVALID';
|
|
4
|
-
readonly message: string;
|
|
5
|
-
};
|
|
6
|
-
export declare function encodeBase64Url(bytes: Uint8Array): string;
|
|
7
|
-
export declare function decodeBase64Url(input: string): Result<Uint8Array, Base64UrlError>;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.encodeBase64Url = encodeBase64Url;
|
|
4
|
-
exports.decodeBase64Url = decodeBase64Url;
|
|
5
|
-
const neverthrow_1 = require("neverthrow");
|
|
6
|
-
function encodeBase64Url(bytes) {
|
|
7
|
-
return Buffer.from(bytes).toString('base64url');
|
|
8
|
-
}
|
|
9
|
-
function decodeBase64Url(input) {
|
|
10
|
-
try {
|
|
11
|
-
return (0, neverthrow_1.ok)(new Uint8Array(Buffer.from(input, 'base64url')));
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return (0, neverthrow_1.err)({ code: 'BASE64URL_INVALID', message: 'Invalid base64url string' });
|
|
15
|
-
}
|
|
16
|
-
}
|