feat(skills): add a create-skill button to capture a session during chat - #5973
feat(skills): add a create-skill button to capture a session during chat#5973RolianTan wants to merge 1 commit into
Conversation
|
👋 Hi! This PR's description is missing some required sections from our PR template. Workflow runs won't be auto-approved until the description is updated. Missing sections:
Please update your PR description to include these sections, then push or re-save the description. The workflows will be approved on the next cycle. |
e08099d to
e31f29c
Compare
Design Review (Fable 5, fork) — 🟡 CONCERNSDesign-level review of I've verified the base-code cascade: with Design-Verdict: CONCERNS Sound capture design, but the "fire-and-forget" pitch and the approval-gated security posture collide in a silently-failing background path. Watch
Suggestions
[DESIGN-REVIEWED] c997aac |
First Principles Review (Fable 5, fork) — 🟡 CONCERNSPremise-level review of I've verified everything against the trusted base. Key facts established: the base already ships the First-Principles-Verdict: CONCERNS "There is no in-chat way to capture one as a skill" is false — What this change shipsIntent: let the owner capture the current chat session as a reviewed, reusable skill without interrupting it — an ADDITION.
Watch
Subtractions
[FIRST-PRINCIPLES-REVIEWED] c997aac |
Opus 4.8 Review (fork) — ✅ no blocking findingsReviewed Review detailsI've validated the single candidate against the code. Candidate 1 (memory/lessons/project injected into the authoring subagent): the claimed wrong outcome — private memory content ending up embedded in the staged skill — dies under falsification. The subagent runs I also examined the No findings. [OPUS-REVIEWED] c997aac |
GPT 5.6 Review (fork) — 🔴 changes requested (blocking)Reviewed BLOCKING -- src/kiro_crew/dashboard/handlers/create_skill.py:212 -- Spawn mode leaves static tool grants unattended FINDING -- src/kiro_crew/dashboard/handlers/create_skill.py:189 -- FINDING -- website/src/pages/ChatPage.tsx:5386 -- direct |
e31f29c to
c997aac
Compare
UX Review (Fable 5, fork) — 🟡 CONCERNSUX-level review of All evidence gathered. The success path is fully silent: the subagent spawns with UX-Verdict: CONCERNS Success is completely silent: the modal just closes, the subagent is Watch
Suggestions
[UX-REVIEWED] c997aac |
|
🤖 Kiro Crew [operator: bolichen97#66809557]: Security scan flagged this PR for manual review. Findings:
A maintainer will review before any automated action is taken. (Separately, the GPT 5.6 blocking finding on |
Open PR relationship auditThis is a consolidated, point-in-time code-level audit note. It compares complete merge-base diffs and current/merged code; it does not treat a shared topic as duplication or partial coverage as completion. Relationship findings
No PR, Issue, label, branch, or review state was changed by the relationship-note portion of this audit. |
Add a "Create skill" action to the chat header's session actions menu. It opens a small modal for a required one-line purpose; submitting hands the current session to a fire-and-forget background subagent that follows the crystallize skill and stages a candidate for review, so authoring never blocks the chat. Backend: owner-only POST /api/skills/-/from-session shapes the session transcript, injects the required purpose (empty is rejected), and spawns the subagent. The subagent is spawned with approval_mode="spawn": the spawn is authorized because the owner triggered it, but its tool calls stay approval-gated and it does NOT inherit a trusted parent's auto policy, because it acts on an untrusted transcript. Permission denials emit a SEL audit event. Private sessions are refused -- incognito/temporary, plus a linked channel session (e.g. a Slack thread set to !incognito) via the session's canonical restriction state rather than the dashboard slot's memory_mode. A "manual" skill namespace keeps user-initiated captures separate from auto-generated ones: approve_pending_skill reads the candidate's namespace and promotes it to manual/<slug> (default stays auto/<slug>). Frontend: the session-menu item plus the purpose modal, wired through ChatPage to api.createSkillFromSession, with the input opted out of password-manager autofill decorations. Strings added to all twelve catalogs and the en-XA pseudolocale. Docs: the subagent and memory-skills-hooks specs are updated in the same commit.
c997aac to
25a1193
Compare
|
Rebased onto main Conflicts, all mechanical relocations with no behaviour change:
Gates run locally: black/isort/flake8 on changed files, pytest on the touched test files (150 passed), Please review the resolution. A maintainer push makes the maintainer the last pusher, so a second approver is needed. Reply if anything looks wrong. |
Problem / Motivation
Reusable procedures emerge inside chat sessions, but there is no in-chat way to capture one as a skill. To turn "what I just did" into a reusable Kiro Crew skill today, a user has to break out of the conversation and hand-author the skill later from memory — so most of that value is simply lost when the chat moves on.
Why it matters
Letting the owner bank a skill the moment they recognize one — without interrupting the running session — is where the payoff is. It also keeps user-captured skills in their own
manual/namespace, cleanly separated from auto-generatedauto/skills, and routes them through the existing pending-review flow so nothing goes live unreviewed.What changed (motivation → approach → change)
Goal: let the owner capture the current session as a reusable skill from the chat UI, without interrupting the session.
Approach: a session-level menu action (it captures the whole session, so it belongs in the session menu, not on one message) that fires a background authoring subagent and returns immediately, staging a candidate for review rather than writing a live skill. Because that subagent operates on an untrusted transcript, it must gain no elevated tool authority.
What was built:
SessionActionsMenumodeSlotsseam (above Move to folder / Tags). It opens a small modal (CreateSkillDialog) that collects a mandatory one-line purpose; password-manager autofill affordances are suppressed, and a failed submit preserves the typed purpose and keeps the modal open.POST /api/skills/-/from-sessionshapes the session transcript (bounded/truncated), requires a non-empty purpose (≤ 500 chars), and spawns a fire-and-forget authoring subagent, returning202immediately. The subagent follows thecrystallizeskill in candidate mode: it stages underauto/.pending/<slug>/taggednamespace: manual, which is promoted to a livemanual/<slug>skill on approval.approval_mode="spawn": authorized to start (owner-triggered), but its tool calls stay approval-gated and it does not inherit any auto-approve policy (parent / YOLO / global config /auto_approve_subagent_toolshook), because the transcript is untrusted; a suppressed hook auto-approve is SEL-audited. It runs under the target session's ownagent/appgovernance identities (validated off the event loop; thedefaultsentinel maps to the host default; an unresolvable named agent is refused, never silently downgraded). A private/incognito session — including a linked Slack thread set to!incognito— is refused, and that check is repeated as the last step before the synchronous spawn to close the TOCTOU window. Every denial emits a SEL audit event.Tests
test/test_dashboard_create_skill.py(new) — endpoint auth (app-token / internal-auth / non-owner denials), purpose + session_key validation, incognito and linked-!incognitorefusal, the TOCTOU pre-spawn re-check, thedefault-agent sentinel path, unresolvable-agent rejection, and that the session'sagent/appreachspawn.test/test_subagent.py—approval_mode="spawn"does not inherit an auto-approve policy (parent / YOLO / global config / hook) and audits the suppression.test/test_skill_pending.py—test_manual_candidate_promotes_to_manual_namespace: amanual-tagged candidate promotes undermanual/<slug>/.website/src/test/CreateSkillDialog.test.tsx(new) — the modal: submit disabled until a purpose is entered, clears/closes only on success, and preserves the draft on a failed submit.Catalog parity across the 12 locale catalogs + the
en-XApseudolocale is enforced by thei18n:checkgate (not a per-PR test).Manual verification
Full gate run locally on the rebased commit, all green:
black --check(new files),flake8,mypy src/kiro_crew(1105 files, clean), 146 pytest passed,npm run i18n:check, andtsc -b(afternpm ci). UI smoke-tested against a local gateway: the Create skill row appears in the session menu after "Switch to Autopilot", the modal enforces a non-empty purpose, and submitting stages a candidate in Skills → Pending review without blocking the chat.Screenshots / video
Related Issues
Closes #3181
Checklist
feat: ...)docs/system-specs/modules/subagent.md,memory-skills-hooks.mdContribution License Agreement
N/A — the repo's template carries a pre-launch CLA placeholder (OSPO supplies the wording); nothing to sign yet.