nexo-brain 7.1.1 → 7.1.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/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -2
- package/bin/nexo-brain.js +198 -92
- package/package.json +1 -1
- package/src/agent_runner.py +10 -8
- package/src/auto_close_sessions.py +19 -2
- package/src/auto_update.py +232 -28
- package/src/autonomy_mandate.py +260 -0
- package/src/bootstrap_docs.py +22 -1
- package/src/cli.py +181 -1
- package/src/cli_email.py +104 -73
- package/src/client_sync.py +22 -1
- package/src/cognitive/_core.py +5 -3
- package/src/core_prompts.py +50 -0
- package/src/cron_recovery.py +81 -7
- package/src/crons/manifest.json +57 -0
- package/src/crons/sync.py +95 -26
- package/src/dashboard/app.py +59 -0
- package/src/dashboard/templates/base.html +2 -0
- package/src/dashboard/templates/feature-disabled.html +27 -0
- package/src/db/_email_accounts.py +67 -18
- package/src/db/_fts.py +5 -5
- package/src/db/_personal_scripts.py +1 -1
- package/src/db/_skills.py +3 -3
- package/src/doctor/providers/runtime.py +35 -20
- package/src/email_config.py +18 -9
- package/src/enforcement_classifier.py +3 -12
- package/src/evolution_cycle.py +37 -149
- package/src/guardian_telemetry.py +3 -2
- package/src/hook_guardrails.py +61 -0
- package/src/hooks/capture-tool-logs.sh +11 -3
- package/src/hooks/daily-briefing-check.sh +7 -2
- package/src/hooks/heartbeat-enforcement.py +14 -1
- package/src/hooks/heartbeat-posttool.sh +2 -0
- package/src/hooks/heartbeat-user-msg.sh +2 -0
- package/src/hooks/inbox-hook.sh +6 -2
- package/src/hooks/post-compact.sh +12 -4
- package/src/hooks/pre-compact.sh +12 -4
- package/src/migrate_embeddings.py +5 -3
- package/src/nexo_migrate.py +3 -1
- package/src/plugin_loader.py +14 -5
- package/src/plugins/adaptive_mode.py +4 -1
- package/src/plugins/backup.py +32 -20
- package/src/plugins/evolution.py +2 -0
- package/src/plugins/memory_export.py +6 -1
- package/src/plugins/personal_plugins.py +17 -7
- package/src/plugins/personal_scripts.py +64 -3
- package/src/presets/entities_universal.json +67 -4
- package/src/product_mode.py +201 -0
- package/src/r14_correction_learning.py +5 -20
- package/src/r15_project_context.py +4 -10
- package/src/r16_declared_done.py +3 -16
- package/src/r17_promise_debt.py +3 -16
- package/src/r18_followup_autocomplete.py +5 -7
- package/src/r19_project_grep.py +5 -8
- package/src/r20_constant_change.py +5 -15
- package/src/r21_legacy_path.py +5 -7
- package/src/r22_personal_script.py +4 -8
- package/src/r23_ssh_without_atlas.py +4 -11
- package/src/r23b_deploy_vhost.py +7 -6
- package/src/r23c_cwd_mismatch.py +7 -6
- package/src/r23d_chown_chmod_recursive.py +6 -6
- package/src/r23e_force_push_main.py +5 -6
- package/src/r23f_db_no_where.py +5 -6
- package/src/r23g_secrets_in_output.py +5 -5
- package/src/r23h_shebang_mismatch.py +6 -5
- package/src/r23i_auto_deploy_ignored.py +5 -6
- package/src/r23j_global_install.py +5 -6
- package/src/r23k_script_duplicates_skill.py +7 -6
- package/src/r23l_resource_collision.py +7 -6
- package/src/r23m_message_duplicate.py +6 -5
- package/src/r24_stale_memory.py +4 -9
- package/src/r25_nora_maria_read_only.py +5 -10
- package/src/r34_identity_coherence.py +6 -13
- package/src/r_catalog.py +3 -7
- package/src/resonance_map.py +13 -13
- package/src/runtime_power.py +29 -80
- package/src/script_registry.py +236 -6
- package/src/scripts/check-context.py +8 -25
- package/src/scripts/deep-sleep/extract.py +6 -10
- package/src/scripts/nexo-auto-update.py +27 -4
- package/src/scripts/nexo-catchup.py +9 -19
- package/src/scripts/nexo-cognitive-decay.py +26 -3
- package/src/scripts/nexo-daily-self-audit.py +50 -51
- package/src/scripts/nexo-email-migrate-config.py +30 -11
- package/src/scripts/nexo-email-monitor.py +97 -238
- package/src/scripts/nexo-followup-runner.py +70 -133
- package/src/scripts/nexo-hook-record.py +1 -1
- package/src/scripts/nexo-immune.py +6 -31
- package/src/scripts/nexo-impact-scorer.py +27 -4
- package/src/scripts/nexo-learning-housekeep.py +26 -3
- package/src/scripts/nexo-learning-validator.py +34 -32
- package/src/scripts/nexo-migrate.py +28 -12
- package/src/scripts/nexo-morning-agent.py +9 -23
- package/src/scripts/nexo-outcome-checker.py +27 -4
- package/src/scripts/nexo-postmortem-consolidator.py +30 -62
- package/src/scripts/nexo-pre-commit.py +28 -0
- package/src/scripts/nexo-proactive-dashboard.py +27 -0
- package/src/scripts/nexo-reflection.py +33 -3
- package/src/scripts/nexo-runtime-preflight.py +27 -2
- package/src/scripts/nexo-send-reply.py +10 -8
- package/src/scripts/nexo-sleep.py +11 -25
- package/src/scripts/nexo-synthesis.py +7 -40
- package/src/scripts/nexo-watchdog-smoke.py +30 -1
- package/src/scripts/nexo-watchdog.sh +23 -17
- package/src/scripts/phase_guardian_analysis.py +27 -4
- package/src/server.py +14 -3
- package/src/storage_router.py +8 -6
- package/src/tools_drive.py +5 -13
- package/src/tools_guardian.py +3 -4
- package/src/tools_menu.py +2 -2
- package/src/tools_reminders_crud.py +17 -0
- package/src/tools_sessions.py +1 -4
- package/src/user_context.py +3 -6
- package/src/user_data_portability.py +31 -23
- package/templates/CLAUDE.md.template +11 -3
- package/templates/CODEX.AGENTS.md.template +11 -3
- package/templates/core-prompts/catchup-assessment.md +19 -0
- package/templates/core-prompts/check-context.md +24 -0
- package/templates/core-prompts/daily-self-audit.md +42 -0
- package/templates/core-prompts/daily-synthesis.md +40 -0
- package/templates/core-prompts/deep-sleep-extract-json-output.md +8 -0
- package/templates/core-prompts/drive-signal-classifier-system.md +4 -0
- package/templates/core-prompts/drive-signal-classifier-user.md +6 -0
- package/templates/core-prompts/email-monitor.md +202 -0
- package/templates/core-prompts/enforcement-classifier-retry.md +1 -0
- package/templates/core-prompts/enforcement-classifier-strict.md +1 -0
- package/templates/core-prompts/evolution-public-contribution.md +32 -0
- package/templates/core-prompts/evolution-public-pr-review.md +38 -0
- package/templates/core-prompts/evolution-weekly.md +71 -0
- package/templates/core-prompts/followup-runner-operator-attention-context.md +4 -0
- package/templates/core-prompts/followup-runner-operator-attention-question.md +1 -0
- package/templates/core-prompts/followup-runner.md +74 -0
- package/templates/core-prompts/immune-triage.md +31 -0
- package/templates/core-prompts/interactive-startup.md +1 -0
- package/templates/core-prompts/json-object-only.md +1 -0
- package/templates/core-prompts/learning-validator.md +25 -0
- package/templates/core-prompts/morning-agent-json-output.md +1 -0
- package/templates/core-prompts/morning-agent.md +23 -0
- package/templates/core-prompts/postmortem-consolidator.md +60 -0
- package/templates/core-prompts/r-catalog.md +1 -0
- package/templates/core-prompts/r14-correction-learning-injection.md +1 -0
- package/templates/core-prompts/r14-correction-learning-question.md +1 -0
- package/templates/core-prompts/r15-project-context-injection.md +1 -0
- package/templates/core-prompts/r16-declared-done-injection.md +1 -0
- package/templates/core-prompts/r16-declared-done-question.md +1 -0
- package/templates/core-prompts/r17-promise-debt-injection.md +1 -0
- package/templates/core-prompts/r17-promise-debt-question.md +1 -0
- package/templates/core-prompts/r18-followup-autocomplete-injection.md +3 -0
- package/templates/core-prompts/r19-project-grep-injection.md +1 -0
- package/templates/core-prompts/r20-constant-change-injection.md +1 -0
- package/templates/core-prompts/r20-constant-change-question.md +1 -0
- package/templates/core-prompts/r21-legacy-path-injection.md +1 -0
- package/templates/core-prompts/r22-personal-script-injection.md +1 -0
- package/templates/core-prompts/r23-ssh-without-atlas-injection.md +1 -0
- package/templates/core-prompts/r23b-deploy-vhost-injection.md +1 -0
- package/templates/core-prompts/r23c-cwd-mismatch-injection.md +1 -0
- package/templates/core-prompts/r23d-chown-chmod-recursive-injection.md +1 -0
- package/templates/core-prompts/r23e-force-push-main-injection.md +1 -0
- package/templates/core-prompts/r23f-db-no-where-injection.md +1 -0
- package/templates/core-prompts/r23g-secrets-in-output-injection.md +1 -0
- package/templates/core-prompts/r23h-shebang-mismatch-injection.md +1 -0
- package/templates/core-prompts/r23i-auto-deploy-ignored-injection.md +1 -0
- package/templates/core-prompts/r23j-global-install-injection.md +1 -0
- package/templates/core-prompts/r23k-script-duplicates-skill-injection.md +1 -0
- package/templates/core-prompts/r23l-resource-collision-injection.md +1 -0
- package/templates/core-prompts/r23m-message-duplicate-injection.md +1 -0
- package/templates/core-prompts/r24-stale-memory-injection.md +1 -0
- package/templates/core-prompts/r25-read-only-host-injection.md +1 -0
- package/templates/core-prompts/r34-identity-coherence-probe.md +1 -0
- package/templates/core-prompts/r34-identity-coherence-question.md +1 -0
- package/templates/core-prompts/sleep.md +25 -0
- package/templates/email-template.md +55 -0
- package/templates/nexo_helper.py +31 -13
- package/templates/plugin-template.py +3 -3
- package/templates/skill-template.md +2 -1
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
"""Product-mode contracts shared by Brain and Desktop."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import paths
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
DESKTOP_PRODUCT_ENV = "NEXO_DESKTOP_MANAGED"
|
|
16
|
+
ALLOW_CORE_WRITES_ENV = "NEXO_ALLOW_CORE_WRITES"
|
|
17
|
+
PRODUCT_MODE_FILENAME = "product-mode.json"
|
|
18
|
+
DESKTOP_PRODUCT_MODE = "desktop_closed_product"
|
|
19
|
+
DESKTOP_DISABLED_FEATURES = ("evolution",)
|
|
20
|
+
DESKTOP_EVOLUTION_DISABLED_REASON = "Disabled by NEXO Desktop product contract"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _now_iso() -> str:
|
|
24
|
+
return time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime())
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def product_mode_path() -> Path:
|
|
28
|
+
return paths.config_dir() / PRODUCT_MODE_FILENAME
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _desktop_install_markers(home: Path | None = None) -> list[Path]:
|
|
32
|
+
base = Path(home) if home is not None else Path.home()
|
|
33
|
+
markers: list[Path] = [
|
|
34
|
+
base / "Applications" / "NEXO Desktop.app",
|
|
35
|
+
base / "Library" / "Application Support" / "NEXO Desktop",
|
|
36
|
+
base / ".local" / "share" / "NEXO Desktop",
|
|
37
|
+
base / ".config" / "NEXO Desktop",
|
|
38
|
+
]
|
|
39
|
+
if home is None and sys.platform == "darwin":
|
|
40
|
+
markers.insert(0, Path("/Applications/NEXO Desktop.app"))
|
|
41
|
+
if os.name == "nt":
|
|
42
|
+
local = Path(os.environ.get("LOCALAPPDATA", str(base / "AppData" / "Local")))
|
|
43
|
+
roaming = Path(os.environ.get("APPDATA", str(base / "AppData" / "Roaming")))
|
|
44
|
+
markers.extend(
|
|
45
|
+
[
|
|
46
|
+
local / "Programs" / "NEXO Desktop",
|
|
47
|
+
roaming / "NEXO Desktop",
|
|
48
|
+
]
|
|
49
|
+
)
|
|
50
|
+
return markers
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def desktop_product_install_detected(home: Path | None = None) -> bool:
|
|
54
|
+
for candidate in _desktop_install_markers(home):
|
|
55
|
+
try:
|
|
56
|
+
if candidate.exists():
|
|
57
|
+
return True
|
|
58
|
+
except Exception:
|
|
59
|
+
continue
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def load_product_mode() -> dict[str, Any]:
|
|
64
|
+
path = product_mode_path()
|
|
65
|
+
try:
|
|
66
|
+
raw = json.loads(path.read_text())
|
|
67
|
+
except Exception:
|
|
68
|
+
return {}
|
|
69
|
+
return raw if isinstance(raw, dict) else {}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def save_product_mode(payload: dict[str, Any]) -> Path:
|
|
73
|
+
path = product_mode_path()
|
|
74
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
75
|
+
tmp_path = path.with_suffix(path.suffix + ".tmp")
|
|
76
|
+
tmp_path.write_text(json.dumps(payload, indent=2, ensure_ascii=False) + "\n")
|
|
77
|
+
tmp_path.replace(path)
|
|
78
|
+
return path
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def desktop_product_requested() -> bool:
|
|
82
|
+
if str(os.environ.get(DESKTOP_PRODUCT_ENV, "")).strip() == "1":
|
|
83
|
+
return True
|
|
84
|
+
payload = load_product_mode()
|
|
85
|
+
if payload.get("desktop_managed") is True:
|
|
86
|
+
return True
|
|
87
|
+
if str(payload.get("product_mode") or "").strip().lower() == DESKTOP_PRODUCT_MODE:
|
|
88
|
+
return True
|
|
89
|
+
return desktop_product_install_detected()
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def mark_desktop_product_managed(*, source: str = "desktop") -> dict[str, Any]:
|
|
93
|
+
existing = load_product_mode()
|
|
94
|
+
payload = dict(existing) if isinstance(existing, dict) else {}
|
|
95
|
+
payload.update(
|
|
96
|
+
{
|
|
97
|
+
"desktop_managed": True,
|
|
98
|
+
"product_mode": DESKTOP_PRODUCT_MODE,
|
|
99
|
+
"disabled_features": list(DESKTOP_DISABLED_FEATURES),
|
|
100
|
+
"updated_at": _now_iso(),
|
|
101
|
+
"source": str(source or "desktop").strip() or "desktop",
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
if not payload.get("created_at"):
|
|
105
|
+
payload["created_at"] = payload["updated_at"]
|
|
106
|
+
save_product_mode(payload)
|
|
107
|
+
return payload
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def _default_objective_payload() -> dict[str, Any]:
|
|
111
|
+
return {
|
|
112
|
+
"objective": "Improve operational excellence and reduce repeated errors",
|
|
113
|
+
"focus_areas": ["error_prevention", "proactivity", "memory_quality"],
|
|
114
|
+
"evolution_enabled": False,
|
|
115
|
+
"evolution_mode": "review",
|
|
116
|
+
"dimensions": {
|
|
117
|
+
"episodic_memory": {"current": 0, "target": 90},
|
|
118
|
+
"autonomy": {"current": 0, "target": 80},
|
|
119
|
+
"proactivity": {"current": 0, "target": 70},
|
|
120
|
+
"self_improvement": {"current": 0, "target": 60},
|
|
121
|
+
"agi": {"current": 0, "target": 20},
|
|
122
|
+
},
|
|
123
|
+
"total_evolutions": 0,
|
|
124
|
+
"consecutive_failures": 0,
|
|
125
|
+
"created_at": _now_iso(),
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _normalize_objective(payload: dict[str, Any]) -> dict[str, Any]:
|
|
130
|
+
try:
|
|
131
|
+
from evolution_cycle import normalize_objective
|
|
132
|
+
|
|
133
|
+
return normalize_objective(payload)
|
|
134
|
+
except Exception:
|
|
135
|
+
return payload
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def load_evolution_objective() -> tuple[Path, dict[str, Any]]:
|
|
139
|
+
objective_path = paths.brain_dir() / "evolution-objective.json"
|
|
140
|
+
try:
|
|
141
|
+
raw = json.loads(objective_path.read_text())
|
|
142
|
+
payload = raw if isinstance(raw, dict) else {}
|
|
143
|
+
except Exception:
|
|
144
|
+
payload = {}
|
|
145
|
+
if not payload:
|
|
146
|
+
payload = _default_objective_payload()
|
|
147
|
+
return objective_path, _normalize_objective(payload)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def enforce_desktop_product_contract(*, source: str = "desktop") -> dict[str, Any]:
|
|
151
|
+
if not desktop_product_requested():
|
|
152
|
+
return {"applied": False, "reason": "desktop_not_requested"}
|
|
153
|
+
|
|
154
|
+
mode_payload = mark_desktop_product_managed(source=source)
|
|
155
|
+
objective_path, objective = load_evolution_objective()
|
|
156
|
+
changed_objective = (
|
|
157
|
+
bool(objective.get("evolution_enabled", True))
|
|
158
|
+
or str(objective.get("disabled_reason") or "") != DESKTOP_EVOLUTION_DISABLED_REASON
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
objective["evolution_enabled"] = False
|
|
162
|
+
objective["disabled_reason"] = DESKTOP_EVOLUTION_DISABLED_REASON
|
|
163
|
+
objective["disabled_by"] = "desktop_product"
|
|
164
|
+
objective["desktop_managed"] = True
|
|
165
|
+
if not objective.get("created_at"):
|
|
166
|
+
objective["created_at"] = _now_iso()
|
|
167
|
+
|
|
168
|
+
objective_path.parent.mkdir(parents=True, exist_ok=True)
|
|
169
|
+
objective_path.write_text(json.dumps(objective, indent=2, ensure_ascii=False) + "\n")
|
|
170
|
+
return {
|
|
171
|
+
"applied": True,
|
|
172
|
+
"mode_path": str(product_mode_path()),
|
|
173
|
+
"objective_path": str(objective_path),
|
|
174
|
+
"changed_objective": changed_objective,
|
|
175
|
+
"mode": mode_payload,
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def is_cron_blocked(cron_id: str | None) -> bool:
|
|
180
|
+
clean = str(cron_id or "").strip().lower()
|
|
181
|
+
return clean == "evolution" and desktop_product_requested()
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def filter_blocked_crons(crons: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
185
|
+
return [dict(cron) for cron in crons if not is_cron_blocked(cron.get("id"))]
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def core_writes_allowed() -> bool:
|
|
189
|
+
return str(os.environ.get(ALLOW_CORE_WRITES_ENV, "")).strip() == "1"
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def is_protected_runtime_core_path(file_path: str | os.PathLike[str] | None) -> bool:
|
|
193
|
+
raw = str(file_path or "").strip()
|
|
194
|
+
if not raw:
|
|
195
|
+
return False
|
|
196
|
+
try:
|
|
197
|
+
candidate = Path(raw).expanduser().resolve(strict=False)
|
|
198
|
+
candidate.relative_to(paths.core_dir().resolve(strict=False))
|
|
199
|
+
return True
|
|
200
|
+
except Exception:
|
|
201
|
+
return False
|
|
@@ -28,27 +28,12 @@ docs/client-parity-checklist.md).
|
|
|
28
28
|
"""
|
|
29
29
|
from __future__ import annotations
|
|
30
30
|
|
|
31
|
+
from core_prompts import render_core_prompt
|
|
31
32
|
|
|
32
|
-
CLASSIFIER_QUESTION = (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"the assistant a rule it should have known. Answer no for simple "
|
|
37
|
-
"questions, thanks, acknowledgments, neutral continuations, or "
|
|
38
|
-
"delegations without feedback."
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
43
|
-
"R14 post-user-correction: the last user message was classified as a "
|
|
44
|
-
"correction (or carried strongly negative valence) and three tool calls "
|
|
45
|
-
"have elapsed without a nexo_learning_add. Capture the rule you just "
|
|
46
|
-
"learned NOW via nexo_learning_add(category=..., title=..., content=..., "
|
|
47
|
-
"reasoning=..., prevention=...). The auto_capture hook fires in parallel, "
|
|
48
|
-
"but this reminder stays active until you either call learning_add or "
|
|
49
|
-
"acknowledge the correction via nexo_cognitive_trust(event='correction'). "
|
|
50
|
-
"Do not produce visible text for this reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
51
|
-
)
|
|
33
|
+
CLASSIFIER_QUESTION = render_core_prompt("r14-correction-learning-question")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt("r14-correction-learning-injection")
|
|
52
37
|
|
|
53
38
|
|
|
54
39
|
DEFAULT_WINDOW_TOOL_CALLS = 3
|
|
@@ -25,17 +25,11 @@ from __future__ import annotations
|
|
|
25
25
|
|
|
26
26
|
import re
|
|
27
27
|
|
|
28
|
+
from core_prompts import render_core_prompt
|
|
28
29
|
|
|
29
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"nor a read of project-atlas.json. Before touching any file or cron "
|
|
33
|
-
"for this project, load its context: run nexo_recall('{project}'), "
|
|
34
|
-
"inspect entity_list(type='project'), and/or cat "
|
|
35
|
-
"~/.nexo/brain/project-atlas.json. Learning #213 / #151 — assuming "
|
|
36
|
-
"server, DNS, or repo details from memory without verifying leads "
|
|
37
|
-
"to concrete incidents. Do not produce visible text for this "
|
|
38
|
-
"reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
30
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
31
|
+
"r15-project-context-injection",
|
|
32
|
+
project="{project}",
|
|
39
33
|
)
|
|
40
34
|
|
|
41
35
|
|
package/src/r16_declared_done.py
CHANGED
|
@@ -19,25 +19,12 @@ next tranche alongside the JS classifier infrastructure).
|
|
|
19
19
|
"""
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
|
+
from core_prompts import render_core_prompt
|
|
22
23
|
|
|
23
|
-
CLASSIFIER_QUESTION = (
|
|
24
|
-
"Does the assistant message below declare that a task is finished, "
|
|
25
|
-
"completed, shipped, or already done? Answer yes only if the assistant "
|
|
26
|
-
"is claiming completion of the current work. Answer no for status "
|
|
27
|
-
"updates, mid-task progress reports, questions, or partial summaries."
|
|
28
|
-
)
|
|
24
|
+
CLASSIFIER_QUESTION = render_core_prompt("r16-declared-done-question")
|
|
29
25
|
|
|
30
26
|
|
|
31
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
32
|
-
"R16 declared-done without task_close: your last message claims the "
|
|
33
|
-
"task is complete, but there is an open protocol_task. Close it now "
|
|
34
|
-
"with nexo_task_close(sid=..., task_id=..., outcome='done', "
|
|
35
|
-
"evidence='<substantive proof>', files_changed='...'). Evidence must "
|
|
36
|
-
"be >= 50 chars AND not a single filler word (R03 validator will "
|
|
37
|
-
"reject empty / 'ok' / 'done' / 'fixed'). If the work is partial, "
|
|
38
|
-
"close with outcome='partial' and outcome_notes instead. Do not "
|
|
39
|
-
"produce visible text for this reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
40
|
-
)
|
|
27
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt("r16-declared-done-injection")
|
|
41
28
|
|
|
42
29
|
|
|
43
30
|
def detect_declared_done(assistant_text: str, *, classifier=None) -> bool:
|
package/src/r17_promise_debt.py
CHANGED
|
@@ -18,24 +18,11 @@ twins at the end of the tranche).
|
|
|
18
18
|
"""
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
21
|
+
from core_prompts import render_core_prompt
|
|
21
22
|
|
|
22
|
-
CLASSIFIER_QUESTION = (
|
|
23
|
-
"Does the assistant message below explicitly promise a FUTURE action "
|
|
24
|
-
"it has not yet executed? Answer yes if the assistant says it will do, "
|
|
25
|
-
"create, send, implement, run, check, or perform something later or "
|
|
26
|
-
"next. Answer no for status reports, summaries, questions, clarifying "
|
|
27
|
-
"statements, or present-tense execution reports (where the action has "
|
|
28
|
-
"already happened)."
|
|
29
|
-
)
|
|
23
|
+
CLASSIFIER_QUESTION = render_core_prompt("r17-promise-debt-question")
|
|
30
24
|
|
|
31
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
32
|
-
"R17 promise-debt: your last message promised a future action but no "
|
|
33
|
-
"tool call matching that promise happened in the next two turns. If "
|
|
34
|
-
"the action is still pending, execute it NOW — promise without "
|
|
35
|
-
"execution opens operational debt (learning #38 / #29 Fase A R29). "
|
|
36
|
-
"If the promise was a misstatement, correct it explicitly in the next "
|
|
37
|
-
"message. Do not produce visible text for this reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
38
|
-
)
|
|
25
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt("r17-promise-debt-injection")
|
|
39
26
|
|
|
40
27
|
DEFAULT_WINDOW_TOOL_CALLS = 2
|
|
41
28
|
|
|
@@ -18,14 +18,12 @@ and run the R04 matcher over it.
|
|
|
18
18
|
"""
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
21
|
+
from core_prompts import render_core_prompt
|
|
21
22
|
|
|
22
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"on it. Do NOT close a followup mechanically — verify the outcome "
|
|
27
|
-
"first. Matching followups:\n{items}\nDo not produce visible text "
|
|
28
|
-
"for this reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
23
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
24
|
+
"r18-followup-autocomplete-injection",
|
|
25
|
+
count="{count}",
|
|
26
|
+
items="{items}",
|
|
29
27
|
)
|
|
30
28
|
|
|
31
29
|
|
package/src/r19_project_grep.py
CHANGED
|
@@ -11,15 +11,12 @@ owned by the caller (HeadlessEnforcer).
|
|
|
11
11
|
"""
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
+
from core_prompts import render_core_prompt
|
|
14
15
|
|
|
15
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
"or constant about to change. BEFORE writing '{path}', run Grep "
|
|
20
|
-
"for the symbol(s) you are introducing / modifying to confirm no "
|
|
21
|
-
"other caller breaks. Do not produce visible text for this "
|
|
22
|
-
"reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
16
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
17
|
+
"r19-project-grep-injection",
|
|
18
|
+
project="{project}",
|
|
19
|
+
path="{path}",
|
|
23
20
|
)
|
|
24
21
|
|
|
25
22
|
|
|
@@ -27,23 +27,13 @@ from __future__ import annotations
|
|
|
27
27
|
|
|
28
28
|
import re
|
|
29
29
|
|
|
30
|
+
from core_prompts import render_core_prompt
|
|
30
31
|
|
|
31
|
-
CLASSIFIER_QUESTION = (
|
|
32
|
-
"Does the code edit below modify a module-level constant, configuration "
|
|
33
|
-
"key, enumeration entry, feature-flag, or shared global value? Answer "
|
|
34
|
-
"yes only if the change affects a symbol that other files in the same "
|
|
35
|
-
"project are likely to import or reference. Answer no for local "
|
|
36
|
-
"variables, function bodies, doc-strings, or purely stylistic edits."
|
|
37
|
-
)
|
|
32
|
+
CLASSIFIER_QUESTION = render_core_prompt("r20-constant-change-question")
|
|
38
33
|
|
|
39
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"Grep of the symbol in the recent tool history. Before shipping this "
|
|
43
|
-
"change, run Grep (or `rg`) against the whole repo for the old symbol "
|
|
44
|
-
"value to confirm every caller is updated (or tolerates the new value). "
|
|
45
|
-
"Learning #144 and the R20 contract require grep-all-usages on shared "
|
|
46
|
-
"state. Do not produce visible text for this reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
34
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
35
|
+
"r20-constant-change-injection",
|
|
36
|
+
path="{path}",
|
|
47
37
|
)
|
|
48
38
|
|
|
49
39
|
|
package/src/r21_legacy_path.py
CHANGED
|
@@ -12,14 +12,12 @@ Operators may add more via nexo_entity_create.
|
|
|
12
12
|
"""
|
|
13
13
|
from __future__ import annotations
|
|
14
14
|
|
|
15
|
+
from core_prompts import render_core_prompt
|
|
15
16
|
|
|
16
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"runtime do not keep the legacy tree alive; writes there end up "
|
|
21
|
-
"orphaned at the next maintenance sweep. Do not produce visible text "
|
|
22
|
-
"for this reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
17
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
18
|
+
"r21-legacy-path-injection",
|
|
19
|
+
legacy="{legacy}",
|
|
20
|
+
canonical="{canonical}",
|
|
23
21
|
)
|
|
24
22
|
|
|
25
23
|
|
|
@@ -16,15 +16,11 @@ Structural check against recent_tool_records, no LLM.
|
|
|
16
16
|
"""
|
|
17
17
|
from __future__ import annotations
|
|
18
18
|
|
|
19
|
+
from core_prompts import render_core_prompt
|
|
19
20
|
|
|
20
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"script cover this via nexo_personal_scripts_list, (2) does a reusable "
|
|
24
|
-
"skill apply via nexo_skill_match, (3) is there a blocking learning "
|
|
25
|
-
"via nexo_learning_search. Run those three probes, surface any hit, "
|
|
26
|
-
"and only then proceed. Do not produce visible text for this "
|
|
27
|
-
"reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
21
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
22
|
+
"r22-personal-script-injection",
|
|
23
|
+
path="{path}",
|
|
28
24
|
)
|
|
29
25
|
|
|
30
26
|
|
|
@@ -15,19 +15,12 @@ db.list_entities(type='host'); this module exposes the pure decision.
|
|
|
15
15
|
"""
|
|
16
16
|
from __future__ import annotations
|
|
17
17
|
|
|
18
|
+
from core_prompts import render_core_prompt
|
|
18
19
|
from r25_nora_maria_read_only import extract_remote_host as _extract_ssh_host
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
"that host is not registered in entity_list(type='host') nor in "
|
|
24
|
-
"project-atlas.json. Before connecting, verify the host: (1) check "
|
|
25
|
-
"project-atlas.json and nexo_entity_list(type='host') for a matching "
|
|
26
|
-
"record; (2) if it is not there, create it via nexo_entity_create "
|
|
27
|
-
"with access_mode and credentials pointer; (3) only then run the "
|
|
28
|
-
"ssh/curl. Learning #151 / #156 — assuming servers and DNS without "
|
|
29
|
-
"verifying leads to confabulation. Do not produce visible text for "
|
|
30
|
-
"this reminder — act on it. After handling the silent action, continue with your previous task; this reminder is silent context, not a new instruction."
|
|
21
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
22
|
+
"r23-ssh-without-atlas-injection",
|
|
23
|
+
host="{host}",
|
|
31
24
|
)
|
|
32
25
|
|
|
33
26
|
|
package/src/r23b_deploy_vhost.py
CHANGED
|
@@ -11,13 +11,14 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
import re
|
|
13
13
|
|
|
14
|
+
from core_prompts import render_core_prompt
|
|
14
15
|
|
|
15
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
16
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
17
|
+
"r23b-deploy-vhost-injection",
|
|
18
|
+
cmd="{cmd}",
|
|
19
|
+
docroot="{docroot}",
|
|
20
|
+
mapped_domain="{mapped_domain}",
|
|
21
|
+
context_domain="{context_domain}",
|
|
21
22
|
)
|
|
22
23
|
|
|
23
24
|
_SCP_RSYNC_RE = re.compile(
|
package/src/r23c_cwd_mismatch.py
CHANGED
|
@@ -18,13 +18,14 @@ from __future__ import annotations
|
|
|
18
18
|
import os
|
|
19
19
|
import re
|
|
20
20
|
|
|
21
|
+
from core_prompts import render_core_prompt
|
|
21
22
|
|
|
22
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
23
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
24
|
+
"r23c-cwd-mismatch-injection",
|
|
25
|
+
cmd="{cmd}",
|
|
26
|
+
cwd="{cwd}",
|
|
27
|
+
project="{project}",
|
|
28
|
+
expected="{expected}",
|
|
28
29
|
)
|
|
29
30
|
|
|
30
31
|
|
|
@@ -11,13 +11,13 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
import re
|
|
13
13
|
|
|
14
|
+
from core_prompts import render_core_prompt
|
|
14
15
|
|
|
15
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"box unbootable."
|
|
16
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
17
|
+
"r23d-chown-chmod-recursive-injection",
|
|
18
|
+
verb="{verb}",
|
|
19
|
+
cmd="{cmd}",
|
|
20
|
+
target="{target}",
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
|
|
@@ -8,13 +8,12 @@ from __future__ import annotations
|
|
|
8
8
|
|
|
9
9
|
import re
|
|
10
10
|
|
|
11
|
+
from core_prompts import render_core_prompt
|
|
11
12
|
|
|
12
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"If the intent is to recover a broken state, prefer `git revert` + a "
|
|
17
|
-
"fresh commit over a history rewrite."
|
|
13
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
14
|
+
"r23e-force-push-main-injection",
|
|
15
|
+
branch="{branch}",
|
|
16
|
+
cmd="{cmd}",
|
|
18
17
|
)
|
|
19
18
|
|
|
20
19
|
# Matches `git push [options] [remote] BRANCH` where --force or -f appears
|
package/src/r23f_db_no_where.py
CHANGED
|
@@ -9,13 +9,12 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
import re
|
|
11
11
|
|
|
12
|
+
from core_prompts import render_core_prompt
|
|
12
13
|
|
|
13
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
14
|
-
"
|
|
15
|
-
"{
|
|
16
|
-
"
|
|
17
|
-
"the DB console with explicit operator confirmation, not via the "
|
|
18
|
-
"enforcement wrapper."
|
|
14
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
15
|
+
"r23f-db-no-where-injection",
|
|
16
|
+
cmd="{cmd}",
|
|
17
|
+
verb="{verb}",
|
|
19
18
|
)
|
|
20
19
|
|
|
21
20
|
# Simple SQL heuristic. Looks for DELETE FROM <tbl> or UPDATE <tbl> SET
|
|
@@ -12,12 +12,12 @@ from __future__ import annotations
|
|
|
12
12
|
|
|
13
13
|
import re
|
|
14
14
|
|
|
15
|
+
from core_prompts import render_core_prompt
|
|
15
16
|
|
|
16
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"the secret manager boundary."
|
|
17
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
18
|
+
"r23g-secrets-in-output-injection",
|
|
19
|
+
cmd="{cmd}",
|
|
20
|
+
reason="{reason}",
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
|
|
@@ -15,12 +15,13 @@ import os
|
|
|
15
15
|
import re
|
|
16
16
|
import shutil
|
|
17
17
|
|
|
18
|
+
from core_prompts import render_core_prompt
|
|
18
19
|
|
|
19
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
20
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
21
|
+
"r23h-shebang-mismatch-injection",
|
|
22
|
+
script="{script}",
|
|
23
|
+
shebang="{shebang}",
|
|
24
|
+
actual="{actual}",
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
|
|
@@ -12,13 +12,12 @@ from __future__ import annotations
|
|
|
12
12
|
|
|
13
13
|
import re
|
|
14
14
|
|
|
15
|
+
from core_prompts import render_core_prompt
|
|
15
16
|
|
|
16
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
"you also commit+push it. Either commit the change or disable "
|
|
21
|
-
"auto-deploy temporarily."
|
|
17
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
18
|
+
"r23i-auto-deploy-ignored-injection",
|
|
19
|
+
project="{project}",
|
|
20
|
+
path="{path}",
|
|
22
21
|
)
|
|
23
22
|
|
|
24
23
|
|
|
@@ -11,13 +11,12 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
import re
|
|
13
13
|
|
|
14
|
+
from core_prompts import render_core_prompt
|
|
14
15
|
|
|
15
|
-
INJECTION_PROMPT_TEMPLATE = (
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"tool. If the operator explicitly asked, retry after saying "
|
|
20
|
-
"`yes install globally` or equivalent."
|
|
16
|
+
INJECTION_PROMPT_TEMPLATE = render_core_prompt(
|
|
17
|
+
"r23j-global-install-injection",
|
|
18
|
+
cmd="{cmd}",
|
|
19
|
+
pkg="{pkg}",
|
|
21
20
|
)
|
|
22
21
|
|
|
23
22
|
|