arkaos 4.3.1 → 4.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/VERSION +1 -1
- package/arka/SKILL.md +4 -4
- package/arka/skills/costs/SKILL.md +1 -1
- package/arka/skills/fusion/SKILL.md +3 -3
- package/bin/arka +225 -0
- package/bin/arka-claude +64 -0
- package/bin/arka-claude.cmd +11 -0
- package/bin/arka-claude.ps1 +126 -0
- package/bin/arka-doctor +391 -0
- package/bin/arka-providers +261 -0
- package/bin/arka-py +46 -0
- package/bin/arka-py.cmd +9 -0
- package/bin/arka-py.ps1 +36 -0
- package/bin/arka-registry-gen +185 -0
- package/bin/arka-skill +300 -0
- package/bin/scheduler-daemon.py +48 -0
- package/config/claude-agents/marta-cqo.md +1 -1
- package/config/claude-agents/paulo-tech-lead.md +1 -1
- package/config/constitution.yaml +5 -5
- package/config/hooks/_lib/arka_python.ps1 +43 -0
- package/config/hooks/_lib/arka_python.sh +63 -0
- package/config/hooks/agent-provision.sh +8 -1
- package/config/hooks/cwd-changed.sh +6 -2
- package/config/hooks/post-tool-use-v2.sh +6 -2
- package/config/hooks/post-tool-use.sh +8 -17
- package/config/hooks/pre-tool-use.ps1 +8 -6
- package/config/hooks/pre-tool-use.sh +8 -17
- package/config/hooks/session-start.sh +23 -21
- package/config/hooks/stop.ps1 +7 -5
- package/config/hooks/stop.sh +8 -17
- package/config/hooks/token-hygiene.sh +5 -1
- package/config/hooks/user-prompt-submit-v2.sh +13 -9
- package/config/hooks/user-prompt-submit.sh +8 -17
- package/core/hooks/__pycache__/post_tool_use.cpython-312.pyc +0 -0
- package/core/hooks/__pycache__/pre_tool_use.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/cost_governor.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/llm_provider.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/openrouter_provider.cpython-312.pyc +0 -0
- package/core/workflow/state_reader.sh +12 -5
- package/departments/ops/skills/update/SKILL.md +2 -2
- package/departments/ops/skills/update/references/sync-engine.md +1 -1
- package/departments/quality/SKILL.md +1 -1
- package/installer/index.js +14 -0
- package/installer/update.js +31 -0
- package/package.json +6 -3
- package/pyproject.toml +1 -1
- package/scripts/seed_initial_patterns.py +1 -1
package/config/constitution.yaml
CHANGED
|
@@ -142,7 +142,7 @@ enforcement_levels:
|
|
|
142
142
|
scope: "All technical: code quality, tests, UX/UI, data integrity, security, performance"
|
|
143
143
|
veto_power: true
|
|
144
144
|
process:
|
|
145
|
-
- "Evidence engine runs first:
|
|
145
|
+
- "Evidence engine runs first: ~/.arkaos/bin/arka-py -m core.governance.evidence_checks — the verdict derives from its report"
|
|
146
146
|
- "Marta receives all output from execution phase plus the evidence report"
|
|
147
147
|
- "Marta dispatches Eduardo (text) and Francisca (technical) in parallel, each in an INDEPENDENT subagent context (clean context, no stake in the work being approved)"
|
|
148
148
|
- "Each reviewer returns a structured QGVerdict (APPROVED or REJECTED) with specific issues; the verdict MUST name the benchmark used (reference_companies.application) and enumerate the concrete rejections a top-tier lead would raise; evidence overall=fail forces REJECTED"
|
|
@@ -197,7 +197,7 @@ enforcement_levels:
|
|
|
197
197
|
# ─── Rule added in PR3 Squad Intelligence Upgrade (2026-05-28) ───────
|
|
198
198
|
- id: agent-experience-persistence
|
|
199
199
|
rule: "Quality Gate REJECTED verdicts MUST result in an Experience record for the failing agent, written to ~/.arkaos/agents/<agent_id>/experiences.jsonl via core.governance.cqo_experience_recorder. Next dispatch of that agent loads the experiences via the Synapse L2.6 layer (core.synapse.agent_experiences_layer) so the lesson carries across sessions. Without this, REJECTED reports evaporate as conversation turns and the same structural mistakes recur."
|
|
200
|
-
enforcement: "PR3 v3.74.0 ships the storage, parser, and Synapse layer. v3.74.1 will wire a PostToolUse hook on the Agent tool that auto-records on REJECTED verdicts. Until then orchestrators MUST call cqo_experience_recorder.record_from_verdict() after every CQO dispatch. Audit via
|
|
200
|
+
enforcement: "PR3 v3.74.0 ships the storage, parser, and Synapse layer. v3.74.1 will wire a PostToolUse hook on the Agent tool that auto-records on REJECTED verdicts. Until then orchestrators MUST call cqo_experience_recorder.record_from_verdict() after every CQO dispatch. Audit via ~/.arkaos/bin/arka-py -m core.governance.agent_experiences_cli list <agent_id>."
|
|
201
201
|
|
|
202
202
|
should:
|
|
203
203
|
description: "Best practices. Encouraged but not enforced."
|
|
@@ -221,17 +221,17 @@ enforcement_levels:
|
|
|
221
221
|
# ─── Rule added in PR6 Squad Intelligence Upgrade (2026-05-28) ───────
|
|
222
222
|
- id: design-system-locked
|
|
223
223
|
rule: "Each project SHOULD declare a `design-system.yaml` at its root listing tokens (colors, spacing, fonts), allowed_components, file_globs to scan, and forbidden_patterns with suggestions. The per-project linter (core.governance.design_system_lint) detects UI/UX drift — hex literals outside the palette, inline style attributes, raw HTML where a Nuxt UI component exists, etc. Adoption is opt-in per project (no YAML at project root → no violations). v3.77.0 is advisory-only; pre-commit hook integration lands in v3.77.x once the rule sets stabilise across the operator's projects."
|
|
224
|
-
enforcement: "Run via
|
|
224
|
+
enforcement: "Run via `~/.arkaos/bin/arka-py -m core.governance.design_system_lint_cli <project_path>` (text or JSON output, optional --exit-on-violations). Example template at `docs/examples/design-system-example.yaml`."
|
|
225
225
|
|
|
226
226
|
# ─── Rule added in PR5 Squad Intelligence Upgrade (2026-05-28) ───────
|
|
227
227
|
- id: dna-fidelity-warn
|
|
228
228
|
rule: "Agent outputs are compared against the `signature_markers` block in each agent's YAML at the end of every turn. Forbidden patterns (avoid_patterns) and missing opening phrases (opening_phrases) generate FidelityViolation records in ~/.arkaos/telemetry/dna-fidelity.jsonl. v3.76.0 is soft-warn — violations are recorded for telemetry and operator review, not blocked. Hard-block mode lands later once the marker set is calibrated against real production usage."
|
|
229
|
-
enforcement: "Stop hook (config/hooks/stop.sh) calls core.governance.dna_fidelity.check_fidelity at turn end. Telemetry inspection:
|
|
229
|
+
enforcement: "Stop hook (config/hooks/stop.sh) calls core.governance.dna_fidelity.check_fidelity at turn end. Telemetry inspection: ~/.arkaos/bin/arka-py -m core.governance.dna_fidelity_cli list|summary. Agents in scope for v3.76.0: tech-lead-paulo, cqo-marta, copy-director-eduardo, tech-director-francisca. Remaining 61 agent YAMLs get signature_markers in v3.76.x curation work."
|
|
230
230
|
|
|
231
231
|
# ─── Rule added in PR4 Squad Intelligence Upgrade (2026-05-28) ───────
|
|
232
232
|
- id: pattern-library-first
|
|
233
233
|
rule: "Before designing any new feature, consult the Pattern Library (core.knowledge.pattern_cards). If a similar pattern exists, reuse it or explicitly document why divergence is justified in the spec. New patterns SHOULD be registered with record_pattern() after Quality Gate APPROVED so future feature work inherits the prior art."
|
|
234
|
-
enforcement: "Synapse layer L7.5 (core.synapse.pattern_library_layer) auto-injects top matching cards as context. Audit via
|
|
234
|
+
enforcement: "Synapse layer L7.5 (core.synapse.pattern_library_layer) auto-injects top matching cards as context. Audit via ~/.arkaos/bin/arka-py -m core.knowledge.pattern_cards_cli list. SHOULD level — promoted from advisory once telemetry shows consistent consultation."
|
|
235
235
|
|
|
236
236
|
tier_hierarchy:
|
|
237
237
|
description: "Agent authority levels inspired by SpaceX/Google/Anthropic org structures"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# ArkaOS shared Python resolver (PowerShell side) — single source of truth.
|
|
2
|
+
#
|
|
3
|
+
# Windows mirror of config/hooks/_lib/arka_python.sh and
|
|
4
|
+
# installer/python-resolver.js. Prefers the ~/.arkaos venv (has pyyaml/
|
|
5
|
+
# pydantic); never silently falls back to a system python that lacks ArkaOS
|
|
6
|
+
# deps. Dot-source this file: it sets $env:ARKA_PY.
|
|
7
|
+
#
|
|
8
|
+
# Resolution order:
|
|
9
|
+
# 1. $env:ARKAOS_PYTHON (explicit override), if it exists.
|
|
10
|
+
# 2. The ArkaOS venv — Scripts\python.exe (Windows) then bin/python.
|
|
11
|
+
# 3. Any python3/python/py on PATH that can `import yaml`.
|
|
12
|
+
# 4. Bare `python` as a last resort.
|
|
13
|
+
|
|
14
|
+
function Resolve-ArkaPython {
|
|
15
|
+
if ($env:ARKAOS_PYTHON -and (Test-Path -LiteralPath $env:ARKAOS_PYTHON)) {
|
|
16
|
+
return $env:ARKAOS_PYTHON
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
$base = if ($env:USERPROFILE) { $env:USERPROFILE } elseif ($HOME) { $HOME } else { "" }
|
|
20
|
+
if ($base) {
|
|
21
|
+
$candidates = @(
|
|
22
|
+
(Join-Path $base ".arkaos\venv\Scripts\python.exe"),
|
|
23
|
+
(Join-Path $base ".arkaos/venv/bin/python"),
|
|
24
|
+
(Join-Path $base ".arkaos\.venv\Scripts\python.exe"),
|
|
25
|
+
(Join-Path $base ".arkaos/.venv/bin/python")
|
|
26
|
+
)
|
|
27
|
+
foreach ($c in $candidates) {
|
|
28
|
+
if (Test-Path -LiteralPath $c) { return $c }
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
foreach ($name in @("python3", "python", "py")) {
|
|
33
|
+
$cmd = Get-Command $name -ErrorAction SilentlyContinue
|
|
34
|
+
if ($cmd) {
|
|
35
|
+
& $cmd.Source -c "import yaml" 2>$null
|
|
36
|
+
if ($LASTEXITCODE -eq 0) { return $cmd.Source }
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return "python"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
$env:ARKA_PY = Resolve-ArkaPython
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# shellcheck shell=bash
|
|
2
|
+
# ArkaOS shared Python resolver (shell side) — single source of truth.
|
|
3
|
+
#
|
|
4
|
+
# Mirrors installer/python-resolver.js (getArkaosPython). Every hook, the
|
|
5
|
+
# state reader, the agent-provision helper, and the `arka-py` shim source
|
|
6
|
+
# THIS file instead of probing for `python3` on their own. Rationale: an
|
|
7
|
+
# unrelated project venv first on PATH, or a system python without pyyaml/
|
|
8
|
+
# pydantic, silently degrades every gate. The ArkaOS venv is authoritative.
|
|
9
|
+
#
|
|
10
|
+
# Contract of arka_resolve_python():
|
|
11
|
+
# Echoes the interpreter path and returns 0 when a provisioned ArkaOS
|
|
12
|
+
# interpreter is found; echoes a best-effort fallback and returns 1 when
|
|
13
|
+
# only a bare `python3` remains (caller degrades gracefully).
|
|
14
|
+
#
|
|
15
|
+
# Resolution order:
|
|
16
|
+
# 1. $ARKAOS_PYTHON (explicit operator override), if executable.
|
|
17
|
+
# 2. The ArkaOS venv — ~/.arkaos/venv then ~/.arkaos/.venv, python then
|
|
18
|
+
# python3. `[ -x ]` follows symlinks, so a Homebrew-rotated broken
|
|
19
|
+
# symlink is skipped automatically.
|
|
20
|
+
# 3. Any python3 on PATH / known locations that can `import yaml`.
|
|
21
|
+
# 4. Bare `python3` as a last resort (return 1).
|
|
22
|
+
|
|
23
|
+
arka_resolve_python() {
|
|
24
|
+
local cand
|
|
25
|
+
|
|
26
|
+
if [ -n "${ARKAOS_PYTHON:-}" ] && [ -x "${ARKAOS_PYTHON}" ]; then
|
|
27
|
+
printf '%s\n' "${ARKAOS_PYTHON}"
|
|
28
|
+
return 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
for cand in \
|
|
32
|
+
"$HOME/.arkaos/venv/bin/python" \
|
|
33
|
+
"$HOME/.arkaos/venv/bin/python3" \
|
|
34
|
+
"$HOME/.arkaos/.venv/bin/python" \
|
|
35
|
+
"$HOME/.arkaos/.venv/bin/python3"; do
|
|
36
|
+
if [ -x "$cand" ]; then
|
|
37
|
+
printf '%s\n' "$cand"
|
|
38
|
+
return 0
|
|
39
|
+
fi
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
for cand in python3 /opt/homebrew/bin/python3 /usr/local/bin/python3 /usr/bin/python3; do
|
|
43
|
+
if command -v "$cand" >/dev/null 2>&1 && "$cand" -c "import yaml" >/dev/null 2>&1; then
|
|
44
|
+
printf '%s\n' "$cand"
|
|
45
|
+
return 0
|
|
46
|
+
fi
|
|
47
|
+
done
|
|
48
|
+
|
|
49
|
+
printf '%s\n' "python3"
|
|
50
|
+
return 1
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Sourcing this file exports ARKA_PY once, so hooks can `exec "$ARKA_PY" ...`
|
|
54
|
+
# without each re-running the probe. Callers that need the return code call
|
|
55
|
+
# arka_resolve_python directly.
|
|
56
|
+
#
|
|
57
|
+
# `|| true` is REQUIRED: arka_resolve_python returns 1 on the last-resort
|
|
58
|
+
# fallback, and under `set -e` a failing command substitution in an
|
|
59
|
+
# assignment aborts the sourcing file mid-way (reproduced on bash 3.2.57).
|
|
60
|
+
# We still want ARKA_PY set to the fallback value, so swallow the status and
|
|
61
|
+
# keep the export unconditional.
|
|
62
|
+
ARKA_PY="$(arka_resolve_python)" || true
|
|
63
|
+
export ARKA_PY
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
|
|
10
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
11
|
+
# The resolver guards its own ARKA_PY assignment with `|| true`, so sourcing
|
|
12
|
+
# is set -e-safe even on the last-resort fallback. The trailing `|| true`
|
|
13
|
+
# here is belt-and-suspenders for a partially-updated lib.
|
|
14
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
15
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB" || true; else ARKA_PY="python3"; fi
|
|
16
|
+
|
|
10
17
|
# Hook contract: stdin is a JSON payload with fields tool_name + tool_input.
|
|
11
18
|
payload="$(cat)"
|
|
12
19
|
|
|
@@ -44,7 +51,7 @@ fi
|
|
|
44
51
|
if [ -d "$core_root/departments" ]; then
|
|
45
52
|
mkdir -p "$project_agents_dir"
|
|
46
53
|
set +e
|
|
47
|
-
|
|
54
|
+
"$ARKA_PY" - "$core_root" "$subagent_type" "$target" <<'PY'
|
|
48
55
|
import os, re, sys
|
|
49
56
|
from pathlib import Path
|
|
50
57
|
|
|
@@ -8,6 +8,10 @@
|
|
|
8
8
|
input=$(cat)
|
|
9
9
|
NEW_CWD=$(echo "$input" | jq -r '.cwd // ""' 2>/dev/null)
|
|
10
10
|
|
|
11
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
12
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
13
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
14
|
+
|
|
11
15
|
if [ -z "$NEW_CWD" ] || [ ! -d "$NEW_CWD" ]; then
|
|
12
16
|
exit 0
|
|
13
17
|
fi
|
|
@@ -23,8 +27,8 @@ fi
|
|
|
23
27
|
ECOSYSTEM=""
|
|
24
28
|
ECOSYSTEM_NAME=""
|
|
25
29
|
|
|
26
|
-
if [ -f "$ECOSYSTEMS_FILE" ] && command -v
|
|
27
|
-
eval "$(
|
|
30
|
+
if [ -f "$ECOSYSTEMS_FILE" ] && command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
31
|
+
eval "$("$ARKA_PY" -c "
|
|
28
32
|
import json, os, sys
|
|
29
33
|
|
|
30
34
|
cwd = '$NEW_CWD'
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
input=$(cat)
|
|
9
9
|
|
|
10
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
11
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
12
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
13
|
+
|
|
10
14
|
ARKAOS_HOME="${HOME}/.arkaos"
|
|
11
15
|
GOTCHAS_FILE="$ARKAOS_HOME/gotchas.json"
|
|
12
16
|
|
|
@@ -74,8 +78,8 @@ project=$(basename "$cwd")
|
|
|
74
78
|
echo "[]" > "$GOTCHAS_FILE"
|
|
75
79
|
fi
|
|
76
80
|
|
|
77
|
-
if command -v
|
|
78
|
-
|
|
81
|
+
if command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
82
|
+
"$ARKA_PY" -c "
|
|
79
83
|
import json, sys
|
|
80
84
|
try:
|
|
81
85
|
with open('$GOTCHAS_FILE') as f:
|
|
@@ -31,7 +31,11 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
31
31
|
fi
|
|
32
32
|
export ARKAOS_ROOT
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
35
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
36
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
37
|
+
|
|
38
|
+
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
35
39
|
echo '{}'
|
|
36
40
|
exit 0
|
|
37
41
|
fi
|
|
@@ -49,20 +53,7 @@ if [ ! -f "$ARKAOS_ROOT/core/hooks/post_tool_use.py" ]; then
|
|
|
49
53
|
fi
|
|
50
54
|
fi
|
|
51
55
|
|
|
52
|
-
# Interpreter resolution
|
|
53
|
-
#
|
|
54
|
-
# python3 without yaml and silently degrade every gate.
|
|
55
|
-
_PY=""
|
|
56
|
-
for _cand in "$HOME/.arkaos/venv/bin/python3" "$HOME/.arkaos/.venv/bin/python3"; do
|
|
57
|
-
if [ -x "$_cand" ]; then _PY="$_cand"; break; fi
|
|
58
|
-
done
|
|
59
|
-
if [ -z "$_PY" ]; then
|
|
60
|
-
_PY="python3"
|
|
61
|
-
if ! "$_PY" -c "import yaml" 2>/dev/null; then
|
|
62
|
-
for _cand in /opt/homebrew/bin/python3 /usr/local/bin/python3 /usr/bin/python3; do
|
|
63
|
-
if [ -x "$_cand" ] && "$_cand" -c "import yaml" 2>/dev/null; then _PY="$_cand"; break; fi
|
|
64
|
-
done
|
|
65
|
-
fi
|
|
66
|
-
fi
|
|
56
|
+
# Interpreter resolution handled by the shared resolver (ARKA_PY): prefers
|
|
57
|
+
# the ArkaOS venv (has pyyaml/pydantic), falls back to a yaml-capable python3.
|
|
67
58
|
PYTHONPATH="$ARKAOS_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
|
|
68
|
-
exec "$
|
|
59
|
+
exec "$ARKA_PY" -m core.hooks.post_tool_use
|
|
@@ -39,9 +39,11 @@ if ([string]::IsNullOrWhiteSpace($env:ARKAOS_ROOT)) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (-
|
|
42
|
+
# Shared resolver (venv-first, yaml-verified). Mirrors _lib/arka_python.sh.
|
|
43
|
+
$arkaLib = Join-Path $PSScriptRoot "_lib\arka_python.ps1"
|
|
44
|
+
if (Test-Path -LiteralPath $arkaLib) { . $arkaLib }
|
|
45
|
+
$pythonExe = $env:ARKA_PY
|
|
46
|
+
if (-not $pythonExe) { exit 0 }
|
|
45
47
|
|
|
46
48
|
# --- KB-first gate (Task #6, runs before flow-marker gate) ---
|
|
47
49
|
$queryHint = ""
|
|
@@ -91,7 +93,7 @@ print(json.dumps({
|
|
|
91
93
|
}))
|
|
92
94
|
'@
|
|
93
95
|
|
|
94
|
-
$kbDecisionJson = $kbScript | & $
|
|
96
|
+
$kbDecisionJson = $kbScript | & $pythonExe -
|
|
95
97
|
if (-not [string]::IsNullOrWhiteSpace($kbDecisionJson)) {
|
|
96
98
|
try {
|
|
97
99
|
$kbDecision = $kbDecisionJson | ConvertFrom-Json
|
|
@@ -172,7 +174,7 @@ print(json.dumps({
|
|
|
172
174
|
}))
|
|
173
175
|
'@
|
|
174
176
|
|
|
175
|
-
$spDecisionJson = $spScript | & $
|
|
177
|
+
$spDecisionJson = $spScript | & $pythonExe -
|
|
176
178
|
if (-not [string]::IsNullOrWhiteSpace($spDecisionJson)) {
|
|
177
179
|
try {
|
|
178
180
|
$spDecision = $spDecisionJson | ConvertFrom-Json
|
|
@@ -241,7 +243,7 @@ print(json.dumps({
|
|
|
241
243
|
}))
|
|
242
244
|
'@
|
|
243
245
|
|
|
244
|
-
$decisionJson = $pyScript | & $
|
|
246
|
+
$decisionJson = $pyScript | & $pythonExe -
|
|
245
247
|
if ([string]::IsNullOrWhiteSpace($decisionJson)) { exit 0 }
|
|
246
248
|
|
|
247
249
|
try {
|
|
@@ -34,8 +34,12 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
34
34
|
fi
|
|
35
35
|
export ARKAOS_ROOT
|
|
36
36
|
|
|
37
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
38
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
39
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
40
|
+
|
|
37
41
|
# ─── Degrade gracefully (fail open, same as before) ─────────────────────
|
|
38
|
-
if ! command -v
|
|
42
|
+
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
39
43
|
exit 0
|
|
40
44
|
fi
|
|
41
45
|
# Self-root fallback: the wrapper ships next to its python entrypoint, so
|
|
@@ -52,20 +56,7 @@ if [ ! -f "$ARKAOS_ROOT/core/hooks/pre_tool_use.py" ]; then
|
|
|
52
56
|
fi
|
|
53
57
|
|
|
54
58
|
# ─── Single python process; stdin/stdout/stderr/exit-code pass through ──
|
|
55
|
-
# Interpreter resolution
|
|
56
|
-
#
|
|
57
|
-
# python3 without yaml and silently degrade every gate.
|
|
58
|
-
_PY=""
|
|
59
|
-
for _cand in "$HOME/.arkaos/venv/bin/python3" "$HOME/.arkaos/.venv/bin/python3"; do
|
|
60
|
-
if [ -x "$_cand" ]; then _PY="$_cand"; break; fi
|
|
61
|
-
done
|
|
62
|
-
if [ -z "$_PY" ]; then
|
|
63
|
-
_PY="python3"
|
|
64
|
-
if ! "$_PY" -c "import yaml" 2>/dev/null; then
|
|
65
|
-
for _cand in /opt/homebrew/bin/python3 /usr/local/bin/python3 /usr/bin/python3; do
|
|
66
|
-
if [ -x "$_cand" ] && "$_cand" -c "import yaml" 2>/dev/null; then _PY="$_cand"; break; fi
|
|
67
|
-
done
|
|
68
|
-
fi
|
|
69
|
-
fi
|
|
59
|
+
# Interpreter resolution handled by the shared resolver (ARKA_PY): prefers
|
|
60
|
+
# the ArkaOS venv (has pyyaml/pydantic), falls back to a yaml-capable python3.
|
|
70
61
|
PYTHONPATH="$ARKAOS_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
|
|
71
|
-
exec "$
|
|
62
|
+
exec "$ARKA_PY" -m core.hooks.pre_tool_use
|
|
@@ -9,9 +9,13 @@ NAME="founder"
|
|
|
9
9
|
COMPANY="WizardingCode"
|
|
10
10
|
VERSION="2.x"
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
13
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
14
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
15
|
+
|
|
16
|
+
if [ -f "$HOME/.arkaos/profile.json" ] && command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
17
|
+
NAME=$("$ARKA_PY" -c "import json; p=json.load(open('$HOME/.arkaos/profile.json')); print(p.get('name', p.get('role', 'founder')))" 2>/dev/null || echo "founder")
|
|
18
|
+
COMPANY=$("$ARKA_PY" -c "import json; print(json.load(open('$HOME/.arkaos/profile.json')).get('company', 'WizardingCode'))" 2>/dev/null || echo "WizardingCode")
|
|
15
19
|
fi
|
|
16
20
|
|
|
17
21
|
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
@@ -29,7 +33,7 @@ SYNC_STATE="$HOME/.arkaos/sync-state.json"
|
|
|
29
33
|
DRIFT=""
|
|
30
34
|
|
|
31
35
|
if [ -f "$SYNC_STATE" ]; then
|
|
32
|
-
SYNCED=$(
|
|
36
|
+
SYNCED=$("$ARKA_PY" -c "import json; print(json.load(open('$SYNC_STATE'))['version'])" 2>/dev/null || echo "none")
|
|
33
37
|
if [ "$SYNCED" != "$VERSION" ]; then
|
|
34
38
|
DRIFT="\\n[arka:update-available] Core v${VERSION} != synced v${SYNCED}. Run /arka update."
|
|
35
39
|
fi
|
|
@@ -71,11 +75,11 @@ _FORGE_LINE=""
|
|
|
71
75
|
if [ -f "$_FORGE_ACTIVE" ]; then
|
|
72
76
|
_FORGE_ID=$(cat "$_FORGE_ACTIVE" 2>/dev/null)
|
|
73
77
|
_FORGE_FILE="$_FORGE_PLANS/${_FORGE_ID}.yaml"
|
|
74
|
-
if [ -f "$_FORGE_FILE" ] && command -v
|
|
75
|
-
_FORGE_NAME=$(FORGE_FILE="$_FORGE_FILE"
|
|
76
|
-
_FORGE_STATUS=$(FORGE_FILE="$_FORGE_FILE"
|
|
77
|
-
_FORGE_PHASES=$(FORGE_FILE="$_FORGE_FILE"
|
|
78
|
-
_FORGE_BRANCH=$(FORGE_FILE="$_FORGE_FILE"
|
|
78
|
+
if [ -f "$_FORGE_FILE" ] && command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
79
|
+
_FORGE_NAME=$(FORGE_FILE="$_FORGE_FILE" "$ARKA_PY" -c "import yaml,os; d=yaml.safe_load(open(os.environ['FORGE_FILE'])); print(d.get('name',''))" 2>/dev/null)
|
|
80
|
+
_FORGE_STATUS=$(FORGE_FILE="$_FORGE_FILE" "$ARKA_PY" -c "import yaml,os; d=yaml.safe_load(open(os.environ['FORGE_FILE'])); print(d.get('status',''))" 2>/dev/null)
|
|
81
|
+
_FORGE_PHASES=$(FORGE_FILE="$_FORGE_FILE" "$ARKA_PY" -c "import yaml,os; d=yaml.safe_load(open(os.environ['FORGE_FILE'])); print(len(d.get('plan_phases',[])))" 2>/dev/null)
|
|
82
|
+
_FORGE_BRANCH=$(FORGE_FILE="$_FORGE_FILE" "$ARKA_PY" -c "import yaml,os; d=yaml.safe_load(open(os.environ['FORGE_FILE'])); print(d.get('governance',{}).get('branch_strategy',''))" 2>/dev/null)
|
|
79
83
|
|
|
80
84
|
if [ "$_FORGE_STATUS" = "approved" ]; then
|
|
81
85
|
_FORGE_LINE=" ⚒ Forge plan pending: ${_FORGE_NAME} | Phases: ${_FORGE_PHASES} | /forge resume"
|
|
@@ -110,12 +114,10 @@ MSG+="\\nAbsence is measured by the Stop hook (warn-only in v2.34.0) before prom
|
|
|
110
114
|
# dashboard/CLI model choices actually govern agent dispatch. Cheap
|
|
111
115
|
# (single python read); skipped silently if the config can't be resolved.
|
|
112
116
|
if [ -n "$REPO" ]; then
|
|
113
|
-
#
|
|
114
|
-
# python3 usually lacks them and routing_directive() would return "".
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if command -v "$_MF_PY" &>/dev/null || [ -x "$_MF_PY" ]; then
|
|
118
|
-
_MF_DIRECTIVE=$(cd "$REPO" && PYTHONPATH="$REPO" "$_MF_PY" -c "
|
|
117
|
+
# ARKA_PY already resolves to the venv python (has pydantic + yaml); the
|
|
118
|
+
# ambient python3 usually lacks them and routing_directive() would return "".
|
|
119
|
+
if command -v "$ARKA_PY" >/dev/null 2>&1 || [ -x "$ARKA_PY" ]; then
|
|
120
|
+
_MF_DIRECTIVE=$(cd "$REPO" && PYTHONPATH="$REPO" "$ARKA_PY" -c "
|
|
119
121
|
try:
|
|
120
122
|
from core.runtime.model_routing_context import routing_directive
|
|
121
123
|
print(routing_directive())
|
|
@@ -132,12 +134,12 @@ fi
|
|
|
132
134
|
# If today's proposal file is missing, fire the reorganizer in the
|
|
133
135
|
# background with a 30s timeout. Best-effort, never blocks session
|
|
134
136
|
# start. Multiple sessions per day no-op because the file now exists.
|
|
135
|
-
if [ -n "$REPO" ] && command -v
|
|
137
|
+
if [ -n "$REPO" ] && command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
136
138
|
_PROPOSAL_DIR="$HOME/.arkaos/reorganize-proposals"
|
|
137
139
|
_TODAY="$(date -u +%Y-%m-%d).md"
|
|
138
140
|
if [ ! -f "$_PROPOSAL_DIR/$_TODAY" ]; then
|
|
139
141
|
(
|
|
140
|
-
cd "$REPO" && timeout 30s
|
|
142
|
+
cd "$REPO" && timeout 30s "$ARKA_PY" -m core.cognition.reorganizer_cli >/dev/null 2>&1
|
|
141
143
|
) &
|
|
142
144
|
disown 2>/dev/null || true
|
|
143
145
|
fi
|
|
@@ -149,7 +151,7 @@ fi
|
|
|
149
151
|
# starts API+UI. Background + disown so it never touches the 5s budget.
|
|
150
152
|
# Toggle off: ~/.arkaos/config.json -> {"dashboard": {"ensure_on_session": false}}
|
|
151
153
|
if [ -n "$REPO" ] && [ -f "$REPO/scripts/start-dashboard.sh" ]; then
|
|
152
|
-
_DASH_ENSURE=$(
|
|
154
|
+
_DASH_ENSURE=$("$ARKA_PY" -c "import json; print(json.load(open('$HOME/.arkaos/config.json')).get('dashboard',{}).get('ensure_on_session', True))" 2>/dev/null || echo "True")
|
|
153
155
|
if [ "$_DASH_ENSURE" = "True" ] || [ "$_DASH_ENSURE" = "true" ]; then
|
|
154
156
|
mkdir -p "$HOME/.arkaos/logs"
|
|
155
157
|
(
|
|
@@ -166,8 +168,8 @@ if [ -n "$REPO" ] && [ -f "$REPO/scripts/start-dashboard.sh" ]; then
|
|
|
166
168
|
fi
|
|
167
169
|
|
|
168
170
|
# --- Session Memory Resume Context ---
|
|
169
|
-
if command -v
|
|
170
|
-
_SESSION_CTX=$(cd "$REPO" &&
|
|
171
|
+
if command -v "$ARKA_PY" >/dev/null 2>&1 && [ -n "$REPO" ]; then
|
|
172
|
+
_SESSION_CTX=$(cd "$REPO" && "$ARKA_PY" -c "
|
|
171
173
|
import sys
|
|
172
174
|
sys.path.insert(0, '$REPO')
|
|
173
175
|
try:
|
|
@@ -182,7 +184,7 @@ except Exception:
|
|
|
182
184
|
fi
|
|
183
185
|
|
|
184
186
|
# ─── Output as systemMessage (same protocol as claude-mem) ─────────────
|
|
185
|
-
|
|
187
|
+
"$ARKA_PY" -c "
|
|
186
188
|
import json
|
|
187
189
|
msg = '''$(echo -e "$MSG")'''
|
|
188
190
|
print(json.dumps({'systemMessage': msg}))
|
package/config/hooks/stop.ps1
CHANGED
|
@@ -43,9 +43,11 @@ if ([string]::IsNullOrWhiteSpace($env:ARKAOS_ROOT)) {
|
|
|
43
43
|
$enforcerPy = Join-Path $env:ARKAOS_ROOT "core/workflow/flow_enforcer.py"
|
|
44
44
|
if (-not (Test-Path $enforcerPy)) { exit 0 }
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (-
|
|
46
|
+
# Shared resolver (venv-first, yaml-verified). Mirrors _lib/arka_python.sh.
|
|
47
|
+
$arkaLib = Join-Path $PSScriptRoot "_lib\arka_python.ps1"
|
|
48
|
+
if (Test-Path -LiteralPath $arkaLib) { . $arkaLib }
|
|
49
|
+
$pythonExe = $env:ARKA_PY
|
|
50
|
+
if (-not $pythonExe) { exit 0 }
|
|
49
51
|
|
|
50
52
|
$env:SESSION_ID_VAL = $sessionId
|
|
51
53
|
$env:TRANSCRIPT_PATH_VAL = $transcriptPath
|
|
@@ -102,7 +104,7 @@ except Exception:
|
|
|
102
104
|
pass
|
|
103
105
|
'@
|
|
104
106
|
|
|
105
|
-
$pyScript | & $
|
|
107
|
+
$pyScript | & $pythonExe - | Out-Null
|
|
106
108
|
|
|
107
109
|
# ─── Auto-documentor enqueue (fire-and-forget) ─────────────────────────
|
|
108
110
|
# Queues a background job when classifier flagged flow, QG approved, and
|
|
@@ -178,7 +180,7 @@ except Exception:
|
|
|
178
180
|
'@
|
|
179
181
|
|
|
180
182
|
try {
|
|
181
|
-
$autoDocScript | & $
|
|
183
|
+
$autoDocScript | & $pythonExe - | Out-Null
|
|
182
184
|
} catch {
|
|
183
185
|
# Swallow — enqueue is fire-and-forget.
|
|
184
186
|
}
|
package/config/hooks/stop.sh
CHANGED
|
@@ -33,7 +33,11 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
33
33
|
fi
|
|
34
34
|
export ARKAOS_ROOT
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
37
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
38
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
39
|
+
|
|
40
|
+
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
37
41
|
exit 0
|
|
38
42
|
fi
|
|
39
43
|
# Self-root fallback: the wrapper ships next to its python entrypoint, so
|
|
@@ -49,21 +53,8 @@ if [ ! -f "$ARKAOS_ROOT/core/hooks/stop.py" ]; then
|
|
|
49
53
|
fi
|
|
50
54
|
fi
|
|
51
55
|
|
|
52
|
-
# Interpreter resolution
|
|
53
|
-
#
|
|
54
|
-
# python3 without yaml and silently degrade every gate.
|
|
55
|
-
_PY=""
|
|
56
|
-
for _cand in "$HOME/.arkaos/venv/bin/python3" "$HOME/.arkaos/.venv/bin/python3"; do
|
|
57
|
-
if [ -x "$_cand" ]; then _PY="$_cand"; break; fi
|
|
58
|
-
done
|
|
59
|
-
if [ -z "$_PY" ]; then
|
|
60
|
-
_PY="python3"
|
|
61
|
-
if ! "$_PY" -c "import yaml" 2>/dev/null; then
|
|
62
|
-
for _cand in /opt/homebrew/bin/python3 /usr/local/bin/python3 /usr/bin/python3; do
|
|
63
|
-
if [ -x "$_cand" ] && "$_cand" -c "import yaml" 2>/dev/null; then _PY="$_cand"; break; fi
|
|
64
|
-
done
|
|
65
|
-
fi
|
|
66
|
-
fi
|
|
56
|
+
# Interpreter resolution handled by the shared resolver (ARKA_PY): prefers
|
|
57
|
+
# the ArkaOS venv (has pyyaml/pydantic), falls back to a yaml-capable python3.
|
|
67
58
|
PYTHONPATH="$ARKAOS_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
|
|
68
|
-
"$
|
|
59
|
+
"$ARKA_PY" -m core.hooks.stop
|
|
69
60
|
exit 0
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
set +e # never fail
|
|
15
15
|
|
|
16
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
17
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
18
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
19
|
+
|
|
16
20
|
_prompt="${ARKA_PROMPT:-}"
|
|
17
21
|
_transcript="${ARKA_TRANSCRIPT_PATH:-}"
|
|
18
22
|
_suggestions=""
|
|
@@ -64,7 +68,7 @@ if [ -n "$_transcript" ] && [ -f "$_transcript" ] && [ -n "$_prompt" ]; then
|
|
|
64
68
|
_cur_kw=$(_kw "$_prompt" | head -20)
|
|
65
69
|
# pull last 3 user messages from transcript jsonl
|
|
66
70
|
_prior=$(tail -n 200 "$_transcript" 2>/dev/null \
|
|
67
|
-
|
|
|
71
|
+
| "$ARKA_PY" -c "
|
|
68
72
|
import sys, json
|
|
69
73
|
msgs=[]
|
|
70
74
|
for line in sys.stdin:
|
|
@@ -7,6 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
input=$(cat)
|
|
9
9
|
|
|
10
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
11
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
12
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
13
|
+
|
|
10
14
|
# ─── V1 Migration Detection ─────────────────────────────────────────────
|
|
11
15
|
V1_PATHS=("$HOME/.claude/skills/arka-os" "$HOME/.claude/skills/arkaos")
|
|
12
16
|
MIGRATION_MARKER="$HOME/.arkaos/migrated-from-v1"
|
|
@@ -27,12 +31,12 @@ if [ -f "$ARKAOS_VERSION_FILE" ]; then
|
|
|
27
31
|
if [ -f "$_REPO_PATH/VERSION" ]; then
|
|
28
32
|
_CURRENT_VERSION=$(cat "$_REPO_PATH/VERSION")
|
|
29
33
|
elif [ -f "$_REPO_PATH/package.json" ]; then
|
|
30
|
-
_CURRENT_VERSION=$(
|
|
34
|
+
_CURRENT_VERSION=$("$ARKA_PY" -c "import json; print(json.load(open('$_REPO_PATH/package.json'))['version'])" 2>/dev/null || echo "")
|
|
31
35
|
fi
|
|
32
36
|
|
|
33
37
|
if [ -n "${_CURRENT_VERSION:-}" ]; then
|
|
34
38
|
if [ -f "$SYNC_STATE" ]; then
|
|
35
|
-
_SYNCED_VERSION=$(
|
|
39
|
+
_SYNCED_VERSION=$("$ARKA_PY" -c "import json; print(json.load(open('$SYNC_STATE'))['version'])" 2>/dev/null || echo "none")
|
|
36
40
|
else
|
|
37
41
|
_SYNCED_VERSION="none"
|
|
38
42
|
fi
|
|
@@ -53,9 +57,9 @@ if [ ! -f "$_SESSION_MARKER" ] && [ ! -f "/tmp/arkaos-greeted-today" ]; then
|
|
|
53
57
|
_GREETING_COMPANY=""
|
|
54
58
|
_GREETING_VERSION=""
|
|
55
59
|
|
|
56
|
-
if [ -f "$HOME/.arkaos/profile.json" ] && command -v
|
|
57
|
-
_GREETING_NAME=$(
|
|
58
|
-
_GREETING_COMPANY=$(
|
|
60
|
+
if [ -f "$HOME/.arkaos/profile.json" ] && command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
61
|
+
_GREETING_NAME=$("$ARKA_PY" -c "import json; p=json.load(open('$HOME/.arkaos/profile.json')); print(p.get('name', p.get('role', 'founder')))" 2>/dev/null)
|
|
62
|
+
_GREETING_COMPANY=$("$ARKA_PY" -c "import json; print(json.load(open('$HOME/.arkaos/profile.json')).get('company', ''))" 2>/dev/null)
|
|
59
63
|
fi
|
|
60
64
|
|
|
61
65
|
if [ -f "$HOME/.arkaos/.repo-path" ]; then
|
|
@@ -111,12 +115,12 @@ fi
|
|
|
111
115
|
python_result=""
|
|
112
116
|
BRIDGE_SCRIPT="${ARKAOS_ROOT}/scripts/synapse-bridge.py"
|
|
113
117
|
|
|
114
|
-
if command -v
|
|
115
|
-
bridge_output=$(echo "{\"user_input\":$(echo "$user_input" |
|
|
116
|
-
| ARKAOS_ROOT="$ARKAOS_ROOT"
|
|
118
|
+
if command -v "$ARKA_PY" >/dev/null 2>&1 && [ -f "$BRIDGE_SCRIPT" ]; then
|
|
119
|
+
bridge_output=$(echo "{\"user_input\":$(echo "$user_input" | "$ARKA_PY" -c "import sys,json; print(json.dumps(sys.stdin.read()))" 2>/dev/null || echo '""')}" \
|
|
120
|
+
| ARKAOS_ROOT="$ARKAOS_ROOT" "$ARKA_PY" "$BRIDGE_SCRIPT" --root "$ARKAOS_ROOT" 2>/dev/null)
|
|
117
121
|
|
|
118
122
|
if [ -n "$bridge_output" ]; then
|
|
119
|
-
python_result=$(echo "$bridge_output" |
|
|
123
|
+
python_result=$(echo "$bridge_output" | "$ARKA_PY" -c "import sys,json; print(json.loads(sys.stdin.read()).get('context_string',''))" 2>/dev/null)
|
|
120
124
|
fi
|
|
121
125
|
fi
|
|
122
126
|
|
|
@@ -34,9 +34,13 @@ if [ -z "${ARKAOS_ROOT:-}" ]; then
|
|
|
34
34
|
fi
|
|
35
35
|
export ARKAOS_ROOT
|
|
36
36
|
|
|
37
|
+
# ─── Shared Python resolver (exports ARKA_PY) ──────────────────────────
|
|
38
|
+
_ARKA_LIB="$(dirname "${BASH_SOURCE[0]:-$0}")/_lib/arka_python.sh"
|
|
39
|
+
if [ -f "$_ARKA_LIB" ]; then . "$_ARKA_LIB"; else ARKA_PY="python3"; fi
|
|
40
|
+
|
|
37
41
|
_ARKA_L0_FALLBACK='{"additionalContext": "[Constitution] NON-NEGOTIABLE: branch-isolation, obsidian-output, authority-boundaries, security-gate, context-first, solid-clean-code, spec-driven, human-writing, squad-routing, full-visibility, sequential-validation, mandatory-qa, arka-supremacy | QUALITY-GATE: marta-cqo, eduardo-copy, francisca-tech-ux | MUST: conventional-commits, test-coverage, pattern-matching, actionable-output, memory-persistence"}'
|
|
38
42
|
|
|
39
|
-
if ! command -v
|
|
43
|
+
if ! command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
40
44
|
echo "$_ARKA_L0_FALLBACK"
|
|
41
45
|
exit 0
|
|
42
46
|
fi
|
|
@@ -54,20 +58,7 @@ if [ ! -f "$ARKAOS_ROOT/core/hooks/user_prompt_submit.py" ]; then
|
|
|
54
58
|
fi
|
|
55
59
|
fi
|
|
56
60
|
|
|
57
|
-
# Interpreter resolution
|
|
58
|
-
#
|
|
59
|
-
# python3 without yaml and silently degrade every gate.
|
|
60
|
-
_PY=""
|
|
61
|
-
for _cand in "$HOME/.arkaos/venv/bin/python3" "$HOME/.arkaos/.venv/bin/python3"; do
|
|
62
|
-
if [ -x "$_cand" ]; then _PY="$_cand"; break; fi
|
|
63
|
-
done
|
|
64
|
-
if [ -z "$_PY" ]; then
|
|
65
|
-
_PY="python3"
|
|
66
|
-
if ! "$_PY" -c "import yaml" 2>/dev/null; then
|
|
67
|
-
for _cand in /opt/homebrew/bin/python3 /usr/local/bin/python3 /usr/bin/python3; do
|
|
68
|
-
if [ -x "$_cand" ] && "$_cand" -c "import yaml" 2>/dev/null; then _PY="$_cand"; break; fi
|
|
69
|
-
done
|
|
70
|
-
fi
|
|
71
|
-
fi
|
|
61
|
+
# Interpreter resolution handled by the shared resolver (ARKA_PY): prefers
|
|
62
|
+
# the ArkaOS venv (has pyyaml/pydantic), falls back to a yaml-capable python3.
|
|
72
63
|
PYTHONPATH="$ARKAOS_ROOT${PYTHONPATH:+:$PYTHONPATH}" \
|
|
73
|
-
exec "$
|
|
64
|
+
exec "$ARKA_PY" -m core.hooks.user_prompt_submit
|
|
Binary file
|