| 220 | * write-back behavior without any template changes. |
| 221 | */ |
| 222 | export function generateBrainWriteBack(ctx: TemplateContext): string { |
| 223 | if (!isPreflightSkill(ctx.skillName)) return ''; |
| 224 | const weight = SKILL_CALIBRATION_WEIGHTS[ctx.skillName]; |
| 225 | if (weight == null) return ''; |
| 226 | // List the cache digests this skill's writes should invalidate. Multiple |
| 227 | // skills write to multiple entities; the invalidation map captures this. |
| 228 | const invalidatesEntities = getInvalidationTargets(`/${ctx.skillName}`); |
| 229 | const invalidateBash = invalidatesEntities |
| 230 | .map((e) => ` ${ctx.paths.binDir}/gstack-brain-cache invalidate ${e} --project "$SLUG" 2>/dev/null || true`) |
| 231 | .join('\n'); |
| 232 | |
| 233 | return `## Brain Calibration Write-Back (Phase 2 / gated) |
| 234 | |
| 235 | When the skill makes a typed prediction worth tracking (scope decision, |
| 236 | TTHW target, architectural bet, wedge commitment), it MAY write a |
| 237 | \`kind=bet\` take to the brain so a calibration profile builds over time. |
| 238 | |
| 239 | **Gated on two things:** |
| 240 | 1. Brain trust policy for the active endpoint is \`personal\` (check via |
| 241 | \`${ctx.paths.binDir}/gstack-config get brain_trust_policy@<endpoint-hash>\`). |
| 242 | Shared brains skip write-back to avoid polluting team calibration. |
| 243 | 2. Feature flag \`BRAIN_CALIBRATION_WRITEBACK\` is set (today: false; flips |
| 244 | to true when upstream gbrain v0.42+ ships \`takes_add\` MCP op). |
| 245 | |
| 246 | When both gates pass, the write-back path uses \`mcp__gbrain__takes_add\` |
| 247 | to record a take with weight ${weight} (per SKILL_CALIBRATION_WEIGHTS). |
| 248 | If the MCP op is unavailable, fall back to \`mcp__gbrain__put_page\` with |
| 249 | a gstack:takes fence block (documented but uglier path). |
| 250 | |
| 251 | Mandatory take frontmatter shape: |
| 252 | \`\`\`yaml |
| 253 | kind: bet |
| 254 | holder: <user identity from whoami> |
| 255 | claim: <one-line prediction the skill is making> |
| 256 | weight: ${weight} |
| 257 | since_date: <today's date> |
| 258 | expected_resolution: <date in 1-3 months depending on skill> |
| 259 | source_skill: ${ctx.skillName} |
| 260 | \`\`\` |
| 261 | |
| 262 | After write, invalidate the affected digests so the next preflight reflects |
| 263 | the new state: |
| 264 | |
| 265 | \`\`\`bash |
| 266 | eval "$(${ctx.paths.binDir}/gstack-slug 2>/dev/null)" 2>/dev/null || true |
| 267 | ${invalidateBash || ' # (no per-skill invalidation targets configured)'} |
| 268 | \`\`\` |
| 269 | `; |
| 270 | } |