Skip to content

feat(project): Precommit hooks#12

Merged
krokoko merged 2 commits into
mainfrom
precommithooks
Apr 9, 2026
Merged

feat(project): Precommit hooks#12
krokoko merged 2 commits into
mainfrom
precommithooks

Conversation

@krokoko
Copy link
Copy Markdown
Contributor

@krokoko krokoko commented Apr 9, 2026

Area

  • cdk — infrastructure, handlers, constructs
  • agent — Python runtime / Docker image
  • clibgagent client
  • docs — guides or design sources (docs/guides/, docs/design/)
  • tooling — root mise.toml, scripts, CI workflows

Tip: AGENTS.md lists where to edit and which tests to extend.

Related

Changes

Acknowledgment

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the project license.

@krokoko krokoko requested a review from a team as a code owner April 9, 2026 15:50
@krokoko krokoko merged commit a3a24b1 into main Apr 9, 2026
5 of 6 checks passed
@krokoko krokoko deleted the precommithooks branch April 12, 2026 17:08
scoropeza pushed a commit to scoropeza/sample-autonomous-cloud-coding-agents that referenced this pull request May 5, 2026
…rokoko review aws-samples#1, aws-samples#5, aws-samples#9, aws-samples#12)

Four related fixes on the fanout + github-comment surface, from the
code review on PR aws-samples#52. Grouped because they share the narrative
"defense-in-depth on the fanout dispatcher" — any one landing without
the others leaves a hole.

## Findings addressed

**aws-samples#1 — Fanout handler returns void despite reportBatchItemFailures: true**

The ``FanOutConsumer`` construct (``cdk/src/constructs/fanout-consumer.ts:146``)
has ``reportBatchItemFailures: true`` on its DDB Stream event-source
mapping. The handler returned ``void``, so Lambda retried the entire
batch on any unhandled throw instead of isolating the poisonous
record. Combined with aws-samples#5 this could cascade into retry storms and
violated the per-task ordering guarantee we rely on (§6.4, AD-9).

Fix: handler return type becomes ``Promise<DynamoDBBatchResponse>``.
Per-record processing is wrapped in try/catch; caught throws push
``{ itemIdentifier: record.eventID }`` to ``batchItemFailures`` and
emit ``fanout.record.failed`` warn. Final ``fanout.batch.complete``
log grows a ``failed`` count.

Note: ``DynamoDBStreamHandler`` constrains return to
``void | Promise<void>``, so the handler is typed as a plain 3-arg
async function. Lambda's runtime accepts either shape; existing
tests (passing ``event, context, cb``) work unchanged.

**aws-samples#5 — Unhandled exception in routeEvent crashes batch**

``routeEvent`` uses ``Promise.allSettled`` internally, but
``resolveTokenSecretArn`` can throw ``AccessDeniedException``
SYNCHRONOUSLY before the ``allSettled`` guard is reached. The new
per-record try/catch from aws-samples#1 catches these too.

**aws-samples#9 — renderCommentBody not self-defending against uncoerced DDB strings**

The ``.toFixed(4)`` call on ``costUsd`` is the same bug class as the
``toFixed is not a function`` crash we fixed at the fanout boundary
in commit 9fe704e. Today the sole call site coerces via the shared
helper; a future caller that forgets to would crash.

Fix: ``renderCommentBody`` coerces ``durationS`` and ``costUsd``
internally via the shared ``coerceNumericOrNull`` helper (second
line of defense; caller's coercion remains the first). Widened
``CommentBodyInput`` fields to ``number | string | null`` to
honestly model the DDB Document-client boundary.

**aws-samples#12 — Markdown injection possible via prUrl in GitHub comment body**

``prUrl`` was interpolated directly into a Markdown link target
(``[link](${input.prUrl})``). A crafted URL containing ``)`` / ``|``
/ ``\n`` could break the table layout or inject content, and a
``javascript:`` scheme could produce a click-to-execute link on some
Markdown renderers.

Fix: new exported ``sanitizeMarkdownLinkTarget`` helper in
``shared/github-comment.ts`` rejects URLs containing
``\r\n\t\s)|]"<>`` characters, validates via ``new URL()``, and
rejects non-http(s) schemes. Returns ``null`` on rejection so
``renderCommentBody`` omits the Pull-request row entirely rather
than emitting a broken or unsafe link.

## Tests

+22 regression tests net (fanout 7 for aws-samples#1+aws-samples#5 + 3 for aws-samples#9; github-comment
12 for aws-samples#12):

- Fanout partial-batch: poison-pill isolation, mixed-batch (good
  record NOT in failures), observability warn, empty-failures
  regression guard, baseline pin that today's ``Promise.allSettled``
  containment still works.
- renderCommentBody numeric self-defense: string-typed values render
  correctly; non-finite strings collapse to null with warn; null
  does NOT warn.
- sanitizeMarkdownLinkTarget unit tests: accept clean http/https,
  reject 9 injection patterns, reject 4 non-http schemes
  (``javascript:``, ``data:``, ``file:``, ``ftp:``), reject
  malformed, handle null/undefined. Plus end-to-end assertions on
  ``renderCommentBody`` proving the PR row is omitted on rejection.

CDK suite: 1029 passing (was 1001).

Refs: krokoko code review on PR aws-samples#52 (findings 1, 5, 9, 12)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant