@tekyzinc/gsd-t 3.10.10 → 3.10.11

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 CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to GSD-T are documented here. Updated with each release.
4
4
 
5
+ ## [3.10.11] - 2026-04-15
6
+
7
+ ### Added
8
+ - `docs/unattended-config.md` — full schema and recipe reference for `.gsd-t/.unattended/config.json`. The supervisor has always loaded this file (M36 safety rails), but there was no user-facing doc explaining the schema, precedence, or common overrides.
9
+ - `commands/gsd-t-unattended.md` Step 1c cross-references the new config doc and calls out the solo-project recipe (`{"protectedBranches": []}` to disable the main/master guard).
10
+
11
+ ### Fixed
12
+ - Flaky test: `scripts/gsd-t-context-meter.e2e.test.js` `HARD_TIMEOUT_MS` bumped 6000 → 12000ms. The hook child process runs fine in 30ms in isolation but was timing out under full-suite parallelism load on some machines. No behavioral change — just a more forgiving outer cap.
13
+ - `commands/gsd-t-unattended.md` gained Step 1e: pre-flight software check that hard-fails the launch if `node`, `claude`, or `git` are missing, and prints soft warnings for missing platform helpers (`caffeinate` on darwin; `systemd-inhibit`/`notify-send` on linux; BurntToast advisory on win32). Replaces the previous "crash mid-run when a helper is missing" behavior with fail-fast + actionable install instructions.
14
+ - `docs/unattended-windows-caveats.md` added §0 "Required Software" matrix listing hard-required and soft-recommended tools per platform.
15
+
16
+ ### Notes
17
+ - No API or contract changes. `.gsd-t/.unattended/config.json` loader and precedence (CLI > env > config > defaults) were already built into M36 safety rails — this release only surfaces them in documentation.
18
+
5
19
  ## [3.10.10] - 2026-04-15
6
20
 
7
21
  ### Major version bump: 2.x → 3.x
@@ -77,6 +77,12 @@ Parse `$ARGUMENTS` for:
77
77
  - `--max-iterations=N` — iteration cap (default: `200`)
78
78
  - `--dry-run` — preflight only; print what would be spawned, do NOT spawn
79
79
 
80
+ **Persistent overrides**: create `.gsd-t/.unattended/config.json` to change
81
+ defaults per-project (caps, protected branches, dirty-tree whitelist). CLI
82
+ flags always win over the config file. See `docs/unattended-config.md` for
83
+ the full schema and common recipes (e.g. `{"protectedBranches": []}` for
84
+ solo projects that commit directly to main).
85
+
80
86
  Run via Bash to read the current milestone from progress.md:
81
87
 
82
88
  ```bash
@@ -0,0 +1,138 @@
1
+ # Unattended Supervisor — Configuration File
2
+
3
+ **File**: `.gsd-t/.unattended/config.json` (optional, per-project)
4
+ **Contract reference**: `.gsd-t/contracts/unattended-supervisor-contract.md` §13
5
+ **Loader**: `bin/gsd-t-unattended-safety.js` → `loadConfig(projectDir)`
6
+ **Consumer**: `bin/gsd-t-unattended.js` (supervisor entrypoint)
7
+
8
+ The unattended supervisor reads an optional JSON config file at
9
+ `.gsd-t/.unattended/config.json`. If present, its fields override the
10
+ hardcoded defaults. If absent, the supervisor runs with the defaults below.
11
+ Malformed JSON fails the launch with exit code 2 (preflight-failure) — the
12
+ supervisor never silently falls back on a broken config.
13
+
14
+ ## Precedence
15
+
16
+ From highest to lowest:
17
+
18
+ 1. **CLI flags** passed to `/user:gsd-t-unattended` (e.g. `--hours=48`)
19
+ 2. **Environment variables** (`GSD_T_HOURS`, `GSD_T_MAX_ITERATIONS`, etc.)
20
+ 3. **`.gsd-t/.unattended/config.json`** fields
21
+ 4. **Hardcoded defaults** in `bin/gsd-t-unattended-safety.js` → `DEFAULTS`
22
+
23
+ A CLI flag always wins. An env var beats the config file. The config file
24
+ beats the built-in defaults. Missing fields fall through to the next level
25
+ individually — a config with only `protectedBranches` still uses the default
26
+ `hours`, `maxIterations`, etc.
27
+
28
+ ## Schema
29
+
30
+ ```json
31
+ {
32
+ "hours": 24,
33
+ "maxIterations": 200,
34
+ "protectedBranches": ["main", "master", "develop", "trunk", "release/*", "hotfix/*"],
35
+ "dirtyTreeWhitelist": [
36
+ ".gsd-t/heartbeat-*.jsonl",
37
+ ".gsd-t/.context-meter-state.json",
38
+ ".gsd-t/events/*.jsonl",
39
+ ".gsd-t/token-metrics.jsonl",
40
+ ".gsd-t/token-log.md",
41
+ ".gsd-t/.unattended/*",
42
+ ".gsd-t/.handoff/*",
43
+ ".claude/settings.local.json",
44
+ ".claude/settings.local.json.bak*"
45
+ ],
46
+ "gutterNoProgressIters": 5,
47
+ "workerTimeoutMs": 3600000
48
+ }
49
+ ```
50
+
51
+ ### Field reference
52
+
53
+ | Field | Type | Default | Purpose |
54
+ |---|---|---|---|
55
+ | `hours` | number | `24` | Wall-clock cap in hours. Supervisor exits with code 6 (gutter) once `wallClockElapsedMs >= hours * 3600 * 1000`. |
56
+ | `maxIterations` | integer | `200` | Iteration cap. Supervisor exits with code 6 once `iter >= maxIterations`. |
57
+ | `protectedBranches` | string[] | `["main","master","develop","trunk","release/*","hotfix/*"]` | Branches where the pre-launch guard refuses to spawn. Glob patterns supported (`*`, `**`, `?`). Empty array = no branch protection. |
58
+ | `dirtyTreeWhitelist` | string[] | (see defaults) | Files that can be dirty without triggering the clean-worktree refusal. Glob patterns supported. Non-whitelisted dirty files cause exit code 8. |
59
+ | `gutterNoProgressIters` | integer | `5` | Lookback window for the no-progress gutter detector. Larger = less sensitive. |
60
+ | `workerTimeoutMs` | integer | `3600000` (1h) | Hard wall-clock timeout for a single `claude -p` worker iteration. Exceeding this causes worker SIGTERM + exit code 3. |
61
+
62
+ ## Common Overrides
63
+
64
+ ### Solo project — commit directly to main
65
+
66
+ For projects where you're the only contributor and main is your working
67
+ branch, disable the protected-branch guard:
68
+
69
+ ```json
70
+ {
71
+ "protectedBranches": []
72
+ }
73
+ ```
74
+
75
+ The safety rail still runs, but with an empty list nothing matches, so the
76
+ guard always allows. The Destructive Action Guard, blocker sentinels, caps,
77
+ and Red Team are all still active — you're only opting out of one specific
78
+ check.
79
+
80
+ ### Long overnight runs
81
+
82
+ Raise the caps for multi-day unattended milestones:
83
+
84
+ ```json
85
+ {
86
+ "hours": 72,
87
+ "maxIterations": 600
88
+ }
89
+ ```
90
+
91
+ ### Extra-noisy project
92
+
93
+ If your project writes logs or caches outside the default whitelist and you
94
+ don't want to commit or stash them before each run:
95
+
96
+ ```json
97
+ {
98
+ "dirtyTreeWhitelist": [
99
+ ".gsd-t/heartbeat-*.jsonl",
100
+ ".gsd-t/.context-meter-state.json",
101
+ ".gsd-t/events/*.jsonl",
102
+ ".gsd-t/token-metrics.jsonl",
103
+ ".gsd-t/token-log.md",
104
+ ".gsd-t/.unattended/*",
105
+ ".gsd-t/.handoff/*",
106
+ ".claude/settings.local.json",
107
+ "logs/**",
108
+ "tmp/**",
109
+ "*.local.cache"
110
+ ]
111
+ }
112
+ ```
113
+
114
+ Whitelist is a replacement, not an append. If you override it, restate the
115
+ defaults you want to keep.
116
+
117
+ ## Validation
118
+
119
+ The loader in `bin/gsd-t-unattended-safety.js` merges field-by-field. Only
120
+ the fields you set are overridden — everything else keeps its default. If
121
+ the file exists but isn't valid JSON, the launcher aborts with:
122
+
123
+ ```
124
+ [gsd-t-unattended] preflight-failure: safety-rails: malformed JSON in
125
+ .gsd-t/.unattended/config.json: <parse error>
126
+ ```
127
+
128
+ and exits with code 2. The PID file, state file, and run log are never
129
+ written on a preflight failure.
130
+
131
+ ## Git
132
+
133
+ `.gsd-t/.unattended/` is in the dirty-tree whitelist, so you can either:
134
+ - **Commit the config** — makes it part of the project's canonical setup
135
+ - **Gitignore the config** — treat it as a per-developer preference
136
+
137
+ Both work. There's no preferred choice — it depends on whether your team
138
+ wants a uniform cap across machines or lets each developer tune their own.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tekyzinc/gsd-t",
3
- "version": "3.10.10",
3
+ "version": "3.10.11",
4
4
  "description": "GSD-T: Contract-Driven Development for Claude Code — 61 slash commands with unattended supervisor relay, headless CI/CD mode, graph-powered code analysis, real-time agent dashboard, execution intelligence, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
5
5
  "author": "Tekyz, Inc.",
6
6
  "license": "MIT",