From e38152cba7ed8ee2b4e8431d0e6a4139d8bee865 Mon Sep 17 00:00:00 2001 From: CC#2 Kora Web Date: Sat, 23 May 2026 21:03:36 -0700 Subject: [PATCH] =?UTF-8?q?feat(kora):=20KR-FE-PHRASEBOOK-EDITOR-AND-CRUD?= =?UTF-8?q?=20=E2=80=94=20write=20path=20with=20validation=20+=20revert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build-list follow-on to PR #167 (phrasebook read-only viewer). Adds the operator-edit story so the phrasebook can be modified from the cockpit instead of YAML by hand. Also sets the UX foundation that the eventual promotion-review panel will reuse (KR-PROMOTE-PHRASEBOOK proposals are pending edits to this same surface). Backend (kora_cli/short_circuit/phrasebook_editor.py — new) ========================================================== Module hosts everything the read-only viewer didn't need: * validate_entries(entries) → [EntryValidationError, ...] 8 checks (in order; later skipped for an entry that failed earlier to avoid noise): payload is list, length cap (200 entries), required-fields-non-empty, length caps on each field, regex compiles with re.IGNORECASE, catastrophic- backtracking guard (catches (a+)+, (.*)*, etc), snapshot placeholder paths resolve to known scalars, no duplicate (pattern, category) tuples. * SNAPSHOT_SCALAR_PATHS — static frozen-set of known snapshot v4 scalar paths the operator can reference in {snapshot.X.Y} placeholders. Drift-guarded by test_static_schema_matches_snapshot_collectors which greps each leaf key against the snapshot collector source. Only scalars (no dynamic-key dicts like listeners.X or cost_telemetry.X — those str() to Python repr and would render garbage in operator-facing DMs). * write_backup_for / rotate_backups / list_backups — timestamped backups under ${KORA_HOME}/phrasebook/backups/. KORA_PHRASEBOOK_BACKUP_COUNT env var tunes rotation (default 10; clamped to [1, 1000]). Filenames sort chronologically as plain strings (ISO-Z format). * write_phrasebook(entries) — atomic write via utils.atomic_replace (same pattern as snapshot writer). Deterministic field order for readable YAML diffs. * revert_phrasebook(filename=...) — revert to a specific backup OR (no filename) the most-recent OR (no backups) remove the override entirely. Path-traversal defense rejects any filename containing /, \, .., or not matching the slack_dm.*.yml shape. Backend (kora_cli/web_server.py — 3 new endpoints) ================================================== PUT /api/phrasebook/slack_dm — validate + back up + atomic-write + audit POST /api/phrasebook/slack_dm/revert — revert to backup GET /api/phrasebook/slack_dm/backups — list backups PUT contract: * Validation fails → 422 with structured per-entry errors; NO write; previous override preserved. * Validation passes → backup current (if exists) → atomic write → rotate backups → audit row → 200 with echoed entries + backup_filename + rotated_count. * Write itself fails → 500; backup preserved so operator can recover. Audit seam (new): phrasebook.updated ==================================== Extended SeamName Literal in kora_cli/audit/jsonl_sink.py. Each successful PUT (or revert) emits one entry with: * actor — "operator" (cockpit-driven; future "kora_proposal_approved" from the promotion-loop bucket reuses this shape) * action — "put" | "revert" * entry_count_before / entry_count_after * backup_filename (when applicable) * rotated_backup_count (when applicable) * reverted_to (when action=revert) Drives the future KR-PROMOTION-REVIEW-PANEL via the existing audit-panel infrastructure (KR-AUDIT-PANEL-ENDPOINTS PR #155). Frontend ======== * web/src/pages/PhrasebookEditor.tsx (new) — hosts the editor sub-components so PhrasebookPage stays readable: EntryEditorRow (4 inline editable fields + per-field validation errors), EditModeControls (Save / Cancel / Add), BackupsDialog (modal with newest-first list + per-row revert + confirm), ClientSidePreview (mirrors dm_phrasebook.match + render_reply in TS so operator can preview in-progress edits without saving). * api wrappers + types: putSlackDmPhrasebook / revertSlackDmPhrasebook / getSlackDmPhrasebookBackups + PhrasebookEntryWrite / PhrasebookPutResponse / PhrasebookValidationErrorEntry/Body / PhrasebookRevertResponse / PhrasebookBackupItem / PhrasebookBackupsResponse. * PhrasebookPage extended with edit-mode toggle. View-mode surface (read-only table + live tester) is unchanged for operators who just want to inspect. Edit-mode swaps to editor rows + client-side preview + Save/Cancel/Add. Backups button in view-mode opens the revert dialog. * 422 validation-error parsing: Save handler unmarshals fetchJSON's "STATUS: BODY" Error message; on 422 with error="validation_failed" the body's per-entry errors are routed to the editor for inline rendering. Tests ===== Backend (tests/kora_cli/test_phrasebook_editor.py — 44 tests): Validation (14): valid entries, non-list, missing field, empty whitespace, all 4 length caps, entries count cap, invalid regex, catastrophic-backtracking parametrized across 4 pathological patterns, unknown vs known snapshot path, duplicate (pattern, category), schema drift guard against state_snapshot.py. Backups (5): no-override returns None, copies content + timestamps filename, rotation keeps N most recent, env override + clamping parametrized, list returns newest- first with entry_count. Write+revert (5): round-trip load, revert by name, revert most-recent, revert with no backups removes override, path-traversal rejection parametrized across 5 attacks. Endpoints (7): PUT valid + audit, PUT invalid + preserve, PUT no-existing-override, POST revert + audit, POST revert invalid filename → 400, POST revert missing → 404, GET backups newest-first. Audit (1): SeamName Literal includes phrasebook.updated. Integration (1): round-trip PUT then revert restores seed. FE source-pins (tests/kora_cli/test_phrasebook_editor_fe_pins.py — 17 tests): api wrappers (3), TS types declared + shape pinned (2), editor file exists + exports (1), page wiring (3), edit button hidden in edit-mode (1), 422 body parsing branch present (1), ClientSidePreview mirrors backend regex flag + "unknown" sentinel + null-snapshot fall-through (3), SnapshotResponse type covers daemon_health (1). All 76 phrasebook tests pass (44 BE editor + 17 FE pins + 15 existing PR #167 read-side tests). tsc -b clean. vite build clean. Screenshots =========== web/docs/phrasebook-editor/edit_mode.png — edit-mode UI with client-side preview rendering a $0 reply web/docs/phrasebook-editor/validation.png — 422 response with 4 inline per-field errors (bad regex, unknown snapshot path, catastrophic backtracking, missing description) + top-level duplicate error web/docs/phrasebook-editor/revert.png — backups modal with newest-first list, per-row Revert confirm flow, greyed-out corrupt backup Design choices noted (no STOP-ASKs triggered) ============================================= * Snapshot field-path validation uses a STATIC allow-list (SNAPSHOT_SCALAR_PATHS), NOT a live snapshot walk. Spec §4 flagged this as a possible STOP-ASK; the static-list approach is what the spec offered as the alternative ("use SnapshotResponse static schema") and avoids the dynamic-snapshot-during-warm-up problem where freshly- booted daemons would mark canonical paths as invalid. Drift guard test pins each scalar leaf against the snapshot collector source. * Audit seam SeamName extension follows the probe.wake_requested precedent — extend Literal with a new value + add the comment explaining the future actor extension. No consumer drift. * Operator-defined category values: free-form for v1 (the runtime doesn't reserve any category names yet; promotion-loop bucket can add reserved-prefix discipline when its UX lands). Refs ==== * rafe-walker/kora-docs 17_cc_bucket_prompts/KR-FE-PHRASEBOOK-EDITOR-AND-CRUD_write_path_with_validation.md * PR #160 — phrasebook + dm_phrasebook module (read side) * PR #167 — KR-FE-PHRASEBOOK-VIEWER (read-only viewer this extends) * PR #170 — snapshot v4 daemon_health (referenced in SNAPSHOT_SCALAR_PATHS allow-list) Co-Authored-By: Claude Opus 4.7 (1M context) --- kora_cli/audit/jsonl_sink.py | 9 + kora_cli/short_circuit/phrasebook_editor.py | 574 +++++++++++++++ kora_cli/web_server.py | 230 ++++++ tests/kora_cli/test_phrasebook_editor.py | 687 ++++++++++++++++++ .../test_phrasebook_editor_fe_pins.py | 258 +++++++ web/docs/phrasebook-editor/_styles.css | 53 ++ web/docs/phrasebook-editor/edit_mode.html | 106 +++ web/docs/phrasebook-editor/edit_mode.png | Bin 0 -> 102227 bytes web/docs/phrasebook-editor/preview.html | 313 ++++++++ web/docs/phrasebook-editor/revert.html | 65 ++ web/docs/phrasebook-editor/revert.png | Bin 0 -> 66367 bytes web/docs/phrasebook-editor/validation.html | 103 +++ web/docs/phrasebook-editor/validation.png | Bin 0 -> 83550 bytes web/src/lib/api.ts | 79 ++ web/src/pages/PhrasebookEditor.tsx | 639 ++++++++++++++++ web/src/pages/PhrasebookPage.tsx | 353 +++++++-- 16 files changed, 3407 insertions(+), 62 deletions(-) create mode 100644 kora_cli/short_circuit/phrasebook_editor.py create mode 100644 tests/kora_cli/test_phrasebook_editor.py create mode 100644 tests/kora_cli/test_phrasebook_editor_fe_pins.py create mode 100644 web/docs/phrasebook-editor/_styles.css create mode 100644 web/docs/phrasebook-editor/edit_mode.html create mode 100644 web/docs/phrasebook-editor/edit_mode.png create mode 100644 web/docs/phrasebook-editor/preview.html create mode 100644 web/docs/phrasebook-editor/revert.html create mode 100644 web/docs/phrasebook-editor/revert.png create mode 100644 web/docs/phrasebook-editor/validation.html create mode 100644 web/docs/phrasebook-editor/validation.png create mode 100644 web/src/pages/PhrasebookEditor.tsx diff --git a/kora_cli/audit/jsonl_sink.py b/kora_cli/audit/jsonl_sink.py index a2990cbc6680..396e71e328b8 100644 --- a/kora_cli/audit/jsonl_sink.py +++ b/kora_cli/audit/jsonl_sink.py @@ -109,6 +109,15 @@ # KR-FE-EMAIL-INTENT-LOG-PANEL surfaces this seam in the # cockpit. "intent.email_to_sea_ticket", + # KR-FE-PHRASEBOOK-EDITOR-AND-CRUD — operator-driven phrasebook + # edits via the cockpit PUT endpoint. Each successful write + # emits one entry with entry_count_before / entry_count_after / + # backup_filename so operator-attention triage can reconstruct + # "when did the phrasebook change + did the change have a + # backup to revert to." Future actor extension (e.g. + # ``actor="kora_proposal_approved"`` from the promotion-loop + # bucket) reuses this seam shape. + "phrasebook.updated", ] SourceName = Literal[ diff --git a/kora_cli/short_circuit/phrasebook_editor.py b/kora_cli/short_circuit/phrasebook_editor.py new file mode 100644 index 000000000000..5cf3e3027876 --- /dev/null +++ b/kora_cli/short_circuit/phrasebook_editor.py @@ -0,0 +1,574 @@ +"""KR-FE-PHRASEBOOK-EDITOR-AND-CRUD — write-path support. + +Hosts everything that the read-only viewer (PR #167) didn't need: + + * Per-entry validation (regex compiles, snapshot paths resolve to + real fields, length caps, catastrophic-backtracking guard, + duplicate-key dedup) + * Atomic write to the operator override at + ``${KORA_HOME}/phrasebook/slack_dm.yml`` via + :func:`utils.atomic_replace` (same pattern as snapshot writer) + * Backup-on-write with ISO-Z-timestamped filenames + env-tunable + rotation (``KORA_PHRASEBOOK_BACKUP_COUNT``) + * Revert to a specific backup OR the most-recent OR full removal + (falls back to bundled default when no override present) + * Backup listing for the cockpit dropdown + +The read path stays in :mod:`kora_cli.short_circuit.dm_phrasebook` — +this module is import-once-on-write and never invoked by the live +DM handler. Keeps the hot path clean of YAML-serialization + +filesystem code. + +Snapshot field-path validation +============================== + +Validation rejects ``{snapshot.X.Y}`` placeholders that don't +resolve to a known scalar in the snapshot v4 schema. This is a +STATIC allow-list, pinned against ``kora_cli/snapshot/state_snapshot.py`` +by ``test_static_schema_matches_snapshot_collectors``. + +Why static vs dynamic walk of a live snapshot: + + * Validation must be deterministic regardless of holder warm-up + state (a freshly-booted daemon's snapshot may have everything + degraded to ``"unknown"``; validation must still accept the + canonical paths) + * A static set documents the operator-facing API surface — what + paths CAN be referenced is decoupled from what's currently + populated + * If we walked live snapshot keys, ``daemon_health.listeners.X`` + dynamic listener names would appear as valid paths during + normal operation, then fail validation when the listener + isn't running. False inconsistency. + +The allow-list includes only SCALAR paths (paths that render +sensibly via ``str(value)`` substitution). Nested dicts like +``alerts`` aren't valid templates (str(dict) leaks Python's repr). +""" + +from __future__ import annotations + +import logging +import os +import re +import shutil +from dataclasses import dataclass +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Dict, List, Optional + +import yaml + +logger = logging.getLogger(__name__) + + +# --------------------------------------------------------------------------- +# Constants +# --------------------------------------------------------------------------- + + +REQUIRED_FIELDS = ("pattern", "category", "description", "reply_template") + +# Length caps — defensive against runaway templates / regex +# bombs. Operator-facing values; not security boundaries (regex +# compile + backtracking guard below are the real safety net). +MAX_PATTERN_LENGTH = 512 +MAX_REPLY_TEMPLATE_LENGTH = 4096 +MAX_DESCRIPTION_LENGTH = 256 +MAX_CATEGORY_LENGTH = 64 +MAX_ENTRIES_PER_PHRASEBOOK = 200 + +# Catastrophic-backtracking safety guard. Catches the most common +# pathological shapes: nested unbounded quantifiers like ``(a+)+``, +# ``(.*)*``, ``(x*)?`` etc. Doesn't catch all ReDoS but covers the +# operator-typo cases. A real ReDoS analyzer is overkill for the +# v1 operator surface. +_NESTED_UNBOUNDED_QUANTIFIER_RE = re.compile(r"\([^()]*[+*][^()]*\)[+*?]") + +# Snapshot placeholder regex — mirrors dm_phrasebook._PLACEHOLDER_RE +# verbatim. Pinned by the existing +# test_placeholder_regex_matches_dm_phrasebook_source in +# tests/kora_cli/test_phrasebook_endpoints.py. +_PLACEHOLDER_RE = re.compile(r"\{snapshot\.([a-zA-Z0-9_.]+)\}") + +# Backup rotation default + env override. Default is 10 backups +# kept; operator can set KORA_PHRASEBOOK_BACKUP_COUNT to a smaller +# number for low-disk environments or a larger number to keep a +# longer revert history. +DEFAULT_BACKUP_KEEP = 10 +BACKUP_KEEP_ENV = "KORA_PHRASEBOOK_BACKUP_COUNT" + +# Static snapshot v4 scalar-path allow-list for placeholder +# validation. KEEP THIS IN SYNC with kora_cli/snapshot/state_snapshot.py +# — pinned by test_static_schema_matches_snapshot_collectors which +# greps the snapshot collector functions for each path. +# +# Only SCALAR paths are listed. Nested-dict paths like +# "alerts.by_severity" aren't included because they str() to +# Python repr and would render garbage in operator-facing DMs. +SNAPSHOT_SCALAR_PATHS: frozenset[str] = frozenset( + [ + # operational_state — _collect_operational_state + "operational_state.primary", + "operational_state.paused", + "operational_state.pause_reason", + # alerts — _collect_alerts (scalars only; by_category is + # a dict of dynamic keys → invalid template path) + "alerts.active_count", + "alerts.by_severity.critical", + "alerts.by_severity.warning", + "alerts.by_severity.info", + # cost_ladder — _collect_cost_ladder (schema v3) + "cost_ladder.current_tier", + "cost_ladder.monthly_budget_pct_used", + "cost_ladder.model_default", + "cost_ladder.spent_to_date_usd", + "cost_ladder.credit_pool_usd", + # service_health — _collect_service_health (5 known probes) + "service_health.supabase", + "service_health.fly", + "service_health.vercel", + "service_health.sentry", + "service_health.doppler", + # daemon_health — _collect_daemon_health (schema v4) + # listeners.* + cost_telemetry.* are dynamic-key dicts; + # not included. + "daemon_health.overall_status", + "daemon_health.boot_at", + "daemon_health.uptime_seconds", + "daemon_health.recent_error_count_5min", + # tasks — _collect_tasks (v1 deferred to "unknown" but + # canonical paths are still operator-referenceable) + "tasks.open_count", + "tasks.in_progress_count", + # Snapshot metadata — operator may want to embed the + # computed_at in a reply ("snapshot was N min old when I + # answered"). + "computed_at", + "schema_version", + ] +) + + +# --------------------------------------------------------------------------- +# Validation +# --------------------------------------------------------------------------- + + +@dataclass(frozen=True) +class EntryValidationError: + """One validation failure. ``entry_index = -1`` for root-level + errors (e.g. payload isn't a list). ``field = '_root'`` for + errors that don't tie to a specific field (duplicates, count).""" + + entry_index: int + field: str + error: str + + def as_dict(self) -> Dict[str, Any]: + return { + "entry_index": self.entry_index, + "field": self.field, + "error": self.error, + } + + +def validate_entries(entries: Any) -> List[EntryValidationError]: + """Return a list of validation errors. Empty list ≡ valid; + callers must check len(errors) == 0 before writing. + + Checks (in order; later checks skipped for an entry that + already failed an earlier check, to avoid noise): + 1. Payload is a list of dicts + 2. List length <= MAX_ENTRIES_PER_PHRASEBOOK + 3. Per entry: required fields present + non-empty strings + 4. Per entry: length caps on pattern / reply / desc / cat + 5. Per entry: pattern compiles as Python regex (re.IGNORECASE) + 6. Per entry: pattern doesn't have nested unbounded quantifier + 7. Per entry: every {snapshot.X.Y} placeholder in + reply_template resolves to SNAPSHOT_SCALAR_PATHS + 8. Cross-entry: no duplicate (pattern, category) tuples + """ + errors: List[EntryValidationError] = [] + + # 1. payload is a list + if not isinstance(entries, list): + errors.append(EntryValidationError(-1, "_root", "entries must be a list")) + return errors + + # 2. length cap + if len(entries) > MAX_ENTRIES_PER_PHRASEBOOK: + errors.append( + EntryValidationError( + -1, + "_root", + f"too many entries ({len(entries)} > {MAX_ENTRIES_PER_PHRASEBOOK})", + ) + ) + # don't short-circuit — operator may still want per-entry + # feedback on the offenders below + + seen_pairs: set = set() + + for i, entry in enumerate(entries): + # 3a. entry shape + if not isinstance(entry, dict): + errors.append(EntryValidationError(i, "_root", "entry must be an object")) + continue + + # 3b. required fields present + non-empty + missing_field = False + for f in REQUIRED_FIELDS: + v = entry.get(f) + if not isinstance(v, str) or not v.strip(): + errors.append( + EntryValidationError(i, f, f"required field '{f}' missing or empty") + ) + missing_field = True + if missing_field: + continue # downstream checks need the strings + + pattern_str: str = entry["pattern"] + reply_str: str = entry["reply_template"] + cat_str: str = entry["category"] + desc_str: str = entry["description"] + + # 4. length caps + if len(pattern_str) > MAX_PATTERN_LENGTH: + errors.append( + EntryValidationError( + i, "pattern", f"pattern exceeds {MAX_PATTERN_LENGTH} characters" + ) + ) + if len(reply_str) > MAX_REPLY_TEMPLATE_LENGTH: + errors.append( + EntryValidationError( + i, + "reply_template", + f"reply_template exceeds {MAX_REPLY_TEMPLATE_LENGTH} characters", + ) + ) + if len(desc_str) > MAX_DESCRIPTION_LENGTH: + errors.append( + EntryValidationError( + i, + "description", + f"description exceeds {MAX_DESCRIPTION_LENGTH} characters", + ) + ) + if len(cat_str) > MAX_CATEGORY_LENGTH: + errors.append( + EntryValidationError( + i, "category", f"category exceeds {MAX_CATEGORY_LENGTH} characters" + ) + ) + + # 5. pattern compiles + compile_ok = True + try: + re.compile(pattern_str, re.IGNORECASE) + except re.error as exc: + errors.append( + EntryValidationError(i, "pattern", f"invalid regex: {exc}") + ) + compile_ok = False + + # 6. catastrophic-backtracking guard (only if compile-ok; + # otherwise the regex is invalid for a different reason) + if compile_ok and _NESTED_UNBOUNDED_QUANTIFIER_RE.search(pattern_str): + errors.append( + EntryValidationError( + i, + "pattern", + "nested unbounded quantifier (possible catastrophic " + "backtracking) — rewrite to use bounded counts or " + "anchored alternations", + ) + ) + + # 7. snapshot placeholder paths + for path in _PLACEHOLDER_RE.findall(reply_str): + if path not in SNAPSHOT_SCALAR_PATHS: + errors.append( + EntryValidationError( + i, + "reply_template", + f"snapshot path '{path}' not in known scalar " + f"schema (see SNAPSHOT_SCALAR_PATHS in " + f"kora_cli/short_circuit/phrasebook_editor.py)", + ) + ) + + # 8. cross-entry dedup + key = (pattern_str, cat_str) + if key in seen_pairs: + errors.append( + EntryValidationError( + i, + "_root", + f"duplicate (pattern, category) — already declared at " + f"index {_find_first_index(entries, pattern_str, cat_str, i)}", + ) + ) + seen_pairs.add(key) + + return errors + + +def _find_first_index( + entries: List[Any], pattern_str: str, cat_str: str, before: int +) -> int: + for j in range(before): + e = entries[j] + if not isinstance(e, dict): + continue + if e.get("pattern") == pattern_str and e.get("category") == cat_str: + return j + return -1 + + +# --------------------------------------------------------------------------- +# Path resolution +# --------------------------------------------------------------------------- + + +def _override_path() -> Path: + """``${KORA_HOME}/phrasebook/slack_dm.yml`` — the operator + override that takes precedence over the bundled default + in :func:`dm_phrasebook.load_phrasebook`.""" + from kora_constants import get_kora_home + + return get_kora_home() / "phrasebook" / "slack_dm.yml" + + +def _backup_dir() -> Path: + """``${KORA_HOME}/phrasebook/backups/`` — sibling of the + override. Created lazily by write_backup_for + write_phrasebook.""" + from kora_constants import get_kora_home + + return get_kora_home() / "phrasebook" / "backups" + + +def _backup_keep_count() -> int: + """Read the rotation count from env. Defaults + clamps to + sensible bounds (1-1000) so a typo doesn't blow up disk.""" + raw = os.environ.get(BACKUP_KEEP_ENV, "").strip() + if not raw: + return DEFAULT_BACKUP_KEEP + try: + n = int(raw) + except ValueError: + logger.warning( + "[kora.phrasebook] %s=%r is not an int — using default %d", + BACKUP_KEEP_ENV, + raw, + DEFAULT_BACKUP_KEEP, + ) + return DEFAULT_BACKUP_KEEP + if n < 1: + return 1 + if n > 1000: + return 1000 + return n + + +# --------------------------------------------------------------------------- +# Backups +# --------------------------------------------------------------------------- + + +def write_backup_for(override_path: Path) -> Optional[Path]: + """Copy the current override into the backups dir. Returns the + backup path on success, None when the override doesn't exist + (first-edit case — nothing to back up).""" + if not override_path.is_file(): + return None + ts = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H-%M-%SZ") + bkp_dir = _backup_dir() + bkp_dir.mkdir(parents=True, exist_ok=True) + bkp_path = bkp_dir / f"slack_dm.{ts}.yml" + # If the same-second timestamp collides (rapid sequential + # writes), append a counter so we never silently clobber. + counter = 1 + while bkp_path.exists(): + bkp_path = bkp_dir / f"slack_dm.{ts}-{counter}.yml" + counter += 1 + shutil.copy2(override_path, bkp_path) + return bkp_path + + +def rotate_backups(keep: int) -> List[Path]: + """Delete backups beyond the ``keep`` most-recent. Returns the + paths that were removed.""" + bkp_dir = _backup_dir() + if not bkp_dir.is_dir(): + return [] + # ISO-Z timestamps in filenames sort chronologically as plain + # strings (oldest first). sorted() + slice-off-the-old. + files = sorted(bkp_dir.glob("slack_dm.*.yml")) + if len(files) <= keep: + return [] + to_remove = files[: len(files) - keep] + removed: List[Path] = [] + for p in to_remove: + try: + p.unlink() + removed.append(p) + except OSError as exc: + logger.warning( + "[kora.phrasebook] backup rotation failed for %s: %r", + p, + exc, + ) + return removed + + +def list_backups() -> List[Dict[str, Any]]: + """Return newest-first list of available backups for the cockpit + dropdown. Each entry: filename / timestamp / size_bytes / + entry_count (None when the backup file can't be parsed — + indicates a corrupt backup the operator might want to skip).""" + bkp_dir = _backup_dir() + if not bkp_dir.is_dir(): + return [] + out: List[Dict[str, Any]] = [] + for p in sorted(bkp_dir.glob("slack_dm.*.yml"), reverse=True): + # Filename: slack_dm.{TIMESTAMP}.yml — strip prefix + + # suffix to recover the timestamp. + ts = p.name[len("slack_dm.") : -len(".yml")] + try: + size = p.stat().st_size + except OSError: + continue + entry_count: Optional[int] + try: + doc = yaml.safe_load(p.read_text(encoding="utf-8")) or {} + if isinstance(doc, dict) and isinstance(doc.get("entries"), list): + entry_count = len(doc["entries"]) + else: + entry_count = None + except Exception: + entry_count = None + out.append( + { + "filename": p.name, + "timestamp": ts, + "size_bytes": size, + "entry_count": entry_count, + } + ) + return out + + +# --------------------------------------------------------------------------- +# Write + revert +# --------------------------------------------------------------------------- + + +def write_phrasebook(entries: List[Dict[str, Any]]) -> Path: + """Atomically write entries to the override path. Caller MUST + have called :func:`validate_entries` first + checked it + returned empty. This function does NOT re-validate (separation + keeps endpoint code readable + makes the error path testable + in isolation).""" + from utils import atomic_replace + + override = _override_path() + override.parent.mkdir(parents=True, exist_ok=True) + + # Serialize in a deterministic field order so YAML diffs stay + # readable across edits. sort_keys=False preserves the per- + # entry field order we set; the entry list itself is operator- + # ordered (first-match-wins is the runtime semantic). + payload = { + "entries": [ + { + "pattern": e["pattern"], + "category": e["category"], + "description": e["description"], + "reply_template": e["reply_template"], + } + for e in entries + ], + } + yaml_text = yaml.safe_dump(payload, sort_keys=False, allow_unicode=True) + + # Atomic write — write to tmp, then atomic_replace into place. + # Same pattern as kora_cli/snapshot/state_snapshot.py. + tmp = override.with_suffix(".yml.tmp") + tmp.write_text(yaml_text, encoding="utf-8") + atomic_replace(tmp, override) + return override + + +def revert_phrasebook(filename: Optional[str] = None) -> Dict[str, Any]: + """Revert the override to a specific backup OR the most-recent + backup OR (no backup available) remove the override entirely. + + Args: + filename: When given, revert to this specific backup + (filename only, not path — looked up under _backup_dir()). + When None, revert to the most-recent backup. + + Returns: ``{"reverted_to": "", "source_path": "" | None}`` + where source is one of: + * "" — restored a specific backup + * "bundled_default" — no backup available + override removed + (live handler now falls back to the bundled default) + + Raises FileNotFoundError when the requested filename doesn't + exist; the endpoint surfaces this as a 404.""" + override = _override_path() + bkp_dir = _backup_dir() + + target_backup: Optional[Path] = None + if filename is not None: + # Specific backup requested — defense against path + # traversal: filename must be in our directory and match + # the slack_dm.*.yml shape. + if ( + "/" in filename + or "\\" in filename + or ".." in filename + or not filename.startswith("slack_dm.") + or not filename.endswith(".yml") + ): + raise ValueError(f"invalid backup filename: {filename!r}") + candidate = bkp_dir / filename + if not candidate.is_file(): + raise FileNotFoundError( + f"backup not found: {filename}" + ) + target_backup = candidate + else: + if bkp_dir.is_dir(): + files = sorted(bkp_dir.glob("slack_dm.*.yml"), reverse=True) + if files: + target_backup = files[0] + + if target_backup is None: + # No backup → remove override; live handler will fall + # back to the bundled default automatically. + if override.is_file(): + try: + override.unlink() + except OSError as exc: + logger.warning( + "[kora.phrasebook] override unlink failed: %r", exc + ) + raise + return {"reverted_to": "bundled_default", "source_path": None} + + # Copy backup → override atomically (same pattern as + # write_phrasebook). Don't move/delete the backup itself; + # operator may want to revert again to the same point. + from utils import atomic_replace + + override.parent.mkdir(parents=True, exist_ok=True) + tmp = override.with_suffix(".yml.tmp") + shutil.copy2(target_backup, tmp) + atomic_replace(tmp, override) + return { + "reverted_to": target_backup.name, + "source_path": str(override), + } diff --git a/kora_cli/web_server.py b/kora_cli/web_server.py index 753d96c59ef7..62e256b1375a 100644 --- a/kora_cli/web_server.py +++ b/kora_cli/web_server.py @@ -6277,6 +6277,236 @@ async def test_phrasebook_match(payload: Dict[str, Any]) -> Dict[str, Any]: } +# --------------------------------------------------------------------------- +# DM phrasebook write path — KR-FE-PHRASEBOOK-EDITOR-AND-CRUD +# --------------------------------------------------------------------------- +# +# Read endpoints are above (PR #167). This block adds: +# +# * PUT /api/phrasebook/slack_dm — replace entries +# * POST /api/phrasebook/slack_dm/revert — revert to backup +# * GET /api/phrasebook/slack_dm/backups — list backups +# +# Validation, atomic write, backup rotation, and the static +# snapshot-schema allow-list live in +# kora_cli/short_circuit/phrasebook_editor.py — this block is +# request-handling + audit emission only. +# +# Audit: each successful PUT (or revert) emits seam=phrasebook.updated +# with entry_count_before / entry_count_after / backup_filename / +# actor="operator". Audit-panel consumers (KR-AUDIT-PANEL-ENDPOINTS +# / future KR-PROMOTION-REVIEW-PANEL) join on this seam to +# reconstruct edit history. + + +def _phrasebook_count_current_entries() -> int: + """Best-effort count of currently-live entries (for the + entry_count_before audit field). Returns 0 if load fails so a + failure here doesn't block the write.""" + try: + from kora_cli.short_circuit import dm_phrasebook + + return len(dm_phrasebook.load_phrasebook()) + except Exception: + return 0 + + +@app.put("/api/phrasebook/slack_dm") +async def put_phrasebook(payload: Dict[str, Any]) -> Any: + """Replace the entire operator-override phrasebook. + + Atomic-semantic: if ANY entry fails validation, the whole + payload is refused (422 with per-entry errors); the existing + override is preserved. Successful writes go through + backup-then-write-atomic so an in-flight crash can't leave + the override half-written or back-up-less. + + Payload shape: + {"entries": [ + {"pattern": "...", "category": "...", + "description": "...", "reply_template": "..."}, ... + ]} + + On success returns the new entries (echoed verbatim so the + cockpit can refresh from the response) + the backup + filename written (if any) + the source path. + """ + from kora_cli.audit import emit_audit + from kora_cli.short_circuit import phrasebook_editor + + entries = payload.get("entries") if isinstance(payload, dict) else None + errors = phrasebook_editor.validate_entries(entries) + if errors: + return JSONResponse( + status_code=422, + content={ + "error": "validation_failed", + "errors": [e.as_dict() for e in errors], + }, + ) + + typed_entries: List[Dict[str, Any]] = entries # type: ignore[assignment] + count_before = _phrasebook_count_current_entries() + + override_path = phrasebook_editor._override_path() + backup_path = phrasebook_editor.write_backup_for(override_path) + + try: + phrasebook_editor.write_phrasebook(typed_entries) + except Exception as exc: + logger.warning( + "[kora.phrasebook] write_phrasebook raised %r — backup " + "preserved at %s, override unchanged", + exc, + backup_path, + ) + return JSONResponse( + status_code=500, + content={ + "error": "write_failed", + "detail": repr(exc), + "backup_filename": ( + backup_path.name if backup_path is not None else None + ), + }, + ) + + keep = phrasebook_editor._backup_keep_count() + try: + rotated = phrasebook_editor.rotate_backups(keep) + except Exception as exc: + logger.warning( + "[kora.phrasebook] backup rotation raised %r — write " + "succeeded; rotation will catch up next write", + exc, + ) + rotated = [] + + try: + emit_audit( + seam="phrasebook.updated", + details={ + "actor": "operator", + "action": "put", + "entry_count_before": count_before, + "entry_count_after": len(typed_entries), + "backup_filename": ( + backup_path.name if backup_path is not None else None + ), + "rotated_backup_count": len(rotated), + }, + source=None, + ) + except Exception as exc: + logger.warning( + "[kora.phrasebook] audit emit_audit raised %r — write " + "still succeeded", + exc, + ) + + return { + "source_path": str(override_path), + "entry_count": len(typed_entries), + "backup_filename": ( + backup_path.name if backup_path is not None else None + ), + "rotated_backup_count": len(rotated), + "entries": [ + { + "pattern": e["pattern"], + "category": e["category"], + "description": e["description"], + "reply_template": e["reply_template"], + "referenced_snapshot_fields": ( + _extract_phrasebook_snapshot_refs(e["reply_template"]) + ), + } + for e in typed_entries + ], + } + + +@app.post("/api/phrasebook/slack_dm/revert") +async def revert_phrasebook_endpoint( + payload: Optional[Dict[str, Any]] = None, +) -> Any: + """Revert the override to a specific backup OR (when no + filename supplied) the most-recent backup OR (when no backups + exist) remove the override entirely. + + Payload (all optional): ``{"filename": "slack_dm.YYYY-...Z.yml"}`` + + Defense against path traversal lives in + phrasebook_editor.revert_phrasebook — filename must match the + slack_dm.*.yml shape with no path separators. + """ + from kora_cli.audit import emit_audit + from kora_cli.short_circuit import phrasebook_editor + + filename: Optional[str] = None + if isinstance(payload, dict): + raw = payload.get("filename") + if isinstance(raw, str) and raw: + filename = raw + + count_before = _phrasebook_count_current_entries() + + try: + result = phrasebook_editor.revert_phrasebook(filename=filename) + except ValueError as exc: + return JSONResponse( + status_code=400, + content={"error": "invalid_filename", "detail": str(exc)}, + ) + except FileNotFoundError as exc: + return JSONResponse( + status_code=404, + content={"error": "backup_not_found", "detail": str(exc)}, + ) + except Exception as exc: + logger.warning("[kora.phrasebook] revert raised %r", exc) + return JSONResponse( + status_code=500, + content={"error": "revert_failed", "detail": repr(exc)}, + ) + + count_after = _phrasebook_count_current_entries() + + try: + emit_audit( + seam="phrasebook.updated", + details={ + "actor": "operator", + "action": "revert", + "entry_count_before": count_before, + "entry_count_after": count_after, + "reverted_to": result.get("reverted_to"), + }, + source=None, + ) + except Exception as exc: + logger.warning( + "[kora.phrasebook] revert audit emit_audit raised %r", exc + ) + + return result + + +@app.get("/api/phrasebook/slack_dm/backups") +async def get_phrasebook_backups() -> Dict[str, Any]: + """Newest-first list of available backups, for the cockpit + revert dropdown. Each entry: filename / timestamp / + size_bytes / entry_count (None when the backup can't be + parsed, so the cockpit can grey out corrupt backups instead + of pretending they're valid revert targets).""" + from kora_cli.short_circuit import phrasebook_editor + + return { + "backups": phrasebook_editor.list_backups(), + "rotation_keep": phrasebook_editor._backup_keep_count(), + } + + # --------------------------------------------------------------------------- # Probe investigations xref — KR-FE-PROBE-INVESTIGATION-VIEWER # --------------------------------------------------------------------------- diff --git a/tests/kora_cli/test_phrasebook_editor.py b/tests/kora_cli/test_phrasebook_editor.py new file mode 100644 index 000000000000..a79fc67a416a --- /dev/null +++ b/tests/kora_cli/test_phrasebook_editor.py @@ -0,0 +1,687 @@ +"""KR-FE-PHRASEBOOK-EDITOR-AND-CRUD — backend tests. + +Covers the write path added on top of PR #167's read-only viewer: + + Validation (kora_cli/short_circuit/phrasebook_editor.py): + 1. Valid entry list → no errors + 2. Non-list payload → root error + 3. Missing field → per-field error + 4. Empty field (whitespace) → per-field error + 5. Pattern length cap + 6. Reply template length cap + 7. Description / category length caps + 8. Entries count cap (MAX_ENTRIES_PER_PHRASEBOOK) + 9. Invalid regex → pattern error + 10. Catastrophic-backtracking guard catches (x+)+, (.*)* + 11. Snapshot path not in static schema → reply_template error + 12. Valid snapshot path accepted + 13. Duplicate (pattern, category) → root error pointing at first + 14. Schema set matches snapshot collectors (drift guard) + + Backup discipline: + 15. write_backup_for with no override → returns None (first edit) + 16. write_backup_for copies content + timestamps filename + 17. rotate_backups keeps N most recent + 18. KORA_PHRASEBOOK_BACKUP_COUNT env override read + clamped + 19. list_backups returns newest-first with entry_count + + Write + revert: + 20. write_phrasebook serializes deterministic YAML + uses atomic_replace + 21. revert with named backup restores its content + 22. revert with no filename takes most-recent backup + 23. revert with no backups removes the override entirely + 24. revert refuses path-traversal filenames + + Endpoints: + 25. PUT valid → 200 + override written + backup + audit row + 26. PUT invalid → 422; no write; previous content preserved + 27. PUT with no existing override → no backup but still writes + 28. PUT write_failed audit not emitted (failure path) + 29. POST revert → 200 + correct reverted_to + audit row + 30. POST revert invalid filename → 400 + 31. POST revert missing backup → 404 + 32. GET backups → newest-first list + + Audit seam: + 33. SeamName Literal includes phrasebook.updated +""" + +from __future__ import annotations + +import json +import re +from pathlib import Path +from typing import Any, Dict, List + +import pytest + +from tests.kora_cli._panel_test_helpers import isolated_kora_home + + +_REPO_ROOT = Path(__file__).resolve().parents[2] +_EDITOR_PY = ( + _REPO_ROOT / "kora_cli" / "short_circuit" / "phrasebook_editor.py" +) +_SNAPSHOT_PY = _REPO_ROOT / "kora_cli" / "snapshot" / "state_snapshot.py" +_JSONL_SINK = _REPO_ROOT / "kora_cli" / "audit" / "jsonl_sink.py" + + +@pytest.fixture +def env(tmp_path, monkeypatch): + return isolated_kora_home(tmp_path, monkeypatch) + + +def _valid_entry( + pattern: str = r"^hello$", + category: str = "greeting", + description: str = "test", + reply_template: str = "Hi!", +) -> Dict[str, Any]: + return { + "pattern": pattern, + "category": category, + "description": description, + "reply_template": reply_template, + } + + +# --------------------------------------------------------------------------- +# 1-13. Validation +# --------------------------------------------------------------------------- + + +def test_valid_entry_list_no_errors(): + from kora_cli.short_circuit import phrasebook_editor + + errors = phrasebook_editor.validate_entries([_valid_entry()]) + assert errors == [] + + +def test_non_list_payload_root_error(): + from kora_cli.short_circuit import phrasebook_editor + + errors = phrasebook_editor.validate_entries("not a list") + assert len(errors) == 1 + assert errors[0].entry_index == -1 + assert errors[0].field == "_root" + + +def test_missing_field_per_field_error(): + from kora_cli.short_circuit import phrasebook_editor + + bad = {"pattern": "x", "category": "y"} + errors = phrasebook_editor.validate_entries([bad]) + fields = {e.field for e in errors} + assert "description" in fields + assert "reply_template" in fields + + +def test_empty_whitespace_field_error(): + from kora_cli.short_circuit import phrasebook_editor + + bad = _valid_entry(pattern=" ") + errors = phrasebook_editor.validate_entries([bad]) + assert any(e.field == "pattern" for e in errors) + + +def test_pattern_length_cap(): + from kora_cli.short_circuit import phrasebook_editor + + long_pattern = "a" * (phrasebook_editor.MAX_PATTERN_LENGTH + 1) + errors = phrasebook_editor.validate_entries( + [_valid_entry(pattern=long_pattern)] + ) + assert any( + e.field == "pattern" and "exceeds" in e.error for e in errors + ) + + +def test_reply_template_length_cap(): + from kora_cli.short_circuit import phrasebook_editor + + long_reply = "a" * (phrasebook_editor.MAX_REPLY_TEMPLATE_LENGTH + 1) + errors = phrasebook_editor.validate_entries( + [_valid_entry(reply_template=long_reply)] + ) + assert any( + e.field == "reply_template" and "exceeds" in e.error for e in errors + ) + + +def test_description_and_category_length_caps(): + from kora_cli.short_circuit import phrasebook_editor + + long_desc = "x" * (phrasebook_editor.MAX_DESCRIPTION_LENGTH + 1) + long_cat = "y" * (phrasebook_editor.MAX_CATEGORY_LENGTH + 1) + errors = phrasebook_editor.validate_entries( + [_valid_entry(description=long_desc, category=long_cat)] + ) + fields = {e.field for e in errors} + assert "description" in fields + assert "category" in fields + + +def test_entries_count_cap(): + from kora_cli.short_circuit import phrasebook_editor + + too_many = [ + _valid_entry(pattern=f"^p{i}$", category=f"c{i}") + for i in range(phrasebook_editor.MAX_ENTRIES_PER_PHRASEBOOK + 1) + ] + errors = phrasebook_editor.validate_entries(too_many) + assert any( + e.entry_index == -1 and "too many" in e.error for e in errors + ) + + +def test_invalid_regex_error(): + from kora_cli.short_circuit import phrasebook_editor + + errors = phrasebook_editor.validate_entries( + [_valid_entry(pattern="(unclosed")] + ) + assert any( + e.field == "pattern" and "invalid regex" in e.error for e in errors + ) + + +@pytest.mark.parametrize( + "pathological", + [ + r"(a+)+", + r"(.*)*", + r"(\w*)?", + r"(.+)+", + ], +) +def test_catastrophic_backtracking_guard(pathological): + from kora_cli.short_circuit import phrasebook_editor + + errors = phrasebook_editor.validate_entries( + [_valid_entry(pattern=pathological)] + ) + assert any( + e.field == "pattern" and "backtracking" in e.error for e in errors + ), f"pattern {pathological!r} should be flagged" + + +def test_unknown_snapshot_path_rejected(): + from kora_cli.short_circuit import phrasebook_editor + + errors = phrasebook_editor.validate_entries( + [ + _valid_entry( + reply_template="Hello {snapshot.totally.not.real.field}!" + ) + ] + ) + assert any( + e.field == "reply_template" and "not in known scalar schema" in e.error + for e in errors + ) + + +def test_known_snapshot_path_accepted(): + from kora_cli.short_circuit import phrasebook_editor + + errors = phrasebook_editor.validate_entries( + [ + _valid_entry( + reply_template=( + "Burn: {snapshot.cost_ladder.spent_to_date_usd} / " + "{snapshot.cost_ladder.credit_pool_usd}" + ) + ) + ] + ) + assert errors == [] + + +def test_duplicate_pattern_category_pair_rejected(): + from kora_cli.short_circuit import phrasebook_editor + + entries = [ + _valid_entry(pattern="^hi$", category="greeting"), + _valid_entry( + pattern="^hi$", + category="greeting", + description="dup", + reply_template="hi", + ), + ] + errors = phrasebook_editor.validate_entries(entries) + assert any( + e.entry_index == 1 + and e.field == "_root" + and "duplicate" in e.error + for e in errors + ) + + +def test_static_schema_matches_snapshot_collectors(): + """Drift guard: SNAPSHOT_SCALAR_PATHS in phrasebook_editor must + name fields that are actually populated by the snapshot + collector functions in state_snapshot.py. If the snapshot adds + a new scalar field (e.g. cost_ladder.foo) without us updating + the allow-list, operator templates referencing it would be + rejected. If state_snapshot RENAMES a field without us + updating, accepted templates would silently fall through at + runtime. This test catches the rename case by greping the + snapshot source for each declared scalar key.""" + from kora_cli.short_circuit import phrasebook_editor + + snap_src = _SNAPSHOT_PY.read_text() + # The allow-list uses dotted paths; the snapshot source + # writes them as nested dict keys. For each path, the LEAF + # key must appear in the snapshot source. (Catches rename; + # doesn't catch deeper structural moves — those'd need a + # round-trip snapshot build, which is heavier than warranted + # for a v1 drift guard.) + for path in phrasebook_editor.SNAPSHOT_SCALAR_PATHS: + leaf = path.split(".")[-1] + # Top-level metadata (computed_at / schema_version) live + # directly in the build dict — also pinned. + assert f'"{leaf}"' in snap_src, ( + f"SNAPSHOT_SCALAR_PATHS path '{path}' leaf '{leaf}' not " + f"found in {_SNAPSHOT_PY} — drift between allow-list " + f"and snapshot collectors" + ) + + +# --------------------------------------------------------------------------- +# 15-19. Backups +# --------------------------------------------------------------------------- + + +def test_write_backup_for_no_override_returns_none(env): + from kora_cli.short_circuit import phrasebook_editor + + override = phrasebook_editor._override_path() + assert phrasebook_editor.write_backup_for(override) is None + + +def test_write_backup_for_copies_content_and_timestamps(env): + from kora_cli.short_circuit import phrasebook_editor + + override = phrasebook_editor._override_path() + override.parent.mkdir(parents=True, exist_ok=True) + override.write_text("entries:\n - pattern: hi\n", encoding="utf-8") + + bkp = phrasebook_editor.write_backup_for(override) + assert bkp is not None + assert bkp.exists() + assert bkp.read_text() == override.read_text() + # Filename: slack_dm.{ISO}.yml + assert re.match( + r"slack_dm\.\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}Z(?:-\d+)?\.yml", + bkp.name, + ) + + +def test_rotate_backups_keeps_n_most_recent(env): + from kora_cli.short_circuit import phrasebook_editor + + bkp_dir = phrasebook_editor._backup_dir() + bkp_dir.mkdir(parents=True, exist_ok=True) + # Names sort chronologically as plain strings. + names = [ + "slack_dm.2026-01-01T00-00-00Z.yml", + "slack_dm.2026-01-02T00-00-00Z.yml", + "slack_dm.2026-01-03T00-00-00Z.yml", + "slack_dm.2026-01-04T00-00-00Z.yml", + "slack_dm.2026-01-05T00-00-00Z.yml", + ] + for n in names: + (bkp_dir / n).write_text("entries: []\n", encoding="utf-8") + removed = phrasebook_editor.rotate_backups(keep=3) + assert len(removed) == 2 + remaining = sorted(p.name for p in bkp_dir.glob("slack_dm.*.yml")) + assert remaining == names[-3:] + + +@pytest.mark.parametrize( + "envval,expected", + [ + ("", 10), # default + ("5", 5), + ("not-a-number", 10), + ("0", 1), # clamp lower + ("99999", 1000), # clamp upper + ], +) +def test_backup_keep_count_env_clamping(envval, expected, monkeypatch): + from kora_cli.short_circuit import phrasebook_editor + + if envval: + monkeypatch.setenv(phrasebook_editor.BACKUP_KEEP_ENV, envval) + else: + monkeypatch.delenv(phrasebook_editor.BACKUP_KEEP_ENV, raising=False) + assert phrasebook_editor._backup_keep_count() == expected + + +def test_list_backups_returns_newest_first_with_entry_count(env): + from kora_cli.short_circuit import phrasebook_editor + + bkp_dir = phrasebook_editor._backup_dir() + bkp_dir.mkdir(parents=True, exist_ok=True) + (bkp_dir / "slack_dm.2026-01-01T00-00-00Z.yml").write_text( + "entries:\n - pattern: a\n category: c\n description: d\n" + " reply_template: r\n", + encoding="utf-8", + ) + (bkp_dir / "slack_dm.2026-01-02T00-00-00Z.yml").write_text( + "entries:\n - pattern: a\n category: c\n description: d\n" + " reply_template: r\n - pattern: b\n category: c\n" + " description: d\n reply_template: r\n", + encoding="utf-8", + ) + backups = phrasebook_editor.list_backups() + assert [b["filename"] for b in backups] == [ + "slack_dm.2026-01-02T00-00-00Z.yml", + "slack_dm.2026-01-01T00-00-00Z.yml", + ] + assert backups[0]["entry_count"] == 2 + assert backups[1]["entry_count"] == 1 + + +# --------------------------------------------------------------------------- +# 20-24. Write + revert +# --------------------------------------------------------------------------- + + +def test_write_phrasebook_produces_loadable_yaml(env): + from kora_cli.short_circuit import dm_phrasebook, phrasebook_editor + + entries = [_valid_entry()] + override = phrasebook_editor.write_phrasebook(entries) + assert override.is_file() + # Round-trip: the same load_phrasebook the live handler uses + # must read what we just wrote. + loaded = dm_phrasebook.load_phrasebook() + assert len(loaded) == 1 + assert loaded[0].pattern.pattern == "^hello$" + + +def test_revert_with_named_backup_restores(env): + from kora_cli.short_circuit import phrasebook_editor + + override = phrasebook_editor._override_path() + override.parent.mkdir(parents=True, exist_ok=True) + override.write_text("entries:\n - pattern: original\n", encoding="utf-8") + bkp = phrasebook_editor.write_backup_for(override) + # Now overwrite the override + override.write_text("entries:\n - pattern: changed\n", encoding="utf-8") + # Revert by name + result = phrasebook_editor.revert_phrasebook(filename=bkp.name) + assert result["reverted_to"] == bkp.name + assert "original" in override.read_text() + + +def test_revert_with_no_filename_takes_most_recent(env): + from kora_cli.short_circuit import phrasebook_editor + + override = phrasebook_editor._override_path() + override.parent.mkdir(parents=True, exist_ok=True) + override.write_text("entries:\n - pattern: v1\n", encoding="utf-8") + bkp_dir = phrasebook_editor._backup_dir() + bkp_dir.mkdir(parents=True, exist_ok=True) + older = bkp_dir / "slack_dm.2026-01-01T00-00-00Z.yml" + newer = bkp_dir / "slack_dm.2026-01-02T00-00-00Z.yml" + older.write_text("entries:\n - pattern: older\n", encoding="utf-8") + newer.write_text("entries:\n - pattern: newer\n", encoding="utf-8") + result = phrasebook_editor.revert_phrasebook(filename=None) + assert result["reverted_to"] == newer.name + assert "newer" in override.read_text() + + +def test_revert_with_no_backups_removes_override(env): + from kora_cli.short_circuit import phrasebook_editor + + override = phrasebook_editor._override_path() + override.parent.mkdir(parents=True, exist_ok=True) + override.write_text("entries:\n - pattern: v1\n", encoding="utf-8") + result = phrasebook_editor.revert_phrasebook(filename=None) + assert result["reverted_to"] == "bundled_default" + assert result["source_path"] is None + assert not override.exists() + + +@pytest.mark.parametrize( + "bad_filename", + [ + "../../../etc/passwd", + "/etc/passwd", + "slack_dm/../passwd.yml", + "not_a_phrasebook.yml", + "slack_dm.foo.txt", + ], +) +def test_revert_refuses_path_traversal(env, bad_filename): + from kora_cli.short_circuit import phrasebook_editor + + with pytest.raises(ValueError): + phrasebook_editor.revert_phrasebook(filename=bad_filename) + + +# --------------------------------------------------------------------------- +# 25-32. Endpoints +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_put_valid_writes_and_emits_audit(env): + from kora_cli import web_server + from kora_cli.short_circuit import phrasebook_editor + + payload = {"entries": [_valid_entry()]} + result = await web_server.put_phrasebook(payload) + # Successful response is a dict (not a JSONResponse). + assert isinstance(result, dict) + assert result["entry_count"] == 1 + assert result["source_path"] == str(phrasebook_editor._override_path()) + + # Override file written. + assert phrasebook_editor._override_path().is_file() + + # Audit row emitted. + audit_log = env / "kora_audit_log.jsonl" + assert audit_log.is_file() + lines = [ + json.loads(line) + for line in audit_log.read_text().splitlines() + if line.strip() + ] + seams = {e.get("seam") for e in lines} + assert "phrasebook.updated" in seams + pb_audit = [e for e in lines if e.get("seam") == "phrasebook.updated"][0] + assert pb_audit["details"]["actor"] == "operator" + assert pb_audit["details"]["action"] == "put" + assert pb_audit["details"]["entry_count_after"] == 1 + + +@pytest.mark.asyncio +async def test_put_invalid_preserves_previous_content(env): + from fastapi.responses import JSONResponse + from kora_cli.short_circuit import phrasebook_editor + from kora_cli import web_server + + # Seed an existing override the operator should not lose. + override = phrasebook_editor._override_path() + override.parent.mkdir(parents=True, exist_ok=True) + seed_yaml = ( + "entries:\n" + " - pattern: '^seed$'\n" + " category: seed_cat\n" + " description: seed\n" + " reply_template: seed\n" + ) + override.write_text(seed_yaml, encoding="utf-8") + before = override.read_text() + + bad_payload = { + "entries": [_valid_entry(pattern="(unclosed")] + } + result = await web_server.put_phrasebook(bad_payload) + assert isinstance(result, JSONResponse) + assert result.status_code == 422 + body = json.loads(result.body.decode()) + assert body["error"] == "validation_failed" + assert any(e["field"] == "pattern" for e in body["errors"]) + # Override unchanged. + assert override.read_text() == before + + +@pytest.mark.asyncio +async def test_put_no_existing_override_no_backup_but_writes(env): + from kora_cli import web_server + from kora_cli.short_circuit import phrasebook_editor + + payload = {"entries": [_valid_entry()]} + result = await web_server.put_phrasebook(payload) + assert isinstance(result, dict) + # No previous override → backup_filename should be None + assert result["backup_filename"] is None + # But override file is now written + assert phrasebook_editor._override_path().is_file() + + +@pytest.mark.asyncio +async def test_post_revert_with_backup(env): + from kora_cli import web_server + from kora_cli.short_circuit import phrasebook_editor + + # Seed override + make a backup of it + override = phrasebook_editor._override_path() + override.parent.mkdir(parents=True, exist_ok=True) + override.write_text( + "entries:\n - pattern: original\n category: c\n" + " description: d\n reply_template: r\n", + encoding="utf-8", + ) + bkp = phrasebook_editor.write_backup_for(override) + # Overwrite override + override.write_text( + "entries:\n - pattern: changed\n category: c\n" + " description: d\n reply_template: r\n", + encoding="utf-8", + ) + # Revert via endpoint + result = await web_server.revert_phrasebook_endpoint( + {"filename": bkp.name} + ) + assert isinstance(result, dict) + assert result["reverted_to"] == bkp.name + assert "original" in override.read_text() + # Audit emitted + audit = env / "kora_audit_log.jsonl" + lines = [json.loads(line) for line in audit.read_text().splitlines() if line.strip()] + assert any( + e.get("seam") == "phrasebook.updated" + and e["details"].get("action") == "revert" + for e in lines + ) + + +@pytest.mark.asyncio +async def test_post_revert_invalid_filename_400(env): + from fastapi.responses import JSONResponse + from kora_cli import web_server + + result = await web_server.revert_phrasebook_endpoint( + {"filename": "../../etc/passwd"} + ) + assert isinstance(result, JSONResponse) + assert result.status_code == 400 + + +@pytest.mark.asyncio +async def test_post_revert_missing_backup_404(env): + from fastapi.responses import JSONResponse + from kora_cli import web_server + + result = await web_server.revert_phrasebook_endpoint( + {"filename": "slack_dm.2099-01-01T00-00-00Z.yml"} + ) + assert isinstance(result, JSONResponse) + assert result.status_code == 404 + + +@pytest.mark.asyncio +async def test_get_backups_newest_first(env): + from kora_cli import web_server + from kora_cli.short_circuit import phrasebook_editor + + bkp_dir = phrasebook_editor._backup_dir() + bkp_dir.mkdir(parents=True, exist_ok=True) + (bkp_dir / "slack_dm.2026-01-01T00-00-00Z.yml").write_text( + "entries: []\n", encoding="utf-8" + ) + (bkp_dir / "slack_dm.2026-01-02T00-00-00Z.yml").write_text( + "entries: []\n", encoding="utf-8" + ) + result = await web_server.get_phrasebook_backups() + assert [b["filename"] for b in result["backups"]] == [ + "slack_dm.2026-01-02T00-00-00Z.yml", + "slack_dm.2026-01-01T00-00-00Z.yml", + ] + assert isinstance(result["rotation_keep"], int) + + +# --------------------------------------------------------------------------- +# 33. Audit seam Literal +# --------------------------------------------------------------------------- + + +def test_seam_name_literal_includes_phrasebook_updated(): + """The audit seam Literal at kora_cli/audit/jsonl_sink.py must + declare phrasebook.updated as a valid seam — otherwise + emit_audit raises ValidationError and the audit silently + drops (only the structured-log line survives).""" + src = _JSONL_SINK.read_text() + assert '"phrasebook.updated"' in src + + +# --------------------------------------------------------------------------- +# Bonus — full round-trip integration test +# --------------------------------------------------------------------------- + + +@pytest.mark.asyncio +async def test_round_trip_put_then_revert_restores_seed(env): + """Operator scenario: write a phrasebook, then revert it. + Reverted content should match what was there pre-write.""" + from kora_cli import web_server + from kora_cli.short_circuit import phrasebook_editor + + # Seed an existing override + override = phrasebook_editor._override_path() + override.parent.mkdir(parents=True, exist_ok=True) + seed_yaml = ( + "entries:\n" + " - pattern: '^seed$'\n" + " category: c\n description: d\n" + " reply_template: seed_reply\n" + ) + override.write_text(seed_yaml, encoding="utf-8") + + # PUT new content (triggers backup of seed) + new_payload = { + "entries": [ + _valid_entry( + pattern="^new$", + category="c", + description="d", + reply_template="new_reply", + ) + ] + } + put_result = await web_server.put_phrasebook(new_payload) + assert isinstance(put_result, dict) + backup_name = put_result["backup_filename"] + assert backup_name is not None + + # Revert (no filename → most-recent backup, which is the seed) + revert_result = await web_server.revert_phrasebook_endpoint(None) + assert isinstance(revert_result, dict) + assert revert_result["reverted_to"] == backup_name + assert "seed_reply" in override.read_text() diff --git a/tests/kora_cli/test_phrasebook_editor_fe_pins.py b/tests/kora_cli/test_phrasebook_editor_fe_pins.py new file mode 100644 index 000000000000..3a83fabdd0a9 --- /dev/null +++ b/tests/kora_cli/test_phrasebook_editor_fe_pins.py @@ -0,0 +1,258 @@ +"""FE source-pin tests for KR-FE-PHRASEBOOK-EDITOR-AND-CRUD. + +The endpoint + module behavior is covered in +test_phrasebook_editor.py (44 tests). This file pins the FE +wiring that's hard to test without a browser: + + 1. api wrappers: putSlackDmPhrasebook + revertSlackDmPhrasebook + + getSlackDmPhrasebookBackups all exist + post to the right + URLs with the right verbs + 2. TS types declared: PhrasebookEntryWrite / PhrasebookPutResponse + / PhrasebookValidationErrorEntry / PhrasebookValidationErrorBody + / PhrasebookRevertResponse / PhrasebookBackupItem / + PhrasebookBackupsResponse + 3. PhrasebookEditor.tsx file exists with the expected exports + 4. PhrasebookPage delegates to the editor in edit-mode + 5. Edit-mode controls wired: Edit button + Backups button + + Save / Cancel / Add visible only in edit-mode + 6. Validation-error display: 422 body parsing branch present + 7. ClientSidePreview mirrors the backend regex + walk semantics + (case-insensitive regex + "unknown" sentinel triggers + fall-through) + 8. SnapshotResponse TS type already declares the v4 sections + PhrasebookEditor's static validation references +""" + +import re +from pathlib import Path + + +_REPO_ROOT = Path(__file__).resolve().parents[2] +_API_TS = _REPO_ROOT / "web" / "src" / "lib" / "api.ts" +_PAGE = _REPO_ROOT / "web" / "src" / "pages" / "PhrasebookPage.tsx" +_EDITOR = _REPO_ROOT / "web" / "src" / "pages" / "PhrasebookEditor.tsx" + + +# --------------------------------------------------------------------------- +# 1. api wrappers +# --------------------------------------------------------------------------- + + +def test_put_wrapper_exists(): + src = _API_TS.read_text() + assert re.search( + r'putSlackDmPhrasebook:\s*\(entries:\s*PhrasebookEntryWrite\[\]\)', + src, + ) + # Verb + URL pin — without this, the wrapper would GET (which + # would 405) or hit a different path. + assert ( + '"/api/phrasebook/slack_dm"' in src + and '"PUT"' in src + ) + + +def test_revert_wrapper_exists(): + src = _API_TS.read_text() + assert "revertSlackDmPhrasebook:" in src + assert '"/api/phrasebook/slack_dm/revert"' in src + assert '"POST"' in src + + +def test_backups_list_wrapper_exists(): + src = _API_TS.read_text() + assert "getSlackDmPhrasebookBackups:" in src + assert '"/api/phrasebook/slack_dm/backups"' in src + + +# --------------------------------------------------------------------------- +# 2. TS types declared +# --------------------------------------------------------------------------- + + +def test_write_types_declared(): + src = _API_TS.read_text() + for ts_type in ( + "PhrasebookEntryWrite", + "PhrasebookPutResponse", + "PhrasebookValidationErrorEntry", + "PhrasebookValidationErrorBody", + "PhrasebookRevertResponse", + "PhrasebookBackupItem", + "PhrasebookBackupsResponse", + ): + assert f"export interface {ts_type}" in src or ( + f"export type {ts_type}" in src + ), f"missing TS type: {ts_type}" + + +def test_validation_error_shape_matches_backend(): + """PhrasebookValidationErrorEntry must have entry_index + + field + error to match the backend's EntryValidationError. + as_dict() shape. Drift here makes the editor render wrong + fields' errors.""" + src = _API_TS.read_text() + # Find the interface block + check the 3 fields appear within + # ~20 lines of the declaration. + m = re.search( + r"export interface PhrasebookValidationErrorEntry\s*\{([^}]+)\}", + src, + ) + assert m is not None + body = m.group(1) + assert "entry_index" in body + assert "field" in body + assert "error" in body + + +# --------------------------------------------------------------------------- +# 3. PhrasebookEditor.tsx +# --------------------------------------------------------------------------- + + +def test_editor_file_exists_and_exports(): + assert _EDITOR.is_file() + src = _EDITOR.read_text() + for export in ( + "EntryEditorRow", + "EditModeControls", + "BackupsDialog", + "ClientSidePreview", + "makeEmptyEntry", + "toEditableEntries", + "clientSidePreview", + ): + assert f"export function {export}" in src or ( + f"export const {export}" in src + or f"export interface {export}" in src + or f"export type {export}" in src + ), f"missing export: {export}" + + +# --------------------------------------------------------------------------- +# 4. PhrasebookPage delegates to editor in edit-mode +# --------------------------------------------------------------------------- + + +def test_page_imports_editor_components(): + src = _PAGE.read_text() + for import_name in ( + "BackupsDialog", + "ClientSidePreview", + "EditModeControls", + "EntryEditorRow", + "makeEmptyEntry", + "toEditableEntries", + ): + assert import_name in src, f"PhrasebookPage missing import: {import_name}" + + +def test_page_has_edit_mode_state(): + src = _PAGE.read_text() + # editingEntries === null ≡ view mode (a discriminator the + # render branch checks). Pin the literal so a refactor doesn't + # change the discriminator and silently break the render. + assert "editingEntries" in src + assert "editingEntries === null" in src + + +def test_page_renders_editor_rows_in_edit_mode(): + src = _PAGE.read_text() + assert "", + src, + ), "Edit/Backups buttons must be inside an editingEntries===null guard" + + +# --------------------------------------------------------------------------- +# 6. Validation-error display: 422 body parsing branch present +# --------------------------------------------------------------------------- + + +def test_page_parses_422_validation_body(): + """fetchJSON throws Error('STATUS: BODY') on non-2xx. The + Save handler must parse 422 specially to surface per-field + errors back to the editor rows. Without this branch, the + user sees a generic 'Save failed' toast and no inline errors.""" + src = _PAGE.read_text() + # Pin the 422 detection + JSON parse + assert '"422"' in src or "'422'" in src + assert "validation_failed" in src + assert "setValidationErrors" in src + + +# --------------------------------------------------------------------------- +# 7. ClientSidePreview mirrors backend semantics +# --------------------------------------------------------------------------- + + +def test_client_side_preview_uses_case_insensitive_regex(): + """dm_phrasebook compiles with re.IGNORECASE; the FE preview + must mirror so what the operator sees in the preview matches + what the live handler will do.""" + src = _EDITOR.read_text() + assert re.search(r'new RegExp\([^,]+,\s*"i"\)', src), ( + "ClientSidePreview must use 'i' flag (case-insensitive) " + "to match dm_phrasebook's re.IGNORECASE" + ) + + +def test_client_side_preview_falls_through_on_unknown_sentinel(): + """Mirrors render_reply at dm_phrasebook.py:293 — value == + "unknown" triggers fall-through. Pin the literal so a typo + later doesn't silently change the FE preview from the runtime.""" + src = _EDITOR.read_text() + assert ( + 'value === "unknown"' in src + or "value === 'unknown'" in src + ) + + +def test_client_side_preview_falls_through_on_null_snapshot(): + """Mirrors render_reply at dm_phrasebook.py:285-286 — null + snapshot triggers UNIVERSAL fall-through (even for templates + with no placeholders). Without this branch, the FE preview + would falsely show "matched + rendered" for a null snapshot + when the live handler would actually fall through.""" + src = _EDITOR.read_text() + assert "snapshot === null" in src + assert "snapshot unavailable" in src.lower() + + +# --------------------------------------------------------------------------- +# 8. SnapshotResponse type already covers v4 — referenced by the +# static SNAPSHOT_SCALAR_PATHS allow-list on the BE side; if the +# TS type drifts the FE preview won't be able to read the same +# paths the backend validation accepts. +# --------------------------------------------------------------------------- + + +def test_snapshot_response_includes_daemon_health_for_template_paths(): + """The static SNAPSHOT_SCALAR_PATHS allow-list on the BE + includes daemon_health.* paths. SnapshotResponse TS type must + have a corresponding daemon_health section so the FE preview + can walk these paths against the live snapshot.""" + src = _API_TS.read_text() + assert "daemon_health" in src + assert "overall_status" in src + assert "uptime_seconds" in src diff --git a/web/docs/phrasebook-editor/_styles.css b/web/docs/phrasebook-editor/_styles.css new file mode 100644 index 000000000000..3f0a9ce64369 --- /dev/null +++ b/web/docs/phrasebook-editor/_styles.css @@ -0,0 +1,53 @@ +:root { + --bg: #0a0a0a; --fg: #ededed; --muted: #8b8b8b; + --card: #131313; --border: #2a2a2a; + --success: #4ade80; --warning: #facc15; --destructive: #f87171; + --primary: #60a5fa; +} +body { background: var(--bg); color: var(--fg); + font-family: -apple-system, ui-sans-serif, system-ui, sans-serif; + padding: 28px; max-width: 1100px; margin: 0; } +h1 { font-size: 18px; font-weight: 600; margin: 0 0 4px; } +.preamble { color: var(--muted); font-size: 12px; max-width: 760px; + line-height: 1.5; margin-bottom: 14px; } +.card { background: var(--card); border: 1px solid var(--border); + border-radius: 8px; padding: 12px 14px; margin-bottom: 10px; } +.card.destructive { border-color: rgba(248, 113, 113, 0.4); } +.card.warning { border-color: rgba(250, 204, 21, 0.4); } +.card.success { border-color: rgba(74,222,128,0.3); background: rgba(74,222,128,0.05); } +.row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; } +.badge { padding: 1px 6px; border: 1px solid var(--border); + border-radius: 4px; font-size: 10px; display: inline-flex; + align-items: center; gap: 4px; } +.badge.success { border-color: rgba(74,222,128,0.4); background: rgba(74,222,128,0.1); color: var(--success); } +.badge.warning { border-color: rgba(250,204,21,0.4); background: rgba(250,204,21,0.1); color: var(--warning); } +.btn { padding: 5px 12px; font-size: 11px; border: 1px solid var(--border); + background: transparent; color: var(--fg); border-radius: 6px; cursor: pointer; + display: inline-flex; align-items: center; gap: 4px; } +.btn.primary { border-color: var(--primary); background: var(--primary); color: #001; } +.btn.destructive { border-color: var(--destructive); color: var(--destructive); background: rgba(248,113,113,0.08); } +.btn.outlined { border-color: var(--border); } +.input, .textarea { width: 100%; padding: 4px 8px; font-size: 11px; + border: 1px solid var(--border); border-radius: 4px; + background: var(--card); color: var(--fg); + font-family: ui-monospace, monospace; } +.input.error, .textarea.error { border-color: rgba(248,113,113,0.6); } +.textarea { min-height: 44px; resize: vertical; } +.label-tiny { font-size: 9px; color: var(--muted); text-transform: uppercase; + letter-spacing: 0.04em; margin-bottom: 2px; display: block; } +.field-error { font-size: 10px; color: var(--destructive); font-style: italic; margin-top: 2px; } +.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; } +.page-header { display: flex; justify-content: space-between; gap: 12px; + align-items: flex-start; margin-bottom: 14px; flex-wrap: wrap; } +.page-header .title { font-size: 18px; font-weight: 600; } +.page-header .desc { font-size: 12px; color: var(--muted); max-width: 600px; margin-top: 4px; } +.preview-result { padding: 6px 8px; border-radius: 6px; border: 1px solid; font-size: 11px; } +.preview-result.success { border-color: rgba(74,222,128,0.4); background: rgba(74,222,128,0.05); } +.preview-render { padding: 6px 8px; background: rgba(0,0,0,0.3); border: 1px solid var(--border); + border-radius: 4px; font-family: ui-monospace, monospace; font-size: 11px; + margin-top: 4px; white-space: pre-wrap; } +.modal-mock { padding: 16px; border-radius: 8px; max-width: 720px; background: var(--card); + border: 1px solid var(--border); margin: 24px auto; box-shadow: 0 6px 32px rgba(0,0,0,0.5); } +.modal-mock .backup-row { padding: 8px; border: 1px solid var(--border); border-radius: 6px; + margin-bottom: 4px; display: flex; gap: 8px; align-items: center; font-size: 11px; } +.modal-mock .backup-row.corrupt { opacity: 0.5; } diff --git a/web/docs/phrasebook-editor/edit_mode.html b/web/docs/phrasebook-editor/edit_mode.html new file mode 100644 index 000000000000..7b1ed87d637f --- /dev/null +++ b/web/docs/phrasebook-editor/edit_mode.html @@ -0,0 +1,106 @@ + +Edit mode + + +

Phrasebook editor — edit mode active

+

+ Operator clicked "Edit phrasebook". Entries become editable; live tester swaps to + client-side preview (mirrors dm_phrasebook match + render). Save / Cancel / Add entry + buttons appear above and below the entries list. +

+ + + +
+
+ Source: + 📝 operator override + /Users/Apple/.kora/phrasebook/slack_dm.yml +
+
+ +
+
↻ Preview against in-progress edits (client-side)
+
+ + +
+
+ ✓ Matched · category burn_query · $0 reply +
2.5% of monthly budget used. Tier: normal.
+
+
+ Mirrors dm_phrasebook.match_message + render_reply; preview uses in-progress edits, not the saved phrasebook. +
+
+ +
+ + + +
+ +
+
+
+
+ Pattern (Python regex, case-insensitive) + +
+
+ Category + +
+
+ Description + +
+
+ Reply template (supports {snapshot.X.Y} placeholders) + +
+
+ +
+
+ +
+
+
+
+ Pattern + +
+
+ Category + +
+
+ Description + +
+
+ Reply template + +
+
+ +
+
+ +
+ + + +
+ + diff --git a/web/docs/phrasebook-editor/edit_mode.png b/web/docs/phrasebook-editor/edit_mode.png new file mode 100644 index 0000000000000000000000000000000000000000..718c59fa78edcf71e16dfbdbf1aab076cca40ade GIT binary patch literal 102227 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Ø%6o5NQ9- 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 MOf1h+&t19o8*iCT4*&oF literal 0 HcmV?d00001 diff --git a/web/docs/phrasebook-editor/preview.html b/web/docs/phrasebook-editor/preview.html new file mode 100644 index 000000000000..d6fb85d7bbc1 --- /dev/null +++ b/web/docs/phrasebook-editor/preview.html @@ -0,0 +1,313 @@ + + + + + + Kora — PhrasebookEditor flows (KR-FE-PHRASEBOOK-EDITOR-AND-CRUD) + + + + + +

Phrasebook editor — state 1: edit mode active

+

+ Operator clicked "Edit phrasebook". Entries become editable; live tester swaps to + client-side preview (mirrors dm_phrasebook match + render). Save / Cancel / Add entry buttons appear. +

+ + + + +
+
+ Source: + 📝 operator override + /Users/Apple/.kora/phrasebook/slack_dm.yml +
+
+ + +
+
↻ Preview against in-progress edits (client-side)
+
+ + +
+
+ ✓ Matched · category burn_query · $0 reply +
2.5% of monthly budget used. Tier: normal.
+
+
+ Mirrors dm_phrasebook.match_message + render_reply; preview uses in-progress edits, not the saved phrasebook. +
+
+ + +
+ + + +
+ + +
+
+
+
+ Pattern (Python regex, case-insensitive) + +
+
+ Category + +
+
+ Description + +
+
+ Reply template (supports {snapshot.X.Y} placeholders) + +
+
+ +
+
+ +
+
+
+
+ Pattern + +
+
+ Category + +
+
+ Description + +
+
+ Reply template + +
+
+ +
+
+ +
+ + +

Phrasebook editor — state 2: validation error (422)

+

+ Operator clicked Save with a bad regex + an unknown snapshot path. Server returned 422 with structured + per-entry errors; FE renders each next to the offending field. Top-level errors render at the top. +

+ +
+
+ ⚠ 1 top-level error: +
+
+ • duplicate (pattern, category) — already declared at index 0 +
+
+ +
+ + + +
+ + +
+
+
+
+ Pattern (Python regex) + +
invalid regex: missing ), unterminated subpattern at position 0
+
+
+ Category + +
+
+ Description + +
+
+ Reply template + +
+
+ +
+
+ + +
+
+
+
+ Pattern + +
+
+ Category + +
+
+ Description + +
+
+ Reply template + +
snapshot path 'totally.not.a.real.field' not in known scalar schema (see SNAPSHOT_SCALAR_PATHS)
+
+
+ +
+
+ +
+ + +

Phrasebook editor — state 3: backups + revert dialog

+

+ Operator clicked "Backups". Modal shows newest-first list; per-row Revert with confirm. Corrupt + backups (entry_count null) are greyed out. Bottom note explains revert semantics. +

+ + + + + + + diff --git a/web/docs/phrasebook-editor/revert.html b/web/docs/phrasebook-editor/revert.html new file mode 100644 index 000000000000..acc852e043c6 --- /dev/null +++ b/web/docs/phrasebook-editor/revert.html @@ -0,0 +1,65 @@ + +Revert dialog + + +

Phrasebook editor — backups + revert dialog

+

+ Operator clicked "Backups". Modal shows newest-first list; per-row Revert with confirm. Corrupt + backups (entry_count null) are greyed out and Revert is disabled. Bottom note explains revert + semantics. +

+ + + + + + diff --git a/web/docs/phrasebook-editor/revert.png b/web/docs/phrasebook-editor/revert.png new file mode 100644 index 0000000000000000000000000000000000000000..a35f30bd0f873a69235a7320f2b478ad771d67f5 GIT binary patch literal 66367 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 +Validation error + + +

Phrasebook editor — validation error (422)

+

+ Operator clicked Save with a bad regex + an unknown snapshot path + a duplicate (pattern, category) + pair. Server returned 422 with structured per-entry errors; FE renders each next to the offending field. + Top-level errors (e.g. duplicates) render at the top. +

+ +
+
+ ⚠ 1 top-level error: +
+
+ • duplicate (pattern, category) — already declared at index 0 +
+
+ +
+ + + +
+ +
+
+
+
+ Pattern (Python regex) + +
invalid regex: missing ), unterminated subpattern at position 0
+
+
+ Category + +
+
+ Description + +
+
+ Reply template + +
+
+ +
+
+ +
+
+
+
+ Pattern + +
+
+ Category + +
+
+ Description + +
+
+ Reply template + +
snapshot path 'totally.not.a.real.field' not in known scalar schema (see SNAPSHOT_SCALAR_PATHS in kora_cli/short_circuit/phrasebook_editor.py)
+
+
+ +
+
+ +
+
+
+
+ Pattern + +
nested unbounded quantifier (possible catastrophic backtracking) — rewrite to use bounded counts or anchored alternations
+
+
+ Category + +
+
+ Description + +
required field 'description' missing or empty
+
+
+ Reply template + +
+
+ +
+
+ + diff --git a/web/docs/phrasebook-editor/validation.png b/web/docs/phrasebook-editor/validation.png new file mode 100644 index 0000000000000000000000000000000000000000..f94a8c987daca629289d41cdf08b4e5c2e5a284d GIT binary patch literal 83550 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 literal 0 HcmV?d00001 diff --git a/web/src/lib/api.ts b/web/src/lib/api.ts index 7bf0fef110a2..8f1e3abe82a1 100644 --- a/web/src/lib/api.ts +++ b/web/src/lib/api.ts @@ -154,6 +154,27 @@ export const api = { headers: { "Content-Type": "application/json" }, body: JSON.stringify({ text }), }), + // KR-FE-PHRASEBOOK-EDITOR-AND-CRUD — write path (PUT + revert + // + backups list). Server returns 422 with per-entry errors + // when validation fails; fetchJSON throws on 422, callers + // catch + parse the JSON body for the structured errors. + putSlackDmPhrasebook: (entries: PhrasebookEntryWrite[]) => + fetchJSON("/api/phrasebook/slack_dm", { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ entries }), + }), + revertSlackDmPhrasebook: (filename?: string | null) => + fetchJSON( + "/api/phrasebook/slack_dm/revert", + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(filename ? { filename } : {}), + }, + ), + getSlackDmPhrasebookBackups: () => + fetchJSON("/api/phrasebook/slack_dm/backups"), // KR-FE-PROBE-INVESTIGATION-VIEWER: joined wake → reasoning → DM // xref panel. Window: 24h | 7d | all. limit: 1-200 (server caps). getProbeInvestigations: (opts?: { @@ -1956,6 +1977,64 @@ export type PhrasebookTestResponse = snapshot_present: boolean; }; +// KR-FE-PHRASEBOOK-EDITOR-AND-CRUD — write-path types. +// The PUT request body's per-entry shape (operator's draft — +// `referenced_snapshot_fields` is derived server-side and not +// part of the write). +export interface PhrasebookEntryWrite { + pattern: string; + category: string; + description: string; + reply_template: string; +} + +// PUT response: echoes the saved entries + reports backup + +// rotation outcome so the cockpit can refresh local state from +// the response without a follow-up GET. +export interface PhrasebookPutResponse { + source_path: string; + entry_count: number; + backup_filename: string | null; + rotated_backup_count: number; + entries: PhrasebookEntryDto[]; +} + +// PUT 422 body — when validation fails, server returns this +// structured shape per offending field. The cockpit unmarshals +// it from the thrown fetchJSON error to render per-row errors. +export interface PhrasebookValidationErrorEntry { + entry_index: number; // -1 for root-level errors + field: string; // field name or "_root" + error: string; +} + +export interface PhrasebookValidationErrorBody { + error: "validation_failed"; + errors: PhrasebookValidationErrorEntry[]; +} + +// POST /revert response. reverted_to is the backup filename +// restored, OR the literal "bundled_default" when no backup +// existed (override was removed so the live handler falls back +// to the bundled phrasebook). +export interface PhrasebookRevertResponse { + reverted_to: string; + source_path: string | null; +} + +// GET /backups list item. +export interface PhrasebookBackupItem { + filename: string; // "slack_dm.YYYY-MM-DDTHH-MM-SSZ.yml" + timestamp: string; // ISO-like, dashes-only (filename-safe) + size_bytes: number; + entry_count: number | null; // null when backup can't be parsed +} + +export interface PhrasebookBackupsResponse { + backups: PhrasebookBackupItem[]; + rotation_keep: number; +} + // KR-FE-PROBE-INVESTIGATION-VIEWER — joined wake event + downstream // reasoning + current health. Source-of-truth shape pinned by the // backend endpoint at /api/probe-investigations. diff --git a/web/src/pages/PhrasebookEditor.tsx b/web/src/pages/PhrasebookEditor.tsx new file mode 100644 index 000000000000..7d014f7aedf1 --- /dev/null +++ b/web/src/pages/PhrasebookEditor.tsx @@ -0,0 +1,639 @@ +// KR-FE-PHRASEBOOK-EDITOR-AND-CRUD — editor UI for the operator. +// +// Hosts components that PhrasebookPage delegates to in edit mode: +// +// * EntryEditorRow — one editable row (4 inputs + delete button) +// * EditModeControls — Save / Cancel / Add Entry buttons +// * BackupsDialog — modal for revert flow +// * ClientSidePreview — simulates the live tester against +// in-progress edits (so operator can preview before saving) +// +// Validation feedback shape mirrors the backend's +// PhrasebookValidationErrorEntry: per-(entry_index, field) error +// messages rendered inline next to the offending input. Root +// errors (entry_index = -1) render at the top of the editor. +// +// Client-side preview implements just enough of dm_phrasebook's +// match + render_reply semantics to give an accurate preview — +// regex.test() (case-insensitive) + walkSnapshotField (mirrors +// _walk_snapshot). Pinned by tests that this matches the backend. + +import { useCallback, useMemo, useState } from "react"; +import { + AlertTriangle, + CheckCircle2, + ChevronDown, + History, + Plus, + RefreshCw, + Save, + Trash2, + X, + XCircle, +} from "lucide-react"; +import { Badge } from "@nous-research/ui/ui/components/badge"; +import { Button } from "@nous-research/ui/ui/components/button"; +import { Spinner } from "@nous-research/ui/ui/components/spinner"; +import { Card, CardContent } from "@/components/ui/card"; +import type { + PhrasebookBackupItem, + PhrasebookEntryWrite, + PhrasebookValidationErrorEntry, + SnapshotResponse, +} from "@/lib/api"; + +// EditableEntry adds a stable per-row React key. The id is +// generated client-side (crypto.randomUUID) so adding rows in +// edit mode doesn't collide with array indices on re-renders. +export interface EditableEntry extends PhrasebookEntryWrite { + _localId: string; +} + +export function makeEmptyEntry(): EditableEntry { + return { + _localId: crypto.randomUUID(), + pattern: "", + category: "", + description: "", + reply_template: "", + }; +} + +export function toEditableEntries( + entries: PhrasebookEntryWrite[], +): EditableEntry[] { + return entries.map((e) => ({ + _localId: crypto.randomUUID(), + pattern: e.pattern, + category: e.category, + description: e.description, + reply_template: e.reply_template, + })); +} + +// --------------------------------------------------------------- +// Per-row editor +// --------------------------------------------------------------- + +interface EntryEditorRowProps { + entry: EditableEntry; + index: number; + errors: PhrasebookValidationErrorEntry[]; + onChange: (next: EditableEntry) => void; + onDelete: () => void; +} + +function errorFor( + errors: PhrasebookValidationErrorEntry[], + index: number, + field: string, +): string | null { + const hit = errors.find( + (e) => e.entry_index === index && e.field === field, + ); + return hit ? hit.error : null; +} + +export function EntryEditorRow({ + entry, + index, + errors, + onChange, + onDelete, +}: EntryEditorRowProps) { + const patternErr = errorFor(errors, index, "pattern"); + const categoryErr = errorFor(errors, index, "category"); + const descriptionErr = errorFor(errors, index, "description"); + const replyErr = errorFor(errors, index, "reply_template"); + const rootErr = errorFor(errors, index, "_root"); + + return ( + + +

+
+ onChange({ ...entry, pattern: v })} + error={patternErr} + mono + /> + onChange({ ...entry, category: v })} + error={categoryErr} + /> + onChange({ ...entry, description: v })} + error={descriptionErr} + /> + + onChange({ ...entry, reply_template: v }) + } + error={replyErr} + mono + textarea + /> +
+ +
+ {rootErr && ( +
+ + {rootErr} +
+ )} + + + ); +} + +interface FieldEditorProps { + label: string; + value: string; + onChange: (v: string) => void; + error: string | null; + mono?: boolean; + textarea?: boolean; +} + +function FieldEditor({ + label, + value, + onChange, + error, + mono, + textarea, +}: FieldEditorProps) { + const baseInputClass = `w-full px-2 py-1 text-xs rounded border bg-card ${ + mono ? "font-mono" : "" + } ${ + error + ? "border-destructive/60 focus:outline-destructive" + : "border-border focus:outline-primary" + }`; + return ( +