diff options
Diffstat (limited to 'makima/src/orchestration/directive.rs')
| -rw-r--r-- | makima/src/orchestration/directive.rs | 190 |
1 files changed, 161 insertions, 29 deletions
diff --git a/makima/src/orchestration/directive.rs b/makima/src/orchestration/directive.rs index 1e025c8..8b3ae7e 100644 --- a/makima/src/orchestration/directive.rs +++ b/makima/src/orchestration/directive.rs @@ -1604,11 +1604,21 @@ Because of this, you MUST chain steps using dependsOn whenever one step's work b If step B modifies files created/changed by step A, step B MUST list step A in its dependsOn — otherwise step B will start from a blank worktree and won't see step A's changes at all. -Guidelines: -- For sequential work, create a linear chain: step1 → step2 → step3 (each depends on the previous). -- Only omit dependsOn for truly independent steps that can start from a fresh checkout. -- Parallel steps that share no files can omit mutual dependencies, but if they both build on a prior step - they should BOTH list that prior step in dependsOn. +Guidelines (DAG SHAPE — READ CAREFULLY): +- DEFAULT TO STRICTLY LINEAR CHAINS: step1 → step2 → step3 → … each step depends on the previous one. + This is the right shape for almost every directive. A linear chain inherits each previous step's + worktree, so later steps can see and build on earlier work, and the final merge is just a fast-forward + with at most a rebase against the base branch. +- ONLY use parallel steps (same orderIndex, no mutual dependsOn) when the work is GENUINELY independent: + the steps modify completely disjoint files or modules AND neither needs the other's output. + Pure-frontend vs pure-backend work in separate folders is the prototypical example. If you can name + even one shared file or one shared concept, the steps must be sequential. +- WHEN IN DOUBT, MAKE IT SEQUENTIAL. The cost of unnecessary serialization is one extra step run. + The cost of unnecessary parallelism is merge conflicts, lost work, and a final PR that has to be + hand-reconciled — exactly the failure mode this rule exists to prevent. +- A directive with N parallel branches is suspicious; a directive with N+1 sequential steps is the norm. + If you find yourself drawing a diamond (A → {{B, C}} → D), strongly reconsider whether B and C are + actually independent or whether one should follow the other. IMPORTANT: Each step's taskPlan must be self-contained. The executing instance won't have your planning context. @@ -1709,6 +1719,11 @@ Goal: {goal} Steps completed: {step_summary} +NOTE: This directive was planned with the strict-linear-DAG rule, so the step branches +should generally merge cleanly. If a merge produces meaningful conflicts, that is a +signal the plan was wrong, not routine work — prefer asking for help over papering +over conflicts with `-X theirs`. + 1. Clear the old PR URL: ``` makima directive update --pr-url "" @@ -1720,7 +1735,6 @@ git fetch origin NEW_BRANCH="{directive_branch}-v$(date +%s)" git checkout -b "$NEW_BRANCH" origin/{base_branch} {merge_commands} -git push -u origin "$NEW_BRANCH" ``` For each step branch merge above, if a merge fails with conflicts: @@ -1728,7 +1742,47 @@ For each step branch merge above, if a merge fails with conflicts: 2. If that also fails, manually resolve the conflicts, `git add .`, and `git commit --no-edit` 3. Continue with remaining merges -3. Generate a descriptive PR title and create a new PR: +## Step 2.5: MANDATORY pre-push verification + +Before pushing or creating the PR, you MUST run all three of these checks. Skipping any +of them is a directive failure. + +a) Build check — make sure the combined branch compiles: + - Rust backend (if any backend files changed): `cd makima && cargo check` + - Frontend (if any frontend files changed): `cd makima/frontend && npm install && npx tsc --noEmit` + Fix any errors before continuing. Do NOT push broken code. + +b) Merge-conflict check — MANDATORY: +``` +makima directive verify --base {base_branch} +``` + This must exit 0. If it exits non-zero, the branch will not merge cleanly into + `{base_branch}` and the PR is not ready. Resolve by: +``` + git fetch origin {base_branch} + git merge origin/{base_branch} + # resolve any conflicts, then `git add . && git commit --no-edit` + makima directive verify --base {base_branch} +``` + Re-run until verify exits 0. Do NOT push, create a PR, or call `makima directive update` + until verify passes. + +c) Goal-alignment self-check: + Run `git diff origin/{base_branch}...HEAD --stat` and review the file list. Confirm + the diff actually delivers the directive goal: + + {goal} + + If the diff is missing work the goal requires, finish the work or call + `makima directive ask "<question>" --phaseguard` for guidance. Do NOT push a PR that + does not deliver the goal. + +3. Push the branch: +``` +git push -u origin "$NEW_BRANCH" +``` + +4. Generate a descriptive PR title and create a new PR: Based on the steps completed above, generate a descriptive PR title that summarizes the actual changes (not just the directive name "{title}"). The title should: - Be concise (under 72 characters) @@ -1741,13 +1795,13 @@ gh pr create --title "<YOUR_GENERATED_TITLE>" --body "{pr_body}" --head "$NEW_BR ``` Replace <YOUR_GENERATED_TITLE> with the concise descriptive title you generated. -4. Store the new PR URL: +5. Store the new PR URL: ``` makima directive update --pr-url "<URL_FROM_GH_PR_CREATE>" ``` Replace the URL with the actual PR URL from the `gh pr create` output. This step is CRITICAL. -5. Update the directive pr_branch to the new branch name: +6. Update the directive pr_branch to the new branch name: ``` makima directive update --pr-branch "$NEW_BRANCH" ``` @@ -1759,14 +1813,13 @@ The PR is still open. Merge new step branches into the existing PR branch. Steps completed: {step_summary} -Run these commands: +Run these commands to update the branch (note: do NOT push yet — verification comes first): ``` git fetch origin git checkout {directive_branch} git pull origin {directive_branch} git merge origin/{base_branch} --no-edit {merge_commands} -git push origin {directive_branch} ``` Already-merged branches will be a no-op. If a merge fails with conflicts: @@ -1774,6 +1827,33 @@ Already-merged branches will be a no-op. If a merge fails with conflicts: 2. If that also fails, manually resolve the conflicts, `git add .`, and `git commit --no-edit` 3. Continue with remaining merges +## MANDATORY pre-push verification (also applies to PR updates) + +Before `git push`, run all three checks. Skipping any of them is a directive failure. + +a) Build check — Rust: `cd makima && cargo check`. Frontend (if changed): + `cd makima/frontend && npm install && npx tsc --noEmit`. Do NOT push broken code. + +b) Merge-conflict check — MANDATORY: +``` +makima directive verify --base {base_branch} +``` + Must exit 0. If not, merge `origin/{base_branch}` in, resolve, commit, re-verify. + Do NOT push until verify passes. + +c) Goal-alignment self-check — review `git diff origin/{base_branch}...HEAD --stat` + and confirm it still delivers the directive goal: + + {goal} + + If the goal has drifted (e.g., new step branches changed scope), update the PR + description after pushing or call `makima directive ask` for guidance. + +Then push: +``` +git push origin {directive_branch} +``` + If you encounter issues you cannot resolve (e.g., persistent merge conflicts, PR update failures), you can ask for help: makima directive ask "Your question" --phaseguard "#, @@ -1800,17 +1880,65 @@ Goal: {goal} Steps completed: {step_summary} -Run these commands to create a combined branch and PR: +NOTE: This directive was planned with the strict-linear-DAG rule, so the step branches +should generally merge cleanly. If a merge produces meaningful conflicts, that is a +signal the plan was wrong, not routine work — prefer asking for help over papering +over conflicts with `-X theirs`. + +## Step 1: Build the combined branch (do NOT push yet) ``` git fetch origin git checkout -b {directive_branch} origin/{base_branch} {merge_commands} -git push -u origin {directive_branch} ``` -Then generate a descriptive PR title and create the PR: +For each step branch merge, if a merge fails with conflicts: +1. First try: `git merge --abort` then retry with `git merge <the-failing-branch> -X theirs --no-edit` +2. If that also fails, manually resolve the conflicts, `git add .`, and `git commit --no-edit` +3. Continue with remaining merges -Based on the steps completed above, generate a descriptive PR title that summarizes the actual changes (not just the directive name "{title}"). The title should: +## Step 2: MANDATORY pre-push verification + +Before pushing or creating the PR, you MUST run all three of these checks. Skipping any +of them is a directive failure. + +a) Build check — make sure the combined branch compiles: + - Rust backend (if any backend files changed): `cd makima && cargo check` + - Frontend (if any frontend files changed): `cd makima/frontend && npm install && npx tsc --noEmit` + Fix any errors before continuing. Do NOT push broken code. + +b) Merge-conflict check — MANDATORY: +``` +makima directive verify --base {base_branch} +``` + This must exit 0. If it exits non-zero, the branch will not merge cleanly into + `{base_branch}` and the PR is not ready. Resolve by: +``` + git fetch origin {base_branch} + git merge origin/{base_branch} + # resolve any conflicts, then `git add . && git commit --no-edit` + makima directive verify --base {base_branch} +``` + Re-run until verify exits 0. Do NOT push, create a PR, or call `makima directive update` + until verify passes. + +c) Goal-alignment self-check: + Run `git diff origin/{base_branch}...HEAD --stat` and review the file list. Confirm + the diff actually delivers the directive goal: + + {goal} + + If the diff is missing work the goal requires, finish the work or call + `makima directive ask "<question>" --phaseguard` for guidance. Do NOT push a PR that + does not deliver the goal. + +## Step 3: Push and create the PR +``` +git push -u origin {directive_branch} +``` + +Generate a descriptive PR title that summarizes the actual changes (not just the directive +name "{title}"). The title should: - Be concise (under 72 characters) - Describe WHAT was done, not just the project name - Use conventional commit style if appropriate (feat:, fix:, refactor:, etc.) @@ -1821,21 +1949,17 @@ gh pr create --title "<YOUR_GENERATED_TITLE>" --body "{pr_body}" --head {directi ``` Replace <YOUR_GENERATED_TITLE> with the concise descriptive title you generated. -IMPORTANT: After creating the PR, you MUST store the PR URL so the directive system can track it. +## Step 4: Store the PR URL (CRITICAL) + +After creating the PR, you MUST store the PR URL so the directive system can track it. -1. Run `gh pr create` as shown above and capture its output -2. The output will contain the PR URL (e.g., https://github.com/owner/repo/pull/123) -3. Then run this command to store the URL: +1. The `gh pr create` output contains the PR URL (e.g., https://github.com/owner/repo/pull/123) +2. Run: ``` makima directive update --pr-url "https://github.com/..." ``` Replace the URL with the actual PR URL from the `gh pr create` output. This step is CRITICAL — the PR will not be tracked by the directive system without it. -For each step branch merge, if a merge fails with conflicts: -1. First try: `git merge --abort` then retry with `git merge <the-failing-branch> -X theirs --no-edit` -2. If that also fails, manually resolve the conflicts, `git add .`, and `git commit --no-edit` -3. Continue with remaining merges - If you encounter issues you cannot resolve (e.g., persistent merge conflicts, PR creation failures), you can ask for help: makima directive ask "Your question" --phaseguard "#, @@ -2195,11 +2319,19 @@ Because of this, you MUST chain steps using dependsOn whenever one step's work b If step B modifies files created/changed by step A, step B MUST list step A in its dependsOn — otherwise step B will start from a blank worktree and won't see step A's changes at all. -Guidelines: -- For sequential work, create a linear chain: step1 → step2 → step3 (each depends on the previous). -- Only omit dependsOn for truly independent steps that can start from a fresh checkout. -- Parallel steps that share no files can omit mutual dependencies, but if they both build on a prior step - they should BOTH list that prior step in dependsOn. +Guidelines (DAG SHAPE — READ CAREFULLY): +- DEFAULT TO STRICTLY LINEAR CHAINS: step1 → step2 → step3 → … each step depends on the previous one. + This is the right shape for almost every directive. A linear chain inherits each previous step's + worktree, so later steps can see and build on earlier work, and the final merge is just a fast-forward + with at most a rebase against the base branch. +- ONLY use parallel steps (same orderIndex, no mutual dependsOn) when the work is GENUINELY independent: + the steps modify completely disjoint files or modules AND neither needs the other's output. + Pure-frontend vs pure-backend work in separate folders is the prototypical example. If you can name + even one shared file or one shared concept, the steps must be sequential. +- WHEN IN DOUBT, MAKE IT SEQUENTIAL. The cost of unnecessary serialization is one extra step run. + The cost of unnecessary parallelism is merge conflicts, lost work, and a final PR that has to be + hand-reconciled — exactly the failure mode this rule exists to prevent. +- A directive with N parallel branches is suspicious; a directive with N+1 sequential steps is the norm. IMPORTANT: Each step's taskPlan must be self-contained. The executing instance won't have your planning context. |
