sbxloop 0.7.4__tar.gz → 0.7.6__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 (66) hide show
  1. {sbxloop-0.7.4 → sbxloop-0.7.6}/PKG-INFO +1 -1
  2. sbxloop-0.7.4/src/sbxloop/_vendor/sbxloop_worker-0.7.4-py3-none-any.whl → sbxloop-0.7.6/src/sbxloop/_vendor/sbxloop_worker-0.7.6-py3-none-any.whl +0 -0
  3. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/_version.py +2 -2
  4. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/backlog.py +6 -1
  5. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/loop.py +17 -1
  6. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/sources.py +9 -4
  7. {sbxloop-0.7.4 → sbxloop-0.7.6}/.gitignore +0 -0
  8. {sbxloop-0.7.4 → sbxloop-0.7.6}/README.md +0 -0
  9. {sbxloop-0.7.4 → sbxloop-0.7.6}/hatch_build.py +0 -0
  10. {sbxloop-0.7.4 → sbxloop-0.7.6}/pyproject.toml +0 -0
  11. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/__init__.py +0 -0
  12. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/cli/__init__.py +0 -0
  13. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/cli/app.py +0 -0
  14. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/cli/doctor.py +0 -0
  15. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/cli/models.py +0 -0
  16. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/cli/tui.py +0 -0
  17. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/config.py +0 -0
  18. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/__init__.py +0 -0
  19. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/audits.py +0 -0
  20. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/control.py +0 -0
  21. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/discord.py +0 -0
  22. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/discord_format.py +0 -0
  23. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/github.py +0 -0
  24. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/model.py +0 -0
  25. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/paths.py +0 -0
  26. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/postmortem.py +0 -0
  27. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/daemon/store.py +0 -0
  28. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/deliver.py +0 -0
  29. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/__init__.py +0 -0
  30. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/engine.py +0 -0
  31. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/model.py +0 -0
  32. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/phases.py +0 -0
  33. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/prompts/__init__.py +0 -0
  34. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/prompts/decompose.md +0 -0
  35. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/prompts/execute.md +0 -0
  36. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/prompts/plan.md +0 -0
  37. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/prompts/scrutinize.md +0 -0
  38. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/prompts/steer.md +0 -0
  39. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/prompts/validate.md +0 -0
  40. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/engine/store.py +0 -0
  41. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/errors.py +0 -0
  42. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/events.py +0 -0
  43. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/gc.py +0 -0
  44. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/gh/__init__.py +0 -0
  45. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/gh/ops.py +0 -0
  46. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/gh/reporter.py +0 -0
  47. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/hostgit.py +0 -0
  48. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/ids.py +0 -0
  49. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/policy.py +0 -0
  50. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/py.typed +0 -0
  51. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/__init__.py +0 -0
  52. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/bake.py +0 -0
  53. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/cli.py +0 -0
  54. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/conformance.py +0 -0
  55. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/models.py +0 -0
  56. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/pair.py +0 -0
  57. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/parse.py +0 -0
  58. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/provision.py +0 -0
  59. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/prune.py +0 -0
  60. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/sandbox.py +0 -0
  61. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/sbx/secretstate.py +0 -0
  62. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/toolchains.py +0 -0
  63. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/verifylint.py +0 -0
  64. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/worker/__init__.py +0 -0
  65. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/worker/client.py +0 -0
  66. {sbxloop-0.7.4 → sbxloop-0.7.6}/src/sbxloop/worker/wheel.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sbxloop
3
- Version: 0.7.4
3
+ Version: 0.7.6
4
4
  Summary: Agentic loop orchestration on Docker Sandboxes (sbx) with isolated credential domains
5
5
  Project-URL: Homepage, https://github.com/brettbergin/sbxloop
6
6
  Project-URL: Repository, https://github.com/brettbergin/sbxloop
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.7.4'
22
- __version_tuple__ = version_tuple = (0, 7, 4)
21
+ __version__ = version = '0.7.6'
22
+ __version_tuple__ = version_tuple = (0, 7, 6)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -47,7 +47,12 @@ AUDIT_INSTRUCTIONS = (
47
47
  "the tool that ran you: its planner, prompts, verify lint, delivery, daemon — "
48
48
  "go under `.sbxloop/backlog/tool/` instead; they are filed to the tool's own "
49
49
  "tracker when the operator configured one, otherwise only noted in the closing "
50
- "comment, never filed as issues of this project."
50
+ "comment, never filed as issues of this project. VERIFICATION: an audit changes "
51
+ "no code, so its tasks need NO verify_commands (leave the list empty) — or at "
52
+ "most a check on the findings you wrote (e.g. `ls .sbxloop/backlog/*.md`). Never "
53
+ "the project's test suite, build or lint: an audit whose charter is to find a "
54
+ "failing test cannot also promise the suite is green (field failure rakvqn6fr, "
55
+ "where exactly that verify command sank the audit and its findings)."
51
56
  )
52
57
 
53
58
  TOOL_SUBDIR = BACKLOG_SUBDIR / "tool"
@@ -665,7 +665,12 @@ class DaemonLoop:
665
665
  self._notify(
666
666
  f"✅ {item.item_id} done ({report.task_summary})"
667
667
  + (f" · PR {report.delivery[1]}" if report.delivery else "")
668
- + (f" · filed {len(report.filed)} finding(s)" if item.kind == "audit" else "")
668
+ + (
669
+ f" · filed {len(report.filed) + len(report.tool_filed)} finding(s)"
670
+ + (f" ({len(report.tool_filed)} upstream)" if report.tool_filed else "")
671
+ if item.kind == "audit"
672
+ else ""
673
+ )
669
674
  )
670
675
  self._file_review(item, run_id, report)
671
676
  return "done"
@@ -682,6 +687,17 @@ class DaemonLoop:
682
687
  self._file_postmortem(item, run_id, f"delivery failed: {report.delivery_error}")
683
688
  return "delivery_failed"
684
689
  reason = str(error) if error is not None else f"run ended {report.state}"
690
+ if item.kind == "audit" and result is not None:
691
+ # An audit that failed on the harness (a verify command it never
692
+ # needed) still wrote its findings; they are evidence, not code,
693
+ # so file them rather than lose them (field: rakvqn6fr).
694
+ filed = self._collect_backlog(run_id, source)
695
+ tool = self._collect_tool_findings(run_id, source)
696
+ if filed or tool.filed:
697
+ self._notify(
698
+ f"🔎 {item.item_id} failed but its findings were filed: "
699
+ f"{len(filed) + len(tool.filed)} issue(s)"
700
+ )
685
701
  attempts_left = self.config.daemon.max_attempts_per_item - item.attempts
686
702
  self._set_breaker(self._breaker_opened_at, self._consecutive_failures + 1)
687
703
  self.dstore.finish_ledger(run_id, "failed", now)
@@ -412,6 +412,7 @@ class GitHubIssueSource:
412
412
  }
413
413
  if trigger not in names:
414
414
  return False
415
+ stale_delivered = self.labels.delivered in names
415
416
  epoch = self._trigger_epoch(ops, number, trigger)
416
417
  token = uuid.uuid4().hex
417
418
  self._comment(
@@ -449,10 +450,14 @@ class GitHubIssueSource:
449
450
  # mode was configured *then*, and a daemon restarted with
450
451
  # close_on_success back on would otherwise leave it beside
451
452
  # in-progress. Best-effort — a leftover label must not un-claim.
452
- self._guard(
453
- "clear delivered label",
454
- lambda ops: self._remove_label(ops, number, self.labels.delivered),
455
- )
453
+ # Only when the re-GET actually showed it: a blind DELETE 404s on
454
+ # every fresh issue and the event stream renders each as an error
455
+ # panel (field noise on every audit claim).
456
+ if stale_delivered:
457
+ self._guard(
458
+ "clear delivered label",
459
+ lambda ops: self._remove_label(ops, number, self.labels.delivered),
460
+ )
456
461
  return True
457
462
 
458
463
  def _trigger_epoch(self, ops: GithubOps, number: str, trigger: str | None = None) -> str:
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes