(capsule)
| 389 | } |
| 390 | |
| 391 | function renderApprovalCapsule(capsule) { |
| 392 | const lines = [ |
| 393 | 'Citadel Approval Capsule', |
| 394 | '='.repeat(40), |
| 395 | `Generated: ${capsule.generatedAt}`, |
| 396 | `Project: ${capsule.projectRoot}`, |
| 397 | `Boundary: ${capsule.boundary}`, |
| 398 | `Risk: ${capsule.risk}`, |
| 399 | '', |
| 400 | 'Request', |
| 401 | capsule.request, |
| 402 | '', |
| 403 | 'Action', |
| 404 | ` Label: ${capsule.action.label}`, |
| 405 | ` Command: ${capsule.action.command}`, |
| 406 | ` Why: ${capsule.action.why}`, |
| 407 | ` Confidence: ${capsule.action.confidence}`, |
| 408 | ]; |
| 409 | |
| 410 | if (capsule.action.runbook) lines.push(` Runbook: ${capsule.action.runbook}`); |
| 411 | |
| 412 | lines.push(''); |
| 413 | lines.push('Context'); |
| 414 | lines.push(` Pending: docSync=${capsule.context.pending.docSync || 0}, mergeReviews=${capsule.context.pending.mergeReviews || 0}, intakeItems=${capsule.context.pending.intakeItems || 0}`); |
| 415 | lines.push(` Git dirty: ${capsule.context.gitStatus.dirty ? 'yes' : 'no'}`); |
| 416 | lines.push(` Actionable hook problems: ${capsule.context.problemSummary.actionable || 0}`); |
| 417 | if (capsule.context.campaigns.length === 0) { |
| 418 | lines.push(' Campaigns: none active'); |
| 419 | } else { |
| 420 | lines.push(' Campaigns:'); |
| 421 | for (const campaign of capsule.context.campaigns) { |
| 422 | lines.push(` - ${campaign.slug}: ${campaign.status}${campaign.phase ? ` (${campaign.phase})` : ''}`); |
| 423 | } |
| 424 | } |
| 425 | if (Array.isArray(capsule.context.stack) && capsule.context.stack.length > 0) { |
| 426 | lines.push(' Stack:'); |
| 427 | for (const [index, item] of capsule.context.stack.entries()) { |
| 428 | lines.push(` ${index + 1}. ${item.pr || item.branch} (${item.branch})`); |
| 429 | lines.push(` head=${item.head || '(unknown)'}, current=${item.currentHead || '(unknown)'}, readiness=${item.readiness || '(unknown)'}`); |
| 430 | if (item.report) lines.push(` report=${item.report}`); |
| 431 | } |
| 432 | } |
| 433 | |
| 434 | lines.push(''); |
| 435 | lines.push('Verification Plan'); |
| 436 | for (const item of capsule.verification) lines.push(` - ${item}`); |
| 437 | |
| 438 | if (Array.isArray(capsule.postApprovalRunbook) && capsule.postApprovalRunbook.length > 0) { |
| 439 | lines.push(''); |
| 440 | lines.push('Post-Approval Landing Runbook'); |
| 441 | for (const [index, item] of capsule.postApprovalRunbook.entries()) { |
| 442 | lines.push(` ${index + 1}. ${item.step}`); |
| 443 | lines.push(` Gate: ${item.gate}`); |
| 444 | lines.push(` Action: ${item.action}`); |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | lines.push(''); |
no outgoing calls
no test coverage detected