@mriekki/project-forge 0.0.0-stage → 2.0.0
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.
- package/README.md +134 -2
- package/assets/components.json +33 -0
- package/assets/core/distribution.json +66 -0
- package/assets/deployment/distribution.json +54 -0
- package/assets/generated/ASSEMBLY.json +557 -0
- package/assets/generated/core/core/agents/coach.agent.md +69 -0
- package/assets/generated/core/core/agents/reviewer.agent.md +85 -0
- package/assets/generated/core/core/instructions/project-forge-docs.instructions.md +45 -0
- package/assets/generated/core/core/instructions/project-forge-workflow.instructions.md +79 -0
- package/assets/generated/core/core/learning/CODING_DRILLS.md +35 -0
- package/assets/generated/core/core/learning/DIAGRAM_GUIDE.md +59 -0
- package/assets/generated/core/core/learning/ENGINEERING_LEARNING_WORKBOOK.md +108 -0
- package/assets/generated/core/core/learning/LEARNING_MAP.md +108 -0
- package/assets/generated/core/core/learning/LEARNING_PROGRESS.md +39 -0
- package/assets/generated/core/core/learning/RESOURCE_CATALOG.md +25 -0
- package/assets/generated/core/core/learning/SQL_DRILLS.md +90 -0
- package/assets/generated/core/core/learning/SYSTEM_DESIGN_DRILLS.md +301 -0
- package/assets/generated/core/core/process/COACHING_GUIDE.md +92 -0
- package/assets/generated/core/core/process/DATABASE_LEARNING_WORKBENCH.md +397 -0
- package/assets/generated/core/core/process/DEPLOYMENT_ENABLEMENT.md +166 -0
- package/assets/generated/core/core/process/GUIDED_NEXT_STEPS.md +48 -0
- package/assets/generated/core/core/process/HUMAN_GATES.md +83 -0
- package/assets/generated/core/core/process/INTERACTIVE_SESSION_GUIDE.md +64 -0
- package/assets/generated/core/core/process/PROJECT_DOCUMENTATION_FRAMEWORK.md +326 -0
- package/assets/generated/core/core/process/PROJECT_FORGE_ENGINEERING_GUIDE.md +308 -0
- package/assets/generated/core/core/process/PR_WORKFLOW.md +55 -0
- package/assets/generated/core/core/process/SETUP_ACCEPTANCE_CHECKLIST.md +72 -0
- package/assets/generated/core/core/process/SYSTEM_DESIGN_LEARNING_WORKBENCH.md +520 -0
- package/assets/generated/core/core/process/WORK_ITEM_MODEL.md +56 -0
- package/assets/generated/core/core/skills/cleanup-branches/SKILL.md +190 -0
- package/assets/generated/core/core/skills/coach/SKILL.md +174 -0
- package/assets/generated/core/core/skills/code-walkthrough/SKILL.md +197 -0
- package/assets/generated/core/core/skills/core-sync/SKILL.md +178 -0
- package/assets/generated/core/core/skills/db-lab/SKILL.md +245 -0
- package/assets/generated/core/core/skills/define-feature/SKILL.md +144 -0
- package/assets/generated/core/core/skills/deliver/SKILL.md +397 -0
- package/assets/generated/core/core/skills/deploy/SKILL.md +188 -0
- package/assets/generated/core/core/skills/deployment-readiness/SKILL.md +234 -0
- package/assets/generated/core/core/skills/developer-env-mode/SKILL.md +231 -0
- package/assets/generated/core/core/skills/docs/SKILL.md +116 -0
- package/assets/generated/core/core/skills/grill-me/SKILL.md +77 -0
- package/assets/generated/core/core/skills/grill-with-docs/SKILL.md +90 -0
- package/assets/generated/core/core/skills/learning-review/SKILL.md +90 -0
- package/assets/generated/core/core/skills/next-step/SKILL.md +221 -0
- package/assets/generated/core/core/skills/progress/SKILL.md +207 -0
- package/assets/generated/core/core/skills/project-forge-update/SKILL.md +228 -0
- package/assets/generated/core/core/skills/pull-latest/SKILL.md +166 -0
- package/assets/generated/core/core/skills/refine-requirements/SKILL.md +207 -0
- package/assets/generated/core/core/skills/setup/SKILL.md +362 -0
- package/assets/generated/core/core/skills/start-work/SKILL.md +190 -0
- package/assets/generated/core/core/skills/system-lab/SKILL.md +333 -0
- package/assets/generated/core/core/skills/tear-down/SKILL.md +140 -0
- package/assets/generated/core/core/skills/upstream-fix/SKILL.md +221 -0
- package/assets/generated/core/core/skills/wait-what/SKILL.md +86 -0
- package/assets/generated/core/core/templates/ADR_TEMPLATE.md +41 -0
- package/assets/generated/core/core/templates/FEATURE_BRIEF_TEMPLATE.md +27 -0
- package/assets/generated/core/core/templates/PRODUCT_BRIEF_TEMPLATE.md +27 -0
- package/assets/generated/core/core/templates/PULL_REQUEST_TEMPLATE.md +37 -0
- package/assets/generated/core/core/templates/REQUIREMENTS_TEMPLATE.md +17 -0
- package/assets/generated/core/profiles/greenfield/project-forge-workspace.json +12 -0
- package/assets/generated/core/tools/db_lab/sqlite_workbench.py +463 -0
- package/assets/generated/core/tools/docs_site/docs_site.py +512 -0
- package/assets/generated/core/tools/package/check_baseline.py +102 -0
- package/assets/generated/core/tools/package/check_upstream.py +171 -0
- package/assets/generated/core/tools/system_lab/system_workbench.py +243 -0
- package/assets/generated/deployment/distribution/project-forge-deploy.py +8 -0
- package/assets/generated/deployment/docs/DEVELOPER_ENVIRONMENTS.md +335 -0
- package/assets/generated/deployment/docs/ENVIRONMENT_PROOF.md +95 -0
- package/assets/generated/deployment/docs/WORKSPACE_INSTANCES.md +154 -0
- package/assets/generated/deployment/docs/images/developer-environment-journey.svg +56 -0
- package/assets/generated/deployment/docs/images/personal-environment-architecture.svg +54 -0
- package/assets/generated/deployment/docs/images/poc-environment-model.svg +61 -0
- package/assets/generated/deployment/src/project_forge_deployment/__init__.py +3 -0
- package/assets/generated/deployment/src/project_forge_deployment/__main__.py +3 -0
- package/assets/generated/deployment/src/project_forge_deployment/app_cli.py +163 -0
- package/assets/generated/deployment/src/project_forge_deployment/app_runtime.py +455 -0
- package/assets/generated/deployment/src/project_forge_deployment/app_runtime_remote.py +416 -0
- package/assets/generated/deployment/src/project_forge_deployment/app_runtime_workstation.py +136 -0
- package/assets/generated/deployment/src/project_forge_deployment/box_platform.py +208 -0
- package/assets/generated/deployment/src/project_forge_deployment/box_platform_assets.py +100 -0
- package/assets/generated/deployment/src/project_forge_deployment/box_platform_remote.py +271 -0
- package/assets/generated/deployment/src/project_forge_deployment/cli.py +437 -0
- package/assets/generated/deployment/src/project_forge_deployment/doctor.py +121 -0
- package/assets/generated/deployment/src/project_forge_deployment/entrypoint.py +37 -0
- package/assets/generated/deployment/src/project_forge_deployment/environment_cli.py +271 -0
- package/assets/generated/deployment/src/project_forge_deployment/environment_probe.py +228 -0
- package/assets/generated/deployment/src/project_forge_deployment/errors.py +5 -0
- package/assets/generated/deployment/src/project_forge_deployment/home_lab.py +328 -0
- package/assets/generated/deployment/src/project_forge_deployment/image_transfer.py +105 -0
- package/assets/generated/deployment/src/project_forge_deployment/keys.py +171 -0
- package/assets/generated/deployment/src/project_forge_deployment/local_cli.py +189 -0
- package/assets/generated/deployment/src/project_forge_deployment/local_runtime.py +526 -0
- package/assets/generated/deployment/src/project_forge_deployment/local_spec.py +82 -0
- package/assets/generated/deployment/src/project_forge_deployment/local_sqlite.py +205 -0
- package/assets/generated/deployment/src/project_forge_deployment/portable_profile.py +181 -0
- package/assets/generated/deployment/src/project_forge_deployment/profile_migration.py +70 -0
- package/assets/generated/deployment/src/project_forge_deployment/profile_repository.py +348 -0
- package/assets/generated/deployment/src/project_forge_deployment/profiles.py +204 -0
- package/assets/generated/deployment/src/project_forge_deployment/registry_access.py +114 -0
- package/assets/generated/deployment/src/project_forge_deployment/registry_cli.py +51 -0
- package/assets/generated/deployment/src/project_forge_deployment/route_registry.py +367 -0
- package/assets/generated/deployment/src/project_forge_deployment/route_registry_remote.py +443 -0
- package/assets/generated/deployment/src/project_forge_deployment/security.py +290 -0
- package/assets/generated/deployment/src/project_forge_deployment/sqlite_adapter.py +335 -0
- package/assets/generated/deployment/src/project_forge_deployment/sqlite_adapter_remote.py +340 -0
- package/assets/generated/deployment/src/project_forge_deployment/sqlite_cli.py +86 -0
- package/assets/generated/deployment/src/project_forge_deployment/sqlite_import_recovery.py +437 -0
- package/assets/generated/deployment/src/project_forge_deployment/ssh.py +119 -0
- package/assets/generated/deployment/src/project_forge_deployment/teardown.py +300 -0
- package/assets/generated/deployment/src/project_forge_deployment/teardown_cli.py +139 -0
- package/assets/generated/deployment/src/project_forge_deployment/teardown_remote.py +100 -0
- package/assets/generated/deployment/src/project_forge_deployment/trust.py +278 -0
- package/bin/project-forge.mjs +9 -0
- package/package.json +31 -4
- package/src/cli.mjs +150 -0
- package/src/engine.mjs +243 -0
- package/src/package-data.mjs +18 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# Developer Environments
|
|
2
|
+
|
|
3
|
+
Status: **CORE WORKSTATION/TARGET MECHANICS IMPLEMENTED; AUTOMATED HOST PACKAGE PREPARATION REMAINS INCREMENTAL**
|
|
4
|
+
|
|
5
|
+
This document is the canonical developer-environment model for Project Forges. It describes the developer-facing progression from a generated repository to local development, optional Staging/Production capability, additional workstations, and additional remote boxes.
|
|
6
|
+
|
|
7
|
+
The happy path intentionally hides Bootstrap/package/control-plane plumbing. Developers should see meaningful milestones and actionable setup, while the underlying repositories retain exact provenance and safety evidence.
|
|
8
|
+
|
|
9
|
+
## Developer journey
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
The normal progression is:
|
|
14
|
+
|
|
15
|
+
```text
|
|
16
|
+
generated POC repository
|
|
17
|
+
→ clone/open workspace
|
|
18
|
+
→ /setup
|
|
19
|
+
→ LOCAL READY
|
|
20
|
+
→ optional remote onboarding
|
|
21
|
+
→ STAGING READY
|
|
22
|
+
→ optional Production onboarding
|
|
23
|
+
→ PRODUCTION READY
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Local readiness is a valid complete developer state. Staging and Production are progressive capabilities, not prerequisites for coding.
|
|
27
|
+
|
|
28
|
+
## One setup front door
|
|
29
|
+
|
|
30
|
+
The generated repository provides deterministic OS launchers:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
Windows .\scripts\setup.ps1
|
|
34
|
+
macOS ./scripts/setup.sh
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The normal conversational entry point is:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
/setup
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`/setup` explains the current state/options and invokes the correct repository-local setup launcher. Direct script invocation remains the non-AI/automation fallback.
|
|
44
|
+
|
|
45
|
+
The first local success target is `LOCAL WORKSPACE READY`. Remote access must not block it unless the POC explicitly requires a remote dependency for local development.
|
|
46
|
+
|
|
47
|
+
## Progress and next action
|
|
48
|
+
|
|
49
|
+
Use `/progress` to answer what is complete, what is blocked/deferred, who owns the next action, and local/Staging/Production capability state.
|
|
50
|
+
|
|
51
|
+
Use `/next-step` for one recommended next action.
|
|
52
|
+
|
|
53
|
+
Progress uses milestone states rather than percentages. Internal Bootstrap/package/generator phases are not developer milestones unless an internal failure becomes the actionable blocker.
|
|
54
|
+
|
|
55
|
+
## Personal environment architecture
|
|
56
|
+
|
|
57
|
+

|
|
58
|
+
|
|
59
|
+
Each developer owns an independent portable profile. Two developers may describe the same physical target, but neither depends on the other's profile or workstation credentials.
|
|
60
|
+
|
|
61
|
+
### Private personal Project Forge profile
|
|
62
|
+
|
|
63
|
+
The standard personal repository is:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
<authenticated-github-user>/project-forge-profile
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
It must be private. The canonical portable file is:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
project-forge-profile.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
It contains only sanitized target definitions:
|
|
76
|
+
|
|
77
|
+
- logical target name;
|
|
78
|
+
- target OS profile;
|
|
79
|
+
- stable DNS/mDNS hostname;
|
|
80
|
+
- SSH user and port;
|
|
81
|
+
- stable SSH host alias/identity name.
|
|
82
|
+
|
|
83
|
+
It does **not** contain SSH private keys, passwords/passphrases, PATs/tokens, `known_hosts` contents, machine-specific credential paths, temporary IP overrides, local runtime/data, or readiness claims.
|
|
84
|
+
|
|
85
|
+
Direct deterministic commands are available beneath `/setup`:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
project-forge-deploy environment profile status
|
|
89
|
+
project-forge-deploy environment profile ensure
|
|
90
|
+
project-forge-deploy environment profile sync --apply
|
|
91
|
+
project-forge-deploy environment profile publish
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`profile ensure` creates/initializes only the authenticated developer's exact private `project-forge-profile` repository and requires:
|
|
95
|
+
|
|
96
|
+
```text
|
|
97
|
+
[PERSONAL PROFILE WRITE]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
An empty profile with `targets: []` is valid. A local-only developer never needs a remote target merely to have a portable workstation profile.
|
|
101
|
+
|
|
102
|
+
`profile sync` fetches and validates the GitHub profile, updates the validated local cache, and with `--apply` creates only missing non-conflicting local target definitions. Existing differing local definitions are never overwritten.
|
|
103
|
+
|
|
104
|
+
`profile publish` merges new non-conflicting local target definitions into the private profile and fails on conflicts rather than silently replacing remote definitions.
|
|
105
|
+
|
|
106
|
+
### Workstation-local state
|
|
107
|
+
|
|
108
|
+
Each workstation owns its own:
|
|
109
|
+
|
|
110
|
+
- SSH private key/identity;
|
|
111
|
+
- host trust;
|
|
112
|
+
- credential-manager entries when explicitly chosen;
|
|
113
|
+
- validated profile cache/last-known-good snapshot;
|
|
114
|
+
- local Docker/runtime state;
|
|
115
|
+
- repository-scoped developer-mode evidence.
|
|
116
|
+
|
|
117
|
+
Private SSH keys are never synchronized between computers. A Mark Windows key, Mark Mac key, Kyle Mac key, and Daniel Windows key are distinct identities even when they can reach the same remote server.
|
|
118
|
+
|
|
119
|
+
## Home Lab remote onboarding
|
|
120
|
+
|
|
121
|
+
The implemented Home Lab path is password-assisted bootstrap followed by normal strict key-only operation.
|
|
122
|
+
|
|
123
|
+
Preview:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
project-forge-deploy environment home-lab plan <target> \
|
|
127
|
+
--host-name <stable-hostname> \
|
|
128
|
+
--user <ssh-user>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Bootstrap:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
project-forge-deploy environment home-lab bootstrap <target> \
|
|
135
|
+
--host-name <stable-hostname> \
|
|
136
|
+
--user <ssh-user>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The password prompt is owned by local OpenSSH. The password is never pasted into chat, passed as a command argument, or persisted by Project Forge.
|
|
140
|
+
|
|
141
|
+
The flow is:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
create/reuse target definition
|
|
145
|
+
→ create/reuse this workstation's key
|
|
146
|
+
→ first-use host pinning in target-specific trust file when needed
|
|
147
|
+
→ local OpenSSH password prompt
|
|
148
|
+
→ append public key idempotently to authorized_keys
|
|
149
|
+
→ strict key-only verification
|
|
150
|
+
→ TARGET ACCESS READY
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The default Home Lab key is unencrypted for convenience. `--protect-key-with-passphrase` delegates a key passphrase prompt to `ssh-keygen`; protected keys must be available to the SSH agent for later non-interactive verification.
|
|
154
|
+
|
|
155
|
+
A changed previously pinned host key remains a blocker and requires explicit trust rotation. Existing stricter console-verified trust is preserved during migration rather than weakened.
|
|
156
|
+
|
|
157
|
+
## Docker and host preparation
|
|
158
|
+
|
|
159
|
+
Docker is a workstation/target capability, not something every POC should reinstall.
|
|
160
|
+
|
|
161
|
+
### Developer workstation
|
|
162
|
+
|
|
163
|
+
The first POC on a computer may install/verify required local tools and Docker through the generated setup contract. Later POCs reuse the ready workstation.
|
|
164
|
+
|
|
165
|
+
### Remote Ubuntu target
|
|
166
|
+
|
|
167
|
+
Target access can now be established from the local workstation, but full automatic Ubuntu package preparation is still an incremental capability. The desired host progression remains:
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
Ubuntu/sudo verification
|
|
171
|
+
→ Docker Engine/Compose if missing
|
|
172
|
+
→ required Project Forge host prerequisites
|
|
173
|
+
→ Project Forge shared host platform
|
|
174
|
+
→ platform doctor
|
|
175
|
+
→ TARGET READY
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The current platform doctor/install contract still requires host prerequisites to exist before shared-platform installation. Until a reviewed host-package bootstrap is added, `/setup remote` must report missing host packages as an actionable preparation gap rather than pretending they were installed.
|
|
179
|
+
|
|
180
|
+
Healthy existing Docker/Project Forge installations are adopted/verified, not recreated. Ambiguous/incompatible existing state fails closed rather than being overwritten.
|
|
181
|
+
|
|
182
|
+
## GitHub/GHCR credentials stay local
|
|
183
|
+
|
|
184
|
+
A developer should not need to SSH to Staging/Production and enter a GitHub PAT.
|
|
185
|
+
|
|
186
|
+
The implemented workstation-mediated artifact path is:
|
|
187
|
+
|
|
188
|
+
```text
|
|
189
|
+
local GitHub/GHCR authentication when needed
|
|
190
|
+
→ acquire/build exact immutable image locally
|
|
191
|
+
→ verify exact identity/digest
|
|
192
|
+
→ stream Docker image over verified SSH
|
|
193
|
+
→ remote docker load
|
|
194
|
+
→ verify exact image remotely
|
|
195
|
+
→ deploy/health-check using the preloaded image
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Remote Home Lab boxes therefore do not need a developer's persistent GitHub PAT for the normal workstation-mediated deployment path.
|
|
199
|
+
|
|
200
|
+
Application deployment selects this with:
|
|
201
|
+
|
|
202
|
+
```text
|
|
203
|
+
--image-source workstation
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The legacy `--image-source remote-registry` path remains available during migration/for explicit target-side registry use.
|
|
207
|
+
|
|
208
|
+
A credential needed to acquire a private image is entered only through the local Docker/GitHub credential boundary. Never paste it into chat or put it on a command line.
|
|
209
|
+
|
|
210
|
+
If the exact immutable image is already cached locally, registry authentication is not required merely to transfer it to the remote target.
|
|
211
|
+
|
|
212
|
+
## POC environment model
|
|
213
|
+
|
|
214
|
+

|
|
215
|
+
|
|
216
|
+
The POC owns project-specific facts such as environment identities/roles, placement, target binding, application image, runtime/health contract, persistence, routes/exposure, and Production classification/authorization.
|
|
217
|
+
|
|
218
|
+
The reusable workstation/target layer owns machine mechanics. A POC references targets; it does not own or duplicate a developer's private credentials.
|
|
219
|
+
|
|
220
|
+
## New workstation
|
|
221
|
+
|
|
222
|
+
A developer normally starts from any generated POC:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
clone repository
|
|
226
|
+
→ open generated VS Code workspace
|
|
227
|
+
→ /setup
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
`/setup` detects whether this is a fresh or already-prepared workstation and converges only missing safe capabilities.
|
|
231
|
+
|
|
232
|
+
When GitHub is reachable, personal profile sync supplies portable target definitions. The new workstation still creates its own SSH identity/trust. Remote setup is optional and can be deferred until needed.
|
|
233
|
+
|
|
234
|
+
## New remote box
|
|
235
|
+
|
|
236
|
+
Adding a new remote target is a workstation-driven onboarding operation, not a POC implementation step:
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
add/import portable target definition
|
|
240
|
+
→ Home Lab or Strict workstation SSH onboarding
|
|
241
|
+
→ verify/prepare Docker host prerequisites
|
|
242
|
+
→ verify/install Project Forge shared platform
|
|
243
|
+
→ TARGET READY
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Once ready, multiple POCs can bind logical environments to that target without repeating host bootstrap.
|
|
247
|
+
|
|
248
|
+
## Portable export/import fallback
|
|
249
|
+
|
|
250
|
+
Normal portability is the developer's private `project-forge-profile`. A sanitized environment bundle is also implemented for explicit sharing/offline bootstrap:
|
|
251
|
+
|
|
252
|
+
```text
|
|
253
|
+
project-forge-deploy environment profile export --target <name> --output project-forge-environment-bundle.json
|
|
254
|
+
project-forge-deploy environment profile preview-import project-forge-environment-bundle.json
|
|
255
|
+
project-forge-deploy environment profile import project-forge-environment-bundle.json
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Export/import is copy-by-value. Importing another developer's target definition creates an independent personal copy; later changes do not silently propagate across users.
|
|
259
|
+
|
|
260
|
+
A portable bundle contains only non-secret definition fields. Import never transfers readiness, private keys, passwords, trust contents, credential paths, or IP overrides and never overwrites a conflicting existing target.
|
|
261
|
+
|
|
262
|
+
## Last-known-good/offline behavior
|
|
263
|
+
|
|
264
|
+
Validated profile state is cached under the user-scoped Project Forge home:
|
|
265
|
+
|
|
266
|
+
```text
|
|
267
|
+
~/.project-forge/profile/current/project-forge-profile.json
|
|
268
|
+
~/.project-forge/profile/last-known-good/project-forge-profile.json
|
|
269
|
+
~/.project-forge/profile/sync-state.json
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
A valid GitHub fetch updates both current and last-known-good snapshots. An invalid/unavailable remote profile never overwrites last-known-good state.
|
|
273
|
+
|
|
274
|
+
When GitHub cannot be reached, profile sync can use the validated last-known-good profile so local work and previously established target definitions remain usable. Remote operations still require independent machine-specific access/trust verification.
|
|
275
|
+
|
|
276
|
+
## Migration for existing developers
|
|
277
|
+
|
|
278
|
+
Existing Mark/Kyle environments should migrate fully to this model rather than remain permanently dual-mode.
|
|
279
|
+
|
|
280
|
+
The migration contract is:
|
|
281
|
+
|
|
282
|
+
```text
|
|
283
|
+
inventory existing workstation/targets
|
|
284
|
+
→ ensure private personal project-forge-profile + validated cache
|
|
285
|
+
→ adopt healthy existing Docker/SSH/trust where valid
|
|
286
|
+
→ establish workstation-mediated artifact delivery
|
|
287
|
+
→ prove Staging end-to-end
|
|
288
|
+
→ verify Production access/readiness without deploying
|
|
289
|
+
→ remove/archive superseded legacy configuration only after verification
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Migration must not reinstall healthy Docker, rotate valid SSH identities merely for consistency, redeploy unrelated applications, reset data, or weaken stricter existing trust.
|
|
293
|
+
|
|
294
|
+
Server-side GHCR credentials/PATs are removed only after proving that no remaining deployment path depends on them. Existing remote application containers/data remain intact while the access/deployment mechanism changes.
|
|
295
|
+
|
|
296
|
+
After migration, the new profile/workstation model is authoritative. Legacy configuration may be retained temporarily only as explicitly inactive migration backup, not as a second active source of truth.
|
|
297
|
+
|
|
298
|
+
## Progressive readiness examples
|
|
299
|
+
|
|
300
|
+
All of these are valid states:
|
|
301
|
+
|
|
302
|
+
```text
|
|
303
|
+
Local READY
|
|
304
|
+
Staging NOT CONFIGURED
|
|
305
|
+
Production NOT CONFIGURED
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
```text
|
|
309
|
+
Local READY
|
|
310
|
+
Staging READY
|
|
311
|
+
Production NOT AUTHORIZED
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
```text
|
|
315
|
+
Local READY
|
|
316
|
+
Staging READY
|
|
317
|
+
Production READY (access/readiness only)
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Production readiness never implies Production deployment authorization.
|
|
321
|
+
|
|
322
|
+
## Developer-facing commands
|
|
323
|
+
|
|
324
|
+
The intended small human surface is:
|
|
325
|
+
|
|
326
|
+
```text
|
|
327
|
+
/setup
|
|
328
|
+
/progress
|
|
329
|
+
/next-step
|
|
330
|
+
/developer-env-mode status|local|remote
|
|
331
|
+
/deployment-readiness <environment>
|
|
332
|
+
/deploy <environment>
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
The first three are the normal guided experience. `project-forge-deploy environment ...` commands are deterministic implementation/fallback surfaces and can be invoked directly when desired.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Environment Proof Deployment
|
|
2
|
+
|
|
3
|
+
A Project Forge environment proof verifies that one developer workstation can exercise the real remote deployment path for one exact named logical environment before the POC application exists or before its first real deployment.
|
|
4
|
+
|
|
5
|
+
It is intentionally **not** the project application.
|
|
6
|
+
|
|
7
|
+
## What it proves
|
|
8
|
+
|
|
9
|
+
For a supported remote-target environment, the proof uses the same reusable mechanics as a normal workstation-mediated application deployment:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
this workstation
|
|
13
|
+
→ verified target/profile access
|
|
14
|
+
→ ready shared host platform
|
|
15
|
+
→ pull small stable probe image locally
|
|
16
|
+
→ resolve exact immutable RepoDigest
|
|
17
|
+
→ transfer exact image over verified SSH
|
|
18
|
+
→ deploy with the managed application runtime
|
|
19
|
+
→ verify HTTP health
|
|
20
|
+
→ tear down the reserved probe runtime
|
|
21
|
+
→ verify cleanup evidence
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The current default probe image tag is `nginx:alpine`. The tag is never treated as the deployed identity: Project Forge pulls it locally and resolves an exact `@sha256:` RepoDigest before image transfer or remote runtime mutation.
|
|
25
|
+
|
|
26
|
+
The probe uses:
|
|
27
|
+
|
|
28
|
+
- no project database;
|
|
29
|
+
- no project persistent data;
|
|
30
|
+
- no project application secrets;
|
|
31
|
+
- a reserved per-repository probe app slug;
|
|
32
|
+
- the exact selected logical environment name;
|
|
33
|
+
- the existing per-app/per-environment deployment lock;
|
|
34
|
+
- automatic cleanup through the existing scoped tear-down machinery.
|
|
35
|
+
|
|
36
|
+
## Commands
|
|
37
|
+
|
|
38
|
+
Read-only plan:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
project-forge-deploy environment proof plan <target> \
|
|
42
|
+
--owner-repo <owner/repo> \
|
|
43
|
+
--environment <name>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Run the proof after authorization:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
project-forge-deploy environment proof run <target> \
|
|
50
|
+
--owner-repo <owner/repo> \
|
|
51
|
+
--environment <name>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
For a named environment whose project purpose is Production, preserve that classification even when its name is custom:
|
|
55
|
+
|
|
56
|
+
```text
|
|
57
|
+
project-forge-deploy environment proof run <target> \
|
|
58
|
+
--owner-repo <owner/repo> \
|
|
59
|
+
--environment prod-east \
|
|
60
|
+
--production
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Use the exact installed CLI/help rather than copying examples blindly.
|
|
64
|
+
|
|
65
|
+
## Authorization
|
|
66
|
+
|
|
67
|
+
Normal non-Production proof:
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
[ENVIRONMENT PROOF WRITE]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Production-class proof:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
[PRODUCTION ENVIRONMENT PROOF]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
A successful proof never authorizes the later real application deployment. Production proof never authorizes a Production application deployment.
|
|
80
|
+
|
|
81
|
+
## Cleanup
|
|
82
|
+
|
|
83
|
+
The proof attempts cleanup even when deployment raises after mutation begins.
|
|
84
|
+
|
|
85
|
+
Successful completion requires terminal cleanup evidence (`removed` or already `absent`) for the reserved probe runtime. If deployment succeeds but cleanup cannot be verified, the command fails rather than reporting a clean proof.
|
|
86
|
+
|
|
87
|
+
The probe must not delete another POC, another application, another logical environment, or shared host platform state.
|
|
88
|
+
|
|
89
|
+
## Relationship to `/setup` and `/deploy`
|
|
90
|
+
|
|
91
|
+
`/setup` may run this proof after the developer selects a named remote environment to prepare on the current workstation.
|
|
92
|
+
|
|
93
|
+
A later first real `/deploy <environment>` can reuse fresh proof evidence for target access/platform/transport mechanics and ask only unresolved application-specific questions such as persistence, health, route/exposure, and immutable application artifact policy.
|
|
94
|
+
|
|
95
|
+
Project-defined environment names are not limited to Staging and Production. `demo`, `qa`, `prod-east`, or another safe configured slug use the same mechanics, while Production purpose/classification keeps the stronger authorization path.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Workspace Instances
|
|
2
|
+
|
|
3
|
+
Status: **SUPPORTED MODEL — ONE PROJECT MAY HAVE MULTIPLE INDEPENDENT WORKSTATION CHECKOUTS**
|
|
4
|
+
|
|
5
|
+
A **workspace instance** is one checkout of one Project Forge on one developer workstation. A project may have multiple workspace instances active at the same time, including different operating systems for the same developer.
|
|
6
|
+
|
|
7
|
+
Examples:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
family-meal-planner-v3
|
|
11
|
+
├─ Mark Windows workspace
|
|
12
|
+
└─ Mark macOS workspace
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Neither workstation is primary. One does not need to be online for the other to work.
|
|
16
|
+
|
|
17
|
+
## Shared project state
|
|
18
|
+
|
|
19
|
+
Git/GitHub is the normal shared source-code coordination boundary. The repository owns project facts such as:
|
|
20
|
+
|
|
21
|
+
- source code and tests;
|
|
22
|
+
- exact project technology/version choices;
|
|
23
|
+
- Project Forge package/baseline state;
|
|
24
|
+
- work-item and architecture documentation;
|
|
25
|
+
- project-owned deployment topology and environment references.
|
|
26
|
+
|
|
27
|
+
Independent workstreams should normally use independent short-lived branches. Different work items may be active from different workstations at the same time.
|
|
28
|
+
|
|
29
|
+
Using the same branch from more than one workstation is allowed but requires ordinary Git coordination. A workspace must treat a remote branch that advanced elsewhere as new evidence and must not resolve divergence with force/reset/history rewriting automatically.
|
|
30
|
+
|
|
31
|
+
## Portable personal state
|
|
32
|
+
|
|
33
|
+
The authenticated developer's private `<login>/project-forge-profile` is portable, non-secret state shared across the developer's workstations.
|
|
34
|
+
|
|
35
|
+
It may carry target definitions/preferences such as logical target, hostname, SSH user/port, OS profile, and stable host alias.
|
|
36
|
+
|
|
37
|
+
It must not carry:
|
|
38
|
+
|
|
39
|
+
- SSH private keys or passphrases;
|
|
40
|
+
- passwords/PATs/tokens;
|
|
41
|
+
- `known_hosts` contents;
|
|
42
|
+
- machine-specific credential paths;
|
|
43
|
+
- local databases or application runtime data;
|
|
44
|
+
- Docker credential state;
|
|
45
|
+
- workstation readiness claims.
|
|
46
|
+
|
|
47
|
+
A new workstation may sync/apply this profile and then establish its own machine-specific identity/trust.
|
|
48
|
+
|
|
49
|
+
## Machine-local workspace state
|
|
50
|
+
|
|
51
|
+
Each workspace instance independently owns:
|
|
52
|
+
|
|
53
|
+
- OS/tool installations;
|
|
54
|
+
- VS Code/editor extensions;
|
|
55
|
+
- local dependency caches;
|
|
56
|
+
- local Docker/runtime state;
|
|
57
|
+
- local development database/data;
|
|
58
|
+
- SSH private key and host trust;
|
|
59
|
+
- GitHub/Docker/registry credentials;
|
|
60
|
+
- repository-scoped developer-mode/readiness evidence.
|
|
61
|
+
|
|
62
|
+
Local mutable application data is not synchronized between workstations by Project Forge. Projects should reproduce schema/migrations/seed behavior rather than silently copying a workstation's development database to another computer.
|
|
63
|
+
|
|
64
|
+
## Setup on another workstation
|
|
65
|
+
|
|
66
|
+
The normal flow for an existing generated POC is:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
clone repository
|
|
70
|
+
→ open generated VS Code workspace
|
|
71
|
+
→ /setup
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`/setup` detects the current OS automatically and chooses the generated launcher:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
Windows .\scripts\setup.ps1
|
|
78
|
+
macOS ./scripts/setup.sh
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
When repository/project evidence exists but workstation-local readiness evidence does not, the developer-facing state is:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
EXISTING PROJECT — NEW WORKSTATION
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Setup should reuse the project definition and portable personal profile, install/verify only missing safe machine capabilities, restore project dependencies, and converge local readiness. Remote access remains optional until needed.
|
|
88
|
+
|
|
89
|
+
OS-specific project limitations remain real. For example, a Windows workspace may edit shared Swift source but cannot claim native iOS build readiness when the selected toolchain requires macOS/Xcode.
|
|
90
|
+
|
|
91
|
+
## Concurrent source work
|
|
92
|
+
|
|
93
|
+
Recommended shape:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
Windows → feature/work-item-a
|
|
97
|
+
macOS → feature/work-item-b
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Both workspaces can build/test/run locally at the same time using independent local runtime/data.
|
|
101
|
+
|
|
102
|
+
If both use the same branch, source coordination remains Git-based:
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
local branch SHA
|
|
106
|
+
vs
|
|
107
|
+
remote branch SHA
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Before history-sensitive work/delivery, fetch/inspect current remote evidence. If another workspace advanced the branch, reconcile explicitly. Never use `git stash` as cross-workstation transport and never force-push merely to make two clones agree.
|
|
111
|
+
|
|
112
|
+
## Concurrent remote environment operations
|
|
113
|
+
|
|
114
|
+
A shared Staging or Production application is different from independent local development. Multiple workstations may have access to the same logical remote environment, but only one mutating application operation for the same app/environment may proceed at a time.
|
|
115
|
+
|
|
116
|
+
The Deployment Kit remote application runtime already acquires a non-blocking per-application/per-environment lock. If another deployment holds the lock, a concurrent deployment exits rather than racing the same runtime. Persistence operations use the same app/environment lock boundary.
|
|
117
|
+
|
|
118
|
+
Conceptually:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
Windows ─┐
|
|
122
|
+
├─> same app / staging ─> one active mutation
|
|
123
|
+
macOS ─┘ └> second mutation blocked
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Readiness/access on each workstation remains machine-specific because credentials/trust are machine-local. Remote environment state itself is shared.
|
|
127
|
+
|
|
128
|
+
## What Project Forge does not need
|
|
129
|
+
|
|
130
|
+
Multi-workstation support does **not** require:
|
|
131
|
+
|
|
132
|
+
- a central device registry;
|
|
133
|
+
- one primary developer computer;
|
|
134
|
+
- another workstation to be online;
|
|
135
|
+
- shared private keys;
|
|
136
|
+
- shared mutable local databases;
|
|
137
|
+
- proprietary file synchronization outside Git;
|
|
138
|
+
- automatic worktree transfer between computers.
|
|
139
|
+
|
|
140
|
+
A friendly machine/workspace label may be shown locally when useful, but it is descriptive only and not a project authority.
|
|
141
|
+
|
|
142
|
+
## Developer-facing commands
|
|
143
|
+
|
|
144
|
+
The normal surface remains small:
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
/setup
|
|
148
|
+
/progress
|
|
149
|
+
/next-step
|
|
150
|
+
/start-work <ID>
|
|
151
|
+
/deliver
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
`/setup` prepares **this** workspace instance. `/progress` reports **this** workspace instance plus shared project/environment evidence. Normal Git/work-item and delivery rules coordinate source changes across workstations.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="520" viewBox="0 0 1200 520" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Project Forge developer environment journey</title>
|
|
3
|
+
<desc id="desc">Generated POC repository progresses through clone and setup to local ready, then optionally to staging ready and production ready.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
6
|
+
<stop offset="0" stop-color="#0b1220"/>
|
|
7
|
+
<stop offset="1" stop-color="#172033"/>
|
|
8
|
+
</linearGradient>
|
|
9
|
+
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
|
10
|
+
<feDropShadow dx="0" dy="8" stdDeviation="10" flood-opacity="0.28"/>
|
|
11
|
+
</filter>
|
|
12
|
+
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="5" orient="auto">
|
|
13
|
+
<path d="M0,0 L10,5 L0,10 Z" fill="#8ea0bd"/>
|
|
14
|
+
</marker>
|
|
15
|
+
</defs>
|
|
16
|
+
<rect width="1200" height="520" rx="24" fill="url(#bg)"/>
|
|
17
|
+
<text x="70" y="70" font-family="Inter,Segoe UI,Arial,sans-serif" font-size="30" font-weight="700" fill="#f7f9fc">Developer Environment Journey</text>
|
|
18
|
+
<text x="70" y="102" font-family="Inter,Segoe UI,Arial,sans-serif" font-size="17" fill="#aebbd0">Start local. Add remote capability only when the project needs it.</text>
|
|
19
|
+
|
|
20
|
+
<g filter="url(#shadow)" font-family="Inter,Segoe UI,Arial,sans-serif">
|
|
21
|
+
<rect x="70" y="180" width="205" height="128" rx="18" fill="#1e2a40" stroke="#405274" stroke-width="2"/>
|
|
22
|
+
<text x="172" y="222" text-anchor="middle" font-size="15" font-weight="700" fill="#91a4c4">PROJECT</text>
|
|
23
|
+
<text x="172" y="254" text-anchor="middle" font-size="22" font-weight="700" fill="#ffffff">Generated POC</text>
|
|
24
|
+
<text x="172" y="282" text-anchor="middle" font-size="15" fill="#b8c5d8">clone + open workspace</text>
|
|
25
|
+
|
|
26
|
+
<rect x="360" y="180" width="205" height="128" rx="18" fill="#1f3440" stroke="#3b7584" stroke-width="2"/>
|
|
27
|
+
<text x="462" y="222" text-anchor="middle" font-size="15" font-weight="700" fill="#8bd2df">SETUP</text>
|
|
28
|
+
<text x="462" y="254" text-anchor="middle" font-size="24" font-weight="700" fill="#ffffff">/setup</text>
|
|
29
|
+
<text x="462" y="282" text-anchor="middle" font-size="15" fill="#b9dbe1">converge this computer</text>
|
|
30
|
+
|
|
31
|
+
<rect x="650" y="170" width="205" height="148" rx="18" fill="#173c35" stroke="#3a9d82" stroke-width="2"/>
|
|
32
|
+
<text x="752" y="216" text-anchor="middle" font-size="15" font-weight="700" fill="#79d9bc">LOCAL</text>
|
|
33
|
+
<text x="752" y="250" text-anchor="middle" font-size="24" font-weight="700" fill="#ffffff">READY</text>
|
|
34
|
+
<text x="752" y="280" text-anchor="middle" font-size="15" fill="#b7ded3">build • test • run</text>
|
|
35
|
+
<text x="752" y="302" text-anchor="middle" font-size="13" fill="#89bcae">valid stopping point</text>
|
|
36
|
+
|
|
37
|
+
<rect x="940" y="126" width="190" height="112" rx="18" fill="#3d3219" stroke="#b58b2e" stroke-width="2"/>
|
|
38
|
+
<text x="1035" y="166" text-anchor="middle" font-size="15" font-weight="700" fill="#e5bf65">STAGING</text>
|
|
39
|
+
<text x="1035" y="198" text-anchor="middle" font-size="23" font-weight="700" fill="#ffffff">READY</text>
|
|
40
|
+
<text x="1035" y="220" text-anchor="middle" font-size="13" fill="#ddc98e">optional remote capability</text>
|
|
41
|
+
|
|
42
|
+
<rect x="940" y="292" width="190" height="112" rx="18" fill="#3b2228" stroke="#b55a6f" stroke-width="2"/>
|
|
43
|
+
<text x="1035" y="332" text-anchor="middle" font-size="15" font-weight="700" fill="#ed8ca2">PRODUCTION</text>
|
|
44
|
+
<text x="1035" y="364" text-anchor="middle" font-size="23" font-weight="700" fill="#ffffff">READY</text>
|
|
45
|
+
<text x="1035" y="386" text-anchor="middle" font-size="13" fill="#ddb2bc">deployment still explicit</text>
|
|
46
|
+
</g>
|
|
47
|
+
|
|
48
|
+
<g stroke="#8ea0bd" stroke-width="3" fill="none" marker-end="url(#arrow)">
|
|
49
|
+
<path d="M275 244 H350"/>
|
|
50
|
+
<path d="M565 244 H640"/>
|
|
51
|
+
<path d="M855 226 C900 226 900 182 930 182"/>
|
|
52
|
+
<path d="M855 270 C900 270 900 348 930 348"/>
|
|
53
|
+
</g>
|
|
54
|
+
|
|
55
|
+
<text x="885" y="454" font-family="Inter,Segoe UI,Arial,sans-serif" font-size="14" fill="#8ea0bd">Remote capabilities are additive; they do not invalidate local readiness.</text>
|
|
56
|
+
</svg>
|