Knowledge Pulse — Background Gardening
SkillDev toolsRun a lightweight freshness pass over company knowledge and policies.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Knowledge Pulse — Background Gardening skill
What this skill tells your AI
The instructions your AI receives, as published by indigoai-us/hq-core in .claude/skills/knowledge-pulse/SKILL.md and read by ahel’s review.
Lightweight, idempotent gardening pass that runs as a background sub-agent spawned by startwork, brainstorm, or plan. Gardens both knowledge docs and policies for a single company.
Never invoked directly. Always spawned via spawn_task by a parent command.
Input (via spawn prompt)
The parent command provides these values in the spawn prompt:
| Field | Required | Description |
|---|---|---|
company_slug | Yes | Company slug from manifest |
knowledge_path | Yes | Resolved path to companies/{co}/knowledge/ |
policies_path | Yes | Resolved path to companies/{co}/policies/ |
caller | Yes | startwork, brainstorm, or plan |
qmd_collection | No | Company's qmd collection for scoped searches |
search_results_summary | No | Condensed qmd hits from parent (brainstorm/plan only) |
discovered_facts | No | New company facts from parent's research (brainstorm/plan only) |
doc_scout_gaps | No | Post-implementation doc gaps (plan only) |
Action Matrix
| Action | startwork | brainstorm | plan |
|---|---|---|---|
| Knowledge INDEX.md refresh | Yes | Yes | Yes |
| Tag untagged knowledge docs | Yes | Yes | Yes |
| Flag stale knowledge (>60d) | Yes | Yes | Yes |
| company-info.md freshness | Yes | Yes | Yes |
| Contradiction detection | No | Yes | Yes |
| Policy frontmatter validation | Yes | Yes | Yes |
| Stale policy detection | Yes | Yes | Yes |
| Cross-scope conflict detection | No | Yes | Yes |
| Orphan policy detection | No | Yes | Yes |
Verify policy when:/on: frontmatter | If changed | If changed | If changed |
Process
Step 0: Idempotency Check
Check for existing report at workspace/reports/knowledge-pulse/{company_slug}-{YYYY-MM-DD}.md.
- If exists from today: skip entire pulse. Print "Pulse already ran for {company_slug} today. Skipping." and exit.
- If not found: proceed.
Step 1: Detect Knowledge Repo Type
Determine the knowledge directory pattern to choose the right commit strategy:
if [ -L "{knowledge_path}" ]; then
repo_type="symlink" # Pattern 2: symlink to repos/
elif [ -d "{knowledge_path}/.git" ]; then
repo_type="embedded" # Pattern 1: standalone .git inside core/knowledge/
else
repo_type="inline" # Pattern 3: tracked by HQ git
fi
If repo_type is symlink, STOP HERE. The layout is invalid (policy
knowledge-repositories-never-symlink): skip Steps 2–4 entirely — no INDEX.md
regeneration, no tagging, no stale-status edits, nothing written through the
link — and jump straight to Step 5 to write a report-only pulse recording the
migration violation (materialize at {knowledge_path}, run hq reindex,
verify ! test -L).
Commit rules:
embedded: commit changes inside the inner repo (git -C {knowledge_path} add . && git -C {knowledge_path} commit)symlink: unreachable — a symlink layout exits to report-only in Step 1inline: skip committing — flag in report as "changes staged but not committed (inline HQ-tracked)"
Step 2: Knowledge Garden
2a. INDEX.md Refresh
- Glob
{knowledge_path}/**/*.mdto get actual file list - Read
{knowledge_path}/INDEX.md(if exists) - Compare: are there files not listed in INDEX, or INDEX entries pointing to missing files?
- If drift detected: regenerate INDEX.md per the index-md-spec pattern (hierarchical, grouped by subdirectory)
- Track:
index_refreshed = true/false
2b. Tag Untagged Docs
For each .md file in {knowledge_path}/ (skip INDEX.md, README.md):
- Read first 10 lines — check for YAML frontmatter (
---delimiters) - If no frontmatter: classify per
core/knowledge/public/hq-core/knowledge-ontology.yaml:type: infer from content (strategy/reference/guide/analysis/brand/overview)domain: infer from content and subdirectory locationstatus: defaultdraftfor untagged docstags: extract 3-5 topic keywords from contentrelates_to: leave empty (vector search for relations is expensive; skip in pulse)
- Prepend YAML frontmatter block to the file
- Track:
docs_taggedcount
Cap: Process at most 20 untagged files per pulse run. If more exist, note remainder in report.
2c. Flag Stale Content
For each .md file in {knowledge_path}/ (skip INDEX.md):
- Check git last-modified date:
git log -1 --format="%ai" -- {file}(run from knowledge repo root, not HQ root) - If >60 days since last commit:
- If file has frontmatter with
status:field: update tostatus: stale - If no frontmatter: skip (will be tagged in next pulse after 2b adds frontmatter)
- If file has frontmatter with
- Track:
stale_flaggedcount, collect files >90 days for report
2d. company-info.md Check
- Check if
{knowledge_path}/company-info.mdexists - If exists: check git age via
git log -1 --format="%ai" -- company-info.md - Track:
company_info_age_days(ornullif missing) - If >90 days stale: flag in report
- If
discovered_factsprovided by parent: note in report as "Potential updates for human review" (do NOT auto-modify company-info.md — it's high-stakes)
2e. Contradiction Detection (brainstorm/plan only)
Skip if caller is startwork.
If search_results_summary provided:
- For each qmd hit path in the summary, read the file
- Compare key facts (pricing, features, architecture claims) against other knowledge docs in the same domain
- If contradictions found: log each as
{file_a, file_b, claim_a, claim_b}in report - Track:
contradictionscount
This is read-only — contradictions are logged, never auto-resolved.
Step 3: Policy Garden
3a. Policy Frontmatter Validation
Glob {policies_path}/*.md (skip example-policy.md).
For each policy file:
- Read first 20 lines — extract YAML frontmatter
- Check required fields per policies-spec:
id,title,scope,trigger,enforcement,version,created,updated,public - If missing required fields: log in report as "Policy {filename} missing fields: {list}"
- Track:
policies_invalidcount
Do NOT auto-fix policy frontmatter — policy content is high-stakes. Report only.
3b. Stale Policy Detection
For each policy file:
- Read the
## Rulesection - Check for references to specific file paths — verify those paths still exist via
ls - Check for references to repo names — verify against
companies/manifest.yamlrepos list - Check for references to worker names — verify against
core/workers/registry.yaml - If broken references found: log as "Policy {filename} references missing {type}: {path/name}"
- Track:
policies_stale_refscount
3c. Cross-Scope Conflict Detection (brainstorm/plan only)
Skip if caller is startwork.
- Read company policies from
{policies_path}/ - Read global policies from
core/policies/(frontmatter only — usecore/scripts/read-policy-frontmatter.sh) - For each company policy: check if a global policy with similar
triggerexists - If both are
enforcement: hardwith potentially conflicting rules: log as "Potential conflict: company {title} vs global {title}" - Track:
policy_conflictscount
3d. Orphan Policy Detection (brainstorm/plan only)
Skip if caller is startwork.
- For each company policy with
scope: repoin frontmatter: verify the referenced repo exists in manifest - For each policy referencing a specific worker: verify the worker exists in registry
- If orphaned: log as "Orphan policy {filename}: references {type} {name} which no longer exists"
- Track:
policies_orphanedcount
3e. Policy Surfacing
No digest rebuild step exists. Policies surface automatically via the SessionStart trigger hook (inject-policy-on-trigger.sh) and the migrate-policy-triggers.sh backfill. If a policy was modified in Steps 3a-3d (currently none are — all report-only), just ensure it still carries when:/on: frontmatter.
Step 4: Commit Changes
Knowledge changes (INDEX.md refresh, tagging, stale flags):
- If
repo_typeisembedded:cd {knowledge_path} git add -A git diff --cached --quiet || git commit -m "pulse: auto-tag and index refresh ({date})" - If
repo_typeissymlink: this step is never reached — Step 1 exits to report-only before any mutation, so there is nothing to commit or decline. The pulse report records the migration violation: materialize the content at{knowledge_path}(runhq reindex), preserve git there if needed, and verify! test -L - If
repo_typeisinline:- Skip commit. Note in report: "Knowledge is HQ-tracked (inline). Changes staged but not committed to avoid race with parent command."
Policy changes: Currently all policy actions are report-only (no file modifications). If future versions add policy auto-fixes, commit to HQ git separately.
Step 5: Write Pulse Report
Write to workspace/reports/knowledge-pulse/{company_slug}-{YYYY-MM-DD}.md:
# Knowledge Pulse: {company_slug}
**Date:** {YYYY-MM-DD} | **Triggered by:** {caller} | **Repo type:** {repo_type}
## Knowledge Actions
- INDEX.md: {refreshed — N files added/removed | no drift detected}
- Tagged: {N} untagged docs {(M remaining, capped at 20) if applicable}
- Stale flags: {N} files marked stale (>60d)
- company-info.md: {fresh (Nd old) | stale (Nd old) — review needed | not found}
- Committed: {yes (hash) | skipped (inline repo)}
## Policy Health
- Validated: {N} policies, {M} with missing frontmatter fields
- Stale references: {N} policies reference missing paths/repos/workers
- Cross-scope conflicts: {N} potential conflicts {(skipped — startwork caller)}
- Orphan policies: {N} reference nonexistent repos/workers {(skipped — startwork caller)}
## Contradictions Found
{table: file_a | file_b | conflicting claims — or "None" or "Skipped (startwork caller)"}
## Stale Files (>90d)
{table: file | last commit | age — or "None"}
## Invalid Policy Frontmatter
{table: file | missing fields — or "None"}
## Stale Policy References
{table: file | references | type | status — or "None"}
## Discovered Facts (for human review)
{list from parent's discovered_facts — or "None provided"}
## Doc Scout Gaps
{list from parent's doc_scout_gaps — or "None provided" or "N/A (not prd caller)"}
Step 6: Append Health Metrics
Append one JSON line to workspace/metrics/knowledge-health.jsonl:
{"timestamp":"{ISO8601}","company":"{company_slug}","caller":"{caller}","repo_type":"{repo_type}","index_refreshed":{bool},"docs_tagged":{N},"stale_flagged":{N},"company_info_age_days":{N|null},"contradictions":{N},"policies_validated":{N},"policies_invalid":{N},"policies_stale_refs":{N},"policy_conflicts":{N},"policies_orphaned":{N}}
Rules
- Idempotent — one pulse per company per day. Second invocation skips entirely
- Non-destructive — never delete, archive, or move files. Only: add frontmatter, update status field, regenerate INDEX.md
- Policy changes are report-only — never auto-modify policy content. Frontmatter validation and stale detection produce reports, not fixes
- company-info.md is hands-off — only report age and discovered facts. Never auto-update
- Cap tagging at 20 files — prevents runaway in large knowledge bases
- Respect repo type — commit only embedded repos. Report symlinks as migration violations and never write through them. Never commit inline knowledge to avoid racing HQ git
- Company isolation — only garden the specified company's knowledge and policies. Never cross-company
- Background execution — this skill runs detached from the parent command. No user interaction, no AskUserQuestion, no plan mode
- Fail gracefully — if qmd is unavailable, skip contradiction detection. If git commands fail, skip stale detection. Always produce a report even if partial
- No INDEX.md reads during startwork — startwork's rule "NEVER read company knowledge dirs" applies to the main command, not this background agent. The pulse agent operates independently
Signals
- GitHub stars
- 84
- Forks
- 15
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
knowledge-pulse- Source
- github.com/indigoai-us/hq-core