Commit graph

170 commits

Author SHA1 Message Date
TÂCHES
54df619891 feat: task isolation for subagent filesystem safety (#254)
* feat: add task isolation for subagent filesystem safety

Subagents can run in isolated git worktrees (or FUSE overlays on Linux)
so concurrent tasks don't stomp on each other's files. Changes are
captured as unified diffs and merged back via git apply.

- New isolation.ts module with worktree and FUSE overlay backends
- TaskIsolationSettings in settings-manager (mode + merge strategy)
- isolated parameter on the subagent tool schema
- Baseline capture/apply mirrors the parent repo's dirty state
- Process exit handler for best-effort cleanup of stale worktrees

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: correct delta capture to exclude parent baseline state

The worktree backend now commits a baseline snapshot after applying the
parent's dirty state, so captureDeltaPatch diffs only the subagent's
actual changes against the post-baseline HEAD (not the original HEAD).

The FUSE overlay backend tracks the parent's dirty file set at mount
time and filters the upper dir during delta capture to exclude inherited
dirty files.

Also removes dead code: findGitRoot (unused), readIsolationMergeStrategy
(exported but never called).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 16:10:55 -06:00
Lex Christopherson
4c2e40b9a3 docs: update system prompt routing for async_bash vs bg_shell 2026-03-13 16:05:09 -06:00
TÂCHES
fa9477f638 feat: async background jobs extension (#260) 2026-03-13 16:01:30 -06:00
Juan Francisco Lebrero
6f50c02a19 fix: auto-resolve .gsd/ planning artifact conflicts during slice merge
The merge conflict auto-resolution only handled RUNTIME_EXCLUSION_PATHS
(.gsd/activity/, .gsd/runtime/, .gsd/metrics.json, etc). Planning
artifacts like DECISIONS.md, REQUIREMENTS.md, PROJECT.md, and
ROADMAP.md were not covered, causing the merge to fail and auto-mode
to loop when both main and the slice branch modified these files.

Now any conflict limited to .gsd/ files is auto-resolved by taking
the slice branch version (--theirs), since the LLM just finished
updating these artifacts during complete-slice.
2026-03-13 18:30:38 -03:00
Lex Christopherson
064c4cfc1a feat: add native Rust GSD file parser for .gsd/ directory parsing
Implements a Rust napi-rs module that parses YAML-like frontmatter,
markdown sections, and roadmap structures from .gsd/ files. Provides
parseFrontmatter, extractSection, extractAllSections, batchParseGsdFiles,
and parseRoadmapFile functions exposed via @gsd/native. The JS parsers
in files.ts fall back transparently when the native module is unavailable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 14:12:17 -06:00
Lex Christopherson
ac34c7c283 feat: add native Rust TTSR regex engine via RegexSet
TTSR's checkDelta() runs O(rules x conditions) regex evaluations per
streaming token — the hottest path in GSD. This adds a Rust native
module that compiles all condition patterns into a single RegexSet,
testing them in one DFA pass instead of sequential JS RegExp iteration.

The TtsrManager transparently uses the native engine when available and
falls back to the existing JS regex loop when it is not.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 13:57:12 -06:00
TÂCHES
6acd001a59 feat(bg-shell): add env action to query shell session state (#238)
Enables querying the current working directory and environment variables
of a persistent shell session. Sends introspection commands to the shell's
stdin, captures output via sentinel-demarcated blocks, and parses key
environment variables. Useful for understanding accumulated shell state
after cd, source, or export commands.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 13:05:18 -06:00
TÂCHES
aaa96e1d1a feat: add run action to bg_shell for blocking command execution on persistent shells (#237)
Adds sentinel-based output demarcation to execute commands on existing
shell sessions, block until completion, and return structured output
with exit codes. Enables using bg-shell as a persistent execution
environment where shell state (env vars, cwd, virtualenvs) accumulates
across commands.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 13:02:11 -06:00
TÂCHES
df1c2b5b54 feat: add shell process type to bg-shell for persistent interactive sessions (#236)
Shell-type processes provide a persistent execution environment where shell
state accumulates across commands. Key behaviors:
- Auto-transitions to ready status after spawn (200ms delay)
- Defaults to user's shell when no command specified
- Extended dead process TTL (6x normal) for potential restart
- Command history tracking via commandHistory field
- Prompt guideline for discoverability

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 13:01:58 -06:00
TÂCHES
41418194e9 fix: untrack runtime files from slice branch before squash-merge (#218) (#220)
Squash-merges fail with conflicts in .gsd/metrics.json and
.gsd/completed-units.json because these runtime files get tracked on the
slice branch. The existing pre-merge untrack only runs on main, so the
squash-merge sees modify/delete conflicts.

Untrack runtime files from the slice branch before merging, matching the
existing main-branch untrack. Also switch runtime conflict auto-resolution
from --ours to --theirs as a more correct fallback.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 12:22:47 -06:00
Lex Christopherson
547610f016 feat: add universal config discovery extension
Auto-detects and normalizes configuration from 8 AI coding tools:
Claude Code, Cursor, Windsurf, Gemini CLI, Codex, Cline, GitHub
Copilot, and VS Code. Discovers MCP servers, rules/instructions,
context files, and settings from both user-level (~/) and project-level
(./) config directories.

Read-only — never modifies other tools' config files.

Provides:
- discover_configs tool (LLM-callable) with optional tool filter and
  session-scoped caching
- /configs slash command for quick overview
- 31 tests covering all 8 tool scanners, the discovery orchestrator,
  and output formatting

Config paths verified against Oh My Pi's discovery module
(can1357/oh-my-pi packages/coding-agent/src/discovery/).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-13 11:55:50 -06:00
TÂCHES
61b7e62f39 fix: resolve TypeScript type errors in misc extension files (#204) (#213)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:36:17 -06:00
TÂCHES
a5eebd8d98 fix: resolve TypeScript type errors in browser-tools extension (#204) (#212)
- Create core.d.ts with type declarations for the untyped core.js module
- Create tsconfig.extensions.json for type-checking browser-tools in isolation
- Fix collectAssertionState adapter to match ToolDeps signature by wrapping with captureCompactPageState binding
- Fix captureAccessibilityMarkdown adapter to match ToolDeps signature by binding getActiveTarget()
- Add explicit Element | null type annotation to refs.ts parent variable (TS7022 circular inference)
- Fix session.ts timeline.count to timeline.retained (nonexistent property on formatTimelineEntries result)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:35:47 -06:00
TÂCHES
940b6a38dc fix: resolve TypeScript type errors in gsd extension files (#204) (#211)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:34:34 -06:00
TÂCHES
5896cd2e2a fix: resolve TypeScript type errors in search-the-web extension (#204) (#210)
- Add .js extensions to all relative imports for NodeNext module resolution
- Cast pi.writeTempFile to (pi as any) since it exists at runtime but not on ExtensionAPI type
- Add details: undefined as unknown to return objects missing the required details field
- Fix onUpdate calls to include details field required by AgentToolResult

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:34:07 -06:00
TÂCHES
1fc3a4ca77 Merge pull request #207 from gsd-build/feat/130-prefs-wizard
feat: add interactive wizard mode for /gsd prefs
2026-03-13 11:01:47 -06:00
Lex Christopherson
c622e1d3a6 fix: address audit findings for prefs wizard (#130)
- YAML-safe string quoting for values with special characters
- Preserve existing body content below frontmatter on wizard save
- Preserve existing version instead of hardcoding version: 1
- Update unknown-command fallback to include wizard|setup subcommands
- Show warning when timeout input is not a valid whole number

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:59:27 -06:00
Lex Christopherson
401397362f fix: deduplicate maxNum logic and add nextMilestoneId tests (#177)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:59:10 -06:00
Lex Christopherson
46a083fc5e feat: add interactive wizard mode for /gsd prefs (#130)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:52:55 -06:00
Lex Christopherson
d2fd92f8fc fix: use max-based milestone ID generation instead of length+1 (#177)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:52:52 -06:00
TÂCHES
d9548cdf26 fix: pause auto-mode on provider errors to prevent reassess-roadmap loop (#95) (#202)
When a provider returns a fetch error, the agent_end hook now detects
stopReason === "error" and pauses auto-mode. This prevents the state
machine from silently re-dispatching the same phase until stuck
detection fires.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:39:00 -06:00
TÂCHES
7d64aac6bb fix: show TAB hint for notes input in discuss-mode survey (#192) (#203)
The "None of the above" option description said "add details in notes
below" without telling users to press TAB to reveal the notes input.
Updated the description to "Press TAB to add optional notes." and made
the footer "tab to add notes" hint always visible in single-select mode
(previously hidden until a selection was committed).

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:38:47 -06:00
Adam Dry
2ed7c830d9 fix: merge slice branches to integration branch instead of main (#200)
When working on a feature branch (e.g. f-123-new-thing), GSD creates
slice branches correctly from the current branch but merges them back
to main instead of the feature branch. This is because getMainBranch()
always resolved to the repo default branch with no concept of where
the user started.

Fix: record the current branch as the "integration branch" in a
per-milestone metadata file (.gsd/milestones/<MID>/<MID>-META.json)
when auto-mode starts. getMainBranch() checks this metadata before
falling back to repo defaults, so switchToMain() and mergeSliceToMain()
target the correct branch.

Key details:
- Integration branch is captured once per milestone (idempotent)
- Committed immediately so it survives branch switches (.gsd/ files
  are discarded during checkout)
- main_branch preference still takes highest priority
- Falls back to existing detection if metadata missing (backward compat)
- Per-milestone: different milestones can target different branches
- Validates branch still exists before using it

Tests: 41 new assertions across git-service.test.ts and worktree.test.ts
covering the full lifecycle, multi-slice workflows, resume scenarios,
backward compatibility, and edge cases.
2026-03-13 10:34:28 -06:00
TÂCHES
3084366d87 fix: handle undefined result from custom() in RPC mode for ask_user_questions (#156, #165, #171) (#199)
In RPC mode, `ctx.ui.custom()` returns `undefined as never`, causing
`showInterviewRound` to return undefined and `Object.keys(result.answers)`
to throw TypeError.

When `showInterviewRound` returns undefined (RPC mode), fall back to
sequential `ctx.ui.select()` calls for each question, forwarding the
abort signal (#171) and supporting `allowMultiple` (#165).

- Add `allowMultiple` to `ExtensionUIDialogOptions`
- Widen `select()` return type to `string | string[] | undefined`
- Add `allowMultiple` to RPC select request and `values` array to response
- Update RPC `select()` to forward `allowMultiple` and parse array responses
- Guard existing `ctx.ui.select()` callers against the widened return type

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:24:57 -06:00
TÂCHES
af27c5dd3c fix: provider-aware model resolution for per-phase preferences (#149) (#198)
Auto mode's model resolution used `allModels.find(m => m.id === modelId)`
which returns the first match regardless of provider. With 30+ duplicate
model IDs across providers, user preferences silently resolved to the
wrong provider.

Three fixes:
- Use `getAvailable()` instead of `getAll()` so only authenticated
  models are considered
- Support `provider/model` format (e.g. "google/gemini-2.5-pro") for
  explicit provider targeting
- For bare IDs, prefer the current session's provider, then first
  available match, with an ambiguity warning
- Store and restore original model provider instead of hardcoding
  "anthropic" when restoring the user's model after auto-mode

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:23:31 -06:00
TÂCHES
f2c6cad4dd fix: align execute-task artifact verification with deriveState and add self-repair (#133) (#195)
verifyExpectedArtifact only checked for the task summary file, but
deriveState determines the next task by finding the first unchecked
checkbox in the slice plan. When the agent writes the summary but
doesn't mark the checkbox, the dispatch loop re-sends the same unit
and gets stuck after max retries.

Part 1: verifyExpectedArtifact now also checks that the task checkbox
is marked [x] in the slice plan for execute-task units.

Part 2: At retry time, if the summary exists but the checkbox is
unmarked, the dispatch logic self-repairs by marking the checkbox
programmatically (via skipExecuteTask) and re-derives state instead
of re-dispatching the same unit.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:23:23 -06:00
TÂCHES
e68f486d8b fix: break research phase infinite loop and sync state on stop (#126) (#193)
Bug 1: resolveMilestoneFile/resolveSliceFile already check file existence
via readdirSync, so the additional loadFile content check was redundant.
Empty research files (exists on disk but no content) caused a loop where
verifyExpectedArtifact marked research complete while dispatch re-triggered
it because loadFile returned falsy for empty files.

Bug 2: stopAuto now calls rebuildState to synchronize disk state, matching
pauseAuto's pattern and preventing stale state on next resume.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:23:15 -06:00
TÂCHES
22cbd2bec3 fix: auto-resolve merge conflicts on .gsd/ runtime files (#189) (#194)
Auto mode exits when mergeSliceToMain() hits conflicts on runtime files
like completed-units.json that were manually committed via `gsd queue`.

Two-part fix:
- Untrack RUNTIME_EXCLUSION_PATHS from the index before merge starts
- If merge conflicts are limited to runtime files, auto-resolve by
  taking ours and removing from index instead of aborting

Closes #189

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:23:07 -06:00
TÂCHES
c344b0af54 fix: use provider field instead of model name prefix for Anthropic detection (#142) (#196)
The before_provider_request hook used model.startsWith("claude") to gate
native web search injection. This matched claude-* models served by any
provider (GitHub Copilot, AWS Bedrock, etc.), incorrectly injecting
Anthropic-only web_search_20250305 tool definitions into non-Anthropic
API requests.

The fix checks the isAnthropicProvider flag (set by model_select via the
provider field) instead of sniffing the model name.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:22:52 -06:00
Lex Christopherson
d9a9a73ab2 fix: replace hardcoded forward-slash path ops with node:path stdlib (#184)
Three locations used lastIndexOf("/") or includes("/") for path
manipulation, which fails on Windows where paths use backslashes.

- auto.ts: writeBlockerPlaceholder directory extraction → dirname()
- interactive-mode.ts: parent directory traversal → path.dirname() loop
- path-utils.ts: non-null assertion on MSYS drive letter access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 10:02:20 -06:00
Lex Christopherson
74278ad865 fix: use relative paths in prompts to prevent Windows drive letter mangling (#184)
On Windows, LLMs convert absolute paths like F:\Projects\.gsd\... to
Unix-style /f/Projects/.gsd/... which Node's path.resolve interprets
as drive-root-relative, creating F:\f\Projects\.gsd\... instead.

Replace all *AbsPath template variables in prompt templates with
relative .gsd/... paths that resolve correctly on all platforms.
Add MSYS path normalization in resolveToCwd as defense-in-depth.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:55:15 -06:00
Lex Christopherson
2846f9fcf7 fix: untrack runtime files already in git index to prevent merge conflicts (#187)
Repos that started tracking .gsd/completed-units.json before the
gitignore rule was added continue to see squash-merge conflicts because
.gitignore only prevents new tracking. This adds a bootstrap step that
runs `git rm --cached` on all RUNTIME_EXCLUSION_PATHS, eliminating the
conflict at its source.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:45:25 -06:00
TÂCHES
dde84fa248 Merge pull request #185 from Jamie-BitFlight/docs/preferences-clarification
docs: clarify preferences semantics and best practices
2026-03-13 09:34:36 -06:00
Lex Christopherson
98c2d23ce6 fix: sanitize Windows NUL redirects to /dev/null in Git Bash (#157)
LLM-generated commands with `> NUL` create undeletable files on Windows
because Git Bash treats NUL as a literal filename. Rewrite NUL redirects
to /dev/null at all three bash spawn sites.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:33:28 -06:00
Jamie McGregor Nelson
5d33805182 docs: add code references to clarify semantics and best practices
Adds verification against actual code:

- Empty arrays deleted: preferences.ts lines 583-587
- Arrays concatenated: preferences.ts lines 504-508, 659-667
- Scalar fields use ??: preferences.ts lines 503, 510, 514
- Object fields shallow merge: preferences.ts line 509
- skill_discovery independent from skill preference fields
2026-03-13 11:25:12 -04:00
Lex Christopherson
498614c95f fix: inject observability warnings into agent prompt for enforcement (#174)
emitObservabilityWarnings only called ctx.ui.notify — the agent never
saw the warnings and ignored them entirely. Validator caught real issues
(missing observability sections, placeholder diagnostics) but had zero
enforcement.

Rename to collectObservabilityWarnings (returns issues), add
buildObservabilityRepairBlock to format issues as actionable prompt
instructions. Appended to the unit prompt so the agent reads flagged
files and fixes gaps before proceeding with the unit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:20:19 -06:00
Lex Christopherson
788c356a25 fix: auto-detect headless environment for Playwright browser launch (#183)
Browser launch was hardcoded to headless: false, crashing on Linux
servers without a display server ($DISPLAY). Auto-detect headless
environments and also support FORCE_HEADLESS=true override.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:16:26 -06:00
Lex Christopherson
66196b4a4f fix: add configurable merge_strategy preference for slice completion (#167)
Squash merge was hardcoded, causing auto-mode to hard-stop when conflicts
arose from long-lived branches or frequently-changing .gsd/* artifacts.

Add git.merge_strategy preference ("squash" | "merge", default: squash).
"merge" uses --no-ff which preserves branch history and handles conflicts
from divergent branches more gracefully. Users hitting repeated squash
merge failures can set merge_strategy: merge in .gsd/preferences.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:16:26 -06:00
Lex Christopherson
71d3a69646 fix: verify UAT artifact before marking complete-slice done (#176, #175)
complete-slice verification only checked for the SUMMARY file, so when
the LLM skipped writing the UAT, the unit was marked complete and UAT
was never produced. Users saw doctor-created placeholder UATs instead
of real test scripts.

- verifyExpectedArtifact now checks both SUMMARY and UAT for complete-slice
- complete-slice prompt strengthened: step 7 requires concrete test cases,
  MUST line lists all three required artifacts with enforcement warning

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:16:26 -06:00
Lex Christopherson
94bd622f0c fix: update stale comment to reflect 7 runtime exclusion paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 09:16:26 -06:00
dan bachelder
064a15f988 fix(gsd-auto): require prior slices complete on main (#160) 2026-03-13 08:56:34 -06:00
deseltrus
87a1e51bc0 fix: smartStage fallback bypasses runtime exclusions when .gsd/ is gitignored (#168)
Three-layer fix for runtime files leaking into git commits:

1. Stage-then-unstage: replace pathspec excludes with git add -A followed
   by git reset HEAD for each exclusion. The old approach failed when .gsd/
   was in .gitignore — git exited non-zero before evaluating the excludes,
   and the catch fallback staged everything unconditionally.

2. Auto-cleanup: on first smartStage call per session, remove any runtime
   files that are already tracked in the index (from the fallback bug) via
   a dedicated commit. This is a one-time migration that self-heals repos
   where runtime files were accidentally committed.

3. Pre-checkout discard: after pre-switch auto-commits that exclude .gsd/,
   run git checkout -- .gsd/ to clear dirty runtime files that would
   otherwise block git checkout when the target branch has different
   tracked versions.

Also adds completed-units.json to RUNTIME_EXCLUSION_PATHS and
BASELINE_PATTERNS (was missing — metrics.json was listed but
completed-units.json was not).
2026-03-13 08:53:58 -06:00
deseltrus
dcd993064c feat(gsd): add discussion depth verification and context write-gate (#181)
- Prompt enhancements: sparring patterns, enrichment reflection, depth
  verification checkpoint, depth-preservation guidance for context.md
- Write-gate: block milestone CONTEXT.md writes until depth verification
  is confirmed via ask_user_questions with depth_verification id
- Discussion persistence: auto-save exchanges to DISCUSSION.md during
  discuss phase with structured markdown formatting
- Depth state management: track verification status, reset on discuss
  phase completion, expose getDiscussionMilestoneId() for gate checks
- 7 unit tests covering write-gate logic (pure function, no mocks needed)
2026-03-13 08:53:00 -06:00
TÂCHES
9009e5dd78 Merge pull request #158 from deseltrus/feat/guided-flow-escape-hatch
feat: add skip/discard escape hatches to no-roadmap wizard
2026-03-13 08:50:04 -06:00
Ryan Harrington
9f58583888 fix/gsd-graceful-exit: make /exit use graceful shutdown (#134)
* fix/gsd-graceful-exit: make /exit use graceful shutdown

* fix/gsd-graceful-exit: restore auto cleanup in exit command
2026-03-13 08:47:55 -06:00
TÂCHES
789a6645da feat: TTSR + blob/artifact storage (ported from oh-my-pi)
* docs(M002): context, requirements, and roadmap

* feat: port TTSR and blob/artifact storage from oh-my-pi

Phase 1 — TTSR (Time Traveling Stream Rules):
- TtsrManager: regex-based stream monitoring with scope filtering,
  repeat gating, and buffer isolation (picomatch replaces Bun.Glob)
- Rule loader: scans ~/.gsd/agent/rules/*.md and .gsd/rules/*.md
  with YAML frontmatter parsing; project rules override global
- TTSR extension: wires into pi event lifecycle (session_start,
  turn_start, message_update, turn_end, agent_end) to abort on
  match and inject violation as system reminder via sendMessage
- Interrupt template for rule violation injection

Phase 2 — Blob/Artifact Storage:
- BlobStore: content-addressed storage at ~/.gsd/agent/blobs/ using
  Node crypto (sha256), sync I/O, automatic deduplication
- ArtifactManager: session-scoped sequential artifact files stored
  alongside session JSONL (lazy dir creation, resume-safe ID scan)
- Session manager integration: prepareForPersistence externalizes
  images ≥1KB to blob store before JSONL write; resolveBlobRefs
  rehydrates on session load; truncates strings >500KB
- Bash tool artifact spill: uses ArtifactManager instead of temp
  files when available, includes artifact:// references in output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: harden blob store, TTSR manager, and dep classification

- Validate SHA-256 hex format in BlobStore.get/has/parseBlobRef to
  prevent path traversal via crafted blob references
- Cap TTSR per-stream buffers at 512KB to prevent unbounded memory growth
- Move picomatch from devDependencies to dependencies (runtime import)
- Warn on invalid regex in TTSR rule conditions instead of silent skip
- Remove .gsd/ planning files that were force-added past .gitignore
- Add trailing newline to ttsr-interrupt.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add tests for blob store, artifact manager, TTSR manager, and rule loader

55 tests covering:
- BlobStore put/get/has, idempotency, path traversal rejection
- parseBlobRef/isBlobRef validation, externalize/resolve round-trips
- ArtifactManager sequential IDs, lazy dir creation, session resume
- TtsrManager rule matching, scope filtering, buffer isolation,
  repeat gating, buffer size cap, injection persistence
- Rule loader frontmatter parsing, directory scanning, merge logic

Also fixes BlobStore constructor to avoid TS parameter property syntax
(incompatible with Node's strip-only TypeScript mode).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:43:56 -06:00
Lex Christopherson
5155d69d55 test(M002/S06): Test coverage
Tasks:
- chore(M002/S06): auto-commit after complete-slice
- chore(M002/S06): auto-commit after complete-slice
- chore(M002/S06/T02): auto-commit after execute-task
- chore(M002/S06/T02): auto-commit after execute-task
- chore(M002/S06/T01): auto-commit after execute-task
- chore(M002/S06/T01): auto-commit after execute-task
- chore(M002/S06): auto-commit after plan-slice
- chore: update state for S06 execution
- docs(S06): add slice plan

Branch: gsd/M002/S06
2026-03-13 08:04:27 -06:00
Lex Christopherson
8c549bd9c7 feat(M002/S05): Intent-ranked retrieval and semantic actions
Tasks:
- chore(M002/S05): auto-commit after complete-slice
- chore(M002/S05): auto-commit after complete-slice
- chore(M002/S05/T01): auto-commit after execute-task
- chore(M002/S05/T01): auto-commit after execute-task
- chore(M002/S05): auto-commit after plan-slice
- docs(S05): add slice plan

Branch: gsd/M002/S05
2026-03-13 08:04:27 -06:00
Lex Christopherson
57f6b0fd90 feat(M002/S04): Form intelligence
Tasks:
- chore(M002/S04): auto-commit after complete-slice
- chore(M002/S04): auto-commit after complete-slice
- chore(M002/S04/T02): auto-commit after execute-task
- chore(M002/S04/T02): auto-commit after execute-task
- chore(M002/S04/T01): auto-commit after execute-task
- chore(M002/S04): auto-commit after plan-slice
- docs(S04): add slice plan

Branch: gsd/M002/S04
2026-03-13 08:04:27 -06:00
Lex Christopherson
68cf10eed5 feat(M002/S03): Screenshot pipeline
Tasks:
- chore(M002/S03): auto-commit after complete-slice
- chore(M002/S03): auto-commit after complete-slice
- chore(M002/S03/T01): auto-commit after execute-task
- chore(M002/S03/T01): auto-commit after execute-task
- chore(M002/S03): auto-commit after plan-slice
- docs(S03): add slice plan

Branch: gsd/M002/S03
2026-03-13 08:04:27 -06:00