fix(constitution): ratify checks what you reviewed; preview and wording say what happens

Session-export review of /constitution. Each item was read on both sides
before changing it.

- ratify promised it would be "refused if the base changed after you
  reviewed it", but it re-read the live file and handed that same digest
  back, so the guard could never fire. `/constitution suggestions` now
  records the digest the user reviewed on `App`, and ratify passes that to
  `UserConstitution::ratify`. Ratify without a review says to review first.
  A ratify after the file moved is refused as StaleBase. The existing ratify
  test now reviews before it ratifies, and checks the unreviewed refusal.
- `preview` claimed to show "the exact block that would be injected", but
  rendered `source="<absolute home path>"`, while the engine injects
  `render_block(None)` (`source="user-global"`). It now renders the same
  block.
- ratify and migrate said the prompt-cache prefix "moved" or "survives".
  The constitution reaches the model as a session message appended at turn
  admission (`record_current_constitution`), outside the cached prefix, as
  prompts.rs's `user_global_constitution_is_captured_outside_the_stable_prefix`
  asserts. The messages now say so, and so does the user_constitution
  module doc. The migrate test checks the new wording.
- The setup wizard printed the assembly order (bundled → user-global → repo
  → AGENTS → memory → current request) under "HIERARCHY OF AUTHORITY".
  That reverses the base prompt's ranking, which says it "is stated here
  and nowhere else". The line is removed from all 15 locale templates, and
  so is the now-unused SetupCheckpointLayerOrder message. "Your direct
  requests always outrank this document" stays.
- The wizard capped the user's own note at 4000 characters, then appended
  it to a ~300-character template. save_to then trimmed the total to 4000,
  silently cutting off the end of the user's own text. The note is now
  capped at MAX_NOTES_LEN - 1000 while typing, so the saved file keeps all
  of it. The longest template is 335 characters before labels.
- zh-Hans used 协作准则 in the /constitution manager and 宪章 (the
  docs/zh_hans/GLOSSARY.md term) elsewhere, sometimes on the same screen.
  It now uses 宪章 throughout, including the model-draft status line.
- The help usage line and docs/CONFIGURATION.md now list base,
  suggestions, ratify, migrate and rollback. The step is named "Working
  agreement" as the wizard shows it. docs/GUIDE.md no longer calls
  /constitution a way to customize the bundled layer.

Not changed here:
- A signed-in user still sees the local file as "active", although the
  account profile is what the model gets. The fix needs an async account
  check, because the credential store must not be read on the UI loop.
- The Runtime API's GET and preview `modelGuidance` shapes differ.
- `doctor` reports autonomy from an inactive file.
- The context inspector lists the personal constitution as a system-prompt
  layer.

Evidence: cargo fmt --all -- --check is clean, and every edited locale file
parses as JSON. The compile and the commands::core::constitution tests are
pending a local test build and hosted CI on codewhale-hq/Codewhale#6957.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
This commit is contained in:
Claude committed 2026-10-11 12:55:08 +00:00
1 parent 674dcc364d
commit e71255e2b5
24 files changed
+128 -118

No files matched your search

+5 -4
View File
@@ -43,10 +43,11 @@
//! silently. [`UserConstitution::migrate_file`] writes a backup first so
//! [`UserConstitution::rollback_file`] can restore the pre-migration bytes.
//! - **The prompt projection is byte-stable.**
//! [`UserConstitution::cache_projection`] returns exactly the bytes that enter
//! the cache-stable prompt prefix plus their digest and measures. Suggested
//! clauses, preserved unknown fields, and schema metadata are all outside it,
//! so recording advice never invalidates a prompt cache.
//! [`UserConstitution::cache_projection`] returns exactly the bytes the model
//! receives (as a session message at turn admission, outside the cache-stable
//! prompt prefix) plus their digest and measures. Suggested clauses,
//! preserved unknown fields, and schema metadata are all outside it, so
//! recording advice never changes what the model receives.
use std::collections::BTreeMap;
use std::fmt::Write;
-1
View File
@@ -1019,7 +1019,6 @@
"SetupStepConstitutionWhy": "Aquest acord guia el comportament, no els permisos d'execució.",
"SetupStepVerificationTitle": "Revisió",
"SetupStepVerificationWhy": "Resumeix l'estat de Setup i mostra quins passos estan verificats, omesos o encara calen acció.",
"SetupCheckpointLayerOrder": "Ordre de capes: constitució inclosa -> constitució global d'usuari -> constitució del repo -> instruccions AGENTS/del projecte -> memòria/handoff -> petició actual.",
"SetupCheckpointDoneBundled": "Punt de control de la constitució complet: s'usa la llei inclosa/per defecte.",
"SetupCheckpointDoneGuided": "Constitució ratificada — la teva llei permanent s'ha desat. Esmena-la en qualsevol moment amb /constitution.",
"SetupCheckpointDoneKept": "Constitució conservada — la teva llei existent continua vigent, sense canvis. Esmena-la en qualsevol moment amb /constitution.",
-1
View File
@@ -1019,7 +1019,6 @@
"SetupStepConstitutionWhy": "Diese Vereinbarung lenkt das Verhalten, nicht die Laufzeitberechtigungen.",
"SetupStepVerificationTitle": "Überprüfung",
"SetupStepVerificationWhy": "Fasst den Setup-Status zusammen und zeigt, welche Schritte verifiziert, übersprungen oder noch offen sind.",
"SetupCheckpointLayerOrder": "Ebenenreihenfolge: mitgelieferte Verfassung -> benutzer-globale Verfassung -> Repo-Verfassung -> AGENTS-/Projektanweisungen -> Memory/Handoff -> aktuelle Anfrage.",
"SetupCheckpointDoneBundled": "Verfassungs-Checkpoint abgeschlossen: mitgeliefertes/Standard-Recht wird verwendet.",
"SetupCheckpointDoneGuided": "Verfassung ratifiziert — dein geltendes Recht ist gespeichert. Jederzeit mit /constitution änderbar.",
"SetupCheckpointDoneKept": "Verfassung beibehalten — dein bestehendes Recht gilt unverändert. Jederzeit mit /constitution änderbar.",
-1
View File
@@ -1042,7 +1042,6 @@
"SetupStepConstitutionWhy": "This agreement guides behavior, not runtime permissions.",
"SetupStepVerificationTitle": "Review",
"SetupStepVerificationWhy": "Summarize setup status and show which steps are verified, skipped, or still need action.",
"SetupCheckpointLayerOrder": "Layer order: bundled Constitution -> user-global constitution -> repo constitution -> AGENTS/project instructions -> memory/handoff -> current request.",
"SetupCheckpointDoneBundled": "Constitution checkpoint complete: using bundled/default law.",
"SetupCheckpointDoneGuided": "Constitution ratified — your standing law is saved. Amend anytime with /constitution.",
"SetupCheckpointDoneKept": "Constitution kept — your existing law stands, unchanged. Amend anytime with /constitution.",
-1
View File
@@ -1042,7 +1042,6 @@
"SetupStepConstitutionWhy": "Este acuerdo guía el comportamiento, no los permisos de ejecución.",
"SetupStepVerificationTitle": "Revisión",
"SetupStepVerificationWhy": "Resume el estado del setup y muestra qué pasos están verificados, saltados o aún necesitan acción.",
"SetupCheckpointLayerOrder": "Orden de capas: Constitution incluida -> constitution global de usuario -> constitution del repo -> instrucciones AGENTS/proyecto -> memoria/handoff -> solicitud actual.",
"SetupCheckpointDoneBundled": "Checkpoint de constitution completo: usando ley incluida/predeterminada.",
"SetupCheckpointDoneGuided": "Constitution ratificada — tu ley permanente fue guardada. Puedes modificarla en cualquier momento con /constitution.",
"SetupCheckpointDoneKept": "Constitution conservada — tu ley existente queda sin cambios. Puedes modificarla en cualquier momento con /constitution.",
-1
View File
@@ -1019,7 +1019,6 @@
"SetupStepConstitutionWhy": "Cet accord guide le comportement, pas les permissions d'exécution.",
"SetupStepVerificationTitle": "Revue",
"SetupStepVerificationWhy": "Résume le statut du setup et montre quelles étapes sont vérifiées, ignorées ou demandent encore une action.",
"SetupCheckpointLayerOrder": "Ordre des couches : Constitution intégrée -> constitution globale utilisateur -> constitution du repo -> instructions AGENTS/projet -> mémoire/handoff -> demande actuelle.",
"SetupCheckpointDoneBundled": "Point de contrôle de la constitution terminé : loi intégrée/par défaut utilisée.",
"SetupCheckpointDoneGuided": "Constitution ratifiée — votre loi permanente est enregistrée. Amendez-la à tout moment avec /constitution.",
"SetupCheckpointDoneKept": "Constitution conservée — votre loi existante reste inchangée. Amendez-la à tout moment avec /constitution.",
-1
View File
@@ -1019,7 +1019,6 @@
"SetupStepConstitutionWhy": "यह समझौता व्यवहार का मार्गदर्शन करता है, रनटाइम अनुमतियों का नहीं।",
"SetupStepVerificationTitle": "समीक्षा",
"SetupStepVerificationWhy": "सेटअप स्थिति का सार दें और दिखाएँ कौन से चरण सत्यापित, छोड़े गए या कार्रवाई माँगते हैं।",
"SetupCheckpointLayerOrder": "परत क्रम: bundled संविधान -> उपयोगकर्ता-वैश्विक संविधान -> रिपो संविधान -> AGENTS/प्रोजेक्ट निर्देश -> मेमोरी/हैंडऑफ़ -> वर्तमान अनुरोध।",
"SetupCheckpointDoneBundled": "संविधान चेकपॉइंट पूर्ण: bundled/डिफ़ॉल्ट कानून उपयोग में।",
"SetupCheckpointDoneGuided": "संविधान अंगीकृत — आपका स्थायी कानून सहेजा गया। /constitution से कभी भी संशोधित करें।",
"SetupCheckpointDoneKept": "संविधान बरकरार — आपका मौजूदा कानून अपरिवर्तित रहा। /constitution से कभी भी संशोधित करें।",
-1
View File
@@ -1019,7 +1019,6 @@
"SetupStepConstitutionWhy": "Kesepakatan ini memandu perilaku, bukan izin runtime.",
"SetupStepVerificationTitle": "Tinjauan",
"SetupStepVerificationWhy": "Ringkas status penyiapan dan tunjukkan langkah mana yang terverifikasi, dilewati, atau masih perlu tindakan.",
"SetupCheckpointLayerOrder": "Urutan lapisan: Konstitusi bawaan -> konstitusi global pengguna -> konstitusi repo -> instruksi AGENTS/proyek -> memori/handoff -> permintaan saat ini.",
"SetupCheckpointDoneBundled": "Checkpoint konstitusi selesai: memakai hukum bawaan/default.",
"SetupCheckpointDoneGuided": "Konstitusi diratifikasi — hukum tetap Anda tersimpan. Amendemen kapan saja dengan /constitution.",
"SetupCheckpointDoneKept": "Konstitusi dipertahankan — hukum Anda yang ada tetap berlaku, tidak berubah. Amendemen kapan saja dengan /constitution.",
-1
View File
@@ -1042,7 +1042,6 @@
"SetupStepConstitutionWhy": "この作業合意は行動を導きますが、実行権限は変えません。",
"SetupStepVerificationTitle": "レビュー",
"SetupStepVerificationWhy": "セットアップ状態を要約し、確認済み、スキップ済み、または対応が必要なステップを表示します。",
"SetupCheckpointLayerOrder": "レイヤー順: 同梱 Constitution -> ユーザーグローバル constitution -> リポジトリ constitution -> AGENTS/プロジェクト指示 -> メモリ/引き継ぎ -> 現在の依頼。",
"SetupCheckpointDoneBundled": "Constitution チェックポイント完了: 同梱/既定のルールを使用します。",
"SetupCheckpointDoneGuided": "Constitution を承認しました。あなたの常設ルールを保存しました。いつでも /constitution で修正できます。",
"SetupCheckpointDoneKept": "Constitution を維持しました。既存のルールは変更されません。いつでも /constitution で修正できます。",
-1
View File
@@ -1042,7 +1042,6 @@
"SetupStepConstitutionWhy": "이 작업 합의는 행동을 안내할 뿐, 실행 권한을 바꾸지 않습니다.",
"SetupStepVerificationTitle": "검토",
"SetupStepVerificationWhy": "설정 상태를 요약하고 어떤 단계가 확인됨, 건너뜀, 또는 아직 조치가 필요한지 표시합니다.",
"SetupCheckpointLayerOrder": "계층 순서: 내장 헌법 -> 사용자 전역 헌법 -> 저장소 헌법 -> AGENTS/프로젝트 지침 -> 메모리/인계 -> 현재 요청.",
"SetupCheckpointDoneBundled": "헌법 체크포인트 완료: 내장/기본 규칙을 사용합니다.",
"SetupCheckpointDoneGuided": "헌법이 승인되었습니다 — 상시 규칙이 저장되었습니다. /constitution으로 언제든지 수정할 수 있습니다.",
"SetupCheckpointDoneKept": "헌법을 유지했습니다 — 기존 규칙이 변경 없이 그대로 적용됩니다. /constitution으로 언제든지 수정할 수 있습니다.",
-1
View File
@@ -1042,7 +1042,6 @@
"SetupStepConstitutionWhy": "Este acordo orienta o comportamento, não as permissões de execução.",
"SetupStepVerificationTitle": "Revisão",
"SetupStepVerificationWhy": "Resume o status do setup e mostra quais etapas estão verificadas, puladas ou ainda precisam de ação.",
"SetupCheckpointLayerOrder": "Ordem de camadas: Constitution embutida -> constitution global do usuário -> constitution do repo -> instruções AGENTS/projeto -> memória/handoff -> pedido atual.",
"SetupCheckpointDoneBundled": "Checkpoint da constitution completo: usando lei embutida/padrão.",
"SetupCheckpointDoneGuided": "Constitution ratificada — sua lei permanente foi salva. Altere a qualquer momento com /constitution.",
"SetupCheckpointDoneKept": "Constitution mantida — sua lei existente continua sem mudanças. Altere a qualquer momento com /constitution.",
-1
View File
@@ -1019,7 +1019,6 @@
"SetupStepConstitutionWhy": "Это соглашение направляет поведение, но не меняет разрешения среды выполнения.",
"SetupStepVerificationTitle": "Проверка",
"SetupStepVerificationWhy": "Сводка статуса настройки: какие шаги проверены, пропущены или ещё требуют действий.",
"SetupCheckpointLayerOrder": "Порядок слоёв: встроенная конституция -> глобальная конституция пользователя -> конституция репозитория -> инструкции AGENTS/проекта -> память/передача -> текущий запрос.",
"SetupCheckpointDoneBundled": "Контрольная точка конституции пройдена: используется встроенный закон по умолчанию.",
"SetupCheckpointDoneGuided": "Конституция утверждена — ваш постоянный закон сохранён. Изменить можно в любой момент через /constitution.",
"SetupCheckpointDoneKept": "Конституция сохранена — ваш текущий закон остаётся без изменений. Изменить можно в любой момент через /constitution.",
-1
View File
@@ -1019,7 +1019,6 @@
"SetupStepConstitutionWhy": "Ця угода спрямовує поведінку, але не змінює дозволи середовища виконання.",
"SetupStepVerificationTitle": "Огляд",
"SetupStepVerificationWhy": "Підсумуйте стан налаштування та подивіться, які кроки перевірено, пропущено або які ще потребують дій.",
"SetupCheckpointLayerOrder": "Порядок шарів: вбудована конституція -> глобальна конституція користувача -> конституція репозиторію -> інструкції AGENTS/проєкту -> пам'ять/передача -> поточний запит.",
"SetupCheckpointDoneBundled": "Контрольну точку конституції завершено: використовується вбудоване/типове право.",
"SetupCheckpointDoneGuided": "Конституцію ратифіковано — ваше чинне право збережено. Змінюйте будь-коли через /constitution.",
"SetupCheckpointDoneKept": "Конституцію залишено — ваше чинне право діє без змін. Змінюйте будь-коли через /constitution.",
-1
View File
@@ -1042,7 +1042,6 @@
"SetupStepConstitutionWhy": "Thỏa thuận này hướng dẫn hành vi, không đổi quyền thực thi.",
"SetupStepVerificationTitle": "Xem lại",
"SetupStepVerificationWhy": "Tóm tắt trạng thái setup và cho biết bước nào đã xác minh, đã bỏ qua hoặc còn cần hành động.",
"SetupCheckpointLayerOrder": "Thứ tự lớp: Constitution tích hợp -> constitution toàn cục của người dùng -> constitution repo -> chỉ dẫn AGENTS/dự án -> bộ nhớ/handoff -> yêu cầu hiện tại.",
"SetupCheckpointDoneBundled": "Checkpoint constitution hoàn tất: dùng luật tích hợp/mặc định.",
"SetupCheckpointDoneGuided": "Constitution đã được phê chuẩn — luật thường trực của bạn đã được lưu. Có thể sửa bất cứ lúc nào bằng /constitution.",
"SetupCheckpointDoneKept": "Constitution được giữ nguyên — luật hiện có không đổi. Có thể sửa bất cứ lúc nào bằng /constitution.",
-1
View File
@@ -1042,7 +1042,6 @@
"SetupStepConstitutionWhy": "此 Codewhale 宪章是工作约定,只指导行为,不会更改运行时权限。",
"SetupStepVerificationTitle": "复核",
"SetupStepVerificationWhy": "汇总设置状态,并显示哪些步骤已验证、已跳过或仍需操作。",
"SetupCheckpointLayerOrder": "层级顺序:内置基础宪章 -> 用户全局宪章 -> 仓库宪章 -> AGENTS/项目说明 -> 记忆/交接 -> 当前请求。",
"SetupCheckpointDoneBundled": "宪章检查点已完成:使用内置/默认宪章。",
"SetupCheckpointDoneGuided": "宪章已确认并保存。可随时用 /constitution 修改。",
"SetupCheckpointDoneKept": "已保留现有宪章,内容保持不变。可随时用 /constitution 修改。",
-1
View File
@@ -1040,7 +1040,6 @@
"SetupStepConstitutionWhy": "此工作約定只引導行為,不會更改執行權限。",
"SetupStepVerificationTitle": "檢視",
"SetupStepVerificationWhy": "總結設定狀態,並顯示哪些步驟已驗證、已略過或仍需操作。",
"SetupCheckpointLayerOrder": "層級順序:內建基礎憲章 -> 使用者全域憲章 -> 儲存庫憲章 -> AGENTS/專案指示 -> 記憶/交接 -> 目前請求。",
"SetupCheckpointDoneBundled": "憲章檢查點完成:使用內建/預設憲章。",
"SetupCheckpointDoneGuided": "憲章已確認並儲存。可隨時用 /constitution 修訂。",
"SetupCheckpointDoneKept": "已保留現有憲章,內容維持不變。可隨時用 /constitution 修訂。",
-2
View File
@@ -1262,7 +1262,6 @@ pub enum MessageId {
SetupStepConstitutionWhy,
SetupStepVerificationTitle,
SetupStepVerificationWhy,
SetupCheckpointLayerOrder,
SetupCheckpointDoneBundled,
SetupCheckpointDoneGuided,
SetupCheckpointDoneKept,
@@ -3888,7 +3887,6 @@ pub const ALL_MESSAGE_IDS: &[MessageId] = &[
MessageId::SetupStepConstitutionWhy,
MessageId::SetupStepVerificationTitle,
MessageId::SetupStepVerificationWhy,
MessageId::SetupCheckpointLayerOrder,
MessageId::SetupCheckpointDoneBundled,
MessageId::SetupCheckpointDoneGuided,
MessageId::SetupCheckpointDoneKept,
@@ -91,7 +91,11 @@ impl RegisterCommand for ConstitutionCmd {
.split_whitespace()
.map(str::to_string)
.collect();
CommandResult::message(ratify_text(app.ui_locale, &ids))
CommandResult::message(ratify_text(
app.ui_locale,
app.constitution_reviewed_digest.as_deref(),
&ids,
))
}
Some("help") => CommandResult::message(help_text(app.ui_locale)),
Some(other) => CommandResult::error(format!(
@@ -151,16 +155,18 @@ fn open_explanation(app: &mut App) {
/// because unratified model advice is not law.
fn open_suggestions(app: &mut App) {
let locale = app.ui_locale;
let text = suggestions_text(locale);
let (text, reviewed) = suggestions_text(locale);
app.constitution_reviewed_digest = reviewed;
open_pager(app, suggestions_title(locale), &text);
}
fn suggestions_text(locale: Locale) -> String {
fn suggestions_text(locale: Locale) -> (String, Option<String>) {
let UserConstitutionStatus::Loaded { constitution, .. } = load_user_constitution() else {
return match locale {
Locale::ZhHans => "没有可供审阅的结构化用户全局协作准则。".to_string(),
let text = match locale {
Locale::ZhHans => "没有可供审阅的结构化用户全局宪章。".to_string(),
_ => "No structured user-global constitution is available to review.".to_string(),
};
return (text, None);
};
let digest = constitution.cache_projection().digest;
let suggested: Vec<_> = constitution.suggested_clauses().collect();
@@ -203,13 +209,14 @@ fn suggestions_text(locale: Locale) -> String {
}
}
}
out
(out, Some(digest))
}
/// Explicit ratification (#3930). Fails closed: it re-reads the live file,
/// hands the live digest back to [`UserConstitution::ratify`], and persists only
/// when the clause set is exactly what the user named.
fn ratify_text(locale: Locale, ids: &[String]) -> String {
/// Explicit ratification (#3930). Fails closed: it hands the digest the user
/// reviewed in `/constitution suggestions` to [`UserConstitution::ratify`],
/// which refuses when the live file has moved since, and persists only when the
/// clause set is exactly what the user named.
fn ratify_text(locale: Locale, reviewed: Option<&str>, ids: &[String]) -> String {
if ids.is_empty() {
return match locale {
Locale::ZhHans => {
@@ -224,14 +231,21 @@ fn ratify_text(locale: Locale, ids: &[String]) -> String {
UserConstitutionStatus::Loaded { path, constitution } => (path, constitution),
_ => {
return match locale {
Locale::ZhHans => "没有可批准的结构化用户全局协作准则。".to_string(),
Locale::ZhHans => "没有可批准的结构化用户全局宪章。".to_string(),
_ => "There is no structured user-global constitution to ratify.".to_string(),
};
}
};
let digest = constitution.cache_projection().digest;
match constitution.ratify(&digest, ids, None) {
let Some(reviewed) = reviewed else {
return match locale {
Locale::ZhHans => {
"未批准任何条款:请先用 /constitution suggestions 审阅待批准条款。".to_string()
}
_ => "Nothing was ratified: review the pending clauses with /constitution suggestions first.".to_string(),
};
};
match constitution.ratify(reviewed, ids, None) {
Err(err) => match locale {
Locale::ZhHans => format!("未批准任何条款:{err}"),
_ => format!("Nothing was ratified: {err}"),
@@ -245,14 +259,14 @@ fn ratify_text(locale: Locale, ids: &[String]) -> String {
},
Ok(()) => match locale {
Locale::ZhHans => format!(
"已批准 {} 条:{}\n摘要 {} → {}\n这些条款现在会注入模型;提示词缓存前缀已随之变化。",
"已批准 {} 条:{}\n摘要 {} → {}\n这些条款从下一轮起作为会话记录中的消息发送给模型;提示词缓存前缀不变。",
ratification.accepted_clause_ids.len(),
ratification.accepted_clause_ids.join(", "),
ratification.before_digest,
ratification.after_digest,
),
_ => format!(
"Ratified {} clause(s): {}\nDigest {} → {}\nThey are injected from the next turn; the prompt-cache prefix moved with them.",
"Ratified {} clause(s): {}\nDigest {} → {}\nThey reach the model from the next turn as a message recorded in the session; the prompt-cache prefix is unchanged.",
ratification.accepted_clause_ids.len(),
ratification.accepted_clause_ids.join(", "),
ratification.before_digest,
@@ -303,9 +317,9 @@ fn migrate_text(locale: Locale) -> String {
receipt.before_digest,
receipt.after_digest,
if receipt.is_cache_stable() {
"未改变,提示词缓存保持有效"
"未改变,模型下一轮收到相同内容"
} else {
"已改变,提示词缓存前缀随之变化"
"已改变,下一轮作为新的会话消息发送"
},
),
_ => format!(
@@ -315,9 +329,9 @@ fn migrate_text(locale: Locale) -> String {
receipt.before_digest,
receipt.after_digest,
if receipt.is_cache_stable() {
"unchanged, so the prompt cache survives"
"unchanged, so the model receives the same text"
} else {
"changed, so the prompt-cache prefix moved"
"changed; the new text is sent as a session message at the next turn"
},
),
}
@@ -545,7 +559,7 @@ fn preview_text(locale: Locale) -> String {
let state = load_setup_state();
let load = load_user_constitution();
match load {
UserConstitutionStatus::Loaded { path, constitution } => {
UserConstitutionStatus::Loaded { constitution, .. } => {
let active = user_constitution_is_active(state.as_ref());
let mut text = String::new();
if !active {
@@ -554,7 +568,7 @@ fn preview_text(locale: Locale) -> String {
}
text.push_str(
&constitution
.render_block(Some(&path))
.render_block(None)
.unwrap_or_else(|| structured_empty_text(locale).to_string()),
);
text
@@ -825,24 +839,24 @@ fn ignored_whale_warnings(warnings: &[String]) -> Vec<&str> {
fn help_text(locale: Locale) -> String {
match locale {
Locale::ZhHans => "\
用法:/constitution [status|preview|bundled|edit|review|repair|repo|explain|posture|help]
用法:/constitution [status|preview|base|suggestions|ratify <id>|migrate|rollback|bundled|edit|review|repair|repo|explain|posture|help]
常用命令:
- /constitution:打开协作准则管理器和当前层级。
- /constitution preview:显示会注入模型的确切用户全局协作准则块;缺失、空、无效或不可读时显示修复说明。
- /constitution edit:打开 /setup 的引导式协作准则步骤;用 1-6 调整,按 G 预览,再按 G 保存。
- /constitution:打开宪章管理器和当前层级。
- /constitution preview:显示会注入模型的确切用户全局宪章块;缺失、空、无效或不可读时显示修复说明。
- /constitution edit:打开 /setup 的引导式宪章步骤;用 1-6 调整,按 G 预览,再按 G 保存。
- /constitution repair:说明当前文件状态,然后打开同一个引导式修复步骤。
- /constitution bundled:记录使用内置/默认准则,不创建自定义文件。
- /constitution repo:查看 .codewhale/constitution.json 仓库本地准则。
- /constitution explain:解释内置基础准则、用户全局协作准则、仓库协作准则、AGENTS.md、记忆和交接的区别。
- /constitution explain:解释内置基础准则、用户全局宪章、仓库宪章、AGENTS.md、记忆和交接的区别。
- /constitution base:显示下一轮实际组装的确切基础提示词,附来源、摘要和字节/词元度量;只读,不发送请求,也不展开工具目录。
- /constitution suggestions:查看待批准的建议条款;它们不会注入模型,也不影响提示词缓存。
- /constitution ratify <id>:明确批准某条建议条款;若基线在审阅后发生变化则拒绝批准。
- /constitution migrate:把协作准则文件迁移到当前架构版本并给出回执;被拒绝时文件保持原样。
- /constitution migrate:把宪章文件迁移到当前架构版本并给出回执;被拒绝时文件保持原样。
- /constitution rollback:恢复迁移前的备份。
- /constitution posture:打开运行时姿态;协作准则只提供模型指导,不会更改批准、沙盒、Shell、网络、信任或 MCP 权限。",
- /constitution posture:打开运行时姿态;宪章只提供模型指导,不会更改批准、沙盒、Shell、网络、信任或 MCP 权限。",
_ => "\
Usage: /constitution [status|preview|bundled|edit|review|repair|repo|explain|posture|help]
Usage: /constitution [status|preview|base|suggestions|ratify <id>|migrate|rollback|bundled|edit|review|repair|repo|explain|posture|help]
Common commands:
- /constitution: open the constitution manager and active stack.
@@ -879,14 +893,14 @@ fn repair_text(locale: Locale) -> String {
match locale {
Locale::ZhHans => format!(
"\
用户全局协作准则修复
用户全局宪章修复
当前文件:{file}
当前状态:{status}
记录选择:{choice}
有效性:{validity}
接下来将打开 /setup 的协作准则步骤。安全修复路径:
接下来将打开 /setup 的宪章步骤。安全修复路径:
- 用 1-6 调整引导式草稿,按 G 预览,再按 G 保存新的结构化 constitution.json。
- 按 U 或运行 /constitution bundled 记录使用内置/默认准则;现有无效/空/不可读文件不会被注入。
- 用 /constitution preview 查看当前错误或渲染结果。
@@ -914,42 +928,42 @@ This only repairs the user-global constitution.json. Runtime approval, sandbox,
fn manager_title(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "协作准则",
Locale::ZhHans => "宪章",
_ => "Constitution",
}
}
fn review_title(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "协作准则检查",
Locale::ZhHans => "宪章检查",
_ => "Constitution Review",
}
}
fn rendered_title(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "渲染后的用户协作准则",
Locale::ZhHans => "渲染后的用户宪章",
_ => "Rendered User Constitution",
}
}
fn repo_title(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "仓库本地协作准则",
Locale::ZhHans => "仓库本地宪章",
_ => "Repo-Local Constitution",
}
}
fn explanation_title(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "AGENTS.md 与协作准则",
Locale::ZhHans => "AGENTS.md 与宪章",
_ => "AGENTS.md vs Constitution",
}
}
fn no_repo_law_text(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "此工作区未找到仓库本地协作准则 .codewhale/constitution.json。",
Locale::ZhHans => "此工作区未找到仓库本地宪章 .codewhale/constitution.json。",
_ => "No repo-local constitution found at .codewhale/constitution.json for this workspace.",
}
}
@@ -963,7 +977,7 @@ fn inactive_preview_text(locale: Locale) -> &'static str {
fn structured_empty_text(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => "结构化协作准则为空。",
Locale::ZhHans => "结构化宪章为空。",
_ => "The structured constitution is empty.",
}
}
@@ -971,7 +985,7 @@ fn structured_empty_text(locale: Locale) -> &'static str {
fn missing_preview_text(locale: Locale, path: &std::path::Path) -> String {
match locale {
Locale::ZhHans => format!(
"未在 {} 找到结构化用户全局协作准则。\n\n当前使用内置准则。使用 /constitution edit 创建引导式长期偏好,或使用 /constitution bundled 明确记录内置/默认。",
"未在 {} 找到结构化用户全局宪章。\n\n当前使用内置准则。使用 /constitution edit 创建引导式长期偏好,或使用 /constitution bundled 明确记录内置/默认。",
path.display()
),
_ => format!(
@@ -984,7 +998,7 @@ fn missing_preview_text(locale: Locale, path: &std::path::Path) -> String {
fn empty_preview_text(locale: Locale, path: &std::path::Path) -> String {
match locale {
Locale::ZhHans => format!(
"{} 的结构化用户全局协作准则为空。使用 /constitution repair 返回引导式协作准则步骤。",
"{} 的结构化用户全局宪章为空。使用 /constitution repair 返回引导式宪章步骤。",
path.display()
),
_ => format!(
@@ -997,7 +1011,7 @@ fn empty_preview_text(locale: Locale, path: &std::path::Path) -> String {
fn invalid_preview_text(locale: Locale, path: &std::path::Path, error: &str) -> String {
match locale {
Locale::ZhHans => format!(
"{} 的结构化用户全局协作准则无效,且不会注入。\n\n{error}\n\n使用 /constitution repair 返回引导式协作准则步骤。",
"{} 的结构化用户全局宪章无效,且不会注入。\n\n{error}\n\n使用 /constitution repair 返回引导式宪章步骤。",
path.display()
),
_ => format!(
@@ -1010,7 +1024,7 @@ fn invalid_preview_text(locale: Locale, path: &std::path::Path, error: &str) ->
fn unreadable_preview_text(locale: Locale, path: &std::path::Path, error: &str) -> String {
match locale {
Locale::ZhHans => format!(
"无法读取 {} 的结构化用户全局协作准则,且不会注入。\n\n{error}\n\n使用 /constitution repair 返回引导式协作准则步骤。",
"无法读取 {} 的结构化用户全局宪章,且不会注入。\n\n{error}\n\n使用 /constitution repair 返回引导式宪章步骤。",
path.display()
),
_ => format!(
@@ -1022,7 +1036,7 @@ fn unreadable_preview_text(locale: Locale, path: &std::path::Path, error: &str)
fn path_error_preview_text(locale: Locale, error: &str) -> String {
match locale {
Locale::ZhHans => format!("无法为用户全局协作准则解析 CODEWHALE_HOME:\n\n{error}"),
Locale::ZhHans => format!("无法为用户全局宪章解析 CODEWHALE_HOME:\n\n{error}"),
_ => {
format!("Could not resolve CODEWHALE_HOME for the user-global constitution:\n\n{error}")
}
@@ -1033,19 +1047,19 @@ fn agents_explanation(locale: Locale) -> &'static str {
match locale {
Locale::ZhHans => {
"\
AGENTS.md 与协作准则
AGENTS.md 与宪章
内置基础准则是精简的全局判断约定:身份、事实、验证、克制和优先级顺序。
用户全局协作准则是个人长期偏好。它是结构化数据,确定性渲染,并低于当前用户请求和内置基础准则。
用户全局宪章是个人长期偏好。它是结构化数据,确定性渲染,并低于当前用户请求和内置基础准则。
.codewhale/constitution.json 是仓库本地协作准则。它属于某个工作区,并作为独立的仓库协作准则块渲染。
.codewhale/constitution.json 是仓库本地宪章。它属于某个工作区,并作为独立的仓库宪章块渲染。
AGENTS.md 和项目说明是项目规则/实现指导。它们可以描述构建命令、仓库规范和本地流程;按优先级顺序,它们低于当前用户请求和内置基础准则,高于用户全局长期偏好、记忆和交接。
WHALE.md 已忽略。将普通项目说明迁移到 AGENTS.md,将 Codewhale 专属权限策略迁移到 .codewhale/constitution.json。
运行时姿态是独立设置。协作准则可以建议主动性,但不会改变批准策略、沙盒、Shell、网络、信任、MCP 权限或默认模式。使用 /constitution posture 查看这些控制。"
运行时姿态是独立设置。宪章可以建议主动性,但不会改变批准策略、沙盒、Shell、网络、信任、MCP 权限或默认模式。使用 /constitution posture 查看这些控制。"
}
_ => {
"\
@@ -1106,17 +1120,17 @@ impl ConstitutionManagerCopy {
fn for_locale(locale: Locale) -> Self {
match locale {
Locale::ZhHans => Self {
manager_header: "协作准则管理器",
manager_header: "宪章管理器",
active_stack_header: "生效层级",
bundled_active: "内置基础准则:始终生效",
user_global_label: "用户全局协作准则",
repo_local_label: "仓库本地协作准则",
user_global_label: "用户全局宪章",
repo_local_label: "仓库本地宪章",
agents_label: "AGENTS/项目说明",
legacy_whale_label: "旧版 WHALE.md",
memory_handoff_label: "记忆/交接",
memory_label: "记忆",
handoff_label: "交接",
user_global_header: "用户全局协作准则",
user_global_header: "用户全局宪章",
choice_label: "选择",
source_label: "来源",
file_label: "文件",
@@ -1130,8 +1144,8 @@ impl ConstitutionManagerCopy {
repo_action: "/constitution repo 会在存在时显示 .codewhale/constitution.json 本地准则。",
maintenance_header: "维护",
maintenance_actions: &[
"编辑引导式协作准则:/constitution edit",
"预览渲染后的协作准则:/constitution preview",
"编辑引导式宪章:/constitution edit",
"预览渲染后的宪章:/constitution preview",
"查看下一轮的确切基础提示词:/constitution base",
"审阅待批准的建议条款:/constitution suggestions",
"批准某条建议条款:/constitution ratify <id>",
@@ -1140,7 +1154,7 @@ impl ConstitutionManagerCopy {
"查看现有内容:/constitution review",
"修复无效/空/不可读文件:/constitution repair",
"显示仓库本地准则:/constitution repo",
"解释 AGENTS.md 与协作准则:/constitution explain",
"解释 AGENTS.md 与宪章:/constitution explain",
"打开运行时姿态:/constitution posture",
],
present: "存在",
@@ -1205,7 +1219,7 @@ impl ConstitutionManagerCopy {
}
fn location_count_unit(&self, count: usize) -> &'static str {
if self.manager_header == "协作准则管理器" {
if self.manager_header == "宪章管理器" {
"处"
} else if count == 1 {
"location"
@@ -1215,7 +1229,7 @@ impl ConstitutionManagerCopy {
}
fn completed_for(&self, version: &str) -> String {
if self.manager_header == "协作准则管理器" {
if self.manager_header == "宪章管理器" {
format!("当前(自 {version} 引入)")
} else {
format!("current (introduced in {version})")
@@ -1446,6 +1460,14 @@ mod tests {
.expect("usage message");
assert!(bare.contains("Usage: /constitution ratify <id>"));
let unreviewed = ConstitutionCmd::execute(&mut app, Some("ratify c1"))
.message
.expect("refusal message");
assert!(unreviewed.contains("Nothing was ratified"), "{unreviewed}");
ConstitutionCmd::execute(&mut app, Some("suggestions"));
pop_pager_body(&mut app);
let unknown = ConstitutionCmd::execute(&mut app, Some("ratify nope"))
.message
.expect("refusal message");
@@ -1484,7 +1506,7 @@ mod tests {
"{message}"
);
assert!(
message.contains("the prompt cache survives"),
message.contains("the model receives the same text"),
"a v1 file carries no clauses, so no model-facing byte moved: {message}"
);
@@ -1550,9 +1572,9 @@ mod tests {
assert!(result.message.is_none());
let body = pop_pager_body(&mut app);
assert!(body.contains("协作准则管理器"));
assert!(body.contains("宪章管理器"));
assert!(body.contains("生效层级"));
assert!(body.contains("用户全局协作准则"));
assert!(body.contains("用户全局宪章"));
assert!(body.contains("/constitution preview 会"));
assert!(!body.contains("宪法"));
assert!(!body.contains("Constitution Manager"));
@@ -1588,7 +1610,7 @@ mod tests {
assert!(result.message.is_none());
let body = pop_pager_body(&mut app);
assert!(body.contains("AGENTS.md 与协作准则"));
assert!(body.contains("AGENTS.md 与宪章"));
assert!(body.contains(".codewhale/constitution.json"));
assert!(body.contains("运行时姿态是独立设置"));
assert!(!body.contains("宪法"));
+1
View File
@@ -1961,6 +1961,7 @@ pub struct App {
/// Exact evidence remains attached to each mutation receipt in all modes.
pub inline_diff_mode: InlineDiffMode,
pub ui_locale: Locale,
pub constitution_reviewed_digest: Option<String>,
pub cost_currency: CostCurrency,
/// Route payment truth. Model pricing alone cannot distinguish metered
/// API calls from OAuth or token-plan quota.
+1
View File
@@ -935,6 +935,7 @@ impl App {
show_tool_details,
inline_diff_mode,
ui_locale,
constitution_reviewed_digest: None,
cost_currency,
billing_presentation: provider_identity.as_ref().map_or(
crate::route_billing::BillingPresentation::Unknown,
+33 -32
View File
@@ -835,63 +835,63 @@ impl GuidedConstitutionDraft {
let own_words = match locale {
Locale::Ja => format!(
"\nユーザー自由原則:{}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::ZhHans => format!(
"\n用户自定义准则:{}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::ZhHant => format!(
"\n使用者自由原則:{}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::PtBr => format!(
"\nPrincípio livre do usuário: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Es419 => format!(
"\nPrincipio libre del usuario: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Vi => format!(
"\nNguyên tắc tự do của người dùng: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Ko => format!(
"\n사용자 자유 원칙: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Ca => format!(
"\nPrincipi lliure de l'usuari: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::De => format!(
"\nFreitext-Prinzip des Nutzers: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Fr => format!(
"\nPrincipe en texte libre de l'utilisateur : {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Id => format!(
"\nPrinsip bebas pengguna: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Hi => format!(
"\nउपयोगकर्ता मुक्त-पाठ सिद्धांत: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Ru => format!(
"\nСвободный принцип пользователя: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
Locale::Uk => format!(
"\nВільний принцип користувача: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
_ => format!(
"\nUser freeform principle: {}",
bounded_freeform_note(note, MAX_NOTES_LEN)
bounded_freeform_note(note, FREEFORM_NOTE_MAX)
),
};
notes.push_str(&own_words);
@@ -2126,6 +2126,8 @@ fn authority_priority(locale: Locale) -> &'static str {
}
}
const FREEFORM_NOTE_MAX: usize = MAX_NOTES_LEN - 1_000;
fn bounded_freeform_note(input: &str, max_chars: usize) -> String {
input
.chars()
@@ -2896,7 +2898,7 @@ impl SetupWizardView {
fn append_freeform_note_text(&mut self, text: &str) {
let mut next = self.freeform_note.clone();
next.push_str(text);
self.freeform_note = bounded_freeform_note(&next, MAX_NOTES_LEN);
self.freeform_note = bounded_freeform_note(&next, FREEFORM_NOTE_MAX);
self.guided_preview_seen = false;
self.model_draft = None;
self.model_draft_label = None;
@@ -4421,7 +4423,6 @@ fn constitution_ratification_text(
Locale::Uk => "Структурована конституція порожня.".to_string(),
_ => "The structured constitution is empty.".to_string(),
});
let layer_order = tr(locale, MessageId::SetupCheckpointLayerOrder);
match locale {
Locale::Ja => {
@@ -4454,7 +4455,7 @@ fn constitution_ratification_text(
すべての個別判断を裁くのではなく権限と境界を定め、セッションを越えて協働を継続させます。\
ただしこれは記憶ではありません。履歴ではなく原則を保持します。\n\n\
{rendered}\n\n\
権限の階層\n{layer_order}\nあなたの直接の指示は常にこの文書より優先されます。\n\n\
権限の階層\nあなたの直接の指示は常にこの文書より優先されます。\n\n\
これができないこと\n\
これは行動を導くものです。承認ポリシー、サンドボックス、Shell、ネットワーク、信頼、MCP 権限、\
既定モード、公開、支出の権限を付与または変更することはできません。これらは実行時にあなたが管理します。\n\n\
@@ -4489,7 +4490,7 @@ fn constitution_ratification_text(
这是 Codewhale 与你协作时长期遵循的偏好和规则。内容应保持简短、便于执行,以持久原则为主,并可随时调整。\
它界定协作方式与行为边界,而不是替你决定每一种情况;它让协作跨会话延续——但它不是记忆,只保留原则,不保留历史。\n\n\
{rendered}\n\n\
权限层级\n{layer_order}\n你的直接指令始终高于本文件。\n\n\
权限层级\n你的直接指令始终高于本文件。\n\n\
它不能做什么\n\
它只提供行为指导,不能授予或更改审批策略、沙箱、Shell、网络、信任、MCP 权限、默认模式、发布或支出权限——这些始终由你在运行时掌控。\n\n\
精简核心与可选策略\n\
@@ -4522,7 +4523,7 @@ fn constitution_ratification_text(
這是 Codewhale 與你協作的長期準則。像優秀的憲法一樣:足夠簡短因而可用,由持久原則而非詳盡規則構成,並且可以隨你修訂。\
它界定權力與邊界,而非裁決每個具體決定;它讓協作跨會話延續,但它不是記憶,它承載的是原則,而非歷史。\n\n\
{rendered}\n\n\
權限層級\n{layer_order}\n你的直接指令始終高於本文件。\n\n\
權限層級\n你的直接指令始終高於本文件。\n\n\
它不能做什麼\n\
它只提供行為指導,不能授予或更改審批策略、沙箱、Shell、網路、信任、MCP 權限、預設模式、發布或支出權限;這些始終由你在執行時掌控。\n\n\
精簡核心與可選模組\n\
@@ -4560,7 +4561,7 @@ fn constitution_ratification_text(
e pode ser emendada conforme você muda. Ela define poderes e limites em vez de decidir cada caso, \
e dá continuidade à colaboração entre sessões. Mas ela não é memória: carrega princípios, não histórico.\n\n\
{rendered}\n\n\
HIERARQUIA DE AUTORIDADE\n{layer_order}\nSeus pedidos diretos sempre superam este documento.\n\n\
HIERARQUIA DE AUTORIDADE\nSeus pedidos diretos sempre superam este documento.\n\n\
O QUE ISTO NÃO PODE FAZER\n\
Isto orienta comportamento. Não pode conceder nem alterar política de aprovação, sandbox, shell, rede, \
confiança, permissões MCP, modo padrão, publicação ou autoridade para gastos; isso continua sob seu controle em tempo de execução.\n\n\
@@ -4600,7 +4601,7 @@ fn constitution_ratification_text(
y enmendable a medida que cambias. Define poderes y límites en vez de decidir cada caso, \
y da continuidad a la colaboración entre sesiones. Pero no es memoria: lleva principios, no historial.\n\n\
{rendered}\n\n\
JERARQUÍA DE AUTORIDAD\n{layer_order}\nTus pedidos directos siempre superan este documento.\n\n\
JERARQUÍA DE AUTORIDAD\nTus pedidos directos siempre superan este documento.\n\n\
LO QUE ESTO NO PUEDE HACER\n\
Orienta comportamiento. No puede conceder ni cambiar política de aprobación, sandbox, shell, red, \
confianza, permisos MCP, modo predeterminado, publicación o autoridad de gasto; eso sigue bajo tu control en tiempo de ejecución.\n\n\
@@ -4640,7 +4641,7 @@ fn constitution_ratification_text(
và có thể sửa khi bạn thay đổi. Nó định khung quyền hạn và giới hạn thay vì quyết định từng trường hợp, \
đồng thời giữ sự liên tục giữa các phiên. Nhưng nó không phải bộ nhớ: nó mang nguyên tắc, không mang lịch sử.\n\n\
{rendered}\n\n\
THỨ BẬC THẨM QUYỀN\n{layer_order}\nYêu cầu trực tiếp của bạn luôn cao hơn tài liệu này.\n\n\
THỨ BẬC THẨM QUYỀN\nYêu cầu trực tiếp của bạn luôn cao hơn tài liệu này.\n\n\
ĐIỀU NÀY KHÔNG THỂ LÀM\n\
Nó hướng dẫn hành vi. Nó không thể cấp hoặc đổi chính sách phê duyệt, sandbox, shell, mạng, \
độ tin cậy, quyền MCP, chế độ mặc định, xuất bản hoặc quyền chi tiêu; những thứ đó vẫn do bạn kiểm soát lúc chạy.\n\n\
@@ -4680,7 +4681,7 @@ fn constitution_ratification_text(
이는 모든 개별 사례를 판단하는 대신 권한과 한계를 규정하며, 세션을 넘어 협업의 연속성을 부여합니다. \
다만 이것은 기억이 아닙니다: 이력이 아니라 원칙을 담습니다.\n\n\
{rendered}\n\n\
권한 계층\n{layer_order}\n당신의 직접적인 요청은 언제나 이 문서보다 우선합니다.\n\n\
권한 계층\n당신의 직접적인 요청은 언제나 이 문서보다 우선합니다.\n\n\
이것이 할 수 없는 일\n\
이것은 행동을 안내할 뿐입니다. 승인 정책, 샌드박스, 셸, 네트워크, 신뢰, MCP 권한, 기본 모드, 게시, 지출 권한을 \
부여하거나 바꿀 수 없습니다; 이는 여전히 런타임에서 당신이 직접 관리합니다.\n\n\
@@ -4720,7 +4721,7 @@ fn constitution_ratification_text(
i esmenable a mesura que canvies. Defineix poders i límits en lloc de decidir cada cas, \
i dona continuïtat a la col·laboració entre sessions — però no és memòria: porta principis, no història.\n\n\
{rendered}\n\n\
JERARQUIA D'AUTORITAT\n{layer_order}\nLes teves peticions directes sempre prevalen sobre aquest document.\n\n\
JERARQUIA D'AUTORITAT\nLes teves peticions directes sempre prevalen sobre aquest document.\n\n\
EL QUE AIXÒ NO POT FER\n\
Orienta el comportament. No pot concedir ni canviar la política d'aprovació, sandbox, shell, xarxa, \
confiança, permisos MCP, mode per defecte, publicació o autoritat de despesa; això queda sota el teu control en temps d'execució.\n\n\
@@ -4760,7 +4761,7 @@ fn constitution_ratification_text(
und lässt sich ändern, wenn du dich änderst. Sie rahmt Befugnisse und Grenzen, statt jeden Einzelfall zu entscheiden, \
und gibt deiner Zusammenarbeit Kontinuität über Sitzungen hinweg — aber sie ist kein Gedächtnis: Sie trägt Prinzipien, nicht Geschichte.\n\n\
{rendered}\n\n\
HIERARCHIE DER AUTORITÄT\n{layer_order}\nDeine direkten Anweisungen stehen immer über diesem Dokument.\n\n\
HIERARCHIE DER AUTORITÄT\nDeine direkten Anweisungen stehen immer über diesem Dokument.\n\n\
WAS DIES NICHT KANN\n\
Sie leitet Verhalten. Sie kann keine Freigaberichtlinie, Sandbox, Shell, Netzwerk, \
Vertrauen, MCP-Berechtigungen, Standardmodus, Veröffentlichung oder Ausgabenbefugnis gewähren oder ändern — die bleiben zur Laufzeit in deiner Hand.\n\n\
@@ -4800,7 +4801,7 @@ fn constitution_ratification_text(
et amendable à mesure que vous changez. Elle encadre les pouvoirs et les limites plutôt que de trancher chaque cas, \
et donne à votre collaboration une continuité entre les sessions — mais elle n'est pas une mémoire : elle porte des principes, pas un historique.\n\n\
{rendered}\n\n\
HIÉRARCHIE D'AUTORITÉ\n{layer_order}\nVos demandes directes priment toujours sur ce document.\n\n\
HIÉRARCHIE D'AUTORITÉ\nVos demandes directes priment toujours sur ce document.\n\n\
CE QU'ELLE NE PEUT PAS FAIRE\n\
Elle guide le comportement. Elle ne peut ni accorder ni modifier la politique d'approbation, le sandbox, le shell, le réseau, \
la confiance, les permissions MCP, le mode par défaut, la publication ou le pouvoir de dépense — ceux-ci restent entre vos mains à l'exécution.\n\n\
@@ -4840,7 +4841,7 @@ fn constitution_ratification_text(
dan dapat diamendemen seiring Anda berubah. Ia membingkai wewenang dan batasan alih-alih memutuskan setiap kasus, \
dan memberi kolaborasi Anda kesinambungan lintas sesi — tetapi ia bukan memori: ia membawa prinsip, bukan riwayat.\n\n\
{rendered}\n\n\
HIERARKI OTORITAS\n{layer_order}\nPermintaan langsung Anda selalu mengungguli dokumen ini.\n\n\
HIERARKI OTORITAS\nPermintaan langsung Anda selalu mengungguli dokumen ini.\n\n\
APA YANG TIDAK BISA DILAKUKANNYA\n\
Ia memandu perilaku. Ia tidak dapat memberi atau mengubah kebijakan persetujuan, sandbox, shell, jaringan, \
kepercayaan, izin MCP, mode default, publikasi, atau wewenang belanja — semua itu tetap di tangan Anda saat runtime.\n\n\
@@ -4878,7 +4879,7 @@ fn constitution_ratification_text(
और आपके बदलने के साथ संशोधनीय है। यह हर मामले का फ़ैसला करने के बजाय शक्तियों और सीमाओं का ढाँचा देता है, \
और आपके सहयोग को सत्रों के पार निरंतरता देता है — लेकिन यह मेमोरी नहीं है: यह इतिहास नहीं, सिद्धांत रखता है।\n\n\
{rendered}\n\n\
अधिकार पदानुक्रम\n{layer_order}\nआपके प्रत्यक्ष अनुरोध हमेशा इस दस्तावेज़ से ऊपर हैं।\n\n\
अधिकार पदानुक्रम\nआपके प्रत्यक्ष अनुरोध हमेशा इस दस्तावेज़ से ऊपर हैं।\n\n\
यह क्या नहीं कर सकता\n\
यह व्यवहार का मार्गदर्शन करता है। यह अनुमति नीति, सैंडबॉक्स, शेल, नेटवर्क, \
ट्रस्ट, MCP अनुमतियाँ, डिफ़ॉल्ट मोड, प्रकाशन या खर्च का अधिकार प्रदान या परिवर्तित नहीं कर सकता — वे रनटाइम पर आपके हाथ में रहते हैं।\n\n\
@@ -4918,7 +4919,7 @@ fn constitution_ratification_text(
и может изменяться вместе с вами. Она очерчивает полномочия и границы, а не решает каждый случай, \
и придаёт вашему сотрудничеству непрерывность между сессиями — но она не память: она хранит принципы, а не историю.\n\n\
{rendered}\n\n\
ИЕРАРХИЯ ПОЛНОМОЧИЙ\n{layer_order}\nВаши прямые указания всегда важнее этого документа.\n\n\
ИЕРАРХИЯ ПОЛНОМОЧИЙ\nВаши прямые указания всегда важнее этого документа.\n\n\
ЧЕГО ОНА НЕ МОЖЕТ\n\
Она направляет поведение. Она не может предоставить или изменить политику одобрения, sandbox, shell, сеть, \
доверие, разрешения MCP, режим по умолчанию, публикацию или право тратить — они остаются в ваших руках во время выполнения.\n\n\
@@ -4958,7 +4959,7 @@ fn constitution_ratification_text(
і може змінюватися разом із вами. Вона окреслює повноваження та межі, а не вирішує кожен випадок, \
і надає вашій співпраці неперервність між сесіями — але вона не пам'ять: вона зберігає принципи, а не історію.\n\n\
{rendered}\n\n\
ІЄРАРХІЯ ПОВНОВАЖЕНЬ\n{layer_order}\nВаші прямі вказівки завжди важливіші за цей документ.\n\n\
ІЄРАРХІЯ ПОВНОВАЖЕНЬ\nВаші прямі вказівки завжди важливіші за цей документ.\n\n\
ЧОГО ВОНА НЕ МОЖЕ\n\
Вона спрямовує поведінку. Вона не може надати або змінити політику схвалення, sandbox, shell, мережу, \
довіру, дозволи MCP, режим за замовчуванням, публікацію чи право витрачати — вони залишаються у ваших руках під час виконання.\n\n\
@@ -5001,7 +5002,7 @@ fn constitution_ratification_text(
continuity across sessions — but it is not memory: it carries principles, \
not history.\n\n\
{rendered}\n\n\
HIERARCHY OF AUTHORITY\n{layer_order}\nYour direct requests always outrank this document.\n\n\
HIERARCHY OF AUTHORITY\nYour direct requests always outrank this document.\n\n\
WHAT THIS CANNOT DO\n\
It guides behavior. It cannot grant or change approval policy, sandbox, shell, \
network, trust, MCP permissions, default mode, publishing, or spending \
+1 -1
View File
@@ -353,7 +353,7 @@ pub(crate) async fn handle_setup_constitution_model_draft(
app.status_message = Some(match locale {
codewhale_localization::Locale::ZhHans => {
format!(
"{model_label} 正在生成协作准则草案……(最多 {}s)",
"{model_label} 正在生成宪章草案……(最多 {}s)",
DRAFT_TIMEOUT.as_secs()
)
}
+4 -3
View File
@@ -77,7 +77,7 @@ required first-run screen. Customize it later through `/constitution` or the
progressive `/setup` guide. Provider/model readiness, workspace trust, and
runtime posture stay separate from this guidance.
On the **Constitution** step:
On the **Working agreement** (constitution) step:
- **`1`–`6`** tune the guided draft. **`G`** previews it, and **`G`** again
ratifies and saves a fresh structured `constitution.json`.
@@ -91,8 +91,9 @@ On the **Constitution** step:
`/constitution` (alias `/law`) is the primary management surface once you are
set up. Subcommands: `status` (the default), `preview`, `review`, `repo` (the
repo-local law block), `explain`, `edit`/`guided`, `repair`, `posture`, and
`bundled`. Managing the constitution never changes runtime approval, sandbox,
repo-local law block), `explain`, `base`, `suggestions`, `ratify <id>`,
`migrate`, `rollback`, `edit`/`guided`, `repair`, `posture`, and `bundled`.
Managing the constitution never changes runtime approval, sandbox,
shell, network, trust, default mode, or MCP authority — those stay in runtime
posture/config.
+1 -1
View File
@@ -94,7 +94,7 @@ server answers. The provider step also has an explicit offline route.
Everything optional stays available after that. Use `/setup` for the
progressive setup and repair guide, `/settings` for the full typed editor, and
`/constitution` when you want to customize the bundled working agreement.
`/constitution` when you want your own constitution on top of the bundled one.
The localized telemetry choice appears only after the workspace is ready and
does not block the composer.