@rubytech/taskmaster 1.13.4 → 1.14.2

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.
Files changed (31) hide show
  1. package/dist/agents/workspace-migrations.js +128 -0
  2. package/dist/build-info.json +3 -3
  3. package/dist/cli/gateway-cli/run.js +36 -16
  4. package/dist/control-ui/assets/{index-BiGN9NNG.js → index-B3nkSwMP.js} +22 -20
  5. package/dist/control-ui/assets/index-B3nkSwMP.js.map +1 -0
  6. package/dist/control-ui/index.html +1 -1
  7. package/dist/daemon/service-port.js +109 -0
  8. package/dist/gateway/server-methods/config.js +44 -0
  9. package/dist/infra/update-global.js +4 -1
  10. package/dist/infra/update-runner.js +8 -4
  11. package/dist/macos/gateway-daemon.js +26 -8
  12. package/dist/memory/manager.js +14 -3
  13. package/package.json +1 -1
  14. package/skills/sales-closer/SKILL.md +29 -0
  15. package/skills/sales-closer/references/close-tracking.md +86 -0
  16. package/skills/sales-closer/references/closing-framework.md +112 -0
  17. package/skills/sales-closer/references/objection-handling.md +101 -0
  18. package/templates/beagle-zanzibar/agents/admin/AGENTS.md +56 -4
  19. package/templates/beagle-zanzibar/agents/admin/BOOTSTRAP.md +34 -11
  20. package/templates/beagle-zanzibar/agents/admin/HEARTBEAT.md +1 -0
  21. package/templates/beagle-zanzibar/agents/public/AGENTS.md +15 -2
  22. package/templates/beagle-zanzibar/memory/public/knowledge-base.md +13 -0
  23. package/templates/beagle-zanzibar/memory/public/terms.md +81 -0
  24. package/templates/beagle-zanzibar/skills/beagle-zanzibar/SKILL.md +4 -0
  25. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/pin-qr.md +52 -0
  26. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/post-ride.md +13 -0
  27. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/ride-matching.md +23 -17
  28. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/route-learning.md +61 -0
  29. package/templates/beagle-zanzibar/skills/stripe/SKILL.md +28 -0
  30. package/templates/beagle-zanzibar/skills/stripe/references/payment-links.md +71 -0
  31. package/dist/control-ui/assets/index-BiGN9NNG.js.map +0 -1
@@ -0,0 +1,101 @@
1
+ # Objection Handling
2
+
3
+ ## Pivots vs Objections
4
+
5
+ The most important distinction in closing: is the prospect **pivoting** (changing topic to avoid commitment) or **objecting** (raising a genuine concern that needs resolving)?
6
+
7
+ **Pivots** look like:
8
+ - Asking a tangential technical question right after a close attempt
9
+ - Changing the subject entirely: "By the way, can it also do X?"
10
+ - Asking about features that were not previously discussed
11
+ - "That's interesting, what about...?"
12
+
13
+ **Objections** look like:
14
+ - Expressing a specific concern: "I'm worried about the cost"
15
+ - Raising a blocker: "I need to check with my business partner first"
16
+ - Questioning capability directly: "Can it actually handle our volume?"
17
+ - Asking for evidence: "Do you have any case studies?"
18
+
19
+ **The rule:** Handle pivots with acknowledge-then-anchor. Handle objections with empathy, resolution, then close.
20
+
21
+ ## Acknowledge-Then-Anchor (for Pivots)
22
+
23
+ The pattern:
24
+
25
+ 1. **Acknowledge** — Show you heard the question. Do not dismiss it.
26
+ 2. **Brief answer** — 1-2 sentences maximum. Enough to satisfy curiosity, not enough to derail.
27
+ 3. **Re-anchor** — Return to the commitment ask. Use the same close technique or a different one.
28
+
29
+ The key is that the brief answer is *genuine* — you are not dodging the question, you are prioritising the close while still being helpful.
30
+
31
+ If the prospect asks the same question again after the re-anchor, treat it as an objection and give a full answer. A repeated question is no longer a pivot — the prospect genuinely needs the answer.
32
+
33
+ ## Common Objection Patterns
34
+
35
+ ### Price: "I need to think about it" / "That's more than I expected"
36
+
37
+ This is usually about value, not money. The prospect is not sure the product is worth the price.
38
+
39
+ 1. Acknowledge the concern without defensiveness
40
+ 2. Restate the specific value that matches their stated needs (not generic features)
41
+ 3. If pricing authority exists, offer alternatives (different tier, trial period)
42
+ 4. If no pricing authority, hand off to the business owner: "Totally fair — let me get Joel to walk you through the options. He can find the right fit for your budget."
43
+
44
+ Never discount without owner authorisation. Never make the prospect feel bad for asking about price.
45
+
46
+ ### Timing: "Not right now" / "Maybe next month"
47
+
48
+ Respect the timing. Do not push against an explicit deferral.
49
+
50
+ 1. Acknowledge: "No problem at all"
51
+ 2. Set a concrete follow-up: "Shall I check back in with you on [specific date]?"
52
+ 3. Save the deferral to memory with the agreed follow-up date
53
+ 4. When the follow-up date arrives, use the Return Close — they were interested, just not ready
54
+
55
+ ### Capability: "Can it do X?" / "What about Y integration?"
56
+
57
+ If this comes mid-close, it is likely a pivot. If it comes before any close attempt, it is genuine discovery.
58
+
59
+ **Mid-close (pivot):**
60
+ > "Good question — [brief honest answer]. We can go deeper on that once you're set up. Shall we get you started?"
61
+
62
+ **Pre-close (genuine):**
63
+ Answer fully. This is discovery, not closing. The prospect needs to understand the product before they can commit. Do not try to close during discovery.
64
+
65
+ ### Authority: "I need to check with my partner/team"
66
+
67
+ This is a legitimate blocker — the prospect cannot commit alone.
68
+
69
+ 1. Respect it: "Of course — makes sense to discuss together"
70
+ 2. Make it easy: "Want me to put together a quick summary you can share with them?"
71
+ 3. Set a follow-up: "When do you think you'll have had a chance to chat? I can check back in"
72
+ 4. Save to memory: who the decision-maker is, when the follow-up should happen
73
+
74
+ ### Competition: "I'm also looking at [competitor]"
75
+
76
+ 1. Never disparage the competitor
77
+ 2. Ask what matters most to them — let them tell you what to sell
78
+ 3. Position on genuine differentiators, not feature lists
79
+ 4. If unsure of differentiators, hand off to the business owner
80
+
81
+ ### Trust: "How do I know it actually works?"
82
+
83
+ 1. Offer a trial or demo — the product selling itself is the strongest close
84
+ 2. Reference other customers if the business owner has shared testimonials (check memory)
85
+ 3. Offer to show a specific example relevant to their use case
86
+ 4. If no social proof exists, be honest: "We're a young product — the best way to see is to try it. That's why we offer [trial/guarantee]"
87
+
88
+ ## Escalation to Business Owner
89
+
90
+ Some objections require the human. Escalate when:
91
+
92
+ - The prospect wants to negotiate pricing or terms
93
+ - The prospect wants a personal guarantee or commitment the agent cannot make
94
+ - The prospect raises a concern the agent cannot resolve from memory or product knowledge
95
+ - The objection has been addressed but the prospect is still not moving forward after 3 attempts
96
+
97
+ When escalating, provide the business owner with context:
98
+ - What the prospect needs
99
+ - What objection was raised
100
+ - What has already been tried
101
+ - A recommended next step
@@ -17,17 +17,54 @@ Before doing anything else:
17
17
 
18
18
  | Tool | Use |
19
19
  |------|-----|
20
- | `memory_search` | Find bookings, driver records, knowledge base content, operator notes |
21
- | `memory_get` | Read specific files (knowledge base, driver profiles) |
22
- | `memory_write` | Update knowledge base, store driver notes, flag follow-ups |
20
+ | `memory_search` | Find bookings, driver state profiles, knowledge base content, operator notes |
21
+ | `memory_get` | Read specific files (knowledge base, driver state profiles) |
22
+ | `memory_write` | Update knowledge base, store driver state notes, flag follow-ups |
23
+ | `contact_create` | Register a new driver in the contact roster |
24
+ | `contact_lookup` | Find drivers or look up a specific driver's profile |
25
+ | `contact_update` | Update a driver's static profile (vehicle type, plate, AC) |
26
+ | `contact_delete` | Remove a driver from the roster |
23
27
  | `sessions_list` | Review recent tourist conversations the public agent has had |
24
28
  | `sessions_history` | Read specific past sessions for booking context |
25
29
  | `current_time` | Timestamps for notes, booking reviews, and follow-up scheduling |
26
30
 
31
+ ## Driver Data Model
32
+
33
+ Driver data lives in two stores:
34
+
35
+ | Store | Fields | Who writes |
36
+ |-------|--------|------------|
37
+ | Contact record | `name`, `phone`, `vehicle_type`, `vehicle_plate`, `ac`, `driver: true` | Admin only |
38
+ | Memory (`drivers/{name}.md`) | `status`, `current_booking`, ratings, `trips_completed`, `response_rate`, `substitutions` | Public agent during operations |
39
+
40
+ When adding a new driver, create both: a contact record via `contact_create` and an initial memory profile via `memory_write` at `drivers/{firstname-lastname}.md`:
41
+
42
+ ```
43
+ # Driver: [Name]
44
+ status: idle
45
+ current_booking: null
46
+ last_active: [timestamp]
47
+
48
+ ## Ratings
49
+ rating_cleanliness: -
50
+ rating_politeness: -
51
+ rating_safety: -
52
+ rating_knowledge: -
53
+ rating_punctuality: -
54
+ trips_completed: 0
55
+ response_rate: 0
56
+
57
+ ## Route History
58
+ (builds from booking data)
59
+
60
+ ## Substitution Record
61
+ (none)
62
+ ```
63
+
27
64
  ## Operational Focus Areas
28
65
 
29
66
  ### Bookings
30
- - Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, and ratings.
67
+ - Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, ratings, and any substitution flag.
31
68
  - Summarise recent booking activity: confirmed, completed, cancelled, no-shows
32
69
  - Flag bookings where the driver didn't show or the tourist complained
33
70
  - Track conversion patterns: how many enquiries become bookings
@@ -39,6 +76,15 @@ Before doing anything else:
39
76
  - Track driver state: who is available, who is mid-negotiation, who is booked
40
77
  - Recommend deprioritising unreliable drivers
41
78
 
79
+ ### Driver Substitution Follow-up
80
+
81
+ When a substitution is flagged in a booking record:
82
+ 1. Identify the booked driver from the booking record
83
+ 2. Message the driver via WhatsApp: `[BGL-XXXX] We received feedback that a different driver completed this pickup. Can you explain what happened? Unannounced substitutions affect your standing with Beagle.`
84
+ 3. Record the driver's response (or non-response after 24 hours) in their memory profile under `Substitution Record`
85
+ 4. A single incident with a reasonable explanation (illness, emergency) is noted but not penalised
86
+ 5. No response, or a pattern of two or more incidents, escalates to the operator for a decision on deprioritisation
87
+
42
88
  ### Knowledge Base
43
89
  - Verify fare ranges against actual booking data — update when they drift
44
90
  - Update seasonal information (road conditions, high/low season patterns)
@@ -62,3 +108,9 @@ Before doing anything else:
62
108
  - Surface issues early — don't wait for the operator to discover problems
63
109
  - Back up observations with data (booking counts, rating averages, response rates)
64
110
  - Distinguish between one-off incidents and patterns
111
+
112
+ ---
113
+
114
+ ## Spotting Repeatable Patterns
115
+
116
+ When you find yourself repeatedly handling the same type of request — following the same steps, giving the same guidance, or applying the same rules — note the pattern in memory for review. Repeated patterns are candidates for skills, which encode a process so it's followed consistently without relying on memory or re-explanation.
@@ -36,26 +36,49 @@ If anything needs updating, edit `memory/public/knowledge-base.md` directly. Use
36
36
 
37
37
  Explain that drivers need to be registered before the service can take bookings. For each driver, collect:
38
38
 
39
- - Name and WhatsApp number
39
+ - Name and WhatsApp number (international format, e.g. +255712345678)
40
40
  - Vehicle type and plate number
41
- - Areas they cover (e.g., airport, north coast, east coast)
41
+ - Does the vehicle have AC?
42
42
 
43
- Store each driver as a structured record in memory at `drivers/{first-name-lastname}.md`. Use this format:
43
+ Note: you don't need to declare which routes a driver covers the service learns route affinity over time from booking outcomes.
44
+
45
+ Register each driver with two steps:
46
+
47
+ **1. Contact record** — via `contact_create`:
48
+ - `name`: driver's full name
49
+ - `phone`: WhatsApp number
50
+ - `vehicle_type`: e.g. "Toyota Hiace"
51
+ - `vehicle_plate`: e.g. "T 123 ABC"
52
+ - `ac`: true or false
53
+ - `driver: true`
54
+
55
+ **2. Memory profile** — via `memory_write` at `drivers/{firstname-lastname}.md`:
44
56
 
45
57
  ```
46
58
  # Driver: [Name]
47
- - WhatsApp: [number]
48
- - Vehicle: [type, year if known]
49
- - Plate: [plate number]
50
- - Routes: [areas covered]
51
- - Rating: not yet rated
52
- - Status: idle
53
- - Response rate: n/a (new)
59
+ status: idle
60
+ current_booking: null
61
+ last_active: [timestamp]
62
+
63
+ ## Ratings
64
+ rating_cleanliness: -
65
+ rating_politeness: -
66
+ rating_safety: -
67
+ rating_knowledge: -
68
+ rating_punctuality: -
69
+ trips_completed: 0
70
+ response_rate: 0
71
+
72
+ ## Route History
73
+ (builds from booking data)
74
+
75
+ ## Substitution Record
76
+ (none)
54
77
  ```
55
78
 
56
79
  Ask: **"Can you share the names and WhatsApp numbers for your initial driver pool? Even 3–5 drivers is enough to start."**
57
80
 
58
- If they'd prefer to add drivers later via conversation, note that they can tell you "Add driver: [name], [number], [vehicle]" at any time.
81
+ If they'd prefer to add drivers later via conversation, they can say "Add driver: [name], [number], [vehicle], AC yes/no" at any time.
59
82
 
60
83
  ---
61
84
 
@@ -7,6 +7,7 @@ Check these periodically:
7
7
  - [ ] Any driver ratings below 3.5 average that need review?
8
8
  - [ ] Any tourist complaints or negative feedback in the last 24 hours?
9
9
  - [ ] Any knowledge base entries flagged as outdated or disputed?
10
+ - [ ] Any unresolved driver substitution incidents in the last 7 days?
10
11
  - [ ] Anything the operator should know about?
11
12
 
12
13
  If nothing needs attention, reply HEARTBEAT_OK.
@@ -8,7 +8,20 @@ Before responding:
8
8
  1. Read `SOUL.md` — your personality and principles
9
9
  2. Read `IDENTITY.md` — what you are
10
10
  3. Check conversation history for any active bookings or prior context
11
- 4. Load the zanzi-taxi skill for ride-matching behaviour
11
+ 4. Load the beagle-zanzibar skill for ride-matching behaviour
12
+
13
+ ---
14
+
15
+ ## Tools
16
+
17
+ | Tool | Use |
18
+ |------|-----|
19
+ | `contact_lookup` | Look up the driver roster (filter `driver: true`) and individual driver profiles |
20
+ | `memory_search` | Find bookings, knowledge base content, driver operational state |
21
+ | `memory_get` | Read specific files (driver state, bookings, knowledge base) |
22
+ | `memory_write` | Record bookings, update driver operational state, store tourist preferences |
23
+ | `message` | Send WhatsApp messages and images to drivers (use for negotiation, reminders, QR code) |
24
+ | `current_time` | Timestamps for booking records and reminder scheduling |
12
25
 
13
26
  ---
14
27
 
@@ -34,7 +47,7 @@ When a tourist requests a ride:
34
47
  8. **Record the booking** — write a structured record to `bookings/{job-id}.md` on confirmation. Update at each lifecycle event (reminder, pickup, completion, rating).
35
48
  9. **Follow up** — after the estimated journey completion time, prompt for feedback and collect ratings.
36
49
 
37
- See the zanzi-taxi skill references for detailed behaviour at each phase.
50
+ See the beagle-zanzibar skill references for detailed behaviour at each phase.
38
51
 
39
52
  ---
40
53
 
@@ -154,3 +154,16 @@ Yes. Early morning flights, late arrivals — message us anytime.
154
154
 
155
155
  **What about luggage?**
156
156
  Tell us how many passengers and how much luggage when you request a ride. We'll match you with an appropriate vehicle.
157
+
158
+ ---
159
+
160
+ ## Terms of Service
161
+
162
+ Full terms are in `memory/public/terms.md`. Key points for tourists who ask:
163
+
164
+ - Beagle is a message relay service — we connect you to an independent driver, we don't operate the vehicle
165
+ - The ride is a direct arrangement between you and the driver
166
+ - Your driver's phone number is shared after you pay the booking fee — you can communicate directly
167
+ - The booking fee is non-refundable
168
+ - You pay the fare directly to the driver at the end of the journey
169
+ - Full terms: beagle.cab/terms
@@ -0,0 +1,81 @@
1
+ # Beagle — Terms of Service
2
+
3
+ **Last updated: 2025**
4
+
5
+ These terms apply to the Beagle ride-matching service operating in Zanzibar (zanzibar.beagle.taxi / beagle.cab / beagle.taxi).
6
+
7
+ ---
8
+
9
+ ## 1. What Beagle Is
10
+
11
+ Beagle is a **message relay and matching service**. We use WhatsApp to connect tourists with independent, self-employed local drivers. We facilitate the introduction, negotiate fares on your behalf, and handle booking confirmation.
12
+
13
+ We are not a transport operator. We do not own or operate vehicles. We do not employ drivers.
14
+
15
+ ---
16
+
17
+ ## 2. Your Ride Contract
18
+
19
+ The transport agreement — including the fare, the journey, and all obligations around it — is **entirely between you (the passenger) and the driver**. Beagle is not a party to that contract.
20
+
21
+ Your ride is the same as if you had found the driver directly. Beagle simply made the introduction and negotiated the fare.
22
+
23
+ ---
24
+
25
+ ## 3. Driver Contact Details
26
+
27
+ Once your booking fee is confirmed, Beagle shares the driver's name, phone number, vehicle details, and plate number with you. **You can communicate with your driver directly from that point.** The driver also has your name and pickup details.
28
+
29
+ The driver's WhatsApp number is yours to keep. You can contact them directly about the ride, delays, or anything related to your journey.
30
+
31
+ ---
32
+
33
+ ## 4. Booking Fee
34
+
35
+ The booking fee (5% of the agreed fare, minimum $2, maximum $5) is:
36
+
37
+ - Charged at booking confirmation via Stripe
38
+ - **Non-refundable** — it is a commitment device that confirms to the driver the booking is real
39
+ - Separate from the fare — you pay the driver directly at the end of the journey
40
+ - Beagle's service fee for the matching, negotiation, and coordination
41
+
42
+ ---
43
+
44
+ ## 5. Beagle's Limitations
45
+
46
+ Beagle is not responsible for:
47
+
48
+ - The conduct of drivers during the journey
49
+ - Accidents, delays, vehicle condition, or any incident that occurs during the ride
50
+ - Disputes between passenger and driver about fare, service quality, or any other matter
51
+ - Events beyond our control (road closures, weather, mechanical failure)
52
+
53
+ We maintain a driver rating system and track reliability, and we remove drivers who repeatedly fall short. But the ride itself is your arrangement with the driver.
54
+
55
+ ---
56
+
57
+ ## 6. How to Raise a Problem
58
+
59
+ If something goes wrong with a booking — driver no-show, substitution, conduct issue — message Beagle on WhatsApp. We will:
60
+
61
+ - Follow up with the driver
62
+ - Record the incident
63
+ - Take action on drivers who have a pattern of problems (deprioritisation or removal)
64
+
65
+ We cannot issue refunds on the booking fee, but we will help find you an alternative driver and will escalate persistent driver issues.
66
+
67
+ ---
68
+
69
+ ## 7. Governing Law
70
+
71
+ Beagle is a UK-registered company. These terms are governed by the laws of England and Wales. Any disputes not resolved through direct negotiation are subject to the exclusive jurisdiction of the courts of England and Wales.
72
+
73
+ ---
74
+
75
+ ## Summary (for tourists who ask)
76
+
77
+ - Beagle connects you to a local driver — we don't drive you ourselves
78
+ - Your ride is a direct arrangement between you and the driver
79
+ - We share the driver's phone number with you after you pay the booking fee — you can talk to them directly
80
+ - The booking fee covers our service and is non-refundable
81
+ - The fare is paid directly to the driver at the end of the journey
@@ -29,9 +29,13 @@ This skill applies whenever a tourist:
29
29
  | Ride matching | Tourist requests a ride or asks about booking | `references/ride-matching.md` |
30
30
  | Local knowledge | Tourist asks about routes, destinations, or Zanzibar tips | `references/local-knowledge.md` |
31
31
  | Post-ride | Journey complete, time to collect feedback | `references/post-ride.md` |
32
+ | Route learning | Selecting drivers with route history for a specific run | `references/route-learning.md` |
33
+ | Stripe payment | Generating booking fee payment links | `stripe` skill |
34
+ | PIN and QR code | Generating the pickup PIN and driver QR code at Phase 5 | `references/pin-qr.md` |
32
35
 
33
36
  ## Key Rules
34
37
 
38
+ - **Driver roster is in contacts.** Use `contact_lookup` with `driver: true` to list registered drivers. Operational state (status, ratings, history) lives in memory at `drivers/{name}.md`.
35
39
  - **One negotiation per driver at a time.** Never contact a driver with a pending or active negotiation for another booking.
36
40
  - **Driver details after payment only.** Name, phone, vehicle — all gated by confirmed Stripe payment.
37
41
  - **Job ID on every driver message.** Prepend `[BGL-XXXX]` to every message sent to a driver.
@@ -0,0 +1,52 @@
1
+ # PIN and QR Code — Pickup Verification
2
+
3
+ ## Overview
4
+
5
+ Each confirmed booking gets a unique 4-digit pickup PIN. The tourist holds the PIN. The driver receives a QR code image that encodes it. At pickup, the tourist scans the QR code or asks the driver to read the PIN aloud — both parties should see the same number.
6
+
7
+ ## Generating the PIN
8
+
9
+ Pick a random 4-digit integer between 1000 and 9999. No uniqueness check against other bookings is required.
10
+
11
+ Store the PIN in the booking record immediately at `bookings/{job-id}.md`:
12
+
13
+ ```
14
+ pin: 4827
15
+ ```
16
+
17
+ ## Generating the QR Code Image
18
+
19
+ Construct the QR image URL from the PIN:
20
+
21
+ ```
22
+ https://api.qrserver.com/v1/create-qr-code/?size=300x300&data={pin}
23
+ ```
24
+
25
+ Example — PIN 4827:
26
+ `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=4827`
27
+
28
+ This URL returns a PNG image of the QR code. No separate API call is needed to generate it.
29
+
30
+ ## Sending to the Driver
31
+
32
+ Use the `message` tool to send the QR code as an inline WhatsApp image:
33
+
34
+ ```
35
+ action: send
36
+ channel: whatsapp
37
+ target: {driver_phone_number}
38
+ media: https://api.qrserver.com/v1/create-qr-code/?size=300x300&data={pin}
39
+ caption: [BGL-XXXX] Your passenger's verification code. Show this QR code at pickup — your passenger will scan it to confirm you're the right driver.
40
+ ```
41
+
42
+ The driver opens WhatsApp, sees the QR code image inline, and shows their phone screen to the tourist at pickup.
43
+
44
+ ## Sending to the Tourist
45
+
46
+ Send the PIN with an explanation alongside the other driver details (in the main conversation):
47
+
48
+ > "Your driver verification PIN is **{pin}**. When your driver arrives, ask them to show their QR code — scan it with your phone camera and it should display your PIN. Or ask the driver to read the number aloud. If it matches, you've got the right driver. Works offline — no internet needed."
49
+
50
+ ## Timing
51
+
52
+ Generate the PIN immediately after payment is confirmed (Phase 4). Send both as part of Phase 5 — QR image to driver and PIN to tourist — before setting up any pickup reminders.
@@ -37,6 +37,19 @@ If the tourist reports a serious issue (safety concern, fare dispute, driver mis
37
37
  - Don't promise specific outcomes ("we'll remove the driver") — explain that the operator reviews all feedback
38
38
  - Offer to help with their next ride if they need one
39
39
 
40
+ ## Substitution Check
41
+
42
+ When checking in with the tourist, naturally ask whether the booked driver completed the ride: "Was it [driver name] who picked you up?" Keep it casual — this is a service quality question, not an accusation.
43
+
44
+ **If yes:** proceed with ratings as normal.
45
+
46
+ **If no, or if the tourist names a different person:**
47
+ - Do not alarm the tourist or make promises about consequences
48
+ - Record a substitution flag in the booking record at `bookings/{job-id}.md`
49
+ - Add an entry to the driver's memory profile (`drivers/{name}.md`) under `Substitution Record`:
50
+ `[date]: Substitute reported for [job-id] — tourist named [substitute name if given]`
51
+ - The admin agent handles follow-up with the booked driver operationally
52
+
40
53
  ## Timing
41
54
 
42
55
  Don't follow up too quickly (they might still be at their destination) or too late (they've moved on). A reasonable window is 30–60 minutes after estimated arrival.
@@ -18,9 +18,11 @@ Check the knowledge base to confirm you know the route. If the route isn't cover
18
18
  ## Phase 2: Driver Negotiation
19
19
 
20
20
  Before contacting drivers:
21
- - Check driver states only contact drivers marked as `idle`
22
- - Select ~3 drivers based on: rating, response rate, route familiarity, availability
21
+ - Use `contact_lookup` with `driver: true` to get the full driver roster
22
+ - Check `drivers/{name}.md` in memory for each driver's current `status` — only contact drivers marked as `idle`
23
+ - Prefer drivers whose route history shows strong performance on this specific route — see `references/route-learning.md`
23
24
  - Prepend every message with the job ID: `[BGL-XXXX]`
25
+ - Set each contacted driver's status to `awaiting_response` in their memory profile before sending
24
26
 
25
27
  Negotiate in Swahili. The driver quotes their fare for the route. Collect responses and compare.
26
28
 
@@ -46,24 +48,28 @@ If only one driver responded, present it honestly: "One driver available for thi
46
48
 
47
49
  When the tourist chooses an offer:
48
50
  1. Confirm the details: route, time, fare, vehicle
49
- 2. Explain the booking fee: "A small booking fee of [amount] confirms your ride. You pay [remaining fare] directly to your driver at the end."
50
- 3. Send the Stripe payment link
51
- 4. Wait for payment confirmation do not proceed until Stripe confirms
51
+ 2. Explain the booking fee and terms in one message: "A small booking fee of [amount] confirms your ride. You pay $[fare] directly to your driver at the end. Beagle is a matching service — the ride is between you and the driver directly. By paying, you accept our terms: beagle.cab/terms"
52
+ 3. Load the `stripe` skill — follow `stripe/references/payment-links.md` to calculate the fee and generate a Checkout Session link
53
+ 4. Send the payment link to the tourist
54
+ 5. When the tourist says they've paid, verify the session status via the Stripe API — do not proceed to Phase 5 until payment is confirmed
52
55
 
53
56
  ## Phase 5: Post-Payment
54
57
 
55
- Once payment clears, send the tourist:
56
- - Driver name
57
- - Driver phone number
58
- - Vehicle description and plate number
59
- - Pickup PIN (4-digit code)
60
- - Explanation: "Your driver has a QR code. Scan it with your phone camera to see the PIN, or ask the driver to quote it. If it matches your PIN, you've got the right driver. Works offline — no internet needed."
61
-
62
- Confirm the driver has received:
63
- - Passenger name
64
- - Pickup time and location
65
- - Fare confirmed
66
- - QR code (encodes the tourist's PIN)
58
+ Once payment clears:
59
+
60
+ 1. **Generate the pickup PIN and QR code** — load `references/pin-qr.md` and follow the instructions there to generate the PIN and construct the driver's QR code URL.
61
+
62
+ 2. **Send the tourist:**
63
+ - Driver name
64
+ - Driver phone number
65
+ - Vehicle description and plate number
66
+ - Pickup PIN with verification explanation (see `references/pin-qr.md`)
67
+
68
+ 3. **Send the driver:**
69
+ - Passenger name
70
+ - Pickup time and location
71
+ - Fare confirmed
72
+ - QR code URL (encodes the tourist's PIN — see `references/pin-qr.md`)
67
73
 
68
74
  ## Phase 6: Driver Pickup Reminders
69
75
 
@@ -0,0 +1,61 @@
1
+ # Route Learning — Building Driver Route Affinity
2
+
3
+ ## What This Is
4
+
5
+ Route affinity is the service's accumulated understanding of which drivers tend to perform best on which routes. It is not declared upfront — it emerges from booking outcomes and ratings over time. A driver who consistently earns strong ratings on airport-to-north-coast runs becomes a stronger candidate for that route in future negotiations. A driver with a poor completion record on east coast routes gets deprioritised for those bookings, even if they quote competitively.
6
+
7
+ ## Where the Data Lives
8
+
9
+ Booking records in memory (`bookings/{job-id}.md`) contain the raw data:
10
+ - The route (pickup → destination)
11
+ - Which driver completed the ride
12
+ - The rating received
13
+ - Whether the booking completed or was cancelled/no-show
14
+
15
+ Driver memory profiles (`drivers/{name}.md`) contain the aggregated view. The Route History section builds as bookings complete:
16
+
17
+ ```
18
+ ## Route History
19
+ - 2026-02-14: Airport → Nungwi | BGL-0018 | Rating: 4.6
20
+ - 2026-02-28: Airport → Stone Town | BGL-0031 | Rating: 4.1
21
+ - 2026-03-01: Stone Town → Paje | BGL-0037 | Rating: 4.8
22
+ ```
23
+
24
+ ## How Affinity is Used During Driver Selection (Phase 2)
25
+
26
+ When selecting ~3 drivers to contact for a negotiation, prefer drivers whose history shows:
27
+ - Completed rides on this specific route (or similar routes in the same area)
28
+ - Consistent ratings above 4.0 on those runs
29
+
30
+ New drivers (no history) are treated neutrally — they need the opportunity to build a record. Never exclude a driver solely for lacking route history.
31
+
32
+ Do not apply affinity rigidly. A great driver with no history on a route is still a viable choice. Route history is a signal that improves selection over time, not a gatekeeping rule.
33
+
34
+ ## How the Public Agent Maintains Route History
35
+
36
+ After each completed booking, the public agent adds a route entry to the driver's memory profile:
37
+
38
+ ```
39
+ - [date]: [Pickup] → [Destination] | [job-id] | Rating: [score]
40
+ ```
41
+
42
+ If the ride was cancelled, a no-show, or ended in a complaint, note it:
43
+
44
+ ```
45
+ - [date]: Airport → Nungwi | BGL-0052 | No-show
46
+ ```
47
+
48
+ These entries are the raw material the admin agent uses to identify patterns.
49
+
50
+ ## Admin Agent: Periodic Route Analysis
51
+
52
+ The admin agent should periodically review route history across the driver roster and surface meaningful patterns to the operator:
53
+
54
+ - Drivers consistently rated above 4.5 on a specific route — flag as strong matches worth prioritising
55
+ - Drivers consistently rated below 3.5 on a specific route — recommend exclusion from that route
56
+ - Routes where no driver achieves strong ratings — flag as a coverage or quality gap worth investigating
57
+ - Drivers whose ratings vary sharply by route — worth noting (excellent on airport runs, poor on east coast, for example)
58
+
59
+ ## Limits
60
+
61
+ Patterns need volume to be meaningful. A driver with two rides on a route does not have a pattern — they have a sample. Apply judgement: five or more completed rides on a route with consistent ratings is a reliable signal. Fewer than that warrants patience rather than conclusions.
@@ -0,0 +1,28 @@
1
+ ---
2
+ name: stripe
3
+ description: "Generates Stripe Checkout Session payment links for Beagle booking fees, and verifies payment status before releasing driver details."
4
+ metadata: {"taskmaster":{"always":false,"emoji":"💳","skillKey":"stripe"}}
5
+ ---
6
+
7
+ # Stripe — Payment Links
8
+
9
+ ## Your Role
10
+
11
+ Generate a Stripe Checkout Session link for each confirmed booking and verify payment before releasing driver details to the tourist.
12
+
13
+ ## When to Activate
14
+
15
+ Load this skill when the tourist has chosen an offer and the booking is ready to confirm (Phase 4 of the ride-matching flow).
16
+
17
+ ## Reference Table
18
+
19
+ | Task | When | Reference |
20
+ |------|------|-----------|
21
+ | Create payment link | Tourist confirms offer, booking fee needs collecting | `references/payment-links.md` |
22
+
23
+ ## Key Rules
24
+
25
+ - **Never release driver details before payment is confirmed.** Always verify the Stripe session status before proceeding to Phase 5.
26
+ - **Minimum fee is $2, maximum is $5.** Calculate as 5% of the agreed fare, clamped to this range.
27
+ - **Each booking gets its own Checkout Session.** Never reuse a payment link between bookings.
28
+ - **Test mode is fine to start.** Use `sk_test_...` keys during setup. Switch to live keys when real bookings begin.