// Page 5 — Agents Instructions function InstructionsPage({ pushToast }) { const [activeRole, setActiveRole] = useState("coder"); const [proposalOpen, setProposalOpen] = useState(false); const [proposal, setProposal] = useState({ pt: "", quote: "", suggestion: "", reason: "" }); const agent = TEAM.find(t => t.role === activeRole); const doc = AGENT_DOCS[activeRole] || ""; // Calculate which points have active rules / recent alerts const highlights = useMemo(() => { const h = {}; // Map rules to points by claudeMdRef RULES.forEach((r) => { if (r.role !== activeRole && r.role !== "any") return; // Extract "§ 3.1" or "§ 3" or "§ 5" const m = r.claudeMdRef.match(/§\s+([\d.]+)/); if (m) h[m[1]] = "active"; }); // Alerts in last 24h ALERTS.forEach((a) => { const m = a.claudeMdRef.match(/agents\/([\w-]+)\/CLAUDE.md\s*§\s+([\d.]+)/); if (m && m[1] === activeRole) h[m[2]] = "alert"; }); return h; }, [activeRole]); const rulesForRole = RULES.filter(r => r.role === activeRole || r.role === "any"); const alertsForRole = ALERTS.filter(a => { const m = a.claudeMdRef.match(/agents\/([\w-]+)\/CLAUDE.md/); return m && m[1] === activeRole; }); const openProposal = (pt) => { // Extract a snippet of text for pt const lines = doc.split("\n"); let quote = ""; let collecting = false; let captured = []; for (const ln of lines) { if (ln.startsWith("##") || ln.startsWith("###")) { const m = ln.match(/(\d+(?:\.\d+)?)/); if (m && m[1] === pt) { collecting = true; continue; } else if (collecting) break; } if (collecting) captured.push(ln); } quote = captured.join("\n").trim().slice(0, 400); setProposal({ pt, quote, suggestion: quote, reason: "" }); setProposalOpen(true); }; return (

Инструкции агентов

Read-only: agents/<role>/CLAUDE.md. Зелёным — пункты, на которые ссылается активное правило. Жёлтым — пункты, по которым недавно сработал алерт.
{/* Left — role list */}

Роли

{TEAM.map((t) => ( ))}
{/* Center — markdown */}

agents / {activeRole} / CLAUDE.md

read-only
правило активно алерт за 24ч
{/* Right — bindings + propose */}

Связи правило ↔ пункт

{rulesForRole.length === 0 ? (
Нет правил.
) : rulesForRole.map((r) => { const ptMatch = r.claudeMdRef.match(/§\s+([\d.]+)/); const pt = ptMatch ? ptMatch[1] : "?"; const hadAlert = highlights[pt] === "alert"; return (
{hadAlert && сработал}
{r.name}
→ § {pt}
); })}

Алерты за 24ч

{alertsForRole.length === 0 ? (
Нет.
) : alertsForRole.map((a) => (
PB-{a.seq}
{a.ruleTitle}
{fmtAgo(a.ts)}
))}
setProposalOpen(false)} title={`Предложить правку — § ${proposal.pt}`}>
Текущая версия
{proposal.quote}
Предложенная версия