arkaos 4.22.0 → 4.24.0
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/README.md +1 -1
- package/THE-ARKAOS-GUIDE.md +72 -0
- package/VERSION +1 -1
- package/arka/SKILL.md +29 -7
- package/arka/skills/bootstrap-agent/SKILL.md +3 -2
- package/arka/skills/conclave/SKILL.md +11 -0
- package/arka/skills/flow/SKILL.md +3 -2
- package/arka/skills/forge/SKILL.md +3 -2
- package/arka/skills/recipes/SKILL.md +3 -2
- package/arka/skills/refine/SKILL.md +3 -2
- package/arka/skills/research/SKILL.md +3 -2
- package/bin/arka-doctor +8 -0
- package/core/cognition/insights/store.py +15 -4
- package/core/forge/persistence.py +27 -9
- package/core/forge/schema.py +45 -22
- package/core/governance/evidence_checks.py +101 -9
- package/core/governance/kb_cite_check.py +16 -6
- package/core/governance/stop_lint.py +38 -11
- package/core/governance/stop_lint_telemetry.py +11 -2
- package/core/hooks/user_prompt_submit.py +21 -23
- package/core/synapse/engine.py +46 -16
- package/core/synapse/graph_context_layer.py +7 -2
- package/core/synapse/kb_cache.py +63 -16
- package/core/synapse/layers.py +93 -30
- package/core/synapse/layers_base.py +16 -0
- package/core/synapse/layers_kb.py +325 -19
- package/dashboard/app/layouts/default.vue +7 -0
- package/dashboard/app/pages/plan-canvas.vue +630 -0
- package/departments/brand/SKILL.md +3 -2
- package/departments/brand/skills/archetype-finder/SKILL.md +3 -2
- package/departments/brand/skills/colors/SKILL.md +3 -2
- package/departments/brand/skills/design-system/SKILL.md +3 -2
- package/departments/brand/skills/identity-system/SKILL.md +3 -2
- package/departments/brand/skills/logo-brief/SKILL.md +3 -2
- package/departments/brand/skills/mockup-generate/SKILL.md +3 -2
- package/departments/brand/skills/naming-evaluate/SKILL.md +3 -2
- package/departments/brand/skills/positioning-statement/SKILL.md +3 -2
- package/departments/brand/skills/primal-audit/SKILL.md +3 -2
- package/departments/brand/skills/ux-audit/SKILL.md +3 -2
- package/departments/brand/skills/voice-guide/SKILL.md +3 -2
- package/departments/brand/skills/wireframe/SKILL.md +3 -2
- package/departments/community/SKILL.md +3 -2
- package/departments/community/skills/ai-community/SKILL.md +3 -2
- package/departments/community/skills/betting-setup/SKILL.md +3 -2
- package/departments/community/skills/business-model/SKILL.md +3 -2
- package/departments/community/skills/content-calendar/SKILL.md +3 -2
- package/departments/community/skills/events-plan/SKILL.md +3 -2
- package/departments/community/skills/gamification-design/SKILL.md +3 -2
- package/departments/community/skills/growth-plan/SKILL.md +3 -2
- package/departments/community/skills/metrics-track/SKILL.md +3 -2
- package/departments/community/skills/moderation/SKILL.md +3 -2
- package/departments/community/skills/monetize-plan/SKILL.md +3 -2
- package/departments/community/skills/niche-setup/SKILL.md +3 -2
- package/departments/community/skills/onboarding-flow/SKILL.md +3 -2
- package/departments/community/skills/platform-select/SKILL.md +3 -2
- package/departments/content/SKILL.md +3 -2
- package/departments/content/skills/ai-workflow/SKILL.md +3 -2
- package/departments/content/skills/analytics/SKILL.md +3 -2
- package/departments/content/skills/calendar/SKILL.md +3 -2
- package/departments/content/skills/content-system/SKILL.md +3 -2
- package/departments/content/skills/monetization-plan/SKILL.md +3 -2
- package/departments/content/skills/newsletter-write/SKILL.md +3 -2
- package/departments/content/skills/platform-optimize/SKILL.md +3 -2
- package/departments/content/skills/repurpose-plan/SKILL.md +3 -2
- package/departments/content/skills/research-compile/SKILL.md +3 -2
- package/departments/content/skills/script-structure/SKILL.md +3 -2
- package/departments/content/skills/short-form/SKILL.md +3 -2
- package/departments/content/skills/thumbnail-package/SKILL.md +3 -2
- package/departments/content/skills/trend-hunt/SKILL.md +3 -2
- package/departments/content/skills/video-produce/SKILL.md +3 -2
- package/departments/content/skills/video-setup/SKILL.md +3 -2
- package/departments/content/skills/viral-design/SKILL.md +3 -2
- package/departments/content/skills/youtube-strategy/SKILL.md +3 -2
- package/departments/dev/SKILL.md +3 -2
- package/departments/dev/skills/ai-assisted-dev/SKILL.md +3 -2
- package/departments/dev/skills/animated-website/SKILL.md +7 -0
- package/departments/dev/skills/architecture-design/SKILL.md +3 -2
- package/departments/dev/skills/code-review/SKILL.md +3 -2
- package/departments/dev/skills/db-design/SKILL.md +3 -2
- package/departments/dev/skills/ddd-model/SKILL.md +3 -2
- package/departments/dev/skills/demo-gif/SKILL.md +3 -2
- package/departments/dev/skills/deploy/SKILL.md +3 -2
- package/departments/dev/skills/devops-pipeline/SKILL.md +3 -2
- package/departments/dev/skills/docs/SKILL.md +3 -2
- package/departments/dev/skills/evaluator-build-loop/SKILL.md +93 -0
- package/departments/dev/skills/mcp/SKILL.md +3 -2
- package/departments/dev/skills/performance-audit/SKILL.md +3 -2
- package/departments/dev/skills/refactor-plan/SKILL.md +3 -2
- package/departments/dev/skills/research/SKILL.md +3 -2
- package/departments/dev/skills/security-compliance/SKILL.md +3 -2
- package/departments/dev/skills/spec-miner/SKILL.md +86 -0
- package/departments/dev/skills/stack-check/SKILL.md +3 -2
- package/departments/ecom/SKILL.md +3 -2
- package/departments/ecom/skills/analytics/SKILL.md +3 -2
- package/departments/ecom/skills/browse-competitor/SKILL.md +3 -2
- package/departments/ecom/skills/cart-recovery/SKILL.md +3 -2
- package/departments/ecom/skills/cro-optimize/SKILL.md +3 -2
- package/departments/ecom/skills/customer-journey/SKILL.md +3 -2
- package/departments/ecom/skills/fulfillment-plan/SKILL.md +3 -2
- package/departments/ecom/skills/marketplace-manage/SKILL.md +3 -2
- package/departments/ecom/skills/pricing-strategy/SKILL.md +3 -2
- package/departments/ecom/skills/product-launch/SKILL.md +3 -2
- package/departments/ecom/skills/rfm-segment/SKILL.md +3 -2
- package/departments/ecom/skills/social-commerce/SKILL.md +3 -2
- package/departments/ecom/skills/store-audit/SKILL.md +3 -2
- package/departments/ecom/skills/subscription-model/SKILL.md +3 -2
- package/departments/finance/SKILL.md +3 -2
- package/departments/finance/skills/budget-plan/SKILL.md +3 -2
- package/departments/finance/skills/cashflow-forecast/SKILL.md +3 -2
- package/departments/finance/skills/ciso-advisor/SKILL.md +3 -2
- package/departments/finance/skills/financial-model/SKILL.md +3 -2
- package/departments/finance/skills/pitch-deck/SKILL.md +3 -2
- package/departments/finance/skills/scenario-analysis/SKILL.md +3 -2
- package/departments/finance/skills/unit-economics/SKILL.md +3 -2
- package/departments/finance/skills/valuation-model/SKILL.md +3 -2
- package/departments/kb/SKILL.md +3 -2
- package/departments/kb/skills/ai-research/SKILL.md +3 -2
- package/departments/kb/skills/competitive-intel/SKILL.md +3 -2
- package/departments/kb/skills/doc-extraction/SKILL.md +3 -2
- package/departments/kb/skills/doc-redaction/SKILL.md +3 -2
- package/departments/kb/skills/knowledge-ops/SKILL.md +3 -2
- package/departments/kb/skills/knowledge-review/SKILL.md +3 -2
- package/departments/kb/skills/learn-content/SKILL.md +3 -2
- package/departments/kb/skills/moc-create/SKILL.md +3 -2
- package/departments/kb/skills/persona-build/SKILL.md +3 -2
- package/departments/kb/skills/research-plan/SKILL.md +3 -2
- package/departments/kb/skills/search-kb/SKILL.md +3 -2
- package/departments/kb/skills/source-evaluate/SKILL.md +3 -2
- package/departments/kb/skills/taxonomy-manage/SKILL.md +3 -2
- package/departments/kb/skills/write-as-persona/SKILL.md +3 -2
- package/departments/landing/SKILL.md +3 -2
- package/departments/landing/skills/ab-test/SKILL.md +3 -2
- package/departments/landing/skills/affiliate-bridge/SKILL.md +3 -2
- package/departments/landing/skills/awareness-diagnose/SKILL.md +3 -2
- package/departments/landing/skills/email-sequence/SKILL.md +3 -2
- package/departments/landing/skills/funnel-metrics/SKILL.md +3 -2
- package/departments/landing/skills/headline-write/SKILL.md +3 -2
- package/departments/landing/skills/launch-sequence/SKILL.md +3 -2
- package/departments/landing/skills/offer-create/SKILL.md +3 -2
- package/departments/landing/skills/optimize-page/SKILL.md +3 -2
- package/departments/landing/skills/page-architect/SKILL.md +3 -2
- package/departments/landing/skills/persuasion-apply/SKILL.md +3 -2
- package/departments/landing/skills/webinar-funnel/SKILL.md +3 -2
- package/departments/leadership/SKILL.md +3 -2
- package/departments/leadership/skills/change-manage/SKILL.md +3 -2
- package/departments/leadership/skills/conflict-resolve/SKILL.md +3 -2
- package/departments/leadership/skills/culture-audit/SKILL.md +3 -2
- package/departments/leadership/skills/delegation-matrix/SKILL.md +3 -2
- package/departments/leadership/skills/disc-assess/SKILL.md +3 -2
- package/departments/leadership/skills/feedback-give/SKILL.md +3 -2
- package/departments/leadership/skills/hiring-plan/SKILL.md +3 -2
- package/departments/leadership/skills/performance-review/SKILL.md +3 -2
- package/departments/marketing/SKILL.md +3 -2
- package/departments/marketing/skills/ab-test/SKILL.md +3 -2
- package/departments/marketing/skills/analytics-report/SKILL.md +3 -2
- package/departments/marketing/skills/audience-segment/SKILL.md +3 -2
- package/departments/marketing/skills/calendar-plan/SKILL.md +3 -2
- package/departments/marketing/skills/competitor-analysis/SKILL.md +3 -2
- package/departments/marketing/skills/content-audit/SKILL.md +3 -2
- package/departments/marketing/skills/email-sequence/SKILL.md +3 -2
- package/departments/marketing/skills/growth-loop/SKILL.md +3 -2
- package/departments/marketing/skills/marketing-automation/SKILL.md +3 -2
- package/departments/marketing/skills/paid-campaign/SKILL.md +3 -2
- package/departments/marketing/skills/programmatic-seo/SKILL.md +3 -2
- package/departments/marketing/skills/seo-audit/SKILL.md +3 -2
- package/departments/marketing/skills/social-strategy/SKILL.md +3 -2
- package/departments/ops/SKILL.md +3 -2
- package/departments/ops/skills/bottleneck-find/SKILL.md +3 -2
- package/departments/ops/skills/dashboard-build/SKILL.md +3 -2
- package/departments/ops/skills/gdpr-compliance/SKILL.md +3 -2
- package/departments/ops/skills/github-ops/SKILL.md +3 -2
- package/departments/ops/skills/gtd-setup/SKILL.md +3 -2
- package/departments/ops/skills/integration-design/SKILL.md +3 -2
- package/departments/ops/skills/iso27001/SKILL.md +3 -2
- package/departments/ops/skills/lean-audit/SKILL.md +3 -2
- package/departments/ops/skills/metrics-dashboard/SKILL.md +3 -2
- package/departments/ops/skills/n8n-flow/SKILL.md +3 -2
- package/departments/ops/skills/quality-management/SKILL.md +3 -2
- package/departments/ops/skills/risk-management/SKILL.md +3 -2
- package/departments/ops/skills/soc2-compliance/SKILL.md +3 -2
- package/departments/ops/skills/sop-create/SKILL.md +3 -2
- package/departments/ops/skills/terminal-ops/SKILL.md +3 -2
- package/departments/ops/skills/workflow-automate/SKILL.md +3 -2
- package/departments/ops/skills/zapier-flow/SKILL.md +3 -2
- package/departments/org/SKILL.md +3 -2
- package/departments/org/skills/compensation-plan/SKILL.md +3 -2
- package/departments/org/skills/culture-define/SKILL.md +3 -2
- package/departments/org/skills/decision-framework/SKILL.md +3 -2
- package/departments/org/skills/hiring-plan/SKILL.md +3 -2
- package/departments/org/skills/meeting-optimize/SKILL.md +3 -2
- package/departments/org/skills/onboarding-design/SKILL.md +3 -2
- package/departments/org/skills/org-design/SKILL.md +3 -2
- package/departments/org/skills/remote-setup/SKILL.md +3 -2
- package/departments/org/skills/sop-process/SKILL.md +3 -2
- package/departments/org/skills/team-assess/SKILL.md +3 -2
- package/departments/pm/SKILL.md +3 -2
- package/departments/pm/skills/backlog-groom/SKILL.md +3 -2
- package/departments/pm/skills/discovery-plan/SKILL.md +3 -2
- package/departments/pm/skills/estimate-forecast/SKILL.md +3 -2
- package/departments/pm/skills/impact-map/SKILL.md +3 -2
- package/departments/pm/skills/kanban-setup/SKILL.md +3 -2
- package/departments/pm/skills/risk-register/SKILL.md +3 -2
- package/departments/pm/skills/roadmap-build/SKILL.md +3 -2
- package/departments/pm/skills/sprint-plan/SKILL.md +3 -2
- package/departments/pm/skills/stakeholder-map/SKILL.md +3 -2
- package/departments/pm/skills/standup-run/SKILL.md +3 -2
- package/departments/pm/skills/story-write/SKILL.md +3 -2
- package/departments/saas/SKILL.md +3 -2
- package/departments/saas/skills/benchmark-compare/SKILL.md +3 -2
- package/departments/saas/skills/churn-analysis/SKILL.md +3 -2
- package/departments/saas/skills/customer-success/SKILL.md +3 -2
- package/departments/saas/skills/growth-plan/SKILL.md +3 -2
- package/departments/saas/skills/gtm-strategy/SKILL.md +3 -2
- package/departments/saas/skills/launch-execute/SKILL.md +3 -2
- package/departments/saas/skills/metrics-dashboard/SKILL.md +3 -2
- package/departments/saas/skills/micro-saas-stack/SKILL.md +3 -2
- package/departments/saas/skills/mvp-build/SKILL.md +3 -2
- package/departments/saas/skills/niche-evaluate/SKILL.md +3 -2
- package/departments/saas/skills/onboarding-optimize/SKILL.md +3 -2
- package/departments/saas/skills/plg-setup/SKILL.md +3 -2
- package/departments/saas/skills/pricing-strategy/SKILL.md +3 -2
- package/departments/saas/skills/validate-idea/SKILL.md +3 -2
- package/departments/sales/SKILL.md +3 -2
- package/departments/sales/skills/challenger-sell/SKILL.md +3 -2
- package/departments/sales/skills/deal-qualify/SKILL.md +3 -2
- package/departments/sales/skills/discovery-call/SKILL.md +3 -2
- package/departments/sales/skills/forecast-revenue/SKILL.md +3 -2
- package/departments/sales/skills/negotiate-plan/SKILL.md +3 -2
- package/departments/sales/skills/objection-handle/SKILL.md +3 -2
- package/departments/sales/skills/pipeline-manage/SKILL.md +3 -2
- package/departments/sales/skills/pricing-negotiate/SKILL.md +3 -2
- package/departments/strategy/SKILL.md +3 -2
- package/departments/strategy/skills/blue-ocean/SKILL.md +3 -2
- package/departments/strategy/skills/bmc/SKILL.md +3 -2
- package/departments/strategy/skills/board-advisor/SKILL.md +3 -2
- package/departments/strategy/skills/cto-advisor/SKILL.md +3 -2
- package/departments/strategy/skills/extract-data/SKILL.md +3 -2
- package/departments/strategy/skills/five-forces/SKILL.md +3 -2
- package/departments/strategy/skills/growth-strategy/SKILL.md +3 -2
- package/departments/strategy/skills/moat-analysis/SKILL.md +3 -2
- package/departments/strategy/skills/position/SKILL.md +3 -2
- package/departments/strategy/skills/scenario-plan/SKILL.md +3 -2
- package/installer/config-seed.js +81 -25
- package/installer/graphify.js +340 -0
- package/installer/index.js +8 -1
- package/installer/keys.js +18 -3
- package/installer/update.js +8 -1
- package/knowledge/skills-manifest.json +27 -1
- package/mcps/registry.json +9 -9
- package/mcps/scripts/apply-mcps.sh +6 -2
- package/package.json +2 -1
- package/pyproject.toml +1 -1
- package/scripts/dashboard-api.py +336 -124
- package/scripts/guide_gen.py +139 -0
- package/scripts/migrate_skills_kb_first.py +3 -2
- package/scripts/synapse-bridge.py +9 -1
package/core/synapse/kb_cache.py
CHANGED
|
@@ -20,6 +20,7 @@ Turn-scoped marker (record_obsidian_query / read_obsidian_query):
|
|
|
20
20
|
as core.workflow.marker_cache).
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
|
+
import contextlib
|
|
23
24
|
import hashlib
|
|
24
25
|
import json
|
|
25
26
|
import os
|
|
@@ -27,12 +28,11 @@ import threading
|
|
|
27
28
|
import time
|
|
28
29
|
import uuid
|
|
29
30
|
from pathlib import Path
|
|
30
|
-
from typing import Any
|
|
31
|
+
from typing import Any
|
|
31
32
|
|
|
32
33
|
from core.shared import safe_session_id as _safe_session_id_module
|
|
33
34
|
from core.shared.temp_paths import arkaos_temp_dir
|
|
34
35
|
|
|
35
|
-
|
|
36
36
|
# Re-export for backward compatibility with any external importers.
|
|
37
37
|
SAFE_SESSION_ID_RE = _safe_session_id_module.SAFE_SESSION_ID_RE
|
|
38
38
|
KB_QUERY_MARKER_DIR = arkaos_temp_dir("arkaos-kb-query")
|
|
@@ -147,8 +147,8 @@ class KBSessionCache:
|
|
|
147
147
|
def __init__(
|
|
148
148
|
self,
|
|
149
149
|
session_id: str,
|
|
150
|
-
project_path:
|
|
151
|
-
cache_dir:
|
|
150
|
+
project_path: str | None = None,
|
|
151
|
+
cache_dir: str | None = None,
|
|
152
152
|
max_entries: int = 150,
|
|
153
153
|
ttl_seconds: int = 5400,
|
|
154
154
|
) -> None:
|
|
@@ -278,8 +278,8 @@ class KBSessionCache:
|
|
|
278
278
|
|
|
279
279
|
def retrieve(
|
|
280
280
|
self,
|
|
281
|
-
query:
|
|
282
|
-
topics:
|
|
281
|
+
query: str | None = None,
|
|
282
|
+
topics: set[str] | None = None,
|
|
283
283
|
threshold: float = 0.3,
|
|
284
284
|
) -> list[dict]:
|
|
285
285
|
"""Retrieve cached knowledge by query or topic overlap.
|
|
@@ -433,11 +433,44 @@ def _kb_query_dir() -> Path:
|
|
|
433
433
|
return KB_QUERY_MARKER_DIR
|
|
434
434
|
|
|
435
435
|
|
|
436
|
-
def _kb_query_path(session_id: str) ->
|
|
436
|
+
def _kb_query_path(session_id: str, kind: str = "obsidian") -> Path | None:
|
|
437
|
+
"""Turn-scoped marker path for one KB source.
|
|
438
|
+
|
|
439
|
+
``kind`` separates the sources so a graphify consult cannot satisfy a
|
|
440
|
+
check that asked about Obsidian, or vice versa. "obsidian" keeps the
|
|
441
|
+
historical unsuffixed filename so existing records stay readable.
|
|
442
|
+
"""
|
|
437
443
|
safe = _safe_session_id_module.safe_session_id(session_id)
|
|
438
444
|
if safe is None:
|
|
439
445
|
return None
|
|
440
|
-
|
|
446
|
+
suffix = "" if kind == "obsidian" else f".{kind}"
|
|
447
|
+
return _kb_query_dir() / f"{safe}{suffix}.json"
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def record_graphify_query(session_id: str, query: str, hit_count: int = 0) -> None:
|
|
451
|
+
"""Record that a Graphify graph query ran in this turn.
|
|
452
|
+
|
|
453
|
+
Counterpart to :func:`record_obsidian_query`. Without it the ``[graph:``
|
|
454
|
+
citation marker is pure narration — anyone can type ``[graph: MadeUpNode]``
|
|
455
|
+
and earn credit (QG review). A consumer that wants evidence rather than a
|
|
456
|
+
claim should require :func:`graphify_queried_this_turn` alongside it.
|
|
457
|
+
"""
|
|
458
|
+
_record_query(session_id, query, hit_count, kind="graphify")
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def read_graphify_query(session_id: str) -> dict | None:
|
|
462
|
+
"""Return the turn-scoped Graphify-query record, or None if absent."""
|
|
463
|
+
return _read_query(session_id, kind="graphify")
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def graphify_queried_this_turn(session_id: str) -> bool:
|
|
467
|
+
"""True iff ``record_graphify_query`` was called since turn start."""
|
|
468
|
+
return read_graphify_query(session_id) is not None
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def invalidate_graphify_query(session_id: str) -> None:
|
|
472
|
+
"""Clear the per-turn Graphify consult marker. Idempotent."""
|
|
473
|
+
_invalidate_query(session_id, kind="graphify")
|
|
441
474
|
|
|
442
475
|
|
|
443
476
|
def record_obsidian_query(session_id: str, query: str, hit_count: int = 0) -> None:
|
|
@@ -455,7 +488,12 @@ def record_obsidian_query(session_id: str, query: str, hit_count: int = 0) -> No
|
|
|
455
488
|
query: The query string that was executed.
|
|
456
489
|
hit_count: Number of notes returned (0 means search ran but empty).
|
|
457
490
|
"""
|
|
458
|
-
|
|
491
|
+
_record_query(session_id, query, hit_count, kind="obsidian")
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def _record_query(session_id: str, query: str, hit_count: int, kind: str) -> None:
|
|
495
|
+
"""Shared writer for every KB source marker. Atomic tmp+rename."""
|
|
496
|
+
path = _kb_query_path(session_id, kind)
|
|
459
497
|
if path is None:
|
|
460
498
|
return
|
|
461
499
|
safe_query = (query or "")[:_MAX_QUERY_LEN]
|
|
@@ -464,7 +502,7 @@ def record_obsidian_query(session_id: str, query: str, hit_count: int = 0) -> No
|
|
|
464
502
|
except (TypeError, ValueError):
|
|
465
503
|
hits = 0
|
|
466
504
|
now = time.time()
|
|
467
|
-
existing =
|
|
505
|
+
existing = _read_query(session_id, kind) or {}
|
|
468
506
|
queries_raw = existing.get("queries")
|
|
469
507
|
queries = list(queries_raw) if isinstance(queries_raw, list) else []
|
|
470
508
|
queries.append({"query": safe_query, "hit_count": hits, "ts": now})
|
|
@@ -472,6 +510,7 @@ def record_obsidian_query(session_id: str, query: str, hit_count: int = 0) -> No
|
|
|
472
510
|
queries = queries[-_MAX_QUERIES_PER_TURN:]
|
|
473
511
|
record = {
|
|
474
512
|
"session_id": session_id,
|
|
513
|
+
"kind": kind,
|
|
475
514
|
"queries": queries,
|
|
476
515
|
"last_query_ts": now,
|
|
477
516
|
"last_hit_count": hits,
|
|
@@ -483,15 +522,18 @@ def record_obsidian_query(session_id: str, query: str, hit_count: int = 0) -> No
|
|
|
483
522
|
tmp.write_text(json.dumps(record), encoding="utf-8")
|
|
484
523
|
os.replace(tmp, path)
|
|
485
524
|
except OSError:
|
|
486
|
-
|
|
525
|
+
with contextlib.suppress(FileNotFoundError):
|
|
487
526
|
tmp.unlink()
|
|
488
|
-
except FileNotFoundError:
|
|
489
|
-
pass
|
|
490
527
|
|
|
491
528
|
|
|
492
|
-
def read_obsidian_query(session_id: str) ->
|
|
529
|
+
def read_obsidian_query(session_id: str) -> dict | None:
|
|
493
530
|
"""Return the turn-scoped Obsidian-query record, or None if absent."""
|
|
494
|
-
|
|
531
|
+
return _read_query(session_id, kind="obsidian")
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
def _read_query(session_id: str, kind: str) -> dict | None:
|
|
535
|
+
"""Shared reader for every KB source marker."""
|
|
536
|
+
path = _kb_query_path(session_id, kind)
|
|
495
537
|
if path is None or not path.exists():
|
|
496
538
|
return None
|
|
497
539
|
try:
|
|
@@ -510,7 +552,12 @@ def obsidian_queried_this_turn(session_id: str) -> bool:
|
|
|
510
552
|
|
|
511
553
|
def invalidate_obsidian_query(session_id: str) -> None:
|
|
512
554
|
"""Clear the per-turn KB consult marker. Idempotent."""
|
|
513
|
-
|
|
555
|
+
_invalidate_query(session_id, kind="obsidian")
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
def _invalidate_query(session_id: str, kind: str) -> None:
|
|
559
|
+
"""Shared invalidator for every KB source marker."""
|
|
560
|
+
path = _kb_query_path(session_id, kind)
|
|
514
561
|
if path is None:
|
|
515
562
|
return
|
|
516
563
|
try:
|
package/core/synapse/layers.py
CHANGED
|
@@ -28,20 +28,20 @@ from typing import Any
|
|
|
28
28
|
from core.synapse.layers_base import Layer, LayerResult, PromptContext
|
|
29
29
|
|
|
30
30
|
__all__ = [
|
|
31
|
-
"Layer",
|
|
32
|
-
"LayerResult",
|
|
33
|
-
"PromptContext",
|
|
34
|
-
"ConstitutionLayer",
|
|
35
|
-
"DepartmentLayer",
|
|
36
31
|
"AgentLayer",
|
|
37
|
-
"ProjectLayer",
|
|
38
32
|
"BranchLayer",
|
|
39
33
|
"CommandHintsLayer",
|
|
40
|
-
"
|
|
41
|
-
"
|
|
34
|
+
"ConstitutionLayer",
|
|
35
|
+
"DepartmentLayer",
|
|
42
36
|
"ForgeContextLayer",
|
|
43
|
-
"SessionContextLayer",
|
|
44
37
|
"KBContextLayer",
|
|
38
|
+
"KnowledgeRetrievalLayer",
|
|
39
|
+
"Layer",
|
|
40
|
+
"LayerResult",
|
|
41
|
+
"ProjectLayer",
|
|
42
|
+
"PromptContext",
|
|
43
|
+
"QualityGateLayer",
|
|
44
|
+
"SessionContextLayer",
|
|
45
45
|
]
|
|
46
46
|
|
|
47
47
|
|
|
@@ -90,22 +90,75 @@ class ConstitutionLayer(Layer):
|
|
|
90
90
|
# --- L1: Department Detection ---
|
|
91
91
|
|
|
92
92
|
DEPARTMENT_PATTERNS: dict[str, str] = {
|
|
93
|
-
"dev":
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
"dev": (
|
|
94
|
+
r"\b("
|
|
95
|
+
r"build|code|feature|deploy|test|review|scaffold|"
|
|
96
|
+
r"debug|refactor|api|migration|stack|implement|fix|"
|
|
97
|
+
r"bug)\b"
|
|
98
|
+
),
|
|
99
|
+
"marketing": (
|
|
100
|
+
r"\b("
|
|
101
|
+
r"social|content|campaign|post|instagram|linkedin|"
|
|
102
|
+
r"twitter|tiktok|seo|marketing|ads|email.?campaign|"
|
|
103
|
+
r"growth|viral)\b"
|
|
104
|
+
),
|
|
105
|
+
"finance": (
|
|
106
|
+
r"\b("
|
|
107
|
+
r"budget|invoice|revenue|forecast|profit|loss|roi|"
|
|
108
|
+
r"margin|cash.?flow|financial|invest|valuation|"
|
|
109
|
+
r"pricing)\b"
|
|
110
|
+
),
|
|
111
|
+
"ecom": (
|
|
112
|
+
r"\b("
|
|
113
|
+
r"store|product|shop|shopify|ecommerce|catalog|"
|
|
114
|
+
r"inventory|cart|checkout|pricing|marketplace)\b"
|
|
115
|
+
),
|
|
116
|
+
"strategy": (
|
|
117
|
+
r"\b("
|
|
118
|
+
r"strategy|brainstorm|market|swot|competitors?|"
|
|
119
|
+
r"roadmap|pivot|growth|porter|blue.?ocean|"
|
|
120
|
+
r"positioning)\b"
|
|
121
|
+
),
|
|
98
122
|
"ops": r"\b(task|automate|meeting|workflow|process|schedule|sop|integration|zapier|n8n)\b",
|
|
99
123
|
"kb": r"\b(learn|persona|knowledge|youtube|transcribe|article|research|zettelkasten|note)\b",
|
|
100
|
-
"brand":
|
|
124
|
+
"brand": (
|
|
125
|
+
r"\b("
|
|
126
|
+
r"brand|logo|colors|palette|mockup|photoshoot|brand.?identity|"
|
|
127
|
+
r"brand.?guide|mood.?board|naming|visual.?design|motion|ux|ui|"
|
|
128
|
+
r"wireframe)\b"
|
|
129
|
+
),
|
|
101
130
|
"saas": r"\b(saas|micro.?saas|plg|freemium|churn|mrr|arr|subscription|onboarding|metrics)\b",
|
|
102
|
-
"landing":
|
|
103
|
-
|
|
131
|
+
"landing": (
|
|
132
|
+
r"\b("
|
|
133
|
+
r"landing|funnel|copy|headline|offer|launch|"
|
|
134
|
+
r"affiliate|webinar|conversion|sales.?page)\b"
|
|
135
|
+
),
|
|
136
|
+
"community": (
|
|
137
|
+
r"\b("
|
|
138
|
+
r"community|group|membership|discord|"
|
|
139
|
+
r"telegram|skool|circle|gamification|"
|
|
140
|
+
r"engagement)\b"
|
|
141
|
+
),
|
|
104
142
|
"content": r"\b(viral|hook|script|repurpose|youtube|tiktok|reels|shorts|newsletter|creator)\b",
|
|
105
143
|
"pm": r"\b(sprint|backlog|standup|retro|scrum|kanban|story|estimate|roadmap|agile)\b",
|
|
106
|
-
"lead":
|
|
107
|
-
|
|
108
|
-
|
|
144
|
+
"lead": (
|
|
145
|
+
r"\b("
|
|
146
|
+
r"leadership|delegation|1on1|feedback|"
|
|
147
|
+
r"culture|hiring|performance.?review|"
|
|
148
|
+
r"team.?build)\b"
|
|
149
|
+
),
|
|
150
|
+
"sales": (
|
|
151
|
+
r"\b("
|
|
152
|
+
r"pipeline|proposal|discovery.?call|objection|negotiate|"
|
|
153
|
+
r"deal|close|prospect|spin|challenger|cold.?email|"
|
|
154
|
+
r"outreach)\b"
|
|
155
|
+
),
|
|
156
|
+
"org": (
|
|
157
|
+
r"\b("
|
|
158
|
+
r"org.?design|hiring.?plan|onboarding|remote|"
|
|
159
|
+
r"meeting.?optimize|compensation|"
|
|
160
|
+
r"decision.?framework)\b"
|
|
161
|
+
),
|
|
109
162
|
}
|
|
110
163
|
|
|
111
164
|
|
|
@@ -317,10 +370,7 @@ class BranchLayer(Layer):
|
|
|
317
370
|
start = time.time()
|
|
318
371
|
branch = ctx.git_branch
|
|
319
372
|
# Hide main/master/dev branches
|
|
320
|
-
if branch in ("main", "master", "dev", ""):
|
|
321
|
-
tag = ""
|
|
322
|
-
else:
|
|
323
|
-
tag = f"[branch:{branch}]"
|
|
373
|
+
tag = "" if branch in ("main", "master", "dev", "") else f"[branch:{branch}]"
|
|
324
374
|
|
|
325
375
|
ms = int((time.time() - start) * 1000)
|
|
326
376
|
return LayerResult(
|
|
@@ -427,7 +477,7 @@ class QualityGateLayer(Layer):
|
|
|
427
477
|
def compute(self, ctx: PromptContext) -> LayerResult:
|
|
428
478
|
start = time.time()
|
|
429
479
|
try:
|
|
430
|
-
from core.governance.quality_api import
|
|
480
|
+
from core.governance.quality_api import list_approved, list_pending
|
|
431
481
|
|
|
432
482
|
pending = list_pending()
|
|
433
483
|
approved = list_approved(limit=3)
|
|
@@ -496,6 +546,17 @@ class KnowledgeRetrievalLayer(Layer):
|
|
|
496
546
|
def cache_ttl(self) -> int:
|
|
497
547
|
return 30
|
|
498
548
|
|
|
549
|
+
@property
|
|
550
|
+
def emits_block(self) -> bool:
|
|
551
|
+
"""The retrieved chunks are a real block, not the tag's value.
|
|
552
|
+
|
|
553
|
+
`[knowledge:N chunks]` makes a QUANTIFIED claim about content the
|
|
554
|
+
model never received before the content channel existed — the
|
|
555
|
+
loudest unbacked claim in the tag line (QG review). Opting in
|
|
556
|
+
delivers what the tag advertises.
|
|
557
|
+
"""
|
|
558
|
+
return True
|
|
559
|
+
|
|
499
560
|
@property
|
|
500
561
|
def priority(self) -> int:
|
|
501
562
|
return 35
|
|
@@ -580,7 +641,10 @@ class KnowledgeRetrievalLayer(Layer):
|
|
|
580
641
|
parts.append(f"[cached] {src}: {text}" if src else f"[cached] {text}")
|
|
581
642
|
parts.extend(snippets)
|
|
582
643
|
|
|
583
|
-
content
|
|
644
|
+
# Self-naming, because the content channel delivers this verbatim to
|
|
645
|
+
# the model: an unlabelled `[cached] file.md: …` fragment would read
|
|
646
|
+
# as stray text (the exact defect the opt-in channel exists to avoid).
|
|
647
|
+
content = f"[arka:knowledge] {' | '.join(parts)}" if parts else ""
|
|
584
648
|
chunk_count = len(snippets) + (len(overlapping) if overlapping else 0)
|
|
585
649
|
# RAG honesty (PR-3 v4.1): keyword-degraded results must never be
|
|
586
650
|
# presented as semantic similarity — label the tag explicitly.
|
|
@@ -639,7 +703,7 @@ class ForgeContextLayer(Layer):
|
|
|
639
703
|
parts = [f"Forge plan: {plan.id} ({plan.status.value})"]
|
|
640
704
|
if plan.critic.confidence > 0:
|
|
641
705
|
decisions = []
|
|
642
|
-
for
|
|
706
|
+
for _source, elements in plan.critic.synthesis.items():
|
|
643
707
|
decisions.extend(elements)
|
|
644
708
|
if decisions:
|
|
645
709
|
parts.append(f"Decisions: {'; '.join(decisions[:5])}")
|
|
@@ -701,7 +765,6 @@ class SessionContextLayer(Layer):
|
|
|
701
765
|
layer_id=self.id, tag="", content="", tokens_est=0, compute_ms=0, cached=False
|
|
702
766
|
)
|
|
703
767
|
|
|
704
|
-
lines = content.split("\n")
|
|
705
768
|
tag = "[session:resume]"
|
|
706
769
|
tokens = len(content.split())
|
|
707
770
|
|
|
@@ -720,6 +783,8 @@ class SessionContextLayer(Layer):
|
|
|
720
783
|
# `core.synapse.layers` import paths and helper references keep working.
|
|
721
784
|
|
|
722
785
|
from core.synapse.layers_kb import ( # noqa: E402,F401
|
|
786
|
+
_KB_CONFIG_PATH,
|
|
787
|
+
_MAX_FALLBACK_NOTES,
|
|
723
788
|
KBContextLayer,
|
|
724
789
|
_apply_grounding_policy,
|
|
725
790
|
_build_note_entry,
|
|
@@ -732,10 +797,8 @@ from core.synapse.layers_kb import ( # noqa: E402,F401
|
|
|
732
797
|
_hit_is_inferred,
|
|
733
798
|
_jaccard,
|
|
734
799
|
_jaccard_fallback,
|
|
735
|
-
_KB_CONFIG_PATH,
|
|
736
800
|
_l25_feature_flag_on,
|
|
737
801
|
_load_fallback_notes,
|
|
738
|
-
_MAX_FALLBACK_NOTES,
|
|
739
802
|
_note_from_vector_hit,
|
|
740
803
|
_tokenize_for_jaccard,
|
|
741
804
|
_vector_search,
|
|
@@ -69,6 +69,22 @@ class Layer(ABC):
|
|
|
69
69
|
"""
|
|
70
70
|
return False
|
|
71
71
|
|
|
72
|
+
@property
|
|
73
|
+
def emits_block(self) -> bool:
|
|
74
|
+
"""True when ``content`` is a self-describing full-text block.
|
|
75
|
+
|
|
76
|
+
OPT-IN, and deliberately so. The engine forwards ``content`` to the
|
|
77
|
+
model only for layers that declare this. Inferring it from
|
|
78
|
+
``content != tag`` looked equivalent and was not: most layers set
|
|
79
|
+
``content`` to their tag's VALUE (``dev``, ``active``,
|
|
80
|
+
``feat/plan-canvas``), so every prompt gained stray unlabeled lines
|
|
81
|
+
carrying nothing the tag had not already said (QG review).
|
|
82
|
+
|
|
83
|
+
A block must stand alone: it names itself (``[arka:kb-context]``,
|
|
84
|
+
``[arka:graph-remote unverified]``) and is meaningful without the tag.
|
|
85
|
+
"""
|
|
86
|
+
return False
|
|
87
|
+
|
|
72
88
|
@property
|
|
73
89
|
def session_sensitive(self) -> bool:
|
|
74
90
|
"""True when compute() has per-session side effects or output.
|