Skip to content

Commit aefbc3e

Browse files
montfortclaude
andauthored
feat(cli): cli-3.19.0 — straymark followups namespace (list/status/drift/promote) (#218)
CLI half of ADR-2026-06-03-001 (companion to fw-4.21.0). The follow-ups backlog registry stops being invisible to tooling: - followups.rs: lenient registry parser (pure functions; move target straymark-core for Loom M0). v0 registries parse forever; writes are surgical text edits that preserve unknown frontmatter fields. - followups list/status: filterable table + registry pulse with counters recomputed on the fly (stale frontmatter flagged — #214 Signal 2). - followups drift: native replacement for the deprecated adopter-side check-followups-drift.sh. --apply extracts per-AILOG, registers ids, recomputes CLI-owned counters and upgrades v0→v1 in place. Anti-noise: closure-marked bullets land as suspected-closed (#214 Signal 1). - followups promote: FU → TDE with promoted_from_followup traceability; prioritization stays human (AGENT-RULES.md §3). - explore TUI: synthetic Follow-ups group (sub-node per bucket, FU badge). - status: Follow-ups block with recomputed breakdown + blocking alert. - split_frontmatter moved charter.rs → utils.rs (one shared definition). - 42 new tests (25 unit + 17 integration); suite at 611 green. - Version bump cli-3.19.0 + docs (CLI-REFERENCE + README + CLAUDE.md, EN/ES/zh-CN). The /straymark-followups skill ships in a follow-up framework release (tracked via dogfooded FU in PR 4). Refs #214, #135 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent c9a5242 commit aefbc3e

25 files changed

Lines changed: 3353 additions & 31 deletions

CHANGELOG.md

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

88
---
99

10+
## CLI 3.19.0 — `straymark followups` namespace (companion to fw-4.21.0)
11+
12+
Ships the native CLI surface for the follow-ups backlog registry crystallized in fw-4.21.0 ([`ADR-2026-06-03-001`](docs/decisions/ADR-2026-06-03-followups-first-class.md), driven by [#214](https://github.com/StrangeDaysTech/straymark/issues/214)). The registry stops being invisible to tooling: it gains a CLI namespace, a synthetic group in `explore`, and a block in `status`. Collapses Tiers 2 and 4 of [#135](https://github.com/StrangeDaysTech/straymark/issues/135) into one native implementation; Tier 3 (`charter close` soft-integration) remains gated.
13+
14+
### Added (CLI)
15+
16+
- **`straymark followups list [--bucket] [--status] [--severity] [--label]`** *(new subcommand group)* — filterable table of registry entries (FU id, status, severity, bucket, destination, description). Malformed `### FU-` headings warn without failing.
17+
- **`straymark followups status [FU-NNN]`** — registry pulse with counters **recomputed on the fly** from actual entry statuses (trustworthy even when the file frontmatter is stale — divergence is flagged), per-bucket breakdown, blocking/suspected-closed alerts, and advisory schema validation against `follow-ups-backlog.schema.v1.json`. With an id: entry field detail.
18+
- **`straymark followups drift [--apply] [--scan-all] [--range]`** — native replacement for the deprecated adopter-side `check-followups-drift.sh` (~296 lines of bash retired). Per-AILOG granularity via `fully_extracted_ailogs` (0 false positives across 76 AILOGs in the reference adopter). `--apply` extracts into `## Bucket: ready`, registers the AILOG, **recomputes the CLI-owned counters** (#214 Signal 2) and upgrades v0 registries to v1 in place — non-destructively (unknown frontmatter fields survive; writes are surgical text edits, never a re-serialization). **Anti-noise refinement** (#214 Signal 1): bullets carrying a closure marker (`closed in-Charter`, `fixed in batch N`, a backtick-wrapped commit hash) land as **`suspected-closed`** instead of `ready`/TBD noise — across both documented occurrences that noise was 20–75% per batch. Seeds the registry from the framework template on first `--apply`.
19+
- **`straymark followups promote FU-NNN [--title]`** — automates the FU → TDE elevation: creates the TDE from the framework template with `promoted_from_followup: FU-NNN`, flips the entry to `promoted` with `Destination`/`Promoted to` → TDE id, recomputes counters. Non-interactive by design (agent-friendly); prioritization stays human per `AGENT-RULES.md §3`.
20+
- **`explore` TUI: synthetic "Follow-ups" group** — the registry file plus one sub-node per non-empty bucket, one entry per FU (badge `FU`; labels surface as tags; `FU-NNN` ids resolve as references). Appears only when the registry exists, mirroring `_charters`.
21+
- **`status`: Follow-ups block** — status breakdown (open / in-progress / suspected-closed / closed+superseded / promoted) recomputed from entry statuses, with a blocking-severity alert; one-line adoption hint when no registry exists.
22+
- **`cli/src/followups.rs`** — lenient registry parser (pure functions, no CLI deps; doc-tagged as the straymark-core move target for Loom M0) + **42 new tests** (25 unit, 17 integration) covering v0 lenient parsing, the v1 dimensions, closure-marker detection, counter recompute, idempotent upgrade, and the promote round-trip.
23+
24+
### Changed (CLI)
25+
26+
- `split_frontmatter` moved from `charter.rs` to `utils.rs` — one shared definition for the Charter and registry parsers.
27+
28+
### Adopter guidance
29+
30+
Run `straymark update` (CLI → `cli-3.19.0`, framework → `fw-4.21.0`). If you maintain a v0 registry: `straymark followups drift --apply` migrates it in one command; then delete the local bash script and point any pre-commit hook at the CLI. The `/straymark-followups` skill ships in a follow-up framework release.
31+
32+
---
33+
1034
## Framework 4.21.0 — Follow-ups backlog becomes a first-class entity (schema v1)
1135

1236
Promotes the follow-ups backlog from documented convention (v0, adopter-side bash) to **first-class framework entity**, following the lane Charter used: canonical schema, shipped agent directives, onboarding-level visibility. Driven by [#214](https://github.com/StrangeDaysTech/straymark/issues/214) (Sentinel post-stage triage at N=91 FUs — extractor noise ×2, silent counter drift, ad-hoc severity) and recorded in [`ADR-2026-06-03-001`](docs/decisions/ADR-2026-06-03-followups-first-class.md), which documents the design-principle #12 reframe: the structural evidence (91 FUs, schema already iterated under empirical pressure, 0 extraction false positives across 76 AILOGs, stable bucket vocabulary, internal Loom roadmap demand) justifies crystallizing as **v1 experimental**; hard stabilization stays gated on a second adopter. The native CLI surface (`straymark followups list/status/drift/promote`) ships in the companion release cli-3.19.0.

CLAUDE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ Users can now run `straymark update-framework` to get the new version.
236236
| `straymark metrics [path]` | Show governance metrics and documentation statistics |
237237
| `straymark analyze [path]` | Analyze code complexity (cognitive + cyclomatic metrics) |
238238
| `straymark analyze declared-vs-wired [path]` | Flag declared symbols (IPC/RPC proxy methods) with no implemented wiring counterpart — config-driven set-difference (POLISH-CHARTER-PATTERN sub-class 5) |
239+
| `straymark followups list [--bucket] [--status] [--severity] [--label]` | List follow-ups registry entries with filters |
240+
| `straymark followups status [FU-NNN]` | Registry pulse (counters recomputed on the fly) or entry detail |
241+
| `straymark followups drift [--apply] [--scan-all]` | Detect/extract AILOGs with unextracted follow-up content (native, anti-noise `suspected-closed`, recomputes CLI-owned counters, upgrades v0→v1) |
242+
| `straymark followups promote FU-NNN` | Elevate an entry to a TDE document with `promoted_from_followup` traceability |
239243
| `straymark audit [path]` | Generate audit trail reports with timeline and traceability |
240244
| `straymark explore [path]` | Interactive TUI documentation browser |
241245
| `straymark about` | Show version and license info |

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ Built-in safeguards ensure humans stay in control:
149149
Built-in commands that turn the discipline into actionable feedback:
150150

151151
- **`straymark charter <new|list|status|close|drift|batch-complete|audit|refresh-suggest|amend>`** — Bounded units of work declared ex-ante, audited ex-post. `close` records post-execution telemetry; `drift` detects file-vs-commit drift with AILOG-aware suppression and (cli-3.13.0+) gates on `### Batch N (pending)` entries in the AILOG `## Batch Ledger`; `batch-complete` (cli-3.13.0+) marks a batch as complete in the ledger for multi-batch Charters (3+ batches or >1 day); `audit` orchestrates a multi-model external review (3-step prepare/calibrate/finalize, orchestration-only — no LLM API calls); `refresh-suggest` (cli-3.14.0+) prints a heuristic recommendation for a pre-declare SpecKit refresh when a multi-Charter module's rolling `r_n_plus_one_emergent_count` mean exceeds a threshold; `amend` (cli-3.14.0+) scaffolds a post-close Batch N.4 amendment (audit-driven remediation) on the same execute branch without opening a new Charter. For IDE-driven workflows, the inline skills `/straymark-audit-prompt` and `/straymark-audit-review` wrap the CLI to surface prompts in the conversation and merge findings into telemetry.
152+
- **`straymark followups <list|status|drift|promote>`** *(cli-3.19.0+)* — First-class follow-ups backlog registry (`.straymark/follow-ups-backlog.md`, schema v1 experimental): `drift --apply` extracts `§Follow-ups` / `R<N> (new)` entries from AILOGs per-AILOG (closure-marked bullets land as `suspected-closed`), counters are CLI-owned and recomputed on every write, and `promote` elevates entries to TDE documents with full traceability. See `STRAYMARK.md §16` and `FOLLOW-UPS-BACKLOG-PATTERN.md`.
152153
- **`straymark approve <doc-id>`** — Record a formal human approval (writes `reviewed_by` / `reviewed_at` / `review_outcome` and the `## Approval` body section in one edit; closes the gap canonized in DOCUMENTATION-POLICY §3.5)
153154
- **`straymark validate`** — 25+ validation rules for document correctness (12 China-specific are scope-aware); `--include-charters` extends to `.straymark/charters/`; `--check-pending-reviews` lists approval backlog (warn-only)
154155
- **`straymark metrics`** — Governance KPIs, review rates, risk distribution, trends
@@ -277,7 +278,7 @@ StrayMark uses independent version tags for each component:
277278
| Component | Tag prefix | Example | Includes |
278279
| --- | --- | --- | --- |
279280
| Framework | `fw-` | `fw-4.21.0` | Templates (12 types), governance, directives, Charter template + schema |
280-
| CLI | `cli-` | `cli-3.18.0` | The `straymark` binary |
281+
| CLI | `cli-` | `cli-3.19.0` | The `straymark` binary |
281282

282283
Check installed versions with `straymark status` or `straymark about`.
283284

@@ -294,6 +295,7 @@ Check installed versions with `straymark status` or `straymark about`.
294295
| `straymark repair [path]` | Restore missing directories and framework files |
295296
| `straymark validate [path]` | Validate documents for compliance and correctness (use `--include-charters` for Charters, `--check-pending-reviews` for approval backlog) |
296297
| `straymark charter <subcommand>` | Manage Charters: `new`, `list`, `status`, `close` (record telemetry), `drift` (file-vs-commit drift with AILOG-awareness + Batch Ledger gate), `batch-complete` (mark a batch as complete in the AILOG `## Batch Ledger` for multi-batch Charters), `audit` (multi-model external review, orchestration-only), `refresh-suggest` (pre-declare SpecKit refresh heuristic for multi-Charter modules, fw-4.16.0+), `amend` (scaffold a post-close Batch N.4 amendment, fw-4.16.0+) |
298+
| `straymark followups <subcommand>` *(cli-3.19.0+)* | Manage the follow-ups backlog registry: `list` (filterable entries), `status` (pulse with CLI-owned counters recomputed on the fly), `drift` (detect/extract unprocessed AILOGs — native replacement for the v0 bash script, with anti-noise `suspected-closed` extraction), `promote` (FU → TDE with `promoted_from_followup` traceability) |
297299
| `straymark approve <doc-id>` | Record a formal human approval on a `review_required: true` document (frontmatter + canonical body section) |
298300
| `straymark compliance [path]` | Check regulatory compliance (EU AI Act, ISO 42001, NIST) |
299301
| `straymark metrics [path]` | Show governance metrics and documentation statistics |

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.18.0"
3+
version = "3.19.0"
44
edition = "2021"
55
description = "CLI for StrayMark — the cognitive discipline your AI-assisted projects need"
66
license = "MIT"

cli/src/charter.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -334,26 +334,9 @@ fn charter_number_from_path(p: &PathBuf) -> Option<u32> {
334334
prefix.parse::<u32>().ok()
335335
}
336336

337-
/// Split a markdown document into (frontmatter, body) at the first pair of `---`
338-
/// delimiters. Returns `None` if the document has no frontmatter block.
339-
/// Accepts both `\n` and `\r\n` line endings on the closing delimiter.
340-
fn split_frontmatter(content: &str) -> Option<(&str, &str)> {
341-
// Opening delimiter: must be at the very start of the file.
342-
let after_open = content.strip_prefix("---\n").or_else(|| content.strip_prefix("---\r\n"))?;
343-
// Closing delimiter: find the first occurrence of `\n---\n` or `\r\n---\r\n`.
344-
let (end, delim_len) = if let Some(idx) = after_open.find("\n---\n") {
345-
(idx, 5)
346-
} else if let Some(idx) = after_open.find("\r\n---\r\n") {
347-
(idx, 7)
348-
} else if let Some(idx) = after_open.find("\n---\r\n") {
349-
(idx, 6)
350-
} else {
351-
return None;
352-
};
353-
let frontmatter = &after_open[..end];
354-
let body = &after_open[end + delim_len..];
355-
Some((frontmatter, body))
356-
}
337+
// `split_frontmatter` moved to `crate::utils` (cli-3.19.0) so the Charter
338+
// parser and the follow-ups registry parser share one definition.
339+
use crate::utils::split_frontmatter;
357340

358341
#[cfg(test)]
359342
mod tests {

0 commit comments

Comments
 (0)