diff --git a/repo-readiness/SKILL.md b/repo-readiness/SKILL.md index 067f2ba..b4b595c 100644 --- a/repo-readiness/SKILL.md +++ b/repo-readiness/SKILL.md @@ -14,7 +14,10 @@ relevant focused skills or tools instead of duplicating their details. When the user asks whether work is done, ready to hand off, or safe to exit, use this skill first for gates and evidence, then use `work-closeout` for final hygiene, artifact cleanup, and durable parking state. Do not force a single -skill when both readiness and closeout are required. +skill when both readiness and closeout are required. A safe-to-exit, wrap-up, +pause, or handoff prompt must not end with a readiness-only final answer; the +final answer must come from `work-closeout` and include both `Love Gate` and +`Safe to exit`. ## Core Goal @@ -108,8 +111,9 @@ findings/status matter. 8. If security is in scope, use `security-review` explicitly; do not silently turn normal readiness into a full security audit. 9. Report readiness concisely. If the user asked for handoff, wrap-up, or - safe-to-exit, continue into `work-closeout` after the readiness answer is - established. + safe-to-exit, treat any readiness report as interim evidence and continue + into `work-closeout` after the readiness answer is established. The closeout + answer owns the final safe-to-exit verdict and must include `Love Gate`. ## Readiness To Closeout Handoff @@ -127,7 +131,8 @@ fields in chat, a PR comment, or the owning issue when durable state is needed: This handoff is evidence for `work-closeout`; it is not cleanup. Do not delete artifacts, remove worktrees, close planning issues, or claim safe-to-exit from -this skill alone. +this skill alone. If the user asked whether they can exit or stop, the final +response belongs to `work-closeout`, not this readiness handoff. Both this skill and `work-closeout` read `.github/github.json` with the same schema expectations: `qualityGate`, `docs`, `metadataFreshness`, `cleanup`, diff --git a/skill-creator/scripts/validate-skill-behavior.py b/skill-creator/scripts/validate-skill-behavior.py index 5386927..4c07381 100644 --- a/skill-creator/scripts/validate-skill-behavior.py +++ b/skill-creator/scripts/validate-skill-behavior.py @@ -1079,6 +1079,54 @@ def test_repo_readiness_and_work_closeout_share_handoff_contract() -> None: ) +def test_safe_exit_requires_love_gate_closeout() -> None: + readiness_text = (ROOT / "repo-readiness" / "SKILL.md").read_text().lower() + closeout_text = (ROOT / "work-closeout" / "SKILL.md").read_text().lower() + normalized_readiness = " ".join(readiness_text.split()) + normalized_closeout = " ".join(closeout_text.split()) + + require( + "must not end with a readiness-only final answer" in normalized_readiness + and "final answer must come from `work-closeout`" in normalized_readiness, + "repo-readiness must route safe-to-exit prompts to work-closeout for the final answer", + ) + require( + "the closeout answer owns the final safe-to-exit verdict and must include `love gate`" in normalized_readiness, + "repo-readiness must preserve Love Gate in safe-to-exit handoff guidance", + ) + require( + "this skill owns the final safe-to-exit answer" in normalized_closeout + and "must include both `love gate` and `safe to exit`" in normalized_closeout, + "work-closeout must own final safe-to-exit output and require Love Gate", + ) + require( + "safe-to-exit and closeout final answers must include a love gate section" in normalized_closeout + and "explicit `love:` and `do not love:` entries" in normalized_closeout, + "work-closeout frontmatter must expose the required Love Gate output shape", + ) + require( + "do not reduce love gate to `passed`, `ready`, or a generic approval sentence" in normalized_closeout, + "work-closeout must prevent pass/fail-only Love Gate summaries", + ) + require( + "any final answer to a safe-to-exit, wrap-up, closeout, pause, or handoff prompt" in normalized_closeout + and "is incomplete unless it includes a `love gate` section" in normalized_closeout, + "work-closeout must make Love Gate mandatory for closeout-style final answers", + ) + require( + "required love gate" in normalized_closeout + and "always include a brief \"love gate\" section" in normalized_closeout, + "work-closeout must make the Love Gate visibly required", + ) + require( + "must include two explicit labels" in normalized_closeout + and "`love:`" in normalized_closeout + and "`do not love:`" in normalized_closeout + and "nothing material" in normalized_closeout, + "work-closeout Love Gate must include explicit Love and Do not love entries", + ) + + def test_launchplane_delegates_github_surfaces() -> None: launchplane = (ROOT / "launchplane" / "SKILL.md").read_text().lower() normalized = " ".join(launchplane.split()) @@ -1382,6 +1430,7 @@ def main() -> None: test_github_cross_repo_pr_create_is_explicit, test_github_merges_land_through_prs, test_repo_readiness_and_work_closeout_share_handoff_contract, + test_safe_exit_requires_love_gate_closeout, test_launchplane_delegates_github_surfaces, test_code_readiness_requires_jetbrains_inspection_evidence, test_work_closeout_requires_issue_aware_safe_exit, diff --git a/work-closeout/SKILL.md b/work-closeout/SKILL.md index 7e395af..ae01928 100644 --- a/work-closeout/SKILL.md +++ b/work-closeout/SKILL.md @@ -1,6 +1,6 @@ --- name: work-closeout -description: Use when the user asks to wrap up, clean up, close out, pause, park, hand off, determine what remains before stopping, preserve plan direction for the next session, update or remove stale plans/handoffs, reconcile issue graph state, remove transient artifacts, or asks whether they can exit. Coordinates GitHub plan cleanup, safe git/worktree hygiene, artifact cleanup, and final state summaries. +description: Use when the user asks to wrap up, clean up, close out, pause, park, hand off, determine what remains before stopping, preserve plan direction for the next session, update or remove stale plans/handoffs, reconcile issue graph state, remove transient artifacts, or asks whether they can exit. Coordinates GitHub plan cleanup, safe git/worktree hygiene, artifact cleanup, and final state summaries. Safe-to-exit and closeout final answers must include a Love Gate section with explicit `Love:` and `Do not love:` entries before the safe-to-exit verdict. metadata: short-description: Close out workstreams cleanly --- @@ -14,7 +14,11 @@ question is whether checks pass or a PR can ship. When the user asks whether work is done, ready to hand off, or safe to exit, compose the skills in order: use `repo-readiness` first for gates and evidence, then use this skill for final hygiene, cleanup, and parking state. Do not force -a single skill when both readiness and closeout are required. +a single skill when both readiness and closeout are required. This skill owns +the final safe-to-exit answer, and that final answer must include both +`Love Gate` and `Safe to exit`. Do not reduce Love Gate to `passed`, `ready`, +or a generic approval sentence; write the two entries explicitly as `Love:` and +`Do not love:`. ## Core Goal @@ -146,6 +150,9 @@ Treat "safe to exit" as strict hygiene, not merely context preservation. Safe to exit means work is ready and hygiene is complete, or unfinished work is intentionally parked with durable state. +Any final answer to a safe-to-exit, wrap-up, closeout, pause, or handoff prompt +is incomplete unless it includes a `Love Gate` section. + Safe to exit: yes - Work is complete or explicitly out of scope. @@ -314,7 +321,7 @@ Treat these as external review context, not the active workstream. - If the user asks about a review result or review worktree specifically, switch context deliberately and inspect that worktree as the task target. -## The Love Gate +## Required Love Gate Before finalizing the closeout, perform a "Love Gate" check. This is an emotional and qualitative alignment step where the agent evaluates the session's @@ -327,8 +334,10 @@ standards. - **Identify what you do not love**: Are there any compromises, technical debt, missing edge cases, or "smells" that remain? Be honest about shortcuts taken due to context limits or task complexity. -- **Report findings**: Include a brief "Love Gate" section in your closeout - summary. +- **Report findings**: Always include a brief "Love Gate" section in closeout + and safe-to-exit final answers. The section must include two explicit labels: + `Love:` for what you love about the result, and `Do not love:` for concerns, + compromises, or "nothing material" when no meaningful concern remains. This gate ensures that the session ends not just with technical passing, but with a shared understanding of the work's quality and "soul." @@ -345,7 +354,8 @@ Use a compact closeout report: fits the active plan. - Checks: gates, inspections, docs, metadata, CI/Actions, and GitHub security/quality signals that passed, failed, were pending, or were not run. -- Love Gate: what you love about the results, and anything you do not love. +- Love Gate: include `Love:` and `Do not love:` entries. Use `Do not love: + nothing material` when no meaningful concern remains. - Cleanup: artifacts, plans, handoffs, branches, or worktrees removed or left intentionally. - State: dirty files, PR status, CI status, or plan status when relevant.