fix(orchestrator): S1 fit, rename once, Deutschlandfunk e2e, squelch, tree cause

Requirement 001 phase 6, S1:

- Fit: Agents and Artifacts in a graph view fill the window from 861 px
  up (body.fit flex column); the e2e walk probes #agents/orbit at every
  width for a page no taller than the window.
- Rename once: a session seen under two names by one source (two claims)
  flipped its name on every state build, so the Stream logged a rename
  each poll. Names.observe keeps only the newest sighting per session
  and source, and the timeline emits each (session, before, after) pair
  once.
- Deutschlandfunk: root cause was the signed media-src, which never
  listed the redirect target f111.rndfnk.com that st01.sslstream.dlf.de
  answers with (fixed in ba97f7c). The e2e now replays that chain, a
  302 from one https origin to a second, in Chromium and Firefox, with
  self-signed throwaway certificates the drivers accept.
- Squelch: a settings slider 0..1 scales every tone; at 0 no beep plays,
  music on or off (Voice.beep skips a silent tone). Stored settings
  without the key load with 1.0.
- Tree: the missing tree file error names `pkgmgr branch tree` and the
  release and install step that makes the timer write it.

Evidence: make test 655 OK, ruff and markdownlint clean
(/tmp/s1-make-test-1.log); e2e 17 OK, none skipped (/tmp/s1-e2e-3.log);
MEDUSA 14 files, 0 findings.

🎯 Fix: 94 %
💥 Break: 4 %
💸 Cost: 100 %
⏱️ Time: –
🛡️ Security: 100 %
🏆 Score: 90
🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 %

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kevin Veen-BirkenbachandClaude Opus 5.5 committed 2026-11-08 13:37:02 +00:00
1 parent 86b55dbc91
commit a388c6ef77
15 files changed
+148 -26

No files matched your search

+18 -2
View File
@@ -65,9 +65,14 @@ class Directory:
def renames(self, begin: float, end: float) -> list[dict]:
found = []
shown = set()
for session, own in self.by_session.items():
for before, after in itertools.pairwise(own):
if before["name"] != after["name"] and begin <= after["first_seen"] <= end:
pair = (session, before["name"], after["name"])
if before["name"] == after["name"] or pair in shown:
continue
shown.add(pair)
if begin <= after["first_seen"] <= end:
found.append(event({
"id": f"rename:{session}:{after['first_seen']}", "ts": after["first_seen"], "kind": "rename", "agent": after["name"],
"now": self.now(session), "session": session, "title": f"{before['name']} heißt jetzt {after['name']}",
@@ -89,9 +94,20 @@ class Names:
self.observed: dict[str, str] = observed if isinstance(observed, dict) else {}
def observe(self, sightings: list[tuple[str, str, float | None, str]], now: float) -> None:
"""Args:
sightings: (session, name, seen, source); of several sightings of
one session from one source only the newest counts, so two
claims under different names cannot flip the name back and
forth on every state build.
"""
newest: dict[tuple[str, str], tuple[str, str, float | None, str]] = {}
for sighting in sightings:
key = (sighting[0], sighting[3])
if key not in newest or (sighting[2] or -math.inf) >= (newest[key][2] or -math.inf):
newest[key] = sighting
with self.lock:
changed = False
for session, name, seen, source in sightings:
for session, name, seen, source in newest.values():
key = f"{session}\x00{source}"
if not session or not name or self.observed.get(key) == name:
continue
@@ -36,6 +36,7 @@ SETTINGS = {
"direct": {"on": True, "volume": 0.5},
"radio": {"on": False, "volume": 0.25},
},
"squelch": 1.0,
"notify": True,
"streams": [],
"speech": {"on": False, "classes": ["mayday", "pan-pan", "security"], "muted": []},
@@ -195,6 +196,7 @@ def valid_settings(raw: object) -> dict:
"colors": {key: color(colors[key], f"colors.{key}") for key in SETTINGS["colors"]},
"music": {"on": flag(music["on"], "music.on"), "volume": number_in(music["volume"], "music.volume", 0.0, 1.0)},
"sounds": {kind_name: tone_setting(sounds[kind_name], kind_name) for kind_name in TONES},
"squelch": number_in(data["squelch"], "squelch", 0.0, 1.0),
"notify": flag(data["notify"], "notify"),
"streams": [stream_entry(entry, index) for index, entry in enumerate(data["streams"])],
"speech": speech_setting(data["speech"]),
+4 -1
View File
@@ -191,7 +191,10 @@ class Tree:
try:
info = self.file.stat()
except OSError as error:
return {"repos": [], "scanned": None, "error": f"no pkgmgr tree file at {self.file}: {error.strerror}"}
return {"repos": [], "scanned": None, "error": (
f"no pkgmgr tree file at {self.file}: {error.strerror}. The tree timer runs `pkgmgr branch tree`, which the installed pkgmgr "
"lacks until a release ships it: release pkgmgr and install it, then the timer writes the file within a minute."
)}
stamp = (info.st_mtime_ns, info.st_size)
if self.cached is None or stamp != self.stamp:
self.cached, self.stamp = read_tree(self.file), stamp