feat: tracker hardening, graph integrity, and ready --explain#2814
Open
harry-miller-trimble wants to merge 18 commits intosteveyegge:mainfrom
Open
feat: tracker hardening, graph integrity, and ready --explain#2814harry-miller-trimble wants to merge 18 commits intosteveyegge:mainfrom
harry-miller-trimble wants to merge 18 commits intosteveyegge:mainfrom
Conversation
- Add retry with exponential backoff to Jira doRequest (was single-attempt) - Add MaxRetries, RetryDelay, MaxResponseSize constants to jira/types.go - Add response body size limit via io.LimitReader to Jira client - Handle permanent errors (400/401/403/404) without retry - Parse Retry-After header for rate-limited responses - Add jitter (0-50% of delay) to backoff in all 5 tracker clients: GitHub, GitLab, Linear, ADO, and Jira - Guard rand.Int64N against zero delay to prevent panics - Add retry tests: 429, 503, no-retry-on-400, max-retries-exceeded Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Linear FetchIssues/FetchIssuesSince: add MaxPages=1000 guard to prevent infinite loops from malformed API responses with hasNextPage=true - Linear: add ctx.Done() checks at start of each pagination iteration - Jira SearchIssues: add ctx.Done() check at start of each pagination iteration - Add MaxPages constant to internal/linear/types.go Fixes: bd-6fy Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…se size limits - Add ui.SanitizeForTerminal() to strip ANSI escape sequences, OSC sequences, and C0/C1 control characters from external content before terminal display. Preserves printable UTF-8, newlines, and tabs. - Apply sanitization in tracker engine dry-run output (3 call sites) - Add MaxResponseSize (50MB) and io.LimitReader to Linear client to prevent OOM from malformed API responses (was the only tracker without this guard) - Add comprehensive test suite for sanitization (17 test cases including ANSI injection, screen clearing, OSC title change, control characters) Fixes: bd-u9u Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Formally documents what beads tracker integrations will and will not build. Establishes that integrations are an adoption bridge, not a product. Explicit out-of-scope: webhooks, cross-tracker orchestration, attachment sync, comment mirroring, credential vaults, UI parity features. Includes design guidelines for new integrations and a decision log. Fixes: bd-9go Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Collect warnings in Engine.warnings during Sync() and populate result.Warnings (field existed but was never used) - Fix createDependencies: return error count, stop silently discarding GetIssueByExternalRef errors (previously used _ discard) - Fix external_ref update failure: now increments stats.Errors when the local link-back fails after creating an external issue - Add Errors field to PullStats and propagate to SyncResult - Dependency creation failures now counted as Skipped in pull stats Fixes: bd-5cx Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bd ready --explain provides a comprehensive view of the dependency graph: - Ready items with reasoning (resolved blockers, dependency counts) - Blocked items with detailed blocker info (ID, title, status, priority) - Cycle detection results - Aggregate summary stats Works in both JSON (--json) and human-readable text modes. JSON output gives agents structured data for graph-aware work prioritization. No storage layer changes — all data comes from existing GetReadyWork, GetBlockedIssues, GetDependencyRecordsForIssues, and DetectCycles APIs. New types: ReadyExplanation, ReadyItem, BlockedItem, BlockerInfo, ExplainSummary (all in internal/types/types.go). Fixes: bd-7zt Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add documentation for: - Trust boundary: all external tracker data treated as untrusted - Content sanitization (ANSI stripping, response size limits) - Credential handling: recommend platform-native auth over plaintext tokens - Sync security model: user-initiated only, no daemons or webhooks - AI agent content safety: prompt injection awareness - Dependency pinning via go.sum Fixes: bd-68o Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Extend write-path CTE and DFS cycle detection to include conditional-blocks (also creates blocking relationships, same as blocks) - Add explicit self-dependency check in AddDependencyInTx - Add bd graph check subcommand: runs DetectCycles, reports results in JSON or human-readable format, exits with code 1 if issues found waits-for is intentionally excluded from cycle detection — it uses gate semantics (fan-in) rather than direct blocking, so A waits-for B does not mean B blocks A in the traditional sense. Fixes: bd-2qr Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add 'Why Beads?' section contrasting flat trackers vs dependency-aware ready queue - Add bd ready --explain example showing full graph reasoning output - Document bd ready vs bd list --status open distinction - Add graph check and explain commands to Next Steps section Fixes: bd-47m Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
TestTracker_InitMissingPAT, InitMissingOrg, and InitMissingProject were not isolating from environment variables. When AZURE_DEVOPS_PAT is set in the environment (common in CI and dev), getConfig falls through to os.Getenv and the PAT check passes, causing the test to hit the org validation instead and fail. Fix: Use t.Setenv to clear all ADO env vars in tests that assert specific missing-config errors. t.Setenv automatically restores the original values after the test. Fixes: bd-czk Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
All three compact paths (single, all, analyze) now show consistent
structured output:
- Per-candidate details: ID, title, closed date, age in days, content size
- Summary footer: total candidates and aggregate content bytes
- JSON output uses {candidates: [...], summary: {...}} structure
Text output uses a tabular format for easy scanning. No changes to
actual compaction behavior.
Fixes: bd-oxs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…f-deps - Enhance mockTracker with createFailAfter/createCount for partial failure simulation (previously only supported all-or-nothing errors) - TestEnginePushPartialFailure: 3 issues, fail after 2 creates, asserts Created=2, Errors=1, warnings collected - TestEngineSyncCollectsWarnings: verifies result.Warnings is populated from push failures (tests the bd-5cx warning collection fix) - TestAddDependency_SelfDependencyRejected: verifies self-dependency check returns error (tests the bd-2qr self-dep guard) Fixes: bd-3jd Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add config.BeadsDirPerm (0700) and config.BeadsFilePerm (0600) constants - Add config.CheckBeadsDirPermissions() for startup warning if permissions are too permissive (non-fatal, checks group/world bits) - Add config.EnsureBeadsDir() helper for consistent directory creation - Tighten all MkdirAll calls for .beads/ paths from 0750/0755 to 0700: init.go, doltserver.go, credentials.go, audit.go, recipes.go, embeddeddolt store.go and flock.go - Add startup check in loadEnvironment() (cmd/bd/main.go) - Windows build tag with no-op implementation (ACL-based permissions) - 6 tests: constants, dir creation perms, warning on permissive, no warning on secure, no error on nonexistent Fixes: bd-kl6 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add MaxPages=1000 pagination guard to SearchIssues() to match the pattern already implemented in Linear, GitHub, and GitLab clients. Without this, a malicious or buggy Jira instance returning inflated Total values could cause an infinite pagination loop. Also fix jitter application: only add jitter to our own exponential backoff delays, not to server-mandated Retry-After values. Adding jitter to Retry-After could violate rate limit contracts. Additionally guard against zero-length pages which could also cause infinite loops even within the MaxPages limit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Apply the same fix as the Jira client: only add jitter to our own exponential backoff delays, not to server-mandated Retry-After values. Adding jitter to Retry-After could violate rate limit contracts by waiting less than the server-specified duration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rnings Extract BuildReadyExplanation into types package as a pure function, enabling unit tests without Dolt dependency. Add 8 test cases covering: empty input, ready with/without deps, resolved blockers, parent links, blocked issues with missing blockers, cycles, and full scenario. Add 7 Dolt integration tests for cycle detection: - conditional-blocks cycles (prevented by AddDependency) - mixed blocks + conditional-blocks cycles - waits-for intentionally excluded from cycle detection - self-dependency rejected for all dependency types - ready work respects conditional-blocks - blocked issues include blocker details Add 4 engine tests: - createDependencies with valid deps - createDependencies with unresolvable external refs (warns) - createDependencies with empty input - warn() collects messages and triggers OnWarning callback Types package coverage: 89.6% → 91.0% Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…koff) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Runtime hardening for all tracker integrations, dependency graph integrity checks, and a new
bd ready --explaincommand for AI-supervised workflows. Addresses 11 issues filed from a comprehensive codebase audit.Changes
Runtime Hardening (tracker clients)
Retry-Afterheader support,MaxPages=1000pagination guard,MaxResponseSize=50MBresponse limitRetry-Afterdelays (respects rate limit contracts)MaxPages=1000pagination guard,io.LimitReaderresponse size limit,ctx.Done()checks in pagination loopsSanitizeForTerminalstrips ANSI escapes and control characters from external tracker content at display time (raw data preserved in Dolt)Graph Integrity
blocksto includeconditional-blocksdependency typebd graph check: New subcommand for forensic cycle detectionNew Feature:
bd ready --explain--jsonfor programmatic consumption by AI agentstypes.BuildReadyExplanationfor testabilitySync Engine
SyncResult.Warningsnow populated (was always empty despite field existing)createDependenciesreturns error count; failures surfaced via warningsPullStats.Errorstracks external_ref update failuresSecurity & Permissions
.beads/directory enforced at0700(warn-only, non-fatal on existing dirs)SECURITY.mdexpanded with trust model, credential guidance, AI content safetydocs/INTEGRATION_CHARTER.md: formal scope boundary for tracker integrationsDocumentation & Tests
docs/QUICKSTART.md: "Why Beads?" section,--explainexamplest.Setenv)Backward Compatibility
.beads/permissions: Warning only — existing dirs with0755get a log warning, not a failure. Windows is a no-op.SyncResult.Warnings: New field in JSON output. Consumers ignoring unknown fields are unaffected.bd graph check: New command, no impact on existing commands.Test Coverage
SanitizeForTerminalBuildReadyExplanationconfig/permissionsChecklist
go build ./...passesgo test -short ./...passes (all non-Dolt packages)make test-full-cgopasses (full suite with Docker)