بنقرة واحدة
learn
Turn reusable findings into scoped policies or insight files.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Turn reusable findings into scoped policies or insight files.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
Deploy or share generated HQ artifacts through hq-deploy.
Mark a company as HQ Pro cloud-backed and sync its team setup.
Send HQ Sync direct messages, prompts, details, or scheduled notes to teammates.
Run a full bidirectional sync for cloud-backed HQ companies.
Scaffold a new HQ company AND optionally take it all the way to operational — business-discovery interview, seeded knowledge/workers/skills/projects, brand design packs (generated from website/PDF/Drive and bound to deploys via policy), connected integrations, org groups + ACL rules, teammate invites, and optional cloud agents.
Resolve HQ Sync conflicts by choosing local, cloud, or discard.
| name | learn |
| description | Turn reusable findings into scoped policies or insight files. |
| allowed-tools | Read, Write, Edit, Grep, Glob, Bash(qmd:*), Bash(grep:*), Bash(mkdir:*), Bash(date:*), Bash(ls:*), Bash(bash:*), Bash(git:*), Bash(rm:*), Bash(stat:*), Bash |
Capture a learning, classify it, and inject the rule directly into the file it governs (or the insight into the insight tree).
Called programmatically by /execute-task and /run-project after task completion or failure. Also callable manually with --hard flag for hard-enforcement rules (formerly /learn --hard). /handoff and /checkpoint call this for session insights.
Input: the user's argument — structured JSON event data, free text description, or empty/"auto" for hook-triggered mode.
Two output types, one pipeline. Content is classified (Step 1.5) and routed to the appropriate format:
| Scope | Target directory | Format |
|---|---|---|
| Company | companies/{co}/policies/{slug}.md | Policy file (YAML frontmatter + Rule + Rationale) |
| Repo | repos/{pub|priv}/{repo}/.claude/policies/{slug}.md | Policy file |
| Command (operator) | personal/policies/{slug}.md (scope: command) | Policy file |
| Global / personal (default) | personal/policies/{slug}.md (scope: global) | Policy file |
| Worker (legacy) | core/workers/*/{id}/worker.yaml | Instructions block ## Learnings |
/learnnever writes tocore/policies/.core/is release-shipped scaffold, replaced wholesale by/update-hq— anything written there is lost on the next upgrade (hard policyhq-customizations-live-in-personal-or-company). Operator-universal learnings go topersonal/policies/, whichreindex.shsymlinks back intocore/policies/so they still load as global at SessionStart — but live in an upgrade-safe location. A genuine product-level core policy (one that should ship to every HQ install) is not captured via/learn: author it locally, then publish through the hq-core staging repo +/promote-hq-core(seestaging-promotion-required). If a learning is judged truly core,/learnstops and points you at that pipeline rather than writing intocore/.
| Scope | Target directory | Format |
|---|---|---|
| Global / repo | workspace/insights/global/{slug}.md | Insight file (YAML frontmatter + Insight + Context) |
| Company | companies/{co}/knowledge/insights/{slug}.md | Insight file (inside company knowledge repo) |
| Tool | workspace/insights/tools/{slug}.md | Insight file |
| Conceptual | workspace/insights/concepts/{slug}.md | Insight file |
See core/knowledge/public/hq-core/insights-spec.md for the insight file format.
Before creating: always scan existing policies/insights for updates (Step 4.5). Update > duplicate.
Before processing, load applicable policies with minimal context burn:
core/policies/ (skip example-policy.md), run bash core/scripts/read-policy-frontmatter.sh {file} to get frontmatter-onlyenforcement: hard titles. Only Read the ## Rule section of hard-enforcement policies if one looks relevant to the current learningSkip full policy body loads — the frontmatter contains enough metadata for the learn pipeline.
Three input modes:
If the argument is empty or "auto":
workspace/learnings/.observe-patterns-latest.jsonobservations arraypattern_type, confidence, description, severity, evidencesource: "hook-observation", scope: "global" (or inferred from pattern type)Example .observe-patterns-latest.json:
{
"metadata": {
"created_at": "2026-03-07T21:35:00Z",
"session_end_timestamp": "20260307-213500",
"git_branch": "main",
"git_commit": "abc1234",
"project_context": "hq"
},
"observations": [
{
"pattern_type": "back-pressure-retry",
"confidence": 0.8,
"description": "Git log shows fixup/amend commits",
"severity": "high",
"evidence": "fixup commits in recent history",
"recommendation": "Extract pattern about what caused retry"
}
]
}
Note: in Codex runtime, the observe-patterns hook is not wired up, so this mode typically returns empty — fall through to manual modes.
If input is a JSON object:
{
"task_id": "TASK-001",
"project": "my-project",
"source": "back-pressure-failure|user-correction|success-pattern|task-completion|build-activity|hook-observation|session-insight",
"severity": "critical|high|medium|low",
"scope": "global|worker:{id}|command:{name}|knowledge:{path}|project:{slug}",
"workers_used": ["backend-dev"],
"back_pressure_failures": [{"worker": "frontend-dev", "check": "lint", "error": "..."}],
"retries": 0,
"key_decisions": ["..."],
"issues_encountered": ["..."],
"patterns_discovered": ["..."]
}
Parse it and proceed to Step 1.5.
Parse for keywords to determine scope. Generate rule statement from the description. Proceed to Step 1.5.
If the input starts with [ (JSON array), enter batch mode:
Batch input format:
[
{"type": "rule|insight", "content": "...", "scope": "global|company:{co}|...", "source": "..."},
...
]
Batch processing rules:
[), enter batch modecontent fields as a single query string for a single qmd vsearch call, then match results against each item individuallyDetermine if input is an operational rule or an educational insight:
| Signal | Type | Route to |
|---|---|---|
| NEVER/ALWAYS/condition→action | rule | Policy file (Steps 2–6) |
| "why X works", "pattern behind", conceptual explanation | insight | workspace/insights/ or companies/{co}/knowledge/insights/ (Step 5b) |
User correction (/learn --hard) | rule | Policy file (always) |
back_pressure_failures | rule | Policy file (always) |
patterns_discovered (educational) | insight | Insight file (Step 5b) |
source: "session-insight" | insight | Insight file (always — from /handoff or /checkpoint step 0c) |
Default: if ambiguous, route as policy (existing behavior). Insights are opt-in.
If content type is insight, skip Steps 2 and 5 (rule extraction and policy creation). Proceed to Step 3 for scope classification, Step 4 for dedup, then Step 5b for insight file creation.
From structured input, generate rules:
back_pressure_failures → NEVER: {anti-pattern that caused failure} (scope: worker:{id})retries > 0 → Rule about what caused retry and how to avoid itkey_decisions → ALWAYS: {pattern} if broadly applicableissues_encountered → Scoped rule to prevent recurrencepatterns_discovered → ALWAYS: {pattern} for success patternsFrom free text:
If no meaningful rules can be extracted (task completed cleanly, no failures, no notable patterns), skip injection — log to event log only.
For each extracted rule, determine scope (most specific wins):
| Signal | Scope | Policy directory |
|---|---|---|
| Related to specific company | company | companies/{co}/policies/ |
| Related to specific repo | repo | repos/{pub|priv}/{repo}/.claude/policies/ |
| Error in specific command | command | personal/policies/ (with scope: command) |
| Failure in specific worker | worker | core/workers/*/{id}/worker.yaml instructions block (legacy, still supported) |
| Active session company (when no explicit repo, command, or global scope) | company | companies/{co}/policies/ |
| Universal pattern (default when no company/repo/session context) | global | personal/policies/ |
| User correction via /learn --hard | From context; default to active session company, then global | Detected scope directory |
/learn does not target core/policies/. The global/command rows route to personal/policies/ — operator-owned and upgrade-safe — and reindex.sh symlinks each entry into core/policies/ so it still loads as a global/command policy. Reserve core/policies/ for release-shipped policies authored through the staging → /promote-hq-core pipeline. If a rule is genuinely product-core (must ship to every HQ install), stop and direct the user to that pipeline; never Write it into core/.
Primary output = policy files. The canonical format for persistent rules is structured policy files (per core/knowledge/public/hq-core/policies-spec.md). Worker.yaml injection is still supported for worker-specific learnings.
Resolve company/repo context (strongest signal wins):
repo, command, or global scope rather than the session default; explicit global scope targets personal/policies/. Verify an explicit company slug against the manifest.companies/<slug>/ segment (the last one in the path, not the first)prd.json metadata if in project contextcompanies/manifest.yaml repo lookup if in repo contextcompanies/{co}/workers/ → {co})bash core/scripts/hq-session.sh get company_slug. For free-text and /learn --hard input with no explicit repo, command, or global scope, default to this active company and target companies/{co}/policies/.Verify every resolved slug, including the active session company_slug, exists in companies/manifest.yaml before targeting companies/{co}/policies/. If the session value is absent or invalid, do not treat it as company context.
Never silently fall back to a global target for a company-specific learning. A global target (→ personal/policies/) is correct ONLY when the rule is genuinely universal to this operator's HQ. If a rule is clearly company-specific but the company can't be resolved unambiguously, stop and ask which company — do not default the write into personal/policies/ (and never into core/policies/). A misrouted company policy syncs into the wrong tenant vault on the next hq-sync (HQ-Pro), a category-1 cross-company bug. See core/policies/hq-company-scoped-writes-verify-company.md.
Primary (if qmd available):
qmd vsearch "{rule text}" --json -n 5
Check results for similarity to the new rule:
Fallback (if qmd unavailable): Use Grep to search for key terms from the rule across the policy directories:
*.md in companies/*/policies/, personal/policies/, core/policies/ (the symlinked + shipped set), and any repo policy dirsReport dedup action taken.
Before creating a new rule, check if an existing policy file already covers this topic:
Resolve policy directories based on scope:
companies/{co}/policies/ (skip example-policy.md){repoPath}/.claude/policies/personal/policies/ (the write target) and core/policies/ (catches shipped + already-symlinked rules)Search for matching policies:
# Grep policy titles and rules for keyword overlap
grep -rl "{key terms from rule}" {policy_dir}/*.md 2>/dev/null
Also check qmd vsearch results from Step 4 for hits in policy files.
If matching policy found:
## Rule section, bump version, update updated datededup_action: "merged-into-policy" in event logIf no matching policy found:
core/knowledge/public/hq-core/policies-spec.md) over injecting into worker.yaml. Policy files are the canonical format for persistent rules. Never write a learned rule into .claude/CLAUDE.md / AGENTS.md — the charter is release-shipped scaffold, not a learning store (policy learned-rules-never-in-claude-md)If Step 4.5 found a matching policy → update was already handled. Otherwise, create a new policy file.
Target directory:
companies/{co}/policies/{slug}.mdrepos/{pub|priv}/{repo}/.claude/policies/{slug}.mdpersonal/policies/{slug}.md (scope: command)personal/policies/{slug}.md (scope: global) — default for non-company/non-repo rulesNever Write a
.mdintocore/policies/from/learn— it is lost on/update-hqand is now mechanically blocked byprotect-core.sh(the block message points back here).personal/policies/entries are symlinked intocore/policies/byreindex.sh, so they load identically as global/command policies. Genuine product-core policies ship via the staging →/promote-hq-corepipeline only.
Create the directory if needed:
mkdir -p {target_directory}
Policy file format (per core/knowledge/public/hq-core/policies-spec.md):
---
id: {scope-prefix}-{slug}
title: {Rule title}
scope: {company|repo|command|global}
trigger: {when this applies}
when: {boolean trigger expr over context words, or `always`}
on: {[PreToolUse, PostToolUse, UserPromptSubmit, AssistantIntent] | [SessionStart]}
enforcement: {hard|soft}
public: {true|false}
version: 1
created: {YYYY-MM-DD}
updated: {YYYY-MM-DD}
source: {back-pressure-failure|user-correction|success-pattern|task-completion|hook-observation}
# applies_to: [vercel, clerk] # optional — stack-specific filter; see mapping below
---
## Rule
{Rule in imperative form}
## Rationale
{Why this rule exists — from context/failure/correction}
Enforcement mapping:
source: user-correction → enforcement: hardseverity: critical → enforcement: hardenforcement: softwhen: / on: trigger (just-in-time injection):
when: is a boolean expression over an OPEN token set — any word that appears in the relevant command/prompt/AI-message text is a live token (git && push, refactor, supabase, .tsx, /deep-plan, secret || credential). Pick the word(s) that naturally show up when the rule is relevant. Operators: && || ! ( ). Full grammar + fact derivation: core/knowledge/public/hq-core/policies-spec.md.on: is where it is evaluated. Default for a real trigger: [PreToolUse, PostToolUse, UserPromptSubmit, AssistantIntent] (the when: does the filtering). Use [SessionStart] only with when: always for ambient governance rules with no concrete signal.when: always + on: [SessionStart] — but prefer a real trigger so the rule loads just-in-time, not every session.migrate-policy-triggers.sh hook backfills them from tags: + trigger: on the next session. Setting them at authoring time is better — the migrator never overwrites an existing when:.applies_to: field mapping (stack applicability filter):
applies_to: line ONLY when the rule is wrong or useless without a specific service. Tag vocabulary must match the services: enum used in companies/manifest.yaml plus inferred vercel / aws. Examples:
applies_to: [vercel]applies_to: [clerk, vercel][clerk, vercel] means "load if workspace has clerk OR vercel." Omit the field for the 89%+ cross-cutting case.bash core/scripts/validate-policy-tags.sh after write (it fails on unknown tags — prevents typos that would silently filter everywhere).core/knowledge/public/hq-core/policies-spec.md → "Applicability Tagging (applies_to)" section.Slug generation: lowercase, hyphens, from rule keywords. Prefix: {co}- for company, {repo}- for repo, hq-cmd-{name}- for command, hq- for global.
For worker-specific learnings, still inject into core/workers/*/{id}/worker.yaml instructions block:
instructions: |
...existing instructions...
## Learnings
- NEVER: {new rule}
If Step 1.5 classified content as insight, skip Step 5 (policy creation) and create an insight file instead.
Target directory by scope:
workspace/insights/global/{slug}.mdcompanies/{co}/knowledge/insights/{slug}.md (create insights/ subdir if needed)workspace/insights/tools/{slug}.mdworkspace/insights/concepts/{slug}.mdInsight file format (per core/knowledge/public/hq-core/insights-spec.md):
---
type: insight
domain: [engineering]
tags: [topic-tags]
scope: global | company:{co} | repo:{repo} | tool:{tool}
source_session: T-{timestamp}-{slug}
created: {YYYY-MM-DD}
confidence: high | medium
relates_to: []
---
# {Title}
## Insight
{Core conceptual understanding, 2-4 paragraphs. Educational, not directive.}
## Context
{When/why this matters. What situation makes this knowledge valuable.}
## Example
{Optional. Concrete example showing the insight in practice.}
Slug generation: kebab-case from title keywords, max 60 chars. No scope prefix (subdirectory provides scope).
Confidence mapping:
confidence: highconfidence: mediumAfter writing: proceed to Step 7 (event logging).
Global promotion means raising a rule's enforcement to hard, in a policy file — never injecting it into the charter. Learned rules never go in .claude/CLAUDE.md / AGENTS.md (policy learned-rules-never-in-claude-md); they already surface for every session through the policy trigger hook (inject-policy-on-trigger.sh), so a hard-enforcement policy file is the global path.
If a rule meets ANY of:
severity == criticalsource == user-correction (explicit /learn --hard invocation)then ensure it lives as a hard-enforcement policy file at global scope:
personal/policies/{slug}.md (reindex symlinks it into core/policies/, so it rides global scope and survives /update-hq).core/policies/{slug}.md with the public marker (promoted via hq-pack-admin).Set enforcement: hard in the policy frontmatter and ensure the file carries when:/on: frontmatter so the SessionStart trigger hook surfaces it (Step 8). Do not touch CLAUDE.md.
mkdir -p workspace/learnings
Write workspace/learnings/learn-{YYYYMMDD-HHMMSS}.json:
{
"event_id": "learn-{timestamp}",
"content_type": "rule|insight",
"rules": [
{
"rule": "NEVER: ...",
"scope": "worker:frontend-dev",
"target_file": "core/workers/public/dev-team/frontend-dev/worker.yaml",
"severity": "high"
}
],
"source": "back-pressure-failure|session-insight",
"task_id": "TASK-001",
"project": "my-project",
"dedup_action": "new|merged|skipped",
"promoted_to_global": true,
"created_at": "{ISO8601}"
}
The event log write is mandatory for every invocation (even skipped/trivial ones) — downstream tooling relies on it.
qmd update 2>/dev/null || true
No manual digest rebuild is needed: policies surface automatically via the SessionStart trigger hook (inject-policy-on-trigger.sh) and the migrate-policy-triggers.sh backfill. Ensure any new policy file carries when:/on: frontmatter so it gets injected. (Personal entries are symlinked into core/policies/ by reindex.sh — run reindex or wait for its Stop/PostToolUse trigger if the symlink isn't present yet.)
Insight-only runs (content_type: insight) write no policy file, so there is nothing for the trigger hook to surface.
Batch mode note: In batch mode (Mode 4), there is no per-item or end-of-batch digest step — each policy file written during the batch surfaces on its own via its when:/on: frontmatter.
For rules (content_type: rule):
Learning captured:
Scope: {company:<slug> | repo:<name> | command | global}
Rule: {rule}
Target: {policy file path | worker.yaml path}
Action: {created-policy | updated-policy | merged-into-policy | worker-yaml-injection}
Global: {promoted|not promoted}
Dedup: {new|merged|skipped}
Event: workspace/learnings/learn-{timestamp}.json
For any scope: company rule, surface the resolved company slug and the full target path and confirm them before writing — this is the visible checkpoint that catches a misroute before it reaches a tenant vault (hq-company-scoped-writes-verify-company).
For insights (content_type: insight):
Insight captured:
Title: {insight title}
Target: {insight file path}
Action: {created-insight | updated-insight | merged-into-insight}
Dedup: {new|merged|skipped}
Event: workspace/learnings/learn-{timestamp}.json
If multiple rules/insights were extracted, report each.
.claude/CLAUDE.md / AGENTS.md; global promotion = a hard-enforcement policy file (policy learned-rules-never-in-claude-md)when:/on: frontmatter — that is what the SessionStart trigger hook (inject-policy-on-trigger.sh) uses to surface a policy; no manual digest rebuild exists anymoreworkspace/learnings/learn-{timestamp}.json is non-optional