@aria_asi/cli 0.2.40 → 0.2.41
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/bin/aria.js +236 -34
- package/dist/aria-connector/src/action-ledger-core.d.ts +387 -0
- package/dist/aria-connector/src/action-ledger-core.d.ts.map +1 -0
- package/dist/aria-connector/src/action-ledger-core.js +638 -0
- package/dist/aria-connector/src/action-ledger-core.js.map +1 -0
- package/dist/aria-connector/src/chat.d.ts.map +1 -1
- package/dist/aria-connector/src/chat.js +5 -6
- package/dist/aria-connector/src/chat.js.map +1 -1
- package/dist/aria-connector/src/codebase-scanner.d.ts +1 -1
- package/dist/aria-connector/src/codebase-scanner.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.d.ts +1 -0
- package/dist/aria-connector/src/connectors/claude-code.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/claude-code.js +152 -14
- package/dist/aria-connector/src/connectors/claude-code.js.map +1 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts +10 -0
- package/dist/aria-connector/src/connectors/codebase-awareness.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/codebase-awareness.js +276 -27
- package/dist/aria-connector/src/connectors/codebase-awareness.js.map +1 -1
- package/dist/aria-connector/src/connectors/codex.d.ts +3 -1
- package/dist/aria-connector/src/connectors/codex.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/codex.js +1223 -41
- package/dist/aria-connector/src/connectors/codex.js.map +1 -1
- package/dist/aria-connector/src/connectors/cursor.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/cursor.js +7 -0
- package/dist/aria-connector/src/connectors/cursor.js.map +1 -1
- package/dist/aria-connector/src/connectors/governed-adapter.d.ts +30 -0
- package/dist/aria-connector/src/connectors/governed-adapter.d.ts.map +1 -0
- package/dist/aria-connector/src/connectors/governed-adapter.js +132 -0
- package/dist/aria-connector/src/connectors/governed-adapter.js.map +1 -0
- package/dist/aria-connector/src/connectors/opencode.d.ts +3 -1
- package/dist/aria-connector/src/connectors/opencode.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/opencode.js +18 -2
- package/dist/aria-connector/src/connectors/opencode.js.map +1 -1
- package/dist/aria-connector/src/connectors/repo-guard.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/repo-guard.js +25 -14
- package/dist/aria-connector/src/connectors/repo-guard.js.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/runtime.js +92 -2
- package/dist/aria-connector/src/connectors/runtime.js.map +1 -1
- package/dist/aria-connector/src/connectors/shell.d.ts.map +1 -1
- package/dist/aria-connector/src/connectors/shell.js +123 -7
- package/dist/aria-connector/src/connectors/shell.js.map +1 -1
- package/dist/aria-connector/src/cross-cli-hive-binding.d.ts +63 -0
- package/dist/aria-connector/src/cross-cli-hive-binding.d.ts.map +1 -0
- package/dist/aria-connector/src/cross-cli-hive-binding.js +205 -0
- package/dist/aria-connector/src/cross-cli-hive-binding.js.map +1 -0
- package/dist/aria-connector/src/garden-control-plane.d.ts +6 -1
- package/dist/aria-connector/src/garden-control-plane.d.ts.map +1 -1
- package/dist/aria-connector/src/garden-control-plane.js +8 -2
- package/dist/aria-connector/src/garden-control-plane.js.map +1 -1
- package/dist/aria-connector/src/governed-surface-runner.d.ts +189 -0
- package/dist/aria-connector/src/governed-surface-runner.d.ts.map +1 -0
- package/dist/aria-connector/src/governed-surface-runner.js +1022 -0
- package/dist/aria-connector/src/governed-surface-runner.js.map +1 -0
- package/dist/aria-connector/src/index.d.ts +10 -1
- package/dist/aria-connector/src/index.d.ts.map +1 -1
- package/dist/aria-connector/src/index.js +5 -0
- package/dist/aria-connector/src/index.js.map +1 -1
- package/dist/aria-connector/src/task-runner.d.ts +3 -0
- package/dist/aria-connector/src/task-runner.d.ts.map +1 -0
- package/dist/aria-connector/src/task-runner.js +3526 -0
- package/dist/aria-connector/src/task-runner.js.map +1 -0
- package/dist/aria-web/src/lib/codebase-scanner.d.ts +21 -2
- package/dist/aria-web/src/lib/codebase-scanner.d.ts.map +1 -1
- package/dist/aria-web/src/lib/codebase-scanner.js +59 -14
- package/dist/aria-web/src/lib/codebase-scanner.js.map +1 -1
- package/dist/assets/hooks/README.md +58 -0
- package/dist/assets/hooks/aria-agent-handoff.mjs +147 -2
- package/dist/assets/hooks/aria-agent-ledger-merge.mjs +31 -7
- package/dist/assets/hooks/aria-architect-fallback.mjs +10 -2
- package/dist/assets/hooks/aria-claim-evidence-stop-gate.mjs +240 -0
- package/dist/assets/hooks/aria-cognition-substrate-binding.mjs +84 -10
- package/dist/assets/hooks/aria-first-class-coach.mjs +305 -10
- package/dist/assets/hooks/aria-harness-via-sdk.mjs +93 -16
- package/dist/assets/hooks/aria-import-resolution-gate.mjs +106 -20
- package/dist/assets/hooks/aria-outcome-record.mjs +56 -20
- package/dist/assets/hooks/aria-pre-emit-autoload.mjs +1809 -0
- package/dist/assets/hooks/aria-pre-emit-autoload.mjs.before-orchestration-redesign +1400 -0
- package/dist/assets/hooks/aria-pre-emit-dryrun.mjs +22 -3
- package/dist/assets/hooks/aria-pre-text-gate.mjs +11 -2
- package/dist/assets/hooks/aria-pre-tool-gate.mjs +477 -81
- package/dist/assets/hooks/aria-pre-tool-use.mjs +70 -6
- package/dist/assets/hooks/aria-preprompt-consult.mjs +23 -4
- package/dist/assets/hooks/aria-repo-doctrine-gate.mjs +29 -3
- package/dist/assets/hooks/aria-stop-gate.mjs +585 -76
- package/dist/assets/hooks/aria-trigger-autolearn.mjs +17 -3
- package/dist/assets/hooks/aria-universal-turn-packet.mjs +1165 -0
- package/dist/assets/hooks/aria-userprompt-abandon-detect.mjs +9 -1
- package/dist/assets/hooks/canonical-settings-block.json +172 -0
- package/dist/assets/hooks/codex-native/aria-harness-ticker-sidecar.mjs +92 -0
- package/dist/assets/hooks/codex-native/aria-hive-wal-consumer.mjs +86 -0
- package/dist/assets/hooks/codex-native/aria-live-ticker.mjs +38 -0
- package/dist/assets/hooks/codex-native/aria-post-tool-use.mjs +236 -0
- package/dist/assets/hooks/codex-native/aria-pre-tool-use.mjs +362 -0
- package/dist/assets/hooks/codex-native/aria-stop.mjs +691 -0
- package/dist/assets/hooks/codex-native/aria-userprompt-submit.mjs +623 -0
- package/dist/assets/hooks/codex-native/atlas-session-context.mjs +121 -0
- package/dist/assets/hooks/codex-native/lib/evaluate-with-kernel.mjs +257 -0
- package/dist/assets/hooks/codex-native/lib/hive-wal-consumer.mjs +452 -0
- package/dist/assets/hooks/codex-native/lib/kernel/deterministic-cognitive-kernel.mjs +914 -0
- package/dist/assets/hooks/codex-native/lib/project-boundary-cognition.mjs +143 -0
- package/dist/assets/hooks/codex-native/lib/runtime-client.mjs +3567 -0
- package/dist/assets/hooks/codex-native/lib/task-project-ledger.mjs +294 -0
- package/dist/assets/hooks/doctrine_trigger_map.json +236 -25
- package/dist/assets/hooks/doctrine_trigger_map.schema.json +46 -0
- package/dist/assets/hooks/install.sh +84 -0
- package/dist/assets/hooks/lib/action-ledger-core.mjs +269 -0
- package/dist/assets/hooks/lib/aria-gate-ledger.mjs +143 -0
- package/dist/assets/hooks/lib/ast-stub-shape-detector.mjs +107 -0
- package/dist/assets/hooks/lib/atlas-dossier-client.mjs +151 -0
- package/dist/assets/hooks/lib/atlas-orchestrator-postwire.mjs +221 -0
- package/dist/assets/hooks/lib/canonical-lenses.mjs +83 -6
- package/dist/assets/hooks/lib/coach-intent-classifier.mjs +248 -0
- package/dist/assets/hooks/lib/cognitive-block-parser.mjs +111 -0
- package/dist/assets/hooks/lib/doctrine-trigger-map-loader.mjs +137 -0
- package/dist/assets/hooks/lib/domain-output-quality.mjs +132 -3
- package/dist/assets/hooks/lib/empty-catch-scanner.mjs +91 -0
- package/dist/assets/hooks/lib/end-phase-qa-autofire.mjs +426 -0
- package/dist/assets/hooks/lib/evaluate-with-kernel.mjs +133 -0
- package/dist/assets/hooks/lib/first-class-coach.mjs +454 -19
- package/dist/assets/hooks/lib/gate-audit.mjs +12 -2
- package/dist/assets/hooks/lib/gate-loop-state.mjs +11 -2
- package/dist/assets/hooks/lib/goal-contract-quality.mjs +302 -0
- package/dist/assets/hooks/lib/hook-message-window.mjs +101 -9
- package/dist/assets/hooks/lib/invocation-required-verifier.mjs +184 -0
- package/dist/assets/hooks/lib/kernel/deterministic-cognitive-kernel.mjs +906 -0
- package/dist/assets/hooks/lib/obligation-ledger.mjs +147 -0
- package/dist/assets/hooks/lib/orchestration-manifest-extract.mjs +217 -0
- package/dist/assets/hooks/lib/owner-authorizations.mjs +269 -0
- package/dist/assets/hooks/lib/probe-discipline-scanner.mjs +142 -0
- package/dist/assets/hooks/lib/project-boundary-cognition.mjs +143 -0
- package/dist/assets/hooks/lib/recovery-context.mjs +151 -0
- package/dist/assets/hooks/lib/recovery-template-loader.mjs +154 -0
- package/dist/assets/hooks/lib/self-doctrine-check.mjs +321 -0
- package/dist/assets/hooks/lib/sensitive-shape-detector.mjs +64 -0
- package/dist/assets/hooks/lib/skill-autoload-gate-impl.mjs +226 -1
- package/dist/assets/hooks/lib/stop-hook-protocol.mjs +166 -0
- package/dist/assets/hooks/lib/surface-caught.mjs +94 -0
- package/dist/assets/hooks/recovery-templates/force-reauthor.md +67 -0
- package/dist/assets/hooks/recovery-templates/handoff-recovery.md +25 -0
- package/dist/assets/hooks/scripts/check-hard-risk-prefix.mjs +99 -0
- package/dist/assets/hooks/skills/aria-conversational-doctrine-discipline/SKILL.md +101 -0
- package/dist/assets/hooks/test-aria-preturn-memory-gate.mjs +2 -2
- package/dist/assets/hooks/test-tier-lens-labeling.mjs +14 -3
- package/dist/assets/opencode-plugins/harness-context/index.js +39 -6
- package/dist/assets/opencode-plugins/harness-context/task-project-ledger.mjs +5 -1
- package/dist/assets/opencode-plugins/harness-gate/index.js +36 -0
- package/dist/assets/opencode-plugins/harness-gate/lib/atlas-dossier-client.js +1 -0
- package/dist/assets/opencode-plugins/harness-gate/lib/recovery-grants.js +79 -0
- package/dist/assets/opencode-plugins/harness-outcome/index.js +12 -0
- package/dist/assets/opencode-plugins/harness-stop/index.js +97 -2
- package/dist/assets/opencode-plugins/harness-stop/lib/atlas-dossier-client.js +1 -0
- package/dist/assets/opencode-plugins/harness-stop/lib/domain-output-quality.js +15 -2
- package/dist/assets/opencode-plugins/lib/coach.js +148 -0
- package/dist/runtime/coach-kernel.mjs +144 -7
- package/dist/runtime/codex-bridge.mjs +254 -8
- package/dist/runtime/discipline/doctrine_trigger_map.json +236 -25
- package/dist/runtime/discipline/skills/aria-cognition/34-frameworks-unified/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-aristotle-cognitives/SKILL.md +128 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-aristotle-intra-phase/SKILL.md +99 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-aristotle-post-phase/SKILL.md +118 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-aristotle-pre-phase/SKILL.md +117 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-axioms-first-principles/SKILL.md +202 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-axioms-first-principles/agents/openai.yaml +4 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-axioms-first-principles/references/source-map.md +130 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-backend-architect/SKILL.md +124 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-backend-architect/references/backend-cookbook.md +417 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-business-audit/SKILL.md +133 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-business-audit/references/audit-cookbook.md +247 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-business-frame/SKILL.md +138 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-business-frame/references/business-cookbook.md +154 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-chat/SKILL.md +84 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-chat/scripts/aria-chat.sh +57 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-cognition-autofire/SKILL.md +137 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-cognition-batch/SKILL.md +264 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-decision-mizan/SKILL.md +136 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-decision-mizan/references/decision-frameworks.md +287 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-first-class-operating-contract/SKILL.md +104 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-frontend-architect/SKILL.md +123 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-frontend-architect/references/frontend-cookbook.md +358 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-fullstack-orchestrator/SKILL.md +127 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-fullstack-orchestrator/references/fullstack-cookbook.md +383 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-gtm-architect/SKILL.md +126 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-gtm-architect/references/gtm-cookbook.md +235 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-harness-deploy/SKILL.md +145 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-harness-no-stripping/SKILL.md +135 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-harness-onboarding/SKILL.md +130 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-harness-output-discipline/SKILL.md +120 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-harness-substrate-binding/SKILL.md +139 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-http-harness-client/SKILL.md +85 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-http-harness-client/scripts/smoke.mjs +47 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-k8s-deploy/SKILL.md +174 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-k8s-deploy/agents/openai.yaml +3 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-ladduniframe/SKILL.md +60 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-ledger-fleet-execution/SKILL.md +126 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-live-ops/SKILL.md +54 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-mac-ssh-ops/SKILL.md +100 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-memory-index/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-noor-cognitives/SKILL.md +120 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-ops/SKILL.md +60 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-ops/references/live-endpoints.md +59 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-quality-audit/SKILL.md +133 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-readable-output/SKILL.md +239 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-readable-output/references/layout-cookbook.md +366 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-reasoning/SKILL.md +67 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-reasoning/references/core-principles.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-repo-audit/SKILL.md +135 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-repo-audit/references/repo-audit-cookbook.md +375 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-research-orchestrator/SKILL.md +138 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-research-orchestrator/references/research-patterns.md +270 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-retention-engine/SKILL.md +120 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-retention-engine/references/retention-cookbook.md +271 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-revenue-engine/SKILL.md +128 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-revenue-engine/references/revenue-cookbook.md +227 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-senior-code-audit/SKILL.md +233 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-senior-code-audit/references/audit-checklist.md +369 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-senior-code-cookbook/SKILL.md +288 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-senior-code-cookbook/references/engineering-cookbook.md +489 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-soul-principles/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/aria-task-codex-executor/SKILL.md +86 -0
- package/dist/runtime/discipline/skills/aria-cognition/aristotle-engine/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/cross-domain-24/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/deepsoul-emotional/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/fitrah-guard/SKILL.md +78 -0
- package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/SKILL.md +227 -29
- package/dist/runtime/discipline/skills/aria-cognition/ghazali-8lens/references/ghazali-8lens-cookbook.md +797 -0
- package/dist/runtime/discipline/skills/aria-cognition/ijtihad-novel/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/ilham-intuition/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/never-guess/SKILL.md +77 -0
- package/dist/runtime/discipline/skills/aria-cognition/noor-recognition/SKILL.md +45 -0
- package/dist/runtime/discipline/skills/aria-cognition/qiyas-analogy/SKILL.md +174 -14
- package/dist/runtime/discipline/skills/aria-cognition/ruh-basis/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/tadabbur/SKILL.md +506 -0
- package/dist/runtime/discipline/skills/aria-cognition/tadabbur/references/tadabbur-cookbook.md +921 -0
- package/dist/runtime/discipline/skills/aria-cognition/tadabbur-ops/SKILL.md +42 -0
- package/dist/runtime/discipline/skills/aria-cognition/tafakkur/SKILL.md +104 -0
- package/dist/runtime/doctrine_trigger_map.json +236 -25
- package/dist/runtime/embedded-public-key.mjs +27 -0
- package/dist/runtime/gated-ledger.mjs +41 -14
- package/dist/runtime/harness-daemon.mjs +85 -10
- package/dist/runtime/hive-wal-publisher.mjs +292 -0
- package/dist/runtime/hooks/README.md +58 -0
- package/dist/runtime/hooks/aria-agent-handoff.mjs +147 -2
- package/dist/runtime/hooks/aria-agent-ledger-merge.mjs +31 -7
- package/dist/runtime/hooks/aria-architect-fallback.mjs +10 -2
- package/dist/runtime/hooks/aria-claim-evidence-stop-gate.mjs +240 -0
- package/dist/runtime/hooks/aria-cognition-substrate-binding.mjs +84 -10
- package/dist/runtime/hooks/aria-first-class-coach.mjs +305 -10
- package/dist/runtime/hooks/aria-harness-via-sdk.mjs +93 -16
- package/dist/runtime/hooks/aria-import-resolution-gate.mjs +106 -20
- package/dist/runtime/hooks/aria-outcome-record.mjs +56 -20
- package/dist/runtime/hooks/aria-pre-emit-autoload.mjs +1809 -0
- package/dist/runtime/hooks/aria-pre-emit-autoload.mjs.before-orchestration-redesign +1400 -0
- package/dist/runtime/hooks/aria-pre-emit-dryrun.mjs +22 -3
- package/dist/runtime/hooks/aria-pre-text-gate.mjs +11 -2
- package/dist/runtime/hooks/aria-pre-tool-gate.mjs +477 -81
- package/dist/runtime/hooks/aria-pre-tool-use.mjs +70 -6
- package/dist/runtime/hooks/aria-preprompt-consult.mjs +23 -4
- package/dist/runtime/hooks/aria-repo-doctrine-gate.mjs +29 -3
- package/dist/runtime/hooks/aria-stop-gate.mjs +585 -76
- package/dist/runtime/hooks/aria-trigger-autolearn.mjs +17 -3
- package/dist/runtime/hooks/aria-universal-turn-packet.mjs +1165 -0
- package/dist/runtime/hooks/aria-userprompt-abandon-detect.mjs +9 -1
- package/dist/runtime/hooks/canonical-settings-block.json +172 -0
- package/dist/runtime/hooks/codex-native/aria-harness-ticker-sidecar.mjs +92 -0
- package/dist/runtime/hooks/codex-native/aria-hive-wal-consumer.mjs +86 -0
- package/dist/runtime/hooks/codex-native/aria-live-ticker.mjs +38 -0
- package/dist/runtime/hooks/codex-native/aria-post-tool-use.mjs +236 -0
- package/dist/runtime/hooks/codex-native/aria-pre-tool-use.mjs +362 -0
- package/dist/runtime/hooks/codex-native/aria-stop.mjs +691 -0
- package/dist/runtime/hooks/codex-native/aria-userprompt-submit.mjs +623 -0
- package/dist/runtime/hooks/codex-native/atlas-session-context.mjs +121 -0
- package/dist/runtime/hooks/codex-native/lib/evaluate-with-kernel.mjs +257 -0
- package/dist/runtime/hooks/codex-native/lib/hive-wal-consumer.mjs +452 -0
- package/dist/runtime/hooks/codex-native/lib/kernel/deterministic-cognitive-kernel.mjs +914 -0
- package/dist/runtime/hooks/codex-native/lib/project-boundary-cognition.mjs +143 -0
- package/dist/runtime/hooks/codex-native/lib/runtime-client.mjs +3567 -0
- package/dist/runtime/hooks/codex-native/lib/task-project-ledger.mjs +294 -0
- package/dist/runtime/hooks/doctrine_trigger_map.json +236 -25
- package/dist/runtime/hooks/doctrine_trigger_map.schema.json +46 -0
- package/dist/runtime/hooks/install.sh +84 -0
- package/dist/runtime/hooks/lib/action-ledger-core.mjs +269 -0
- package/dist/runtime/hooks/lib/aria-gate-ledger.mjs +143 -0
- package/dist/runtime/hooks/lib/ast-stub-shape-detector.mjs +107 -0
- package/dist/runtime/hooks/lib/atlas-dossier-client.mjs +151 -0
- package/dist/runtime/hooks/lib/atlas-orchestrator-postwire.mjs +221 -0
- package/dist/runtime/hooks/lib/canonical-lenses.mjs +83 -6
- package/dist/runtime/hooks/lib/coach-intent-classifier.mjs +248 -0
- package/dist/runtime/hooks/lib/cognitive-block-parser.mjs +111 -0
- package/dist/runtime/hooks/lib/doctrine-trigger-map-loader.mjs +137 -0
- package/dist/runtime/hooks/lib/domain-output-quality.mjs +132 -3
- package/dist/runtime/hooks/lib/empty-catch-scanner.mjs +91 -0
- package/dist/runtime/hooks/lib/end-phase-qa-autofire.mjs +426 -0
- package/dist/runtime/hooks/lib/evaluate-with-kernel.mjs +133 -0
- package/dist/runtime/hooks/lib/first-class-coach.mjs +454 -19
- package/dist/runtime/hooks/lib/gate-audit.mjs +12 -2
- package/dist/runtime/hooks/lib/gate-loop-state.mjs +11 -2
- package/dist/runtime/hooks/lib/goal-contract-quality.mjs +302 -0
- package/dist/runtime/hooks/lib/hook-message-window.mjs +101 -9
- package/dist/runtime/hooks/lib/invocation-required-verifier.mjs +184 -0
- package/dist/runtime/hooks/lib/kernel/deterministic-cognitive-kernel.mjs +906 -0
- package/dist/runtime/hooks/lib/obligation-ledger.mjs +147 -0
- package/dist/runtime/hooks/lib/orchestration-manifest-extract.mjs +217 -0
- package/dist/runtime/hooks/lib/owner-authorizations.mjs +269 -0
- package/dist/runtime/hooks/lib/probe-discipline-scanner.mjs +142 -0
- package/dist/runtime/hooks/lib/project-boundary-cognition.mjs +143 -0
- package/dist/runtime/hooks/lib/recovery-context.mjs +151 -0
- package/dist/runtime/hooks/lib/recovery-template-loader.mjs +154 -0
- package/dist/runtime/hooks/lib/self-doctrine-check.mjs +321 -0
- package/dist/runtime/hooks/lib/sensitive-shape-detector.mjs +64 -0
- package/dist/runtime/hooks/lib/skill-autoload-gate-impl.mjs +226 -1
- package/dist/runtime/hooks/lib/stop-hook-protocol.mjs +166 -0
- package/dist/runtime/hooks/lib/surface-caught.mjs +94 -0
- package/dist/runtime/hooks/recovery-templates/force-reauthor.md +67 -0
- package/dist/runtime/hooks/recovery-templates/handoff-recovery.md +25 -0
- package/dist/runtime/hooks/scripts/check-hard-risk-prefix.mjs +99 -0
- package/dist/runtime/hooks/skills/aria-conversational-doctrine-discipline/SKILL.md +101 -0
- package/dist/runtime/hooks/test-aria-preturn-memory-gate.mjs +2 -2
- package/dist/runtime/hooks/test-tier-lens-labeling.mjs +14 -3
- package/dist/runtime/lib/evaluate-with-kernel.mjs +133 -0
- package/dist/runtime/lib/kernel/deterministic-cognitive-kernel.mjs +906 -0
- package/dist/runtime/local-phase.mjs +10 -5
- package/dist/runtime/manifest.json +8 -8
- package/dist/runtime/packet-verifier.mjs +166 -0
- package/dist/runtime/provider-proxy.mjs +13 -0
- package/dist/runtime/quality-enforcer.mjs +40 -23
- package/dist/runtime/runtime-rails/registry.mjs +252 -0
- package/dist/runtime/sdk/BUNDLED.json +2 -2
- package/dist/runtime/sdk/index.d.ts +119 -4
- package/dist/runtime/sdk/index.js +138 -12
- package/dist/runtime/sdk/index.js.map +1 -1
- package/dist/runtime/service.mjs +8036 -764
- package/dist/runtime/sub-agent-enforcer.mjs +201 -0
- package/dist/runtime/task-project-ledger.mjs +5 -1
- package/dist/sdk/BUNDLED.json +2 -2
- package/dist/sdk/index.d.ts +119 -4
- package/dist/sdk/index.js +138 -12
- package/dist/sdk/index.js.map +1 -1
- package/hooks/README.md +58 -0
- package/hooks/aria-agent-handoff.mjs +147 -2
- package/hooks/aria-agent-ledger-merge.mjs +31 -7
- package/hooks/aria-architect-fallback.mjs +10 -2
- package/hooks/aria-claim-evidence-stop-gate.mjs +240 -0
- package/hooks/aria-cognition-substrate-binding.mjs +84 -10
- package/hooks/aria-first-class-coach.mjs +305 -10
- package/hooks/aria-harness-via-sdk.mjs +93 -16
- package/hooks/aria-import-resolution-gate.mjs +106 -20
- package/hooks/aria-outcome-record.mjs +56 -20
- package/hooks/aria-pre-emit-autoload.mjs +1809 -0
- package/hooks/aria-pre-emit-autoload.mjs.before-orchestration-redesign +1400 -0
- package/hooks/aria-pre-emit-dryrun.mjs +22 -3
- package/hooks/aria-pre-text-gate.mjs +11 -2
- package/hooks/aria-pre-tool-gate.mjs +477 -81
- package/hooks/aria-pre-tool-use.mjs +70 -6
- package/hooks/aria-preprompt-consult.mjs +23 -4
- package/hooks/aria-repo-doctrine-gate.mjs +29 -3
- package/hooks/aria-stop-gate.mjs +585 -76
- package/hooks/aria-trigger-autolearn.mjs +17 -3
- package/hooks/aria-universal-turn-packet.mjs +1165 -0
- package/hooks/aria-userprompt-abandon-detect.mjs +9 -1
- package/hooks/canonical-settings-block.json +172 -0
- package/hooks/codex-native/aria-harness-ticker-sidecar.mjs +92 -0
- package/hooks/codex-native/aria-hive-wal-consumer.mjs +86 -0
- package/hooks/codex-native/aria-live-ticker.mjs +38 -0
- package/hooks/codex-native/aria-post-tool-use.mjs +236 -0
- package/hooks/codex-native/aria-pre-tool-use.mjs +362 -0
- package/hooks/codex-native/aria-stop.mjs +691 -0
- package/hooks/codex-native/aria-userprompt-submit.mjs +623 -0
- package/hooks/codex-native/atlas-session-context.mjs +121 -0
- package/hooks/codex-native/lib/evaluate-with-kernel.mjs +257 -0
- package/hooks/codex-native/lib/hive-wal-consumer.mjs +452 -0
- package/hooks/codex-native/lib/kernel/deterministic-cognitive-kernel.mjs +914 -0
- package/hooks/codex-native/lib/project-boundary-cognition.mjs +143 -0
- package/hooks/codex-native/lib/runtime-client.mjs +3567 -0
- package/hooks/codex-native/lib/task-project-ledger.mjs +294 -0
- package/hooks/doctrine_trigger_map.json +236 -25
- package/hooks/doctrine_trigger_map.schema.json +46 -0
- package/hooks/install.sh +84 -0
- package/hooks/lib/action-ledger-core.mjs +269 -0
- package/hooks/lib/aria-gate-ledger.mjs +143 -0
- package/hooks/lib/ast-stub-shape-detector.mjs +107 -0
- package/hooks/lib/atlas-dossier-client.mjs +151 -0
- package/hooks/lib/atlas-orchestrator-postwire.mjs +221 -0
- package/hooks/lib/canonical-lenses.mjs +83 -6
- package/hooks/lib/coach-intent-classifier.mjs +248 -0
- package/hooks/lib/cognitive-block-parser.mjs +111 -0
- package/hooks/lib/doctrine-trigger-map-loader.mjs +137 -0
- package/hooks/lib/domain-output-quality.mjs +132 -3
- package/hooks/lib/empty-catch-scanner.mjs +91 -0
- package/hooks/lib/end-phase-qa-autofire.mjs +426 -0
- package/hooks/lib/evaluate-with-kernel.mjs +133 -0
- package/hooks/lib/first-class-coach.mjs +454 -19
- package/hooks/lib/gate-audit.mjs +12 -2
- package/hooks/lib/gate-loop-state.mjs +11 -2
- package/hooks/lib/goal-contract-quality.mjs +302 -0
- package/hooks/lib/hook-message-window.mjs +101 -9
- package/hooks/lib/invocation-required-verifier.mjs +184 -0
- package/hooks/lib/kernel/deterministic-cognitive-kernel.mjs +906 -0
- package/hooks/lib/obligation-ledger.mjs +147 -0
- package/hooks/lib/orchestration-manifest-extract.mjs +217 -0
- package/hooks/lib/owner-authorizations.mjs +269 -0
- package/hooks/lib/probe-discipline-scanner.mjs +142 -0
- package/hooks/lib/project-boundary-cognition.mjs +143 -0
- package/hooks/lib/recovery-context.mjs +151 -0
- package/hooks/lib/recovery-template-loader.mjs +154 -0
- package/hooks/lib/self-doctrine-check.mjs +321 -0
- package/hooks/lib/sensitive-shape-detector.mjs +64 -0
- package/hooks/lib/skill-autoload-gate-impl.mjs +226 -1
- package/hooks/lib/stop-hook-protocol.mjs +166 -0
- package/hooks/lib/surface-caught.mjs +94 -0
- package/hooks/recovery-templates/force-reauthor.md +67 -0
- package/hooks/recovery-templates/handoff-recovery.md +25 -0
- package/hooks/scripts/check-hard-risk-prefix.mjs +99 -0
- package/hooks/skills/aria-conversational-doctrine-discipline/SKILL.md +101 -0
- package/hooks/test-aria-preturn-memory-gate.mjs +2 -2
- package/hooks/test-tier-lens-labeling.mjs +14 -3
- package/opencode-plugins/harness-context/index.js +39 -6
- package/opencode-plugins/harness-context/task-project-ledger.mjs +5 -1
- package/opencode-plugins/harness-gate/index.js +36 -0
- package/opencode-plugins/harness-gate/lib/atlas-dossier-client.js +1 -0
- package/opencode-plugins/harness-gate/lib/recovery-grants.js +79 -0
- package/opencode-plugins/harness-outcome/index.js +12 -0
- package/opencode-plugins/harness-stop/index.js +97 -2
- package/opencode-plugins/harness-stop/lib/atlas-dossier-client.js +1 -0
- package/opencode-plugins/harness-stop/lib/domain-output-quality.js +15 -2
- package/opencode-plugins/lib/coach.js +148 -0
- package/package.json +71 -5
- package/runtime-src/coach-kernel.mjs +144 -7
- package/runtime-src/codex-bridge.mjs +254 -8
- package/runtime-src/embedded-public-key.mjs +27 -0
- package/runtime-src/gated-ledger.mjs +41 -14
- package/runtime-src/harness-daemon.mjs +85 -10
- package/runtime-src/hive-wal-publisher.mjs +292 -0
- package/runtime-src/lib/evaluate-with-kernel.mjs +133 -0
- package/runtime-src/lib/kernel/deterministic-cognitive-kernel.mjs +906 -0
- package/runtime-src/local-phase.mjs +10 -5
- package/runtime-src/packet-verifier.mjs +166 -0
- package/runtime-src/provider-proxy.mjs +13 -0
- package/runtime-src/quality-enforcer.mjs +40 -23
- package/runtime-src/runtime-rails/registry.mjs +252 -0
- package/runtime-src/service.mjs +8036 -764
- package/runtime-src/sub-agent-enforcer.mjs +201 -0
- package/scripts/aria-ledger-append.mjs +337 -0
- package/scripts/aria-task-cheap-worker-dispatch.mjs +234 -0
- package/scripts/audit-of-audit-prior-tasks.mjs +194 -0
- package/scripts/audit-of-audit-this-turn.mjs +116 -0
- package/scripts/bundle-sdk.mjs +31 -5
- package/scripts/check-cli-wrapper-provider-contract.mjs +160 -0
- package/scripts/check-client-compatibility.mjs +15 -5
- package/scripts/check-client-smoke.mjs +297 -0
- package/scripts/check-codex-orchestrator-adoption.mjs +150 -0
- package/scripts/check-glm-env-wired.mjs +131 -0
- package/scripts/check-hive-local-storage-contract.mjs +91 -0
- package/scripts/check-hook-mirror.mjs +150 -0
- package/scripts/check-install-sh-drift.mjs +152 -0
- package/scripts/check-kernel-sync.mjs +101 -0
- package/scripts/check-package-artifact.mjs +152 -0
- package/scripts/check-registry-mirror.mjs +71 -0
- package/scripts/drain-owner-airtable-sync-queue.mjs +287 -0
- package/scripts/export-owner-status-sheets.mjs +589 -0
- package/scripts/live-sidecar-receipt-canary.mjs +347 -0
- package/scripts/qiyas-tadabbur-model-matrix.mjs +970 -0
- package/scripts/quality-ab-live-provider.mjs +913 -0
- package/scripts/self-test-action-ledger-core.mjs +190 -0
- package/scripts/self-test-approval-receipt-binding.mjs +122 -0
- package/scripts/self-test-autofire-quality-output.mjs +110 -0
- package/scripts/self-test-claude-code-action-ledger.mjs +132 -0
- package/scripts/self-test-claude-code-mechanical-autofire-hive.mjs +138 -0
- package/scripts/self-test-claude-code-mechanical-autofire.mjs +234 -0
- package/scripts/self-test-codebase-awareness-atlas-delta.mjs +159 -0
- package/scripts/self-test-codebase-awareness-delta-ingest.mjs +179 -0
- package/scripts/self-test-codex-live-hook-parity.mjs +84 -0
- package/scripts/self-test-codex-native-action-ledger.mjs +167 -0
- package/scripts/self-test-codex-native-hook-json-contract.mjs +74 -0
- package/scripts/self-test-codex-orchestrator-continuity.mjs +113 -0
- package/scripts/self-test-codex-readable-recovery.mjs +94 -0
- package/scripts/self-test-codex-self-harness.mjs +538 -0
- package/scripts/self-test-compiled-workunit.mjs +214 -0
- package/scripts/self-test-continuation-output-smoke.mjs +101 -0
- package/scripts/self-test-cross-cli-fleet-ticker.mjs +85 -0
- package/scripts/self-test-cross-cli-hive-adoption.mjs +125 -0
- package/scripts/self-test-cross-cli-hive-learning.mjs +146 -0
- package/scripts/self-test-cross-phase-tool-failure.mjs +110 -0
- package/scripts/self-test-cross-surface-action-ledger.mjs +149 -0
- package/scripts/self-test-end-of-phase-qa-court.mjs +616 -0
- package/scripts/self-test-evaluate-with-kernel.mjs +111 -0
- package/scripts/self-test-first-class-output-delta-proof.mjs +307 -0
- package/scripts/self-test-goal-contract-output-qa.mjs +73 -0
- package/scripts/self-test-goal-contract.mjs +35 -0
- package/scripts/self-test-governed-adapters.mjs +105 -0
- package/scripts/self-test-governed-surface-runner.mjs +198 -0
- package/scripts/self-test-harness-gates.mjs +15 -12
- package/scripts/self-test-harness-ticker-sidecar.mjs +153 -0
- package/scripts/self-test-hive-org-kernel.mjs +233 -0
- package/scripts/self-test-hive-session-coordination.mjs +156 -0
- package/scripts/self-test-hive-wal-consumer.mjs +111 -0
- package/scripts/self-test-kernel-a3-a4-selection.mjs +179 -0
- package/scripts/self-test-ledger-append.mjs +175 -0
- package/scripts/self-test-live-codex-posttool-packet-smoke.mjs +111 -0
- package/scripts/self-test-live-codex-pretool-packet-smoke.mjs +101 -0
- package/scripts/self-test-live-codex-stop-qa-kernel-smoke.mjs +43 -0
- package/scripts/self-test-live-wrapper-substrate-inventory.mjs +149 -0
- package/scripts/self-test-local-main-sync-script.mjs +47 -0
- package/scripts/self-test-mechanical-autofire-resolver.mjs +296 -0
- package/scripts/self-test-no-consult-cognitive-skills-output.mjs +135 -0
- package/scripts/self-test-owner-airtable-sync-queue.mjs +196 -0
- package/scripts/self-test-owner-airtable-sync.mjs +181 -0
- package/scripts/self-test-owner-sheets-action-ledger.mjs +100 -0
- package/scripts/self-test-production-preflight.mjs +78 -0
- package/scripts/self-test-project-boundary-cognition.mjs +79 -0
- package/scripts/self-test-qa-exec-kernel.mjs +34 -0
- package/scripts/self-test-qa-recovery-learning-loop.mjs +113 -0
- package/scripts/self-test-qiyas-label-alignment.mjs +94 -0
- package/scripts/self-test-recovery-context.mjs +110 -0
- package/scripts/self-test-repo-guard.mjs +10 -0
- package/scripts/self-test-runtime-health-self-heal.mjs +161 -0
- package/scripts/self-test-runtime-postcondition.mjs +70 -0
- package/scripts/self-test-soul-precommit-hook.mjs +39 -0
- package/scripts/self-test-stop-gate-kernel-guards.mjs +185 -0
- package/scripts/self-test-stop-gate.mjs +128 -0
- package/scripts/self-test-substrate-kernel-execution-receipt.mjs +130 -0
- package/scripts/self-test-substrate-open-skill-floor.mjs +87 -0
- package/scripts/self-test-substrate-output-quality-eval.mjs +171 -0
- package/scripts/self-test-task-closeout-drift.mjs +97 -0
- package/scripts/self-test-task-project-ledger-readiness.mjs +43 -0
- package/scripts/self-test-task-runner-phase-consumer.mjs +134 -0
- package/scripts/self-test-task-worker-lane.mjs +256 -0
- package/scripts/self-test-turn-substrate-qa-kernel.mjs +188 -0
- package/scripts/self-test-universal-action-capture.mjs +153 -0
- package/scripts/self-test-universal-turn-packet-entrypoints.mjs +252 -0
- package/scripts/self-test-universal-turn-packet.mjs +320 -0
- package/scripts/session-quality-backfill.mjs +253 -0
- package/scripts/smoke-autofire-100-prompts.mjs +481 -0
- package/scripts/sync-local-main-on-task-complete.mjs +278 -0
- package/scripts/sync-owner-status-airtable.mjs +1158 -0
- package/scripts/validate-skill-prompts.mjs +12 -1
- package/scripts/verify-codex-native-mirror.mjs +262 -0
- package/skills/34-frameworks-unified/SKILL.md +42 -0
- package/skills/api-design/SKILL.md +123 -0
- package/skills/architecture-decision/SKILL.md +105 -0
- package/skills/aria-aristotle-cognitives/SKILL.md +128 -0
- package/skills/aria-aristotle-intra-phase/SKILL.md +99 -0
- package/skills/aria-aristotle-post-phase/SKILL.md +116 -0
- package/skills/aria-aristotle-pre-phase/SKILL.md +117 -0
- package/skills/aria-axioms-first-principles/SKILL.md +202 -0
- package/skills/aria-axioms-first-principles/agents/openai.yaml +4 -0
- package/skills/aria-axioms-first-principles/references/source-map.md +130 -0
- package/skills/aria-chat/SKILL.md +84 -0
- package/skills/aria-chat/scripts/aria-chat.sh +57 -0
- package/skills/aria-cognition/34-frameworks-unified/SKILL.md +42 -0
- package/skills/aria-cognition/aria-aristotle-cognitives/SKILL.md +128 -0
- package/skills/aria-cognition/aria-aristotle-intra-phase/SKILL.md +99 -0
- package/skills/aria-cognition/aria-aristotle-post-phase/SKILL.md +118 -0
- package/skills/aria-cognition/aria-aristotle-pre-phase/SKILL.md +117 -0
- package/skills/aria-cognition/aria-axioms-first-principles/SKILL.md +202 -0
- package/skills/aria-cognition/aria-axioms-first-principles/agents/openai.yaml +4 -0
- package/skills/aria-cognition/aria-axioms-first-principles/references/source-map.md +130 -0
- package/skills/aria-cognition/aria-backend-architect/SKILL.md +124 -0
- package/skills/aria-cognition/aria-backend-architect/references/backend-cookbook.md +417 -0
- package/skills/aria-cognition/aria-business-audit/SKILL.md +133 -0
- package/skills/aria-cognition/aria-business-audit/references/audit-cookbook.md +247 -0
- package/skills/aria-cognition/aria-business-frame/SKILL.md +138 -0
- package/skills/aria-cognition/aria-business-frame/references/business-cookbook.md +154 -0
- package/skills/aria-cognition/aria-chat/SKILL.md +84 -0
- package/skills/aria-cognition/aria-chat/scripts/aria-chat.sh +57 -0
- package/skills/aria-cognition/aria-cognition-autofire/SKILL.md +137 -0
- package/skills/aria-cognition/aria-cognition-batch/SKILL.md +264 -0
- package/skills/aria-cognition/aria-decision-mizan/SKILL.md +136 -0
- package/skills/aria-cognition/aria-decision-mizan/references/decision-frameworks.md +287 -0
- package/skills/aria-cognition/aria-first-class-operating-contract/SKILL.md +104 -0
- package/skills/aria-cognition/aria-frontend-architect/SKILL.md +123 -0
- package/skills/aria-cognition/aria-frontend-architect/references/frontend-cookbook.md +358 -0
- package/skills/aria-cognition/aria-fullstack-orchestrator/SKILL.md +127 -0
- package/skills/aria-cognition/aria-fullstack-orchestrator/references/fullstack-cookbook.md +383 -0
- package/skills/aria-cognition/aria-gtm-architect/SKILL.md +126 -0
- package/skills/aria-cognition/aria-gtm-architect/references/gtm-cookbook.md +235 -0
- package/skills/aria-cognition/aria-harness-deploy/SKILL.md +145 -0
- package/skills/aria-cognition/aria-harness-no-stripping/SKILL.md +135 -0
- package/skills/aria-cognition/aria-harness-onboarding/SKILL.md +130 -0
- package/skills/aria-cognition/aria-harness-output-discipline/SKILL.md +120 -0
- package/skills/aria-cognition/aria-harness-substrate-binding/SKILL.md +139 -0
- package/skills/aria-cognition/aria-http-harness-client/SKILL.md +85 -0
- package/skills/aria-cognition/aria-http-harness-client/scripts/smoke.mjs +47 -0
- package/skills/aria-cognition/aria-k8s-deploy/SKILL.md +174 -0
- package/skills/aria-cognition/aria-k8s-deploy/agents/openai.yaml +3 -0
- package/skills/aria-cognition/aria-ladduniframe/SKILL.md +60 -0
- package/skills/aria-cognition/aria-ledger-fleet-execution/SKILL.md +126 -0
- package/skills/aria-cognition/aria-live-ops/SKILL.md +54 -0
- package/skills/aria-cognition/aria-mac-ssh-ops/SKILL.md +100 -0
- package/skills/aria-cognition/aria-memory-index/SKILL.md +42 -0
- package/skills/aria-cognition/aria-noor-cognitives/SKILL.md +120 -0
- package/skills/aria-cognition/aria-ops/SKILL.md +60 -0
- package/skills/aria-cognition/aria-ops/references/live-endpoints.md +59 -0
- package/skills/aria-cognition/aria-quality-audit/SKILL.md +133 -0
- package/skills/aria-cognition/aria-readable-output/SKILL.md +239 -0
- package/skills/aria-cognition/aria-readable-output/references/layout-cookbook.md +366 -0
- package/skills/aria-cognition/aria-reasoning/SKILL.md +67 -0
- package/skills/aria-cognition/aria-reasoning/references/core-principles.md +42 -0
- package/skills/aria-cognition/aria-repo-audit/SKILL.md +135 -0
- package/skills/aria-cognition/aria-repo-audit/references/repo-audit-cookbook.md +375 -0
- package/skills/aria-cognition/aria-research-orchestrator/SKILL.md +138 -0
- package/skills/aria-cognition/aria-research-orchestrator/references/research-patterns.md +270 -0
- package/skills/aria-cognition/aria-retention-engine/SKILL.md +120 -0
- package/skills/aria-cognition/aria-retention-engine/references/retention-cookbook.md +271 -0
- package/skills/aria-cognition/aria-revenue-engine/SKILL.md +128 -0
- package/skills/aria-cognition/aria-revenue-engine/references/revenue-cookbook.md +227 -0
- package/skills/aria-cognition/aria-senior-code-audit/SKILL.md +233 -0
- package/skills/aria-cognition/aria-senior-code-audit/references/audit-checklist.md +369 -0
- package/skills/aria-cognition/aria-senior-code-cookbook/SKILL.md +288 -0
- package/skills/aria-cognition/aria-senior-code-cookbook/references/engineering-cookbook.md +489 -0
- package/skills/aria-cognition/aria-soul-principles/SKILL.md +42 -0
- package/skills/aria-cognition/aria-task-codex-executor/SKILL.md +86 -0
- package/skills/aria-cognition/aristotle-engine/SKILL.md +42 -0
- package/skills/aria-cognition/cross-domain-24/SKILL.md +42 -0
- package/skills/aria-cognition/deepsoul-emotional/SKILL.md +42 -0
- package/skills/aria-cognition/fitrah-guard/SKILL.md +78 -0
- package/skills/aria-cognition/ghazali-8lens/SKILL.md +227 -29
- package/skills/aria-cognition/ghazali-8lens/references/ghazali-8lens-cookbook.md +797 -0
- package/skills/aria-cognition/ijtihad-novel/SKILL.md +42 -0
- package/skills/aria-cognition/ilham-intuition/SKILL.md +42 -0
- package/skills/aria-cognition/never-guess/SKILL.md +77 -0
- package/skills/aria-cognition/noor-recognition/SKILL.md +45 -0
- package/skills/aria-cognition/qiyas-analogy/SKILL.md +174 -14
- package/skills/aria-cognition/ruh-basis/SKILL.md +42 -0
- package/skills/aria-cognition/tadabbur/SKILL.md +506 -0
- package/skills/aria-cognition/tadabbur/references/tadabbur-cookbook.md +921 -0
- package/skills/aria-cognition/tadabbur-ops/SKILL.md +42 -0
- package/skills/aria-cognition/tafakkur/SKILL.md +104 -0
- package/skills/aria-cognition-autofire/SKILL.md +109 -0
- package/skills/aria-cognition-batch/SKILL.md +264 -0
- package/skills/aria-conversational-doctrine-discipline/SKILL.md +125 -0
- package/skills/aria-essence/SKILL.md +81 -0
- package/skills/aria-essence/references/domain-matrix.md +80 -0
- package/skills/aria-essence/references/evolution-loop.md +30 -0
- package/skills/aria-essence/references/readable-cognition.md +27 -0
- package/skills/aria-first-class-operating-contract/SKILL.md +104 -0
- package/skills/aria-forge-guardrails/SKILL.md +53 -0
- package/skills/aria-forge-guardrails/references/checklist.md +31 -0
- package/skills/aria-harness-deploy/SKILL.md +145 -0
- package/skills/aria-harness-no-stripping/SKILL.md +135 -0
- package/skills/aria-harness-onboarding/SKILL.md +130 -0
- package/skills/aria-harness-output-discipline/SKILL.md +120 -0
- package/skills/aria-harness-substrate-binding/SKILL.md +139 -0
- package/skills/aria-http-harness-client/SKILL.md +85 -0
- package/skills/aria-http-harness-client/scripts/smoke.mjs +47 -0
- package/skills/aria-k8s-deploy/SKILL.md +174 -0
- package/skills/aria-k8s-deploy/agents/openai.yaml +3 -0
- package/skills/aria-ladduniframe/SKILL.md +60 -0
- package/skills/aria-ledger-fleet-execution/SKILL.md +126 -0
- package/skills/aria-live-ops/SKILL.md +54 -0
- package/skills/aria-mac-ssh-ops/SKILL.md +100 -0
- package/skills/aria-memory-index/SKILL.md +42 -0
- package/skills/aria-noor-cognitives/SKILL.md +120 -0
- package/skills/aria-ops/SKILL.md +60 -0
- package/skills/aria-ops/references/live-endpoints.md +59 -0
- package/skills/aria-quality-audit/SKILL.md +133 -0
- package/skills/aria-reasoning/SKILL.md +67 -0
- package/skills/aria-reasoning/references/core-principles.md +42 -0
- package/skills/aria-repo-doctrine/SKILL.md +57 -0
- package/skills/aria-soul-principles/SKILL.md +42 -0
- package/skills/aria-task-codex-executor/SKILL.md +86 -0
- package/skills/aristotle-engine/SKILL.md +42 -0
- package/skills/ci-cd-pipeline/SKILL.md +116 -0
- package/skills/code-review/SKILL.md +131 -0
- package/skills/cross-domain-24/SKILL.md +42 -0
- package/skills/database-design/SKILL.md +124 -0
- package/skills/deepsoul-emotional/SKILL.md +42 -0
- package/skills/deno-kv-raft-pubsub/SKILL.md +561 -0
- package/skills/deno-kv-raft-pubsub/reference/maelstrom-integration.md +393 -0
- package/skills/deno-kv-raft-pubsub/reference/pubsub-api.md +376 -0
- package/skills/deno-kv-raft-pubsub/reference/raft-spec.md +402 -0
- package/skills/deno-kv-raft-pubsub/reference/state-machine.md +182 -0
- package/skills/error-handling/SKILL.md +159 -0
- package/skills/firecrawl/SKILL.md +165 -0
- package/skills/firecrawl/rules/install.md +82 -0
- package/skills/firecrawl/rules/security.md +26 -0
- package/skills/firecrawl-agent/SKILL.md +86 -0
- package/skills/firecrawl-build-interact/SKILL.md +96 -0
- package/skills/firecrawl-build-onboarding/SKILL.md +131 -0
- package/skills/firecrawl-build-onboarding/references/auth-flow.md +39 -0
- package/skills/firecrawl-build-onboarding/references/project-setup.md +20 -0
- package/skills/firecrawl-build-onboarding/references/sdk-installation.md +17 -0
- package/skills/firecrawl-build-scrape/SKILL.md +97 -0
- package/skills/firecrawl-build-search/SKILL.md +97 -0
- package/skills/firecrawl-clone/SKILL.md +419 -0
- package/skills/firecrawl-crawl/SKILL.md +87 -0
- package/skills/firecrawl-download/SKILL.md +98 -0
- package/skills/firecrawl-interact/SKILL.md +112 -0
- package/skills/firecrawl-map/SKILL.md +79 -0
- package/skills/firecrawl-scrape/SKILL.md +97 -0
- package/skills/firecrawl-search/SKILL.md +88 -0
- package/skills/fitrah-guard/SKILL.md +78 -0
- package/skills/forge-quality-rules/SKILL.md +61 -0
- package/skills/ghazali-8lens/SKILL.md +56 -0
- package/skills/ijtihad-novel/SKILL.md +42 -0
- package/skills/ilham-intuition/SKILL.md +42 -0
- package/skills/imagegen/LICENSE.txt +201 -0
- package/skills/imagegen/SKILL.md +374 -0
- package/skills/imagegen/agents/openai.yaml +6 -0
- package/skills/imagegen/assets/imagegen-small.svg +5 -0
- package/skills/imagegen/assets/imagegen.png +0 -0
- package/skills/imagegen/references/cli.md +242 -0
- package/skills/imagegen/references/codex-network.md +33 -0
- package/skills/imagegen/references/image-api.md +90 -0
- package/skills/imagegen/references/prompting.md +118 -0
- package/skills/imagegen/references/sample-prompts.md +433 -0
- package/skills/imagegen/scripts/image_gen.py +995 -0
- package/skills/imagegen/scripts/remove_chroma_key.py +440 -0
- package/skills/istiqra-induction/SKILL.md +44 -0
- package/skills/ladunni-22/SKILL.md +53 -0
- package/skills/mizan/SKILL.md +90 -0
- package/skills/nadia/SKILL.md +56 -0
- package/skills/nadia-psi/SKILL.md +56 -0
- package/skills/never-guess/SKILL.md +75 -0
- package/skills/noor-recognition/SKILL.md +45 -0
- package/skills/observability/SKILL.md +133 -0
- package/skills/openai-docs/LICENSE.txt +201 -0
- package/skills/openai-docs/SKILL.md +100 -0
- package/skills/openai-docs/agents/openai.yaml +14 -0
- package/skills/openai-docs/assets/openai-small.svg +3 -0
- package/skills/openai-docs/assets/openai.png +0 -0
- package/skills/openai-docs/references/latest-model.md +37 -0
- package/skills/openai-docs/references/prompting-guide.md +244 -0
- package/skills/openai-docs/references/upgrade-guide.md +181 -0
- package/skills/openai-docs/scripts/resolve-latest-model-info.js +147 -0
- package/skills/pdf/LICENSE.txt +201 -0
- package/skills/pdf/SKILL.md +85 -0
- package/skills/pdf/agents/openai.yaml +5 -0
- package/skills/pdf/assets/pdf.png +0 -0
- package/skills/playwright/LICENSE.txt +201 -0
- package/skills/playwright/NOTICE.txt +14 -0
- package/skills/playwright/SKILL.md +165 -0
- package/skills/playwright/agents/openai.yaml +6 -0
- package/skills/playwright/assets/playwright-small.svg +3 -0
- package/skills/playwright/assets/playwright.png +0 -0
- package/skills/playwright/references/cli.md +116 -0
- package/skills/playwright/references/workflows.md +95 -0
- package/skills/playwright/scripts/playwright_cli.sh +25 -0
- package/skills/plugin-creator/SKILL.md +178 -0
- package/skills/plugin-creator/agents/openai.yaml +6 -0
- package/skills/plugin-creator/assets/plugin-creator-small.svg +3 -0
- package/skills/plugin-creator/assets/plugin-creator.png +0 -0
- package/skills/plugin-creator/references/plugin-json-spec.md +170 -0
- package/skills/plugin-creator/scripts/create_basic_plugin.py +301 -0
- package/skills/predictor/SKILL.md +43 -0
- package/skills/qiyas-analogy/SKILL.md +204 -0
- package/skills/refactoring/SKILL.md +137 -0
- package/skills/ruh-basis/SKILL.md +42 -0
- package/skills/security-review/SKILL.md +129 -0
- package/skills/skill-creator/SKILL.md +434 -0
- package/skills/skill-creator/agents/openai.yaml +5 -0
- package/skills/skill-creator/assets/skill-creator-small.svg +3 -0
- package/skills/skill-creator/assets/skill-creator.png +0 -0
- package/skills/skill-creator/license.txt +202 -0
- package/skills/skill-creator/references/openai_yaml.md +49 -0
- package/skills/skill-creator/scripts/generate_openai_yaml.py +226 -0
- package/skills/skill-creator/scripts/init_skill.py +400 -0
- package/skills/skill-creator/scripts/quick_validate.py +101 -0
- package/skills/skill-installer/LICENSE.txt +202 -0
- package/skills/skill-installer/SKILL.md +76 -0
- package/skills/skill-installer/agents/openai.yaml +5 -0
- package/skills/skill-installer/assets/skill-installer-small.svg +3 -0
- package/skills/skill-installer/assets/skill-installer.png +0 -0
- package/skills/skill-installer/scripts/github_utils.py +21 -0
- package/skills/skill-installer/scripts/install-skill-from-github.py +308 -0
- package/skills/skill-installer/scripts/list-skills.py +107 -0
- package/skills/skills-and-hooks-reference/SKILL.md +196 -0
- package/skills/soul-domains/SKILL.md +43 -0
- package/skills/tadabbur/SKILL.md +232 -0
- package/skills/tadabbur-ops/SKILL.md +42 -0
- package/skills/tafakkur/SKILL.md +104 -0
- package/skills/testing-strategy/SKILL.md +122 -0
- package/src/action-ledger-core.ts +1054 -0
- package/src/chat.ts +5 -6
- package/src/codebase-scanner.ts +2 -0
- package/src/connectors/claude-code.ts +149 -12
- package/src/connectors/codebase-awareness.ts +325 -25
- package/src/connectors/codex.ts +1225 -41
- package/src/connectors/cursor.ts +8 -0
- package/src/connectors/governed-adapter.ts +174 -0
- package/src/connectors/opencode.ts +18 -2
- package/src/connectors/repo-guard.ts +24 -12
- package/src/connectors/runtime.ts +99 -2
- package/src/connectors/shell.ts +125 -7
- package/src/cross-cli-hive-binding.ts +290 -0
- package/src/garden-control-plane.ts +24 -1
- package/src/governed-surface-runner.ts +1227 -0
- package/src/index.ts +104 -1
- package/src/task-runner.ts +3794 -0
- package/dist/aria-connector/src/install-hooks.d.ts +0 -18
- package/dist/aria-connector/src/install-hooks.d.ts.map +0 -1
- package/dist/aria-connector/src/install-hooks.js +0 -224
- package/dist/aria-connector/src/install-hooks.js.map +0 -1
- package/dist/aria-connector/src/onboarding-wizard.d.ts +0 -5
- package/dist/aria-connector/src/onboarding-wizard.d.ts.map +0 -1
- package/dist/aria-connector/src/onboarding-wizard.js +0 -188
- package/dist/aria-connector/src/onboarding-wizard.js.map +0 -1
- package/dist/cli-0.2.38.tgz +0 -0
- package/dist/install.sh +0 -13
- package/src/__tests__/anthropic-oauth.test.ts +0 -186
- package/src/__tests__/auth-commands.test.ts +0 -132
- package/src/__tests__/owner-login.test.ts +0 -311
|
@@ -0,0 +1,1809 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// aria-pre-emit-autoload.mjs — UserPromptSubmit hook
|
|
3
|
+
//
|
|
4
|
+
// Redesigned 2026-05-09 per Hamza directive: cognition must FRAME the work
|
|
5
|
+
// pre-flight, not be written as ceremony at end-of-turn. Hooks cannot invoke
|
|
6
|
+
// tools, but they CAN inject content as additionalContext. This hook is the
|
|
7
|
+
// pre-flight cognition delivery mechanism: it reads each required skill's
|
|
8
|
+
// BODY (operative rules, workflow, triggers — not just the description) and
|
|
9
|
+
// injects it into the assistant's UserPromptSubmit context BEFORE drafting.
|
|
10
|
+
//
|
|
11
|
+
// Decoupled from the gates-off marker. The gates-off marker disables BLOCKING
|
|
12
|
+
// gates (coach, recovery-executor); it must NOT disable content enrichment,
|
|
13
|
+
// because the very thing that makes the agent's work first-class is having
|
|
14
|
+
// the doctrine content present in context. Use ARIA_AUTOLOAD_DISABLE=1 only
|
|
15
|
+
// for genuine debugging of this hook itself.
|
|
16
|
+
//
|
|
17
|
+
// Triplet honored:
|
|
18
|
+
// - Thinking: classifier picks required skills based on prompt + carry-forward
|
|
19
|
+
// - Implementation: this file reads bodies + injects them
|
|
20
|
+
// - Accountability: sidecar records body excerpts; gate-ledger records byte counts
|
|
21
|
+
//
|
|
22
|
+
// What this hook does on every UserPromptSubmit:
|
|
23
|
+
// 1. Read user prompt from hook event
|
|
24
|
+
// 2. Seed canonical floor substrate; manifest drives per-turn workflow
|
|
25
|
+
// invocation downstream instead of prompt-keyword classification
|
|
26
|
+
// 3. For each required skill, read SKILL.md body (frontmatter stripped,
|
|
27
|
+
// redundant trailing boilerplate stripped, capped at 4KB per skill)
|
|
28
|
+
// 4. Build structured additionalContext: FRAME (skill bodies) +
|
|
29
|
+
// DRIVING-RULES (operative summary) + POST-QA (predicate template) +
|
|
30
|
+
// cognition vocabulary
|
|
31
|
+
// 5. Persist sidecar at ~/.claude/.aria-current-turn-context.json with
|
|
32
|
+
// body excerpts for post-phase QA reference
|
|
33
|
+
// 6. Append gate-ledger entry with byte counts injected
|
|
34
|
+
//
|
|
35
|
+
// What this hook does NOT do:
|
|
36
|
+
// - Does not invoke the Skill tool itself (Claude Code hooks cannot mutate
|
|
37
|
+
// the assistant's tool-call list). Body content arrives as context.
|
|
38
|
+
// - Does not block. Pre-emit is enrichment; pre-tool-gate enforces.
|
|
39
|
+
|
|
40
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, lstatSync, readdirSync } from 'node:fs';
|
|
41
|
+
import { dirname } from 'node:path';
|
|
42
|
+
import { homedir } from 'node:os';
|
|
43
|
+
import { createHash } from 'node:crypto';
|
|
44
|
+
import { parseLoadFirstSection } from './lib/skill-autoload-gate-impl.mjs';
|
|
45
|
+
import { appendGateLedger } from './lib/aria-gate-ledger.mjs';
|
|
46
|
+
import { loadDoctrineTriggerMap } from './lib/doctrine-trigger-map-loader.mjs';
|
|
47
|
+
// A3 + A4 (2026-05-17) — atlas-driven skill selection + end-phase court
|
|
48
|
+
// verdict feedback. Static import is safe because the kernel mirror is
|
|
49
|
+
// guaranteed-present per kernel-sync gate (packages/aria-connector/scripts/
|
|
50
|
+
// check-kernel-sync.mjs). Kernel call itself is wrapped in try/catch with
|
|
51
|
+
// LOUD-stderr fallback per feedback_no_silent_fail_open_in_hooks.md.
|
|
52
|
+
import { compileCognitiveOptions } from './lib/kernel/deterministic-cognitive-kernel.mjs';
|
|
53
|
+
// A5 (2026-05-18) — atlas dossier client. Atlas-as-orchestrator: the daemon's
|
|
54
|
+
// per-file governing_skills knowledge is consulted per turn alongside the
|
|
55
|
+
// kernel's class-anchored selection. File-shape tokens in the prompt are
|
|
56
|
+
// resolved against the dossier index; resulting governing_skills are unioned
|
|
57
|
+
// into the cascade so substrate carries both the kernel floor + atlas's
|
|
58
|
+
// per-target reinforcement. fetchGoverningSkills is already LOUD-on-fail per
|
|
59
|
+
// feedback_no_silent_fail_open_in_hooks.md.
|
|
60
|
+
import { fetchGoverningSkills } from './lib/atlas-dossier-client.mjs';
|
|
61
|
+
|
|
62
|
+
const HOME = homedir();
|
|
63
|
+
const RUNTIME_URL = (process.env.ARIA_RUNTIME_URL || 'http://127.0.0.1:4319').replace(/\/+$/, '');
|
|
64
|
+
const SIDECAR_PATH = `${HOME}/.claude/.aria-current-turn-context.json`;
|
|
65
|
+
const SKILLS_DIR = `${HOME}/.claude/skills`;
|
|
66
|
+
const HOOK_EVENT_NAME = 'UserPromptSubmit';
|
|
67
|
+
const HEADER_PREFIX = '[ARIA_PRE_EMIT_AUTOLOAD]';
|
|
68
|
+
|
|
69
|
+
// Budget caps. Per-skill 4KB keeps each skill's operative section in scope
|
|
70
|
+
// without bloating context. Total 25KB stays well within additionalContext
|
|
71
|
+
// tolerance observed in this surface. Hard file-size cap 50KB rejects
|
|
72
|
+
// abnormally large or attacker-planted SKILL.md files.
|
|
73
|
+
const MAX_BYTES_PER_SKILL = 4096;
|
|
74
|
+
const MAX_BYTES_TOTAL = 25 * 1024;
|
|
75
|
+
const MAX_SKILL_FILE_BYTES = 50 * 1024;
|
|
76
|
+
const SUBSTRATE_OPEN_TIMEOUT_MS = Number(process.env.ARIA_SUBSTRATE_OPEN_TIMEOUT_MS || 900);
|
|
77
|
+
|
|
78
|
+
// AI-11803-LOOP1 (2026-05-12): cascade-depth cap. Each loaded skill body is
|
|
79
|
+
// scanned for Load First / Mode Selection / Load Order / Ta'aqqul Autofire
|
|
80
|
+
// sections; named skills cascade onto the load set. Depth 3 covers
|
|
81
|
+
// autofire → quality-audit → first-principles cascades without unbounded
|
|
82
|
+
// recursion through skills that load each other.
|
|
83
|
+
const MAX_CASCADE_DEPTH = 3;
|
|
84
|
+
|
|
85
|
+
// AI-11803-LOOP2 (2026-05-12): doctrine-trigger map pre-emit pass caps.
|
|
86
|
+
// The trigger map has 79 entries; scanning the user prompt against each
|
|
87
|
+
// regex is O(79 * promptLen). The cap on matched triggers prevents a
|
|
88
|
+
// pathological prompt from producing a giant alert block. The per-trigger
|
|
89
|
+
// byte budget keeps each alert compact (teaching + counter_action + memory
|
|
90
|
+
// file name + trigger). Total budget fits inside additionalContext alongside
|
|
91
|
+
// skill bodies without competing for the 25KB skill-body cap.
|
|
92
|
+
const DOCTRINE_TRIGGER_MAP_PATH = `${HOME}/.claude/hooks/doctrine_trigger_map.json`;
|
|
93
|
+
const MEMORY_DIR = `${HOME}/.claude/projects/-home-hamzaibrahim1/memory`;
|
|
94
|
+
const MAX_DOCTRINE_TRIGGER_MATCHES = 8;
|
|
95
|
+
const MAX_BYTES_PER_TRIGGER_ALERT = 480;
|
|
96
|
+
// AI-11803-QA-GAP3 (2026-05-12): per-memory body injection cap.
|
|
97
|
+
// QA-FIX (2026-05-12 same turn): raised to 4KB so the must-satisfy Recovery
|
|
98
|
+
// Contract section (Pre-Conditions + Classification A/B/C/D + Loop Safety +
|
|
99
|
+
// Turn-End Checklist) fits. Same-memory dedup keeps total bounded to
|
|
100
|
+
// ~12KB worst-case (3 distinct memories × 4KB) but typically 4-8KB.
|
|
101
|
+
const MAX_BYTES_PER_MEMORY_BODY = 4096;
|
|
102
|
+
// File-size ceiling raised to 32KB so strengthened doctrine memories
|
|
103
|
+
// (Recovery Contracts + qiyas + tadabbur + 8-lens substrate) don't get
|
|
104
|
+
// silently rejected. Per-body cap above still bounds what gets injected;
|
|
105
|
+
// the ceiling only rejects abnormally-large or attacker-planted files.
|
|
106
|
+
const MAX_MEMORY_FILE_CEILING = 32 * 1024;
|
|
107
|
+
// QA-FIX-SECTION-AWARE: when a memory body has a "# Recovery Contract"
|
|
108
|
+
// section, prefer to extract from that section forward. This makes the
|
|
109
|
+
// must-satisfy operative content load-bearing in autoload context even
|
|
110
|
+
// when the memory is 12-18KB. Falls back to top-of-body truncation when
|
|
111
|
+
// the header isn't present. Header pattern matches "# Recovery Contract"
|
|
112
|
+
// or "# Recovery contract" (case-insensitive) anchored on a heading line.
|
|
113
|
+
const RECOVERY_CONTRACT_HEADER_RX = /^#{1,3}\s+Recovery\s+Contract\b/im;
|
|
114
|
+
|
|
115
|
+
// AI-11803-STEP5 (2026-05-12) — cookbook auto-pull on trigger match.
|
|
116
|
+
// Skill bodies reference `references/<name>.md` cookbooks (1KB-79KB). The
|
|
117
|
+
// cascade primitive loads SKILL.md but NOT the referenced cookbooks. This
|
|
118
|
+
// primitive scans loaded skill bodies for the reference pattern, parses
|
|
119
|
+
// each cookbook's section headers, scores sections by prompt-keyword
|
|
120
|
+
// overlap, and injects the top-1 section per cookbook into context.
|
|
121
|
+
//
|
|
122
|
+
// Deterministic selection (no LLM call, no faux-fallback):
|
|
123
|
+
// 1. Extract keywords from prompt: lowercase tokens length ≥ 4, deduped.
|
|
124
|
+
// 2. Score each `## ` or `### ` section by count of distinct prompt
|
|
125
|
+
// keywords appearing in section text (header to next header of
|
|
126
|
+
// same/higher level).
|
|
127
|
+
// 3. Min threshold: section must score ≥ 2 distinct keywords. Below
|
|
128
|
+
// threshold → skip the cookbook entirely. NO faux-fallback to "first
|
|
129
|
+
// section if no match" — that would be polluting context with
|
|
130
|
+
// arbitrary content (cf. tadabbur INVERSION + forge-guardrails).
|
|
131
|
+
// 4. Tie-break: later position in file wins.
|
|
132
|
+
// 5. Per-cookbook injection capped at MAX_BYTES_PER_COOKBOOK_SECTION (2KB).
|
|
133
|
+
// 6. Total cookbook injection capped at MAX_BYTES_COOKBOOK_TOTAL (4KB).
|
|
134
|
+
//
|
|
135
|
+
// Loop safety: depth cap = 1 (no transitive cookbook→cookbook expansion);
|
|
136
|
+
// each cookbook path injected at most once per turn (Set dedup).
|
|
137
|
+
//
|
|
138
|
+
// Kill switch: ARIA_AUTOLOAD_COOKBOOK_OFF=1.
|
|
139
|
+
// Captures both same-skill (`references/x.md`) and cross-skill
|
|
140
|
+
// (`../<other-skill>/references/x.md`) reference patterns. Group 1 (if
|
|
141
|
+
// present) is the cross-skill name; group 2 is the cookbook filename.
|
|
142
|
+
// QA-FIX (2026-05-12 same turn): cross-skill references were previously
|
|
143
|
+
// silently mis-resolved to the wrong skill dir → invisible to autoload.
|
|
144
|
+
const COOKBOOK_REF_RX = /(?:\.\.\/([a-z0-9_-]+)\/)?references\/([a-z0-9_-]+\.md)/gi;
|
|
145
|
+
|
|
146
|
+
// AI-11803-F3 (2026-05-12) — sub-agent parent-handoff inheritance.
|
|
147
|
+
// When this autoload fires inside a sub-agent session, the parent
|
|
148
|
+
// orchestrator's aria-agent-handoff.mjs wrote a handoff JSON containing
|
|
149
|
+
// the parent's autoload pins (skill names, memory filenames, cookbook
|
|
150
|
+
// section selections). Read those FIRST, layer them into the load set,
|
|
151
|
+
// then let the sub-agent's own classifier add task-specific skills on
|
|
152
|
+
// top. Augment, not override.
|
|
153
|
+
//
|
|
154
|
+
// Loop safety: handoff JSON includes chainDepth=1 marker; downstream
|
|
155
|
+
// hops (sub-sub-agent) DROP propagation when constructing their own
|
|
156
|
+
// handoff (write-side check in aria-agent-handoff.mjs).
|
|
157
|
+
//
|
|
158
|
+
// TTL: handoff carries ttlMs (5min); if expired vs writtenAt, ignore.
|
|
159
|
+
// Stale handoffs aren't an error — they're from a finished parent turn
|
|
160
|
+
// whose context is no longer load-bearing.
|
|
161
|
+
//
|
|
162
|
+
// Kill switch: ARIA_AUTOLOAD_PARENT_HANDOFF_OFF=1
|
|
163
|
+
const PARENT_HANDOFF_PATH = `${HOME}/.claude/aria-agent-harness-handoff.json`;
|
|
164
|
+
const COOKBOOK_HEADER_RX = /^(#{2,3})\s+(.+)$/gm;
|
|
165
|
+
const MAX_BYTES_PER_COOKBOOK_SECTION = 2048;
|
|
166
|
+
const MAX_BYTES_COOKBOOK_TOTAL = 4096;
|
|
167
|
+
const COOKBOOK_MIN_SCORE = 2;
|
|
168
|
+
const COOKBOOK_KEYWORD_MIN_LEN = 4;
|
|
169
|
+
const COOKBOOK_FILE_CEILING = 200 * 1024; // 200KB hard ceiling on cookbook files (largest seen is 79KB)
|
|
170
|
+
|
|
171
|
+
// AI-11803-STEP4 (2026-05-12) — MEMORY.md auto-load + top-N body injection.
|
|
172
|
+
// MEMORY.md is the master index of every Aria doctrine memory written across
|
|
173
|
+
// sessions. Without this primitive, the model only sees memory bodies when a
|
|
174
|
+
// doctrine-trigger regex fires (lib/doctrine-trigger-map-loader.mjs path) —
|
|
175
|
+
// which means ~80% of accumulated doctrine is invisible per turn. Hamza
|
|
176
|
+
// directive 2026-05-12: "memory.md should def auto load."
|
|
177
|
+
//
|
|
178
|
+
// Budget split (hard cap 8KB total so this doesn't crowd the 25KB skill-body
|
|
179
|
+
// budget):
|
|
180
|
+
// - 4KB MEMORY.md index (one-line entries from the file verbatim,
|
|
181
|
+
// gracefully truncated with a tail marker naming how many entries fell
|
|
182
|
+
// off the cap so the agent knows to consult the file directly)
|
|
183
|
+
// - 4KB for top-N memory bodies (default N=3, ~1.3KB each)
|
|
184
|
+
//
|
|
185
|
+
// Priority signal for top-N selection (deterministic, no faux-priority):
|
|
186
|
+
// 1. Frontmatter `priority: <number>` field if present (explicit owner
|
|
187
|
+
// signal — honest first-tier). Higher number = higher priority.
|
|
188
|
+
// 2. mtime descending (recency fallback when no explicit priority — the
|
|
189
|
+
// most-recently authored or edited memory is the most likely to be
|
|
190
|
+
// currently relevant; this matches Hamza's authoring cadence).
|
|
191
|
+
//
|
|
192
|
+
// Dedup contract: top-N body injection MUST skip memories already injected
|
|
193
|
+
// by buildDoctrineTriggerInjection() this turn (trigger-map regex matched
|
|
194
|
+
// → memory body inlined already). Without dedup, the same memory body could
|
|
195
|
+
// land twice on the same turn. Implemented via a Set<string> of memory
|
|
196
|
+
// filenames passed from main() after doctrineScan.matches is computed.
|
|
197
|
+
const MAX_BYTES_MEMORY_INDEX = 4096;
|
|
198
|
+
const MAX_BYTES_MEMORY_BODIES = 4096;
|
|
199
|
+
const TOP_N_MEMORY_BODIES = 3;
|
|
200
|
+
const MEMORY_INDEX_PATH = `${MEMORY_DIR}/MEMORY.md`;
|
|
201
|
+
|
|
202
|
+
// Trailing boilerplate sections that are identical across skills and add
|
|
203
|
+
// only noise when injected. Stripping these gives 1-1.5KB of headroom per
|
|
204
|
+
// skill back to the operative content (Trigger, Rules, Workflow). This is
|
|
205
|
+
// trimming redundant duplication, NOT contract-stripping per the
|
|
206
|
+
// no-stripping-as-workaround doctrine.
|
|
207
|
+
const REDUNDANT_TRAILING_SECTIONS = [
|
|
208
|
+
/## First-Class Production Contract[\s\S]*?(?=\n## |\n# |$)/i,
|
|
209
|
+
/## Self-Executing Recovery Contract[\s\S]*?(?=\n## |\n# |$)/i,
|
|
210
|
+
/## Required Workflow[\s\S]*?(?=\n## |\n# |$)/i, // generic 5-step list also identical across skills
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
function readEvent() {
|
|
214
|
+
try {
|
|
215
|
+
const raw = readFileSync(0, 'utf8');
|
|
216
|
+
return raw.trim() ? JSON.parse(raw) : {};
|
|
217
|
+
} catch {
|
|
218
|
+
return {};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// A4 (2026-05-17) — end-phase court verdict feedback loop.
|
|
223
|
+
// Reads the tail-N entries from ~/.aria/runtime/state/end-of-phase-qa-court.jsonl
|
|
224
|
+
// (written by lib/end-phase-qa-autofire.mjs at every Stop). The kernel uses
|
|
225
|
+
// these to reinforce quality skills when recent verdicts indicate failure.
|
|
226
|
+
// LOUD-fallback to [] per feedback_no_silent_fail_open_in_hooks.md so the
|
|
227
|
+
// caller can proceed with cascade-only manifest if court state unreadable.
|
|
228
|
+
const END_PHASE_COURT_JSONL = `${HOME}/.aria/runtime/state/end-of-phase-qa-court.jsonl`;
|
|
229
|
+
const RECENT_COURT_TAIL_LIMIT = Number(process.env.ARIA_AUTOLOAD_COURT_TAIL || 3);
|
|
230
|
+
// A5 (2026-05-18) — hardening-directive consumer. Stop-gate writes
|
|
231
|
+
// aria.atlas_orchestrator_hardening_directive.v1 to the hive WAL when a
|
|
232
|
+
// prior turn's atlas-selected skills weren't all invoked OR the QA court
|
|
233
|
+
// verdict was below verified. This pre-emit reads the most recent N
|
|
234
|
+
// directives and force-adds their `forceInvokeNextTurn` skills to
|
|
235
|
+
// invocationRequired. Single-pass tail read; LOUD-fallback to [] on read
|
|
236
|
+
// failure so cascade-only manifest is preserved.
|
|
237
|
+
const HIVE_LEDGER_WAL_PATH = `${HOME}/.aria/runtime/state/hive-ledger-wal.jsonl`;
|
|
238
|
+
const HARDENING_DIRECTIVE_TAIL_LIMIT = Number(process.env.ARIA_AUTOLOAD_HARDENING_TAIL || 16);
|
|
239
|
+
|
|
240
|
+
function readRecentHardeningDirectives(limit = HARDENING_DIRECTIVE_TAIL_LIMIT) {
|
|
241
|
+
try {
|
|
242
|
+
if (!existsSync(HIVE_LEDGER_WAL_PATH)) return [];
|
|
243
|
+
const raw = readFileSync(HIVE_LEDGER_WAL_PATH, 'utf8').trim();
|
|
244
|
+
if (!raw) return [];
|
|
245
|
+
const lines = raw.split('\n');
|
|
246
|
+
// Tail scan — only the most recent N candidate lines (bounds memory + IO).
|
|
247
|
+
const tail = lines.slice(-Math.max(1, limit * 8));
|
|
248
|
+
const directives = [];
|
|
249
|
+
for (let i = tail.length - 1; i >= 0 && directives.length < limit; i--) {
|
|
250
|
+
try {
|
|
251
|
+
const obj = JSON.parse(tail[i]);
|
|
252
|
+
if (obj?.schema === 'aria.atlas_orchestrator_hardening_directive.v1' && Array.isArray(obj.forceInvokeNextTurn)) {
|
|
253
|
+
directives.push({
|
|
254
|
+
at: obj.at || null,
|
|
255
|
+
session_id: obj.session_id || null,
|
|
256
|
+
reason: obj.reason || null,
|
|
257
|
+
forceInvokeNextTurn: obj.forceInvokeNextTurn.filter((s) => typeof s === 'string'),
|
|
258
|
+
qaVerdict: obj.qaVerdict || null,
|
|
259
|
+
adherenceRatio: typeof obj.adherenceRatio === 'number' ? obj.adherenceRatio : null,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
} catch { /* malformed line non-fatal */ }
|
|
263
|
+
}
|
|
264
|
+
return directives;
|
|
265
|
+
} catch (err) {
|
|
266
|
+
process.stderr.write(`[aria-pre-emit-autoload:hardening-directive-read] LOUD ${err instanceof Error ? err.message : String(err)} — proceeding without hardening feedback\n`);
|
|
267
|
+
return [];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function readRecentCourtVerdicts(limit = RECENT_COURT_TAIL_LIMIT) {
|
|
272
|
+
try {
|
|
273
|
+
if (!existsSync(END_PHASE_COURT_JSONL)) return [];
|
|
274
|
+
const raw = readFileSync(END_PHASE_COURT_JSONL, 'utf8').trim();
|
|
275
|
+
if (!raw) return [];
|
|
276
|
+
const lines = raw.split('\n');
|
|
277
|
+
const tail = lines.slice(-Math.max(1, limit));
|
|
278
|
+
const verdicts = [];
|
|
279
|
+
for (const ln of tail) {
|
|
280
|
+
try {
|
|
281
|
+
const obj = JSON.parse(ln);
|
|
282
|
+
if (obj && typeof obj === 'object' && typeof obj.verdict === 'string') {
|
|
283
|
+
verdicts.push({
|
|
284
|
+
verdict: obj.verdict,
|
|
285
|
+
at: obj.at || null,
|
|
286
|
+
phase_id: obj.phase_id || null,
|
|
287
|
+
trigger: obj.trigger || null,
|
|
288
|
+
session_id: obj.session_id || null,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
} catch {
|
|
292
|
+
// Single malformed line is non-fatal — court is append-only JSONL
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return verdicts;
|
|
296
|
+
} catch (err) {
|
|
297
|
+
process.stderr.write(`[aria-pre-emit-autoload:court-read-fallback] LOUD-fail path=${END_PHASE_COURT_JSONL} err=${err?.message || String(err)}\n`);
|
|
298
|
+
return [];
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function emit(envelope) {
|
|
303
|
+
process.stdout.write(`${JSON.stringify(envelope)}\n`);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function emitNoop(reason) {
|
|
307
|
+
emit({
|
|
308
|
+
hookSpecificOutput: {
|
|
309
|
+
hookEventName: HOOK_EVENT_NAME,
|
|
310
|
+
additionalContext: `${HEADER_PREFIX} skipped: ${reason}`,
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
process.exit(0);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
async function openRuntimeSubstrate({ event, prompt, requiredSkills }) {
|
|
317
|
+
const controller = new AbortController();
|
|
318
|
+
const timeout = setTimeout(() => controller.abort(), SUBSTRATE_OPEN_TIMEOUT_MS);
|
|
319
|
+
try {
|
|
320
|
+
const response = await fetch(`${RUNTIME_URL}/substrate/open`, {
|
|
321
|
+
method: 'POST',
|
|
322
|
+
headers: { 'content-type': 'application/json' },
|
|
323
|
+
signal: controller.signal,
|
|
324
|
+
body: JSON.stringify({
|
|
325
|
+
surface: 'claude-code-pre-emit',
|
|
326
|
+
sessionId: event.session_id || event.sessionId || process.env.CLAUDE_SESSION_ID || `pre-emit-${process.pid}`,
|
|
327
|
+
prompt,
|
|
328
|
+
requiredSkills,
|
|
329
|
+
source: 'aria-pre-emit-autoload',
|
|
330
|
+
event: 'pre_emit_autoload',
|
|
331
|
+
}),
|
|
332
|
+
});
|
|
333
|
+
const text = await response.text();
|
|
334
|
+
let data = null;
|
|
335
|
+
try { data = text ? JSON.parse(text) : null; } catch { data = { raw: text.slice(0, 500) }; }
|
|
336
|
+
return response.ok && data?.ok === true
|
|
337
|
+
? { ok: true, status: response.status, packet: data }
|
|
338
|
+
: { ok: false, status: response.status, packet: data, error: data?.error || 'substrate_open_failed' };
|
|
339
|
+
} catch (error) {
|
|
340
|
+
return { ok: false, status: 0, error: error instanceof Error ? error.message : String(error) };
|
|
341
|
+
} finally {
|
|
342
|
+
clearTimeout(timeout);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function buildSubstrateOpenInjection(substrateOpen) {
|
|
347
|
+
if (!substrateOpen?.ok || !substrateOpen.packet) {
|
|
348
|
+
return [
|
|
349
|
+
'═══ ARIA SUBSTRATE OPEN GAP ═══',
|
|
350
|
+
`runtime=${RUNTIME_URL}`,
|
|
351
|
+
`status=${substrateOpen?.status || 0}`,
|
|
352
|
+
`error=${substrateOpen?.error || 'substrate_open_unavailable'}`,
|
|
353
|
+
'Treat Atlas/Hive binding as unverified for this turn; completion claims require direct evidence.',
|
|
354
|
+
].join('\n');
|
|
355
|
+
}
|
|
356
|
+
const packet = substrateOpen.packet;
|
|
357
|
+
const forge = packet.atlasFirstPrinciplesForgeReceipt || {};
|
|
358
|
+
return [
|
|
359
|
+
'═══ ARIA SUBSTRATE OPEN — ATLAS FIRST-PRINCIPLES FORGE ═══',
|
|
360
|
+
`work_unit_id=${packet.workUnitId}`,
|
|
361
|
+
`hive_project_id=${packet.projectId}`,
|
|
362
|
+
`hive_thread_id=${packet.threadId}`,
|
|
363
|
+
`atlas_status=${forge.atlas?.status || 'missing'}`,
|
|
364
|
+
`atlas_context_hash=${forge.atlas?.contextHash || 'missing'}`,
|
|
365
|
+
`first_principles_mode=${forge.mode || 'missing'}`,
|
|
366
|
+
`generative_axioms=${forge.generativeAxiomCount || 0}`,
|
|
367
|
+
`required_skills=${(packet.requiredSkillIds || []).join(',')}`,
|
|
368
|
+
`drift_correction=${forge.driftCorrection?.correctedPurpose || 'missing'}`,
|
|
369
|
+
'Binding rule: first principles must generate cross-domain connections, bounded novelty trials, and breakthrough candidates. Truth protection is a boundary, not the primary purpose.',
|
|
370
|
+
].join('\n');
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
function writeSidecar(payload) {
|
|
374
|
+
try {
|
|
375
|
+
mkdirSync(dirname(SIDECAR_PATH), { recursive: true, mode: 0o700 });
|
|
376
|
+
writeFileSync(SIDECAR_PATH, `${JSON.stringify(payload, null, 2)}\n`, { mode: 0o600 });
|
|
377
|
+
} catch (err) {
|
|
378
|
+
process.stderr.write(`[aria-pre-emit-autoload:sidecar-write] ${err instanceof Error ? err.message : String(err)}\n`);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// Read and prepare a skill body for injection. Returns { body, bytes,
|
|
383
|
+
// fullBytes, redacted, reason } so caller can record what was injected and
|
|
384
|
+
// why. Hardens against:
|
|
385
|
+
// - non-regular files (symlinks, fifos, devices) → reject
|
|
386
|
+
// - oversize SKILL.md (> MAX_SKILL_FILE_BYTES) → reject
|
|
387
|
+
// - missing files → empty body, no crash
|
|
388
|
+
function readSkillBody(skillName) {
|
|
389
|
+
const path = `${SKILLS_DIR}/${skillName}/SKILL.md`;
|
|
390
|
+
if (!existsSync(path)) {
|
|
391
|
+
return { body: '', bytes: 0, fullBytes: 0, redacted: false, reason: 'missing' };
|
|
392
|
+
}
|
|
393
|
+
let lst;
|
|
394
|
+
try {
|
|
395
|
+
lst = lstatSync(path);
|
|
396
|
+
} catch (err) {
|
|
397
|
+
return { body: '', bytes: 0, fullBytes: 0, redacted: false, reason: `lstat-failed: ${err?.message || err}` };
|
|
398
|
+
}
|
|
399
|
+
if (!lst.isFile()) {
|
|
400
|
+
return { body: '', bytes: 0, fullBytes: 0, redacted: true, reason: 'not-regular-file' };
|
|
401
|
+
}
|
|
402
|
+
if (lst.size > MAX_SKILL_FILE_BYTES) {
|
|
403
|
+
return { body: '', bytes: 0, fullBytes: lst.size, redacted: true, reason: `oversize: ${lst.size}B > ${MAX_SKILL_FILE_BYTES}B` };
|
|
404
|
+
}
|
|
405
|
+
let raw;
|
|
406
|
+
try {
|
|
407
|
+
raw = readFileSync(path, 'utf8');
|
|
408
|
+
} catch (err) {
|
|
409
|
+
return { body: '', bytes: 0, fullBytes: lst.size, redacted: false, reason: `read-failed: ${err?.message || err}` };
|
|
410
|
+
}
|
|
411
|
+
const fullBytes = Buffer.byteLength(raw, 'utf8');
|
|
412
|
+
// Strip YAML frontmatter (--- ... --- at top of file)
|
|
413
|
+
let trimmed = raw.replace(/^---[\s\S]*?---\s*/, '');
|
|
414
|
+
// Strip redundant trailing boilerplate sections that are identical
|
|
415
|
+
// across all skills (per pre-phase analysis). This is duplication
|
|
416
|
+
// trimming, not contract stripping.
|
|
417
|
+
for (const rx of REDUNDANT_TRAILING_SECTIONS) {
|
|
418
|
+
trimmed = trimmed.replace(rx, '');
|
|
419
|
+
}
|
|
420
|
+
trimmed = trimmed.trimEnd();
|
|
421
|
+
// Apply per-skill byte cap. If we have to truncate, leave a marker so
|
|
422
|
+
// the agent knows there's more content available via Skill tool.
|
|
423
|
+
let body = trimmed;
|
|
424
|
+
let truncated = false;
|
|
425
|
+
if (Buffer.byteLength(body, 'utf8') > MAX_BYTES_PER_SKILL) {
|
|
426
|
+
// Truncate at a paragraph boundary near the cap when possible.
|
|
427
|
+
const buf = Buffer.from(body, 'utf8').slice(0, MAX_BYTES_PER_SKILL);
|
|
428
|
+
body = buf.toString('utf8');
|
|
429
|
+
const lastBreak = Math.max(body.lastIndexOf('\n\n'), body.lastIndexOf('\n## '));
|
|
430
|
+
if (lastBreak > MAX_BYTES_PER_SKILL * 0.6) {
|
|
431
|
+
body = body.slice(0, lastBreak);
|
|
432
|
+
}
|
|
433
|
+
truncated = true;
|
|
434
|
+
body += `\n\n[…body truncated at ${MAX_BYTES_PER_SKILL}B; full SKILL.md available via /skills/${skillName}/SKILL.md…]`;
|
|
435
|
+
}
|
|
436
|
+
const bytes = Buffer.byteLength(body, 'utf8');
|
|
437
|
+
return {
|
|
438
|
+
body,
|
|
439
|
+
bytes,
|
|
440
|
+
fullBytes,
|
|
441
|
+
redacted: false,
|
|
442
|
+
truncated,
|
|
443
|
+
reason: 'ok',
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// AI-11803-LOOP2 (2026-05-12) — doctrine-trigger pre-emit scan.
|
|
448
|
+
// Runs the 79-trigger doctrine map against the user's prompt text at
|
|
449
|
+
// UserPromptSubmit so prose-pattern matches (e.g., "graceful degradation",
|
|
450
|
+
// "out of scope", "want me to") surface their bound doctrine memory +
|
|
451
|
+
// teaching + counter_action BEFORE the model drafts. Prior architecture
|
|
452
|
+
// only ran the trigger map post-emit (after the answer was drafted), which
|
|
453
|
+
// caught drift after the fact instead of preventing it.
|
|
454
|
+
//
|
|
455
|
+
// Output shape: a separate "[ARIA_DOCTRINE_TRIGGERS_MATCHED]" section in
|
|
456
|
+
// additionalContext, formatted as compact one-line-per-trigger alerts.
|
|
457
|
+
// Does NOT inject the bound memory file content (separate from skill-body
|
|
458
|
+
// injection); the memory filename surfaces so the model can read it via
|
|
459
|
+
// the existing memory-consumption gate at PreToolUse.
|
|
460
|
+
//
|
|
461
|
+
// Fail-allow: any error in trigger map load returns empty matches list and
|
|
462
|
+
// LOUD telemetry — never blocks the autoload's emission.
|
|
463
|
+
//
|
|
464
|
+
// Kill switch: ARIA_AUTOLOAD_TRIGGER_MAP_OFF=1.
|
|
465
|
+
function scanDoctrineTriggers(promptText) {
|
|
466
|
+
if (/^(?:1|true|yes|on)$/i.test(String(process.env.ARIA_AUTOLOAD_TRIGGER_MAP_OFF || ''))) {
|
|
467
|
+
return { matches: [], errors: [], skipped: 'env-disabled' };
|
|
468
|
+
}
|
|
469
|
+
if (!promptText || typeof promptText !== 'string') {
|
|
470
|
+
return { matches: [], errors: [], skipped: 'empty-prompt' };
|
|
471
|
+
}
|
|
472
|
+
let loaded;
|
|
473
|
+
try {
|
|
474
|
+
loaded = loadDoctrineTriggerMap(DOCTRINE_TRIGGER_MAP_PATH);
|
|
475
|
+
} catch (err) {
|
|
476
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
477
|
+
process.stderr.write(`[aria-pre-emit-autoload:trigger-map-load-error] ${msg}\n`);
|
|
478
|
+
return { matches: [], errors: [msg], skipped: 'load-error' };
|
|
479
|
+
}
|
|
480
|
+
const matches = [];
|
|
481
|
+
const seen = new Set();
|
|
482
|
+
for (const entry of loaded.triggers) {
|
|
483
|
+
if (matches.length >= MAX_DOCTRINE_TRIGGER_MATCHES) break;
|
|
484
|
+
// Each entry's compiled regex carries the `gi` flags; reset lastIndex
|
|
485
|
+
// so re-use across multiple scans doesn't skip from prior call state.
|
|
486
|
+
entry.regex.lastIndex = 0;
|
|
487
|
+
if (!entry.regex.test(promptText)) continue;
|
|
488
|
+
// De-dup by memory file (multiple triggers may bind the same memory).
|
|
489
|
+
if (seen.has(entry.memory)) continue;
|
|
490
|
+
seen.add(entry.memory);
|
|
491
|
+
matches.push({
|
|
492
|
+
trigger: entry.trigger,
|
|
493
|
+
memory: entry.memory,
|
|
494
|
+
teaching: entry.teaching,
|
|
495
|
+
counter_action: entry.counter_action,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
return { matches, errors: loaded.errors || [], skipped: null };
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// AI-11803-QA-GAP3 (2026-05-12): read memory body for injection.
|
|
502
|
+
// Returns frontmatter-stripped, cap-truncated body or empty string on any
|
|
503
|
+
// failure. Per parallel-session safety, never throws.
|
|
504
|
+
function readMemoryBody(memoryFilename) {
|
|
505
|
+
if (!memoryFilename || typeof memoryFilename !== 'string') return '';
|
|
506
|
+
const path = `${MEMORY_DIR}/${memoryFilename}`;
|
|
507
|
+
if (!existsSync(path)) return '';
|
|
508
|
+
let lst;
|
|
509
|
+
try { lst = lstatSync(path); } catch { return ''; }
|
|
510
|
+
if (!lst.isFile()) return '';
|
|
511
|
+
if (lst.size > MAX_MEMORY_FILE_CEILING) return ''; // hard ceiling on file size
|
|
512
|
+
let raw;
|
|
513
|
+
try { raw = readFileSync(path, 'utf8'); } catch { return ''; }
|
|
514
|
+
// Strip YAML frontmatter; if absent, raw passes through.
|
|
515
|
+
let body = raw.replace(/^---[\s\S]*?---\s*/, '').trimStart();
|
|
516
|
+
// QA-FIX-SECTION-AWARE: if the body has a "# Recovery Contract" section,
|
|
517
|
+
// extract from that section forward. The must-satisfy contract becomes
|
|
518
|
+
// the operative content; preceding rationale (qiyas / tadabbur / 8-lens
|
|
519
|
+
// pre-amble) stays in the file for read-on-demand but doesn't crowd the
|
|
520
|
+
// pre-emit context.
|
|
521
|
+
const recoveryMatch = body.match(RECOVERY_CONTRACT_HEADER_RX);
|
|
522
|
+
let extractionMode = 'top-of-body';
|
|
523
|
+
if (recoveryMatch) {
|
|
524
|
+
const headerStart = body.indexOf(recoveryMatch[0]);
|
|
525
|
+
const before = body.slice(0, headerStart);
|
|
526
|
+
const beforeBytes = Buffer.byteLength(before, 'utf8');
|
|
527
|
+
body = `[…body preamble omitted, ${beforeBytes}B; recovery contract follows…]\n\n${body.slice(headerStart)}`;
|
|
528
|
+
extractionMode = 'recovery-contract-section';
|
|
529
|
+
}
|
|
530
|
+
if (Buffer.byteLength(body, 'utf8') > MAX_BYTES_PER_MEMORY_BODY) {
|
|
531
|
+
const buf = Buffer.from(body, 'utf8').slice(0, MAX_BYTES_PER_MEMORY_BODY);
|
|
532
|
+
body = buf.toString('utf8');
|
|
533
|
+
const lastBreak = Math.max(body.lastIndexOf('\n\n'), body.lastIndexOf('\n'));
|
|
534
|
+
if (lastBreak > MAX_BYTES_PER_MEMORY_BODY * 0.6) body = body.slice(0, lastBreak);
|
|
535
|
+
body += `\n[…memory body truncated at ${MAX_BYTES_PER_MEMORY_BODY}B; mode=${extractionMode}; full file at ${path}…]`;
|
|
536
|
+
}
|
|
537
|
+
return body;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function buildDoctrineTriggerInjection(matches) {
|
|
541
|
+
if (!matches || matches.length === 0) return '';
|
|
542
|
+
const lines = [];
|
|
543
|
+
lines.push('═══ ARIA DOCTRINE TRIGGERS MATCHED (prose patterns in your prompt bind to these memories) ═══');
|
|
544
|
+
for (const m of matches) {
|
|
545
|
+
let teaching = m.teaching;
|
|
546
|
+
let counter = m.counter_action;
|
|
547
|
+
// Per-alert byte cap — truncate teaching+counter if combined exceed budget.
|
|
548
|
+
const baseLen = ` • [${m.trigger}] → ${m.memory}: `.length;
|
|
549
|
+
const budget = MAX_BYTES_PER_TRIGGER_ALERT - baseLen;
|
|
550
|
+
const combined = `${teaching} || ${counter}`;
|
|
551
|
+
const slice = combined.length > budget ? `${combined.slice(0, budget - 3)}...` : combined;
|
|
552
|
+
lines.push(` • [${m.trigger}] → ${m.memory}: ${slice}`);
|
|
553
|
+
// AI-11803-QA-GAP3: inject memory body (capped) so the model sees the
|
|
554
|
+
// operative rule + Why + How-to-apply lines directly, not just a pointer.
|
|
555
|
+
const memBody = readMemoryBody(m.memory);
|
|
556
|
+
if (memBody) {
|
|
557
|
+
lines.push(` ┌─ memory body (${m.memory}):`);
|
|
558
|
+
for (const ln of memBody.split('\n')) lines.push(` │ ${ln}`);
|
|
559
|
+
lines.push(` └─`);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
lines.push('Apply each: the trigger phrase in the prompt names a doctrine the agent must honor THIS turn.');
|
|
563
|
+
return lines.join('\n');
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// AI-11803-LOOP1 (2026-05-12) — cascade autoload.
|
|
567
|
+
// Expand the initial skill set by reading each skill body and parsing its
|
|
568
|
+
// Load First / Mode Selection / Load Order / Ta'aqqul Autofire Pattern
|
|
569
|
+
// sections. Recursive BFS bounded by MAX_CASCADE_DEPTH and MAX_BYTES_TOTAL.
|
|
570
|
+
// Returns the load order, body map, total bytes, and observed depth so the
|
|
571
|
+
// caller can build skillBodies + sidecar + ledger telemetry from one pass.
|
|
572
|
+
//
|
|
573
|
+
// Cycle-safe: each skill is read at most once (Set<string> seen tracker).
|
|
574
|
+
// Budget-safe: once total bytes would exceed MAX_BYTES_TOTAL, subsequent
|
|
575
|
+
// skills are recorded with reason="budget-exhausted (cascade-depth=N)"
|
|
576
|
+
// instead of being dropped silently — the agent still sees that the skill
|
|
577
|
+
// was wanted but unavailable in context.
|
|
578
|
+
// Existence-filtered: cascade candidates are only enqueued if the SKILL.md
|
|
579
|
+
// actually exists on disk, so mode-label noise (`qa`, `light`, `batch`)
|
|
580
|
+
// and stale skill names from older bodies don't pollute the queue.
|
|
581
|
+
function expandSkillCascade(initialSkills) {
|
|
582
|
+
const loadedBodies = new Map(); // skill -> readSkillBody result
|
|
583
|
+
const order = []; // load order in BFS-by-depth
|
|
584
|
+
const seen = new Set();
|
|
585
|
+
let totalBytes = 0;
|
|
586
|
+
let queue = [...new Set(initialSkills)];
|
|
587
|
+
let depth = 0;
|
|
588
|
+
let maxObservedDepth = 0;
|
|
589
|
+
let maxAttemptedDepth = 0;
|
|
590
|
+
while (queue.length > 0 && depth <= MAX_CASCADE_DEPTH) {
|
|
591
|
+
const nextQueue = [];
|
|
592
|
+
for (const skill of queue) {
|
|
593
|
+
if (seen.has(skill)) continue;
|
|
594
|
+
seen.add(skill);
|
|
595
|
+
const result = readSkillBody(skill);
|
|
596
|
+
// Skip skills that don't exist on disk — keeps cascade quiet on mode
|
|
597
|
+
// labels and stale references.
|
|
598
|
+
if (result.reason === 'missing') continue;
|
|
599
|
+
// AI-11803-QA-GAP1 (2026-05-12): track attempted-depth separately from
|
|
600
|
+
// injected-depth. A candidate enqueued at depth N counts toward
|
|
601
|
+
// maxAttemptedDepth even if its body is budget-exhausted and bytes=0.
|
|
602
|
+
// Prior telemetry conflated "no body injected" with "no depth observed",
|
|
603
|
+
// under-reporting cascade reach when the 25KB cap saturated early.
|
|
604
|
+
maxAttemptedDepth = Math.max(maxAttemptedDepth, depth);
|
|
605
|
+
if (loadedBodies.size > 0 && totalBytes + result.bytes > MAX_BYTES_TOTAL) {
|
|
606
|
+
loadedBodies.set(skill, {
|
|
607
|
+
...result,
|
|
608
|
+
body: '',
|
|
609
|
+
bytes: 0,
|
|
610
|
+
truncated: false,
|
|
611
|
+
redacted: false,
|
|
612
|
+
reason: `budget-exhausted (cascade-depth=${depth})`,
|
|
613
|
+
});
|
|
614
|
+
order.push(skill);
|
|
615
|
+
// Even when body is budget-exhausted, we still scan for downstream
|
|
616
|
+
// cascade candidates — but only if we have the body (we don't here),
|
|
617
|
+
// so this branch terminates the cascade for this skill's children.
|
|
618
|
+
continue;
|
|
619
|
+
}
|
|
620
|
+
loadedBodies.set(skill, result);
|
|
621
|
+
order.push(skill);
|
|
622
|
+
totalBytes += result.bytes;
|
|
623
|
+
maxObservedDepth = depth;
|
|
624
|
+
if (result.body) {
|
|
625
|
+
for (const c of parseLoadFirstSection(result.body)) {
|
|
626
|
+
if (seen.has(c)) continue;
|
|
627
|
+
if (!existsSync(`${SKILLS_DIR}/${c}/SKILL.md`)) continue;
|
|
628
|
+
nextQueue.push(c);
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
queue = nextQueue;
|
|
633
|
+
depth++;
|
|
634
|
+
}
|
|
635
|
+
return {
|
|
636
|
+
loadedBodies,
|
|
637
|
+
order,
|
|
638
|
+
totalBytes,
|
|
639
|
+
cascadeDepth: maxObservedDepth, // depth at which a body was injected (legacy alias for telemetry compat)
|
|
640
|
+
depthInjected: maxObservedDepth,
|
|
641
|
+
depthAttempted: maxAttemptedDepth,
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// AI-11803-STEP4 (2026-05-12) — read MEMORY.md as an index, capped at
|
|
646
|
+
// MAX_BYTES_MEMORY_INDEX.
|
|
647
|
+
//
|
|
648
|
+
// QA-FIX-1 (2026-05-12, qiyas Owner-Hamza-tomorrow + scale + tadabbur
|
|
649
|
+
// INVERSION): tail-bias the truncation. MEMORY.md is append-only — Hamza
|
|
650
|
+
// writes new memories as entries at the BOTTOM. A head-bias truncation
|
|
651
|
+
// (drop from end) would drop the NEWEST doctrine first, recreating the
|
|
652
|
+
// exact gap this step was meant to close. Tail-bias keeps recent doctrine
|
|
653
|
+
// visible and drops older entries with a head-marker.
|
|
654
|
+
//
|
|
655
|
+
// Algorithm: walk lines from END to START, accumulate while under cap,
|
|
656
|
+
// reverse the kept set, prepend a head-marker naming how many earlier
|
|
657
|
+
// entries were dropped.
|
|
658
|
+
function readMemoryIndex() {
|
|
659
|
+
if (!existsSync(MEMORY_INDEX_PATH)) {
|
|
660
|
+
return { body: '', bytes: 0, totalLines: 0, droppedLines: 0, reason: 'missing' };
|
|
661
|
+
}
|
|
662
|
+
let lst;
|
|
663
|
+
try { lst = lstatSync(MEMORY_INDEX_PATH); } catch (err) {
|
|
664
|
+
return { body: '', bytes: 0, totalLines: 0, droppedLines: 0, reason: `lstat-failed: ${err?.message || err}` };
|
|
665
|
+
}
|
|
666
|
+
if (!lst.isFile()) {
|
|
667
|
+
return { body: '', bytes: 0, totalLines: 0, droppedLines: 0, reason: 'not-regular-file' };
|
|
668
|
+
}
|
|
669
|
+
let raw;
|
|
670
|
+
try { raw = readFileSync(MEMORY_INDEX_PATH, 'utf8'); } catch (err) {
|
|
671
|
+
return { body: '', bytes: 0, totalLines: 0, droppedLines: 0, reason: `read-failed: ${err?.message || err}` };
|
|
672
|
+
}
|
|
673
|
+
const lines = raw.split('\n');
|
|
674
|
+
const totalLines = lines.length;
|
|
675
|
+
if (Buffer.byteLength(raw, 'utf8') <= MAX_BYTES_MEMORY_INDEX) {
|
|
676
|
+
return { body: raw.trimEnd(), bytes: Buffer.byteLength(raw, 'utf8'), totalLines, droppedLines: 0, reason: 'ok' };
|
|
677
|
+
}
|
|
678
|
+
// Tail-bias: walk from end, accumulate newest lines first.
|
|
679
|
+
const keptReversed = [];
|
|
680
|
+
let accBytes = 0;
|
|
681
|
+
const reserveForMarker = 140;
|
|
682
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
683
|
+
const line = lines[i];
|
|
684
|
+
const lineBytes = Buffer.byteLength(line, 'utf8') + 1; // +1 for newline
|
|
685
|
+
if (accBytes + lineBytes > MAX_BYTES_MEMORY_INDEX - reserveForMarker) break;
|
|
686
|
+
keptReversed.push(line);
|
|
687
|
+
accBytes += lineBytes;
|
|
688
|
+
}
|
|
689
|
+
const kept = keptReversed.reverse();
|
|
690
|
+
const droppedLines = Math.max(0, totalLines - kept.length);
|
|
691
|
+
const headMarker = `[…MEMORY.md tail-biased: ${droppedLines} older entries dropped; full file at ${MEMORY_INDEX_PATH}. Showing latest ${kept.length} entries below…]`;
|
|
692
|
+
const body = `${headMarker}\n\n${kept.join('\n').trimEnd()}`;
|
|
693
|
+
return { body, bytes: Buffer.byteLength(body, 'utf8'), totalLines, droppedLines, reason: 'tail-biased' };
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// AI-11803-STEP4 (2026-05-12) — score every memory file in MEMORY_DIR by
|
|
697
|
+
// (a) frontmatter `priority: <number>` if present (explicit), or
|
|
698
|
+
// (b) mtime descending (recency fallback).
|
|
699
|
+
// Returns sorted array of { filename, score, source } where higher score is
|
|
700
|
+
// more important. `source` is either "frontmatter:<n>" or "mtime:<ms>" so
|
|
701
|
+
// telemetry can audit which signal won.
|
|
702
|
+
//
|
|
703
|
+
// Filters: MEMORY.md itself is excluded (we inject it separately as the
|
|
704
|
+
// index). Non-.md files excluded. Files unreadable or non-regular are
|
|
705
|
+
// skipped silently — never throws.
|
|
706
|
+
function scoreMemoriesForPriority() {
|
|
707
|
+
let entries;
|
|
708
|
+
try { entries = readdirSync(MEMORY_DIR); } catch (err) {
|
|
709
|
+
return { scored: [], errors: [err?.message || String(err)] };
|
|
710
|
+
}
|
|
711
|
+
const scored = [];
|
|
712
|
+
const errors = [];
|
|
713
|
+
for (const filename of entries) {
|
|
714
|
+
if (filename === 'MEMORY.md') continue;
|
|
715
|
+
if (!filename.endsWith('.md')) continue;
|
|
716
|
+
const fullPath = `${MEMORY_DIR}/${filename}`;
|
|
717
|
+
let lst;
|
|
718
|
+
try { lst = lstatSync(fullPath); } catch (err) {
|
|
719
|
+
errors.push(`lstat ${filename}: ${err?.message || err}`);
|
|
720
|
+
continue;
|
|
721
|
+
}
|
|
722
|
+
if (!lst.isFile()) continue;
|
|
723
|
+
// Read just the frontmatter region — first ~1KB is plenty for YAML.
|
|
724
|
+
let head;
|
|
725
|
+
try {
|
|
726
|
+
const fd = readFileSync(fullPath, 'utf8');
|
|
727
|
+
head = fd.slice(0, 2048);
|
|
728
|
+
} catch (err) {
|
|
729
|
+
errors.push(`read ${filename}: ${err?.message || err}`);
|
|
730
|
+
continue;
|
|
731
|
+
}
|
|
732
|
+
const fmMatch = head.match(/^---\s*\n([\s\S]*?)\n---/);
|
|
733
|
+
let priority = null;
|
|
734
|
+
if (fmMatch) {
|
|
735
|
+
const fm = fmMatch[1];
|
|
736
|
+
const pMatch = fm.match(/^priority:\s*(-?\d+(?:\.\d+)?)\s*$/m);
|
|
737
|
+
if (pMatch) {
|
|
738
|
+
const parsed = Number(pMatch[1]);
|
|
739
|
+
if (Number.isFinite(parsed)) priority = parsed;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
if (priority !== null) {
|
|
743
|
+
scored.push({ filename, score: priority, source: `frontmatter:${priority}`, tier: 'explicit' });
|
|
744
|
+
} else {
|
|
745
|
+
const mtimeMs = lst.mtimeMs || 0;
|
|
746
|
+
scored.push({ filename, score: mtimeMs, source: `mtime:${Math.floor(mtimeMs)}`, tier: 'recency' });
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
// Explicit-tier always outranks recency-tier. Within tier, score desc.
|
|
750
|
+
scored.sort((a, b) => {
|
|
751
|
+
if (a.tier !== b.tier) return a.tier === 'explicit' ? -1 : 1;
|
|
752
|
+
return b.score - a.score;
|
|
753
|
+
});
|
|
754
|
+
return { scored, errors };
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// AI-11803-STEP4 (2026-05-12) — select top-N memory files for body injection,
|
|
758
|
+
// excluding those already injected by trigger-map. Reads each body via the
|
|
759
|
+
// existing readMemoryBody primitive (so the same per-memory cap +
|
|
760
|
+
// frontmatter-strip + size-ceiling applies). Stops once
|
|
761
|
+
// MAX_BYTES_MEMORY_BODIES is exhausted to enforce the hard 8KB total.
|
|
762
|
+
//
|
|
763
|
+
// Returns { injected: [{ filename, body, bytes, tier, score }], totalBytes,
|
|
764
|
+
// dedupedFilenames, scoredCount } so telemetry can audit selection + dedup.
|
|
765
|
+
function selectTopNMemoryBodies(alreadyInjectedFilenames) {
|
|
766
|
+
const { scored, errors } = scoreMemoriesForPriority();
|
|
767
|
+
const dedupedFilenames = [];
|
|
768
|
+
const injected = [];
|
|
769
|
+
let totalBytes = 0;
|
|
770
|
+
for (const entry of scored) {
|
|
771
|
+
if (injected.length >= TOP_N_MEMORY_BODIES) break;
|
|
772
|
+
if (alreadyInjectedFilenames && alreadyInjectedFilenames.has(entry.filename)) {
|
|
773
|
+
dedupedFilenames.push(entry.filename);
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
const body = readMemoryBody(entry.filename);
|
|
777
|
+
if (!body) continue;
|
|
778
|
+
const bodyBytes = Buffer.byteLength(body, 'utf8');
|
|
779
|
+
if (totalBytes + bodyBytes > MAX_BYTES_MEMORY_BODIES) {
|
|
780
|
+
// Don't take a body that would bust the cap; try the next-priority
|
|
781
|
+
// entry (which may be smaller). This avoids a single oversized
|
|
782
|
+
// memory starving subsequent smaller-but-still-important entries.
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
injected.push({ filename: entry.filename, body, bytes: bodyBytes, tier: entry.tier, score: entry.score });
|
|
786
|
+
totalBytes += bodyBytes;
|
|
787
|
+
}
|
|
788
|
+
return { injected, totalBytes, dedupedFilenames, scoredCount: scored.length, errors };
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
function buildMemoryAutoloadInjection({ indexResult, bodyResult }) {
|
|
792
|
+
// Kill-switch and pure-missing cases: emit nothing rather than a stub
|
|
793
|
+
// that crowds context with a "[unavailable]" placeholder.
|
|
794
|
+
if (indexResult.reason === 'env-disabled' && bodyResult.injected.length === 0) {
|
|
795
|
+
return '';
|
|
796
|
+
}
|
|
797
|
+
const lines = [];
|
|
798
|
+
lines.push('═══ MEMORY.md INDEX (auto-loaded — every doctrine memory available this session) ═══');
|
|
799
|
+
if (indexResult.bytes === 0) {
|
|
800
|
+
lines.push(`[MEMORY.md unavailable: ${indexResult.reason}]`);
|
|
801
|
+
} else {
|
|
802
|
+
lines.push(indexResult.body);
|
|
803
|
+
}
|
|
804
|
+
if (bodyResult.injected.length > 0) {
|
|
805
|
+
lines.push('');
|
|
806
|
+
lines.push(`═══ TOP-${bodyResult.injected.length} MEMORY BODIES (priority-selected, dedup'd against trigger-map matches) ═══`);
|
|
807
|
+
for (const entry of bodyResult.injected) {
|
|
808
|
+
lines.push('');
|
|
809
|
+
lines.push(`──── ${entry.filename} [${entry.tier === 'explicit' ? `priority=${entry.score}` : `mtime-rank`}] ────`);
|
|
810
|
+
lines.push(entry.body);
|
|
811
|
+
}
|
|
812
|
+
}
|
|
813
|
+
if (bodyResult.dedupedFilenames.length > 0) {
|
|
814
|
+
lines.push('');
|
|
815
|
+
lines.push(`[dedup: ${bodyResult.dedupedFilenames.length} top-N candidate(s) already injected by doctrine-trigger match: ${bodyResult.dedupedFilenames.join(', ')}]`);
|
|
816
|
+
}
|
|
817
|
+
return lines.join('\n');
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// A5 (2026-05-18) — extract file-path-shape tokens from prompt for atlas
|
|
821
|
+
// dossier consultation. Looks for repo-relative paths (e.g.
|
|
822
|
+
// apps/aria-telemetry/src/mizan.ts, packages/aria-connector/runtime-src/
|
|
823
|
+
// service.mjs) — extension-suffixed tokens, slash-separated. Dedup, cap at
|
|
824
|
+
// ATLAS_DOSSIER_TARGETS_MAX so a long prompt with many paths doesn't fan-out
|
|
825
|
+
// arbitrarily against the atlas socket budget.
|
|
826
|
+
const ATLAS_DOSSIER_TARGETS_MAX = 8;
|
|
827
|
+
const ATLAS_DOSSIER_OVERALL_BUDGET_MS = 800;
|
|
828
|
+
const ATLAS_DOSSIER_PER_TARGET_MS = 300;
|
|
829
|
+
const PATH_SHAPE_RX = /[a-z0-9_.-]+(?:\/[a-z0-9_.-]+){1,}\.(?:ts|tsx|js|jsx|mjs|cjs|json|yaml|yml|md|sh|py|sql|prisma|toml|css|html|tf)/gi;
|
|
830
|
+
function harvestPromptTargets(promptText) {
|
|
831
|
+
if (!promptText || typeof promptText !== 'string') return [];
|
|
832
|
+
const seen = new Set();
|
|
833
|
+
const out = [];
|
|
834
|
+
PATH_SHAPE_RX.lastIndex = 0;
|
|
835
|
+
let m;
|
|
836
|
+
while ((m = PATH_SHAPE_RX.exec(promptText)) !== null) {
|
|
837
|
+
const tok = m[0];
|
|
838
|
+
// Skip URLs (https://..., npm://...) — prefix with letters+colon.
|
|
839
|
+
if (/^[a-z]+:/i.test(tok)) continue;
|
|
840
|
+
if (seen.has(tok)) continue;
|
|
841
|
+
seen.add(tok);
|
|
842
|
+
out.push(tok);
|
|
843
|
+
if (out.length >= ATLAS_DOSSIER_TARGETS_MAX) break;
|
|
844
|
+
}
|
|
845
|
+
return out;
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
// A5 (2026-05-18) — atlas dossier-as-orchestrator: resolve harvested path
|
|
849
|
+
// targets to governing_skills via the atlas daemon. Parallel fan-out bounded
|
|
850
|
+
// by an overall budget; per-target timeout is enforced inside fetch helper.
|
|
851
|
+
// Returns { governingSkills: string[], targetsResolved: number, targetsErr:
|
|
852
|
+
// number, durationMs: number }. LOUD-on-fail is handled per-target by
|
|
853
|
+
// fetchGoverningSkills itself (atlas-dossier-client emits stderr lines on
|
|
854
|
+
// timeout/socket-missing/parse-fail etc).
|
|
855
|
+
async function atlasGoverningSkillsForPrompt(targets) {
|
|
856
|
+
const started = Date.now();
|
|
857
|
+
const out = { governingSkills: [], targetsResolved: 0, targetsErr: 0, durationMs: 0 };
|
|
858
|
+
if (!Array.isArray(targets) || targets.length === 0) return out;
|
|
859
|
+
const seenSkills = new Set();
|
|
860
|
+
const overallDeadline = started + ATLAS_DOSSIER_OVERALL_BUDGET_MS;
|
|
861
|
+
const promises = targets.map((target) => fetchGoverningSkills(target, { timeoutMs: ATLAS_DOSSIER_PER_TARGET_MS })
|
|
862
|
+
.then((skills) => ({ target, skills, err: null }))
|
|
863
|
+
.catch((err) => ({ target, skills: [], err: err?.message || String(err) })),
|
|
864
|
+
);
|
|
865
|
+
// Race the whole batch against the overall budget. Settled-promises
|
|
866
|
+
// contribute their results; un-settled count as errors (LOUD already by helper).
|
|
867
|
+
let settled;
|
|
868
|
+
try {
|
|
869
|
+
settled = await Promise.race([
|
|
870
|
+
Promise.allSettled(promises),
|
|
871
|
+
new Promise((r) => setTimeout(() => r('budget_exceeded'), Math.max(50, overallDeadline - Date.now()))),
|
|
872
|
+
]);
|
|
873
|
+
} catch {
|
|
874
|
+
settled = 'budget_exceeded';
|
|
875
|
+
}
|
|
876
|
+
if (settled === 'budget_exceeded') {
|
|
877
|
+
process.stderr.write(`[aria-pre-emit-autoload:atlas-orchestrator] LOUD budget_exceeded overall_ms=${ATLAS_DOSSIER_OVERALL_BUDGET_MS} targets=${targets.length}\n`);
|
|
878
|
+
out.targetsErr = targets.length;
|
|
879
|
+
out.durationMs = Date.now() - started;
|
|
880
|
+
return out;
|
|
881
|
+
}
|
|
882
|
+
for (const entry of settled) {
|
|
883
|
+
if (entry.status !== 'fulfilled' || !entry.value) {
|
|
884
|
+
out.targetsErr++;
|
|
885
|
+
continue;
|
|
886
|
+
}
|
|
887
|
+
const v = entry.value;
|
|
888
|
+
if (v.err) {
|
|
889
|
+
out.targetsErr++;
|
|
890
|
+
continue;
|
|
891
|
+
}
|
|
892
|
+
out.targetsResolved++;
|
|
893
|
+
for (const s of v.skills || []) {
|
|
894
|
+
if (typeof s !== 'string' || !s.trim()) continue;
|
|
895
|
+
if (!seenSkills.has(s)) {
|
|
896
|
+
seenSkills.add(s);
|
|
897
|
+
out.governingSkills.push(s);
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
out.durationMs = Date.now() - started;
|
|
902
|
+
return out;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
// AI-11803-STEP5 — extract keywords from prompt for cookbook scoring.
|
|
906
|
+
// Lowercase, tokenize on non-word characters, filter to length ≥ 4, dedup.
|
|
907
|
+
// Returns Set<string> for O(1) membership check in section scoring.
|
|
908
|
+
function extractPromptKeywords(promptText) {
|
|
909
|
+
if (!promptText || typeof promptText !== 'string') return new Set();
|
|
910
|
+
const tokens = promptText.toLowerCase().split(/[^a-z0-9_-]+/);
|
|
911
|
+
const keywords = new Set();
|
|
912
|
+
for (const t of tokens) {
|
|
913
|
+
if (t.length >= COOKBOOK_KEYWORD_MIN_LEN) keywords.add(t);
|
|
914
|
+
}
|
|
915
|
+
return keywords;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
// AI-11803-STEP5 — scan a loaded skill body for `references/<name>.md`
|
|
919
|
+
// patterns and resolve to absolute paths under the skill's references/
|
|
920
|
+
// directory. Returns array of { skill, cookbookName, absPath }, dedup by
|
|
921
|
+
// absPath so two skills referencing the same cookbook only enqueue it once.
|
|
922
|
+
function discoverCookbookReferences(skillBodies) {
|
|
923
|
+
const found = [];
|
|
924
|
+
const seenPaths = new Set();
|
|
925
|
+
for (const entry of skillBodies) {
|
|
926
|
+
if (!entry.body || typeof entry.body !== 'string') continue;
|
|
927
|
+
COOKBOOK_REF_RX.lastIndex = 0;
|
|
928
|
+
let m;
|
|
929
|
+
while ((m = COOKBOOK_REF_RX.exec(entry.body)) !== null) {
|
|
930
|
+
const crossSkillName = m[1]; // may be undefined for same-skill refs
|
|
931
|
+
const cookbookName = m[2];
|
|
932
|
+
// Resolve to the correct skill directory: cross-skill targets the
|
|
933
|
+
// named other skill; otherwise stays in the source skill's own dir.
|
|
934
|
+
const resolvedSkill = crossSkillName || entry.skill;
|
|
935
|
+
const absPath = `${SKILLS_DIR}/${resolvedSkill}/references/${cookbookName}`;
|
|
936
|
+
if (seenPaths.has(absPath)) continue;
|
|
937
|
+
if (!existsSync(absPath)) continue;
|
|
938
|
+
seenPaths.add(absPath);
|
|
939
|
+
found.push({
|
|
940
|
+
skill: entry.skill,
|
|
941
|
+
referencedSkill: resolvedSkill,
|
|
942
|
+
cookbookName,
|
|
943
|
+
absPath,
|
|
944
|
+
crossSkill: !!crossSkillName,
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
return found;
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// AI-11803-STEP5 — parse a cookbook into sections by `## ` and `### `
|
|
952
|
+
// headers. Each section = { level, title, headerLine, bodyStart, bodyEnd }
|
|
953
|
+
// where bodyEnd is the byte-offset of the next header (or end of file).
|
|
954
|
+
// Returns sections array in document order.
|
|
955
|
+
function parseCookbookSections(cookbookText) {
|
|
956
|
+
const sections = [];
|
|
957
|
+
const lines = cookbookText.split('\n');
|
|
958
|
+
// Build line offsets so we can map header line index → byte offset.
|
|
959
|
+
const lineOffsets = [0];
|
|
960
|
+
for (let i = 0; i < lines.length - 1; i++) {
|
|
961
|
+
lineOffsets.push(lineOffsets[i] + Buffer.byteLength(lines[i], 'utf8') + 1); // +1 for \n
|
|
962
|
+
}
|
|
963
|
+
const totalBytes = Buffer.byteLength(cookbookText, 'utf8');
|
|
964
|
+
// First pass: collect header positions.
|
|
965
|
+
const headerPositions = [];
|
|
966
|
+
for (let i = 0; i < lines.length; i++) {
|
|
967
|
+
const headerMatch = lines[i].match(/^(#{2,3})\s+(.+?)\s*$/);
|
|
968
|
+
if (headerMatch) {
|
|
969
|
+
headerPositions.push({
|
|
970
|
+
level: headerMatch[1].length,
|
|
971
|
+
title: headerMatch[2],
|
|
972
|
+
lineIdx: i,
|
|
973
|
+
byteOffset: lineOffsets[i],
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
// Second pass: build sections with bodyEnd = next header byteOffset.
|
|
978
|
+
for (let i = 0; i < headerPositions.length; i++) {
|
|
979
|
+
const h = headerPositions[i];
|
|
980
|
+
const next = headerPositions[i + 1];
|
|
981
|
+
sections.push({
|
|
982
|
+
level: h.level,
|
|
983
|
+
title: h.title,
|
|
984
|
+
headerByteOffset: h.byteOffset,
|
|
985
|
+
bodyEnd: next ? next.byteOffset : totalBytes,
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
return sections;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
// AI-11803-STEP5 — score a section by counting distinct prompt keywords
|
|
992
|
+
// in its body text. Deterministic, observable. Returns integer.
|
|
993
|
+
function scoreSectionByKeywords(cookbookText, section, promptKeywords) {
|
|
994
|
+
if (promptKeywords.size === 0) return 0;
|
|
995
|
+
const sectionText = cookbookText
|
|
996
|
+
.slice(section.headerByteOffset, section.bodyEnd)
|
|
997
|
+
.toLowerCase();
|
|
998
|
+
let score = 0;
|
|
999
|
+
for (const kw of promptKeywords) {
|
|
1000
|
+
if (sectionText.includes(kw)) score++;
|
|
1001
|
+
}
|
|
1002
|
+
return score;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
// AI-11803-STEP5 — pick the top-1 section for a cookbook by keyword score.
|
|
1006
|
+
// Returns { section, score, extracted } or null if no section meets the
|
|
1007
|
+
// min-score threshold. extracted is the section text capped at
|
|
1008
|
+
// MAX_BYTES_PER_COOKBOOK_SECTION with a truncation marker if needed.
|
|
1009
|
+
function selectTopSectionForCookbook(cookbookText, sections, promptKeywords) {
|
|
1010
|
+
let best = null;
|
|
1011
|
+
for (const sec of sections) {
|
|
1012
|
+
const score = scoreSectionByKeywords(cookbookText, sec, promptKeywords);
|
|
1013
|
+
if (score < COOKBOOK_MIN_SCORE) continue;
|
|
1014
|
+
// Tie-break: later position wins (later sections often more refined).
|
|
1015
|
+
if (best === null || score > best.score || (score === best.score && sec.headerByteOffset > best.section.headerByteOffset)) {
|
|
1016
|
+
best = { section: sec, score };
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
if (!best) return null;
|
|
1020
|
+
let extracted = cookbookText.slice(best.section.headerByteOffset, best.section.bodyEnd).trimEnd();
|
|
1021
|
+
if (Buffer.byteLength(extracted, 'utf8') > MAX_BYTES_PER_COOKBOOK_SECTION) {
|
|
1022
|
+
const buf = Buffer.from(extracted, 'utf8').slice(0, MAX_BYTES_PER_COOKBOOK_SECTION);
|
|
1023
|
+
extracted = buf.toString('utf8');
|
|
1024
|
+
const lastBreak = Math.max(extracted.lastIndexOf('\n\n'), extracted.lastIndexOf('\n'));
|
|
1025
|
+
if (lastBreak > MAX_BYTES_PER_COOKBOOK_SECTION * 0.6) extracted = extracted.slice(0, lastBreak);
|
|
1026
|
+
extracted += `\n[…section truncated at ${MAX_BYTES_PER_COOKBOOK_SECTION}B; full section available in source file…]`;
|
|
1027
|
+
}
|
|
1028
|
+
return { section: best.section, score: best.score, extracted };
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
// AI-11803-STEP5 — orchestrate cookbook discovery + selection + injection.
|
|
1032
|
+
// Returns { injected: [{ skill, cookbookName, absPath, sectionTitle,
|
|
1033
|
+
// score, bytes }], totalBytes, scannedCount, skippedBelowThreshold,
|
|
1034
|
+
// errors }. Never throws; on any file-read error, the cookbook is
|
|
1035
|
+
// recorded as skipped with the error reason.
|
|
1036
|
+
function autoloadCookbookSections(skillBodies, promptKeywords) {
|
|
1037
|
+
if (/^(?:1|true|yes|on)$/i.test(String(process.env.ARIA_AUTOLOAD_COOKBOOK_OFF || ''))) {
|
|
1038
|
+
return { injected: [], totalBytes: 0, scannedCount: 0, skippedBelowThreshold: [], errors: [], skipped: 'env-disabled' };
|
|
1039
|
+
}
|
|
1040
|
+
const refs = discoverCookbookReferences(skillBodies);
|
|
1041
|
+
const injected = [];
|
|
1042
|
+
const skippedBelowThreshold = [];
|
|
1043
|
+
const errors = [];
|
|
1044
|
+
let totalBytes = 0;
|
|
1045
|
+
for (const ref of refs) {
|
|
1046
|
+
if (totalBytes >= MAX_BYTES_COOKBOOK_TOTAL) {
|
|
1047
|
+
skippedBelowThreshold.push({ ...ref, reason: 'total-budget-exhausted' });
|
|
1048
|
+
continue;
|
|
1049
|
+
}
|
|
1050
|
+
let lst;
|
|
1051
|
+
try { lst = lstatSync(ref.absPath); } catch (err) {
|
|
1052
|
+
errors.push(`lstat ${ref.cookbookName}: ${err?.message || err}`);
|
|
1053
|
+
continue;
|
|
1054
|
+
}
|
|
1055
|
+
if (!lst.isFile()) continue;
|
|
1056
|
+
if (lst.size > COOKBOOK_FILE_CEILING) {
|
|
1057
|
+
errors.push(`oversize ${ref.cookbookName}: ${lst.size}B > ${COOKBOOK_FILE_CEILING}B`);
|
|
1058
|
+
continue;
|
|
1059
|
+
}
|
|
1060
|
+
let raw;
|
|
1061
|
+
try { raw = readFileSync(ref.absPath, 'utf8'); } catch (err) {
|
|
1062
|
+
errors.push(`read ${ref.cookbookName}: ${err?.message || err}`);
|
|
1063
|
+
continue;
|
|
1064
|
+
}
|
|
1065
|
+
const sections = parseCookbookSections(raw);
|
|
1066
|
+
if (sections.length === 0) {
|
|
1067
|
+
skippedBelowThreshold.push({ ...ref, reason: 'no-sections-parsed' });
|
|
1068
|
+
continue;
|
|
1069
|
+
}
|
|
1070
|
+
const result = selectTopSectionForCookbook(raw, sections, promptKeywords);
|
|
1071
|
+
if (!result) {
|
|
1072
|
+
skippedBelowThreshold.push({ ...ref, reason: `no-section-met-min-score-${COOKBOOK_MIN_SCORE}` });
|
|
1073
|
+
continue;
|
|
1074
|
+
}
|
|
1075
|
+
const remainingBudget = MAX_BYTES_COOKBOOK_TOTAL - totalBytes;
|
|
1076
|
+
const extractedBytes = Buffer.byteLength(result.extracted, 'utf8');
|
|
1077
|
+
if (extractedBytes > remainingBudget) {
|
|
1078
|
+
skippedBelowThreshold.push({ ...ref, reason: `total-budget-would-overflow (${extractedBytes}B > ${remainingBudget}B remaining)` });
|
|
1079
|
+
continue;
|
|
1080
|
+
}
|
|
1081
|
+
injected.push({
|
|
1082
|
+
skill: ref.skill,
|
|
1083
|
+
cookbookName: ref.cookbookName,
|
|
1084
|
+
absPath: ref.absPath,
|
|
1085
|
+
sectionTitle: result.section.title,
|
|
1086
|
+
score: result.score,
|
|
1087
|
+
bytes: extractedBytes,
|
|
1088
|
+
extracted: result.extracted,
|
|
1089
|
+
});
|
|
1090
|
+
totalBytes += extractedBytes;
|
|
1091
|
+
}
|
|
1092
|
+
return { injected, totalBytes, scannedCount: refs.length, skippedBelowThreshold, errors, skipped: null };
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
function buildCookbookInjection({ result, promptKeywords }) {
|
|
1096
|
+
if (result.skipped === 'env-disabled') return '';
|
|
1097
|
+
if (result.injected.length === 0) {
|
|
1098
|
+
// Emit a low-information stub only when at least 1 cookbook was scanned
|
|
1099
|
+
// but none scored above threshold — surfaces signal that scoring fired
|
|
1100
|
+
// but selected nothing, so the agent knows cookbook context is empty
|
|
1101
|
+
// by design, not by error.
|
|
1102
|
+
if (result.scannedCount > 0) {
|
|
1103
|
+
return `═══ COOKBOOK AUTOLOAD (scanned ${result.scannedCount} cookbook(s); 0 section(s) met min-score=${COOKBOOK_MIN_SCORE}; ${promptKeywords.size} prompt keywords) ═══`;
|
|
1104
|
+
}
|
|
1105
|
+
return '';
|
|
1106
|
+
}
|
|
1107
|
+
const lines = [];
|
|
1108
|
+
lines.push(`═══ COOKBOOK AUTOLOAD (top-1 sections from ${result.injected.length} cookbook(s); deterministic keyword-overlap scoring) ═══`);
|
|
1109
|
+
for (const entry of result.injected) {
|
|
1110
|
+
lines.push('');
|
|
1111
|
+
lines.push(`──── ${entry.cookbookName} [section: "${entry.sectionTitle}" — score=${entry.score}] ────`);
|
|
1112
|
+
lines.push(entry.extracted);
|
|
1113
|
+
}
|
|
1114
|
+
return lines.join('\n');
|
|
1115
|
+
}
|
|
1116
|
+
|
|
1117
|
+
// AI-11803-F3 (2026-05-12) — read the parent handoff JSON if present
|
|
1118
|
+
// and within TTL. Returns the `parentAutoload` field (skill names,
|
|
1119
|
+
// memory filenames, cookbook section pointers) or null if absent / stale
|
|
1120
|
+
// / kill-switched / malformed.
|
|
1121
|
+
function readParentHandoffAutoload() {
|
|
1122
|
+
if (/^(?:1|true|yes|on)$/i.test(String(process.env.ARIA_AUTOLOAD_PARENT_HANDOFF_OFF || ''))) {
|
|
1123
|
+
return { result: null, skipped: 'env-disabled' };
|
|
1124
|
+
}
|
|
1125
|
+
if (!existsSync(PARENT_HANDOFF_PATH)) {
|
|
1126
|
+
return { result: null, skipped: 'no-handoff-file' };
|
|
1127
|
+
}
|
|
1128
|
+
let raw;
|
|
1129
|
+
try { raw = readFileSync(PARENT_HANDOFF_PATH, 'utf-8'); } catch (err) {
|
|
1130
|
+
process.stderr.write(`[aria-pre-emit-autoload:parent-handoff-read-error] ${err?.message || err}\n`);
|
|
1131
|
+
return { result: null, skipped: `read-error:${err?.message || err}` };
|
|
1132
|
+
}
|
|
1133
|
+
let parsed;
|
|
1134
|
+
try { parsed = JSON.parse(raw); } catch (err) {
|
|
1135
|
+
process.stderr.write(`[aria-pre-emit-autoload:parent-handoff-parse-error] ${err?.message || err}\n`);
|
|
1136
|
+
return { result: null, skipped: `parse-error:${err?.message || err}` };
|
|
1137
|
+
}
|
|
1138
|
+
// TTL check — if handoff older than ttlMs vs writtenAt, ignore.
|
|
1139
|
+
const ttlMs = Number(parsed.ttlMs) || (5 * 60 * 1000);
|
|
1140
|
+
const writtenAtMs = new Date(parsed.writtenAt || 0).getTime();
|
|
1141
|
+
if (Number.isFinite(writtenAtMs) && writtenAtMs > 0) {
|
|
1142
|
+
const ageMs = Date.now() - writtenAtMs;
|
|
1143
|
+
if (ageMs > ttlMs) {
|
|
1144
|
+
return { result: null, skipped: `stale:age=${Math.round(ageMs/1000)}s>ttl=${Math.round(ttlMs/1000)}s` };
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
const parentAutoload = parsed.parentAutoload;
|
|
1148
|
+
if (!parentAutoload || typeof parentAutoload !== 'object') {
|
|
1149
|
+
return { result: null, skipped: 'no-parentAutoload-field' };
|
|
1150
|
+
}
|
|
1151
|
+
return { result: parentAutoload, skipped: null, ageMs: Date.now() - writtenAtMs };
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// Default cognition vocabulary anchors the named-lens labels the
|
|
1155
|
+
// substrate-binding gate parses. Agents in the same session converge on
|
|
1156
|
+
// one vocabulary so emissions stay coherent across a turn.
|
|
1157
|
+
function chooseCognitionVocabulary() {
|
|
1158
|
+
return ['nur', 'mizan', 'hikma', 'tafakkur', 'tadabbur', 'ilham', 'wahi', 'firasah'];
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
// Stage 5 — cross-turn substrate feedback: read recent gate-block events
|
|
1162
|
+
// from the gate-ledger and surface them as next-turn FRAME content. This
|
|
1163
|
+
// turns past gate-blocks into structural pressure on the next turn so the
|
|
1164
|
+
// agent literally cannot drift the same way twice without seeing it.
|
|
1165
|
+
function readRecentGateBlocks({ maxAgeMinutes = 30, maxEntries = 8, sessionId = null } = {}) {
|
|
1166
|
+
const ledgerPath = `${HOME}/.claude/.aria-gate-ledger.jsonl`;
|
|
1167
|
+
if (!existsSync(ledgerPath)) return [];
|
|
1168
|
+
let raw;
|
|
1169
|
+
try {
|
|
1170
|
+
raw = readFileSync(ledgerPath, 'utf8');
|
|
1171
|
+
} catch {
|
|
1172
|
+
return [];
|
|
1173
|
+
}
|
|
1174
|
+
const lines = raw.split('\n').filter(Boolean);
|
|
1175
|
+
const recent = lines.slice(-300); // bound the parse cost
|
|
1176
|
+
const cutoff = Date.now() - maxAgeMinutes * 60 * 1000;
|
|
1177
|
+
const blocks = [];
|
|
1178
|
+
for (let i = recent.length - 1; i >= 0 && blocks.length < maxEntries; i--) {
|
|
1179
|
+
let entry;
|
|
1180
|
+
try { entry = JSON.parse(recent[i]); } catch { continue; }
|
|
1181
|
+
if (!entry || typeof entry !== 'object') continue;
|
|
1182
|
+
if (entry.decision !== 'block') continue;
|
|
1183
|
+
const t = Date.parse(entry.ts || '');
|
|
1184
|
+
if (!Number.isFinite(t) || t < cutoff) continue;
|
|
1185
|
+
if (sessionId && entry.sessionId && entry.sessionId !== sessionId) continue;
|
|
1186
|
+
blocks.push({
|
|
1187
|
+
ts: entry.ts,
|
|
1188
|
+
hook: entry.hook,
|
|
1189
|
+
source: entry.source,
|
|
1190
|
+
reason: entry.reasonShort || '(no reason)',
|
|
1191
|
+
});
|
|
1192
|
+
}
|
|
1193
|
+
return blocks;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
function buildFrameInjection({ requiredSkills, reasons, redirectOnly, cognitionVocab, skillBodies, totalBytes, recentBlocks = [] }) {
|
|
1197
|
+
if (!requiredSkills || requiredSkills.length === 0) {
|
|
1198
|
+
const lines = [`${HEADER_PREFIX} no doctrine-bound skills required for this prompt; standard cognition expected.`];
|
|
1199
|
+
if (recentBlocks && recentBlocks.length > 0) {
|
|
1200
|
+
lines.push('');
|
|
1201
|
+
lines.push('═══ STAGE 5 — RECENT GATE BLOCKS (cross-turn substrate feedback) ═══');
|
|
1202
|
+
lines.push(`Past ${recentBlocks.length} block(s) within last 30 minutes for this session — adjust this turn to NOT recur:`);
|
|
1203
|
+
for (const b of recentBlocks) {
|
|
1204
|
+
lines.push(` - [${b.hook}] ${b.source}: ${b.reason}`);
|
|
1205
|
+
}
|
|
1206
|
+
lines.push('Apply the lesson: same block reason in this turn means same drift pattern; address the root, not the surface.');
|
|
1207
|
+
}
|
|
1208
|
+
return lines.join('\n');
|
|
1209
|
+
}
|
|
1210
|
+
const lines = [];
|
|
1211
|
+
lines.push(`${HEADER_PREFIX} FRAME — required skills loaded for this turn (content below should shape your work BEFORE you draft).`);
|
|
1212
|
+
lines.push('');
|
|
1213
|
+
lines.push(`Required skills (${requiredSkills.length}): ${requiredSkills.join(', ')}`);
|
|
1214
|
+
if (reasons.length > 0) {
|
|
1215
|
+
lines.push('Why these skills:');
|
|
1216
|
+
for (const reason of reasons) lines.push(` - ${reason}`);
|
|
1217
|
+
}
|
|
1218
|
+
lines.push('');
|
|
1219
|
+
lines.push(`Total injected: ${totalBytes}B across ${skillBodies.filter(s => s.bytes > 0).length} skill(s).`);
|
|
1220
|
+
lines.push('');
|
|
1221
|
+
lines.push('═══ SKILL BODIES (operative content — apply, do not narrate) ═══');
|
|
1222
|
+
lines.push('');
|
|
1223
|
+
for (const entry of skillBodies) {
|
|
1224
|
+
if (entry.bytes === 0) {
|
|
1225
|
+
if (entry.reason !== 'missing' && entry.reason !== 'ok') {
|
|
1226
|
+
lines.push(`──── ${entry.skill} ──── [SKIPPED: ${entry.reason}]`);
|
|
1227
|
+
lines.push('');
|
|
1228
|
+
}
|
|
1229
|
+
continue;
|
|
1230
|
+
}
|
|
1231
|
+
lines.push(`──── ${entry.skill}${entry.truncated ? ' (truncated)' : ''} ────`);
|
|
1232
|
+
lines.push(entry.body);
|
|
1233
|
+
lines.push('');
|
|
1234
|
+
}
|
|
1235
|
+
lines.push('═══ END SKILL BODIES ═══');
|
|
1236
|
+
lines.push('');
|
|
1237
|
+
lines.push('═══ DRIVING RULES (apply during work) ═══');
|
|
1238
|
+
lines.push('- Each skill above carries operative rules. Apply them as you draft, edit, and tool-call.');
|
|
1239
|
+
lines.push('- Do NOT emit lens blocks as ceremony at end-of-turn. The lens IS the thinking that already happened.');
|
|
1240
|
+
lines.push('- If a skill names a doctrine memory, treat it as an active constraint, not a citation.');
|
|
1241
|
+
lines.push('- If two skills conflict, the more specific one (e.g., aria-harness-deploy) outranks the general (e.g., aria-forge-guardrails).');
|
|
1242
|
+
lines.push('');
|
|
1243
|
+
lines.push('═══ COGNITION VOCABULARY ═══');
|
|
1244
|
+
lines.push(`Use these named lenses for substantive emissions: ${cognitionVocab.join(', ')}`);
|
|
1245
|
+
lines.push('Per substantive action emit:');
|
|
1246
|
+
lines.push(' <cognition> with all 8 named lenses (≥20 chars per lens, anchored to substrate)');
|
|
1247
|
+
lines.push(' <expected> with measurable predicate');
|
|
1248
|
+
lines.push(' <applied_cognition> with decision_delta + dominant_domain + binds_to + expected_predicate + artifact_change');
|
|
1249
|
+
lines.push('');
|
|
1250
|
+
lines.push('═══ POST-QA CRITERIA (verify before completion claim) ═══');
|
|
1251
|
+
lines.push('- Did at least one substrate change as a result of cognition firing?');
|
|
1252
|
+
lines.push('- Is every readiness/completion word ("done", "fixed", "shipped", "verified") backed by tool-output evidence?');
|
|
1253
|
+
lines.push('- Does the closing prose match output discipline (no raw IPs/SHAs/file-paths in chat; semantic reframing applied)?');
|
|
1254
|
+
lines.push('- Are unresolved discoveries either fixed-now or tracked-as-task before turn end?');
|
|
1255
|
+
lines.push('');
|
|
1256
|
+
lines.push('═══ PHASE 2 ORCHESTRATION MANIFEST CONTRACT ═══');
|
|
1257
|
+
lines.push('For substantive turns, emit an OrchestrationManifest_v1 alongside the response so downstream hooks consume typed workflow/gate fields instead of prompt-keyword guesses.');
|
|
1258
|
+
lines.push('Accepted shape: <orchestration_manifest>{...JSON...}</orchestration_manifest> or a json-fenced object with schema_version:"v1".');
|
|
1259
|
+
lines.push('The manifest is the workflow-routing source: intent.workflow_skills_to_invoke names active workflows; gates.* names cognition/verification requirements; voice.* names response shape.');
|
|
1260
|
+
lines.push('No manifest means downstream hooks keep the strict legacy gate path.');
|
|
1261
|
+
if (redirectOnly) {
|
|
1262
|
+
lines.push('');
|
|
1263
|
+
lines.push('NOTE: redirectOnly mode — gate guides not hard-blocks. Treat guidance as quality bar, not skip-license.');
|
|
1264
|
+
}
|
|
1265
|
+
if (recentBlocks && recentBlocks.length > 0) {
|
|
1266
|
+
lines.push('');
|
|
1267
|
+
lines.push('═══ STAGE 5 — RECENT GATE BLOCKS (cross-turn substrate feedback) ═══');
|
|
1268
|
+
lines.push(`Past ${recentBlocks.length} block(s) within last 30 minutes for this session — adjust this turn to NOT recur:`);
|
|
1269
|
+
for (const b of recentBlocks) {
|
|
1270
|
+
lines.push(` - [${b.hook}] ${b.source}: ${b.reason}`);
|
|
1271
|
+
}
|
|
1272
|
+
lines.push('Apply the lesson: the same block reason in this turn means the same drift pattern; address the root, not the surface.');
|
|
1273
|
+
}
|
|
1274
|
+
return lines.join('\n');
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
// Canonical floor substrate that loads unconditionally for any non-empty
|
|
1278
|
+
// prompt. Step 6 removes autoload's prompt-keyword classifier from the
|
|
1279
|
+
// UserPromptSubmit path: workflow choice moves to the emitted manifest,
|
|
1280
|
+
// while this floor keeps evidence, doctrine, output, and source-trust rules
|
|
1281
|
+
// present before drafting.
|
|
1282
|
+
const CANONICAL_FLOOR_SKILLS = [
|
|
1283
|
+
'aria-cognition-autofire',
|
|
1284
|
+
'aria-first-class-operating-contract',
|
|
1285
|
+
'aria-harness-output-discipline',
|
|
1286
|
+
'aria-readable-output',
|
|
1287
|
+
'aria-repo-doctrine',
|
|
1288
|
+
'never-guess',
|
|
1289
|
+
];
|
|
1290
|
+
|
|
1291
|
+
// AI-11803-F5 (2026-05-12): active-workflow skill allow-list. These
|
|
1292
|
+
// skills have explicit "Required Workflow" / "Apply the pipeline" /
|
|
1293
|
+
// "TRIGGER for cognitive turn" imperatives in their bodies. Loading
|
|
1294
|
+
// them as context is NOT the same as running their workflow — the LLM
|
|
1295
|
+
// MUST invoke them via the Skill tool when their body is loaded.
|
|
1296
|
+
// See feedback_autoload_does_not_invoke_skills.md for the full Recovery
|
|
1297
|
+
// Contract (classification A/B/C/D, 5-per-turn cap, parent composition).
|
|
1298
|
+
// Maintenance protocol: review new skills' frontmatter for active-shape
|
|
1299
|
+
// signals; add to this list. False-positive operator-frustration → move
|
|
1300
|
+
// back to passive-substrate (default).
|
|
1301
|
+
// QA-FIX-1 (2026-05-12, qiyas Tadabbur EXCAVATE): allow-list expanded from
|
|
1302
|
+
// 5 to 8 after qiyas+tadabbur QA pass found 3 missing active-workflow
|
|
1303
|
+
// skills. ghazali-8lens has explicit Required Workflow + 8-lens validation
|
|
1304
|
+
// pipeline. aria-decision-mizan is active refusal-shape (refuses to choose
|
|
1305
|
+
// for owner, surfaces both options — active not passive). tafakkur has
|
|
1306
|
+
// explicit 5-lens contemplation workflow. Cap is per-TURN INVOCATION count
|
|
1307
|
+
// (5), not list size; list can grow as more active skills are identified.
|
|
1308
|
+
const ACTIVE_WORKFLOW_SKILLS = new Set([
|
|
1309
|
+
'tadabbur',
|
|
1310
|
+
'qiyas-analogy',
|
|
1311
|
+
'aria-cognition-batch',
|
|
1312
|
+
'mizan',
|
|
1313
|
+
'aria-forge-guardrails',
|
|
1314
|
+
'ghazali-8lens',
|
|
1315
|
+
'aria-decision-mizan',
|
|
1316
|
+
'tafakkur',
|
|
1317
|
+
]);
|
|
1318
|
+
const INVOCATION_CAP_PER_TURN = 5;
|
|
1319
|
+
|
|
1320
|
+
async function main() {
|
|
1321
|
+
const event = readEvent();
|
|
1322
|
+
const prompt = String(
|
|
1323
|
+
event.user_prompt ??
|
|
1324
|
+
event.userPrompt ??
|
|
1325
|
+
event.prompt ??
|
|
1326
|
+
event.text ??
|
|
1327
|
+
event.message ??
|
|
1328
|
+
''
|
|
1329
|
+
).trim();
|
|
1330
|
+
|
|
1331
|
+
// ARIA_AUTOLOAD_DISABLE is the proper kill switch for this hook
|
|
1332
|
+
// specifically. Use only when debugging the autoload itself. The
|
|
1333
|
+
// gates-off marker is for blocking gates, NOT for disabling content
|
|
1334
|
+
// enrichment — disabling enrichment is exactly what made cognition
|
|
1335
|
+
// ceremonial in the first place.
|
|
1336
|
+
if (/^(?:1|true|yes|on)$/i.test(String(process.env.ARIA_AUTOLOAD_DISABLE || ''))) {
|
|
1337
|
+
appendGateLedger({ hook: 'pre-emit-autoload', event: HOOK_EVENT_NAME, decision: 'bypass', source: 'pre-emit/autoload-disabled-env', reasonShort: 'ARIA_AUTOLOAD_DISABLE=1', sessionId: event.session_id });
|
|
1338
|
+
emitNoop('ARIA_AUTOLOAD_DISABLE=1');
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
if (!prompt) {
|
|
1342
|
+
appendGateLedger({ hook: 'pre-emit-autoload', event: HOOK_EVENT_NAME, decision: 'allow', source: 'pre-emit/empty-prompt', sessionId: event.session_id });
|
|
1343
|
+
emitNoop('empty user prompt');
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
const classified = {
|
|
1347
|
+
requiredSkills: [],
|
|
1348
|
+
recoveryMissing: [],
|
|
1349
|
+
reasons: ['Phase 2 manifest-mode autoload: canonical floor substrate loaded; workflow invocation is manifest-driven.'],
|
|
1350
|
+
redirectOnly: false,
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
const initialSkillSet = new Set();
|
|
1354
|
+
for (const s of CANONICAL_FLOOR_SKILLS) {
|
|
1355
|
+
if (existsSync(`${SKILLS_DIR}/${s}/SKILL.md`)) initialSkillSet.add(s);
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
// AI-11803-F3: parent-handoff substrate inheritance. If this autoload
|
|
1359
|
+
// is firing inside a sub-agent session, layer the parent's pinned
|
|
1360
|
+
// skill names into the load set BEFORE cascade expansion. Sub-agent's
|
|
1361
|
+
// own classifier output is preserved (already in initialSkillSet);
|
|
1362
|
+
// parent pins are additive — sub-agent sees its own narrow-prompt
|
|
1363
|
+
// skills + the parent's broader doctrine context.
|
|
1364
|
+
const parentHandoffRead = readParentHandoffAutoload();
|
|
1365
|
+
const parentHandoff = parentHandoffRead.result;
|
|
1366
|
+
if (parentHandoff && Array.isArray(parentHandoff.requiredSkills)) {
|
|
1367
|
+
let inheritedCount = 0;
|
|
1368
|
+
for (const s of parentHandoff.requiredSkills) {
|
|
1369
|
+
if (typeof s !== 'string') continue;
|
|
1370
|
+
if (existsSync(`${SKILLS_DIR}/${s}/SKILL.md`) && !initialSkillSet.has(s)) {
|
|
1371
|
+
initialSkillSet.add(s);
|
|
1372
|
+
inheritedCount++;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
process.stderr.write(`[aria-pre-emit-autoload:parent-handoff-inherited] skills=${inheritedCount} memories=${(parentHandoff.memoryFilenames||[]).length} cookbooks=${(parentHandoff.cookbookSelections||[]).length} ageMs=${parentHandoffRead.ageMs}\n`);
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
const cognitionVocab = chooseCognitionVocabulary();
|
|
1379
|
+
|
|
1380
|
+
// AI-11803-LOOP1 (2026-05-12) — cascade expansion replaces the prior
|
|
1381
|
+
// single-pass body-injection loop. The cascade reads each skill body,
|
|
1382
|
+
// parses its Load First / Mode Selection / Load Order sections, and
|
|
1383
|
+
// recursively enqueues the named skills (existence-filtered, cycle-safe,
|
|
1384
|
+
// budget-capped). Final requiredSkills reflects the FULL loaded set so
|
|
1385
|
+
// sidecar + ledger downstream consumers see what actually ran in context.
|
|
1386
|
+
const cascade = expandSkillCascade([...initialSkillSet]);
|
|
1387
|
+
|
|
1388
|
+
// A5 (2026-05-18) — atlas-as-orchestrator: query the atlas daemon for
|
|
1389
|
+
// per-file governing_skills against path-shape tokens harvested from the
|
|
1390
|
+
// prompt. Unioned into cascade BEFORE the kernel selection block so the
|
|
1391
|
+
// kernel sees a substrate already enriched by atlas's per-target knowledge.
|
|
1392
|
+
// Fail-open: if atlas socket is down or every target returns 404 the
|
|
1393
|
+
// manifest is unchanged from the cascade floor. Helper LOUD-on-fail per
|
|
1394
|
+
// feedback_no_silent_fail_open_in_hooks.md.
|
|
1395
|
+
let atlasOrchestrator = null;
|
|
1396
|
+
let atlasOrchestratorErr = null;
|
|
1397
|
+
try {
|
|
1398
|
+
const promptTargets = harvestPromptTargets(prompt);
|
|
1399
|
+
if (promptTargets.length > 0) {
|
|
1400
|
+
atlasOrchestrator = await atlasGoverningSkillsForPrompt(promptTargets);
|
|
1401
|
+
let unionedByDossier = 0;
|
|
1402
|
+
for (const s of atlasOrchestrator.governingSkills) {
|
|
1403
|
+
if (typeof s !== 'string') continue;
|
|
1404
|
+
if (cascade.order.includes(s)) continue;
|
|
1405
|
+
if (existsSync(`${SKILLS_DIR}/${s}/SKILL.md`)) {
|
|
1406
|
+
cascade.order.push(s);
|
|
1407
|
+
unionedByDossier++;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
atlasOrchestrator.targetsHarvested = promptTargets.length;
|
|
1411
|
+
atlasOrchestrator.unionedByDossier = unionedByDossier;
|
|
1412
|
+
process.stderr.write(`[aria-pre-emit-autoload:atlas-orchestrator] targets=${promptTargets.length} resolved=${atlasOrchestrator.targetsResolved} err=${atlasOrchestrator.targetsErr} governingSkills=${atlasOrchestrator.governingSkills.length} unioned=${unionedByDossier} durationMs=${atlasOrchestrator.durationMs}\n`);
|
|
1413
|
+
} else {
|
|
1414
|
+
atlasOrchestrator = { governingSkills: [], targetsHarvested: 0, targetsResolved: 0, targetsErr: 0, unionedByDossier: 0, durationMs: 0 };
|
|
1415
|
+
}
|
|
1416
|
+
} catch (err) {
|
|
1417
|
+
atlasOrchestratorErr = err?.message || String(err);
|
|
1418
|
+
process.stderr.write(`[aria-pre-emit-autoload:atlas-orchestrator-fallback] LOUD-fail err=${atlasOrchestratorErr} — falling back to cascade+kernel-only manifest\n`);
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
// A3 + A4 (2026-05-17) — atlas-driven skill selection feeds back into the
|
|
1422
|
+
// cascade BEFORE the requiredSkills publish. Kernel sees observation kind,
|
|
1423
|
+
// prior end-phase court verdicts (A4 loop), and returns selectedSkillIds.
|
|
1424
|
+
// UNIONed into cascade.order (additive — never replaces the cascade floor)
|
|
1425
|
+
// so the manifest carries both the doctrinal floor + atlas's per-turn
|
|
1426
|
+
// reinforcement. Failure path: LOUD-stderr + fall back to cascade-only.
|
|
1427
|
+
let atlasSelection = null;
|
|
1428
|
+
let atlasSelectionErr = null;
|
|
1429
|
+
try {
|
|
1430
|
+
const priorCourtVerdicts = readRecentCourtVerdicts();
|
|
1431
|
+
const observationKind = (() => {
|
|
1432
|
+
const cls = classified?.taskClass || classified?.kind || '';
|
|
1433
|
+
if (typeof cls !== 'string') return 'default';
|
|
1434
|
+
// Map autoload's task class vocabulary onto kernel SKILL_SELECTION_MAP keys.
|
|
1435
|
+
// Conservative: known kinds pass through; everything else hits 'default'
|
|
1436
|
+
// (kernel handles unknown keys via its own default branch).
|
|
1437
|
+
if (['output_emit', 'goal_contract_eval', 'edit', 'deploy', 'sensitive_artifact_in_tool_input'].includes(cls)) return cls;
|
|
1438
|
+
return 'default';
|
|
1439
|
+
})();
|
|
1440
|
+
const compilation = compileCognitiveOptions({
|
|
1441
|
+
kind: observationKind,
|
|
1442
|
+
source: 'aria-pre-emit-autoload',
|
|
1443
|
+
summary: 'turn-start skill+runtime selection (A3/A4 autofire)',
|
|
1444
|
+
attrs: {
|
|
1445
|
+
surface: 'claude-code',
|
|
1446
|
+
priorCourtVerdictsCount: priorCourtVerdicts.length,
|
|
1447
|
+
},
|
|
1448
|
+
priorCourtVerdicts,
|
|
1449
|
+
evidence: priorCourtVerdicts.map((v, idx) => ({
|
|
1450
|
+
kind: 'prior_court_verdict',
|
|
1451
|
+
id: `court_${idx}`,
|
|
1452
|
+
value: v.verdict,
|
|
1453
|
+
at: v.at,
|
|
1454
|
+
})),
|
|
1455
|
+
});
|
|
1456
|
+
atlasSelection = {
|
|
1457
|
+
selectedSkillIds: Array.isArray(compilation?.selectedSkillIds) ? compilation.selectedSkillIds : [],
|
|
1458
|
+
selectedRuntimeIds: Array.isArray(compilation?.selectedRuntimeIds) ? compilation.selectedRuntimeIds : [],
|
|
1459
|
+
selectionMeta: compilation?.selectionMeta || null,
|
|
1460
|
+
compilation_hash: compilation?.compilation_hash || null,
|
|
1461
|
+
observationKind,
|
|
1462
|
+
priorCourtVerdictCount: priorCourtVerdicts.length,
|
|
1463
|
+
};
|
|
1464
|
+
// UNION: add kernel-selected skills that exist on disk + aren't already cascaded
|
|
1465
|
+
let unioned = 0;
|
|
1466
|
+
for (const s of atlasSelection.selectedSkillIds) {
|
|
1467
|
+
if (typeof s !== 'string') continue;
|
|
1468
|
+
if (cascade.order.includes(s)) continue;
|
|
1469
|
+
if (existsSync(`${SKILLS_DIR}/${s}/SKILL.md`)) {
|
|
1470
|
+
cascade.order.push(s);
|
|
1471
|
+
unioned++;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
atlasSelection.unionedSkillCount = unioned;
|
|
1475
|
+
process.stderr.write(`[aria-pre-emit-autoload:atlas-selection] kind=${atlasSelection.observationKind} selected=${atlasSelection.selectedSkillIds.length} runtimes=${atlasSelection.selectedRuntimeIds.length} unioned=${unioned} courtFeedback=${Boolean(atlasSelection.selectionMeta?.courtFeedbackApplied)} priorVerdicts=${atlasSelection.priorCourtVerdictCount} hash=${(atlasSelection.compilation_hash || '').slice(0, 12)}\n`);
|
|
1476
|
+
} catch (err) {
|
|
1477
|
+
atlasSelectionErr = err?.message || String(err);
|
|
1478
|
+
process.stderr.write(`[aria-pre-emit-autoload:atlas-selection-fallback] LOUD-fail err=${atlasSelectionErr} — falling back to cascade-only manifest (no behavior change vs pre-A3 baseline)\n`);
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
classified.requiredSkills = [...new Set(cascade.order)].sort();
|
|
1482
|
+
const skillBodies = cascade.order.map((skill) => ({ skill, ...cascade.loadedBodies.get(skill) }));
|
|
1483
|
+
const totalBytes = cascade.totalBytes;
|
|
1484
|
+
const cascadeDepth = cascade.cascadeDepth;
|
|
1485
|
+
const depthInjected = cascade.depthInjected;
|
|
1486
|
+
const depthAttempted = cascade.depthAttempted;
|
|
1487
|
+
const cascadedSkills = cascade.order.filter((s) => !initialSkillSet.has(s));
|
|
1488
|
+
|
|
1489
|
+
// AI-11803-LOOP2: doctrine-trigger pre-emit scan. Matches the prompt
|
|
1490
|
+
// against the 79-trigger map. Computed here (before sidecar+ledger writes)
|
|
1491
|
+
// so its results land in the meta + sidecar telemetry too.
|
|
1492
|
+
const doctrineScan = scanDoctrineTriggers(prompt);
|
|
1493
|
+
|
|
1494
|
+
// AI-11803-F5 (2026-05-12) — compute invocationRequired set: which of
|
|
1495
|
+
// the loaded skills this turn are active-workflow (Skill tool MUST be
|
|
1496
|
+
// called) vs passive-substrate (body-as-context is sufficient). Capped
|
|
1497
|
+
// at INVOCATION_CAP_PER_TURN to prevent operator-overhead from too many
|
|
1498
|
+
// sequential invocations. The list is surfaced to the LLM via a
|
|
1499
|
+
// dedicated additionalContext section AND persisted to sidecar so the
|
|
1500
|
+
// future F5.c stop-gate can verify the named skills were actually
|
|
1501
|
+
// invoked before turn-close.
|
|
1502
|
+
//
|
|
1503
|
+
// QA-FIX-2 (2026-05-12): source the candidate skills from cascade.order
|
|
1504
|
+
// (the FINAL loaded set after cascade expansion) instead of
|
|
1505
|
+
// classified.requiredSkills (initial classifier output). Cascade can
|
|
1506
|
+
// pull active-workflow skills depth-N (e.g. aria-cognition-batch in
|
|
1507
|
+
// initial set loads tadabbur via Load First section); those depth-N
|
|
1508
|
+
// active skills must also appear in invocationRequired or the contract
|
|
1509
|
+
// misses them.
|
|
1510
|
+
//
|
|
1511
|
+
// QA-FIX-3 (2026-05-12): include parent-handoff inherited active skills
|
|
1512
|
+
// so sub-agents continue to honor the parent's invocation requirements
|
|
1513
|
+
// even when the sub-agent's own classifier didn't trigger them.
|
|
1514
|
+
const invocationRequiredSet = new Set();
|
|
1515
|
+
for (const skill of cascade.order) {
|
|
1516
|
+
if (invocationRequiredSet.size >= INVOCATION_CAP_PER_TURN) break;
|
|
1517
|
+
if (ACTIVE_WORKFLOW_SKILLS.has(skill)) invocationRequiredSet.add(skill);
|
|
1518
|
+
}
|
|
1519
|
+
if (parentHandoff && Array.isArray(parentHandoff.invocationRequired)) {
|
|
1520
|
+
for (const skill of parentHandoff.invocationRequired) {
|
|
1521
|
+
if (invocationRequiredSet.size >= INVOCATION_CAP_PER_TURN) break;
|
|
1522
|
+
if (typeof skill === 'string' && ACTIVE_WORKFLOW_SKILLS.has(skill)) {
|
|
1523
|
+
invocationRequiredSet.add(skill);
|
|
1524
|
+
}
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
// A5 (2026-05-18) — atlas-orchestrator + kernel-class selections force-add
|
|
1528
|
+
// to invocationRequired regardless of ACTIVE_WORKFLOW_SKILLS membership.
|
|
1529
|
+
// Atlas's per-turn selection IS the trigger; pre-tool-gate enforces these
|
|
1530
|
+
// as a floor before any Bash/Edit/Write/NotebookEdit. Closes the
|
|
1531
|
+
// mechanical-firing gap surfaced by feedback_substrate_load_session_violation
|
|
1532
|
+
// _2026_05_14.md (substrate loaded, invocation absent). Cap honored.
|
|
1533
|
+
const atlasForceInvoke = [];
|
|
1534
|
+
if (atlasOrchestrator && Array.isArray(atlasOrchestrator.governingSkills)) {
|
|
1535
|
+
for (const s of atlasOrchestrator.governingSkills) {
|
|
1536
|
+
if (invocationRequiredSet.size >= INVOCATION_CAP_PER_TURN) break;
|
|
1537
|
+
if (typeof s !== 'string' || !s.trim()) continue;
|
|
1538
|
+
if (invocationRequiredSet.has(s)) continue;
|
|
1539
|
+
if (existsSync(`${SKILLS_DIR}/${s}/SKILL.md`)) {
|
|
1540
|
+
invocationRequiredSet.add(s);
|
|
1541
|
+
atlasForceInvoke.push({ source: 'atlas-dossier', skill: s });
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
if (atlasSelection && Array.isArray(atlasSelection.selectedSkillIds)) {
|
|
1546
|
+
for (const s of atlasSelection.selectedSkillIds) {
|
|
1547
|
+
if (invocationRequiredSet.size >= INVOCATION_CAP_PER_TURN) break;
|
|
1548
|
+
if (typeof s !== 'string' || !s.trim()) continue;
|
|
1549
|
+
if (invocationRequiredSet.has(s)) continue;
|
|
1550
|
+
if (existsSync(`${SKILLS_DIR}/${s}/SKILL.md`)) {
|
|
1551
|
+
invocationRequiredSet.add(s);
|
|
1552
|
+
atlasForceInvoke.push({ source: 'atlas-kernel-class', skill: s });
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
}
|
|
1556
|
+
// A5 hardening loop — read prior-turn atlas-orchestrator hardening
|
|
1557
|
+
// directives from the hive WAL. Each directive lists skills that were
|
|
1558
|
+
// selected-by-atlas the prior turn but NOT invoked (adherence gap) OR
|
|
1559
|
+
// were ordered re-invoked because the QA court verdict was below
|
|
1560
|
+
// verified. Force-add to invocationRequired this turn. Same cap.
|
|
1561
|
+
const hardeningDirectives = readRecentHardeningDirectives();
|
|
1562
|
+
for (const directive of hardeningDirectives) {
|
|
1563
|
+
if (invocationRequiredSet.size >= INVOCATION_CAP_PER_TURN) break;
|
|
1564
|
+
for (const s of directive.forceInvokeNextTurn || []) {
|
|
1565
|
+
if (invocationRequiredSet.size >= INVOCATION_CAP_PER_TURN) break;
|
|
1566
|
+
if (typeof s !== 'string' || !s.trim()) continue;
|
|
1567
|
+
if (invocationRequiredSet.has(s)) continue;
|
|
1568
|
+
if (existsSync(`${SKILLS_DIR}/${s}/SKILL.md`)) {
|
|
1569
|
+
invocationRequiredSet.add(s);
|
|
1570
|
+
atlasForceInvoke.push({ source: 'atlas-hardening-directive', skill: s, reason: directive.reason });
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
const invocationRequired = [...invocationRequiredSet];
|
|
1575
|
+
if (atlasForceInvoke.length > 0) {
|
|
1576
|
+
const sourceCounts = atlasForceInvoke.reduce((acc, e) => { acc[e.source] = (acc[e.source] || 0) + 1; return acc; }, {});
|
|
1577
|
+
process.stderr.write(`[aria-pre-emit-autoload:atlas-invocation-floor] forced=${atlasForceInvoke.length} bySource=${JSON.stringify(sourceCounts)} hardeningDirectivesRead=${hardeningDirectives.length}\n`);
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1580
|
+
// AI-11803-STEP4 (2026-05-12) — MEMORY.md auto-load + top-N body injection.
|
|
1581
|
+
// Dedup set: memories already injected via trigger-map this turn must not
|
|
1582
|
+
// double-inject as top-N bodies (would waste budget + repeat content).
|
|
1583
|
+
// QA-FIX-2 (2026-05-12): kill switch parity with cascade + trigger-map.
|
|
1584
|
+
// ARIA_AUTOLOAD_MEMORY_OFF=1 disables memory autoload while leaving the
|
|
1585
|
+
// other primitives running, for isolated debugging of this primitive.
|
|
1586
|
+
const memoryAutoloadDisabled = /^(?:1|true|yes|on)$/i.test(String(process.env.ARIA_AUTOLOAD_MEMORY_OFF || ''));
|
|
1587
|
+
const triggerMatchedMemories = new Set(doctrineScan.matches.map((m) => m.memory));
|
|
1588
|
+
const memoryIndexResult = memoryAutoloadDisabled
|
|
1589
|
+
? { body: '', bytes: 0, totalLines: 0, droppedLines: 0, reason: 'env-disabled' }
|
|
1590
|
+
: readMemoryIndex();
|
|
1591
|
+
const memoryBodyResult = memoryAutoloadDisabled
|
|
1592
|
+
? { injected: [], totalBytes: 0, dedupedFilenames: [], scoredCount: 0, errors: [] }
|
|
1593
|
+
: selectTopNMemoryBodies(triggerMatchedMemories);
|
|
1594
|
+
|
|
1595
|
+
// AI-11803-STEP5 (2026-05-12) — cookbook auto-pull from loaded skill bodies.
|
|
1596
|
+
// Scans skillBodies for `references/<name>.md` patterns, parses each
|
|
1597
|
+
// cookbook's sections, scores by prompt-keyword overlap, injects top-1
|
|
1598
|
+
// section per cookbook above min-score threshold. Same-turn dedup via
|
|
1599
|
+
// Set of absPath. Loop-safe: depth cap = 1 (cookbooks don't transitively
|
|
1600
|
+
// pull other cookbooks). Kill switch: ARIA_AUTOLOAD_COOKBOOK_OFF=1.
|
|
1601
|
+
const promptKeywords = extractPromptKeywords(prompt);
|
|
1602
|
+
const cookbookResult = autoloadCookbookSections(skillBodies, promptKeywords);
|
|
1603
|
+
const substrateOpen = await openRuntimeSubstrate({
|
|
1604
|
+
event,
|
|
1605
|
+
prompt,
|
|
1606
|
+
requiredSkills: classified.requiredSkills,
|
|
1607
|
+
});
|
|
1608
|
+
|
|
1609
|
+
const sidecar = {
|
|
1610
|
+
schema: 'aria-current-turn-context.v2',
|
|
1611
|
+
ts: new Date().toISOString(),
|
|
1612
|
+
sessionId: event.session_id ?? null,
|
|
1613
|
+
// AI-11803-F3: chain-depth marker — if this autoload inherited parent
|
|
1614
|
+
// handoff substrate, downstream Agent dispatch hook reads this and
|
|
1615
|
+
// SKIPS propagating to grandchild (chain depth cap = 1).
|
|
1616
|
+
parentHandoffChainDepth: parentHandoff ? 1 : 0,
|
|
1617
|
+
parentHandoffSkipped: parentHandoffRead.skipped,
|
|
1618
|
+
// AI-11803-F5: active-workflow skills that MUST be invoked via the
|
|
1619
|
+
// Skill tool this turn. Doctrine: feedback_autoload_does_not_invoke_skills.md.
|
|
1620
|
+
// The F5.c stop-gate (future step) reads this and verifies invocations
|
|
1621
|
+
// before turn-close.
|
|
1622
|
+
invocationRequired,
|
|
1623
|
+
promptHash: createHash('sha256').update(prompt).digest('hex').slice(0, 16),
|
|
1624
|
+
requiredSkills: classified.requiredSkills,
|
|
1625
|
+
redirectOnly: classified.redirectOnly === true,
|
|
1626
|
+
reasons: classified.reasons,
|
|
1627
|
+
cognitionVocabulary: cognitionVocab,
|
|
1628
|
+
injection: {
|
|
1629
|
+
totalBytes,
|
|
1630
|
+
perSkill: skillBodies.map(s => ({
|
|
1631
|
+
skill: s.skill,
|
|
1632
|
+
bytes: s.bytes,
|
|
1633
|
+
fullBytes: s.fullBytes,
|
|
1634
|
+
truncated: !!s.truncated,
|
|
1635
|
+
redacted: !!s.redacted,
|
|
1636
|
+
reason: s.reason,
|
|
1637
|
+
// First 600 chars of injected body so post-phase can verify what
|
|
1638
|
+
// was actually visible to the agent.
|
|
1639
|
+
excerpt: typeof s.body === 'string' ? s.body.slice(0, 600) : '',
|
|
1640
|
+
})),
|
|
1641
|
+
},
|
|
1642
|
+
memoryAutoload: {
|
|
1643
|
+
indexBytes: memoryIndexResult.bytes,
|
|
1644
|
+
indexReason: memoryIndexResult.reason,
|
|
1645
|
+
indexDroppedLines: memoryIndexResult.droppedLines,
|
|
1646
|
+
bodiesBytes: memoryBodyResult.totalBytes,
|
|
1647
|
+
bodiesInjected: memoryBodyResult.injected.map((e) => ({
|
|
1648
|
+
filename: e.filename, tier: e.tier, score: e.score, bytes: e.bytes,
|
|
1649
|
+
})),
|
|
1650
|
+
bodiesDeduped: memoryBodyResult.dedupedFilenames,
|
|
1651
|
+
scoredCount: memoryBodyResult.scoredCount,
|
|
1652
|
+
},
|
|
1653
|
+
cookbookAutoload: {
|
|
1654
|
+
scannedCount: cookbookResult.scannedCount,
|
|
1655
|
+
keywordCount: promptKeywords.size,
|
|
1656
|
+
totalBytes: cookbookResult.totalBytes,
|
|
1657
|
+
injected: cookbookResult.injected.map((e) => ({
|
|
1658
|
+
skill: e.skill,
|
|
1659
|
+
cookbookName: e.cookbookName,
|
|
1660
|
+
sectionTitle: e.sectionTitle,
|
|
1661
|
+
score: e.score,
|
|
1662
|
+
bytes: e.bytes,
|
|
1663
|
+
})),
|
|
1664
|
+
skippedBelowThreshold: cookbookResult.skippedBelowThreshold,
|
|
1665
|
+
skipped: cookbookResult.skipped,
|
|
1666
|
+
errors: cookbookResult.errors,
|
|
1667
|
+
},
|
|
1668
|
+
substrateOpen: substrateOpen.ok
|
|
1669
|
+
? {
|
|
1670
|
+
ok: true,
|
|
1671
|
+
workUnitId: substrateOpen.packet?.workUnitId,
|
|
1672
|
+
projectId: substrateOpen.packet?.projectId,
|
|
1673
|
+
threadId: substrateOpen.packet?.threadId,
|
|
1674
|
+
atlasStatus: substrateOpen.packet?.atlasFirstPrinciplesForgeReceipt?.atlas?.status,
|
|
1675
|
+
generativeAxiomCount: substrateOpen.packet?.atlasFirstPrinciplesForgeReceipt?.generativeAxiomCount,
|
|
1676
|
+
receiptHash: substrateOpen.packet?.receiptHash,
|
|
1677
|
+
}
|
|
1678
|
+
: {
|
|
1679
|
+
ok: false,
|
|
1680
|
+
status: substrateOpen.status,
|
|
1681
|
+
error: substrateOpen.error,
|
|
1682
|
+
},
|
|
1683
|
+
// A3 + A4 (2026-05-17) — kernel-class selection receipt persisted so
|
|
1684
|
+
// post-turn QA can verify deterministic skill-selection input/output.
|
|
1685
|
+
atlasSelection: atlasSelection || (atlasSelectionErr ? { error: atlasSelectionErr } : null),
|
|
1686
|
+
// A5 (2026-05-18) — atlas-as-orchestrator receipt. Per-turn governing-
|
|
1687
|
+
// skill resolution against atlas daemon dossier for path-shape prompt
|
|
1688
|
+
// targets. Empty when prompt has no path tokens; targetsErr > 0 indicates
|
|
1689
|
+
// the atlas daemon was unavailable for one or more lookups (LOUD-stderr
|
|
1690
|
+
// already emitted by atlas-dossier-client).
|
|
1691
|
+
atlasOrchestrator: atlasOrchestrator || (atlasOrchestratorErr ? { error: atlasOrchestratorErr } : null),
|
|
1692
|
+
};
|
|
1693
|
+
writeSidecar(sidecar);
|
|
1694
|
+
|
|
1695
|
+
appendGateLedger({
|
|
1696
|
+
hook: 'pre-emit-autoload',
|
|
1697
|
+
event: HOOK_EVENT_NAME,
|
|
1698
|
+
decision: 'allow',
|
|
1699
|
+
source: 'pre-emit/autoload',
|
|
1700
|
+
reasonShort: classified.requiredSkills.length > 0
|
|
1701
|
+
? `injected=${totalBytes}B skills=${classified.requiredSkills.join(',')}`
|
|
1702
|
+
: 'no doctrine-bound skills required',
|
|
1703
|
+
meta: {
|
|
1704
|
+
requiredSkills: classified.requiredSkills,
|
|
1705
|
+
redirectOnly: classified.redirectOnly === true,
|
|
1706
|
+
promptLen: prompt.length,
|
|
1707
|
+
injectedBytes: totalBytes,
|
|
1708
|
+
injectedSkills: skillBodies.filter(s => s.bytes > 0).map(s => s.skill),
|
|
1709
|
+
skippedSkills: skillBodies.filter(s => s.bytes === 0).map(s => ({ skill: s.skill, reason: s.reason })),
|
|
1710
|
+
cascadeDepth,
|
|
1711
|
+
depthInjected,
|
|
1712
|
+
depthAttempted,
|
|
1713
|
+
cascadedSkills,
|
|
1714
|
+
doctrineTriggerMatchCount: doctrineScan.matches.length,
|
|
1715
|
+
doctrineTriggersMatched: doctrineScan.matches.map((m) => m.trigger),
|
|
1716
|
+
doctrineTriggerSkipped: doctrineScan.skipped,
|
|
1717
|
+
memoryIndexBytes: memoryIndexResult.bytes,
|
|
1718
|
+
memoryIndexReason: memoryIndexResult.reason,
|
|
1719
|
+
memoryIndexDroppedLines: memoryIndexResult.droppedLines,
|
|
1720
|
+
memoryBodiesInjected: memoryBodyResult.injected.length,
|
|
1721
|
+
memoryBodiesInjectedBytes: memoryBodyResult.totalBytes,
|
|
1722
|
+
memoryBodiesScoredCount: memoryBodyResult.scoredCount,
|
|
1723
|
+
memoryBodiesDeduped: memoryBodyResult.dedupedFilenames,
|
|
1724
|
+
memoryBodiesSelected: memoryBodyResult.injected.map((e) => ({ filename: e.filename, tier: e.tier, bytes: e.bytes })),
|
|
1725
|
+
cookbookScannedCount: cookbookResult.scannedCount,
|
|
1726
|
+
cookbookInjectedCount: cookbookResult.injected.length,
|
|
1727
|
+
cookbookInjectedBytes: cookbookResult.totalBytes,
|
|
1728
|
+
cookbookKeywordCount: promptKeywords.size,
|
|
1729
|
+
cookbookSkippedReasons: cookbookResult.skippedBelowThreshold.map((s) => `${s.cookbookName}:${s.reason}`),
|
|
1730
|
+
cookbookSkipped: cookbookResult.skipped,
|
|
1731
|
+
invocationRequired,
|
|
1732
|
+
invocationRequiredCount: invocationRequired.length,
|
|
1733
|
+
substrateOpenOk: substrateOpen.ok === true,
|
|
1734
|
+
substrateWorkUnitId: substrateOpen.packet?.workUnitId || null,
|
|
1735
|
+
atlasFirstPrinciplesForgeHash: substrateOpen.packet?.atlasFirstPrinciplesForgeReceipt?.evidenceHash || null,
|
|
1736
|
+
},
|
|
1737
|
+
sessionId: event.session_id,
|
|
1738
|
+
});
|
|
1739
|
+
|
|
1740
|
+
// Stage 5: pull recent gate-blocks for this session so the agent sees
|
|
1741
|
+
// them as pre-flight FRAME context and cannot drift the same way twice.
|
|
1742
|
+
const recentBlocks = readRecentGateBlocks({ sessionId: event.session_id });
|
|
1743
|
+
|
|
1744
|
+
const doctrineInjection = buildDoctrineTriggerInjection(doctrineScan.matches);
|
|
1745
|
+
|
|
1746
|
+
const memoryInjection = buildMemoryAutoloadInjection({
|
|
1747
|
+
indexResult: memoryIndexResult,
|
|
1748
|
+
bodyResult: memoryBodyResult,
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
const frameInjection = buildFrameInjection({
|
|
1752
|
+
requiredSkills: classified.requiredSkills,
|
|
1753
|
+
reasons: classified.reasons,
|
|
1754
|
+
redirectOnly: classified.redirectOnly === true,
|
|
1755
|
+
cognitionVocab,
|
|
1756
|
+
skillBodies,
|
|
1757
|
+
totalBytes,
|
|
1758
|
+
recentBlocks,
|
|
1759
|
+
});
|
|
1760
|
+
|
|
1761
|
+
const cookbookInjection = buildCookbookInjection({
|
|
1762
|
+
result: cookbookResult,
|
|
1763
|
+
promptKeywords,
|
|
1764
|
+
});
|
|
1765
|
+
|
|
1766
|
+
// AI-11803-F5: INVOCATION REQUIRED section — make it explicit that
|
|
1767
|
+
// active-workflow skills loaded as bodies still need Skill tool
|
|
1768
|
+
// invocation. Doctrine drift if skipped (see
|
|
1769
|
+
// feedback_autoload_does_not_invoke_skills.md).
|
|
1770
|
+
let invocationInjection = '';
|
|
1771
|
+
if (invocationRequired.length > 0) {
|
|
1772
|
+
const lines = [];
|
|
1773
|
+
lines.push('═══ INVOCATION REQUIRED (active-workflow skills — body in context is NOT enough) ═══');
|
|
1774
|
+
lines.push(`The following loaded skills are ACTIVE-WORKFLOW. You MUST invoke each via the Skill tool BEFORE drafting substantive work this turn. Reading the body in context does NOT run the workflow.`);
|
|
1775
|
+
lines.push('');
|
|
1776
|
+
for (const skill of invocationRequired) {
|
|
1777
|
+
lines.push(` • ${skill}`);
|
|
1778
|
+
}
|
|
1779
|
+
lines.push('');
|
|
1780
|
+
lines.push('Doctrine: feedback_autoload_does_not_invoke_skills.md');
|
|
1781
|
+
lines.push('Recovery Contract — every loaded active-workflow skill closes the turn classified as:');
|
|
1782
|
+
lines.push(' A. INVOKED — Skill tool call visible in transcript');
|
|
1783
|
+
lines.push(' B. COMPOSED-VIA-PARENT — parent skill (e.g., aria-cognition-batch) invoked, child is a composition member');
|
|
1784
|
+
lines.push(' C. SCOPE-EXEMPT — prompt is read-only inspection of the skill body, not asking the workflow to run');
|
|
1785
|
+
lines.push(' D. CAP-DEFERRED — > 5 active-workflow skills loaded; deferred to follow-up');
|
|
1786
|
+
lines.push(`No other classifications permitted. "I considered it" / "it's loaded" / "substrate has it" = the antipattern.`);
|
|
1787
|
+
invocationInjection = lines.join('\n');
|
|
1788
|
+
}
|
|
1789
|
+
|
|
1790
|
+
const parts = [frameInjection];
|
|
1791
|
+
parts.push(buildSubstrateOpenInjection(substrateOpen));
|
|
1792
|
+
if (invocationInjection) parts.push(invocationInjection);
|
|
1793
|
+
if (doctrineInjection) parts.push(doctrineInjection);
|
|
1794
|
+
if (memoryInjection) parts.push(memoryInjection);
|
|
1795
|
+
if (cookbookInjection) parts.push(cookbookInjection);
|
|
1796
|
+
const additionalContext = parts.join('\n\n');
|
|
1797
|
+
|
|
1798
|
+
emit({
|
|
1799
|
+
hookSpecificOutput: {
|
|
1800
|
+
hookEventName: HOOK_EVENT_NAME,
|
|
1801
|
+
additionalContext,
|
|
1802
|
+
},
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
|
|
1806
|
+
main().catch((err) => {
|
|
1807
|
+
process.stderr.write(`[aria-pre-emit-autoload] ${err instanceof Error ? err.message : String(err)}\n`);
|
|
1808
|
+
emitNoop('fatal pre-emit autoload error');
|
|
1809
|
+
});
|