From cf4d0774657e8fbc3f3c94e20130f9a497f62bb8 Mon Sep 17 00:00:00 2001 From: Mike Clay Date: Mon, 17 Aug 2026 11:01:31 +0100 Subject: [PATCH] Close four gates that cannot open, and give the branch prefix a producer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The meta orchestrator records reaching the end of its client activity loop, so close-out can tell a completed run from one that stopped at the iteration bound. The flag that gate reads defaults to false and its only writer — the checkpoint option that returns to the workflow — also sets it false, so the session-metrics revision the terminal activity binds never executed. Three files document a mid-run write of the trace and usage artifacts as a draft that revision rewrites; both shipped as drafts in every run. The branch-name prefix has a total mapping and a producer. The issue-type enum declares five categories; the table mapped four, left task and enhancement to be chosen between two prefixes with no rule, and named none for epic — so an epic-typed work package reached branch composition and the prefix was invented, which is a value two runs on the same epic disagree about. Each category now maps to one prefix the repository already uses, with the reason stated per row, and the prefix itself is a step-local the composition step reads rather than an unanchored reference no declared input resolves. The complex-problem path into the analysis workflow dispatches it. It was an action step with an empty action list, so a complex work package ran the structural-analysis technique inline on the simple path and nothing at all on its own. It now declares the trigger and binds handle-sub-workflow, following the prism-audit activity that already dispatches the same child. The workflow-design audit technique names arguments that exist. One step instructed a re-snapshot flag the binding guard does not have and has never had — classification there is a human verdict in the triage register — and two guard invocations passed no corpus root, so an authoring run reviewing a worktree measured the server checkout instead and reported a clean pass on definitions it never read. Co-Authored-By: Claude Opus 5 (1M context) --- .../03-dispatch-client-workflow.yaml | 10 +++++++++- .../activities/10-post-impl-review.yaml | 16 +++++++++++++--- work-package/techniques/naming-conventions.md | 18 ++++++++++++++---- .../techniques/audit-schema-validation.md | 10 ++++++---- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/meta/activities/03-dispatch-client-workflow.yaml b/meta/activities/03-dispatch-client-workflow.yaml index f3559bb05..f6492bc1d 100644 --- a/meta/activities/03-dispatch-client-workflow.yaml +++ b/meta/activities/03-dispatch-client-workflow.yaml @@ -1,5 +1,5 @@ id: dispatch-client-workflow -version: 5.7.0 +version: 5.8.0 name: Dispatch Client Workflow description: Drive the client workflow's activity loop, each worker carrying a bounded run of activities. required: true @@ -95,6 +95,13 @@ steps: - action: set target: worker_agent_id value: null + - kind: action + id: record-client-completion + when: current_activity == null + actions: + - action: set + target: client_workflow_completed + value: true transitions: - to: end-workflow condition: @@ -107,3 +114,4 @@ outcome: - Each worker carried a bounded run of activities in one context, so the harness baseline was paid once a run rather than once an activity - The user retained control over every decision point — checkpoints surfaced to them and their selections steered the workflow - The client workflow has no further activities to run, so the meta can proceed to close it out + - Reaching the end of the activity loop is recorded, so close-out can tell a completed run from one that stopped at the iteration bound diff --git a/work-package/activities/10-post-impl-review.yaml b/work-package/activities/10-post-impl-review.yaml index a89148837..e55606236 100644 --- a/work-package/activities/10-post-impl-review.yaml +++ b/work-package/activities/10-post-impl-review.yaml @@ -1,8 +1,15 @@ id: post-impl-review -version: 1.20.0 +version: 1.21.0 name: Post-Implementation Review description: Review implementation quality before validation. required: true +triggers: + - workflow: prism + description: Run the full analytical pipeline over the change surface when the problem is complex; a simpler one binds prism/structural-analysis inline instead. + passContext: + - target_path + - component_name + - issue_title steps: - kind: action id: announce-start @@ -76,10 +83,13 @@ steps: inputs: findings_destination: code-review.md when: problem_complexity != 'complex' - - kind: action + - kind: technique id: dispatch-prism when: problem_complexity == 'complex' - actions: [] + technique: + name: workflow-engine::handle-sub-workflow + inputs: + workflow_id: prism - kind: technique id: test-suite-review technique: review-test-suite diff --git a/work-package/techniques/naming-conventions.md b/work-package/techniques/naming-conventions.md index 2fe8dd297..b16a63e5b 100644 --- a/work-package/techniques/naming-conventions.md +++ b/work-package/techniques/naming-conventions.md @@ -1,6 +1,6 @@ --- metadata: - version: 1.0.0 + version: 1.1.0 --- ## Capability @@ -11,7 +11,7 @@ Derive the feature branch name and the canonical worktree target path for a work ### issue_type -The issue category (feature, bug, task, enhancement, epic) — drives the branch-name type prefix. +The issue category (feature, bug, task, enhancement, epic) — drives the branch-name type prefix through a total mapping, one prefix per category. ### issue_title @@ -42,9 +42,19 @@ Canonical feature-worktree path `/.worktrees//`, distinct from ` ## Protocol 1. Skip branch derivation when `{is_review_mode}` is `true` — `{branch_name}` was already captured from the PR reference. -2. Derive the branch-name type prefix from `{issue_type}`: feature → `feat`, bug → `fix`, task/enhancement → `chore`/`refactor` as appropriate. +2. Set `{$branch_type_prefix}` from `{issue_type}`, which is one of the five categories [issue-type-detection](./issue-type-detection.md) settles. The table is total, so no run supplies a prefix of its own: + + | `{issue_type}` | `{$branch_type_prefix}` | Why | + |---|---|---| + | `feature` | `feat` | delivers capability that was not there | + | `enhancement` | `feat` | delivers capability the user sees, on something already there | + | `epic` | `feat` | the epic's own delivery branch; its member tickets carry their own | + | `bug` | `fix` | restores stated behaviour | + | `task` | `chore` | maintenance with no change to capability | + + Stop and report when `{issue_type}` is unset, which is what an unsettled category leaves behind: the prefix is part of the branch and pull-request identity and is expensive to change once a pull request is open, so the category is the binding activity's gate to settle, never this step's to guess. 3. Slugify `{issue_title}` (lowercase, dashes, max ~40 chars) for the description segment. -4. Set `{branch_name}` to `{type}/{issue_number}-{slugified-title}` per the convention `type/issue-number-short-description`. +4. Set `{branch_name}` to `{$branch_type_prefix}/{issue_number}-{slugified-title}` per the convention `type/issue-number-short-description`. 5. Determine the work-package slug `{$wp_slug}` as the basename of `{planning_folder_path}` (the planning slug `YYYY-MM-DD-{initiative-name}`), so the worktree name stays aligned with the server's planning folder. In review mode, derive `{$wp_slug}` from the PR title or branch name instead. 6. Take `{$checkout_root}` as the ancestor of `{planning_folder_path}` above `.engineering/artifacts/planning/`, and set `{target_path}` to `{$checkout_root}/.worktrees/{$wp_slug}/` — the gitignored feature-worktree directory nested in the checkout. From this point on, "inside `{target_path}`" refers to this worktree (not the checkout at `{host_repo_path}`). Never place `{target_path}` under `{planning_folder_path}` or under `{host_repo_path}`, and never anchor it to a home directory or an install root. diff --git a/workflow-design/techniques/audit-schema-validation.md b/workflow-design/techniques/audit-schema-validation.md index 0fbb80baf..a3cb42196 100644 --- a/workflow-design/techniques/audit-schema-validation.md +++ b/workflow-design/techniques/audit-schema-validation.md @@ -1,6 +1,6 @@ --- metadata: - version: 1.1.0 + version: 1.2.0 --- ## Capability @@ -21,14 +21,16 @@ Count of YAML files that failed schema validation. ### 1. Validate YAML Schemas -- Run `npx tsx scripts/validate-workflow-yaml.ts ` on every YAML file (`workflow.yaml`, activity files, technique files) +- Run `npx tsx scripts/validate-workflow-yaml.ts ` on every YAML file (`workflow.yaml`, activity files, technique files), where `` is the workflow directory **inside the tree under review** - Record pass/fail per file with the validator's error message; resolve every failure - Set `{pass_count}` and `{fail_count}` ### 2. Check Technique References -- Run `npx tsx scripts/check-all-refs.ts` to verify every `step.technique` reference resolves through the loader +- Run `npx tsx scripts/check-all-refs.ts --root ` to verify every `step.technique` reference resolves through the loader +- `` is the corpus root of the tree under review. Every guard resolves its corpus as `--root` > `WORKFLOWS_DIR` > the server checkout's own `workflows/`, so an omitted root measures that checkout and reports a clean pass on definitions the review never looked at ### 3. Check Binding Fidelity -- Run `npx tsx scripts/check-binding-fidelity.ts` to verify the change introduces no new binding drift — every `step.technique.inputs` key is a declared input, and every interpolation/condition read resolves to a producer (a declared id, a dollar-prefixed step-local, a `workflow.yaml` variable, or a set-target). It fails only on violations beyond the committed baseline; if a flagged change is intentional, re-snapshot with `--update-baseline` +- Run `npx tsx scripts/check-binding-fidelity.ts --root ` to verify the change introduces no new binding drift — every `step.technique.inputs` key is a declared input, and every interpolation/condition read resolves to a producer (a declared id, a dollar-prefixed step-local, a `workflow.yaml` variable, or a set-target) +- A finding the guard has no verdict for is reported as untriaged. Give it one in `scripts/binding-fidelity-triage.json` — `harmless`, `fix-later`, or `live-bug`, each against a named rationale — so an accepted finding and a real defect stop being the same silence. Classification is a human judgement: there is no flag that suppresses a finding without one