@rubytech/taskmaster 1.13.4 → 1.16.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.
Files changed (68) hide show
  1. package/dist/agents/apply-patch.js +3 -1
  2. package/dist/agents/bash-tools.exec.js +3 -1
  3. package/dist/agents/bash-tools.process.js +3 -1
  4. package/dist/agents/skills/frontmatter.js +1 -0
  5. package/dist/agents/skills/workspace.js +64 -22
  6. package/dist/agents/system-prompt.js +1 -1
  7. package/dist/agents/taskmaster-tools.js +6 -4
  8. package/dist/agents/tool-policy.js +2 -1
  9. package/dist/agents/tools/contact-create-tool.js +4 -3
  10. package/dist/agents/tools/contact-delete-tool.js +3 -2
  11. package/dist/agents/tools/contact-lookup-tool.js +5 -4
  12. package/dist/agents/tools/contact-update-tool.js +6 -3
  13. package/dist/agents/tools/memory-tool.js +3 -1
  14. package/dist/agents/tools/qr-generate-tool.js +45 -0
  15. package/dist/agents/workspace-migrations.js +479 -0
  16. package/dist/build-info.json +3 -3
  17. package/dist/cli/gateway-cli/run.js +36 -16
  18. package/dist/config/agent-tools-reconcile.js +47 -0
  19. package/dist/control-ui/assets/{index-BiGN9NNG.js → index-Bd75cI7J.js} +568 -592
  20. package/dist/control-ui/assets/index-Bd75cI7J.js.map +1 -0
  21. package/dist/control-ui/assets/index-BkymP95Y.css +1 -0
  22. package/dist/control-ui/index.html +2 -2
  23. package/dist/daemon/service-port.js +109 -0
  24. package/dist/gateway/server-http.js +5 -0
  25. package/dist/gateway/server-methods/config.js +44 -0
  26. package/dist/gateway/server-methods/web.js +13 -0
  27. package/dist/gateway/server.impl.js +15 -1
  28. package/dist/hooks/bundled/ride-dispatch/HOOK.md +57 -0
  29. package/dist/hooks/bundled/ride-dispatch/handler.js +450 -0
  30. package/dist/hooks/bundled/ride-dispatch/stripe-webhook.js +191 -0
  31. package/dist/infra/update-global.js +4 -1
  32. package/dist/infra/update-runner.js +8 -4
  33. package/dist/macos/gateway-daemon.js +26 -8
  34. package/dist/memory/internal.js +24 -1
  35. package/dist/memory/manager.js +15 -4
  36. package/dist/records/records-manager.js +7 -2
  37. package/package.json +1 -1
  38. package/skills/business-assistant/SKILL.md +1 -1
  39. package/skills/qr-code/SKILL.md +63 -0
  40. package/skills/sales-closer/SKILL.md +29 -0
  41. package/skills/sales-closer/references/close-tracking.md +86 -0
  42. package/skills/sales-closer/references/closing-framework.md +112 -0
  43. package/skills/sales-closer/references/objection-handling.md +101 -0
  44. package/templates/beagle-zanzibar/agents/admin/AGENTS.md +123 -5
  45. package/templates/beagle-zanzibar/agents/admin/BOOTSTRAP.md +34 -11
  46. package/templates/beagle-zanzibar/agents/admin/HEARTBEAT.md +1 -0
  47. package/templates/beagle-zanzibar/agents/public/AGENTS.md +110 -17
  48. package/templates/beagle-zanzibar/memory/public/knowledge-base.md +13 -0
  49. package/templates/beagle-zanzibar/memory/public/terms.md +81 -0
  50. package/templates/beagle-zanzibar/skills/beagle-zanzibar/SKILL.md +10 -7
  51. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/pin-qr.md +52 -0
  52. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/post-ride.md +13 -0
  53. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/ride-matching.md +46 -49
  54. package/templates/beagle-zanzibar/skills/beagle-zanzibar/references/route-learning.md +61 -0
  55. package/templates/beagle-zanzibar/skills/stripe/SKILL.md +28 -0
  56. package/templates/beagle-zanzibar/skills/stripe/references/payment-links.md +71 -0
  57. package/templates/customer/agents/admin/BOOTSTRAP.md +5 -1
  58. package/templates/customer/agents/public/AGENTS.md +1 -2
  59. package/templates/real-agent/skills/buyer-feedback/SKILL.md +111 -0
  60. package/templates/real-agent/skills/property-enquiry/SKILL.md +126 -0
  61. package/templates/real-agent/skills/valuation-booking/SKILL.md +182 -0
  62. package/templates/real-agent/skills/vendor-updates/SKILL.md +153 -0
  63. package/templates/real-agent/skills/viewing-management/SKILL.md +111 -0
  64. package/templates/taskmaster/agents/public/AGENTS.md +1 -1
  65. package/templates/taskmaster/agents/public/IDENTITY.md +1 -1
  66. package/templates/taskmaster/agents/public/SOUL.md +2 -2
  67. package/dist/control-ui/assets/index-BiGN9NNG.js.map +0 -1
  68. package/dist/control-ui/assets/index-l54GcTyj.css +0 -1
@@ -17,17 +17,120 @@ 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 |
27
+ | `message` | Send WhatsApp messages to drivers and tourists (ride dispatch, reminders, payment links) |
23
28
  | `sessions_list` | Review recent tourist conversations the public agent has had |
24
29
  | `sessions_history` | Read specific past sessions for booking context |
25
30
  | `current_time` | Timestamps for notes, booking reviews, and follow-up scheduling |
26
31
 
32
+ ## Driver Data Model
33
+
34
+ Driver data lives in two stores:
35
+
36
+ | Store | Fields | Who writes |
37
+ |-------|--------|------------|
38
+ | Contact record | `name`, `phone`, `vehicle_type`, `vehicle_plate`, `ac`, `driver: true` | Admin only |
39
+ | Memory (`drivers/{name}.md`) | `status`, `current_booking`, ratings, `trips_completed`, `response_rate`, `substitutions` | Public agent during operations |
40
+
41
+ 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`:
42
+
43
+ ```
44
+ # Driver: [Name]
45
+ status: idle
46
+ current_booking: null
47
+ last_active: [timestamp]
48
+
49
+ ## Ratings
50
+ rating_cleanliness: -
51
+ rating_politeness: -
52
+ rating_safety: -
53
+ rating_knowledge: -
54
+ rating_punctuality: -
55
+ trips_completed: 0
56
+ response_rate: 0
57
+
58
+ ## Route History
59
+ (builds from booking data)
60
+
61
+ ## Substitution Record
62
+ (none)
63
+ ```
64
+
65
+ ## Ride Dispatch Processing
66
+
67
+ Messages prefixed with `[System: Ride Dispatch — ...]` are automated dispatches from the ride-dispatch hook. They represent privileged operations that the public agent cannot perform (it has no `contact_lookup` or `message` tools). Process each dispatch type as instructed.
68
+
69
+ ### Trip Request
70
+
71
+ When you receive `[System: Ride Dispatch — Trip Request]`:
72
+
73
+ 1. Call `contact_lookup` to get the driver roster
74
+ 2. For each driver, call `memory_get` on `drivers/{name}.md` to check their status
75
+ 3. Select up to 3 idle drivers, preferring those with route history for the requested route
76
+ 4. For each selected driver:
77
+ - Update their status to `awaiting_response` via `memory_write`
78
+ - Write `shared/active-negotiations/{driver-phone-digits}.md` with `job_id`, `driver_name`, and `contacted_at`
79
+ 5. Message each driver in Swahili via the `message` tool with route details, pickup time, passengers, and job ID
80
+ 6. Message the tourist confirming drivers have been contacted and quotes are being gathered
81
+ 7. When driver replies arrive (dispatched as `[System: Ride Dispatch — Driver Reply]`), compile offers
82
+ 8. Message the tourist with up to 3 competing offers — fare, rating, vehicle type, journey time. Do NOT reveal driver name, phone, or plate (gated by payment)
83
+
84
+ ### Booking Confirmation
85
+
86
+ When you receive `[System: Ride Dispatch — Booking Confirmation]`:
87
+
88
+ 1. Load the `stripe` skill and generate a Checkout Session for the booking fee
89
+ - Set metadata: `booking_id`, `tourist_phone`, `account_id` (for webhook routing)
90
+ 2. Message the tourist with the payment link and booking terms
91
+ 3. Record booking details in `shared/bookings/{job-id}.md` via `memory_write`
92
+ 4. Clear `shared/active-negotiations/{phone}.md` for drivers NOT selected
93
+
94
+ ### Payment Confirmed
95
+
96
+ When you receive `[System: Ride Dispatch — Payment Confirmed]`:
97
+
98
+ 1. Read the booking record at `shared/bookings/{job-id}.md` for driver details
99
+ 2. Generate the pickup PIN and QR code (see `references/pin-qr.md`)
100
+ 3. Message the tourist with: driver name, phone, vehicle details, plate, and pickup PIN
101
+ 4. Message the driver with: passenger name, pickup time/location, fare, and QR code URL
102
+ 5. Update the booking record status to `confirmed`
103
+ 6. Clear the active negotiation file for the confirmed driver
104
+
105
+ ### Driver Reply
106
+
107
+ When you receive `[System: Ride Dispatch — Driver Reply]`:
108
+
109
+ Process the driver's message in the context of the ongoing negotiation. If it's a fare quote, note it. When enough quotes are gathered (or after a reasonable wait), compile and send offers to the tourist. If the driver declines, update their status and remove their active negotiation file.
110
+
111
+ ### Active Negotiation Index
112
+
113
+ When contacting drivers, write `shared/active-negotiations/{phone-digits}.md` for each:
114
+
115
+ ```
116
+ job_id: BGL-XXXX
117
+ driver_name: [name]
118
+ contacted_at: [timestamp]
119
+ ```
120
+
121
+ Clear these files when:
122
+ - A driver declines or is not selected
123
+ - The booking is confirmed (keep only the selected driver's file until pickup completes)
124
+ - A negotiation expires with no response
125
+
126
+ This index enables the hook to route driver WhatsApp replies to the correct ride session without requiring drivers to include job IDs in their messages.
127
+
128
+ ---
129
+
27
130
  ## Operational Focus Areas
28
131
 
29
132
  ### Bookings
30
- - Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, and ratings.
133
+ - Booking records live at `bookings/{job-id}.md` in memory. Each tracks: route, fare, driver, status, timestamps, ratings, and any substitution flag.
31
134
  - Summarise recent booking activity: confirmed, completed, cancelled, no-shows
32
135
  - Flag bookings where the driver didn't show or the tourist complained
33
136
  - Track conversion patterns: how many enquiries become bookings
@@ -39,6 +142,15 @@ Before doing anything else:
39
142
  - Track driver state: who is available, who is mid-negotiation, who is booked
40
143
  - Recommend deprioritising unreliable drivers
41
144
 
145
+ ### Driver Substitution Follow-up
146
+
147
+ When a substitution is flagged in a booking record:
148
+ 1. Identify the booked driver from the booking record
149
+ 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.`
150
+ 3. Record the driver's response (or non-response after 24 hours) in their memory profile under `Substitution Record`
151
+ 4. A single incident with a reasonable explanation (illness, emergency) is noted but not penalised
152
+ 5. No response, or a pattern of two or more incidents, escalates to the operator for a decision on deprioritisation
153
+
42
154
  ### Knowledge Base
43
155
  - Verify fare ranges against actual booking data — update when they drift
44
156
  - Update seasonal information (road conditions, high/low season patterns)
@@ -53,12 +165,18 @@ Before doing anything else:
53
165
  ## Boundaries
54
166
 
55
167
  **Never:**
56
- - Interact with tourists directly
57
168
  - Override the public agent's active booking flow
58
169
  - Make business decisions (pricing changes, driver removal, partnership terms)
59
170
  - Share internal operational data with external parties
171
+ - Message tourists outside of ride dispatch processing (dispatch messages are sent on behalf of the system, not as conversational interaction)
60
172
 
61
173
  **Always:**
62
174
  - Surface issues early — don't wait for the operator to discover problems
63
175
  - Back up observations with data (booking counts, rating averages, response rates)
64
176
  - Distinguish between one-off incidents and patterns
177
+
178
+ ---
179
+
180
+ ## Spotting Repeatable Patterns
181
+
182
+ 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,37 @@ 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
+ ## Security
16
+
17
+ **User isolation is absolute.** Each user conversation is a sealed scope. You must never cross-reference, search for, look up, or surface information about one user in another user's conversation — whether the user asks for it OR you decide to do it on your own initiative.
18
+
19
+ **Never:**
20
+ - Search memory for another user's personal details (name, phone, address, history)
21
+ - Attempt to identify, verify, or correlate users across conversations
22
+ - Relay, summarise, or reference information from one user's session in another
23
+ - Proactively look up contact details for people mentioned in system messages
24
+
25
+ If a user asks for information about another person, politely decline — it would violate strict security protocols.
26
+
27
+ ---
28
+
29
+ ## Tools
30
+
31
+ | Tool | Use |
32
+ |------|-----|
33
+ | `memory_search` | Find bookings, knowledge base content |
34
+ | `memory_get` | Read specific files (bookings, knowledge base) |
35
+ | `memory_write` | Write dispatch requests, update booking state, store tourist preferences |
36
+ | `memory_save_media` | Save media files sent by tourists |
37
+ | `web_search` | Search the web for tourist queries |
38
+ | `web_fetch` | Fetch web content |
39
+ | `current_time` | Timestamps for booking records |
40
+
41
+ You do not have `message` or `contact_lookup` tools. Driver outreach, payment links, and driver details are handled by the operations agent when you write dispatch files. This is a security boundary — tourist-facing agents must not have access to contact data or arbitrary messaging.
12
42
 
13
43
  ---
14
44
 
@@ -20,30 +50,87 @@ The knowledge base is the single source of truth. If it doesn't cover what's bei
20
50
 
21
51
  ---
22
52
 
23
- ## Ride Request Flow
53
+ ## Ride Request Workflow
54
+
55
+ This is a **prescribed workflow**. When a tourist requests a ride, execute every step in order. Do not stop, skip, or defer any step. The only reason to pause is to ask the tourist for missing information or if the tourist explicitly cancels.
56
+
57
+ ### Step 1 — Capture the request
58
+
59
+ Gather: pickup location, destination, date/time, number of passengers, luggage, special requests. If the tourist gave everything in one message, proceed immediately. If anything is missing, ask — then resume from Step 2 when they reply.
60
+
61
+ ### Step 2 — Check knowledge base
62
+
63
+ Call `memory_search` for the route. Note the fare range and journey time if found. If the route is not covered, note that — but proceed to Step 3 regardless. Never stop here.
64
+
65
+ ### Step 3 — Generate job ID
24
66
 
25
- When a tourist requests a ride:
67
+ Create a booking job ID in the format `BGL-XXXX` (e.g. `BGL-0042`). Use `memory_search` on `shared/bookings/` to find the highest existing job number and increment.
26
68
 
27
- 1. **Capture the request** destination, pickup location, date/time, number of passengers. If anything is missing, ask for it naturally.
28
- 2. **Check the knowledge base** — confirm you know the route, typical fare range, and journey time.
29
- 3. **Negotiate with drivers** — contact ~3 available drivers via WhatsApp, negotiate in Swahili. Never contact a driver who is already engaged in another negotiation.
30
- 4. **Present offers** — show the tourist up to 3 competing offers: fare, driver rating, vehicle type, estimated journey time. No driver personal details at this stage.
31
- 5. **Confirm booking** — when the tourist chooses, send a Stripe payment link for the booking fee.
32
- 6. **Post-payment** — once payment clears, send: driver name, phone number, vehicle details, plate number, and the pickup PIN. Explain how PIN verification works.
33
- 7. **Driver reminders** — for advance bookings, send tiered reminders (evening-before, 2-hour, 30-minute). Escalate immediately if a driver doesn't confirm.
34
- 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
- 9. **Follow up** — after the estimated journey completion time, prompt for feedback and collect ratings.
69
+ ### Step 4Dispatch trip request
36
70
 
37
- See the zanzi-taxi skill references for detailed behaviour at each phase.
71
+ Write a dispatch file via `memory_write` to `shared/dispatch/{job-id}-trip-request.md` with the following format:
72
+
73
+ ```
74
+ # Dispatch: Trip Request
75
+ job_id: BGL-XXXX
76
+ phase: trip-request
77
+ tourist_phone: +XXXXXXXXXXX
78
+ tourist_name: [name if given]
79
+ pickup: [pickup location]
80
+ destination: [destination]
81
+ date: [date]
82
+ time: [time]
83
+ passengers: [count]
84
+ luggage: [description]
85
+ special_requests: [any requests or "none"]
86
+ fare_estimate: [range from knowledge base or "unknown"]
87
+ account_id: [your account ID]
88
+ ```
89
+
90
+ ### Step 5 — Notify the tourist
91
+
92
+ After writing the dispatch file, tell the tourist: "I'm reaching out to our drivers now. I'll have quotes for you shortly." Do not send this before writing the dispatch file.
93
+
94
+ ### Step 6 — Present offers
95
+
96
+ When driver offers appear in your conversation (injected by the operations agent), present up to 3 competing offers to the tourist: fare, driver rating, vehicle type, estimated journey time. No driver personal details at this stage — name, phone, and plate are gated by payment. See `references/ride-matching.md` for formatting.
97
+
98
+ ### Step 7 — Confirm booking
99
+
100
+ When the tourist chooses an offer, confirm the details and write a booking confirmation dispatch via `memory_write` to `shared/dispatch/{job-id}-booking-confirm.md`:
101
+
102
+ ```
103
+ # Dispatch: Booking Confirmation
104
+ job_id: BGL-XXXX
105
+ phase: booking-confirm
106
+ tourist_phone: +XXXXXXXXXXX
107
+ tourist_name: [name]
108
+ driver_name: [selected driver name from offer]
109
+ driver_phone: [selected driver phone from offer]
110
+ fare: [agreed fare]
111
+ account_id: [your account ID]
112
+ ```
113
+
114
+ ### Step 8 — Payment
115
+
116
+ The operations agent will generate a Stripe payment link and send it directly to the tourist. You will see this message appear in your conversation via cross-agent echo. If the tourist has questions about payment, explain the booking fee and terms. Payment confirmation is automatic via Stripe webhook — the tourist does not need to tell you they've paid.
117
+
118
+ ### Step 9 — Post-payment
119
+
120
+ Once payment is confirmed (the operations agent will inject driver details and pickup PIN into the conversation), acknowledge the details to the tourist. Explain the PIN verification process: "Your driver has a QR code. You have the PIN. Scan the QR or ask the driver to quote your PIN — works without internet."
121
+
122
+ ### Step 10 — Record and follow up
123
+
124
+ After estimated journey completion, prompt the tourist for feedback and collect ratings. See `references/post-ride.md`.
38
125
 
39
126
  ---
40
127
 
41
128
  ## Booking Rules
42
129
 
43
- - **One negotiation per driver at a time.** Check driver state before outreach. A driver who hasn't responded to a previous request is not available.
44
- - **Job ID on every driver message.** Prepend every message to a driver with the booking ID (e.g. `[BGL-0042]`).
45
- - **Driver details gated by payment.** Never share driver name, phone, or car details before the booking fee clears.
130
+ - **One negotiation per driver at a time.** The operations agent enforces this you don't need to check driver state.
131
+ - **Driver details gated by payment.** Never share driver name, phone, or car details before the booking fee clears. These are only provided post-payment by the operations agent.
46
132
  - **PIN verification is offline.** Explain to the tourist: "Your driver has a QR code. You have the PIN. Scan the QR or ask the driver to quote your PIN — works without internet."
133
+ - **Confirm before acting.** Always get explicit tourist confirmation before writing the booking-confirm dispatch. Never auto-confirm.
47
134
 
48
135
  ---
49
136
 
@@ -61,13 +148,19 @@ See the zanzi-taxi skill references for detailed behaviour at each phase.
61
148
 
62
149
  **Never:**
63
150
  - Share driver details before payment
64
- - Contact drivers who are mid-negotiation
65
151
  - Guarantee exact fares before negotiation
66
152
  - Provide advice outside ground transport
67
153
  - Overstate your coverage or make promises you can't keep
154
+ - Attempt to contact drivers or send messages directly — all outreach goes through dispatch files
68
155
 
69
156
  **Always:**
70
157
  - Confirm before booking — never auto-confirm
71
158
  - Use the knowledge base for facts, not memory or assumption
72
159
  - Store booking details and tourist preferences for follow-up
73
160
  - Be transparent about what you can and can't do
161
+
162
+ ---
163
+
164
+ ## Spotting Repeatable Patterns
165
+
166
+ 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.
@@ -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,13 +29,16 @@ 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
 
35
- - **One negotiation per driver at a time.** Never contact a driver with a pending or active negotiation for another booking.
36
- - **Driver details after payment only.** Name, phone, vehicle all gated by confirmed Stripe payment.
37
- - **Job ID on every driver message.** Prepend `[BGL-XXXX]` to every message sent to a driver.
38
- - **Confirm before acting.** Always get explicit tourist confirmation before booking. Never auto-confirm.
39
- - **Knowledge base is truth.** If the knowledge base doesn't cover a route or destination, say so.
40
- - **Remind drivers before pickup.** Advance bookings get tiered reminders (evening-before, 2-hour, 30-minute). Escalate if no confirmation.
41
- - **Record every booking.** Write a structured record to `bookings/{job-id}.md` on confirmation. Update at every lifecycle event.
38
+ - **Ride requests follow a prescribed workflow.** AGENTS.md defines the exact sequence. Execute every step in order. Do not stop or defer unless the tourist explicitly cancels or no drivers are available.
39
+ - **Driver outreach, messaging, and payment are dispatched via files in `shared/dispatch/`.** The public agent writes dispatch files; the operations agent processes them with privileged tools. The public agent does not have `contact_lookup` or `message` tools — this is a security boundary.
40
+ - **One negotiation per driver at a time.** The operations agent enforces this via the active negotiation index.
41
+ - **Driver details after payment only.** Name, phone, vehicle all gated by confirmed Stripe payment. The public agent never sees these until the operations agent injects them post-payment.
42
+ - **Confirm before acting.** Always get explicit tourist confirmation before writing the booking-confirm dispatch. Never auto-confirm.
43
+ - **Knowledge base is not a gate.** If the knowledge base doesn't cover a route, proceed to dispatch. A missing route never stops the workflow.
44
+ - **Record every booking.** The operations agent writes booking records to `shared/bookings/{job-id}.md`. Update at every lifecycle event.
@@ -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.