Lokale Matrix liefert Ergebnisse: 119 Anforderungen aus Gemma und Qwen
Skill 13.0.0/13.1.0, Adapter 2.5.2. Spiegel-Arbeitsverzeichnis: OpenCode laeuft nicht mehr direkt im Codebasis-Root, sondern in einem Verzeichnis aus Junctions auf die Top-Level-Eintraege, mit einem echten Ergebnisverzeichnis, dessen Inhalt nach dem Lauf uebernommen wird. Damit landen relative wie absolute Ausgabepfade am richtigen Ort, ohne dass der Prompt vom Wortlaut der Claude-Laeufe abweichen muss. Der Spiegel liegt in _meta des Laufs; die Codebasis bleibt unberuehrt. Der Spiegel allein genuegte nicht. Sechs Laeufe schrieben mit korrektem absolutem Pfad und wurden dennoch abgewiesen, weil OpenCode Ziele im Repository gegen den worktree-relativen Pfad abgleicht - ein Befund, der seit Skill 10.0.2 dokumentiert war und erst sichtbar wurde, als der Spiegel vom Temp-Verzeichnis ins Projekt wanderte. analyse-anforderungen.py erkennt Kennungen als Markdown-Ueberschrift, auch ohne Feldnamen, sofern die Pflichtfelder folgen. Regressionsprobe an fuenf Claude-Laeufen unveraendert. Ergebnisse der gueltigen Laeufe: Qwen 3.5-9B liefert 107 der 119 Anforderungen, davon 75 im Modus custom mit nur drei Subagenten. Gemma kommt auf 12. Der Modus builtin fiel bei beiden Modellen aus - drei von drei Laeufen endeten nach einem Turn ohne einen Werkzeugaufruf. Die 13 Laeufe mit Adapter 2.3.0 bis 2.5.1 sind Artefakte der Fehlersuche und als adapterbedingte Fehlmessungen gekennzeichnet. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
28e927013b
commit
6c5c26a2e4
@@ -202,6 +202,81 @@ class ReadonlyShellTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class SpiegelTests(unittest.TestCase):
|
||||
"""Der Spiegel loest relative Ausgabepfade, ohne die Quelle zu beruehren."""
|
||||
|
||||
def test_relativer_schreibpfad_landet_im_laufverzeichnis(self):
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp = Path(temp_dir)
|
||||
quelle = temp / "codebasis"
|
||||
(quelle / "src").mkdir(parents=True)
|
||||
(quelle / "src" / "a.cs").write_text("Quellcode", encoding="utf-8")
|
||||
(quelle / "README.md").write_text("Liesmich", encoding="utf-8")
|
||||
ausgabe = temp / "lauf" / "Ergebnisse"
|
||||
ausgabe.mkdir(parents=True)
|
||||
spiegel = temp / "spiegel"
|
||||
|
||||
ADAPTER.erstelle_spiegel(quelle, spiegel, ausgabe, lambda _: None)
|
||||
try:
|
||||
self.assertTrue((spiegel / "src" / "a.cs").is_file())
|
||||
self.assertTrue((spiegel / "README.md").is_file())
|
||||
# `Ergebnisse` ist im Spiegel ein echtes Verzeichnis - ein
|
||||
# relativer Schreibpfad landet dort und wird danach uebernommen.
|
||||
(spiegel / "Ergebnisse" / "StRS.md").write_text("X", encoding="utf-8")
|
||||
self.assertFalse((ausgabe / "StRS.md").is_file())
|
||||
anzahl = ADAPTER.uebernimm_ergebnisse(spiegel, ausgabe, lambda _: None)
|
||||
self.assertEqual(1, anzahl)
|
||||
self.assertTrue((ausgabe / "StRS.md").is_file())
|
||||
self.assertEqual("X", (ausgabe / "StRS.md").read_text(encoding="utf-8"))
|
||||
finally:
|
||||
ADAPTER.entferne_spiegel(spiegel, lambda _: None)
|
||||
|
||||
# Der Abbau darf die Quelle nicht durch die Junction hindurch loeschen.
|
||||
self.assertFalse(spiegel.exists())
|
||||
self.assertTrue((quelle / "src" / "a.cs").is_file())
|
||||
self.assertEqual("Quellcode", (quelle / "src" / "a.cs").read_text(encoding="utf-8"))
|
||||
self.assertTrue((ausgabe / "StRS.md").is_file())
|
||||
|
||||
def test_freigabe_enthaelt_arbeitsverzeichnis_relative_form(self):
|
||||
"""resolve() folgt der Junction - die relative Form darf nicht verloren gehen."""
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp = Path(temp_dir)
|
||||
quelle = temp / "codebasis"
|
||||
(quelle / "src").mkdir(parents=True)
|
||||
ausgabe = temp / "lauf" / "Ergebnisse"
|
||||
ausgabe.mkdir(parents=True)
|
||||
spiegel = temp / "spiegel"
|
||||
ADAPTER.erstelle_spiegel(quelle, spiegel, ausgabe, lambda _: None)
|
||||
try:
|
||||
config = ADAPTER.build_run_config(
|
||||
{}, "lmstudio/x", "x", "solo", spiegel, ausgabe, None,
|
||||
provider="lmstudio",
|
||||
zusatz_ausgaben=[spiegel / ausgabe.name],
|
||||
)
|
||||
finally:
|
||||
ADAPTER.entferne_spiegel(spiegel, lambda _: None)
|
||||
erlaubt = [k for k, v in config["permission"]["edit"].items() if v == "allow"]
|
||||
self.assertIn("Ergebnisse", erlaubt)
|
||||
self.assertIn("Ergebnisse/**", erlaubt)
|
||||
|
||||
def test_quelle_bleibt_ohne_neue_eintraege(self):
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
temp = Path(temp_dir)
|
||||
quelle = temp / "codebasis"
|
||||
(quelle / "src").mkdir(parents=True)
|
||||
vorher = sorted(p.name for p in quelle.iterdir())
|
||||
ausgabe = temp / "lauf" / "Ergebnisse"
|
||||
ausgabe.mkdir(parents=True)
|
||||
spiegel = temp / "spiegel"
|
||||
|
||||
ADAPTER.erstelle_spiegel(quelle, spiegel, ausgabe, lambda _: None)
|
||||
(spiegel / "Ergebnisse" / "datei.md").write_text("X", encoding="utf-8")
|
||||
ADAPTER.uebernimm_ergebnisse(spiegel, ausgabe, lambda _: None)
|
||||
ADAPTER.entferne_spiegel(spiegel, lambda _: None)
|
||||
|
||||
self.assertEqual(vorher, sorted(p.name for p in quelle.iterdir()))
|
||||
|
||||
|
||||
class UsageCapturedTests(unittest.TestCase):
|
||||
"""Eine Null aus einem laufenden Subagenten ist kein Messwert."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user