stateforge-dpt 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.
- stateforge_dpt-0.1.0/.env.example +10 -0
- stateforge_dpt-0.1.0/.gitignore +18 -0
- stateforge_dpt-0.1.0/PKG-INFO +149 -0
- stateforge_dpt-0.1.0/README.md +121 -0
- stateforge_dpt-0.1.0/docs/architecture.md +95 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/index-BqmCo4Xq.js +39 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/index-D4tYCe7n.css +1 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png/stateforge-mark-1024.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png/stateforge-mark-128.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png/stateforge-mark-16.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png/stateforge-mark-256.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png/stateforge-mark-32.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png/stateforge-mark-512.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png/stateforge-mark-64.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png-dark-background/stateforge-mark-dark-1024.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png-dark-background/stateforge-mark-dark-128.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png-dark-background/stateforge-mark-dark-16.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png-dark-background/stateforge-mark-dark-256.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png-dark-background/stateforge-mark-dark-32.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png-dark-background/stateforge-mark-dark-512.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/png-dark-background/stateforge-mark-dark-64.png +0 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/react/StateForgeLogo.tsx +163 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/svg/stateforge-favicon.svg +19 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/svg/stateforge-mark-black.svg +27 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/svg/stateforge-mark-currentcolor.svg +31 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/svg/stateforge-mark-dark-background.svg +21 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/svg/stateforge-mark-glow.svg +31 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/svg/stateforge-mark-white.svg +27 -0
- stateforge_dpt-0.1.0/frontend/dist/assets/stateforge/svg/stateforge-mark.svg +31 -0
- stateforge_dpt-0.1.0/frontend/dist/index.html +17 -0
- stateforge_dpt-0.1.0/frontend/index.html +16 -0
- stateforge_dpt-0.1.0/frontend/package-lock.json +3206 -0
- stateforge_dpt-0.1.0/frontend/package.json +25 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png/stateforge-mark-1024.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png/stateforge-mark-128.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png/stateforge-mark-16.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png/stateforge-mark-256.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png/stateforge-mark-32.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png/stateforge-mark-512.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png/stateforge-mark-64.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png-dark-background/stateforge-mark-dark-1024.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png-dark-background/stateforge-mark-dark-128.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png-dark-background/stateforge-mark-dark-16.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png-dark-background/stateforge-mark-dark-256.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png-dark-background/stateforge-mark-dark-32.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png-dark-background/stateforge-mark-dark-512.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/png-dark-background/stateforge-mark-dark-64.png +0 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/react/StateForgeLogo.tsx +163 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/svg/stateforge-favicon.svg +19 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/svg/stateforge-mark-black.svg +27 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/svg/stateforge-mark-currentcolor.svg +31 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/svg/stateforge-mark-dark-background.svg +21 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/svg/stateforge-mark-glow.svg +31 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/svg/stateforge-mark-white.svg +27 -0
- stateforge_dpt-0.1.0/frontend/public/assets/stateforge/svg/stateforge-mark.svg +31 -0
- stateforge_dpt-0.1.0/frontend/src/App.tsx +2845 -0
- stateforge_dpt-0.1.0/frontend/src/PlanEditor.tsx +830 -0
- stateforge_dpt-0.1.0/frontend/src/api.ts +66 -0
- stateforge_dpt-0.1.0/frontend/src/main.tsx +12 -0
- stateforge_dpt-0.1.0/frontend/src/styles.css +995 -0
- stateforge_dpt-0.1.0/frontend/src/types.ts +216 -0
- stateforge_dpt-0.1.0/frontend/src/ui.tsx +198 -0
- stateforge_dpt-0.1.0/frontend/tsconfig.json +22 -0
- stateforge_dpt-0.1.0/frontend/vite.config.ts +13 -0
- stateforge_dpt-0.1.0/pyproject.toml +91 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/__init__.py +3 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/__main__.py +5 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/app.py +836 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/bootstrap.py +178 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/cli.py +115 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/config.py +94 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/database.py +284 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/git.py +205 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/github.py +465 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/models.py +212 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/plan_file.py +142 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/security.py +45 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/service.py +2238 -0
- stateforge_dpt-0.1.0/src/stateforge_dpt/terminal.py +66 -0
- stateforge_dpt-0.1.0/tests/test_database.py +54 -0
- stateforge_dpt-0.1.0/tests/test_git_auth.py +64 -0
- stateforge_dpt-0.1.0/tests/test_github_artifacts.py +657 -0
- stateforge_dpt-0.1.0/tests/test_github_device_flow.py +349 -0
- stateforge_dpt-0.1.0/tests/test_package_smoke.py +30 -0
- stateforge_dpt-0.1.0/tests/test_plan_management.py +153 -0
- stateforge_dpt-0.1.0/tests/test_portable_plan.py +611 -0
- stateforge_dpt-0.1.0/tests/test_repositories.py +162 -0
- stateforge_dpt-0.1.0/tests/test_runtime.py +266 -0
- stateforge_dpt-0.1.0/tools/check_distributions.py +59 -0
- stateforge_dpt-0.1.0/tools/smoke_test_package.py +112 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
STATEFORGE_DPT_HOST=127.0.0.1
|
|
2
|
+
STATEFORGE_DPT_PORT=8463
|
|
3
|
+
# Save user configuration in ~/.stateforge-dpt/.env. Paths are independent of cwd.
|
|
4
|
+
# Defaults: data in ~/.stateforge-dpt; clones in ~/.stateforge-dpt/projects/.
|
|
5
|
+
# STATEFORGE_DPT_DATA_DIR=~/.stateforge-dpt
|
|
6
|
+
# STATEFORGE_DPT_WORKING_DIRECTORY=~/.stateforge-dpt
|
|
7
|
+
# Optional override; installed releases include the built frontend.
|
|
8
|
+
# STATEFORGE_DPT_FRONTEND_DIR=/absolute/path/to/frontend/dist
|
|
9
|
+
# Optional override for a different GitHub App.
|
|
10
|
+
STATEFORGE_DPT_GITHUB_CLIENT_ID=Iv23lidYTyPNl3LWbjTI
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: stateforge-dpt
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local development progress control for StateForge repositories.
|
|
5
|
+
Project-URL: Repository, https://github.com/stateforge-org/stateforge-dpt
|
|
6
|
+
Project-URL: Issues, https://github.com/stateforge-org/stateforge-dpt/issues
|
|
7
|
+
Keywords: development,git,github,planning,project-management
|
|
8
|
+
Classifier: Development Status :: 3 - Alpha
|
|
9
|
+
Classifier: Environment :: Web Environment
|
|
10
|
+
Classifier: Framework :: FastAPI
|
|
11
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
12
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
13
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Topic :: Software Development
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: cryptography>=44.0
|
|
22
|
+
Requires-Dist: fastapi>=0.115
|
|
23
|
+
Requires-Dist: httpx>=0.28
|
|
24
|
+
Requires-Dist: pydantic>=2.10
|
|
25
|
+
Requires-Dist: python-dotenv>=1.0
|
|
26
|
+
Requires-Dist: uvicorn>=0.34
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# StateForge DPT
|
|
30
|
+
|
|
31
|
+
StateForge Development Progress Tracking is a local-first control application
|
|
32
|
+
for coordinating work across the StateForge repositories.
|
|
33
|
+
|
|
34
|
+
DPT edits the implementation plan locally, publishes its complete portable
|
|
35
|
+
manifest into an identical `STATEFORGE_DPT.md` in every managed repository, and
|
|
36
|
+
derives delivery progress from issues, pull requests, reviews, checks, and merge
|
|
37
|
+
evidence retrieved from GitHub.
|
|
38
|
+
|
|
39
|
+
## Run DPT
|
|
40
|
+
|
|
41
|
+
DPT is packaged for Linux, macOS, and Windows. Requirements are Python 3.11 or
|
|
42
|
+
newer and Git 2.31 or newer on PATH. Node.js is only needed when developing or
|
|
43
|
+
building a release, not when installing and running DPT.
|
|
44
|
+
|
|
45
|
+
Once the first release is published to PyPI:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python -m pip install stateforge-dpt
|
|
49
|
+
stateforge-dpt run
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
On macOS/Linux, use `python3` if that is your Python command. On Windows, you can
|
|
53
|
+
use `py -m pip install stateforge-dpt` and `py -m stateforge_dpt run` if the
|
|
54
|
+
console command is not on PATH. A virtual environment is recommended; do not use
|
|
55
|
+
`sudo pip install`. Before PyPI publication, install a downloaded wheel with
|
|
56
|
+
`python -m pip install /path/to/stateforge_dpt-0.1.0-py3-none-any.whl`.
|
|
57
|
+
|
|
58
|
+
Run `stateforge-dpt run` from any directory, then open
|
|
59
|
+
[http://127.0.0.1:8463](http://127.0.0.1:8463) in your browser. The command prints
|
|
60
|
+
the browser address and workspace locations at startup. Installed release wheels
|
|
61
|
+
include the frontend; no separate frontend server is needed.
|
|
62
|
+
|
|
63
|
+
By default, the SQLite working copy and encrypted GitHub credentials live in
|
|
64
|
+
`~/.stateforge-dpt/`. Suggested clones live under
|
|
65
|
+
`~/.stateforge-dpt/projects/<PROJECT_NAME>/<REPOSITORY_NAME>`.
|
|
66
|
+
|
|
67
|
+
User configuration is read from `~/.stateforge-dpt/.env`, with environment
|
|
68
|
+
variables taking precedence. Editable source installations also read the
|
|
69
|
+
checkout's `.env` as a lower-priority development configuration. Relative paths
|
|
70
|
+
in a configuration file are resolved beside that file, never against the launch
|
|
71
|
+
directory. Relative environment paths are resolved under `~/.stateforge-dpt/`.
|
|
72
|
+
See [.env.example](.env.example) for overrides.
|
|
73
|
+
|
|
74
|
+
Existing databases are not moved or overwritten. To open a previous workspace:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
stateforge-dpt run --data-dir /absolute/path/to/previous/.stateforge-dpt
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The `--working-directory` option changes the parent workspace for suggested
|
|
81
|
+
clones without changing the data directory.
|
|
82
|
+
|
|
83
|
+
## Development and packaging
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
python3.11 -m venv .venv
|
|
87
|
+
. .venv/bin/activate
|
|
88
|
+
cd frontend && npm install && npm run build && cd ..
|
|
89
|
+
python -m pip install -e .
|
|
90
|
+
stateforge-dpt run
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Build the frontend before building a Python release (`python -m build`). Both
|
|
94
|
+
wheels and source distributions carry that build, so installing them does not
|
|
95
|
+
require Node.js. A missing frontend build produces an actionable startup error
|
|
96
|
+
instead of a server that returns 404 at its home page.
|
|
97
|
+
|
|
98
|
+
The package workflow builds the frontend, creates a wheel and source
|
|
99
|
+
distribution, checks their metadata, and installs the same wheel on Linux,
|
|
100
|
+
macOS, and Windows using Python 3.11–3.14. Each environment runs the test suite
|
|
101
|
+
and starts the installed console command from an unrelated directory to check
|
|
102
|
+
the frontend, JavaScript, CSS, favicon, API, and default data directory.
|
|
103
|
+
|
|
104
|
+
### Publish a release
|
|
105
|
+
|
|
106
|
+
Publishing is manual; ordinary pushes and pull requests never upload to PyPI.
|
|
107
|
+
Create the pending `stateforge-dpt` project in PyPI's Trusted Publishing settings
|
|
108
|
+
with owner `stateforge-org`, repository `stateforge-dpt`, workflow `publish.yml`,
|
|
109
|
+
and environment `pypi`. Configure the equivalent publisher on TestPyPI with
|
|
110
|
+
environment `testpypi`. Protect these GitHub environments with required reviewer
|
|
111
|
+
approval. No permanent PyPI token needs to be stored in the repository.
|
|
112
|
+
|
|
113
|
+
Then run **Publish pip package (manual)** in GitHub Actions, choosing TestPyPI
|
|
114
|
+
first. The workflow rebuilds and tests the distributions on all three operating
|
|
115
|
+
systems before publishing. Choose PyPI for the production release. Increment
|
|
116
|
+
the version in `pyproject.toml` for subsequent releases; PyPI versions cannot be
|
|
117
|
+
overwritten. See [PyPI's Trusted Publishing guide](https://docs.pypi.org/trusted-publishers/).
|
|
118
|
+
|
|
119
|
+
Select **Continue with GitHub** and authorize the StateForge DPT GitHub App
|
|
120
|
+
with the displayed one-time code. DPT uses GitHub Device Flow: no callback URL,
|
|
121
|
+
client secret, or user-managed token is required. Access and refresh tokens are
|
|
122
|
+
encrypted locally and never exposed to the browser.
|
|
123
|
+
|
|
124
|
+
## Core authority model
|
|
125
|
+
|
|
126
|
+
- Git-tracked `STATEFORGE_DPT.md` files are the portable project authority. An
|
|
127
|
+
embedded versioned manifest preserves every repository, milestone, planned
|
|
128
|
+
branch, dependency, ordering rule, project revision, and content fingerprint.
|
|
129
|
+
- SQLite is each computer's local editable working copy and GitHub evidence
|
|
130
|
+
cache. DPT refuses to silently overwrite local edits or choose between
|
|
131
|
+
divergent Git copies.
|
|
132
|
+
- Every project has an explicit plan source branch (for example,
|
|
133
|
+
`mvp/implementation`). Reconciliation fetches that branch and reads only its
|
|
134
|
+
`STATEFORGE_DPT.md` through Git; it never checks out, rebases, or modifies the
|
|
135
|
+
developer's current branch or working tree.
|
|
136
|
+
- Importing any participating clone recreates the full project. Only that clone
|
|
137
|
+
is attached immediately; the remaining repositories are ready to clone or
|
|
138
|
+
attach on the new computer.
|
|
139
|
+
- Publishing writes the next identical revision to every attached clone. Commit
|
|
140
|
+
and push those generated files normally, then merge them into the configured
|
|
141
|
+
plan source branch. Reconciliation on another computer automatically imports
|
|
142
|
+
a strictly newer, conflict-free revision into its local SQLite working copy.
|
|
143
|
+
- Local unpublished edits and same-revision divergence are never overwritten;
|
|
144
|
+
DPT surfaces the existing source chooser so the user can resolve them.
|
|
145
|
+
- GitHub is the authority for delivery progress, not project definition.
|
|
146
|
+
- DPT validates GitHub evidence against the dependency graph and reports real
|
|
147
|
+
workflow violations.
|
|
148
|
+
|
|
149
|
+
See [docs/architecture.md](docs/architecture.md) for the complete design.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# StateForge DPT
|
|
2
|
+
|
|
3
|
+
StateForge Development Progress Tracking is a local-first control application
|
|
4
|
+
for coordinating work across the StateForge repositories.
|
|
5
|
+
|
|
6
|
+
DPT edits the implementation plan locally, publishes its complete portable
|
|
7
|
+
manifest into an identical `STATEFORGE_DPT.md` in every managed repository, and
|
|
8
|
+
derives delivery progress from issues, pull requests, reviews, checks, and merge
|
|
9
|
+
evidence retrieved from GitHub.
|
|
10
|
+
|
|
11
|
+
## Run DPT
|
|
12
|
+
|
|
13
|
+
DPT is packaged for Linux, macOS, and Windows. Requirements are Python 3.11 or
|
|
14
|
+
newer and Git 2.31 or newer on PATH. Node.js is only needed when developing or
|
|
15
|
+
building a release, not when installing and running DPT.
|
|
16
|
+
|
|
17
|
+
Once the first release is published to PyPI:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
python -m pip install stateforge-dpt
|
|
21
|
+
stateforge-dpt run
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
On macOS/Linux, use `python3` if that is your Python command. On Windows, you can
|
|
25
|
+
use `py -m pip install stateforge-dpt` and `py -m stateforge_dpt run` if the
|
|
26
|
+
console command is not on PATH. A virtual environment is recommended; do not use
|
|
27
|
+
`sudo pip install`. Before PyPI publication, install a downloaded wheel with
|
|
28
|
+
`python -m pip install /path/to/stateforge_dpt-0.1.0-py3-none-any.whl`.
|
|
29
|
+
|
|
30
|
+
Run `stateforge-dpt run` from any directory, then open
|
|
31
|
+
[http://127.0.0.1:8463](http://127.0.0.1:8463) in your browser. The command prints
|
|
32
|
+
the browser address and workspace locations at startup. Installed release wheels
|
|
33
|
+
include the frontend; no separate frontend server is needed.
|
|
34
|
+
|
|
35
|
+
By default, the SQLite working copy and encrypted GitHub credentials live in
|
|
36
|
+
`~/.stateforge-dpt/`. Suggested clones live under
|
|
37
|
+
`~/.stateforge-dpt/projects/<PROJECT_NAME>/<REPOSITORY_NAME>`.
|
|
38
|
+
|
|
39
|
+
User configuration is read from `~/.stateforge-dpt/.env`, with environment
|
|
40
|
+
variables taking precedence. Editable source installations also read the
|
|
41
|
+
checkout's `.env` as a lower-priority development configuration. Relative paths
|
|
42
|
+
in a configuration file are resolved beside that file, never against the launch
|
|
43
|
+
directory. Relative environment paths are resolved under `~/.stateforge-dpt/`.
|
|
44
|
+
See [.env.example](.env.example) for overrides.
|
|
45
|
+
|
|
46
|
+
Existing databases are not moved or overwritten. To open a previous workspace:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
stateforge-dpt run --data-dir /absolute/path/to/previous/.stateforge-dpt
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The `--working-directory` option changes the parent workspace for suggested
|
|
53
|
+
clones without changing the data directory.
|
|
54
|
+
|
|
55
|
+
## Development and packaging
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
python3.11 -m venv .venv
|
|
59
|
+
. .venv/bin/activate
|
|
60
|
+
cd frontend && npm install && npm run build && cd ..
|
|
61
|
+
python -m pip install -e .
|
|
62
|
+
stateforge-dpt run
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Build the frontend before building a Python release (`python -m build`). Both
|
|
66
|
+
wheels and source distributions carry that build, so installing them does not
|
|
67
|
+
require Node.js. A missing frontend build produces an actionable startup error
|
|
68
|
+
instead of a server that returns 404 at its home page.
|
|
69
|
+
|
|
70
|
+
The package workflow builds the frontend, creates a wheel and source
|
|
71
|
+
distribution, checks their metadata, and installs the same wheel on Linux,
|
|
72
|
+
macOS, and Windows using Python 3.11–3.14. Each environment runs the test suite
|
|
73
|
+
and starts the installed console command from an unrelated directory to check
|
|
74
|
+
the frontend, JavaScript, CSS, favicon, API, and default data directory.
|
|
75
|
+
|
|
76
|
+
### Publish a release
|
|
77
|
+
|
|
78
|
+
Publishing is manual; ordinary pushes and pull requests never upload to PyPI.
|
|
79
|
+
Create the pending `stateforge-dpt` project in PyPI's Trusted Publishing settings
|
|
80
|
+
with owner `stateforge-org`, repository `stateforge-dpt`, workflow `publish.yml`,
|
|
81
|
+
and environment `pypi`. Configure the equivalent publisher on TestPyPI with
|
|
82
|
+
environment `testpypi`. Protect these GitHub environments with required reviewer
|
|
83
|
+
approval. No permanent PyPI token needs to be stored in the repository.
|
|
84
|
+
|
|
85
|
+
Then run **Publish pip package (manual)** in GitHub Actions, choosing TestPyPI
|
|
86
|
+
first. The workflow rebuilds and tests the distributions on all three operating
|
|
87
|
+
systems before publishing. Choose PyPI for the production release. Increment
|
|
88
|
+
the version in `pyproject.toml` for subsequent releases; PyPI versions cannot be
|
|
89
|
+
overwritten. See [PyPI's Trusted Publishing guide](https://docs.pypi.org/trusted-publishers/).
|
|
90
|
+
|
|
91
|
+
Select **Continue with GitHub** and authorize the StateForge DPT GitHub App
|
|
92
|
+
with the displayed one-time code. DPT uses GitHub Device Flow: no callback URL,
|
|
93
|
+
client secret, or user-managed token is required. Access and refresh tokens are
|
|
94
|
+
encrypted locally and never exposed to the browser.
|
|
95
|
+
|
|
96
|
+
## Core authority model
|
|
97
|
+
|
|
98
|
+
- Git-tracked `STATEFORGE_DPT.md` files are the portable project authority. An
|
|
99
|
+
embedded versioned manifest preserves every repository, milestone, planned
|
|
100
|
+
branch, dependency, ordering rule, project revision, and content fingerprint.
|
|
101
|
+
- SQLite is each computer's local editable working copy and GitHub evidence
|
|
102
|
+
cache. DPT refuses to silently overwrite local edits or choose between
|
|
103
|
+
divergent Git copies.
|
|
104
|
+
- Every project has an explicit plan source branch (for example,
|
|
105
|
+
`mvp/implementation`). Reconciliation fetches that branch and reads only its
|
|
106
|
+
`STATEFORGE_DPT.md` through Git; it never checks out, rebases, or modifies the
|
|
107
|
+
developer's current branch or working tree.
|
|
108
|
+
- Importing any participating clone recreates the full project. Only that clone
|
|
109
|
+
is attached immediately; the remaining repositories are ready to clone or
|
|
110
|
+
attach on the new computer.
|
|
111
|
+
- Publishing writes the next identical revision to every attached clone. Commit
|
|
112
|
+
and push those generated files normally, then merge them into the configured
|
|
113
|
+
plan source branch. Reconciliation on another computer automatically imports
|
|
114
|
+
a strictly newer, conflict-free revision into its local SQLite working copy.
|
|
115
|
+
- Local unpublished edits and same-revision divergence are never overwritten;
|
|
116
|
+
DPT surfaces the existing source chooser so the user can resolve them.
|
|
117
|
+
- GitHub is the authority for delivery progress, not project definition.
|
|
118
|
+
- DPT validates GitHub evidence against the dependency graph and reports real
|
|
119
|
+
workflow violations.
|
|
120
|
+
|
|
121
|
+
See [docs/architecture.md](docs/architecture.md) for the complete design.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Process model
|
|
4
|
+
|
|
5
|
+
StateForge DPT runs on the developer's machine. A FastAPI process owns SQLite,
|
|
6
|
+
GitHub communication, Git operations, and controlled filesystem access. The
|
|
7
|
+
browser interface communicates only with that local process.
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
Browser interface
|
|
11
|
+
|
|
|
12
|
+
Local FastAPI backend
|
|
13
|
+
+-- SQLite local working plan and audit cache
|
|
14
|
+
+-- GitHub App authentication and API reconciliation
|
|
15
|
+
+-- Git repository controller
|
|
16
|
+
+-- STATEFORGE_DPT.md renderer
|
|
17
|
+
|
|
|
18
|
+
Managed local repository clones <----> GitHub
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Sources of authority
|
|
22
|
+
|
|
23
|
+
The Git-tracked `STATEFORGE_DPT.md` is the portable project authority. Its
|
|
24
|
+
invisible, versioned JSON manifest contains the lossless project definition:
|
|
25
|
+
project identity and revision, repositories, delivery steps, required results,
|
|
26
|
+
dependencies, planned branches, and stable ordering. A SHA-256 fingerprint
|
|
27
|
+
detects divergent or modified manifests. The visible Markdown remains a
|
|
28
|
+
human-readable plan and is generated identically in every attached repository.
|
|
29
|
+
|
|
30
|
+
SQLite is the local working copy. It holds edits that have not been published,
|
|
31
|
+
machine-specific clone paths, credentials, GitHub evidence, and audit activity.
|
|
32
|
+
Publishing creates the next manifest revision in every attached clone; normal
|
|
33
|
+
Git commits, pushes, pulls, and reviews distribute that revision exactly like
|
|
34
|
+
source code.
|
|
35
|
+
|
|
36
|
+
On another computer, importing `STATEFORGE_DPT.md` from any participating clone
|
|
37
|
+
recreates all repositories and milestones. The source clone is attached and the
|
|
38
|
+
remaining repositories are registered for cloning or attachment. When Git has a
|
|
39
|
+
newer revision, DPT can import it. If local unpublished edits exist, or two Git
|
|
40
|
+
copies claim the same revision with different fingerprints, DPT stops and asks
|
|
41
|
+
the user to choose rather than silently overwriting a plan.
|
|
42
|
+
|
|
43
|
+
Each project also records a portable plan source branch, conventionally the
|
|
44
|
+
shared parent branch from which milestone branches are derived (for example,
|
|
45
|
+
`mvp/implementation`). Reconciliation runs a narrow Git fetch in each attached
|
|
46
|
+
clone and reads `STATEFORGE_DPT.md` directly from the fetched ref. It does not
|
|
47
|
+
check out that ref, merge, rebase, or write any worktree file. Valid snapshots
|
|
48
|
+
are checksummed and cached in SQLite. A strictly newer snapshot is imported only
|
|
49
|
+
when the SQLite plan has no unpublished edits; otherwise it is presented as a
|
|
50
|
+
conflict. This allows plan changes merged by another computer to appear locally
|
|
51
|
+
while the developer remains on any feature branch.
|
|
52
|
+
|
|
53
|
+
GitHub supplies observed execution evidence. Stable labels bind an issue or
|
|
54
|
+
pull request to a DPT step:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
dpt:project:stateforge
|
|
58
|
+
dpt:release:mvp
|
|
59
|
+
dpt:step:P1
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
An open issue is pending work, an open pull request is under review, a merged
|
|
63
|
+
pull request is completed work, and a closed unmerged pull request is cancelled.
|
|
64
|
+
When no GitHub artifact exists, dependencies determine whether a step is ready
|
|
65
|
+
or blocked. Reconciliation reports workflow violations, such as opening a pull
|
|
66
|
+
request before its prerequisites are complete. Issues may be prepared in
|
|
67
|
+
advance without changing the dependency graph.
|
|
68
|
+
|
|
69
|
+
## Generated-file safety
|
|
70
|
+
|
|
71
|
+
The renderer is deterministic. DPT records the last digest written to each
|
|
72
|
+
clone and refuses to overwrite a changed generated file without an explicit
|
|
73
|
+
force action. The embedded manifest is independently checksummed and parsed
|
|
74
|
+
through a strict schema with duplicate, missing-dependency, and cycle checks.
|
|
75
|
+
Files are written atomically. Absolute local paths, credentials, cached GitHub
|
|
76
|
+
activity, and tokens never appear in the generated document.
|
|
77
|
+
|
|
78
|
+
## GitHub authentication
|
|
79
|
+
|
|
80
|
+
The browser requests a one-time GitHub device code from the local backend. The
|
|
81
|
+
backend keeps the associated device credential encrypted, enforces GitHub's
|
|
82
|
+
polling interval, and creates a session only after GitHub confirms the user.
|
|
83
|
+
Access and refresh tokens are encrypted at rest. The browser receives only a
|
|
84
|
+
random session identifier in an HTTP-only SameSite cookie. No GitHub client
|
|
85
|
+
secret or callback endpoint is used.
|
|
86
|
+
|
|
87
|
+
## Repository control
|
|
88
|
+
|
|
89
|
+
A repository may be attached to an existing clone or cloned by DPT. Before it
|
|
90
|
+
is accepted, DPT verifies that the path is a Git worktree and that its `origin`
|
|
91
|
+
remote matches the selected GitHub repository. Repository mutations are
|
|
92
|
+
performed without a shell and are presented to the user before commit or push.
|
|
93
|
+
Remote plan reads use argument-based Git commands with prompting disabled. The
|
|
94
|
+
current HEAD, index, untracked files, and worktree are invariant across the
|
|
95
|
+
operation.
|