Skip to content

release: ship tiny-asl-machine 1.0 with stronger AWS parity #33

Merged
gabrielmoreira merged 1 commit into
mainfrom
v1.0-local
Apr 17, 2026
Merged

release: ship tiny-asl-machine 1.0 with stronger AWS parity #33
gabrielmoreira merged 1 commit into
mainfrom
v1.0-local

Conversation

@gabrielmoreira

Copy link
Copy Markdown
Owner

Highlights:

  • promote major conformance coverage to dual-environment execution across Catch, InputPath, TaskShapes, MapErrors, Task.State, Map.State, Parallel.State, JSONata composition, and related suites
  • tighten local-only cases with explicit AWS-backed divergence reasons instead of vague caveats
  • fix runtime parity issues proven by AWS, including query-language-aware template replacement and JSONata assign/result composition behavior
  • simplify top-level docs and skill guidance to be shorter, clearer, and more practical for users and contributors
  • rebase the branch onto origin/main carefully while preserving the parity work
  • publish a public migration guide for npm users upgrading from 0.0.10 to 1.0.0
  • prepare the release metadata for 1.0.0

This release is intentionally more AWS-aligned and less permissive than the old published 0.x line in several areas. Users upgrading should review MIGRATION_GUIDE.md and rerun parity-sensitive workflows against AWS when exact behavior matters.

Copilot AI review requested due to automatic review settings April 16, 2026 23:36

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Prepares the tiny-asl-machine 1.0.0 release by expanding AWS-backed conformance coverage, tightening AWS parity semantics (notably around query-language-aware template evaluation), and streamlining contributor/user guidance.

Changes:

  • Added many AWS Step Functions snapshot fixtures to broaden dual-environment conformance coverage for Choice operators and related suites.
  • Updated template parsing/evaluation utilities (including JSONata wrapper handling and improved parser error reporting).
  • Added/adjusted tooling and docs for release workflows (new scripts, agent instructions, lint/format config, and a new “skill” doc).

Reviewed changes

Copilot reviewed 198 out of 1938 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tests/conformance/cases/.snapshots/aws/* Adds AWS snapshot fixtures for expanded conformance/parity validation.
src/utils/replacePathTemplateFields.ts Makes template replacement query-language aware and supports JSONata template field evaluation.
src/utils/parseStringTemplate.ts Improves template parser error handling for unmatched braces.
src/utils/parseTemplate.spec.ts Adds tests for unmatched brace error cases.
src/utils/parseIntrinsicFunction.ts Adds intrinsic function signature metadata and tightens argument parsing errors.
src/utils/jsonataTemplate.ts Introduces helpers for detecting/extracting JSONata wrapper templates.
src/utils/jsonataTemplate.spec.ts Adds unit tests for JSONata template helper behavior.
src/choices/operators.spec.ts Aligns Choice-state “no match + no Default” error expectations with AWS behavior.
src/utils/runtime.spec.ts Formatting-only change for UUID regex assertion readability.
src/index.ts Re-exports additional JSONPath/JSONata-specific public types.
skills/write-local-state-machine-tests/SKILL.md Adds concise guidance for writing local state machine tests with mocked resources.
AGENTS.md Adds contributor workflow/testing command guidance.
scripts/package.json Marks scripts/ as ESM to support .ts/.mjs tooling.
scripts/build-package-exports.ts Generates an ESM entrypoint shim for package exports.
scripts/aws-remove-stack.ts Adds a helper script to remove AWS harness stack/resources cleanly.
scripts/aws-create-deployment-config.ts Adds a helper script to create local AWS deployment config scaffolding.
scripts/aws-lambda/index.mjs Adds a Lambda handler that executes harness scripts with AWS SDK clients in scope.
.oxlintrc.json Adds oxlint configuration for repo linting.
.oxfmtrc.json Adds oxfmt configuration including ignore patterns for snapshots/artifacts.
pnpm-workspace.yaml Updates pnpm build allowlist configuration.
.github/dependabot.yml Normalizes quoting/formatting for Dependabot config.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if (typeof value !== 'string') {
throw new TypeError(`Expected JSONPath string for template field ${key}`);
}

Copilot AI Apr 16, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In JSONata query-language mode, this still evaluates .<field>.$ entries using selectPath(...) (JSONPath). That conflicts with the intent of “query-language-aware template replacement” and can silently apply JSONPath semantics when queryLanguage === 'JSONata'. Consider guarding this branch (e.g., reject .$ fields in JSONata mode with a clear error, or route to the correct evaluator) so the behavior is strictly query-language aware.

Suggested change
if (queryLanguage === 'JSONata') {
throw new TypeError(
`Template field ${key} uses JSONPath-only '.$' syntax, which is not supported when QueryLanguage is JSONata`
);
}

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still evaluating this one under the AWS-first rule. I have not changed .$ handling in JSONata mode yet because I want an AWS-backed reproduction before either rejecting the shape locally or routing it differently. Leaving this thread open for now instead of making an unproven semantic change.

Comment thread src/utils/replacePathTemplateFields.ts
Comment thread src/utils/replacePathTemplateFields.ts
Comment thread src/utils/parseIntrinsicFunction.ts
Comment thread src/utils/jsonataTemplate.ts
Comment thread scripts/aws-lambda/index.mjs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 147719294d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/states/index.ts Outdated
Comment thread src/states/index.ts
Comment on lines +1371 to +1372
const fields = line.split(delimiter);
return Object.fromEntries(headers.map((header, index) => [header, fields[index] ?? '']));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Handle quoted CSV fields when materializing ItemReader rows

Splitting each CSV line with line.split(delimiter) breaks valid CSV records that contain quoted delimiters (for example "last, first") and can shift values into the wrong headers. Since ItemReader advertises CSV support, this causes incorrect map-item payloads for common real-world CSV inputs; row parsing needs quote-aware CSV logic instead of raw string splitting.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this is a plausible limitation in the current local CSV materializer, but I am leaving the thread open until I add an AWS-backed reproduction for quoted-field behavior. Per the repo rule for parity work, I do not want to change the parser semantics here without first pinning the symptom with a focused conformance case.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7696aac6fc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/states/index.ts Outdated
Comment thread src/states/index.ts
Comment thread src/choices/operators.ts
Comment on lines +25 to +26
const rfc3339TimestampPattern =
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reinstate semantic RFC3339 validation for IsTimestamp

The new IsTimestamp check now relies on a shape-only regex, so invalid timestamps such as 2026-99-99T99:99:99Z are treated as valid and can incorrectly match IsTimestamp: true branches. The prior implementation validated calendar and time ranges; dropping that validation regresses choice accuracy for malformed-but-pattern-matching inputs.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I inspected this one again before changing anything. The current code still uses a shape regex for IsTimestamp, and the existing conformance catalog explicitly treats broader timestamp semantics as not yet finalized (see Choice.IsTimestamp case 004 notes). I am leaving this thread open until I can reproduce an AWS-backed mismatch with a focused conformance case, rather than guessing stricter semantics locally.

@gabrielmoreira
gabrielmoreira force-pushed the v1.0-local branch 2 times, most recently from 00d1543 to 5b87fc1 Compare April 17, 2026 01:47
@gabrielmoreira gabrielmoreira changed the title release: ship tiny-asl-machine 1.0 with stronger AWS parity and clean… release: ship tiny-asl-machine 1.0 with stronger AWS parity Apr 17, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5b87fc1978

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/states/index.ts
isRecord(objectPayload) && 'Body' in objectPayload ? objectPayload.Body : objectPayload;
const objectString =
typeof objectBody === 'string' ? objectBody : JSON.stringify(objectBody);
const parsed = JSON.parse(objectString) as unknown;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Parse LOAD_AND_FLATTEN objects with configured InputType

The LOAD_AND_FLATTEN branch unconditionally does JSON.parse(objectString), so valid configurations with ReaderConfig.InputType set to CSV or JSONL fail at runtime (or are mis-materialized) instead of producing map items. This breaks distributed-map fan-out for non-JSON object collections even though InputType is already read and only PARQUET is explicitly rejected; the parsing logic here needs to branch by InputType (e.g., CSV/JSONL parsers) rather than always assuming JSON.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks plausible from the current code path, but I have not changed it yet because I want the same reproduce-first treatment as the other ItemReader issues: add a focused case, then only fix what I can verify without drifting from AWS behavior. Leaving the thread open while I scope that reproduction.

Comment thread src/states/index.ts

const payload = await context.Resources?.invoke(itemReader.Resource, parameters);
const body = isRecord(payload) && 'Body' in payload ? payload.Body : payload;
const bodyString = typeof body === 'string' ? body : JSON.stringify(body);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decode non-string S3 bodies before ItemReader parsing

When s3:getObject returns a non-string body (for example Buffer/Uint8Array from common S3 adapters), this path uses JSON.stringify(body) instead of decoding bytes to text, so JSON/CSV/JSONL parsing operates on serialized metadata rather than file contents. In those environments, ItemReader will fail or produce incorrect rows even with valid objects; the body should be normalized via byte-to-UTF8 decoding instead of JSON stringification.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also plausible, especially for local adapters that return byte bodies instead of strings, but I have not reproduced it in the current harness yet. I am leaving this open until I can pin it with a focused test and then decide the narrowest safe normalization path.

…er docs

- expand AWS-backed conformance coverage and promote more cases to dual-environment validation
- harden query-language-aware JSONata/JSONPath behavior without diverging from observed AWS semantics
- simplify public and contributor documentation for the 1.0 release
- publish a migration guide from the real npm baseline (0.0.10) and bump package version to 1.0.0
- adopt the repaired Vite+ tooling layer while keeping pnpm scripts as the normal project interface
- switch the Vitest launcher to pnpm exec vp test and update related tooling config
- aggressively upgrade key tooling and AWS SDK dependencies
- fix package publish artifacts by including root types/ and excluding emitted spec files
- verify format, lint, typecheck, unit tests, local+AWS conformance, build, and packed artifact shape
@gabrielmoreira
gabrielmoreira merged commit 074eab0 into main Apr 17, 2026
6 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d8c416bdab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/states/index.ts
Comment on lines +501 to +504
runUntilFinished(
definition,
createChildScopeContext(context),
inputData,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate sub-definition QueryLanguage into branch execution

This branch execution reuses the parent context without applying the child StateDefinition query-language default, so nested definitions that set QueryLanguage: 'JSONata' at the definition level are still evaluated as JSONPath unless every inner state repeats QueryLanguage. That breaks valid mixed-language workflows (for example JSONata Output/Condition fields in branch states being treated as plain strings). Please derive the child context with the nested definition’s query language before calling runUntilFinished (and mirror this for map iterator/item-processor execution too).

Useful? React with 👍 / 👎.

Comment thread src/states/index.ts
Comment on lines +1280 to +1284
const timestamp =
getQueryLanguage(context, state) === 'JSONata'
? String(
await replacePathTemplateFields(
state.Timestamp,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject non-string JSONata Wait timestamps before parsing

The JSONata Wait.Timestamp path coerces the evaluated value with String(...) before parsing, so non-string results are silently accepted and fed into Date.parse. Inputs like numeric/object JSONata results can therefore become unintended dates or NaN, leading to wrong delay behavior instead of a clear runtime/query-evaluation error. This should validate the evaluated type as string first, then parse.

Useful? React with 👍 / 👎.

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.

2 participants