-
Notifications
You must be signed in to change notification settings - Fork 4
feat: /titan-run orchestrator with diff review, semantic assertions, arch snapshots #557
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
fec01d4
33aabcc
41d664f
a16cf19
5f82586
fb539be
30fdd26
5511385
2fce690
3b6dccf
b0e5c30
bb37b52
f6a15cf
61035c2
ea192ea
f3d16a1
af56987
58f2238
5168c3d
9c1433a
1144217
a296b58
acee01f
1f74144
e5501fc
05a4281
5dded2f
15c051d
9274f3f
f37ec9e
058f027
9fe3b70
e4b6d9f
a6bb425
6f25000
4e8669c
ed4851c
5d259ac
ce85671
e5d8901
bef6a03
c36861d
cd51577
1f5cc23
512ba3c
cd07a93
5707a1f
d1d704b
054030e
112c062
57ea4d7
f3d637a
c3ccac8
095c198
30328fa
e2a1828
eb28018
3f6b519
b308512
862863d
d8bc686
382fbf6
7f45252
f92521d
e6ed6c6
7760313
27b76d5
b85ba9b
a3dd667
eace8d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| --- | ||
| name: titan-forge | ||
| description: Execute the sync.json plan — refactor code, validate with /titan-gate, commit, and advance state (Titan Paradigm Phase 4) | ||
| argument-hint: <--phase N> <--target name> <--dry-run> <--yes> | ||
| argument-hint: <--phase N> <--target name> <--dry-run> | ||
| allowed-tools: Bash, Read, Write, Edit, Glob, Grep, Skill, Agent | ||
| --- | ||
|
|
||
|
|
@@ -18,7 +18,7 @@ Your goal: read `sync.json`, find the next incomplete execution phase, make the | |
| - `--phase N` → jump to specific phase | ||
| - `--target <name>` → run single target only (for retrying failures) | ||
| - `--dry-run` → show what would be done without changing code | ||
| - `--yes` → skip confirmation prompt | ||
| - `--yes` → skip confirmation prompt (typically passed by `/titan-run` orchestrator) | ||
|
|
||
| --- | ||
|
|
||
|
|
@@ -55,7 +55,8 @@ Your goal: read `sync.json`, find the next incomplete execution phase, make the | |
| "failedTargets": [], | ||
| "commits": [], | ||
| "currentSubphase": null, | ||
| "completedSubphases": [] | ||
| "completedSubphases": [], | ||
| "diffWarnings": [] | ||
| } | ||
| } | ||
| ``` | ||
|
|
@@ -135,26 +136,101 @@ For each target in the current phase: | |
|
|
||
| 7. **Apply the change** based on phase strategy (Step 1) + gauntlet recommendation. | ||
|
|
||
| 8. **Run tests:** | ||
| 8. **Stage changed files:** | ||
| ```bash | ||
| npm test 2>&1 | ||
| git add <specific changed files> | ||
| ``` | ||
| If tests fail → go to rollback (step 11). | ||
|
|
||
| 9. **Run /titan-gate:** | ||
| Use the Skill tool to invoke `titan-gate`. If FAIL → go to rollback (step 11). | ||
| 9. **Diff review (intent verification):** | ||
| Before running gate or tests, verify the diff matches the intent. This catches cases where the code change is structurally valid but doesn't match what was planned. | ||
|
|
||
| 10. **On success:** | ||
| Collect the context: | ||
| ```bash | ||
| git diff --cached --stat | ||
| git diff --cached | ||
| ``` | ||
|
|
||
| Load the gauntlet entry for this target (from `gauntlet.ndjson`) and the sync plan entry (from `sync.json → executionOrder[currentPhase]`). | ||
|
|
||
| **Check all of the following:** | ||
|
|
||
| **D1. Scope — only planned files touched:** | ||
| Compare staged file paths against `sync.json → executionOrder[currentPhase].targets` and their known file paths (from gauntlet entries). Flag any file NOT associated with the current target or phase. | ||
| - File in a completely different domain → **DIFF FAIL** | ||
| - File is a direct dependency of the target (consumer or import) → **OK** (expected ripple) | ||
| - Test file for the target → **OK** | ||
|
|
||
| **D2. Intent match — diff aligns with gauntlet recommendation:** | ||
| First, check if this target is a dead-code target (present in `titan-state.json → roles.deadSymbols`). If so, the expected recommendation is "remove dead code" — skip gauntlet entry lookup (dead-code targets have no gauntlet.ndjson entry) and verify the diff shows only deletions (no new functions or logic added). If the diff contains non-trivial additions for a dead-code target → **DIFF FAIL**. | ||
|
|
||
| Otherwise, read the gauntlet entry's `recommendation` field and `violations` list. Verify the diff addresses them: | ||
| - If recommendation says "split" → diff should show new functions extracted, original simplified | ||
| - If recommendation says "remove dead code" → diff should show deletions, not additions | ||
| - If violation was "complexity > threshold" → diff should reduce complexity, not just move code around | ||
| - If the diff does something **entirely different** from the recommendation → **DIFF FAIL** | ||
|
|
||
| **D3. Commit message accuracy:** | ||
| Compare the planned commit message from `sync.json` against what the diff actually does. | ||
| - Message says "remove dead code" but diff adds new functions → **DIFF WARN** | ||
| - Message says "extract X from Y" but diff only modifies Y without creating X → **DIFF FAIL** | ||
|
|
||
| **D4. Deletion audit:** | ||
| If the diff deletes code (lines removed > 10), identify deleted symbols by comparing the pre-change file against removed lines: | ||
| ```bash | ||
| # Get the pre-change version's symbols (temp file for shell portability) | ||
| D4_PRE_TMP=$(mktemp /tmp/titan-d4-pre-XXXXXX) | ||
| git show HEAD:<changed-file> > "$D4_PRE_TMP" | ||
| codegraph where --file "$D4_PRE_TMP" -T --json 2>/dev/null | ||
| rm -f "$D4_PRE_TMP" | ||
| ``` | ||
| Cross-reference with `git diff --cached -- <changed-file>` to find symbols whose definitions appear only in removed lines (lines starting with `-`). For each deleted symbol: | ||
| ```bash | ||
| codegraph fn-impact <deleted-symbol> -T --json 2>/dev/null | ||
| ``` | ||
| If the deleted symbol has active callers not updated in this diff → **DIFF FAIL**: "Deleted <symbol> still has <N> callers not updated in this commit." | ||
|
|
||
| **D5. Leftover check:** | ||
| If the gauntlet recommendation mentioned specific symbols to remove/refactor, verify they were actually addressed: | ||
| - Dead symbols listed for removal but still present in the diff → **DIFF WARN**: "Gauntlet listed `<symbol>` for removal but it was not deleted." | ||
| - Functions marked for decomposition but original is unchanged → **DIFF WARN**: "Gauntlet recommended decomposing `<symbol>` but original function was not simplified." | ||
| - If all recommended symbols were addressed → **DIFF PASS** (implicit — no warnings emitted) | ||
|
|
||
| **On DIFF FAIL:** | ||
| ```bash | ||
| git reset HEAD <changed files> | ||
| git checkout -- <changed files> | ||
| ``` | ||
| Add to `execution.failedTargets` with reason starting with `"diff-review: "`. Continue to next target. | ||
| **On DIFF WARN:** Log the warning but proceed to gate. Include the warning in the gate-log entry. | ||
|
|
||
| 10. **Run tests** (detect the project's test command from package.json scripts — `npm test`, `yarn test`, `pnpm test`, etc.): | ||
| ```bash | ||
| <detected-test-command> 2>&1 | ||
| ``` | ||
| If tests fail → go to rollback (step 13). | ||
|
Comment on lines
+206
to
+210
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Step 10 runs the test suite: <detected-test-command> 2>&1Then Step 11 invokes The Step 10 pre-gate test run makes sense as a fast-fail optimization (failing before triggering all gate codegraph checks), but this tradeoff should be documented. Consider noting the rationale inline, or providing a way to skip the Step 10 test if the user prefers the gate to handle all checks (e.g., an environment variable or a The same applies to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Documented — added a Note block after Step 10 explaining the pre-gate test is a fast-fail optimization with the tradeoff: catches failures faster at the cost of 2x test time on passing targets. Applied to both copies. |
||
|
|
||
| > **Note:** Gate (Step 11) also runs tests. This pre-gate test is a fast-fail optimization — it catches obvious breakage before running the full gate checks (codegraph analysis, semantic assertions, arch snapshot). For projects with fast test suites the duplication is negligible; for slow suites, the tradeoff is: catch failures ~2x faster at the cost of ~2x test time on passing targets. | ||
|
|
||
| 11. **Run /titan-gate:** | ||
| Use the Skill tool to invoke `titan-gate`. | ||
| - If FAIL on **test/lint/build** (gate auto-rolls back staged changes) → go to rollback (step 13) to also revert working tree. | ||
| - If FAIL on **semantic/structural** (gate does not auto-rollback its staging area, but forge must clean up for the next target) → unstage with `git reset HEAD <files> && git checkout -- <files>`, add to `execution.failedTargets` with reason, log the gate report, and continue to the next target. Do NOT go to step 13 — that step is for test/gate failures where gate already unstaged; going there again would attempt a duplicate rollback. | ||
|
|
||
| 12. **On success:** | ||
| ```bash | ||
| git add <specific changed files> | ||
| git commit -m "<commit message from sync.json>" | ||
| ``` | ||
| - Record commit SHA in `execution.commits` | ||
| - Add target to `execution.completedTargets` | ||
| - Record any diff-review warnings in `execution.diffWarnings` (if any). Each entry must follow this schema: | ||
| ```json | ||
| { "target": "<target-name>", "check": "D1|D3|D5", "message": "<warning text>", "phase": N } | ||
| ``` | ||
| - Update `titan-state.json` | ||
|
|
||
| 11. **On failure (test or gate):** | ||
| 13. **On failure (test or gate):** | ||
| ```bash | ||
| git reset HEAD <changed files> | ||
| git checkout -- <changed files> | ||
| ``` | ||
| - Add to `execution.failedTargets` with reason: `{ "target": "<name>", "reason": "<why>", "phase": N }` | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
D2 reads "the gauntlet entry's
recommendationfield" for the current target. However, dead-code targets (deletions of unreferenced symbols) come fromtitan-state.json → roles.deadSymbolsidentified during RECON — they have nogauntlet.ndjsonentry. When forge processes one of these dead-code targets, D2 would find no matching entry and either skip the intent check or hallucinate the recommendation field, letting any diff pass without verification.V9 in titan-run already acknowledges this: "OR in
titan-state.json → roles.deadSymbols". D2 should have a corresponding guard:The same fix is needed in
docs/examples/claude-code-skills/titan-forge/SKILL.md.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed — D2 now checks if the target is in titan-state.json deadSymbols first. For dead-code targets, it skips gauntlet entry lookup and verifies the diff shows only deletions. Applied to both copies.