Personal skill learning
Post-turn personal skill learning
Automatic skill review is offered only for an opted-in human web/CLI request. TurnContextBuilder computes that flag, autoLearnSkills, for such a request: opted in, not internal and not automated (src/brain/service/turnContextBuilder.ts:122). The owner runner arms the review from that flag (src/brain/service/turnRunner.ts:780-805), so the decision to review is made there, not in TurnContextBuilder. The owner runner supplies successful current-turn evidence through reviewableTurn (src/brain/service/skillReviewEvidence.ts:17) and omits the effect for failed, steered or compacted exchanges. settleTurn (src/brain/session/turnSettled.ts:225) owns the non-blocking invocation and its abort deadline; channel callers omit the effect entirely, since src/brain/channels.ts never sets skillReview. The registered Skills plugin owns the per-account tool-call count, procedure selection, personal files and the agent-provenance mark that keeps it from changing skills a person wrote or edited, through registerSkillPostTurnReviewer, not MemoryCurator. The provenance mark is set on creation and cleared by any human edit (plugins/skills/lib/skillFiles.mjs:278-280). A learned skill is an ordinary personal skill: whether it reaches a session is decided by core's catalog and grants alone, with no separate approval state.
The operator's policy stays in core. It comes from the runtime limits (runtime.limits, passed to the owner runner as skillReviewLimits in src/daemon/brainCore.ts:1504). The owner runner reads it when it arms the review (src/brain/service/turnRunner.ts:784) and again in the fresh authorize check, which the reviewer runs before it writes (src/brain/service/turnRunner.ts:468, plugins/skills/lib/reviewer.mjs:236). It is therefore not a snapshot taken once per turn. skillReviewMinToolCalls is the fewest proven successful tool calls ONE completed exchange needs to be eligible at all, so a smaller exchange is neither reviewed nor counted (src/brain/service/turnRunner.ts:790). skillReviewEveryToolCalls is the cadence counted ACROSS eligible exchanges, and skillReviewMaxOps caps proposed skill writes, not inference calls. The latter two reach the reviewer as reviewEveryToolCalls and budget (src/brain/service/turnRunner.ts:801). All three are edited in Settings → Runtime like every other runtime limit; the eligibility and safety rules above are fixed, not knobs.
skillLearningAllowed in src/plugins/skillLearningAccess.ts is the shared availability check for the owner runner and /auth/me/cli-settings (src/api/routes/selfSettings.ts:63). Callers supply tool authority from toolAuthorityForUser, never reconstruct an allow-list. It combines that resolved policy with the live reviewer and CreateSkill plugin grants and a positive write budget; absent registration or authority means unavailable. The runner's fresh authorize callback additionally checks the account's opt-in and the exact registered reviewer before the plugin spends inference or writes. A review runs in a clean author policy scope without callbacks belonging to the settled turn. skillReviewInferenceFor wraps the account's memory-helper model with withOriginUsage and attributes its spend to that author under INTERNAL_ORIGIN (src/brain/skillReviewInference.ts:10-16); no resolved model means no review. The bounded, best-effort redacted evidence is still untrusted data. The full limits, cancellation requirements and real Skills plugin consumer are documented in the plugin seam catalog, row 59.
Minimal use: the Skills plugin registers its reviewer once at boot with ctx.registerSkillPostTurnReviewer({ run: reviewer.run }) (plugins/skills/index.mjs:94). Core then calls run with the account, the turn's text, the trajectory, the inference handle, budget, reviewEveryToolCalls and an authorize callback (src/brain/service/turnRunner.ts:796-801). The reviewer runs detached, and its abort signal fires at the settlement deadline (src/brain/session/turnSettled.ts:242-249).
Absent behavior: with no registered reviewer, or with a write budget of 0, skillLearningAllowed returns false and no review is armed (src/plugins/skillLearningAccess.ts:18, src/brain/service/turnRunner.ts:785). Only one reviewer is allowed per daemon. A second registration is refused with a warning and the first one wins (src/plugins/registry.ts:1602-1604).