provenance-cli 0.1.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 (31) hide show
  1. provenance_cli-0.1.0/LICENSE +21 -0
  2. provenance_cli-0.1.0/PKG-INFO +423 -0
  3. provenance_cli-0.1.0/README.md +397 -0
  4. provenance_cli-0.1.0/pyproject.toml +38 -0
  5. provenance_cli-0.1.0/setup.cfg +4 -0
  6. provenance_cli-0.1.0/src/prov/__init__.py +4 -0
  7. provenance_cli-0.1.0/src/prov/cli.py +105 -0
  8. provenance_cli-0.1.0/src/prov/commands/__init__.py +32 -0
  9. provenance_cli-0.1.0/src/prov/commands/check_slug.py +27 -0
  10. provenance_cli-0.1.0/src/prov/commands/context.py +74 -0
  11. provenance_cli-0.1.0/src/prov/commands/diff.py +106 -0
  12. provenance_cli-0.1.0/src/prov/commands/domain.py +57 -0
  13. provenance_cli-0.1.0/src/prov/commands/find.py +31 -0
  14. provenance_cli-0.1.0/src/prov/commands/impact.py +70 -0
  15. provenance_cli-0.1.0/src/prov/commands/init.py +41 -0
  16. provenance_cli-0.1.0/src/prov/commands/orient.py +62 -0
  17. provenance_cli-0.1.0/src/prov/commands/rebuild.py +57 -0
  18. provenance_cli-0.1.0/src/prov/commands/reconcile.py +62 -0
  19. provenance_cli-0.1.0/src/prov/commands/scope.py +70 -0
  20. provenance_cli-0.1.0/src/prov/commands/sync.py +201 -0
  21. provenance_cli-0.1.0/src/prov/commands/validate.py +111 -0
  22. provenance_cli-0.1.0/src/prov/commands/write.py +135 -0
  23. provenance_cli-0.1.0/src/prov/indexing.py +119 -0
  24. provenance_cli-0.1.0/src/prov/model.py +55 -0
  25. provenance_cli-0.1.0/src/prov/spec_io.py +401 -0
  26. provenance_cli-0.1.0/src/prov/writer.py +180 -0
  27. provenance_cli-0.1.0/src/provenance_cli.egg-info/PKG-INFO +423 -0
  28. provenance_cli-0.1.0/src/provenance_cli.egg-info/SOURCES.txt +29 -0
  29. provenance_cli-0.1.0/src/provenance_cli.egg-info/dependency_links.txt +1 -0
  30. provenance_cli-0.1.0/src/provenance_cli.egg-info/entry_points.txt +2 -0
  31. provenance_cli-0.1.0/src/provenance_cli.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,423 @@
1
+ Metadata-Version: 2.4
2
+ Name: provenance-cli
3
+ Version: 0.1.0
4
+ Summary: Living requirements index + CLI for spec-driven development
5
+ Author: Provenance
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/nndn/Provenance
8
+ Project-URL: Repository, https://github.com/nndn/Provenance
9
+ Keywords: spec,requirements,provenance,cli,spec-driven
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Software Development
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Dynamic: license-file
26
+
27
+ # Provenance
28
+
29
+ > Living requirements index + CLI for spec-driven development. Works with any AI agent.
30
+
31
+ **Provenance** (prov) keeps your requirements in plain markdown next to your code, gives you a CLI to query them, and teaches your AI agent to read before it writes.
32
+
33
+ ---
34
+
35
+ ## Installation
36
+
37
+ **Requirements:** Python 3.9+
38
+
39
+ ### Install the `prov` CLI (recommended)
40
+
41
+ Install from PyPI (after release) or GitHub:
42
+
43
+ | Platform | Command |
44
+ |----------|---------|
45
+ | **macOS / Linux / Windows (PyPI)** | `pipx install provenance-cli` |
46
+ | **macOS / Linux (GitHub)** | `pipx install 'provenance-cli @ git+https://github.com/nndn/Provenance.git'` |
47
+ | **Any (pip)** | `pip install provenance-cli` or `pip install 'provenance-cli @ git+https://github.com/nndn/Provenance.git'` |
48
+
49
+ **Recommendation:** Use [pipx](https://pypa.github.io/pipx/) for CLI tools — it installs `prov` in an isolated environment without affecting your project dependencies.
50
+
51
+ ```sh
52
+ # Install pipx first (if needed)
53
+ # macOS: brew install pipx && pipx ensurepath
54
+ # Linux: apt install pipx # or your package manager
55
+ # Windows: pip install pipx && pipx ensurepath
56
+
57
+ pipx install provenance-cli # from PyPI (recommended)
58
+ # or, before release:
59
+ pipx install 'provenance-cli @ git+https://github.com/nndn/Provenance.git'
60
+ prov --help
61
+ ```
62
+
63
+ To install a specific version:
64
+
65
+ ```sh
66
+ pipx install 'provenance-cli==0.1.0' # from PyPI
67
+ pipx install 'provenance-cli @ git+https://github.com/nndn/Provenance.git@v0.1.0' # from GitHub
68
+ ```
69
+
70
+ ### Install into a project (copy prov into your repo)
71
+
72
+ If you prefer to copy the CLI into your project instead of a global install:
73
+
74
+ ```sh
75
+ git clone https://github.com/nndn/Provenance.git /tmp/provenance
76
+ cd /path/to/your-project
77
+ sh /tmp/provenance/install.sh
78
+ ```
79
+
80
+ This creates `prov/prov.py` and `prov/CONTEXT.md` in your project. Run with:
81
+
82
+ ```sh
83
+ python prov/prov.py orient
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Publishing to PyPI
89
+
90
+ Releases are published automatically when you create a GitHub release. One-time setup:
91
+
92
+ 1. Create an account at [pypi.org](https://pypi.org) and [test.pypi.org](https://test.pypi.org) (optional, for test releases).
93
+
94
+ 2. Enable trusted publishing on PyPI:
95
+ - Create a new project at pypi.org (name: `provenance-cli`) or use an existing one.
96
+ - Go to **Your project** → **Publishing** → **Add a new pending publisher**.
97
+ - Owner: `nndn`, Repository: `Provenance`, Workflow: `publish-pypi.yml`.
98
+
99
+ 3. Create a release:
100
+ ```sh
101
+ git tag v0.1.0
102
+ git push origin v0.1.0
103
+ ```
104
+ Then create the release on GitHub ( Releases → Create a new release → Choose the tag).
105
+
106
+ The workflow builds and publishes to PyPI on release publish.
107
+
108
+ **Manual publish:**
109
+ ```sh
110
+ pip install build twine
111
+ python -m build
112
+ twine upload dist/*
113
+ ```
114
+ (requires `TWINE_USERNAME` and `TWINE_PASSWORD` or API token.)
115
+
116
+ ---
117
+
118
+ ## What you get
119
+
120
+ | File | Purpose |
121
+ |---|---|
122
+ | `prov/prov.py` | CLI — scope, context, impact, validate, diff, write, reconcile |
123
+ | `agent.md` | Agent rules — drop into Cursor, Claude, or any agent config |
124
+ | `scripts/install-spec-pre-commit.sh` | Git hook — validates spec on every commit |
125
+
126
+ No external dependencies. Python 3.9+. Everything is plain text — grep always works.
127
+
128
+ **Repo structure (for contributors):** CLI source lives in `src/prov.py`. This repo's own spec (meta) is in `specs/`. After install, user projects get `prov/prov.py` (copied from `src/prov.py`) and use `prov/` for their spec files. To run the CLI from this repo: `SPEC_DIR=specs python src/prov.py <command>`.
129
+
130
+ ---
131
+
132
+ ## Quick start
133
+
134
+ ```sh
135
+ # Option A: Install CLI globally (from GitHub)
136
+ pipx install provenance-cli
137
+
138
+ # Option B: Install into your project
139
+ git clone https://github.com/nndn/Provenance.git /tmp/provenance
140
+ cd /path/to/your-project
141
+ sh /tmp/provenance/install.sh
142
+
143
+ # Then: edit prov/CONTEXT.md (or prov/CONTEXT.md) and run
144
+ prov orient # if installed globally
145
+ # or
146
+ python prov/prov.py orient # if using project-local copy
147
+ ```
148
+
149
+ After install:
150
+
151
+ ```
152
+ your-project/
153
+ prov/
154
+ CONTEXT.md ← edit this: project name, purpose, domain map
155
+ prov.py ← the CLI
156
+ agent.md ← copy to your AI agent config
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Set up your AI agent
162
+
163
+ Copy `agent.md` to wherever your agent reads rules:
164
+
165
+ | Agent | Location |
166
+ |---|---|
167
+ | Cursor | `.cursorrules` or `.cursor/rules/prov.md` |
168
+ | Claude Code | `CLAUDE.md` |
169
+ | Codex / GPT | `AGENTS.md` |
170
+ | Any | append to your existing rules file |
171
+
172
+ Once the agent reads `agent.md`, it will automatically call `prov scope` before touching code, `prov validate` before committing, and `prov diff` for human review.
173
+
174
+ ---
175
+
176
+ ## CLI
177
+
178
+ Run `prov <command>` (if installed globally) or `python prov/prov.py <command>` (project-local).
179
+
180
+ ```sh
181
+ prov orient # start every session here
182
+
183
+ prov scope <path> # what governs this file or directory?
184
+ prov context <slug> # full entry: statement, provenance, deps, code refs
185
+ prov impact <slug> # blast radius before changing anything
186
+
187
+ prov find <keywords> # search when you don't know the slug
188
+ prov domain <name> # load a full domain
189
+
190
+ prov check-slug <slug> # is this slug available?
191
+ prov write # add entries (JSON input, validates before writing)
192
+
193
+ prov validate # run before every commit — zero errors only
194
+ prov diff [ref] # semantic change manifest vs HEAD or any ref
195
+ prov reconcile <path> # detect code↔spec drift
196
+ prov rebuild # rebuild .spec/ cache from files
197
+
198
+ prov init # scaffold CONTEXT.md in a new project
199
+ ```
200
+
201
+ ---
202
+
203
+ ## What a spec entry looks like
204
+
205
+ ```
206
+ session-expiry: Sessions expire after 30 days of inactivity.
207
+ > "standard session timeout, nothing crazy"
208
+ ! assumed 30 days — "nothing crazy" is unconfirmed
209
+ @ C:jwt-stateless
210
+ ~ src/middleware/session.py:44
211
+ ~ src/middleware/session.py:101
212
+ ```
213
+
214
+ | Part | Meaning |
215
+ |---|---|
216
+ | `session-expiry` | Slug — permanent, globally unique, used in `spec:` backlinks in code |
217
+ | Statement | What the system does. Current state only. Never "previously", "changed from". |
218
+ | `>` | Provenance — user's words where possible. Required on every entry. |
219
+ | `!` | Assumption the agent filled in — needs user confirmation before removing. |
220
+ | `@` | This entry depends on another slug. |
221
+ | `~` | Code file implementing this. One line per file. |
222
+ | `[planned]` | Not yet coded. Remove when implemented, add `~` lines. |
223
+
224
+ **Node types (column 0):**
225
+
226
+ ```
227
+ slug: requirement — observable behavior
228
+ C:slug: constraint — non-negotiable rule
229
+ Q:slug: question — unresolved decision blocking implementation
230
+ ```
231
+
232
+ ### Domain file structure
233
+
234
+ ```markdown
235
+ # Auth
236
+
237
+ > OAuth-based auth and stateless JWT sessions.
238
+
239
+ ## Constraints
240
+
241
+ C:oauth-only: OAuth only — no email/password.
242
+
243
+ > "I don't want to deal with password resets"
244
+
245
+ ## Requirements
246
+
247
+ google-login: Users authenticate via Google OAuth.
248
+
249
+ > "we'll just do Google login for now"
250
+ > @ C:oauth-only
251
+ > ~ src/api/auth/google.py
252
+
253
+ session-expiry: Sessions expire after 30 days of inactivity.
254
+
255
+ > "standard session timeout, nothing crazy"
256
+ ! assumed 30 days — unconfirmed
257
+ @ C:jwt-stateless
258
+ ~ src/middleware/session.py:44
259
+
260
+ ## Open Questions
261
+
262
+ Q:admin-scope: Does admin-revoke apply to one session or all user sessions?
263
+
264
+ > blocks: admin-revoke
265
+
266
+ ## Out of scope
267
+
268
+ MFA, SSO/SAML.
269
+
270
+ ## Refs
271
+
272
+ ~ src/api/auth/
273
+ ~ src/middleware/session.py
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Code backlinks
279
+
280
+ Every function or block that implements a spec entry carries a `spec:` comment:
281
+
282
+ ```python
283
+ # spec: session-expiry
284
+ def refresh_session(token: str) -> Session: ...
285
+
286
+ # spec: billing-cap, C:usage-hard-limit
287
+ class PlanLimitMiddleware: ...
288
+ ```
289
+
290
+ ```typescript
291
+ // spec: admin-revoke
292
+ async function revokeSession(userId: string): Promise<void>
293
+ ```
294
+
295
+ `prov validate` checks that every `spec:` slug in code has a matching entry. `prov reconcile` surfaces drift when code and spec get out of sync.
296
+
297
+ ---
298
+
299
+ ## Pre-commit hook
300
+
301
+ ```sh
302
+ ./scripts/install-spec-pre-commit.sh
303
+ ```
304
+
305
+ When spec files are staged, the hook:
306
+ 1. Runs `prov validate` — blocks commit on any error
307
+ 2. Runs `prov rebuild` — regenerates `.spec/` cache
308
+ 3. Stages `.spec/` automatically
309
+
310
+ ---
311
+
312
+ ## Adding a new domain
313
+
314
+ 1. Create `prov/<domain>.md` with the standard structure (see above)
315
+ 2. Add it to the `## Domain map` in `prov/CONTEXT.md`:
316
+ ```
317
+ auth prov/auth.md
318
+ ```
319
+ 3. Run `python prov/prov.py orient` to verify it loads
320
+
321
+ ---
322
+
323
+ ## Writing new entries
324
+
325
+ ### Via CLI (validated, shows preview)
326
+
327
+ ```sh
328
+ echo '{
329
+ "domain": "auth",
330
+ "entries": [{
331
+ "slug": "password-reset",
332
+ "type": "requirement",
333
+ "statement": "Users can reset their password via email link.",
334
+ "provenance": "\"I need a forgot password flow\"",
335
+ "planned": true
336
+ }]
337
+ }' | python prov/prov.py write --yes
338
+ ```
339
+
340
+ ### Directly in markdown
341
+
342
+ Edit the domain file. Follow the format above. Run `python prov/prov.py validate` when done.
343
+
344
+ ---
345
+
346
+ ## CONTEXT.md structure
347
+
348
+ ```markdown
349
+ # <Project Name>
350
+
351
+ > One sentence: what it does and who uses it.
352
+
353
+ ## Purpose
354
+
355
+ 2-3 sentences on the problem being solved.
356
+
357
+ ## User goals
358
+
359
+ 1. Primary goal
360
+ 2. Secondary goal
361
+
362
+ ## Hard constraints
363
+
364
+ C:example: Non-negotiable rule.
365
+
366
+ > "why"
367
+
368
+ ## Non-goals
369
+
370
+ - Explicit out-of-scope items
371
+
372
+ ## Domain map
373
+
374
+ auth prov/auth.md
375
+ billing prov/billing.md
376
+ ```
377
+
378
+ ---
379
+
380
+ ## Commit message format
381
+
382
+ ```sh
383
+ # Spec-only
384
+ prov(auth): add session-expiry requirement
385
+ prov(auth): implement admin-revoke, close Q:admin-scope
386
+ prov: reconcile src/api/
387
+
388
+ # Code + spec together (required)
389
+ feat(auth): implement session expiry
390
+ prov: implement session-expiry
391
+ ```
392
+
393
+ ---
394
+
395
+ ## Validation checks
396
+
397
+ | Severity | Check | Meaning |
398
+ |---|---|---|
399
+ | ERROR | `ghost-scope` | Entry has no `>` line |
400
+ | ERROR | `dead-ref` | `~` path doesn't exist |
401
+ | ERROR | `phantom-slug` | `spec:` in code, no entry |
402
+ | ERROR | `duplicate-slug` | Same slug in two files |
403
+ | ERROR | `no-dangling-dep` | `@` target doesn't exist |
404
+ | WARN | `silent-impl` | `[planned]` but code has `spec:` |
405
+ | WARN | `orphan-question` | `Q:` not referenced by any `?` |
406
+
407
+ All ERRORs must be zero before committing.
408
+
409
+ ---
410
+
411
+ ## Fallback (no Python)
412
+
413
+ The spec is always greppable without any tooling:
414
+
415
+ ```sh
416
+ grep -rh "^>" prov/*.md # domain summaries
417
+ grep -r "^Q:" prov/ # open questions
418
+ grep -r "\[planned\]" prov/ # backlog
419
+ grep -r "^ !" prov/ # unconfirmed assumptions
420
+ grep -r "^C:" prov/ # all constraints
421
+ grep -A 20 "^session-expiry:" prov/ # entry by slug
422
+ grep -r "~src/api/auth" prov/ # what owns this path
423
+ ```