Repository navigation
Expand file tree
/
Copy pathlab-examples.js
More file actions
29 lines (28 loc) · 8.36 KB
/
Copy pathlab-examples.js
File metadata and controls
29 lines (28 loc) · 8.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/** Website scenarios use the frozen recipe source; these are separate input snapshots. */
export const stories={
'water-total':{title:"Total the water readings",question:"How does a new set of readings change the total?",rule:"Add the readings and count how many were supplied.",assumption:"Readings are supplied in liters. This program has no sensor or stored running total.",change:"Load 2, 3 and 4 liters. The total becomes 9 while the reading count stays 3.",after:{readings:[2,3,4]},focus:'total'},
'route-preview':{title:"Find an open route",question:"Can D still be reached when C closes?",rule:"Find the route with the fewest edges from A to D, using neighbor order to break ties.",assumption:"The caller marks the map current. Each edge has equal cost, and the walking proposal is a local simulation.",change:"Close C. The route changes from A–C–D to A–B–D, still two edges.",after:{blocked:['C']},focus:'route'},
'craft-quote':{title:"Quote a batch of work",question:"How many of the four requested batches fit the available materials and space?",rule:"min(requested, floor(ore / 2), wood, floor(freeCapacity / 2))",assumption:"Each batch uses two ore, one wood and two spaces. The quote reserves no materials.",change:"Increase capacity from 5 to 8. The quote rises from two batches to three; seven ore still prevents a fourth.",after:{freeCapacity:8},focus:'feasible'},
'confirmed-checkpoints':{title:"Check both checkpoints",question:"Can both checkpoints stay supported when a new observation denies arrival?",rule:"Check the two supplied claims named “haul” and “arrival.” Each is supported if at least one qualifying observation says true and none says false. Completion is true when both are supported.",assumption:"A qualifying report must be marked observation, dated no later than now, and no older than maxAge. Its revision is the declared update number and must be at least minRevision. The caller supplies the clock and these limits; source labels do not authenticate witnesses.",change:"Add an observation denying arrival at tick 10, revision 1, the same time and revision as the existing reports. At now 12, its age is 2, meeting maxAge 2; revision 1 meets minRevision 1. Arrival becomes conflict and completion false, while haul stays supported.",transform:v=>({...v,records:[...v.records,{id:'denial',source:'other',claim:'arrival',value:false,kind:'observation',observedAt:10,revision:1}]}),focus:'arrivalState'},
'evidence-ledger':{title:"Keep conflicting evidence",question:"What happens when one source says both yes and no?",rule:"Count each source once for support and once for refutation, keeping both sides of a conflict.",assumption:"Records may be observations, testimony or inference, dated no later than now and no older than maxAge. A record’s revision is its declared update number and must be at least minRevision. Source labels do not authenticate witnesses; renaming one does not establish an independent source.",baseline:1,fixture:2,change:"Add a denial from the same source. Support stays 1, refutation becomes 1, and the source count stays 1.",focus:'ledger'},
'trade-preview':{title:"Check a sale quote",question:"Does the quote survive one tick past the offer’s expiry?",rule:"Quote the full quantity only when it is positive and offer, expiry, stock, inventory and allowance checks pass.",assumption:"The recipe selects the offer named “offer.” It quotes a sale in symbolic crystal units and makes no payment.",fixture:1,change:"Advance the supplied time from 10 to 11. The expired offer yields quantity 0 and proceeds 0.",focus:'unexpired'},
'needs-triage':{title:"Choose a food candidate",question:"Which fresh edible food has the highest restoration value?",rule:"Choose the greatest restoration value, breaking ties by ascending item ID.",assumption:"An eating proposal requires positive hunger and a snapshot marked current. Freshness is supplied; zero-restoration food remains eligible. Proposals are simulated.",change:"Raise b’s restoration from 8 to 9 so it becomes the chosen food ahead of a.",transform:v=>({...v,foods:v.foods.map(f=>({...f,restoration:f.id==='b'?9:f.restoration}))}),focus:'chosenId'},
'receipt-reconciliation':{title:"Review retry advice",question:"After one confirmed unit, does an unknown second attempt allow a retry?",rule:"Retain confirmed units and withhold retry advice while an attempt is pending or unknown.",assumption:"The program reviews the attempt history supplied by the caller and submits no work.",baselineInputs:{receipts:[{id:'a',operation:'craft',attempt:'attempt1',sequence:1,status:'confirmed',units:1}],policy:{operation:'craft',requested:3,maxAttempts:4}},transform:v=>({...v,receipts:[...v.receipts,{id:'z',operation:'craft',attempt:'attempt2',sequence:1,status:'unknown',units:0}]}),change:"Add an unknown second attempt. The confirmed unit remains, while mayRetry changes from true to false.",focus:'result'},
'gather-readiness':{title:"Check collection readiness",question:"Is the observation still recent enough for a collection proposal?",rule:"Require all six checks and an observation no later than now and no older than maxAge.",assumption:"Checks mean skill, route, reservation, capacity, owner permission and remaining uses, in that order. The caller supplies these values.",change:"Advance now from 12 to 13. The observation becomes too old, so the simulated proposal is skipped.",after:{now:13},focus:'ready'},
'work-schedule':{title:"Follow job dependencies",question:"Does one extra tick on job a push work past the deadline?",rule:"Start each job when all its dependencies end. Independent jobs can start together.",assumption:"The estimate assumes unlimited parallel capacity. It reserves no workers and executes no jobs.",change:"Increase a from 3 to 4 ticks. Job b finishes at 6 instead of 5, past the deadline of 5.",transform:v=>({...v,jobs:v.jobs.map(j=>({...j,duration:j.id==='a'?4:j.duration}))}),focus:'makespan'}
};
export const order=['water-total','route-preview','receipt-reconciliation','confirmed-checkpoints','craft-quote','evidence-ledger','work-schedule','trade-preview','needs-triage','gather-readiness'];
export function baseline(recipe){return structuredClone(stories[recipe.id].baselineInputs??recipe.fixtures[stories[recipe.id].baseline??0].inputs);}
export function changed(recipe){const story=stories[recipe.id],v=baseline(recipe);return story.transform?story.transform(v):story.fixture!==undefined?structuredClone(recipe.fixtures[story.fixture].inputs):{...v,...structuredClone(story.after)};}
export function cappedWaterIntent(recipe){const intent=structuredClone(recipe.intent);intent.name='Water readings capped at five liters';intent.steps.splice(intent.steps.findIndex(n=>n.id==='summary'),0,{id:'cappedWater',op:'clamp',inputs:['total'],params:{min:0,max:5}});intent.steps.find(n=>n.id==='summary').inputs=['cappedWater','count'];intent.thought.tasks[0].nodes.push('cappedWater');intent.thought.tasks[0].text='Sum supplied readings and report a total capped at five liters, alongside their count.';intent.thought.plans[0].text=intent.thought.tasks[0].text;return intent;}
/** Authored alternative, never a mutation of the retained needs-triage source. */
export function positiveFoodIntent(recipe){
const intent=structuredClone(recipe.intent);intent.name='Food candidate with positive restoration';
const additions=[{id:'chosenRestoration',op:'get',inputs:['food'],params:{path:'value.restoration'}},{id:'restores',op:'compare',inputs:['chosenRestoration'],params:{operator:'gt',value:0}},{id:'usefulCandidate',op:'choose',inputs:['found','restores','no'],params:{}}];
intent.steps.splice(intent.steps.findIndex(n=>n.id==='ready'),0,...additions);
intent.steps.find(n=>n.id==='ready').inputs=intent.steps.find(n=>n.id==='ready').inputs.map(id=>id==='found'?'usefulCandidate':id);
intent.steps.push({id:'candidateReport',op:'report',inputs:['chosenId','chosenRestoration','restores','ready'],params:{labels:['candidate','restoration','positiveRestoration','ready']}});intent.outputs.push('candidateReport');
intent.thought.tasks[0].nodes.push(...additions.map(n=>n.id),'candidateReport');intent.thought.tasks[0].outputs.push('candidateReport');
const description='Rank fresh edible foods by restoration and item ID, require positive restoration plus positive hunger and a current snapshot for a simulated eating proposal, and report the chosen restoration.';
intent.thought.tasks[0].text=description;intent.thought.plans[0].text=description;return intent;
}