stagemesh 0.6.0__py3-none-any.whl

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 (205) hide show
  1. stagemesh/__init__.py +7 -0
  2. stagemesh/_build_info.py +3 -0
  3. stagemesh/acceptance.py +121 -0
  4. stagemesh/acceptance_matrix.py +52 -0
  5. stagemesh/activity.py +989 -0
  6. stagemesh/activity_periods.py +282 -0
  7. stagemesh/agent_policy.py +241 -0
  8. stagemesh/agent_skills.py +519 -0
  9. stagemesh/api_server.py +1372 -0
  10. stagemesh/attribution.py +48 -0
  11. stagemesh/audit.py +71 -0
  12. stagemesh/auto_plan.py +497 -0
  13. stagemesh/autonomy/__init__.py +30 -0
  14. stagemesh/autonomy/base_state.py +291 -0
  15. stagemesh/autonomy/ci_diagnosis.py +644 -0
  16. stagemesh/autonomy/cli.py +219 -0
  17. stagemesh/autonomy/corpus.py +142 -0
  18. stagemesh/autonomy/decisions.py +325 -0
  19. stagemesh/autonomy/delivery.py +373 -0
  20. stagemesh/autonomy/dependencies.py +315 -0
  21. stagemesh/autonomy/destructive_git.py +104 -0
  22. stagemesh/autonomy/gitfacts.py +235 -0
  23. stagemesh/autonomy/github_adapter.py +310 -0
  24. stagemesh/autonomy/hooks.py +39 -0
  25. stagemesh/autonomy/integration.py +65 -0
  26. stagemesh/autonomy/isolation.py +313 -0
  27. stagemesh/autonomy/merge_policy.py +319 -0
  28. stagemesh/autonomy/provenance.py +385 -0
  29. stagemesh/autonomy/recovery_policy.py +148 -0
  30. stagemesh/autonomy/review_adapter.py +139 -0
  31. stagemesh/autonomy/review_policy.py +198 -0
  32. stagemesh/autonomy/scope.py +80 -0
  33. stagemesh/autonomy/supervisor.py +1302 -0
  34. stagemesh/autonomy/wiring.py +145 -0
  35. stagemesh/baseline.py +117 -0
  36. stagemesh/block_kinds.py +259 -0
  37. stagemesh/blocked_recovery.py +188 -0
  38. stagemesh/candidate_environments.py +363 -0
  39. stagemesh/candidate_inspection.py +211 -0
  40. stagemesh/capabilities.py +1580 -0
  41. stagemesh/capability_contracts.py +546 -0
  42. stagemesh/capability_discovery.py +341 -0
  43. stagemesh/capability_vendor.py +512 -0
  44. stagemesh/capacity.py +96 -0
  45. stagemesh/ci.py +76 -0
  46. stagemesh/ci_optimization.py +259 -0
  47. stagemesh/ci_validation_plan.py +356 -0
  48. stagemesh/ci_wait.py +27 -0
  49. stagemesh/claude_plugin_capabilities.py +344 -0
  50. stagemesh/cli.py +6188 -0
  51. stagemesh/completion_audit.py +112 -0
  52. stagemesh/concurrency.py +257 -0
  53. stagemesh/config.py +1146 -0
  54. stagemesh/config_migration.py +245 -0
  55. stagemesh/continuous_driver.py +628 -0
  56. stagemesh/contract_binding.py +176 -0
  57. stagemesh/contract_check.py +275 -0
  58. stagemesh/contract_feasibility.py +284 -0
  59. stagemesh/contracts.py +1428 -0
  60. stagemesh/coordinator.py +1320 -0
  61. stagemesh/dashboard.py +81 -0
  62. stagemesh/delivery_followup.py +493 -0
  63. stagemesh/delivery_state.py +223 -0
  64. stagemesh/demo.py +71 -0
  65. stagemesh/diagnosis.py +926 -0
  66. stagemesh/distributed.py +144 -0
  67. stagemesh/domain.py +109 -0
  68. stagemesh/driver_child.py +66 -0
  69. stagemesh/driver_scheduler.py +241 -0
  70. stagemesh/e2e_acceptance.py +66 -0
  71. stagemesh/e2e_evidence.py +486 -0
  72. stagemesh/efficiency.py +669 -0
  73. stagemesh/execution.py +755 -0
  74. stagemesh/execution_ownership.py +61 -0
  75. stagemesh/external_evidence.py +86 -0
  76. stagemesh/fast_forward.py +712 -0
  77. stagemesh/final_report.py +212 -0
  78. stagemesh/focused_validation.py +269 -0
  79. stagemesh/follow_through.py +227 -0
  80. stagemesh/followup_scheduler.py +103 -0
  81. stagemesh/gate_execution.py +188 -0
  82. stagemesh/gate_process.py +243 -0
  83. stagemesh/git.py +208 -0
  84. stagemesh/git_identity.py +310 -0
  85. stagemesh/github.py +278 -0
  86. stagemesh/github_acceptance.py +73 -0
  87. stagemesh/github_bootstrap.py +154 -0
  88. stagemesh/handoff.py +630 -0
  89. stagemesh/hands_off_recovery.py +54 -0
  90. stagemesh/integration.py +221 -0
  91. stagemesh/integration_recovery.py +266 -0
  92. stagemesh/landing_recovery.py +696 -0
  93. stagemesh/lifecycle.py +49 -0
  94. stagemesh/mcp_capabilities.py +302 -0
  95. stagemesh/mcp_proxy.py +288 -0
  96. stagemesh/migrations.py +203 -0
  97. stagemesh/objective_governance.py +1126 -0
  98. stagemesh/objective_roots.py +87 -0
  99. stagemesh/objectives.py +109 -0
  100. stagemesh/observability.py +212 -0
  101. stagemesh/operator.py +446 -0
  102. stagemesh/operator_actions.py +417 -0
  103. stagemesh/operator_attention.py +165 -0
  104. stagemesh/operator_control.py +390 -0
  105. stagemesh/operator_diagnostics.py +191 -0
  106. stagemesh/operator_doctor.py +256 -0
  107. stagemesh/operator_projects.py +136 -0
  108. stagemesh/operator_providers.py +355 -0
  109. stagemesh/outbound_lifecycle.py +115 -0
  110. stagemesh/parallel.py +1103 -0
  111. stagemesh/persistence.py +2046 -0
  112. stagemesh/persistence_backends.py +56 -0
  113. stagemesh/planning_execution.py +559 -0
  114. stagemesh/postgres_store.py +306 -0
  115. stagemesh/process_identity.py +151 -0
  116. stagemesh/profile.py +345 -0
  117. stagemesh/profile_default.py +93 -0
  118. stagemesh/profile_smoke.py +377 -0
  119. stagemesh/progress.py +245 -0
  120. stagemesh/provider_acceptance.py +556 -0
  121. stagemesh/provider_auth.py +184 -0
  122. stagemesh/provider_authorization.py +263 -0
  123. stagemesh/provider_catalog.py +118 -0
  124. stagemesh/provider_cooldown.py +175 -0
  125. stagemesh/provider_events.py +440 -0
  126. stagemesh/provider_pool.py +1348 -0
  127. stagemesh/providers.py +1838 -0
  128. stagemesh/quality_policy.py +293 -0
  129. stagemesh/queue_control.py +127 -0
  130. stagemesh/queue_reconcile.py +178 -0
  131. stagemesh/queue_run.py +226 -0
  132. stagemesh/queue_visibility.py +117 -0
  133. stagemesh/readiness.py +323 -0
  134. stagemesh/reattribution.py +73 -0
  135. stagemesh/recovery.py +1695 -0
  136. stagemesh/recovery_decision.py +234 -0
  137. stagemesh/redaction.py +130 -0
  138. stagemesh/registry.py +125 -0
  139. stagemesh/regression_orchestrator.py +1219 -0
  140. stagemesh/release.py +143 -0
  141. stagemesh/release_readiness.py +135 -0
  142. stagemesh/remediation.py +432 -0
  143. stagemesh/remediation_recovery.py +116 -0
  144. stagemesh/remote_hosting.py +138 -0
  145. stagemesh/research_context.py +645 -0
  146. stagemesh/retry.py +81 -0
  147. stagemesh/review.py +1041 -0
  148. stagemesh/review_disposition.py +299 -0
  149. stagemesh/review_identity.py +148 -0
  150. stagemesh/routing.py +116 -0
  151. stagemesh/run_ready.py +1230 -0
  152. stagemesh/run_window.py +1568 -0
  153. stagemesh/runtime_freshness.py +132 -0
  154. stagemesh/runtime_info.py +192 -0
  155. stagemesh/scheduling.py +59 -0
  156. stagemesh/security.py +24 -0
  157. stagemesh/selection_scope.py +300 -0
  158. stagemesh/serialized_integration.py +410 -0
  159. stagemesh/skill_packs/frontend-design/LICENSE.txt +177 -0
  160. stagemesh/skill_packs/frontend-design/SKILL.md +71 -0
  161. stagemesh/skill_packs/manifest.json +57 -0
  162. stagemesh/skill_packs/superpowers/LICENSE.txt +21 -0
  163. stagemesh/skill_packs/superpowers/receiving-code-review/SKILL.md +205 -0
  164. stagemesh/skill_packs/superpowers/systematic-debugging/SKILL.md +283 -0
  165. stagemesh/skill_packs/superpowers/systematic-debugging/condition-based-waiting-example.ts +158 -0
  166. stagemesh/skill_packs/superpowers/systematic-debugging/condition-based-waiting.md +115 -0
  167. stagemesh/skill_packs/superpowers/systematic-debugging/defense-in-depth.md +122 -0
  168. stagemesh/skill_packs/superpowers/systematic-debugging/find-polluter.sh +72 -0
  169. stagemesh/skill_packs/superpowers/systematic-debugging/root-cause-tracing.md +169 -0
  170. stagemesh/skill_packs/superpowers/test-driven-development/SKILL.md +330 -0
  171. stagemesh/skill_packs/superpowers/test-driven-development/writing-good-tests.md +198 -0
  172. stagemesh/skill_packs/superpowers/verification-before-completion/SKILL.md +120 -0
  173. stagemesh/spec_integrity.py +1390 -0
  174. stagemesh/spec_planning.py +578 -0
  175. stagemesh/spec_refs.py +93 -0
  176. stagemesh/stage_dispatch.py +48 -0
  177. stagemesh/step_progress.py +144 -0
  178. stagemesh/survivor_wave.py +1256 -0
  179. stagemesh/task_completion.py +236 -0
  180. stagemesh/task_selection.py +424 -0
  181. stagemesh/task_sources.py +685 -0
  182. stagemesh/test_isolation.py +291 -0
  183. stagemesh/test_taxonomy.py +999 -0
  184. stagemesh/timing.py +146 -0
  185. stagemesh/ui/app.css +57 -0
  186. stagemesh/ui/app.js +1691 -0
  187. stagemesh/ui/index.html +387 -0
  188. stagemesh/ui_launcher.py +129 -0
  189. stagemesh/validation.py +553 -0
  190. stagemesh/validation_components.py +353 -0
  191. stagemesh/validation_plan.py +489 -0
  192. stagemesh/validation_reuse.py +216 -0
  193. stagemesh/validation_services.py +969 -0
  194. stagemesh/validation_slot.py +228 -0
  195. stagemesh/visual_reference.py +283 -0
  196. stagemesh/window_journal.py +90 -0
  197. stagemesh/work_transport.py +125 -0
  198. stagemesh/workers.py +83 -0
  199. stagemesh/workspace_guard.py +1028 -0
  200. stagemesh/workspaces.py +351 -0
  201. stagemesh-0.6.0.dist-info/LICENSE +21 -0
  202. stagemesh-0.6.0.dist-info/METADATA +172 -0
  203. stagemesh-0.6.0.dist-info/RECORD +205 -0
  204. stagemesh-0.6.0.dist-info/WHEEL +4 -0
  205. stagemesh-0.6.0.dist-info/entry_points.txt +2 -0
stagemesh/__init__.py ADDED
@@ -0,0 +1,7 @@
1
+ """StageMesh vNext."""
2
+
3
+ from .hands_off_recovery import apply_provider_no_progress_recovery_patch
4
+
5
+ __version__ = "0.6.0"
6
+
7
+ apply_provider_no_progress_recovery_patch()
@@ -0,0 +1,3 @@
1
+ SOURCE_COMMIT = 'a89f9461be3e6f339a39c950effadb9022f45f03'
2
+ SOURCE_DIRTY = False
3
+ BUILT_FROM = '/home/runner/work/stagemesh/stagemesh'
@@ -0,0 +1,121 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import subprocess
5
+ import sys
6
+ import time
7
+ from dataclasses import dataclass
8
+ from pathlib import Path
9
+
10
+ from .security import WorkspaceBoundary
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class AcceptanceCheck:
15
+ name: str
16
+ status: str
17
+ output: str
18
+
19
+
20
+ class AcceptanceValidationError(ValueError):
21
+ pass
22
+
23
+
24
+ def run_check(name: str, command: list[str], cwd: Path) -> AcceptanceCheck:
25
+ name = _validate_text(name, "acceptance check name")
26
+ command = _validate_command(command)
27
+ cwd = _validate_root(cwd)
28
+ result = subprocess.run(command, cwd=cwd, text=True, capture_output=True, check=False)
29
+ status = "PASS" if result.returncode == 0 else "FAIL"
30
+ return AcceptanceCheck(name, status, result.stdout + result.stderr)
31
+
32
+
33
+ def local_acceptance_report(root: Path, include_acceptance: bool = True) -> dict[str, object]:
34
+ root = _validate_root(root)
35
+ checks = [
36
+ run_check("compile", [sys.executable, "-m", "compileall", "-q", "src", "scripts", "build_backend.py"], root),
37
+ run_check("invariants", [sys.executable, "scripts/invariants.py"], root),
38
+ run_check("provider_acceptance", [sys.executable, "scripts/provider_acceptance.py"], root),
39
+ run_check("github_acceptance", [sys.executable, "scripts/github_acceptance.py"], root),
40
+ run_check("live_acceptance", [sys.executable, "scripts/live_acceptance.py", "--json"], root),
41
+ run_check("clean_acceptance", [sys.executable, "scripts/clean_acceptance.py"], root),
42
+ run_check("install", [sys.executable, "-m", "pip", "install", ".", "--target", ".tmp-install", "--no-cache-dir", "--upgrade"], root),
43
+ ]
44
+ if include_acceptance:
45
+ checks.insert(2, run_check("acceptance", [sys.executable, "scripts/acceptance.py"], root))
46
+ gaps = proof_gaps(checks)
47
+ return {
48
+ "generated_at": time.time(),
49
+ "status": "PASS" if all(check.status == "PASS" for check in checks) else "FAIL",
50
+ "proof_status": "BLOCKED_ON_EXTERNAL_EVIDENCE" if gaps else "PROVEN",
51
+ "proof_gaps": gaps,
52
+ "checks": [
53
+ {"name": check.name, "status": check.status, "output": check.output[-4000:]}
54
+ for check in checks
55
+ ],
56
+ }
57
+
58
+
59
+ def write_acceptance_report(root: Path, output: Path, include_acceptance: bool = True) -> None:
60
+ root = _validate_root(root)
61
+ output = WorkspaceBoundary(root).require_inside(output)
62
+ output.parent.mkdir(parents=True, exist_ok=True)
63
+ output.write_text(
64
+ json.dumps(local_acceptance_report(root, include_acceptance), indent=2, sort_keys=True),
65
+ encoding="utf-8",
66
+ )
67
+
68
+
69
+ def proof_gaps(checks: list[AcceptanceCheck]) -> list[dict[str, str]]:
70
+ gaps: list[dict[str, str]] = []
71
+ for check in checks:
72
+ parsed = _structured_proof_gaps(check)
73
+ if parsed:
74
+ gaps.extend(parsed)
75
+ continue
76
+ for line in check.output.splitlines():
77
+ if "NOT_CONFIGURED" in line or "NOT_PROVEN" in line:
78
+ gaps.append({"check": check.name, "evidence": line.strip()})
79
+ return gaps
80
+
81
+
82
+ def _structured_proof_gaps(check: AcceptanceCheck) -> list[dict[str, str]]:
83
+ try:
84
+ data = json.loads(check.output)
85
+ except json.JSONDecodeError:
86
+ return []
87
+ if not isinstance(data, dict) or not isinstance(data.get("checks"), list):
88
+ return []
89
+ gaps: list[dict[str, str]] = []
90
+ for item in data["checks"]:
91
+ if not isinstance(item, dict):
92
+ continue
93
+ name = item.get("name")
94
+ status = item.get("status")
95
+ if isinstance(name, str) and status in {"NOT_CONFIGURED", "NOT_PROVEN"}:
96
+ gaps.append({"check": check.name, "evidence": f"{name}: {status}"})
97
+ return gaps
98
+
99
+
100
+ def _validate_text(value: str, field: str, max_length: int = 200) -> str:
101
+ if not isinstance(value, str):
102
+ raise AcceptanceValidationError(f"{field} must be a string")
103
+ normalized = value.strip()
104
+ if not normalized:
105
+ raise AcceptanceValidationError(f"{field} must be a non-empty string")
106
+ if len(normalized) > max_length:
107
+ raise AcceptanceValidationError(f"{field} must be {max_length} characters or fewer")
108
+ return normalized
109
+
110
+
111
+ def _validate_command(command: list[str]) -> list[str]:
112
+ if not isinstance(command, list) or not command:
113
+ raise AcceptanceValidationError("acceptance command must be a non-empty list")
114
+ return [_validate_text(arg, "acceptance command argument", 1000) for arg in command]
115
+
116
+
117
+ def _validate_root(root: Path) -> Path:
118
+ resolved = Path(root).resolve()
119
+ if not resolved.exists() or not resolved.is_dir():
120
+ raise AcceptanceValidationError("acceptance root must be an existing directory")
121
+ return resolved
@@ -0,0 +1,52 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from dataclasses import dataclass
5
+ from pathlib import Path
6
+
7
+ from .completion_audit import completion_audit
8
+ from .persistence import Store
9
+ from .security import WorkspaceBoundary
10
+
11
+
12
+ class AcceptanceMatrixValidationError(ValueError):
13
+ pass
14
+
15
+
16
+ @dataclass(frozen=True)
17
+ class MatrixRow:
18
+ area: str
19
+ status: str
20
+ evidence: str
21
+
22
+
23
+ def acceptance_matrix(store: Store | None = None, candidate_sha: str | None = None) -> dict[str, object]:
24
+ audit = completion_audit(store, candidate_sha)
25
+ rows = [
26
+ MatrixRow(str(item["requirement"]), str(item["status"]), str(item["evidence"]))
27
+ for item in audit["items"]
28
+ ]
29
+ proven = sum(1 for row in rows if row.status == "PROVEN")
30
+ return {
31
+ "status": "COMPLETE" if proven == len(rows) else "INCOMPLETE",
32
+ "proven": proven,
33
+ "total": len(rows),
34
+ "rows": [row.__dict__ for row in rows],
35
+ }
36
+
37
+
38
+ def write_acceptance_matrix(
39
+ path: Path, store: Store | None = None, root: Path | None = None, candidate_sha: str | None = None
40
+ ) -> None:
41
+ path = _validate_output(path, root)
42
+ path.parent.mkdir(parents=True, exist_ok=True)
43
+ path.write_text(json.dumps(acceptance_matrix(store, candidate_sha), indent=2, sort_keys=True), encoding="utf-8")
44
+
45
+
46
+ def _validate_output(path: Path, root: Path | None) -> Path:
47
+ output = Path(path).resolve()
48
+ if root is not None:
49
+ return WorkspaceBoundary(Path(root).resolve()).require_inside(output)
50
+ if not output.name or output.is_dir():
51
+ raise AcceptanceMatrixValidationError("acceptance matrix output must name a file")
52
+ return output