Learnings API
Kheish exposes the daemon-owned learning plane through three related HTTP surfaces:- learning candidates
- published learnings
- promoted procedural skills
kheish-daemon learnings ....
Resource model
The normal flow is:- create or capture a learning candidate
- review it manually or through daemon automation
- publish it into a durable learning record, or reject it
- later revoke or supersede the learning
- optionally promote one reviewed
procedurelearning into a daemon-owned skill
Scope rules
Every candidate and learning belongs to one scope:sessionpersonaprojectworkspace
workspace, the stable scope id is always default.
If you pass scope_kind=workspace without scope_id, the HTTP API normalizes that to default.
For query filters:
scope_idwithoutscope_kindis rejectedscope_kindwithoutscope_idis rejected forsession,persona, andproject- only
workspacemay omitscope_id
Learning candidates
Endpoints
GET /v1/learning-candidatesPOST /v1/learning-candidatesGET /v1/learning-candidates/{candidate_id}POST /v1/learning-candidates/{candidate_id}/publishPOST /v1/learning-candidates/{candidate_id}/reject
List filters
GET /v1/learning-candidates supports:
queryscope_kindscope_idkindstate
Create payload
POST /v1/learning-candidates accepts:
scopekindsensitivitycontentconfidencesourceevidence_refsexpires_at_ms
contentis requiredcontentis capped at1600charactersconfidencemust stay in0..=100sensitivitydefaults toscopedconfidencedefaults to80sourcedefaults to an empty source object- public attempts to create
run_summarycandidates are rejected becauserun_summarycapture is daemon-owned
Candidate origins
Returned candidates retain one ingress origin:apidaemon
- daemon automation only treats
sourceandevidence_refsas trusted policy inputs for daemon-origin candidates - API-origin candidates may still auto-publish through other matching rules, but they do not satisfy the
require_*trusted-input gates
Candidate states and automation review
Returned candidates expose:originstateautomation_reviewpublished_learning_id
pendingescalatedpublishedrejected
automation_review is the daemon-owned audit record written by the automation worker. It includes:
modeactionreviewed_at_msmatched_rule_namejudgereason
automation_review.judge includes:
actionjudged_at_msreason
Publish payload
POST /v1/learning-candidates/{candidate_id}/publish accepts optional overrides:
scopekindsensitivitycontentconfidenceexpires_at_mspublish_tierevidence_refssupersedes
- the daemon normalizes
policy_decisiontomanual - the daemon normalizes
policy_actortooperator publish_tierdefaults toactivewhen omittedpublish_tier=provisionalproduces a durable learning withstatus=provisionalpublish_tier=activeproduces a durable learning withstatus=activesupersedesis only accepted when the published record usespublish_tier=active
Reject behavior
POST /v1/learning-candidates/{candidate_id}/reject marks the candidate as rejected. Rejected candidates are not converted into learnings.
Automatic learning policy
The daemon can review and publish candidates automatically through runtime policy. Operator surfaces:GET /v1/runtime/learning-policyPOST /v1/runtime/learning-policykheish-daemon runtime learning-policy getkheish-daemon runtime learning-policy set
modecapturepublicationjudge
manual_onlyshadowenabled
shadow.
Important update rule:
POST /v1/runtime/learning-policyreplaces the full policy- send
modeexplicitly when mutating policy
Capture settings
capture currently contains:
run_summary_candidatessemantic_candidates
capture.run_summary_candidates defaults to true.
capture.semantic_candidates currently contains:
enabledmodeltimeout_msmax_candidates_per_run
enabled=falsemodel=nulltimeout_ms=nullmax_candidates_per_run=2
timeout_msmust be greater than zero when providedmax_candidates_per_runmust be between1and8
Publication settings
publication currently contains:
default_actionallow_api_origin_active_publicationquarantined_rule_namesrules
manual_reviewrejectpublish_provisionalpublish_active
default_actioncannot bepublish_active- a
publish_activerule must declare an explicitkind publish_activeis not supported forprocedurelearnings- quarantined rule names must be non-empty and unique
Judge settings
judge currently contains:
enabledmodeltimeout_ms
enabled mode, judge failures fail closed to manual_review.
Current validation rule:
judge.timeout_msmust be greater than zero when provided
Rule matching semantics
Publication rules are evaluated in order. The first matching rule wins. If no rule matches, the daemon falls back topublication.default_action.
Each rule can match on:
namescope_kindscope_idkindsensitivitymin_confidencerequire_evidencerequire_source_runrequire_source_sessionactionexpires_after_ms
require_evidencerequire_source_runrequire_source_session
Automatic publication outcomes
The automation worker can currently decide:manual_reviewrejectpublish_provisionalpublish_active
procedurecan never auto-publish with the active tier- API-origin candidates are downgraded from automatic
publish_activetopublish_provisionalunlessallow_api_origin_active_publication=true - named quarantined rules are skipped during evaluation
Automatic active verification
publish_active is still guarded by daemon-owned verification.
Current behavior:
- the candidate must carry a non-empty
content - the candidate must have
source.run_id - for daemon-origin semantic
fact,preference, anddecisioncandidates, the daemon can verify the content against the persisted run-memory record of the source run - otherwise the daemon checks source-run debug artifacts referenced by
evidence_refs - if verification fails, the daemon downgrades the result to
publish_provisional
publish_active, but the stored learning lands as provisional when daemon-owned verification does not support active publication.
Published learnings
Endpoints
GET /v1/learningsGET /v1/learnings/{learning_id}POST /v1/learnings/{learning_id}/revokePOST /v1/learnings/{learning_id}/supersedePOST /v1/learnings/revoke-matchingPOST /v1/learnings/{learning_id}/promote-skill
List filters
GET /v1/learnings supports:
queryscope_kindscope_idkindstatuspolicy_decisionpolicy_actormatched_rule_name
statuspublish_tierverification_statuspolicy_decisionpolicy_actorevidence_refssupersedessuperseded_by
Revoke payload
POST /v1/learnings/{learning_id}/revoke accepts:
reason
Bulk revoke payload
POST /v1/learnings/revoke-matching accepts the same main filters as learning listing plus:
reason
queryscope_kindscope_idkindstatuspolicy_decisionpolicy_actormatched_rule_name
Supersede payload
POST /v1/learnings/{learning_id}/supersede accepts:
scopekindsensitivitycontentconfidenceexpires_at_ms
content is required for supersession. The same 1600-character limit applies.
This creates a new active learning and marks the older record as superseded.
Current supersession rule:
- the replacement record always uses
publish_tier=active
Prompt visibility versus durability
Published learnings are the source of truth, but they are not all prompt-eligible. To inspect the effective eligible projection before final prompt packing, use:GET /v1/sessions/{session_id}/memory-context
- active
procedurelearnings remain excluded fromlearned_context - active
run_summarylearnings remain excluded fromlearned_context - learnings with
publish_tier=provisionalremain excluded - learnings with
verification_status=failedremain excluded - automatically published learnings are prompt-visible only after
verification_status=verified - learnings with
policy_decision=escalatedremain excluded - promoted procedure skills appear through
visible_skillsinstead
learned_context and recovered_memory later when it packs the final prompt for a specific input and model budget.
Session memory search
To inspect the broader session-visible memory browse/search surface, use:GET /v1/sessions/{session_id}/memory-search
- visible learnings
- recovered runs visible through the session’s learning scopes
- visible skills
Promoted procedural skills
Promotion turns one reviewedprocedure learning into a daemon-owned reusable skill.
Promotion constraints
Current production rules:- the source learning must have kind
procedure - the source learning must be
active - the source learning must use
publish_tier=active - the source learning must use
workspacescope - promoted procedure skills must use
fork - promoted procedure skills must resolve to the
verificationagent profile
Endpoints
POST /v1/learnings/{learning_id}/promote-skillGET /v1/learning-skillsGET /v1/learning-skills/{skill_name}POST /v1/learning-skills/{skill_name}/revoke
Promotion payload
POST /v1/learnings/{learning_id}/promote-skill accepts:
skill_namedescriptionwhen_to_useversioninstructionsallowed_toolsblocked_toolscontextagent_profileprovidermodelfallback_modelstatus
contextmust resolve toforkagent_profilemust resolve toverificationskill_namemust be single-line ASCII and may contain only letters, digits,:,_, and-- empty or whitespace-only
descriptionfalls back to the generic non-sensitive default description - empty or whitespace-only
agent_profile,provider,model, andfallback_modelare normalized away - omitted
agent_profiledefaults toverification - omitted
statusdefaults todraft - new promoted skills cannot start directly in
active
Learning-skill list filters
GET /v1/learning-skills supports:
source_learning_idstatus
statusverification_statusevidence_refssuccessful_run_countdistinct_session_countverifier_run_idsreal_daemon_verifiedlast_verified_workspace_digestcanary_success_countcanary_failure_count
Revoke payload
POST /v1/learning-skills/{skill_name}/revoke accepts:
reason
Relationship to the normal skills catalog
Promoted skills are only added to the normal skill catalog when their promoted-skill record isactive.
Current rollout behavior:
draftstays durable but hiddenverifiedstays durable but hiddencanarystays durable but hiddenactivebecomes visible through/v1/skillsand session-visible skill projectionrevokedis removed from the visible catalog but retained durably for audit
use_skill.
CLI surface
The CLI mirrors the learning plane:kheish-daemon learnings candidates ...kheish-daemon learnings listkheish-daemon learnings getkheish-daemon learnings revokekheish-daemon learnings revoke-matchingkheish-daemon learnings supersedekheish-daemon learnings skills listkheish-daemon learnings skills getkheish-daemon learnings skills promotekheish-daemon learnings skills revoke
- the CLI candidate-create surface does not currently expose
evidence_refs - use the HTTP API when you need explicit evidence-backed automatic
publish_activetesting
Error model
The learning surfaces return normal400, 404, and 409 control-plane errors for validation and conflict cases.
Examples of current client-visible validation failures include:
- invalid learning scope
- missing or empty content
- content longer than
1600characters - confidence outside
0..=100 - promoting a non-
procedurelearning - promoting a non-
activelearning - promoting a non-
workspacelearning - using a promoted-procedure context other than
fork - invalid
skill_name - invalid learning-policy publication rules
Operational behavior
The current implementation is durable and restart-aware:- published learnings survive restart
- promoted procedural skills survive restart
- semantic capture can replay pending runs on boot without duplication
- revoking or superseding a promoted source learning also revokes the linked promoted skill
- the daemon repairs missing promoted-skill files on boot
- the daemon does not silently rebind a promoted-skill record to an unrelated skill root
