napkinstack 0.7.2__tar.gz → 0.7.3__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.
- {napkinstack-0.7.2 → napkinstack-0.7.3}/PKG-INFO +4 -4
- {napkinstack-0.7.2 → napkinstack-0.7.3}/README.md +3 -3
- {napkinstack-0.7.2 → napkinstack-0.7.3}/pyproject.toml +1 -1
- {napkinstack-0.7.2 → napkinstack-0.7.3}/pyproject.toml.orig +1 -1
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/cli.py +15 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/provenance.py +23 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/LICENSE +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/__init__.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/assurance.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/compat.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/discovery.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/doctor.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/fitness/__init__.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/fitness/boundaries.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/fitness/hygiene.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/fitness/manifests.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/fitness/plan.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/fitness/pr_scope.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/landed.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/modules.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/project.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/pull_request.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/settings.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/skills.py +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/contracts/AGENTS.md +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/contracts/MANIFEST.yaml +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/contracts/README.md +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/contracts/docs/runbook.md +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/contracts/tests/.gitkeep +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/module/AGENTS.md +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/module/MANIFEST.yaml +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/module/README.md +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/module/docs/adr/.gitkeep +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/module/src/.gitkeep +0 -0
- {napkinstack-0.7.2 → napkinstack-0.7.3}/src/napkinstack/templates/module/tests/.gitkeep +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: napkinstack
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.3
|
|
4
4
|
Summary: Engineering framework for several teams and their agents working in one repository: modules, contracts, guardrails in CI.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -20,7 +20,7 @@ modules, contracts, guardrails in CI. On the Django or Rails model, one command
|
|
|
20
20
|
the project, which then receives new versions on demand; no application stack is imposed.
|
|
21
21
|
Positioning and vocabulary: [`PRODUCT.md`](PRODUCT.md) §1.
|
|
22
22
|
|
|
23
|
-
> **Status: v0.7.
|
|
23
|
+
> **Status: v0.7.3, published** on [PyPI](https://pypi.org/project/napkinstack/).
|
|
24
24
|
> What each version changes, engine and project apart: [`CHANGELOG.md`](CHANGELOG.md).
|
|
25
25
|
> What is open: [`docs/governance/workstreams.md`](docs/governance/workstreams.md).
|
|
26
26
|
|
|
@@ -84,8 +84,8 @@ To try it without installing anything, or to install it from this repository ins
|
|
|
84
84
|
registry — always pinned to a release tag:
|
|
85
85
|
|
|
86
86
|
```bash
|
|
87
|
-
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.7.
|
|
88
|
-
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.7.
|
|
87
|
+
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.7.3" nstack init my-project
|
|
88
|
+
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.7.3"
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
**Two channels, one published artefact.** The registry publishes: the PyPI artefact of a
|
|
@@ -5,7 +5,7 @@ modules, contracts, guardrails in CI. On the Django or Rails model, one command
|
|
|
5
5
|
the project, which then receives new versions on demand; no application stack is imposed.
|
|
6
6
|
Positioning and vocabulary: [`PRODUCT.md`](PRODUCT.md) §1.
|
|
7
7
|
|
|
8
|
-
> **Status: v0.7.
|
|
8
|
+
> **Status: v0.7.3, published** on [PyPI](https://pypi.org/project/napkinstack/).
|
|
9
9
|
> What each version changes, engine and project apart: [`CHANGELOG.md`](CHANGELOG.md).
|
|
10
10
|
> What is open: [`docs/governance/workstreams.md`](docs/governance/workstreams.md).
|
|
11
11
|
|
|
@@ -69,8 +69,8 @@ To try it without installing anything, or to install it from this repository ins
|
|
|
69
69
|
registry — always pinned to a release tag:
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
|
-
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.7.
|
|
73
|
-
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.7.
|
|
72
|
+
uvx --from "git+https://github.com/NapkinStack/engineering-os@v0.7.3" nstack init my-project
|
|
73
|
+
uv tool install "napkinstack @ git+https://github.com/NapkinStack/engineering-os@v0.7.3"
|
|
74
74
|
```
|
|
75
75
|
|
|
76
76
|
**Two channels, one published artefact.** The registry publishes: the PyPI artefact of a
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import argparse
|
|
6
6
|
import json
|
|
7
|
+
import sys
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
|
|
9
10
|
from napkinstack import assurance
|
|
@@ -148,7 +149,21 @@ JUDGES = {"manifests", "boundaries", "plan", "skills", "hygiene", "fitness", "do
|
|
|
148
149
|
"pr-check", "compat", "landed"} # the commands whose verdict depends on the framework's rules
|
|
149
150
|
|
|
150
151
|
|
|
152
|
+
def _named_root(argv: list[str]) -> Path:
|
|
153
|
+
"""The root a command line names, read before the line is parsed: a command this engine
|
|
154
|
+
does not know is refused by the parser, and the reason may be the engine's age (D90)."""
|
|
155
|
+
for index, word in enumerate(argv):
|
|
156
|
+
if word == "--root" and index + 1 < len(argv):
|
|
157
|
+
return Path(argv[index + 1])
|
|
158
|
+
if word.startswith("--root="):
|
|
159
|
+
return Path(word.removeprefix("--root="))
|
|
160
|
+
return Path(".")
|
|
161
|
+
|
|
162
|
+
|
|
151
163
|
def main(argv: list[str] | None = None) -> int:
|
|
164
|
+
argv = sys.argv[1:] if argv is None else argv
|
|
165
|
+
if late := provenance.behind(_named_root(argv)):
|
|
166
|
+
print(late, file=sys.stderr, flush=True)
|
|
152
167
|
args = build_parser().parse_args(argv)
|
|
153
168
|
if args.command in JUDGES:
|
|
154
169
|
print(provenance.judged_by(args.root), flush=True)
|
|
@@ -68,3 +68,26 @@ def judged_by(root: Path) -> str:
|
|
|
68
68
|
return (f"Judged by an UNPUBLISHED NapkinStack — {source}"
|
|
69
69
|
+ (f", project pinned to {unpublished}" if unpublished else on)
|
|
70
70
|
+ ": these rules are no published version.")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def behind(root: Path) -> str | None:
|
|
74
|
+
"""What a workstation is told when its engine is older than the project it runs in (D90).
|
|
75
|
+
|
|
76
|
+
A teammate's update, once merged, leaves every other workstation there: a command the
|
|
77
|
+
project's manual names answers "invalid choice", and a verdict comes from rules the project
|
|
78
|
+
has left. Said before anything else, on every command — the one that does not exist included.
|
|
79
|
+
An engine ahead of the project is not said: it is the state an update starts from."""
|
|
80
|
+
project = recorded(root)
|
|
81
|
+
if not project or not PUBLISHED.fullmatch(project):
|
|
82
|
+
return None
|
|
83
|
+
version, _ = engine()
|
|
84
|
+
try:
|
|
85
|
+
here = tuple(int(part) for part in version.split(".")[:3])
|
|
86
|
+
except ValueError:
|
|
87
|
+
return None
|
|
88
|
+
wanted = project.removeprefix("v")
|
|
89
|
+
if here >= tuple(int(part) for part in wanted.split(".")):
|
|
90
|
+
return None
|
|
91
|
+
return (f"This workstation runs nstack {version}; the project is on {project}. A command it names "
|
|
92
|
+
"may not exist here, and a verdict given here is not CI's.\n"
|
|
93
|
+
f' Action: uv tool install "napkinstack=={wanted}" --with-executables-from pre-commit')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|