Tom Boucher 75287effb9 feat(115): secret-scan exclusion governance + --strict reduced-scan mode (#134)
* test(115): add failing tests for secret-scan exclusion lint + strict mode

Adds tests/secret-scan-lint.test.cjs covering all 7 acceptance criteria
for issue #115 (secret-scan exclusion governance):

  1. Lint exits 0 on fully-annotated .secretscanignore fixture
  2. Lint exits 1 on fixture missing required key (reason/owner/expires)
  3. Lint exits 1 on fixture with expires date in the past
  4. Lint exits 1 on wildcard pattern without rule-id
  5. Lint exits 0 on grandfathered entry (default mode), exits 1 under --strict
  6. secret-scan --strict does not honour grandfathered exclusions
     (temp workspace fixture: file with real AWS-key pattern excluded by a
     grandfathered entry → default exits 0, strict exits 1)
  7. secret-scan default mode behaviour unchanged for existing .secretscanignore
     entries (regression test)

All 24 tests confirmed RED on origin/main before any implementation.
Test helpers use spawnSync throughout so both stdout and stderr are always
captured regardless of exit code (fixes the execFileSync/stderr gap from
the existing security-scan.test.cjs pattern).

Design references cited in test file:
  - GitGuardian exclusion annotation convention:
    https://docs.gitguardian.com/internal-repositories-monitoring/integrations/cli/secrets
  - CNCF Security TAG threat-model exception lifecycle:
    https://github.com/cncf/tag-security/blob/main/community/working-groups/threat-modeling/templates/threats.md

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

* feat(115): add secret-scan-lint.sh + --strict mode + annotation parser

Implements secret-scan exclusion governance for issue #115.

## secret-scan-lint.sh (new script)

Exit codes (match secret-scan.sh convention):
  0 = all exclusions valid (or grandfathered with warning)
  1 = annotation violation: missing key, expired date, wildcard without rule-id,
      or (under --strict) any grandfathered entry
  2 = config error (file not found, bad args)

Annotation format (sidecar comment, immediately preceding the path):
  # allow: <pattern>  reason="..."  owner="..."  expires="YYYY-MM-DD"  [rule-id="..."]
  <pattern>

Required keys: reason, owner, expires
Optional key:  rule-id — required when pattern contains * wildcards

Grandfathered entries (plain comment, no structured keys):
  - Default mode: exit 0 + deprecation warning to stderr
  - --strict mode: exit 1

## secret-scan.sh (modified: --strict flag)

--strict flag for release/security-review CI lanes:
  - Grandfathered entries are NOT applied (file is scanned, not skipped)
  - Exclusions whose expires date is past are NOT applied
  - Default mode behaviour is fully preserved

load_ignorelist() now parses annotations:
  - Reads prev_comment to determine annotation status per entry
  - Uses date comparison (YYYY-MM-DD lexicographic) for expires checks
  - Emits DEPRECATION WARNING to stderr for grandfathered entries in default mode
  - Emits WARNING under --strict when skipping a grandfathered entry

Design references:
  - GitGuardian exclusion annotation convention:
    https://docs.gitguardian.com/internal-repositories-monitoring/integrations/cli/secrets
  - CNCF Security TAG threat-model exception lifecycle:
    https://github.com/cncf/tag-security/blob/main/community/working-groups/threat-modeling/templates/threats.md
  - TruffleHog / GitLeaks wildcard-exclusion risk informed the rule-id requirement
    for wildcard entries (unguarded wildcards can accidentally suppress real findings)

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

* chore(115): annotate existing .secretscanignore entries + wire CI lint step

## .secretscanignore migration

Existing entry `get-shit-done/workflows/plan-phase.md` has been migrated
from a bare plain comment to a fully-structured annotation:

  # allow: get-shit-done/workflows/plan-phase.md
  #   reason="contains illustrative DATABASE_URL/REDIS_URL example strings
  #           used as documentation placeholders — not real credentials"
  #   owner="@open-gsd/maintainers"
  #   expires="2027-06-30"

This entry now passes lint (exit 0) in both default and --strict modes.
The expiration date of 2027-06-30 gives the team ~13 months to review
whether the file still needs to be excluded before the entry expires.

## CI workflow change (.github/workflows/security-scan.yml)

Added step "Secret scan exclusion lint" immediately before the existing
"Planning directory check" step:

  - name: Secret scan exclusion lint
    run: |
      chmod +x scripts/secret-scan-lint.sh
      scripts/secret-scan-lint.sh --file .secretscanignore

The step has no ${{ }} context interpolation in its run block (no
injection surface). It runs on every PR targeting main, release/**, hotfix/**.

This implements CI acceptance criterion from issue #115:
"CI lint fails for unmanaged wildcard exclusions"
"CI enforces policy format"

## Header added to .secretscanignore

Added governance documentation block explaining annotation format,
required/optional keys, and references to design sources:
  - GitGuardian exclusion annotation convention:
    https://docs.gitguardian.com/internal-repositories-monitoring/integrations/cli/secrets
  - CNCF Security TAG threat-model exception lifecycle:
    https://github.com/cncf/tag-security/blob/main/community/working-groups/threat-modeling/templates/threats.md

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

* docs(115): document exclusion governance + periodic reduced-scan procedure

Updates SECURITY.md with a new section "Secret-Scan Exclusion Governance"
covering:

  1. Annotation format (required/optional keys, wildcard rule)
  2. Local lint command
  3. Periodic reduced-exclusion scan procedure using --strict mode

The procedure section explicitly states when to run (every release +
scheduled security review), what --strict does differently, and what to do
when --strict finds findings that default mode does not.

No runbooks/security-audit*.md exists in this repo. SECURITY.md is the
correct location as it is what secret-scan.sh references in its header
docstring (via the "See SECURITY.md" note pattern common in this codebase).

References cited:
  - GitGuardian exclusion annotation convention:
    https://docs.gitguardian.com/internal-repositories-monitoring/integrations/cli/secrets
  - CNCF Security TAG threat-model exception lifecycle:
    https://github.com/cncf/tag-security/blob/main/community/working-groups/threat-modeling/templates/threats.md

Closes #115 (together with feat and chore commits on this branch)

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

* fix(#115): exclude scanner's own test fixtures from diff-mode scan

Add */secret-scan-lint.test.cjs to should_skip_file(), consistent with
the existing exclusions for security-scan.test.cjs and
security-prompt-injection.test.cjs. The test fixture at line 465
contains a DATABASE_URL credential-shaped string that exercises the
Env Variable Leak detector — scanning it as live code is a false positive.

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-23 10:58:14 -04:00
2026-05-15 18:16:33 -04:00

⚠️ This is the active fork

📢 Read the announcement: why the fork, what changed, what's next →

The original repo at gsd-build/get-shit-done appears compromised or abandoned. The maintainer (TÂCHES) has not been reachable since 2026-04-01. TÂCHES social accounts appear deleted, and a $GSD token associated with the project has been linked publicly to a rug-pull.

I have no inside information beyond what is publicly visible. I am stating absence-of-information deliberately — absence of news is not the same as evidence.

What I can confirm

  • No contact with the original maintainer since 2026-04-01.
  • TÂCHES social accounts appear deleted or unreachable.
  • The $GSD token has been linked publicly to a rug-pull.
  • The repo at gsd-build/get-shit-done continues to exist but I cannot vouch for any changes pushed there from this point forward.

What changed

Before After
GitHub gsd-build/get-shit-done open-gsd/get-shit-done-redux
npm (main) get-shit-done-cc → get-shit-done-redux @opengsd/get-shit-done-redux
npm (sdk) @gsd-build/sdk → @gsd-redux/sdk @opengsd/gsd-sdk
Issue numbers per source renumbered; original is in body as [from gsd-build/get-shit-done#N]

If you can reach the original maintainer, please open an issue here and CC them. If you have technical evidence that materially changes the picture above, please share it in an issue.

— trek-e, fork maintainer


GET SHIT DONE

English · Português · 简体中文 · 日本語 · 한국어

A light-weight meta-prompting, context engineering, and spec-driven development system for Claude Code, OpenCode, Gemini CLI, Kilo, Codex, Copilot, Cursor, Windsurf, and more.

Solves context rot — the quality degradation that happens as your AI fills its context window.

npm version npm downloads Tests Discord GitHub stars License


npx @opengsd/get-shit-done-redux@latest

Works on Mac, Windows, and Linux.


GSD Install


"If you know clearly what you want, this WILL build it for you. No bs."

"I've done SpecKit, OpenSpec and Taskmaster — this has produced the best results for me."

"By far the most powerful addition to my Claude Code. Nothing over-engineered. Literally just gets shit done."


Trusted by engineers at Amazon, Google, Shopify, and Webflow.


Important

Returning to GSD?

Run /gsd-map-codebase to re-index your codebase, then /gsd-new-project to rebuild GSD's planning context. Your code is fine — GSD just needs its context rebuilt. See the CHANGELOG for what's new.


Why I Built This

I'm a solo developer. I don't write code — Claude Code does.

Other spec-driven tools exist, but they're all built for 50-person engineering orgs — sprint ceremonies, story points, stakeholder syncs, Jira workflows. I'm not that. I'm a creative person trying to build great things consistently.

So I built GSD. The complexity is in the system, not in your workflow. Behind the scenes: context engineering, XML prompt formatting, subagent orchestration, state management. What you see: a few commands that just work.

The system gives Claude everything it needs to do the work and verify it. I trust the workflow. It just does a good job.

— TÂCHES


How It Works

The loop is six commands. Each one does exactly one thing.

1. Initialize

/gsd-new-project

Questions → research → requirements → roadmap. You approve it, then you're ready to build.

Already have code? Run /gsd-map-codebase first. It analyzes your stack, architecture, and conventions so /gsd-new-project asks the right questions.

2. Discuss

/gsd-discuss-phase 1

Your roadmap has a sentence per phase. That's not enough to build it the way you imagine it. Discuss captures your decisions before anything gets planned: layouts, API shapes, error handling, data structures — whatever gray areas exist for this specific phase.

The output feeds directly into research and planning. Skip it, get reasonable defaults. Use it, get your vision.

3. Plan

/gsd-plan-phase 1

Research → plan → verify, in a loop until the plans pass. Each plan is small enough to execute in a fresh context window.

4. Execute

/gsd-execute-phase 1

Plans run in parallel waves. Each executor gets a fresh 200k-token context. Each task gets its own atomic commit. Walk away, come back to completed work with a clean git history.

Your main context window stays at 30–40%. The work happens in the subagents.

5. Verify

/gsd-verify-work 1

Walk through what was built. Anything broken gets a diagnosed fix plan — ready for immediate re-execution. You don't debug manually; you just run execute again.

6. Repeat → Ship

/gsd-ship 1
/gsd-complete-milestone
/gsd-new-milestone

Loop discuss → plan → execute → verify → ship until the milestone is done. Then archive, tag, and start the next one fresh.


Getting Started

npx @opengsd/get-shit-done-redux@latest

The installer prompts for your runtime (Claude Code, OpenCode, Gemini CLI, Kilo, Codex, Copilot, Cursor, Windsurf, and more) and whether to install globally or locally.

claude --dangerously-skip-permissions

GSD is built for frictionless automation. Skip-permissions is how it's intended to run.

Install only the skills you need with --profile=core (six core-loop skills), --profile=standard (core + phase management), or the default full install. Profiles compose: --profile=core,audit. --minimal is an alias for --profile=core. See docs/USER-GUIDE.md for the full walkthrough, non-interactive install flags for all 15 runtimes, and permissions configuration. See ADR-0011 for the profile model and runtime surface control.

Current release highlights are in docs/RELEASE-v1.42.1.md: package legitimacy checks, safer installer migrations, runtime surface control, custom ship PR sections, reviewer defaults, fallow structural review, and quota-aware execution recovery.


Commands

The main loop:

Command What it does
/gsd-new-project Questions → research → requirements → roadmap
/gsd-discuss-phase [N] Capture implementation decisions before planning
/gsd-plan-phase [N] Research + plan + verify
/gsd-execute-phase <N> Execute plans in parallel waves
/gsd-verify-work [N] Manual acceptance testing
/gsd-ship [N] Create PR from verified phase work
/gsd-progress --next Auto-detect and run the next step
/gsd-complete-milestone Archive milestone and tag release
/gsd-new-milestone Start next version
/gsd:surface Enable/disable skill clusters at runtime without reinstall

For ad-hoc tasks, autonomous mode, codebase analysis, forensics, and the full command surface — see docs/COMMANDS.md.


Why It Works

Three things most AI-coding setups get wrong:

1. Context bloat. As a session grows, quality degrades. GSD keeps your main context clean by doing the heavy work in fresh subagent contexts. Researchers, planners, and executors each start fresh with exactly what they need.

2. No shared memory. GSD maintains structured artifacts that survive session boundaries: PROJECT.md (vision), REQUIREMENTS.md (scope), ROADMAP.md (where you're going), STATE.md (current position and decisions), CONTEXT.md (per-phase implementation decisions). Every new session loads these and knows exactly where things stand.

3. No verification. Code that "runs" isn't code that "works." GSD's verify step walks you through what was built, diagnoses failures with dedicated debug agents, and generates fix plans before you declare a phase done.

See docs/ARCHITECTURE.md for how the multi-agent orchestration and context engineering work in detail.


Configuration

Settings live in .planning/config.json. Configure during /gsd-new-project or update with /gsd-settings.

Key dials:

Setting What it controls
mode interactive (confirm each step) or yolo (auto-approve)
Model profiles quality / balanced / budget — controls which model each agent uses
workflow.research / plan_check / verifier Toggle the quality agents that add tokens and time
parallelization.enabled Run independent plans simultaneously

Optional structural review: set code_quality.fallow.enabled to true to add a fallow pre-pass to /gsd-code-review. GSD writes .planning/phases/<phase>/FALLOW.json and surfaces a Structural Findings (fallow) section in REVIEW.md. Install with npm install -D fallow@^2.70.0 (or system-wide via cargo install fallow; note that the Rust binary's JSON schema must match the documented v2.70+ contract — older versions may produce silent zero-finding output).

Package legitimacy checks are built into the research, planning, and execution path: recommended dependencies get audited, unverified packages require a human checkpoint, and failed installs stop instead of trying similarly named alternatives.

For the full configuration reference — all settings, git branching strategies, per-runtime model overrides, workstream config inheritance, agent skills injection — see docs/CONFIGURATION.md.


Documentation

Doc What's in it
User Guide End-to-end walkthrough, install options, all runtime flags, configuration reference
Commands Every command with flags and examples
Configuration Full config schema, model profiles, git branching
Architecture How the multi-agent orchestration works
CLI Tools gsd-sdk query and programmatic SDK dispatch seams
Features Complete feature index
Changelog What changed in each release

Troubleshooting

Commands not showing up? Restart your runtime after install. GSD installs to ~/.claude/skills/gsd-*/ (Claude Code), ~/.codex/skills/gsd-*/ (Codex), or the equivalent for your runtime.

Codex users — minimum supported CLI version is 0.130.0. Codex CLI 0.130.0 (release notes) removed extra-skill-roots discovery via openai/codex#21485; from that version onward Codex discovers skills from standard roots (including ~/.codex/skills/<name>/SKILL.md). GSD installs there directly. Earlier Codex CLI versions may still discover additional roots, which can surface duplicate gsd-* entries (one from extra-roots discovery, one from ~/.codex/skills/); restart Codex after install and either upgrade or accept the duplicate listing.

Something broken? Re-run the installer — it's idempotent:

npx @opengsd/get-shit-done-redux@latest

Containers or Docker? Set CLAUDE_CONFIG_DIR before installing to avoid tilde-expansion issues:

CLAUDE_CONFIG_DIR=/home/youruser/.claude npx @opengsd/get-shit-done-redux --global

Full troubleshooting and uninstall instructions in docs/USER-GUIDE.md.


Community

Project Platform
gsd-opencode Original OpenCode port
Discord Community support

Star History

Star History Chart

License

MIT License. See LICENSE for details.


Claude Code is powerful. GSD makes it reliable.

Description
No description provided
Readme MIT 77 MiB
Languages
JavaScript 82.3%
TypeScript 17.4%
Shell 0.3%