Doctrine: die Leitung steuert ihre Einheit, ohne jeden Auftragstext anzufassen (#698)
- SqliteDoctrineStore: je Einheit versioniert (Tabelle Doctrines: Text, Autor, Lauf, Grund),
hoechstens 2000 Zeichen, leer entfernt; im Speicher gehalten fuer jeden Lauf
- OrgBriefing: die Doctrine der eigenen Einheit, nur eine Ebene tief, mit dem Satz,
dass ein Widerspruch zur Aufgabe eskaliert wird; Leitungen erfahren doctrine_set
- Escalation: doctrine_read, doctrine_set (nur die Leitung, Grund Pflicht)
- IAgentTool.Vorgabe(operation, context): Einstufung mit dem Aufrufkontext; eine Leitung
der Fremdinhalt-Stufe legt doctrine_set zur Freigabe vor
- API GET/PUT /organisation/units/{id}/doctrine; WebUI-Karte mit Verlauf und Markierung
haeufiger Aenderungen; i18n en/de
- Tests: DoctrineTests (5)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c608af1abb
commit
679333b382
@@ -100,6 +100,11 @@
|
||||
"org.approvalsOperations": "Operationen",
|
||||
"org.approvalsPerDay": "Höchstens je Tag",
|
||||
"org.approvalsHours": "Stunden je Freigabe",
|
||||
"org.doctrine": "Doktrin",
|
||||
"org.doctrineHint": "Was in dieser Einheit gerade gilt — Rahmen für jede Aufgabe ihrer Mitglieder, von ihrer Leitung ohne Rückfrage gesetzt. Sie erreicht nur die Mitglieder dieser Einheit, nicht die Untereinheiten; die haben ihre eigene. Kurz halten: Sie geht in jeden Lauf. Leer entfernt sie.",
|
||||
"org.doctrinePlaceholder": "Jeder Lieferantenkontakt wird in der Datenbank erfasst, bevor er weitergegeben wird.",
|
||||
"org.doctrineFrequent": "In den letzten 7 Tagen {count}-mal geändert — eine Doktrin, die oft wechselt, ist Mikromanagement mit Tokenkosten.",
|
||||
"org.doctrineRemoved": "(entfernt)",
|
||||
"org.ceilingInherited": "Von oben begrenzt auf: {tools}",
|
||||
"org.settings": "Sammelwerte",
|
||||
"org.settingsHint": "Werden nach einer Vorschau in die Agenten geschrieben. Die Einheit merkt sich den Wert nur als Vorgabe für neue Mitglieder — zur Laufzeit übertrumpft nichts einen Agenten.",
|
||||
|
||||
@@ -100,6 +100,11 @@
|
||||
"org.approvalsOperations": "Operations",
|
||||
"org.approvalsPerDay": "Per day at most",
|
||||
"org.approvalsHours": "Hours per approval",
|
||||
"org.doctrine": "Doctrine",
|
||||
"org.doctrineHint": "What holds in this unit now — a frame for every task of its members, set by its lead without asking. It reaches this unit's members only, not the sub-units; they have their own. Short: it goes into every run. Empty removes it.",
|
||||
"org.doctrinePlaceholder": "Every supplier contact is entered in the database before it is passed on.",
|
||||
"org.doctrineFrequent": "Changed {count} times in the last 7 days — a doctrine that changes often is micro-management with token costs.",
|
||||
"org.doctrineRemoved": "(removed)",
|
||||
"org.ceilingInherited": "Limited from above to: {tools}",
|
||||
"org.settings": "Unit-wide values",
|
||||
"org.settingsHint": "Written into the agents after a preview. The unit keeps the value only as a default for new members — nothing overrides an agent at run time.",
|
||||
|
||||
@@ -367,6 +367,7 @@ function unitPanel(unit) {
|
||||
cards.push(unitWorkspaceCard(unit));
|
||||
cards.push(ceilingCard(unit));
|
||||
cards.push(approvalsCard(unit));
|
||||
cards.push(doctrineCard(unit));
|
||||
cards.push(settingsCard(unit));
|
||||
|
||||
// Members.
|
||||
@@ -462,6 +463,46 @@ function approvalsCard(unit) {
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* #698: What holds in the unit now — set by its lead, readable and settable here. It reaches
|
||||
* the unit's members only, not the sub-units. Every version stays; frequent changes are marked,
|
||||
* because a doctrine that changes weekly is micro-management with token costs.
|
||||
*/
|
||||
function doctrineCard(unit) {
|
||||
const text = erstelleElement("textarea", { rows: 5, maxlength: "2000", placeholder: t("org.doctrinePlaceholder") });
|
||||
const history = erstelleElement("div", { klasse: "org-doktrin-verlauf" });
|
||||
const counter = erstelleElement("span", { klasse: "gedaempft text-klein" });
|
||||
const sync = () => { counter.textContent = `${text.value.length} / 2000`; };
|
||||
text.addEventListener("input", sync);
|
||||
|
||||
(async () => {
|
||||
let versions = [];
|
||||
try { versions = await api(`/organisation/units/${encodeURIComponent(unit.id)}/doctrine`); } catch { versions = []; }
|
||||
text.value = versions[0]?.text ?? "";
|
||||
sync();
|
||||
const weekAgo = Date.now() - 7 * 24 * 3600 * 1000;
|
||||
const recent = versions.filter((v) => new Date(v.setAt).getTime() >= weekAgo).length;
|
||||
if (recent >= 3) history.append(erstelleElement("p", { klasse: "hinweis-box warnung", text: t("org.doctrineFrequent", { count: recent }) }));
|
||||
for (const v of versions.slice(0, 10)) {
|
||||
history.append(erstelleElement("details", { klasse: "org-doktrin-version" },
|
||||
erstelleElement("summary", { text: `v${v.version} · ${v.setBy === "human" ? t("cases.humanAuthor") : v.setBy} · ${formatiereDatumZeit(v.setAt)}${v.reason ? " · " + v.reason : ""}` }),
|
||||
erstelleElement("pre", { klasse: "code-block", text: v.text || t("org.doctrineRemoved") })));
|
||||
}
|
||||
})();
|
||||
|
||||
return erstelleKarte(t("org.doctrine"), [
|
||||
erstelleElement("p", { klasse: "gedaempft text-klein", text: t("org.doctrineHint") }),
|
||||
text,
|
||||
erstelleElement("div", { klasse: "gruppe-horizontal" },
|
||||
counter,
|
||||
erstelleElement("button", {
|
||||
type: "button", klasse: "klein", text: t("common.save"),
|
||||
onclick: () => send(`/organisation/units/${encodeURIComponent(unit.id)}/doctrine`, "PUT", { text: text.value, reason: reason() })
|
||||
})),
|
||||
history
|
||||
]);
|
||||
}
|
||||
|
||||
function settingsCard(unit) {
|
||||
const setting = erstelleElement("select", {},
|
||||
...SETTINGS.map((s) => erstelleElement("option", { value: s, text: t(`org.setting.${s}`) })));
|
||||
|
||||
Reference in New Issue
Block a user