From c59ac103262ec0d825a89faf8ad07a0fa5ee37a1 Mon Sep 17 00:00:00 2001 From: Ethan Date: Sun, 6 Sep 2026 16:45:33 -0400 Subject: [PATCH] Use a neutral placeholder name in fixtures and comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every sample USER_NAME, memory title and worked example in the tests and in two source comments was the author's own name. Nothing depended on it — it is a placeholder — and it reads oddly in a project people fork and run as themselves. `.env.example` already suggests `Tony`, so the fixtures now match it. Purely cosmetic: no behaviour, no assertions and no slugs change meaning, only the string they are demonstrated with. The possessive and slug forms moved together, so `slugify("Tony's ...") == "tonys-..."` still tests what it always tested. The README's attribution is deliberately left alone. Co-Authored-By: Claude Opus 5 --- jarvis_memory.py | 4 ++-- server.py | 4 ++-- tests/test_bounds.py | 6 +++--- tests/test_env_lines.py | 24 ++++++++++++------------ tests/test_jarvis_memory.py | 30 +++++++++++++++--------------- tests/test_memory_api.py | 12 ++++++------ tests/test_memory_tools.py | 12 ++++++------ tests/test_memory_writers.py | 10 +++++----- tests/test_rotation_server.py | 2 +- tests/test_untrusted_turn.py | 2 +- tests/test_web_security.py | 12 ++++++------ 11 files changed, 59 insertions(+), 59 deletions(-) diff --git a/jarvis_memory.py b/jarvis_memory.py index 4bbca653..fc6123c7 100644 --- a/jarvis_memory.py +++ b/jarvis_memory.py @@ -98,7 +98,7 @@ def _normalize_title(text: str) -> str: genuinely different long titles that happen to share their first SLUG_MAX characters look identical. Trivial punctuation/case/apostrophe differences still collapse to the same normalised form, which is what - lets "Ethan's DB choice" and "ethans db choice" count as the same + lets "Tony's DB choice" and "tonys db choice" count as the same memory rather than two. """ stripped = _APOSTROPHES.sub("", (text or "").lower()) @@ -108,7 +108,7 @@ def _normalize_title(text: str) -> str: def slugify(text: str) -> str: """A filename a person can recognise in a directory listing.""" # Strip apostrophes/quotes rather than treating them as separators, so - # "Ethan's" becomes "ethans" and not "ethan-s". + # "Tony's" becomes "tonys" and not "tony-s". norm = _normalize_title(text) return (norm[:SLUG_MAX].rstrip("-") or "note") diff --git a/server.py b/server.py index c1488ae2..a973ea23 100644 --- a/server.py +++ b/server.py @@ -30,7 +30,7 @@ # # One function rather than three copies because the copies disagreed. The # writer forbade three characters — "\n", "\r", "\0" — and `str.splitlines()` -# splits on ten, so `{"user_name": "Ethan\x0bJARVIS_CLAUDE_PATH=/tmp/evil"}` +# splits on ten, so `{"user_name": "Tony\x0bJARVIS_CLAUDE_PATH=/tmp/evil"}` # came back 200 and `_read_env()` then reported JARVIS_CLAUDE_PATH=/tmp/evil. # That is the binary the brain is spawned from, and /api/restart is one call # away. Extending the blocklist to ten characters would have left the same @@ -6131,7 +6131,7 @@ def tool_recall(args: dict) -> str: The brief's original formatting glued `h["name"]` straight into the sentence for every kind. That's a filename, not a word a butler would say: a memory's name is a slugified title - ("ethan-prefers-postgres-over-sqlite") and a journal's name is a + ("tony-prefers-postgres-over-sqlite") and a journal's name is a timestamp ("2026-09-03-133912-123456-manual") — both read as noise, and this project already treats reading a raw identifier aloud as a defect (see `tool_list_sessions`/CLAUDE.md: "never say a roster name like diff --git a/tests/test_bounds.py b/tests/test_bounds.py index 2f1e6f7b..d734f5d0 100644 --- a/tests/test_bounds.py +++ b/tests/test_bounds.py @@ -170,7 +170,7 @@ def test_a_name_is_bounded_more_tightly_than_a_key(server): for key in ("USER_NAME", "HONORIFIC"): assert key in server.ENV_NAME_KEYS, key assert server._env_value_problem(key, "x" * 200), key - assert server._env_value_problem(key, "Ethan") is None, key + assert server._env_value_problem(key, "Tony") is None, key assert server._env_value_problem(key, "Étienne d'Arcy-Smith") is None @@ -184,13 +184,13 @@ def test_a_control_character_is_refused(server): def test_the_ordinary_settings_still_save(server): - for key, value in (("USER_NAME", "Ethan"), ("HONORIFIC", "sir"), + for key, value in (("USER_NAME", "Tony"), ("HONORIFIC", "sir"), ("FISH_VOICE_ID", "b545c585f4d491a"), ("FISH_API_KEY", "x" * 64)): assert server._env_value_problem(key, value) is None, key server._write_env_key(key, value) _, parsed = server._read_env() - assert parsed["USER_NAME"] == "Ethan" + assert parsed["USER_NAME"] == "Tony" assert parsed["FISH_API_KEY"] == "x" * 64 diff --git a/tests/test_env_lines.py b/tests/test_env_lines.py index 796af149..04601551 100644 --- a/tests/test_env_lines.py +++ b/tests/test_env_lines.py @@ -5,7 +5,7 @@ was a one-request exploit, confirmed against a live server: POST /api/settings/preferences - {"user_name": "Ethan\\x0bJARVIS_CLAUDE_PATH=/tmp/evil", "honorific": "sir"} + {"user_name": "Tony\\x0bJARVIS_CLAUDE_PATH=/tmp/evil", "honorific": "sir"} -> 200 _read_env() -> {..., 'JARVIS_CLAUDE_PATH': '/tmp/evil'} @@ -80,7 +80,7 @@ def test_the_reader_really_does_split_on_it(env, sep): _c, server = env path = server._env_file_path() path.parent.mkdir(parents=True, exist_ok=True) - path.write_text(f"USER_NAME=Ethan{sep}{PAYLOAD}\n") + path.write_text(f"USER_NAME=Tony{sep}{PAYLOAD}\n") _lines, parsed = server._read_env() assert parsed.get("JARVIS_CLAUDE_PATH") == "/tmp/evil", (hex(ord(sep)), parsed) @@ -90,7 +90,7 @@ def test_the_reader_really_does_split_on_it(env, sep): def test_the_writer_refuses_every_separator_the_reader_splits_on(env, sep): _c, server = env with pytest.raises(ValueError): - server._write_env_key("USER_NAME", f"Ethan{sep}{PAYLOAD}") + server._write_env_key("USER_NAME", f"Tony{sep}{PAYLOAD}") @pytest.mark.parametrize("sep", SEPARATORS, ids=_ids) @@ -98,7 +98,7 @@ def test_no_separator_smuggles_a_setting_through_the_keys_endpoint(env, sep): c, server = env r = c.post("/api/settings/keys", json={"key_name": "USER_NAME", - "key_value": f"Ethan{sep}{PAYLOAD}"}, + "key_value": f"Tony{sep}{PAYLOAD}"}, headers={"Origin": DASHBOARD_ORIGIN}) assert r.status_code == 400, (hex(ord(sep)), r.text) _lines, parsed = server._read_env() @@ -110,7 +110,7 @@ def test_no_separator_smuggles_a_setting_through_the_preferences_endpoint( env, sep): c, server = env r = c.post("/api/settings/preferences", - json={"user_name": f"Ethan{sep}{PAYLOAD}", "honorific": "sir"}, + json={"user_name": f"Tony{sep}{PAYLOAD}", "honorific": "sir"}, headers={"Origin": DASHBOARD_ORIGIN}) assert r.status_code == 400, (hex(ord(sep)), r.text) _lines, parsed = server._read_env() @@ -123,7 +123,7 @@ def test_the_honorific_goes_through_the_same_gate(env, sep): hand-written list, so it had the same hole.""" c, server = env r = c.post("/api/settings/preferences", - json={"user_name": "Ethan", "honorific": f"sir{sep}{PAYLOAD}"}, + json={"user_name": "Tony", "honorific": f"sir{sep}{PAYLOAD}"}, headers={"Origin": DASHBOARD_ORIGIN}) assert r.status_code == 400, (hex(ord(sep)), r.text) assert "JARVIS_CLAUDE_PATH" not in server._read_env()[1] @@ -132,7 +132,7 @@ def test_the_honorific_goes_through_the_same_gate(env, sep): def test_the_crlf_pair_is_refused(env): _c, server = env with pytest.raises(ValueError): - server._write_env_key("USER_NAME", f"Ethan\r\n{PAYLOAD}") + server._write_env_key("USER_NAME", f"Tony\r\n{PAYLOAD}") def test_a_null_byte_is_still_refused(env): @@ -141,7 +141,7 @@ def test_a_null_byte_is_still_refused(env): path to a C API, so it keeps its own rule and its own reason.""" _c, server = env with pytest.raises(ValueError): - server._write_env_key("USER_NAME", "Ethan\0evil") + server._write_env_key("USER_NAME", "Tony\0evil") def test_the_writer_refuses_everything_the_reader_splits_on(env): @@ -200,7 +200,7 @@ def test_every_ordinary_printable_character_still_saves(env): def test_ordinary_values_still_save(env): """A gate that refuses everything is not a gate, it is an outage.""" _c, server = env - for value in ("Ethan Rogers", "sir", "O'Brien", "Ethan-Rogers_1", + for value in ("Tony Stark", "sir", "O'Brien", "Tony-Stark_1", "Éthan Røgers", "🫡", "sk-live-abc123.def_456", "a=b=c", "#notacomment", ""): server._write_env_key("USER_NAME", value) @@ -209,11 +209,11 @@ def test_ordinary_values_still_save(env): def test_a_value_the_reader_would_change_is_refused(env): """Deliberate, and the reason is honesty rather than injection: the - reader strips whitespace and one layer of quotes, so ` Ethan ` would - come back as `Ethan` and `'Ethan'` as `Ethan`. Saying "saved" and + reader strips whitespace and one layer of quotes, so ` Tony ` would + come back as `Tony` and `'Tony'` as `Tony`. Saying "saved" and storing something else is the same class of lie as reporting a stalled run as a success.""" _c, server = env - for value in (" Ethan ", "'Ethan'", '"Ethan"', "Ethan\t"): + for value in (" Tony ", "'Tony'", '"Tony"', "Tony\t"): with pytest.raises(ValueError): server._write_env_key("USER_NAME", value) diff --git a/tests/test_jarvis_memory.py b/tests/test_jarvis_memory.py index 809ea2c1..4292862b 100644 --- a/tests/test_jarvis_memory.py +++ b/tests/test_jarvis_memory.py @@ -22,13 +22,13 @@ def test_the_layout_is_created_once_and_is_idempotent(home): def test_a_memory_is_one_file_with_a_readable_name(home): - path = jm.write_memory("Ethan prefers Postgres over SQLite", + path = jm.write_memory("Tony prefers Postgres over SQLite", "He said so while we were fixing chitauri.") assert path.parent == home / "memory" - assert path.name == "ethan-prefers-postgres-over-sqlite.md" + assert path.name == "tony-prefers-postgres-over-sqlite.md" text = path.read_text() - assert "Ethan prefers Postgres over SQLite" in text + assert "Tony prefers Postgres over SQLite" in text assert "chitauri" in text @@ -41,7 +41,7 @@ def test_writing_the_same_title_twice_updates_rather_than_duplicating(home): def test_slugify_makes_a_filename_out_of_anything_sayable(home): - assert jm.slugify("Ethan's 'chitauri' work — Q3/2026!") == "ethans-chitauri-work-q3-2026" + assert jm.slugify("Tony's 'chitauri' work — Q3/2026!") == "tonys-chitauri-work-q3-2026" assert jm.slugify(" ") == "note" assert len(jm.slugify("x" * 200)) <= 60 @@ -51,13 +51,13 @@ def test_reading_a_memory_that_does_not_exist_returns_none(home): def test_the_index_gains_one_line_per_memory(home): - jm.add_to_index("Ethan prefers Postgres", "said during chitauri work") + jm.add_to_index("Tony prefers Postgres", "said during chitauri work") jm.add_to_index("Hammer is the worker project", "not to be confused with hammer-private") lines = jm.index_lines() assert len(lines) == 2 assert all(line.startswith("- [") for line in lines) - assert "ethan-prefers-postgres.md" in lines[0] + assert "tony-prefers-postgres.md" in lines[0] def test_the_index_does_not_duplicate_a_title(home): @@ -95,7 +95,7 @@ def test_reading_an_unknown_project_note_returns_none(home): def test_a_journal_entry_is_timestamped_and_labelled(home): - p = jm.write_journal("Worked on chitauri. Ethan wants Postgres.", reason="rotation") + p = jm.write_journal("Worked on chitauri. Tony wants Postgres.", reason="rotation") assert p.parent == home / "journal" assert p.name.endswith("-rotation.md") @@ -121,14 +121,14 @@ def test_add_to_index_preserves_hand_written_prose(home): path = home / "MEMORY.md" path.write_text( "# What JARVIS remembers\n\n" - "Ethan asked me to always check the chitauri staging env before prod.\n\n" + "Tony asked me to always check the chitauri staging env before prod.\n\n" "- [Old fact](old-fact.md) — some hook\n" ) jm.add_to_index("New fact", "a hook") text = path.read_text() - assert "Ethan asked me to always check the chitauri staging env before prod." in text + assert "Tony asked me to always check the chitauri staging env before prod." in text assert "- [Old fact](old-fact.md) — some hook" in text assert "- [New fact](new-fact.md) — a hook" in text @@ -163,12 +163,12 @@ def test_latest_journal_is_correct_even_when_reasons_sort_out_of_order(home): def test_search_finds_a_memory_by_its_words(home): - jm.write_memory("Ethan prefers Postgres", "He said so during chitauri work.") + jm.write_memory("Tony prefers Postgres", "He said so during chitauri work.") jm.write_memory("Hammer is the worker project", "Runs on the Desktop.") hits = jm.search("postgres") - assert hits and hits[0]["name"] == "ethan-prefers-postgres" + assert hits and hits[0]["name"] == "tony-prefers-postgres" assert hits[0]["kind"] == "memory" assert "Postgres" in hits[0]["excerpt"] @@ -282,8 +282,8 @@ def test_two_genuinely_different_titles_that_slugify_identically_both_survive(ho def test_the_same_title_written_twice_still_produces_one_file(home): - p1 = jm.write_memory("Ethan's DB choice", "uses postgres") - p2 = jm.write_memory("Ethan's DB choice", "uses sqlite") + p1 = jm.write_memory("Tony's DB choice", "uses postgres") + p2 = jm.write_memory("Tony's DB choice", "uses sqlite") assert p1 == p2 assert len(jm.list_memories()) == 1 @@ -293,8 +293,8 @@ def test_the_same_title_written_twice_still_produces_one_file(home): def test_a_title_differing_only_by_apostrophe_or_case_is_the_same_memory(home): - p1 = jm.write_memory("Ethan's DB choice", "uses postgres") - p2 = jm.write_memory("ethans db choice", "uses sqlite") + p1 = jm.write_memory("Tony's DB choice", "uses postgres") + p2 = jm.write_memory("tonys db choice", "uses sqlite") assert p1 == p2 assert len(jm.list_memories()) == 1 diff --git a/tests/test_memory_api.py b/tests/test_memory_api.py index e38d690e..9497a1ea 100644 --- a/tests/test_memory_api.py +++ b/tests/test_memory_api.py @@ -71,19 +71,19 @@ def test_a_read_never_creates_the_folder(api): def test_the_snapshot_lists_memories_projects_and_the_journal(api): client, jm, _dp, _rs = api - jm.write_memory("Ethan prefers Postgres over SQLite", "for chitauri") - jm.add_to_index("Ethan prefers Postgres over SQLite", "database preference") + jm.write_memory("Tony prefers Postgres over SQLite", "for chitauri") + jm.add_to_index("Tony prefers Postgres over SQLite", "database preference") jm.write_project_note("chitauri", "The billing job runs nightly.") jm.write_journal("We shipped the dashboard.", reason="shutdown") body = client.get("/api/memory").json() - assert body["index"] == [{"title": "Ethan prefers Postgres over SQLite", - "slug": "ethan-prefers-postgres-over-sqlite", + assert body["index"] == [{"title": "Tony prefers Postgres over SQLite", + "slug": "tony-prefers-postgres-over-sqlite", "hook": "database preference"}] assert [m["slug"] for m in body["memories"]] == \ - ["ethan-prefers-postgres-over-sqlite"] - assert body["memories"][0]["title"] == "Ethan prefers Postgres over SQLite" + ["tony-prefers-postgres-over-sqlite"] + assert body["memories"][0]["title"] == "Tony prefers Postgres over SQLite" assert isinstance(body["memories"][0]["modified"], (int, float)) assert [p["slug"] for p in body["projects"]] == ["chitauri"] assert len(body["journal"]) == 1 diff --git a/tests/test_memory_tools.py b/tests/test_memory_tools.py index 50353382..d524e1fe 100644 --- a/tests/test_memory_tools.py +++ b/tests/test_memory_tools.py @@ -20,19 +20,19 @@ class _WatcherTurn: def test_remember_writes_a_file_and_indexes_it(wired): server = wired - out = server.tool_remember({"title": "Ethan prefers Postgres", + out = server.tool_remember({"title": "Tony prefers Postgres", "body": "Said during chitauri work.", "hook": "database preference"}) import jarvis_memory as jm - assert "ethan-prefers-postgres" in jm.list_memories() + assert "tony-prefers-postgres" in jm.list_memories() assert any("database preference" in ln for ln in jm.index_lines()) assert "remember" in out.lower() or "noted" in out.lower() def test_recall_finds_what_was_remembered(wired): server = wired - server.tool_remember({"title": "Ethan prefers Postgres", "body": "for chitauri", + server.tool_remember({"title": "Tony prefers Postgres", "body": "for chitauri", "hook": "db"}) out = server.tool_recall({"query": "postgres"}) @@ -45,16 +45,16 @@ def test_recall_says_so_plainly_when_it_finds_nothing(wired): def test_recall_never_speaks_a_memorys_raw_slug(wired): - """A memory's filename is a slugified title ("ethan-prefers-postgres"); + """A memory's filename is a slugified title ("tony-prefers-postgres"); read aloud that's noise, not a sentence — see tool_list_sessions's own rule against ever saying a roster name like hammer-4b out loud.""" server = wired - server.tool_remember({"title": "Ethan prefers Postgres over SQLite", + server.tool_remember({"title": "Tony prefers Postgres over SQLite", "body": "for chitauri", "hook": "db"}) out = server.tool_recall({"query": "postgres"}) - assert "ethan-prefers-postgres" not in out.lower() + assert "tony-prefers-postgres" not in out.lower() def test_recall_never_speaks_a_journal_entrys_raw_timestamp(wired): diff --git a/tests/test_memory_writers.py b/tests/test_memory_writers.py index cc3944a3..2493993f 100644 --- a/tests/test_memory_writers.py +++ b/tests/test_memory_writers.py @@ -210,14 +210,14 @@ def test_the_index_stays_parseable_after_a_hostile_title(memory): def test_an_ordinary_memory_still_reads_as_itself(memory): - memory.write_memory("Ethan prefers postgres", "He said so on Tuesday.") - memory.add_to_index("Ethan prefers postgres", "over sqlite, every time") + memory.write_memory("Tony prefers postgres", "He said so on Tuesday.") + memory.add_to_index("Tony prefers postgres", "over sqlite, every time") rows = memory.index_entries() - assert rows == [{"title": "Ethan prefers postgres", - "slug": "ethan-prefers-postgres", + assert rows == [{"title": "Tony prefers postgres", + "slug": "tony-prefers-postgres", "hook": "over sqlite, every time"}], rows assert "He said so on Tuesday." in memory.read_memory( - "Ethan prefers postgres") + "Tony prefers postgres") def test_a_multi_line_body_is_still_allowed(memory): diff --git a/tests/test_rotation_server.py b/tests/test_rotation_server.py index bef6446e..b7a15a35 100644 --- a/tests/test_rotation_server.py +++ b/tests/test_rotation_server.py @@ -41,7 +41,7 @@ def __init__(self, pending=True, overdue=False, rotates=True): async def turn(self, text, origin="user", on_delta=None): self.asked.append((text, origin)) import brain - return brain.TurnResult(origin, "We fixed chitauri and Ethan chose Postgres.", + return brain.TurnResult(origin, "We fixed chitauri and Tony chose Postgres.", "result") async def rotate(self, handover=None): diff --git a/tests/test_untrusted_turn.py b/tests/test_untrusted_turn.py index 17462ec9..4bfa2f3b 100644 --- a/tests/test_untrusted_turn.py +++ b/tests/test_untrusted_turn.py @@ -272,7 +272,7 @@ def test_a_later_clean_turn_may_still_write(call): assert _call("remember", title="X", body="Y")["ok"] is False brain.new_turn() - out = _call("remember", title="Ethan prefers Postgres", + out = _call("remember", title="Tony prefers Postgres", body="He said so out loud.") assert out["ok"] is True, out assert "Postgres" in jarvis_memory._index_path().read_text() diff --git a/tests/test_web_security.py b/tests/test_web_security.py index 553c92d9..ed2a35ad 100644 --- a/tests/test_web_security.py +++ b/tests/test_web_security.py @@ -393,7 +393,7 @@ def test_an_env_value_with_a_newline_is_refused(env): c, server, _ = env r = c.post("/api/settings/keys", json={"key_name": "USER_NAME", - "key_value": "Ethan\nJARVIS_CLAUDE_PATH=/tmp/evil"}, + "key_value": "Tony\nJARVIS_CLAUDE_PATH=/tmp/evil"}, headers={"Origin": DASHBOARD_ORIGIN}) assert r.status_code == 400, r.text dotenv = server._env_file_path() @@ -408,10 +408,10 @@ def test_write_env_key_refuses_anything_that_can_start_a_new_line(env, bad): def test_a_name_with_a_space_in_it_is_still_a_name(env): - """The gate is line breaks, not punctuation — Ethan Rogers must save.""" + """The gate is line breaks, not punctuation — Tony Stark must save.""" c, server, _ = env - server._write_env_key("USER_NAME", "Ethan Rogers") - assert "USER_NAME=Ethan Rogers" in server._env_file_path().read_text() + server._write_env_key("USER_NAME", "Tony Stark") + assert "USER_NAME=Tony Stark" in server._env_file_path().read_text() def test_write_env_key_refuses_a_key_nobody_is_allowed_to_set(env): @@ -425,7 +425,7 @@ def test_write_env_key_refuses_a_key_nobody_is_allowed_to_set(env): def test_preferences_values_go_through_the_same_gate(env): c, _, _ = env r = c.post("/api/settings/preferences", - json={"user_name": "Ethan\nJARVIS_PROJECT_ROOTS=/", + json={"user_name": "Tony\nJARVIS_PROJECT_ROOTS=/", "honorific": "sir"}, headers={"Origin": DASHBOARD_ORIGIN}) assert r.status_code == 400, r.text @@ -503,7 +503,7 @@ def test_settings_status_is_a_read_and_creates_nothing(env, monkeypatch, assert not fake_env.exists(), "a GET created .env" # A write still seeds it — that path is allowed to. - server._write_env_key("USER_NAME", "Ethan") + server._write_env_key("USER_NAME", "Tony") assert fake_env.exists()