feat(ultraplan-local): v1.8.0 — close Opus 4.7 schema-drift gap
Opus 4.7 reads agent instructions more literally than 4.6. The v1.7 planning-orchestrator described the Step+Manifest schema via prose + procedural rules, which 4.6 inferred correctly but 4.7 sometimes rendered as narrative "Fase N" prose — producing plans ultraexecute Phase 2 rejected. First observed 2026-04-17 during llm-security v6.2.0 planning. v1.8.0 closes the gap: - planning-orchestrator Phase 5 embeds a literal copyable Step+Manifest example (JWT middleware) replacing "read the template" prose - Explicit forbidden-format clause: ## Fase N, ### Phase N, ### Stage N, and any non-"### Step N:" heading are denied - Phase 5.5 schema self-check: grep-verify canonical Step count matches Manifest count and narrative heading count is zero, before handing to plan-critic - ultraexecute-local --validate mode: schema-only check that parses steps + manifests, reports READY/FAIL with actionable error hints, no security scan, no execution. Fast sanity check between /ultraplan-local and full execution. Static verification: 17/17 PASS. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
9f893c3858
commit
9ecd66929c
7 changed files with 203 additions and 9 deletions
|
|
@ -191,6 +191,62 @@ the title. This signals to ultraexecute-local that the plan includes per-step
|
|||
verification manifests and enables strict audit mode. Plans without this
|
||||
marker are treated as legacy v1.6 with synthesized minimal manifests.
|
||||
|
||||
### Mandatory step format — copy this exactly
|
||||
|
||||
The Implementation Plan section MUST contain numbered steps using the EXACT
|
||||
format shown below. The executor (`ultraexecute-local`) parses plans with
|
||||
strict regex matching. Any deviation breaks parsing and forces the user to
|
||||
re-run planning.
|
||||
|
||||
**FORBIDDEN heading formats** (the executor's parser rejects these):
|
||||
- `## Fase 1`, `### Fase 1` — Norwegian narrative format
|
||||
- `## Phase 1`, `### Phase 1` — narrative phase format
|
||||
- `## Stage 1`, `### Stage 1` — narrative stage format
|
||||
- `### 1.` or `### 1)` — numbered without "Step"
|
||||
- `### Step 1 —` (em-dash instead of colon)
|
||||
- Any heading that doesn't match the regex `^### Step \d+: `
|
||||
|
||||
**REQUIRED heading format:** `### Step N: <description>` (where N is 1, 2, 3, ...
|
||||
and the colon is followed by a single space then the description).
|
||||
|
||||
**REQUIRED step body** — every step MUST include all of these fields, in this
|
||||
order, formatted as bullet points:
|
||||
|
||||
```markdown
|
||||
### Step 1: Add JWT verification middleware
|
||||
|
||||
- **Files:** `src/middleware/jwt.ts`
|
||||
- **Changes:** Create new middleware function `verifyJWT(req, res, next)` that reads `Authorization: Bearer <token>` header, verifies signature with `process.env.JWT_SECRET`, attaches decoded payload to `req.user`, and returns 401 on invalid/missing token. (new file)
|
||||
- **Reuses:** `jsonwebtoken.verify()` (already in package.json), pattern from `src/middleware/cors.ts`
|
||||
- **Test first:**
|
||||
- File: `src/middleware/jwt.test.ts` (new)
|
||||
- Verifies: valid token attaches user; invalid token returns 401; missing header returns 401
|
||||
- Pattern: `src/middleware/cors.test.ts` (follow this style)
|
||||
- **Verify:** `npm test -- jwt.test.ts` → expected: `3 passing`
|
||||
- **On failure:** revert — `git checkout -- src/middleware/jwt.ts src/middleware/jwt.test.ts`
|
||||
- **Checkpoint:** `git commit -m "feat(auth): add JWT verification middleware"`
|
||||
- **Manifest:**
|
||||
```yaml
|
||||
manifest:
|
||||
expected_paths:
|
||||
- src/middleware/jwt.ts
|
||||
- src/middleware/jwt.test.ts
|
||||
min_file_count: 2
|
||||
commit_message_pattern: "^feat\\(auth\\): add JWT verification middleware$"
|
||||
bash_syntax_check: []
|
||||
forbidden_paths:
|
||||
- src/middleware/cors.ts
|
||||
must_contain:
|
||||
- path: src/middleware/jwt.ts
|
||||
pattern: "verifyJWT"
|
||||
```
|
||||
```
|
||||
|
||||
The example above is the canonical shape. Substitute your own file paths,
|
||||
descriptions, and patterns — but preserve the exact heading format, bullet
|
||||
field names, and Manifest YAML structure. Do not invent new field names. Do
|
||||
not skip fields. Do not nest steps under sub-headings.
|
||||
|
||||
### Manifest generation rules (REQUIRED for every step)
|
||||
|
||||
Every implementation step MUST include a `Manifest:` block as its last field,
|
||||
|
|
@ -230,6 +286,32 @@ Derive the manifest fields mechanically from the step's other fields:
|
|||
|
||||
If any validation fails, fix the plan before handing to Phase 6 review.
|
||||
|
||||
### Phase 5.5 — Schema self-check (REQUIRED before Phase 6)
|
||||
|
||||
After writing the plan file, verify the output conforms to the executor's
|
||||
parser BEFORE handing to plan-critic. Use Bash to grep the plan file:
|
||||
|
||||
```bash
|
||||
# Count canonical step headings
|
||||
grep -c '^### Step [0-9]\+: ' "$plan_path"
|
||||
|
||||
# Count manifest blocks
|
||||
grep -c '^ manifest:' "$plan_path"
|
||||
|
||||
# Detect forbidden narrative formats
|
||||
grep -cE '^(##|###) (Fase|Phase|Stage) [0-9]' "$plan_path"
|
||||
```
|
||||
|
||||
**Pass criteria:**
|
||||
- Step count ≥ 1
|
||||
- Manifest count == Step count
|
||||
- Forbidden narrative count == 0
|
||||
|
||||
**If the plan fails schema self-check:** rewrite the Implementation Plan
|
||||
section using the exact literal template shown earlier in Phase 5. Do NOT
|
||||
proceed to Phase 6 with a schema-failing plan — plan-critic cannot repair
|
||||
format drift, only content issues.
|
||||
|
||||
### Failure recovery (REQUIRED for every step)
|
||||
|
||||
Each implementation step MUST include:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue