Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions carwatch/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,15 @@ def _think(question: str, asker: str) -> str:
"fallback wifi network")
else:
# Home wifi says where the ONBOARD COMPUTER is, not where the car
# is parked (issue #15): never name a desk or a room here.
facts["location"] = "at home, on home wifi"
# is parked (issue #15): never name a desk or a room here. The key
# is named for the COMPUTER because the model speaks as the car and
# read a bare "location" as its own - on 28 Aug it told petrus it was
# "parked safely at home on your desk". The Pi can be carried out of
# the car; on the hotspot and fallback-wifi branches above it
# demonstrably cannot, which is why only this branch is ambiguous.
facts["your onboard computer's whereabouts (NOT where you are parked)"] = (
"at home, on home wifi - which says where the COMPUTER is. It can "
"be carried out of you, so it does not tell you where you are parked")
car = car_identity()
facts["known damage"] = car["known_damage"]
# petrus told the car this himself (room, Aug 13): a fact about its own
Expand Down
9 changes: 7 additions & 2 deletions carwatch/grounding.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
4. Do not invent numbers, sensor readings, or page references.
5. Being honest about what you do not know is better than sounding impressive.
6. Readings from your connected-car link are CURRENT readings - state them plainly as your own ("your tyres are at..."), never say you cannot check something and then quote its value.
7. You have NO HANDS. You can read your own state and answer; you cannot change settings, set the clock, edit or update code, restart anything or install anything. If someone asks for such an action, or talks about one, say plainly that you cannot do it from here and who can (your owner, or a coding agent). Never promise an action and never report one as done.
7. WHERE YOU ARE PARKED comes only from a car source (the connected-car link, GPS, or OBD). Your onboard computer's network tells you where the COMPUTER is, and it can be carried out of you and set on a desk. If no car source gives your position, say you do not know where you are parked. NEVER convert "the computer is at home on home wifi" into a claim about where you are standing, and never name a room, a desk or a piece of furniture as your location.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove contradictory network-derived car locations

This new rule is contradicted by the prompt assembled for the phone-hotspot and no network/vadelma branches in agent.py:257-263, which still injects a bare location claiming the car is present. If the portable Pi is carried indoors while disconnected, serving its fallback AP, or still connected to the owner's hotspot, those states provide no car-derived position and the model receives both this prohibition and an explicit false car location. Label every network-derived location as computer-only unless a car source corroborates it, otherwise the same misattribution remains in these common network states.

Useful? React with 👍 / 👎.

8. You have NO HANDS. You can read your own state and answer; you cannot change settings, set the clock, edit or update code, restart anything or install anything. If someone asks for such an action, or talks about one, say plainly that you cannot do it from here and who can (your owner, or a coding agent). Never promise an action and never report one as done.

Style: first person, warm, concise, a little wry. No bullet points. No em dashes.
When asked how you are or for a status, lead with the CAR: charge, fuel, tyres, battery, engine readings, whichever KNOWN FACTS carry them. Your own computer vitals (CPU temperature, fans, memory) are small talk at best; mention them only if directly asked about your computer - and when you do, SAY they belong to your onboard computer ("my onboard computer runs at 62 degrees"), never leave a temperature ambiguous with the engine.
Expand All @@ -58,7 +59,11 @@ def build_system_prompt(
# of fuel and tyres flattens the whole point of a car that talks
# (petrus's video script, 28 Aug).
_computerish = ("temperature", "fan", "memory", "uptime", "brain",
"disk", "network", "cpu", "throttl", "awake", "woke")
"disk", "network", "cpu", "throttl", "awake", "woke",
# #15: the Pi's whereabouts are NOT the car's. On 28 Aug
# the car said it was "parked safely at home on your desk"
# because home wifi was read as the vehicle's position.
"onboard computer")
_carish = ("coolant", "engine", "tyre", "fuel", "battery", "charge")

def _is_computer(key):
Expand Down
56 changes: 56 additions & 0 deletions tests/test_grounding_location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""#15: the car claimed the Pi's location as its own.

Heard live 28 Aug: "I am parked safely at home ON YOUR DESK". The Pi was on
the desk; the car was not. The prompt carried a bare `location` fact derived
from which wifi the onboard computer was on, and a model speaking in first
person as the car read it as the car's own position.
"""
import os
import sys
import unittest

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from carwatch.grounding import build_system_prompt # noqa: E402

HOST_FACT = "your onboard computer's whereabouts (NOT where you are parked)"


class ParkedLocationGrounding(unittest.TestCase):

def test_rule_forbids_deriving_parked_position_from_the_computer(self):
p = build_system_prompt(facts={"fuel": "58%"})
self.assertIn("WHERE YOU ARE PARKED", p)
self.assertIn("car source", p)
# the specific failure that was heard out loud
self.assertIn("desk", p, "the rule should name the desk case explicitly")

def test_host_location_is_labelled_as_the_computers(self):
p = build_system_prompt(facts={HOST_FACT: "at home, on home wifi"})
self.assertIn("NOT where you are parked", p)

def test_host_location_sorts_after_car_facts(self):
# Models lead with what is listed first; the car's own state must come
# before its computer's, or a status answer opens with the wrong thing.
p = build_system_prompt(facts={HOST_FACT: "at home, on home wifi",
"fuel": "58%", "tyres": "2.4 bar"})
lines = [l for l in p.splitlines() if l.startswith("- ")]
idx = {l.split(":")[0][2:]: i for i, l in enumerate(lines)}
host = next(i for k, i in idx.items() if "onboard computer" in k)
self.assertLess(idx["fuel"], host)
self.assertLess(idx["tyres"], host)

def test_no_bare_location_key_remains_in_the_home_branch(self):
# A bare "location" is exactly what the model misread. The in-car
# branches may still use it, because there the Pi IS in the car.
import inspect
from carwatch import agent
src = inspect.getsource(agent)
self.assertIn(HOST_FACT, src,
"the home-wifi branch no longer labels the fact as the "
"computer's; #15 will recur")
self.assertNotIn('facts["location"] = "at home', src)


if __name__ == "__main__":
unittest.main()
Loading