An interactive planning tool that scans Linear issues, detects gaps in DoD and dependencies, and applies approved wave-by-wave architecture updates back to Linear.
Sightjack uses Claude Code to analyze Linear issues across clusters, detect missing DoD (Definition of Done), hidden dependencies, and technical debt resurrection — then guides you through wave-by-wave approval to incrementally improve issue completeness.
sightjack runThis single command makes Sightjack repeat the following cycle:
- Scan all Linear issues and classify them into thematic clusters
- Deep-scan each cluster for completeness gaps and hidden dependencies
- Generate execution waves with prerequisites and completeness deltas
- Present the Link Navigator — you choose which wave to tackle
- Review, discuss with the Architect agent, approve or modify
- Apply changes to Linear, unlock dependent waves, repeat
- Stop when all issues reach target completeness
The system design is inspired by the core mechanic of Forbidden Siren (SIREN), a PS2 survival horror game by Japan Studio (2003).
In the game, the player has a unique ability called "Sightjack" — tuning into enemies' visual perspectives like a radio dial, seeing through their eyes to discover threats hidden by fog and darkness. The game's Link Navigator lets you freely choose scenarios across characters and timelines, with completion of one scenario unlocking others.
This structure maps directly to issue architecture:
| Game Concept | Sightjack | Design Meaning |
|---|---|---|
| Sightjack | AI cross-issue analysis | See through each issue's perspective to find blind spots |
| Link Navigator | Matrix Navigator UI | Cluster x Wave matrix — choose your next scenario |
| Scenario | Wave | AI-generated batch of actions per cluster |
| Character | Issue Cluster | Thematic group (Auth, API, DB, Frontend...) |
| Scenario Unlock | Wave prerequisites | Completing Wave A unlocks Wave B |
| End Condition 1 | Functional DoD | Basic acceptance criteria fulfilled |
| End Condition 2 | Non-functional DoD | Hidden requirements the AI discovers |
| Archive | ADR (Architecture Decision Record) | Design decisions auto-generated during discussion |
| Shibito Revival | Technical debt detection | Closed issues whose patterns resurface in current work |
| Fog of War | Undiscovered requirements | New waves emerge as earlier ones complete |
- Sightjack, don't guess — AI scans every issue's perspective. Hidden dependencies and missing DoD are discovered, not assumed.
- Wave by wave, not issue by issue — Decisions are made in meaningful batches (waves), not per-issue micro-dialogs. Like choosing a scenario in SIREN, not individual steps.
- Ripples reveal the whole — Each wave completion shows ripple effects across clusters. The "aha, that's connected!" moment is the core experience.
Three SIREN-inspired mechanics control session quality:
Past closed issues are scanned for patterns that resurface in current work. Like Shibito in SIREN that revive after being defeated.
[Sightjack] Shibito Revival Detected:
ENG-045 (closed) -> ENG-201 (current)
"Token circular dependency" — occurred in old auth, risk of recurrence
- Warnings shown once at session start
- Count tracked in state for session awareness
Controls how aggressively the AI enforces DoD completeness. Like SIREN's difficulty affecting enemy awareness.
fog -> DoD gaps shown as warnings only (prototype/spike)
alert -> Missing must-have DoD triggers sub-issue proposals
lockdown -> All DoD required, dependencies enforced as blocked
Strictness uses a 3-layer resolution where strictness can only go up:
- Default -- project-wide baseline from
strictness.defaultconfig - Estimated -- auto-generated per-cluster by the LLM during deep scan, persisted to
strictness.estimatedin config - Manual (Overrides) -- explicit per-label/cluster overrides from
strictness.overridesconfig (always wins if stronger)
Resolution: max(default, estimated, overrides) per cluster/label key.
- Affects wave generation: strict mode adds final consistency waves
After each wave completion, the AI generates follow-up waves based on what was learned. Like SIREN's scenarios that only appear after certain conditions are met.
[Wave Complete] Auth W1: Dependency Ordering
-> New wave generated: Auth W2: "JWT vs Session ADR" (emerged from W1 analysis)
-> API W2 prerequisites updated (now depends on Auth W2)
Sightjack communicates with downstream tools (amadeus, paintress) via D-Mail, a file-based message protocol. D-Mail kinds:
| Kind | Direction | Description |
|---|---|---|
specification |
outbound | Wave specification sent to downstream tools |
report |
outbound | Wave completion report |
design-feedback |
inbound | Design feedback from downstream tools (injected into nextgen prompts) |
convergence |
inbound | Convergence signal — requires user approval before session proceeds |
When a convergence D-Mail is detected at session startup, the convergence gate activates:
- Notify — desktop notification (fire-and-forget, non-blocking with 30s timeout)
- Approve — blocking prompt (stdin y/N, external command, or auto-approve)
- Re-drain — checks for late-arriving convergence and loops if found
The gate runs before the interactive wave loop in the run command (which supports resuming or rescanning from previous sessions). Gate behavior is configurable via gate: config section or --notify-cmd / --approve-cmd / --auto-approve CLI flags.
After the convergence gate, a D-Mail waiting phase polls the inbox for design-feedback D-Mails. The waiting timeout is configurable via --wait-timeout (default: 30 minutes, 0 = 24h safety cap, negative = disable).
SKILL.md files in .siren/skills/ declare produces/consumes routing for phonewave discovery using Agent Skills spec format with dmail-schema-version: "1".
scan --json ──→ waves ──→ select ──→ discuss ──→ apply ──→ nextgen
| | | | | |
v v v v v v
ScanResult WavePlan Wave DiscussResult ApplyResult WavePlan
|
└──→ adr ──→ ADR Markdown
All data flows as JSON through Unix pipes. Each subcommand is a standalone filter:
- stdin: JSON from previous command (or file)
- stdout: JSON for next command (or file)
- stderr: all log output
- /dev/tty: interactive prompts (select, discuss)
Sightjack (binary)
|
| Pass 1: Classify
| +-- Claude Code: cluster issues by theme
|
| Pass 2: DeepScan
| +-- goroutines: parallel per-cluster analysis
| +-- semaphore: bounded concurrency
|
| Pass 3: WaveGenerate
| +-- Claude Code: generate waves per cluster
| +-- EvaluateUnlocks: prerequisite chain resolution
|
v
Matrix Navigator (interactive)
|
| Per Wave:
| +-- PromptWaveSelection -> PromptWaveApproval
| +-- Architect Agent: design discussion (optional)
| +-- Scribe Agent: ADR generation (optional)
| +-- Selective approval: pick individual actions
|
v
Pass 4: WaveApply
| +-- Claude Code: apply changes to Linear via MCP
| +-- Ripple effects displayed
| +-- Nextgen: dynamic follow-up wave generation
| +-- State saved (crash resilience)
|
v
Linear (via MCP Server)
+-- Issues updated (DoD, dependencies, sub-issues)
+-- ADRs stored as documents
+-- Ready labels applied
| Agent | Role | Game Concept |
|---|---|---|
| Scanner | Classify + DeepScan + WaveGenerate | Sightjack (seeing through issues) |
| Architect | Design discussion during wave approval | Character dialogue |
| Scribe | ADR generation from design decisions (auto-discuss in auto-approve mode) | Archive collection |
| (Handoff) | Ready-issue labeling for downstream tools | Next expedition |
What Sightjack does:
- Scan Linear issues and detect missing DoD, hidden dependencies, and technical debt revival
- Generate wave-by-wave execution plans with prerequisite chains
- Guide interactive approval and apply approved changes to Linear via MCP
- Generate ADRs from design discussions (Scribe agent)
- Send specification/report D-Mails to downstream tools
What Sightjack does NOT do:
- Implement code changes (paintress handles implementation)
- Verify post-merge integrity (amadeus handles verification)
- Deliver D-Mails (phonewave handles routing)
- Modify source code or git repositories directly
# Build and install
just install
# Initialize project config (Linear team key, etc.)
sightjack init
# Re-initialize (upgrade SKILL.md, regenerate config)
sightjack init --force
# Check environment (config, tools, skills, event store, context-budget with per-item diagnostics, Docker)
sightjack doctor
# Run — .siren/ is created automatically
sightjack runSightjack creates .siren/ and all state/run files automatically at runtime. The insights/ subdirectory is git-tracked and accumulates semantic knowledge (Shibito warnings, strictness estimates) across sessions.
Running sightjack without a subcommand defaults to scan (classify and deep-scan Linear issues). Unlike the other three tools (phonewave, amadeus, paintress) which default to run, sightjack's primary operation is scanning — the interactive run loop builds on top of scan results.
| Command | Description |
|---|---|
sightjack scan |
Classify and deep-scan Linear issues (default when no subcommand given) |
sightjack run |
Interactive wave approval and apply loop (auto-resumes from state) |
sightjack show |
Display last scan results (or pipe JSON from stdin) |
sightjack init |
Initialize .siren/config.yaml interactively (--force to overwrite) |
sightjack doctor |
Check environment, tools, skills, event store integrity, context-budget (per-item diagnostics), Docker |
sightjack config show |
Display current configuration |
sightjack config set |
Set a configuration value (e.g., config set strictness.default alert) |
sightjack version |
Print version, commit, date, and Go version (-j for JSON) |
sightjack update |
Self-update to the latest GitHub release (-C to check only) |
sightjack status |
Show sightjack operational status |
sightjack clean |
Remove state directory (.siren/) |
sightjack archive-prune |
Remove expired scan archives (-x to execute, default: dry-run) |
Each subcommand reads JSON from stdin and writes JSON to stdout. Logs go to stderr. Interactive prompts use /dev/tty (falls back to CONIN$ on Windows).
| Command | stdin | stdout | Description |
|---|---|---|---|
sightjack scan --json |
— | ScanResult |
Scan and output structured JSON |
sightjack waves |
ScanResult |
WavePlan |
Generate execution waves |
sightjack select |
WavePlan |
Wave |
Interactive wave selection (tty) |
sightjack discuss |
Wave |
DiscussResult |
Architect discussion (tty) |
sightjack apply |
Wave |
ApplyResult |
Apply wave actions to Linear |
sightjack adr |
DiscussResult |
ADR Markdown | Generate ADR document |
sightjack nextgen |
ApplyResult |
WavePlan |
Generate follow-up waves |
sightjack show |
ScanResult or WavePlan |
human-readable | Render piped JSON for display |
All commands accept an optional [path] argument. When omitted, the current working directory is used. Flags and subcommand can be placed in any order. All flags support GNU/POSIX long (--flag) and short (-f) forms:
sightjack scan --dry-run # flags after subcommand
sightjack --dry-run scan # flags before subcommand
sightjack -n scan # short alias
sightjack --lang=ja run # --flag=value form# Scan only (classify + deep-scan, no interactive loop)
sightjack scan
# Full interactive loop (scan + wave approval + apply)
sightjack run
# Display last scan results
sightjack show
# Dry run (generate prompts without executing Claude)
sightjack scan -n
sightjack run --dry-run
# Japanese prompts
sightjack run -l ja
# Custom config path
sightjack run -c .siren/config.yaml
# Auto-approve convergence gate (CI mode)
sightjack run --auto-approve
# D-Mail waiting mode with custom timeout (default: 30m)
sightjack run --wait-timeout 10m
# Disable D-Mail waiting phase
sightjack run --wait-timeout=-1s
# Skip session prompt (rescan without interaction)
sightjack run --session-mode rescan --auto-approve
# Custom notification command
sightjack run --notify-cmd 'echo {title}: {message}'
# Custom approval command (exit 0 = approve)
sightjack run --approve-cmd 'my-approval-tool {message}'
# Verbose logging
sightjack run -v
# Scan a different repository
sightjack scan /path/to/repo
# Version info
sightjack version
sightjack version -j # JSON output
# Check for updates
sightjack update -C # check only
sightjack update # check and install
# Archive pruning
sightjack archive-prune -d 14 # 14-day retention (dry-run)
sightjack archive-prune -x # execute deletion# Full pipeline: scan → select wave → discuss → apply
sightjack scan --json | sightjack waves | sightjack select | sightjack apply
# Generate ADR from discussion
sightjack scan --json | sightjack waves | sightjack select | sightjack discuss | sightjack adr > docs/adr/0005-foo.md
# Preview scan results
sightjack scan --json | sightjack show
# Save intermediate results
sightjack scan --json | tee scan.json | sightjack waves | tee plan.json | sightjack select > wave.json
# Generate follow-up waves after apply
cat wave.json | sightjack apply | sightjack nextgen| Flag | Short | Default | Description |
|---|---|---|---|
--config |
-c |
.siren/config.yaml |
Config file path |
--lang |
-l |
config (ja) |
Language override (en / ja) |
--verbose |
-v |
false |
Verbose logging |
--output |
-o |
text |
Output format: text or json |
--dry-run |
-n |
false |
Generate prompts without executing Claude |
--no-color |
false |
Disable colored output (also respects NO_COLOR env) |
For full flag reference per subcommand, see docs/cli/.
# .siren/config.yaml
tracker:
team: "ENG" # Linear team key
project: "My Project" # Linear project name
cycle: "" # Optional: filter by cycle
scan:
chunk_size: 20 # Issues per scan chunk
max_concurrency: 3 # Parallel scan workers
claude_cmd: "claude" # Claude CLI command
model: "opus" # Model override (default: "opus")
timeout_sec: 1980 # Per-invocation timeout (33 min)
scribe:
enabled: true # ADR generation via Scribe agent
auto_discuss_rounds: 2 # Devil's Advocate rounds in auto-approve mode (0 = skip)
strictness:
default: "fog" # Default strictness (fog/alert/lockdown)
overrides: # Manual per-label/cluster strictness (always wins if stronger)
security: "lockdown"
spike: "fog"
computed:
estimated_strictness: # Auto-generated by LLM during scan (persisted after scan)
auth: "alert"
retry:
max_attempts: 3 # Retry on Claude failures
base_delay_sec: 2 # Base backoff between retries
labels:
enabled: true # Auto-label ready issues in Linear
prefix: "sightjack" # Label prefix (default: "sightjack")
ready_label: "sightjack:ready" # Ready-for-execution label name
gate:
notify_cmd: "" # Custom notification command ({title}, {message} placeholders)
approve_cmd: "" # Custom approval command ({message} placeholder, exit 0 = approve)
auto_approve: false # Skip approval gate for convergence D-Mail
wait_timeout: 30m # D-Mail waiting phase timeout (0 = 24h safety cap, <0 = disable)
dod_templates: # Custom DoD templates by issue type
api_endpoint:
must:
- "Error responses (4xx/5xx) defined"
- "Auth/authz requirements specified"
should:
- "Rate limiting documented"
lang: "ja" # Language (en/ja)Sightjack instruments key operations (scan, wave generation, architect discussion, etc.) with OpenTelemetry spans and events. Tracing is off by default (noop tracer) and activates when OTEL_EXPORTER_OTLP_ENDPOINT is set.
# Start Jaeger (all-in-one trace viewer)
just jaeger
# Run with tracing enabled
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 sightjack run
# View traces at http://localhost:16686
# Stop Jaeger
just jaeger-downAll code lives in internal/ (Go convention). See docs/conformance.md for layer architecture and directory responsibilities. Run just --list for available tasks.
See docs/conformance.md for the full conformance table (single source).
- docs/ — Full documentation index
- docs/conformance.md — What/Why/How conformance table
- docs/siren-directory.md —
.siren/directory structure - docs/policies.md — Event → Policy mapping
- docs/otel-backends.md — OTel backend configuration
- docs/testing.md — Test strategy and conventions
- docs/adr/ — Architecture Decision Records
- docs/shared-adr/ — Cross-tool shared ADRs
- Go 1.26+
- just task runner
- Claude Code CLI
- Linear MCP Server configured for Claude
- Docker for tracing (Jaeger)
See LICENSE for details.