scriveno 2.6.0 → 2.7.1

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![CI](https://github.com/aihxp/scriveno/actions/workflows/ci.yml/badge.svg)](https://github.com/aihxp/scriveno/actions/workflows/ci.yml)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
5
- [![Version](https://img.shields.io/badge/version-2.6.0-blue)](CHANGELOG.md)
5
+ [![Version](https://img.shields.io/badge/version-2.7.1-blue)](CHANGELOG.md)
6
6
  [![npm](https://img.shields.io/npm/v/scriveno.svg)](https://www.npmjs.com/package/scriveno)
7
7
  [![Downloads](https://img.shields.io/npm/dm/scriveno.svg)](https://www.npmjs.com/package/scriveno)
8
8
  [![Status CLI](https://img.shields.io/badge/status%20CLI-scriveno%20status-blue)](docs/runtime-support.md#shared-auto-invoke-engine)
@@ -40,7 +40,7 @@ Scriveno is a command system that turns your AI coding agent into a voice-preser
40
40
  The wedge comes first: Scriveno profiles the writer, loads that voice into every drafting step, and keeps each unit on fresh context so the prose stays specific to the project. From there, it expands into 113 writing commands covering the rest of the pipeline:
41
41
 
42
42
  - **Create** -- Set up a project with tailored context files. Progressive onboarding, never overwhelming.
43
- - **Write** -- Discuss, plan, draft, and revise one unit at a time. The drafter agent loads your Voice DNA and writes in *your* voice, not generic AI prose.
43
+ - **Write** -- Discuss, plan, draft, and revise one unit at a time. The drafter agent loads your Voice DNA and writes in *your* voice, not generic AI prose. Run `/scr:progress` any time to open a per-unit ledger (`.manuscript/PROGRESS.md`) showing what is done, in progress, and untouched.
44
44
  - **Polish** -- Editor review, line edit, copy edit, continuity check, voice check, beta reader simulation, sensitivity review.
45
45
  - **Publish** -- Front/back matter, cover art, blurbs, query letters, KDP packages, IngramSpark packages, EPUB, PDF, Fountain, Final Draft, LaTeX.
46
46
  - **Translate** -- Deep translation with glossary management, cultural adaptation, back-translation verification, multi-language simultaneous publishing.
@@ -246,11 +246,11 @@ Scriveno currently ships installer targets for these AI tooling environments:
246
246
 
247
247
  ## Status
248
248
 
249
- **Version:** 2.6.0
249
+ **Version:** 2.7.1
250
250
 
251
251
  Scriveno's core command surface is stable across 113 commands, 50 work types, and 11 installer targets. The current repo baseline includes shipped planning milestones through `v2.0 Publishing Cover Packaging`, plus the creative-context, record-store, branching-next, runtime-sync, adaptive concierge, human-first writing-safeguard, authenticity-diagnostic, domain-grilling, installer-marker cleanup, cross-runtime agent metadata, visible automation status, the shared `scriveno status --project .` auto-invoke engine, route-intelligence lanes, safe apply reporting, runtime smoke checks, agent availability checks, route graph audits, the full audit repair pass through `2.0.11`, the first-run proof surface in `2.5.0`, and the executable `/scr:first-run` path. See [Quick Proof](docs/quick-proof.md) for the fastest proof path, [Shipped Assets](docs/shipped-assets.md) for the canonical asset inventory, and [Runtime Support](docs/runtime-support.md) for the runtime compatibility matrix.
252
252
 
253
- Version `2.6.0` publishes Scriveno under the package name `scriveno`, so the current install command is `npx scriveno@latest`. The older `scriveno-cli` package name is historical and was unpublished during the rename, so npm cannot attach a deprecation notice to it while it has no active registry record. The older `scriven-cli` package remains on npm only as a deprecated legacy name that points users to `scriveno`. Do not treat either legacy package name as active unless a deliberate compatibility shim is republished. See [CHANGELOG](CHANGELOG.md) for the full list and [docs/release-notes.md](docs/release-notes.md) for the public-facing summary.
253
+ Version `2.7.1` publishes Scriveno under the package name `scriveno`, so the current install command is `npx scriveno@latest`. The older `scriveno-cli` package name is historical and was unpublished during the rename, so npm cannot attach a deprecation notice to it while it has no active registry record. The older `scriven-cli` package remains on npm only as a deprecated legacy name that points users to `scriveno`. Do not treat either legacy package name as active unless a deliberate compatibility shim is republished. See [CHANGELOG](CHANGELOG.md) for the full list and [docs/release-notes.md](docs/release-notes.md) for the public-facing summary.
254
254
 
255
255
  Package history is tracked in [CHANGELOG.md](CHANGELOG.md), and the public-facing summary for this release is in [docs/release-notes.md](docs/release-notes.md).
256
256
 
@@ -38,7 +38,7 @@ FOR each unit in OUTLINE.md (starting from current position):
38
38
  If writer says "skip": advance to next unit, update STATE.md
39
39
  ```
40
40
 
41
- When the loop completes (all units through all stages), show a completion summary: total units, total word count, voice consistency across the manuscript, open record threads or promises, and any flags or issues encountered.
41
+ When the loop completes (all units through all stages), show a completion summary: total units, total word count, voice consistency across the manuscript, open record threads or promises, any flags or issues encountered, and a pointer to the per-unit ledger at `.manuscript/PROGRESS.md`.
42
42
 
43
43
  ## Profile rules
44
44
 
@@ -141,6 +141,7 @@ After each stage execution:
141
141
  2. Update progress counters: `units_discussed`, `units_planned`, `units_drafted`, `units_reviewed`, `units_submitted`
142
142
  3. Update `current_unit` and next step
143
143
  4. Update `total_words` running count
144
+ 5. Refresh `.manuscript/PROGRESS.md` so the openable ledger advances unit by unit during the run, per `docs/progress-protocol.md`
144
145
 
145
146
  On pause or stop:
146
147
  1. Write current position to "Session handoff" section so `--resume` can pick up exactly where you left off
@@ -168,6 +169,7 @@ Spawned agents:
168
169
  - continuity-checker: {count}
169
170
  Local operations:
170
171
  - STATE.md updated: yes/no
172
+ - PROGRESS.md refreshed: yes/no
171
173
  - HISTORY.log updated: yes/no
172
174
  Pause:
173
175
  - status: none/guided/supervised/quality-gate/blocker
@@ -201,11 +203,13 @@ If the command stops because a prerequisite is missing, suggest the command that
201
203
 
202
204
  ## Tone
203
205
 
204
- **Progress updates:** Concise, one line per unit.
205
- - "Drafted chapter 3: 1,247 words. Voice check: passed."
206
+ **Progress updates:** Concise, one line per unit, anchored to the whole manuscript so progress is visible during the run.
207
+ - "Drafted chapter 3 (3 of 12, 25%): 1,247 words. Voice check: passed."
206
208
  - "Planned scenes 1-4 for chapter 5."
207
209
  - "Editor review complete for chapter 2: 3 notes."
208
210
 
211
+ Every few units, show a one-line manuscript bar pulled from the deliverable progress in `docs/progress-protocol.md`, for example: `████░░░░░░ 5/12 chapters done (42%)`. The full per-unit ledger is `.manuscript/PROGRESS.md`.
212
+
209
213
  **At pause points:** Warm, non-technical.
210
214
  - "Chapter 3 is ready for your review."
211
215
  - "The first act is complete -- 4 chapters, 12,340 words."
@@ -49,9 +49,9 @@ Require `.manuscript/plans/{N}-*-PLAN.md` files to exist. If none exist, also ch
49
49
 
50
50
  6. **Surface state nudges.** If the drafter emits `CHARACTER STATE NUDGE`, suggest `/scr:character-touch <name>` after drafting. If the drafter emits `SUBJECT DYNAMICS NUDGE`, suggest `/scr:subject-touch <subject>` after drafting. These nudges go to the writer, not into the draft file.
51
51
 
52
- 7. **Update STATE.md:** mark unit as drafted, note word count, flag any voice-check issues.
52
+ 7. **Update STATE.md:** mark unit as drafted, note word count, flag any voice-check issues. Then refresh `.manuscript/PROGRESS.md` so the ledger advances (this unit moves to in progress or done) per `docs/progress-protocol.md`.
53
53
 
54
- 8. **Tell the writer:** "Drafted {unit} {N}: X words across Y {atomic_units}. Voice consistency: Z% (the voice-checker Overall score for this unit; omit this figure if the voice-check could not run). Updated RECORD.md with what the draft established. Ready for editor review? Run `/scr:editor-review N` or `/scr:next`."
54
+ 8. **Tell the writer:** "Drafted {unit} {N} ({N} of {total}, {pct}% of the manuscript): X words across Y {atomic_units}. Voice consistency: Z% (the voice-checker Overall score for this unit; omit this figure if the voice-check could not run). Updated RECORD.md with what the draft established. Ready for editor review? Run `/scr:editor-review N` or `/scr:next`." The full per-unit ledger is in `.manuscript/PROGRESS.md`.
55
55
 
56
56
  ## Agent and Automation Status
57
57
 
@@ -67,6 +67,7 @@ Local operations:
67
67
  - draft files written: {count}
68
68
  - RECORD.md updated: yes/no
69
69
  - STATE.md updated: yes/no
70
+ - PROGRESS.md refreshed: yes/no
70
71
  Auto-invoked:
71
72
  - /scr:editor-review N: yes/no
72
73
  Why: {autopilot.enabled true, full-auto profile, supervised pause, or writer-facing manual mode}
@@ -113,6 +114,6 @@ If the command stops because a prerequisite is missing, suggest the command that
113
114
 
114
115
  ## Tone
115
116
 
116
- Don't narrate each atomic unit being drafted. That's noise. Show progress concisely: "Drafted scene 1/4... 2/4... 3/4... 4/4. Voice check: passed."
117
+ Don't narrate each atomic unit being drafted. That's noise. Show progress concisely, and anchor it to the whole manuscript so the writer sees momentum: "Drafted scene 1/4... 2/4... 3/4... 4/4. Voice check: passed. Chapter 5 of 12 done (42%)." Pull the unit-of-total figure and percent from the deliverable progress defined in `docs/progress-protocol.md`.
117
118
 
118
119
  Let the writer read the actual prose in the draft files. Your job is orchestration, not performance.
@@ -168,6 +168,7 @@ Write the standard review report to `.manuscript/reviews/{N}-REVIEW.md`. If an o
168
168
 
169
169
  If all beats passed:
170
170
  - Mark act as "reviewed" in STATE.md
171
+ - Refresh `.manuscript/PROGRESS.md` so the ledger reflects the new review status, per `docs/progress-protocol.md`
171
172
  - Apply confirmed compact updates to RECORD.md when the review established or corrected the work's durable content state
172
173
  - Suggest moving to `/scr:submit N` or `/scr:discuss {N+1}`
173
174
 
@@ -94,17 +94,17 @@ If the user passes `--detail`, append a per-unit breakdown table after the summa
94
94
  ```
95
95
  Unit Breakdown
96
96
  --------------
97
- Ch 1: The Beginning 3,200 words ~13 pages
98
- Ch 2: The Middle 4,100 words ~16 pages
99
- Ch 3: The Climax 2,800 words ~11 pages
100
- (not yet drafted)
101
- Ch 4: The Resolution --- words --- pages
97
+ Ch 1: The Beginning [x] done 3,200 words ~13 pages
98
+ Ch 2: The Middle [x] done 4,100 words ~16 pages
99
+ Ch 3: The Climax [~] in progress 2,800 words ~11 pages
100
+ Ch 4: The Resolution [ ] untouched --- words --- pages
102
101
  --------------
103
- Total 10,100 words ~40 pages
102
+ Total 10,100 words ~40 pages
104
103
  ```
105
104
 
106
105
  - Use the hierarchy's mid-level label (e.g., "Ch" for chapter, "Sc" for scene, "Sec" for section) from CONSTRAINTS.json.
107
- - For units not yet drafted, show `(not yet drafted)` with dashes for counts.
106
+ - Show each unit's status (`[x]` done, `[~]` in progress, `[ ]` untouched) derived from disk per `docs/progress-protocol.md`. The full per-unit ledger lives in `.manuscript/PROGRESS.md`.
107
+ - For units not yet drafted, show dashes for counts.
108
108
  - Right-align word counts and page counts for visual clarity.
109
109
  - Include a total row at the bottom.
110
110
 
@@ -69,7 +69,7 @@ Always create `RECORD.md` from `templates/RECORD.md` without renaming it. It is
69
69
  Write `.manuscript/config.json` by starting from `templates/config.json` and filling the project-specific values. The generated config must include the shared settings blocks that later commands read:
70
70
  ```json
71
71
  {
72
- "scriveno_version": "2.6.0",
72
+ "scriveno_version": "2.7.1",
73
73
  "work_type": "<chosen>",
74
74
  "group": "<group>",
75
75
  "command_unit": "<unit>",
@@ -62,6 +62,7 @@ Proactive checks:
62
62
  Translation: <none | follow-up available>
63
63
  Export: <fresh | stale, suggest /scr:export>
64
64
  Save: <clean | unsaved manuscript changes, suggest /scr:save>
65
+ Progress: <X/Y units done -- see .manuscript/PROGRESS.md or /scr:progress>
65
66
  ```
66
67
 
67
68
  ## Routing logic
@@ -22,7 +22,7 @@ You are an outline manager. Load:
22
22
  - `.manuscript/config.json` (to get `work_type`)
23
23
  - Scriveno's installed/shared `CONSTRAINTS.json` (global `~/.scriveno/data/CONSTRAINTS.json` or project `.scriveno/data/CONSTRAINTS.json`) (to check `work_types[type].hierarchy` for unit labels, and `file_adaptations`)
24
24
  - `.manuscript/OUTLINE.md` (the outline data -- read it fully)
25
- - `.manuscript/STATE.md` (to get drafted/planned/pending status per unit)
25
+ - `.manuscript/STATE.md` (aggregate counters) plus each unit's files on disk (plans, drafts, reviews) to derive per-unit status -- see `docs/progress-protocol.md`. The persisted per-unit ledger is `.manuscript/PROGRESS.md` when present.
26
26
 
27
27
  **Work-type adaptation:** Read the hierarchy from CONSTRAINTS.json for the current work type to determine the correct unit terminology:
28
28
  - Novel: part > chapter > scene
@@ -56,7 +56,7 @@ Present the hierarchical outline with:
56
56
  2. **For each unit, show:**
57
57
  - Unit number and title
58
58
  - 1-line summary (from OUTLINE.md)
59
- - Status: drafted | planned | pending (from STATE.md)
59
+ - Status: drafted | planned | pending (derived from disk per `docs/progress-protocol.md`, not from STATE.md aggregates)
60
60
  - Word count (if drafted, from STATE.md or draft file)
61
61
  - Arc position (if mapped in PLOT-GRAPH.md)
62
62
 
@@ -33,7 +33,7 @@ You are helping the writer pause their session gracefully. Your job is to captur
33
33
  - Outcome: `Paused session`
34
34
  Keep this pause marker in the Last actions table because `/scr:session-report` and future resume logic use it as a session boundary.
35
35
 
36
- 6. **Regenerate `.manuscript/CONTEXT.md`** using the `templates/CONTEXT.md` scaffold and the field set described in `/scr:save` step 7, with `{{LAST_COMMAND}}` set to `/scr:pause-work`. This is the file the next session reads first; refreshing it on pause means the writer (or a fresh AI session) returns to a current view without having to call `/scr:resume-work` to bootstrap.
36
+ 6. **Regenerate `.manuscript/CONTEXT.md`** using the `templates/CONTEXT.md` scaffold and the field set described in `/scr:save` step 7, with `{{LAST_COMMAND}}` set to `/scr:pause-work`. This is the file the next session reads first; refreshing it on pause means the writer (or a fresh AI session) returns to a current view without having to call `/scr:resume-work` to bootstrap. Also regenerate `.manuscript/PROGRESS.md` (the per-unit progress ledger) per `/scr:save` step 8 and `docs/progress-protocol.md`, so the saved ledger matches where the writer is pausing.
37
37
 
38
38
  7. **Append one line to `.manuscript/HISTORY.log`** per `docs/history-protocol.md`:
39
39
  ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Show current project state and next step. How far along, what is drafted, what is pending.
2
+ description: Show project progress -- a unit progress bar, what is done / in progress / untouched, pipeline position, and a pointer to the per-unit ledger.
3
3
  argument-hint: ""
4
4
  ---
5
5
 
@@ -18,7 +18,7 @@ node "$HOME/.scriveno/lib/auto-invoke-engine.js" --project "$PWD" --trigger /scr
18
18
  node .scriveno/lib/auto-invoke-engine.js --project "$PWD" --trigger /scr:progress
19
19
  ```
20
20
 
21
- This engine is installed into Scriveno shared assets for every runtime, including Claude Code, Codex, Cursor, Gemini CLI, OpenCode, GitHub Copilot, Windsurf, Antigravity, Manus, Perplexity Desktop, and the generic skill fallback. If the engine is not present, perform the read-only progress logic below.
21
+ This engine is installed into Scriveno shared assets for every runtime, including Claude Code, Codex, Cursor, Gemini CLI, OpenCode, GitHub Copilot, Windsurf, Antigravity, Manus, Perplexity Desktop, and the generic skill fallback. The engine exposes `computeProgressLedger(manuscriptDir)` (see `lib/auto-invoke-engine.js` and `docs/progress-protocol.md`), which returns the deliverable bar, percent, and the done / in progress / untouched bucket counts deterministically from disk; a runtime that loads the module should prefer it over re-deriving counts by hand. If the engine is not present, perform the read-only progress logic below.
22
22
 
23
23
  ## Prerequisites
24
24
 
@@ -26,15 +26,19 @@ This engine is installed into Scriveno shared assets for every runtime, includin
26
26
 
27
27
  ## What to do
28
28
 
29
- 1. Load `.manuscript/STATE.md`, `.manuscript/OUTLINE.md`, `.manuscript/RECORD.md` when present, and `.manuscript/config.json`
30
- 2. Count total units, drafted units, submitted units, and pending units
31
- 3. Calculate word count from existing draft files
32
- 4. Determine the next step (what unit to discuss, plan, or draft next)
33
- 5. Display a progress summary:
34
- - "{drafted}/{total} units drafted. {submitted}/{total} submitted."
29
+ 1. Load `.manuscript/STATE.md`, `.manuscript/OUTLINE.md`, `.manuscript/config.json`, and `.manuscript/RECORD.md` when present. Read `.manuscript/PROGRESS.md` if it exists -- it is the saved ledger snapshot.
30
+ 2. Derive per-unit status from disk per `docs/progress-protocol.md`: for each outline unit, resolve its stage (untouched / discussed / planned / drafted / reviewed / submitted) and its headline bucket (done / in progress / untouched). Count units in each bucket plus the total, and calculate word count from existing draft files.
31
+ 3. Determine the pipeline position: the first incomplete stage on the writing lifecycle `seed > voice > outline > discuss > plan > draft > review > revise > publish > translate`, expressed as `Stage {index} of {total}: {Name}`.
32
+ 4. Determine the next step (what unit to discuss, plan, or draft next), using the work type's unit label from CONSTRAINTS.json (chapter, act, surah, section, and so on).
33
+ 5. Display the progress report, leading with the deliverable view:
34
+ - A progress bar over units, for example `████████░░ 4/5 scenes done (80%)` (block characters `U+2588` filled and `U+2591` empty; use the work type's plural unit label).
35
+ - "Done: {done} In progress: {in_progress} Untouched: {untouched}."
35
36
  - "{word_count} words so far."
37
+ - "Pipeline: Stage {index} of {total} ({stage_name})."
36
38
  - "{open_threads} open record threads." (only when RECORD.md exists)
37
39
  - "Next: {next_action}"
40
+ - "Full per-unit ledger: `.manuscript/PROGRESS.md`" -- the file the writer can open any time to see every unit's status. If it is missing or older than the newest draft, add: "(run `/scr:save` to refresh the saved ledger)".
41
+ When the project is small (20 units or fewer) or the writer asks, render the per-unit ledger table inline per `docs/progress-protocol.md` instead of only pointing at the file.
38
42
  6. Run the Level 1 proactive sweep:
39
43
  - If STATE.md counts disagree with draft files, suggest `/scr:scan`.
40
44
  - If reports show unresolved review items, suggest the matching review command.
@@ -55,14 +59,15 @@ Candidate agents:
55
59
  - <recommended agent route or none>
56
60
  Local operations:
57
61
  - progress counts computed: yes/no
62
+ - per-unit ledger rendered: yes/no
58
63
  - proactive sweep: read-only
59
64
  Candidate local helpers:
60
- - <recommended helper or none>
65
+ - /scr:save to refresh the saved .manuscript/PROGRESS.md when it is stale
61
66
  Manual gates:
62
67
  - <writer-owned route or none>
63
68
  Auto-invoked:
64
69
  - none
65
- Why: progress is read-only; it recommends next commands without mutating files
70
+ Why: progress is read-only; it renders the ledger live and points at .manuscript/PROGRESS.md without writing it
66
71
  ```
67
72
 
68
73
  ## Response Contract
@@ -46,7 +46,7 @@ You are welcoming the writer back and orienting them. Your job is to read the se
46
46
  Example:
47
47
  > Last time you drafted chapter 3 (1,247 words across 4 scenes, voice check passed). You were working on chapter 4 -- you noted you wanted it shorter and more tense, with Marcus discovering the letter. I'd suggest starting with /scr:discuss 4 to shape the plan.
48
48
 
49
- 6. **Regenerate `.manuscript/CONTEXT.md`** using the `templates/CONTEXT.md` scaffold and the same field set described in `/scr:save` step 7, with `{{LAST_COMMAND}}` set to `/scr:resume-work`. This refreshes the bootstrap file so the next session opens to a current view -- the act of resuming is itself a state event worth recording.
49
+ 6. **Regenerate `.manuscript/CONTEXT.md`** using the `templates/CONTEXT.md` scaffold and the same field set described in `/scr:save` step 7, with `{{LAST_COMMAND}}` set to `/scr:resume-work`. This refreshes the bootstrap file so the next session opens to a current view -- the act of resuming is itself a state event worth recording. Also regenerate `.manuscript/PROGRESS.md` (the per-unit progress ledger) per `/scr:save` step 8 and `docs/progress-protocol.md`.
50
50
 
51
51
  7. **Append one line to `.manuscript/HISTORY.log`** per `docs/history-protocol.md`:
52
52
  ```
@@ -56,20 +56,22 @@ Follow the auto-invoke policy. In the source repository it is documented at `doc
56
56
  - `{{LAST_SCAN}}`, `{{LAST_SCAN_VERDICT}}` -- from STATE.md if recorded; otherwise `never run` and `unknown`
57
57
  Save to `.manuscript/CONTEXT.md`. This file is committed alongside STATE.md.
58
58
 
59
- 8. **Append one line to `.manuscript/HISTORY.log`** per `docs/history-protocol.md`:
59
+ 8. **Regenerate `.manuscript/PROGRESS.md`** before staging. This is the openable per-unit progress ledger. Use the `templates/PROGRESS.md` scaffold and derive per-unit status from disk per `docs/progress-protocol.md` (plan, draft, and review files reconciled with STATE.md). Fill the unit ledger, the deliverable progress bar, the pipeline position, and the bucket counts (done / in progress / untouched). Save to `.manuscript/PROGRESS.md`; it is committed alongside STATE.md and CONTEXT.md.
60
+
61
+ 9. **Append one line to `.manuscript/HISTORY.log`** per `docs/history-protocol.md`:
60
62
  ```
61
63
  {ISO timestamp} | scr:save | message="{generated message}" | files={changed file count} | outcome=committed
62
64
  ```
63
65
  If HISTORY.log does not exist, create it. Do not stage it as a separate operation -- step 9 picks it up.
64
66
 
65
- 9. **Execute the save:**
67
+ 10. **Execute the save:**
66
68
  ```
67
69
  git add .manuscript/
68
70
  git commit -m "{generated message}"
69
71
  ```
70
- This commit must include the `STATE.md`, `CONTEXT.md`, and `HISTORY.log` updates from steps 6 through 8 so the worktree is clean immediately after a successful save.
72
+ This commit must include the `STATE.md`, `CONTEXT.md`, `PROGRESS.md`, and `HISTORY.log` updates from steps 6 through 9 so the worktree is clean immediately after a successful save.
71
73
 
72
- 10. **Tell the writer** the result (see output section below).
74
+ 11. **Tell the writer** the result (see output section below).
73
75
 
74
76
  ## Automation Status
75
77
 
@@ -85,6 +87,7 @@ Candidate agents:
85
87
  Local operations:
86
88
  - STATE.md updated: yes/no
87
89
  - CONTEXT.md regenerated: yes/no
90
+ - PROGRESS.md regenerated: yes/no
88
91
  - HISTORY.log appended: yes/no
89
92
  - manuscript files saved: yes/no
90
93
  Candidate local helpers:
@@ -5,7 +5,7 @@ argument-hint: "[--fix] [--quiet]"
5
5
 
6
6
  # /scr:scan -- Context Drift Scanner
7
7
 
8
- You are the project's drift detector. Trust nothing. Compare what `.manuscript/STATE.md`, `OUTLINE.md`, `RECORD.md`, `config.json`, and the various structural files **claim** against what the filesystem actually contains, and report every mismatch.
8
+ You are the project's drift detector. Trust nothing. Compare what `.manuscript/STATE.md`, `OUTLINE.md`, `RECORD.md`, `PROGRESS.md`, `config.json`, and the various structural files **claim** against what the filesystem actually contains, and report every mismatch.
9
9
 
10
10
  Follow the auto-invoke policy. In the source repository it is documented at `docs/auto-invoke-policy.md`. `/scr:scan` does not spawn agents. It may run deterministic local checks and, under `--fix` after confirmation, deterministic local repairs.
11
11
 
@@ -23,7 +23,7 @@ This complements `/scr:health` (which fixes structural issues like missing direc
23
23
 
24
24
  ## Instruction
25
25
 
26
- Load `.manuscript/config.json`, `.manuscript/STATE.md`, `.manuscript/OUTLINE.md`, and `.manuscript/RECORD.md` when present. Each check below produces a finding with one of three severities:
26
+ Load `.manuscript/config.json`, `.manuscript/STATE.md`, `.manuscript/OUTLINE.md`, `.manuscript/RECORD.md`, and `.manuscript/PROGRESS.md` when present. Each check below produces a finding with one of three severities:
27
27
 
28
28
  - **DRIFT** -- recorded state contradicts disk reality. Trust nothing downstream until resolved.
29
29
  - **WARNING** -- an artifact is stale or out of date. Downstream work may be silently using outdated input.
@@ -206,6 +206,20 @@ Do not over-claim. RECORD.md is an interpretive store, so uncertain findings sho
206
206
 
207
207
  ---
208
208
 
209
+ ### CHECK 12: PROGRESS.md ledger staleness
210
+
211
+ If `.manuscript/PROGRESS.md` exists, compare its mtime against STATE.md and the newest draft. If PROGRESS.md is older than either, the saved per-unit ledger no longer reflects the work on disk. Emit:
212
+
213
+ ```
214
+ WARNING .manuscript/PROGRESS.md is older than the recorded state.
215
+ The saved per-unit ledger may show stale unit status.
216
+ Fix: /scr:save to rebuild it (or /scr:scan --fix).
217
+ ```
218
+
219
+ Recompute per-unit status from disk per `docs/progress-protocol.md`. If the bucket counts (done / in progress / untouched) disagree with what PROGRESS.md records, emit a DRIFT finding citing both. If PROGRESS.md does not exist, emit INFO with a one-line suggestion to run `/scr:save` once to generate the openable ledger.
220
+
221
+ ---
222
+
209
223
  ### REPORT
210
224
 
211
225
  Output a single structured report:
@@ -248,7 +262,7 @@ If `--quiet` was passed and there are zero findings, exit silently with no outpu
248
262
 
249
263
  When `--fix` is passed, after the report, group findings by auto-fixability:
250
264
 
251
- - **Auto-fixable now** -- finding has a deterministic fix Scriveno can apply (e.g. update STATE.md unit counts to match disk, initialize missing RECORD.md from the installed template, regenerate stale CONTEXT.md, sort orphan drafts into a `_unsorted/` review directory). For each, ask the writer once:
265
+ - **Auto-fixable now** -- finding has a deterministic fix Scriveno can apply (e.g. update STATE.md unit counts to match disk, initialize missing RECORD.md from the installed template, regenerate stale CONTEXT.md, regenerate stale or missing PROGRESS.md from disk per `docs/progress-protocol.md`, sort orphan drafts into a `_unsorted/` review directory). For each, ask the writer once:
252
266
  > Apply [N] auto-fixes? (yes / no / show me what each does)
253
267
  - **Requires writer decision** -- finding needs a judgment call (e.g. character orphans, scaffold pending, voice drift). List with suggested next command.
254
268
  - **Manual** -- finding requires manual cleanup (e.g. malformed HISTORY.log lines).
@@ -20,7 +20,8 @@ Load `.manuscript/config.json` for `command_unit`. The runnable command stays `/
20
20
  1. Load `.manuscript/config.json` for project context
21
21
  2. Check that the specified unit has been through editor review. Prefer `.manuscript/reviews/{N}-REVIEW.md`; if it is missing, accept legacy `{N}-EDITOR-NOTES.md`.
22
22
  3. Mark the unit as submitted in `STATE.md`
23
- 4. Report: "Unit {N} submitted. {remaining} units remaining."
23
+ 4. Refresh `.manuscript/PROGRESS.md` so the ledger shows this unit as done, per `docs/progress-protocol.md`.
24
+ 5. Report: "Unit {N} submitted. {remaining} units remaining."
24
25
 
25
26
  ## Response Contract
26
27
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "./constraints.schema.json",
3
- "version": "2.6.0",
3
+ "version": "2.7.1",
4
4
  "description": "Scriveno constraint system: work types, command availability, exports, and dependencies. Every command checks this file at runtime.",
5
5
  "_notes": {
6
6
  "sacred_keys": "Sacred subcommands live at commands/scr/sacred/<name>.md and run as /scr:sacred:<name>. Their CONSTRAINTS keys use the sacred:<name> form so /scr:help can render the runnable slash-command path directly. The sacred-numbering-format entry is a separate flat command (commands/scr/sacred-numbering-format.md) that surfaces the active tradition's numbering format. It used to be named sacred-verse-numbering, which collided with sacred:verse-numbering at install time -- both flattened to scr-sacred-verse-numbering. Renamed in v1.6.x; the installer now refuses to install when two sources share a flat skill name."
@@ -3744,6 +3744,7 @@
3744
3744
  "default": {
3745
3745
  "BRIEF.md": "BRIEF.md",
3746
3746
  "RECORD.md": "RECORD.md",
3747
+ "PROGRESS.md": "PROGRESS.md",
3747
3748
  "CHARACTERS.md": "CHARACTERS.md",
3748
3749
  "RELATIONSHIPS.md": "RELATIONSHIPS.md",
3749
3750
  "WORLD.md": "WORLD.md",
@@ -3753,6 +3754,7 @@
3753
3754
  "academic": {
3754
3755
  "BRIEF.md": "PROPOSAL.md",
3755
3756
  "RECORD.md": "RECORD.md",
3757
+ "PROGRESS.md": "PROGRESS.md",
3756
3758
  "CHARACTERS.md": "CONCEPTS.md",
3757
3759
  "WORLD.md": "CONTEXT.md",
3758
3760
  "PLOT-GRAPH.md": "ARGUMENT-MAP.md",
@@ -3761,6 +3763,7 @@
3761
3763
  "technical": {
3762
3764
  "BRIEF.md": "DOC-BRIEF.md",
3763
3765
  "RECORD.md": "RECORD.md",
3766
+ "PROGRESS.md": "PROGRESS.md",
3764
3767
  "CHARACTERS.md": "AUDIENCE.md",
3765
3768
  "RELATIONSHIPS.md": "DEPENDENCIES.md",
3766
3769
  "WORLD.md": "SYSTEM.md",
@@ -3770,6 +3773,7 @@
3770
3773
  "sacred": {
3771
3774
  "BRIEF.md": "FRAMEWORK.md",
3772
3775
  "RECORD.md": "RECORD.md",
3776
+ "PROGRESS.md": "PROGRESS.md",
3773
3777
  "CHARACTERS.md": "FIGURES.md",
3774
3778
  "RELATIONSHIPS.md": "LINEAGES.md",
3775
3779
  "WORLD.md": "COSMOLOGY.md",
@@ -175,6 +175,8 @@ scriveno/
175
175
  WRITING-RULES.md Universal AI-tell rulebook (1.6.0+)
176
176
  THEMES.md Thematic threads template
177
177
  STATE.md Progress tracking template
178
+ CONTEXT.md Session bootstrap scaffold (derived, auto-regenerated)
179
+ PROGRESS.md Per-unit progress ledger scaffold (derived, 2.7.0+)
178
180
  BRIEF.md Project brief template
179
181
  WORLD.md World-building template
180
182
  pitfalls/ Per-work-type pitfall packs (1.6.0+)
@@ -355,7 +357,7 @@ Codex uses a skill-native variation of this strategy. The installer generates on
355
357
 
356
358
  Scriveno also ships `lib/auto-invoke-engine.js`, exposed through `scriveno status --project .`, `scriveno status . --json`, `scriveno status --project . --apply-safe`, `scriveno sync --check`, `scriveno smoke`, `scriveno agents`, and `scriveno routes`. The installer copies this library into the shared Scriveno asset directory for global and project installs, so command surfaces can call a single status and audit engine before falling back to embedded markdown logic.
357
359
 
358
- The engine checks disk evidence only: project presence, required project files, STATE.md, CONTEXT.md freshness, plan files, draft files, review coverage, unresolved notes, revision-track proposals, translation work, publishing prerequisites, exports, history, and save signals. It recommends the next command, but it does not mutate files and does not spawn agents by itself. That boundary keeps proactive behavior portable across Claude Code, Codex, Cursor, Gemini CLI, OpenCode, GitHub Copilot, Windsurf, Antigravity, Manus, Perplexity Desktop, and the generic fallback.
360
+ The engine checks disk evidence only: project presence, required project files, STATE.md, CONTEXT.md freshness, plan files, draft files, review coverage, unresolved notes, revision-track proposals, translation work, publishing prerequisites, exports, history, and save signals. It also computes the per-unit progress ledger (done / in progress / untouched) through `computeProgressLedger`, which `/scr:progress` and `.manuscript/PROGRESS.md` build on. It recommends the next command, but it does not mutate files and does not spawn agents by itself. That boundary keeps proactive behavior portable across Claude Code, Codex, Cursor, Gemini CLI, OpenCode, GitHub Copilot, Windsurf, Antigravity, Manus, Perplexity Desktop, and the generic fallback.
359
361
 
360
362
  The engine now reports three automation lanes:
361
363
 
@@ -63,7 +63,7 @@ Use `Automation status:` for command chains and `Sync status:` for runtime insta
63
63
  | Level | Behavior | Default | Examples |
64
64
  |-------|----------|---------|----------|
65
65
  | 1 | Read-only suggestion | Run by default | `/scr:next` route, progress sweep, review queue surfacing |
66
- | 2 | Safe local helper | Run when directly triggered | `CONTEXT.md` regeneration, `HISTORY.log` append, scan report, stats count |
66
+ | 2 | Safe local helper | Run when directly triggered | `CONTEXT.md` regeneration, `PROGRESS.md` ledger regeneration, `HISTORY.log` append, scan report, stats count |
67
67
  | 3 | Scoped agent | Spawn when the command implies it or evidence is bounded | drafter, plan-checker, voice-checker, continuity-checker, translator, beta-reader |
68
68
  | 4 | Writer-owned action | Require confirmation | publishing, destructive edits, merge decisions, accepting review findings |
69
69
 
@@ -81,6 +81,7 @@ Run these read-only checks in `/scr:next`, `/scr:progress`, and closeouts for ma
81
81
  - If front matter, back matter, blurb, or cover handoff assets are missing, surface the specific publishing prerequisite before packaging.
82
82
  - If export outputs are older than source files, suggest `/scr:export` or `/scr:publish`.
83
83
  - If no save exists after recent manuscript changes, suggest `/scr:save`.
84
+ - Surface deliverable progress (units done / in progress / untouched) and point at the per-unit ledger `.manuscript/PROGRESS.md`; if it is stale, suggest `/scr:save` to refresh it.
84
85
 
85
86
  These checks must not mutate files.
86
87
 
@@ -88,10 +89,10 @@ These checks must not mutate files.
88
89
 
89
90
  Run these only when the current command directly owns the file operation:
90
91
 
91
- - `/scr:save` regenerates `.manuscript/CONTEXT.md`, appends `HISTORY.log`, and commits `.manuscript/`.
92
+ - `/scr:save` regenerates `.manuscript/CONTEXT.md` and `.manuscript/PROGRESS.md` (the per-unit ledger), appends `HISTORY.log`, and commits `.manuscript/`.
92
93
  - `/scr:scan --fix` applies deterministic state repairs after confirmation and appends `HISTORY.log`.
93
94
  - `/scr:resume-work` may regenerate `CONTEXT.md` from disk state.
94
- - `/scr:progress` may count drafts, submitted units, open record threads, and stale reports, but does not write.
95
+ - `/scr:progress` may count drafts, submitted units, open record threads, and stale reports and render the per-unit ledger live, but does not write. The saved `.manuscript/PROGRESS.md` is refreshed by `/scr:save`, `/scr:draft`, `/scr:autopilot`, and `/scr:scan --fix`.
95
96
  - Runtime `/scr:sync --apply` runs the installer and verifies installed command, skill, and agent surfaces.
96
97
 
97
98
  Report these as local operations, not spawned agents.
@@ -293,17 +293,22 @@ Show publishing-related commands available for your work type. Without a categor
293
293
 
294
294
  ### `/scr:progress`
295
295
 
296
- **Description:** Show current state and next step. How far along are you, what's drafted, what's pending.
296
+ **Description:** Show project progress: a unit progress bar, what's done / in progress / untouched, pipeline position, and a pointer to the per-unit ledger.
297
297
 
298
298
  **Usage:** `/scr:progress`
299
299
 
300
300
  **Prerequisites:** None
301
301
 
302
+ **Output includes:**
303
+ - A deliverable progress bar over units (done / in progress / untouched) with percent
304
+ - Pipeline position on the writing lifecycle (e.g., "Stage 6 of 10: Drafting")
305
+ - A pointer to `.manuscript/PROGRESS.md`, the openable per-unit ledger you can read any time
306
+
302
307
  **Example:**
303
308
  ```
304
309
  /scr:progress
305
310
  ```
306
- See "Chapter 4 of 12 drafted. 32,000 words. Next: discuss-chapter 5."
311
+ See "████████░░ 4/12 chapters done (33%). Pipeline: Stage 6 of 10 (Drafting). Next: discuss chapter 5. Full ledger: .manuscript/PROGRESS.md."
307
312
 
308
313
  ---
309
314
 
@@ -57,7 +57,7 @@ When a writer runs `/scr:new-work`, Scriveno creates `.manuscript/config.json`.
57
57
 
58
58
  ```json
59
59
  {
60
- "scriveno_version": "2.6.0",
60
+ "scriveno_version": "2.7.1",
61
61
  "work_type": "<chosen>",
62
62
  "group": "<group>",
63
63
  "command_unit": "<unit>",
@@ -6,6 +6,7 @@ It is part of the trust layer:
6
6
  - `STATE.md` -- structured snapshot (data)
7
7
  - `RECORD.md` -- compact established-content store
8
8
  - `.manuscript/CONTEXT.md` -- one-page narrative bootstrap (synthesis)
9
+ - `.manuscript/PROGRESS.md` -- per-unit progress ledger (derived; see `docs/progress-protocol.md`)
9
10
  - `.manuscript/HISTORY.log` -- append-only audit trail
10
11
 
11
12
  ## The rule
@@ -71,7 +72,7 @@ Filesystem mtime is a cheap, durable signal that does not require parsing the fi
71
72
  - **Drafter agents** (drafter.md, voice-checker.md, etc.) -- they need the full source files for fidelity.
72
73
  - **Read-only data display commands** (`/scr:progress`, `/scr:session-report`) -- already cheap; no orientation files to skip.
73
74
  - **First-write commands** (`/scr:new-work`, `/scr:import`) -- no CONTEXT.md exists yet.
74
- - **The CONTEXT.md regenerators themselves** (`/scr:save`, `/scr:pause-work`, `/scr:resume-work`) -- they MUST load the raw files to rebuild CONTEXT.md correctly. They are the *writers* of CONTEXT.md, not consumers.
75
+ - **The CONTEXT.md and PROGRESS.md regenerators themselves** (`/scr:save`, `/scr:pause-work`, `/scr:resume-work`) -- they MUST load the raw files to rebuild CONTEXT.md and the per-unit PROGRESS.md ledger correctly. They are the *writers* of those derived files, not consumers.
75
76
  - **`/scr:scan`** -- its job is to detect drift, so it must read the raw files to compare against CONTEXT.md.
76
77
 
77
78
  ## Expected savings
@@ -56,7 +56,7 @@ Do not turn `.manuscript/CONTEXT.md` into a glossary. It is an auto-regenerated
56
56
  | `cast` | `CHARACTERS.md`, `FIGURES.md` | Character state, voice anchors, relationships, figure continuity |
57
57
  | `world` | `WORLD.md`, `COSMOLOGY.md`, `SYSTEM.md` | Setting, constraints, environment, cosmology, operating rules |
58
58
  | `themes` | `THEMES.md`, `DOCTRINES.md`, `QUESTIONS.md` | Motifs, doctrine, argument, inquiry, recurring meaning |
59
- | `continuity` | `STATE.md`, `CONTEXT.md`, `HISTORY.log` | Current position, recent activity, open items, disk truth |
59
+ | `continuity` | `STATE.md`, `CONTEXT.md`, `PROGRESS.md`, `HISTORY.log` | Current position, recent activity, per-unit progress ledger, open items, disk truth |
60
60
  | `publication` | front matter, back matter, build files | Export and publishing intent |
61
61
  | `translation` | glossary, translation memory, language config | Term consistency and cultural adaptation |
62
62
  | `art` | cover, illustration, storyboard assets | Visual continuity and image direction |
@@ -1,6 +1,6 @@
1
1
  # HISTORY.log Protocol
2
2
 
3
- `.manuscript/HISTORY.log` is the project's append-only chronological record of Scriveno commands that mutate state. It is the third leg of the context-integrity stool, alongside `STATE.md` (structured snapshot) and `.manuscript/CONTEXT.md` (one-page bootstrap). Where STATE.md records *what is true now* and CONTEXT.md narrates *where you are*, HISTORY.log records *how you got here, in order*.
3
+ `.manuscript/HISTORY.log` is the project's append-only chronological record of Scriveno commands that mutate state. It is part of the context-integrity layer alongside `STATE.md` (structured snapshot), `RECORD.md` (established content), `.manuscript/CONTEXT.md` (one-page bootstrap), and `.manuscript/PROGRESS.md` (per-unit progress ledger). Where STATE.md records *what is true now* and CONTEXT.md narrates *where you are*, HISTORY.log records *how you got here, in order*.
4
4
 
5
5
  This document is the single source of truth for the line format. Every command that appends to HISTORY.log must follow this contract.
6
6
 
@@ -0,0 +1,132 @@
1
+ # Progress ledger protocol
2
+
3
+ This is the canonical contract for `.manuscript/PROGRESS.md`, Scriveno's openable per-unit progress ledger, and for how every command derives and renders unit status. The goal is one consistent answer to the question a writer asks most often: *what is done, what is in progress, what is untouched, and where are we in the journey?*
4
+
5
+ It is part of the trust layer, alongside the other derived and recorded surfaces:
6
+
7
+ - `STATE.md` -- structured workflow snapshot (aggregate counters, current position)
8
+ - `RECORD.md` -- compact established-content store
9
+ - `.manuscript/CONTEXT.md` -- one-page narrative bootstrap (synthesis, read first by a fresh session)
10
+ - `.manuscript/PROGRESS.md` -- per-unit progress ledger (the file you open to see every unit's status)
11
+ - `.manuscript/HISTORY.log` -- append-only audit trail
12
+
13
+ `STATE.md` answers "how many units are drafted." `PROGRESS.md` answers "which ones, and what state is each in." They never disagree because both are reconciled against disk, and `/scr:scan` is the trust check.
14
+
15
+ ## What PROGRESS.md is for
16
+
17
+ `STATE.md` holds aggregate counts (`Units drafted: 4 of 5`). That tells the writer how far along they are but not *which* unit is where. `PROGRESS.md` is the deliverable-level view: a single human-readable file the writer can open to see every unit with its status (done / in progress / untouched), the macro pipeline position, recent activity, and the next step. It is the writing-domain analog of a requirements checklist.
18
+
19
+ The template lives at `templates/PROGRESS.md`. The file is **derived**: never hand-edited, always rebuilt from disk. Like `CONTEXT.md`, it is not created at `/scr:new-work`; it is generated the first time a unit-status-changing command or a save/pause/resume runs.
20
+
21
+ ## The three status buckets
22
+
23
+ Every unit resolves to exactly one headline status. Derive it from disk first, then reconcile with `STATE.md`:
24
+
25
+ | Bucket | Marker | Disk condition |
26
+ |--------|--------|----------------|
27
+ | **Untouched** | `[ ]` | No plan file and no draft file for the unit. Not yet worked. |
28
+ | **In progress** | `[~]` | Started but not finished: a plan exists without a draft, a draft exists without a clean review, a review has open editor notes, or revisions are pending. |
29
+ | **Done** | `[x]` | The unit needs no more work this pass: it is submitted, or (for flows that stop at review) reviewed with no open notes. |
30
+
31
+ The headline bucket sits next to a finer **stage** so the writer sees both the rollup and the precise position.
32
+
33
+ ## Per-unit stage derivation (disk-first)
34
+
35
+ Match each outline unit to its files by unit number. Use the same evidence `/scr:scan` uses (see `commands/scr/scan.md`, checks 1-3):
36
+
37
+ - **untouched** -- no `.manuscript/plans/{N}-*-PLAN.md` (or legacy `.manuscript/{N}-*-PLAN.md`) and no `.manuscript/drafts/body/{N}-*-DRAFT.md`
38
+ - **discussed** -- a `{N}-CONTEXT.md` exists but no plan or draft yet
39
+ - **planned** -- a plan file exists, no draft file
40
+ - **drafted** -- a draft file exists, no review report
41
+ - **reviewed** -- a `.manuscript/reviews/{N}-REVIEW.md` (or legacy `{N}-EDITOR-NOTES.md`) exists; treat as *reviewed with open notes* (in progress) when the review or `STATE.md` lists unresolved items, otherwise *reviewed clean*
42
+ - **submitted** -- `STATE.md` marks the unit submitted
43
+
44
+ Map stages to buckets: `untouched` -> untouched; `discussed`, `planned`, `drafted`, `reviewed-with-open-notes`, `revisions-pending` -> in progress; `reviewed-clean` (when the flow stops at review) and `submitted` -> done.
45
+
46
+ Word count per unit comes from the unit's draft file(s); show `--` for units with no draft.
47
+
48
+ ## Pipeline position
49
+
50
+ The macro writing lifecycle is the default map (same chain `/scr:next` walks):
51
+
52
+ ```
53
+ seed > voice > outline > discuss > plan > draft > review > revise > publish > translate
54
+ ```
55
+
56
+ Compute the current stage as the first incomplete step across the whole project, render it as `Stage {index} of {total}: {Name}`, and show the track with the current stage bracketed, for example:
57
+
58
+ ```
59
+ seed > voice > outline > discuss > plan > [draft] > review > revise > publish > translate
60
+ ```
61
+
62
+ Translate is only relevant when the project has target languages configured; keep it in the track for orientation but never treat its absence as incomplete for a single-language project.
63
+
64
+ ## The deliverable progress bar
65
+
66
+ Render a 10-cell bar over the done fraction using block characters (`U+2588` filled, `U+2591` empty), followed by counts and percent:
67
+
68
+ ```
69
+ ████████░░ 4/5 scenes done (80%)
70
+ ```
71
+
72
+ The denominator is the total unit count from `OUTLINE.md`. Percent is `round(done / total * 100)`. Use the work type's plural unit label (scenes, chapters, surahs, procedures, poems, and so on) from `CONSTRAINTS.json`; never hard-code "chapter."
73
+
74
+ ## Ledger table shape
75
+
76
+ Group rows by the work type's mid level (act, part, sequence) when the outline has one, with a per-group rollup in the heading. Within a group, one row per atomic unit:
77
+
78
+ ```
79
+ ### Act I -- Disruption (2/2 done)
80
+
81
+ | # | Title | Stage | Status | Words |
82
+ |---|-------|-------|--------|-------|
83
+ | 1 | The Letter | submitted | [x] | 1,020 |
84
+ | 2 | The Workshop | reviewed | [x] | 1,010 |
85
+
86
+ ### Act II -- Decision (0/1 done, 1 in progress)
87
+
88
+ | # | Title | Stage | Status | Words |
89
+ |---|-------|-------|--------|-------|
90
+ | 3 | The Pier | drafted | [~] | 890 |
91
+ ```
92
+
93
+ For work types without a mid level (short story, poetry collection), use a single flat table.
94
+
95
+ ## Who regenerates PROGRESS.md
96
+
97
+ The ledger is a Level 2 safe local helper (see `docs/auto-invoke-policy.md`). It is rebuilt by the commands that change unit status or refresh derived state, never by a read-only command:
98
+
99
+ - `/scr:draft` -- after a unit is drafted and STATE.md is updated
100
+ - `/scr:editor-review` -- after a unit is marked reviewed
101
+ - `/scr:submit` -- after a unit is marked submitted
102
+ - `/scr:autopilot` -- after every unit, as part of the mandatory state update (so the file advances visibly during a run)
103
+ - `/scr:save`, `/scr:pause-work`, `/scr:resume-work` -- alongside `CONTEXT.md` regeneration, from the shared field set in `/scr:save` step 7
104
+ - `/scr:scan --fix` -- when the ledger is missing or stale
105
+
106
+ `/scr:progress` is read-only: it renders this picture live from disk and points the writer at `PROGRESS.md`, but it does not write the file. When the live view is ahead of the saved file (units changed since the last refresh), `/scr:progress` says so and suggests `/scr:save`.
107
+
108
+ ## Token reference
109
+
110
+ A regenerator fills these tokens in `templates/PROGRESS.md`:
111
+
112
+ | Token | Source |
113
+ |-------|--------|
114
+ | `{{LAST_UPDATED}}` | ISO 8601 timestamp of this regeneration |
115
+ | `{{LAST_COMMAND}}` | the command that triggered the rebuild |
116
+ | `{{TITLE}}`, `{{WORK_TYPE}}` | `config.json` |
117
+ | `{{UNIT_LABEL}}`, `{{UNIT_LABEL_PLURAL}}` | `CONSTRAINTS.json` hierarchy for the work type |
118
+ | `{{PROGRESS_BAR}}`, `{{DONE_PERCENT}}` | computed from the done fraction |
119
+ | `{{DONE_COUNT}}`, `{{IN_PROGRESS_COUNT}}`, `{{UNTOUCHED_COUNT}}`, `{{TOTAL_COUNT}}` | per-unit derivation above |
120
+ | `{{WORD_COUNT}}` | sum of draft word counts |
121
+ | `{{STAGE_INDEX}}`, `{{STAGE_TOTAL}}`, `{{STAGE_NAME}}`, `{{LIFECYCLE_TRACK}}` | pipeline position above |
122
+ | `{{LEDGER_TABLE}}` | grouped ledger rows above |
123
+ | `{{RECENT_ACTIONS}}` | last 3-5 lines of `HISTORY.log` (or STATE.md Last actions) as rows |
124
+ | `{{NEXT_STEP}}` | the suggestion `/scr:next` would emit |
125
+ | `{{LAST_SCAN}}`, `{{LAST_SCAN_VERDICT}}` | `STATE.md` if recorded, else `never run` / `unknown` |
126
+
127
+ ## When this protocol does not apply
128
+
129
+ - **Read-only views** (`/scr:progress`, `/scr:manuscript-stats`, `/scr:outline`) consume and render the derivation but do not write `PROGRESS.md`.
130
+ - **First-write commands** (`/scr:new-work`, `/scr:import`) -- no units exist yet; the ledger is generated on the first status-changing command or save.
131
+
132
+ The protocol is a hint, not a hard gate. A command that cannot parse the outline cleanly should fall back to the aggregate `STATE.md` counts and say so, rather than emit a wrong per-unit ledger.
@@ -2,6 +2,35 @@
2
2
 
3
3
  This document is the public-facing summary of what changed between package releases. For package history, see the root [CHANGELOG](../CHANGELOG.md).
4
4
 
5
+ ## 2.7.1 - 2026-05-30
6
+
7
+ ### What changed
8
+
9
+ - `scriveno status` now prints the progress ledger directly (a `Progress:` line with bar, done / in progress / untouched, and pipeline position), so the deliverable view is visible from the bundled CLI, not only to runtimes that load the engine module.
10
+ - Documentation-integrity pass: corrected the context-integrity layer description (now five files), added `PROGRESS.md` to the scan trust-file lists and the architecture template tree, and refreshed stale version and count references across the docs.
11
+
12
+ ### Why it matters
13
+
14
+ It closes the loop on the 2.7.0 progress ledger: the numbers are surfaced everywhere a writer looks, and the documentation matches the shipped behavior.
15
+
16
+ ## 2.7.0 - 2026-05-30
17
+
18
+ ### What changed
19
+
20
+ - Added a per-unit progress ledger: `.manuscript/PROGRESS.md` shows every unit as done / in progress / untouched, with a deliverable progress bar and pipeline position, and `/scr:progress` now leads with that view and points at the ledger file.
21
+ - `/scr:draft` and `/scr:autopilot` now narrate progress against the whole manuscript (unit N of total, percent).
22
+ - `lib/auto-invoke-engine.js` exposes `computeProgressLedger` so the ledger numbers are deterministic across runtimes; `docs/progress-protocol.md` documents the contract.
23
+
24
+ ### Why it matters
25
+
26
+ Writers asked for one place to see what is done, in progress, and untouched without re-deriving it each time. The ledger is that file, and because it is derived from disk it cannot silently drift from the real state of the manuscript.
27
+
28
+ ### Affected areas
29
+
30
+ - progress, draft, autopilot, outline, manuscript-stats, and scan commands
31
+ - the shared auto-invoke engine (computeProgressLedger)
32
+ - the trust-layer docs and templates
33
+
5
34
  ## 2.6.0 - 2026-05-29
6
35
 
7
36
  ### What changed
@@ -13,7 +13,7 @@ The text report summarizes command count, graph edges, agent-capable routes, loc
13
13
 
14
14
  ## Current Shape
15
15
 
16
- As of `2.6.0`, the route graph contains:
16
+ As of `2.7.1`, the route graph contains:
17
17
 
18
18
  - 113 commands
19
19
  - intent-order edges from `command_intents`
@@ -27,14 +27,16 @@ A contributor adding `templates/pitfalls/<work_type>.md` is automatically picked
27
27
 
28
28
  ## Context Integrity Assets Shipped Since 2.0.0
29
29
 
30
- These files ship in `templates/` and `docs/` and provide the trust trio for session-aware AI work:
30
+ These files ship in `templates/` and `docs/` and provide the context-integrity set for session-aware AI work:
31
31
 
32
32
  - `templates/CONTEXT.md` -- one-page session bootstrap scaffold copied into every project. Auto-regenerated on `/scr:save`, `/scr:pause-work`, `/scr:resume-work`. Read first by `/scr:next` and `/scr:resume-work` for orientation, with stale-detection + STATE.md fallback.
33
+ - `templates/PROGRESS.md` -- per-unit progress ledger scaffold: the openable file showing every unit as done / in progress / untouched, plus a deliverable progress bar and pipeline position. Derived from disk; auto-regenerated on `/scr:draft`, `/scr:editor-review`, `/scr:submit`, `/scr:autopilot`, `/scr:save`, `/scr:pause-work`, `/scr:resume-work`, and `/scr:scan --fix`. Rendered live by `/scr:progress`.
33
34
  - `templates/RECORD.md` -- compact established-content store copied into every project. It tracks what the work has established, including open threads, promises, payoffs, continuity facts, movement, and next-unit obligations. It is deliberately neutral so sacred, academic, technical, poetry, script, visual, and prose projects can all use the same filename.
34
35
  - `docs/context-protocol.md` -- canonical contract for the CONTEXT.md preference rule. The 12 high-impact commands that opt into the protocol reference this doc.
36
+ - `docs/progress-protocol.md` -- canonical contract for the `.manuscript/PROGRESS.md` per-unit ledger: status derivation from disk, the done / in progress / untouched buckets, pipeline position, the progress bar, and the regeneration points.
35
37
  - `docs/history-protocol.md` -- canonical line-format spec for `.manuscript/HISTORY.log`, the append-only audit trail. Pipe-delimited, UTC ISO timestamps, committed to git.
36
38
 
37
- `STATE.md` (workflow data) + `RECORD.md` (established content) + `CONTEXT.md` (narrative bootstrap) + `HISTORY.log` (audit trail) together form the integrity layer. `/scr:scan` is the trust check that interrogates whether the recorded state still matches disk.
39
+ `STATE.md` (workflow data) + `RECORD.md` (established content) + `CONTEXT.md` (narrative bootstrap) + `PROGRESS.md` (per-unit ledger) + `HISTORY.log` (audit trail) together form the integrity layer. `/scr:scan` is the trust check that interrogates whether the recorded state still matches disk.
38
40
 
39
41
  ## Runtime Sync Asset Shipped Today
40
42
 
@@ -820,6 +820,7 @@ function analyzeProject(projectRoot = process.cwd(), options = {}) {
820
820
  commandUnit: config.command_unit || 'unit',
821
821
  workType: config.work_type || '',
822
822
  counts: { drafts: 0, plans: 0, reviews: 0 },
823
+ progress: computeProgressLedger(manuscriptDir),
823
824
  signals,
824
825
  recommendation,
825
826
  automation,
@@ -871,6 +872,7 @@ function analyzeProject(projectRoot = process.cwd(), options = {}) {
871
872
  commandUnit: config.command_unit || 'unit',
872
873
  workType: config.work_type || '',
873
874
  counts,
875
+ progress: computeProgressLedger(manuscriptDir),
874
876
  signals,
875
877
  recommendation,
876
878
  automation,
@@ -879,12 +881,17 @@ function analyzeProject(projectRoot = process.cwd(), options = {}) {
879
881
 
880
882
  function formatProactiveChecks(analysis) {
881
883
  const { signals } = analysis;
884
+ const progress = analysis.progress || {};
882
885
  const stateLine = signals.hasProject
883
886
  ? ` State: ${signals.hasState ? 'fresh' : 'missing, suggest /scr:scan'}`
884
887
  : ' Project: missing, suggest /scr:new-work';
888
+ const progressLine = progress.total
889
+ ? ` Progress: ${progress.bar} ${progress.done}/${progress.total} done (${progress.percent}%), ${progress.inProgress} in progress, ${progress.untouched} untouched`
890
+ : ' Progress: no units yet';
885
891
  return [
886
892
  'Proactive checks:',
887
893
  stateLine,
894
+ progressLine,
888
895
  ` Readiness: ${signals.readiness?.state || 'none'}${signals.readiness?.missing?.length ? `, missing ${signals.readiness.missing.join(', ')}` : ''}`,
889
896
  ` Session: ${signals.context.state}${signals.context.suggest ? `, suggest ${signals.context.suggest}` : ''}`,
890
897
  ` Plans: ${signals.plan?.state || 'none'}${signals.plan?.suggest ? `, suggest ${signals.plan.suggest}` : ''}`,
@@ -1377,6 +1384,93 @@ if (require.main === module) {
1377
1384
  }
1378
1385
  }
1379
1386
 
1387
+ // Progress ledger: deterministic deliverable-progress computation from disk.
1388
+ // See docs/progress-protocol.md. Additive helper used by /scr:progress and any
1389
+ // runtime that loads this module, so the ledger is consistent across hosts.
1390
+ function ledgerUnitNumbers(dir, suffixRegex) {
1391
+ const found = new Set();
1392
+ let entries;
1393
+ try {
1394
+ entries = fs.readdirSync(dir);
1395
+ } catch (err) {
1396
+ return found;
1397
+ }
1398
+ for (const name of entries) {
1399
+ const match = name.match(suffixRegex);
1400
+ if (match) {
1401
+ found.add(parseInt(match[1], 10));
1402
+ }
1403
+ }
1404
+ return found;
1405
+ }
1406
+
1407
+ function ledgerOutlineUnitCount(manuscriptDir) {
1408
+ let text;
1409
+ try {
1410
+ text = fs.readFileSync(path.join(manuscriptDir, 'OUTLINE.md'), 'utf8');
1411
+ } catch (err) {
1412
+ return 0;
1413
+ }
1414
+ const tableRows = text.match(/^\|\s*\d+\s*\|/gm);
1415
+ if (tableRows && tableRows.length) {
1416
+ return tableRows.length;
1417
+ }
1418
+ const numberedLines = text.match(/^\s*\d+[.)]\s+\S/gm);
1419
+ return numberedLines ? numberedLines.length : 0;
1420
+ }
1421
+
1422
+ function ledgerBar(done, total, width) {
1423
+ const cells = width || 10;
1424
+ const filled = total > 0 ? Math.round((done / total) * cells) : 0;
1425
+ const clamped = Math.max(0, Math.min(cells, filled));
1426
+ return '█'.repeat(clamped) + '░'.repeat(cells - clamped);
1427
+ }
1428
+
1429
+ // Returns deliverable progress for a project's .manuscript directory: total
1430
+ // units, per-stage counts, the done / in-progress / untouched buckets, a
1431
+ // percent, a rendered bar, and the unit-number sets. Derived purely from disk
1432
+ // (plan/draft/review files reconciled with the OUTLINE unit count).
1433
+ function computeProgressLedger(manuscriptDir) {
1434
+ const drafted = ledgerUnitNumbers(
1435
+ path.join(manuscriptDir, 'drafts', 'body'),
1436
+ /^(\d+)\D.*DRAFT\.md$/i
1437
+ );
1438
+ const planned = ledgerUnitNumbers(path.join(manuscriptDir, 'plans'), /^(\d+)\D.*PLAN\.md$/i);
1439
+ for (const unit of ledgerUnitNumbers(manuscriptDir, /^(\d+)\D.*PLAN\.md$/i)) {
1440
+ planned.add(unit);
1441
+ }
1442
+ const reviewed = ledgerUnitNumbers(path.join(manuscriptDir, 'reviews'), /^(\d+)\D.*REVIEW\.md$/i);
1443
+ for (const unit of ledgerUnitNumbers(manuscriptDir, /^(\d+)\D.*EDITOR-NOTES\.md$/i)) {
1444
+ reviewed.add(unit);
1445
+ }
1446
+
1447
+ const worked = new Set([...planned, ...drafted, ...reviewed]);
1448
+ const maxWorked = worked.size ? Math.max(...worked) : 0;
1449
+ const total = Math.max(ledgerOutlineUnitCount(manuscriptDir), worked.size, maxWorked);
1450
+
1451
+ const done = reviewed.size;
1452
+ const inProgress = [...worked].filter((unit) => !reviewed.has(unit)).length;
1453
+ const untouched = Math.max(0, total - worked.size);
1454
+ const percent = total > 0 ? Math.round((done / total) * 100) : 0;
1455
+
1456
+ return {
1457
+ total,
1458
+ drafted: drafted.size,
1459
+ planned: planned.size,
1460
+ reviewed: reviewed.size,
1461
+ done,
1462
+ inProgress,
1463
+ untouched,
1464
+ percent,
1465
+ bar: ledgerBar(done, total, 10),
1466
+ units: {
1467
+ drafted: [...drafted].sort((a, b) => a - b),
1468
+ planned: [...planned].sort((a, b) => a - b),
1469
+ reviewed: [...reviewed].sort((a, b) => a - b),
1470
+ },
1471
+ };
1472
+ }
1473
+
1380
1474
  module.exports = {
1381
1475
  AGENT_ROUTE_POLICIES,
1382
1476
  CATEGORY_ROUTE_POLICIES,
@@ -1404,4 +1498,5 @@ module.exports = {
1404
1498
  inspectRuntimeSmoke,
1405
1499
  listRuntimeAgentSupport,
1406
1500
  parseCliArgs,
1501
+ computeProgressLedger,
1407
1502
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scriveno",
3
- "version": "2.6.0",
3
+ "version": "2.7.1",
4
4
  "description": "Spec-driven creative writing, publishing, and translation pipeline for AI coding agents. From blank page to published book.",
5
5
  "bin": {
6
6
  "scriveno": "bin/install.js"
@@ -0,0 +1,56 @@
1
+ ---
2
+ creative_pillar: continuity
3
+ always_load_for: [progress]
4
+ authority: derived
5
+ ---
6
+
7
+ # Progress ledger
8
+
9
+ This file is auto-regenerated by Scriveno. It is the one place to open and see every {{UNIT_LABEL}} at a glance: what is done, what is in progress, and what is untouched. Do not hand-edit -- it is rebuilt from disk whenever the project's unit status changes (on `/scr:draft`, `/scr:editor-review`, `/scr:submit`, `/scr:autopilot`, `/scr:save`, `/scr:pause-work`, `/scr:resume-work`, and `/scr:scan --fix`).
10
+
11
+ If this file is missing, stale, or disagrees with the live view from `/scr:progress`, run `/scr:save` (or `/scr:scan --fix`) to rebuild it. `/scr:progress` always renders the current picture from disk; this file is the saved snapshot you can open any time.
12
+
13
+ **Updated:** {{LAST_UPDATED}}
14
+ **Updated by:** {{LAST_COMMAND}}
15
+ **Project:** {{TITLE}} ({{WORK_TYPE}})
16
+
17
+ ## Deliverable progress
18
+
19
+ {{PROGRESS_BAR}} {{DONE_COUNT}}/{{TOTAL_COUNT}} {{UNIT_LABEL_PLURAL}} done ({{DONE_PERCENT}}%)
20
+
21
+ - **Done:** {{DONE_COUNT}}
22
+ - **In progress:** {{IN_PROGRESS_COUNT}}
23
+ - **Untouched:** {{UNTOUCHED_COUNT}}
24
+ - **Words:** {{WORD_COUNT}}
25
+
26
+ ## Pipeline position
27
+
28
+ Stage {{STAGE_INDEX}} of {{STAGE_TOTAL}}: {{STAGE_NAME}}
29
+
30
+ `{{LIFECYCLE_TRACK}}`
31
+
32
+ ## {{UNIT_LABEL}} ledger
33
+
34
+ Status key: `[x]` done `[~]` in progress `[ ]` untouched
35
+
36
+ {{LEDGER_TABLE}}
37
+
38
+ ## Recent activity
39
+
40
+ The last few recorded actions, newest first. Full history lives in `.manuscript/HISTORY.log`.
41
+
42
+ {{RECENT_ACTIONS}}
43
+
44
+ ## What's next
45
+
46
+ {{NEXT_STEP}}
47
+
48
+ ## Trust check
49
+
50
+ The status above is derived from disk: plan files in `.manuscript/plans/`, drafts in `.manuscript/drafts/body/`, and reviews in `.manuscript/reviews/`, reconciled with `.manuscript/STATE.md`. The numbers are claims, not facts -- run `/scr:scan` to confirm they still match disk.
51
+
52
+ **Last `/scr:scan` run:** {{LAST_SCAN}}
53
+ **Last drift verdict:** {{LAST_SCAN_VERDICT}}
54
+
55
+ ---
56
+ *Derived ledger. See `docs/progress-protocol.md` for how status is computed. This file is the saved snapshot; `/scr:progress` renders the same picture live.*
@@ -1,5 +1,5 @@
1
1
  {
2
- "scriveno_version": "2.6.0",
2
+ "scriveno_version": "2.7.1",
3
3
  "work_type": "",
4
4
  "group": "",
5
5
  "command_unit": "",