Main shipped /plan-ceo-review + /office-hours mode-posture fixes as
v1.1.2.0 — same version slot this branch used. Bumped ours to
v1.1.3.0.
Resolved conflicts:
- VERSION / package.json: 1.1.2.0 → 1.1.3.0
- CHANGELOG.md: our entry moved up to [1.1.3.0], main's mode-posture
entry kept at [1.1.2.0]. Sequence: 1.1.3.0 → 1.1.2.0 → 1.1.1.0 →
1.1.0.0 → 1.0.0.0
- Migration renamed v1.1.2.0.sh → v1.1.3.0.sh (version string inside
+ test path reference + hardening test describe block all updated)
Also expanded our CHANGELOG entry to reflect the testing work that
landed over the debugging loop: 8 live-fire E2E tests, 21 free-tier
hardening tests, collision sentinel, env: param on runSkillTest, and
GSTACK_HOME storage-path fix.
No code overlap with main's changes (main edited preamble writing-style
rules + plan-ceo-review and office-hours templates; ours edited
context-save / context-restore / migration / tests). SKILL.md files
regenerated via bun run gen:skill-docs --host all. Golden fixtures
updated.
bun test: 0 failures after renaming v1.1.2.0 → v1.1.3.0 in the hardening
test describe block and MIGRATION constant.
21 unit-level tests covering the security + correctness hardening
that landed in commit 3df8ea86. Free tier, 142ms runtime.
Title sanitizer (9 tests):
- Shell metachars stripped to allowlist [a-z0-9.-]
- Path traversal (../../../) can't escape CHECKPOINT_DIR
- Uppercase lowercased
- Whitespace collapsed to single hyphen
- Length capped at 60 chars
- Empty title → "untitled"
- Only-special-chars → "untitled"
- Unicode (日本語, emoji) stripped to ASCII
- Legitimate semver-ish titles (v1.0.1-release-notes) preserved
Filename collision (4 tests):
- First save → predictable path
- Second save same-second same-title → random suffix appended
- Prior file intact after collision-resolved write (append-only contract)
- Different titles same second → no suffix needed
Restore flow cap + empty-set (5 tests):
- Missing directory → NO_CHECKPOINTS
- Empty directory → NO_CHECKPOINTS
- Non-.md files only (incl .DS_Store) → NO_CHECKPOINTS
- 50 files → exactly 20 returned, newest-by-filename first
- Scrambled mtimes → still sorts by filename prefix (not ls -1t)
- No cwd-fallback when empty (macOS xargs ls gotcha)
Migration HOME guard (2 tests):
- HOME unset → exits 0 with diagnostic, no stdout
- HOME="" → exits 0 with diagnostic, no stdout (no "Removed stale"
messages proves no filesystem access attempted)
The bash snippets are copied verbatim from context-save/SKILL.md.tmpl
and context-restore/SKILL.md.tmpl. If the templates drift, these tests
fail — intentional pinning of the current behavior.