@opengsd/gsd-path 1.6.2 → 1.7.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/CHANGELOG.md +21 -0
- package/DOCS.md +27 -1
- package/FULL.md +2 -1
- package/HOOKS.md +38 -4
- package/QUICK.md +1 -1
- package/README.md +19 -11
- package/RUNTIME.md +5 -3
- package/WORKFLOW.md +9 -2
- package/package.json +1 -1
- package/scripts/_common.py +76 -2
- package/scripts/archive_milestone.py +129 -7
- package/scripts/build_recovery.py +25 -2
- package/scripts/build_state.py +333 -8
- package/scripts/check_handoffs.py +437 -30
- package/scripts/check_task_briefs.py +135 -11
- package/scripts/discussion_validate.py +46 -10
- package/scripts/dispatch_driver.py +28 -3
- package/scripts/git_guard.py +44 -4
- package/scripts/guard_hook.py +456 -9
- package/scripts/install.py +34 -4
- package/scripts/integration.py +196 -39
- package/scripts/isolation.py +996 -38
- package/scripts/lean_verification.py +28 -13
- package/scripts/loop_run.py +9 -4
- package/scripts/members.py +17 -3
- package/scripts/pipeline_diagnose.py +104 -1
- package/scripts/pipeline_state.py +10 -2
- package/scripts/runtime_store.py +88 -3
- package/scripts/state_checkpoint.py +15 -0
- package/scripts/status_runtime.py +73 -2
- package/scripts/workflow_run.py +10 -3
- package/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path/BUILD.md +3 -1
- package/skills/gsd-path/DEFINE.md +2 -1
- package/skills/gsd-path/PLAN.md +10 -0
- package/skills/gsd-path/SHIP.md +41 -8
- package/skills/gsd-path/SKILL.md +16 -1
- package/skills/gsd-path/references/build-native.md +20 -3
- package/skills/gsd-path/references/coder.md +6 -3
- package/skills/gsd-path/references/reviewer-final.md +10 -0
- package/skills/gsd-path/references/reviewer-wave.md +61 -22
- package/skills/gsd-path/references/reviewer.md +8 -6
- package/skills/gsd-path/references/runtime-selection.md +36 -0
- package/skills/gsd-path/references/spec-probes.md +19 -1
- package/skills/gsd-path/scripts/_common.py +76 -2
- package/skills/gsd-path/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path/scripts/build_recovery.py +25 -2
- package/skills/gsd-path/scripts/build_state.py +333 -8
- package/skills/gsd-path/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path/scripts/dispatch_driver.py +28 -3
- package/skills/gsd-path/scripts/git_guard.py +44 -4
- package/skills/gsd-path/scripts/integration.py +196 -39
- package/skills/gsd-path/scripts/isolation.py +996 -38
- package/skills/gsd-path/scripts/lean_verification.py +28 -13
- package/skills/gsd-path/scripts/loop_run.py +9 -4
- package/skills/gsd-path/scripts/members.py +17 -3
- package/skills/gsd-path/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path/scripts/status_runtime.py +73 -2
- package/skills/gsd-path/scripts/workflow_run.py +10 -3
- package/skills/gsd-path/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path/templates/intent.md +5 -3
- package/skills/gsd-path/templates/task.md +8 -1
- package/skills/gsd-path/templates/wave-review.md +24 -8
- package/skills/gsd-path-build/SKILL.md +3 -1
- package/skills/gsd-path-build/references/build-native.md +20 -3
- package/skills/gsd-path-build/references/coder.md +6 -3
- package/skills/gsd-path-build/references/reviewer-final.md +10 -0
- package/skills/gsd-path-build/references/reviewer-wave.md +61 -22
- package/skills/gsd-path-build/references/reviewer.md +8 -6
- package/skills/gsd-path-build/references/runtime-selection.md +36 -0
- package/skills/gsd-path-build/references/spec-probes.md +19 -1
- package/skills/gsd-path-build/scripts/_common.py +76 -2
- package/skills/gsd-path-build/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-build/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-build/scripts/build_state.py +333 -8
- package/skills/gsd-path-build/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-build/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-build/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-build/scripts/dispatch_driver.py +28 -3
- package/skills/gsd-path-build/scripts/integration.py +196 -39
- package/skills/gsd-path-build/scripts/isolation.py +996 -38
- package/skills/gsd-path-build/scripts/loop_run.py +9 -4
- package/skills/gsd-path-build/scripts/members.py +17 -3
- package/skills/gsd-path-build/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-build/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-build/scripts/workflow_run.py +10 -3
- package/skills/gsd-path-build/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-build/templates/task.md +8 -1
- package/skills/gsd-path-build/templates/wave-review.md +24 -8
- package/skills/gsd-path-decide/references/runtime-selection.md +36 -0
- package/skills/gsd-path-decide/scripts/_common.py +76 -2
- package/skills/gsd-path-decide/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-decide/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-decide/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-decide/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-decide/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-decide/scripts/integration.py +196 -39
- package/skills/gsd-path-decide/scripts/isolation.py +996 -38
- package/skills/gsd-path-decide/scripts/loop_run.py +9 -4
- package/skills/gsd-path-decide/scripts/members.py +17 -3
- package/skills/gsd-path-decide/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-decide/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-decide/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-define/SKILL.md +2 -1
- package/skills/gsd-path-define/references/runtime-selection.md +36 -0
- package/skills/gsd-path-define/references/spec-probes.md +19 -1
- package/skills/gsd-path-define/scripts/_common.py +76 -2
- package/skills/gsd-path-define/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-define/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-define/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-define/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-define/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-define/scripts/integration.py +196 -39
- package/skills/gsd-path-define/scripts/isolation.py +996 -38
- package/skills/gsd-path-define/scripts/loop_run.py +9 -4
- package/skills/gsd-path-define/scripts/members.py +17 -3
- package/skills/gsd-path-define/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-define/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-define/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-define/templates/intent.md +5 -3
- package/skills/gsd-path-discuss/references/runtime-selection.md +36 -0
- package/skills/gsd-path-discuss/scripts/_common.py +76 -2
- package/skills/gsd-path-discuss/scripts/loop_run.py +9 -4
- package/skills/gsd-path-discuss/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-docs-audit/references/runtime-selection.md +36 -0
- package/skills/gsd-path-docs-audit/scripts/_common.py +76 -2
- package/skills/gsd-path-docs-audit/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-docs-audit/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-docs-audit/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-docs-audit/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-docs-audit/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-docs-audit/scripts/integration.py +196 -39
- package/skills/gsd-path-docs-audit/scripts/isolation.py +996 -38
- package/skills/gsd-path-docs-audit/scripts/loop_run.py +9 -4
- package/skills/gsd-path-docs-audit/scripts/members.py +17 -3
- package/skills/gsd-path-docs-audit/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-docs-audit/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-docs-audit/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-forensics/references/runtime-selection.md +36 -0
- package/skills/gsd-path-forensics/scripts/_common.py +76 -2
- package/skills/gsd-path-forensics/scripts/loop_run.py +9 -4
- package/skills/gsd-path-forensics/scripts/pipeline_diagnose.py +104 -1
- package/skills/gsd-path-forensics/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-inspect/references/runtime-selection.md +36 -0
- package/skills/gsd-path-inspect/scripts/_common.py +76 -2
- package/skills/gsd-path-inspect/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-inspect/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-inspect/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-inspect/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-inspect/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-inspect/scripts/integration.py +196 -39
- package/skills/gsd-path-inspect/scripts/isolation.py +996 -38
- package/skills/gsd-path-inspect/scripts/loop_run.py +9 -4
- package/skills/gsd-path-inspect/scripts/members.py +17 -3
- package/skills/gsd-path-inspect/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-inspect/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-inspect/scripts/workflow_run.py +10 -3
- package/skills/gsd-path-inspect/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-loop/references/runtime-selection.md +36 -0
- package/skills/gsd-path-loop/scripts/_common.py +76 -2
- package/skills/gsd-path-loop/scripts/loop_run.py +9 -4
- package/skills/gsd-path-loop/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-migrate/references/runtime-selection.md +36 -0
- package/skills/gsd-path-migrate/scripts/_common.py +76 -2
- package/skills/gsd-path-migrate/scripts/loop_run.py +9 -4
- package/skills/gsd-path-plan/SKILL.md +10 -0
- package/skills/gsd-path-plan/references/runtime-selection.md +36 -0
- package/skills/gsd-path-plan/references/spec-probes.md +19 -1
- package/skills/gsd-path-plan/scripts/_common.py +76 -2
- package/skills/gsd-path-plan/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-plan/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-plan/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-plan/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-plan/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-plan/scripts/integration.py +196 -39
- package/skills/gsd-path-plan/scripts/isolation.py +996 -38
- package/skills/gsd-path-plan/scripts/loop_run.py +9 -4
- package/skills/gsd-path-plan/scripts/members.py +17 -3
- package/skills/gsd-path-plan/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-plan/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-plan/scripts/workflow_run.py +10 -3
- package/skills/gsd-path-plan/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-plan/templates/task.md +8 -1
- package/skills/gsd-path-research/references/runtime-selection.md +36 -0
- package/skills/gsd-path-research/scripts/_common.py +76 -2
- package/skills/gsd-path-research/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-research/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-research/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-research/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-research/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-research/scripts/integration.py +196 -39
- package/skills/gsd-path-research/scripts/isolation.py +996 -38
- package/skills/gsd-path-research/scripts/loop_run.py +9 -4
- package/skills/gsd-path-research/scripts/members.py +17 -3
- package/skills/gsd-path-research/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-research/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-research/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-roadmap/references/runtime-selection.md +36 -0
- package/skills/gsd-path-roadmap/scripts/_common.py +76 -2
- package/skills/gsd-path-roadmap/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-roadmap/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-roadmap/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-roadmap/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-roadmap/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-roadmap/scripts/integration.py +196 -39
- package/skills/gsd-path-roadmap/scripts/isolation.py +996 -38
- package/skills/gsd-path-roadmap/scripts/loop_run.py +9 -4
- package/skills/gsd-path-roadmap/scripts/members.py +17 -3
- package/skills/gsd-path-roadmap/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-roadmap/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-roadmap/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-ship/SKILL.md +41 -8
- package/skills/gsd-path-ship/references/reviewer-final.md +10 -0
- package/skills/gsd-path-ship/references/reviewer-wave.md +61 -22
- package/skills/gsd-path-ship/references/reviewer.md +8 -6
- package/skills/gsd-path-ship/references/runtime-selection.md +36 -0
- package/skills/gsd-path-ship/references/spec-probes.md +19 -1
- package/skills/gsd-path-ship/scripts/_common.py +76 -2
- package/skills/gsd-path-ship/scripts/archive_milestone.py +129 -7
- package/skills/gsd-path-ship/scripts/build_recovery.py +25 -2
- package/skills/gsd-path-ship/scripts/build_state.py +333 -8
- package/skills/gsd-path-ship/scripts/check_handoffs.py +437 -30
- package/skills/gsd-path-ship/scripts/check_task_briefs.py +135 -11
- package/skills/gsd-path-ship/scripts/discussion_validate.py +46 -10
- package/skills/gsd-path-ship/scripts/integration.py +196 -39
- package/skills/gsd-path-ship/scripts/isolation.py +996 -38
- package/skills/gsd-path-ship/scripts/lean_verification.py +28 -13
- package/skills/gsd-path-ship/scripts/loop_run.py +9 -4
- package/skills/gsd-path-ship/scripts/members.py +17 -3
- package/skills/gsd-path-ship/scripts/pipeline_state.py +10 -2
- package/skills/gsd-path-ship/scripts/state_checkpoint.py +15 -0
- package/skills/gsd-path-ship/scripts/workflow_run.py +10 -3
- package/skills/gsd-path-ship/scripts/worktree_paths.py +45 -0
- package/skills/gsd-path-ship/templates/wave-review.md +24 -8
- package/skills/gsd-path-undo/references/runtime-selection.md +36 -0
- package/skills/gsd-path-undo/scripts/_common.py +76 -2
- package/skills/gsd-path-undo/scripts/loop_run.py +9 -4
- package/skills/gsd-path-undo/scripts/worktree_paths.py +45 -0
- package/skills/path/BUILD.md +3 -1
- package/skills/path/DEFINE.md +2 -1
- package/skills/path/PLAN.md +10 -0
- package/skills/path/SHIP.md +41 -8
- package/skills/path/SKILL.md +16 -1
- package/skills/path/references/build-native.md +20 -3
- package/skills/path/references/coder.md +6 -3
- package/skills/path/references/reviewer-final.md +10 -0
- package/skills/path/references/reviewer-wave.md +61 -22
- package/skills/path/references/reviewer.md +8 -6
- package/skills/path/references/runtime-selection.md +36 -0
- package/skills/path/references/spec-probes.md +19 -1
- package/skills/path/scripts/_common.py +76 -2
- package/skills/path/scripts/archive_milestone.py +129 -7
- package/skills/path/scripts/build_recovery.py +25 -2
- package/skills/path/scripts/build_state.py +333 -8
- package/skills/path/scripts/check_handoffs.py +437 -30
- package/skills/path/scripts/check_task_briefs.py +135 -11
- package/skills/path/scripts/discussion_validate.py +46 -10
- package/skills/path/scripts/dispatch_driver.py +28 -3
- package/skills/path/scripts/git_guard.py +44 -4
- package/skills/path/scripts/integration.py +196 -39
- package/skills/path/scripts/isolation.py +996 -38
- package/skills/path/scripts/lean_verification.py +28 -13
- package/skills/path/scripts/loop_run.py +9 -4
- package/skills/path/scripts/members.py +17 -3
- package/skills/path/scripts/pipeline_state.py +10 -2
- package/skills/path/scripts/state_checkpoint.py +15 -0
- package/skills/path/scripts/status_runtime.py +73 -2
- package/skills/path/scripts/workflow_run.py +10 -3
- package/skills/path/scripts/worktree_paths.py +45 -0
- package/skills/path/templates/intent.md +5 -3
- package/skills/path/templates/task.md +8 -1
- package/skills/path/templates/wave-review.md +24 -8
package/skills/path/DEFINE.md
CHANGED
|
@@ -273,7 +273,8 @@ question. The rules change for every primary mode:
|
|
|
273
273
|
for kept prohibitions, each with a recommended ruling first. A ruling
|
|
274
274
|
observable where the user sees the work becomes or amends a success
|
|
275
275
|
criterion; write every ruling into `## Edge coverage` and
|
|
276
|
-
`## Prohibitions`.
|
|
276
|
+
`## Prohibitions`. Bound every absence criterion in the edge round
|
|
277
|
+
(search space, check, absent result). Program mode skips this step (each milestone runs it
|
|
277
278
|
in milestone mode); milestone mode runs it inside its confirmation.
|
|
278
279
|
7. Classify the proposed milestone lane before writing the approval draft.
|
|
279
280
|
Milestone mode keeps `Lane: milestone` and skips this classification.
|
package/skills/path/PLAN.md
CHANGED
|
@@ -114,6 +114,11 @@ as stated in Lookahead mode.
|
|
|
114
114
|
`worktree: null`, and `task_branch: null` values on every new task.
|
|
115
115
|
In patch mode, tasks already `done` keep their landed metadata; only
|
|
116
116
|
the appended patch tasks must start clean.
|
|
117
|
+
- A `status: withdrawn` task is an owner-ruled tombstone: its file and id
|
|
118
|
+
stay in place, it is never dispatched, and its Log must carry a
|
|
119
|
+
`Withdrawn — <date>: <owner ruling verbatim>` entry. Reject an uncited
|
|
120
|
+
tombstone, a dependent that is not `done` or withdrawn, and an SC it
|
|
121
|
+
still owns; re-own or remove that SC through a Define INTENT Correction.
|
|
117
122
|
- Require every dependency id to exist, forbid later-wave dependencies,
|
|
118
123
|
detect cycles, and forbid unordered file overlap between planned tasks
|
|
119
124
|
in the same wave. Same-wave tasks may share files only when one
|
|
@@ -266,6 +271,11 @@ as stated in Lookahead mode.
|
|
|
266
271
|
A landed brief is immutable history: the helper checks its `files` scope
|
|
267
272
|
at the recorded historical base and does not check the paths that its
|
|
268
273
|
prose and Verify name.
|
|
274
|
+
Approval also refuses unsupported `.project/` entries (anything outside
|
|
275
|
+
the fixed set of state files and milestone directories): remove or
|
|
276
|
+
relocate them first — a staged `git rm` already satisfies the gate and
|
|
277
|
+
the approval checkpoint commits the removal. Task `files` may not
|
|
278
|
+
declare anything under `.project/`.
|
|
269
279
|
This applies to plan re-approval too; the dispatch CLI remains HEAD-only
|
|
270
280
|
with no overrides.
|
|
271
281
|
|
package/skills/path/SHIP.md
CHANGED
|
@@ -90,7 +90,14 @@ so the position is unchanged. Then:
|
|
|
90
90
|
head and holds the exact output; there is no reusable ledger entry.
|
|
91
91
|
Single-repo re-entry at the same command and commit reuses the execution,
|
|
92
92
|
including a failed one, and finishes interrupted collection without running
|
|
93
|
-
the command again.
|
|
93
|
+
the command again. The one exception is an owner-diagnosed host failure (for
|
|
94
|
+
example a host toolchain version the project does not pin): re-run
|
|
95
|
+
`workflow_run.py prepare-final` with `--rerun` to retire the recorded
|
|
96
|
+
execution, run the command again, and append a second ledger entry marked
|
|
97
|
+
`rerun` — the failed entry stays as history. Product failures never take
|
|
98
|
+
`--rerun`; they go through the patch plan. The sidecar inherits the
|
|
99
|
+
orchestrator environment, PATH included, by design: the Verify must run the
|
|
100
|
+
project's own toolchain, so a host/PATH mismatch is a host failure.
|
|
94
101
|
Missing legacy output requires evidence reconciliation, not a blind rerun.
|
|
95
102
|
Any non-zero result stops this step; preserve its stderr and diagnose through
|
|
96
103
|
the bundled forensics contract. Do not launch reviewers while project Verify
|
|
@@ -146,7 +153,8 @@ so the position is unchanged. Then:
|
|
|
146
153
|
verdict `met` with a non-`none` Check or Reference, and every criterion
|
|
147
154
|
listed in PLAN.md's Surface contract requires a matching `Surface` field
|
|
148
155
|
and a non-`none` Check. A non-zero exit is
|
|
149
|
-
`ship/blocked`; never rerun project Verify to repair the evidence
|
|
156
|
+
`ship/blocked`; never rerun project Verify to repair the evidence (a
|
|
157
|
+
host-caused command failure uses the `prepare-final --rerun` route above).
|
|
150
158
|
6. Redispatch one complete corrected brief for a missing or invalid reviewer
|
|
151
159
|
artifact under the same logical task name, following the runtime dispatch
|
|
152
160
|
contract. Before dispatch, record the invalid destination's exact SHA-256.
|
|
@@ -275,7 +283,16 @@ The persisted `STATE.archive` field is the transaction identity.
|
|
|
275
283
|
`awaiting-merge`, report the member PR
|
|
276
284
|
link, stop, and rerun the same command after the user merges it; never
|
|
277
285
|
merge a member PR yourself. When it returns `integrated`, keep its `body`
|
|
278
|
-
for the ship commit below.
|
|
286
|
+
for the ship commit below. When it refuses with
|
|
287
|
+
`member reviewed HEAD reached <default> outside Path`, the member's work
|
|
288
|
+
was already published past its reviewed HEAD by an earlier user-approved
|
|
289
|
+
step: present the member, its reviewed HEAD, and the live default-branch
|
|
290
|
+
tip, and ask the user whether to adopt that landing. Only on an explicit
|
|
291
|
+
user approval rerun the same command with
|
|
292
|
+
`--adopt-landed-member <member>=<live tip SHA>`; the helper then publishes
|
|
293
|
+
the bound branch and an `adopted-landing` milestone tag at that tip and
|
|
294
|
+
makes no merge. A mismatched or stale SHA is refused, and a later rerun
|
|
295
|
+
validates the adoption without the flag.
|
|
279
296
|
5. Only after preflight passes, record shipment through the journaled helper;
|
|
280
297
|
for a program it atomically replaces both ROADMAP.md and STATE.md, setting
|
|
281
298
|
the current entry to `Status: shipped` with the exact `Archive:` pointer:
|
|
@@ -330,7 +347,13 @@ The persisted `STATE.archive` field is the transaction identity.
|
|
|
330
347
|
`build/rebase-adoption.json`) may advance the ref from the adopted head
|
|
331
348
|
to its immediate, canonical `.project/`-only ship child under an exact-SHA
|
|
332
349
|
lease after the helper proves the clean ship state, receipt, and archived
|
|
333
|
-
tasks
|
|
350
|
+
tasks, and a strict ancestor of the ship commit — a build task may have
|
|
351
|
+
legitimately pushed the bound branch as a deploy pin (#464) — is adopted
|
|
352
|
+
only after the user approves, by rerunning with
|
|
353
|
+
`integrate --adopt-published-bound <live 40-hex SHA>`; the helper requires
|
|
354
|
+
the SHA to equal the live tip exactly and fast-forwards under the same
|
|
355
|
+
exact lease, and direct integration only. Every other value blocks. If
|
|
356
|
+
origin/main advances
|
|
334
357
|
after the local merge but rejects the push, a retry may discard and
|
|
335
358
|
rebuild only the unpublished canonical merge and tag under the helper's
|
|
336
359
|
existing recovery checks.
|
|
@@ -417,10 +440,15 @@ Run this recovery setup from a separate checkout, outside the closed primary
|
|
|
417
440
|
worktree's guard.
|
|
418
441
|
|
|
419
442
|
1. Create separate disposable trust and validation checkouts from the same
|
|
420
|
-
published origin and
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
443
|
+
published origin and its default branch (checking out `STATE.branch` when
|
|
444
|
+
it still exists; a rebase-merged pull request may have deleted it). This
|
|
445
|
+
separation is required because an explicit runtime upgrade changes the
|
|
446
|
+
trust checkout's declaration and launcher, while archive validation
|
|
447
|
+
requires a clean checkout. Never use the primary worktree for either role.
|
|
448
|
+
A rebase-merged milestone additionally needs the original ship commits to
|
|
449
|
+
resolve — use a checkout that fetched and retained them (the primary
|
|
450
|
+
always does; a clone that never fetched the bound branch does not), and a
|
|
451
|
+
checkout whose originals were collected cannot carry a full validation.
|
|
424
452
|
2. From the trusted fixed GSD Path checkout, preview and then explicitly upgrade only the
|
|
425
453
|
disposable trust checkout's managed trust anchor:
|
|
426
454
|
|
|
@@ -448,6 +476,11 @@ worktree's guard.
|
|
|
448
476
|
python3 -B <verified-runtime>/archive_milestone.py validate-integrated --repo <validation-root> --slug <STATE.milestone>
|
|
449
477
|
```
|
|
450
478
|
|
|
479
|
+
When the validation checkout is on the default branch after the milestone
|
|
480
|
+
closed (the bound branch is gone), pass `--historical`; a rebase-merged
|
|
481
|
+
landing is then accepted only through the milestone tag's Ship/Landing
|
|
482
|
+
pair plus a re-proven rebase replay.
|
|
483
|
+
|
|
451
484
|
4. A pass restores the normal shipped handoff without another commit or
|
|
452
485
|
publication action. Remove only the disposable checkouts. A failure is a
|
|
453
486
|
new validation finding: report it with the primary worktree's archived
|
package/skills/path/SKILL.md
CHANGED
|
@@ -227,7 +227,9 @@ A coordinator project can change other repositories (members) in the same
|
|
|
227
227
|
milestone; `.project/MEMBERS.md` lists them. Change members only at a
|
|
228
228
|
milestone boundary, never during build or ship. Resolve the bundled
|
|
229
229
|
`scripts/members.py` to an absolute path and use it; never edit MEMBERS.md
|
|
230
|
-
or a member marker by hand
|
|
230
|
+
or a member marker by hand (the one exception is adding the optional
|
|
231
|
+
`Prepare:` row below through a reviewed change — `members.py` has no
|
|
232
|
+
subcommand for it yet).
|
|
231
233
|
|
|
232
234
|
- To add an existing repository, it needs a GitHub.com `origin`, a clean
|
|
233
235
|
worktree, and no active milestone of its own. Its default branch can have
|
|
@@ -240,6 +242,19 @@ or a member marker by hand.
|
|
|
240
242
|
When `validate` or member close later reports
|
|
241
243
|
`remote default must be <recorded>`, stop and report it; never edit the
|
|
242
244
|
record.
|
|
245
|
+
- A member whose isolates need more than tracked files — uninitialized
|
|
246
|
+
submodules, gitignored build inputs — declares a `Prepare:` command in its
|
|
247
|
+
MEMBERS.md row (added by editing the committed file through a reviewed
|
|
248
|
+
change; `members.py` validates it like any field). The runtime runs it
|
|
249
|
+
inside every fresh member isolate, task or verify, before any Verify: it
|
|
250
|
+
must provision by copying from the member's primary checkout, never by
|
|
251
|
+
linking (retirement defuses links, and a link would let the isolate mutate
|
|
252
|
+
shared inputs). For submodules, the offline recipe is
|
|
253
|
+
`git config submodule.<name>.url <primary>/.git/modules/<name> && git -c protocol.file.allow=always submodule update --init <name>`
|
|
254
|
+
— it reads the primary's object store and touches no network. A failed
|
|
255
|
+
Prepare fails the isolation loudly with its output before a Verify runs.
|
|
256
|
+
Retained isolates keep their provisioning: a re-authorized rerun does not
|
|
257
|
+
Prepare again.
|
|
243
258
|
- To create a new member repository, present the exact `owner/name`,
|
|
244
259
|
visibility, and checkout path as the **Review** surface and get approval
|
|
245
260
|
first, as for a new GitHub repository. Then run the same command with
|
|
@@ -207,7 +207,16 @@ dispatch contract and perform steps 1–5 by hand.
|
|
|
207
207
|
its exact base prove the remaining branch before deletion. Create the retry
|
|
208
208
|
from the new clean primary HEAD. A member task (`repo: <member>`) stays
|
|
209
209
|
`pending` in the coordinator; its rejected attempt lives in the member
|
|
210
|
-
sidecar.
|
|
210
|
+
sidecar. When the failure was environmental — the isolate could not build
|
|
211
|
+
a Verify for reasons outside the product, and the coder fixed the
|
|
212
|
+
environment inside the retained sidecar — do not re-isolate: rerun
|
|
213
|
+
`python3 <absolute isolation.py> activate-member-task --repo <absolute
|
|
214
|
+
primary> --member <member> --task-id <id> --reauthorize` after checking
|
|
215
|
+
that the live copy's Log stayed append-only and the member base is
|
|
216
|
+
unchanged; it re-arms the authorization the failed finish cleared, and the
|
|
217
|
+
next `finish` runs the full Verify set once and lands (#461). A
|
|
218
|
+
product-failure rejection instead follows the full retry: copy the live
|
|
219
|
+
copy's Log delta into the coordinator task file,
|
|
211
220
|
checkpoint it, then retire the sidecar with `python3 <absolute isolation.py>
|
|
212
221
|
retire-member-task --repo <absolute primary> --member <member> --task-id
|
|
213
222
|
<id> --task-file <task path> --force`. It refuses until the committed task
|
|
@@ -231,7 +240,11 @@ dispatch contract and perform steps 1–5 by hand.
|
|
|
231
240
|
`python3 <absolute check_handoffs.py> plan --repo <absolute repo root>`
|
|
232
241
|
before creating any worktree; a lint or coverage failure is a documented plan
|
|
233
242
|
defect — repair it against INTENT.md and SYNTHESIS.md, then re-establish
|
|
234
|
-
the base.
|
|
243
|
+
the base. The brief lint is read-only and idempotent; it reports progress
|
|
244
|
+
on stderr (one line every 20 tasks) and its stdout is exactly the result
|
|
245
|
+
JSON. A host timeout that cut it off with no failure output is not a
|
|
246
|
+
contract verdict — rerun it with a larger timeout and judge only the
|
|
247
|
+
completed run. Then isolate each ready task with
|
|
235
248
|
`python3 <absolute workflow_run.py> prepare-task --repo <absolute primary>
|
|
236
249
|
--expected-head <recorded base> --task-id <id> --round-size <N>` where N is the
|
|
237
250
|
number of tasks in this dispatch round. For a coordinator task, serial
|
|
@@ -619,7 +632,11 @@ dispatch contract and perform steps 1–5 by hand.
|
|
|
619
632
|
Log waiver — or, in program flow (ROADMAP.md exists), to abandon the
|
|
620
633
|
milestone under the Milestone abandon procedure — listing the
|
|
621
634
|
orchestrator's recommended option first marked `(recommended)` with a
|
|
622
|
-
one-line reason drawn from the review evidence.
|
|
635
|
+
one-line reason drawn from the review evidence. When the cap cycle is
|
|
636
|
+
later than 1 and a blocking group in its `groups` has `first_seen_cycle`
|
|
637
|
+
1, recommend sending it
|
|
638
|
+
to define: fix cycles since cycle 1 have not closed that criterion, so it
|
|
639
|
+
is likely unbounded. Never choose silently.
|
|
623
640
|
When the canonical verdict is `pass` and `wave-N.cycleC.panel.md` reports
|
|
624
641
|
`Actionable` greater than 0, do not advance silently: present **Outcome**
|
|
625
642
|
with the canonical pass plus the actionable count, **Review** linking the
|
|
@@ -35,7 +35,10 @@ reality:
|
|
|
35
35
|
item in INTENT.md `## Success criteria`.
|
|
36
36
|
- Confirm your Interface contract text appears verbatim in every sibling
|
|
37
37
|
task file it exchanges with. Sibling task files under `.project/tasks/`
|
|
38
|
-
are readable in your worktree — read-only; never edit them.
|
|
38
|
+
are readable in your worktree — read-only; never edit them. On a member
|
|
39
|
+
task the orchestrator pins them under
|
|
40
|
+
`.gsd-path-coordinator/.project/tasks/` beside your live task copy —
|
|
41
|
+
read them there.
|
|
39
42
|
- Confirm every path the Verify command references exists or is declared.
|
|
40
43
|
|
|
41
44
|
Route any mismatch before writing a line of product code: a clear defect — a
|
|
@@ -86,8 +89,8 @@ them.
|
|
|
86
89
|
|
|
87
90
|
- You are not alone in the repository. Other agents may use sibling worktrees;
|
|
88
91
|
do not inspect, revert, or overwrite their changes.
|
|
89
|
-
- Never edit `base`, `worktree`, `task_branch`, `status`,
|
|
90
|
-
The orchestrator owns them.
|
|
92
|
+
- Never edit `base`, `worktree`, `task_branch`, `status`, `agent`, or
|
|
93
|
+
`member_base` (member tasks). The orchestrator owns them.
|
|
91
94
|
- Never stage, commit, amend, rebase, reset, or otherwise mutate Git.
|
|
92
95
|
- Never add an unnamed dependency, weaken verification, or improve adjacent
|
|
93
96
|
code.
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
## Final integration mode
|
|
2
2
|
|
|
3
3
|
Use only final-review.md. Treat INTENT.md success criteria as the rubric.
|
|
4
|
+
To locate each task's authoritative accepted evidence instead of joining
|
|
5
|
+
task Logs, ledger rows, and gap artifacts by hand, run
|
|
6
|
+
`python3 <absolute build_state.py> evidence-manifest --repo
|
|
7
|
+
<absolute primary> --project-dir .project --head <reviewed HEAD>`:
|
|
8
|
+
it classifies every task as `ledger`, `log-only`, `rejected`,
|
|
9
|
+
`superseded`, or `missing` and names the receipt, and reports the member
|
|
10
|
+
project Verify as `gap-embedded` only from a passing `final-gap-1.md` at
|
|
11
|
+
the reviewed HEAD — a
|
|
12
|
+
`log-only` task is accepted through its retained isolated-Verify Log, and
|
|
13
|
+
an absent ledger row is explained, never treated as data loss.
|
|
4
14
|
Each `### SCn —` heading must have every word of the criterion in INTENT.md
|
|
5
15
|
`## Success criteria`: join indented continuation lines and sub-bullets
|
|
6
16
|
with a single space. You can keep or remove the `- ` markers of the
|
|
@@ -8,19 +8,45 @@ tasks in this wave as the rubric. For each task:
|
|
|
8
8
|
Never infer either SHA from task ids, branch position, or nearby history.
|
|
9
9
|
2. Fail a missing, malformed, or invalid SHA. Inspect the commit with
|
|
10
10
|
`git show --format=fuller --stat --patch <commit> --`.
|
|
11
|
-
3.
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
3. Select the inspection mode your brief supplies and record it — never
|
|
12
|
+
improvise a third:
|
|
13
|
+
- **Reconstructed product** (default): the brief supplies a verify
|
|
14
|
+
sidecar at `base`. In it, apply only the complete binary patch from
|
|
15
|
+
`commit^..commit` for the task's declared product files and inspect
|
|
16
|
+
the diff. Use the orchestrator's recorded isolated Verify output in
|
|
17
|
+
that task's Log as the Verify evidence.
|
|
18
|
+
- **Immutable patch**: the brief supplies one later combined checkout
|
|
19
|
+
with report-write authority only. Inspect the immutable objects
|
|
20
|
+
directly — `git show`/`git diff` on the recorded commits — and prove
|
|
21
|
+
the identity before judging: (a) the landing commit's parent
|
|
22
|
+
`commit^` equals the task file's recorded `base` (or the patch's
|
|
23
|
+
resulting blobs at `base` equal the landing commit's blobs for the
|
|
24
|
+
declared files), and (b) any file judged from the combined checkout
|
|
25
|
+
has its blob there equal to the landing commit's blob at that path.
|
|
26
|
+
Without both identities the review blocks: a mismatch means the
|
|
27
|
+
supplied checkout is not the reviewed product.
|
|
28
|
+
In both modes: do not re-run the task Verify command or PLAN.md's
|
|
29
|
+
project Verify; re-run a command only when the recorded output plus
|
|
30
|
+
the diff cannot check the criterion. Never use the primary worktree
|
|
31
|
+
or branch tip as task evidence. Do not create or remove Git worktrees
|
|
32
|
+
yourself.
|
|
33
|
+
4. Mark `pass` or `fail`. Before the evidence separator (` — `), name the
|
|
34
|
+
criterion (see Review file format below): copy the complete task
|
|
35
|
+
acceptance or interface criterion verbatim, or — on a `pass` line only —
|
|
36
|
+
cite the criterion by its stable id in the task's numbered acceptance or
|
|
37
|
+
interface list (`T012/AC3`, `T012/IF2`) together with the evidence. A
|
|
38
|
+
`fail` line always copies the criterion verbatim: finding grouping binds
|
|
39
|
+
that text to the task. Give the observed result, `file:line`, and
|
|
23
40
|
concrete fix direction for each failure.
|
|
41
|
+
5. Account for every claim. Each acceptance criterion (`T012/AC3`) and
|
|
42
|
+
interface bullet (`T012/IF2`) of the task must appear in its
|
|
43
|
+
section as an evidence reference, a finding, or an explicitly
|
|
44
|
+
authorized disposition — a bare line naming the id with
|
|
45
|
+
`disposition: <authority and date> (<Cn>): <reason>`, where `Cn` is a
|
|
46
|
+
numbered INTENT.md correction. No citation, or a `Cn` that
|
|
47
|
+
`## Corrections` does not define, fails the gate. One observation may
|
|
48
|
+
support several claims when each is identified by its id. The wave gate
|
|
49
|
+
rejects a review that leaves a claim unaccounted for.
|
|
24
50
|
|
|
25
51
|
A Log entry `orchestrator regression Verify of <task id> retired: superseded
|
|
26
52
|
by <task id>` is not evidence: judge the superseding task's acceptance
|
|
@@ -30,8 +56,12 @@ criteria. The same applies to the entry `orchestrator regression Verify of
|
|
|
30
56
|
Then check each INTENT.md success criterion owned by a task in this wave
|
|
31
57
|
against that same isolated product. In each `### SCn —` heading, copy the
|
|
32
58
|
complete criterion text from INTENT.md `## Success criteria` (see Review
|
|
33
|
-
file format below).
|
|
34
|
-
|
|
59
|
+
file format below). Write the headings in ascending SC id order (SC2 before
|
|
60
|
+
SC4), and separate the id from the text with an em dash (—). Mark `pass`
|
|
61
|
+
or `fail` with evidence; a failed owned SC blocks the wave. Under a `pass`
|
|
62
|
+
SC, record each subclaim a numbered INTENT.md correction excludes as
|
|
63
|
+
`- Excluded by <Cn>: <subclaim>`; the gate rejects an exclusion under a
|
|
64
|
+
failing SC or one that cites an undefined correction. Omit the Intent coverage section when no task in the wave owns
|
|
35
65
|
an SC. When INTENT.md `## Edge coverage` or `## Prohibitions` has rows for
|
|
36
66
|
an owned SC, judge it against those rulings too: cite each `held-out` edge
|
|
37
67
|
id with its held-out test's recorded output and each `judgment` prohibition
|
|
@@ -40,8 +70,12 @@ fails the SC.
|
|
|
40
70
|
|
|
41
71
|
Allow changed paths only in the task's `files` plus its assigned task file.
|
|
42
72
|
Within the task file, allow orchestrator-owned `base`, `worktree`,
|
|
43
|
-
`task_branch`, `status`, and `agent` fields
|
|
44
|
-
entries; block contract-body changes
|
|
73
|
+
`task_branch`, `status`, and `agent` fields — and, on a member task,
|
|
74
|
+
`member_base` — plus append-only Log entries; block contract-body changes
|
|
75
|
+
in the task commit. `base` names the task's starting commit in the
|
|
76
|
+
coordinator repository; `member_base` names the starting commit in the
|
|
77
|
+
member repository from which the member task branch and isolate were
|
|
78
|
+
created. Warn on disabled tests
|
|
45
79
|
or Verify commands that cannot fail unless either defeats a criterion. Set the
|
|
46
80
|
wave verdict to `pass` only when every task passes and every owned INTENT
|
|
47
81
|
success criterion for the wave passes.
|
|
@@ -65,10 +99,14 @@ criterion text does not match. Apply the rules before you write the file.
|
|
|
65
99
|
`- ❌ ` for fail. Each task section and each `### SCn —` block needs one
|
|
66
100
|
or more lines with the marker of its own verdict. A failed task needs a
|
|
67
101
|
`- ❌ ` criterion line, also when other text describes the failure.
|
|
68
|
-
- **Criterion text.** In a
|
|
69
|
-
copy every word of the criterion. Join wrapped lines and
|
|
70
|
-
one space. You can keep or remove the `- ` markers of
|
|
71
|
-
A changed, added, removed or moved word does not
|
|
102
|
+
- **Criterion text.** In a `### SCn —` heading and on every `- ❌ ` fail
|
|
103
|
+
line, copy every word of the criterion. Join wrapped lines and
|
|
104
|
+
sub-bullets with one space. You can keep or remove the `- ` markers of
|
|
105
|
+
the sub-bullets. A changed, added, removed or moved word does not
|
|
106
|
+
match. On a `- ✅ ` pass line, name the criterion either by copying it
|
|
107
|
+
verbatim or by citing its stable id in the task's numbered acceptance
|
|
108
|
+
or interface list (`T001/AC1`, `T001/IF2`) together with the evidence;
|
|
109
|
+
the wave gate does not compare pass-line criterion text.
|
|
72
110
|
- **Angle brackets.** Text such as `<b>` or `<path>` outside backticks reads
|
|
73
111
|
as an unfilled template placeholder and is rejected. Write literal markup
|
|
74
112
|
and code in backticks inside a sentence, for example: the output has
|
|
@@ -116,8 +154,9 @@ runtime checks freshness and derives the final view from these records.
|
|
|
116
154
|
## Deep review lenses
|
|
117
155
|
|
|
118
156
|
A `deep` wave spawns two independent reviewers in parallel, each with a fresh
|
|
119
|
-
context and its own
|
|
120
|
-
|
|
157
|
+
context and its own isolated workspace at the recorded review base (a verify
|
|
158
|
+
sidecar in reconstructed mode, or the supplied combined checkout in immutable
|
|
159
|
+
mode). Every Wave mode rule above applies to both lenses.
|
|
121
160
|
|
|
122
161
|
- **Contract** — logical task name
|
|
123
162
|
`review_wave_<wave>_cycle_<cycle>_contract`; stages
|
|
@@ -5,16 +5,18 @@ Verify written GSD Path expectations and block failures. Never fix code.
|
|
|
5
5
|
## Brief contract
|
|
6
6
|
|
|
7
7
|
- Require the mode, all inputs, exact canonical output path, applicable
|
|
8
|
-
template, repository root
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
template, and repository root by absolute path. Wave mode also requires
|
|
9
|
+
the absolute INTENT.md path and names the inspection mode: a verify
|
|
10
|
+
sidecar root for reconstructed-product review, or one combined checkout
|
|
11
|
+
with report-write authority for immutable-patch review. The brief must
|
|
12
|
+
also name the staged output path under that workspace.
|
|
12
13
|
- Read AGENTS.md and the template before reviewing.
|
|
13
|
-
- Write only the exact assigned review output under the supplied
|
|
14
|
+
- Write only the exact assigned review output under the supplied workspace
|
|
14
15
|
at its staged `.project/review/` path. The orchestrator validates and
|
|
15
16
|
atomically transfers that file to the canonical primary `.project/review/`
|
|
16
17
|
path after collection. Temporary patch/test effects are allowed solely
|
|
17
|
-
inside supplied sidecars
|
|
18
|
+
inside supplied sidecars; an immutable-mode combined checkout carries
|
|
19
|
+
report-write authority only. Never edit a product path or any other
|
|
18
20
|
primary-worktree path. Stop on a missing input or template.
|
|
19
21
|
|
|
20
22
|
## Load the assigned mode
|
|
@@ -20,6 +20,42 @@ references to bundled copies of those helpers. Other skill helpers, templates,
|
|
|
20
20
|
and role briefs remain in the installed skill bundle. Pass `-B` to Python helper
|
|
21
21
|
invocations so execution does not create bytecode in the runtime store.
|
|
22
22
|
|
|
23
|
+
When the runtime enforcing an active task cannot finish it, one narrowly
|
|
24
|
+
authorized recovery exists:
|
|
25
|
+
`python3 -B <absolute isolation.py> runtime-hotfix --repo <absolute primary>
|
|
26
|
+
--task-id <id> --runtime <64-hex runtime digest printed by runtime_store.py publish>
|
|
27
|
+
--authorized-by <the owner ruling>` validates the replacement runtime,
|
|
28
|
+
re-runs that task's Verify in a fresh sidecar at the recorded base under the
|
|
29
|
+
replacement pin, and records the receipt twice: a Log line in the task file
|
|
30
|
+
naming the task, base, and both runtime digests, and an identical blob behind
|
|
31
|
+
the local ref `refs/gsd-path/runtime-hotfix/<task>-<base>`. Only a Log line
|
|
32
|
+
whose exact twin that ref holds later admits `.gsd-path/runtime.json` into that
|
|
33
|
+
task's landing, and only when the pin names exactly the receipt's runtime; any
|
|
34
|
+
other task, base, a Log line alone, or a bare mention authorizes nothing, and a
|
|
35
|
+
failing re-run refuses the hotfix. Limits: the command serves only a serial
|
|
36
|
+
task working in the primary and refuses parallel or member tasks; the ref is
|
|
37
|
+
local repository state, so a clone without it cannot land the pin and the
|
|
38
|
+
proof fails closed. The guard applies two rules to agent shell commands. It
|
|
39
|
+
denies any command where `runtime-hotfix` directly follows `isolation.py`, stdin
|
|
40
|
+
`-`, or an `isolation` module operand (`-m isolation`, `-Bm isolation`,
|
|
41
|
+
`-misolation`). It also denies every Git command with a word, including global
|
|
42
|
+
`-c` options and inline variable assignments, that contains `refs/gsd-path/` or
|
|
43
|
+
`runtime-hotfix`. This deliberately blocks read-only uses such as
|
|
44
|
+
`git log refs/gsd-path/<ref>` or `git log --grep runtime-hotfix`, and commit
|
|
45
|
+
messages or branch names that contain `runtime-hotfix`. Limits: it cannot see a copied or renamed
|
|
46
|
+
`isolation.py`, a refspec stored in a Git config file, a ref write made from
|
|
47
|
+
inside another program, a direct edit of files under `.git/`, or shell
|
|
48
|
+
expansion that splits both protected words, such as
|
|
49
|
+
`refs/gs{d,}-path/task-authorizations/<task>`.
|
|
50
|
+
|
|
51
|
+
Publishing a runtime to the shared store is project-free:
|
|
52
|
+
`python3 -B <absolute runtime_store.py> publish --source <absolute package root>`
|
|
53
|
+
verifies and publishes the content-addressed runtime, printing its version,
|
|
54
|
+
digest, and store path as JSON; `--provenance` records a note in that output
|
|
55
|
+
only. Publication alone neither authorizes execution nor changes a project's
|
|
56
|
+
trusted runtime — a project runs the bytes only when its own pin names that
|
|
57
|
+
digest.
|
|
58
|
+
|
|
23
59
|
The selected runtime is authoritative for each helper in its `manifest.json`;
|
|
24
60
|
this includes `review_findings.py` and `task_context.py`. A selected runtime
|
|
25
61
|
that was published before a helper became a runtime file does not list that
|
|
@@ -96,6 +96,23 @@ Present the kept items with a recommended ruling and record each as a row:
|
|
|
96
96
|
Work that affects no person directly records a single row instead, and no
|
|
97
97
|
other: `| N1 | all | none | dismissed | <why no person is affected> |`.
|
|
98
98
|
|
|
99
|
+
## Absence criteria
|
|
100
|
+
|
|
101
|
+
A criterion that claims absence ("X does not exist", "no X anywhere",
|
|
102
|
+
"never Y"), including one written from a prohibition, has no end until it
|
|
103
|
+
says where to look. Each review can look somewhere new, so the build loops
|
|
104
|
+
to the cycle cap. Every absence criterion states:
|
|
105
|
+
|
|
106
|
+
- the search space: the files, surfaces, or artifacts to check;
|
|
107
|
+
- the check: the command or observation that covers that space;
|
|
108
|
+
- the absent result: the output that counts as absent.
|
|
109
|
+
|
|
110
|
+
When one is missing, propose a bounded form in the same question round as
|
|
111
|
+
the edges, recommended form first, and amend the criterion after the user
|
|
112
|
+
rules. Do not choose the search space yourself: a narrower space is a scope
|
|
113
|
+
ruling. Under pre-approval, an unbounded absence criterion is a required
|
|
114
|
+
answer: stop and ask.
|
|
115
|
+
|
|
99
116
|
## INTENT.md tables
|
|
100
117
|
|
|
101
118
|
```markdown
|
|
@@ -131,7 +148,8 @@ rechecked; a near-miss heading fails the gate rather than switching it off.
|
|
|
131
148
|
the owning task's Approach so the coder knows the line.
|
|
132
149
|
- **Review.** A row pins the reading of its criterion. A reviewer does not
|
|
133
150
|
pass a reading that contradicts a ruling in either table, and cites each
|
|
134
|
-
held-out edge and judgment prohibition id with its evidence.
|
|
151
|
+
held-out edge and judgment prohibition id with its evidence. An absence
|
|
152
|
+
criterion is judged over its stated search space only.
|
|
135
153
|
- **Final review.** A criterion that carries a held-out edge or a judgment
|
|
136
154
|
prohibition is `met` only when its Check, Observed, or Reference cites
|
|
137
155
|
every such id with the evidence: the held-out test's recorded passing
|
|
@@ -14,6 +14,7 @@ import sys
|
|
|
14
14
|
# Runtime helpers must not modify their immutable installation.
|
|
15
15
|
sys.dont_write_bytecode = True
|
|
16
16
|
|
|
17
|
+
import atexit
|
|
17
18
|
import contextlib
|
|
18
19
|
import errno
|
|
19
20
|
import json
|
|
@@ -23,9 +24,10 @@ import shlex
|
|
|
23
24
|
import shutil
|
|
24
25
|
import signal
|
|
25
26
|
import subprocess
|
|
27
|
+
import tempfile
|
|
26
28
|
import time
|
|
27
29
|
from pathlib import Path
|
|
28
|
-
from typing import BinaryIO, Iterable, Iterator, List, Optional, Sequence, Tuple
|
|
30
|
+
from typing import BinaryIO, Iterable, Iterator, List, Optional, Sequence, Set, Tuple
|
|
29
31
|
|
|
30
32
|
|
|
31
33
|
# Chosen by what imports, not os.name, so tests can emulate Windows on POSIX.
|
|
@@ -65,6 +67,23 @@ VERIFY_LEDGER_PATH = ".project/build/verify-ledger.jsonl"
|
|
|
65
67
|
VERIFY_RESULTS = ("pass", "fail")
|
|
66
68
|
VERIFY_LEDGER_SCHEMA = "gsd-path/verify-ledger/v2"
|
|
67
69
|
VERIFY_BLOCK_PATTERN = re.compile(r"```bash[ \t]*\n(?P<block>.*?)```", re.DOTALL)
|
|
70
|
+
# The owner citation a withdrawn task tombstone must carry in its Log (#483).
|
|
71
|
+
# One definition shared by every gate that reads the representation.
|
|
72
|
+
WITHDRAWN_CITATION = re.compile(
|
|
73
|
+
r"^- Withdrawn — (?P<date>\d{4}-\d{2}-\d{2}): (?P<ruling>.+)$", re.MULTILINE)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def withdrawn_citations(task_text: str) -> list[str]:
|
|
77
|
+
"""The owner citations in a withdrawn task's Log, as `date: ruling`.
|
|
78
|
+
|
|
79
|
+
The Log is the append-only record of rulings; a Withdrawn line in any
|
|
80
|
+
other section is not the citation the gates accept (#483).
|
|
81
|
+
"""
|
|
82
|
+
body = section_body(task_text, "Log")
|
|
83
|
+
if body is None:
|
|
84
|
+
return []
|
|
85
|
+
return [f"{m.group('date')}: {m.group('ruling')}"
|
|
86
|
+
for m in WITHDRAWN_CITATION.finditer(body)]
|
|
68
87
|
|
|
69
88
|
REVIEW_BULLET_HEADING_PATTERN = re.compile(r"^#{2,3} ")
|
|
70
89
|
REVIEW_BULLET_FIELD_LABEL_PATTERN = re.compile(r"^- \*\*[^*]+\*\*:")
|
|
@@ -197,6 +216,19 @@ def section_body(text: str, heading: str) -> Optional[str]:
|
|
|
197
216
|
return match.group("body") if match else None
|
|
198
217
|
|
|
199
218
|
|
|
219
|
+
def contract_shapes(body: str) -> Set[str]:
|
|
220
|
+
"""The whitespace-normalized `- ` entries of an Interface contract body.
|
|
221
|
+
|
|
222
|
+
HTML comments are dropped and continuation lines join their entry. A
|
|
223
|
+
body that says only `None` has no shapes.
|
|
224
|
+
"""
|
|
225
|
+
cleaned = re.sub(r"(?s)<!--.*?-->", "", body).strip()
|
|
226
|
+
if " ".join(cleaned.split()) in {"", "None", "- None"}:
|
|
227
|
+
return set()
|
|
228
|
+
entries = re.split(r"(?m)^-[ \t]+", cleaned)
|
|
229
|
+
return {shape for shape in (" ".join(entry.split()) for entry in entries) if shape}
|
|
230
|
+
|
|
231
|
+
|
|
200
232
|
def overlapping_paths(left: Sequence[str], right: Sequence[str]) -> List[str]:
|
|
201
233
|
"""Return the sorted paths that two task `files` lists both cover.
|
|
202
234
|
|
|
@@ -875,8 +907,50 @@ def find_bash() -> str:
|
|
|
875
907
|
)
|
|
876
908
|
|
|
877
909
|
|
|
910
|
+
def _remove_quietly(path: str) -> None:
|
|
911
|
+
try:
|
|
912
|
+
os.remove(path)
|
|
913
|
+
except OSError:
|
|
914
|
+
pass
|
|
915
|
+
|
|
916
|
+
|
|
917
|
+
def _command_script_dir() -> str:
|
|
918
|
+
"""A temp directory for command scripts that cannot dirty the running tree.
|
|
919
|
+
|
|
920
|
+
TMPDIR/TEMP/TMP may point into the tree being verified, and a script file
|
|
921
|
+
there shows up in git status and blocks landings (#448), so fall back to a
|
|
922
|
+
system directory when the environment temp sits inside the current tree.
|
|
923
|
+
"""
|
|
924
|
+
candidate = os.path.realpath(tempfile.gettempdir())
|
|
925
|
+
tree = os.path.realpath(os.getcwd())
|
|
926
|
+
if candidate != tree and not candidate.startswith(tree + os.sep):
|
|
927
|
+
return candidate
|
|
928
|
+
for fallback in (
|
|
929
|
+
os.path.join(os.environ.get("SystemRoot", r"C:\Windows"), "Temp"),
|
|
930
|
+
"/var/tmp",
|
|
931
|
+
"/tmp",
|
|
932
|
+
):
|
|
933
|
+
resolved = os.path.realpath(fallback)
|
|
934
|
+
if os.path.isdir(resolved) and resolved != tree and not resolved.startswith(tree + os.sep):
|
|
935
|
+
return resolved
|
|
936
|
+
raise OSError("no temp directory outside the current worktree for a command script")
|
|
937
|
+
|
|
938
|
+
|
|
878
939
|
def bash_argv(command: str) -> List[str]:
|
|
879
|
-
|
|
940
|
+
if os.name != "nt":
|
|
941
|
+
return [find_bash(), "-c", command]
|
|
942
|
+
# Git for Windows' bash (MSYS2) cuts an argument that carries a double
|
|
943
|
+
# quote near 8 KB before bash sees it, so a long Verify dies mid-script
|
|
944
|
+
# or silently passes when the cut lands in comments (#448). Run the exact
|
|
945
|
+
# bytes from a temp file outside every worktree instead.
|
|
946
|
+
bash = find_bash()
|
|
947
|
+
descriptor, path = tempfile.mkstemp(
|
|
948
|
+
prefix="gsd-path-command-", suffix=".sh", dir=_command_script_dir()
|
|
949
|
+
)
|
|
950
|
+
with os.fdopen(descriptor, "w", encoding="utf-8", newline="\n") as handle:
|
|
951
|
+
handle.write(command)
|
|
952
|
+
atexit.register(_remove_quietly, path)
|
|
953
|
+
return [bash, path]
|
|
880
954
|
|
|
881
955
|
|
|
882
956
|
# cmd.exe re-parses the arguments of a .cmd or .bat target, so these would
|