arkaos 4.3.0 → 4.3.2
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 +13 -6
- 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 +40 -15
- 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/fusion/__pycache__/cli.cpython-313.pyc +0 -0
- package/core/fusion/__pycache__/panel_builder.cpython-313.pyc +0 -0
- package/core/fusion/cli.py +57 -6
- package/core/fusion/panel_builder.py +58 -0
- package/core/hooks/__pycache__/post_tool_use.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/pre_tool_use.cpython-313.pyc +0 -0
- package/core/hooks/__pycache__/pre_tool_use.cpython-314.pyc +0 -0
- package/core/hooks/__pycache__/user_prompt_submit.cpython-313.pyc +0 -0
- package/core/hooks/post_tool_use.py +26 -12
- package/core/hooks/pre_tool_use.py +4 -0
- package/core/hooks/user_prompt_submit.py +7 -0
- package/core/memory/__pycache__/rehydrator.cpython-312.pyc +0 -0
- package/core/memory/__pycache__/session_store.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/llm_provider.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/model_router.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/model_routing_context.cpython-313.pyc +0 -0
- package/core/runtime/__pycache__/openrouter_provider.cpython-312.pyc +0 -0
- package/core/runtime/__pycache__/runtime_models.cpython-313.pyc +0 -0
- package/core/runtime/model_router.py +17 -0
- package/core/runtime/model_routing_context.py +82 -0
- package/core/runtime/runtime_models.py +51 -0
- package/core/workflow/__pycache__/flow_authorization.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/flow_authorization.cpython-314.pyc +0 -0
- package/core/workflow/__pycache__/flow_enforcer.cpython-313.pyc +0 -0
- package/core/workflow/__pycache__/flow_enforcer.cpython-314.pyc +0 -0
- package/core/workflow/flow_authorization.py +181 -0
- package/core/workflow/flow_enforcer.py +56 -11
- package/core/workflow/state_reader.sh +12 -5
- package/dashboard/app/pages/models.vue +23 -4
- 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/cli.js +21 -0
- package/installer/index.js +14 -0
- package/installer/update.js +13 -0
- package/package.json +5 -2
- package/pyproject.toml +1 -1
- package/scripts/__pycache__/dashboard-api.cpython-313.pyc +0 -0
- package/scripts/dashboard-api.py +13 -2
- package/scripts/seed_initial_patterns.py +1 -1
package/README.md
CHANGED
|
@@ -491,7 +491,7 @@ npx arkaos uninstall # Remove ArkaOS
|
|
|
491
491
|
**Release pipeline (operator-side, headless):**
|
|
492
492
|
|
|
493
493
|
```
|
|
494
|
-
|
|
494
|
+
~/.arkaos/bin/arka-py -m core.release.preflight_cli --expected-npm-user <user>
|
|
495
495
|
# Step 0 NON-NEGOTIABLE before any tag/push/publish (v2.43.0+).
|
|
496
496
|
# Six checks: version-alignment / npm-auth / npm-publish-capability /
|
|
497
497
|
# gh-auth / git-remote / git-clean. Plus no-client-name-leaks
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.3.
|
|
1
|
+
4.3.2
|
package/arka/SKILL.md
CHANGED
|
@@ -180,10 +180,10 @@ violation (squad-routing, arka-supremacy, spec-driven, mandatory-qa).
|
|
|
180
180
|
| Command | Description |
|
|
181
181
|
|---------|-------------|
|
|
182
182
|
| `/arka status` | System status (version, departments, agents, active projects). Includes **LLM costs (24h)** section: top-line cost + cache hit rate + call count from `core.runtime.llm_cost_telemetry.summarise(period="today")`. Also includes **Enforcement (24h)** section: total calls, block rate, top blocked tools/reasons from `core.governance.enforcement_telemetry.summarise(period="today")` (PR19 v2.41.0). Plus **Reorganization (today)** section: today's proposal path + artifact count from `core.cognition.reorganizer_scheduler.status_summary()` (PR24 v2.46.0). |
|
|
183
|
-
| `/arka costs [period]` | LLM cost visibility — aggregates telemetry by day/week/month/all, with top expensive sessions. See `arka/skills/costs/SKILL.md`. Shells out to
|
|
184
|
-
| `/arka enforcement [period]` | Enforcement compliance — aggregates flow-marker enforcement telemetry by day/week/month/all. Shows block rate, top blocked tools, top reasons. Shells out to
|
|
185
|
-
| `/arka compliance [period]` | Behavior compliance summary (PR29 v2.48.0) — aggregates stop-hook telemetry by day/week/month/all. Shows rates for the four contracts: closing marker, `[arka:meta]` tag, KB citation pass, sycophancy clean. Shells out to
|
|
186
|
-
| `/arka reorganize [--since-days N]` | Dreaming → Agent reorganizer. Aggregates recent KB pattern/anti-pattern/lesson artifacts (default last 7 days) into a markdown proposal at `~/.arkaos/reorganize-proposals/<date>.md`. **Propose-only** — never modifies agent YAMLs. Sanitizes client identifiers from titles and body excerpts; drops `tags:` field entirely to prevent project-name leaks. **Auto-fires on session start when today's proposal is missing** (PR24 v2.46.0 stale-aware trigger, 30s timeout, background). Shells out to
|
|
183
|
+
| `/arka costs [period]` | LLM cost visibility — aggregates telemetry by day/week/month/all, with top expensive sessions. See `arka/skills/costs/SKILL.md`. Shells out to `~/.arkaos/bin/arka-py -m core.runtime.llm_cost_telemetry_cli <period>`. |
|
|
184
|
+
| `/arka enforcement [period]` | Enforcement compliance — aggregates flow-marker enforcement telemetry by day/week/month/all. Shows block rate, top blocked tools, top reasons. Shells out to `~/.arkaos/bin/arka-py -m core.governance.enforcement_telemetry_cli <period>`. |
|
|
185
|
+
| `/arka compliance [period]` | Behavior compliance summary (PR29 v2.48.0) — aggregates stop-hook telemetry by day/week/month/all. Shows rates for the four contracts: closing marker, `[arka:meta]` tag, KB citation pass, sycophancy clean. Shells out to `~/.arkaos/bin/arka-py -m core.governance.compliance_telemetry_cli <period>`. |
|
|
186
|
+
| `/arka reorganize [--since-days N]` | Dreaming → Agent reorganizer. Aggregates recent KB pattern/anti-pattern/lesson artifacts (default last 7 days) into a markdown proposal at `~/.arkaos/reorganize-proposals/<date>.md`. **Propose-only** — never modifies agent YAMLs. Sanitizes client identifiers from titles and body excerpts; drops `tags:` field entirely to prevent project-name leaks. **Auto-fires on session start when today's proposal is missing** (PR24 v2.46.0 stale-aware trigger, 30s timeout, background). Shells out to `~/.arkaos/bin/arka-py -m core.cognition.reorganizer_cli [--since-days N] [--dry-run]`. |
|
|
187
187
|
| `/arka standup` | Daily standup (projects, priorities, blockers, updates) |
|
|
188
188
|
| `/arka monitor` | System health monitoring |
|
|
189
189
|
| `/arka onboard <path>` | Onboard an existing project into ArkaOS |
|
|
@@ -42,7 +42,7 @@ surfaces usage and emits soft advisories. It never blocks a call.
|
|
|
42
42
|
This skill shells out to the Python CLI:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
-
|
|
45
|
+
~/.arkaos/bin/arka-py -m core.runtime.llm_cost_telemetry_cli <period>
|
|
46
46
|
```
|
|
47
47
|
|
|
48
48
|
Source:
|
|
@@ -24,9 +24,9 @@ mechanical work economises.
|
|
|
24
24
|
Run and read all three:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
~/.arkaos/bin/arka-py -m core.runtime.model_router_cli discover # Ollama + local models
|
|
28
|
+
~/.arkaos/bin/arka-py -m core.runtime.model_router_cli --json # current routing
|
|
29
|
+
~/.arkaos/bin/arka-py -m core.runtime.model_router_cli usage --period week --json
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
Also check key presence (never print values): `OPENROUTER_API_KEY` /
|
|
@@ -75,11 +75,18 @@ Produce a table: role → provider/model + ONE-line rationale each. Rules:
|
|
|
75
75
|
|
|
76
76
|
```bash
|
|
77
77
|
npx arkaos models set <role> <provider>/<model> --effort <effort>
|
|
78
|
+
npx arkaos fusion --save "<a first question>" # persist a panel + run it
|
|
78
79
|
```
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
`npx arkaos fusion --show` prints the panel that would run (a sensible
|
|
82
|
+
default is built from the machine's models when none is configured);
|
|
83
|
+
`npx arkaos fusion --save "question"` writes the panel into
|
|
84
|
+
`~/.arkaos/models.yaml` and runs it; `npx arkaos fusion "question"` runs
|
|
85
|
+
without persisting. For fine-grained panel/judge edits, edit
|
|
86
|
+
`~/.arkaos/models.yaml` directly (keep comments). Show the final
|
|
87
|
+
`npx arkaos models` table as proof and remind: the dashboard Models page
|
|
88
|
+
shows the same state + live usage, and the SessionStart hook now injects
|
|
89
|
+
the routing so it governs agent dispatch.
|
|
83
90
|
|
|
84
91
|
## Hard rules
|
|
85
92
|
|
|
@@ -23,7 +23,7 @@ evidence, not from model size.
|
|
|
23
23
|
## Review Rubric (evidence interpretation, not role-play)
|
|
24
24
|
|
|
25
25
|
1. Run the engine first — no verdict without a report:
|
|
26
|
-
|
|
26
|
+
`~/.arkaos/bin/arka-py -m core.governance.evidence_checks <project_dir> [--changed-files ...] [--test-command '...'] --json`
|
|
27
27
|
2. Dispatch Eduardo (spellcheck + changed copy) and Francisca
|
|
28
28
|
(lint/typecheck/tests/coverage/security-grep) with the report and the
|
|
29
29
|
structured output schema `QG_VERDICT_JSON_SCHEMA` from
|
|
@@ -24,7 +24,7 @@ not cut corners to look fast.
|
|
|
24
24
|
dispatch with `[arka:dispatch] paulo -> <specialist>`.
|
|
25
25
|
3. Evidence over narration: a task is done when its tests RAN and exited 0
|
|
26
26
|
on record — never when a subagent says it is done. Run
|
|
27
|
-
|
|
27
|
+
`~/.arkaos/bin/arka-py -m core.governance.evidence_checks <project_dir> --json` before
|
|
28
28
|
claiming completion.
|
|
29
29
|
4. Submit to the Quality Gate (marta-cqo) with the evidence report; expect
|
|
30
30
|
a structured `QGVerdict` back. REJECTED means loop, not negotiate.
|
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"
|
|
@@ -105,16 +109,37 @@ MSG+="\\nFields: kb=N (Obsidian/KB notes consulted), research=X (MCPs invoked: p
|
|
|
105
109
|
MSG+="\\nMandatory after: EFFECT tool calls, plan/recommendation outputs, QG verdicts. Optional for pure read-only status replies."
|
|
106
110
|
MSG+="\\nAbsence is measured by the Stop hook (warn-only in v2.34.0) before promotion to hard enforcement."
|
|
107
111
|
|
|
112
|
+
# ─── Model Fabric routing (consumption layer) ───────────────────────────
|
|
113
|
+
# Feed the operator's ~/.arkaos/models.yaml back to the orchestrator so
|
|
114
|
+
# dashboard/CLI model choices actually govern agent dispatch. Cheap
|
|
115
|
+
# (single python read); skipped silently if the config can't be resolved.
|
|
116
|
+
if [ -n "$REPO" ]; then
|
|
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 "
|
|
121
|
+
try:
|
|
122
|
+
from core.runtime.model_routing_context import routing_directive
|
|
123
|
+
print(routing_directive())
|
|
124
|
+
except Exception:
|
|
125
|
+
pass
|
|
126
|
+
" 2>/dev/null)
|
|
127
|
+
if [ -n "$_MF_DIRECTIVE" ]; then
|
|
128
|
+
MSG+="\\n\\n${_MF_DIRECTIVE}"
|
|
129
|
+
fi
|
|
130
|
+
fi
|
|
131
|
+
fi
|
|
132
|
+
|
|
108
133
|
# ─── Stale-aware reorganizer trigger (PR24 v2.46.0) ─────────────────────
|
|
109
134
|
# If today's proposal file is missing, fire the reorganizer in the
|
|
110
135
|
# background with a 30s timeout. Best-effort, never blocks session
|
|
111
136
|
# start. Multiple sessions per day no-op because the file now exists.
|
|
112
|
-
if [ -n "$REPO" ] && command -v
|
|
137
|
+
if [ -n "$REPO" ] && command -v "$ARKA_PY" >/dev/null 2>&1; then
|
|
113
138
|
_PROPOSAL_DIR="$HOME/.arkaos/reorganize-proposals"
|
|
114
139
|
_TODAY="$(date -u +%Y-%m-%d).md"
|
|
115
140
|
if [ ! -f "$_PROPOSAL_DIR/$_TODAY" ]; then
|
|
116
141
|
(
|
|
117
|
-
cd "$REPO" && timeout 30s
|
|
142
|
+
cd "$REPO" && timeout 30s "$ARKA_PY" -m core.cognition.reorganizer_cli >/dev/null 2>&1
|
|
118
143
|
) &
|
|
119
144
|
disown 2>/dev/null || true
|
|
120
145
|
fi
|
|
@@ -126,7 +151,7 @@ fi
|
|
|
126
151
|
# starts API+UI. Background + disown so it never touches the 5s budget.
|
|
127
152
|
# Toggle off: ~/.arkaos/config.json -> {"dashboard": {"ensure_on_session": false}}
|
|
128
153
|
if [ -n "$REPO" ] && [ -f "$REPO/scripts/start-dashboard.sh" ]; then
|
|
129
|
-
_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")
|
|
130
155
|
if [ "$_DASH_ENSURE" = "True" ] || [ "$_DASH_ENSURE" = "true" ]; then
|
|
131
156
|
mkdir -p "$HOME/.arkaos/logs"
|
|
132
157
|
(
|
|
@@ -143,8 +168,8 @@ if [ -n "$REPO" ] && [ -f "$REPO/scripts/start-dashboard.sh" ]; then
|
|
|
143
168
|
fi
|
|
144
169
|
|
|
145
170
|
# --- Session Memory Resume Context ---
|
|
146
|
-
if command -v
|
|
147
|
-
_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 "
|
|
148
173
|
import sys
|
|
149
174
|
sys.path.insert(0, '$REPO')
|
|
150
175
|
try:
|
|
@@ -159,7 +184,7 @@ except Exception:
|
|
|
159
184
|
fi
|
|
160
185
|
|
|
161
186
|
# ─── Output as systemMessage (same protocol as claude-mem) ─────────────
|
|
162
|
-
|
|
187
|
+
"$ARKA_PY" -c "
|
|
163
188
|
import json
|
|
164
189
|
msg = '''$(echo -e "$MSG")'''
|
|
165
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
|