diff --git a/cli/src/commands/charter/audit.rs b/cli/src/commands/charter/audit.rs index 7afd1ab0..fd8bc346 100644 --- a/cli/src/commands/charter/audit.rs +++ b/cli/src/commands/charter/audit.rs @@ -114,6 +114,7 @@ pub fn run( let audit_dir = straymark_dir.join("audits").join(&canonical_id); utils::ensure_dir(&audit_dir)?; + let range_explicit = range.is_some(); let range = match range { Some(r) => r.to_string(), None => resolve_default_range(project_root), @@ -166,7 +167,7 @@ pub fn run( // Default action: prepare. The --prepare flag is accepted for // self-documenting invocations but is also the implicit default. let _ = prepare; - run_prepare(project_root, &straymark_dir, &audit_dir, &charter, &range) + run_prepare(project_root, &straymark_dir, &audit_dir, &charter, &range, range_explicit) } // ── Step 1: prepare ──────────────────────────────────────────────────────── @@ -177,6 +178,7 @@ fn run_prepare( audit_dir: &Path, charter: &Charter, range: &str, + range_explicit: bool, ) -> Result<()> { println!( "{} {} ({})", @@ -185,6 +187,29 @@ fn run_prepare( charter.frontmatter.charter_id.dimmed() ); + // #208: a multi-batch Charter whose earlier phases already merged to the base + // branch will silently under-cover when audited with the default range + // (origin/main..HEAD excludes the merged commits). Warn when completed batches + // are detected and the operator did not pin an explicit --range. + if !range_explicit { + let completed = completed_batch_numbers(project_root, charter); + if !completed.is_empty() { + let list = completed + .iter() + .map(|n| format!("Batch {n}")) + .collect::>() + .join(", "); + eprintln!( + "{} this Charter has completed batches ({list}) — earlier phases may \ + already be merged to the base branch. The default audit range \ + (origin/main..HEAD) EXCLUDES already-merged commits, so a phase-scoped \ + audit can silently under-cover. Pass --range ..HEAD \ + explicitly to span the whole phase.", + "warn:".yellow().bold() + ); + } + } + let context = build_audit_context(project_root, charter, range)?; let lang = crate::config::StrayMarkConfig::resolve_language(project_root); @@ -578,6 +603,44 @@ fn build_audit_context( }) } +/// Batch numbers marked completed in the Charter body or its referenced AILOGs' +/// Batch Ledgers (an entry is completed when its body is not `(pending)`). A +/// non-empty result signals earlier phases likely landed on the base branch +/// already — the condition that makes the default audit range under-cover (#208). +fn completed_batch_numbers(project_root: &Path, charter: &Charter) -> Vec { + let agent_logs = project_root + .join(".straymark") + .join("07-ai-audit") + .join("agent-logs"); + let mut sources: Vec = vec![charter.body.clone()]; + let ids = charter + .frontmatter + .originating_ailogs + .iter() + .flatten() + .chain(charter.frontmatter.execution_ailogs.iter().flatten()); + for id in ids { + let prefix = id.split('-').take(5).collect::>().join("-"); + if let Some(found) = walk_for_prefix(&agent_logs, &prefix) { + if let Ok(body) = std::fs::read_to_string(&found) { + sources.push(body); + } + } + } + let mut completed: Vec = Vec::new(); + for src in &sources { + if let Some(entries) = crate::ailog::parse_batch_ledger(src) { + for e in entries { + if !e.is_pending && !completed.contains(&e.n) { + completed.push(e.n); + } + } + } + } + completed.sort_unstable(); + completed +} + fn read_originating_ailogs(project_root: &Path, charter: &Charter) -> Result<(String, String)> { let ailog_ids = match &charter.frontmatter.originating_ailogs { Some(ids) if !ids.is_empty() => ids.clone(), diff --git a/cli/src/commands/charter/status.rs b/cli/src/commands/charter/status.rs index 25c98da7..97a78aed 100644 --- a/cli/src/commands/charter/status.rs +++ b/cli/src/commands/charter/status.rs @@ -85,10 +85,6 @@ fn print_detail(c: &Charter, project_root: &std::path::Path) { } println!(); - println!(" {}", "Phase 2 features (not yet available):".dimmed()); - println!(" {}", "telemetry — straymark charter close (planned cli-3.7.0)".dimmed()); - println!(" {}", "drift-check — straymark charter drift (planned cli-3.7.0)".dimmed()); - println!(); } fn print_recent(charters: &[Charter]) { diff --git a/cli/src/main.rs b/cli/src/main.rs index dee6b9ca..75b840b3 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -579,7 +579,10 @@ enum CharterCommands { charter_id: String, /// Git revision range (default: origin/main..HEAD with fallback to /// origin/master..HEAD; falls back to HEAD~1..HEAD with warning when - /// no upstream is reachable). Override with explicit value as needed. + /// no upstream is reachable). For a phase-scoped audit of a multi-batch + /// Charter whose earlier phases already merged, pass an explicit range + /// from the Charter's first commit (e.g. ..HEAD) — the + /// default excludes already-merged commits and would under-cover. #[arg(long)] range: Option, /// Generate the unified audit prompt and write it to diff --git a/cli/tests/charter_audit_test.rs b/cli/tests/charter_audit_test.rs index fb43e701..b49ab92f 100644 --- a/cli/tests/charter_audit_test.rs +++ b/cli/tests/charter_audit_test.rs @@ -1010,3 +1010,69 @@ fn audit_prepare_uses_en_canonical_when_language_en() { assert!(!resolved.contains("## Tu rol")); } + +/// #208: a Charter whose AILOG batch ledger has a completed batch triggers a +/// multi-batch under-coverage warning when prepared WITHOUT an explicit --range, +/// and stays silent WITH an explicit range. +#[test] +fn audit_prepare_warns_on_multibatch_without_explicit_range() { + if !bash_available() { + eprintln!("skipping: git not available"); + return; + } + let dir = TempDir::new().unwrap(); + setup_straymark(dir.path()); + + // AILOG with a Batch Ledger: Batch 1 completed, Batch 2 still pending. + let ailog = "\ +--- +id: AILOG-2026-06-20-001-exec +title: Execution log +status: accepted +--- + +## Batch Ledger + +### Batch 1 — Phase one + +Done on 2026-06-19. Files: src/foo.rs. + +### Batch 2 — Phase two + +(pending) +"; + std::fs::write( + dir.path().join(".straymark/07-ai-audit/agent-logs/AILOG-2026-06-20-001-exec.md"), + ailog, + ) + .unwrap(); + + // Charter referencing that AILOG. + let charters = dir.path().join(".straymark/charters"); + std::fs::create_dir_all(&charters).unwrap(); + std::fs::write( + charters.join("01-multibatch.md"), + "---\ncharter_id: CHARTER-01\nstatus: in-progress\neffort_estimate: M\ntrigger: \"t\"\noriginating_ailogs: [AILOG-2026-06-20-001-exec]\n---\n\n# Charter: Multibatch\n\n## Files to modify\n\n| File | Change |\n|---|---|\n| `src/foo.rs` | edit |\n", + ) + .unwrap(); + init_repo_with_diff(dir.path()); + + // Without --range: the warning fires. + cargo_bin_cmd!("straymark") + .args(["charter", "audit", "CHARTER-01", "--prepare", "--path"]) + .arg(dir.path().to_str().unwrap()) + .assert() + .success() + .stderr(predicate::str::contains("completed batches")) + .stderr(predicate::str::contains("under-cover")); + + // With explicit --range: the warning is suppressed. + cargo_bin_cmd!("straymark") + .args([ + "charter", "audit", "CHARTER-01", "--prepare", "--range", "HEAD~1..HEAD", "--path", + ]) + .arg(dir.path().to_str().unwrap()) + .assert() + .success() + .stderr(predicate::str::contains("completed batches").not()); +} diff --git a/cli/tests/charter_test.rs b/cli/tests/charter_test.rs index ba51bcff..191f3f29 100644 --- a/cli/tests/charter_test.rs +++ b/cli/tests/charter_test.rs @@ -1059,3 +1059,31 @@ fn charter_new_empty_slug_flag_falls_back_to_title() { assert!(dir.path().join(".straymark/charters/01-hello-world.md").exists()); } + +#[test] +fn charter_status_omits_stale_phase2_section() { + // #207 Part 2: drift-check and telemetry have shipped; `charter status` + // must no longer advertise them as "not yet available". + let dir = TempDir::new().unwrap(); + setup_straymark_with_charter_template(dir.path()); + + cargo_bin_cmd!("straymark") + .arg("charter") + .arg("new") + .arg("--title") + .arg("Phase Two") + .arg(dir.path().to_str().unwrap()) + .assert() + .success(); + + cargo_bin_cmd!("straymark") + .arg("charter") + .arg("status") + .arg("CHARTER-01-phase-two") + .arg("--path") + .arg(dir.path().to_str().unwrap()) + .assert() + .success() + .stdout(predicate::str::contains("not yet available").not()) + .stdout(predicate::str::contains("planned cli-3.7.0").not()); +} diff --git a/dist/.agent/workflows/straymark-audit-prompt.md b/dist/.agent/workflows/straymark-audit-prompt.md index e8900c9b..df91a8e0 100644 --- a/dist/.agent/workflows/straymark-audit-prompt.md +++ b/dist/.agent/workflows/straymark-audit-prompt.md @@ -38,6 +38,8 @@ The CLI writes the resolved prompt to: The prompt is self-contained: it embeds the Charter content, the originating AILOGs, the git diff over the resolved range (default `origin/main..HEAD`, falls back to `HEAD~1..HEAD` if no upstream is reachable), and the discipline rules (REGLA ABSOLUTA — SOLO LECTURA, evidence-citation, severity calibration). The prompt template lifts the seven universal sections from Sentinel's pre-StrayMark audit skill and parameterizes the project-specific hardcodes. +> Multi-batch Charters — pass an explicit `--range`. When auditing one phase of a Charter whose earlier phases already merged to the base branch, the default `origin/main..HEAD` excludes the already-merged commits and the prompt silently under-covers the phase. Pass `--range ..HEAD` so all of the phase's commits are in the diff. The CLI prints a warning when it detects completed batches in the Charter's Batch Ledger and no explicit range was given. + The CLI does NOT invoke any LLM. It only resolves placeholders. ### 3. Notify the operator diff --git a/dist/.claude/skills/straymark-audit-prompt/SKILL.md b/dist/.claude/skills/straymark-audit-prompt/SKILL.md index 467983f7..c5c63491 100644 --- a/dist/.claude/skills/straymark-audit-prompt/SKILL.md +++ b/dist/.claude/skills/straymark-audit-prompt/SKILL.md @@ -40,6 +40,8 @@ The CLI writes the resolved prompt to: The prompt is self-contained: it embeds the Charter content, the originating AILOGs, the git diff over the resolved range (default `origin/main..HEAD`, falls back to `HEAD~1..HEAD` if no upstream is reachable), and the discipline rules (REGLA ABSOLUTA — SOLO LECTURA, evidence-citation, severity calibration). The prompt template lifts the seven universal sections from Sentinel's pre-StrayMark audit skill and parameterizes the project-specific hardcodes. +> **Multi-batch Charters — pass an explicit `--range`.** When auditing one phase of a Charter whose earlier phases already merged to the base branch, the default `origin/main..HEAD` *excludes* the already-merged commits and the prompt silently under-covers the phase. Pass `--range ..HEAD` so all of the phase's commits are in the diff. The CLI prints a warning when it detects completed batches in the Charter's Batch Ledger and no explicit range was given. + The CLI does NOT invoke any LLM. It only resolves placeholders. ### 3. Notify the operator diff --git a/dist/.codex/skills/straymark-audit-prompt/SKILL.md b/dist/.codex/skills/straymark-audit-prompt/SKILL.md index a60edfb7..ce1a8b3f 100644 --- a/dist/.codex/skills/straymark-audit-prompt/SKILL.md +++ b/dist/.codex/skills/straymark-audit-prompt/SKILL.md @@ -39,6 +39,8 @@ The CLI writes the resolved prompt to: The prompt is self-contained: it embeds the Charter content, the originating AILOGs, the git diff over the resolved range (default `origin/main..HEAD`, falls back to `HEAD~1..HEAD` if no upstream is reachable), and the discipline rules (REGLA ABSOLUTA — SOLO LECTURA, evidence-citation, severity calibration). The prompt template lifts the seven universal sections from Sentinel's pre-StrayMark audit skill and parameterizes the project-specific hardcodes. +> **Multi-batch Charters — pass an explicit `--range`.** When auditing one phase of a Charter whose earlier phases already merged to the base branch, the default `origin/main..HEAD` *excludes* the already-merged commits and the prompt silently under-covers the phase. Pass `--range ..HEAD` so all of the phase's commits are in the diff. The CLI prints a warning when it detects completed batches in the Charter's Batch Ledger and no explicit range was given. + The CLI does NOT invoke any LLM. It only resolves placeholders. ### 3. Notify the operator diff --git a/dist/.gemini/skills/straymark-audit-prompt/SKILL.md b/dist/.gemini/skills/straymark-audit-prompt/SKILL.md index a60edfb7..ce1a8b3f 100644 --- a/dist/.gemini/skills/straymark-audit-prompt/SKILL.md +++ b/dist/.gemini/skills/straymark-audit-prompt/SKILL.md @@ -39,6 +39,8 @@ The CLI writes the resolved prompt to: The prompt is self-contained: it embeds the Charter content, the originating AILOGs, the git diff over the resolved range (default `origin/main..HEAD`, falls back to `HEAD~1..HEAD` if no upstream is reachable), and the discipline rules (REGLA ABSOLUTA — SOLO LECTURA, evidence-citation, severity calibration). The prompt template lifts the seven universal sections from Sentinel's pre-StrayMark audit skill and parameterizes the project-specific hardcodes. +> **Multi-batch Charters — pass an explicit `--range`.** When auditing one phase of a Charter whose earlier phases already merged to the base branch, the default `origin/main..HEAD` *excludes* the already-merged commits and the prompt silently under-covers the phase. Pass `--range ..HEAD` so all of the phase's commits are in the diff. The CLI prints a warning when it detects completed batches in the Charter's Batch Ledger and no explicit range was given. + The CLI does NOT invoke any LLM. It only resolves placeholders. ### 3. Notify the operator diff --git a/dist/.straymark/templates/charter/charter-template.md b/dist/.straymark/templates/charter/charter-template.md index 328285e3..3c3d8fda 100644 --- a/dist/.straymark/templates/charter/charter-template.md +++ b/dist/.straymark/templates/charter/charter-template.md @@ -150,13 +150,13 @@ follow-up insights are captured if the risk surfaces lessons for a later cycle.] a bounded code-level fix, see STRAYMARK.md §15.B (post-close Batch N.4 amendment) and `straymark charter amend` instead of opening a new Charter. 7. Local verification passes clean. -8. **Auto-checklist drift** (when Phase 2 of the CLI roadmap ships): - `straymark charter drift CHARTER-NN ` to detect drifts between declared - and modified files **before** commit. If it reports omissions, complete the work +8. **Auto-checklist drift**: + `straymark charter drift CHARTER-NN --range ` to detect drifts between + declared and modified files **before** commit (the range is optional; it defaults + to `HEAD~1..HEAD`). If it reports omissions, complete the work or document in the AILOG under `## Risk` as `R (new, not in Charter)`. If it reports scope expansion, document in the AILOG the reason (mock updates, generated - files, drift fix pre-existing, etc.). Until Phase 2 ships, run Sentinel's - `check-plan-drift.sh` manually for the same effect. + files, drift fix pre-existing, etc.). 9. Commit + push + open PR. ## Charter Closure @@ -171,10 +171,9 @@ When closing this Charter: stale and confuses future readers (PLAN-07 of Sentinel demonstrated the failure mode that this step prevents). -2. **Post-merge drift check** (automated when Phase 2 ships + manual review): - - Run `straymark charter drift CHARTER-NN origin/main..HEAD` (Phase 2) or the - equivalent Sentinel script, and validate the output is clean or that all - drifts are documented in the AILOG. +2. **Post-merge drift check**: + - Run `straymark charter drift CHARTER-NN --range origin/main..HEAD`, and + validate the output is clean or that all drifts are documented in the AILOG. - This catches the rare case where drift is introduced post-merge (squash mangling, admin amendments, etc.) and the atomic step in #1 could not apply. @@ -241,8 +240,8 @@ v3 addition" — the partition was Sentinel's iteration log, not structural). Sentinel 2026-05-02-001 formalized the gap and proposed format v4 (this template embodies it). -6. Auto-checklist drift (`straymark charter drift`, Phase 2 of the CLI roadmap; - Sentinel had `scripts/check-plan-drift.sh`) runs in pre-commit (Tasks #7) and at +6. Auto-checklist drift (`straymark charter drift`; Sentinel originally had + `scripts/check-plan-drift.sh`) runs in pre-commit (Tasks #7) and at Charter closure. Detects OMISSION drifts (file declared, not touched) and SCOPE EXPANSION drifts (file touched, not declared). Reason: external auditors caught implementation-gap and hallucination drifts that the implementer did not document diff --git a/dist/.straymark/templates/charter/i18n/es/charter-template.md b/dist/.straymark/templates/charter/i18n/es/charter-template.md index 99fa5789..5fe046b4 100644 --- a/dist/.straymark/templates/charter/i18n/es/charter-template.md +++ b/dist/.straymark/templates/charter/i18n/es/charter-template.md @@ -151,13 +151,13 @@ captura el follow-up si el riesgo destapa lecciones para un ciclo posterior.] cualquier `### Batch N` que quede como `(pending)`. Saltar este paso en Charters de un solo lote — `## Acciones Realizadas` en el AILOG basta. 7. Verification local pasa limpio. -8. **Auto-checklist drift** (cuando entregue Fase 2 del CLI roadmap): - `straymark charter drift CHARTER-NN ` para detectar drifts entre lo declarado - y lo modificado **antes** del commit. Si reporta omisiones, completar el trabajo +8. **Auto-checklist drift**: + `straymark charter drift CHARTER-NN --range ` para detectar drifts entre lo + declarado y lo modificado **antes** del commit (el rango es opcional; por defecto + `HEAD~1..HEAD`). Si reporta omisiones, completar el trabajo o documentar en AILOG bajo `## Risk` como `R (nuevo, no en Charter)`. Si reporta scope expansion, documentar en AILOG el motivo (mock updates, generated - files, drift fix pre-existente, etc.). Hasta que Fase 2 entregue, correr el - `check-plan-drift.sh` de Sentinel manualmente para el mismo efecto. + files, drift fix pre-existente, etc.). 9. Commit + push + abrir PR. ## Cierre del Charter @@ -171,10 +171,9 @@ Al cerrar este Charter: el Charter coherente con la ejecución; diferirlo deja el Charter stale y confunde a lectores futuros (PLAN-07 de Sentinel demostró el failure mode que este step previene). -2. **Post-merge drift check** (automatizado cuando entregue Fase 2 + revisión manual): - - Correr `straymark charter drift CHARTER-NN origin/main..HEAD` (Fase 2) o el - script de Sentinel equivalente, y validar que el output esté limpio o que - todos los drifts estén documentados en el AILOG. +2. **Post-merge drift check**: + - Correr `straymark charter drift CHARTER-NN --range origin/main..HEAD`, y validar + que el output esté limpio o que todos los drifts estén documentados en el AILOG. - Esto atrapa el caso raro donde drift se introduce post-merge (squash mangling, amendments admin, etc.) y el step atomic en #1 no pudo aplicar. @@ -243,8 +242,8 @@ Sentinel, no estructural). futuros — AIDEC-2026-05-02-001 de Sentinel formalizó el gap y propuso format v4 (este template lo encarna). -6. Auto-checklist drift (`straymark charter drift`, Fase 2 del CLI roadmap; Sentinel - tenía `scripts/check-plan-drift.sh`) corre en pre-commit (Tasks #7) y al cierre +6. Auto-checklist drift (`straymark charter drift`; Sentinel tenía originalmente + `scripts/check-plan-drift.sh`) corre en pre-commit (Tasks #7) y al cierre del Charter. Detecta drifts de OMISIÓN (archivo declarado, no tocado) y de SCOPE EXPANSION (archivo tocado, no declarado). Razón: los auditores externos capturaron drifts de implementation-gap y hallucination que el implementador no documentó diff --git a/dist/.straymark/templates/charter/i18n/zh-CN/charter-template.md b/dist/.straymark/templates/charter/i18n/zh-CN/charter-template.md index cec02789..4d7de3fd 100644 --- a/dist/.straymark/templates/charter/i18n/zh-CN/charter-template.md +++ b/dist/.straymark/templates/charter/i18n/zh-CN/charter-template.md @@ -142,12 +142,11 @@ curl -X PUT "https://${SERVICE_HOST}/api/v1/.../..." \ `### Batch N`。对于单批次 Charter,请跳过此步骤——AILOG 中的 `## 执行的操作` 已足够。 7. 本地验证通过且干净. -8. **自动检查清单漂移**(当 CLI 路线图的第 2 阶段发布时): - `straymark charter drift CHARTER-NN ` 在提交**之前**检测声明的文件 - 与修改的文件之间的漂移。如果它报告遗漏,请完成工作或在 AILOG 的 - `## Risk` 下记录为 `R (new, not in Charter)`。如果它报告范围扩展, - 请在 AILOG 中记录原因(mock 更新、生成的文件、漂移修复预先存在等)。 - 在第 2 阶段发布之前,手动运行 Sentinel 的 `check-plan-drift.sh` 以获得相同效果。 +8. **自动检查清单漂移**: + `straymark charter drift CHARTER-NN --range ` 在提交**之前**检测声明的文件 + 与修改的文件之间的漂移(范围可选;默认为 `HEAD~1..HEAD`)。如果它报告遗漏, + 请完成工作或在 AILOG 的 `## Risk` 下记录为 `R (new, not in Charter)`。 + 如果它报告范围扩展,请在 AILOG 中记录原因(mock 更新、生成的文件、漂移修复预先存在等)。 9. 提交 + 推送 + 打开 PR. ## Charter 关闭 @@ -161,10 +160,9 @@ curl -X PUT "https://${SERVICE_HOST}/api/v1/.../..." \ 会使 Charter 变得陈旧,并使未来的读者感到困惑(Sentinel 的 PLAN-07 演示了此步骤所防止的失败模式)。 -2. **合并后漂移检查**(第 2 阶段发布时自动化 + 手动审查): - - 运行 `straymark charter drift CHARTER-NN origin/main..HEAD`(第 2 阶段)或 - 等效的 Sentinel 脚本,并验证输出是干净的,或所有 - 漂移都已在 AILOG 中记录。 +2. **合并后漂移检查**: + - 运行 `straymark charter drift CHARTER-NN --range origin/main..HEAD`,并验证 + 输出是干净的,或所有漂移都已在 AILOG 中记录。 - 这捕获了在合并后引入漂移的罕见情况(squash 改写、管理员修订等), 而 #1 中的原子步骤无法应用。 @@ -225,8 +223,8 @@ curl -X PUT "https://${SERVICE_HOST}/api/v1/.../..." \ 读者感到困惑 — Sentinel 2026-05-02-001 的 AIDEC 形式化了该差距 并提出了格式 v4(此模板体现了它)。 -6. 自动检查清单漂移(`straymark charter drift`,CLI 路线图的第 2 阶段; - Sentinel 有 `scripts/check-plan-drift.sh`)在 pre-commit(任务 #7)和 +6. 自动检查清单漂移(`straymark charter drift`;Sentinel 最初有 + `scripts/check-plan-drift.sh`)在 pre-commit(任务 #7)和 Charter 关闭时运行。检测 OMISSION 漂移(声明的文件未触及)和 SCOPE EXPANSION 漂移(触及的文件未声明)。原因:外部审计员捕获了实现者 未在其 AILOG 中记录的 implementation-gap 和 hallucination 漂移。 diff --git a/docs/adopters/CLI-REFERENCE.md b/docs/adopters/CLI-REFERENCE.md index 06d28038..9292fa16 100644 --- a/docs/adopters/CLI-REFERENCE.md +++ b/docs/adopters/CLI-REFERENCE.md @@ -754,7 +754,7 @@ Two steps, each invokable independently: | Argument/Flag | Default | Description | |---|---|---| | `` | — | Same resolution rules as `charter status` | -| `--range` | `origin/main..HEAD` (with fallback to `origin/master..HEAD`, then `HEAD~1..HEAD` with warning) | Git revision range the auditors review. The default captures the full feature-branch implementation set; explicit `--range ` overrides without probing for upstream. | +| `--range` | `origin/main..HEAD` (with fallback to `origin/master..HEAD`, then `HEAD~1..HEAD` with warning) | Git revision range the auditors review. The default captures the full feature-branch implementation set; explicit `--range ` overrides without probing for upstream. **Multi-batch pitfall:** for a phase-scoped audit of a Charter whose earlier phases already merged to the base branch, the default `origin/main..HEAD` *excludes* the merged commits and silently under-covers the phase — pass an explicit `--range ..HEAD` to span it. `--prepare` prints a warning when it detects completed batches and no explicit range. | | `--prepare` | off (default action when no other flag) | Run step 1. Mutually exclusive with `--merge-reports`. | | `--merge-reports` | off | Run step 2. Mutually exclusive with `--prepare`. | | `--merge-into ` | — | With `--merge-reports`: append the `external_audit:` array directly into the telemetry YAML at `` instead of printing to stdout. The CLI rejects re-audit (telemetry already has the key) with a clear error. | diff --git a/docs/i18n/es/adopters/CLI-REFERENCE.md b/docs/i18n/es/adopters/CLI-REFERENCE.md index 3ba6edf0..a2537532 100644 --- a/docs/i18n/es/adopters/CLI-REFERENCE.md +++ b/docs/i18n/es/adopters/CLI-REFERENCE.md @@ -668,7 +668,7 @@ Dos pasos, cada uno invocable independientemente: | Argumento/Flag | Default | Descripción | |---|---|---| | `` | — | Mismas reglas de resolución que `charter status`. | -| `--range` | `origin/main..HEAD` (con fallback a `origin/master..HEAD`, luego `HEAD~1..HEAD` con warning) | Rango git que los auditores revisan. El default captura el set completo de commits de la feature branch; el override explícito vía `--range ` no prueba upstream. | +| `--range` | `origin/main..HEAD` (con fallback a `origin/master..HEAD`, luego `HEAD~1..HEAD` con warning) | Rango git que los auditores revisan. El default captura el set completo de commits de la feature branch; el override explícito vía `--range ` no prueba upstream. **Pitfall multi-batch:** para una auditoría phase-scoped de un Charter cuyas fases anteriores ya se mergearon a la rama base, el default `origin/main..HEAD` *excluye* los commits mergeados y sub-cubre la fase silenciosamente — pasa un `--range ..HEAD` explícito para abarcarla. `--prepare` imprime un aviso cuando detecta batches completados sin rango explícito. | | `--prepare` | off (acción default cuando ningún otro flag se pasa) | Corre el paso 1. Mutuamente excluyente con `--merge-reports`. | | `--merge-reports` | off | Corre el paso 2. Mutuamente excluyente con `--prepare`. | | `--merge-into ` | — | Con `--merge-reports`: anexa el array `external_audit:` directamente a la telemetría YAML en `` en lugar de imprimir a stdout. El CLI rechaza re-audit (la telemetría ya tiene la clave) con error claro. | diff --git a/docs/i18n/zh-CN/adopters/CLI-REFERENCE.md b/docs/i18n/zh-CN/adopters/CLI-REFERENCE.md index 34ee53fd..95102177 100644 --- a/docs/i18n/zh-CN/adopters/CLI-REFERENCE.md +++ b/docs/i18n/zh-CN/adopters/CLI-REFERENCE.md @@ -686,7 +686,7 @@ OK `### Batch 5` written. | 参数/标志 | 默认值 | 描述 | |---|---|---| | `` | — | 与 `charter status` 相同的解析规则。 | -| `--range` | `HEAD~1..HEAD` | 审计员将审查的 git 修订范围。 | +| `--range` | `origin/main..HEAD`(回退到 `origin/master..HEAD`,再到 `HEAD~1..HEAD` 并告警) | 审计员将审查的 git 修订范围。**多批次陷阱:** 对于早期阶段已合并到基础分支的章程,做按阶段审计时,默认的 `origin/main..HEAD` 会*排除*已合并的提交,从而静默地覆盖不足——请传入显式的 `--range <章程首个提交>..HEAD` 以覆盖整个阶段。当 `--prepare` 检测到已完成批次且未指定显式范围时会打印告警。 | | `--calibrate` | off | 运行步骤 2。与 `--finalize` 互斥。 | | `--finalize` | off | 运行步骤 3。与 `--calibrate` 互斥。 | | `--path` | `.` | 项目目录。 |