devtime-ei 0.1.3__tar.gz → 0.3.0__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 (77) hide show
  1. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/PKG-INFO +30 -4
  2. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/README.md +28 -2
  3. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/pyproject.toml +2 -2
  4. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/__init__.py +1 -1
  5. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/cli.py +113 -0
  6. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/db/schema.sql +15 -0
  7. devtime_ei-0.3.0/src/devtime/intelligence/verification.py +603 -0
  8. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/mcp/transport.py +45 -1
  9. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/nextjs.py +14 -2
  10. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/signals.py +5 -1
  11. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime_ei.egg-info/PKG-INFO +30 -4
  12. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime_ei.egg-info/SOURCES.txt +1 -0
  13. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/LICENSE +0 -0
  14. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/setup.cfg +0 -0
  15. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/ai/__init__.py +0 -0
  16. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/ai/local.py +0 -0
  17. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/ai/prompts.py +0 -0
  18. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/ai/providers.py +0 -0
  19. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/assets/devtimeignore.starter +0 -0
  20. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/config.py +0 -0
  21. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/db/__init__.py +0 -0
  22. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/db/connection.py +0 -0
  23. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/db/migrations.py +0 -0
  24. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/db/repository.py +0 -0
  25. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/demo.py +0 -0
  26. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/fixtures/__init__.py +0 -0
  27. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/fixtures/assertions.py +0 -0
  28. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/fixtures/loader.py +0 -0
  29. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/fixtures/runner.py +0 -0
  30. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/__init__.py +0 -0
  31. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/claims.py +0 -0
  32. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/concepts.py +0 -0
  33. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/context_pack.py +0 -0
  34. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/evidence.py +0 -0
  35. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/lineage.py +0 -0
  36. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/risk.py +0 -0
  37. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/intelligence/scoring.py +0 -0
  38. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/mcp/__init__.py +0 -0
  39. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/mcp/schemas.py +0 -0
  40. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/mcp/server.py +0 -0
  41. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/mcp/tools.py +0 -0
  42. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/output/__init__.py +0 -0
  43. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/output/json_export.py +0 -0
  44. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/output/markdown.py +0 -0
  45. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/output/terminal.py +0 -0
  46. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/paths.py +0 -0
  47. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/privacy.py +0 -0
  48. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/.devtimeignore +0 -0
  49. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/README.md +0 -0
  50. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/docs/decisions/0001-use-jwt.md +0 -0
  51. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/package.json +0 -0
  52. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/admin/permissions.ts +0 -0
  53. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/auth/login.ts +0 -0
  54. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/auth/middleware.ts +0 -0
  55. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/auth/tokens.ts +0 -0
  56. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/billing/stripe-webhook.ts +0 -0
  57. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/billing/subscription-service.ts +0 -0
  58. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/export/export-csv.ts +0 -0
  59. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/jobs/email-worker.ts +0 -0
  60. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/src/jobs/queues.ts +0 -0
  61. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/tests/auth-login.test.ts +0 -0
  62. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/resources/demo-saas/tests/stripe-signature.test.ts +0 -0
  63. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/__init__.py +0 -0
  64. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/__init__.py +0 -0
  65. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/base.py +0 -0
  66. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/config_files.py +0 -0
  67. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/docs.py +0 -0
  68. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/python.py +0 -0
  69. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/tests.py +0 -0
  70. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/extractors/typescript.py +0 -0
  71. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/file_walker.py +0 -0
  72. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/ignore.py +0 -0
  73. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime/scanner/language.py +0 -0
  74. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime_ei.egg-info/dependency_links.txt +0 -0
  75. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime_ei.egg-info/entry_points.txt +0 -0
  76. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime_ei.egg-info/requires.txt +0 -0
  77. {devtime_ei-0.1.3 → devtime_ei-0.3.0}/src/devtime_ei.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devtime-ei
3
- Version: 0.1.3
3
+ Version: 0.3.0
4
4
  Summary: Local-first Engineering Intelligence for software repositories
5
5
  Author-email: Aviad Shakargi <aviad94@gmail.com>
6
6
  Maintainer-email: Aviad Shakargi <aviad94@gmail.com>
@@ -8,7 +8,7 @@ License: Apache-2.0
8
8
  Project-URL: Homepage, https://github.com/Shakargy/devtime
9
9
  Project-URL: Repository, https://github.com/Shakargy/devtime
10
10
  Project-URL: Issues, https://github.com/Shakargy/devtime/issues
11
- Project-URL: Release Notes, https://github.com/Shakargy/devtime/releases/tag/v0.1.3
11
+ Project-URL: Release Notes, https://github.com/Shakargy/devtime/releases/tag/v0.3.0
12
12
  Project-URL: Demo, https://youtu.be/1Hiu3Y9J_SI
13
13
  Keywords: devtools,cli,static-analysis,repository-analysis,engineering-intelligence,local-first
14
14
  Classifier: Development Status :: 3 - Alpha
@@ -204,6 +204,7 @@ Anything outside these six is out of scope for V0. See [LIMITATIONS.md](LIMITATI
204
204
  | `dtc context <concept>` | Create a governed Context Pack for agents or humans. |
205
205
  | `dtc risk --diff` | Review a git diff for risky changes using local evidence (advisory). |
206
206
  | `dtc decision add` | Add a local decision record that can reduce uncertainty. |
207
+ | `dtc verify [claim]` | Verify a repository claim against evidence: status, contradictions, freshness (experimental). |
207
208
 
208
209
  (Also available: `dtc evidence`, `dtc debt`, `dtc status`, `dtc doctor --privacy`,
209
210
  `dtc export`, `dtc reset`, `dtc mcp start`.)
@@ -246,9 +247,10 @@ Or in any MCP client that reads `.mcp.json`:
246
247
  }
247
248
  ```
248
249
 
249
- The agent gets three read-only tools: `list_concepts`, `explain_concept`, and
250
+ The agent gets four read-only tools: `list_concepts`, `explain_concept`,
250
251
  `get_context_pack` (governed context with do-not-change-without-review paths, tests
251
- to run, and agent guidance). Local stdio only - no network listener, no write tools,
252
+ to run, and agent guidance), and `verify_claim` (claim status, contradictions, and
253
+ missing evidence, computed fresh and never persisted). Local stdio only - no network listener, no write tools,
252
254
  no source code returned, only evidence file paths.
253
255
 
254
256
  DevTime is listed in the official MCP Registry as `io.github.Shakargy/devtime`.
@@ -294,6 +296,30 @@ python -m venv .venv
294
296
  pip install -e ".[dev]"
295
297
  ```
296
298
 
299
+ ## Verify claims (experimental)
300
+
301
+ DevTime is growing into a verification layer: ask whether a statement about the
302
+ repository is actually supported.
303
+
304
+ ```bash
305
+ dtc verify billing-webhook-signature
306
+ ```
307
+
308
+ ```
309
+ Billing Webhook Signature Verification
310
+ Claim: Incoming billing webhooks verify the payment provider's signature.
311
+ Status: CONTRADICTED
312
+
313
+ Contradictions:
314
+ - The billing webhook endpoint cannot verify signatures because it is a disabled stub.
315
+ claimed: apps/web/pages/api/stripe/webhook.ts is named and routed as a billing webhook endpoint.
316
+ observed: The handler's only behavior is a 404/501 response.
317
+ ```
318
+
319
+ Statuses are SUPPORTED, WEAK, CONTRADICTED, or UNKNOWN; contradictions always
320
+ show both sides; changed evidence marks a claim STALE. Two built-in claims ship
321
+ (billing webhook signatures, JWT authentication). See **[VERIFICATION.md](VERIFICATION.md)**.
322
+
297
323
  ## Example output
298
324
 
299
325
  ```
@@ -165,6 +165,7 @@ Anything outside these six is out of scope for V0. See [LIMITATIONS.md](LIMITATI
165
165
  | `dtc context <concept>` | Create a governed Context Pack for agents or humans. |
166
166
  | `dtc risk --diff` | Review a git diff for risky changes using local evidence (advisory). |
167
167
  | `dtc decision add` | Add a local decision record that can reduce uncertainty. |
168
+ | `dtc verify [claim]` | Verify a repository claim against evidence: status, contradictions, freshness (experimental). |
168
169
 
169
170
  (Also available: `dtc evidence`, `dtc debt`, `dtc status`, `dtc doctor --privacy`,
170
171
  `dtc export`, `dtc reset`, `dtc mcp start`.)
@@ -207,9 +208,10 @@ Or in any MCP client that reads `.mcp.json`:
207
208
  }
208
209
  ```
209
210
 
210
- The agent gets three read-only tools: `list_concepts`, `explain_concept`, and
211
+ The agent gets four read-only tools: `list_concepts`, `explain_concept`,
211
212
  `get_context_pack` (governed context with do-not-change-without-review paths, tests
212
- to run, and agent guidance). Local stdio only - no network listener, no write tools,
213
+ to run, and agent guidance), and `verify_claim` (claim status, contradictions, and
214
+ missing evidence, computed fresh and never persisted). Local stdio only - no network listener, no write tools,
213
215
  no source code returned, only evidence file paths.
214
216
 
215
217
  DevTime is listed in the official MCP Registry as `io.github.Shakargy/devtime`.
@@ -255,6 +257,30 @@ python -m venv .venv
255
257
  pip install -e ".[dev]"
256
258
  ```
257
259
 
260
+ ## Verify claims (experimental)
261
+
262
+ DevTime is growing into a verification layer: ask whether a statement about the
263
+ repository is actually supported.
264
+
265
+ ```bash
266
+ dtc verify billing-webhook-signature
267
+ ```
268
+
269
+ ```
270
+ Billing Webhook Signature Verification
271
+ Claim: Incoming billing webhooks verify the payment provider's signature.
272
+ Status: CONTRADICTED
273
+
274
+ Contradictions:
275
+ - The billing webhook endpoint cannot verify signatures because it is a disabled stub.
276
+ claimed: apps/web/pages/api/stripe/webhook.ts is named and routed as a billing webhook endpoint.
277
+ observed: The handler's only behavior is a 404/501 response.
278
+ ```
279
+
280
+ Statuses are SUPPORTED, WEAK, CONTRADICTED, or UNKNOWN; contradictions always
281
+ show both sides; changed evidence marks a claim STALE. Two built-in claims ship
282
+ (billing webhook signatures, JWT authentication). See **[VERIFICATION.md](VERIFICATION.md)**.
283
+
258
284
  ## Example output
259
285
 
260
286
  ```
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "devtime-ei"
3
- version = "0.1.3"
3
+ version = "0.3.0"
4
4
  description = "Local-first Engineering Intelligence for software repositories"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -50,7 +50,7 @@ dev = [
50
50
  Homepage = "https://github.com/Shakargy/devtime"
51
51
  Repository = "https://github.com/Shakargy/devtime"
52
52
  Issues = "https://github.com/Shakargy/devtime/issues"
53
- "Release Notes" = "https://github.com/Shakargy/devtime/releases/tag/v0.1.3"
53
+ "Release Notes" = "https://github.com/Shakargy/devtime/releases/tag/v0.3.0"
54
54
  Demo = "https://youtu.be/1Hiu3Y9J_SI"
55
55
 
56
56
  [project.scripts]
@@ -1,6 +1,6 @@
1
1
  """DevTime - local-first Engineering Intelligence for repository memory."""
2
2
 
3
- __version__ = "0.1.3"
3
+ __version__ = "0.3.0"
4
4
 
5
5
  # Version metadata (Builder Edition, Chapter 20).
6
6
  EVIDENCE_MODEL = "2026.06.1"
@@ -78,6 +78,119 @@ def demo_init(
78
78
  console.print(' dtc explain "Billing Webhooks"')
79
79
 
80
80
 
81
+ @app.command()
82
+ def verify(
83
+ claim: str = typer.Argument(None, help="Claim id to verify. Omit to verify all built-in claims."),
84
+ list_claims: bool = typer.Option(False, "--list", help="List built-in claims with last status and freshness."),
85
+ as_json: bool = typer.Option(False, "--json", help="Stable machine-readable output."),
86
+ ) -> None:
87
+ """Verify a repository claim against scanned evidence (v0.2 experimental)."""
88
+ import json as _json
89
+
90
+ from devtime.db import connection
91
+ from devtime.intelligence import verification as ver
92
+
93
+ if not paths.is_initialized():
94
+ console.print("[red]Not initialized.[/red] Run dtc init first.")
95
+ raise typer.Exit(code=2)
96
+
97
+ conn = connection.connect()
98
+ try:
99
+ if list_claims:
100
+ rows = []
101
+ for slug, definition in ver.BUILTIN_CLAIMS.items():
102
+ latest = ver.load_latest_verification(conn, slug)
103
+ freshness, changed = ver.freshness_for(conn, slug)
104
+ rows.append(
105
+ {
106
+ "claim_id": slug,
107
+ "name": definition.name,
108
+ "statement": definition.statement,
109
+ "last_status": latest[0]["status"] if latest else None,
110
+ "freshness": freshness,
111
+ "changed_evidence": changed,
112
+ }
113
+ )
114
+ if as_json:
115
+ console.print_json(_json.dumps({"schema_version": "1", "claims": rows}))
116
+ else:
117
+ console.print("[bold]Built-in claims[/bold]\n")
118
+ for r in rows:
119
+ status_txt = r["last_status"] or "never verified"
120
+ console.print(f" {r['claim_id']}")
121
+ console.print(f" {r['statement']}")
122
+ console.print(f" last status: {status_txt} freshness: {r['freshness']}")
123
+ for p in r["changed_evidence"]:
124
+ console.print(f" changed since verification: {p}", markup=False)
125
+ console.print("")
126
+ return
127
+
128
+ slugs = [claim] if claim else list(ver.BUILTIN_CLAIMS.keys())
129
+ results = []
130
+ for slug in slugs:
131
+ try:
132
+ result = ver.verify_claim(conn, slug)
133
+ except KeyError:
134
+ console.print(f"[red]Unknown claim:[/red] {slug}")
135
+ console.print("Run [bold]dtc verify --list[/bold] to see built-in claims.")
136
+ raise typer.Exit(code=1)
137
+ ver.save_verification(conn, result)
138
+ results.append(result)
139
+
140
+ if as_json:
141
+ console.print_json(
142
+ _json.dumps(
143
+ {
144
+ "schema_version": "1",
145
+ "command": "verify",
146
+ "results": [r.to_dict() for r in results],
147
+ }
148
+ )
149
+ )
150
+ return
151
+
152
+ for result in results:
153
+ _print_verification(result)
154
+ finally:
155
+ conn.close()
156
+
157
+
158
+ def _print_verification(result) -> None:
159
+ color = {
160
+ "SUPPORTED": "green",
161
+ "WEAK": "yellow",
162
+ "CONTRADICTED": "red",
163
+ "UNKNOWN": "cyan",
164
+ }.get(result.status, "white")
165
+ console.print(f"[bold]{result.claim_name}[/bold]")
166
+ console.print(f"Claim: {result.statement}")
167
+ console.print(f"Status: [{color}]{result.status}[/{color}]")
168
+ console.print("")
169
+ console.print("Why:")
170
+ for line in result.why:
171
+ console.print(f" - {line}", markup=False)
172
+ if result.supporting:
173
+ console.print("\nSupporting evidence:")
174
+ for e in result.supporting[:6]:
175
+ loc = f":{e.start_line}" if e.start_line else ""
176
+ console.print(f" - {e.path}{loc} [{e.strength}]", markup=False)
177
+ console.print(f" {e.observation}", markup=False)
178
+ if result.contradictions:
179
+ console.print("\n[red]Contradictions:[/red]")
180
+ for c in result.contradictions:
181
+ console.print(f" - {c.summary}", markup=False)
182
+ console.print(f" claimed: {c.claimed_side}", markup=False)
183
+ console.print(f" observed: {c.observed_side}", markup=False)
184
+ if result.missing:
185
+ console.print("\nMissing evidence:")
186
+ for m in result.missing:
187
+ console.print(f" - {m}", markup=False)
188
+ console.print("\nLimitations:")
189
+ for lim in result.limitations:
190
+ console.print(f" - {lim}", markup=False)
191
+ console.print("")
192
+
193
+
81
194
  @app.command()
82
195
  def status() -> None:
83
196
  """Show local storage, AI, cloud, telemetry, MCP, and scan status."""
@@ -135,6 +135,21 @@ CREATE TABLE IF NOT EXISTS risk_findings (
135
135
  created_at TEXT NOT NULL
136
136
  );
137
137
 
138
+ -- v0.2.0: immutable claim verification results (the verification slice).
139
+ -- Databases created before v0.2.0 get this table lazily via
140
+ -- verification.ensure_verifications_table (idempotent, no migration needed).
141
+ CREATE TABLE IF NOT EXISTS verifications (
142
+ id TEXT PRIMARY KEY,
143
+ repository_id TEXT NOT NULL,
144
+ claim_slug TEXT NOT NULL,
145
+ status TEXT NOT NULL,
146
+ scan_id TEXT,
147
+ result_json TEXT NOT NULL,
148
+ evidence_fingerprints_json TEXT NOT NULL DEFAULT '[]',
149
+ engine_version TEXT NOT NULL,
150
+ created_at TEXT NOT NULL
151
+ );
152
+
138
153
  CREATE TABLE IF NOT EXISTS context_packs (
139
154
  id TEXT PRIMARY KEY,
140
155
  concept_id TEXT NOT NULL,