openclaw-hybrid-memory 2026.5.310 → 2026.6.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/plugin-runtime.ts +2 -0
- package/backends/facts-db/contradictions.ts +1 -1
- package/cli/cmd-extract-directives.ts +225 -11
- package/cli/cmd-extract-proposals.ts +5 -6
- package/cli/cmd-extract-reinforcement.ts +71 -0
- package/cli/cmd-feedback.ts +15 -9
- package/cli/commands/manage/register-reflection-pipeline.ts +247 -13
- package/cli/commands/manage/register-storage-maintenance.ts +224 -15
- package/cli/commands/manage/storage-stats-helpers.ts +13 -2
- package/cli/context.ts +9 -19
- package/cli/distill.ts +31 -1
- package/cli/register.ts +28 -38
- package/dist/api/plugin-runtime.js.map +1 -1
- package/dist/backends/agent-health-store.js.map +1 -1
- package/dist/backends/apitap-store.js.map +1 -1
- package/dist/backends/audit-store.js.map +1 -1
- package/dist/backends/base-sqlite-store.js.map +1 -1
- package/dist/backends/cost-tracker.js.map +1 -1
- package/dist/backends/credentials-db.js +2 -3
- package/dist/backends/credentials-db.js.map +1 -1
- package/dist/backends/crystallization-store.js.map +1 -1
- package/dist/backends/edict-store.js.map +1 -1
- package/dist/backends/event-bus.js.map +1 -1
- package/dist/backends/event-log.js.map +1 -1
- package/dist/backends/facts-db/cache-manager.js.map +1 -1
- package/dist/backends/facts-db/clusters.js.map +1 -1
- package/dist/backends/facts-db/contradictions.js +1 -1
- package/dist/backends/facts-db/contradictions.js.map +1 -1
- package/dist/backends/facts-db/crud.js.map +1 -1
- package/dist/backends/facts-db/db-connection.js.map +1 -1
- package/dist/backends/facts-db/entity-autolink.js.map +1 -1
- package/dist/backends/facts-db/entity-layer.js.map +1 -1
- package/dist/backends/facts-db/episodes.js.map +1 -1
- package/dist/backends/facts-db/fact-queries.js.map +1 -1
- package/dist/backends/facts-db/fact-read-queries.js.map +1 -1
- package/dist/backends/facts-db/facts-db-layer1.js.map +1 -1
- package/dist/backends/facts-db/facts-db-layer2.js.map +1 -1
- package/dist/backends/facts-db/facts-db-layer3.js.map +1 -1
- package/dist/backends/facts-db/fts-text.js.map +1 -1
- package/dist/backends/facts-db/generated-skills/policy.js.map +1 -1
- package/dist/backends/facts-db/generated-skills.js.map +1 -1
- package/dist/backends/facts-db/housekeeping.js.map +1 -1
- package/dist/backends/facts-db/links.js.map +1 -1
- package/dist/backends/facts-db/maintenance.js.map +1 -1
- package/dist/backends/facts-db/procedures/crud.js.map +1 -1
- package/dist/backends/facts-db/procedures/internal.js.map +1 -1
- package/dist/backends/facts-db/procedures/promotion.js.map +1 -1
- package/dist/backends/facts-db/procedures/search.js.map +1 -1
- package/dist/backends/facts-db/procedures/stats.js.map +1 -1
- package/dist/backends/facts-db/reinforcement.js.map +1 -1
- package/dist/backends/facts-db/row-mapper.js.map +1 -1
- package/dist/backends/facts-db/scan-cursors.js.map +1 -1
- package/dist/backends/facts-db/schema-bootstrap.js.map +1 -1
- package/dist/backends/facts-db/scope-sql.js.map +1 -1
- package/dist/backends/facts-db/search.js.map +1 -1
- package/dist/backends/facts-db/stats.js.map +1 -1
- package/dist/backends/facts-db/types.js.map +1 -1
- package/dist/backends/facts-db/variants.js.map +1 -1
- package/dist/backends/identity-reflection-store.js.map +1 -1
- package/dist/backends/issue-store.js.map +1 -1
- package/dist/backends/learnings-db.js.map +1 -1
- package/dist/backends/migrations/facts-migrations.js.map +1 -1
- package/dist/backends/migrations/procedures.js.map +1 -1
- package/dist/backends/narratives-db.js.map +1 -1
- package/dist/backends/persona-state-store.js.map +1 -1
- package/dist/backends/proposals-db.js.map +1 -1
- package/dist/backends/scope-filter-sql.js.map +1 -1
- package/dist/backends/sqlite-schema-meta.js.map +1 -1
- package/dist/backends/tool-proposal-store.js.map +1 -1
- package/dist/backends/vector-db/constants.js.map +1 -1
- package/dist/backends/vector-db/path-utils.js.map +1 -1
- package/dist/backends/vector-db/runtime-locks.js.map +1 -1
- package/dist/backends/vector-db/vector-db-class.js.map +1 -1
- package/dist/backends/wal.js.map +1 -1
- package/dist/backends/workflow-store.js.map +1 -1
- package/dist/benchmark/shadow-eval.js.map +1 -1
- package/dist/cli/active-tasks.js.map +1 -1
- package/dist/cli/backup.js.map +1 -1
- package/dist/cli/benchmark.js.map +1 -1
- package/dist/cli/cmd-backfill.js.map +1 -1
- package/dist/cli/cmd-config.js.map +1 -1
- package/dist/cli/cmd-credentials.js.map +1 -1
- package/dist/cli/cmd-demo.js.map +1 -1
- package/dist/cli/cmd-distill.js.map +1 -1
- package/dist/cli/cmd-doctor.js.map +1 -1
- package/dist/cli/cmd-examples.js.map +1 -1
- package/dist/cli/cmd-extract-daily.js.map +1 -1
- package/dist/cli/cmd-extract-directives.js +141 -10
- package/dist/cli/cmd-extract-directives.js.map +1 -1
- package/dist/cli/cmd-extract-procedures.js.map +1 -1
- package/dist/cli/cmd-extract-proposals.js +3 -2
- package/dist/cli/cmd-extract-proposals.js.map +1 -1
- package/dist/cli/cmd-extract-reinforcement.js +39 -0
- package/dist/cli/cmd-extract-reinforcement.js.map +1 -1
- package/dist/cli/cmd-extract-sessions.js.map +1 -1
- package/dist/cli/cmd-feedback.js +9 -4
- package/dist/cli/cmd-feedback.js.map +1 -1
- package/dist/cli/cmd-health.js.map +1 -1
- package/dist/cli/cmd-providers.js.map +1 -1
- package/dist/cli/cmd-selfcorrection.js.map +1 -1
- package/dist/cli/cmd-setup.js.map +1 -1
- package/dist/cli/cmd-status.js.map +1 -1
- package/dist/cli/cmd-store.js.map +1 -1
- package/dist/cli/cmd-user-friendly.js.map +1 -1
- package/dist/cli/cmd-verify.js.map +1 -1
- package/dist/cli/commands/manage/bindings.js.map +1 -1
- package/dist/cli/commands/manage/dream-cycle-followup.js.map +1 -1
- package/dist/cli/commands/manage/maintenance-heartbeat.js.map +1 -1
- package/dist/cli/commands/manage/register-agents-audit-runall.js.map +1 -1
- package/dist/cli/commands/manage/register-analyze-maintenance-logs.js.map +1 -1
- package/dist/cli/commands/manage/register-budget-proposals.js.map +1 -1
- package/dist/cli/commands/manage/register-config-cli.js.map +1 -1
- package/dist/cli/commands/manage/register-corrections-and-pipeline.js.map +1 -1
- package/dist/cli/commands/manage/register-corrections.js.map +1 -1
- package/dist/cli/commands/manage/register-council.js.map +1 -1
- package/dist/cli/commands/manage/register-credentials-scope.js.map +1 -1
- package/dist/cli/commands/manage/register-digest.js.map +1 -1
- package/dist/cli/commands/manage/register-lifecycle.js.map +1 -1
- package/dist/cli/commands/manage/register-procedure-lifecycle.js.map +1 -1
- package/dist/cli/commands/manage/register-reconcile-cron-ledgers.js.map +1 -1
- package/dist/cli/commands/manage/register-reflection-pipeline.js +144 -7
- package/dist/cli/commands/manage/register-reflection-pipeline.js.map +1 -1
- package/dist/cli/commands/manage/register-self-correction-feedback.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-and-stats.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-entities-decay.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-graph-audit.js.map +1 -1
- package/dist/cli/commands/manage/register-storage-maintenance.js +152 -9
- package/dist/cli/commands/manage/register-storage-maintenance.js.map +1 -1
- package/dist/cli/commands/manage/register-validate-cron-exit.js.map +1 -1
- package/dist/cli/commands/manage/storage-stats-helpers.js +10 -3
- package/dist/cli/commands/manage/storage-stats-helpers.js.map +1 -1
- package/dist/cli/commands/register-manage-commands.js.map +1 -1
- package/dist/cli/config-feature-summaries.js.map +1 -1
- package/dist/cli/config-output-sink.js.map +1 -1
- package/dist/cli/distill-session-jsonl.js.map +1 -1
- package/dist/cli/distill.js +10 -1
- package/dist/cli/distill.js.map +1 -1
- package/dist/cli/global-verbose.js.map +1 -1
- package/dist/cli/goals.js.map +1 -1
- package/dist/cli/hybrid-mem-commander-utils.js.map +1 -1
- package/dist/cli/install/config-merge.js.map +1 -1
- package/dist/cli/install/cron-jobs.js.map +1 -1
- package/dist/cli/install/embedding-detect.js.map +1 -1
- package/dist/cli/install/run-install.js.map +1 -1
- package/dist/cli/install/workspace.js.map +1 -1
- package/dist/cli/proposals.js.map +1 -1
- package/dist/cli/register.js.map +1 -1
- package/dist/cli/shared.js.map +1 -1
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/task-queue-status.js.map +1 -1
- package/dist/cli/verified.js.map +1 -1
- package/dist/cli/verify/fact-count.js.map +1 -1
- package/dist/cli/verify/openclaw-config.js.map +1 -1
- package/dist/cli/verify/plugin-config-credentials.js.map +1 -1
- package/dist/cli/verify/sections/config-cron.js.map +1 -1
- package/dist/cli/verify/sections/embeddings.js.map +1 -1
- package/dist/cli/verify/sections/infrastructure.js.map +1 -1
- package/dist/cli/verify/sections/llm-models.js.map +1 -1
- package/dist/cli/verify/sections/reconcile.js.map +1 -1
- package/dist/cli/verify/verify-run-state.js.map +1 -1
- package/dist/cli/verify-llm-azure-auth.js.map +1 -1
- package/dist/cli/verify.js.map +1 -1
- package/dist/config/hybrid-schema.js.map +1 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/maintenance-fallback-policy.js.map +1 -1
- package/dist/config/parsers/capture.js.map +1 -1
- package/dist/config/parsers/core.js.map +1 -1
- package/dist/config/parsers/features.js.map +1 -1
- package/dist/config/parsers/index.js.map +1 -1
- package/dist/config/parsers/maintenance.js.map +1 -1
- package/dist/config/parsers/retrieval.js.map +1 -1
- package/dist/config/parsers/sensors.js.map +1 -1
- package/dist/config/skill-sections.js.map +1 -1
- package/dist/config/skill-size-limits.js.map +1 -1
- package/dist/config/types/agents.js.map +1 -1
- package/dist/config/types/bootstrap.js.map +1 -1
- package/dist/config/types/core.js.map +1 -1
- package/dist/config/types/index.js.map +1 -1
- package/dist/config/utils.js.map +1 -1
- package/dist/index-help.js.map +1 -1
- package/dist/index-testing-exports.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/hook-resolution-api.js.map +1 -1
- package/dist/lifecycle/hooks.js +0 -1
- package/dist/lifecycle/hooks.js.map +1 -1
- package/dist/lifecycle/resolve-agent-id.js.map +1 -1
- package/dist/lifecycle/session-state.js.map +1 -1
- package/dist/lifecycle/stage-active-task.js.map +1 -1
- package/dist/lifecycle/stage-auth-failure.js.map +1 -1
- package/dist/lifecycle/stage-capture/run-capture.js.map +1 -1
- package/dist/lifecycle/stage-capture.js.map +1 -1
- package/dist/lifecycle/stage-cleanup.js.map +1 -1
- package/dist/lifecycle/stage-credential-hint.js.map +1 -1
- package/dist/lifecycle/stage-frustration.js.map +1 -1
- package/dist/lifecycle/stage-goal-stewardship.js.map +1 -1
- package/dist/lifecycle/stage-goal-subagent.js.map +1 -1
- package/dist/lifecycle/stage-injection.js +1 -1
- package/dist/lifecycle/stage-injection.js.map +1 -1
- package/dist/lifecycle/stage-recall/run-recall.js.map +1 -1
- package/dist/lifecycle/stage-recall.js.map +1 -1
- package/dist/lifecycle/stage-setup.js.map +1 -1
- package/dist/routes/dashboard/collectors.js.map +1 -1
- package/dist/routes/dashboard/html.js.map +1 -1
- package/dist/routes/dashboard/server.js.map +1 -1
- package/dist/routes/dashboard-graph.js.map +1 -1
- package/dist/routes/graphql-resolvers.js.map +1 -1
- package/dist/routes/graphql-server.js.map +1 -1
- package/dist/services/active-task-checkpoint.js.map +1 -1
- package/dist/services/active-task-injection.js.map +1 -1
- package/dist/services/active-task.js.map +1 -1
- package/dist/services/adaptive-catch-up-pacing.js +25 -0
- package/dist/services/adaptive-catch-up-pacing.js.map +1 -0
- package/dist/services/adaptive-maintenance-llm.js.map +1 -1
- package/dist/services/adaptive-model-limits.js.map +1 -1
- package/dist/services/ambient-retrieval.js.map +1 -1
- package/dist/services/apitap-service.js.map +1 -1
- package/dist/services/audit-health-exit-info.js.map +1 -1
- package/dist/services/audit-health-json.js.map +1 -1
- package/dist/services/auth-failure-detect.js.map +1 -1
- package/dist/services/auto-capture.js.map +1 -1
- package/dist/services/auto-classifier.js.map +1 -1
- package/dist/services/auto-skills-audit.js.map +1 -1
- package/dist/services/bootstrap-optional.js.map +1 -1
- package/dist/services/bootstrap-priority.js.map +1 -1
- package/dist/services/bootstrap.js.map +1 -1
- package/dist/services/capture-provenance.js.map +1 -1
- package/dist/services/capture-utils.js.map +1 -1
- package/dist/services/chat.js +22 -3
- package/dist/services/chat.js.map +1 -1
- package/dist/services/classification-scope.js.map +1 -1
- package/dist/services/classification.js.map +1 -1
- package/dist/services/cli-sql-dump.js.map +1 -1
- package/dist/services/consolidation.js.map +1 -1
- package/dist/services/context-audit.js +1 -1
- package/dist/services/context-audit.js.map +1 -1
- package/dist/services/context-budget.js.map +1 -1
- package/dist/services/context-engine.js.map +1 -1
- package/dist/services/contextual-variants.js.map +1 -1
- package/dist/services/continuous-verifier.js.map +1 -1
- package/dist/services/contradiction-adjudicator.js.map +1 -1
- package/dist/services/cost-context.js.map +1 -1
- package/dist/services/cost-feature-labels.js.map +1 -1
- package/dist/services/credential-migration.js.map +1 -1
- package/dist/services/credential-scanner.js.map +1 -1
- package/dist/services/credential-validation.js.map +1 -1
- package/dist/services/cron-exit-validator.js.map +1 -1
- package/dist/services/cron-guard.js.map +1 -1
- package/dist/services/cron-job-bash-harness.js +52 -5
- package/dist/services/cron-job-bash-harness.js.map +1 -1
- package/dist/services/cron-maintenance-reconciler.js +1 -3
- package/dist/services/cron-maintenance-reconciler.js.map +1 -1
- package/dist/services/cross-agent-learning.js.map +1 -1
- package/dist/services/crystallization-proposer.js.map +1 -1
- package/dist/services/dedupe-policy.js.map +1 -1
- package/dist/services/deprecated-cron-commands.js.map +1 -1
- package/dist/services/directive-extract.js.map +1 -1
- package/dist/services/document-chunker.js.map +1 -1
- package/dist/services/document-grader.js.map +1 -1
- package/dist/services/dream-cycle.js.map +1 -1
- package/dist/services/embedding-migration.js.map +1 -1
- package/dist/services/embedding-registry.js.map +1 -1
- package/dist/services/embeddings/chain-provider.js.map +1 -1
- package/dist/services/embeddings/factory.js.map +1 -1
- package/dist/services/embeddings/fallback-provider.js.map +1 -1
- package/dist/services/embeddings/ollama-provider.js.map +1 -1
- package/dist/services/embeddings/onnx-provider.js.map +1 -1
- package/dist/services/embeddings/openai-provider.js.map +1 -1
- package/dist/services/embeddings/shared.js +3 -3
- package/dist/services/embeddings/shared.js.map +1 -1
- package/dist/services/embeddings/types.js.map +1 -1
- package/dist/services/entity-enrichment-adaptive.js +128 -0
- package/dist/services/entity-enrichment-adaptive.js.map +1 -0
- package/dist/services/entity-enrichment-cli.js +389 -42
- package/dist/services/entity-enrichment-cli.js.map +1 -1
- package/dist/services/entity-enrichment.js +31 -5
- package/dist/services/entity-enrichment.js.map +1 -1
- package/dist/services/error-reporter/noisy-errors.js.map +1 -1
- package/dist/services/error-reporter/sanitize.js.map +1 -1
- package/dist/services/error-reporter.js.map +1 -1
- package/dist/services/event-hub-repair.js.map +1 -1
- package/dist/services/export-memory.js.map +1 -1
- package/dist/services/fact-extraction.js.map +1 -1
- package/dist/services/feedback-effectiveness.js.map +1 -1
- package/dist/services/find-duplicates.js.map +1 -1
- package/dist/services/frustration-detector.js.map +1 -1
- package/dist/services/fts-search.js.map +1 -1
- package/dist/services/gap-detector.js.map +1 -1
- package/dist/services/generated-skill-lifecycle.js.map +1 -1
- package/dist/services/generated-skill-validation.js.map +1 -1
- package/dist/services/goal-active-task-mirror.js.map +1 -1
- package/dist/services/goal-circuit-breaker.js.map +1 -1
- package/dist/services/goal-health.js.map +1 -1
- package/dist/services/goal-registry.js.map +1 -1
- package/dist/services/goal-stewardship-heartbeat.js.map +1 -1
- package/dist/services/goal-stewardship-llm-triage.js.map +1 -1
- package/dist/services/goal-stewardship-verify-cron.js.map +1 -1
- package/dist/services/goal-stewardship.js.map +1 -1
- package/dist/services/goal-subagent.js.map +1 -1
- package/dist/services/graph-retrieval.js.map +1 -1
- package/dist/services/humanizer-score.js.map +1 -1
- package/dist/services/hybrid-mem-cron-default-job-steps.js.map +1 -1
- package/dist/services/hyde-helper.js.map +1 -1
- package/dist/services/identity-reflection.js.map +1 -1
- package/dist/services/implicit-feedback-extract.js.map +1 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/ingest-utils.js.map +1 -1
- package/dist/services/intent-template.js.map +1 -1
- package/dist/services/json-array-parser.js.map +1 -1
- package/dist/services/knowledge-gaps.js.map +1 -1
- package/dist/services/language-keywords-build.js.map +1 -1
- package/dist/services/lifecycle/github-adapter.js.map +1 -1
- package/dist/services/llm-rate-limit-headers.js +1 -2
- package/dist/services/llm-rate-limit-headers.js.map +1 -1
- package/dist/services/maintenance-auto-fix.js.map +1 -1
- package/dist/services/maintenance-log-analyzer.js +7 -1
- package/dist/services/maintenance-log-analyzer.js.map +1 -1
- package/dist/services/maintenance-timestamp.js.map +1 -1
- package/dist/services/memory-diagnostics.js.map +1 -1
- package/dist/services/memory-index.js.map +1 -1
- package/dist/services/merge-results.js.map +1 -1
- package/dist/services/model-capabilities.js.map +1 -1
- package/dist/services/model-pricing.js.map +1 -1
- package/dist/services/narrative-recall.js.map +1 -1
- package/dist/services/openclaw-session-artifact.js.map +1 -1
- package/dist/services/passive-observer.js.map +1 -1
- package/dist/services/pattern-detector-hash.js.map +1 -1
- package/dist/services/pattern-detector.js.map +1 -1
- package/dist/services/pending-autopilot/foundation.js.map +1 -1
- package/dist/services/pending-autopilot/redaction.js.map +1 -1
- package/dist/services/pending-autopilot/store.js.map +1 -1
- package/dist/services/pending-autopilot/types.js.map +1 -1
- package/dist/services/pending-digest-autopilot-cron.js.map +1 -1
- package/dist/services/pending-digest-autopilot.js.map +1 -1
- package/dist/services/pending-review-digest.js.map +1 -1
- package/dist/services/persona-proposal-triage.js.map +1 -1
- package/dist/services/persona-state-promotion.js.map +1 -1
- package/dist/services/post-compaction-recall.js.map +1 -1
- package/dist/services/pre-consolidation-flush.js.map +1 -1
- package/dist/services/pre-finalization-guard.js.map +1 -1
- package/dist/services/procedure-cluster.js.map +1 -1
- package/dist/services/procedure-extractor.js.map +1 -1
- package/dist/services/procedure-promotion/duplicate-skill-cache.js.map +1 -1
- package/dist/services/procedure-promotion-policy.js.map +1 -1
- package/dist/services/procedure-selection-metrics.js.map +1 -1
- package/dist/services/procedure-skill-eval.js.map +1 -1
- package/dist/services/procedure-skill-generator.js.map +1 -1
- package/dist/services/procedure-skill-recipe.js.map +1 -1
- package/dist/services/procedure-skill-shrink.js.map +1 -1
- package/dist/services/procedure-skill-workflow.js.map +1 -1
- package/dist/services/provenance.js.map +1 -1
- package/dist/services/public-export-bundle.js.map +1 -1
- package/dist/services/python-bridge.js.map +1 -1
- package/dist/services/query-expander.js.map +1 -1
- package/dist/services/query-validator.js.map +1 -1
- package/dist/services/recall-pipeline.js.map +1 -1
- package/dist/services/recall-timing.js.map +1 -1
- package/dist/services/recent-http-attempts.js.map +1 -1
- package/dist/services/reflection/shared.js.map +1 -1
- package/dist/services/reflection.js.map +1 -1
- package/dist/services/reinforcement-extract.js.map +1 -1
- package/dist/services/reranker.js.map +1 -1
- package/dist/services/responses-adapter.js.map +1 -1
- package/dist/services/retrieval-aliases.js.map +1 -1
- package/dist/services/retrieval-mode-policy.js.map +1 -1
- package/dist/services/retrieval-orchestrator/packing.js.map +1 -1
- package/dist/services/retrieval-orchestrator.d.ts +2 -3
- package/dist/services/retrieval-orchestrator.js.map +1 -1
- package/dist/services/rrf-fusion.js.map +1 -1
- package/dist/services/self-correction-extract.js.map +1 -1
- package/dist/services/session-observability.js.map +1 -1
- package/dist/services/session-pre-filter.js.map +1 -1
- package/dist/services/shortest-path.js.map +1 -1
- package/dist/services/skill-allowed-tools.js.map +1 -1
- package/dist/services/skill-creator-validator.js.map +1 -1
- package/dist/services/skill-crystallizer-helpers.js.map +1 -1
- package/dist/services/skill-crystallizer.js.map +1 -1
- package/dist/services/skill-description-builder.js.map +1 -1
- package/dist/services/skill-eval-synthesizer.js.map +1 -1
- package/dist/services/skill-examples-builder.js.map +1 -1
- package/dist/services/skill-frontmatter.js.map +1 -1
- package/dist/services/skill-name-validator.js.map +1 -1
- package/dist/services/skill-prompt-injection.js.map +1 -1
- package/dist/services/skill-reference-sidecar.js.map +1 -1
- package/dist/services/skill-script-bundler.js.map +1 -1
- package/dist/services/skill-validator.js.map +1 -1
- package/dist/services/startup-memory-attribution.js.map +1 -1
- package/dist/services/task-hygiene.js.map +1 -1
- package/dist/services/task-ledger/canonical.js.map +1 -1
- package/dist/services/task-ledger-facts.js.map +1 -1
- package/dist/services/task-queue-leases.js.map +1 -1
- package/dist/services/task-queue-watchdog.js.map +1 -1
- package/dist/services/tool-effectiveness.js.map +1 -1
- package/dist/services/tool-proposer.js.map +1 -1
- package/dist/services/tools-md-section.js.map +1 -1
- package/dist/services/topic-clusters.js.map +1 -1
- package/dist/services/trajectory-tracker.js.map +1 -1
- package/dist/services/vector-backend-observability.js.map +1 -1
- package/dist/services/vector-lifecycle-audit.js.map +1 -1
- package/dist/services/vector-maintenance.js.map +1 -1
- package/dist/services/vector-search.js.map +1 -1
- package/dist/services/verification-store.js.map +1 -1
- package/dist/services/verified-fact-triage.js.map +1 -1
- package/dist/services/wal-helpers.js.map +1 -1
- package/dist/services/workflow-tracker.js.map +1 -1
- package/dist/setup/bootstrap-databases.js.map +1 -1
- package/dist/setup/cli-context/cli-services.js.map +1 -1
- package/dist/setup/cli-context/help-text.js.map +1 -1
- package/dist/setup/cli-context/metadata.js.map +1 -1
- package/dist/setup/cli-context/register-cli-with-help.js.map +1 -1
- package/dist/setup/cli-context/register-full.js.map +1 -1
- package/dist/setup/cli-context/register-help.js.map +1 -1
- package/dist/setup/cost-instrumentation.js.map +1 -1
- package/dist/setup/hybrid-memory-generation-state.js.map +1 -1
- package/dist/setup/hybrid-memory-reload-coordinator.js +13 -13
- package/dist/setup/hybrid-memory-reload-coordinator.js.map +1 -1
- package/dist/setup/plugin-service.js.map +1 -1
- package/dist/setup/provider-router.js.map +1 -1
- package/dist/setup/register-context-engine.js.map +1 -1
- package/dist/setup/register-hooks.js.map +1 -1
- package/dist/setup/register-plugin.js +25 -21
- package/dist/setup/register-plugin.js.map +1 -1
- package/dist/setup/register-tools.js.map +1 -1
- package/dist/setup/reregister-policy.js +2 -2
- package/dist/setup/reregister-policy.js.map +1 -1
- package/dist/setup/tool-installers.js.map +1 -1
- package/dist/setup/workspace-bootstrap.js.map +1 -1
- package/dist/src/worker/narratives.js.map +1 -1
- package/dist/tools/apitap-tools.js.map +1 -1
- package/dist/tools/credential-tools.js.map +1 -1
- package/dist/tools/crystallization-tools.js.map +1 -1
- package/dist/tools/dashboard-routes.js.map +1 -1
- package/dist/tools/document-tools.js.map +1 -1
- package/dist/tools/goal-tools.js.map +1 -1
- package/dist/tools/graph-tools.js.map +1 -1
- package/dist/tools/issue-tools.js.map +1 -1
- package/dist/tools/memory/build-runtime.js.map +1 -1
- package/dist/tools/memory/helpers.js.map +1 -1
- package/dist/tools/memory/register-checkpoint-tools.js.map +1 -1
- package/dist/tools/memory/register-directory-tools.js.map +1 -1
- package/dist/tools/memory/register-edict-tools.js.map +1 -1
- package/dist/tools/memory/register-episode-tools.js.map +1 -1
- package/dist/tools/memory/register-recall-tools.js.map +1 -1
- package/dist/tools/memory/register-store-tools.js.map +1 -1
- package/dist/tools/memory-tools.js.map +1 -1
- package/dist/tools/persona-tools.js.map +1 -1
- package/dist/tools/provenance-tools.js.map +1 -1
- package/dist/tools/public-api-routes.js.map +1 -1
- package/dist/tools/safe-register-http-route.js.map +1 -1
- package/dist/tools/self-extension-tools.js.map +1 -1
- package/dist/tools/task-hygiene-tools.js.map +1 -1
- package/dist/tools/utility-tools.js.map +1 -1
- package/dist/tools/verification-tools.js.map +1 -1
- package/dist/tools/workflow-tools.js.map +1 -1
- package/dist/types/issue-types.js.map +1 -1
- package/dist/types/learnings-types.js.map +1 -1
- package/dist/types/memory.js.map +1 -1
- package/dist/utils/apim-gateway-fetch.js.map +1 -1
- package/dist/utils/atomic-write.js.map +1 -1
- package/dist/utils/auth-failover.js.map +1 -1
- package/dist/utils/auth.js.map +1 -1
- package/dist/utils/compaction-model-watchdog.js.map +1 -1
- package/dist/utils/consolidation-controls.js.map +1 -1
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/date-detector.js.map +1 -1
- package/dist/utils/dates.js.map +1 -1
- package/dist/utils/decay.js.map +1 -1
- package/dist/utils/duration.js.map +1 -1
- package/dist/utils/embed-call.js.map +1 -1
- package/dist/utils/entity-lookup-resolve.js.map +1 -1
- package/dist/utils/entity-mention-quality.js.map +1 -1
- package/dist/utils/entity-stopwords.js.map +1 -1
- package/dist/utils/env-manager.js.map +1 -1
- package/dist/utils/error-tracking.js.map +1 -1
- package/dist/utils/event-loop-yield.js.map +1 -1
- package/dist/utils/extract-last-user-message.js.map +1 -1
- package/dist/utils/extraction-from-template.js.map +1 -1
- package/dist/utils/fact-embeddings.js.map +1 -1
- package/dist/utils/file-snapshot.js.map +1 -1
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/fs.js.map +1 -1
- package/dist/utils/gh-repo-arg.js.map +1 -1
- package/dist/utils/hybrid-mem-json-cli.js.map +1 -1
- package/dist/utils/language-keywords.js.map +1 -1
- package/dist/utils/lifecycle-generation.js.map +1 -1
- package/dist/utils/llm-json-array.js.map +1 -1
- package/dist/utils/llm-selection.js.map +1 -1
- package/dist/utils/logger.js.map +1 -1
- package/dist/utils/model-provider-family.js.map +1 -1
- package/dist/utils/model-tier.js.map +1 -1
- package/dist/utils/openclaw-agent-defaults.js.map +1 -1
- package/dist/utils/path.js.map +1 -1
- package/dist/utils/plugin-root.js.map +1 -1
- package/dist/utils/plugin-update-check.js.map +1 -1
- package/dist/utils/procedure-risk.js.map +1 -1
- package/dist/utils/progress-indicators.js.map +1 -1
- package/dist/utils/prompt-loader.js.map +1 -1
- package/dist/utils/provenance.js.map +1 -1
- package/dist/utils/provider-detection.js.map +1 -1
- package/dist/utils/registration-superseded.js.map +1 -1
- package/dist/utils/salience.js.map +1 -1
- package/dist/utils/sanitize-messages.js.map +1 -1
- package/dist/utils/scope-filter.js.map +1 -1
- package/dist/utils/skill-discovery.js.map +1 -1
- package/dist/utils/sqlite-file-perms.js.map +1 -1
- package/dist/utils/sqlite-outcome-compat.js.map +1 -1
- package/dist/utils/sqlite-transaction.js.map +1 -1
- package/dist/utils/stable-stringify.js.map +1 -1
- package/dist/utils/subagent-ended-utils.js.map +1 -1
- package/dist/utils/tags.js.map +1 -1
- package/dist/utils/text.js.map +1 -1
- package/dist/utils/timeout.js.map +1 -1
- package/dist/utils/typebox.js.map +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/wal-replay.js.map +1 -1
- package/dist/versionInfo.js.map +1 -1
- package/index.ts +2 -2
- package/lifecycle/hooks.ts +0 -1
- package/npm-shrinkwrap.json +487 -186
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
- package/services/adaptive-catch-up-pacing.ts +28 -0
- package/services/chat.ts +34 -1
- package/services/cron-job-bash-harness.ts +52 -5
- package/services/embeddings/shared.ts +5 -2
- package/services/entity-enrichment-adaptive.ts +245 -0
- package/services/entity-enrichment-cli.ts +553 -47
- package/services/entity-enrichment.ts +43 -2
- package/services/llm-rate-limit-headers.ts +1 -4
- package/services/maintenance-log-analyzer.ts +13 -9
- package/services/reinforcement-extract.ts +19 -0
- package/setup/hybrid-memory-reload-coordinator.ts +26 -0
- package/setup/register-plugin.ts +62 -32
- package/setup/reregister-policy.ts +10 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-stats-helpers.js","names":[],"sources":["../../../../cli/commands/manage/storage-stats-helpers.ts"],"sourcesContent":["/**\n * CLI registration functions for management commands.\n * Extracted from cli/register.ts lines 290-1552.\n */\n\nimport { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { GraphConnectedStats } from \"../../../backends/facts-db/links.js\";\nimport type { ProcedurePromotionBlockReason } from \"../../../backends/facts-db/procedures.js\";\nimport { type GraphExpansionStats, expandGraph, resolveGraphHubDegreeCap } from \"../../../services/graph-retrieval.js\";\nimport type { MemoryEntry } from \"../../../types/memory.js\";\nimport { isEntityStopWord } from \"../../../utils/entity-stopwords.js\";\nimport { SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER } from \"../../cmd-feedback.js\";\nimport type { ManageBindings } from \"./bindings.js\";\n/** Max rows sampled for implicit-feedback prefix histogram (#1193); keeps audit bounded on huge pattern tables. */\nexport const IMPLICIT_FEEDBACK_HISTOGRAM_SAMPLE_CAP = 20_000;\n/**\n * Legacy category aliases observed in long-lived stores.\n * These are treated as intentionally remappable when their configured\n * canonical targets exist, so audit health can avoid strict-mode noise\n * while still surfacing counts in categories.unknown.\n */\nconst LEGACY_CATEGORY_REMAPS: Readonly<Record<string, string>> = {\n forge_busy: \"forge\",\n forge_dispatch: \"forge\",\n forge_ops: \"forge\",\n episode: \"ops_summary\",\n};\n\ntype ReindexCheckpoint = {\n offset: number;\n total: number;\n migrated: number;\n skipped: number;\n ts: number;\n};\n\nexport function defaultReindexCheckpointPath(resolvedSqlitePath: string): string {\n return join(dirname(resolvedSqlitePath), \".reindex_checkpoint.json\");\n}\n\nexport function readReindexCheckpoint(path: string): ReindexCheckpoint | null {\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf-8\")) as Partial<ReindexCheckpoint>;\n if (\n typeof parsed.offset === \"number\" &&\n typeof parsed.total === \"number\" &&\n typeof parsed.migrated === \"number\" &&\n typeof parsed.skipped === \"number\" &&\n typeof parsed.ts === \"number\"\n ) {\n return {\n offset: Math.max(0, Math.floor(parsed.offset)),\n total: Math.max(0, Math.floor(parsed.total)),\n migrated: Math.max(0, Math.floor(parsed.migrated)),\n skipped: Math.max(0, Math.floor(parsed.skipped)),\n ts: Math.max(0, Math.floor(parsed.ts)),\n };\n }\n } catch {\n // ignore malformed checkpoints; caller treats as absent\n }\n return null;\n}\n\nexport function writeReindexCheckpoint(path: string, state: ReindexCheckpoint): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(state, null, 2), \"utf-8\");\n}\n\nexport function parseBoundedIntOption(raw: unknown, fallback: number, min: number, max: number): number {\n const parsed = Number.parseInt(String(raw ?? fallback), 10);\n const value = Number.isFinite(parsed) ? parsed : fallback;\n return Math.max(min, Math.min(max, value));\n}\n\nexport function parseBoundedFloatOption(raw: unknown, fallback: number, min: number, max: number): number {\n const parsed = Number.parseFloat(String(raw ?? fallback));\n const value = Number.isFinite(parsed) ? parsed : fallback;\n return Math.max(min, Math.min(max, value));\n}\n\ntype SyncBundleFile = {\n path: string;\n contentBase64: string;\n};\n\nconst SYNC_BUNDLE_MIN_ITERATIONS = 100_000;\nconst SYNC_BUNDLE_MAX_ITERATIONS = 2_000_000;\nconst SYNC_BUNDLE_SALT_BYTES = 16;\nconst SYNC_BUNDLE_IV_BYTES = 12;\nconst SYNC_BUNDLE_TAG_BYTES = 16;\n\nexport function collectExportBundleFiles(root: string, dir = root): SyncBundleFile[] {\n const files: SyncBundleFile[] = [];\n for (const name of readdirSync(dir).sort()) {\n const fullPath = join(dir, name);\n const st = statSync(fullPath);\n if (st.isDirectory()) {\n files.push(...collectExportBundleFiles(root, fullPath));\n continue;\n }\n if (!st.isFile()) continue;\n const rel = fullPath.slice(root.length + 1).replace(/\\\\/g, \"/\");\n files.push({ path: rel, contentBase64: readFileSync(fullPath).toString(\"base64\") });\n }\n return files;\n}\n\nfunction decodeRequiredBase64Field(envelope: Record<string, unknown>, field: string, expectedBytes?: number): Buffer {\n const raw = envelope[field];\n if (typeof raw !== \"string\" || raw.length === 0) {\n throw new Error(`sync bundle field ${field} must be a non-empty base64 string`);\n }\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(raw) || raw.length % 4 !== 0) {\n throw new Error(`sync bundle field ${field} is not valid base64`);\n }\n const decoded = Buffer.from(raw, \"base64\");\n if (expectedBytes !== undefined && decoded.length !== expectedBytes) {\n throw new Error(`sync bundle field ${field} must decode to ${expectedBytes} bytes`);\n }\n if (expectedBytes === undefined && decoded.length === 0) {\n throw new Error(`sync bundle field ${field} must not be empty`);\n }\n return decoded;\n}\n\nexport function validateSyncEnvelope(raw: unknown): {\n schemaVersion: 1;\n type: \"hybrid-memory-sync-bundle\";\n alg: \"aes-256-gcm\";\n kdf: \"pbkdf2-sha256\";\n iterations: number;\n salt: Buffer;\n iv: Buffer;\n tag: Buffer;\n ciphertext: Buffer;\n} {\n if (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new Error(\"sync bundle must be a JSON object\");\n }\n const envelope = raw as Record<string, unknown>;\n if (envelope.schemaVersion !== 1) throw new Error(\"unsupported sync bundle schemaVersion\");\n if (envelope.type !== \"hybrid-memory-sync-bundle\") throw new Error(\"unsupported sync bundle type\");\n if (envelope.alg !== \"aes-256-gcm\") throw new Error(\"unsupported sync bundle algorithm\");\n if (envelope.kdf !== \"pbkdf2-sha256\") throw new Error(\"unsupported sync bundle KDF\");\n const iterations = envelope.iterations;\n if (\n typeof iterations !== \"number\" ||\n !Number.isInteger(iterations) ||\n iterations < SYNC_BUNDLE_MIN_ITERATIONS ||\n iterations > SYNC_BUNDLE_MAX_ITERATIONS\n ) {\n throw new Error(\n `sync bundle iterations must be an integer between ${SYNC_BUNDLE_MIN_ITERATIONS} and ${SYNC_BUNDLE_MAX_ITERATIONS}`,\n );\n }\n return {\n schemaVersion: 1,\n type: \"hybrid-memory-sync-bundle\",\n alg: \"aes-256-gcm\",\n kdf: \"pbkdf2-sha256\",\n iterations,\n salt: decodeRequiredBase64Field(envelope, \"salt\", SYNC_BUNDLE_SALT_BYTES),\n iv: decodeRequiredBase64Field(envelope, \"iv\", SYNC_BUNDLE_IV_BYTES),\n tag: decodeRequiredBase64Field(envelope, \"tag\", SYNC_BUNDLE_TAG_BYTES),\n ciphertext: decodeRequiredBase64Field(envelope, \"ciphertext\"),\n };\n}\n\n/**\n * Insert one `storage_growth_history` row per UTC calendar day (idempotent).\n * Enables `audit health` 7d deltas when combined with daily cron (#audit remediation).\n */\nexport function recordStorageGrowthSample(\n factsDb: ManageBindings[\"factsDb\"],\n lanceBytes: number | null,\n opts?: { force?: boolean; dryRun?: boolean },\n): {\n inserted: boolean;\n recordedAt: number;\n sampleId: number | null;\n status: \"recorded\" | \"skipped\" | \"dry_run\";\n reason: \"already_sampled_today\" | \"storage_unavailable\" | null;\n sample: {\n recordedAt: number;\n sqliteBytes: number | null;\n lanceBytes: number | null;\n linkCount: number;\n factCount: number;\n };\n} {\n const raw = factsDb.getRawDb?.();\n const nowSecReport = Math.floor(Date.now() / 1000);\n const storageBytes = factsDb.estimateStorageBytes?.();\n const activeFacts = factsDb.getCount();\n const linkCountTotal = raw\n ? Number((raw.prepare(\"SELECT COUNT(*) AS c FROM memory_links\").get() as { c: number } | undefined)?.c ?? 0)\n : 0;\n const sample = {\n recordedAt: nowSecReport,\n sqliteBytes: storageBytes?.sqliteBytes ?? null,\n lanceBytes,\n linkCount: linkCountTotal,\n factCount: activeFacts,\n };\n if (!raw) {\n return {\n inserted: false,\n recordedAt: nowSecReport,\n sampleId: null,\n status: \"skipped\",\n reason: \"storage_unavailable\",\n sample,\n };\n }\n if (opts?.dryRun) {\n return {\n inserted: false,\n recordedAt: nowSecReport,\n sampleId: null,\n status: \"dry_run\",\n reason: null,\n sample,\n };\n }\n const d = new Date();\n const startOfDayUtc = Math.floor(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()) / 1000);\n const alreadyToday =\n !opts?.force &&\n (raw.prepare(\"SELECT 1 AS ok FROM storage_growth_history WHERE recorded_at >= ? LIMIT 1\").get(startOfDayUtc) as\n | { ok: number }\n | undefined);\n if (alreadyToday) {\n return {\n inserted: false,\n recordedAt: nowSecReport,\n sampleId: null,\n status: \"skipped\",\n reason: \"already_sampled_today\",\n sample,\n };\n }\n const insertResult = raw\n .prepare(\n \"INSERT INTO storage_growth_history (recorded_at, sqlite_bytes, lance_bytes, link_count, fact_count) VALUES (?, ?, ?, ?, ?)\",\n )\n .run(sample.recordedAt, sample.sqliteBytes, sample.lanceBytes, sample.linkCount, sample.factCount) as {\n lastInsertRowid?: number | bigint;\n };\n const sampleId = insertResult.lastInsertRowid ? Number(insertResult.lastInsertRowid) : null;\n return {\n inserted: true,\n recordedAt: nowSecReport,\n sampleId,\n status: \"recorded\",\n reason: null,\n sample,\n };\n}\n\n/** Apply optional CLI filters to merged hybrid search results (category/entity/key/source/tier). */\nexport function entryMatchesHybridSearchFilters(\n entry: MemoryEntry,\n opts?: {\n category?: string;\n entity?: string;\n key?: string;\n source?: string;\n tier?: string;\n },\n): boolean {\n if (!opts) return true;\n if (opts.category && entry.category !== opts.category) return false;\n if (opts.entity != null && opts.entity !== \"\" && entry.entity !== opts.entity) return false;\n if (opts.key != null && opts.key !== \"\" && entry.key !== opts.key) return false;\n if (opts.source != null && opts.source !== \"\" && entry.source !== opts.source) return false;\n if (opts.tier != null && opts.tier !== \"\" && entry.tier !== opts.tier) return false;\n return true;\n}\n\nexport type AuditHealthReport = {\n schemaVersion: 1;\n generatedAt: string;\n /** \"ok\" when no warnings and no generation errors; \"partial\" when degraded (warnings, timeouts, or non-fatal errors). */\n status: \"ok\" | \"partial\" | \"failed\";\n /** @deprecated Use `status` instead. Kept for backward compatibility. */\n ok: boolean;\n warningCount: number;\n errorCount: number;\n activeFacts: number;\n /** Age (in days) of the oldest active fact. Used to gate sparse-store warnings (#1193). */\n storeAgeDays: number;\n canonicalEmbeddings: number;\n vectorless: number;\n vectorlessBySource: Array<{ source: string; count: number }>;\n procedures: {\n total: number;\n validated: number;\n promoted: number;\n validatedNotPromoted: number;\n blocked: number;\n topBlockReason: string | null;\n /** Breakdown of blocked (validated, not-promoted) procedures by block reason. */\n byBlockReason: Record<ProcedurePromotionBlockReason, number>;\n };\n graphHubs: Array<{\n id: string;\n outDegree: number;\n textPreview: string | null;\n overCap: boolean;\n eventTypeHistogram: Record<string, number>;\n }>;\n structuralEligibleWarmFacts: number;\n patternBloat: {\n implicitFeedbackPatterns: number;\n /** Top 5 leading-token prefixes for implicit-feedback rows (legacy category=pattern and trajectory lessons, #1193, #1736). */\n implicitFeedbackPrefixHistogram: Array<{ prefix: string; count: number }>;\n };\n entityStopwordMatches: Array<{ entity: string; count: number }>;\n /** Top entities with configured stop-words removed (retrieval-aligned view, #1193). */\n topEntitiesFiltered: Array<{ entity: string; count: number }>;\n storage: {\n sqliteBytes: number | null;\n walBytes: number | null;\n shmBytes: number | null;\n /** LanceDB directory size on disk in bytes (#1193). */\n lanceBytes: number | null;\n };\n storageGrowth: {\n lastSampleAt: number | null;\n delta7d: {\n sqliteBytes: number | null;\n lanceBytes: number | null;\n linkCount: number | null;\n factCount: number | null;\n } | null;\n /** Lance bytes per week derived from delta7d (null when unknown). */\n lanceBytesPerWeekDelta: number | null;\n };\n implicitFeedbackSignalNoise: {\n rowsPerDay30d: Record<string, number>;\n paraphraseRatio: number | null;\n };\n tiers: Record<string, number>;\n decay: Record<string, number>;\n /**\n * Stickiness ratio: `(stable + permanent) / activeFacts`. Surfaced separately from `decay` so\n * dashboards can render a single number and gate the 60% warning (#1193).\n */\n stableStickiness: { stablePermanent: number; activeFacts: number; ratio: number };\n vectorIntegrity: {\n score: number;\n degraded: boolean;\n degradedReason: string | null;\n vectorlessRatio: number;\n orphanSignals: {\n sqliteFactsWithoutCanonicalEmbedding: number;\n };\n };\n vectorLifecycleSlo: {\n targets: {\n maxVectorlessRatio: number;\n minIntegrityScore: number;\n };\n breaches: Array<{ key: \"vectorless_ratio\" | \"integrity_score\"; actual: number; target: number }>;\n };\n categories: {\n configured: string[];\n present: string[];\n /** Per-category drift counts so the JSON consumer doesn't need to re-query (#1193). */\n unknown: Array<{ category: string; count: number }>;\n };\n sources: Record<string, number>;\n implicitFeedbackTrajectorySignals: number;\n graphHubGuard: {\n configuredCap: number | null | undefined;\n effectiveCap: number | null;\n connectedProbe: GraphConnectedStats;\n expansionProbe: GraphExpansionStats;\n } | null;\n warnings: string[];\n remediation: string[];\n /** Errors encountered during report generation (e.g., timeouts, query failures). */\n errors: Array<{ section: string; message: string }>;\n /** Optional operator budget used for audit-health command execution. */\n timeoutMs?: number;\n /** Elapsed wall-clock time spent building the report. */\n elapsedMs?: number;\n};\n\nexport function countImplicitFeedbackTrajectorySignals(factsDb: ManageBindings[\"factsDb\"]): number {\n const raw = factsDb.getRawDb?.();\n if (!raw) return 0;\n const row = raw\n .prepare(\n `SELECT COUNT(*) as cnt FROM facts WHERE source = 'implicit-feedback' AND superseded_at IS NULL AND ${SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER}`,\n )\n .get() as { cnt: number } | undefined;\n return row?.cnt ?? 0;\n}\n\nexport function buildAuditHealthReport(\n factsDb: ManageBindings[\"factsDb\"],\n getMemoryCategories: () => readonly string[],\n entityStopWords: readonly string[] = [],\n graphHubDegreeCap?: number | null,\n options?: {\n lanceBytes?: number | null;\n preReportErrors?: Array<{ section: string; message: string }>;\n timeoutMs?: number;\n startedAtMs?: number;\n deadlineMs?: number;\n degradedState?: { active: boolean; reason: string | null };\n },\n): AuditHealthReport {\n const startedAtMs = options?.startedAtMs ?? Date.now();\n const deadlineMs = options?.deadlineMs;\n const errors: Array<{ section: string; message: string }> = [...(options?.preReportErrors ?? [])];\n const timeoutRecorded = new Set<string>();\n const hasBudget = (section: string): boolean => {\n if (deadlineMs == null || Date.now() <= deadlineMs) return true;\n if (!timeoutRecorded.has(section)) {\n timeoutRecorded.add(section);\n errors.push({\n section,\n message: `Skipped: audit-health timeout budget exceeded${options?.timeoutMs ? ` (${options.timeoutMs}ms)` : \"\"}`,\n });\n }\n return false;\n };\n const capForHubListing = graphHubDegreeCap === undefined ? 500 : graphHubDegreeCap;\n const activeFacts = factsDb.getCount();\n const canonicalEmbeddings = factsDb.countCanonicalEmbeddings();\n const procedures = factsDb.proceduresCount();\n const validated = factsDb.proceduresValidatedCount();\n const promoted = factsDb.proceduresPromotedCount();\n const tiers = factsDb.statsBreakdownByTier();\n const decay = factsDb.statsBreakdownByDecayClass();\n const present = factsDb.uniqueMemoryCategories().slice().sort();\n const configured = [...getMemoryCategories()].slice().sort();\n const configuredSet = new Set(configured);\n const sources = factsDb.statsBySource();\n const implicitFeedbackTrajectorySignals = countImplicitFeedbackTrajectorySignals(factsDb);\n const vectorless = factsDb.countVectorlessActiveFacts();\n const vectorlessBySource = factsDb.vectorlessActiveFactsBySource(10);\n const procedureTriage = factsDb.triageProcedures({ status: \"validated\", notPromoted: true, limit: 10_000 });\n const raw = factsDb.getRawDb?.();\n\n // #1193: surface per-category drift counts directly so JSON consumers do not need to re-query.\n const unknown: Array<{ category: string; count: number }> = (() => {\n const drift = present.filter((category: string) => !configuredSet.has(category));\n if (drift.length === 0) return [];\n if (!raw || !hasBudget(\"categories.unknown\")) return drift.map((category) => ({ category, count: 0 }));\n return drift.map((category) => {\n const row = raw\n .prepare(`SELECT COUNT(*) AS cnt FROM facts WHERE COALESCE(category, 'other') = ? AND superseded_at IS NULL`)\n .get(category) as { cnt: number } | undefined;\n return { category, count: Number(row?.cnt ?? 0) };\n });\n })();\n const unconfiguredCategories = unknown.filter((row) => {\n const mappedTarget = LEGACY_CATEGORY_REMAPS[row.category];\n return !mappedTarget || !configuredSet.has(mappedTarget);\n });\n\n // #1193: store age (days) gates sparse-store warnings — a brand-new install with hot=0 is\n // expected, and the operator should not get a \"memory is broken\" warning during the first\n // two weeks while the store warms up.\n const oldestRow =\n raw != null\n ? (raw.prepare(\"SELECT MIN(created_at) AS oldest FROM facts WHERE superseded_at IS NULL\").get() as\n | { oldest: number | null }\n | undefined)\n : undefined;\n const nowSecForAge = Math.floor(Date.now() / 1000);\n const storeAgeDays = oldestRow?.oldest != null ? Math.max(0, (nowSecForAge - oldestRow.oldest) / 86400) : 0;\n const graphHubs =\n raw && hasBudget(\"graphHubs\")\n ? (\n raw\n .prepare(\n `SELECT ml.source_fact_id AS id, COUNT(*) AS cnt, SUBSTR(f.text, 1, 120) AS text_preview\n FROM memory_links ml\n LEFT JOIN facts f ON f.id = ml.source_fact_id\n WHERE ml.link_type != 'CONTRADICTS'\n GROUP BY ml.source_fact_id\n ORDER BY cnt DESC\n LIMIT 10`,\n )\n .all() as Array<{ id: string; cnt: number; text_preview: string | null }>\n ).map((row) => {\n const eventTypeHistogram: Record<string, number> = {};\n if (raw) {\n const pr = raw.prepare(\"SELECT provenance_json FROM facts WHERE id = ?\").get(row.id) as\n | { provenance_json: string | null }\n | undefined;\n if (pr?.provenance_json) {\n try {\n const parsed = JSON.parse(pr.provenance_json) as { sourceEvents?: Array<{ eventType?: string }> };\n for (const ev of parsed.sourceEvents ?? []) {\n const t = typeof ev.eventType === \"string\" && ev.eventType ? ev.eventType : \"unknown\";\n eventTypeHistogram[t] = (eventTypeHistogram[t] ?? 0) + 1;\n }\n } catch {\n /* ignore malformed provenance */\n }\n }\n }\n return {\n id: row.id,\n outDegree: Number(row.cnt ?? 0),\n textPreview: row.text_preview ?? null,\n overCap: capForHubListing != null && Number(row.cnt ?? 0) > capForHubListing,\n eventTypeHistogram,\n };\n })\n : [];\n const structuralEligibleWarmFacts = raw\n ? Number(\n (\n raw\n .prepare(\n `SELECT COUNT(*) AS cnt FROM facts\n WHERE superseded_at IS NULL\n AND (expires_at IS NULL OR expires_at > ?)\n AND TRIM(COALESCE(key, '')) != ''\n AND TRIM(COALESCE(value, '')) != ''\n AND NOT (key = 'implicit_feedback_signal')\n AND COALESCE(tier, 'warm') = 'warm'`,\n )\n .get(Math.floor(Date.now() / 1000)) as { cnt: number } | undefined\n )?.cnt ?? 0,\n )\n : 0;\n const implicitFeedbackPatterns = raw\n ? Number(\n (\n raw\n .prepare(\n `SELECT COUNT(*) AS cnt FROM facts\n WHERE superseded_at IS NULL\n AND category = 'pattern'\n AND source = 'implicit-feedback'`,\n )\n .get() as { cnt: number } | undefined\n )?.cnt ?? 0,\n )\n : 0;\n // #1193, #1736: aggregate the leading 6 tokens of implicit-feedback rows (legacy category=pattern\n // and modern trajectory lessons) to surface \"should never store\" duplicate prefixes (e.g. paraphrases\n // of the same self-correction) without scanning every row.\n // LIMIT added to prevent hanging on long-lived stores with thousands of implicit-feedback patterns.\n const implicitFeedbackPrefixHistogram: Array<{ prefix: string; count: number }> = (() => {\n if (!raw || !hasBudget(\"implicitFeedbackPrefixHistogram\")) return [];\n const cap = IMPLICIT_FEEDBACK_HISTOGRAM_SAMPLE_CAP;\n try {\n // Fetch cap + 1 rows so we only flag truncation when another row exists (exactly `cap` rows is not truncated).\n // Include both legacy category=pattern rows and modern trajectory lesson rows (#1736).\n const rows = raw\n .prepare(\n `SELECT text FROM facts\n WHERE superseded_at IS NULL AND source = 'implicit-feedback'\n AND (category = 'pattern' OR (${SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER}))\n LIMIT ?`,\n )\n .all(cap + 1) as Array<{ text: string | null }>;\n const truncated = rows.length > cap;\n const forAgg = truncated ? rows.slice(0, cap) : rows;\n if (forAgg.length === 0) return [];\n const counts = new Map<string, number>();\n for (const row of forAgg) {\n const text = (row.text ?? \"\").trim().toLowerCase();\n if (!text) continue;\n const tokens = text.split(/\\s+/).slice(0, 6).join(\" \");\n const prefix = tokens.length > 0 ? tokens.slice(0, 80) : \"<empty>\";\n counts.set(prefix, (counts.get(prefix) ?? 0) + 1);\n }\n const result = [...counts.entries()]\n .map(([prefix, count]) => ({ prefix, count }))\n .filter((row) => row.count >= 2)\n .sort((a, b) => b.count - a.count || a.prefix.localeCompare(b.prefix))\n .slice(0, 5);\n if (truncated) {\n const totalSampled = Number(\n (\n raw\n .prepare(\n `SELECT COUNT(*) AS cnt FROM facts\n WHERE superseded_at IS NULL AND source = 'implicit-feedback'\n AND (category = 'pattern' OR (${SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER}))`,\n )\n .get() as { cnt: number } | undefined\n )?.cnt ?? 0,\n );\n errors.push({\n section: \"implicitFeedbackPrefixHistogram\",\n message: `Truncated: histogram sampled first ${cap} of ${totalSampled} implicit-feedback row(s)`,\n });\n }\n return result;\n } catch (err) {\n errors.push({\n section: \"implicitFeedbackPrefixHistogram\",\n message: err instanceof Error ? err.message : String(err),\n });\n return [];\n }\n })();\n const entityStopwordMatches = factsDb\n .topEntities(50)\n .filter((row) => isEntityStopWord(row.entity, entityStopWords))\n .slice(0, 10);\n const topEntitiesFiltered = factsDb.topEntitiesFiltered(10, entityStopWords);\n const storageBytes = factsDb.estimateStorageBytes?.();\n const lanceBytes = options?.lanceBytes ?? null;\n const nowSecReport = Math.floor(Date.now() / 1000);\n\n let storageGrowth: AuditHealthReport[\"storageGrowth\"] = {\n lastSampleAt: null,\n delta7d: null,\n lanceBytesPerWeekDelta: null,\n };\n if (raw && hasBudget(\"storageGrowth\")) {\n recordStorageGrowthSample(factsDb, lanceBytes);\n const lastRow = raw\n .prepare(\"SELECT recorded_at FROM storage_growth_history ORDER BY recorded_at DESC LIMIT 1\")\n .get() as { recorded_at: number } | undefined;\n const latestSnap = raw\n .prepare(\n \"SELECT sqlite_bytes, lance_bytes, link_count, fact_count, recorded_at FROM storage_growth_history ORDER BY recorded_at DESC LIMIT 1\",\n )\n .get() as\n | {\n sqlite_bytes: number | null;\n lance_bytes: number | null;\n link_count: number | null;\n fact_count: number;\n recorded_at: number;\n }\n | undefined;\n const cutoff7d = nowSecReport - 7 * 86400;\n const baselineSnap = raw\n .prepare(\n \"SELECT sqlite_bytes, lance_bytes, link_count, fact_count, recorded_at FROM storage_growth_history WHERE recorded_at <= ? ORDER BY recorded_at DESC LIMIT 1\",\n )\n .get(cutoff7d) as\n | {\n sqlite_bytes: number | null;\n lance_bytes: number | null;\n link_count: number | null;\n fact_count: number;\n recorded_at: number;\n }\n | undefined;\n\n let delta7d: AuditHealthReport[\"storageGrowth\"][\"delta7d\"] = null;\n if (latestSnap && baselineSnap && latestSnap.recorded_at !== baselineSnap.recorded_at) {\n delta7d = {\n sqliteBytes:\n latestSnap.sqlite_bytes != null && baselineSnap.sqlite_bytes != null\n ? latestSnap.sqlite_bytes - baselineSnap.sqlite_bytes\n : null,\n lanceBytes:\n latestSnap.lance_bytes != null && baselineSnap.lance_bytes != null\n ? latestSnap.lance_bytes - baselineSnap.lance_bytes\n : null,\n linkCount:\n latestSnap.link_count != null && baselineSnap.link_count != null\n ? latestSnap.link_count - baselineSnap.link_count\n : null,\n factCount: latestSnap.fact_count - baselineSnap.fact_count,\n };\n }\n const ageWeeks =\n latestSnap && baselineSnap && latestSnap.recorded_at !== baselineSnap.recorded_at\n ? (latestSnap.recorded_at - baselineSnap.recorded_at) / (7 * 86400)\n : 0;\n const lanceBytesPerWeekDelta =\n delta7d?.lanceBytes != null && ageWeeks > 0 ? Math.round(delta7d.lanceBytes / ageWeeks) : null;\n storageGrowth = { lastSampleAt: lastRow?.recorded_at ?? null, delta7d, lanceBytesPerWeekDelta };\n }\n\n const implicitFeedbackSignalNoise: AuditHealthReport[\"implicitFeedbackSignalNoise\"] =\n raw && hasBudget(\"implicitFeedbackSignalNoise\")\n ? (() => {\n const since30d = nowSecReport - 30 * 86400;\n const perDayRows = raw\n .prepare(\n `SELECT date(created_at, 'unixepoch') AS day, COUNT(*) AS cnt FROM facts\n WHERE source = 'implicit-feedback' AND superseded_at IS NULL AND created_at >= ?\n GROUP BY day`,\n )\n .all(since30d) as Array<{ day: string; cnt: number }>;\n const rowsPerDay30d: Record<string, number> = {};\n for (const r of perDayRows) rowsPerDay30d[String(r.day)] = Number(r.cnt ?? 0);\n const pr = raw\n .prepare(\n `SELECT COUNT(*) AS total, COUNT(DISTINCT normalized_hash) AS dist FROM facts\n WHERE source = 'implicit-feedback' AND superseded_at IS NULL AND created_at >= ?`,\n )\n .get(since30d) as { total: number; dist: number };\n const paraphraseRatio = pr.total > 0 ? pr.dist / pr.total : null;\n return { rowsPerDay30d, paraphraseRatio };\n })()\n : { rowsPerDay30d: {}, paraphraseRatio: null };\n\n // #1193: stickiness flag is `(stable + permanent) / activeFacts > 0.6`. The previous 50%\n // stable-only rule fired for healthy stores (because `permanent` decisions are normal).\n const stablePermanentCount = (decay.stable ?? 0) + (decay.permanent ?? 0);\n const stableStickinessRatio = activeFacts > 0 ? stablePermanentCount / activeFacts : 0;\n const stableStickiness = {\n stablePermanent: stablePermanentCount,\n activeFacts,\n ratio: stableStickinessRatio,\n };\n const vectorlessRatio = activeFacts > 0 ? vectorless / activeFacts : 0;\n const degraded = options?.degradedState?.active === true;\n const degradedReason = options?.degradedState?.reason ?? null;\n let integrityScore = 100;\n integrityScore -= Math.min(60, Math.round(vectorlessRatio * 100));\n if (degraded) integrityScore -= 30;\n if (errors.length > 0) integrityScore -= Math.min(20, errors.length * 5);\n integrityScore = Math.max(0, Math.min(100, integrityScore));\n const vectorLifecycleSloTargets = {\n maxVectorlessRatio: 0.02,\n minIntegrityScore: 85,\n } as const;\n const vectorLifecycleSloBreaches: AuditHealthReport[\"vectorLifecycleSlo\"][\"breaches\"] = [];\n if (vectorlessRatio > vectorLifecycleSloTargets.maxVectorlessRatio) {\n vectorLifecycleSloBreaches.push({\n key: \"vectorless_ratio\",\n actual: Number(vectorlessRatio.toFixed(4)),\n target: vectorLifecycleSloTargets.maxVectorlessRatio,\n });\n }\n if (integrityScore < vectorLifecycleSloTargets.minIntegrityScore) {\n vectorLifecycleSloBreaches.push({\n key: \"integrity_score\",\n actual: integrityScore,\n target: vectorLifecycleSloTargets.minIntegrityScore,\n });\n }\n\n const warnings: string[] = [];\n // #1193: gate hot=0/structural=0 warnings on storeAgeDays > 14 to avoid false positives during\n // the first 14 days of a fresh install (no facts have aged into warm/cold yet).\n if (storeAgeDays > 14) {\n if ((tiers.hot ?? 0) === 0)\n warnings.push(\"No HOT tier facts detected; tiering may not be promoting active memory.\");\n if ((tiers.structural ?? 0) === 0)\n warnings.push(\"No STRUCTURAL tier facts detected; key/value facts may be stuck in warm tier.\");\n }\n if (activeFacts > 0 && stableStickinessRatio > 0.6) {\n warnings.push(\n `${(stableStickinessRatio * 100).toFixed(1)}% of active facts are stable+permanent — decay reclassifier may need to run.`,\n );\n }\n if (unconfiguredCategories.length > 0)\n warnings.push(\n `Unconfigured categories present in DB: ${unconfiguredCategories.map((u) => `${u.category}=${u.count}`).join(\", \")}`,\n );\n if (graphHubs.some((hub) => hub.overCap))\n warnings.push(\n `${graphHubs.filter((hub) => hub.overCap).length} graph hub(s) exceed degree cap ${capForHubListing}.`,\n );\n if (structuralEligibleWarmFacts > 100)\n warnings.push(\n `${structuralEligibleWarmFacts} warm fact(s) qualify for structural tier (non-empty key+value; implicit_feedback_signal excluded) but are not structural yet.`,\n );\n if (implicitFeedbackPatterns > 1000)\n warnings.push(`${implicitFeedbackPatterns} implicit-feedback pattern fact(s) may indicate pattern bloat.`);\n if (implicitFeedbackPrefixHistogram.length > 0 && implicitFeedbackPrefixHistogram[0].count >= 10)\n warnings.push(\n `Implicit-feedback patterns share a \"${implicitFeedbackPrefixHistogram[0].prefix}…\" prefix ${implicitFeedbackPrefixHistogram[0].count}× — likely paraphrase duplicates.`,\n );\n if (entityStopwordMatches.length > 0)\n warnings.push(\n `Top entities include stop-word-like labels: ${entityStopwordMatches.map((row) => row.entity).join(\", \")}.`,\n );\n if (vectorless > 0) warnings.push(`${vectorless} active non-kv fact(s) are missing canonical embeddings.`);\n if (degraded)\n warnings.push(\n `Vector store is in degraded mode${degradedReason ? ` (reason: ${degradedReason})` : \"\"}; semantic retrieval may be unavailable.`,\n );\n if (vectorLifecycleSloBreaches.length > 0)\n warnings.push(\n `Vector lifecycle SLO breach(es): ${vectorLifecycleSloBreaches.map((b) => `${b.key} actual=${b.actual} target=${b.target}`).join(\"; \")}`,\n );\n if (procedureTriage.summary.total > 0) {\n const reasonBreakdown = Object.entries(procedureTriage.summary.byReason)\n .filter(([, count]) => count > 0)\n .map(([reason, count]) => `${reason}=${count}`)\n .join(\", \");\n warnings.push(`${procedureTriage.summary.total} validated procedure(s) are not promoted (${reasonBreakdown}).`);\n }\n const remediation: string[] = [];\n if ((tiers.hot ?? 0) === 0 || (tiers.structural ?? 0) === 0 || structuralEligibleWarmFacts > 0)\n remediation.push(\"Run `openclaw hybrid-mem retier --apply`.\");\n if (graphHubs.some((hub) => hub.overCap))\n remediation.push(\n \"Run `openclaw hybrid-mem graph repair --collapse-event-hubs --apply` and keep graph hub guards enabled.\",\n );\n if (unconfiguredCategories.length > 0)\n remediation.push(\"Run `openclaw hybrid-mem categories audit`, then `categories remap --apply` where appropriate.\");\n if (activeFacts > 0 && stableStickinessRatio > 0.6) {\n remediation.push(\n \"Run `openclaw hybrid-mem decay reclassify --dry-run --stable-only`, then `openclaw hybrid-mem decay reclassify --apply --stable-only` if the report looks correct.\",\n );\n }\n if (vectorless > 0) remediation.push(\"Run `openclaw hybrid-mem reembed-vectorless --apply`.\");\n if (degraded) remediation.push(\"Run `openclaw hybrid-mem repair-vectors` and validate LanceDB connectivity.\");\n if (procedureTriage.summary.total > 0) {\n remediation.push(\n \"Run `openclaw hybrid-mem procedures triage --not-promoted` and `generate-auto-skills` where appropriate.\",\n );\n if ((procedureTriage.summary.byReason.low_recall ?? 0) > 0)\n remediation.push(\n \"Low-recall procedures need more successful uses before promotion; retrain or merge duplicates via `openclaw hybrid-mem procedures triage --not-promoted --reason low_recall`.\",\n );\n }\n if (\n implicitFeedbackPatterns > 1000 ||\n (implicitFeedbackPrefixHistogram.length > 0 && implicitFeedbackPrefixHistogram[0].count >= 10)\n ) {\n remediation.push(\n \"Run `openclaw hybrid-mem reflect-meta --collapse-implicit-feedback --include-legacy` (omit `--dry-run` to apply mutations).\",\n );\n }\n if (entityStopwordMatches.length > 0) {\n remediation.push(\n \"Run `openclaw hybrid-mem entities clean --stopwords --apply` to null stop-word entity labels from existing facts.\",\n );\n }\n\n let graphHubGuard: AuditHealthReport[\"graphHubGuard\"] = null;\n if (raw && hasBudget(\"graphHubGuard\")) {\n const probeRow = raw.prepare(\"SELECT id FROM facts WHERE superseded_at IS NULL LIMIT 1\").get() as\n | { id: string }\n | undefined;\n if (probeRow?.id) {\n const connectedProbe: GraphConnectedStats = { nodesConsidered: 0, nodesSkipped: 0, hubsSkipped: 0 };\n factsDb.getConnectedFactIds([probeRow.id], 2, { hubDegreeCap: graphHubDegreeCap, stats: connectedProbe });\n const entry = factsDb.getById(probeRow.id);\n if (entry) {\n const { stats: expansionProbe } = expandGraph(factsDb, [{ factId: probeRow.id, score: 1, entry }], {\n maxDepth: 2,\n maxExpandedResults: 20,\n hubDegreeCap: graphHubDegreeCap,\n });\n graphHubGuard = {\n configuredCap: graphHubDegreeCap,\n effectiveCap: resolveGraphHubDegreeCap(graphHubDegreeCap),\n connectedProbe,\n expansionProbe,\n };\n }\n }\n }\n\n const status: AuditHealthReport[\"status\"] = errors.length > 0 || warnings.length > 0 ? \"partial\" : \"ok\";\n\n return {\n schemaVersion: 1,\n generatedAt: new Date().toISOString(),\n status,\n ok: warnings.length === 0 && errors.length === 0,\n warningCount: warnings.length,\n errorCount: errors.length,\n activeFacts,\n storeAgeDays: Number(storeAgeDays.toFixed(2)),\n canonicalEmbeddings,\n vectorless,\n vectorlessBySource,\n procedures: {\n total: procedures,\n validated,\n promoted,\n validatedNotPromoted: Math.max(0, validated - promoted),\n blocked: procedureTriage.summary.total,\n topBlockReason: procedureTriage.summary.topReason,\n byBlockReason: procedureTriage.summary.byReason,\n },\n graphHubs,\n structuralEligibleWarmFacts,\n patternBloat: { implicitFeedbackPatterns, implicitFeedbackPrefixHistogram },\n entityStopwordMatches,\n topEntitiesFiltered,\n storage: {\n sqliteBytes: storageBytes?.sqliteBytes ?? null,\n walBytes: storageBytes?.walBytes ?? null,\n shmBytes: storageBytes?.shmBytes ?? null,\n lanceBytes,\n },\n storageGrowth,\n implicitFeedbackSignalNoise,\n tiers,\n decay,\n stableStickiness,\n vectorIntegrity: {\n score: integrityScore,\n degraded,\n degradedReason,\n vectorlessRatio: Number(vectorlessRatio.toFixed(4)),\n orphanSignals: {\n sqliteFactsWithoutCanonicalEmbedding: vectorless,\n },\n },\n vectorLifecycleSlo: {\n targets: vectorLifecycleSloTargets,\n breaches: vectorLifecycleSloBreaches,\n },\n categories: { configured, present, unknown },\n sources,\n implicitFeedbackTrajectorySignals,\n graphHubGuard,\n warnings,\n remediation,\n errors,\n timeoutMs: options?.timeoutMs,\n elapsedMs: Date.now() - startedAtMs,\n };\n}\n\nexport function printAuditHealthMarkdown(report: AuditHealthReport): void {\n console.log(\"# Hybrid-memory audit health\");\n console.log(\"\");\n console.log(`Status: ${report.status}`);\n console.log(`Generated: ${report.generatedAt}`);\n console.log(`Schema version: ${report.schemaVersion}`);\n console.log(`Active facts: ${report.activeFacts}`);\n console.log(`Store age (days): ${report.storeAgeDays.toFixed(1)}`);\n console.log(`Canonical embeddings: ${report.canonicalEmbeddings}`);\n console.log(`Vectorless active non-kv facts: ${report.vectorless}`);\n console.log(\n `Vector integrity score: ${report.vectorIntegrity.score}/100 (degraded=${report.vectorIntegrity.degraded ? \"yes\" : \"no\"}; vectorlessRatio=${report.vectorIntegrity.vectorlessRatio})`,\n );\n if (report.vectorIntegrity.degradedReason) {\n console.log(`Vector degraded reason: ${report.vectorIntegrity.degradedReason}`);\n }\n if (report.vectorLifecycleSlo.breaches.length > 0) {\n console.log(\n `Vector lifecycle SLO breaches: ${report.vectorLifecycleSlo.breaches.map((b) => `${b.key} actual=${b.actual} target=${b.target}`).join(\", \")}`,\n );\n }\n if (report.vectorlessBySource.length > 0) {\n console.log(`Vectorless by source: ${report.vectorlessBySource.map((r) => `${r.source}=${r.count}`).join(\", \")}`);\n }\n console.log(\n `Procedures: ${report.procedures.total} (validated: ${report.procedures.validated}, promoted: ${report.procedures.promoted}, blocked: ${report.procedures.blocked}${report.procedures.topBlockReason ? ` by ${report.procedures.topBlockReason}` : \"\"})`,\n );\n console.log(`Tiers: ${JSON.stringify(report.tiers)}`);\n console.log(`Decay: ${JSON.stringify(report.decay)}`);\n console.log(\n `Unknown categories: ${report.categories.unknown.length ? report.categories.unknown.map((u) => `${u.category}=${u.count}`).join(\", \") : \"none\"}`,\n );\n console.log(\n `Stable+permanent stickiness: ${report.stableStickiness.stablePermanent}/${report.stableStickiness.activeFacts} (${(\n report.stableStickiness.ratio * 100\n ).toFixed(1)}%)`,\n );\n console.log(`Graph hubs over cap: ${report.graphHubs.filter((hub) => hub.overCap).length}`);\n if (report.graphHubs.length > 0) {\n // #1193: TTY summary now mirrors the JSON `top 10`, not the previous truncated 3.\n console.log(\n `Top graph hubs: ${report.graphHubs\n .slice(0, 10)\n .map((hub) => `${hub.id.slice(0, 8)}=${hub.outDegree}`)\n .join(\", \")}`,\n );\n }\n console.log(`Structural-eligible warm facts: ${report.structuralEligibleWarmFacts}`);\n console.log(`Implicit-feedback pattern facts: ${report.patternBloat.implicitFeedbackPatterns}`);\n if (report.patternBloat.implicitFeedbackPrefixHistogram.length > 0) {\n console.log(\n `Implicit-feedback prefix histogram: ${report.patternBloat.implicitFeedbackPrefixHistogram\n .map((row) => `\"${row.prefix}\"=${row.count}`)\n .join(\", \")}`,\n );\n }\n if (report.topEntitiesFiltered.length > 0) {\n console.log(\n `Top entities (retrieval view, stop-words removed): ${report.topEntitiesFiltered.map((row) => `${row.entity}=${row.count}`).join(\", \")}`,\n );\n }\n if (report.entityStopwordMatches.length > 0) {\n console.log(\n `Entity stop-word matches: ${report.entityStopwordMatches.map((row) => `${row.entity}=${row.count}`).join(\", \")}`,\n );\n }\n if (report.storage.sqliteBytes != null) console.log(`SQLite bytes: ${report.storage.sqliteBytes}`);\n if (report.storage.lanceBytes != null) console.log(`Lance bytes: ${report.storage.lanceBytes}`);\n if (report.storageGrowth.lastSampleAt != null) {\n const lanceWeekly = report.storageGrowth.lanceBytesPerWeekDelta;\n const lanceWeeklyStr = lanceWeekly != null ? `; lance/week=${lanceWeekly}` : \"\";\n console.log(\n `Storage growth (last sample unix): ${report.storageGrowth.lastSampleAt}; 7d delta: ${JSON.stringify(report.storageGrowth.delta7d)}${lanceWeeklyStr}`,\n );\n }\n console.log(\n `Implicit-feedback signal noise (30d): paraphraseRatio=${String(report.implicitFeedbackSignalNoise.paraphraseRatio)} days=${Object.keys(report.implicitFeedbackSignalNoise.rowsPerDay30d).length}`,\n );\n console.log(`Implicit-feedback trajectory signals: ${report.implicitFeedbackTrajectorySignals}`);\n if (report.graphHubGuard) {\n const g = report.graphHubGuard;\n console.log(\n `Graph hub guard probe (cap=${String(g.configuredCap)} effective=${String(g.effectiveCap)}): connected considered=${g.connectedProbe.nodesConsidered} skipped=${g.connectedProbe.nodesSkipped} hubsSkipped=${g.connectedProbe.hubsSkipped}; expansion considered=${g.expansionProbe.nodesConsidered} skipped=${g.expansionProbe.nodesSkipped} hubsSkipped=${g.expansionProbe.hubsSkipped}`,\n );\n }\n console.log(\"\");\n if (report.errors.length > 0) {\n console.log(\"Errors:\");\n for (const error of report.errors) console.log(`- [${error.section}] ${error.message}`);\n console.log(\"\");\n }\n if (report.warnings.length === 0) {\n console.log(\"Warnings: none\");\n } else {\n console.log(\"Warnings:\");\n for (const warning of report.warnings) console.log(`- ${warning}`);\n }\n if (report.remediation.length > 0) {\n console.log(\"\");\n console.log(\"Remediation:\");\n for (const hint of report.remediation) console.log(`- ${hint}`);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"storage-stats-helpers.js","names":[],"sources":["../../../../cli/commands/manage/storage-stats-helpers.ts"],"sourcesContent":["/**\n * CLI registration functions for management commands.\n * Extracted from cli/register.ts lines 290-1552.\n */\n\nimport { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { GraphConnectedStats } from \"../../../backends/facts-db/links.js\";\nimport type { ProcedurePromotionBlockReason } from \"../../../backends/facts-db/procedures.js\";\nimport { type GraphExpansionStats, expandGraph, resolveGraphHubDegreeCap } from \"../../../services/graph-retrieval.js\";\nimport type { MemoryEntry } from \"../../../types/memory.js\";\nimport { isEntityStopWord } from \"../../../utils/entity-stopwords.js\";\nimport { SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER } from \"../../cmd-feedback.js\";\nimport type { ManageBindings } from \"./bindings.js\";\n/** Max rows sampled for implicit-feedback prefix histogram (#1193); keeps audit bounded on huge pattern tables. */\nexport const IMPLICIT_FEEDBACK_HISTOGRAM_SAMPLE_CAP = 20_000;\n/**\n * Legacy category aliases observed in long-lived stores.\n * These are treated as intentionally remappable when their configured\n * canonical targets exist, so audit health can avoid strict-mode noise\n * while still surfacing counts in categories.unknown.\n */\nconst LEGACY_CATEGORY_REMAPS: Readonly<Record<string, string>> = {\n forge_busy: \"forge\",\n forge_dispatch: \"forge\",\n forge_ops: \"forge\",\n episode: \"ops_summary\",\n};\n\ntype ReindexCheckpoint = {\n offset: number;\n total: number;\n migrated: number;\n skipped: number;\n ts: number;\n};\n\nexport function defaultReindexCheckpointPath(resolvedSqlitePath: string): string {\n return join(dirname(resolvedSqlitePath), \".reindex_checkpoint.json\");\n}\n\nexport function readReindexCheckpoint(path: string): ReindexCheckpoint | null {\n if (!existsSync(path)) return null;\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf-8\")) as Partial<ReindexCheckpoint>;\n if (\n typeof parsed.offset === \"number\" &&\n typeof parsed.total === \"number\" &&\n typeof parsed.migrated === \"number\" &&\n typeof parsed.skipped === \"number\" &&\n typeof parsed.ts === \"number\"\n ) {\n return {\n offset: Math.max(0, Math.floor(parsed.offset)),\n total: Math.max(0, Math.floor(parsed.total)),\n migrated: Math.max(0, Math.floor(parsed.migrated)),\n skipped: Math.max(0, Math.floor(parsed.skipped)),\n ts: Math.max(0, Math.floor(parsed.ts)),\n };\n }\n } catch {\n // ignore malformed checkpoints; caller treats as absent\n }\n return null;\n}\n\nexport function writeReindexCheckpoint(path: string, state: ReindexCheckpoint): void {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, JSON.stringify(state, null, 2), \"utf-8\");\n}\n\nexport function parseBoundedIntOption(raw: unknown, fallback: number, min: number, max: number): number {\n const parsed = Number.parseInt(String(raw ?? fallback), 10);\n const value = Number.isFinite(parsed) ? parsed : fallback;\n return Math.max(min, Math.min(max, value));\n}\n\nexport function parseBoundedFloatOption(raw: unknown, fallback: number, min: number, max: number): number {\n const parsed = Number.parseFloat(String(raw ?? fallback));\n const value = Number.isFinite(parsed) ? parsed : fallback;\n return Math.max(min, Math.min(max, value));\n}\n\nfunction formatRatioPercent(value: number): string {\n return `${(value * 100).toFixed(2)}%`;\n}\n\nfunction formatVectorLifecycleSloBreach(breach: AuditHealthReport[\"vectorLifecycleSlo\"][\"breaches\"][number]): string {\n if (breach.key === \"vectorless_ratio\") {\n return `${breach.key} actual=${breach.actual} (${formatRatioPercent(breach.actual)}) target=${breach.target} (${formatRatioPercent(breach.target)})`;\n }\n return `${breach.key} actual=${breach.actual} target=${breach.target}`;\n}\n\ntype SyncBundleFile = {\n path: string;\n contentBase64: string;\n};\n\nconst SYNC_BUNDLE_MIN_ITERATIONS = 100_000;\nconst SYNC_BUNDLE_MAX_ITERATIONS = 2_000_000;\nconst SYNC_BUNDLE_SALT_BYTES = 16;\nconst SYNC_BUNDLE_IV_BYTES = 12;\nconst SYNC_BUNDLE_TAG_BYTES = 16;\n\nexport function collectExportBundleFiles(root: string, dir = root): SyncBundleFile[] {\n const files: SyncBundleFile[] = [];\n for (const name of readdirSync(dir).sort()) {\n const fullPath = join(dir, name);\n const st = statSync(fullPath);\n if (st.isDirectory()) {\n files.push(...collectExportBundleFiles(root, fullPath));\n continue;\n }\n if (!st.isFile()) continue;\n const rel = fullPath.slice(root.length + 1).replace(/\\\\/g, \"/\");\n files.push({ path: rel, contentBase64: readFileSync(fullPath).toString(\"base64\") });\n }\n return files;\n}\n\nfunction decodeRequiredBase64Field(envelope: Record<string, unknown>, field: string, expectedBytes?: number): Buffer {\n const raw = envelope[field];\n if (typeof raw !== \"string\" || raw.length === 0) {\n throw new Error(`sync bundle field ${field} must be a non-empty base64 string`);\n }\n if (!/^[A-Za-z0-9+/]*={0,2}$/.test(raw) || raw.length % 4 !== 0) {\n throw new Error(`sync bundle field ${field} is not valid base64`);\n }\n const decoded = Buffer.from(raw, \"base64\");\n if (expectedBytes !== undefined && decoded.length !== expectedBytes) {\n throw new Error(`sync bundle field ${field} must decode to ${expectedBytes} bytes`);\n }\n if (expectedBytes === undefined && decoded.length === 0) {\n throw new Error(`sync bundle field ${field} must not be empty`);\n }\n return decoded;\n}\n\nexport function validateSyncEnvelope(raw: unknown): {\n schemaVersion: 1;\n type: \"hybrid-memory-sync-bundle\";\n alg: \"aes-256-gcm\";\n kdf: \"pbkdf2-sha256\";\n iterations: number;\n salt: Buffer;\n iv: Buffer;\n tag: Buffer;\n ciphertext: Buffer;\n} {\n if (raw === null || typeof raw !== \"object\" || Array.isArray(raw)) {\n throw new Error(\"sync bundle must be a JSON object\");\n }\n const envelope = raw as Record<string, unknown>;\n if (envelope.schemaVersion !== 1) throw new Error(\"unsupported sync bundle schemaVersion\");\n if (envelope.type !== \"hybrid-memory-sync-bundle\") throw new Error(\"unsupported sync bundle type\");\n if (envelope.alg !== \"aes-256-gcm\") throw new Error(\"unsupported sync bundle algorithm\");\n if (envelope.kdf !== \"pbkdf2-sha256\") throw new Error(\"unsupported sync bundle KDF\");\n const iterations = envelope.iterations;\n if (\n typeof iterations !== \"number\" ||\n !Number.isInteger(iterations) ||\n iterations < SYNC_BUNDLE_MIN_ITERATIONS ||\n iterations > SYNC_BUNDLE_MAX_ITERATIONS\n ) {\n throw new Error(\n `sync bundle iterations must be an integer between ${SYNC_BUNDLE_MIN_ITERATIONS} and ${SYNC_BUNDLE_MAX_ITERATIONS}`,\n );\n }\n return {\n schemaVersion: 1,\n type: \"hybrid-memory-sync-bundle\",\n alg: \"aes-256-gcm\",\n kdf: \"pbkdf2-sha256\",\n iterations,\n salt: decodeRequiredBase64Field(envelope, \"salt\", SYNC_BUNDLE_SALT_BYTES),\n iv: decodeRequiredBase64Field(envelope, \"iv\", SYNC_BUNDLE_IV_BYTES),\n tag: decodeRequiredBase64Field(envelope, \"tag\", SYNC_BUNDLE_TAG_BYTES),\n ciphertext: decodeRequiredBase64Field(envelope, \"ciphertext\"),\n };\n}\n\n/**\n * Insert one `storage_growth_history` row per UTC calendar day (idempotent).\n * Enables `audit health` 7d deltas when combined with daily cron (#audit remediation).\n */\nexport function recordStorageGrowthSample(\n factsDb: ManageBindings[\"factsDb\"],\n lanceBytes: number | null,\n opts?: { force?: boolean; dryRun?: boolean },\n): {\n inserted: boolean;\n recordedAt: number;\n sampleId: number | null;\n status: \"recorded\" | \"skipped\" | \"dry_run\";\n reason: \"already_sampled_today\" | \"storage_unavailable\" | null;\n sample: {\n recordedAt: number;\n sqliteBytes: number | null;\n lanceBytes: number | null;\n linkCount: number;\n factCount: number;\n };\n} {\n const raw = factsDb.getRawDb?.();\n const nowSecReport = Math.floor(Date.now() / 1000);\n const storageBytes = factsDb.estimateStorageBytes?.();\n const activeFacts = factsDb.getCount();\n const linkCountTotal = raw\n ? Number((raw.prepare(\"SELECT COUNT(*) AS c FROM memory_links\").get() as { c: number } | undefined)?.c ?? 0)\n : 0;\n const sample = {\n recordedAt: nowSecReport,\n sqliteBytes: storageBytes?.sqliteBytes ?? null,\n lanceBytes,\n linkCount: linkCountTotal,\n factCount: activeFacts,\n };\n if (!raw) {\n return {\n inserted: false,\n recordedAt: nowSecReport,\n sampleId: null,\n status: \"skipped\",\n reason: \"storage_unavailable\",\n sample,\n };\n }\n if (opts?.dryRun) {\n return {\n inserted: false,\n recordedAt: nowSecReport,\n sampleId: null,\n status: \"dry_run\",\n reason: null,\n sample,\n };\n }\n const d = new Date();\n const startOfDayUtc = Math.floor(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()) / 1000);\n const alreadyToday =\n !opts?.force &&\n (raw.prepare(\"SELECT 1 AS ok FROM storage_growth_history WHERE recorded_at >= ? LIMIT 1\").get(startOfDayUtc) as\n | { ok: number }\n | undefined);\n if (alreadyToday) {\n return {\n inserted: false,\n recordedAt: nowSecReport,\n sampleId: null,\n status: \"skipped\",\n reason: \"already_sampled_today\",\n sample,\n };\n }\n const insertResult = raw\n .prepare(\n \"INSERT INTO storage_growth_history (recorded_at, sqlite_bytes, lance_bytes, link_count, fact_count) VALUES (?, ?, ?, ?, ?)\",\n )\n .run(sample.recordedAt, sample.sqliteBytes, sample.lanceBytes, sample.linkCount, sample.factCount) as {\n lastInsertRowid?: number | bigint;\n };\n const sampleId = insertResult.lastInsertRowid ? Number(insertResult.lastInsertRowid) : null;\n return {\n inserted: true,\n recordedAt: nowSecReport,\n sampleId,\n status: \"recorded\",\n reason: null,\n sample,\n };\n}\n\n/** Apply optional CLI filters to merged hybrid search results (category/entity/key/source/tier). */\nexport function entryMatchesHybridSearchFilters(\n entry: MemoryEntry,\n opts?: {\n category?: string;\n entity?: string;\n key?: string;\n source?: string;\n tier?: string;\n },\n): boolean {\n if (!opts) return true;\n if (opts.category && entry.category !== opts.category) return false;\n if (opts.entity != null && opts.entity !== \"\" && entry.entity !== opts.entity) return false;\n if (opts.key != null && opts.key !== \"\" && entry.key !== opts.key) return false;\n if (opts.source != null && opts.source !== \"\" && entry.source !== opts.source) return false;\n if (opts.tier != null && opts.tier !== \"\" && entry.tier !== opts.tier) return false;\n return true;\n}\n\nexport type AuditHealthReport = {\n schemaVersion: 1;\n generatedAt: string;\n /** \"ok\" when no warnings and no generation errors; \"partial\" when degraded (warnings, timeouts, or non-fatal errors). */\n status: \"ok\" | \"partial\" | \"failed\";\n /** @deprecated Use `status` instead. Kept for backward compatibility. */\n ok: boolean;\n warningCount: number;\n errorCount: number;\n activeFacts: number;\n /** Age (in days) of the oldest active fact. Used to gate sparse-store warnings (#1193). */\n storeAgeDays: number;\n canonicalEmbeddings: number;\n vectorless: number;\n vectorlessBySource: Array<{ source: string; count: number }>;\n procedures: {\n total: number;\n validated: number;\n promoted: number;\n validatedNotPromoted: number;\n blocked: number;\n topBlockReason: string | null;\n /** Breakdown of blocked (validated, not-promoted) procedures by block reason. */\n byBlockReason: Record<ProcedurePromotionBlockReason, number>;\n };\n graphHubs: Array<{\n id: string;\n outDegree: number;\n textPreview: string | null;\n overCap: boolean;\n eventTypeHistogram: Record<string, number>;\n }>;\n structuralEligibleWarmFacts: number;\n patternBloat: {\n implicitFeedbackPatterns: number;\n /** Top 5 leading-token prefixes for implicit-feedback rows (legacy category=pattern and trajectory lessons, #1193, #1736). */\n implicitFeedbackPrefixHistogram: Array<{ prefix: string; count: number }>;\n };\n entityStopwordMatches: Array<{ entity: string; count: number }>;\n /** Top entities with configured stop-words removed (retrieval-aligned view, #1193). */\n topEntitiesFiltered: Array<{ entity: string; count: number }>;\n storage: {\n sqliteBytes: number | null;\n walBytes: number | null;\n shmBytes: number | null;\n /** LanceDB directory size on disk in bytes (#1193). */\n lanceBytes: number | null;\n };\n storageGrowth: {\n lastSampleAt: number | null;\n delta7d: {\n sqliteBytes: number | null;\n lanceBytes: number | null;\n linkCount: number | null;\n factCount: number | null;\n } | null;\n /** Lance bytes per week derived from delta7d (null when unknown). */\n lanceBytesPerWeekDelta: number | null;\n };\n implicitFeedbackSignalNoise: {\n rowsPerDay30d: Record<string, number>;\n paraphraseRatio: number | null;\n };\n tiers: Record<string, number>;\n decay: Record<string, number>;\n /**\n * Stickiness ratio: `(stable + permanent) / activeFacts`. Surfaced separately from `decay` so\n * dashboards can render a single number and gate the 60% warning (#1193).\n */\n stableStickiness: { stablePermanent: number; activeFacts: number; ratio: number };\n vectorIntegrity: {\n score: number;\n degraded: boolean;\n degradedReason: string | null;\n vectorlessRatio: number;\n orphanSignals: {\n sqliteFactsWithoutCanonicalEmbedding: number;\n };\n };\n vectorLifecycleSlo: {\n targets: {\n maxVectorlessRatio: number;\n minIntegrityScore: number;\n };\n breaches: Array<{ key: \"vectorless_ratio\" | \"integrity_score\"; actual: number; target: number }>;\n };\n categories: {\n configured: string[];\n present: string[];\n /** Per-category drift counts so the JSON consumer doesn't need to re-query (#1193). */\n unknown: Array<{ category: string; count: number }>;\n };\n sources: Record<string, number>;\n implicitFeedbackTrajectorySignals: number;\n graphHubGuard: {\n configuredCap: number | null | undefined;\n effectiveCap: number | null;\n connectedProbe: GraphConnectedStats;\n expansionProbe: GraphExpansionStats;\n } | null;\n warnings: string[];\n remediation: string[];\n /** Errors encountered during report generation (e.g., timeouts, query failures). */\n errors: Array<{ section: string; message: string }>;\n /** Optional operator budget used for audit-health command execution. */\n timeoutMs?: number;\n /** Elapsed wall-clock time spent building the report. */\n elapsedMs?: number;\n};\n\nexport function countImplicitFeedbackTrajectorySignals(factsDb: ManageBindings[\"factsDb\"]): number {\n const raw = factsDb.getRawDb?.();\n if (!raw) return 0;\n const row = raw\n .prepare(\n `SELECT COUNT(*) as cnt FROM facts WHERE source = 'implicit-feedback' AND superseded_at IS NULL AND ${SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER}`,\n )\n .get() as { cnt: number } | undefined;\n return row?.cnt ?? 0;\n}\n\nexport function buildAuditHealthReport(\n factsDb: ManageBindings[\"factsDb\"],\n getMemoryCategories: () => readonly string[],\n entityStopWords: readonly string[] = [],\n graphHubDegreeCap?: number | null,\n options?: {\n lanceBytes?: number | null;\n preReportErrors?: Array<{ section: string; message: string }>;\n timeoutMs?: number;\n startedAtMs?: number;\n deadlineMs?: number;\n degradedState?: { active: boolean; reason: string | null };\n },\n): AuditHealthReport {\n const startedAtMs = options?.startedAtMs ?? Date.now();\n const deadlineMs = options?.deadlineMs;\n const errors: Array<{ section: string; message: string }> = [...(options?.preReportErrors ?? [])];\n const timeoutRecorded = new Set<string>();\n const hasBudget = (section: string): boolean => {\n if (deadlineMs == null || Date.now() <= deadlineMs) return true;\n if (!timeoutRecorded.has(section)) {\n timeoutRecorded.add(section);\n errors.push({\n section,\n message: `Skipped: audit-health timeout budget exceeded${options?.timeoutMs ? ` (${options.timeoutMs}ms)` : \"\"}`,\n });\n }\n return false;\n };\n const capForHubListing = graphHubDegreeCap === undefined ? 500 : graphHubDegreeCap;\n const activeFacts = factsDb.getCount();\n const canonicalEmbeddings = factsDb.countCanonicalEmbeddings();\n const procedures = factsDb.proceduresCount();\n const validated = factsDb.proceduresValidatedCount();\n const promoted = factsDb.proceduresPromotedCount();\n const tiers = factsDb.statsBreakdownByTier();\n const decay = factsDb.statsBreakdownByDecayClass();\n const present = factsDb.uniqueMemoryCategories().slice().sort();\n const configured = [...getMemoryCategories()].slice().sort();\n const configuredSet = new Set(configured);\n const sources = factsDb.statsBySource();\n const implicitFeedbackTrajectorySignals = countImplicitFeedbackTrajectorySignals(factsDb);\n const vectorless = factsDb.countVectorlessActiveFacts();\n const vectorlessBySource = factsDb.vectorlessActiveFactsBySource(10);\n const procedureTriage = factsDb.triageProcedures({ status: \"validated\", notPromoted: true, limit: 10_000 });\n const raw = factsDb.getRawDb?.();\n\n // #1193: surface per-category drift counts directly so JSON consumers do not need to re-query.\n const unknown: Array<{ category: string; count: number }> = (() => {\n const drift = present.filter((category: string) => !configuredSet.has(category));\n if (drift.length === 0) return [];\n if (!raw || !hasBudget(\"categories.unknown\")) return drift.map((category) => ({ category, count: 0 }));\n return drift.map((category) => {\n const row = raw\n .prepare(`SELECT COUNT(*) AS cnt FROM facts WHERE COALESCE(category, 'other') = ? AND superseded_at IS NULL`)\n .get(category) as { cnt: number } | undefined;\n return { category, count: Number(row?.cnt ?? 0) };\n });\n })();\n const unconfiguredCategories = unknown.filter((row) => {\n const mappedTarget = LEGACY_CATEGORY_REMAPS[row.category];\n return !mappedTarget || !configuredSet.has(mappedTarget);\n });\n\n // #1193: store age (days) gates sparse-store warnings — a brand-new install with hot=0 is\n // expected, and the operator should not get a \"memory is broken\" warning during the first\n // two weeks while the store warms up.\n const oldestRow =\n raw != null\n ? (raw.prepare(\"SELECT MIN(created_at) AS oldest FROM facts WHERE superseded_at IS NULL\").get() as\n | { oldest: number | null }\n | undefined)\n : undefined;\n const nowSecForAge = Math.floor(Date.now() / 1000);\n const storeAgeDays = oldestRow?.oldest != null ? Math.max(0, (nowSecForAge - oldestRow.oldest) / 86400) : 0;\n const graphHubs =\n raw && hasBudget(\"graphHubs\")\n ? (\n raw\n .prepare(\n `SELECT ml.source_fact_id AS id, COUNT(*) AS cnt, SUBSTR(f.text, 1, 120) AS text_preview\n FROM memory_links ml\n LEFT JOIN facts f ON f.id = ml.source_fact_id\n WHERE ml.link_type != 'CONTRADICTS'\n GROUP BY ml.source_fact_id\n ORDER BY cnt DESC\n LIMIT 10`,\n )\n .all() as Array<{ id: string; cnt: number; text_preview: string | null }>\n ).map((row) => {\n const eventTypeHistogram: Record<string, number> = {};\n if (raw) {\n const pr = raw.prepare(\"SELECT provenance_json FROM facts WHERE id = ?\").get(row.id) as\n | { provenance_json: string | null }\n | undefined;\n if (pr?.provenance_json) {\n try {\n const parsed = JSON.parse(pr.provenance_json) as { sourceEvents?: Array<{ eventType?: string }> };\n for (const ev of parsed.sourceEvents ?? []) {\n const t = typeof ev.eventType === \"string\" && ev.eventType ? ev.eventType : \"unknown\";\n eventTypeHistogram[t] = (eventTypeHistogram[t] ?? 0) + 1;\n }\n } catch {\n /* ignore malformed provenance */\n }\n }\n }\n return {\n id: row.id,\n outDegree: Number(row.cnt ?? 0),\n textPreview: row.text_preview ?? null,\n overCap: capForHubListing != null && Number(row.cnt ?? 0) > capForHubListing,\n eventTypeHistogram,\n };\n })\n : [];\n const structuralEligibleWarmFacts = raw\n ? Number(\n (\n raw\n .prepare(\n `SELECT COUNT(*) AS cnt FROM facts\n WHERE superseded_at IS NULL\n AND (expires_at IS NULL OR expires_at > ?)\n AND TRIM(COALESCE(key, '')) != ''\n AND TRIM(COALESCE(value, '')) != ''\n AND NOT (key = 'implicit_feedback_signal')\n AND COALESCE(tier, 'warm') = 'warm'`,\n )\n .get(Math.floor(Date.now() / 1000)) as { cnt: number } | undefined\n )?.cnt ?? 0,\n )\n : 0;\n const implicitFeedbackPatterns = raw\n ? Number(\n (\n raw\n .prepare(\n `SELECT COUNT(*) AS cnt FROM facts\n WHERE superseded_at IS NULL\n AND category = 'pattern'\n AND source = 'implicit-feedback'`,\n )\n .get() as { cnt: number } | undefined\n )?.cnt ?? 0,\n )\n : 0;\n // #1193, #1736: aggregate the leading 6 tokens of implicit-feedback rows (legacy category=pattern\n // and modern trajectory lessons) to surface \"should never store\" duplicate prefixes (e.g. paraphrases\n // of the same self-correction) without scanning every row.\n // LIMIT added to prevent hanging on long-lived stores with thousands of implicit-feedback patterns.\n const implicitFeedbackPrefixHistogram: Array<{ prefix: string; count: number }> = (() => {\n if (!raw || !hasBudget(\"implicitFeedbackPrefixHistogram\")) return [];\n const cap = IMPLICIT_FEEDBACK_HISTOGRAM_SAMPLE_CAP;\n try {\n // Fetch cap + 1 rows so we only flag truncation when another row exists (exactly `cap` rows is not truncated).\n // Include both legacy category=pattern rows and modern trajectory lesson rows (#1736).\n const rows = raw\n .prepare(\n `SELECT text FROM facts\n WHERE superseded_at IS NULL AND source = 'implicit-feedback'\n AND (category = 'pattern' OR (${SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER}))\n LIMIT ?`,\n )\n .all(cap + 1) as Array<{ text: string | null }>;\n const truncated = rows.length > cap;\n const forAgg = truncated ? rows.slice(0, cap) : rows;\n if (forAgg.length === 0) return [];\n const counts = new Map<string, number>();\n for (const row of forAgg) {\n const text = (row.text ?? \"\").trim().toLowerCase();\n if (!text) continue;\n const tokens = text.split(/\\s+/).slice(0, 6).join(\" \");\n const prefix = tokens.length > 0 ? tokens.slice(0, 80) : \"<empty>\";\n counts.set(prefix, (counts.get(prefix) ?? 0) + 1);\n }\n const result = [...counts.entries()]\n .map(([prefix, count]) => ({ prefix, count }))\n .filter((row) => row.count >= 2)\n .sort((a, b) => b.count - a.count || a.prefix.localeCompare(b.prefix))\n .slice(0, 5);\n if (truncated) {\n const totalSampled = Number(\n (\n raw\n .prepare(\n `SELECT COUNT(*) AS cnt FROM facts\n WHERE superseded_at IS NULL AND source = 'implicit-feedback'\n AND (category = 'pattern' OR (${SQL_IMPLICIT_TRAJECTORY_LESSON_FILTER}))`,\n )\n .get() as { cnt: number } | undefined\n )?.cnt ?? 0,\n );\n errors.push({\n section: \"implicitFeedbackPrefixHistogram\",\n message: `Truncated: histogram sampled first ${cap} of ${totalSampled} implicit-feedback row(s)`,\n });\n }\n return result;\n } catch (err) {\n errors.push({\n section: \"implicitFeedbackPrefixHistogram\",\n message: err instanceof Error ? err.message : String(err),\n });\n return [];\n }\n })();\n const entityStopwordMatches = factsDb\n .topEntities(50)\n .filter((row) => isEntityStopWord(row.entity, entityStopWords))\n .slice(0, 10);\n const topEntitiesFiltered = factsDb.topEntitiesFiltered(10, entityStopWords);\n const storageBytes = factsDb.estimateStorageBytes?.();\n const lanceBytes = options?.lanceBytes ?? null;\n const nowSecReport = Math.floor(Date.now() / 1000);\n\n let storageGrowth: AuditHealthReport[\"storageGrowth\"] = {\n lastSampleAt: null,\n delta7d: null,\n lanceBytesPerWeekDelta: null,\n };\n if (raw && hasBudget(\"storageGrowth\")) {\n recordStorageGrowthSample(factsDb, lanceBytes);\n const lastRow = raw\n .prepare(\"SELECT recorded_at FROM storage_growth_history ORDER BY recorded_at DESC LIMIT 1\")\n .get() as { recorded_at: number } | undefined;\n const latestSnap = raw\n .prepare(\n \"SELECT sqlite_bytes, lance_bytes, link_count, fact_count, recorded_at FROM storage_growth_history ORDER BY recorded_at DESC LIMIT 1\",\n )\n .get() as\n | {\n sqlite_bytes: number | null;\n lance_bytes: number | null;\n link_count: number | null;\n fact_count: number;\n recorded_at: number;\n }\n | undefined;\n const cutoff7d = nowSecReport - 7 * 86400;\n const baselineSnap = raw\n .prepare(\n \"SELECT sqlite_bytes, lance_bytes, link_count, fact_count, recorded_at FROM storage_growth_history WHERE recorded_at <= ? ORDER BY recorded_at DESC LIMIT 1\",\n )\n .get(cutoff7d) as\n | {\n sqlite_bytes: number | null;\n lance_bytes: number | null;\n link_count: number | null;\n fact_count: number;\n recorded_at: number;\n }\n | undefined;\n\n let delta7d: AuditHealthReport[\"storageGrowth\"][\"delta7d\"] = null;\n if (latestSnap && baselineSnap && latestSnap.recorded_at !== baselineSnap.recorded_at) {\n delta7d = {\n sqliteBytes:\n latestSnap.sqlite_bytes != null && baselineSnap.sqlite_bytes != null\n ? latestSnap.sqlite_bytes - baselineSnap.sqlite_bytes\n : null,\n lanceBytes:\n latestSnap.lance_bytes != null && baselineSnap.lance_bytes != null\n ? latestSnap.lance_bytes - baselineSnap.lance_bytes\n : null,\n linkCount:\n latestSnap.link_count != null && baselineSnap.link_count != null\n ? latestSnap.link_count - baselineSnap.link_count\n : null,\n factCount: latestSnap.fact_count - baselineSnap.fact_count,\n };\n }\n const ageWeeks =\n latestSnap && baselineSnap && latestSnap.recorded_at !== baselineSnap.recorded_at\n ? (latestSnap.recorded_at - baselineSnap.recorded_at) / (7 * 86400)\n : 0;\n const lanceBytesPerWeekDelta =\n delta7d?.lanceBytes != null && ageWeeks > 0 ? Math.round(delta7d.lanceBytes / ageWeeks) : null;\n storageGrowth = { lastSampleAt: lastRow?.recorded_at ?? null, delta7d, lanceBytesPerWeekDelta };\n }\n\n const implicitFeedbackSignalNoise: AuditHealthReport[\"implicitFeedbackSignalNoise\"] =\n raw && hasBudget(\"implicitFeedbackSignalNoise\")\n ? (() => {\n const since30d = nowSecReport - 30 * 86400;\n const perDayRows = raw\n .prepare(\n `SELECT date(created_at, 'unixepoch') AS day, COUNT(*) AS cnt FROM facts\n WHERE source = 'implicit-feedback' AND superseded_at IS NULL AND created_at >= ?\n GROUP BY day`,\n )\n .all(since30d) as Array<{ day: string; cnt: number }>;\n const rowsPerDay30d: Record<string, number> = {};\n for (const r of perDayRows) rowsPerDay30d[String(r.day)] = Number(r.cnt ?? 0);\n const pr = raw\n .prepare(\n `SELECT COUNT(*) AS total, COUNT(DISTINCT normalized_hash) AS dist FROM facts\n WHERE source = 'implicit-feedback' AND superseded_at IS NULL AND created_at >= ?`,\n )\n .get(since30d) as { total: number; dist: number };\n const paraphraseRatio = pr.total > 0 ? pr.dist / pr.total : null;\n return { rowsPerDay30d, paraphraseRatio };\n })()\n : { rowsPerDay30d: {}, paraphraseRatio: null };\n\n // #1193: stickiness flag is `(stable + permanent) / activeFacts > 0.6`. The previous 50%\n // stable-only rule fired for healthy stores (because `permanent` decisions are normal).\n const stablePermanentCount = (decay.stable ?? 0) + (decay.permanent ?? 0);\n const stableStickinessRatio = activeFacts > 0 ? stablePermanentCount / activeFacts : 0;\n const stableStickiness = {\n stablePermanent: stablePermanentCount,\n activeFacts,\n ratio: stableStickinessRatio,\n };\n const vectorlessRatio = activeFacts > 0 ? vectorless / activeFacts : 0;\n const degraded = options?.degradedState?.active === true;\n const degradedReason = options?.degradedState?.reason ?? null;\n let integrityScore = 100;\n integrityScore -= Math.min(60, Math.round(vectorlessRatio * 100));\n if (degraded) integrityScore -= 30;\n if (errors.length > 0) integrityScore -= Math.min(20, errors.length * 5);\n integrityScore = Math.max(0, Math.min(100, integrityScore));\n const vectorLifecycleSloTargets = {\n maxVectorlessRatio: 0.02,\n minIntegrityScore: 85,\n } as const;\n const vectorLifecycleSloBreaches: AuditHealthReport[\"vectorLifecycleSlo\"][\"breaches\"] = [];\n if (vectorlessRatio > vectorLifecycleSloTargets.maxVectorlessRatio) {\n vectorLifecycleSloBreaches.push({\n key: \"vectorless_ratio\",\n actual: Number(vectorlessRatio.toFixed(4)),\n target: vectorLifecycleSloTargets.maxVectorlessRatio,\n });\n }\n if (integrityScore < vectorLifecycleSloTargets.minIntegrityScore) {\n vectorLifecycleSloBreaches.push({\n key: \"integrity_score\",\n actual: integrityScore,\n target: vectorLifecycleSloTargets.minIntegrityScore,\n });\n }\n\n const warnings: string[] = [];\n // #1193: gate hot=0/structural=0 warnings on storeAgeDays > 14 to avoid false positives during\n // the first 14 days of a fresh install (no facts have aged into warm/cold yet).\n if (storeAgeDays > 14) {\n if ((tiers.hot ?? 0) === 0)\n warnings.push(\"No HOT tier facts detected; tiering may not be promoting active memory.\");\n if ((tiers.structural ?? 0) === 0)\n warnings.push(\"No STRUCTURAL tier facts detected; key/value facts may be stuck in warm tier.\");\n }\n if (activeFacts > 0 && stableStickinessRatio > 0.6) {\n warnings.push(\n `${(stableStickinessRatio * 100).toFixed(1)}% of active facts are stable+permanent — decay reclassifier may need to run.`,\n );\n }\n if (unconfiguredCategories.length > 0)\n warnings.push(\n `Unconfigured categories present in DB: ${unconfiguredCategories.map((u) => `${u.category}=${u.count}`).join(\", \")}`,\n );\n if (graphHubs.some((hub) => hub.overCap))\n warnings.push(\n `${graphHubs.filter((hub) => hub.overCap).length} graph hub(s) exceed degree cap ${capForHubListing}.`,\n );\n if (structuralEligibleWarmFacts > 100)\n warnings.push(\n `${structuralEligibleWarmFacts} warm fact(s) qualify for structural tier (non-empty key+value; implicit_feedback_signal excluded) but are not structural yet.`,\n );\n if (implicitFeedbackPatterns > 1000)\n warnings.push(`${implicitFeedbackPatterns} implicit-feedback pattern fact(s) may indicate pattern bloat.`);\n if (implicitFeedbackPrefixHistogram.length > 0 && implicitFeedbackPrefixHistogram[0].count >= 10)\n warnings.push(\n `Implicit-feedback patterns share a \"${implicitFeedbackPrefixHistogram[0].prefix}…\" prefix ${implicitFeedbackPrefixHistogram[0].count}× — likely paraphrase duplicates.`,\n );\n if (entityStopwordMatches.length > 0)\n warnings.push(\n `Top entities include stop-word-like labels: ${entityStopwordMatches.map((row) => row.entity).join(\", \")}.`,\n );\n if (vectorless > 0) warnings.push(`${vectorless} active non-kv fact(s) are missing canonical embeddings.`);\n if (degraded)\n warnings.push(\n `Vector store is in degraded mode${degradedReason ? ` (reason: ${degradedReason})` : \"\"}; semantic retrieval may be unavailable.`,\n );\n if (vectorLifecycleSloBreaches.length > 0)\n warnings.push(\n `Vector lifecycle SLO breach(es): ${vectorLifecycleSloBreaches.map(formatVectorLifecycleSloBreach).join(\"; \")}`,\n );\n if (procedureTriage.summary.total > 0) {\n const reasonBreakdown = Object.entries(procedureTriage.summary.byReason)\n .filter(([, count]) => count > 0)\n .map(([reason, count]) => `${reason}=${count}`)\n .join(\", \");\n warnings.push(`${procedureTriage.summary.total} validated procedure(s) are not promoted (${reasonBreakdown}).`);\n }\n const remediation: string[] = [];\n if ((tiers.hot ?? 0) === 0 || (tiers.structural ?? 0) === 0 || structuralEligibleWarmFacts > 0)\n remediation.push(\"Run `openclaw hybrid-mem retier --apply`.\");\n if (graphHubs.some((hub) => hub.overCap))\n remediation.push(\n \"Run `openclaw hybrid-mem graph repair --collapse-event-hubs --apply` and keep graph hub guards enabled.\",\n );\n if (unconfiguredCategories.length > 0)\n remediation.push(\"Run `openclaw hybrid-mem categories audit`, then `categories remap --apply` where appropriate.\");\n if (activeFacts > 0 && stableStickinessRatio > 0.6) {\n remediation.push(\n \"Run `openclaw hybrid-mem decay reclassify --dry-run --stable-only`, then `openclaw hybrid-mem decay reclassify --apply --stable-only` if the report looks correct.\",\n );\n }\n if (vectorless > 0) remediation.push(\"Run `openclaw hybrid-mem reembed-vectorless --apply`.\");\n if (degraded) remediation.push(\"Run `openclaw hybrid-mem repair-vectors` and validate LanceDB connectivity.\");\n if (procedureTriage.summary.total > 0) {\n remediation.push(\n \"Run `openclaw hybrid-mem procedures triage --not-promoted` and `generate-auto-skills` where appropriate.\",\n );\n if ((procedureTriage.summary.byReason.low_recall ?? 0) > 0)\n remediation.push(\n \"Low-recall procedures need more successful uses before promotion; retrain or merge duplicates via `openclaw hybrid-mem procedures triage --not-promoted --reason low_recall`.\",\n );\n }\n if (\n implicitFeedbackPatterns > 1000 ||\n (implicitFeedbackPrefixHistogram.length > 0 && implicitFeedbackPrefixHistogram[0].count >= 10)\n ) {\n remediation.push(\n \"Run `openclaw hybrid-mem reflect-meta --collapse-implicit-feedback --include-legacy` (omit `--dry-run` to apply mutations).\",\n );\n }\n if (entityStopwordMatches.length > 0) {\n remediation.push(\n \"Run `openclaw hybrid-mem entities clean --stopwords --apply` to null stop-word entity labels from existing facts.\",\n );\n }\n\n let graphHubGuard: AuditHealthReport[\"graphHubGuard\"] = null;\n if (raw && hasBudget(\"graphHubGuard\")) {\n const probeRow = raw.prepare(\"SELECT id FROM facts WHERE superseded_at IS NULL LIMIT 1\").get() as\n | { id: string }\n | undefined;\n if (probeRow?.id) {\n const connectedProbe: GraphConnectedStats = { nodesConsidered: 0, nodesSkipped: 0, hubsSkipped: 0 };\n factsDb.getConnectedFactIds([probeRow.id], 2, { hubDegreeCap: graphHubDegreeCap, stats: connectedProbe });\n const entry = factsDb.getById(probeRow.id);\n if (entry) {\n const { stats: expansionProbe } = expandGraph(factsDb, [{ factId: probeRow.id, score: 1, entry }], {\n maxDepth: 2,\n maxExpandedResults: 20,\n hubDegreeCap: graphHubDegreeCap,\n });\n graphHubGuard = {\n configuredCap: graphHubDegreeCap,\n effectiveCap: resolveGraphHubDegreeCap(graphHubDegreeCap),\n connectedProbe,\n expansionProbe,\n };\n }\n }\n }\n\n const status: AuditHealthReport[\"status\"] = errors.length > 0 || warnings.length > 0 ? \"partial\" : \"ok\";\n\n return {\n schemaVersion: 1,\n generatedAt: new Date().toISOString(),\n status,\n ok: warnings.length === 0 && errors.length === 0,\n warningCount: warnings.length,\n errorCount: errors.length,\n activeFacts,\n storeAgeDays: Number(storeAgeDays.toFixed(2)),\n canonicalEmbeddings,\n vectorless,\n vectorlessBySource,\n procedures: {\n total: procedures,\n validated,\n promoted,\n validatedNotPromoted: Math.max(0, validated - promoted),\n blocked: procedureTriage.summary.total,\n topBlockReason: procedureTriage.summary.topReason,\n byBlockReason: procedureTriage.summary.byReason,\n },\n graphHubs,\n structuralEligibleWarmFacts,\n patternBloat: { implicitFeedbackPatterns, implicitFeedbackPrefixHistogram },\n entityStopwordMatches,\n topEntitiesFiltered,\n storage: {\n sqliteBytes: storageBytes?.sqliteBytes ?? null,\n walBytes: storageBytes?.walBytes ?? null,\n shmBytes: storageBytes?.shmBytes ?? null,\n lanceBytes,\n },\n storageGrowth,\n implicitFeedbackSignalNoise,\n tiers,\n decay,\n stableStickiness,\n vectorIntegrity: {\n score: integrityScore,\n degraded,\n degradedReason,\n vectorlessRatio: Number(vectorlessRatio.toFixed(4)),\n orphanSignals: {\n sqliteFactsWithoutCanonicalEmbedding: vectorless,\n },\n },\n vectorLifecycleSlo: {\n targets: vectorLifecycleSloTargets,\n breaches: vectorLifecycleSloBreaches,\n },\n categories: { configured, present, unknown },\n sources,\n implicitFeedbackTrajectorySignals,\n graphHubGuard,\n warnings,\n remediation,\n errors,\n timeoutMs: options?.timeoutMs,\n elapsedMs: Date.now() - startedAtMs,\n };\n}\n\nexport function printAuditHealthMarkdown(report: AuditHealthReport): void {\n console.log(\"# Hybrid-memory audit health\");\n console.log(\"\");\n console.log(`Status: ${report.status}`);\n console.log(`Generated: ${report.generatedAt}`);\n console.log(`Schema version: ${report.schemaVersion}`);\n console.log(`Active facts: ${report.activeFacts}`);\n console.log(`Store age (days): ${report.storeAgeDays.toFixed(1)}`);\n console.log(`Canonical embeddings: ${report.canonicalEmbeddings}`);\n console.log(`Vectorless active non-kv facts: ${report.vectorless}`);\n console.log(\n `Vector integrity score: ${report.vectorIntegrity.score}/100 (degraded=${report.vectorIntegrity.degraded ? \"yes\" : \"no\"}; vectorlessRatio=${report.vectorIntegrity.vectorlessRatio})`,\n );\n if (report.vectorIntegrity.degradedReason) {\n console.log(`Vector degraded reason: ${report.vectorIntegrity.degradedReason}`);\n }\n if (report.vectorLifecycleSlo.breaches.length > 0) {\n console.log(\n `Vector lifecycle SLO breaches: ${report.vectorLifecycleSlo.breaches.map(formatVectorLifecycleSloBreach).join(\", \")}`,\n );\n }\n if (report.vectorlessBySource.length > 0) {\n console.log(`Vectorless by source: ${report.vectorlessBySource.map((r) => `${r.source}=${r.count}`).join(\", \")}`);\n }\n console.log(\n `Procedures: ${report.procedures.total} (validated: ${report.procedures.validated}, promoted: ${report.procedures.promoted}, blocked: ${report.procedures.blocked}${report.procedures.topBlockReason ? ` by ${report.procedures.topBlockReason}` : \"\"})`,\n );\n console.log(`Tiers: ${JSON.stringify(report.tiers)}`);\n console.log(`Decay: ${JSON.stringify(report.decay)}`);\n console.log(\n `Unknown categories: ${report.categories.unknown.length ? report.categories.unknown.map((u) => `${u.category}=${u.count}`).join(\", \") : \"none\"}`,\n );\n console.log(\n `Stable+permanent stickiness: ${report.stableStickiness.stablePermanent}/${report.stableStickiness.activeFacts} (${(\n report.stableStickiness.ratio * 100\n ).toFixed(1)}%)`,\n );\n console.log(`Graph hubs over cap: ${report.graphHubs.filter((hub) => hub.overCap).length}`);\n if (report.graphHubs.length > 0) {\n // #1193: TTY summary now mirrors the JSON `top 10`, not the previous truncated 3.\n console.log(\n `Top graph hubs: ${report.graphHubs\n .slice(0, 10)\n .map((hub) => `${hub.id.slice(0, 8)}=${hub.outDegree}`)\n .join(\", \")}`,\n );\n }\n console.log(`Structural-eligible warm facts: ${report.structuralEligibleWarmFacts}`);\n console.log(`Implicit-feedback pattern facts: ${report.patternBloat.implicitFeedbackPatterns}`);\n if (report.patternBloat.implicitFeedbackPrefixHistogram.length > 0) {\n console.log(\n `Implicit-feedback prefix histogram: ${report.patternBloat.implicitFeedbackPrefixHistogram\n .map((row) => `\"${row.prefix}\"=${row.count}`)\n .join(\", \")}`,\n );\n }\n if (report.topEntitiesFiltered.length > 0) {\n console.log(\n `Top entities (retrieval view, stop-words removed): ${report.topEntitiesFiltered.map((row) => `${row.entity}=${row.count}`).join(\", \")}`,\n );\n }\n if (report.entityStopwordMatches.length > 0) {\n console.log(\n `Entity stop-word matches: ${report.entityStopwordMatches.map((row) => `${row.entity}=${row.count}`).join(\", \")}`,\n );\n }\n if (report.storage.sqliteBytes != null) console.log(`SQLite bytes: ${report.storage.sqliteBytes}`);\n if (report.storage.lanceBytes != null) console.log(`Lance bytes: ${report.storage.lanceBytes}`);\n if (report.storageGrowth.lastSampleAt != null) {\n const lanceWeekly = report.storageGrowth.lanceBytesPerWeekDelta;\n const lanceWeeklyStr = lanceWeekly != null ? `; lance/week=${lanceWeekly}` : \"\";\n console.log(\n `Storage growth (last sample unix): ${report.storageGrowth.lastSampleAt}; 7d delta: ${JSON.stringify(report.storageGrowth.delta7d)}${lanceWeeklyStr}`,\n );\n }\n console.log(\n `Implicit-feedback signal noise (30d): paraphraseRatio=${String(report.implicitFeedbackSignalNoise.paraphraseRatio)} days=${Object.keys(report.implicitFeedbackSignalNoise.rowsPerDay30d).length}`,\n );\n console.log(`Implicit-feedback trajectory signals: ${report.implicitFeedbackTrajectorySignals}`);\n if (report.graphHubGuard) {\n const g = report.graphHubGuard;\n console.log(\n `Graph hub guard probe (cap=${String(g.configuredCap)} effective=${String(g.effectiveCap)}): connected considered=${g.connectedProbe.nodesConsidered} skipped=${g.connectedProbe.nodesSkipped} hubsSkipped=${g.connectedProbe.hubsSkipped}; expansion considered=${g.expansionProbe.nodesConsidered} skipped=${g.expansionProbe.nodesSkipped} hubsSkipped=${g.expansionProbe.hubsSkipped}`,\n );\n }\n console.log(\"\");\n if (report.errors.length > 0) {\n console.log(\"Errors:\");\n for (const error of report.errors) console.log(`- [${error.section}] ${error.message}`);\n console.log(\"\");\n }\n if (report.warnings.length === 0) {\n console.log(\"Warnings: none\");\n } else {\n console.log(\"Warnings:\");\n for (const warning of report.warnings) console.log(`- ${warning}`);\n }\n if (report.remediation.length > 0) {\n console.log(\"\");\n console.log(\"Remediation:\");\n for (const hint of report.remediation) console.log(`- ${hint}`);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-manage-commands.js","names":[],"sources":["../../../cli/commands/register-manage-commands.ts"],"sourcesContent":["/**\n * CLI registration for management commands — thin orchestrator (Issue #955).\n */\nimport type { ManageContext } from \"../context.js\";\nimport type { Chainable } from \"../shared.js\";\nimport { buildManageBindings } from \"./manage/bindings.js\";\nimport { registerManageAgentsAuditRunall } from \"./manage/register-agents-audit-runall.js\";\nimport { registerManageBudgetAndProposals } from \"./manage/register-budget-proposals.js\";\nimport { registerManageCorrectionsAndPipeline } from \"./manage/register-corrections-and-pipeline.js\";\nimport { registerManageCouncil } from \"./manage/register-council.js\";\nimport { registerManageCredentialsAndScope } from \"./manage/register-credentials-scope.js\";\nimport { registerManageProcedureAndLifecycle } from \"./manage/register-procedure-lifecycle.js\";\nimport { registerManageDigest } from \"./manage/register-digest.js\";\nimport { registerExpireBySourceCommands, registerLifecycleSyncCommands } from \"./manage/register-lifecycle.js\";\nimport { registerAnalyzeMaintenanceLogsCommand } from \"./manage/register-analyze-maintenance-logs.js\";\nimport { registerManageStorageAndStats } from \"./manage/register-storage-and-stats.js\";\nimport { registerValidateCronExit } from \"./manage/register-validate-cron-exit.js\";\nimport { registerReconcileCronLedgers } from \"./manage/register-reconcile-cron-ledgers.js\";\n\nexport function registerManageCommands(mem: Chainable, ctx: ManageContext): void {\n const b = buildManageBindings(ctx);\n registerExpireBySourceCommands(mem, b);\n registerLifecycleSyncCommands(mem, b);\n registerManageAgentsAuditRunall(mem, b);\n registerManageStorageAndStats(mem, b);\n registerManageBudgetAndProposals(mem, b);\n registerManageCorrectionsAndPipeline(mem, b);\n registerManageCredentialsAndScope(mem, b);\n registerManageProcedureAndLifecycle(mem, b);\n registerManageCouncil(mem, b);\n registerManageDigest(mem, b);\n registerAnalyzeMaintenanceLogsCommand(mem, b);\n registerValidateCronExit(mem);\n registerReconcileCronLedgers(mem);\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,uBAAuB,KAAgB,KAA0B;CAC/E,MAAM,IAAI,oBAAoB,
|
|
1
|
+
{"version":3,"file":"register-manage-commands.js","names":[],"sources":["../../../cli/commands/register-manage-commands.ts"],"sourcesContent":["/**\n * CLI registration for management commands — thin orchestrator (Issue #955).\n */\nimport type { ManageContext } from \"../context.js\";\nimport type { Chainable } from \"../shared.js\";\nimport { buildManageBindings } from \"./manage/bindings.js\";\nimport { registerManageAgentsAuditRunall } from \"./manage/register-agents-audit-runall.js\";\nimport { registerManageBudgetAndProposals } from \"./manage/register-budget-proposals.js\";\nimport { registerManageCorrectionsAndPipeline } from \"./manage/register-corrections-and-pipeline.js\";\nimport { registerManageCouncil } from \"./manage/register-council.js\";\nimport { registerManageCredentialsAndScope } from \"./manage/register-credentials-scope.js\";\nimport { registerManageProcedureAndLifecycle } from \"./manage/register-procedure-lifecycle.js\";\nimport { registerManageDigest } from \"./manage/register-digest.js\";\nimport { registerExpireBySourceCommands, registerLifecycleSyncCommands } from \"./manage/register-lifecycle.js\";\nimport { registerAnalyzeMaintenanceLogsCommand } from \"./manage/register-analyze-maintenance-logs.js\";\nimport { registerManageStorageAndStats } from \"./manage/register-storage-and-stats.js\";\nimport { registerValidateCronExit } from \"./manage/register-validate-cron-exit.js\";\nimport { registerReconcileCronLedgers } from \"./manage/register-reconcile-cron-ledgers.js\";\n\nexport function registerManageCommands(mem: Chainable, ctx: ManageContext): void {\n const b = buildManageBindings(ctx);\n registerExpireBySourceCommands(mem, b);\n registerLifecycleSyncCommands(mem, b);\n registerManageAgentsAuditRunall(mem, b);\n registerManageStorageAndStats(mem, b);\n registerManageBudgetAndProposals(mem, b);\n registerManageCorrectionsAndPipeline(mem, b);\n registerManageCredentialsAndScope(mem, b);\n registerManageProcedureAndLifecycle(mem, b);\n registerManageCouncil(mem, b);\n registerManageDigest(mem, b);\n registerAnalyzeMaintenanceLogsCommand(mem, b);\n registerValidateCronExit(mem);\n registerReconcileCronLedgers(mem);\n}\n"],"mappings":";;;;;;;;;;;;;;AAmBA,SAAgB,uBAAuB,KAAgB,KAA0B;CAC/E,MAAM,IAAI,oBAAoB,GAAG;CACjC,+BAA+B,KAAK,CAAC;CACrC,8BAA8B,KAAK,CAAC;CACpC,gCAAgC,KAAK,CAAC;CACtC,8BAA8B,KAAK,CAAC;CACpC,iCAAiC,KAAK,CAAC;CACvC,qCAAqC,KAAK,CAAC;CAC3C,kCAAkC,KAAK,CAAC;CACxC,oCAAoC,KAAK,CAAC;CAC1C,sBAAsB,KAAK,CAAC;CAC5B,qBAAqB,KAAK,CAAC;CAC3B,sCAAsC,KAAK,CAAC;CAC5C,yBAAyB,GAAG;CAC5B,6BAA6B,GAAG;AAClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-feature-summaries.js","names":[],"sources":["../../cli/config-feature-summaries.ts"],"sourcesContent":["/**\n * Shared human-readable summaries for goal stewardship and active-task settings\n * (used by `hybrid-mem config`, `goals config`, `active-tasks config`).\n */\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\n\nimport type { ActiveTaskConfig, GoalStewardshipConfig } from \"../config.js\";\nimport { getEnv } from \"../utils/env-manager.js\";\n\n/** Default workspace root for resolving relative paths in CLI output. */\nexport function workspaceRootForCli(): string {\n return getEnv(\"OPENCLAW_WORKSPACE\") ?? join(homedir(), \".openclaw\", \"workspace\");\n}\n\n/** Absolute path to the active-task markdown file / projection target. */\nexport function resolvedActiveTaskFilePath(at: ActiveTaskConfig): string {\n const fp = typeof at.filePath === \"string\" && at.filePath.trim().length > 0 ? at.filePath.trim() : \"ACTIVE-TASKS.md\";\n return isAbsolute(fp) ? fp : join(workspaceRootForCli(), fp);\n}\n\n/** Lines for `openclaw hybrid-mem goals config`. */\nexport function formatGoalStewardshipConfigLines(gs: GoalStewardshipConfig): string[] {\n const lines: string[] = [];\n lines.push(`Goal stewardship — ${gs.enabled ? \"enabled\" : \"disabled\"}`);\n lines.push(` goalsDir: ${gs.goalsDir}`);\n lines.push(` model: ${gs.model?.trim() ? gs.model.trim() : \"(default from LLM tiers)\"}`);\n lines.push(` heartbeatStewardship: ${gs.heartbeatStewardship ? \"on\" : \"off\"}`);\n lines.push(` watchdogHealthCheck: ${gs.watchdogHealthCheck ? \"on\" : \"off\"}`);\n lines.push(\n ` heartbeatRefreshActiveTask (Goals mirror in ACTIVE-TASKS.md): ${gs.heartbeatRefreshActiveTask ? \"on\" : \"off\"}`,\n );\n lines.push(` llmTriageOnHeartbeat: ${gs.llmTriageOnHeartbeat ? \"on\" : \"off\"}`);\n lines.push(` multiGoal: max ${gs.multiGoalMaxGoals} goals, ${gs.multiGoalMaxChars} chars cap`);\n lines.push(\n ` escalationPolicy.taskHygieneOnBlockedGoals: ${gs.escalationPolicy.taskHygieneOnBlockedGoals ? \"on\" : \"off\"}`,\n );\n lines.push(` circuitBreaker: ${gs.circuitBreaker.enabled ? \"on\" : \"off\"}`);\n if (gs.circuitBreaker.enabled) {\n lines.push(` sameBlockerRepeatLimit: ${gs.circuitBreaker.sameBlockerRepeatLimit}`);\n lines.push(` maxAssessmentsWithoutProgress: ${gs.circuitBreaker.maxAssessmentsWithoutProgress}`);\n }\n lines.push(\n ` allowCommandVerification: ${gs.allowCommandVerification ? \"on\" : \"off\"} (watchdog shell checks; off by default)`,\n );\n lines.push(` allowPrVerification: ${gs.allowPrVerification ? \"on\" : \"off\"} (GitHub pr_merged; off by default)`);\n lines.push(\n ` globalLimits: max ${gs.globalLimits.maxActiveGoals} active goals, ${gs.globalLimits.maxDispatchesPerHour} dispatches/hour`,\n );\n lines.push(\n ` defaults: maxDispatches=${gs.defaults.maxDispatches}, maxAssessments=${gs.defaults.maxAssessments}, cooldown=${gs.defaults.cooldownMinutes}m, priority=${gs.defaults.priority}`,\n );\n lines.push(\"\");\n lines.push(\"Toggle: openclaw hybrid-mem config-set goalStewardship enabled|disabled\");\n lines.push(\"Help: openclaw hybrid-mem help config-set goalStewardship.enabled\");\n return lines;\n}\n\n/** Lines for `openclaw hybrid-mem active-tasks config`. */\nexport function formatActiveTaskConfigLines(at: ActiveTaskConfig): string[] {\n const path = resolvedActiveTaskFilePath(at);\n const lines: string[] = [];\n lines.push(`Active task — ${at.enabled ? \"enabled\" : \"disabled\"}`);\n lines.push(\n ` ledger: ${at.ledger} — ${at.ledger === \"facts\" ? \"source: SQLite category:project facts; ACTIVE-TASKS.md can be rendered\" : \"source: ACTIVE-TASKS.md\"}`,\n );\n lines.push(` filePath: ${path}`);\n lines.push(` staleThreshold: ${at.staleThreshold}`);\n lines.push(` injectionBudget: ${at.injectionBudget} tokens (shared across active-task prepend blocks)`);\n lines.push(` injectionMaxTasks: ${at.injectionMaxTasks ?? \"(none — uses projection.maxRowsPerSection if set)\"}`);\n lines.push(` autoCheckpoint: ${at.autoCheckpoint ? \"on\" : \"off\"}`);\n lines.push(` flushOnComplete: ${at.flushOnComplete !== false ? \"on\" : \"off\"}`);\n lines.push(` staleWarning: ${at.staleWarning.enabled ? \"on\" : \"off\"}`);\n lines.push(\n ` taskHygiene — suggestGoalAfterTaskAgeDays: ${at.taskHygiene.suggestGoalAfterTaskAgeDays ?? 0} (0 = off)`,\n );\n lines.push(\n ` projection — mode: ${at.projection.mode}, sectioned: ${at.projection.sectioned}, dedupeBy: ${at.projection.dedupeBy}, maxRowsPerSection: ${at.projection.maxRowsPerSection ?? \"(none)\"}`,\n );\n lines.push(\"\");\n lines.push(\"Naming: JSON config uses camelCase `activeTask.*`; CLI command is `active-tasks` (plural).\");\n lines.push(\"The working-memory file default is ACTIVE-TASKS.md (see filePath above).\");\n lines.push(\"Toggle: openclaw hybrid-mem config-set activeTask enabled|disabled\");\n lines.push(\"Ledger: openclaw hybrid-mem config-set activeTask.ledger markdown|facts\");\n lines.push(\"Help: openclaw hybrid-mem help config-set activeTask.enabled\");\n return lines;\n}\n"],"mappings":";;;;;;;;;AAWA,SAAgB,sBAA8B;CAC5C,OAAO,OAAO,
|
|
1
|
+
{"version":3,"file":"config-feature-summaries.js","names":[],"sources":["../../cli/config-feature-summaries.ts"],"sourcesContent":["/**\n * Shared human-readable summaries for goal stewardship and active-task settings\n * (used by `hybrid-mem config`, `goals config`, `active-tasks config`).\n */\nimport { homedir } from \"node:os\";\nimport { isAbsolute, join } from \"node:path\";\n\nimport type { ActiveTaskConfig, GoalStewardshipConfig } from \"../config.js\";\nimport { getEnv } from \"../utils/env-manager.js\";\n\n/** Default workspace root for resolving relative paths in CLI output. */\nexport function workspaceRootForCli(): string {\n return getEnv(\"OPENCLAW_WORKSPACE\") ?? join(homedir(), \".openclaw\", \"workspace\");\n}\n\n/** Absolute path to the active-task markdown file / projection target. */\nexport function resolvedActiveTaskFilePath(at: ActiveTaskConfig): string {\n const fp = typeof at.filePath === \"string\" && at.filePath.trim().length > 0 ? at.filePath.trim() : \"ACTIVE-TASKS.md\";\n return isAbsolute(fp) ? fp : join(workspaceRootForCli(), fp);\n}\n\n/** Lines for `openclaw hybrid-mem goals config`. */\nexport function formatGoalStewardshipConfigLines(gs: GoalStewardshipConfig): string[] {\n const lines: string[] = [];\n lines.push(`Goal stewardship — ${gs.enabled ? \"enabled\" : \"disabled\"}`);\n lines.push(` goalsDir: ${gs.goalsDir}`);\n lines.push(` model: ${gs.model?.trim() ? gs.model.trim() : \"(default from LLM tiers)\"}`);\n lines.push(` heartbeatStewardship: ${gs.heartbeatStewardship ? \"on\" : \"off\"}`);\n lines.push(` watchdogHealthCheck: ${gs.watchdogHealthCheck ? \"on\" : \"off\"}`);\n lines.push(\n ` heartbeatRefreshActiveTask (Goals mirror in ACTIVE-TASKS.md): ${gs.heartbeatRefreshActiveTask ? \"on\" : \"off\"}`,\n );\n lines.push(` llmTriageOnHeartbeat: ${gs.llmTriageOnHeartbeat ? \"on\" : \"off\"}`);\n lines.push(` multiGoal: max ${gs.multiGoalMaxGoals} goals, ${gs.multiGoalMaxChars} chars cap`);\n lines.push(\n ` escalationPolicy.taskHygieneOnBlockedGoals: ${gs.escalationPolicy.taskHygieneOnBlockedGoals ? \"on\" : \"off\"}`,\n );\n lines.push(` circuitBreaker: ${gs.circuitBreaker.enabled ? \"on\" : \"off\"}`);\n if (gs.circuitBreaker.enabled) {\n lines.push(` sameBlockerRepeatLimit: ${gs.circuitBreaker.sameBlockerRepeatLimit}`);\n lines.push(` maxAssessmentsWithoutProgress: ${gs.circuitBreaker.maxAssessmentsWithoutProgress}`);\n }\n lines.push(\n ` allowCommandVerification: ${gs.allowCommandVerification ? \"on\" : \"off\"} (watchdog shell checks; off by default)`,\n );\n lines.push(` allowPrVerification: ${gs.allowPrVerification ? \"on\" : \"off\"} (GitHub pr_merged; off by default)`);\n lines.push(\n ` globalLimits: max ${gs.globalLimits.maxActiveGoals} active goals, ${gs.globalLimits.maxDispatchesPerHour} dispatches/hour`,\n );\n lines.push(\n ` defaults: maxDispatches=${gs.defaults.maxDispatches}, maxAssessments=${gs.defaults.maxAssessments}, cooldown=${gs.defaults.cooldownMinutes}m, priority=${gs.defaults.priority}`,\n );\n lines.push(\"\");\n lines.push(\"Toggle: openclaw hybrid-mem config-set goalStewardship enabled|disabled\");\n lines.push(\"Help: openclaw hybrid-mem help config-set goalStewardship.enabled\");\n return lines;\n}\n\n/** Lines for `openclaw hybrid-mem active-tasks config`. */\nexport function formatActiveTaskConfigLines(at: ActiveTaskConfig): string[] {\n const path = resolvedActiveTaskFilePath(at);\n const lines: string[] = [];\n lines.push(`Active task — ${at.enabled ? \"enabled\" : \"disabled\"}`);\n lines.push(\n ` ledger: ${at.ledger} — ${at.ledger === \"facts\" ? \"source: SQLite category:project facts; ACTIVE-TASKS.md can be rendered\" : \"source: ACTIVE-TASKS.md\"}`,\n );\n lines.push(` filePath: ${path}`);\n lines.push(` staleThreshold: ${at.staleThreshold}`);\n lines.push(` injectionBudget: ${at.injectionBudget} tokens (shared across active-task prepend blocks)`);\n lines.push(` injectionMaxTasks: ${at.injectionMaxTasks ?? \"(none — uses projection.maxRowsPerSection if set)\"}`);\n lines.push(` autoCheckpoint: ${at.autoCheckpoint ? \"on\" : \"off\"}`);\n lines.push(` flushOnComplete: ${at.flushOnComplete !== false ? \"on\" : \"off\"}`);\n lines.push(` staleWarning: ${at.staleWarning.enabled ? \"on\" : \"off\"}`);\n lines.push(\n ` taskHygiene — suggestGoalAfterTaskAgeDays: ${at.taskHygiene.suggestGoalAfterTaskAgeDays ?? 0} (0 = off)`,\n );\n lines.push(\n ` projection — mode: ${at.projection.mode}, sectioned: ${at.projection.sectioned}, dedupeBy: ${at.projection.dedupeBy}, maxRowsPerSection: ${at.projection.maxRowsPerSection ?? \"(none)\"}`,\n );\n lines.push(\"\");\n lines.push(\"Naming: JSON config uses camelCase `activeTask.*`; CLI command is `active-tasks` (plural).\");\n lines.push(\"The working-memory file default is ACTIVE-TASKS.md (see filePath above).\");\n lines.push(\"Toggle: openclaw hybrid-mem config-set activeTask enabled|disabled\");\n lines.push(\"Ledger: openclaw hybrid-mem config-set activeTask.ledger markdown|facts\");\n lines.push(\"Help: openclaw hybrid-mem help config-set activeTask.enabled\");\n return lines;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-output-sink.js","names":[],"sources":["../../cli/config-output-sink.ts"],"sourcesContent":["import type { VerifyCliSink } from \"./types.js\";\n\nexport function createConfigOutputSink(format: \"text\" | \"json\"): VerifyCliSink {\n if (format === \"json\") {\n return {\n log: (s: string) => {\n try {\n JSON.parse(s);\n process.stdout.write(`${s}\\n`);\n return;\n } catch {\n // Route non-JSON diagnostics away from machine-readable stdout.\n }\n console.error(s);\n },\n error: (s: string) => console.error(s),\n };\n }\n return { log: (s: string) => console.log(s), error: (s: string) => console.error(s) };\n}\n"],"mappings":";AAEA,SAAgB,uBAAuB,QAAwC;CAC7E,IAAI,WAAW,QACb,OAAO;EACL,MAAM,MAAc;GAClB,IAAI;IACF,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"config-output-sink.js","names":[],"sources":["../../cli/config-output-sink.ts"],"sourcesContent":["import type { VerifyCliSink } from \"./types.js\";\n\nexport function createConfigOutputSink(format: \"text\" | \"json\"): VerifyCliSink {\n if (format === \"json\") {\n return {\n log: (s: string) => {\n try {\n JSON.parse(s);\n process.stdout.write(`${s}\\n`);\n return;\n } catch {\n // Route non-JSON diagnostics away from machine-readable stdout.\n }\n console.error(s);\n },\n error: (s: string) => console.error(s),\n };\n }\n return { log: (s: string) => console.log(s), error: (s: string) => console.error(s) };\n}\n"],"mappings":";AAEA,SAAgB,uBAAuB,QAAwC;CAC7E,IAAI,WAAW,QACb,OAAO;EACL,MAAM,MAAc;GAClB,IAAI;IACF,KAAK,MAAM,CAAC;IACZ,QAAQ,OAAO,MAAM,GAAG,EAAE,GAAG;IAC7B;GACF,QAAQ,CAER;GACA,QAAQ,MAAM,CAAC;EACjB;EACA,QAAQ,MAAc,QAAQ,MAAM,CAAC;CACvC;CAEF,OAAO;EAAE,MAAM,MAAc,QAAQ,IAAI,CAAC;EAAG,QAAQ,MAAc,QAAQ,MAAM,CAAC;CAAE;AACtF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distill-session-jsonl.js","names":[],"sources":["../../cli/distill-session-jsonl.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\n\n/**\n * Extract text content from session JSONL file.\n */\nexport function extractTextFromSessionJsonl(filePath: string): string {\n const lines = readFileSync(filePath, \"utf-8\").split(\"\\n\");\n const parts: string[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const obj = JSON.parse(trimmed) as {\n type?: string;\n message?: { role?: string; content?: Array<{ type?: string; text?: string }> };\n };\n if (!obj || typeof obj !== \"object\" || Array.isArray(obj)) continue;\n if (obj.type !== \"message\" || !obj.message) continue;\n const msg = obj.message;\n if (msg.role !== \"user\" && msg.role !== \"assistant\") continue;\n const content = msg.content;\n if (!Array.isArray(content)) continue;\n for (const block of content) {\n if (block?.type === \"text\" && typeof block.text === \"string\" && block.text.trim().length > 0) {\n parts.push(block.text.trim());\n }\n }\n } catch {\n // NOTE: Intentionally NOT using capturePluginError here to avoid flooding\n // error logs with JSON parse errors from malformed session lines.\n // This is a best-effort parser; we skip bad lines silently.\n }\n }\n return parts.join(\"\\n\\n\");\n}\n"],"mappings":";;;;;AAKA,SAAgB,4BAA4B,UAA0B;CACpE,MAAM,QAAQ,aAAa,UAAU,
|
|
1
|
+
{"version":3,"file":"distill-session-jsonl.js","names":[],"sources":["../../cli/distill-session-jsonl.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\n\n/**\n * Extract text content from session JSONL file.\n */\nexport function extractTextFromSessionJsonl(filePath: string): string {\n const lines = readFileSync(filePath, \"utf-8\").split(\"\\n\");\n const parts: string[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n try {\n const obj = JSON.parse(trimmed) as {\n type?: string;\n message?: { role?: string; content?: Array<{ type?: string; text?: string }> };\n };\n if (!obj || typeof obj !== \"object\" || Array.isArray(obj)) continue;\n if (obj.type !== \"message\" || !obj.message) continue;\n const msg = obj.message;\n if (msg.role !== \"user\" && msg.role !== \"assistant\") continue;\n const content = msg.content;\n if (!Array.isArray(content)) continue;\n for (const block of content) {\n if (block?.type === \"text\" && typeof block.text === \"string\" && block.text.trim().length > 0) {\n parts.push(block.text.trim());\n }\n }\n } catch {\n // NOTE: Intentionally NOT using capturePluginError here to avoid flooding\n // error logs with JSON parse errors from malformed session lines.\n // This is a best-effort parser; we skip bad lines silently.\n }\n }\n return parts.join(\"\\n\\n\");\n}\n"],"mappings":";;;;;AAKA,SAAgB,4BAA4B,UAA0B;CACpE,MAAM,QAAQ,aAAa,UAAU,OAAO,EAAE,MAAM,IAAI;CACxD,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,UAAU,KAAK,KAAK;EAC1B,IAAI,CAAC,SAAS;EACd,IAAI;GACF,MAAM,MAAM,KAAK,MAAM,OAAO;GAI9B,IAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG;GAC3D,IAAI,IAAI,SAAS,aAAa,CAAC,IAAI,SAAS;GAC5C,MAAM,MAAM,IAAI;GAChB,IAAI,IAAI,SAAS,UAAU,IAAI,SAAS,aAAa;GACrD,MAAM,UAAU,IAAI;GACpB,IAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;GAC7B,KAAK,MAAM,SAAS,SAClB,IAAI,OAAO,SAAS,UAAU,OAAO,MAAM,SAAS,YAAY,MAAM,KAAK,KAAK,EAAE,SAAS,GACzF,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC;EAGlC,QAAQ,CAIR;CACF;CACA,OAAO,MAAM,KAAK,MAAM;AAC1B"}
|
package/dist/cli/distill.js
CHANGED
|
@@ -124,8 +124,12 @@ function registerDistillCommands(mem, ctx) {
|
|
|
124
124
|
const skipped = result.incidents.length - stored;
|
|
125
125
|
console.log(`Stored ${stored} directives as facts${skipped > 0 ? ` (${skipped} duplicates skipped)` : ""}.`);
|
|
126
126
|
if ((result.rejected ?? 0) > 0) console.log(`Rejected ${result.rejected} non-durable/untrusted directive candidate(s).`);
|
|
127
|
-
if (result.
|
|
127
|
+
if (result.directiveRejected) console.log(`Status: directiveRejected=permanent:${result.directiveRejected.permanent},retryable:${result.directiveRejected.retryable},parserOrModelFailure:${result.directiveRejected.parserOrModelFailure},boundedPartialRetry:${result.directiveRejected.boundedPartialRetry}`);
|
|
128
|
+
if (result.partial) console.log("Status: partial (retryable rejections detected; cursor not advanced).");
|
|
128
129
|
if (result.dedupeDegraded) console.log("Status: degraded dedupe (lexical-only fallback used).");
|
|
130
|
+
if (result.directiveDedupeMode) console.log(`Status: directiveDedupeMode=${result.directiveDedupeMode}`);
|
|
131
|
+
if (typeof result.cursorAdvanced === "boolean") console.log(`Status: cursorAdvanced=${result.cursorAdvanced}`);
|
|
132
|
+
if (result.cursorBlockedReason) console.log(`Status: cursorBlockedReason=${result.cursorBlockedReason}`);
|
|
129
133
|
}
|
|
130
134
|
}));
|
|
131
135
|
mem.command("extract-reinforcement").description("Extract reinforcement incidents from session JSONL and annotate facts/procedures").option("--days <n>", "Scan sessions from last N days (default: 3)", "3").option("-v, --verbose", "Log each reinforcement as it is detected").option("--dry-run", "Show what would be annotated without storing").option("--full", "Force full re-scan (ignore watermark, process all sessions in window)").action(withExit(async (opts, cmd) => {
|
|
@@ -146,6 +150,11 @@ function registerDistillCommands(mem, ctx) {
|
|
|
146
150
|
const status = result.annotationStatus;
|
|
147
151
|
if (status) {
|
|
148
152
|
console.log(`Annotation status: ${status}`);
|
|
153
|
+
if (result.annotationDiagnostic) {
|
|
154
|
+
const diagnostic = result.annotationDiagnostic;
|
|
155
|
+
console.log(`Annotation diagnostic: ${diagnostic.kind} — ${diagnostic.summary}`);
|
|
156
|
+
for (const action of diagnostic.recommendedActions) console.log(` next: ${action}`);
|
|
157
|
+
}
|
|
149
158
|
if (status === "failed_annotation" || status === "degraded_model_or_parser") process.exitCode = 1;
|
|
150
159
|
}
|
|
151
160
|
} else if (factsReinforced > 0 && result.annotationReasons?.errors && result.annotationReasons.errors > 0) process.exitCode = 2;
|
package/dist/cli/distill.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"distill.js","names":[],"sources":["../../cli/distill.ts"],"sourcesContent":["/**\n * CLI commands for distillation and extraction (distill, extract-*, generate-auto-skills, record-distill).\n */\n\nimport { type CommanderOptsParent, readHybridMemVerbose } from \"./global-verbose.js\";\nimport { type Chainable, withExit } from \"./shared.js\";\nimport type { ReinforcementExtractResult } from \"../services/reinforcement-extract.js\";\nimport type {\n DistillCliResult,\n DistillCliSink,\n DistillWindowResult,\n ExtractDailyResult,\n ExtractDailySink,\n ExtractProceduresResult,\n GenerateAutoSkillsResult,\n RecordDistillResult,\n} from \"./types.js\";\n\nexport type DistillContext = {\n runDistillWindow: (opts: { json: boolean }) => Promise<DistillWindowResult>;\n runRecordDistill: () => Promise<RecordDistillResult>;\n runExtractDaily: (\n opts: { days: number; dryRun: boolean; verbose?: boolean },\n sink: ExtractDailySink,\n ) => Promise<ExtractDailyResult>;\n runExtractProcedures: (opts: {\n sessionDir?: string;\n days?: number;\n dryRun: boolean;\n verbose?: boolean;\n full?: boolean;\n }) => Promise<ExtractProceduresResult>;\n runGenerateAutoSkills: (opts: {\n dryRun: boolean;\n apply?: boolean;\n verbose?: boolean;\n max?: number;\n policy?: string;\n json?: boolean;\n bypassDuplicateSkillCache?: boolean;\n }) => Promise<GenerateAutoSkillsResult>;\n runDistill: (\n opts: {\n dryRun: boolean;\n all?: boolean;\n days?: number;\n since?: string;\n model?: string;\n verbose?: boolean;\n maxSessions?: number;\n maxSessionTokens?: number;\n full?: boolean;\n },\n sink: DistillCliSink,\n ) => Promise<DistillCliResult>;\n runExtractDirectives: (opts: { days?: number; verbose?: boolean; dryRun?: boolean; full?: boolean }) => Promise<{\n incidents: Array<{\n userMessage: string;\n categories: string[];\n extractedRule: string;\n precedingAssistant: string;\n confidence: number;\n timestamp?: string;\n sessionFile: string;\n }>;\n sessionsScanned: number;\n stored?: number;\n rejected?: number;\n partial?: boolean;\n dedupeDegraded?: boolean;\n skipped?: boolean;\n }>;\n runExtractReinforcement: (opts: {\n days?: number;\n verbose?: boolean;\n dryRun?: boolean;\n full?: boolean;\n }) => Promise<ReinforcementExtractResult>;\n runGenerateProposals?: (opts: { dryRun: boolean; verbose?: boolean }) => Promise<{ created: number }>;\n};\n\nexport function registerDistillCommands(mem: Chainable, ctx: DistillContext): void {\n const {\n runDistillWindow,\n runRecordDistill,\n runExtractDaily,\n runExtractProcedures,\n runGenerateAutoSkills,\n runDistill,\n runExtractDirectives,\n runExtractReinforcement,\n runGenerateProposals,\n } = ctx;\n\n mem\n .command(\"distill\")\n .description(\n \"Index session JSONL into memory (extract facts via LLM, dedup, store). Use distill-window for date range info.\",\n )\n .option(\"--dry-run\", \"Show what would be processed without storing\")\n .option(\"--all\", \"Process all sessions (last 90 days)\")\n .option(\"--days <n>\", \"Process sessions from last N days (default: 3)\", \"3\")\n .option(\"--since <date>\", \"Process sessions since date (YYYY-MM-DD)\")\n .option(\n \"--model <model>\",\n \"LLM for extraction (recommended: gemini-3.1-pro-preview for 1M context). Default: config.distill.defaultModel or gemini-3.1-pro-preview\",\n )\n .option(\"-v, --verbose\", \"Log each fact as it is stored\")\n .option(\"--max-sessions <n>\", \"Limit sessions to process (for cost control)\", \"0\")\n .option(\n \"--max-session-tokens <n>\",\n \"Max tokens per session chunk; oversized sessions are split into overlapping chunks (default: batch limit)\",\n \"0\",\n )\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n dryRun?: boolean;\n all?: boolean;\n days?: string;\n since?: string;\n model?: string;\n verbose?: boolean;\n maxSessions?: string;\n maxSessionTokens?: string;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const sink = {\n log: (s: string) => console.log(s),\n warn: (s: string) => console.warn(s),\n };\n const maxSessions = Math.max(0, Number.parseInt(opts.maxSessions || \"0\", 10) || 0);\n const maxSessionTokens = Math.max(0, Number.parseInt(opts.maxSessionTokens || \"0\", 10) || 0);\n const days = opts.days != null ? Number.parseInt(opts.days, 10) : undefined;\n const result = await runDistill(\n {\n dryRun: !!opts.dryRun,\n all: !!opts.all,\n days: Number.isFinite(days) ? days : undefined,\n since: opts.since?.trim() || undefined,\n model: opts.model,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n maxSessions: maxSessions > 0 ? maxSessions : undefined,\n maxSessionTokens: maxSessionTokens > 0 ? maxSessionTokens : undefined,\n full: !!opts.full,\n },\n sink,\n );\n if (result.dryRun) {\n console.log(`\\nWould extract ${result.factsExtracted} facts from ${result.sessionsScanned} sessions.`);\n } else {\n console.log(\n `\\nDistill done: ${result.stored} stored, ${result.dedupSkipped} skipped (${result.factsExtracted} extracted from ${result.sessionsScanned} sessions).`,\n );\n }\n },\n ),\n );\n\n mem\n .command(\"distill-window\")\n .description(\n \"Print the session distillation window (full or incremental). Use at start of a distillation job to decide what to process.\",\n )\n .option(\"--json\", \"Output machine-readable JSON only (mode, startDate, endDate, mtimeDays)\")\n .action(\n withExit(async (opts: { json?: boolean }) => {\n const result = await runDistillWindow({ json: !!opts.json });\n if (opts.json) {\n console.log(JSON.stringify(result));\n return;\n }\n console.log(`Distill window: ${result.mode}`);\n console.log(` startDate: ${result.startDate}`);\n console.log(` endDate: ${result.endDate}`);\n console.log(` mtimeDays: ${result.mtimeDays} (use find ... -mtime -${result.mtimeDays} for session files)`);\n console.log(\"Process sessions from that window; distill will record the run automatically.\");\n }),\n );\n\n mem\n .command(\"record-distill\")\n .description(\n \"Record that session distillation was run (writes timestamp to .distill_last_run for 'verify' to show)\",\n )\n .action(\n withExit(async () => {\n const result = await runRecordDistill();\n console.log(`Recorded distillation run: ${result.timestamp}`);\n console.log(`Written to ${result.path}. Run 'openclaw hybrid-mem verify' to see it.`);\n }),\n );\n\n mem\n .command(\"extract-daily\")\n .description(\"Extract structured facts from daily memory files\")\n .option(\"--days <n>\", \"How many days back to scan\", \"7\")\n .option(\"--dry-run\", \"Show extractions without storing\")\n .option(\"-v, --verbose\", \"Log each extracted fact as it is stored\")\n .action(\n withExit(async (opts: { days: string; dryRun?: boolean; verbose?: boolean }, cmd?: CommanderOptsParent) => {\n const daysBack = Number.parseInt(opts.days, 10);\n const result = await runExtractDaily(\n {\n days: daysBack,\n dryRun: !!opts.dryRun,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n },\n { log: (s) => console.log(s), warn: (s) => console.warn(s) },\n );\n if (result.dryRun) {\n console.log(`\\nWould extract: ${result.totalExtracted} facts from last ${result.daysBack} days`);\n } else {\n console.log(\n `\\nExtracted ${result.totalStored} new facts (${result.totalExtracted} candidates, ${\n result.totalExtracted - result.totalStored\n } duplicates skipped)`,\n );\n }\n }),\n );\n\n mem\n .command(\"extract-procedures\")\n .description(\"Procedural memory: extract tool-call sequences from session JSONL and store as procedures\")\n .option(\"--dir <path>\", \"Session directory (default: config procedures.sessionsDir)\")\n .option(\"--days <n>\", \"Only sessions modified in last N days (default: all in dir)\", \"\")\n .option(\"--dry-run\", \"Show what would be stored without writing\")\n .option(\"-v, --verbose\", \"Log why each session was skipped (no_task_intent, fewer_than_2_steps)\")\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n dir?: string;\n days?: string;\n dryRun?: boolean;\n verbose?: boolean;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const days = opts.days != null ? Number.parseInt(opts.days, 10) : undefined;\n const result = await runExtractProcedures({\n sessionDir: opts.dir,\n days: Number.isFinite(days) ? days : undefined,\n dryRun: !!opts.dryRun,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n full: !!opts.full,\n });\n if (result.dryRun) {\n console.log(\n `\\n[dry-run] Sessions scanned: ${result.sessionsScanned}, procedures that would be stored: ${result.proceduresStored} (${result.positiveCount} positive, ${result.negativeCount} negative)`,\n );\n } else {\n console.log(\n `\\nSessions scanned: ${result.sessionsScanned}; procedures stored/updated: ${result.proceduresStored} (${result.positiveCount} positive, ${result.negativeCount} negative)`,\n );\n }\n },\n ),\n );\n\n mem\n .command(\"generate-auto-skills\")\n .description(\"Generate verified draft SKILL.md + recipe/eval metadata for safe validated procedures\")\n .option(\"--dry-run\", \"Show what would be generated without writing (default unless --apply is passed)\")\n .option(\"--apply\", \"Apply policy result. Draft writes only occur when the effective policy is auto-safe.\")\n .option(\"--max <n>\", \"Maximum procedures to inspect\", \"10\")\n .option(\n \"--policy <policy>\",\n \"Promotion policy: draft-only, manual, auto-safe (default: dry-run draft-only; non-dry-run/apply defaults to auto-safe for legacy maintenance callers)\",\n )\n .option(\"--json\", \"Emit structured JSON summary\")\n .option(\"--bypass-skill-duplicate-cache\", \"Re-read every SKILL.md for duplicate detection (ignore mtime cache)\")\n .option(\"-v, --verbose\", \"Log each decision and generated skill path\")\n .action(\n withExit(\n async (\n opts: {\n dryRun?: boolean;\n apply?: boolean;\n verbose?: boolean;\n max?: string;\n policy?: string;\n json?: boolean;\n bypassSkillDuplicateCache?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const max = Number.parseInt(opts.max ?? \"10\", 10);\n if (!Number.isFinite(max) || max < 1) {\n console.error(\"error: --max must be a positive integer\");\n process.exitCode = 1;\n return;\n }\n const apply = opts.apply === true;\n const result = await runGenerateAutoSkills({\n dryRun: !apply || opts.dryRun === true,\n apply,\n max,\n policy: opts.policy,\n json: opts.json,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n bypassDuplicateSkillCache: opts.bypassSkillDuplicateCache === true,\n });\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n const s = result.summary;\n const counts = s\n ? `candidates=${s.candidates}, eligible=${s.eligible}, drafted=${s.drafted}, rejected=${s.rejected}, deferred=${s.deferred}, failedValidation=${s.failedValidation}, failedEval=${s.failedEval}`\n : `generated=${result.generated}, skipped=${result.skipped}`;\n if (result.dryRun) {\n console.log(`\\n[dry-run] Procedure skill promotion summary: ${counts}`);\n } else {\n console.log(`\\nProcedure skill promotion summary: ${counts}`);\n for (const p of result.paths) console.log(` ${p}`);\n }\n },\n ),\n );\n\n mem\n .command(\"generate-proposals\")\n .description(\"Generate persona proposals from reflection insights (patterns, rules, meta). Use after reflect-meta.\")\n .option(\"--dry-run\", \"Show what would be proposed without creating\")\n .option(\"-v, --verbose\", \"Log each proposal created\")\n .action(\n withExit(async (opts?: { dryRun?: boolean; verbose?: boolean }, cmd?: CommanderOptsParent) => {\n if (!runGenerateProposals) {\n console.log(\"Generate-proposals not available (personaProposals disabled).\");\n return;\n }\n const result = await runGenerateProposals({\n dryRun: !!opts?.dryRun,\n verbose: !!opts?.verbose || readHybridMemVerbose(cmd),\n });\n if (opts?.dryRun) {\n console.log(`\\n[dry-run] Would create ${result.created} proposal(s).`);\n } else {\n console.log(`\\nCreated ${result.created} proposal(s).`);\n }\n }),\n );\n\n mem\n .command(\"extract-directives\")\n .description(\"Extract directive incidents from session JSONL (10 categories)\")\n .option(\"--days <n>\", \"Scan sessions from last N days (default: 3)\", \"3\")\n .option(\"-v, --verbose\", \"Log each directive as it is detected\")\n .option(\"--dry-run\", \"Show what would be extracted without storing\")\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n days?: string;\n verbose?: boolean;\n dryRun?: boolean;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const days = Number.parseInt(opts.days ?? \"3\", 10);\n const result = await runExtractDirectives({\n days,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n dryRun: opts.dryRun,\n full: opts.full,\n });\n console.log(`\\nSessions scanned: ${result.sessionsScanned}; directives found: ${result.incidents.length}`);\n if (opts.dryRun) {\n console.log(`[dry-run] Would store ${result.incidents.length} directives as facts.`);\n } else {\n const stored = result.stored ?? result.incidents.length;\n const skipped = result.incidents.length - stored;\n console.log(\n `Stored ${stored} directives as facts${skipped > 0 ? ` (${skipped} duplicates skipped)` : \"\"}.`,\n );\n if ((result.rejected ?? 0) > 0) {\n console.log(`Rejected ${result.rejected} non-durable/untrusted directive candidate(s).`);\n }\n if (result.partial) {\n console.log(\"Status: partial (rejections detected; cursor not advanced).\");\n }\n if (result.dedupeDegraded) {\n console.log(\"Status: degraded dedupe (lexical-only fallback used).\");\n }\n }\n },\n ),\n );\n\n mem\n .command(\"extract-reinforcement\")\n .description(\"Extract reinforcement incidents from session JSONL and annotate facts/procedures\")\n .option(\"--days <n>\", \"Scan sessions from last N days (default: 3)\", \"3\")\n .option(\"-v, --verbose\", \"Log each reinforcement as it is detected\")\n .option(\"--dry-run\", \"Show what would be annotated without storing\")\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n days?: string;\n verbose?: boolean;\n dryRun?: boolean;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const days = Number.parseInt(opts.days ?? \"3\", 10);\n const result = await runExtractReinforcement({\n days,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n dryRun: opts.dryRun,\n full: opts.full,\n });\n console.log(\n `\\nSessions scanned: ${result.sessionsScanned}; reinforcement incidents found: ${result.incidents.length}`,\n );\n if (opts.dryRun) {\n console.log(\"[dry-run] Would annotate facts/procedures with reinforcement data.\");\n } else {\n const factsReinforced = result.annotated ?? 0;\n console.log(`Annotated ${factsReinforced} facts with reinforcement data.`);\n if (result.incidents.length > 0 && factsReinforced === 0) {\n const reasons = result.annotationReasons;\n if (reasons) {\n console.log(\n `Annotation reason breakdown: noRecalledIds=${reasons.noRecalledIds} reinforced=${reasons.reinforced} recalledIdsNoMatch=${reasons.recalledIdsNoMatch} errors=${reasons.errors}`,\n );\n }\n const status = result.annotationStatus;\n if (status) {\n console.log(`Annotation status: ${status}`);\n if (status === \"failed_annotation\" || status === \"degraded_model_or_parser\") {\n process.exitCode = 1;\n }\n }\n } else if (factsReinforced > 0 && result.annotationReasons?.errors && result.annotationReasons.errors > 0) {\n process.exitCode = 2;\n }\n }\n },\n ),\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"distill.js","names":[],"sources":["../../cli/distill.ts"],"sourcesContent":["/**\n * CLI commands for distillation and extraction (distill, extract-*, generate-auto-skills, record-distill).\n */\n\nimport { type CommanderOptsParent, readHybridMemVerbose } from \"./global-verbose.js\";\nimport { type Chainable, withExit } from \"./shared.js\";\nimport type { ReinforcementExtractResult } from \"../services/reinforcement-extract.js\";\nimport type {\n DistillCliResult,\n DistillCliSink,\n DistillWindowResult,\n ExtractDailyResult,\n ExtractDailySink,\n ExtractProceduresResult,\n GenerateAutoSkillsResult,\n RecordDistillResult,\n} from \"./types.js\";\n\nexport type DistillContext = {\n runDistillWindow: (opts: { json: boolean }) => Promise<DistillWindowResult>;\n runRecordDistill: () => Promise<RecordDistillResult>;\n runExtractDaily: (\n opts: { days: number; dryRun: boolean; verbose?: boolean },\n sink: ExtractDailySink,\n ) => Promise<ExtractDailyResult>;\n runExtractProcedures: (opts: {\n sessionDir?: string;\n days?: number;\n dryRun: boolean;\n verbose?: boolean;\n full?: boolean;\n }) => Promise<ExtractProceduresResult>;\n runGenerateAutoSkills: (opts: {\n dryRun: boolean;\n apply?: boolean;\n verbose?: boolean;\n max?: number;\n policy?: string;\n json?: boolean;\n bypassDuplicateSkillCache?: boolean;\n }) => Promise<GenerateAutoSkillsResult>;\n runDistill: (\n opts: {\n dryRun: boolean;\n all?: boolean;\n days?: number;\n since?: string;\n model?: string;\n verbose?: boolean;\n maxSessions?: number;\n maxSessionTokens?: number;\n full?: boolean;\n },\n sink: DistillCliSink,\n ) => Promise<DistillCliResult>;\n runExtractDirectives: (opts: { days?: number; verbose?: boolean; dryRun?: boolean; full?: boolean }) => Promise<{\n incidents: Array<{\n userMessage: string;\n categories: string[];\n extractedRule: string;\n precedingAssistant: string;\n confidence: number;\n timestamp?: string;\n sessionFile: string;\n }>;\n sessionsScanned: number;\n stored?: number;\n rejected?: number;\n partial?: boolean;\n dedupeDegraded?: boolean;\n directiveDedupeMode?: \"vector\" | \"lexical-only\" | \"mixed\";\n directiveRejected?: {\n permanent: number;\n retryable: number;\n parserOrModelFailure: number;\n boundedPartialRetry: number;\n };\n cursorAdvanced?: boolean;\n cursorBlockedReason?: \"retryable_rejections\" | \"parser_or_model_failure\" | \"bounded_partial_retry\";\n skipped?: boolean;\n }>;\n runExtractReinforcement: (opts: {\n days?: number;\n verbose?: boolean;\n dryRun?: boolean;\n full?: boolean;\n }) => Promise<ReinforcementExtractResult>;\n runGenerateProposals?: (opts: { dryRun: boolean; verbose?: boolean }) => Promise<{ created: number }>;\n};\n\nexport function registerDistillCommands(mem: Chainable, ctx: DistillContext): void {\n const {\n runDistillWindow,\n runRecordDistill,\n runExtractDaily,\n runExtractProcedures,\n runGenerateAutoSkills,\n runDistill,\n runExtractDirectives,\n runExtractReinforcement,\n runGenerateProposals,\n } = ctx;\n\n mem\n .command(\"distill\")\n .description(\n \"Index session JSONL into memory (extract facts via LLM, dedup, store). Use distill-window for date range info.\",\n )\n .option(\"--dry-run\", \"Show what would be processed without storing\")\n .option(\"--all\", \"Process all sessions (last 90 days)\")\n .option(\"--days <n>\", \"Process sessions from last N days (default: 3)\", \"3\")\n .option(\"--since <date>\", \"Process sessions since date (YYYY-MM-DD)\")\n .option(\n \"--model <model>\",\n \"LLM for extraction (recommended: gemini-3.1-pro-preview for 1M context). Default: config.distill.defaultModel or gemini-3.1-pro-preview\",\n )\n .option(\"-v, --verbose\", \"Log each fact as it is stored\")\n .option(\"--max-sessions <n>\", \"Limit sessions to process (for cost control)\", \"0\")\n .option(\n \"--max-session-tokens <n>\",\n \"Max tokens per session chunk; oversized sessions are split into overlapping chunks (default: batch limit)\",\n \"0\",\n )\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n dryRun?: boolean;\n all?: boolean;\n days?: string;\n since?: string;\n model?: string;\n verbose?: boolean;\n maxSessions?: string;\n maxSessionTokens?: string;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const sink = {\n log: (s: string) => console.log(s),\n warn: (s: string) => console.warn(s),\n };\n const maxSessions = Math.max(0, Number.parseInt(opts.maxSessions || \"0\", 10) || 0);\n const maxSessionTokens = Math.max(0, Number.parseInt(opts.maxSessionTokens || \"0\", 10) || 0);\n const days = opts.days != null ? Number.parseInt(opts.days, 10) : undefined;\n const result = await runDistill(\n {\n dryRun: !!opts.dryRun,\n all: !!opts.all,\n days: Number.isFinite(days) ? days : undefined,\n since: opts.since?.trim() || undefined,\n model: opts.model,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n maxSessions: maxSessions > 0 ? maxSessions : undefined,\n maxSessionTokens: maxSessionTokens > 0 ? maxSessionTokens : undefined,\n full: !!opts.full,\n },\n sink,\n );\n if (result.dryRun) {\n console.log(`\\nWould extract ${result.factsExtracted} facts from ${result.sessionsScanned} sessions.`);\n } else {\n console.log(\n `\\nDistill done: ${result.stored} stored, ${result.dedupSkipped} skipped (${result.factsExtracted} extracted from ${result.sessionsScanned} sessions).`,\n );\n }\n },\n ),\n );\n\n mem\n .command(\"distill-window\")\n .description(\n \"Print the session distillation window (full or incremental). Use at start of a distillation job to decide what to process.\",\n )\n .option(\"--json\", \"Output machine-readable JSON only (mode, startDate, endDate, mtimeDays)\")\n .action(\n withExit(async (opts: { json?: boolean }) => {\n const result = await runDistillWindow({ json: !!opts.json });\n if (opts.json) {\n console.log(JSON.stringify(result));\n return;\n }\n console.log(`Distill window: ${result.mode}`);\n console.log(` startDate: ${result.startDate}`);\n console.log(` endDate: ${result.endDate}`);\n console.log(` mtimeDays: ${result.mtimeDays} (use find ... -mtime -${result.mtimeDays} for session files)`);\n console.log(\"Process sessions from that window; distill will record the run automatically.\");\n }),\n );\n\n mem\n .command(\"record-distill\")\n .description(\n \"Record that session distillation was run (writes timestamp to .distill_last_run for 'verify' to show)\",\n )\n .action(\n withExit(async () => {\n const result = await runRecordDistill();\n console.log(`Recorded distillation run: ${result.timestamp}`);\n console.log(`Written to ${result.path}. Run 'openclaw hybrid-mem verify' to see it.`);\n }),\n );\n\n mem\n .command(\"extract-daily\")\n .description(\"Extract structured facts from daily memory files\")\n .option(\"--days <n>\", \"How many days back to scan\", \"7\")\n .option(\"--dry-run\", \"Show extractions without storing\")\n .option(\"-v, --verbose\", \"Log each extracted fact as it is stored\")\n .action(\n withExit(async (opts: { days: string; dryRun?: boolean; verbose?: boolean }, cmd?: CommanderOptsParent) => {\n const daysBack = Number.parseInt(opts.days, 10);\n const result = await runExtractDaily(\n {\n days: daysBack,\n dryRun: !!opts.dryRun,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n },\n { log: (s) => console.log(s), warn: (s) => console.warn(s) },\n );\n if (result.dryRun) {\n console.log(`\\nWould extract: ${result.totalExtracted} facts from last ${result.daysBack} days`);\n } else {\n console.log(\n `\\nExtracted ${result.totalStored} new facts (${result.totalExtracted} candidates, ${\n result.totalExtracted - result.totalStored\n } duplicates skipped)`,\n );\n }\n }),\n );\n\n mem\n .command(\"extract-procedures\")\n .description(\"Procedural memory: extract tool-call sequences from session JSONL and store as procedures\")\n .option(\"--dir <path>\", \"Session directory (default: config procedures.sessionsDir)\")\n .option(\"--days <n>\", \"Only sessions modified in last N days (default: all in dir)\", \"\")\n .option(\"--dry-run\", \"Show what would be stored without writing\")\n .option(\"-v, --verbose\", \"Log why each session was skipped (no_task_intent, fewer_than_2_steps)\")\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n dir?: string;\n days?: string;\n dryRun?: boolean;\n verbose?: boolean;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const days = opts.days != null ? Number.parseInt(opts.days, 10) : undefined;\n const result = await runExtractProcedures({\n sessionDir: opts.dir,\n days: Number.isFinite(days) ? days : undefined,\n dryRun: !!opts.dryRun,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n full: !!opts.full,\n });\n if (result.dryRun) {\n console.log(\n `\\n[dry-run] Sessions scanned: ${result.sessionsScanned}, procedures that would be stored: ${result.proceduresStored} (${result.positiveCount} positive, ${result.negativeCount} negative)`,\n );\n } else {\n console.log(\n `\\nSessions scanned: ${result.sessionsScanned}; procedures stored/updated: ${result.proceduresStored} (${result.positiveCount} positive, ${result.negativeCount} negative)`,\n );\n }\n },\n ),\n );\n\n mem\n .command(\"generate-auto-skills\")\n .description(\"Generate verified draft SKILL.md + recipe/eval metadata for safe validated procedures\")\n .option(\"--dry-run\", \"Show what would be generated without writing (default unless --apply is passed)\")\n .option(\"--apply\", \"Apply policy result. Draft writes only occur when the effective policy is auto-safe.\")\n .option(\"--max <n>\", \"Maximum procedures to inspect\", \"10\")\n .option(\n \"--policy <policy>\",\n \"Promotion policy: draft-only, manual, auto-safe (default: dry-run draft-only; non-dry-run/apply defaults to auto-safe for legacy maintenance callers)\",\n )\n .option(\"--json\", \"Emit structured JSON summary\")\n .option(\"--bypass-skill-duplicate-cache\", \"Re-read every SKILL.md for duplicate detection (ignore mtime cache)\")\n .option(\"-v, --verbose\", \"Log each decision and generated skill path\")\n .action(\n withExit(\n async (\n opts: {\n dryRun?: boolean;\n apply?: boolean;\n verbose?: boolean;\n max?: string;\n policy?: string;\n json?: boolean;\n bypassSkillDuplicateCache?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const max = Number.parseInt(opts.max ?? \"10\", 10);\n if (!Number.isFinite(max) || max < 1) {\n console.error(\"error: --max must be a positive integer\");\n process.exitCode = 1;\n return;\n }\n const apply = opts.apply === true;\n const result = await runGenerateAutoSkills({\n dryRun: !apply || opts.dryRun === true,\n apply,\n max,\n policy: opts.policy,\n json: opts.json,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n bypassDuplicateSkillCache: opts.bypassSkillDuplicateCache === true,\n });\n if (opts.json) {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n const s = result.summary;\n const counts = s\n ? `candidates=${s.candidates}, eligible=${s.eligible}, drafted=${s.drafted}, rejected=${s.rejected}, deferred=${s.deferred}, failedValidation=${s.failedValidation}, failedEval=${s.failedEval}`\n : `generated=${result.generated}, skipped=${result.skipped}`;\n if (result.dryRun) {\n console.log(`\\n[dry-run] Procedure skill promotion summary: ${counts}`);\n } else {\n console.log(`\\nProcedure skill promotion summary: ${counts}`);\n for (const p of result.paths) console.log(` ${p}`);\n }\n },\n ),\n );\n\n mem\n .command(\"generate-proposals\")\n .description(\"Generate persona proposals from reflection insights (patterns, rules, meta). Use after reflect-meta.\")\n .option(\"--dry-run\", \"Show what would be proposed without creating\")\n .option(\"-v, --verbose\", \"Log each proposal created\")\n .action(\n withExit(async (opts?: { dryRun?: boolean; verbose?: boolean }, cmd?: CommanderOptsParent) => {\n if (!runGenerateProposals) {\n console.log(\"Generate-proposals not available (personaProposals disabled).\");\n return;\n }\n const result = await runGenerateProposals({\n dryRun: !!opts?.dryRun,\n verbose: !!opts?.verbose || readHybridMemVerbose(cmd),\n });\n if (opts?.dryRun) {\n console.log(`\\n[dry-run] Would create ${result.created} proposal(s).`);\n } else {\n console.log(`\\nCreated ${result.created} proposal(s).`);\n }\n }),\n );\n\n mem\n .command(\"extract-directives\")\n .description(\"Extract directive incidents from session JSONL (10 categories)\")\n .option(\"--days <n>\", \"Scan sessions from last N days (default: 3)\", \"3\")\n .option(\"-v, --verbose\", \"Log each directive as it is detected\")\n .option(\"--dry-run\", \"Show what would be extracted without storing\")\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n days?: string;\n verbose?: boolean;\n dryRun?: boolean;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const days = Number.parseInt(opts.days ?? \"3\", 10);\n const result = await runExtractDirectives({\n days,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n dryRun: opts.dryRun,\n full: opts.full,\n });\n console.log(`\\nSessions scanned: ${result.sessionsScanned}; directives found: ${result.incidents.length}`);\n if (opts.dryRun) {\n console.log(`[dry-run] Would store ${result.incidents.length} directives as facts.`);\n } else {\n const stored = result.stored ?? result.incidents.length;\n const skipped = result.incidents.length - stored;\n console.log(\n `Stored ${stored} directives as facts${skipped > 0 ? ` (${skipped} duplicates skipped)` : \"\"}.`,\n );\n if ((result.rejected ?? 0) > 0) {\n console.log(`Rejected ${result.rejected} non-durable/untrusted directive candidate(s).`);\n }\n if (result.directiveRejected) {\n console.log(\n `Status: directiveRejected=permanent:${result.directiveRejected.permanent},retryable:${result.directiveRejected.retryable},parserOrModelFailure:${result.directiveRejected.parserOrModelFailure},boundedPartialRetry:${result.directiveRejected.boundedPartialRetry}`,\n );\n }\n if (result.partial) {\n console.log(\"Status: partial (retryable rejections detected; cursor not advanced).\");\n }\n if (result.dedupeDegraded) {\n console.log(\"Status: degraded dedupe (lexical-only fallback used).\");\n }\n if (result.directiveDedupeMode) {\n console.log(`Status: directiveDedupeMode=${result.directiveDedupeMode}`);\n }\n if (typeof result.cursorAdvanced === \"boolean\") {\n console.log(`Status: cursorAdvanced=${result.cursorAdvanced}`);\n }\n if (result.cursorBlockedReason) {\n console.log(`Status: cursorBlockedReason=${result.cursorBlockedReason}`);\n }\n }\n },\n ),\n );\n\n mem\n .command(\"extract-reinforcement\")\n .description(\"Extract reinforcement incidents from session JSONL and annotate facts/procedures\")\n .option(\"--days <n>\", \"Scan sessions from last N days (default: 3)\", \"3\")\n .option(\"-v, --verbose\", \"Log each reinforcement as it is detected\")\n .option(\"--dry-run\", \"Show what would be annotated without storing\")\n .option(\"--full\", \"Force full re-scan (ignore watermark, process all sessions in window)\")\n .action(\n withExit(\n async (\n opts: {\n days?: string;\n verbose?: boolean;\n dryRun?: boolean;\n full?: boolean;\n },\n cmd?: CommanderOptsParent,\n ) => {\n const days = Number.parseInt(opts.days ?? \"3\", 10);\n const result = await runExtractReinforcement({\n days,\n verbose: !!opts.verbose || readHybridMemVerbose(cmd),\n dryRun: opts.dryRun,\n full: opts.full,\n });\n console.log(\n `\\nSessions scanned: ${result.sessionsScanned}; reinforcement incidents found: ${result.incidents.length}`,\n );\n if (opts.dryRun) {\n console.log(\"[dry-run] Would annotate facts/procedures with reinforcement data.\");\n } else {\n const factsReinforced = result.annotated ?? 0;\n console.log(`Annotated ${factsReinforced} facts with reinforcement data.`);\n if (result.incidents.length > 0 && factsReinforced === 0) {\n const reasons = result.annotationReasons;\n if (reasons) {\n console.log(\n `Annotation reason breakdown: noRecalledIds=${reasons.noRecalledIds} reinforced=${reasons.reinforced} recalledIdsNoMatch=${reasons.recalledIdsNoMatch} errors=${reasons.errors}`,\n );\n }\n const status = result.annotationStatus;\n if (status) {\n console.log(`Annotation status: ${status}`);\n if (result.annotationDiagnostic) {\n const diagnostic = result.annotationDiagnostic;\n console.log(`Annotation diagnostic: ${diagnostic.kind} — ${diagnostic.summary}`);\n for (const action of diagnostic.recommendedActions) {\n console.log(` next: ${action}`);\n }\n }\n if (status === \"failed_annotation\" || status === \"degraded_model_or_parser\") {\n process.exitCode = 1;\n }\n }\n } else if (factsReinforced > 0 && result.annotationReasons?.errors && result.annotationReasons.errors > 0) {\n process.exitCode = 2;\n }\n }\n },\n ),\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-verbose.js","names":[],"sources":["../../cli/global-verbose.ts"],"sourcesContent":["/**\n * Read `hybrid-mem -v/--verbose` from the parent Commander command chain.\n */\n\n/** Minimal Commander command shape for reading inherited opts (hybrid-mem --verbose). */\nexport type CommanderOptsParent = {\n opts: () => { verbose?: boolean };\n parent?: CommanderOptsParent | null;\n};\n\nexport function readHybridMemVerbose(cmd: CommanderOptsParent | undefined): boolean {\n let c: CommanderOptsParent | undefined = cmd;\n while (c) {\n const o = c.opts() as { verbose?: boolean };\n if (o.verbose) return true;\n c = c.parent ?? undefined;\n }\n return false;\n}\n"],"mappings":";AAUA,SAAgB,qBAAqB,KAA+C;CAClF,IAAI,IAAqC;CACzC,OAAO,GAAG;EAER,IADU,EAAE,
|
|
1
|
+
{"version":3,"file":"global-verbose.js","names":[],"sources":["../../cli/global-verbose.ts"],"sourcesContent":["/**\n * Read `hybrid-mem -v/--verbose` from the parent Commander command chain.\n */\n\n/** Minimal Commander command shape for reading inherited opts (hybrid-mem --verbose). */\nexport type CommanderOptsParent = {\n opts: () => { verbose?: boolean };\n parent?: CommanderOptsParent | null;\n};\n\nexport function readHybridMemVerbose(cmd: CommanderOptsParent | undefined): boolean {\n let c: CommanderOptsParent | undefined = cmd;\n while (c) {\n const o = c.opts() as { verbose?: boolean };\n if (o.verbose) return true;\n c = c.parent ?? undefined;\n }\n return false;\n}\n"],"mappings":";AAUA,SAAgB,qBAAqB,KAA+C;CAClF,IAAI,IAAqC;CACzC,OAAO,GAAG;EAER,IADU,EAAE,KACR,EAAE,SAAS,OAAO;EACtB,IAAI,EAAE,UAAU,KAAA;CAClB;CACA,OAAO;AACT"}
|