graphite-code 0.3.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.
- graphite/__init__.py +41 -0
- graphite/__main__.py +7 -0
- graphite/_cleanup_worker.py +525 -0
- graphite/activation.py +164 -0
- graphite/agent_hooks.py +577 -0
- graphite/agent_settings.py +226 -0
- graphite/analyze.py +146 -0
- graphite/answer_contract.py +420 -0
- graphite/bootstrap.py +210 -0
- graphite/buildlock.py +99 -0
- graphite/cache.py +131 -0
- graphite/channel.py +1325 -0
- graphite/cli.py +3053 -0
- graphite/cluster.py +111 -0
- graphite/config.py +209 -0
- graphite/context.py +355 -0
- graphite/daemon.py +745 -0
- graphite/daemon_health.py +733 -0
- graphite/debt.py +118 -0
- graphite/dependency_install.py +1597 -0
- graphite/detach.py +33 -0
- graphite/doctor.py +678 -0
- graphite/doctor_probes.py +2100 -0
- graphite/engine_identity.py +238 -0
- graphite/export/__init__.py +6 -0
- graphite/export/html.py +244 -0
- graphite/export/json.py +39 -0
- graphite/export/md.py +68 -0
- graphite/extract/__init__.py +4 -0
- graphite/extract/ast.py +1964 -0
- graphite/freshness.py +127 -0
- graphite/git.py +406 -0
- graphite/graph.py +117 -0
- graphite/graph_io.py +188 -0
- graphite/health.py +147 -0
- graphite/hook_entry.py +68 -0
- graphite/hookinstall.py +224 -0
- graphite/hookshim.py +86 -0
- graphite/incident_ledger.py +247 -0
- graphite/ingest.py +279 -0
- graphite/init.py +791 -0
- graphite/io.py +32 -0
- graphite/listing.py +51 -0
- graphite/llm.py +518 -0
- graphite/llm_probe.py +157 -0
- graphite/mcp.py +7 -0
- graphite/mcp_server.py +450 -0
- graphite/natural_query.py +252 -0
- graphite/overlays.py +713 -0
- graphite/probe_process.py +879 -0
- graphite/probe_workspace.py +728 -0
- graphite/process_contracts.py +22 -0
- graphite/provider_observer.py +397 -0
- graphite/query.py +646 -0
- graphite/query_plan.py +97 -0
- graphite/replacement_audit.py +291 -0
- graphite/resolve.py +660 -0
- graphite/review.py +782 -0
- graphite/routing/__init__.py +5 -0
- graphite/routing/approval.py +362 -0
- graphite/routing/classifier.py +169 -0
- graphite/routing/claude_executor.py +419 -0
- graphite/routing/claude_probe.py +102 -0
- graphite/routing/cli_identity.py +84 -0
- graphite/routing/codex_executor.py +383 -0
- graphite/routing/codex_probe.py +93 -0
- graphite/routing/context_builder.py +327 -0
- graphite/routing/contracts.py +802 -0
- graphite/routing/diff_policy.py +468 -0
- graphite/routing/edit_apply.py +166 -0
- graphite/routing/effort.py +43 -0
- graphite/routing/lifecycle.py +771 -0
- graphite/routing/lifecycle_operator.py +227 -0
- graphite/routing/lifecycle_service.py +555 -0
- graphite/routing/lifecycle_storage.py +977 -0
- graphite/routing/ollama_executor.py +341 -0
- graphite/routing/ollama_probe.py +72 -0
- graphite/routing/openrouter_executor.py +338 -0
- graphite/routing/openrouter_probe.py +188 -0
- graphite/routing/policy.py +815 -0
- graphite/routing/probe_runner.py +543 -0
- graphite/routing/process_runner.py +523 -0
- graphite/routing/profiles.py +554 -0
- graphite/routing/prompt.py +58 -0
- graphite/routing/registry.py +444 -0
- graphite/routing/route_pool.py +629 -0
- graphite/routing/route_pool_execution.py +275 -0
- graphite/routing/schema_validation.py +169 -0
- graphite/routing/service.py +1263 -0
- graphite/routing/settings.py +99 -0
- graphite/routing/shadow.py +201 -0
- graphite/routing/storage.py +4001 -0
- graphite/routing/telemetry.py +346 -0
- graphite/routing/worktree.py +259 -0
- graphite/routing/zai_edit.py +113 -0
- graphite/routing/zai_executor.py +191 -0
- graphite/routing/zai_probe.py +126 -0
- graphite/savings.py +84 -0
- graphite/ts_bridge.py +142 -0
- graphite/ts_resolver.mjs +314 -0
- graphite/typescript_activation.py +1586 -0
- graphite/usage_ledger.py +156 -0
- graphite/validation.py +148 -0
- graphite/watch.py +167 -0
- graphite/windows_job.py +368 -0
- graphite/windows_startup.py +144 -0
- graphite/windows_task.py +212 -0
- graphite_code-0.3.0.dist-info/METADATA +743 -0
- graphite_code-0.3.0.dist-info/RECORD +112 -0
- graphite_code-0.3.0.dist-info/WHEEL +4 -0
- graphite_code-0.3.0.dist-info/entry_points.txt +3 -0
- graphite_code-0.3.0.dist-info/licenses/LICENSE +21 -0
graphite/debt.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Declared debt, with the interval that makes it actionable.
|
|
2
|
+
|
|
3
|
+
The target for this project was never "zero known issues". That bar punishes the
|
|
4
|
+
sessions that find real defects, and it is satisfiable by not looking. What
|
|
5
|
+
matters is the LATENCY: how long a blind spot stays known-but-undeclared, and
|
|
6
|
+
then how long a declared one stays open.
|
|
7
|
+
|
|
8
|
+
`CAVEAT_REGISTRY` already records both endpoints -- `since` is the day a
|
|
9
|
+
blindspot class was confirmed, `retired_by` the day it stopped being emitted,
|
|
10
|
+
and its process rule requires the entry on the day of confirmation, decoupled
|
|
11
|
+
from the fix. So the series existed and nothing read it.
|
|
12
|
+
|
|
13
|
+
Deliberately offline and deterministic, like every other canonical surface here:
|
|
14
|
+
`as_of` is a parameter rather than a call to `date.today()`, so the output can
|
|
15
|
+
be asserted on and compared across runs. GitHub issues are NOT consulted --
|
|
16
|
+
that would put a network call and a non-reproducible answer inside a diagnostic
|
|
17
|
+
whose whole value is being comparable.
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from datetime import date
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from .answer_contract import CAVEAT_REGISTRY
|
|
25
|
+
|
|
26
|
+
DEBT_SCHEMA = 1
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _parse(stamp: str) -> date:
|
|
30
|
+
return date.fromisoformat(stamp)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def debt_report(*, as_of: date) -> dict[str, Any]:
|
|
34
|
+
"""Declared blind spots, open and retired, as of a given day."""
|
|
35
|
+
open_items: list[dict[str, Any]] = []
|
|
36
|
+
retired_items: list[dict[str, Any]] = []
|
|
37
|
+
|
|
38
|
+
for entry in CAVEAT_REGISTRY:
|
|
39
|
+
since = _parse(entry["since"])
|
|
40
|
+
retired_by = entry.get("retired_by")
|
|
41
|
+
if retired_by:
|
|
42
|
+
retired_items.append(
|
|
43
|
+
{
|
|
44
|
+
"code": entry["code"],
|
|
45
|
+
"summary": entry["summary"],
|
|
46
|
+
"since": entry["since"],
|
|
47
|
+
"retired_by": retired_by,
|
|
48
|
+
# Declaration -> fix. Zero is a real and good value: the
|
|
49
|
+
# process rule allows an entry and its fix on the same day.
|
|
50
|
+
"latency_days": (_parse(retired_by) - since).days,
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
continue
|
|
54
|
+
open_items.append(
|
|
55
|
+
{
|
|
56
|
+
"code": entry["code"],
|
|
57
|
+
"summary": entry["summary"],
|
|
58
|
+
"since": entry["since"],
|
|
59
|
+
# Clamped at zero: `as_of` is operator input and can precede a
|
|
60
|
+
# declaration. A negative age would read as a fresh item and
|
|
61
|
+
# sort itself to the bottom of the list, which is the one place
|
|
62
|
+
# nobody looks.
|
|
63
|
+
"age_days": max(0, (as_of - since).days),
|
|
64
|
+
}
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Oldest first: the list is read top-down, and the top is where attention
|
|
68
|
+
# goes. Ties break on code so the ordering is total and the report is
|
|
69
|
+
# comparable across runs.
|
|
70
|
+
open_items.sort(key=lambda item: (-item["age_days"], item["code"]))
|
|
71
|
+
retired_items.sort(key=lambda item: (item["retired_by"], item["code"]))
|
|
72
|
+
|
|
73
|
+
latencies = sorted(item["latency_days"] for item in retired_items)
|
|
74
|
+
summary = {
|
|
75
|
+
"open_count": len(open_items),
|
|
76
|
+
"retired_count": len(retired_items),
|
|
77
|
+
"oldest_open_days": open_items[0]["age_days"] if open_items else 0,
|
|
78
|
+
"oldest_open_code": open_items[0]["code"] if open_items else None,
|
|
79
|
+
"median_retire_latency_days": (
|
|
80
|
+
latencies[len(latencies) // 2] if latencies else None
|
|
81
|
+
),
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
"schema_version": DEBT_SCHEMA,
|
|
86
|
+
"as_of": as_of.isoformat(),
|
|
87
|
+
"open": open_items,
|
|
88
|
+
"retired": retired_items,
|
|
89
|
+
"summary": summary,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def render_debt(report: dict[str, Any]) -> str:
|
|
94
|
+
"""Human rendering. The ages are the point, so they lead each line."""
|
|
95
|
+
lines = [f"[graphite] declared debt as of {report['as_of']}"]
|
|
96
|
+
summary = report["summary"]
|
|
97
|
+
|
|
98
|
+
if not report["open"]:
|
|
99
|
+
lines.append(" no open blind spots declared")
|
|
100
|
+
else:
|
|
101
|
+
lines.append(f" OPEN ({summary['open_count']}):")
|
|
102
|
+
for item in report["open"]:
|
|
103
|
+
lines.append(f" {item['age_days']:>5}d {item['code']}")
|
|
104
|
+
lines.append(f" {item['summary']}")
|
|
105
|
+
|
|
106
|
+
if report["retired"]:
|
|
107
|
+
lines.append(f" RETIRED ({summary['retired_count']}), declaration -> fix:")
|
|
108
|
+
for item in report["retired"]:
|
|
109
|
+
lines.append(f" {item['latency_days']:>5}d {item['code']}")
|
|
110
|
+
|
|
111
|
+
median = summary["median_retire_latency_days"]
|
|
112
|
+
if median is not None:
|
|
113
|
+
lines.append(f" median time to retire: {median}d")
|
|
114
|
+
lines.append(
|
|
115
|
+
" note: counts are not the target -- an unfixed blind spot that is "
|
|
116
|
+
"DECLARED is working as designed; an undeclared one is the failure."
|
|
117
|
+
)
|
|
118
|
+
return "\n".join(lines)
|