quality-loop 0.2.1__tar.gz → 0.2.2__tar.gz

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 (50) hide show
  1. {quality_loop-0.2.1/quality_loop.egg-info → quality_loop-0.2.2}/PKG-INFO +1 -1
  2. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/__init__.py +1 -1
  3. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/report.py +6 -1
  4. {quality_loop-0.2.1 → quality_loop-0.2.2/quality_loop.egg-info}/PKG-INFO +1 -1
  5. {quality_loop-0.2.1 → quality_loop-0.2.2}/tests/test_scenario_report.py +8 -0
  6. {quality_loop-0.2.1 → quality_loop-0.2.2}/LICENSE +0 -0
  7. {quality_loop-0.2.1 → quality_loop-0.2.2}/README.md +0 -0
  8. {quality_loop-0.2.1 → quality_loop-0.2.2}/pyproject.toml +0 -0
  9. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/OPERATOR.md +0 -0
  10. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/__main__.py +0 -0
  11. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/adapter.py +0 -0
  12. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/audit.py +0 -0
  13. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/cli.py +0 -0
  14. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/compare.py +0 -0
  15. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/config.py +0 -0
  16. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/drive/__init__.py +0 -0
  17. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/drive/_mac.py +0 -0
  18. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/drive/_windows.py +0 -0
  19. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/drive/keys.py +0 -0
  20. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/drive/terminal.py +0 -0
  21. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/install.py +0 -0
  22. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/mcp.py +0 -0
  23. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/operator.py +0 -0
  24. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/pages.py +0 -0
  25. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/processes.py +0 -0
  26. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/progress.py +0 -0
  27. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/room.py +0 -0
  28. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/runner.py +0 -0
  29. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/scenario.py +0 -0
  30. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/screens/__init__.py +0 -0
  31. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/screens/_mac.py +0 -0
  32. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/screens/_windows.py +0 -0
  33. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/session.py +0 -0
  34. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/skill/SKILL.md +0 -0
  35. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/skill/references/filing.md +0 -0
  36. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/skill/references/setup.md +0 -0
  37. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/standin.py +0 -0
  38. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop/transcript.py +0 -0
  39. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop.egg-info/SOURCES.txt +0 -0
  40. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop.egg-info/dependency_links.txt +0 -0
  41. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop.egg-info/entry_points.txt +0 -0
  42. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop.egg-info/requires.txt +0 -0
  43. {quality_loop-0.2.1 → quality_loop-0.2.2}/quality_loop.egg-info/top_level.txt +0 -0
  44. {quality_loop-0.2.1 → quality_loop-0.2.2}/setup.cfg +0 -0
  45. {quality_loop-0.2.1 → quality_loop-0.2.2}/tests/test_core.py +0 -0
  46. {quality_loop-0.2.1 → quality_loop-0.2.2}/tests/test_drive.py +0 -0
  47. {quality_loop-0.2.1 → quality_loop-0.2.2}/tests/test_loop.py +0 -0
  48. {quality_loop-0.2.1 → quality_loop-0.2.2}/tests/test_mcp.py +0 -0
  49. {quality_loop-0.2.1 → quality_loop-0.2.2}/tests/test_operator.py +0 -0
  50. {quality_loop-0.2.1 → quality_loop-0.2.2}/tests/test_screens.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quality-loop
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Measure what a product teaches - its skill, tools or manual - with isolated agent runs of real tasks, reported by an operator agent
5
5
  Author: craftware
6
6
  License-Expression: MIT
@@ -12,4 +12,4 @@ room is handed, putting the user's machine back - is code here, not an
12
12
  agent's discretion.
13
13
  """
14
14
 
15
- __version__ = "0.2.1"
15
+ __version__ = "0.2.2"
@@ -125,7 +125,12 @@ def parse(text: str, room: str = "") -> tuple[list[Problem], list[str]]:
125
125
  value = field["value"].strip()
126
126
  key = by_label[field["label"].strip().lower()]
127
127
  if key == "id":
128
- value = value.strip("`")
128
+ # The id is the first code span, or else the first word. The
129
+ # first Keyhac run with a known list had operators write
130
+ # "`dialog-gone` (known)", and the note became part of the id,
131
+ # so every known problem was counted as new.
132
+ code = re.match(r"`([^`]+)`", value)
133
+ value = code[1].strip() if code else (value.split() or [""])[0]
129
134
  if key == "kind":
130
135
  value = value.lower()
131
136
  setattr(current, key, value)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quality-loop
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Measure what a product teaches - its skill, tools or manual - with isolated agent runs of real tasks, reported by an operator agent
5
5
  Author: craftware
6
6
  License-Expression: MIT
@@ -146,6 +146,14 @@ def test_a_field_continued_as_a_nested_list_is_kept():
146
146
  assert "indented paragraph" in problems[0].detail
147
147
 
148
148
 
149
+ @pytest.mark.parametrize("written", ["`dialog-gone` (known)", "dialog-gone (known)",
150
+ "`dialog-gone`", "dialog-gone"])
151
+ def test_a_note_after_the_id_is_not_part_of_it(written):
152
+ problems, malformed = report.parse(
153
+ f"### [medium] Dialog\n- **Id:** {written}\n- **Evidence:** calls\n")
154
+ assert not malformed and problems[0].id == "dialog-gone"
155
+
156
+
149
157
  def test_findings_concatenate_and_count_most_severe_first(tmp_path):
150
158
  path = report.write_findings(tmp_path, [
151
159
  ("11_f1", "F1 off", REPORT),
File without changes
File without changes
File without changes