You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Closes Cubeta A of #150 — surfaced by Sentinel after running a single
specs/002-commshub/plan.md through seven consecutive Charters
(CHARTER-07..17, ~1 month). The bridge doc covered Charter declaration
but said nothing about spec maintenance during multi-Charter execution
— and naively re-running /speckit-plan regenerates assertions about
already-shipped user stories that the actual code does not implement.
This patch documents the canonical discipline; Cubeta B (the
straymark spec-drift CLI mechanizing Gate (a) + cross-Charter
lessons-learned per #146 Proposal D) is deferred to a dedicated
post-announcement Charter, tracked separately.
Framework changes (fw-4.14.3):
- dist/.straymark/00-governance/SPECKIT-CHARTER-BRIDGE.md (EN + ES +
zh-CN): new section "Spec maintenance during multi-Charter
execution" with subsections covering when to refresh (4 heuristics),
how to refresh (scope-limited prompt), three mechanical gates (code
validation, hunk-by-hunk review, two-PR split), the explicit
prohibition on re-running /speckit-tasks, Constitution Check
re-evaluation cadence, and the spec-drift CLI roadmap signal.
- Anti-pattern entry against re-running /speckit-tasks added, with
pointer to the safe path.
- docs/contributors/WHAT-IS-A-CHARTER.md §4 Mode A: cross-link to the
new bridge-doc section inserted at the natural decision point
("what happens when a single spec drives many Charters?").
No CLI changes (cli-3.13.1 remains the matching CLI version), no
schemas or templates moved. Sentinel can read the new section before
filling CHARTER-18.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Framework-only patch that closes a governance gap reported by Sentinel after running a single `specs/002-commshub/plan.md` through **seven consecutive Charters** over ~1 month. The bridge doc (`SPECKIT-CHARTER-BRIDGE.md`) covered Charter *declaration* but said nothing about *spec maintenance during multi-Charter execution* — and naively re-running `/speckit-plan` regenerates assertions about already-shipped user stories that the actual code does not implement, propagating stale state into future audits.
13
+
14
+
Ships **Cubeta A** of the issue's two-bucket plan: pure governance documentation. **Cubeta B** (the `straymark spec-drift` CLI that mechanizes Gate (a), plus a cross-Charter `lessons-learned` index per [#146 Proposal D](https://github.com/StrangeDaysTech/straymark/issues/146)) is deferred to a dedicated post-announcement Charter — tracked separately so the context survives.
15
+
16
+
### Added (Framework)
17
+
18
+
-**`dist/.straymark/00-governance/SPECKIT-CHARTER-BRIDGE.md`** (EN + i18n/es + i18n/zh-CN) — new section **"Spec maintenance during multi-Charter execution"** with the empirical anchor (Sentinel CHARTER-07..17 cycle, 12 unreflected learnings). Subsections:
19
+
-**When to refresh** — four heuristics (≥3 closed Charters, ≥4 weeks + ≥2 Charters, `R<N>(new)` count >6, target US touches refined infra). Explicit guidance to *skip* the refresh when none hold.
20
+
-**How to refresh: scope-limited prompt** — name the target phase, list locked sections, cite refinement AILOGs, forbid `tasks.md` regeneration.
21
+
-**Three mechanical gates** — (a) Validation against code reality (diff non-target-phase entities/endpoints vs migrations/handler signatures), (b) Granular hunk-by-hunk review, (c) Two-PR split (refresh PR separate from Charter-fill PR).
22
+
-**Why NOT re-run `/speckit-tasks`** — regenerating destroys `[X]` completion marks and `*CHARTER-NN:* <sha>*` annotations that form the historical trace. Manual edit for the target phase only.
23
+
-**Constitution Check re-evaluation cadence** — codifies per-Charter (recommended) + per-spec-refresh (mandatory) + NOT per-framework-bump alone, closing the implicit-cadence ambiguity reported by Sentinel.
24
+
-**Roadmap: `straymark spec-drift`** — names the deferred CLI explicitly so adopters reading the policy know mechanization of Gate (a) is coming post-announcement.
25
+
-**Anti-pattern entry** — new bullet against re-running `/speckit-tasks` mid-execution, pointing to the new section for the safe path.
26
+
27
+
### Changed (Repo-level docs, not shipped via `straymark init`)
28
+
29
+
-**`docs/contributors/WHAT-IS-A-CHARTER.md`** §4 Mode A — cross-link inserted right after the SpecKit-driven flow diagram, surfacing the "what happens when a single spec drives many Charters?" question with a pointer to the new bridge-doc section. Contributors landing on the conceptual doc now find the operational discipline at the natural decision point.
30
+
-**Governance footers** updated to `v4.14.3` across `QUICK-REFERENCE.md`, `AGENT-RULES.md`, `DOCUMENTATION-POLICY.md`, `C4-DIAGRAM-GUIDE.md`, `FOLLOW-UPS-BACKLOG-PATTERN.md`, `SPECKIT-CHARTER-BRIDGE.md` (EN + ES + zh-CN, plus the top-level `dist/.straymark/QUICK-REFERENCE.md`).
31
+
-**Version tables** in `README.md` (root + i18n) and `CLI-REFERENCE.md` (EN + ES + zh-CN) bumped to `fw-4.14.3`. Canonical-output examples (`Framework updated to fw-4.14.3`, etc.) follow.
32
+
33
+
### Deferred — Cubeta B (post-announcement Charter)
34
+
35
+
The empirical pattern around #150 reinforces the gap surfaced by [#146 Proposal D](https://github.com/StrangeDaysTech/straymark/issues/146) (cross-Charter `lessons-learned` index). Both #146 D and #150 Ask 3 are mechanics that live *above* the Charter as a unit — the missing "cross-Charter knowledge layer". A dedicated Charter post-announcement will design this layer cohesively: lessons-learned index + `straymark spec-drift` CLI + possible umbrella `straymark spec` command. A tracking issue is filed to preserve the context across the announcement cycle.
36
+
37
+
### Why a patch release for docs only
38
+
39
+
`dist/.straymark/00-governance/SPECKIT-CHARTER-BRIDGE.md` is shipped to every adopter via `straymark init`. Without a framework bump, `straymark update-framework` would not bring the new section to existing installations. Sentinel needs the canonical recommendation before filling CHARTER-18 — the ~50% probability of inheriting a critical/high finding from stale-premise inheritance is real and time-sensitive.
40
+
41
+
### Adopter guidance
42
+
43
+
`straymark update-framework` brings the updated bridge doc and footers. No behavior changes: the CLI is unchanged (`cli-3.13.1` remains the matching CLI version), no schemas or templates moved. Adopters running multi-Charter specs should read the new section *before* declaring their next Charter against an aging spec.
Closes [#149](https://github.com/StrangeDaysTech/straymark/issues/149) — surfaced by Sentinel post-CHARTER-17 housekeeping. TDE adopters who keep documents on disk as audit history after the debt is paid had no canonical status to mark the closure; `accepted` / `superseded` / `deprecated` all carry the wrong semantics. The validator rejected `resolved` with `META-003`.
| Cut shipped | Close Charter | `straymark charter close CHARTER-NN` (status: `closed`, telemetry yaml emitted) |
133
133
134
+
## Spec maintenance during multi-Charter execution
135
+
136
+
> **Empirical anchor**: surfaced by [issue #150](https://github.com/StrangeDaysTech/straymark/issues/150) after Sentinel ran a single `specs/002-commshub/plan.md` (committed 2026-04-21) through **seven consecutive Charters** (CHARTER-07 through CHARTER-17, ~1 month). Twelve aprendizajes empíricos that materially impact the next Charter's scope were *not* reflected in the plan. The pattern below codifies what Sentinel discovered before CHARTER-18 fill.
137
+
138
+
The lifecycle map above assumes **one-pass**: SpecKit artifacts are generated once, then Charters are declared and executed. This scales fine for features that produce a single Charter. When a single spec drives many Charters spaced weeks apart, **planning artifacts drift relative to shipped code** — and naively re-running `/speckit-plan` is *worse*, not better: regeneration asserts things about already-shipped user stories that the actual code does not implement, and future readers (auditors, agents, new operators) trust those regenerated artifacts as ground truth.
139
+
140
+
This section answers **how**, not **whether**: what discipline keeps the spec in sync with code during multi-Charter execution **without** the regeneration step lying about the parts that already shipped.
141
+
142
+
### When to refresh
143
+
144
+
A spec-refresh is warranted when *any* of the following hold:
145
+
146
+
1. **≥3 Charters closed against the same spec** — the volume of unreflected execution detail is high enough that the next Charter's scope decisions risk inheriting stale premises.
147
+
2. **≥4 calendar weeks** since the spec was last refreshed (or since initial generation) and ≥2 Charters closed in that window.
148
+
3. **AILOG `## Risk: R<N>(new, not in Charter)` count on the spec exceeds ~6 across closed Charters** — the spec's anticipation of risk has measurably under-described the territory.
149
+
4. **The next Charter's user story touches infrastructure the prior Charters refined empirically** (new tables/migrations created, helpers extracted, contracts crystallized) and the spec describes the pre-refinement state.
150
+
151
+
If none hold and the next Charter targets a fresh sub-system the prior Charters didn't touch, **skip the refresh**. Spec stability has value; refreshing on every Charter creates churn without proportional clarity gain.
152
+
153
+
### How to refresh: scope-limited prompt
154
+
155
+
Do **not** re-run `/speckit-plan` with a blank slate. The regenerated `plan.md` + `research.md` + `data-model.md` + `contracts/` + `quickstart.md` will assert things about already-shipped user stories that the actual code does not implement.
156
+
157
+
Instead, invoke `/speckit-plan` with a **scope-limited prompt** that:
158
+
159
+
1. **Names the target phase explicitly** (e.g., "refresh planning for US5 only — failover + tracking").
160
+
2. **Lists locked sections that must not change** (e.g., "Foundation, US1, US2, US3, US4 sections are immutable — the code shipped against them is the ground truth, not the plan").
161
+
3. **Cites the AILOGs that document refinements** (e.g., "see AILOG-2026-05-11-043 §R5 for the `processed_events` reuse pattern; reflect this in the refreshed data model").
162
+
4. **Forbids regenerating `tasks.md`** — see next subsection.
163
+
164
+
The output is a `plan.md` (and possibly `research.md` / `data-model.md` / `contracts/`) where the target-phase content is fresh and the locked sections carry forward the actually-shipped state, not the original aspirational state.
165
+
166
+
### Three mechanical gates post-refresh
167
+
168
+
Before merging the spec-refresh PR, three gates run sequentially:
169
+
170
+
**Gate (a) — Validation against code reality.**
171
+
For each non-target-phase entity in `data-model.md`, diff against the actual `db/migrations/*.sql` (or equivalent schema source). For each non-target-phase endpoint in `contracts/*.md`, diff against actual handler signatures. Any divergence in a *locked* section blocks merge — that's the regeneration lying. Adopters may script this against their stack; a CLI helper (`straymark spec-drift`) is on the roadmap (see #150 Ask 3).
172
+
173
+
**Gate (b) — Granular diff hunk-by-hunk review.**
174
+
Run `git diff specs/NNN-feature/` and review file-by-file, hunk-by-hunk. No changes to locked sections accepted without an explicit justification comment in the PR. The diff is small enough when scope-limited that this is feasible in one sitting.
175
+
176
+
**Gate (c) — Two-PR split.**
177
+
Land the spec-refresh as its own PR. Review it against the *code*, not against the plan-only output. Then fill the target Charter against the refreshed spec in a *separate* PR. Mixing the two collapses review surfaces: reviewers can no longer tell whether a hunk reflects new shipped state or new planned state.
178
+
179
+
### Why NOT re-run `/speckit-tasks` mid-spec-execution
180
+
181
+
The `tasks.md` file accumulates implementation trace state during execution: `[X]`checkboxes on completed tasks, `*CHARTER-NN: <commit-sha>*` annotations citing which Charter shipped which task, possibly `^skipped` markers with rationale. **Regenerating `tasks.md` destroys this state.** The file becomes a fresh task list with no record of what already shipped.
182
+
183
+
Discipline: **never** re-run `/speckit-tasks` while a spec is in the middle of multi-Charter execution. Instead, **manually edit `tasks.md`** for the target phase only — append new tasks for the refreshed scope, leave the already-shipped sections (`[X]` + `*CHARTER-NN:*` annotations) untouched.
184
+
185
+
If you discover that the original `tasks.md` had errors in shipped sections (e.g., a task was incorrectly marked `[X]` when its work was actually split across two Charters), correct it manually with a Git commit. Treat `tasks.md` as a historical record from the point of first execution onward; it is no longer a regeneratable artifact.
186
+
187
+
### Constitution Check re-evaluation cadence
188
+
189
+
SpecKit's Constitution Check is typically run once at `/speckit-plan` time. In multi-Charter execution against a single spec, the question of *when* to re-evaluate is left implicit. To make this explicit:
190
+
191
+
- **Per-Charter (recommended)** — re-evaluate Constitution Check at the start of each new Charter declared against the spec. The check is cheap (read the constitution; compare against the Charter's declared scope) and catches drift early, before execution commits.
192
+
- **Per-spec-refresh (mandatory when the refresh happens)** — when a scope-limited `/speckit-plan` refresh lands, the refresh PR must re-run Constitution Check against the refreshed plan. If the framework version moved (e.g., `fw-4.10.x → fw-4.14.x`), Constitution Check may yield different results because new gates exist.
193
+
- **NOT per-framework-bump alone** — a `straymark update-framework` between Charters does *not* require an immediate Constitution Check re-run on the open spec. The check applies at the next natural boundary (next Charter declaration or spec-refresh).
194
+
195
+
Codifying this as explicit cadence (rather than "whoever decides") closes a recurring ambiguity reported by Sentinel post-CHARTER-17.
196
+
197
+
### Roadmap: `straymark spec-drift`
198
+
199
+
A CLI command analogous to `straymark charter drift`, but operating at spec granularity — parse `data-model.md` → entities → diff against `db/migrations/*.sql`; parse `contracts/*.md` → endpoints → diff against handler signatures. It would mechanize Gate (a) above.
200
+
201
+
Deferred deliberately to a post-announcement Charter (tracked separately). The CLI surface is meaningful only for adopters whose spec format follows SpecKit conventions; the language-detection layer (Go vs Rust vs TypeScript vs Python handlers; SQL vs ORM-defined schemas) is non-trivial and warrants its own design cycle informed by real adopter stacks. The discipline above (Gates a/b/c executed manually) is the v0; the CLI is the v1 that mechanizes the most expensive gate.
202
+
134
203
## Anti-patterns
135
204
136
205
**Don't open a Charter "to be safe".** A Charter without a clear shippable cut becomes a wishlist. Operators end up closing it as `closed: aborted` and the telemetry is meaningless.
**Don't flip status to `closed` before drift check + telemetry yaml.** `straymark charter close` does both atomically; manual closure skips invariants.
145
214
215
+
**Don't re-run `/speckit-tasks` mid-spec-execution.** Regenerating `tasks.md` destroys the `[X]` completion marks and `*CHARTER-NN:* …` annotations that form the historical trace. See "Spec maintenance during multi-Charter execution" above for the safe path (manual edit for the target phase only).
216
+
146
217
## When this pattern doesn't fit
147
218
148
219
This bridge assumes a SpecKit-driven feature flow with multi-task, multi-session implementation. It does not fit:
0 commit comments