Initial server source import

This commit is contained in:
sashatrask
2026-09-30 20:30:56 +03:00
commit 170dd941b9
498 changed files with 261563 additions and 0 deletions
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-08-20
@@ -0,0 +1,55 @@
## Context
GitLab project discovery calls `api_request` without an explicit retry budget. Direct requests therefore receive one attempt, and `ApiRequestError` escapes `run_configured_source`, which terminates the supervised child. The supervisor restarts the child and the persisted query position prevents confirmed target loss, but every transient 30-second read timeout creates avoidable churn and delay.
## Goals / Non-Goals
**Goals:**
- Retry idempotent GitLab project discovery requests with a small bounded budget.
- Keep the GitLab child alive when the bounded network budget is exhausted.
- Persist a failed source cycle without advancing the query or damaging auth state.
- Preserve existing rate-limit and authentication handling.
**Non-Goals:**
- Change TruffleHog scan commands or target retry policy.
- Retry non-idempotent requests.
- Hide persistent GitLab outages or loop without delay.
- Change other source APIs in this change.
## Decisions
### Configure attempts at the GitLab source boundary
GitLab source configuration will provide `discovery_request_attempts: 3` and `discovery_retry_delay: 5`. These values flow only into project discovery calls and use the existing `api_request` retry implementation.
Alternative considered: change the direct-request default globally. Rejected because it would silently alter every source and API call without source-specific evidence.
### Convert exhausted discovery transport errors into failed cycles
GitLab project discovery will wrap exhausted request transport failures in a dedicated `GitLabDiscoveryTransportError`. `run_configured_source` will catch only that error for GitLab, roll back any open database transaction, finish the source cycle as failed, retain the current query, and return to the normal configured-source cooldown. It will not mark the token invalid or terminate the process. Payload and programming errors retain fail-fast behavior.
Alternative considered: rely on supervisor restart. Rejected because process restart is expensive error handling for an ordinary transient network condition.
### Preserve rate-limit and auth paths
HTTP 429, 401, and 403 responses continue through the existing GitLab API and auth-pool policy. Only transport failures and the existing retryable HTTP status set use the discovery retry budget.
## Risks / Trade-offs
- [A persistent outage lengthens a failed cycle] -> Bound attempts to three and delay to five seconds.
- [A failed page could cause partial discovery ambiguity] -> Discard the cycle's fetched list on failure and retain the current query for the next cycle.
- [A catch could hide programming errors] -> Catch only `ApiRequestError` for the GitLab source; all other exceptions retain fail-fast behavior.
- [Auth state could be corrupted] -> Do not invoke token cooldown or invalidation for transport-only failures.
## Migration Plan
1. Add retry and failed-cycle tests using injected timeout responses.
2. Deploy the GitLab-only configuration and error handling.
3. Restart the managed runtime and observe at least one full query rotation or an injected exhaustion test.
4. Roll back by removing the GitLab source settings and narrow exception handler.
## Open Questions
- Whether the same direct-request policy should later be adopted by other sources requires separate evidence.
@@ -0,0 +1,27 @@
## Why
One transient GitLab project-search timeout currently terminates the entire supervised source process. Four single-attempt read timeouts caused four avoidable GitLab restarts in the latest runtime window even though the token remained healthy and the same query succeeded after restart.
## What Changes
- Retry transient GitLab discovery requests with a small bounded attempt count and delay.
- Treat exhausted discovery transport failures as a failed source cycle with backoff instead of terminating the supervised child.
- Preserve the current query and authentication state so a failed cycle can resume without a coverage gap.
- Add focused retry, exhaustion, state, and non-GitLab isolation coverage.
- Keep TruffleHog process lifecycle changes outside this change.
## Capabilities
### New Capabilities
- `gitlab-discovery-resilience`: Defines bounded transport retry and nonfatal cycle behavior for GitLab project discovery.
### Modified Capabilities
None.
## Impact
- Affects GitLab discovery requests and config-cycle error handling in `app/scanner.py` and `app/console_runner.py`.
- Adds source configuration for the retry budget and delay.
- Does not change GitLab token validity, rate-limit rotation, target scan policy, or other source APIs.
@@ -0,0 +1,34 @@
## ADDED Requirements
### Requirement: Bounded GitLab discovery transport retries
The system SHALL retry idempotent GitLab project discovery requests after transient transport failures using a source-configured bounded attempt count and delay.
#### Scenario: Transient timeout succeeds on retry
- **WHEN** a GitLab project discovery request times out and a later attempt within the configured budget succeeds
- **THEN** discovery continues using the successful response without restarting the source
#### Scenario: Retry budget is bounded
- **WHEN** every GitLab project discovery attempt fails transiently
- **THEN** the request stops after the configured attempt count and does not retry indefinitely
### Requirement: Exhausted discovery is a nonfatal source cycle
The system SHALL record an exhausted GitLab discovery transport failure as a failed cycle without terminating the supervised source child.
#### Scenario: Discovery attempts are exhausted
- **WHEN** GitLab project discovery exhausts its transport attempt budget
- **THEN** the cycle is finished as failed and the configured source loop remains alive
#### Scenario: Query position is retained
- **WHEN** a GitLab discovery cycle fails from an exhausted transport error
- **THEN** the current query is not advanced and is eligible for the next cycle
### Requirement: Discovery failure isolation
The system SHALL keep transport-only GitLab discovery failures separate from authentication, rate-limit, scanner, and non-GitLab source policy.
#### Scenario: Token remains healthy after transport failure
- **WHEN** GitLab discovery fails only because of a network transport error
- **THEN** the active token is not marked invalid or rate limited
#### Scenario: Other source behavior is unchanged
- **WHEN** a non-GitLab source encounters an API request failure
- **THEN** this GitLab-only cycle handling does not alter its existing behavior
@@ -0,0 +1,17 @@
## 1. GitLab Discovery Policy
- [x] 1.1 Add source-configured GitLab discovery request attempts and retry delay.
- [x] 1.2 Pass the bounded settings only to GitLab project discovery requests.
- [x] 1.3 Convert exhausted GitLab discovery transport errors into failed cycles without advancing query or auth state.
## 2. Regression Coverage
- [x] 2.1 Test timeout-then-success and bounded exhaustion behavior.
- [x] 2.2 Test failed-cycle persistence, query retention, token health, and non-GitLab isolation.
- [x] 2.3 Run focused and broader regression suites with bytecode writes disabled.
## 3. Validation And Rollout
- [x] 3.1 Run strict OpenSpec validation and verify implementation against artifacts.
- [x] 3.2 Restart the managed runtime and confirm GitLab source, PostgreSQL, and pipeline health.
- [x] 3.3 Observe a GitLab discovery canary and confirm transient API errors no longer restart the source.