Run artifact

evidence/prompt_outputs/20260822.180459.019Z_jq_plan_codex.output.txt

=== BEGIN ARTIFACT FEATURE-Path-Discovery.md ===
# FEATURE: Path Discovery and Projection

| Field       | Value |
|-------------|-------|
| Version     | 20260822 V1 |
| Description | Discovers jq paths and constructs projections from path expressions. |
| Depends On  | FEATURE-Destructuring.md, FEATURE-Accessors.md |
| Provides    | path, paths, pick, path projections |
| Consumes    | destructuring and field/index access |

## Questions

- None.

## Scope

Implement exact and generated path expressions, recursive path enumeration, filtered `paths`, and `pick` projections. Path results preserve jq's ordering and use string object keys and numeric array indices. Invalid path expressions raise runtime errors according to jq semantics.

## Programmatic Acceptance

=== AC path-001-conformance ===
Intent: Path discovery and projection behavior executes successfully for representative path, paths, and pick programs.
Suite: scoped
Requires: executable=python3; scope=test

import subprocess

path_result = subprocess.run(
    ["./jq", "-c", "path(.a)",],
    input='{"a":1}\n',
    capture_output=True,
    text=True,
)
paths_result = subprocess.run(
    ["./jq", "-c", "paths",],
    input='{"a":1,"b":[2]}\n',
    capture_output=True,
    text=True,
)
pick_result = subprocess.run(
    ["./jq", "-c", "pick(.a)",],
    input='{"a":1,"b":2}\n',
    capture_output=True,
    text=True,
)
assert path_result.returncode == 0
assert path_result.stdout.splitlines() == ['["a"]']
assert paths_result.returncode == 0
assert paths_result.stdout.splitlines() == ['["a"]', '["b",0]']
assert pick_result.returncode == 0
assert pick_result.stdout.splitlines() == ['{"a":1}']
=== END AC path-001-conformance ===

## User Acceptance

- None.

## Guardrails

- Path enumeration must preserve traversal order and distinguish empty root paths from descendant paths.
- Projection must not mutate the source value.
=== END ARTIFACT ===

=== BEGIN ARTIFACT FEATURE-Path-Primitives.md ===
# FEATURE: Path Access and Mutation Primitives

| Field       | Value |
|-------------|-------|
| Version     | 20260822 V1 |
| Description | Reads, creates, replaces, and deletes nested values through jq path primitives. |
| Depends On  | FEATURE-Path-Discovery.md |
| Provides    | getpath, setpath, delpaths |
| Consumes    | path discovery and projection |

## Questions

- None.

## Scope

Implement `getpath`, `setpath`, and `delpaths` for nested object and array paths. Operations create intermediate containers where jq requires them, expand arrays with null values, preserve immutable-value semantics, and reject invalid or excessively deep paths with runtime errors.

## Programmatic Acceptance

=== AC path-002-conformance ===
Intent: Path access and mutation primitives execute successfully for representative getpath, setpath, and delpaths programs.
Suite: scoped
Requires: executable=python3; scope=test

import subprocess

get_result = subprocess.run(
    ["./jq", "-c", "getpath([\"a\", \"b\"])",],
    input='{"a":{"b":3}}\n',
    capture_output=True,
    text=True,
)
set_result = subprocess.run(
    ["./jq", "-c", "setpath([\"a\", \"b\"]; 4)",],
    input='{"a":{}}\n',
    capture_output=True,
    text=True,
)
del_result = subprocess.run(
    ["./jq", "-c", "delpaths([[\"a\"]])",],
    input='{"a":1,"b":2}\n',
    capture_output=True,
    text=True,
)
assert get_result.returncode == 0
assert get_result.stdout.splitlines() == ["3"]
assert set_result.returncode == 0
assert set_result.stdout.splitlines() == ['{"a":{"b":4}}']
assert del_result.returncode == 0
assert del_result.stdout.splitlines() == ['{"b":2}']
=== END AC path-002-conformance ===

## User Acceptance

- None.

## Guardrails

- Path operations must not mutate previously produced values.
- Invalid path types and excessive depth must remain runtime errors, not compile failures.
=== END ARTIFACT ===

=== BEGIN ARTIFACT FEATURE-Process-Contract.md ===
# FEATURE: jq Process Contract

| Field       | Value |
|-------------|-------|
| Version     | 20260822 V1 |
| Description | Defines jq compilation, runtime failure, success, partial-output, and diagnostic process behavior. |
| Depends On  | FEATURE-Executable-Entry-Point.md |
| Provides    | compile exit 3, runtime exit 5, success exit 0, stderr diagnostics |
| Consumes    | ./jq -c program execution |

## Questions

- None.

## Compile and Runtime Outcomes

| Condition | Exit |
|---|---:|
| Program compiles and finishes | `0` |
| Program is rejected during compilation | `3` |
| Program compiles and raises during evaluation | `5` |

A compile failure must not be reported as a runtime failure. A runtime failure may occur after values have already been emitted; those values remain observable on stdout. Diagnostics go to stderr and are not part of the value stream.

## Programmatic Acceptance

=== AC exec-002-compile-runtime ===
Intent: The executable distinguishes compile failures, runtime failures, and successful completion.
Suite: scoped
Requires: executable=python3; scope=test

import subprocess

compile_result = subprocess.run(
    ["./jq", "-c", "{",],
    input="null\n",
    capture_output=True,
    text=True,
)
runtime_result = subprocess.run(
    ["./jq", "-c", "error"],
    input="null\n",
    capture_output=True,
    text=True,
)
success_result = subprocess.run(
    ["./jq", "-c", "."],
    input="null\n",
    capture_output=True,
    text=True,
)
assert compile_result.returncode == 3
assert runtime_result.returncode == 5
assert success_result.returncode == 0
assert compile_result.stderr != ""
assert runtime_result.stderr != ""
=== END AC exec-002-compile-runtime ===

=== AC exec-002-statuses ===
Intent: The executable exposes distinct compile, runtime, and successful completion statuses.

import subprocess

compile_result = subprocess.run(
    ["./jq", "-c", "{",],
    input="null\n",
    capture_output=True,
    text=True,
)
runtime_result = subprocess.run(
    ["./jq", "-c", "error"],
    input="null\n",
    capture_output=True,
    text=True,
)
success_result = subprocess.run(
    ["./jq", "-c", "."],
    input="null\n",
    capture_output=True,
    text=True,
)
assert compile_result.returncode == 3
assert runtime_result.returncode == 5
assert success_result.returncode == 0
=== END AC exec-002-statuses ===

=== AC exec-002-partial-output ===
Intent: A runtime failure preserves values emitted before the failure and keeps diagnostics off standard output.

import subprocess

result = subprocess.run(
    ["./jq", "-c", "1, error"],
    input="null\n",
    capture_output=True,
    text=True,
)
print(result.stdout)
print(result.stderr, file=__import__("sys").stderr)
assert result.returncode == 5
assert result.stdout.splitlines() == ["1"]
assert result.stderr != ""
=== END AC exec-002-partial-output ===

## User Acceptance

- None.

## Guardrails

- Compile failures exit `3`.
- Runtime failures exit `5`.
- Successful completion exits `0`.
- Runtime output produced before failure is preserved.
- Diagnostics are written to stderr only.
=== END ARTIFACT ===

=== BEGIN ARTIFACT FEATURE-Recursive-Generators.md ===
# FEATURE: Recursive Generators

| Field       | Value |
|-------------|-------|
| Version     | 20260822 V1 |
| Description | Provides jq recursive and repeated generator filters. |
| Depends On  | FEATURE-Reductions-and-Iteration-Control.md |
| Provides    | while, until, repeat, recurse, recursive descent |
| Consumes    | reductions and ordered generator evaluation |

## Questions

- None.

## Workflow

The evaluator supports recursive descent and the `while`, `until`, `repeat`, and `recurse` generators. Recursive filters emit values in jq order, terminate according to their predicates or caught errors, and preserve branching when an update yields multiple values.

## Programmatic Acceptance

=== AC recursive-generators-scoped ===
Intent: Recursive generator behavior executes successfully for representative while, until, and recurse programs.
Suite: scoped

import subprocess

while_result = subprocess.run(
    ["./jq", "-c", "1 | while(. < 3; . + 1)",],
    input="null\n",
    capture_output=True,
    text=True,
)
until_result = subprocess.run(
    ["./jq", "-c", "1 | until(. >= 3; . + 1)",],
    input="null\n",
    capture_output=True,
    text=True,
)
recurse_result = subprocess.run(
    ["./jq", "-c", "1 | recurse(. < 3; . + 1)",],
    input="null\n",
    capture_output=True,
    text=True,
)
assert while_result.returncode == 0
assert until_result.returncode == 0
assert recurse_result.returncode == 0
assert while_result.stdout != ""
assert until_result.stdout != ""
assert recurse_result.stdout != ""
=== END AC recursive-generators-scoped ===

=== AC recursive-descent-scoped ===
Intent: Recursive-descent syntax executes successfully and emits descendants.
Suite: scoped

import subprocess

result = subprocess.run(
    ["./jq", "-c", "..",],
    input='{"a":1}\n',
    capture_output=True,
    text=True,
)
lines = result.stdout.splitlines()
assert result.returncode == 0
assert len(lines) >= 2
assert "1" in lines
=== END AC recursive-descent-scoped ===

## User Acceptance

- None.

## Guardrails

- Recursive generators must not emit duplicate or incorrectly ordered values.
- Termination must not depend on a fixed shallow recursion cutoff.
- Runtime errors from repeated expressions must remain catchable.
=== END ARTIFACT ===

=== BEGIN ARTIFACT FEATURE-Reductions-and-Iteration-Control.md ===
# FEATURE: Reductions and Iteration Control

| Field       | Value |
|-------------|-------|
| Version     | 20260822 V1 |
| Description | Provides jq reductions and generator control primitives. |
| Depends On  | FEATURE-Labels-and-Breaks.md, FEATURE-Generator-Core.md |
| Provides    | reduce, foreach, limit, skip, first, last, nth, range |
| Consumes    | label and break evaluation, ordered generator evaluation |

## Questions

- None.

## Workflow

The evaluator implements stateful `reduce` and `foreach` operations, bounded and skipped generator consumption, first/last/nth selection, and range generation. All operations preserve jq stream ordering, multiplicity, cartesian argument behavior, and lexical break handling.

## Programmatic Acceptance

=== AC reductions-scoped ===
Intent: Reduction and iteration-control behavior executes successfully for representative reduce, foreach, limit, first, and nth programs.
Suite: scoped

import subprocess

reduce_result = subprocess.run(
    ["./jq", "-c", "reduce range(1; 4) as $x (0; . + $x)",],
    input="null\n",
    capture_output=True,
    text=True,
)
foreach_result = subprocess.run(
    ["./jq", "-c", "foreach range(1; 4) as $x (0; . + $x)",],
    input="null\n",
    capture_output=True,
    text=True,
)
limit_result = subprocess.run(
    ["./jq", "-c", "limit(2; range(5))",],
    input="null\n",
    capture_output=True,
    text=True,
)
assert reduce_result.returncode == 0
assert foreach_result.returncode == 0
assert limit_result.returncode == 0
assert reduce_result.stdout != ""
assert foreach_result.stdout != ""
assert limit_result.stdout.splitlines() == ["0", "1"]
=== END AC reductions-scoped ===

=== AC range-scoped ===
Intent: Range generation executes successfully and preserves generated values.
Suite: scoped

import subprocess

result = subprocess.run(
    ["./jq", "-c", "range(2; 5)",],
    input="null\n",
    capture_output=True,
    text=True,
)
lines = result.stdout.splitlines()
assert result.returncode == 0
assert lines == ["2", "3", "4"]
assert len(lines) > 0
=== END AC range-scoped ===

## User Acceptance

- None.

## Guardrails

- Preserve generator ordering, multiplicity, backtracking, and partial runtime output.
- Do not implement reductions as scalar-only operations.
- Negative limits, skips, and nth indices must retain jq runtime-error behavior.
=== END ARTIFACT ===