devtime-ei 0.4.0__tar.gz → 0.5.1__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.
- {devtime_ei-0.4.0/src/devtime_ei.egg-info → devtime_ei-0.5.1}/PKG-INFO +67 -40
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/README.md +65 -38
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/pyproject.toml +2 -2
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/__init__.py +1 -1
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/cli.py +115 -11
- devtime_ei-0.5.1/src/devtime/intelligence/verification.py +1212 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/mcp/transport.py +30 -9
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/typescript.py +33 -3
- {devtime_ei-0.4.0 → devtime_ei-0.5.1/src/devtime_ei.egg-info}/PKG-INFO +67 -40
- devtime_ei-0.4.0/src/devtime/intelligence/verification.py +0 -635
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/LICENSE +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/setup.cfg +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/ai/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/ai/local.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/ai/prompts.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/ai/providers.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/assets/devtimeignore.starter +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/config.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/db/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/db/connection.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/db/migrations.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/db/repository.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/db/schema.sql +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/demo.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/fixtures/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/fixtures/assertions.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/fixtures/loader.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/fixtures/runner.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/claims.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/concepts.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/context_pack.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/evidence.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/lineage.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/risk.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/intelligence/scoring.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/mcp/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/mcp/schemas.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/mcp/server.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/mcp/tools.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/output/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/output/json_export.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/output/markdown.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/output/terminal.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/paths.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/privacy.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/.devtimeignore +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/README.md +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/docs/decisions/0001-use-jwt.md +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/package.json +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/admin/permissions.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/auth/login.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/auth/middleware.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/auth/tokens.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/billing/stripe-webhook.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/billing/subscription-service.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/export/export-csv.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/jobs/email-worker.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/src/jobs/queues.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/tests/auth-login.test.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/resources/demo-saas/tests/stripe-signature.test.ts +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/__init__.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/base.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/config_files.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/docs.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/nextjs.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/python.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/extractors/tests.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/file_walker.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/ignore.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/language.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime/scanner/signals.py +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime_ei.egg-info/SOURCES.txt +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime_ei.egg-info/dependency_links.txt +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime_ei.egg-info/entry_points.txt +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/src/devtime_ei.egg-info/requires.txt +0 -0
- {devtime_ei-0.4.0 → devtime_ei-0.5.1}/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.
|
|
3
|
+
Version: 0.5.1
|
|
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.
|
|
11
|
+
Project-URL: Release Notes, https://github.com/Shakargy/devtime/releases/tag/v0.5.1
|
|
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
|
|
@@ -39,17 +39,17 @@ Dynamic: license-file
|
|
|
39
39
|
|
|
40
40
|
# DevTime
|
|
41
41
|
|
|
42
|
-
**
|
|
42
|
+
**DevTime verifies what your repository can actually prove.**
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
A file named `stripe/webhook.ts` looks like proof that a repo handles Stripe
|
|
45
|
+
webhooks. It might be a handler that only returns 404. DevTime checks statements
|
|
46
|
+
about a repository against its implementation, tests, configuration, and recorded
|
|
47
|
+
decisions, then reports what is supported, what is contradicted, what is missing,
|
|
48
|
+
and what went stale.
|
|
49
49
|
|
|
50
50
|
> No cloud. No telemetry. No code execution. No AI required.
|
|
51
51
|
|
|
52
|
-

|
|
53
53
|
|
|
54
54
|
Prefer video? [Watch the 2-minute demo](https://youtu.be/1Hiu3Y9J_SI): DevTime scans
|
|
55
55
|
a repo locally, explains concepts from evidence, surfaces uncertainty, catches a
|
|
@@ -65,8 +65,17 @@ dtc demo init
|
|
|
65
65
|
cd devtime-demo-saas
|
|
66
66
|
dtc init
|
|
67
67
|
dtc scan
|
|
68
|
-
dtc
|
|
69
|
-
|
|
68
|
+
dtc verify
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
On the demo repo that ends with billing webhook signature verification
|
|
72
|
+
SUPPORTED, JWT authentication SUPPORTED, and route test association WEAK, naming
|
|
73
|
+
the routes with no test importing them. Point it at your own repository and the
|
|
74
|
+
answers change:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
cd your-repo
|
|
78
|
+
dtc init && dtc scan && dtc verify
|
|
70
79
|
```
|
|
71
80
|
|
|
72
81
|
The PyPI distribution is `devtime-ei`. The Python package remains `devtime`, and the
|
|
@@ -115,6 +124,39 @@ dtc risk --diff
|
|
|
115
124
|
A full, copy-pasteable walkthrough (including the risk-diff and corroborated-decision
|
|
116
125
|
steps) is in **[DEMO_SCRIPT.md](DEMO_SCRIPT.md)**.
|
|
117
126
|
|
|
127
|
+
## Verify claims (experimental)
|
|
128
|
+
|
|
129
|
+
A claim is a statement about the repository. Verification answers it with a
|
|
130
|
+
status and receipts, never with confidence the evidence cannot back.
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
Status: CONTRADICTED
|
|
134
|
+
|
|
135
|
+
Contradictions:
|
|
136
|
+
- The billing webhook endpoint cannot verify signatures
|
|
137
|
+
because it is a disabled stub.
|
|
138
|
+
claimed: pages/api/stripe/webhook.ts is named and routed
|
|
139
|
+
as a billing webhook endpoint.
|
|
140
|
+
observed: The handler's only behavior is a 404/501 response.
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
- **SUPPORTED** - required behavior evidence exists in the current scan
|
|
144
|
+
- **WEAK** - the surface exists, but the proving evidence is missing
|
|
145
|
+
- **CONTRADICTED** - credible evidence conflicts with the claim, both sides shown
|
|
146
|
+
- **UNKNOWN** - the surface exists but coverage cannot responsibly decide
|
|
147
|
+
- **NOT_APPLICABLE** - the repository has no surface this claim is about
|
|
148
|
+
|
|
149
|
+
Four built-in claims ship: route test association, admin authorization, billing
|
|
150
|
+
webhook signatures, and JWT authentication. `dtc verify` leads with what it can
|
|
151
|
+
actually verify in your repository, and when nothing applies it says what would
|
|
152
|
+
make a claim verifiable instead of dead-ending.
|
|
153
|
+
|
|
154
|
+
Truth and freshness are separate: when a file behind a verified claim changes,
|
|
155
|
+
the claim goes STALE and names the file. `dtc risk --diff` reports which verified
|
|
156
|
+
claims a diff destabilizes.
|
|
157
|
+
|
|
158
|
+
See **[VERIFICATION.md](VERIFICATION.md)** for the full model and its limits.
|
|
159
|
+
|
|
118
160
|
## Why this exists
|
|
119
161
|
|
|
120
162
|
Git records what changed, but it does not preserve the reasoning behind those
|
|
@@ -142,6 +184,7 @@ It is especially useful if you:
|
|
|
142
184
|
|
|
143
185
|
Questions DevTime helps answer include:
|
|
144
186
|
|
|
187
|
+
- Can this repository actually prove the thing its file names imply?
|
|
145
188
|
- Where is authentication actually implemented?
|
|
146
189
|
- What files prove that Billing Webhooks exist?
|
|
147
190
|
- What is still uncertain?
|
|
@@ -150,17 +193,25 @@ Questions DevTime helps answer include:
|
|
|
150
193
|
|
|
151
194
|
## What DevTime does
|
|
152
195
|
|
|
196
|
+
- Verifies claims about a repository and reports status, evidence, and both sides
|
|
197
|
+
of any contradiction.
|
|
198
|
+
- Tracks freshness, so a verified claim goes stale when the evidence behind it changes.
|
|
153
199
|
- Detects concepts from routes, tests, configs, dependencies, and docs.
|
|
154
200
|
- Explains from evidence by linking claims to files and signals.
|
|
155
201
|
- Surfaces uncertainty when evidence is missing or weak.
|
|
156
202
|
- Scores understanding with an Understanding Score and Understanding Debt label.
|
|
157
|
-
- Reviews narrow risky diffs with advisory findings
|
|
203
|
+
- Reviews narrow risky diffs with advisory findings, including which verified
|
|
204
|
+
claims a diff destabilizes.
|
|
158
205
|
- Records decisions locally so rationale can reduce uncertainty when corroborated by code.
|
|
159
206
|
|
|
160
207
|
## Supported concepts
|
|
161
208
|
|
|
162
|
-
|
|
163
|
-
|
|
209
|
+
Underneath verification is a scanner that builds local, evidence-backed memory:
|
|
210
|
+
|
|
211
|
+

|
|
212
|
+
|
|
213
|
+
DevTime detects six supported concept families. It does not discover arbitrary
|
|
214
|
+
domain concepts yet:
|
|
164
215
|
|
|
165
216
|
- Authentication
|
|
166
217
|
- Billing Webhooks
|
|
@@ -169,7 +220,7 @@ concepts yet:
|
|
|
169
220
|
- Admin Permissions
|
|
170
221
|
- File Uploads
|
|
171
222
|
|
|
172
|
-
Anything outside these six is out of scope for
|
|
223
|
+
Anything outside these six is out of scope for now. See [LIMITATIONS.md](LIMITATIONS.md).
|
|
173
224
|
|
|
174
225
|
## What DevTime does not do
|
|
175
226
|
|
|
@@ -204,7 +255,7 @@ Anything outside these six is out of scope for V0. See [LIMITATIONS.md](LIMITATI
|
|
|
204
255
|
| `dtc context <concept>` | Create a governed Context Pack for agents or humans. |
|
|
205
256
|
| `dtc risk --diff` | Review a git diff for risky changes using local evidence (advisory). |
|
|
206
257
|
| `dtc decision add` | Add a local decision record that can reduce uncertainty. |
|
|
207
|
-
| `dtc verify [claim]` | Verify
|
|
258
|
+
| `dtc verify [claim]` | Verify repository claims against evidence: status, contradictions, freshness (experimental). |
|
|
208
259
|
|
|
209
260
|
(Also available: `dtc evidence`, `dtc debt`, `dtc status`, `dtc doctor --privacy`,
|
|
210
261
|
`dtc export`, `dtc reset`, `dtc mcp start`.)
|
|
@@ -296,30 +347,6 @@ python -m venv .venv
|
|
|
296
347
|
pip install -e ".[dev]"
|
|
297
348
|
```
|
|
298
349
|
|
|
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
|
-
|
|
323
350
|
## Example output
|
|
324
351
|
|
|
325
352
|
```
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# DevTime
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**DevTime verifies what your repository can actually prove.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
A file named `stripe/webhook.ts` looks like proof that a repo handles Stripe
|
|
6
|
+
webhooks. It might be a handler that only returns 404. DevTime checks statements
|
|
7
|
+
about a repository against its implementation, tests, configuration, and recorded
|
|
8
|
+
decisions, then reports what is supported, what is contradicted, what is missing,
|
|
9
|
+
and what went stale.
|
|
10
10
|
|
|
11
11
|
> No cloud. No telemetry. No code execution. No AI required.
|
|
12
12
|
|
|
13
|
-

|
|
14
14
|
|
|
15
15
|
Prefer video? [Watch the 2-minute demo](https://youtu.be/1Hiu3Y9J_SI): DevTime scans
|
|
16
16
|
a repo locally, explains concepts from evidence, surfaces uncertainty, catches a
|
|
@@ -26,8 +26,17 @@ dtc demo init
|
|
|
26
26
|
cd devtime-demo-saas
|
|
27
27
|
dtc init
|
|
28
28
|
dtc scan
|
|
29
|
-
dtc
|
|
30
|
-
|
|
29
|
+
dtc verify
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
On the demo repo that ends with billing webhook signature verification
|
|
33
|
+
SUPPORTED, JWT authentication SUPPORTED, and route test association WEAK, naming
|
|
34
|
+
the routes with no test importing them. Point it at your own repository and the
|
|
35
|
+
answers change:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd your-repo
|
|
39
|
+
dtc init && dtc scan && dtc verify
|
|
31
40
|
```
|
|
32
41
|
|
|
33
42
|
The PyPI distribution is `devtime-ei`. The Python package remains `devtime`, and the
|
|
@@ -76,6 +85,39 @@ dtc risk --diff
|
|
|
76
85
|
A full, copy-pasteable walkthrough (including the risk-diff and corroborated-decision
|
|
77
86
|
steps) is in **[DEMO_SCRIPT.md](DEMO_SCRIPT.md)**.
|
|
78
87
|
|
|
88
|
+
## Verify claims (experimental)
|
|
89
|
+
|
|
90
|
+
A claim is a statement about the repository. Verification answers it with a
|
|
91
|
+
status and receipts, never with confidence the evidence cannot back.
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
Status: CONTRADICTED
|
|
95
|
+
|
|
96
|
+
Contradictions:
|
|
97
|
+
- The billing webhook endpoint cannot verify signatures
|
|
98
|
+
because it is a disabled stub.
|
|
99
|
+
claimed: pages/api/stripe/webhook.ts is named and routed
|
|
100
|
+
as a billing webhook endpoint.
|
|
101
|
+
observed: The handler's only behavior is a 404/501 response.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- **SUPPORTED** - required behavior evidence exists in the current scan
|
|
105
|
+
- **WEAK** - the surface exists, but the proving evidence is missing
|
|
106
|
+
- **CONTRADICTED** - credible evidence conflicts with the claim, both sides shown
|
|
107
|
+
- **UNKNOWN** - the surface exists but coverage cannot responsibly decide
|
|
108
|
+
- **NOT_APPLICABLE** - the repository has no surface this claim is about
|
|
109
|
+
|
|
110
|
+
Four built-in claims ship: route test association, admin authorization, billing
|
|
111
|
+
webhook signatures, and JWT authentication. `dtc verify` leads with what it can
|
|
112
|
+
actually verify in your repository, and when nothing applies it says what would
|
|
113
|
+
make a claim verifiable instead of dead-ending.
|
|
114
|
+
|
|
115
|
+
Truth and freshness are separate: when a file behind a verified claim changes,
|
|
116
|
+
the claim goes STALE and names the file. `dtc risk --diff` reports which verified
|
|
117
|
+
claims a diff destabilizes.
|
|
118
|
+
|
|
119
|
+
See **[VERIFICATION.md](VERIFICATION.md)** for the full model and its limits.
|
|
120
|
+
|
|
79
121
|
## Why this exists
|
|
80
122
|
|
|
81
123
|
Git records what changed, but it does not preserve the reasoning behind those
|
|
@@ -103,6 +145,7 @@ It is especially useful if you:
|
|
|
103
145
|
|
|
104
146
|
Questions DevTime helps answer include:
|
|
105
147
|
|
|
148
|
+
- Can this repository actually prove the thing its file names imply?
|
|
106
149
|
- Where is authentication actually implemented?
|
|
107
150
|
- What files prove that Billing Webhooks exist?
|
|
108
151
|
- What is still uncertain?
|
|
@@ -111,17 +154,25 @@ Questions DevTime helps answer include:
|
|
|
111
154
|
|
|
112
155
|
## What DevTime does
|
|
113
156
|
|
|
157
|
+
- Verifies claims about a repository and reports status, evidence, and both sides
|
|
158
|
+
of any contradiction.
|
|
159
|
+
- Tracks freshness, so a verified claim goes stale when the evidence behind it changes.
|
|
114
160
|
- Detects concepts from routes, tests, configs, dependencies, and docs.
|
|
115
161
|
- Explains from evidence by linking claims to files and signals.
|
|
116
162
|
- Surfaces uncertainty when evidence is missing or weak.
|
|
117
163
|
- Scores understanding with an Understanding Score and Understanding Debt label.
|
|
118
|
-
- Reviews narrow risky diffs with advisory findings
|
|
164
|
+
- Reviews narrow risky diffs with advisory findings, including which verified
|
|
165
|
+
claims a diff destabilizes.
|
|
119
166
|
- Records decisions locally so rationale can reduce uncertainty when corroborated by code.
|
|
120
167
|
|
|
121
168
|
## Supported concepts
|
|
122
169
|
|
|
123
|
-
|
|
124
|
-
|
|
170
|
+
Underneath verification is a scanner that builds local, evidence-backed memory:
|
|
171
|
+
|
|
172
|
+

|
|
173
|
+
|
|
174
|
+
DevTime detects six supported concept families. It does not discover arbitrary
|
|
175
|
+
domain concepts yet:
|
|
125
176
|
|
|
126
177
|
- Authentication
|
|
127
178
|
- Billing Webhooks
|
|
@@ -130,7 +181,7 @@ concepts yet:
|
|
|
130
181
|
- Admin Permissions
|
|
131
182
|
- File Uploads
|
|
132
183
|
|
|
133
|
-
Anything outside these six is out of scope for
|
|
184
|
+
Anything outside these six is out of scope for now. See [LIMITATIONS.md](LIMITATIONS.md).
|
|
134
185
|
|
|
135
186
|
## What DevTime does not do
|
|
136
187
|
|
|
@@ -165,7 +216,7 @@ Anything outside these six is out of scope for V0. See [LIMITATIONS.md](LIMITATI
|
|
|
165
216
|
| `dtc context <concept>` | Create a governed Context Pack for agents or humans. |
|
|
166
217
|
| `dtc risk --diff` | Review a git diff for risky changes using local evidence (advisory). |
|
|
167
218
|
| `dtc decision add` | Add a local decision record that can reduce uncertainty. |
|
|
168
|
-
| `dtc verify [claim]` | Verify
|
|
219
|
+
| `dtc verify [claim]` | Verify repository claims against evidence: status, contradictions, freshness (experimental). |
|
|
169
220
|
|
|
170
221
|
(Also available: `dtc evidence`, `dtc debt`, `dtc status`, `dtc doctor --privacy`,
|
|
171
222
|
`dtc export`, `dtc reset`, `dtc mcp start`.)
|
|
@@ -257,30 +308,6 @@ python -m venv .venv
|
|
|
257
308
|
pip install -e ".[dev]"
|
|
258
309
|
```
|
|
259
310
|
|
|
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
|
-
|
|
284
311
|
## Example output
|
|
285
312
|
|
|
286
313
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "devtime-ei"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.5.1"
|
|
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.
|
|
53
|
+
"Release Notes" = "https://github.com/Shakargy/devtime/releases/tag/v0.5.1"
|
|
54
54
|
Demo = "https://youtu.be/1Hiu3Y9J_SI"
|
|
55
55
|
|
|
56
56
|
[project.scripts]
|
|
@@ -97,51 +97,71 @@ def verify(
|
|
|
97
97
|
conn = connection.connect()
|
|
98
98
|
try:
|
|
99
99
|
if list_claims:
|
|
100
|
+
# Relevance is computed live so the list answers the useful question:
|
|
101
|
+
# which of these claims apply to THIS repository?
|
|
102
|
+
current = {r.claim_slug: r for r in ver.verify_all(conn)}
|
|
100
103
|
rows = []
|
|
101
104
|
for slug, definition in ver.BUILTIN_CLAIMS.items():
|
|
102
105
|
latest = ver.load_latest_verification(conn, slug)
|
|
103
106
|
freshness, changed = ver.freshness_for(conn, slug)
|
|
107
|
+
live = current.get(slug)
|
|
104
108
|
rows.append(
|
|
105
109
|
{
|
|
106
110
|
"claim_id": slug,
|
|
107
111
|
"name": definition.name,
|
|
108
112
|
"statement": definition.statement,
|
|
113
|
+
"applies_here": bool(
|
|
114
|
+
live and live.status in ver.APPLICABLE_STATUSES
|
|
115
|
+
),
|
|
116
|
+
"current_status": live.status if live else None,
|
|
109
117
|
"last_status": latest[0]["status"] if latest else None,
|
|
110
118
|
"freshness": freshness,
|
|
111
119
|
"changed_evidence": changed,
|
|
112
120
|
}
|
|
113
121
|
)
|
|
122
|
+
rows.sort(key=lambda r: (not r["applies_here"], r["claim_id"]))
|
|
114
123
|
if as_json:
|
|
115
|
-
console.print_json(_json.dumps({"schema_version": "
|
|
124
|
+
console.print_json(_json.dumps({"schema_version": "2", "claims": rows}))
|
|
116
125
|
else:
|
|
117
126
|
console.print("[bold]Built-in claims[/bold]\n")
|
|
118
127
|
for r in rows:
|
|
128
|
+
if not r["applies_here"]:
|
|
129
|
+
console.print(f" [dim]{r['claim_id']} (not applicable here)[/dim]")
|
|
130
|
+
continue
|
|
119
131
|
status_txt = r["last_status"] or "never verified"
|
|
120
132
|
console.print(f" {r['claim_id']}")
|
|
121
133
|
console.print(f" {r['statement']}")
|
|
122
|
-
console.print(
|
|
134
|
+
console.print(
|
|
135
|
+
f" current: {r['current_status']} "
|
|
136
|
+
f"last verified: {status_txt} freshness: {r['freshness']}"
|
|
137
|
+
)
|
|
123
138
|
for p in r["changed_evidence"]:
|
|
124
139
|
console.print(f" changed since verification: {p}", markup=False)
|
|
125
140
|
console.print("")
|
|
126
141
|
return
|
|
127
142
|
|
|
128
|
-
|
|
129
|
-
results = []
|
|
130
|
-
for slug in slugs:
|
|
143
|
+
if claim:
|
|
131
144
|
try:
|
|
132
|
-
|
|
145
|
+
results = [ver.verify_claim(conn, claim)]
|
|
133
146
|
except KeyError:
|
|
134
|
-
console.print(f"[red]Unknown claim:[/red] {
|
|
147
|
+
console.print(f"[red]Unknown claim:[/red] {claim}")
|
|
135
148
|
console.print("Run [bold]dtc verify --list[/bold] to see built-in claims.")
|
|
136
149
|
raise typer.Exit(code=1)
|
|
137
|
-
|
|
138
|
-
results.
|
|
150
|
+
else:
|
|
151
|
+
results = ver.verify_all(conn)
|
|
152
|
+
|
|
153
|
+
# Only real verifications are recorded. A claim that does not apply to
|
|
154
|
+
# this repository was not verified, so storing it would pollute
|
|
155
|
+
# freshness and diff impact with claims that have no evidence.
|
|
156
|
+
for result in results:
|
|
157
|
+
if result.status in ver.APPLICABLE_STATUSES:
|
|
158
|
+
ver.save_verification(conn, result)
|
|
139
159
|
|
|
140
160
|
if as_json:
|
|
141
161
|
console.print_json(
|
|
142
162
|
_json.dumps(
|
|
143
163
|
{
|
|
144
|
-
"schema_version": "
|
|
164
|
+
"schema_version": "2",
|
|
145
165
|
"command": "verify",
|
|
146
166
|
"results": [r.to_dict() for r in results],
|
|
147
167
|
}
|
|
@@ -149,11 +169,94 @@ def verify(
|
|
|
149
169
|
)
|
|
150
170
|
return
|
|
151
171
|
|
|
152
|
-
|
|
172
|
+
_print_report(results, single=bool(claim))
|
|
173
|
+
finally:
|
|
174
|
+
conn.close()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _print_report(results: list, single: bool) -> None:
|
|
178
|
+
"""Report card: what DevTime can and cannot verify about this repository."""
|
|
179
|
+
from devtime.intelligence import verification as ver
|
|
180
|
+
|
|
181
|
+
applicable = [r for r in results if r.status in ver.APPLICABLE_STATUSES]
|
|
182
|
+
not_applicable = [r for r in results if r.status == ver.NOT_APPLICABLE]
|
|
183
|
+
|
|
184
|
+
for result in applicable:
|
|
185
|
+
_print_verification(result)
|
|
186
|
+
|
|
187
|
+
if not_applicable and not single:
|
|
188
|
+
console.print("[dim]Not applicable to this repository:[/dim]")
|
|
189
|
+
for r in not_applicable:
|
|
190
|
+
reason = r.why[0] if r.why else "No relevant surface was found."
|
|
191
|
+
console.print(f" - {r.claim_slug}: {reason}", markup=False)
|
|
192
|
+
console.print("")
|
|
193
|
+
|
|
194
|
+
if single and not applicable:
|
|
195
|
+
# An explicitly requested claim that does not apply still explains itself.
|
|
196
|
+
for result in not_applicable:
|
|
153
197
|
_print_verification(result)
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
if not applicable:
|
|
201
|
+
_print_nothing_verifiable()
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _print_nothing_verifiable() -> None:
|
|
205
|
+
"""Never a dead end: say what was scanned and what would unlock a claim."""
|
|
206
|
+
from devtime.db import connection
|
|
207
|
+
|
|
208
|
+
conn = connection.connect()
|
|
209
|
+
try:
|
|
210
|
+
scan = conn.execute(
|
|
211
|
+
"SELECT id, file_count, signal_count FROM scans WHERE status = 'completed' "
|
|
212
|
+
"ORDER BY started_at DESC LIMIT 1"
|
|
213
|
+
).fetchone()
|
|
214
|
+
kinds = []
|
|
215
|
+
if scan:
|
|
216
|
+
kinds = conn.execute(
|
|
217
|
+
"SELECT kind, COUNT(*) c FROM signals WHERE scan_id = ? "
|
|
218
|
+
"GROUP BY kind ORDER BY c DESC LIMIT 6",
|
|
219
|
+
(scan["id"],),
|
|
220
|
+
).fetchall()
|
|
154
221
|
finally:
|
|
155
222
|
conn.close()
|
|
156
223
|
|
|
224
|
+
console.print("[bold]No built-in claim applies to this repository yet.[/bold]")
|
|
225
|
+
console.print("")
|
|
226
|
+
if scan:
|
|
227
|
+
console.print(
|
|
228
|
+
f"DevTime scanned {scan['file_count']} files and found "
|
|
229
|
+
f"{scan['signal_count']} signals.",
|
|
230
|
+
markup=False,
|
|
231
|
+
)
|
|
232
|
+
if kinds:
|
|
233
|
+
summary = ", ".join(f"{k['kind']}={k['c']}" for k in kinds)
|
|
234
|
+
console.print(f"Evidence collected: {summary}", markup=False)
|
|
235
|
+
else:
|
|
236
|
+
console.print(
|
|
237
|
+
"No evidence was extracted, which usually means this repository's "
|
|
238
|
+
"language or framework is outside current scanner coverage.",
|
|
239
|
+
markup=False,
|
|
240
|
+
)
|
|
241
|
+
console.print("")
|
|
242
|
+
console.print("Built-in claims become verifiable when a repository has:")
|
|
243
|
+
console.print(" - HTTP routes and tests (route-test-coverage)")
|
|
244
|
+
console.print(" - admin, staff, or back-office routes (admin-authorization)")
|
|
245
|
+
console.print(" - JWT usage or a JWT dependency (jwt-authentication)")
|
|
246
|
+
console.print(" - billing webhooks or a payment provider (billing-webhook-signature)")
|
|
247
|
+
console.print("")
|
|
248
|
+
console.print(
|
|
249
|
+
"This is a coverage limit, not a verdict on your repository. "
|
|
250
|
+
"Scanner support is strongest on TypeScript, Next.js, Express, and "
|
|
251
|
+
"FastAPI-style code; see LIMITATIONS.md.",
|
|
252
|
+
markup=False,
|
|
253
|
+
)
|
|
254
|
+
console.print(
|
|
255
|
+
"If DevTime missed something your repository clearly has, that is worth "
|
|
256
|
+
"an issue: https://github.com/Shakargy/devtime/issues",
|
|
257
|
+
markup=False,
|
|
258
|
+
)
|
|
259
|
+
|
|
157
260
|
|
|
158
261
|
def _print_verification(result) -> None:
|
|
159
262
|
color = {
|
|
@@ -161,6 +264,7 @@ def _print_verification(result) -> None:
|
|
|
161
264
|
"WEAK": "yellow",
|
|
162
265
|
"CONTRADICTED": "red",
|
|
163
266
|
"UNKNOWN": "cyan",
|
|
267
|
+
"NOT_APPLICABLE": "dim",
|
|
164
268
|
}.get(result.status, "white")
|
|
165
269
|
console.print(f"[bold]{result.claim_name}[/bold]")
|
|
166
270
|
console.print(f"Claim: {result.statement}")
|