Repository navigation
feat(telemetry): correlation ID and structured events for ingestion (C5, F-011) - #9
Merged
Merged
Conversation
Additive migration and model wiring for F-011 correlation ID propagation; existing rows stay null and remain readable. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…hannel AssignCorrelationId validates/generates X-Request-Id per API request and echoes it on the response. App\Support\Telemetry writes JSON domain events to a new additive "telemetry" log channel; the default stack/single channels are untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…emetry start()/run()/fail() thread the correlation ID into IngestionRun.log entries (as an added field on existing entries, never a new leading entry) and emit ingestion.enqueued/started/completed/failed telemetry events; ingestion.failed reads its code from the existing log `code` key per ADR-27/BRAIN-007. Webhook, manual sync, and scheduled sync each resolve or generate their own ID; scheduled runs get one ID per run. Jobs read the ID from the persisted run, so no job payload change is needed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…try events Unit coverage for CorrelationId validation/generation/fallback. Feature coverage: valid X-Request-Id flows through webhook response header, run, and every IngestionRun.log entry; an unsafe/oversized ID is discarded and replaced everywhere downstream; an invalid signature logs webhook.github.rejected; a forced GitHub failure logs ingestion.failed with the ADR-27 code; a reused run keeps its original correlation id while the new request's own id is only recorded on its ingestion.enqueued event; each scheduled run gets its own id. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Without an explicit "name", Monolog fell back to APP_ENV ("local") as
the channel field in emitted JSON lines instead of "telemetry",
making the structured events harder to filter by an operator.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ok propagation test The webhook success fixture previously parsed one clean document with no warnings, so IngestionRun.log stayed empty and the correlation-id propagation assertion for log entries was vacuously true. Add a second, unchanged markdown file so the run always produces at least one log entry to assert against. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ator PCRE's "$" matches before a trailing newline unless the "D" modifier is set, so "id\n" passed CorrelationId::isValid() and was echoed back raw in the response header and persisted on the run row (log injection vector explicitly forbidden by the F-011 prompt). Add the "D" modifier and regression coverage for trailing \n, \r, and \r\n at both the unit (CorrelationId::isValid) and feature (webhook end-to-end: header + IngestionRun.correlation_id) levels. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…emetry-correlation
Registers ADR-29 (correlation ID and structured telemetry for the ingestion flow) and BRAIN-008 (edge validation and record ownership of correlation IDs), marks F-011 as partially mitigated with its remaining gaps, updates CURRENT_STATE and NEXT_ACTIONS, and adds the C5 handoff. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Replaces the PENDING combined-suite gate with the pull request CI result (86 tests, 0 failed, 0 skipped) and records that every Feature test reports a Pest warning in CI, a pattern already present on main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.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.
Audited remediation item C5, closing F-011 partially. A single correlation ID now follows an incident from the API request to the ingestion run, the queued job, every
IngestionRun.logentry, and the structured telemetry events.What changes
AssignCorrelationIdmiddleware (prepend onapi): a clientX-Request-Idis accepted only if it matches^[A-Za-z0-9._:-]{1,128}$with the PCREDmodifier, otherwise a UUID is generated. The ID is returned in the response header.ingestion_runs.correlation_id, written when the run is created. The job reloads the run and reads it.IngestionService::start()keeps its creator's ID; the reusing caller's ID appears only in itsingestion.enqueuedevent (reused: true).IngestionRun.logentry gains acorrelation_idfield. No entry is added, so index-based assertions keep holding.telemetrychannel (JSON,storage/logs/telemetry.log):ingestion.enqueued,ingestion.started,ingestion.completed,ingestion.failed,webhook.github.accepted,webhook.github.rejected.ingestion.failedreads the existingcodekey (ADR-27). The default log channel is unchanged.Validation
X-Request-Idending in\npassed the bare-$pattern and was echoed raw. Fixed ina388496with theDmodifier and regression tests for trailing\n,\r,\r\n.ingestion.failedwith code on a forced 500; valid JSON events; no secret, token, signature, or Markdown in any log; pre-migration runs readable.25bbb3c. This branch then mergedmainat29a7881(server-side sanitization) without conflicts; the combined suite could not run locally because Docker Desktop stopped responding, so this PR's CI is the gate of record for the combined suite.Not covered (tracked in NEXT_ACTIONS)
The GitHub call, Meilisearch indexing, and
CommandIndexUpdateddo not carry the ID yet; the other taxonomy events and duration/latency metrics are out of scope;telemetry.loghas no rotation.🤖 Generated with Claude Code