Files
Claude-Code-Workflow/.codex/skills/analyze-with-file/EXECUTE.md
catlog22 80ab955f8b fix(skills): respect tab=hub URL parameter in SkillsManagerPage
- Read URL tab parameter using useSearchParams
- Initialize locationFilter to 'hub' when tab=hub is present
- Allows /skill-hub route to correctly display hub content
2026-02-24 19:12:45 +08:00

12 KiB

Analyze Task Generation Spec

Purpose: Quality standards for converting conclusions.json recommendations into .task/*.json files. Consumer: Phase 5 of analyze-with-file workflow. Execution: Handled by unified-execute-with-file — this document covers generation only.


Task Generation Flow

conclusions.json ──┐
                   ├── resolveTargetFiles() ──┐
codebaseContext ───┘                          ├── .task/TASK-001.json
                                              ├── .task/TASK-002.json
explorations.json ── enrichContext() ─────────┘

Input artifacts (all from session folder):

Artifact Required Provides
conclusions.json Yes recommendations[] with action, rationale, priority, target_files, changes, implementation_hints, evidence_refs
exploration-codebase.json No relevant_files[], patterns[], constraints[], integration_points[] — primary source for file resolution
explorations.json No sources[], key_findings[] — fallback for file resolution
perspectives.json No Multi-perspective findings — alternative to explorations.json

File Resolution Algorithm

Target files are resolved with a 3-priority fallback chain:

function resolveTargetFiles(rec, codebaseContext, explorations) {
  // Priority 1: Explicit target_files from recommendations (Phase 4 enriched)
  if (rec.target_files?.length) {
    return rec.target_files.map(path => ({
      path,
      action: 'modify',
      target: null,
      changes: rec.changes || []
    }))
  }

  // Priority 2: Match from exploration-codebase.json relevant_files
  if (codebaseContext?.relevant_files?.length) {
    const keywords = extractKeywords(rec.action + ' ' + rec.rationale)
    const matched = codebaseContext.relevant_files.filter(f =>
      keywords.some(kw =>
        f.path.toLowerCase().includes(kw) ||
        f.summary?.toLowerCase().includes(kw) ||
        f.relevance?.toLowerCase().includes(kw)
      )
    )
    if (matched.length) {
      return matched.map(f => ({
        path: f.path,
        action: 'modify',
        target: null,
        changes: rec.changes || []
      }))
    }
  }

  // Priority 3: Match from explorations.json sources
  if (explorations?.sources?.length) {
    const actionVerb = rec.action.split(' ')[0].toLowerCase()
    const matched = explorations.sources.filter(s =>
      s.summary?.toLowerCase().includes(actionVerb) ||
      s.file?.includes(actionVerb)
    )
    if (matched.length) {
      return matched.map(s => ({
        path: s.file,
        action: 'modify',
        target: null,
        changes: []
      }))
    }
  }

  // Fallback: empty array — task relies on description + implementation for guidance
  return []
}

function extractKeywords(text) {
  return text
    .toLowerCase()
    .replace(/[^a-z0-9\u4e00-\u9fa5\s]/g, ' ')
    .split(/\s+/)
    .filter(w => w.length > 2)
    .filter(w => !['the', 'and', 'for', 'with', 'from', 'that', 'this'].includes(w))
}

Task Type Inference

Recommendation Pattern Inferred Type
fix, resolve, repair, patch, correct fix
refactor, restructure, extract, reorganize, decouple refactor
add, implement, create, build, introduce feature
improve, optimize, enhance, upgrade, streamline enhancement
test, coverage, validate, verify, assert testing
function inferTaskType(rec) {
  const text = (rec.action + ' ' + rec.rationale).toLowerCase()
  const patterns = [
    { type: 'fix',         keywords: ['fix', 'resolve', 'repair', 'patch', 'correct', 'bug'] },
    { type: 'refactor',    keywords: ['refactor', 'restructure', 'extract', 'reorganize', 'decouple'] },
    { type: 'feature',     keywords: ['add', 'implement', 'create', 'build', 'introduce'] },
    { type: 'enhancement', keywords: ['improve', 'optimize', 'enhance', 'upgrade', 'streamline'] },
    { type: 'testing',     keywords: ['test', 'coverage', 'validate', 'verify', 'assert'] }
  ]
  for (const p of patterns) {
    if (p.keywords.some(kw => text.includes(kw))) return p.type
  }
  return 'enhancement'  // safe default
}

Effort Inference

Signal Effort
priority=high AND files >= 3 large
priority=high OR files=2 medium
priority=medium AND files <= 1 medium
priority=low OR single file small
function inferEffort(rec) {
  const fileCount = rec.target_files?.length || 0
  if (rec.priority === 'high' && fileCount >= 3) return 'large'
  if (rec.priority === 'high' || fileCount >= 2) return 'medium'
  if (rec.priority === 'low' || fileCount <= 1) return 'small'
  return 'medium'
}

Convergence Quality Validation

Every task's convergence MUST pass quality gates before writing to disk.

Quality Rules

Field Requirement Validation
criteria[] Testable — assertions or concrete manual steps Reject vague patterns; each criterion must reference observable behavior
verification Executable — shell command or explicit step sequence Must contain a runnable command or step-by-step verification procedure
definition_of_done Business language — non-technical stakeholder can judge Must NOT contain technical commands (jest, tsc, npm, build)

Vague Pattern Detection

const VAGUE_PATTERNS = /正常|正确|好|可以|没问题|works|fine|good|correct|properly|as expected/i
const TECHNICAL_IN_DOD = /compile|build|lint|npm|npx|jest|tsc|eslint|cargo|pytest|go test/i

function validateConvergenceQuality(tasks) {
  const issues = []
  tasks.forEach(task => {
    // Rule 1: No vague criteria
    task.convergence.criteria.forEach((c, i) => {
      if (VAGUE_PATTERNS.test(c) && c.length < 20) {
        issues.push({
          task: task.id, field: `criteria[${i}]`,
          problem: 'Vague criterion', value: c,
          fix: 'Replace with specific observable condition from evidence'
        })
      }
    })

    // Rule 2: Verification should be executable
    if (task.convergence.verification && task.convergence.verification.length < 5) {
      issues.push({
        task: task.id, field: 'verification',
        problem: 'Too short to be executable', value: task.convergence.verification,
        fix: 'Provide shell command or numbered step sequence'
      })
    }

    // Rule 3: DoD should be business language
    if (TECHNICAL_IN_DOD.test(task.convergence.definition_of_done)) {
      issues.push({
        task: task.id, field: 'definition_of_done',
        problem: 'Contains technical commands', value: task.convergence.definition_of_done,
        fix: 'Rewrite in business language describing user/system outcome'
      })
    }

    // Rule 4: files[].changes should not be empty when files exist
    task.files?.forEach((f, i) => {
      if (f.action === 'modify' && (!f.changes || f.changes.length === 0) && !f.change) {
        issues.push({
          task: task.id, field: `files[${i}].changes`,
          problem: 'No change description for modify action', value: f.path,
          fix: 'Describe what specifically changes in this file'
        })
      }
    })

    // Rule 5: implementation steps should exist
    if (!task.implementation || task.implementation.length === 0) {
      issues.push({
        task: task.id, field: 'implementation',
        problem: 'No implementation steps',
        fix: 'Add at least one step describing how to realize this task'
      })
    }
  })

  // Auto-fix where possible, log remaining issues
  issues.forEach(issue => {
    // Attempt auto-fix based on available evidence
    // If unfixable, log warning — task still generated but flagged
  })
  return issues
}

Good vs Bad Examples

Criteria:

Bad Good
"Code works correctly" "refreshToken() returns a new JWT with >0 expiry when called with expired token"
"No errors" "Error handler at auth.ts:45 returns 401 status with { error: 'token_expired' } body"
"Performance is good" "API response time < 200ms at p95 for /api/users endpoint under 100 concurrent requests"

Verification:

Bad Good
"Check it" "jest --testPathPattern=auth.test.ts && npx tsc --noEmit"
"Run tests" "1. Run npm test -- --grep 'token refresh' 2. Verify no TypeScript errors with npx tsc --noEmit"

Definition of Done:

Bad Good
"jest passes" "Users remain logged in across token expiration without manual re-login"
"No TypeScript errors" "Authentication flow handles all user-facing error scenarios with clear error messages"

Required Task Fields (analyze-with-file producer)

Per task-schema.json _field_usage_by_producer, the analyze-with-file producer MUST populate:

Block Fields Required
IDENTITY id, title, description Yes
CLASSIFICATION type, priority, effort Yes
DEPENDENCIES depends_on Yes (empty array if none)
CONVERGENCE convergence.criteria[], convergence.verification, convergence.definition_of_done Yes
FILES files[].path, files[].action, files[].changes/files[].change Yes (if files identified)
IMPLEMENTATION implementation[] with step + description Yes
CONTEXT evidence, source.tool, source.session_id, source.original_id Yes

Task JSON Example

{
  "id": "TASK-001",
  "title": "Fix authentication token refresh",
  "description": "Token refresh fails silently when JWT expires, causing users to be logged out unexpectedly",
  "type": "fix",
  "priority": "high",
  "effort": "medium",
  "files": [
    {
      "path": "src/auth/token.ts",
      "action": "modify",
      "target": "refreshToken",
      "changes": [
        "Add await to refreshToken() call at line 89",
        "Add error propagation for refresh failure"
      ],
      "change": "Add await to refreshToken() call and propagate errors"
    },
    {
      "path": "src/middleware/auth.ts",
      "action": "modify",
      "target": "authMiddleware",
      "changes": [
        "Update error handler at line 45 to distinguish refresh failures from auth failures"
      ],
      "change": "Update error handler to propagate refresh failures"
    }
  ],
  "depends_on": [],
  "convergence": {
    "criteria": [
      "refreshToken() returns new valid JWT when called with expired token",
      "Expired token triggers automatic refresh without user action",
      "Failed refresh returns 401 with { error: 'token_expired' } body"
    ],
    "verification": "jest --testPathPattern=token.test.ts && npx tsc --noEmit",
    "definition_of_done": "Users remain logged in across token expiration without manual re-login"
  },
  "implementation": [
    {
      "step": "1",
      "description": "Add await to refreshToken() call in token.ts",
      "actions": ["Read token.ts", "Add await keyword at line 89", "Verify async chain"]
    },
    {
      "step": "2",
      "description": "Update error handler in auth middleware",
      "actions": ["Read auth.ts", "Modify error handler at line 45", "Add refresh-specific error type"]
    }
  ],
  "evidence": ["src/auth/token.ts:89", "src/middleware/auth.ts:45"],
  "source": {
    "tool": "analyze-with-file",
    "session_id": "ANL-auth-token-refresh-2025-01-21",
    "original_id": "TASK-001"
  }
}

Execution Delegation

After .task/*.json generation, execution is handled by unified-execute-with-file:

/codex:unified-execute-with-file PLAN="${sessionFolder}/.task/"

The execution engine provides:

  • Pre-execution analysis (dependency validation, file conflicts, topological sort)
  • Serial task execution with convergence verification
  • Progress tracking via execution.md + execution-events.md
  • Auto-commit per task (conventional commit format)
  • Failure handling with retry/skip/abort options

No inline execution logic in analyze-with-file — single execution engine avoids duplication and ensures consistent behavior across all skill producers.