chronos-ruby 0.9.0.pre.3 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +34 -0
  3. data/README.md +101 -181
  4. data/contracts/integration-verification-response-v1.schema.json +76 -0
  5. data/docs/adr/ADR-007-feature-detection.md +25 -0
  6. data/docs/adr/ADR-008-context-store.md +25 -0
  7. data/docs/adr/ADR-009-sampling.md +25 -0
  8. data/docs/adr/ADR-010-opentelemetry-interoperability.md +25 -0
  9. data/docs/adr/ADR-018-pre-1.0-hardening.md +6 -2
  10. data/docs/compatibility.md +30 -23
  11. data/docs/data-collected.md +3 -0
  12. data/docs/deprecation-policy.md +1 -1
  13. data/docs/migration-from-airbrake.md +1 -1
  14. data/docs/modules/breadcrumbs.md +23 -0
  15. data/docs/modules/context.md +21 -0
  16. data/docs/modules/deploys.md +23 -0
  17. data/docs/modules/integration-verification.md +65 -0
  18. data/docs/modules/job-monitoring.md +22 -0
  19. data/docs/modules/request-monitoring.md +20 -0
  20. data/docs/modules/runtime-metrics.md +22 -0
  21. data/docs/modules/sampling.md +22 -0
  22. data/docs/modules/sidekiq-legacy.md +1 -1
  23. data/docs/modules/sql-monitoring.md +22 -0
  24. data/docs/performance.md +13 -2
  25. data/docs/protocol-v1.md +3 -1
  26. data/docs/release-1.0-readiness.md +17 -15
  27. data/docs/security-review.md +4 -3
  28. data/docs/troubleshooting.md +6 -0
  29. data/lib/chronos/adapters/net_http_transport.rb +36 -2
  30. data/lib/chronos/agent.rb +21 -0
  31. data/lib/chronos/application/delivery_pipeline.rb +6 -3
  32. data/lib/chronos/application/verify_integration.rb +262 -0
  33. data/lib/chronos/core/integration_verification_result.rb +108 -0
  34. data/lib/chronos/errors.rb +11 -0
  35. data/lib/chronos/ports/transport.rb +18 -1
  36. data/lib/chronos/rails/railtie.rb +5 -0
  37. data/lib/chronos/rake_tasks.rb +41 -0
  38. data/lib/chronos/version.rb +1 -1
  39. data/lib/chronos.rb +26 -0
  40. metadata +35 -4
@@ -0,0 +1,25 @@
1
+ # ADR-007 — Feature detection nas integrações
2
+
3
+ ## Status
4
+
5
+ Aceito para 1.0.
6
+
7
+ ## Contexto
8
+
9
+ Rails 4.2/5.2, Active Job e Sidekiq 4/5 expõem conjuntos diferentes de constantes e hooks. Comparar apenas números de versão cria falsos positivos em instalações parciais.
10
+
11
+ ## Decisão
12
+
13
+ Integrações opcionais verificam a presença da biblioteca e das APIs públicas necessárias antes de instalar middleware, subscribers ou extensões. A instalação é idempotente e não exige Zeitwerk.
14
+
15
+ ## Alternativas
16
+
17
+ Branches por versão e uso de APIs privadas foram rejeitados por fragilidade e custo de manutenção.
18
+
19
+ ## Consequências positivas
20
+
21
+ O núcleo permanece carregável em Ruby puro e combinações validadas compartilham adapters menores.
22
+
23
+ ## Consequências negativas
24
+
25
+ Cada caminho detectado exige contrato e aplicação de exemplo; uma biblioteca que imite parcialmente a API pode precisar de tratamento dedicado.
@@ -0,0 +1,25 @@
1
+ # ADR-008 — Context store por runtime
2
+
3
+ ## Status
4
+
5
+ Aceito para 1.0 legado.
6
+
7
+ ## Contexto
8
+
9
+ Requests e jobs concorrentes não podem compartilhar usuário, parâmetros, breadcrumbs ou trace ID, mas Ruby 2.2 não oferece uma estratégia fiber-local moderna uniforme.
10
+
11
+ ## Decisão
12
+
13
+ Definir uma porta de context store e usar armazenamento thread-local na linha 0.x/1.0 legado. Todo escopo restaura o valor anterior e limpa em `ensure`; somente IDs permitidos atravessam processos.
14
+
15
+ ## Alternativas
16
+
17
+ Estado global foi rejeitado por vazamento entre execuções. Fiber local foi adiado para a linha moderna.
18
+
19
+ ## Consequências positivas
20
+
21
+ O isolamento é testável e o núcleo não depende da primitiva concreta.
22
+
23
+ ## Consequências negativas
24
+
25
+ Threads e fibers criadas pela aplicação exigem propagação explícita; adapters futuros precisam preservar a mesma porta.
@@ -0,0 +1,25 @@
1
+ # ADR-009 — Sampling limitado localmente
2
+
3
+ ## Status
4
+
5
+ Aceito para 1.0.
6
+
7
+ ## Contexto
8
+
9
+ O agente precisa controlar volume durante carga alta e aceitar redução remota sem permitir expansão inesperada da coleta.
10
+
11
+ ## Decisão
12
+
13
+ Usar `sampling_rate` local como teto. Configuração remota pode somente reduzir a taxa, desabilitar tipos ou ativar kill switch. As opções são allowlisted, limitadas e nunca incluem código/regex.
14
+
15
+ ## Alternativas
16
+
17
+ Sampling exclusivamente no servidor desperdiça transporte. Sampling remoto sem teto local foi rejeitado por privacidade e previsibilidade.
18
+
19
+ ## Consequências positivas
20
+
21
+ O operador conserva controle e a decisão ocorre antes de HTTP/retry.
22
+
23
+ ## Consequências negativas
24
+
25
+ Sampling uniforme pode perder eventos raros; análises devem considerar a taxa efetiva.
@@ -0,0 +1,25 @@
1
+ # ADR-010 — Interoperabilidade futura com OpenTelemetry
2
+
3
+ ## Status
4
+
5
+ Adiado; limite aceito para 1.0 legado.
6
+
7
+ ## Contexto
8
+
9
+ O Chronos precisa correlacionar trace/request sem duplicar SDKs ou impor dependências modernas a Ruby 2.2–2.6.
10
+
11
+ ## Decisão
12
+
13
+ Manter IDs de correlação e portas independentes do fornecedor na 1.0. Não depender de OpenTelemetry nem instalar instrumentação global na linha legado. Uma ponte opcional será projetada na linha transitional/modern e deverá traduzir somente campos permitidos.
14
+
15
+ ## Alternativas
16
+
17
+ Adicionar o SDK como dependência obrigatória foi rejeitado por incompatibilidade e overhead. Copiar spans completos foi rejeitado por cardinalidade e privacidade.
18
+
19
+ ## Consequências positivas
20
+
21
+ O protocolo v1 permanece estável e aplicações legadas não recebem novas dependências.
22
+
23
+ ## Consequências negativas
24
+
25
+ Não há propagação automática com ecossistemas OpenTelemetry na 1.0; integrações futuras exigirão contrato e matriz próprios.
@@ -1,9 +1,13 @@
1
1
  # ADR-018: Pre-1.0 hardening gates
2
2
 
3
+ ## Status
4
+
5
+ Concluído pela versão 1.0.0.
6
+
3
7
  ## Decision
4
8
 
5
- Keep the release at `0.9.0.pre.2` while any mandatory 1.0 evidence remains external or incomplete. Add bounded local ignore rules, Active Job envelope propagation, real Sidekiq compatibility jobs, repeatable comparative/load benchmarks, and explicit release/security policies.
9
+ Keep the release in prerelease while any mandatory 1.0 evidence remains external or incomplete. Promote only after bounded local ignore rules, Active Job envelope propagation, real Sidekiq compatibility jobs, repeatable comparative/load benchmarks, and explicit release/security policies are present and green.
6
10
 
7
11
  ## Consequences
8
12
 
9
- The stable API is not promised before the full legacy matrix passes. Active Job gains one namespaced serialized field without changing arguments. Application callbacks remain bounded in count but their execution cost belongs to the application. Package checksums are used until a trusted signing lifecycle is available.
13
+ The complete candidate matrix passed before the 1.0 promotion. Active Job has one namespaced serialized field without changing arguments. Application callbacks remain bounded in count but their execution cost belongs to the application. Trusted Publishing, package checksums and SBOMs are used until a trusted signing lifecycle is available.
@@ -1,36 +1,43 @@
1
1
  # Compatibility
2
2
 
3
- Chronos Ruby 0.x is the legacy line. Technical compatibility does not make an end-of-life Ruby or Rails release secure.
3
+ Chronos Ruby 1.0 is the stable legacy line. Technical compatibility does not make an end-of-life Ruby, Rails, Rack, or Sidekiq release secure.
4
4
 
5
- | Ruby | Rails integration | Status | Evidence |
6
- |---|---|---|---|
7
- | 2.2.10 | Rails 4.2 | Best effort | Core CI, Rails 4.2 example, dedicated smoke gate |
8
- | 2.3.8 | Rails 4.2 / 5.0 | Best effort | Core CI and feature-detection contract; dedicated app gate incomplete |
9
- | 2.4.10 | Rails 4.2 / 5.0 | Best effort | Core CI and feature-detection contract; dedicated app gate incomplete |
10
- | 2.5.9 | Rails 5.2 | Best effort | Core CI, Rails 5.2 example, dedicated smoke gate |
11
- | 2.6.10 | Rails 5.2 | Best effort | Core CI and feature-detection contract; dedicated app gate incomplete |
12
- | 2.7 and newer | None in 0.x | Unsupported | Belongs to transitional or modern lines |
13
-
14
- | Ruby | Sidekiq integration | Status | Evidence |
15
- |---|---|---|---|
16
- | 2.2.10 | Sidekiq 4.2.10 | Best effort | Unit/integration contracts and dedicated real-gem Docker job |
17
- | 2.5.9 | Sidekiq 5.2.10 | Best effort | Unit/integration contracts and dedicated real-gem Docker job |
5
+ ## Core and Rack
18
6
 
19
- Version 0.5 includes Rails 4.2 and 5.2 applications plus a dedicated matrix, but this document conservatively keeps the combinations at `Best effort` until all release-gate evidence, including fake-server payload validation, is green. Rails 5.0 uses the same feature-detected public APIs but does not yet have its own example application.
7
+ | Ruby | Status | Evidence |
8
+ |---|---|---|
9
+ | 2.2.10 | Supported | Full unit, integration, contract, Rack, concurrency, fork, transport, privacy, and lint gate |
10
+ | 2.3.8 | Supported | Same dedicated Docker gate |
11
+ | 2.4.10 | Supported | Same dedicated Docker gate |
12
+ | 2.5.9 | Supported | Same dedicated Docker gate |
13
+ | 2.6.10 | Supported | Same dedicated Docker gate |
14
+ | 2.7 and newer | Unsupported in 1.x legacy | Belongs to the transitional or modern lines |
20
15
 
21
- Version `0.9.0.pre.2` adds dedicated Sidekiq 4.2.10 and 5.2.10 real-gem jobs. Status remains `Best effort` until both external jobs pass on the release candidate.
16
+ ## Rails
22
17
 
23
- Active Job propagation uses the standard `serialize`, `deserialize`, and `perform_now` extension points with a namespaced bounded field. Rails 4.2/5.2 example jobs and unit contracts provide evidence; the complete external matrix must still pass before stable support is declared.
18
+ | Ruby | Rails | Status | Evidence |
19
+ |---|---|---|---|
20
+ | 2.2.10 | 4.2 | Supported | Real application boot, successful/error request, SQL, view, cache, Active Job, mailer, fake endpoint, flush, and shutdown |
21
+ | 2.3.8 | 4.2 | Supported | Same dedicated application gate |
22
+ | 2.5.9 | 5.2 | Supported | Same dedicated application gate |
23
+ | 2.6.10 | 5.2 | Supported | Same dedicated application gate |
24
+ | Other Ruby/Rails pairs | — | Unsupported | No complete release gate; feature detection alone is not a support claim |
24
25
 
25
- Version `0.7.0.pre.1` keeps the same Ruby/Rails matrix and implements APM aggregation without modern concurrency or SQL-parser dependencies. Its compatibility remains `Best effort` until request/SQL/job aggregate payloads pass the dedicated fake-server gates for every listed runtime.
26
+ ## Sidekiq
27
+
28
+ | Ruby | Sidekiq | Status | Evidence |
29
+ |---|---|---|---|
30
+ | 2.2.10 | 4.2.10 | Supported | Real-gem client/server middleware smoke with context, success/failure, and deduplication |
31
+ | 2.5.9 | 5.2.10 | Supported | Same dedicated application gate |
32
+ | Other Ruby/Sidekiq pairs | — | Unsupported | No complete release gate |
26
33
 
27
- Version `0.8.0.pre.1` uses per-object `Module#prepend`, legacy `Net::HTTP`, standard-library SHA-256, and loaded-spec feature detection. It adds no runtime dependency and keeps the same matrix. Outbound HTTP, cache, and dependency gates must pass every listed runtime before support is promoted.
34
+ Active Job uses the public `serialize`, `deserialize`, and `perform_now` extension points with a bounded namespaced field. Support follows the validated Rails pairs above. Adapters that bypass these hooks require their own evidence.
28
35
 
29
- Version `0.9.0.pre.1` adds only standard-library URI/SecureRandom processing, bounded hashes, and the existing synchronous delivery path. Capistrano is optional and feature-detected; Kamal and GitHub Actions integrations are commands/examples. The Ruby/Rails matrix remains unchanged and `Best effort` until deploy/correlation payload gates pass every listed runtime.
36
+ The release workflow repeats every supported pair before publishing. The green candidate evidence that permitted the 1.0 promotion is recorded in [Version 1.0 readiness](release-1.0-readiness.md).
30
37
 
31
38
  Status meanings:
32
39
 
33
- - Supported: the complete required compatibility gate passes.
34
- - Best effort: intended to work, but the complete gate has not passed yet.
40
+ - Supported: every mandatory compatibility gate for the exact pair passes.
41
+ - Best effort: intended to work but missing a complete gate; no 1.0 pair is advertised this way.
35
42
  - Deprecated: still tested while removal is planned.
36
- - Unsupported: outside this release line.
43
+ - Unsupported: outside the tested 1.0 contract.
@@ -48,6 +48,7 @@ Version 0.9 emits exceptions, cache telemetry, dependency/deploy events, and agg
48
48
  | Rails, web server, database adapter, Sidekiq, release | Included when safely detectable/configured | Loaded constants/specs and `app_version` |
49
49
  | Event release, revision, deploy ID, environment, service, region, instance | Present as bounded correlation; values optional | Explicit immutable configuration or normalized deploy payload |
50
50
  | Deploy environment, revision, version, repository, actor, deploy ID, service, region, instance | Explicit synchronous deploy API | Application/deployment integration arguments |
51
+ | Integration verification ID, fixed test marker, synthetic exception class/message, and receipt correlation | Only when `Chronos.verify_integration` or its Rake task is invoked | Locally generated bounded values |
51
52
 
52
53
  The gem never collects request bodies, response bodies, raw query strings, cookies, HTTP authorization headers, environment variables in bulk, Git state, source code, raw SQL, SQL bind values, database rows, raw cache keys/values, mail bodies/recipients, Active Job arguments, gem paths, or lockfile contents. Active Job IDs, Sidekiq JIDs/arguments, loaded gem names/versions, and deploy fields are documented integration data.
53
54
 
@@ -55,4 +56,6 @@ APM dimensions never include user ID, job ID, raw URL, exception message, bind v
55
56
 
56
57
  The secret `project_key` is an authentication header and is excluded from the JSON payload and logger diagnostics. The envelope field named `project_key` contains the public `project_id` required by the current v1 server contract.
57
58
 
59
+ The integration check uses the fixed class `Chronos::IntegrationVerificationError`, tag/fingerprint `chronos-integration-verification`, and `context.integration_verification.test: true`. Its returned object allowlists only project identity/status/environment, receiver name/status/receipt time, correlation IDs, booleans, and safe guidance. Raw response bodies and Chronos implementation details are discarded.
60
+
58
61
  See [Privacy and LGPD](privacy-lgpd.md) for redaction rules and the payload audit procedure.
@@ -4,4 +4,4 @@ After `1.0.0`, a public API scheduled for removal remains available for at least
4
4
 
5
5
  Warnings are emitted at most once per process through the configured safe logger and must not include application payloads. Security fixes, behavior that can expose secrets, and upstream runtime incompatibilities may require faster action; the security advisory and changelog must explain the exception. Ruby/Rails support changes are recorded in `docs/compatibility.md` before removal.
6
6
 
7
- Prereleases may revise APIs without the full stable window, but every incompatible revision must remain explicit. Version `0.9.0.pre.2` introduces no removal.
7
+ Prereleases may revise APIs without the full stable window, but every incompatible revision must remain explicit. Version `1.0.0` starts the stable deprecation window and introduces no removal.
@@ -1,6 +1,6 @@
1
1
  # Migration from Airbrake
2
2
 
3
- Version `0.9.0.pre.2` provides a staged migration path. Run both agents only long enough to compare delivery, then remove Airbrake to avoid duplicate reports and overhead.
3
+ Version `1.0.0` provides a staged migration path. Run both agents only long enough to compare delivery, then remove Airbrake to avoid duplicate reports and overhead.
4
4
 
5
5
  | Airbrake concept | Chronos equivalent |
6
6
  |---|---|
@@ -0,0 +1,23 @@
1
+ # Breadcrumbs
2
+
3
+ ## Problema e limite
4
+
5
+ Breadcrumbs preservam uma trilha curta do fluxo que antecedeu uma falha. Não são logs, tracing completo ou armazenamento de payloads brutos.
6
+
7
+ ## Fluxo e classes
8
+
9
+ `Chronos.add_breadcrumb` normaliza a categoria e os metadados em `Chronos::Core::Breadcrumb`. `BreadcrumbBuffer` mantém um anel de capacidade fixa no context store. O `NoticeBuilder` copia a fotografia atual; sanitizer e serializer aplicam novamente limites antes da entrega.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ Integrações podem registrar apenas categorias conhecidas e metadados de baixa cardinalidade. Mensagens e metadados continuam sendo dados da aplicação e podem conter informação pessoal se o chamador ignorar minimização.
14
+
15
+ ```ruby
16
+ Chronos.add_breadcrumb(
17
+ :category => "custom",
18
+ :message => "invoice queued",
19
+ :metadata => {"provider" => "example"}
20
+ )
21
+ ```
22
+
23
+ Os limites e a herança por captura são testados em `spec/unit/core/breadcrumb_spec.rb`, `spec/unit/agent_spec.rb` e nos specs de Rack.
@@ -0,0 +1,21 @@
1
+ # Contexto de execução
2
+
3
+ ## Problema e limite
4
+
5
+ O contexto relaciona uma exceção ou métrica ao request/job atual sem criar dependência do núcleo com Rack, Rails ou Sidekiq. Ele guarda somente valores delimitados e não é um repositório de estado da aplicação.
6
+
7
+ ## Fluxo e classes
8
+
9
+ `Chronos::Ports::ContextStore` define `get`, `set`, `clear` e `with_context`. Na linha legado, `Chronos::Adapters::ThreadLocalContextStore` isola o valor por thread. A fachada combina o contexto explícito com o escopo atual; o serializer sanitiza e limita tudo antes da fila. Rack limpa o escopo em `ensure`, enquanto Sidekiq e Active Job propagam apenas `trace_id` e `request_id`.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ Um adaptador alternativo pode ser configurado quando implementar a porta completa. Ele precisa restaurar escopos aninhados e garantir limpeza após exceções. Thread local não acompanha automaticamente fibers ou threads criadas pela aplicação; nesses casos, propague somente os identificadores permitidos.
14
+
15
+ ```ruby
16
+ Chronos.with_context("trace_id" => "trace-42", "request_id" => "request-7") do
17
+ Chronos.notify(RuntimeError.new("failure"))
18
+ end
19
+ ```
20
+
21
+ Os contratos estão em `spec/unit/ports/context_store_spec.rb`, `spec/unit/adapters/thread_local_context_store_spec.rb` e `spec/integration/rack_middleware_concurrency_spec.rb`.
@@ -0,0 +1,23 @@
1
+ # Deploys
2
+
3
+ ## Problema e limite
4
+
5
+ Deploys criam o marco temporal usado para comparar erros e desempenho antes/depois de uma release. A gem informa o evento; reconciliação e análise pertencem ao SaaS.
6
+
7
+ ## Fluxo e classes
8
+
9
+ `Chronos.notify_deploy` passa atributos explícitos a `Core::DeployNormalizer`, sanitiza o evento e usa entrega síncrona com idempotência. `CorrelationContext` copia release, revision, deploy ID, ambiente, serviço, região e instância para todos os envelopes. Uma entrega bem-sucedida libera um novo snapshot de dependências.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ Capistrano possui hook opcional; Kamal e GitHub Actions usam comandos documentados. A gem não lê Git nem variáveis automaticamente. O retorno `false` deve ser tratado conforme a política de deploy da aplicação.
14
+
15
+ ```ruby
16
+ Chronos.notify_deploy(
17
+ :environment => "production",
18
+ :revision => ENV["GIT_SHA"],
19
+ :version => ENV["APP_VERSION"]
20
+ )
21
+ ```
22
+
23
+ Veja `spec/unit/core/deploy_normalizer_spec.rb`, `spec/unit/integrations/capistrano_spec.rb` e `spec/integration/deploy_delivery_spec.rb`.
@@ -0,0 +1,65 @@
1
+ # Integration verification
2
+
3
+ `Chronos.verify_integration` performs an explicit end-to-end check of configuration, credentials, receiver availability, and ingestion acknowledgement. Rails registers `chronos:verify_integration` automatically through the Railtie. The command prints exactly one JSON object and exits nonzero unless verification succeeds.
4
+
5
+ ## Flow and ownership
6
+
7
+ `Chronos::Application::VerifyIntegration` creates one normal v1 exception envelope, delivers it synchronously through `DeliveryPipeline`, and validates the response. `IntegrationVerificationResult` exposes the immutable, bounded public outcome. `RakeTasks` only loads the application environment, calls the facade, prints JSON, and selects the exit status.
8
+
9
+ The synthetic event is recognizable without changing the event protocol:
10
+
11
+ ```json
12
+ {
13
+ "event_type": "exception",
14
+ "payload": {
15
+ "exception": {"class": "Chronos::IntegrationVerificationError"},
16
+ "tags": ["chronos-integration-verification"],
17
+ "fingerprint": "chronos-integration-verification"
18
+ },
19
+ "context": {
20
+ "integration_verification": {
21
+ "schema_version": "1.0",
22
+ "verification_id": "generated-uuid",
23
+ "kind": "integration_verification",
24
+ "test": true
25
+ }
26
+ }
27
+ }
28
+ ```
29
+
30
+ Chronos must authenticate before acknowledging the event and must correlate both `verification_id` and the envelope event ID. A `2xx` response alone is insufficient. The accepted response must conform exactly to [`integration-verification-response-v1.schema.json`](../../contracts/integration-verification-response-v1.schema.json):
31
+
32
+ ```json
33
+ {
34
+ "schema_version": "1.0",
35
+ "success": true,
36
+ "status": "accepted",
37
+ "verification_id": "generated-uuid",
38
+ "credentials_valid": true,
39
+ "event_received": true,
40
+ "event": {"id": "event-uuid"},
41
+ "project": {"id": "project-id", "name": "Project", "status": "active", "environment": "production"},
42
+ "receiver": {"name": "chronos", "status": "operational", "received_at": "2026-07-22T12:00:00Z"},
43
+ "error": null
44
+ }
45
+ ```
46
+
47
+ The client rejects missing, mismatched, or additional fields. It copies only the allowlisted project and receiver values and never returns the raw body.
48
+
49
+ ## Result and failure classification
50
+
51
+ The Ruby result supports `success?`, `to_h`, and `to_json`. Its status is `verified` only after the correlated acknowledgement. Failures use `configuration_invalid`, `invalid_credentials`, `project_inactive`, `receiver_unavailable`, `receiver_internal_error`, `rate_limited`, `request_rejected`, `invalid_response`, or `verification_failed`.
52
+
53
+ - `401` and untrusted `403` responses become `invalid_credentials` with instructions to create an active project API key and verify the configured identifiers.
54
+ - A contractual authenticated `403` response may become `project_inactive`.
55
+ - network errors, timeouts, an open circuit, and `502`/`503`/`504` become `receiver_unavailable`.
56
+ - other `5xx` responses become `receiver_internal_error`.
57
+ - malformed or uncorrelated success responses become `invalid_response`.
58
+
59
+ Failure output uses local messages and guidance. Server exception messages, stack traces, SQL, paths, classes, credentials, response headers, and architecture details are never copied.
60
+
61
+ ## Usage
62
+
63
+ In Rails, configure Chronos normally and run `bundle exec rake chronos:verify_integration`. In plain Ruby, require `chronos/rake_tasks` and call `Chronos::RakeTasks.install` from the Rakefile. Programmatic callers can use `Chronos.verify_integration` directly.
64
+
65
+ Verification is an explicit synchronous diagnostic operation. It bypasses sampling and ignore rules so an operator-requested check cannot silently disappear, but it still uses the configured bounded retry, timeout, TLS, circuit, serializer, and transport protections. The receiver should record it as a verification/audit receipt rather than a production application incident.
@@ -0,0 +1,22 @@
1
+ # Monitoramento de jobs
2
+
3
+ ## Problema e limite
4
+
5
+ Jobs precisam manter correlação entre enqueue e execução e registrar duração/falha sem abrir threads ou conexões por job. A versão 1.0 cobre Sidekiq 4/5 e Active Job disponível em Rails 4.2/5.2; Resque e Delayed Job permanecem fora do escopo estável.
6
+
7
+ ## Fluxo e classes
8
+
9
+ O middleware Sidekiq injeta um envelope Chronos separado dos argumentos públicos. O servidor restaura contexto, mede fila/execução e deduplica exceções aninhadas. A integração Active Job usa os hooks públicos de serialização e `perform_now`. As observações seguem para `ApmAggregator` e as exceções para o notice pipeline.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ Adapters que substituem hooks públicos exigem testes próprios. Argumentos Sidekiq são limitados e sanitizados, mas a aplicação deve evitar segredos e dados pessoais desnecessários.
14
+
15
+ ```ruby
16
+ require "chronos/sidekiq"
17
+ Sidekiq.configure_server do |config|
18
+ config.server_middleware { |chain| chain.add Chronos::Integrations::Sidekiq::ServerMiddleware }
19
+ end
20
+ ```
21
+
22
+ Veja `spec/unit/integrations/sidekiq_spec.rb`, `spec/unit/integrations/active_job_spec.rb` e `spec/integration/sidekiq_delivery_spec.rb`.
@@ -0,0 +1,20 @@
1
+ # Monitoramento de requests
2
+
3
+ ## Problema e limite
4
+
5
+ Requests Rack/Rails alimentam métricas de duração, status e breakdown com dimensões limitadas. O módulo não lê bodies, cookies, autorização ou query string bruta.
6
+
7
+ ## Fluxo e classes
8
+
9
+ O middleware Rack cria contexto isolado e mede o request. Subscribers Rails enriquecem controller/action e evitam duplicação. `CaptureTelemetry` envia a observação a `ApmAggregator`; por padrão ela integra um `metric_batch`, e com APM desativado vira evento individual sanitizado.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ Rotas devem ser normalizadas para evitar cardinalidade por ID. Aplicações Rack podem fornecer um normalizador por meio dos campos já aceitos, sem incluir parâmetros sensíveis.
14
+
15
+ ```ruby
16
+ use Chronos::Integrations::Rack::Middleware,
17
+ :include_user_agent => false
18
+ ```
19
+
20
+ Veja `spec/integration/rack_middleware_spec.rb`, `spec/integration/rack_middleware_concurrency_spec.rb` e `spec/integration/apm_aggregation_delivery_spec.rb`.
@@ -0,0 +1,22 @@
1
+ # Informações de runtime
2
+
3
+ ## Problema e limite
4
+
5
+ O agente identifica o runtime necessário para diagnóstico e inventário sem varrer o ambiente, o sistema de arquivos ou conexões da aplicação. A versão 1.0 não implementa profiling nem coleta contínua de CPU/RSS.
6
+
7
+ ## Fluxo e classes
8
+
9
+ `Chronos::Core::RuntimeInfo` produz engine, versão, plataforma, PID, thread opaca e hostname permitido. `DependencyReporter` adiciona versões já carregadas de Ruby, Rails, servidor, adaptador de banco e Sidekiq em um evento separado e limitado, no máximo uma vez por agente e após deploy bem-sucedido.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ Aplicações podem configurar versão, release, região e instância explicitamente. Hostname, IDs de processo e inventário podem ser dados pessoais ou revelar topologia; desative `dependency_reporting` quando a finalidade não justificar a coleta.
14
+
15
+ ```ruby
16
+ Chronos.configure do |config|
17
+ config.dependency_reporting = false
18
+ config.app_version = "2026.07.29"
19
+ end
20
+ ```
21
+
22
+ Veja `spec/unit/core/runtime_info_spec.rb`, `spec/unit/application/dependency_reporter_spec.rb` e `spec/integration/dependency_delivery_spec.rb`.
@@ -0,0 +1,22 @@
1
+ # Sampling
2
+
3
+ ## Problema e limite
4
+
5
+ Sampling reduz volume de eventos sem permitir que o servidor amplie a coleta decidida localmente. Ele não substitui quotas no receptor e não deve ser usado para esconder falhas do agente.
6
+
7
+ ## Fluxo e classes
8
+
9
+ `Chronos::Configuration` valida `sampling_rate` entre `0.0` e `1.0`. `Chronos::Application::RemoteConfiguration` calcula o limite efetivo, que nunca excede o valor local, e `DeliveryPipeline` decide antes do transporte. Deploys e verificações explícitas usam seus próprios caminhos síncronos e não são descartados pelo sampling comum.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ O gerador aleatório pode ser injetado nos objetos internos para testes determinísticos; a API pública expõe somente a taxa. Taxas baixas podem ocultar eventos raros e não garantem amostragem estatística estratificada.
14
+
15
+ ```ruby
16
+ Chronos.configure do |config|
17
+ config.sampling_rate = 0.25
18
+ config.remote_configuration = true
19
+ end
20
+ ```
21
+
22
+ O comportamento é coberto por `spec/unit/application/remote_configuration_spec.rb`, `spec/unit/application/delivery_pipeline_spec.rb` e `spec/integration/deploy_delivery_spec.rb`.
@@ -4,7 +4,7 @@ Version `0.6.0.pre.1` starts the legacy jobs line with optional Sidekiq 4 and 5
4
4
 
5
5
  ```ruby
6
6
  gem "sidekiq", "~> 5.0"
7
- gem "chronos-ruby", "0.9.0.pre.3", :require => "chronos/sidekiq"
7
+ gem "chronos-ruby", "~> 1.0.0", :require => "chronos/sidekiq"
8
8
  ```
9
9
 
10
10
  `chronos/sidekiq` installs middleware through the public `configure_client` and `configure_server` APIs. It does nothing when Sidekiq is unavailable, and the core gem never requires Sidekiq. Installation adds no Chronos thread or Redis/database connection per job; delivery continues through the agent's existing fixed worker pool.
@@ -0,0 +1,22 @@
1
+ # Monitoramento SQL
2
+
3
+ ## Problema e limite
4
+
5
+ O monitoramento SQL mede operação, tabela e duração sem transmitir SQL bruto ou binds. Sinais locais de lentidão, repetição, possível N+1, transação longa, conexão e deadlock são diagnósticos heurísticos.
6
+
7
+ ## Fluxo e classes
8
+
9
+ `Rails::NotificationsSubscriber` extrai somente campos permitidos. `Core::SqlNormalizer` remove comentários e literais, limita identificadores e calcula fingerprint SHA-256. `ApmAggregator` mantém grupos e fingerprints por trace com capacidades fixas, então drena lotes pelo pipeline comum.
10
+
11
+ ## Extensão, riscos e exemplo
12
+
13
+ Thresholds podem ser configurados, mas dimensões de alta cardinalidade não devem ser adicionadas. Nomes de schema, tabela e coluna ainda podem revelar domínio e precisam de avaliação LGPD.
14
+
15
+ ```ruby
16
+ Chronos.configure do |config|
17
+ config.apm_slow_query_threshold_ms = 500.0
18
+ config.apm_n_plus_one_threshold = 5
19
+ end
20
+ ```
21
+
22
+ Veja `spec/unit/core/sql_normalizer_spec.rb`, `spec/unit/application/apm_aggregator_spec.rb` e `spec/integration/rails_telemetry_delivery_spec.rb`.
data/docs/performance.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Performance
2
2
 
3
- Performance is a functional requirement, but version 0.9 makes no unverified speed claim.
3
+ Performance is a functional requirement, but version 1.0 makes no unverified speed claim.
4
4
 
5
5
  Current controls:
6
6
 
@@ -29,7 +29,7 @@ Current controls:
29
29
 
30
30
  Run the scripts under `benchmarks/` and record Ruby version, operating system, CPU, warmup, iteration count, median, and dispersion before publishing results. `benchmarks/filtering.rb` measures privacy filtering, `benchmarks/retry_backlog.rb` measures fixed-memory outage behavior, `benchmarks/request_overhead.rb` compares Rack-protocol calls, and `benchmarks/rails_notifications.rb` isolates subscriber normalization overhead.
31
31
 
32
- ## Version 0.9.0.pre.3 release gates
32
+ ## Version 1.0.0 release gates
33
33
 
34
34
  `benchmarks/comparative.rb` compares the same successful Rack fixture without and with Chronos instrumentation. It performs configurable warmup, at least three samples, and reports median plus median absolute deviation. `benchmarks/fake_endpoint_load.rb` sends asynchronous exception events to a local TCP endpoint, verifies the v1 schema marker, ensures the secret key is absent from every payload, and fails on loss, rejection, invalid payload, or timeout.
35
35
 
@@ -40,6 +40,17 @@ ITERATIONS=500 bundle exec ruby benchmarks/fake_endpoint_load.rb
40
40
 
41
41
  Results are environment-specific evidence, not a general speed claim. Record CPU, OS, Ruby, gem commit, and environment variables with any published result. Airbrake comparison remains optional and must use a legally compatible, equivalent sanitized payload on the same supported runtime.
42
42
 
43
+ ### Stable candidate measurement
44
+
45
+ The 1.0 candidate was measured on 2026-07-29 on an Apple Silicon arm64 host running macOS 26.6, with Ruby 2.2.10 executing as x86_64. The working tree was based on commit `ce7c67852dd39406f514499b0347a67c5b09bb8c` plus the 1.0 release changes. This is release-gate evidence for this environment, not a universal performance claim.
46
+
47
+ | Gate | Configuration | Result |
48
+ |---|---|---|
49
+ | Rack comparison | 1,000 warmup calls, 10,000 calls/sample, 5 samples | direct median 0.016036 s (MAD 0.000187); Chronos median 0.482321 s (MAD 0.016988); median incremental work 46.628 µs/request |
50
+ | Fake endpoint load | 500 asynchronous exceptions, 2 workers, queue 500 | 500/500 accepted and received, zero invalid/secret-bearing payloads, 1.444941 s, 346.03 events/s |
51
+
52
+ The release workflow repeats both gates on the tag. It does not enforce a cross-hardware timing threshold; correctness, bounded delivery, complete receipt, privacy and repeatability are hard failures, while timing regressions are reviewed with the recorded environment.
53
+
43
54
  ## Version 0.5 Rails subscriber benchmark
44
55
 
45
56
  Run:
data/docs/protocol-v1.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Protocol v1 stability
2
2
 
3
- The schemas under `contracts/` are the source of truth for protocol v1. Version `0.9.0.pre.3` keeps `schema_version: "1.0"` and treats every required field, enum value, privacy exclusion, and maximum as a compatibility contract.
3
+ The schemas under `contracts/` are the source of truth for protocol v1. Version `1.0.0` freezes `schema_version: "1.0"` and treats every required field, enum value, privacy exclusion, and maximum as a compatibility contract.
4
4
 
5
5
  Compatible changes may add optional bounded fields or new event types accepted by the server. Removing or renaming a field, changing its type/meaning, weakening a bound, or making an optional field required needs a new protocol major schema. Authentication remains outside the JSON payload. Contract tests and `script/verify_docs` must pass before a release.
6
+
7
+ The explicit integration check uses the normal exception envelope and identifies itself through `context.integration_verification`. Its receiver acknowledgement is governed separately by [`integration-verification-response-v1.schema.json`](../contracts/integration-verification-response-v1.schema.json). A successful HTTP status without a complete, correlated response is not proof of authentication or ingestion.
@@ -1,18 +1,20 @@
1
- # Version 1.0 readiness
1
+ # Version 1.0 release evidence
2
2
 
3
- Version `0.9.0.pre.3` is a hardening release, not the stable release. The local suite, lint, documentation verifier, build, load test, and comparative benchmark are required evidence. The release can advance to `1.0.0` only after the GitHub Actions matrix is green for every declared legacy Ruby/framework/job combination.
3
+ Version `1.0.0` is the first stable legacy release. Promotion was based on the complete candidate commit `ce7c67852dd39406f514499b0347a67c5b09bb8c`; future tags must pass the same gates again inside the release workflow before publishing.
4
4
 
5
- | Gate | State in pre.2 |
6
- |---|---|
7
- | Ruby pure, Rack, Rails 4.2/5.2 | Implemented; external legacy matrix must pass |
8
- | Sidekiq 4/5 real gems | Dedicated Docker matrix added; must pass |
9
- | Active Job metadata/error/context | Implemented and contract-tested |
10
- | filters, bounded ignore rules, context, breadcrumbs | Implemented and documented |
11
- | request/SQL/job APM, deploy, retry/backlog, remote configuration | Implemented and contract-tested |
12
- | payload fixture privacy | Contract-tested |
13
- | public API/options/protocol review | Documented; final review required |
14
- | Airbrake migration, SemVer, deprecation, security review | Added in pre.2 |
15
- | fake endpoint load and repeatable comparison | Executable gates added |
16
- | package signing | Not currently feasible; protected secret plus checksum is the interim control |
5
+ | Gate | Evidence for the candidate | Enforcement for the tag |
6
+ |---|---|---|
7
+ | Ruby 2.2.10–2.6.10 | [Legacy CI: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291304) | `legacy-core` matrix |
8
+ | Rails 4.2/5.2 applications | [Legacy Rails CI: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291287) | `legacy-rails` matrix |
9
+ | Sidekiq 4/5 real gems | [Legacy Sidekiq CI: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291327) | `legacy-sidekiq` matrix |
10
+ | Documentation and package | [Repository checks: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/29891291350) | `release-readiness` plus publish build |
11
+ | Dependency audit | [Security: success](https://github.com/antoniojefferson/chronos-ruby/actions/runs/30251211355) | scheduled and pull-request security workflow |
12
+ | Unit/integration/contracts/lint | 179 examples, 0 failures; 197 files, 0 offenses on Ruby 2.2.10 | every core matrix job |
13
+ | Payload privacy | Contract tests reject secrets in payload and retry backlog | every core matrix job and fake-endpoint load gate |
14
+ | API/options/protocol | Public facade, configuration table, v1 schemas, SemVer and deprecation policy reviewed | documentation verifier and contract suite |
15
+ | Airbrake migration | Staged migration and rollback guide | documentation verifier |
16
+ | Load and repeatable comparison | Local bounded fake endpoint plus median/MAD Rack comparison | `release-readiness` job |
17
+ | Security/release artifacts | Security review, Trusted Publishing, SHA-256 and SPDX SBOM | publish job after all dependencies pass |
18
+ | Package signing | Not currently feasible without a trusted key lifecycle | documented residual control: OIDC publishing, checksum and SBOM |
17
19
 
18
- Do not change compatibility status from `Best effort` or create a `v1.0.0` tag until all external jobs and the dependency audit pass without skips.
20
+ `publish` depends on all four release jobs. A failed or skipped supported runtime/framework/job pair, documentation check, comparison, or load test prevents RubyGems publication.
@@ -1,6 +1,6 @@
1
- # Security review for 0.9.0.pre.3
1
+ # Security review for 1.0.0
2
2
 
3
- Review date: 2026-07-21. Scope: capture, serialization, transport, remote configuration, framework/job integrations, release workflow, examples, and fixtures.
3
+ Review date: 2026-07-29. Scope: capture, serialization, transport, integration verification, remote configuration, framework/job integrations, stable release workflow, examples, and fixtures.
4
4
 
5
5
  Verified by contracts and implementation review:
6
6
 
@@ -12,5 +12,6 @@ Verified by contracts and implementation review:
12
12
  - integrations contain agent failures and do not collect bodies, authorization, raw SQL/binds, mail content, or raw cache keys;
13
13
  - Active Job propagation uses a namespaced v1 field containing only bounded trace/request identifiers and does not alter job arguments;
14
14
  - fixture privacy is enforced by contract tests and dependency advisories are checked by the security workflow.
15
+ - integration verification accepts only a strict correlated response and never exposes raw receiver bodies, credentials, stack traces, paths, SQL, or internal architecture.
15
16
 
16
- Residual risks: supported Ruby/Rails versions are end-of-life; in-memory backlog is lost at exit; application filters/ignore rules execute application code; project identifiers and documented job IDs may be personal data in some deployments; package signing is not enabled because no trusted certificate/key lifecycle exists. Release artifacts should use protected environments and published SHA-256 checksums until signing can be operated safely.
17
+ Residual risks: supported Ruby/Rails versions are end-of-life; in-memory backlog is lost at exit; application filters/ignore rules execute application code; project identifiers and documented job IDs may be personal data in some deployments; package signing is not enabled because no trusted certificate/key lifecycle exists. Stable artifacts use a protected environment, Trusted Publishing, SHA-256 checksums and SPDX SBOMs until signing can be operated safely.
@@ -12,6 +12,12 @@ The agent may be unconfigured, disabled, ignored in the current environment, una
12
12
 
13
13
  Check DNS, TLS certificates, credentials, HTTP status, proxy configuration, and timeout values. The resilience layer retries only network errors, HTTP `408`, `429`, and `5xx` responses. Inspect `agent.diagnostics` when constructing an agent directly to see retry state, backlog usage, and the circuit state.
14
14
 
15
+ ## `chronos:verify_integration` fails
16
+
17
+ Read the single JSON object printed by the task and use `status` and `error.guidance`. `invalid_credentials` means an active project API key must be created or the configured `project_id`/`project_key` corrected. `project_inactive` means authentication succeeded but the selected project must be activated. `receiver_unavailable` covers DNS, TLS, network, timeout, circuit-open, and gateway/service-unavailable failures. `receiver_internal_error` means Chronos reached its own safe internal-error boundary. `invalid_response` means the receiver did not implement the correlated response v1 contract. Every failure exits nonzero and deliberately omits raw receiver messages and implementation details.
18
+
19
+ If Rails does not list the task, require `chronos/rails` and confirm the application initializer loads. A `not_configured` result means the current Rake process did not execute `Chronos.configure`; update to a release containing the Rails environment prerequisite fix and confirm the variables are exported into that process. In plain Ruby, require `chronos/rake_tasks` and call `Chronos::RakeTasks.install` from the Rakefile after loading configuration.
20
+
15
21
  ## Rack exception is not captured
16
22
 
17
23
  Confirm that `Chronos.configure` runs before the middleware handles requests and that the middleware wraps the application component that raises. Version 0.5 captures exceptions raised by the initial downstream Rack call; an exception raised later while a server enumerates a streaming response body is outside this release. The original exception is always re-raised, so the server log should still show it.