arkaos 4.48.0 → 4.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/THE-ARKAOS-GUIDE.md +2 -2
- package/VERSION +1 -1
- package/arka/SKILL.md +1 -1
- package/config/hooks/_lib/fastpath/engine.cjs +29 -5
- package/config/hooks/gate-manifest.json +14 -1
- package/core/hooks/gate_manifest.py +12 -0
- package/core/hooks/post_tool_use.py +46 -4
- package/core/hooks/pre_tool_use.py +36 -3
- package/core/workflow/flow_enforcer.py +112 -20
- package/core/workflow/frontend_gate.py +64 -5
- package/core/workflow/specialist_enforcer.py +48 -15
- package/departments/kb/SKILL.md +1 -0
- package/departments/kb/skills/research-deep/SKILL.md +192 -0
- package/departments/kb/skills/research-deep/THIRD-PARTY-NOTICES.md +15 -0
- package/harness/codex/AGENTS.md +2 -2
- package/harness/copilot/copilot-instructions.md +2 -2
- package/harness/cursor/rules/arkaos.mdc +3 -3
- package/harness/gemini/GEMINI.md +2 -2
- package/harness/opencode/AGENTS.md +2 -2
- package/harness/opencode/agents/arka-architect-gabriel.md +1 -1
- package/harness/opencode/agents/arka-brand-director-valentina.md +1 -1
- package/harness/opencode/agents/arka-cfo-helena.md +1 -1
- package/harness/opencode/agents/arka-chief-of-staff-afonso.md +1 -1
- package/harness/opencode/agents/arka-community-strategist-beatriz.md +1 -1
- package/harness/opencode/agents/arka-content-strategist-rafael.md +1 -1
- package/harness/opencode/agents/arka-conversion-strategist-ines.md +1 -1
- package/harness/opencode/agents/arka-coo-sofia.md +1 -1
- package/harness/opencode/agents/arka-copy-director-eduardo.md +1 -1
- package/harness/opencode/agents/arka-cqo-marta.md +1 -1
- package/harness/opencode/agents/arka-cto-marco.md +1 -1
- package/harness/opencode/agents/arka-design-ops-lead-iris.md +1 -1
- package/harness/opencode/agents/arka-ecom-director-ricardo.md +1 -1
- package/harness/opencode/agents/arka-knowledge-director-clara.md +1 -1
- package/harness/opencode/agents/arka-leadership-director-rodrigo.md +1 -1
- package/harness/opencode/agents/arka-marketing-director-luna.md +1 -1
- package/harness/opencode/agents/arka-ops-lead-daniel.md +1 -1
- package/harness/opencode/agents/arka-pm-director-carolina.md +1 -1
- package/harness/opencode/agents/arka-revops-lead-vicente.md +1 -1
- package/harness/opencode/agents/arka-saas-strategist-tiago.md +1 -1
- package/harness/opencode/agents/arka-sales-director-miguel.md +1 -1
- package/harness/opencode/agents/arka-strategy-director-tomas.md +1 -1
- package/harness/opencode/agents/arka-tech-director-francisca.md +1 -1
- package/harness/opencode/agents/arka-tech-lead-paulo.md +1 -1
- package/harness/opencode/agents/arka-video-producer-simao.md +1 -1
- package/harness/zed/.rules +2 -2
- package/knowledge/commands-registry.json +25 -3
- package/knowledge/skills-manifest.json +14 -1
- package/package.json +1 -1
- package/pyproject.toml +1 -1
|
@@ -35,8 +35,9 @@ from __future__ import annotations
|
|
|
35
35
|
import json
|
|
36
36
|
import os
|
|
37
37
|
import re
|
|
38
|
+
import time
|
|
38
39
|
from dataclasses import asdict, dataclass
|
|
39
|
-
from datetime import
|
|
40
|
+
from datetime import UTC, datetime
|
|
40
41
|
from pathlib import Path
|
|
41
42
|
|
|
42
43
|
from core.shared import safe_session_id as _safe_session_id_module
|
|
@@ -44,6 +45,7 @@ from core.workflow import design_authorization
|
|
|
44
45
|
from core.workflow.flow_enforcer import (
|
|
45
46
|
TRIVIAL_RE,
|
|
46
47
|
_load_last_assistant_messages,
|
|
48
|
+
shadow_deny_on,
|
|
47
49
|
)
|
|
48
50
|
from core.workflow.specialist_enforcer import _locked_append
|
|
49
51
|
|
|
@@ -93,6 +95,11 @@ class Decision:
|
|
|
93
95
|
marker_found: str | None = None
|
|
94
96
|
marker_kind: str = "none" # structured | legacy | trivial | none
|
|
95
97
|
ui_scope: str = "suffix" # suffix | heuristic
|
|
98
|
+
# PR-A5a shadow-deny — see flow_enforcer.Decision: what hard mode
|
|
99
|
+
# WOULD have decided, recorded while warn/off modes keep allowing.
|
|
100
|
+
would_block: bool = False
|
|
101
|
+
shadow_reason: str = ""
|
|
102
|
+
shadow_ms: float = 0.0
|
|
96
103
|
|
|
97
104
|
def to_stderr_message(self) -> str:
|
|
98
105
|
if self.reason == "legacy-marker":
|
|
@@ -237,6 +244,51 @@ def _marker_decision(
|
|
|
237
244
|
ui_scope=ui_scope)
|
|
238
245
|
|
|
239
246
|
|
|
247
|
+
def _shadow_off_decision(
|
|
248
|
+
session_id: str,
|
|
249
|
+
file_path: str,
|
|
250
|
+
ui_scope: str,
|
|
251
|
+
transcript_path: str,
|
|
252
|
+
messages: list[str] | None,
|
|
253
|
+
) -> Decision:
|
|
254
|
+
"""Off mode with shadow-deny on (PR-A5a): evaluate the marker chain
|
|
255
|
+
anyway and record what hard mode would have decided — silently
|
|
256
|
+
(reason "flag-off" produces no stderr message)."""
|
|
257
|
+
if os.environ.get("ARKA_BYPASS_DESIGN") == "1":
|
|
258
|
+
return Decision(allow=True, reason="flag-off", mode="off",
|
|
259
|
+
target_file=file_path, ui_scope=ui_scope,
|
|
260
|
+
shadow_reason="env-bypass")
|
|
261
|
+
start = time.perf_counter()
|
|
262
|
+
if messages is None:
|
|
263
|
+
messages = _load_last_assistant_messages(
|
|
264
|
+
transcript_path, ASSISTANT_WINDOW
|
|
265
|
+
)
|
|
266
|
+
marker, kind = _classify_marker(messages)
|
|
267
|
+
inner = _marker_decision(session_id, marker, kind, "hard", file_path, ui_scope)
|
|
268
|
+
return Decision(
|
|
269
|
+
allow=True, reason="flag-off", mode="off", target_file=file_path,
|
|
270
|
+
marker_found=inner.marker_found, marker_kind=inner.marker_kind,
|
|
271
|
+
ui_scope=ui_scope, would_block=not inner.allow,
|
|
272
|
+
shadow_reason=inner.reason,
|
|
273
|
+
shadow_ms=round((time.perf_counter() - start) * 1000, 3),
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def _annotate_warn_shadow(decision: Decision) -> Decision:
|
|
278
|
+
"""Warn mode already evaluates the full chain — annotate what hard
|
|
279
|
+
mode would have denied (suffix scope, no structured/trivial/persisted
|
|
280
|
+
marker). Zero added transcript reads; gated on the same kill-switch."""
|
|
281
|
+
if (
|
|
282
|
+
decision.allow
|
|
283
|
+
and decision.ui_scope == "suffix"
|
|
284
|
+
and decision.reason in ("legacy-marker", "no-design-marker")
|
|
285
|
+
and shadow_deny_on()
|
|
286
|
+
):
|
|
287
|
+
decision.would_block = True
|
|
288
|
+
decision.shadow_reason = decision.reason
|
|
289
|
+
return decision
|
|
290
|
+
|
|
291
|
+
|
|
240
292
|
def evaluate(
|
|
241
293
|
tool_name: str,
|
|
242
294
|
transcript_path: str,
|
|
@@ -252,8 +304,12 @@ def evaluate(
|
|
|
252
304
|
return Decision(allow=True, reason="not-ui-scope", target_file=file_path)
|
|
253
305
|
mode = _mode()
|
|
254
306
|
if mode == "off":
|
|
255
|
-
|
|
256
|
-
|
|
307
|
+
if not shadow_deny_on():
|
|
308
|
+
return Decision(allow=True, reason="flag-off", mode=mode,
|
|
309
|
+
target_file=file_path, ui_scope=ui_scope)
|
|
310
|
+
return _shadow_off_decision(
|
|
311
|
+
session_id, file_path, ui_scope, transcript_path, messages
|
|
312
|
+
)
|
|
257
313
|
if os.environ.get("ARKA_BYPASS_DESIGN") == "1":
|
|
258
314
|
return Decision(allow=True, reason="env-bypass", mode=mode,
|
|
259
315
|
target_file=file_path, ui_scope=ui_scope)
|
|
@@ -262,7 +318,10 @@ def evaluate(
|
|
|
262
318
|
transcript_path, ASSISTANT_WINDOW
|
|
263
319
|
)
|
|
264
320
|
marker, kind = _classify_marker(messages)
|
|
265
|
-
|
|
321
|
+
decision = _marker_decision(session_id, marker, kind, mode, file_path, ui_scope)
|
|
322
|
+
if mode == "warn":
|
|
323
|
+
decision = _annotate_warn_shadow(decision)
|
|
324
|
+
return decision
|
|
266
325
|
|
|
267
326
|
|
|
268
327
|
def record_telemetry(session_id: str, tool: str, decision: Decision) -> None:
|
|
@@ -275,7 +334,7 @@ def record_telemetry(session_id: str, tool: str, decision: Decision) -> None:
|
|
|
275
334
|
if safe is None:
|
|
276
335
|
return
|
|
277
336
|
entry = {
|
|
278
|
-
"ts": datetime.now(
|
|
337
|
+
"ts": datetime.now(UTC).isoformat(),
|
|
279
338
|
"session_id": safe,
|
|
280
339
|
"tool": tool,
|
|
281
340
|
**asdict(decision),
|
|
@@ -39,8 +39,9 @@ flow-gate. Same Decision JSON contract as core.workflow.flow_enforcer.
|
|
|
39
39
|
import contextlib
|
|
40
40
|
import json
|
|
41
41
|
import re
|
|
42
|
+
import time
|
|
42
43
|
from contextlib import contextmanager
|
|
43
|
-
from dataclasses import asdict, dataclass, field
|
|
44
|
+
from dataclasses import asdict, dataclass, field, replace
|
|
44
45
|
from datetime import UTC, datetime
|
|
45
46
|
from functools import lru_cache
|
|
46
47
|
from pathlib import Path
|
|
@@ -49,6 +50,7 @@ import yaml
|
|
|
49
50
|
|
|
50
51
|
from core.shared import safe_session_id as _safe_session_id_module
|
|
51
52
|
from core.workflow import specialist_authorization, transcript_scope
|
|
53
|
+
from core.workflow.flow_enforcer import shadow_deny_on
|
|
52
54
|
|
|
53
55
|
try:
|
|
54
56
|
import fcntl # POSIX only
|
|
@@ -138,6 +140,11 @@ class Decision:
|
|
|
138
140
|
persona_source: str = ""
|
|
139
141
|
is_sidechain: bool = False
|
|
140
142
|
msgs_since_marker: int | None = None
|
|
143
|
+
# PR-A5a shadow-deny — see flow_enforcer.Decision: what enforcement
|
|
144
|
+
# WOULD have decided while hooks.specialistEnforcement stays off.
|
|
145
|
+
would_block: bool = False
|
|
146
|
+
shadow_reason: str = ""
|
|
147
|
+
shadow_ms: float = 0.0
|
|
141
148
|
|
|
142
149
|
def to_stderr_message(self) -> str:
|
|
143
150
|
"""The message a blocked session reads.
|
|
@@ -432,10 +439,38 @@ def _check_tool_gated(ctx: _Ctx) -> Decision | None:
|
|
|
432
439
|
return None
|
|
433
440
|
|
|
434
441
|
|
|
435
|
-
def
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
442
|
+
def _decide_populated(ctx: _Ctx) -> Decision:
|
|
443
|
+
"""The enforcement pipeline behind the feature flag: populate the
|
|
444
|
+
context, run the late checks, resolve ownership."""
|
|
445
|
+
_populate_context(ctx)
|
|
446
|
+
for late_check in (_check_no_persona, _check_c_suite, _check_lead_allowed_file):
|
|
447
|
+
decision = late_check(ctx)
|
|
448
|
+
if decision is not None:
|
|
449
|
+
return decision
|
|
450
|
+
return _resolve_ownership_outcome(ctx)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def _shadow_decision(ctx: _Ctx) -> Decision:
|
|
454
|
+
"""Run the pipeline in shadow (PR-A5a): allow regardless, record what
|
|
455
|
+
enforcement would have decided, carrying the resolved persona and
|
|
456
|
+
ownership context into telemetry. Silent by construction — allow=True
|
|
457
|
+
means to_stderr_message() returns "". bypass_used/bypass_reason are
|
|
458
|
+
reset: a bypass of an inactive gate is not a bypass and must not
|
|
459
|
+
inflate the specialist-telemetry counter — shadow_reason still says
|
|
460
|
+
"bypass-with-reason", so no information is lost (QG r1, Francisca B1).
|
|
461
|
+
"""
|
|
462
|
+
start = time.perf_counter()
|
|
463
|
+
inner = _decide_populated(ctx)
|
|
464
|
+
return replace(
|
|
465
|
+
inner,
|
|
466
|
+
allow=True,
|
|
467
|
+
reason="feature-flag-off",
|
|
468
|
+
bypass_used=False,
|
|
469
|
+
bypass_reason=None,
|
|
470
|
+
would_block=not inner.allow,
|
|
471
|
+
shadow_reason=inner.reason,
|
|
472
|
+
shadow_ms=round((time.perf_counter() - start) * 1000, 3),
|
|
473
|
+
)
|
|
439
474
|
|
|
440
475
|
|
|
441
476
|
def _msgs_since_marker(messages: list[str]) -> int | None:
|
|
@@ -626,16 +661,14 @@ def evaluate(
|
|
|
626
661
|
session_id=session_id, cwd=cwd, tool_input=tool_input or {},
|
|
627
662
|
preloaded_messages=messages, is_sidechain=is_sidechain,
|
|
628
663
|
)
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
return decision
|
|
638
|
-
return _resolve_ownership_outcome(ctx)
|
|
664
|
+
decision = _check_tool_gated(ctx)
|
|
665
|
+
if decision is not None:
|
|
666
|
+
return decision
|
|
667
|
+
if _feature_flag_on():
|
|
668
|
+
return _decide_populated(ctx)
|
|
669
|
+
if not shadow_deny_on():
|
|
670
|
+
return Decision(allow=True, reason="feature-flag-off")
|
|
671
|
+
return _shadow_decision(ctx)
|
|
639
672
|
|
|
640
673
|
|
|
641
674
|
def record_telemetry(
|
package/departments/kb/SKILL.md
CHANGED
|
@@ -24,6 +24,7 @@ allowed-tools: [Read, Write, Edit, Bash, Grep, Glob, Agent, WebFetch, WebSearch]
|
|
|
24
24
|
| `/kb learn <url>` | Ingest content (YouTube, article, PDF) into KB | Enterprise |
|
|
25
25
|
| `/kb research <topic>` | Research plan and execution with source evaluation | Focused |
|
|
26
26
|
| `/kb ai-research <topic>` | AI-augmented research (Elicit, Perplexity, Claude) | Focused |
|
|
27
|
+
| `/kb research-deep <question>` | Ladder over the operator's own corpus: Obsidian → NotebookLM (egress-guarded) → web, with vault write-back | Focused |
|
|
27
28
|
| `/kb persona <name>` | Build or view a persona from the KB | Enterprise |
|
|
28
29
|
| `/kb moc <cluster>` | Create/update Map of Content | Specialist |
|
|
29
30
|
| `/kb zettelkasten <note>` | Process a note through Zettelkasten workflow | Specialist |
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kb/research-deep
|
|
3
|
+
description: >
|
|
4
|
+
Heavy-research ladder over the operator's own knowledge: Obsidian
|
|
5
|
+
vault first (cite or declare the gap), then the operator's NotebookLM
|
|
6
|
+
notebook through the egress-guarded chokepoint, then open web for
|
|
7
|
+
whatever gap remains — ending in a synthesis note written back to the
|
|
8
|
+
vault with provenance frontmatter (egress_decision, degraded).
|
|
9
|
+
TRIGGER: "research deep", "pesquisa profunda", "pergunta ao
|
|
10
|
+
NotebookLM", "usa o notebook", "deep dive com as minhas fontes",
|
|
11
|
+
"/kb research-deep <question>". SKIP: general fan-out research whose
|
|
12
|
+
deliverable is a cited KB note -> arka-research (5 parallel external
|
|
13
|
+
searchers; this skill is depth over the operator's OWN corpus);
|
|
14
|
+
defining a research question and its method from scratch ->
|
|
15
|
+
kb/research-plan (owns the 5-step methodology; this skill executes a
|
|
16
|
+
source ladder against an already-framed question);
|
|
17
|
+
library/framework evaluation -> dev research (Lucas); a named
|
|
18
|
+
competitor -> kb/competitive-intel.
|
|
19
|
+
allowed-tools: [Read, Write, Bash, Grep, Glob, WebFetch, WebSearch, mcp__obsidian__search_notes, mcp__obsidian__write_note, mcp__graphify__query_graph]
|
|
20
|
+
metadata:
|
|
21
|
+
origin: arkaos
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
<!-- arka:kb-first-prefix begin -->
|
|
25
|
+
> **KB-first:** query `mcp__obsidian__search_notes` (and
|
|
26
|
+
> `mcp__graphify__query_graph` when configured) and cite `[[wikilinks]]`
|
|
27
|
+
> or graph nodes — or declare the gap — BEFORE any external research.
|
|
28
|
+
> Full doctrine: `arka/SKILL.md` (KB-First Research).
|
|
29
|
+
<!-- arka:kb-first-prefix end -->
|
|
30
|
+
|
|
31
|
+
# Research Deep — `/kb research-deep <question>`
|
|
32
|
+
|
|
33
|
+
> **Agent:** Clara (Knowledge Director) | **Framework:** KB-first ladder (Obsidian → NotebookLM → web)
|
|
34
|
+
|
|
35
|
+
## What It Does
|
|
36
|
+
|
|
37
|
+
Answers a hard question by climbing four rungs in order — three that
|
|
38
|
+
research, one that writes back — asking the cheapest and most-trusted
|
|
39
|
+
source first. Each rung either answers, or narrows the gap the next rung
|
|
40
|
+
has to fill. The output is a synthesis note written back to the Obsidian
|
|
41
|
+
vault with provenance frontmatter, so the next run starts from a fuller
|
|
42
|
+
vault.
|
|
43
|
+
|
|
44
|
+
NotebookLM is reached EXCLUSIVELY through the `core.kb.nlm_client`
|
|
45
|
+
chokepoint — the egress guard (deny-by-default policy, client-identifier
|
|
46
|
+
redaction, salted audit trail) screens every payload before anything
|
|
47
|
+
leaves the machine. Never invoke the `notebooklm` binary directly, and
|
|
48
|
+
never install or vendor `notebooklm-py` from this skill: when the tool
|
|
49
|
+
is absent the chokepoint says so and the ladder continues.
|
|
50
|
+
|
|
51
|
+
## Rung 1 — Obsidian (mandatory, never skipped)
|
|
52
|
+
|
|
53
|
+
1. `mcp__obsidian__search_notes` on the question and its key terms
|
|
54
|
+
(plus `mcp__graphify__query_graph` when configured).
|
|
55
|
+
2. Read the hits that matter. Cite them as `[[wikilinks]]` in the
|
|
56
|
+
synthesis.
|
|
57
|
+
3. Decide honestly: answered, partially answered (name the residual
|
|
58
|
+
gap), or gap. Only a named gap justifies the next rung.
|
|
59
|
+
|
|
60
|
+
## Rung 2 — NotebookLM (chokepoint-only, degradation never blocks)
|
|
61
|
+
|
|
62
|
+
Preflight once per session:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
~/.arkaos/bin/arka-py - <<'PY'
|
|
66
|
+
from core.kb.nlm_client import check
|
|
67
|
+
r = check()
|
|
68
|
+
print("ok" if r.ok else r.marker)
|
|
69
|
+
PY
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Then ask. **Never interpolate the question into the command.** A research
|
|
73
|
+
question routinely carries backticks, `$`, quotes and `$HOME`, and a
|
|
74
|
+
shell that expands them executes the question instead of asking it (and
|
|
75
|
+
`$HOME` expansion alone manufactures a false confidentiality denial).
|
|
76
|
+
The heredoc below is quoted (`<<'PY'`), so the shell passes it through
|
|
77
|
+
untouched.
|
|
78
|
+
|
|
79
|
+
The scratch path is fixed — `$HOME/.arkaos/tmp/research-deep-gap.txt` —
|
|
80
|
+
so no agent-chosen path reaches the program either. Write the gap there
|
|
81
|
+
with the Write tool (absolute path, expand `$HOME` yourself; create the
|
|
82
|
+
directory first if your runtime's write primitive does not), then:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
~/.arkaos/bin/arka-py - <<'PY'
|
|
86
|
+
from pathlib import Path
|
|
87
|
+
from core.kb.nlm_client import send
|
|
88
|
+
gap_file = Path.home() / ".arkaos" / "tmp" / "research-deep-gap.txt"
|
|
89
|
+
gap = gap_file.read_text()
|
|
90
|
+
gap_file.unlink() # one gap per ask: a stale read fails loudly instead
|
|
91
|
+
r = send(gap, action="ask", output_format="markdown")
|
|
92
|
+
print(r.stdout if r.ok else r.marker)
|
|
93
|
+
PY
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
A `FileNotFoundError` here means the Write did not land — write the gap
|
|
97
|
+
again rather than re-running the ask, which would otherwise have sent
|
|
98
|
+
the previous session's question.
|
|
99
|
+
|
|
100
|
+
Reading the result — the contract is `NotebookLMResult`:
|
|
101
|
+
|
|
102
|
+
| Field | Meaning |
|
|
103
|
+
|---|---|
|
|
104
|
+
| `ok=True` | `r.stdout` is the answer; cite it as `NotebookLM (notebook)` |
|
|
105
|
+
| `ok=False, denied=True` | the egress guard refused the payload (e.g. client identifiers survived redaction) — do NOT rephrase-and-retry to evade it; record the marker and move on |
|
|
106
|
+
| `ok=False, degraded=True` | tool absent, timeout, or unusable run — record the marker and move on |
|
|
107
|
+
|
|
108
|
+
Branch on `ok`, never on `degraded` alone (a denied payload is not a
|
|
109
|
+
success path). When `ok` is False, put the marker line —
|
|
110
|
+
`[arka:source-skipped] notebooklm (<reason>)` — on record in your reply
|
|
111
|
+
AND in the synthesis note, then continue to rung 3. A broken or refused
|
|
112
|
+
upstream narrows the ladder; it never blocks it. Other actions in
|
|
113
|
+
`ALLOWED_ACTIONS`: `report` and `mindmap` (same result contract), and
|
|
114
|
+
`add-source`, which pushes a text INTO the notebook — see the optional
|
|
115
|
+
step in rung 4.
|
|
116
|
+
|
|
117
|
+
If the preflight says the tool is missing and the operator wants it,
|
|
118
|
+
the install is THEIR command, not this skill's:
|
|
119
|
+
`uv tool install 'notebooklm-py[browser]'`.
|
|
120
|
+
|
|
121
|
+
## Rung 3 — Open web (only for the residual gap)
|
|
122
|
+
|
|
123
|
+
`WebSearch` / `WebFetch` scoped to what rungs 1-2 could not answer.
|
|
124
|
+
Prefer primary sources; carry URLs into the synthesis. If rung 2 was
|
|
125
|
+
denied, remember the payload was refused for a confidentiality reason —
|
|
126
|
+
do not paste the same refused content into a web search either.
|
|
127
|
+
|
|
128
|
+
## Rung 4 — Write-back (always, even on partial answers)
|
|
129
|
+
|
|
130
|
+
Write the synthesis note to the vault via `mcp__obsidian__write_note`
|
|
131
|
+
(fallback: Write into the vault path), with provenance frontmatter:
|
|
132
|
+
|
|
133
|
+
```markdown
|
|
134
|
+
---
|
|
135
|
+
title: <question, short>
|
|
136
|
+
type: research-note
|
|
137
|
+
skill: kb/research-deep
|
|
138
|
+
date: <YYYY-MM-DD>
|
|
139
|
+
provenance:
|
|
140
|
+
rungs_used: [obsidian, notebooklm, web] # the rungs that ran
|
|
141
|
+
egress_decision: ok # ok | denied | degraded | not-attempted
|
|
142
|
+
egress_reason: "" # NotebookLMResult.reason when not ok
|
|
143
|
+
degraded: false # NotebookLMResult.degraded
|
|
144
|
+
payload_sha256: "<hex>" # see the note below — set on denial too
|
|
145
|
+
sources:
|
|
146
|
+
- "[[<vault note>]]"
|
|
147
|
+
- "NotebookLM (notebook)"
|
|
148
|
+
- "<url>"
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
<synthesis: what is known, what each rung contributed, what remains open>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Field mapping, exactly:
|
|
155
|
+
|
|
156
|
+
- `degraded`, `egress_reason` and `payload_sha256` are copied from
|
|
157
|
+
`NotebookLMResult.degraded`, `.reason` and `.payload_sha256`.
|
|
158
|
+
- `egress_decision` names whichever of `ok` / `denied` / `degraded` the
|
|
159
|
+
result carries, or `not-attempted` when rung 2 never ran — never
|
|
160
|
+
inferred from the answer text.
|
|
161
|
+
- `payload_sha256` is populated on a DENIAL too (the guard digests what
|
|
162
|
+
it refused), so record it whenever the field is non-empty and let
|
|
163
|
+
`egress_decision: denied` say that nothing left the machine.
|
|
164
|
+
|
|
165
|
+
Optionally feed the notebook back: when the synthesis is worth keeping
|
|
166
|
+
in NotebookLM, send it with `action="add-source"` through the same
|
|
167
|
+
quoted-heredoc pattern as rung 2 (same guard, same result contract).
|
|
168
|
+
|
|
169
|
+
Link related notes with `[[wikilinks]]` so the graph face of the KB
|
|
170
|
+
benefits too.
|
|
171
|
+
|
|
172
|
+
## Output
|
|
173
|
+
|
|
174
|
+
One Obsidian note per run — the synthesis, its `[[wikilinks]]` and URL
|
|
175
|
+
sources, and the provenance frontmatter above (`rungs_used`,
|
|
176
|
+
`egress_decision`, `egress_reason`, `degraded`, `payload_sha256`). Plus,
|
|
177
|
+
in the reply itself, the `[arka:source-skipped]` marker for every rung
|
|
178
|
+
that could not answer.
|
|
179
|
+
|
|
180
|
+
## Guardrails
|
|
181
|
+
|
|
182
|
+
- Chokepoint-only: any path to NotebookLM other than
|
|
183
|
+
`core.kb.nlm_client` is a campaign-decision violation (egress
|
|
184
|
+
fail-closed, 2026-07-26; contract:
|
|
185
|
+
`.arkaos/specs/notebooklm-chokepoint.yaml`).
|
|
186
|
+
- Never interpolate research text into a shell command, and never
|
|
187
|
+
interpolate a chosen path into the program — quoted heredoc plus the
|
|
188
|
+
fixed scratch path, always.
|
|
189
|
+
- A `denied` result is a confidentiality signal, not an obstacle —
|
|
190
|
+
evading it through rephrasing, chunking, or the web is forbidden.
|
|
191
|
+
- Rungs that did not run are not listed in `rungs_used`, and markers for
|
|
192
|
+
skipped sources appear in the note body.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Third-party notices — kb/research-deep
|
|
2
|
+
|
|
3
|
+
This skill's content is ArkaOS-native. At runtime, its NotebookLM rung
|
|
4
|
+
shells out — exclusively through the `core.kb.nlm_client` chokepoint —
|
|
5
|
+
to the `notebooklm` CLI provided by the **notebooklm-py** project:
|
|
6
|
+
|
|
7
|
+
- Project: notebooklm-py — https://github.com/teng-lin/notebooklm-py
|
|
8
|
+
- License: MIT (PyPI metadata, verified 2026-08-03 at version 0.8.0)
|
|
9
|
+
- Relationship: runtime dependency only. ArkaOS does not vendor,
|
|
10
|
+
redistribute, or auto-install notebooklm-py; the operator installs it
|
|
11
|
+
themselves (`uv tool install 'notebooklm-py[browser]'`) and the skill
|
|
12
|
+
degrades gracefully when it is absent.
|
|
13
|
+
|
|
14
|
+
No notebooklm-py source code or documentation text is included in this
|
|
15
|
+
skill.
|
package/harness/codex/AGENTS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ArkaOS — The Operating System for AI Agent Teams
|
|
2
2
|
|
|
3
|
-
> v4.
|
|
3
|
+
> v4.49.0 — 89 agents, 17 departments, 333 skills. Generated by `scripts/harness_gen.py`; do not edit.
|
|
4
4
|
|
|
5
5
|
You are operating within ArkaOS. Every request routes through the
|
|
6
6
|
appropriate department squad — never respond as a generic assistant.
|
|
@@ -28,7 +28,7 @@ appropriate department squad — never respond as a generic assistant.
|
|
|
28
28
|
| `/fin` | Helena | 10 |
|
|
29
29
|
| `/strat` | Tomas | 10 |
|
|
30
30
|
| `/ecom` | Ricardo | 18 |
|
|
31
|
-
| `/kb` | Clara |
|
|
31
|
+
| `/kb` | Clara | 23 |
|
|
32
32
|
| `/ops` | Daniel | 25 |
|
|
33
33
|
| `/pm` | Carolina | 12 |
|
|
34
34
|
| `/saas` | Tiago | 15 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ArkaOS — The Operating System for AI Agent Teams
|
|
2
2
|
|
|
3
|
-
> v4.
|
|
3
|
+
> v4.49.0 — 89 agents, 17 departments, 333 skills. Generated by `scripts/harness_gen.py`; do not edit.
|
|
4
4
|
|
|
5
5
|
You are operating within ArkaOS. Every request routes through the
|
|
6
6
|
appropriate department squad — never respond as a generic assistant.
|
|
@@ -28,7 +28,7 @@ appropriate department squad — never respond as a generic assistant.
|
|
|
28
28
|
| `/fin` | Helena | 10 |
|
|
29
29
|
| `/strat` | Tomas | 10 |
|
|
30
30
|
| `/ecom` | Ricardo | 18 |
|
|
31
|
-
| `/kb` | Clara |
|
|
31
|
+
| `/kb` | Clara | 23 |
|
|
32
32
|
| `/ops` | Daniel | 25 |
|
|
33
33
|
| `/pm` | Carolina | 12 |
|
|
34
34
|
| `/saas` | Tiago | 15 |
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: ArkaOS v4.
|
|
2
|
+
description: ArkaOS v4.49.0 agent-team contract
|
|
3
3
|
alwaysApply: true
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ArkaOS — The Operating System for AI Agent Teams
|
|
7
7
|
|
|
8
|
-
> v4.
|
|
8
|
+
> v4.49.0 — 89 agents, 17 departments, 333 skills. Generated by `scripts/harness_gen.py`; do not edit.
|
|
9
9
|
|
|
10
10
|
You are operating within ArkaOS. Every request routes through the
|
|
11
11
|
appropriate department squad — never respond as a generic assistant.
|
|
@@ -33,7 +33,7 @@ appropriate department squad — never respond as a generic assistant.
|
|
|
33
33
|
| `/fin` | Helena | 10 |
|
|
34
34
|
| `/strat` | Tomas | 10 |
|
|
35
35
|
| `/ecom` | Ricardo | 18 |
|
|
36
|
-
| `/kb` | Clara |
|
|
36
|
+
| `/kb` | Clara | 23 |
|
|
37
37
|
| `/ops` | Daniel | 25 |
|
|
38
38
|
| `/pm` | Carolina | 12 |
|
|
39
39
|
| `/saas` | Tiago | 15 |
|
package/harness/gemini/GEMINI.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ArkaOS — The Operating System for AI Agent Teams
|
|
2
2
|
|
|
3
|
-
> v4.
|
|
3
|
+
> v4.49.0 — 89 agents, 17 departments, 333 skills. Generated by `scripts/harness_gen.py`; do not edit.
|
|
4
4
|
|
|
5
5
|
You are operating within ArkaOS. Every request routes through the
|
|
6
6
|
appropriate department squad — never respond as a generic assistant.
|
|
@@ -28,7 +28,7 @@ appropriate department squad — never respond as a generic assistant.
|
|
|
28
28
|
| `/fin` | Helena | 10 |
|
|
29
29
|
| `/strat` | Tomas | 10 |
|
|
30
30
|
| `/ecom` | Ricardo | 18 |
|
|
31
|
-
| `/kb` | Clara |
|
|
31
|
+
| `/kb` | Clara | 23 |
|
|
32
32
|
| `/ops` | Daniel | 25 |
|
|
33
33
|
| `/pm` | Carolina | 12 |
|
|
34
34
|
| `/saas` | Tiago | 15 |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# ArkaOS — The Operating System for AI Agent Teams
|
|
2
2
|
|
|
3
|
-
> v4.
|
|
3
|
+
> v4.49.0 — 89 agents, 17 departments, 333 skills. Generated by `scripts/harness_gen.py`; do not edit.
|
|
4
4
|
|
|
5
5
|
You are operating within ArkaOS. Every request routes through the
|
|
6
6
|
appropriate department squad — never respond as a generic assistant.
|
|
@@ -28,7 +28,7 @@ appropriate department squad — never respond as a generic assistant.
|
|
|
28
28
|
| `/fin` | Helena | 10 |
|
|
29
29
|
| `/strat` | Tomas | 10 |
|
|
30
30
|
| `/ecom` | Ricardo | 18 |
|
|
31
|
-
| `/kb` | Clara |
|
|
31
|
+
| `/kb` | Clara | 23 |
|
|
32
32
|
| `/ops` | Daniel | 25 |
|
|
33
33
|
| `/pm` | Carolina | 12 |
|
|
34
34
|
| `/saas` | Tiago | 15 |
|
|
@@ -3,7 +3,7 @@ description: "Software Architect — ArkaOS /dev department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Gabriel, Software Architect of the ArkaOS /dev department (v4.
|
|
6
|
+
You are Gabriel, Software Architect of the ArkaOS /dev department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: system design, system visualization via dev/diagram (architecture + dataflow diagrams delivered as browser artifacts), domain modeling (event storming, bounded contexts), design patterns (GoF, PoEAA), business / domain analysis, API design.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Creative Director — ArkaOS /brand department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Valentina, Creative Director of the ArkaOS /brand department (v4.
|
|
6
|
+
You are Valentina, Creative Director of the ArkaOS /brand department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: brand identity creation, reference-video visual analysis via dev/watch (complete frames + transcript — motion and art direction judged on evidence, never on screenshots), visual design direction, UX/UI strategy, design systems, brand voice & tone.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Chief Financial Officer — ArkaOS /fin department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Helena, Chief Financial Officer of the ArkaOS /fin department (v4.
|
|
6
|
+
You are Helena, Chief Financial Officer of the ArkaOS /fin department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: financial planning & analysis, valuation & investment, unit economics & SaaS metrics, risk management & ERM, fundraising & cap tables, cash flow management.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Chief of Staff & Governance Lead — ArkaOS /org department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Afonso, Chief of Staff & Governance Lead of the ArkaOS /org department (v4.
|
|
6
|
+
You are Afonso, Chief of Staff & Governance Lead of the ArkaOS /org department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: meeting cadence (daily/weekly/quarterly/annual), OKR & CFR orchestration cross-department, decision records & RACI, premortem / blameless postmortem rituals, governance, board & founder-CEO succession, strategic alignment & single-threaded leadership.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Community Strategist — ArkaOS /community department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Beatriz, Community Strategist of the ArkaOS /community department (v4.
|
|
6
|
+
You are Beatriz, Community Strategist of the ArkaOS /community department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: community strategy & design, platform selection (Discord, Telegram, Skool, Circle), member onboarding & retention, monetization (membership, courses, coaching), gamification & engagement, niche communities (betting, AI, vertical).
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Content Strategist — ArkaOS /content department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Rafael, Content Strategist of the ArkaOS /content department (v4.
|
|
6
|
+
You are Rafael, Content Strategist of the ArkaOS /content department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: viral content design, reference-video analysis via dev/watch (frames + timestamped transcript before judging any video), hook writing & packaging, script structure, content operating systems, platform-specific optimization.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Conversion Strategist — ArkaOS /landing department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Ines, Conversion Strategist of the ArkaOS /landing department (v4.
|
|
6
|
+
You are Ines, Conversion Strategist of the ArkaOS /landing department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: sales funnels, landing page optimization, offer creation, copywriting (direct response), launch sequences, affiliate marketing.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Chief Operations Officer — ArkaOS /org department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Sofia, Chief Operations Officer of the ArkaOS /org department (v4.
|
|
6
|
+
You are Sofia, Chief Operations Officer of the ArkaOS /org department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: organizational design, process optimization, cross-department coordination, culture & team health, scaling operations, workflow automation.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Copy & Language Director — ArkaOS /quality department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Eduardo, Copy & Language Director of the ArkaOS /quality department (v4.
|
|
6
|
+
You are Eduardo, Copy & Language Director of the ArkaOS /quality department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: spelling and grammar (EN, PT-PT, PT-BR, ES, FR), tone and voice consistency, AI pattern detection and removal, accentuation and orthography, copywriting quality, factual accuracy in text.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Chief Quality Officer — ArkaOS /quality department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Marta, Chief Quality Officer of the ArkaOS /quality department (v4.
|
|
6
|
+
You are Marta, Chief Quality Officer of the ArkaOS /quality department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: quality assurance orchestration, cross-department quality standards, text quality (spelling, grammar, tone), technical quality (code, UX, data), compliance and audit.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Chief Technology Officer — ArkaOS /dev department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Marco, Chief Technology Officer of the ArkaOS /dev department (v4.
|
|
6
|
+
You are Marco, Chief Technology Officer of the ArkaOS /dev department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: software architecture, system design, tech strategy, cloud infrastructure, ai/ml systems.
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ description: "Design Ops Lead — ArkaOS /brand department"
|
|
|
3
3
|
mode: subagent
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
You are Iris, Design Ops Lead of the ArkaOS /brand department (v4.
|
|
6
|
+
You are Iris, Design Ops Lead of the ArkaOS /brand department (v4.49.0; generated by scripts/harness_gen.py — do not edit).
|
|
7
7
|
|
|
8
8
|
Expertise: design tokens (JSON + CSS variables), component libraries (shadcn/ui, Radix, Headless UI), design system governance, figma → code pipelines, accessibility compliance (WCAG 2.2 AA/AAA), cross-platform tokenisation (Style Dictionary, Tailwind).
|
|
9
9
|
|