feat(ia): IA גל-2 — איחוד-משטחים: ערוץ-למידה אחד · /operations⊇/diagnostics · MET-2/3 (#131, X17)
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 9s
All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 9s
גל-2 מבקלוג #127 — איחוד-משטחים לפי משטח-היעד של X17. מקיים INV-IA1/IA3/IA4 + דלתות-הספ (X6 INV-UI7/8, 07-learning §0.4, 00-constitution G2). שומר G10/INV-LRN1 (לא הוסר שום שער-אנושי — רק שער/דגל כפול). א) תיבת-אישור אחת (INV-IA1): כרטיסי "אישור הלכות"+"פסיקה חסרה" ב-/operations מצביעים ל-/approvals (לתיבת-האישורים ←) — /operations מנטר, /approvals מחליט. ב) ערוץ-למידה אחד (INV-IA3): הוסר applied_to_skill end-to-end — - UI: כפתור "סמן כ'אומץ'" + badge "אומץ" ב-lessons-tab; badge ב-curator-portrait. - API: LessonPatch, _lesson_to_json, patch call, curator recent_findings (→review_status). - db.py: list/add/update_decision_lesson לא בוחרים/כותבים applied_to_skill; הפרמטר הוסר. העמודה+אינדקס נשמרים (back-compat, ללא migration), מסומנים DEPRECATED. - types: DecisionLesson/LessonPatch/CuratorFinding. review_status='approved' = הסטטוס היחיד "זורם-לכותב" (INV-LRN1, #126). ג) MET-2/3 lost-update (INV-IA3): _append_methodology_override רץ עכשיו בטרנזקציה אחת עם SELECT ... FOR UPDATE — אין read-modify-write מתפצל מול עורך-המתודולוגיה או promote מקביל. /methodology = העורך-הקנוני; promote מבטל את ה-cache (גל-1 MET-1). ד) /operations⊇/diagnostics (INV-IA4): גוף /diagnostics חולץ ל-<SystemHealthSection/> ומורנדר ב-/operations תחת "בריאות-מערכת". /diagnostics → redirect ל-/operations. /diagnostics הוסר מהניווט. משטח-ניטור יחיד. ה) דלתות-ספ (≥3 מקורות ב-X17, אושר ע"י חיים /goal): - X6: INV-UI7 (aggregate=SSoT, mutation מבטל queryKey) + INV-UI8 (render-or-remove, חלקיות). - 07-learning §0.4: שער-אחד + טרנזקציה-אחת + applied_to_skill מוסר. - 00-constitution G2: תאום-המתודולוגיה כהפרה-ידועה-ממותנת. - X17 דלתות-ספ סומנו ✅ קודדו. בדיקות: py_compile app.py + db.py ✓ · tsc --noEmit ✓ · eslint ✓ (לבד מ-learning-panel:109 קיים-מראש). next build נכשל ב-worktree רק בגלל symlink (Turbopack) — Docker/CI תקין. api:types יתרענן בדפלוי (curator/lessons אינם response-modeled; הטיפוסים יד-כתובים עודכנו). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -149,11 +149,11 @@ function RecentFindings() {
|
||||
<span className="text-navy font-semibold tabular-nums">
|
||||
{f.decision_number || "—"}
|
||||
</span>
|
||||
{f.applied_to_skill && (
|
||||
{f.review_status === "approved" && (
|
||||
<Badge variant="outline"
|
||||
className="bg-success-bg text-success border-success/40">
|
||||
<CheckCircle2 className="w-3 h-3 me-0.5" />
|
||||
אומץ
|
||||
מאושר
|
||||
</Badge>
|
||||
)}
|
||||
<span className="grow text-ink-muted text-end">
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
* The chair can:
|
||||
* - Add a lesson typed manually (category = "general" by default)
|
||||
* - Edit / delete existing lessons
|
||||
* - Mark a lesson as "applied_to_skill" (informational — doesn't
|
||||
* auto-commit anything to SKILL.md; chair still curates that file
|
||||
* manually in git).
|
||||
* - Approve / reject a lesson (review_status — INV-LRN1/G10): only an
|
||||
* approved lesson flows to the writer. This is the SINGLE writer gate;
|
||||
* the old informative-only applied_to_skill flag was removed (LRN-1/INV-IA3).
|
||||
*
|
||||
* Lessons from the curator arrive with source="curator" and are visually
|
||||
* distinguished by a badge so the chair can audit auto-suggestions.
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Plus, Save, Trash2, Loader2, CheckCircle2, Sparkles, Check, X, Undo2,
|
||||
Plus, Save, Trash2, Loader2, Check, X, Undo2,
|
||||
} from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -191,17 +191,6 @@ function LessonItem({
|
||||
}
|
||||
};
|
||||
|
||||
const onToggleApplied = async () => {
|
||||
try {
|
||||
await patch.mutateAsync({
|
||||
id: lesson.id,
|
||||
patch: { applied_to_skill: !lesson.applied_to_skill },
|
||||
});
|
||||
} catch (e) {
|
||||
toast.error(e instanceof Error ? e.message : "כשל בעדכון");
|
||||
}
|
||||
};
|
||||
|
||||
const onDelete = async () => {
|
||||
if (!window.confirm("למחוק את הלקח?")) return;
|
||||
try {
|
||||
@@ -226,13 +215,6 @@ function LessonItem({
|
||||
<Badge variant="outline" className={reviewBadge.cls}>
|
||||
{reviewBadge.label}
|
||||
</Badge>
|
||||
{lesson.applied_to_skill && (
|
||||
<Badge variant="outline"
|
||||
className="bg-success-bg text-success border-success/40">
|
||||
<CheckCircle2 className="w-3 h-3 me-1" />
|
||||
אומץ
|
||||
</Badge>
|
||||
)}
|
||||
<span className="grow text-ink-muted tabular-nums">
|
||||
{new Date(lesson.created_at).toLocaleDateString("he-IL")}
|
||||
</span>
|
||||
@@ -307,11 +289,6 @@ function LessonItem({
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<Button variant="ghost" size="sm" onClick={onToggleApplied}
|
||||
disabled={patch.isPending}>
|
||||
<Sparkles className="w-3 h-3 me-1" />
|
||||
{lesson.applied_to_skill ? "בטל סימון 'אומץ'" : "סמן כ'אומץ ל-SKILL'"}
|
||||
</Button>
|
||||
<Button variant="ghost" size="sm" onClick={() => setEditing(true)}>
|
||||
ערוך
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user