dflow-sdd-ddd 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +824 -1
- package/CONTRIBUTING.md +16 -10
- package/README.en.md +156 -200
- package/README.md +89 -144
- package/TEMPLATE-COVERAGE.md +15 -8
- package/TEMPLATE-LANGUAGE-GLOSSARY.md +15 -1
- package/bin/dflow.js +36 -4
- package/docs/commands.en.md +110 -0
- package/docs/commands.md +101 -0
- package/docs/doctor-uncertainty.en.md +212 -0
- package/docs/doctor-uncertainty.md +212 -0
- package/docs/evaluating-dflow.en.md +29 -11
- package/docs/evaluating-dflow.md +8 -6
- package/docs/npm-publish-checklist.md +3 -1
- package/docs/release-versioning-policy.md +8 -2
- package/docs/upgrading.en.md +196 -0
- package/docs/upgrading.md +197 -0
- package/docs/using-with-claude-code.en.md +25 -10
- package/docs/using-with-claude-code.md +20 -7
- package/docs/using-with-codex.en.md +18 -6
- package/docs/using-with-codex.md +16 -5
- package/docs/using-with-github-copilot.en.md +25 -10
- package/docs/using-with-github-copilot.md +21 -8
- package/lib/doc-shapes.json +997 -0
- package/lib/doctor-checks.js +2654 -0
- package/lib/init.js +3583 -107
- package/lib/render-diagrams.js +1474 -0
- package/lib/render.js +865 -49
- package/package.json +2 -2
- package/templates/brownfield/references/drift-verification.md +4 -0
- package/templates/brownfield/references/finish-feature-flow.md +635 -88
- package/templates/brownfield/references/finish-feature-follow-up.md +60 -0
- package/templates/brownfield/references/finish-feature-minimal-host.md +406 -0
- package/templates/brownfield/references/finish-feature-post-hoc-hotfix.md +95 -0
- package/templates/brownfield/references/git-integration.md +160 -15
- package/templates/brownfield/references/init-project-flow.md +26 -4
- package/templates/brownfield/references/modify-existing-flow.md +412 -87
- package/templates/brownfield/references/modify-existing-follow-up.md +121 -0
- package/templates/brownfield/references/modify-existing-post-hoc-hotfix.md +82 -0
- package/templates/brownfield/references/new-feature-flow.md +61 -6
- package/templates/brownfield/references/new-phase-flow.md +57 -7
- package/templates/brownfield/references/pr-review-checklist.md +303 -10
- package/templates/brownfield/scaffolding/AI-AGENT-GUIDE.md +158 -34
- package/templates/brownfield/scaffolding/CLAUDE-md-snippet.md +1 -1
- package/templates/brownfield/scaffolding/Git-principles-gitflow.md +75 -6
- package/templates/brownfield/scaffolding/Git-principles-trunk.md +82 -8
- package/templates/brownfield/scaffolding/_conventions.md +50 -28
- package/templates/brownfield/scaffolding/_overview.md +1 -0
- package/templates/brownfield/templates/_index.md +151 -7
- package/templates/brownfield/templates/analysis.md +79 -0
- package/templates/brownfield/templates/behavior.md +1 -0
- package/templates/brownfield/templates/context-definition.md +1 -0
- package/templates/brownfield/templates/context-map.md +2 -1
- package/templates/brownfield/templates/glossary.md +1 -0
- package/templates/brownfield/templates/lightweight-spec.md +154 -11
- package/templates/brownfield/templates/models.md +1 -0
- package/templates/brownfield/templates/phase-spec.md +9 -1
- package/templates/brownfield/templates/rules.md +1 -0
- package/templates/brownfield/templates/tech-debt.md +1 -0
- package/templates/common/references/ddd-modeling-guide.md +33 -16
- package/templates/{greenfield → common}/references/dflow-feedback-flow.md +2 -1
- package/templates/common/references/flow-rationale-registry.md +130 -0
- package/templates/common/skill/SKILL.md +13 -11
- package/templates/greenfield/references/drift-verification.md +4 -0
- package/templates/greenfield/references/finish-feature-flow.md +625 -89
- package/templates/greenfield/references/finish-feature-follow-up.md +60 -0
- package/templates/greenfield/references/finish-feature-minimal-host.md +363 -0
- package/templates/greenfield/references/finish-feature-post-hoc-hotfix.md +95 -0
- package/templates/greenfield/references/git-integration.md +148 -15
- package/templates/greenfield/references/init-project-flow.md +28 -8
- package/templates/greenfield/references/modify-existing-flow.md +378 -85
- package/templates/greenfield/references/modify-existing-follow-up.md +103 -0
- package/templates/greenfield/references/modify-existing-post-hoc-hotfix.md +82 -0
- package/templates/greenfield/references/new-feature-flow.md +67 -4
- package/templates/greenfield/references/new-phase-flow.md +56 -7
- package/templates/greenfield/references/pr-review-checklist.md +287 -8
- package/templates/greenfield/scaffolding/AI-AGENT-GUIDE.md +153 -32
- package/templates/greenfield/scaffolding/CLAUDE-md-snippet.md +5 -2
- package/templates/greenfield/scaffolding/Git-principles-gitflow.md +74 -6
- package/templates/greenfield/scaffolding/Git-principles-trunk.md +88 -12
- package/templates/greenfield/scaffolding/_conventions.md +50 -28
- package/templates/greenfield/scaffolding/_overview.md +6 -2
- package/templates/greenfield/templates/_index.md +137 -7
- package/templates/greenfield/templates/aggregate-design.md +1 -0
- package/templates/greenfield/templates/analysis.md +79 -0
- package/templates/greenfield/templates/behavior.md +1 -0
- package/templates/greenfield/templates/context-definition.md +1 -0
- package/templates/greenfield/templates/context-map.md +2 -1
- package/templates/greenfield/templates/events.md +4 -1
- package/templates/greenfield/templates/glossary.md +1 -0
- package/templates/greenfield/templates/lightweight-spec.md +154 -11
- package/templates/greenfield/templates/models.md +1 -0
- package/templates/greenfield/templates/phase-spec.md +9 -1
- package/templates/greenfield/templates/rules.md +1 -0
- package/templates/greenfield/templates/tech-debt.md +1 -0
- package/templates/brownfield/references/dflow-feedback-flow.md +0 -251
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Step 6: Reverse-Update Follow-up Tracking — Brownfield Progressive Extraction
|
|
2
|
+
|
|
3
|
+
Branch file of `references/finish-feature-flow.md`. It **adds** the follow-up
|
|
4
|
+
closing rules; it does not restate or override anything in that flow.
|
|
5
|
+
|
|
6
|
+
**You are here because** that flow's Step 6 dispatched you — it owns whether
|
|
7
|
+
this route applies.
|
|
8
|
+
|
|
9
|
+
For features that were created as follow-ups of an earlier completed
|
|
10
|
+
feature, update the Follow-up Tracking table of **every** original this host's
|
|
11
|
+
`follow-up-of` names — one parent, or several when the field is a YAML array.
|
|
12
|
+
For each of them:
|
|
13
|
+
|
|
14
|
+
1. Locate `dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md`
|
|
15
|
+
2. Find the Follow-up Tracking section's row for this feature's SPEC-ID
|
|
16
|
+
3. Flip Status → `completed`
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# The AI makes the edit and may offer to commit it (Y / N), per the AI commit policy
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This flip is a **sanctioned post-completion mutation, not a checkpoint** —
|
|
23
|
+
the follow-up host is already closed out and archived, so it is recorded in
|
|
24
|
+
**no** Checkpoint Log (neither this original feature's nor the follow-up
|
|
25
|
+
host's). It **must still be committed**, though: the flip is a real edit to
|
|
26
|
+
the original feature's `_index.md`. Require the tracking commit — the AI offers
|
|
27
|
+
it (Y / N); if the developer declines or the commit fails, **stop and do not
|
|
28
|
+
declare closeout complete** until the flip is committed. After it commits,
|
|
29
|
+
verify **per original** with
|
|
30
|
+
`git show HEAD:dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md`
|
|
31
|
+
that the Follow-up Tracking row now reads `completed` in the **committed** blob,
|
|
32
|
+
and that `git status --short` is clean. **Then check the commit itself, two ways
|
|
33
|
+
— neither replaces the other.**
|
|
34
|
+
**(1) Its full path set** (`git show --stat HEAD`) contains **only** the
|
|
35
|
+
`_index.md` of the originals this host's `follow-up-of` names: nothing under the
|
|
36
|
+
archived follow-up host — that would be a third host-mutating commit, which the
|
|
37
|
+
two-checkpoint lifecycle does not allow — and nothing else at all.
|
|
38
|
+
**(2) Its patch per original** (`git show HEAD -- {that path}`) carries **that
|
|
39
|
+
row's own transition** — the `in-progress` line removed, the `completed` line
|
|
40
|
+
added — and **no Checkpoint Log change**: this flip enters *neither* ledger, so
|
|
41
|
+
a Checkpoint Log row appearing in a parent is a violation even when the flip
|
|
42
|
+
itself is correct.
|
|
43
|
+
Why both: the blob proves the final state, not who wrote it — a commit that
|
|
44
|
+
merely edits other text in parent A while flipping parent B leaves both blobs
|
|
45
|
+
reading `completed` with the flips split across two commits — and the patch in
|
|
46
|
+
(2) is **path-filtered**, so it cannot see what else the commit touched. Only
|
|
47
|
+
(1) can. The commit message references the
|
|
48
|
+
follow-up host's SPEC-ID. Where there are several originals, flip them **in one
|
|
49
|
+
commit** — for a minimal follow-up host that keeps this the single post-closeout
|
|
50
|
+
tracking commit named in `modify-existing-flow.md` Step 1.6's minimal variant.
|
|
51
|
+
|
|
52
|
+
After the update:
|
|
53
|
+
> "Follow-up Tracking row updated to Status = `completed` in
|
|
54
|
+
> `{原 SPEC-ID}-{原 slug}/_index.md` (and every other original listed).
|
|
55
|
+
> Closeout complete."
|
|
56
|
+
|
|
57
|
+
The connection is bidirectional and weakly redundant: the new feature's
|
|
58
|
+
`follow-up-of` field is the authoritative source; the old feature's
|
|
59
|
+
Follow-up Tracking row is a derived index. If they ever disagree, trust
|
|
60
|
+
`follow-up-of`.
|
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Minimal Host (Zero-Phase) Closeout — Brownfield Progressive Extraction
|
|
2
|
+
|
|
3
|
+
Branch file of `references/finish-feature-flow.md`. It **adds** the checks and
|
|
4
|
+
field rules a minimal (zero-phase) host takes; it does not restate or override
|
|
5
|
+
anything in that flow.
|
|
6
|
+
|
|
7
|
+
**You are here when** `references/finish-feature-flow.md` Step 1's minimal-host
|
|
8
|
+
selector sent you — it states the condition; this file does not restate it.
|
|
9
|
+
|
|
10
|
+
**Keep this file for the whole closeout.** It adds to four of that flow's
|
|
11
|
+
steps — Step 1, Step 3, Step 4's post-commit verification, and Step 5 — and each
|
|
12
|
+
of those places points back here.
|
|
13
|
+
|
|
14
|
+
## Hash evidence
|
|
15
|
+
|
|
16
|
+
**Hash evidence** (several checks in this file use this test). A hash recorded in
|
|
17
|
+
`_index.md` passes *hash evidence* when all three hold:
|
|
18
|
+
- **(a) it is a commit** — `git cat-file -t {hash}` reports `commit`;
|
|
19
|
+
- **(b) it is on this branch** — `git merge-base --is-ancestor {hash} HEAD`
|
|
20
|
+
succeeds;
|
|
21
|
+
- **(c) its diff carries what the record claims** — the commit's **changed
|
|
22
|
+
paths** include the artifact that row or checkpoint points at; each check
|
|
23
|
+
in this file names which. **Tree presence is not enough**: every commit
|
|
24
|
+
inherits the files an earlier one added, so a commit that only touched the
|
|
25
|
+
implementation would otherwise satisfy (c) for an artifact it never wrote. (a)
|
|
26
|
+
and (b) alone prove only that *some* earlier commit exists on this branch; (c)
|
|
27
|
+
is what ties it to the record.
|
|
28
|
+
|
|
29
|
+
## Step 1 — additional validation checks
|
|
30
|
+
|
|
31
|
+
Run these as part of `references/finish-feature-flow.md` Step 1's checklist, in
|
|
32
|
+
the order given here, and report `✓` / `✗` for each exactly as that flow says.
|
|
33
|
+
A `✗` here stops closeout there, on the same terms.
|
|
34
|
+
|
|
35
|
+
- [ ] **Minimal host (zero-phase) only** — every row in `_index.md` Lightweight
|
|
36
|
+
Changes has a **non-empty `Commit` cell that passes hash evidence**; for
|
|
37
|
+
(c), the commit carries that row's own work: a **T2**'s
|
|
38
|
+
`lightweight-*.md` / `BUG-*.md` file; for a **T3** an `_index.md` that
|
|
39
|
+
already carries this row at that hash — Step 1.7 writes every row *before*
|
|
40
|
+
checkpoint 1, which is what makes that provable here; for a **baseline**
|
|
41
|
+
row, the capture it records — and for a
|
|
42
|
+
baseline the capture must be **added or modified** by that commit and
|
|
43
|
+
**exist in its tree**, never deleted or renamed away: a commit that
|
|
44
|
+
*removes* the document cannot be the one that captured it, yet it changes
|
|
45
|
+
the same path. This applies to
|
|
46
|
+
**T2, T3, and baseline rows alike**. Three failures, all blocking —
|
|
47
|
+
**report the one that is true**, because the message is the developer's
|
|
48
|
+
only clue about what to do next: an **empty** cell means that change is not
|
|
49
|
+
committed yet; a cell holding a **placeholder** (`{hash}`, `{pending}`,
|
|
50
|
+
`(待 commit)` — anything `git cat-file -t` cannot resolve) means the cell
|
|
51
|
+
was **never filled in**, which is a different repair and may well have a
|
|
52
|
+
commit sitting there unrecorded; a **resolvable** value that fails (a)–(c)
|
|
53
|
+
means the hash is the wrong one. ⚠ Do not collapse the middle case into the
|
|
54
|
+
first.
|
|
55
|
+
(`modify-existing-flow.md` Step 1.7 "Finalize + close" is where the
|
|
56
|
+
**cell** gets backfilled once its commit exists.)
|
|
57
|
+
**Deliberately not run on a phase-bearing host.** Those hosts keep
|
|
58
|
+
`references/finish-feature-flow.md` Step 1's two `Tier = T2` checks, which
|
|
59
|
+
never covered a T3 row anyway — a T3 has
|
|
60
|
+
no spec file in Dflow (`references/git-integration.md` § Gate Checks by
|
|
61
|
+
Branch Type).
|
|
62
|
+
- [ ] **Minimal host (zero-phase), baseline only** — **a `spec-baseline`
|
|
63
|
+
checkpoint and a `Tier = baseline` row imply each other**, and the host
|
|
64
|
+
carries the capture and nothing else, proved against the **commit**, not
|
|
65
|
+
only the ledger. This check selects when **either** appears: checkpoint 1
|
|
66
|
+
named `spec-baseline`, **or** any `Tier = baseline` row in the Lightweight
|
|
67
|
+
Changes table. Selecting on the checkpoint alone leaves the other
|
|
68
|
+
direction open — a baseline row sitting under an ordinary
|
|
69
|
+
`implementation | committed ({hash})` checkpoint would never be examined,
|
|
70
|
+
while `modify-existing-flow.md` Step 1.7 says a baseline capture is
|
|
71
|
+
observation-only and **never** uses `implementation`. So checkpoint 1
|
|
72
|
+
**must** read `spec-baseline` with Result `committed ({hash})`, and all
|
|
73
|
+
three of these hold:
|
|
74
|
+
(1) the Lightweight Changes table holds **exactly one** row and it is the
|
|
75
|
+
`Tier = baseline` one;
|
|
76
|
+
(2) the Current BR Snapshot is **empty**;
|
|
77
|
+
(3) that commit's diff (`git show --stat {hash}`) contains **only this
|
|
78
|
+
list and nothing else** — (i) the BC-layer documents the `Tier = baseline`
|
|
79
|
+
row declares, (ii) this host's own `_index.md`, (iii) for a
|
|
80
|
+
**follow-up** baseline, the `_index.md` of **every** original this host's
|
|
81
|
+
`follow-up-of` names — it may be a YAML array, and Step 1.6 requires the
|
|
82
|
+
opening reverse-link row in **each** of them to ride this commit, so a
|
|
83
|
+
singular reading would reject the second parent — and (iv) the **global**
|
|
84
|
+
documents a capture records into (`glossary.md`, `domain/analysis.md`,
|
|
85
|
+
`migration/tech-debt.md`), which belong to no bounded context and are
|
|
86
|
+
named as capture destinations by Part A's observation-only routing and by
|
|
87
|
+
Step 2's Systematic Baseline Capture. **Any other path blocks —
|
|
88
|
+
implementation source above all.**
|
|
89
|
+
(A **phase-bearing** host may legitimately hold a `Tier = baseline` row
|
|
90
|
+
alongside other work; it is not zero-phase and never reaches this check.)
|
|
91
|
+
- [ ] **Minimal host (zero-phase) only** — the Lightweight Changes table has
|
|
92
|
+
**at least one row** (a T2, T3, or baseline row). An empty Phase Specs
|
|
93
|
+
table **and** an empty Lightweight Changes table is an **empty host** →
|
|
94
|
+
reject closeout.
|
|
95
|
+
- [ ] **Minimal host (zero-phase) only** — **every spec file in the host
|
|
96
|
+
directory is named by a row.** The row-driven checks — this file's
|
|
97
|
+
`Commit` cell check and `references/finish-feature-flow.md` Step 1's two
|
|
98
|
+
`Tier = T2` items — walk rows → files, so a spec file that no row names is
|
|
99
|
+
never examined by them; this item closes
|
|
100
|
+
the other direction. A `phase-spec-*` always fails (the Phase Specs table
|
|
101
|
+
is empty by definition); a `lightweight-*.md` / `BUG-*.md` with no
|
|
102
|
+
Tier = T2 row fails the same way. A **T3-only** or **baseline** host
|
|
103
|
+
carries no spec file at all, so any spec file there fails this check.
|
|
104
|
+
- [ ] **Minimal host (zero-phase) only** — the Checkpoint Log shows a
|
|
105
|
+
**committed** first checkpoint before this closeout: Checkpoint
|
|
106
|
+
`implementation` with Result `committed ({hash})` (normal) or `reconciled
|
|
107
|
+
({merged-hotfix-hash})` (hotfix post-hoc), or — for a **baseline** host —
|
|
108
|
+
Checkpoint `spec-baseline` with Result `committed ({hash})`. A first
|
|
109
|
+
checkpoint still reading `skipped` or `failed` **blocks** closeout — but
|
|
110
|
+
they are not the same problem. `failed` means the commit was attempted and
|
|
111
|
+
did not land: the work is genuinely uncommitted and has to land. `skipped`
|
|
112
|
+
means only that **the AI's offer was declined**
|
|
113
|
+
(`references/git-integration.md` § Commit Checkpoints), *not* that no
|
|
114
|
+
commit exists — the developer may have made it themselves, which leaves
|
|
115
|
+
the ledger **incomplete rather than final**. Complete it:
|
|
116
|
+
`modify-existing-flow.md` Step 1.7's "Finalize + close" backfills the row
|
|
117
|
+
to `committed ({hash})` with the developer's real hash. Do **not** waive
|
|
118
|
+
this check for a `skipped` row, and do **not** write a hash you have not
|
|
119
|
+
verified.
|
|
120
|
+
- [ ] **Minimal host (zero-phase) only** — **the Checkpoint Log carries exactly
|
|
121
|
+
one row at this point.** A minimal host takes exactly two checkpoints and
|
|
122
|
+
the second is the closeout row `references/finish-feature-flow.md` Step 4
|
|
123
|
+
instruction 1 adds, so before closeout there is exactly one: the first
|
|
124
|
+
checkpoint the preceding item validated. Any second pre-closeout row
|
|
125
|
+
**blocks** — **report the one that is true**, because the repairs differ.
|
|
126
|
+
What separates them is **whether the row records a checkpoint this host
|
|
127
|
+
actually reached**, not what its cells hold. A row that records none is
|
|
128
|
+
repaired **by deleting it**, however it is filled in: a `closeout` row is
|
|
129
|
+
one, because no closeout has run yet — Step 4 instruction 1 writes it at
|
|
130
|
+
closeout — and so is any row carried over from `templates/_index.md`'s
|
|
131
|
+
example table. A row that does record a reached checkpoint — a second
|
|
132
|
+
`implementation` or `spec-baseline`, a leftover from an abandoned attempt,
|
|
133
|
+
or one this list does not name — says the host did not take the two-commit
|
|
134
|
+
lifecycle, and that is settled with the developer, not by deleting a line.
|
|
135
|
+
A failed or declined attempt does **not** add a row: both are recorded by
|
|
136
|
+
editing the existing one in place.
|
|
137
|
+
This counts the rows in **this
|
|
138
|
+
host's own table** — it is not the whole-history assertion, which stays
|
|
139
|
+
with `references/pr-review-checklist.md`.
|
|
140
|
+
- [ ] **Minimal host (zero-phase) only** — **that first commit is real, and it
|
|
141
|
+
is this host's.** The Checkpoint Log is prose; verify the hash behind it
|
|
142
|
+
against **hash evidence**. Take the hash that stands for checkpoint 1 —
|
|
143
|
+
for a **normal** host the `committed ({hash})` value; for a **baseline**
|
|
144
|
+
host the `spec-baseline` row's `committed ({hash})` value; for a **hotfix
|
|
145
|
+
post-hoc** host the Lightweight Changes row's `Commit` cell (**not** the
|
|
146
|
+
`reconciled (...)` hash, which names the already-merged hotfix). For (c),
|
|
147
|
+
touching *some* path under
|
|
148
|
+
`dflow/specs/features/active/{SPEC-ID}-{slug}/` is **not enough** — a
|
|
149
|
+
stray host-open commit does that much while the work is still
|
|
150
|
+
uncommitted. Require the tier's artifact **among the commit's changed
|
|
151
|
+
paths** — (c) is what this commit wrote, not what its tree contains: a
|
|
152
|
+
**T2**'s `lightweight-*.md` / `BUG-*.md` spec file; for a **T3** an
|
|
153
|
+
`_index.md` the commit **changed** *and* which, as committed at that hash,
|
|
154
|
+
already carries this change's Lightweight Changes row — `git show --stat
|
|
155
|
+
{hash}` **and** `git show
|
|
156
|
+
{hash}:dflow/specs/features/active/{SPEC-ID}-{slug}/_index.md`, both, not
|
|
157
|
+
either; for a **baseline**, the capture it claims to record —
|
|
158
|
+
**added or modified** and present in that commit's tree, never deleted or
|
|
159
|
+
renamed away — together with the `Tier = baseline` row. Any of (a)–(c)
|
|
160
|
+
failing **blocks** closeout.
|
|
161
|
+
- [ ] **Minimal host (zero-phase) only** — **checkpoint 1 is *one* commit, and
|
|
162
|
+
every row names it.** For a **normal** host the Checkpoint Log's
|
|
163
|
+
`committed ({hash})` and **every** Lightweight Changes row's `Commit` must
|
|
164
|
+
be the **same** hash, and that commit's diff must **touch the
|
|
165
|
+
implementation paths** its lightweight-spec or rows describe. Step 1.7
|
|
166
|
+
requires the artifact to **declare** those paths; an artifact naming none
|
|
167
|
+
leaves nothing to compare against, so a missing declaration **blocks** —
|
|
168
|
+
it never passes vacuously. For a **baseline** host the same equality holds
|
|
169
|
+
between the `spec-baseline` row's `committed ({hash})` and the
|
|
170
|
+
`Tier = baseline` row's `Commit`; its counterpart to "implementation
|
|
171
|
+
paths" is the documents that capture recorded.
|
|
172
|
+
Assert the **equality itself**, not merely that each value passes hash
|
|
173
|
+
evidence on its own: two hashes that each resolve, are each reachable, and
|
|
174
|
+
each contain some named artifact describe a **three**-commit host —
|
|
175
|
+
host+spec at A, implementation at B, closeout at C — which clears every
|
|
176
|
+
other check on this list while breaking the two-commit lifecycle.
|
|
177
|
+
**Exempt — post-hoc hotfix only, and only this much:** the
|
|
178
|
+
`reconciled (...)` checkpoint hash and the row `Commit` cells name
|
|
179
|
+
different commits **by design** (Step 1.8), so do not assert equality
|
|
180
|
+
*between those two*, and do not apply the implementation-path condition to
|
|
181
|
+
this host's own commit — this file's `Minimal host, hotfix post-hoc only`
|
|
182
|
+
check tests the merged hotfix instead.
|
|
183
|
+
**Everything else still holds:** a post-hoc host can be compound too
|
|
184
|
+
(Step 1.7, "minimal means zero-phase, not one-artifact"), so **every** row
|
|
185
|
+
`Commit` must still name the **same single documentation commit**.
|
|
186
|
+
- [ ] **Minimal host (zero-phase) only** — **nothing that constitutes the change
|
|
187
|
+
itself is still uncommitted.** This is deliberately not "the host
|
|
188
|
+
directory is clean": **checkpoint 1 carries the change, the closeout
|
|
189
|
+
commit carries the record the flow writes afterwards.** Checkpoint 1 sits
|
|
190
|
+
at `modify-existing-flow.md`'s Step 5 → Step 6 gate and holds the change
|
|
191
|
+
itself — for a **T2** its lightweight-spec plus the implementation source,
|
|
192
|
+
for a **T3** its `_index.md` row plus the implementation source, and for a
|
|
193
|
+
**baseline** host the capture itself, which *is* that host's
|
|
194
|
+
change. What the flow writes *after* that gate — Step 6's completion
|
|
195
|
+
checklist and Step 1.7's "Finalize + close" — is derived record and rides
|
|
196
|
+
into the closeout commit.
|
|
197
|
+
**A post-hoc host (Step 1.8) inverts the source half, and this is where
|
|
198
|
+
the reconciliation contract is enforced.** Its change is the *already
|
|
199
|
+
merged* hotfix; checkpoint 1 is the **documentation** commit. So that
|
|
200
|
+
commit must carry the spec / row and this host's `_index.md` and must
|
|
201
|
+
**not** touch any implementation path the artifact declares — read
|
|
202
|
+
`git show --stat {checkpoint-1-hash}` and block if one appears. A
|
|
203
|
+
re-implementation committed there passes every other gate on this list
|
|
204
|
+
(rows agree, the `reconciled` hash differs from it and touches the
|
|
205
|
+
declared paths, the tree is clean) while breaking §8's "reconcile, do not
|
|
206
|
+
re-run" outright, so nothing else catches it.
|
|
207
|
+
**What this proves and what it does not — do not widen it here.** It
|
|
208
|
+
proves checkpoint 1 is documentation-only. It does **not** prove the
|
|
209
|
+
branch carries no re-implementation elsewhere: a second commit beside
|
|
210
|
+
checkpoint 1, or a re-implementation in a path the artifact does not
|
|
211
|
+
declare, both survive it. Widening it to the branch was tried and does not
|
|
212
|
+
work from inside closeout — the range needs a base branch, and Dflow
|
|
213
|
+
deliberately does not know yours. ⚠ **No check covers it today.** The
|
|
214
|
+
whole-history item `references/finish-feature-flow.md` Step 1 assigns to
|
|
215
|
+
`references/pr-review-checklist.md` is **not** it: that one counts commits
|
|
216
|
+
under this host's spec directory, so a re-implementation commit touching
|
|
217
|
+
only source never appears in its output. Review is where the missing
|
|
218
|
+
assertion belongs — a reviewer has the base branch in front of them — but
|
|
219
|
+
do not read the existing item as discharging it.
|
|
220
|
+
**Blocks closeout:** any of the **implementation source** files this
|
|
221
|
+
host's lightweight-spec or rows describe, staged or unstaged in
|
|
222
|
+
`git status --porcelain`; for a **baseline** host the documents
|
|
223
|
+
its `Tier = baseline` row records, which are that capture's own content
|
|
224
|
+
and belong in the `spec-baseline` commit — never in closeout; any
|
|
225
|
+
**untracked** file under
|
|
226
|
+
`dflow/specs/features/active/{SPEC-ID}-{slug}/`; and any tracked file
|
|
227
|
+
dirty beyond the closed list below.
|
|
228
|
+
**May ride into the closeout commit — this list and nothing else:**
|
|
229
|
+
(i) `_index.md`, with its uncommitted delta confined to Lightweight
|
|
230
|
+
Changes `Commit` cells, Checkpoint Log rows, Resume Pointer, and Current
|
|
231
|
+
BR Snapshot;
|
|
232
|
+
(ii) an **already-committed** `lightweight-*.md` / `BUG-*.md`, with its
|
|
233
|
+
uncommitted delta confined to the frontmatter `status:` flip to
|
|
234
|
+
`completed` and the `Implementation Tasks` edits
|
|
235
|
+
`modify-existing-flow.md` Step 6's completion checklist makes ("applies
|
|
236
|
+
to both phase-spec and lightweight-spec"): ticking the tasks this change
|
|
237
|
+
completed and labelling each unchecked one as follow-up (6.1), and — when
|
|
238
|
+
the developer accepted the offer — collapsing or removing the section
|
|
239
|
+
(6.2). On a minimal host that checklist necessarily runs *after*
|
|
240
|
+
checkpoint 1, so these edits are uncommitted here by construction;
|
|
241
|
+
(iii) the Domain-layer documents **this change's Step 6.3 sweep** updates
|
|
242
|
+
— under `dflow/specs/domain/`, plus
|
|
243
|
+
`dflow/specs/migration/tech-debt.md` — scoped to *this change's* delta.
|
|
244
|
+
A **T3** has no Domain sweep at all (`modify-existing-flow.md` Step 6's
|
|
245
|
+
tier-conditional note), so
|
|
246
|
+
nothing qualifies under (iii) for a T3. A **no-BC** host has no
|
|
247
|
+
*BC-scoped* sweep — a dirty `dflow/specs/domain/{context}/…` or
|
|
248
|
+
`context-map.md` under one is fiction and **blocks** — but the **global**
|
|
249
|
+
documents (`glossary.md`, `domain/analysis.md`,
|
|
250
|
+
`migration/tech-debt.md`) belong to no bounded context, stay in its sweep,
|
|
251
|
+
and therefore still qualify under (iii). **(iii) never covers a baseline
|
|
252
|
+
host** either — its capture *is* the change, and is blocked
|
|
253
|
+
above.
|
|
254
|
+
Read each delta (`git diff -- {path}`) — do not infer it from the
|
|
255
|
+
filename. **The list is closed** — if a later change adds another
|
|
256
|
+
finalization field, add it here explicitly; "a host file is dirty" is never
|
|
257
|
+
on its own a reason to pass. (Unrelated work in progress elsewhere is
|
|
258
|
+
fine; say which files you judged unrelated.)
|
|
259
|
+
- [ ] **Minimal host (zero-phase), no-BC only** — **the host did not commit a
|
|
260
|
+
bounded context it does not have.** This file's `nothing that constitutes
|
|
261
|
+
the change itself is still uncommitted` check reads the *working
|
|
262
|
+
tree*; this one reads the **committed** side, because a fictitious
|
|
263
|
+
`{context}` invented at Step 2 and committed into checkpoint 1 leaves a
|
|
264
|
+
perfectly clean tree. Inspect checkpoint 1's diff
|
|
265
|
+
(`git show --stat {hash}`, with status — **not path names alone**): for a
|
|
266
|
+
host that declared itself no-BC that commit must **not touch, in any way**
|
|
267
|
+
— add, modify, delete or rename — any `dflow/specs/domain/{context}/…`
|
|
268
|
+
document. A deletion is a BC-layer change like any other, and reading only
|
|
269
|
+
the path list would accept one as if nothing had happened. The documents:
|
|
270
|
+
`rules.md`, `behavior.md`, `models.md`, `analysis.md` — and no
|
|
271
|
+
`context-map.md` (the Brownfield context map is optional and grows
|
|
272
|
+
organically, so a no-BC host inventing a row in it is the same fiction).
|
|
273
|
+
Any of them **blocks**
|
|
274
|
+
(`modify-existing-flow.md` Step 2's no-BC guard is where this should have
|
|
275
|
+
been caught first). A **baseline** host is not a no-BC host and this
|
|
276
|
+
check does not apply to it — its capture is the point.
|
|
277
|
+
**Do not over-reach:** this rejects only Domain documents that commit
|
|
278
|
+
*added or changed* — pre-existing Domain files it never touched are
|
|
279
|
+
irrelevant, and the **global** documents (`glossary.md`,
|
|
280
|
+
`domain/analysis.md`, `migration/tech-debt.md`) belong to no bounded
|
|
281
|
+
context and stay legitimate for a no-BC host, exactly as that check's
|
|
282
|
+
allow-list says.
|
|
283
|
+
**What this check cannot decide — stated, not asserted:** ⚠ **the rule it
|
|
284
|
+
enforces is not minimal-host-only; only this proof is.** *No no-BC host of
|
|
285
|
+
any shape may commit BC-scoped Domain material* — and what this reads is
|
|
286
|
+
**checkpoint 1**, one commit. It is not a branch-range proof: a second
|
|
287
|
+
commit beside checkpoint 1 carrying a `domain/{context}/…` document
|
|
288
|
+
survives it, and a **phase-bearing** no-BC host has no single checkpoint to
|
|
289
|
+
inspect at all, so it never runs this check in the first place. Closeout
|
|
290
|
+
cannot widen it — the range needs a base branch and Dflow deliberately does
|
|
291
|
+
not know yours (the same limit that working-tree check states).
|
|
292
|
+
**The branch-range assertion is confirmed by
|
|
293
|
+
`references/pr-review-checklist.md`'s "A no-BC host committed no BC-scoped
|
|
294
|
+
Domain material" item**, in that file's *Delegated to review by
|
|
295
|
+
`finish-feature-flow.md`* block, which applies to **every** no-BC host.
|
|
296
|
+
Its exemptions match this check's: the global documents stay legitimate,
|
|
297
|
+
and a **baseline** host is not a no-BC host there either.
|
|
298
|
+
Keep this check anyway: it blocks earlier and more cheaply than review.
|
|
299
|
+
- [ ] **Minimal host (zero-phase), follow-up only** — **the reverse link was
|
|
300
|
+
opened, not only closed.** Step 1.6 requires the original feature's
|
|
301
|
+
Follow-up Tracking row for this host to be created as `in-progress` and to
|
|
302
|
+
ride checkpoint 1; `references/finish-feature-flow.md` Step 6 flips it to
|
|
303
|
+
`completed` afterwards. Verify the
|
|
304
|
+
opening half here, from committed state: for **every** SPEC-ID this host's
|
|
305
|
+
`follow-up-of` names — it may be a YAML array, so check each one —
|
|
306
|
+
`git show {checkpoint-1-hash}:dflow/specs/features/completed/{原 SPEC-ID}-{原 slug}/_index.md`
|
|
307
|
+
must already carry this host's row with Status `in-progress`. A row absent
|
|
308
|
+
there **blocks** closeout: the Step 6 flip would then create it directly as
|
|
309
|
+
`completed`, and the `absent → in-progress → completed` history the
|
|
310
|
+
follow-up contract requires never happened. A **completed-only baseline**
|
|
311
|
+
host is a follow-up variant and takes this check too.
|
|
312
|
+
**What this check cannot decide — stated, not asserted:** ⚠ **only this
|
|
313
|
+
*proof* is minimal-host-only.** `references/finish-feature-flow.md`'s
|
|
314
|
+
Step 5 → Step 6 post-Local-closeout confirmation carries the requirement
|
|
315
|
+
itself and names who confirms it for a phase-bearing follow-up host; do
|
|
316
|
+
not read this check's scope as the requirement's scope. The evidence is what stops here: that host has no
|
|
317
|
+
single commit required to carry the row, so there is no committed blob for
|
|
318
|
+
this check to read and it never runs there.
|
|
319
|
+
- [ ] **Minimal host, hotfix post-hoc only** — the reconciliation record is
|
|
320
|
+
complete, **within a stated boundary**. This check proves **plausibility,
|
|
321
|
+
not identity**: that `{merged-hotfix-hash}` is a credible candidate, and
|
|
322
|
+
that the developer has said on the record which fix it is and how they
|
|
323
|
+
know. Whether it is *the* merged hotfix is **not decidable from inside
|
|
324
|
+
this flow** — the repository holds no independent record of which commit
|
|
325
|
+
that was; only the developer and the issue tracker do. Do not read a pass
|
|
326
|
+
here as identity confirmed. Identity is
|
|
327
|
+
**asserted** at `modify-existing-flow.md` Step 1.8 and **confirmed** by
|
|
328
|
+
`references/pr-review-checklist.md` — the same assignment
|
|
329
|
+
`references/finish-feature-flow.md` Step 1 gives the whole-history
|
|
330
|
+
assertion.
|
|
331
|
+
The plausibility conditions, all required: the
|
|
332
|
+
`reconciled ({merged-hotfix-hash})` value passes hash evidence — (a) and
|
|
333
|
+
(b) as usual, and for **(c)** its diff touches the implementation paths
|
|
334
|
+
the T2 lightweight-spec or the T3 row **declares** (Step 1.7 requires that
|
|
335
|
+
declaration; an artifact naming none leaves (c) nothing to compare and
|
|
336
|
+
**blocks** rather than passing vacuously). It must also **differ**
|
|
337
|
+
from the Lightweight Changes row's documentation-commit hash (different
|
|
338
|
+
provenance; see Step 1.8). The per-tier trace must exist too: a **T2**
|
|
339
|
+
carries `hotfix-branch:` in its lightweight-spec frontmatter, a **T3** has
|
|
340
|
+
its Lightweight Changes row Description marked as a hotfix. Finally the
|
|
341
|
+
developer's identity assertion must be **present and cited** — Step 1.8
|
|
342
|
+
requires the source it rests on (PR / incident / tracker reference), and
|
|
343
|
+
it lives with the per-tier trace, so look for it there: beside
|
|
344
|
+
`hotfix-branch:` in a **T2**'s lightweight-spec, in the row Description
|
|
345
|
+
for a **T3**. An uncited hash **blocks** closeout: it leaves pr-review
|
|
346
|
+
nothing to confirm against, and this gate is not a substitute for that
|
|
347
|
+
confirmation.
|
|
348
|
+
|
|
349
|
+
> **Zero-phase minimal host (`modify-existing-flow.md` Step 1.7 / the Step 1.6
|
|
350
|
+
> minimal variant / Step 1.8's post-hoc hotfix, whose linkage resolves to one of
|
|
351
|
+
> those two).** A standalone / follow-up minimal host, or a baseline
|
|
352
|
+
> capture, closes out with an **empty Phase Specs table** — that is valid, not
|
|
353
|
+
> a failure: the "every
|
|
354
|
+
> Phase Specs row is completed" check passes vacuously and there is no
|
|
355
|
+
> `phase-spec-*` file to look for. A no-BR / T3 host also has an intentionally
|
|
356
|
+
> empty Current BR Snapshot — `references/finish-feature-flow.md` Step 1's
|
|
357
|
+
> **Current BR Snapshot** check decides that from the host's own record, not
|
|
358
|
+
> from a declaration. Do **not**
|
|
359
|
+
> manufacture a phase-spec or a BR row to make a check "pass".
|
|
360
|
+
|
|
361
|
+
## Step 3 — sync input
|
|
362
|
+
|
|
363
|
+
**Minimal host — sync input.** A minimal host has no phase-spec: read the
|
|
364
|
+
"phase-spec" references in `references/finish-feature-flow.md` Step 3's sync
|
|
365
|
+
instructions ("each phase-spec's Delta") as the host's **lightweight-spec**
|
|
366
|
+
recorded delta plus its Current BR Snapshot. A
|
|
367
|
+
no-BR family that changed a documented behaviour still syncs `behavior.md` from
|
|
368
|
+
that lightweight-spec's delta.
|
|
369
|
+
⚠ What is minimal-host-only here is the **input binding** — the instruction to
|
|
370
|
+
read "phase-spec" as "lightweight-spec", which a host with no phase-spec needs
|
|
371
|
+
and a phase-bearing one must not apply. It is **not** that step's
|
|
372
|
+
**Every host — lightweight-spec deltas are a sync input too** paragraph, which
|
|
373
|
+
every host shape needs.
|
|
374
|
+
|
|
375
|
+
## Step 4 — post-commit verification, additionally
|
|
376
|
+
|
|
377
|
+
Add this to `references/finish-feature-flow.md` Step 4's post-commit
|
|
378
|
+
verification, inside its archived-host-directory item:
|
|
379
|
+
|
|
380
|
+
**Minimal host (zero-phase) additionally**: the **first** checkpoint row
|
|
381
|
+
still carries the hash this file's Step 1 checks validated —
|
|
382
|
+
`implementation` with `committed ({hash})`,
|
|
383
|
+
`reconciled ({merged-hotfix-hash})`, or — for a **baseline** host —
|
|
384
|
+
`spec-baseline` with `committed ({hash})`.
|
|
385
|
+
|
|
386
|
+
## Step 5 — Integration Summary, exact fields
|
|
387
|
+
|
|
388
|
+
**Zero-phase minimal host — exact fields** (these must match the
|
|
389
|
+
`references/finish-feature-flow.md` Step 3 branch — do not require a field that
|
|
390
|
+
step left empty). A standalone or follow-up
|
|
391
|
+
minimal host has `Phase Count: 0`, an empty Phase List, and at least one row in
|
|
392
|
+
Lightweight Changes.
|
|
393
|
+
|
|
394
|
+
- a **no-BC host** (that step's case ii) sets `BC: none` (nothing was synced).
|
|
395
|
+
**`Related BR-IDs` is not fixed to `none`**: it reports what this change's own
|
|
396
|
+
record carries, not what was synced, so it takes the same values a BC-bearing
|
|
397
|
+
host would — **empty**, or the **per-family no-BR marker** when the T2 carries
|
|
398
|
+
one. A T3-only no-BC host has neither and leaves it empty.
|
|
399
|
+
- a **BC-bearing host** (that step's case i) sets `BC:` to the context and `Related
|
|
400
|
+
BR-IDs:` to what it actually touched — a real set, the per-family no-BR
|
|
401
|
+
marker, or empty for a no-BR host.
|
|
402
|
+
- a **baseline minimal host** (that step's case iii) sets `BC:` to the captured
|
|
403
|
+
context (not `none`); **every other field keeps its zero-phase form**, and
|
|
404
|
+
`Related BR-IDs:` is **empty** — an observation-only capture has no BR delta,
|
|
405
|
+
and BRs it merely *found* already in the code are system state, not this
|
|
406
|
+
change's evidence.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Post-Hoc Hotfix Reconciliation — Brownfield Progressive Extraction
|
|
2
|
+
|
|
3
|
+
Branch file of `references/finish-feature-flow.md`. It **adds** the
|
|
4
|
+
reconciliation rules; it does not restate or override anything in that flow.
|
|
5
|
+
|
|
6
|
+
**Two different places in `references/finish-feature-flow.md` send you here, at
|
|
7
|
+
two different times. Read only the section that matches the one that sent you.**
|
|
8
|
+
|
|
9
|
+
- **Step 1's pre-checklist callout** — the branches met while this host was
|
|
10
|
+
still open → § Before closeout.
|
|
11
|
+
- **Step 5** — Step 4 has already archived and committed this host → § After
|
|
12
|
+
closeout.
|
|
13
|
+
|
|
14
|
+
## Before closeout
|
|
15
|
+
|
|
16
|
+
**You are here when** `references/finish-feature-flow.md` Step 1's hotfix
|
|
17
|
+
callout sent you — it states the condition; this file does not restate it.
|
|
18
|
+
|
|
19
|
+
**What you classify here is the merge-resolution delta, not the hotfix.** The
|
|
20
|
+
hotfix records itself in its **own** minimal host through Step 1.8 — follow-up
|
|
21
|
+
or standalone, never an in-flight feature — and that host is where
|
|
22
|
+
`reconciled ({merged-hotfix-hash})`, the identity citation and the per-tier
|
|
23
|
+
trace live. If the hotfix has not been documented yet, run Step 1.8 for it
|
|
24
|
+
first and come back; do **not** absorb it into this feature, whose ordinary
|
|
25
|
+
checkpoints would record none of that. What is left for this host is only what
|
|
26
|
+
*choosing between the two versions* changed. **Classify that by the cascade,
|
|
27
|
+
then record what the classification calls for:**
|
|
28
|
+
|
|
29
|
+
- **No tracked delta** — the cascade's **below workflow** level. It stays in
|
|
30
|
+
the integration commit message; do **not** manufacture a row or a document.
|
|
31
|
+
Nothing to validate, so nothing changes below. This is the common case.
|
|
32
|
+
- **A tracked delta (T3 or above), phase-bearing host** — record it in this
|
|
33
|
+
host and let it ride the normal checkpoints, then run
|
|
34
|
+
`references/finish-feature-flow.md` Step 1's checklist against the result. A
|
|
35
|
+
phase-bearing host has no fixed commit count, so an extra checkpoint is
|
|
36
|
+
ordinary.
|
|
37
|
+
- **A tracked delta (T3 or above), minimal (zero-phase) host** — it does
|
|
38
|
+
**not** go into this host: the two-commit lifecycle has one implementation
|
|
39
|
+
(or `spec-baseline`) checkpoint and one closeout, and every Lightweight
|
|
40
|
+
Changes row must belong to that first commit. This host closes on what it
|
|
41
|
+
already carries, and the delta is routed **after** Step 4 archives it — by
|
|
42
|
+
the **A tracked delta (T3 or above)** bullet of § After closeout, the same
|
|
43
|
+
route every post-closeout leftover takes.
|
|
44
|
+
Do **not** route it now: you are mid-closeout, and routing would open a
|
|
45
|
+
second host before this one is sealed. Note it, finish the closeout, then
|
|
46
|
+
take § After closeout's route — back through `/dflow:modify-existing`, which
|
|
47
|
+
picks the host the way it always does. Do not decide that here: by then this feature
|
|
48
|
+
is *completed*, so the normal completed-feature disambiguation applies and
|
|
49
|
+
the answer may be a follow-up or a standalone host.
|
|
50
|
+
|
|
51
|
+
Classification decides, never "is it worth writing down". After closeout the
|
|
52
|
+
host is frozen — § After closeout says what is left over, and applies the same
|
|
53
|
+
cascade.
|
|
54
|
+
|
|
55
|
+
## After closeout
|
|
56
|
+
|
|
57
|
+
**You are here when** `references/finish-feature-flow.md` Step 5 sent you.
|
|
58
|
+
|
|
59
|
+
**A mainline hotfix that overlapped this feature.** A T2 / T3 post-hoc hotfix
|
|
60
|
+
(`modify-existing-flow.md` Step 1.8) records itself in its own host, so when
|
|
61
|
+
this feature's branch finally meets the mainline both may have touched the same
|
|
62
|
+
code, and whoever merges picks between two existing versions. By the time you
|
|
63
|
+
read this, **Step 4 has already archived and committed this feature — its host
|
|
64
|
+
is frozen.** Classify whatever is left by the cascade (`AI-AGENT-GUIDE.md`
|
|
65
|
+
§ Ceremony Scaling), never by "is it worth writing down":
|
|
66
|
+
|
|
67
|
+
- **No conflict, or a resolution with no tracked delta** — it stays in the
|
|
68
|
+
integration commit message. That is the cascade's **below workflow** level:
|
|
69
|
+
do not manufacture a document, and do not reopen this feature.
|
|
70
|
+
- **A tracked delta (T3 or above)** — completed features are frozen, so it goes
|
|
71
|
+
where every post-completion change goes: back through
|
|
72
|
+
`/dflow:modify-existing`, which opens a follow-up or standalone host for it.
|
|
73
|
+
Do **not** edit the archived `_index.md`.
|
|
74
|
+
- **The resolution moves system state** — if choosing between the two versions
|
|
75
|
+
changes a business rule, a documented behaviour, or an extracted model, the
|
|
76
|
+
owning document (`rules.md` / `behavior.md` / `models.md`) **must** be
|
|
77
|
+
updated. That update is itself a tracked change and takes the route above;
|
|
78
|
+
system-state truth is never below workflow.
|
|
79
|
+
- **It is bigger than a merge** — if resolving it means *new or changed*
|
|
80
|
+
behaviour rather than choosing between two that already exist, it is not a
|
|
81
|
+
merge question at all: run it through the cascade and open the flow its tier
|
|
82
|
+
calls for.
|
|
83
|
+
|
|
84
|
+
**Reconciling before closeout is simpler.** If the branches meet while this
|
|
85
|
+
feature is still in flight — a rebase onto the mainline, say — handle it then
|
|
86
|
+
as ordinary in-flow work — but **which host takes it depends on this host's
|
|
87
|
+
shape**. A **phase-bearing** host absorbs a tracked delta (T3 or above) and
|
|
88
|
+
rides the normal checkpoints; a **minimal (zero-phase)** host **cannot** once
|
|
89
|
+
checkpoint 1 has landed, because every Lightweight Changes row must belong to
|
|
90
|
+
that commit — it closes on what it carries and the delta is routed afterwards.
|
|
91
|
+
No tracked delta stays below workflow, in the integration commit message.
|
|
92
|
+
§ Before closeout states that whole side in full, minimal-host branch
|
|
93
|
+
included. The four bullets above decide it whichever side of closeout you are on —
|
|
94
|
+
they are principles, not a checklist; the situation is rare and varied, so use
|
|
95
|
+
judgement.
|