@mriekki/project-forge 4.1.0 → 4.2.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/assets/components.json +3 -3
- package/assets/deployment/distribution.json +1 -0
- package/assets/generated/ASSEMBLY.json +16 -11
- package/assets/generated/core/core/instructions/project-forge-workflow.instructions.md +3 -1
- package/assets/generated/core/core/skills/setup/SKILL.md +61 -0
- package/assets/generated/core/core/skills/upstream-fix/SKILL.md +137 -18
- package/assets/generated/deployment/docs/ENVIRONMENT_PROOF.md +26 -0
- package/assets/generated/deployment/src/project_forge_deployment/environment_probe.py +7 -0
- package/assets/generated/deployment/src/project_forge_deployment/environment_setup.py +106 -24
- package/assets/generated/deployment/src/project_forge_deployment/home_lab.py +22 -1
- package/assets/generated/deployment/src/project_forge_deployment/proof_receipt.py +183 -0
- package/assets/generated/deployment/src/project_forge_deployment/ssh.py +277 -23
- package/package.json +1 -1
package/assets/components.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": "@mriekki/project-forge",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.2.0",
|
|
5
5
|
"defaultProfile": "greenfield-project",
|
|
6
6
|
"profiles": {
|
|
7
7
|
"greenfield-project": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"components": {
|
|
15
15
|
"core": {
|
|
16
16
|
"repository": "mriekki/project-forge-core",
|
|
17
|
-
"commit": "
|
|
17
|
+
"commit": "d84829629d151c85bbe4680bc2297abfdf3a3022",
|
|
18
18
|
"version": "4.0.0",
|
|
19
19
|
"distribution": "greenfield-workspace",
|
|
20
20
|
"descriptor": "assets/core/distribution.json",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"deployment": {
|
|
25
25
|
"repository": "mriekki/project-forge-deployment-kit",
|
|
26
|
-
"commit": "
|
|
26
|
+
"commit": "e974c227d9d0768e64605550709db89ccaf93434",
|
|
27
27
|
"distribution": "greenfield-project",
|
|
28
28
|
"descriptor": "assets/deployment/distribution.json",
|
|
29
29
|
"sourceRoot": "assets/generated/deployment",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
{"source": "src/project_forge_deployment/profile_migration.py", "destination": "tools/project-forge-deployment/project_forge_deployment/profile_migration.py"},
|
|
32
32
|
{"source": "src/project_forge_deployment/profile_repository.py", "destination": "tools/project-forge-deployment/project_forge_deployment/profile_repository.py"},
|
|
33
33
|
{"source": "src/project_forge_deployment/profiles.py", "destination": "tools/project-forge-deployment/project_forge_deployment/profiles.py"},
|
|
34
|
+
{"source": "src/project_forge_deployment/proof_receipt.py", "destination": "tools/project-forge-deployment/project_forge_deployment/proof_receipt.py"},
|
|
34
35
|
{"source": "src/project_forge_deployment/registry_access.py", "destination": "tools/project-forge-deployment/project_forge_deployment/registry_access.py"},
|
|
35
36
|
{"source": "src/project_forge_deployment/registry_cli.py", "destination": "tools/project-forge-deployment/project_forge_deployment/registry_cli.py"},
|
|
36
37
|
{"source": "src/project_forge_deployment/route_registry.py", "destination": "tools/project-forge-deployment/project_forge_deployment/route_registry.py"},
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"package": "@mriekki/project-forge",
|
|
4
|
-
"version": "4.
|
|
4
|
+
"version": "4.2.0",
|
|
5
5
|
"components": {
|
|
6
6
|
"core": {
|
|
7
7
|
"repository": "mriekki/project-forge-core",
|
|
8
|
-
"commit": "
|
|
8
|
+
"commit": "d84829629d151c85bbe4680bc2297abfdf3a3022",
|
|
9
9
|
"version": "4.0.0",
|
|
10
10
|
"distribution": "greenfield-workspace",
|
|
11
11
|
"files": [
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
{
|
|
23
23
|
"source": "core/instructions/project-forge-workflow.instructions.md",
|
|
24
24
|
"destination": ".github/instructions/project-forge-workflow.instructions.md",
|
|
25
|
-
"sha256": "
|
|
25
|
+
"sha256": "85568ba56681831e34c63aa14f91702522a451e8b2fa883da631d609440d7a7c"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"source": "core/instructions/project-forge-docs.instructions.md",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
{
|
|
53
53
|
"source": "core/skills/setup/SKILL.md",
|
|
54
54
|
"destination": ".github/skills/setup/SKILL.md",
|
|
55
|
-
"sha256": "
|
|
55
|
+
"sha256": "deb64d0e7ce3a7788e5674182c9788219f2422468ed3e0cc767d49ce569acaea"
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
"source": "core/skills/build/SKILL.md",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
{
|
|
108
108
|
"source": "core/skills/upstream-fix/SKILL.md",
|
|
109
109
|
"destination": ".github/skills/upstream-fix/SKILL.md",
|
|
110
|
-
"sha256": "
|
|
110
|
+
"sha256": "cec11a112840b37a5ff61e28281d26eb9490e9d7b05df99ae5fa152231316798"
|
|
111
111
|
},
|
|
112
112
|
{
|
|
113
113
|
"source": "core/skills/wait-what/SKILL.md",
|
|
@@ -328,7 +328,7 @@
|
|
|
328
328
|
},
|
|
329
329
|
"deployment": {
|
|
330
330
|
"repository": "mriekki/project-forge-deployment-kit",
|
|
331
|
-
"commit": "
|
|
331
|
+
"commit": "e974c227d9d0768e64605550709db89ccaf93434",
|
|
332
332
|
"distribution": "greenfield-project",
|
|
333
333
|
"files": [
|
|
334
334
|
{
|
|
@@ -404,12 +404,12 @@
|
|
|
404
404
|
{
|
|
405
405
|
"source": "src/project_forge_deployment/environment_probe.py",
|
|
406
406
|
"destination": "tools/project-forge-deployment/project_forge_deployment/environment_probe.py",
|
|
407
|
-
"sha256": "
|
|
407
|
+
"sha256": "4e9a49a7cf0427dcdef1e28f955297569ec8cd0ee9d071404ef876e3ce036313"
|
|
408
408
|
},
|
|
409
409
|
{
|
|
410
410
|
"source": "src/project_forge_deployment/environment_setup.py",
|
|
411
411
|
"destination": "tools/project-forge-deployment/project_forge_deployment/environment_setup.py",
|
|
412
|
-
"sha256": "
|
|
412
|
+
"sha256": "a79919da8655a6c42fded3224373f6381d15c8c68869b70c31d6edb7702fd348"
|
|
413
413
|
},
|
|
414
414
|
{
|
|
415
415
|
"source": "src/project_forge_deployment/errors.py",
|
|
@@ -419,7 +419,7 @@
|
|
|
419
419
|
{
|
|
420
420
|
"source": "src/project_forge_deployment/home_lab.py",
|
|
421
421
|
"destination": "tools/project-forge-deployment/project_forge_deployment/home_lab.py",
|
|
422
|
-
"sha256": "
|
|
422
|
+
"sha256": "481b22ee7983dbe39b9e727ad874356a5dc4d55a4d7380545f2577e4a9ea45e7"
|
|
423
423
|
},
|
|
424
424
|
{
|
|
425
425
|
"source": "src/project_forge_deployment/image_transfer.py",
|
|
@@ -471,6 +471,11 @@
|
|
|
471
471
|
"destination": "tools/project-forge-deployment/project_forge_deployment/profiles.py",
|
|
472
472
|
"sha256": "c8fb1c378af9d39d28f46b300064bec967e2a6f7a13e22d089fc00413c42fd9d"
|
|
473
473
|
},
|
|
474
|
+
{
|
|
475
|
+
"source": "src/project_forge_deployment/proof_receipt.py",
|
|
476
|
+
"destination": "tools/project-forge-deployment/project_forge_deployment/proof_receipt.py",
|
|
477
|
+
"sha256": "9b4bbb559747fc4ee3ba984a050fc6425e532527ae82f9897c73e04d8d0291b6"
|
|
478
|
+
},
|
|
474
479
|
{
|
|
475
480
|
"source": "src/project_forge_deployment/registry_access.py",
|
|
476
481
|
"destination": "tools/project-forge-deployment/project_forge_deployment/registry_access.py",
|
|
@@ -519,7 +524,7 @@
|
|
|
519
524
|
{
|
|
520
525
|
"source": "src/project_forge_deployment/ssh.py",
|
|
521
526
|
"destination": "tools/project-forge-deployment/project_forge_deployment/ssh.py",
|
|
522
|
-
"sha256": "
|
|
527
|
+
"sha256": "88d59b62f63dc6b7206b6074dd109af4ea7c8f022f506e67f7204f1f06240d26"
|
|
523
528
|
},
|
|
524
529
|
{
|
|
525
530
|
"source": "src/project_forge_deployment/teardown.py",
|
|
@@ -554,7 +559,7 @@
|
|
|
554
559
|
{
|
|
555
560
|
"source": "docs/ENVIRONMENT_PROOF.md",
|
|
556
561
|
"destination": "docs/project-forge/ENVIRONMENT_PROOF.md",
|
|
557
|
-
"sha256": "
|
|
562
|
+
"sha256": "2ce7225ad6166a4ee30f51ea67ec077de0c29ce3a5c39b4ff57bf11cbe25e927"
|
|
558
563
|
},
|
|
559
564
|
{
|
|
560
565
|
"source": "docs/images/developer-environment-journey.svg",
|
|
@@ -34,7 +34,9 @@ For deployment readiness, inspect existing non-secret configuration before askin
|
|
|
34
34
|
|
|
35
35
|
Shared managed code keeps its canonical owner. When a consumer contains `CORE_BASELINE.json` or `DEPLOYMENT_BASELINE.json`, treat those baselines as ownership evidence. A temporary edit to a shared-managed consumer file may be used to diagnose or prove a reusable defect, but it is not the canonical deliverable.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
When reusable Project Forge drift is detected, distinguish unexplained drift from an explained temporary upstream proof. Unexplained managed drift remains fail-closed before delivery writes. For explained drift, route through `/upstream-fix`, preserve `.project-forge/UPSTREAM_FIX_HANDOFF.md`, and offer one explicit `Continue consumer work with acknowledged Project Forge drift` override when the current work can proceed without committing the managed workaround. That override is session/work-item continuation authority only; it does not authorize committing shared-managed paths, editing baselines, bypassing required CI/policy, or claiming that the canonical fix has been adopted.
|
|
38
|
+
|
|
39
|
+
After an accepted continuation override, do not repeatedly halt normal consumer implementation solely because the same documented managed workaround remains present. Keep the handoff and workaround unstaged. Before consumer `/deliver`, warn about the acknowledged drift, selectively stage only accepted consumer-owned changes, and disclose when local validation depended on the workaround. Required CI/policy remains authoritative. If the workaround is staged, appears in the proposed consumer commit/PR, no longer matches the handoff, or ownership becomes ambiguous, stop and re-evaluate.
|
|
38
40
|
|
|
39
41
|
Package-managed generated Projects use `/project-forge-update`. Direct `/core-sync` remains only for component-only Core consumers without `PROJECT_FORGE_BASELINE.json` and is not part of the normal greenfield Project command surface.
|
|
40
42
|
|
|
@@ -132,6 +132,8 @@ When application source/runtime exists, converge only the repository-owned local
|
|
|
132
132
|
|
|
133
133
|
Verify supported tools/versions using repository setup/doctor tooling when present. Run repository-defined dependency restore/setup commands when missing or stale. Preserve pinned versions and project conventions.
|
|
134
134
|
|
|
135
|
+
Treat **installation**, **version compatibility**, and **operational readiness** as separate evidence when tooling exposes those distinctions. A successful CLI/version probe does not prove that the backing service/runtime is operational. For Docker-based setup, do not call the runtime ready merely because `docker --version` succeeds; require the repository/doctor operational probe before relying on Docker Engine capability.
|
|
136
|
+
|
|
135
137
|
### B. Local persistence
|
|
136
138
|
|
|
137
139
|
For SQLite local development, resolve the project-owned database path and migration/initialization contract from repository evidence. Prefer installed Deployment Kit local SQLite ensure/status primitives when available.
|
|
@@ -244,6 +246,63 @@ For remote SSH preserve strict host identity. Unknown/changed host identity is a
|
|
|
244
246
|
|
|
245
247
|
Remote readiness does not require configuring Production when the selected environment is non-Production. Production classification remains project topology/policy, not a literal-name check.
|
|
246
248
|
|
|
249
|
+
### Guided remote failure recovery is part of `/setup`
|
|
250
|
+
|
|
251
|
+
A supported deterministic setup/readiness failure is not, by itself, the end of `/setup`. When installed Deployment Kit tooling returns structured diagnosis or a bounded next action, continue through that diagnosis automatically until one of these boundaries is reached:
|
|
252
|
+
|
|
253
|
+
- the failure is repaired through already-authorized routine setup work;
|
|
254
|
+
- a missing human fact is required;
|
|
255
|
+
- a separate write/Production/destructive authorization is required;
|
|
256
|
+
- a trusted-console or already-authorized administrative action is required;
|
|
257
|
+
- the capability is unsupported or remains blocked after bounded diagnosis.
|
|
258
|
+
|
|
259
|
+
Do **not** merely repeat an opaque subprocess exit code and tell the developer to fix access independently when deterministic diagnosis is available.
|
|
260
|
+
|
|
261
|
+
For SSH target-access failure, prefer the Deployment Kit's structured environment setup status/plan evidence. Preserve distinct categories such as:
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
name resolution / address path
|
|
265
|
+
TCP reachability
|
|
266
|
+
host identity/trust
|
|
267
|
+
server-advertised authentication methods
|
|
268
|
+
configured identity fingerprint/offered key
|
|
269
|
+
local signing/passphrase/agent failure
|
|
270
|
+
remote public-key rejection
|
|
271
|
+
remote account/source-policy rejection
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
Keep credentials, private keys, raw secure-prompt content, and unbounded SSH transcripts out of conversational diagnostics and journals.
|
|
275
|
+
|
|
276
|
+
If client-side evidence shows that the configured key reached the server but access is still rejected, stop reinstalling the same key. Route to a trusted target console or already-authorized administrative session to inspect effective account/source policy. Do not guess that `AllowUsers`, `AllowGroups`, PAM, or another server rule is the exact cause until server-side evidence establishes it.
|
|
277
|
+
|
|
278
|
+
### Gate password-assisted bootstrap on server capability
|
|
279
|
+
|
|
280
|
+
Before recommending a password-assisted/Home Lab bootstrap against a reachable server, use deterministic evidence of the server-advertised authentication methods when the installed Deployment Kit supports that probe.
|
|
281
|
+
|
|
282
|
+
- If password or keyboard-interactive authentication is not advertised, do not send the developer through a password bootstrap that cannot succeed.
|
|
283
|
+
- Route instead to strict key onboarding plus a trusted console/already-authorized session for any required server-side key/account-policy change.
|
|
284
|
+
- Never recommend enabling password SSH merely to make Project Forge onboarding work.
|
|
285
|
+
|
|
286
|
+
For Production-class environments, prefer the higher-assurance Strict onboarding path for new target trust/access unless the project/operator explicitly chooses a different supported security profile. Staging and other non-Production environments use the same target-access mechanics, with their own environment classification and authorization policy.
|
|
287
|
+
|
|
288
|
+
### Console-assisted recovery instructions
|
|
289
|
+
|
|
290
|
+
When a trusted-console action is required, optimize for reliable execution rather than dense shell snippets:
|
|
291
|
+
|
|
292
|
+
- one short command or one coherent semicolon-separated command per step;
|
|
293
|
+
- avoid unnecessary wildcards, escaping, and shell-specific quoting;
|
|
294
|
+
- say explicitly what the developer should run versus what output to return;
|
|
295
|
+
- state the expected evidence and the stop condition;
|
|
296
|
+
- use screenshot inspection when transcription is repeatedly failing.
|
|
297
|
+
|
|
298
|
+
Never silently edit `sshd`, widen account/source policy, disable host verification, or switch authentication policy merely to make setup pass.
|
|
299
|
+
|
|
300
|
+
### Treat target evidence and environment evidence separately
|
|
301
|
+
|
|
302
|
+
A verified workstation-to-target access relationship may be reused by multiple Projects/environments that bind to the same logical target. Environment proof remains specific to the Project + named environment + target + adapter/isolation contract.
|
|
303
|
+
|
|
304
|
+
When Staging and Production share one physical target, explicitly surface the shared failure domain and verify that their Project/environment-owned runtime identity, compose project, route/port allocation, persistence paths, and locking cannot collide. Staging evidence does not become Production evidence merely because the host is shared.
|
|
305
|
+
|
|
247
306
|
## 8. Prove supported remote mechanics with a disposable Project Forge probe
|
|
248
307
|
|
|
249
308
|
When the installed Deployment Kit exposes environment proof operations, a selected remote environment should normally be taken through an end-to-end **environment proof deployment** during setup.
|
|
@@ -276,6 +335,8 @@ For a Production-class environment, keep the proof explicitly labeled as a **PRO
|
|
|
276
335
|
|
|
277
336
|
If cleanup fails, report `PROOF PASSED — CLEANUP ACTION NEEDED`; do not claim a clean setup.
|
|
278
337
|
|
|
338
|
+
When installed Deployment Kit provides a durable local proof receipt or equivalent discoverable evidence, record/reuse it rather than relying on chat history. Reuse only while its target binding, host identity, workstation identity, adapter/provenance, logical environment, and cleanup result remain applicable. A new chat alone must not invalidate valid machine evidence.
|
|
339
|
+
|
|
279
340
|
## 9. `repair` is bounded and fail-closed
|
|
280
341
|
|
|
281
342
|
`/setup repair` may re-run safe deterministic setup/readiness operations after classifying the blocker. It may create missing local directories/caches, restore dependencies, rebuild outputs, create a new owned local database, run normal forward initialization, or recreate an owned disposable/local runtime when the repository contract permits those actions.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: upstream-fix
|
|
3
|
-
description: Route reusable bugs discovered in a consumer to the canonical shared repository, allow bounded upstream implementation,
|
|
3
|
+
description: Route reusable bugs discovered in a consumer to the canonical shared repository, allow bounded upstream implementation, preserve a portable handoff, and let consumer work continue with explicitly acknowledged temporary Project Forge drift.
|
|
4
4
|
argument-hint: "[optional problem summary]"
|
|
5
5
|
user-invocable: true
|
|
6
6
|
disable-model-invocation: true
|
|
@@ -15,8 +15,10 @@ The governing rule is:
|
|
|
15
15
|
```text
|
|
16
16
|
discover in consumer
|
|
17
17
|
→ diagnose/prove in consumer
|
|
18
|
-
→
|
|
19
|
-
→
|
|
18
|
+
→ classify canonical owner
|
|
19
|
+
→ preserve a portable upstream handoff
|
|
20
|
+
→ optionally continue consumer work with acknowledged temporary drift
|
|
21
|
+
→ fix/deliver in owning canonical repository
|
|
20
22
|
→ adopt through the consumer's recorded distribution boundary
|
|
21
23
|
→ verify again in consumer
|
|
22
24
|
```
|
|
@@ -29,10 +31,11 @@ Invoking `/upstream-fix` authorizes:
|
|
|
29
31
|
|
|
30
32
|
- read-only ownership/provenance inspection in the consumer;
|
|
31
33
|
- classification to the smallest canonical owner;
|
|
34
|
+
- creation/update of the ignored local handoff artifact `.project-forge/UPSTREAM_FIX_HANDOFF.md`;
|
|
32
35
|
- inspection of already-available local canonical repository candidates;
|
|
33
36
|
- when ownership and the bounded patch are clear and a canonical checkout is safe, routine creation/use of one short-lived canonical work branch and application of only that bounded fix plus focused tests/docs.
|
|
34
37
|
|
|
35
|
-
Invocation does **not** authorize commit, push, PR creation, merge, release publication, package publication, deployment, rewriting/discarding consumer work,
|
|
38
|
+
Invocation does **not** authorize commit, push, PR creation, merge, release publication, package publication, deployment, rewriting/discarding consumer work, changing multiple canonical repositories in one bounded fix, or committing a temporary shared-managed consumer workaround.
|
|
36
39
|
|
|
37
40
|
Normal review and `/deliver` occur later while focused on the owning canonical repository.
|
|
38
41
|
|
|
@@ -99,7 +102,7 @@ Owner: package/platform repository supported by evidence
|
|
|
99
102
|
|
|
100
103
|
If the package payload is correct but generation/publication/orchestration materializes it incorrectly, classify Bootstrap/control-plane ownership from evidence rather than patching a generated consumer.
|
|
101
104
|
|
|
102
|
-
If ownership is genuinely ambiguous,
|
|
105
|
+
If ownership is genuinely ambiguous, report `UPSTREAM OWNER UNCLEAR`. Preserve the observed evidence in the handoff artifact, but do not write to multiple repositories speculatively.
|
|
103
106
|
|
|
104
107
|
## 4. Temporary consumer proof
|
|
105
108
|
|
|
@@ -111,12 +114,95 @@ Report it explicitly:
|
|
|
111
114
|
TEMPORARY SHARED-MANAGED PROOF
|
|
112
115
|
Consumer path: <path>
|
|
113
116
|
Canonical owner: <repo>
|
|
114
|
-
Do not deliver this consumer copy.
|
|
117
|
+
Do not deliver this consumer copy as product code.
|
|
115
118
|
```
|
|
116
119
|
|
|
117
120
|
Do not silently discard the proof and do not stage/commit it as ordinary consumer implementation.
|
|
118
121
|
|
|
119
|
-
## 5.
|
|
122
|
+
## 5. Preserve a portable handoff
|
|
123
|
+
|
|
124
|
+
Once a likely shared owner exists, create or refresh:
|
|
125
|
+
|
|
126
|
+
```text
|
|
127
|
+
.project-forge/UPSTREAM_FIX_HANDOFF.md
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This file is workstation/session evidence for transfer into ChatGPT or another canonical-owner workspace. It is not product documentation and must remain unstaged/uncommitted. Generated Project Forge projects normally ignore `.project-forge/`; if repository policy does not ignore it, keep the handoff out of the consumer delivery diff.
|
|
131
|
+
|
|
132
|
+
Include only observed/non-secret evidence:
|
|
133
|
+
|
|
134
|
+
```markdown
|
|
135
|
+
# Project Forge Upstream Fix Handoff
|
|
136
|
+
|
|
137
|
+
## Consumer context
|
|
138
|
+
- Repository: <owner/repo or local identity>
|
|
139
|
+
- Branch/work item: <observed>
|
|
140
|
+
- Project Forge package/baseline: <observed version/commit/profile>
|
|
141
|
+
|
|
142
|
+
## Classification
|
|
143
|
+
- Owner: <Core | Deployment Kit | Platform | Bootstrap | Control Plane | unclear>
|
|
144
|
+
- Canonical repository: <repo when known>
|
|
145
|
+
- Managed consumer paths involved: <paths>
|
|
146
|
+
|
|
147
|
+
## Problem
|
|
148
|
+
<concise symptom and expected behavior>
|
|
149
|
+
|
|
150
|
+
## Reproduction
|
|
151
|
+
<minimal observed reproduction>
|
|
152
|
+
|
|
153
|
+
## Temporary consumer proof
|
|
154
|
+
- Status: <none | local proof present>
|
|
155
|
+
- Paths: <paths>
|
|
156
|
+
- Diff summary: <summary, not secrets>
|
|
157
|
+
- Validation: <observed checks>
|
|
158
|
+
|
|
159
|
+
## Recommended upstream scope
|
|
160
|
+
<smallest reusable change and focused regression coverage>
|
|
161
|
+
|
|
162
|
+
## Adoption boundary
|
|
163
|
+
<package release / component sync / regeneration / other evidence-backed path>
|
|
164
|
+
|
|
165
|
+
## Consumer continuation
|
|
166
|
+
- Override: <not requested | accepted>
|
|
167
|
+
- Managed workaround must remain unstaged/uncommitted: yes
|
|
168
|
+
- Known dependency of current consumer checks on workaround: <yes/no/unknown>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
The handoff is useful even when a canonical checkout is unavailable or the upstream fix will be handled later.
|
|
172
|
+
|
|
173
|
+
## 6. Consumer continuation override
|
|
174
|
+
|
|
175
|
+
A reusable-platform defect is **not automatically a reason to halt the consumer work item**.
|
|
176
|
+
|
|
177
|
+
After classification/handoff, when the current consumer work can still proceed without committing the temporary shared-managed workaround, present one bounded single-select choice through the host-native question UI when available:
|
|
178
|
+
|
|
179
|
+
- `Continue consumer work with acknowledged Project Forge drift` — permits the current consumer session/work item to continue while the shared-managed workaround remains local and excluded from delivery. **RECOMMENDED** when the workaround is isolated and continuing will produce useful consumer-owned work.
|
|
180
|
+
- `Resolve the upstream fix now` — switch focus to the canonical owner and continue the upstream workflow.
|
|
181
|
+
- `Stop here` — preserve state without further writes.
|
|
182
|
+
|
|
183
|
+
Use a numbered text list only when native structured choice UI is unavailable.
|
|
184
|
+
|
|
185
|
+
Selecting the continuation option means:
|
|
186
|
+
|
|
187
|
+
```text
|
|
188
|
+
PROJECT FORGE DRIFT OVERRIDE ACCEPTED
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Record that choice in `.project-forge/UPSTREAM_FIX_HANDOFF.md` and continue normal consumer implementation. Do not repeatedly ask the same override question in the same unchanged session/work-item state.
|
|
192
|
+
|
|
193
|
+
The override authorizes **continuation only**. It does not authorize:
|
|
194
|
+
|
|
195
|
+
- staging/committing/pushing shared-managed drift;
|
|
196
|
+
- editing baselines to bless the drift;
|
|
197
|
+
- bypassing required CI, Reviewer, merge, release, or Production gates;
|
|
198
|
+
- destructive cleanup of the workaround;
|
|
199
|
+
- claiming the consumer has adopted the canonical fix.
|
|
200
|
+
|
|
201
|
+
If consumer-owned implementation genuinely cannot be separated from the modified managed file, report that dependency clearly. The human may still continue exploratory/product work under the override, but normal delivery can only stage consumer-owned paths and required CI/policy may still fail until the upstream fix is distributed.
|
|
202
|
+
|
|
203
|
+
Unexplained managed drift, suspected secrets, ambiguous ownership, or a staged/shared-managed workaround remains a stop condition until classified or removed from the proposed consumer delivery scope.
|
|
204
|
+
|
|
205
|
+
## 7. Resolve a safe canonical checkout
|
|
120
206
|
|
|
121
207
|
For the classified owner consider, in order:
|
|
122
208
|
|
|
@@ -128,7 +214,9 @@ Do not broadly scan the filesystem and do not clone automatically merely to cont
|
|
|
128
214
|
|
|
129
215
|
A candidate is safe only when it is the expected repository, has no merge/rebase/cherry-pick in progress, has no unrelated local work, and does not require stash/reset/rebase/force/discard operations.
|
|
130
216
|
|
|
131
|
-
|
|
217
|
+
If no safe canonical checkout is available, the handoff plus continuation override is a valid outcome; do not block consumer implementation solely because canonical work cannot start immediately.
|
|
218
|
+
|
|
219
|
+
## 8. Port the bounded fix upstream
|
|
132
220
|
|
|
133
221
|
When a safe canonical checkout exists and the equivalent reusable fix is clear:
|
|
134
222
|
|
|
@@ -141,9 +229,9 @@ When a safe canonical checkout exists and the equivalent reusable fix is clear:
|
|
|
141
229
|
7. run relevant local checks;
|
|
142
230
|
8. show the meaningful canonical diff and observed validation.
|
|
143
231
|
|
|
144
|
-
If the consumer proof cannot be generalized safely,
|
|
232
|
+
If the consumer proof cannot be generalized safely, reclassify and update the handoff rather than forcing it upstream.
|
|
145
233
|
|
|
146
|
-
##
|
|
234
|
+
## 9. Handoff to canonical delivery
|
|
147
235
|
|
|
148
236
|
When the upstream implementation is ready:
|
|
149
237
|
|
|
@@ -153,13 +241,16 @@ UPSTREAM FIX READY
|
|
|
153
241
|
Owner: <canonical repo>
|
|
154
242
|
Branch: <branch>
|
|
155
243
|
Consumer proof: <path/status>
|
|
244
|
+
Portable handoff: .project-forge/UPSTREAM_FIX_HANDOFF.md
|
|
156
245
|
Validation: <observed checks>
|
|
157
246
|
Next: focus the canonical repository and run /deliver
|
|
158
247
|
```
|
|
159
248
|
|
|
160
249
|
`/upstream-fix` does not commit/push/open/merge the canonical PR itself.
|
|
161
250
|
|
|
162
|
-
|
|
251
|
+
If the consumer continuation override was accepted, returning to consumer work does not wait for canonical delivery unless current work truly requires the distributed fix.
|
|
252
|
+
|
|
253
|
+
## 10. Adopt the accepted fix through the right boundary
|
|
163
254
|
|
|
164
255
|
After the canonical PR is merged and required default-branch CI is green, re-read the consumer provenance before choosing adoption.
|
|
165
256
|
|
|
@@ -182,7 +273,8 @@ Until that package exists, report:
|
|
|
182
273
|
|
|
183
274
|
```text
|
|
184
275
|
PACKAGE RELEASE REQUIRED
|
|
185
|
-
|
|
276
|
+
Canonical consumer adoption requires a Project Forge package that contains the accepted upstream commit.
|
|
277
|
+
Consumer work may continue under an accepted drift override as long as shared-managed workaround paths remain outside consumer delivery.
|
|
186
278
|
```
|
|
187
279
|
|
|
188
280
|
Do not silently patch `PROJECT_FORGE_BASELINE.json`, `CORE_BASELINE.json`, or `DEPLOYMENT_BASELINE.json` to pretend the package contains the new component.
|
|
@@ -199,15 +291,40 @@ A Deployment-owned fix may return through the canonical Deployment Kit component
|
|
|
199
291
|
|
|
200
292
|
Validate through that platform's canonical regeneration/update path, never by manually editing generated managed files.
|
|
201
293
|
|
|
202
|
-
Then rerun the original reproduction and baseline checks in the consumer.
|
|
294
|
+
Then rerun the original reproduction and baseline checks in the consumer when adoption actually occurs.
|
|
295
|
+
|
|
296
|
+
## 11. Consumer delivery guard
|
|
297
|
+
|
|
298
|
+
Before consumer `/deliver`, distinguish **unexplained managed drift** from **explained/acknowledged temporary upstream proof**.
|
|
299
|
+
|
|
300
|
+
### Unexplained managed drift
|
|
301
|
+
|
|
302
|
+
If `/deliver` finds Core-, Deployment-, or Project Forge-package-managed drift with no matching upstream classification/handoff/override, stop before staging/commit/push and route through `/upstream-fix`.
|
|
303
|
+
|
|
304
|
+
### Explained drift with accepted continuation override
|
|
203
305
|
|
|
204
|
-
|
|
306
|
+
When `.project-forge/UPSTREAM_FIX_HANDOFF.md` records the current managed paths and the human accepted continuation for the unchanged issue:
|
|
307
|
+
|
|
308
|
+
1. warn prominently that Project Forge managed drift is still present;
|
|
309
|
+
2. keep all shared-managed drift and the handoff file unstaged/uncommitted;
|
|
310
|
+
3. selectively stage only the human-accepted consumer-owned implementation;
|
|
311
|
+
4. disclose in the PR body that local validation may have used an acknowledged Project Forge workaround when that is true;
|
|
312
|
+
5. proceed with normal PR/CI mechanics rather than hard-stopping solely because the local workaround exists.
|
|
313
|
+
|
|
314
|
+
Use a compact warning such as:
|
|
315
|
+
|
|
316
|
+
```text
|
|
317
|
+
PROJECT FORGE DRIFT WARNING
|
|
318
|
+
Upstream handoff: .project-forge/UPSTREAM_FIX_HANDOFF.md
|
|
319
|
+
Managed workaround: present locally, excluded from consumer delivery
|
|
320
|
+
Consumer delivery: continuing under accepted override
|
|
321
|
+
```
|
|
205
322
|
|
|
206
|
-
|
|
323
|
+
Required CI/policy remains authoritative. Do not waive a failing required check because the failure is caused by the absent upstream fix.
|
|
207
324
|
|
|
208
|
-
|
|
325
|
+
If any shared-managed path is already staged, appears in the proposed consumer commit/PR, no longer matches the handoff, or ownership becomes ambiguous, stop and re-evaluate before writing.
|
|
209
326
|
|
|
210
|
-
##
|
|
327
|
+
## 12. Boundaries
|
|
211
328
|
|
|
212
329
|
`/upstream-fix` never:
|
|
213
330
|
|
|
@@ -218,4 +335,6 @@ Consumer-owned changes may be delivered normally when managed baselines are clea
|
|
|
218
335
|
- auto-stashes, resets, rebases, force-pushes, or discards work;
|
|
219
336
|
- requires ordinary consumer users to clone shared repositories;
|
|
220
337
|
- treats a temporary managed consumer edit as a permanent fork;
|
|
221
|
-
- bypasses `PROJECT_FORGE_BASELINE.json` with component-only sync
|
|
338
|
+
- bypasses `PROJECT_FORGE_BASELINE.json` with component-only sync;
|
|
339
|
+
- treats the continuation override as authorization to commit shared-managed drift;
|
|
340
|
+
- treats the continuation override as a waiver of required CI or merge policy.
|
|
@@ -56,6 +56,8 @@ project-forge-deploy environment setup plan <target> \
|
|
|
56
56
|
|
|
57
57
|
These commands never perform the proof or authorize a write. They make `TARGET ACCESS READY`, `HOST PLATFORM READY`, and `DEPLOYMENT PATH PROVEN` separate states.
|
|
58
58
|
|
|
59
|
+
When owner/repository and logical environment context are supplied, setup planning also checks the current workstation for a still-applicable prior proof receipt before recommending another proof run.
|
|
60
|
+
|
|
59
61
|
## Commands
|
|
60
62
|
|
|
61
63
|
Read-only plan:
|
|
@@ -120,6 +122,8 @@ mutated
|
|
|
120
122
|
finalMutationState
|
|
121
123
|
error
|
|
122
124
|
cleanupError
|
|
125
|
+
receipt
|
|
126
|
+
receiptError
|
|
123
127
|
```
|
|
124
128
|
|
|
125
129
|
A read-only plan does not claim `mutated: false` as though it were the eventual run result. The run reports whether transfer/runtime mutation actually occurred and whether cleanup completed.
|
|
@@ -136,6 +140,28 @@ A loaded Docker image may remain cached after runtime cleanup. That state is rep
|
|
|
136
140
|
|
|
137
141
|
The probe must not delete another Project, another application, another logical environment, or shared host platform state.
|
|
138
142
|
|
|
143
|
+
## Workstation-local proof receipt
|
|
144
|
+
|
|
145
|
+
Every terminal proof run attempts to write a compact workstation-local proof receipt under the user's Project Forge evidence directory. The receipt is diagnostic/readiness evidence only; it is not deployment authorization and is not repository content.
|
|
146
|
+
|
|
147
|
+
The receipt records only non-secret evidence needed to decide whether the prior proof is still applicable, including:
|
|
148
|
+
|
|
149
|
+
- Project owner/repository;
|
|
150
|
+
- exact logical environment;
|
|
151
|
+
- logical target name and Production classification;
|
|
152
|
+
- Deployment Kit/proof contract version;
|
|
153
|
+
- proof/cleanup/final mutation state;
|
|
154
|
+
- immutable probe artifact identities when available;
|
|
155
|
+
- a hash-based signature of the current target profile, configured workstation identity fingerprint, and target trust file.
|
|
156
|
+
|
|
157
|
+
It never stores private keys, passwords, tokens, known-host contents, or application secrets.
|
|
158
|
+
|
|
159
|
+
`environment setup plan` treats the receipt as `PROVEN` only when the latest receipt passed with terminal cleanup and still matches the current Project/environment/target context and current workstation target identity/trust. A target/profile/trust change, Production-classification change, proof-contract change, or Deployment Kit version change makes the evidence stale and causes a new proof to be planned.
|
|
160
|
+
|
|
161
|
+
A **new chat or new assistant session alone does not invalidate proof**. Evidence validity is based on machine/project/environment facts, not conversation history.
|
|
162
|
+
|
|
163
|
+
A failed proof may also leave a receipt, but that receipt is explicitly `not-proven` and is never promoted to readiness.
|
|
164
|
+
|
|
139
165
|
## Relationship to `/setup` and `/deploy`
|
|
140
166
|
|
|
141
167
|
`/setup remote` or `/setup <environment>` may use deterministic setup status/plan first, then run this proof after the developer selects the named remote environment and the relevant write authorization is granted.
|
|
@@ -14,6 +14,7 @@ from .app_runtime_workstation import apply_app_deploy_with_preloaded_image
|
|
|
14
14
|
from .box_platform import platform_status
|
|
15
15
|
from .errors import DeploymentKitError
|
|
16
16
|
from .image_transfer import remote_image_present, transfer_image, verify_local_image
|
|
17
|
+
from .proof_receipt import write_environment_proof_receipt
|
|
17
18
|
from .registry_access import normalize_registry_image
|
|
18
19
|
from .teardown import tear_down_project
|
|
19
20
|
|
|
@@ -152,6 +153,8 @@ def _proof_result(plan: dict[str, Any]) -> dict[str, Any]:
|
|
|
152
153
|
"finalMutationState": "none",
|
|
153
154
|
"error": None,
|
|
154
155
|
"cleanupError": None,
|
|
156
|
+
"receipt": None,
|
|
157
|
+
"receiptError": None,
|
|
155
158
|
}
|
|
156
159
|
|
|
157
160
|
|
|
@@ -298,4 +301,8 @@ def run_environment_proof(plan: dict[str, Any]) -> dict[str, Any]:
|
|
|
298
301
|
result["error"] = "Environment proof cleanup did not return terminal runtime cleanup evidence."
|
|
299
302
|
|
|
300
303
|
result["finalMutationState"] = _final_mutation_state(result)
|
|
304
|
+
try:
|
|
305
|
+
result["receipt"] = write_environment_proof_receipt(result)
|
|
306
|
+
except Exception as error: # proof result stays truthful even if local evidence persistence fails
|
|
307
|
+
result["receiptError"] = str(error)
|
|
301
308
|
return result
|