Skip to content

Commit bcaa491

Browse files
montfortclaude
andauthored
fix(cli): cli-3.12.1 — validator accepts TDE identified status (closes #130) (#131) (#133)
Latent bug exposed by #129's TDE activation trigger: `straymark new --doc-type tde` shipped documents with the canonical `status: identified` (per TEMPLATE-TDE.md and DOCUMENTATION-POLICY.md §6), but `straymark validate` rejected them with META-003. The validator's hardcoded VALID_STATUSES was missing the only non-`draft`/non-`accepted` default in the type matrix. Fixed (CLI): - validation.rs:45 — VALID_STATUSES now includes `identified` alongside draft/review/accepted/superseded/deprecated. Flat enum still applies to all 12+ doc types; per-type validation sets deferred to v1 against the same second-adopter gate as the follow-ups CLI. - cli/tests/validate_test.rs — new regression test `test_validate_tde_document_valid()` exercises `status: identified`. TDD red→green verified: test fails on unpatched validator, passes after the fix. Changed (Framework, no separate version bump — ships with fw-4.13.0): - DOCUMENTATION-POLICY.md §3 "Document Statuses" (EN + ES + zh-CN): lifecycle diagram extended to show `identified` as a TDE-only entry state. Reconciles §3 prose with the §6 per-type defaults table that already declared TDE → `identified`. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 2ae3802 commit bcaa491

14 files changed

Lines changed: 93 additions & 22 deletions

File tree

CHANGELOG.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ and this project uses [independent versioning](README.md#versioning) for Framewo
77

88
---
99

10+
## CLI 3.12.1 — Validator accepts TDE `identified` status
11+
12+
Closes [#130](https://github.com/StrangeDaysTech/straymark/issues/130). Latent in `cli-3.12.0` and earlier; fully exposed by the `fw-4.13.0` TDE activation trigger (which makes TDE creation likely). Surfaced empirically while verifying #128: a freshly-created TDE via `straymark new --doc-type tde` shipped with the canonical `status: identified` per `TEMPLATE-TDE.md` + `DOCUMENTATION-POLICY.md §6`, but `straymark validate` immediately rejected it with `META-003 Invalid status 'identified'`. Validator's hardcoded enumeration was missing the only non-`draft`/non-`accepted` default in the type matrix.
13+
14+
### Fixed (CLI)
15+
16+
- **`validation.rs:45`**`VALID_STATUSES` now includes `identified` alongside `draft`, `review`, `accepted`, `superseded`, `deprecated`. No per-doc-type dispatch yet — flat list still applies to all 12+ document types, but every documented default now lives in the list. A per-type validation set is deferred to v1 against a second-adopter validation gate (same gate as the follow-ups CLI per `FOLLOW-UPS-BACKLOG-PATTERN.md`).
17+
- **`cli/tests/validate_test.rs`** — new regression test `test_validate_tde_document_valid()` exercises the canonical `status: identified` flow. The test fails against unpatched validators (proven during TDD) and would have caught the bug at `fw-4.13.0` ship time.
18+
19+
### Changed (Framework)
20+
21+
- **`DOCUMENTATION-POLICY.md §3 "Document Statuses"`** (EN + ES + zh-CN) — lifecycle diagram and table extended to document `identified` as the TDE-only entry state. Functionally equivalent to `draft` for lifecycle gating, semantically distinct so adopter analytics can distinguish "agent-discovered debt" from "human-drafted document". Reconciles §3 prose with the §6 per-type default table that already declared TDE → `identified`. Ships as part of `fw-4.13.0` — no separate framework bump.
22+
23+
### Adopter guidance
24+
25+
- Adopters on `cli-3.12.0` or earlier with one or more TDE documents in `06-evolution/technical-debt/` will see `straymark validate` start passing once they upgrade via `straymark update-cli`. No document edits required; the canonical `status: identified` is now accepted.
26+
- Operators who manually changed TDE documents to `status: draft` to work around the bug may revert to `status: identified` for semantic clarity, but the workaround keeps working too.
27+
28+
---
29+
1030
## Framework 4.13.0 — TDE activation trigger
1131

1232
Closes [#128](https://github.com/StrangeDaysTech/straymark/issues/128). The TDE (Technical Debt) document type had structural shape — template, destination folder, autonomy boundary — but no operational activation trigger in the agent-facing governance. Empirical signal from the Sentinel adopter (primary, fw-4.12.0): zero TDEs created across 13 closed Charters despite ≥7 instances of transversal debt being routed through parallel mechanisms (`R<N> (new, not in Charter)` in AILOG `§Risk`, or follow-ups in `follow-ups-backlog.md`). This release adds the trigger and the `R<N>` vs TDE disambiguation, plus a promotion path from the follow-ups backlog. Governance-docs-only — no CLI changes; the `straymark debt list/status/close` subcommand trio is deferred to v1 (same gate as the follow-ups CLI per `FOLLOW-UPS-BACKLOG-PATTERN.md`).

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ StrayMark uses independent version tags for each component:
275275
| Component | Tag prefix | Example | Includes |
276276
|-----------|-----------|---------|----------|
277277
| Framework | `fw-` | `fw-4.13.0` | Templates (12 types), governance, directives, Charter template + schema |
278-
| CLI | `cli-` | `cli-3.12.0` | The `straymark` binary |
278+
| CLI | `cli-` | `cli-3.12.1` | The `straymark` binary |
279279

280280
Check installed versions with `straymark status` or `straymark about`.
281281

cli/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "straymark-cli"
3-
version = "3.12.0"
3+
version = "3.12.1"
44
edition = "2021"
55
description = "CLI for StrayMark — the cognitive discipline your AI-assisted projects need"
66
license = "MIT"

cli/src/validation.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,18 @@ impl ValidationResult {
4141
}
4242
}
4343

44-
/// Valid status values per DOCUMENTATION-POLICY.md
45-
const VALID_STATUSES: &[&str] = &["draft", "review", "accepted", "superseded", "deprecated"];
44+
/// Valid status values per DOCUMENTATION-POLICY.md §3 lifecycle + §6 per-type defaults.
45+
/// `identified` is the canonical TDE entry state (agent-driven discovery, awaits
46+
/// human prioritization); functionally equivalent to `draft` for lifecycle gating
47+
/// but semantically distinct in adopter analytics.
48+
const VALID_STATUSES: &[&str] = &[
49+
"draft",
50+
"identified",
51+
"review",
52+
"accepted",
53+
"superseded",
54+
"deprecated",
55+
];
4656

4757
/// Valid risk levels
4858
const VALID_RISK_LEVELS: &[&str] = &["low", "medium", "high", "critical"];

cli/tests/validate_test.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,29 @@ fn test_validate_dpia_document_valid() {
349349
.stdout(predicate::str::contains("passed validation"));
350350
}
351351

352+
/// Regression test for issue #130: TDE documents ship with `status: identified`
353+
/// per TEMPLATE-TDE.md and DOCUMENTATION-POLICY.md §6 — the validator must accept
354+
/// it as a valid lifecycle entry state.
355+
#[test]
356+
fn test_validate_tde_document_valid() {
357+
let dir = TempDir::new().unwrap();
358+
setup_straymark(dir.path());
359+
360+
create_doc(
361+
dir.path(),
362+
"06-evolution/technical-debt",
363+
"TDE-2026-05-11-001-architectural-refactor.md",
364+
"id: TDE-2026-05-11-001\ntitle: Architectural Refactor Debt\nstatus: identified\ncreated: 2026-05-11\nagent: claude-code-v1.0\nconfidence: high\nreview_required: false\nrisk_level: medium\ntype: architecture\nimpact: high\neffort: medium\ntags:\n - architecture\nrelated: []\npriority: null\nassigned_to: null",
365+
);
366+
367+
let mut cmd = Command::cargo_bin("straymark").unwrap();
368+
cmd.arg("validate")
369+
.arg(dir.path().to_str().unwrap())
370+
.assert()
371+
.success()
372+
.stdout(predicate::str::contains("passed validation"));
373+
}
374+
352375
/// F2.QA.02.01 — Also verify that MCARD and DPIA fail without review_required: true
353376
#[test]
354377
fn test_validate_mcard_requires_review() {

dist/.straymark/00-governance/DOCUMENTATION-POLICY.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,25 @@ related:
149149
## 3. Document Statuses
150150

151151
```
152-
draft ──────► accepted ──────► deprecated
153-
│ │
154-
│ ▼
155-
└──────► superseded
152+
identified ──┐
153+
├──► draft ──────► accepted ──────► deprecated
154+
│ │ │
155+
│ │ ▼
156+
│ └──────► superseded
157+
158+
└──► (TDE-only entry state, see §6)
156159
```
157160
158161
| Status | Description |
159162
|--------|-------------|
163+
| `identified` | Entry state for agent-driven discovery types (TDE today). Functionally equivalent to `draft` for lifecycle gating — a human reviewer is expected to prioritize and promote it. Semantically distinct so adopter analytics can distinguish "agent found this debt" from "human is drafting a deliberate doc". |
160164
| `draft` | In draft, pending review |
161165
| `accepted` | Approved and current |
162166
| `deprecated` | Obsolete, but kept as reference |
163167
| `superseded` | Replaced by another document |
164168
169+
The per-type default status mapping lives in §6 — most types enter at `draft` or `accepted`, but TDE enters at `identified` per the agent-autonomy boundary (agent identifies, human prioritizes).
170+
165171
---
166172
167173
## 3.5 Recording Approval

dist/.straymark/00-governance/i18n/es/DOCUMENTATION-POLICY.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,25 @@ related:
149149
## 3. Estados de Documentos
150150

151151
```
152-
draft ──────► accepted ──────► deprecated
153-
│ │
154-
│ ▼
155-
└──────► superseded
152+
identified ──┐
153+
├──► draft ──────► accepted ──────► deprecated
154+
│ │ │
155+
│ │ ▼
156+
│ └──────► superseded
157+
158+
└──► (estado de entrada TDE-only, ver §6)
156159
```
157160
158161
| Estado | Descripción |
159162
|--------|-------------|
163+
| `identified` | Estado de entrada para los tipos de descubrimiento dirigidos por agente (TDE hoy). Funcionalmente equivalente a `draft` para el lifecycle gating — se espera que un revisor humano lo priorice y lo promueva. Semánticamente distinto para que las analíticas del adopter puedan distinguir "el agente encontró esta deuda" de "un humano está redactando un documento deliberado". |
160164
| `draft` | En borrador, pendiente de revisión |
161165
| `accepted` | Aprobado y vigente |
162166
| `deprecated` | Obsoleto, pero se mantiene como referencia |
163167
| `superseded` | Reemplazado por otro documento |
164168
169+
El mapeo de status por defecto por tipo vive en §6 — la mayoría de tipos entran en `draft` o `accepted`, pero TDE entra en `identified` por la frontera de autonomía del agente (el agente identifica, el humano prioriza).
170+
165171
---
166172
167173
## 3.5 Registro de Aprobación

dist/.straymark/00-governance/i18n/zh-CN/DOCUMENTATION-POLICY.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,19 +149,25 @@ related:
149149
## 3. 文档状态
150150

151151
```
152-
draft ──────► accepted ──────► deprecated
153-
│ │
154-
│ ▼
155-
└──────► superseded
152+
identified ──┐
153+
├──► draft ──────► accepted ──────► deprecated
154+
│ │ │
155+
│ │ ▼
156+
│ └──────► superseded
157+
158+
└──► (TDE 专用入口状态,见 §6)
156159
```
157160
158161
| 状态 | 说明 |
159162
|------|------|
163+
| `identified` | 由代理驱动发现的类型的入口状态(今日仅 TDE)。在生命周期校验上等同于 `draft`——期望人工审阅者来排定优先级并推进。语义上有所区分,以便 adopter 的分析能够区分"代理发现了此债务"与"人工正在起草一份有意识的文档"。 |
160164
| `draft` | 草稿中,待审核 |
161165
| `accepted` | 已批准且为当前有效版本 |
162166
| `deprecated` | 已废弃,但保留作为参考 |
163167
| `superseded` | 已被其他文档替代 |
164168
169+
按类型的默认 status 映射位于 §6——大多数类型以 `draft` 或 `accepted` 进入,但 TDE 因代理自主权边界(代理识别、人工排序)以 `identified` 进入。
170+
165171
---
166172
167173
## 3.5 审批记录

docs/adopters/CLI-REFERENCE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ StrayMark uses **independent version tags** for each component:
4949
| Component | Tag prefix | Example | What it includes |
5050
|-----------|-----------|---------|------------------|
5151
| Framework | `fw-` | `fw-4.13.0` | Templates (12 types), governance docs, directives, Charter template + schema |
52-
| CLI | `cli-` | `cli-3.12.0` | The `straymark` binary |
52+
| CLI | `cli-` | `cli-3.12.1` | The `straymark` binary |
5353

5454
Framework and CLI are released independently. A framework update does not require a CLI update, and vice versa.
5555

0 commit comments

Comments
 (0)