Skip to content

Add status_from field to step.json_response for dynamic status codes#382

Merged
intel352 merged 5 commits intomainfrom
copilot/add-status-from-field
Mar 26, 2026
Merged

Add status_from field to step.json_response for dynamic status codes#382
intel352 merged 5 commits intomainfrom
copilot/add-status-from-field

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 26, 2026

Implements the status_from field on step.json_response, enabling dynamic HTTP status codes resolved from the pipeline context at runtime.

Changes Made

  • module/pipeline_step_json_response.go: Added statusFrom field to JSONResponseStep, parsed from config in the factory. New resolveStatus(pc) method resolves a dotted path (e.g. steps.call_upstream.status_code) via resolveBodyFrom, handling int, float64, and int64 values. Resolved values are validated to be whole numbers within the valid HTTP status code range (100–599); fractional floats and out-of-range values fall back to the static status field (default 200). Execute now calls resolveStatus(pc) instead of using the static status directly.

  • schema/step_schema_builtins.go: Added status_from ConfigFieldDef to the step.json_response schema. Made status optional (removed Required: true, added DefaultValue: "200") so configs using only status_from are valid.

  • schema/module_schema.go: Added status_from field to the step.json_response ModuleSchema used by UI/editor tooling.

  • module/pipeline_step_json_response_test.go: Added tests covering status_from with integer value, float64 value, fallback on missing path, precedence over static status, no-HTTP-writer scenario, fractional float fallback, out-of-range status codes (0, -1, 9999, 99, 600), and boundary-valid codes (100, 599).

  • DOCUMENTATION.md: Updated step.json_response table entry to mention status_from.

Behavior

  • status_from accepts a dotted path reference (e.g. steps.call_upstream.status_code) resolved at runtime from the pipeline context
  • If status_from resolves to a valid whole-number integer within the HTTP range (100–599), it is used as the HTTP status code
  • Fractional floats (e.g. 404.9) and out-of-range values are rejected and fall back to status
  • If both status and status_from are provided, status_from takes precedence when resolved to a valid code
  • If status_from is absent or resolves to an invalid/missing value, falls back to status (or 200 default)
  • status is now optional in schema validation; status_from alone is a valid configuration

Example

- name: call_upstream
  type: step.http_call
  config:
    url: "https://upstream-service/api/resource"
    method: GET

- name: respond
  type: step.json_response
  config:
    status_from: steps.call_upstream.status_code
    body_from: steps.call_upstream.body

Testing

  • ✅ All existing tests pass
  • ✅ Tests added for status_from behaviors including integer, float64, fallback, precedence, no-writer, fractional float rejection, out-of-range rejection, and boundary validation
  • ✅ Build and linter clean
Original prompt

This section details on the original issue you should resolve

<issue_title>Add status_from field to step.json_response for dynamic HTTP status codes</issue_title>
<issue_description>## Summary

step.json_response currently only supports a static status integer field, which is parsed as a literal at YAML load time. We need a status_from field that resolves a dynamic value from the pipeline context at runtime.

Use Case

In a facade/proxy pattern, a pipeline calls an upstream service via step.http_call, then needs to return the upstream's actual HTTP status code to the caller:

- name: call_upstream
  type: step.http_call
  config:
    url: "https://upstream-service/api/resource"
    method: GET

- name: respond
  type: step.json_response
  config:
    status_from: steps.call_upstream.status_code   # <-- NEW: dynamic status
    body_from: steps.call_upstream.body

Currently the only option is status: 200 (or any other hardcoded integer), which means the facade always returns a fixed status regardless of what the upstream returned.

Proposed Behavior

  • Add status_from field to step.json_response config
  • status_from accepts a template reference (e.g., steps.call_upstream.status_code) that resolves to an integer at runtime
  • If both status and status_from are provided, status_from takes precedence
  • If status_from resolves to a non-integer or is empty, fall back to status (or 200 default)

Context

This is a blocker for enabling shadow mode in a multi-service migration (App → Chimera). Shadow mode calls both services, returns the primary's response, and logs divergence. Without status_from, the facade returns hardcoded 200 regardless of the upstream's actual response.</issue_description>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

@intel352
Copy link
Copy Markdown
Contributor

@copilot try again

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 26, 2026

@copilot try again

Done in commit 18f577d. The status_from field is now implemented on step.json_response:

  • statusFrom field added to the struct and parsed from config
  • resolveStatus(pc) resolves a dotted path (e.g. steps.call_upstream.status_code) from the pipeline context, handling int, float64, and int64 values
  • Falls back to the static status (or 200 default) when status_from is absent or unresolvable
  • status_from takes precedence over status when it resolves to a valid integer
  • Schema updated with the new status_from config field
  • 6 new tests cover all the specified behaviors

Copilot AI changed the title [WIP] Add status_from field to step.json_response for dynamic status codes Add status_from field to step.json_response for dynamic status codes Mar 26, 2026
@intel352 intel352 marked this pull request as ready for review March 26, 2026 08:50
Copilot AI review requested due to automatic review settings March 26, 2026 08:50
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds dynamic HTTP status support to step.json_response via a new status_from config field, allowing status codes to be resolved from pipeline context at runtime (e.g., proxying step.http_call’s status_code).

Changes:

  • Add status_from parsing and runtime resolution in step.json_response.
  • Extend built-in step schema and documentation to mention status_from.
  • Add unit tests covering common status_from behaviors and fallbacks.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
module/pipeline_step_json_response.go Implements status_from and resolves status at runtime before writing the response.
schema/step_schema_builtins.go Adds status_from to the built-in schema for step.json_response.
module/pipeline_step_json_response_test.go Adds tests for status_from behavior, precedence, and fallback scenarios.
DOCUMENTATION.md Updates step.json_response entry to mention status_from.

Comment on lines +80 to +89
if s.statusFrom != "" {
if val := resolveBodyFrom(s.statusFrom, pc); val != nil {
switch v := val.(type) {
case int:
return v
case float64:
return int(v)
case int64:
return int(v)
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

resolveStatus currently converts float64 (and int64) to int via a plain cast. This will silently truncate non-integer floats (e.g. 404.9 -> 404) and can allow out-of-range/invalid HTTP status codes to reach WriteHeader, which can cause runtime errors depending on the underlying ResponseWriter. Consider validating that the resolved value is an integer (no fractional part) and within the valid HTTP status code range before using it; otherwise fall back to the configured static status (or 200).

Copilot uses AI. Check for mistakes.
Comment on lines +518 to +548
func TestJSONResponseStep_StatusFromFloat64(t *testing.T) {
// JSON numbers are often decoded as float64; ensure conversion works.
factory := NewJSONResponseStepFactory()
step, err := factory("proxy-respond", map[string]any{
"status_from": "steps.upstream.status_code",
}, nil)
if err != nil {
t.Fatalf("factory error: %v", err)
}

recorder := httptest.NewRecorder()
pc := NewPipelineContext(nil, map[string]any{
"_http_response_writer": recorder,
})
pc.MergeStepOutput("upstream", map[string]any{
"status_code": float64(503),
})

result, err := step.Execute(context.Background(), pc)
if err != nil {
t.Fatalf("execute error: %v", err)
}

resp := recorder.Result()
if resp.StatusCode != 503 {
t.Errorf("expected status 503 from float64 status_from, got %d", resp.StatusCode)
}
if result.Output["status"] != 503 {
t.Errorf("expected output status=503, got %v", result.Output["status"])
}
}
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Test coverage for status_from doesn’t currently cover invalid resolved values (e.g. a float64 with a fractional part, or an out-of-range status like 0/9999). Adding a couple of negative tests would help lock in the intended “valid integer only, otherwise fall back” behavior once validation is added in resolveStatus.

Copilot generated this review using guidance from organization custom instructions.
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 26, 2026

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:245: parsing iteration count: invalid syntax
baseline-bench.txt:285123: parsing iteration count: invalid syntax
baseline-bench.txt:588061: parsing iteration count: invalid syntax
baseline-bench.txt:880412: parsing iteration count: invalid syntax
baseline-bench.txt:1194432: parsing iteration count: invalid syntax
baseline-bench.txt:1470604: parsing iteration count: invalid syntax
benchmark-results.txt:245: parsing iteration count: invalid syntax
benchmark-results.txt:338982: parsing iteration count: invalid syntax
benchmark-results.txt:659971: parsing iteration count: invalid syntax
benchmark-results.txt:1031474: parsing iteration count: invalid syntax
benchmark-results.txt:1341480: parsing iteration count: invalid syntax
benchmark-results.txt:1730386: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4              3.308m ± 208%
ComponentLoad-4                    3.619m ±   1%
ComponentExecute-4                 1.938µ ±   0%
PoolContention/workers-1-4         1.088µ ±   1%
PoolContention/workers-2-4         1.091µ ±   2%
PoolContention/workers-4-4         1.093µ ±   1%
PoolContention/workers-8-4         1.098µ ±   1%
PoolContention/workers-16-4        1.097µ ±   1%
ComponentLifecycle-4               3.662m ±   1%
SourceValidation-4                 2.263µ ±   1%
RegistryConcurrent-4               799.7n ±   5%
LoaderLoadFromString-4             3.677m ±   1%
geomean                            17.60µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               2.027Mi ± 0%
ComponentLoad-4                     2.180Mi ± 0%
ComponentExecute-4                  1.203Ki ± 0%
PoolContention/workers-1-4          1.203Ki ± 0%
PoolContention/workers-2-4          1.203Ki ± 0%
PoolContention/workers-4-4          1.203Ki ± 0%
PoolContention/workers-8-4          1.203Ki ± 0%
PoolContention/workers-16-4         1.203Ki ± 0%
ComponentLifecycle-4                2.183Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.182Mi ± 0%
geomean                             15.25Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.68k ± 0%
ComponentLoad-4                      18.02k ± 0%
ComponentExecute-4                    25.00 ± 0%
PoolContention/workers-1-4            25.00 ± 0%
PoolContention/workers-2-4            25.00 ± 0%
PoolContention/workers-4-4            25.00 ± 0%
PoolContention/workers-8-4            25.00 ± 0%
PoolContention/workers-16-4           25.00 ± 0%
ComponentLifecycle-4                 18.07k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               18.06k ± 0%
geomean                               183.3

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                 3.028m ± 230%
ComponentLoad-4                       3.443m ±   7%
ComponentExecute-4                    2.058µ ±   1%
PoolContention/workers-1-4            1.185µ ±   2%
PoolContention/workers-2-4            1.185µ ±   2%
PoolContention/workers-4-4            1.187µ ±   3%
PoolContention/workers-8-4            1.189µ ±   0%
PoolContention/workers-16-4           1.194µ ±   1%
ComponentLifecycle-4                  3.443m ±   0%
SourceValidation-4                    2.242µ ±   1%
RegistryConcurrent-4                  877.2n ±   2%
LoaderLoadFromString-4                3.473m ±   1%
geomean                               18.05µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  2.027Mi ± 0%
ComponentLoad-4                        2.180Mi ± 0%
ComponentExecute-4                     1.203Ki ± 0%
PoolContention/workers-1-4             1.203Ki ± 0%
PoolContention/workers-2-4             1.203Ki ± 0%
PoolContention/workers-4-4             1.203Ki ± 0%
PoolContention/workers-8-4             1.203Ki ± 0%
PoolContention/workers-16-4            1.203Ki ± 0%
ComponentLifecycle-4                   2.183Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.182Mi ± 0%
geomean                                15.25Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.68k ± 0%
ComponentLoad-4                         18.02k ± 0%
ComponentExecute-4                       25.00 ± 0%
PoolContention/workers-1-4               25.00 ± 0%
PoolContention/workers-2-4               25.00 ± 0%
PoolContention/workers-4-4               25.00 ± 0%
PoolContention/workers-8-4               25.00 ± 0%
PoolContention/workers-16-4              25.00 ± 0%
ComponentLifecycle-4                    18.07k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  18.06k ± 0%
geomean                                  183.3

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  285.6n ± 1%
CircuitBreakerExecution_Success-4          22.49n ± 0%
CircuitBreakerExecution_Failure-4          64.82n ± 1%
geomean                                    74.67n

                                  │ baseline-bench.txt │
                                  │        B/op        │
CircuitBreakerDetection-4                 144.0 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │
                                  │     allocs/op      │
CircuitBreakerDetection-4                 1.000 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     456.6n ± 1%
CircuitBreakerExecution_Success-4             59.71n ± 0%
CircuitBreakerExecution_Failure-4             65.24n ± 0%
geomean                                       121.2n

                                  │ benchmark-results.txt │
                                  │         B/op          │
CircuitBreakerDetection-4                    144.0 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

                                  │ benchmark-results.txt │
                                  │       allocs/op       │
CircuitBreakerDetection-4                    1.000 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
JQTransform_Simple-4                     945.6n ± 18%
JQTransform_ObjectConstruction-4         1.425µ ±  1%
JQTransform_ArraySelect-4                3.310µ ±  1%
JQTransform_Complex-4                    38.36µ ±  1%
JQTransform_Throughput-4                 1.765µ ±  1%
SSEPublishDelivery-4                     69.81n ±  1%
geomean                                  1.662µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
JQTransform_Simple-4                   1.273Ki ± 0%
JQTransform_ObjectConstruction-4       1.773Ki ± 0%
JQTransform_ArraySelect-4              2.625Ki ± 0%
JQTransform_Complex-4                  16.22Ki ± 0%
JQTransform_Throughput-4               1.984Ki ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │
                                 │     allocs/op      │
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    324.0 ± 0%
JQTransform_Throughput-4                 17.00 ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                 │ benchmark-results.txt │
                                 │        sec/op         │
JQTransform_Simple-4                        961.6n ± 21%
JQTransform_ObjectConstruction-4            1.462µ ±  0%
JQTransform_ArraySelect-4                   3.192µ ±  0%
JQTransform_Complex-4                       35.46µ ±  1%
JQTransform_Throughput-4                    1.781µ ±  0%
SSEPublishDelivery-4                        72.67n ±  1%
geomean                                     1.656µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
JQTransform_Simple-4                      1.273Ki ± 0%
JQTransform_ObjectConstruction-4          1.773Ki ± 0%
JQTransform_ArraySelect-4                 2.625Ki ± 0%
JQTransform_Complex-4                     16.22Ki ± 0%
JQTransform_Throughput-4                  1.984Ki ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                 │ benchmark-results.txt │
                                 │       allocs/op       │
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       324.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 7763 64-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.107µ ± 2%
SchemaValidation_AllFields-4                 1.658µ ± 3%
SchemaValidation_FormatValidation-4          1.570µ ± 2%
SchemaValidation_ManySchemas-4               1.799µ ± 3%
geomean                                      1.509µ

                                    │ baseline-bench.txt │
                                    │        B/op        │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │
                                    │     allocs/op      │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                      1.034µ ± 11%
SchemaValidation_AllFields-4                   1.520µ ±  3%
SchemaValidation_FormatValidation-4            1.473µ ±  1%
SchemaValidation_ManySchemas-4                 1.486µ ±  4%
geomean                                        1.362µ

                                    │ benchmark-results.txt │
                                    │         B/op          │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

                                    │ benchmark-results.txt │
                                    │       allocs/op       │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.182µ ± 46%
EventStoreAppend_SQLite-4                  2.365m ±  9%
GetTimeline_InMemory/events-10-4           13.96µ ±  3%
GetTimeline_InMemory/events-50-4           60.70µ ± 30%
GetTimeline_InMemory/events-100-4          121.8µ ±  1%
GetTimeline_InMemory/events-500-4          626.6µ ±  0%
GetTimeline_InMemory/events-1000-4         1.283m ±  1%
GetTimeline_SQLite/events-10-4             111.2µ ±  1%
GetTimeline_SQLite/events-50-4             250.0µ ±  1%
GetTimeline_SQLite/events-100-4            418.0µ ±  0%
GetTimeline_SQLite/events-500-4            1.762m ±  0%
GetTimeline_SQLite/events-1000-4           3.433m ±  0%
geomean                                    224.4µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  817.5 ± 9%
EventStoreAppend_SQLite-4                  1.985Ki ± 2%
GetTimeline_InMemory/events-10-4           7.953Ki ± 0%
GetTimeline_InMemory/events-50-4           46.62Ki ± 0%
GetTimeline_InMemory/events-100-4          94.48Ki ± 0%
GetTimeline_InMemory/events-500-4          472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4         944.3Ki ± 0%
GetTimeline_SQLite/events-10-4             16.74Ki ± 0%
GetTimeline_SQLite/events-50-4             87.14Ki ± 0%
GetTimeline_SQLite/events-100-4            175.4Ki ± 0%
GetTimeline_SQLite/events-500-4            846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4           1.639Mi ± 0%
geomean                                    67.54Ki

                                   │ baseline-bench.txt │
                                   │     allocs/op      │
EventStoreAppend_InMemory-4                  7.000 ± 0%
EventStoreAppend_SQLite-4                    53.00 ± 2%
GetTimeline_InMemory/events-10-4             125.0 ± 0%
GetTimeline_InMemory/events-50-4             653.0 ± 0%
GetTimeline_InMemory/events-100-4           1.306k ± 0%
GetTimeline_InMemory/events-500-4           6.514k ± 0%
GetTimeline_InMemory/events-1000-4          13.02k ± 0%
GetTimeline_SQLite/events-10-4               382.0 ± 0%
GetTimeline_SQLite/events-50-4              1.852k ± 0%
GetTimeline_SQLite/events-100-4             3.681k ± 0%
GetTimeline_SQLite/events-500-4             18.54k ± 0%
GetTimeline_SQLite/events-1000-4            37.29k ± 0%
geomean                                     1.162k

cpu: Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.149µ ± 11%
EventStoreAppend_SQLite-4                     1.026m ±  1%
GetTimeline_InMemory/events-10-4              13.65µ ±  1%
GetTimeline_InMemory/events-50-4              72.85µ ± 18%
GetTimeline_InMemory/events-100-4             120.3µ ±  0%
GetTimeline_InMemory/events-500-4             614.2µ ±  1%
GetTimeline_InMemory/events-1000-4            1.250m ±  1%
GetTimeline_SQLite/events-10-4                79.99µ ±  1%
GetTimeline_SQLite/events-50-4                233.1µ ±  1%
GetTimeline_SQLite/events-100-4               424.0µ ±  1%
GetTimeline_SQLite/events-500-4               1.914m ±  1%
GetTimeline_SQLite/events-1000-4              3.750m ±  2%
geomean                                       206.9µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     815.0 ± 9%
EventStoreAppend_SQLite-4                     1.983Ki ± 2%
GetTimeline_InMemory/events-10-4              7.953Ki ± 0%
GetTimeline_InMemory/events-50-4              46.62Ki ± 0%
GetTimeline_InMemory/events-100-4             94.48Ki ± 0%
GetTimeline_InMemory/events-500-4             472.8Ki ± 0%
GetTimeline_InMemory/events-1000-4            944.3Ki ± 0%
GetTimeline_SQLite/events-10-4                16.74Ki ± 0%
GetTimeline_SQLite/events-50-4                87.14Ki ± 0%
GetTimeline_SQLite/events-100-4               175.4Ki ± 0%
GetTimeline_SQLite/events-500-4               846.1Ki ± 0%
GetTimeline_SQLite/events-1000-4              1.639Mi ± 0%
geomean                                       67.52Ki

                                   │ benchmark-results.txt │
                                   │       allocs/op       │
EventStoreAppend_InMemory-4                     7.000 ± 0%
EventStoreAppend_SQLite-4                       53.00 ± 0%
GetTimeline_InMemory/events-10-4                125.0 ± 0%
GetTimeline_InMemory/events-50-4                653.0 ± 0%
GetTimeline_InMemory/events-100-4              1.306k ± 0%
GetTimeline_InMemory/events-500-4              6.514k ± 0%
GetTimeline_InMemory/events-1000-4             13.02k ± 0%
GetTimeline_SQLite/events-10-4                  382.0 ± 0%
GetTimeline_SQLite/events-50-4                 1.852k ± 0%
GetTimeline_SQLite/events-100-4                3.681k ± 0%
GetTimeline_SQLite/events-500-4                18.54k ± 0%
GetTimeline_SQLite/events-1000-4               37.29k ± 0%
geomean                                        1.162k

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352
Copy link
Copy Markdown
Contributor

@copilot apply changes based on the comments in this thread

…al, update schemas and tests

Co-authored-by: intel352 <77607+intel352@users.noreply.github.com>
Agent-Logs-Url: https://github.com/GoCodeAlone/workflow/sessions/d591ca56-9504-43b4-8afb-21808a4d9e47
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 26, 2026

@copilot apply changes based on the comments in this thread

Applied in commit feb1e97:

  • status field is now optional (Required: true removed, DefaultValue: "200") in step_schema_builtins.go
  • status_from field added to the ModuleSchema in module_schema.go
  • resolveStatus now rejects fractional floats and values outside the valid HTTP range (100–599), falling back to the static status in both cases
  • Tests added for: fractional float fallback, out-of-range codes (0, -1, 9999, 99, 600), and boundary-valid codes (100, 599)
  • Schema golden file updated

@intel352 intel352 merged commit 2c7b961 into main Mar 26, 2026
18 checks passed
@intel352 intel352 deleted the copilot/add-status-from-field branch March 26, 2026 14:26
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.

Add status_from field to step.json_response for dynamic HTTP status codes

3 participants