feat(evolution): Kilo Code release sync & APAW system hardening (v2026-05-07)

Security & Permissions:
- All 30 agents: task[*]=deny, task[subagent]=deny (cascade prevention)
- orchestrator & release-manager: bash=ask (hardening)
- New .kilo/rules/subagent-security.md with audit rules
- Updated .kilo/rules/global.md with Security & Permissions section
- Updated .kilo/agents/orchestrator.md with Security Enforcement block

Session Management:
- New .kilo/rules/session-persistence.md (checkpoint format, worktree isolation)
- Updated .kilo/rules/branch-strategy.md (worktree per agent)
- pipeline-runner.ts: Checkpoint interface + save/load/resume methods

Plan Persistence:
- Updated .kilo/rules/lead-developer.md (plan handover section)

Per-Agent Reasoning:
- capability-index.yaml: reasoning_effort for all 30 agents (xhigh/high/medium/low)

MCP Cleanup:
- New .kilo/skills/docker-security/SKILL.md (--rm, orphaned process cleanup)

Config Validation:
- Updated .kilo/rules/docker.md (startup checks, commit scoping, location awareness)

Docs:
- README.md: v2026-05-07 evolution badges
- .kilo/EVOLUTION_LOG.md: Entry #6 with full metrics
- .gitignore: ignore dist/ + bun.lock

Gitea: Milestone #66, Issues #91-#98
Architect: 9/9 sections fresh (express project type)
This commit is contained in:
NW
2026-05-08 18:54:08 +01:00
parent 74ad7c4b6e
commit f01e2064fb
18 changed files with 1951 additions and 2237 deletions

View File

@@ -22,6 +22,8 @@ import {
logAgentPerformance,
detectRepository
} from "./gitea-client"
import * as fs from "fs"
import * as path from "path"
export interface PipelineConfig {
giteaToken?: string
@@ -46,6 +48,16 @@ export interface PipelineResult {
errors: string[]
}
export interface Checkpoint {
issueNumber: number
phase: string
agentName: string
filesModified: string[]
status: string
timestamp: string
nextAgent: string | null
}
export class PipelineRunner {
private client: GiteaClient
private efficiencyThreshold: number
@@ -246,6 +258,57 @@ export class PipelineRunner {
relatedIssues: minedIssues,
}
}
async saveCheckpoint(checkpoint: Checkpoint): Promise<void> {
// Ensure the checkpoints directory exists
const checkpointDir = path.join(process.cwd(), '.kilo', 'logs', 'checkpoints');
if (!fs.existsSync(checkpointDir)) {
fs.mkdirSync(checkpointDir, { recursive: true });
}
// Save the checkpoint as JSON
const filename = `${checkpoint.issueNumber}-${checkpoint.phase}.json`;
const filepath = path.join(checkpointDir, filename);
fs.writeFileSync(filepath, JSON.stringify(checkpoint, null, 2));
}
async loadCheckpoint(issueNumber: number): Promise<Checkpoint | null> {
const checkpointDir = path.join(process.cwd(), '.kilo', 'logs', 'checkpoints');
// Check if directory exists
if (!fs.existsSync(checkpointDir)) {
return null;
}
// Find the latest checkpoint file for this issue
const files = fs.readdirSync(checkpointDir);
const issueFiles = files.filter(file =>
file.startsWith(`${issueNumber}-`) && file.endsWith('.json')
);
if (issueFiles.length === 0) {
return null;
}
// Sort by modification time to get the latest
const sortedFiles = issueFiles.sort((a, b) => {
const statA = fs.statSync(path.join(checkpointDir, a));
const statB = fs.statSync(path.join(checkpointDir, b));
return statB.mtime.getTime() - statA.mtime.getTime();
});
const latestFile = sortedFiles[0];
const filepath = path.join(checkpointDir, latestFile);
const content = fs.readFileSync(filepath, 'utf8');
return JSON.parse(content) as Checkpoint;
}
async resumeFromCheckpoint(issueNumber: number): Promise<string | null> {
const checkpoint = await this.loadCheckpoint(issueNumber);
return checkpoint ? checkpoint.nextAgent : null;
}
}
export async function createPipelineRunner(config?: PipelineConfig): Promise<PipelineRunner> {