stepfork 0.1.0a2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/bug_report.yml +52 -0
- stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/config.yml +11 -0
- stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/documentation.yml +32 -0
- stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/feature_request.yml +32 -0
- stepfork-0.1.0a2/.github/pull_request_template.md +15 -0
- stepfork-0.1.0a2/.github/workflows/ci.yml +50 -0
- stepfork-0.1.0a2/.github/workflows/docs.yml +83 -0
- stepfork-0.1.0a2/.github/workflows/publish.yml +76 -0
- stepfork-0.1.0a2/.gitignore +59 -0
- stepfork-0.1.0a2/.python-version +1 -0
- stepfork-0.1.0a2/CHANGELOG.md +85 -0
- stepfork-0.1.0a2/CODE_OF_CONDUCT.md +118 -0
- stepfork-0.1.0a2/CONTRIBUTING.md +100 -0
- stepfork-0.1.0a2/LICENSE +184 -0
- stepfork-0.1.0a2/PKG-INFO +377 -0
- stepfork-0.1.0a2/README.md +352 -0
- stepfork-0.1.0a2/SECURITY.md +47 -0
- stepfork-0.1.0a2/assets/stepfork-logo.png +0 -0
- stepfork-0.1.0a2/assets/stepfork-workflow.png +0 -0
- stepfork-0.1.0a2/docs/.gitkeep +0 -0
- stepfork-0.1.0a2/docs/architecture.md +96 -0
- stepfork-0.1.0a2/docs/assets/stepfork-logo.png +0 -0
- stepfork-0.1.0a2/docs/cli.md +348 -0
- stepfork-0.1.0a2/docs/community/early-adopter-guide.md +144 -0
- stepfork-0.1.0a2/docs/concepts.md +104 -0
- stepfork-0.1.0a2/docs/development.md +106 -0
- stepfork-0.1.0a2/docs/diff.md +46 -0
- stepfork-0.1.0a2/docs/examples.md +67 -0
- stepfork-0.1.0a2/docs/getting-started.md +132 -0
- stepfork-0.1.0a2/docs/index.md +73 -0
- stepfork-0.1.0a2/docs/integrations.md +87 -0
- stepfork-0.1.0a2/docs/pypi-publishing.md +118 -0
- stepfork-0.1.0a2/docs/pytest-export.md +80 -0
- stepfork-0.1.0a2/docs/recording.md +104 -0
- stepfork-0.1.0a2/docs/release-checklist.md +59 -0
- stepfork-0.1.0a2/docs/releases/v0.1.0a1.md +83 -0
- stepfork-0.1.0a2/docs/releases/v0.1.0a2.md +100 -0
- stepfork-0.1.0a2/docs/replay.md +65 -0
- stepfork-0.1.0a2/docs/security.md +87 -0
- stepfork-0.1.0a2/docs/trace-format.md +88 -0
- stepfork-0.1.0a2/docs/troubleshooting.md +121 -0
- stepfork-0.1.0a2/examples/__init__.py +1 -0
- stepfork-0.1.0a2/examples/booking_agent/__init__.py +30 -0
- stepfork-0.1.0a2/examples/booking_agent/agent.py +111 -0
- stepfork-0.1.0a2/examples/booking_agent/demo.py +268 -0
- stepfork-0.1.0a2/examples/booking_agent/expected.json +5 -0
- stepfork-0.1.0a2/examples/quickstart/README.md +54 -0
- stepfork-0.1.0a2/examples/quickstart/__init__.py +24 -0
- stepfork-0.1.0a2/examples/quickstart/agent.py +76 -0
- stepfork-0.1.0a2/examples/quickstart/demo.py +256 -0
- stepfork-0.1.0a2/examples/quickstart/expected.json +1 -0
- stepfork-0.1.0a2/examples/refund_agent/__init__.py +30 -0
- stepfork-0.1.0a2/examples/refund_agent/agent.py +161 -0
- stepfork-0.1.0a2/examples/refund_agent/demo.py +268 -0
- stepfork-0.1.0a2/examples/refund_agent/expected.json +7 -0
- stepfork-0.1.0a2/mkdocs.yml +49 -0
- stepfork-0.1.0a2/pyproject.toml +135 -0
- stepfork-0.1.0a2/scripts/terminal-demo/README.md +49 -0
- stepfork-0.1.0a2/scripts/terminal-demo/stepfork-demo.gif +0 -0
- stepfork-0.1.0a2/scripts/terminal-demo/stepfork-demo.tape +36 -0
- stepfork-0.1.0a2/src/stepfork/__init__.py +32 -0
- stepfork-0.1.0a2/src/stepfork/__main__.py +6 -0
- stepfork-0.1.0a2/src/stepfork/cli/__init__.py +1 -0
- stepfork-0.1.0a2/src/stepfork/cli/diff.py +156 -0
- stepfork-0.1.0a2/src/stepfork/cli/export.py +210 -0
- stepfork-0.1.0a2/src/stepfork/cli/inspect.py +155 -0
- stepfork-0.1.0a2/src/stepfork/cli/main.py +54 -0
- stepfork-0.1.0a2/src/stepfork/cli/replay.py +221 -0
- stepfork-0.1.0a2/src/stepfork/cli/validate.py +160 -0
- stepfork-0.1.0a2/src/stepfork/diff/__init__.py +25 -0
- stepfork-0.1.0a2/src/stepfork/diff/compare.py +144 -0
- stepfork-0.1.0a2/src/stepfork/diff/engine.py +267 -0
- stepfork-0.1.0a2/src/stepfork/diff/models.py +63 -0
- stepfork-0.1.0a2/src/stepfork/export/__init__.py +20 -0
- stepfork-0.1.0a2/src/stepfork/export/entrypoint.py +58 -0
- stepfork-0.1.0a2/src/stepfork/export/generator.py +178 -0
- stepfork-0.1.0a2/src/stepfork/export/runtime.py +101 -0
- stepfork-0.1.0a2/src/stepfork/fork/__init__.py +4 -0
- stepfork-0.1.0a2/src/stepfork/inspect/__init__.py +11 -0
- stepfork-0.1.0a2/src/stepfork/inspect/inspector.py +143 -0
- stepfork-0.1.0a2/src/stepfork/inspect/models.py +42 -0
- stepfork-0.1.0a2/src/stepfork/minimize/__init__.py +4 -0
- stepfork-0.1.0a2/src/stepfork/py.typed +0 -0
- stepfork-0.1.0a2/src/stepfork/recorder/__init__.py +21 -0
- stepfork-0.1.0a2/src/stepfork/recorder/llm.py +68 -0
- stepfork-0.1.0a2/src/stepfork/recorder/session.py +500 -0
- stepfork-0.1.0a2/src/stepfork/recorder/tooling.py +208 -0
- stepfork-0.1.0a2/src/stepfork/replay/__init__.py +32 -0
- stepfork-0.1.0a2/src/stepfork/replay/exceptions.py +37 -0
- stepfork-0.1.0a2/src/stepfork/replay/plan.py +282 -0
- stepfork-0.1.0a2/src/stepfork/replay/session.py +338 -0
- stepfork-0.1.0a2/src/stepfork/trace/__init__.py +115 -0
- stepfork-0.1.0a2/src/stepfork/trace/canonical.py +55 -0
- stepfork-0.1.0a2/src/stepfork/trace/hashing.py +75 -0
- stepfork-0.1.0a2/src/stepfork/trace/integrity.py +196 -0
- stepfork-0.1.0a2/src/stepfork/trace/jsonable.py +97 -0
- stepfork-0.1.0a2/src/stepfork/trace/manifest.py +85 -0
- stepfork-0.1.0a2/src/stepfork/trace/models.py +271 -0
- stepfork-0.1.0a2/src/stepfork/trace/redaction.py +294 -0
- stepfork-0.1.0a2/src/stepfork/trace/replay_policy.py +18 -0
- stepfork-0.1.0a2/src/stepfork/trace/schema.py +25 -0
- stepfork-0.1.0a2/src/stepfork/trace/storage.py +250 -0
- stepfork-0.1.0a2/src/stepfork/trace/validation.py +285 -0
- stepfork-0.1.0a2/src/stepfork/version.py +5 -0
- stepfork-0.1.0a2/tests/golden/.gitkeep +0 -0
- stepfork-0.1.0a2/tests/golden/README.md +17 -0
- stepfork-0.1.0a2/tests/golden/build_fixtures.py +72 -0
- stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/events.jsonl +4 -0
- stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/integrity.json +9 -0
- stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/manifest.json +21 -0
- stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/redactions.json +4 -0
- stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/events.jsonl +4 -0
- stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/integrity.json +9 -0
- stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/manifest.json +21 -0
- stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/redactions.json +4 -0
- stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/events.jsonl +4 -0
- stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/integrity.json +9 -0
- stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/manifest.json +25 -0
- stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/redactions.json +4 -0
- stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/events.jsonl +5 -0
- stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/integrity.json +9 -0
- stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/manifest.json +25 -0
- stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/redactions.json +11 -0
- stepfork-0.1.0a2/tests/golden/legacy_v01.sftrace/events.jsonl +2 -0
- stepfork-0.1.0a2/tests/golden/legacy_v01.sftrace/manifest.json +21 -0
- stepfork-0.1.0a2/tests/golden/legacy_v01.sftrace/redactions.json +4 -0
- stepfork-0.1.0a2/tests/golden/partial_run.sftrace/events.jsonl +1 -0
- stepfork-0.1.0a2/tests/golden/partial_run.sftrace/integrity.json +9 -0
- stepfork-0.1.0a2/tests/golden/partial_run.sftrace/manifest.json +21 -0
- stepfork-0.1.0a2/tests/golden/partial_run.sftrace/redactions.json +4 -0
- stepfork-0.1.0a2/tests/golden/successful_run.sftrace/events.jsonl +6 -0
- stepfork-0.1.0a2/tests/golden/successful_run.sftrace/integrity.json +9 -0
- stepfork-0.1.0a2/tests/golden/successful_run.sftrace/manifest.json +21 -0
- stepfork-0.1.0a2/tests/golden/successful_run.sftrace/redactions.json +4 -0
- stepfork-0.1.0a2/tests/integration/.gitkeep +0 -0
- stepfork-0.1.0a2/tests/integration/test_docs_assets.py +52 -0
- stepfork-0.1.0a2/tests/integration/test_failure_to_test.py +137 -0
- stepfork-0.1.0a2/tests/integration/test_golden_fixtures.py +120 -0
- stepfork-0.1.0a2/tests/integration/test_quickstart_failure_to_test.py +127 -0
- stepfork-0.1.0a2/tests/integration/test_refund_failure_to_test.py +140 -0
- stepfork-0.1.0a2/tests/integration/test_secure_trace_roundtrip.py +144 -0
- stepfork-0.1.0a2/tests/integration/test_trace_infrastructure_flow.py +124 -0
- stepfork-0.1.0a2/tests/integration/test_trace_roundtrip.py +59 -0
- stepfork-0.1.0a2/tests/property/.gitkeep +0 -0
- stepfork-0.1.0a2/tests/property/test_trace_properties.py +98 -0
- stepfork-0.1.0a2/tests/unit/test_canonical.py +61 -0
- stepfork-0.1.0a2/tests/unit/test_cli.py +27 -0
- stepfork-0.1.0a2/tests/unit/test_cli_diff.py +67 -0
- stepfork-0.1.0a2/tests/unit/test_cli_export.py +272 -0
- stepfork-0.1.0a2/tests/unit/test_cli_inspect.py +135 -0
- stepfork-0.1.0a2/tests/unit/test_cli_replay.py +233 -0
- stepfork-0.1.0a2/tests/unit/test_cli_validate.py +133 -0
- stepfork-0.1.0a2/tests/unit/test_diff.py +210 -0
- stepfork-0.1.0a2/tests/unit/test_export.py +350 -0
- stepfork-0.1.0a2/tests/unit/test_hashing.py +84 -0
- stepfork-0.1.0a2/tests/unit/test_inspector.py +147 -0
- stepfork-0.1.0a2/tests/unit/test_integrity.py +158 -0
- stepfork-0.1.0a2/tests/unit/test_invalid_bundles.py +121 -0
- stepfork-0.1.0a2/tests/unit/test_jsonable.py +49 -0
- stepfork-0.1.0a2/tests/unit/test_llm_request.py +151 -0
- stepfork-0.1.0a2/tests/unit/test_manifest.py +118 -0
- stepfork-0.1.0a2/tests/unit/test_recording_session.py +243 -0
- stepfork-0.1.0a2/tests/unit/test_redaction.py +127 -0
- stepfork-0.1.0a2/tests/unit/test_replay_plan.py +117 -0
- stepfork-0.1.0a2/tests/unit/test_replay_tool.py +269 -0
- stepfork-0.1.0a2/tests/unit/test_schema.py +42 -0
- stepfork-0.1.0a2/tests/unit/test_storage.py +333 -0
- stepfork-0.1.0a2/tests/unit/test_trace_models.py +310 -0
- stepfork-0.1.0a2/tests/unit/test_trace_tool.py +124 -0
- stepfork-0.1.0a2/tests/unit/test_validation.py +196 -0
- stepfork-0.1.0a2/uv.lock +1510 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
name: Bug report
|
|
2
|
+
description: Report a reproducible problem in Stepfork
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for reporting a bug. Do not include secrets, API keys, private
|
|
10
|
+
prompts, credentials, or sensitive trace data.
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: Description
|
|
15
|
+
description: What happened?
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: minimal-reproduction
|
|
20
|
+
attributes:
|
|
21
|
+
label: Minimal reproduction
|
|
22
|
+
description: Provide the smallest reproduction you can share safely.
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: expected-behavior
|
|
27
|
+
attributes:
|
|
28
|
+
label: Expected behavior
|
|
29
|
+
description: What did you expect to happen?
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
- type: input
|
|
33
|
+
id: stepfork-version
|
|
34
|
+
attributes:
|
|
35
|
+
label: Stepfork version
|
|
36
|
+
placeholder: "0.1.0.dev0"
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
- type: input
|
|
40
|
+
id: python-version
|
|
41
|
+
attributes:
|
|
42
|
+
label: Python version
|
|
43
|
+
placeholder: "3.11.9"
|
|
44
|
+
validations:
|
|
45
|
+
required: true
|
|
46
|
+
- type: input
|
|
47
|
+
id: operating-system
|
|
48
|
+
attributes:
|
|
49
|
+
label: Operating system
|
|
50
|
+
placeholder: "macOS 15, Ubuntu 24.04, Windows 11"
|
|
51
|
+
validations:
|
|
52
|
+
required: true
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: Report a security vulnerability
|
|
4
|
+
url: https://github.com/utsab345/stepfork/security/advisories/new
|
|
5
|
+
about: Report security issues privately. Do not open a public issue.
|
|
6
|
+
- name: Documentation
|
|
7
|
+
url: https://utsab345.github.io/stepfork/
|
|
8
|
+
about: Read the documentation and CLI reference before opening an issue.
|
|
9
|
+
- name: Contributing guide
|
|
10
|
+
url: https://github.com/utsab345/stepfork/blob/main/CONTRIBUTING.md
|
|
11
|
+
about: Local setup, development workflow, and pull request expectations.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Documentation issue
|
|
2
|
+
description: Report unclear, incorrect, or missing documentation
|
|
3
|
+
title: "[Docs]: "
|
|
4
|
+
labels: ["documentation"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for improving the docs. Do not include secrets, API keys,
|
|
10
|
+
private prompts, credentials, or sensitive trace data.
|
|
11
|
+
- type: input
|
|
12
|
+
id: location
|
|
13
|
+
attributes:
|
|
14
|
+
label: Where
|
|
15
|
+
description: URL, file path, or CLI reference section with the problem.
|
|
16
|
+
placeholder: docs/cli.md, `stepfork export` section
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: problem
|
|
21
|
+
attributes:
|
|
22
|
+
label: What is wrong or missing
|
|
23
|
+
description: Quote the text if possible and explain what is incorrect or unclear.
|
|
24
|
+
validations:
|
|
25
|
+
required: true
|
|
26
|
+
- type: textarea
|
|
27
|
+
id: suggestion
|
|
28
|
+
attributes:
|
|
29
|
+
label: Suggested improvement
|
|
30
|
+
description: What should the documentation say or show?
|
|
31
|
+
validations:
|
|
32
|
+
required: false
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
name: Feature request
|
|
2
|
+
description: Suggest an improvement for Stepfork
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for suggesting an improvement. Do not include secrets, API keys,
|
|
10
|
+
private prompts, credentials, or sensitive trace data.
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: problem
|
|
13
|
+
attributes:
|
|
14
|
+
label: Problem
|
|
15
|
+
description: What problem should this solve?
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
- type: textarea
|
|
19
|
+
id: proposed-solution
|
|
20
|
+
attributes:
|
|
21
|
+
label: Proposed solution
|
|
22
|
+
description: What would you like Stepfork to do?
|
|
23
|
+
validations:
|
|
24
|
+
required: true
|
|
25
|
+
- type: textarea
|
|
26
|
+
id: desired-example
|
|
27
|
+
attributes:
|
|
28
|
+
label: Desired CLI/API example
|
|
29
|
+
description: Show the command or code you wish existed.
|
|
30
|
+
render: shell
|
|
31
|
+
validations:
|
|
32
|
+
required: true
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Summary
|
|
2
|
+
|
|
3
|
+
## Changes
|
|
4
|
+
|
|
5
|
+
## Testing
|
|
6
|
+
|
|
7
|
+
## Checklist
|
|
8
|
+
|
|
9
|
+
- [ ] Tests added/updated
|
|
10
|
+
- [ ] pytest passes
|
|
11
|
+
- [ ] ruff check passes
|
|
12
|
+
- [ ] ruff format check passes
|
|
13
|
+
- [ ] mypy passes
|
|
14
|
+
- [ ] docs updated if necessary
|
|
15
|
+
- [ ] no secrets/sensitive traces included
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
pull_request:
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
name: Python ${{ matrix.python-version }}
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
|
|
17
|
+
strategy:
|
|
18
|
+
fail-fast: false
|
|
19
|
+
matrix:
|
|
20
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Install uv
|
|
27
|
+
uses: astral-sh/setup-uv@v10.1.0
|
|
28
|
+
|
|
29
|
+
- name: Set up Python
|
|
30
|
+
uses: actions/setup-python@v5
|
|
31
|
+
with:
|
|
32
|
+
python-version: ${{ matrix.python-version }}
|
|
33
|
+
|
|
34
|
+
- name: Sync dependencies
|
|
35
|
+
run: uv sync --locked --python ${{ matrix.python-version }}
|
|
36
|
+
|
|
37
|
+
- name: Ruff lint
|
|
38
|
+
run: uv run ruff check .
|
|
39
|
+
|
|
40
|
+
- name: Ruff format check
|
|
41
|
+
run: uv run ruff format --check .
|
|
42
|
+
|
|
43
|
+
- name: MyPy
|
|
44
|
+
run: uv run mypy
|
|
45
|
+
|
|
46
|
+
- name: Pytest
|
|
47
|
+
run: uv run pytest --cov=stepfork --cov-report=term-missing
|
|
48
|
+
|
|
49
|
+
- name: Build package
|
|
50
|
+
run: uv build
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["main"]
|
|
6
|
+
paths:
|
|
7
|
+
- "docs/**"
|
|
8
|
+
- "mkdocs.yml"
|
|
9
|
+
- "pyproject.toml"
|
|
10
|
+
- "uv.lock"
|
|
11
|
+
pull_request:
|
|
12
|
+
branches: ["main"]
|
|
13
|
+
paths:
|
|
14
|
+
- "docs/**"
|
|
15
|
+
- "mkdocs.yml"
|
|
16
|
+
workflow_dispatch:
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
build:
|
|
23
|
+
name: Build docs
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- name: Checkout
|
|
27
|
+
uses: actions/checkout@v4
|
|
28
|
+
|
|
29
|
+
- name: Install uv
|
|
30
|
+
uses: astral-sh/setup-uv@v10.1.0
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.12"
|
|
36
|
+
|
|
37
|
+
- name: Sync dependencies
|
|
38
|
+
run: uv sync --locked
|
|
39
|
+
|
|
40
|
+
- name: Build with MkDocs
|
|
41
|
+
run: uv run mkdocs build --strict
|
|
42
|
+
|
|
43
|
+
deploy:
|
|
44
|
+
name: Deploy to GitHub Pages
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
if: github.ref == 'refs/heads/main'
|
|
47
|
+
needs: build
|
|
48
|
+
environment:
|
|
49
|
+
name: github-pages
|
|
50
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
51
|
+
permissions:
|
|
52
|
+
contents: read
|
|
53
|
+
pages: write
|
|
54
|
+
id-token: write
|
|
55
|
+
steps:
|
|
56
|
+
- name: Checkout
|
|
57
|
+
uses: actions/checkout@v4
|
|
58
|
+
|
|
59
|
+
- name: Install uv
|
|
60
|
+
uses: astral-sh/setup-uv@v10.1.0
|
|
61
|
+
|
|
62
|
+
- name: Set up Python
|
|
63
|
+
uses: actions/setup-python@v5
|
|
64
|
+
with:
|
|
65
|
+
python-version: "3.12"
|
|
66
|
+
|
|
67
|
+
- name: Sync dependencies
|
|
68
|
+
run: uv sync --locked
|
|
69
|
+
|
|
70
|
+
- name: Build with MkDocs
|
|
71
|
+
run: uv run mkdocs build --strict
|
|
72
|
+
|
|
73
|
+
- name: Configure Pages
|
|
74
|
+
uses: actions/configure-pages@v5
|
|
75
|
+
|
|
76
|
+
- name: Upload artifact
|
|
77
|
+
uses: actions/upload-pages-artifact@v3
|
|
78
|
+
with:
|
|
79
|
+
path: site
|
|
80
|
+
|
|
81
|
+
- name: Deploy
|
|
82
|
+
id: deployment
|
|
83
|
+
uses: actions/deploy-pages@v4
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
# Publishes to PyPI using trusted publishing (OIDC). No API token is stored.
|
|
4
|
+
#
|
|
5
|
+
# This workflow runs ONLY when a GitHub Release is published. It has no
|
|
6
|
+
# workflow_dispatch trigger and never runs on pushes or pull requests, so
|
|
7
|
+
# untrusted code cannot reach the publishing credentials. The release tag must
|
|
8
|
+
# match the version in src/stepfork/version.py exactly, or the build job fails
|
|
9
|
+
# before the publish job starts.
|
|
10
|
+
#
|
|
11
|
+
# Prerequisites before the first publish (see docs/pypi-publishing.md):
|
|
12
|
+
# - a PyPI pending/trusted publisher for owner `utsab345`, repo `stepfork`,
|
|
13
|
+
# workflow `publish.yml`, environment `pypi`;
|
|
14
|
+
# - a GitHub environment named `pypi` (optionally with required reviewers).
|
|
15
|
+
|
|
16
|
+
on:
|
|
17
|
+
release:
|
|
18
|
+
types: [published]
|
|
19
|
+
|
|
20
|
+
permissions:
|
|
21
|
+
contents: read
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
build:
|
|
25
|
+
name: Build distributions
|
|
26
|
+
runs-on: ubuntu-latest
|
|
27
|
+
steps:
|
|
28
|
+
- name: Checkout
|
|
29
|
+
uses: actions/checkout@v4
|
|
30
|
+
|
|
31
|
+
- name: Install uv
|
|
32
|
+
uses: astral-sh/setup-uv@v10.1.0
|
|
33
|
+
|
|
34
|
+
- name: Build sdist and wheel
|
|
35
|
+
run: uv build
|
|
36
|
+
|
|
37
|
+
- name: Validate distributions
|
|
38
|
+
run: uvx twine check dist/*
|
|
39
|
+
|
|
40
|
+
- name: Verify version matches release tag
|
|
41
|
+
run: |
|
|
42
|
+
version=$(python3 -c "import pathlib,re; print(re.search(r'__version__\\s*=\\s*\"([^\"]+)\"', pathlib.Path('src/stepfork/version.py').read_text()).group(1))")
|
|
43
|
+
tag="${GITHUB_REF_NAME#v}"
|
|
44
|
+
if [ "${GITHUB_REF_TYPE}" != "tag" ]; then
|
|
45
|
+
echo "publish must run from a tag ref, got ${GITHUB_REF_TYPE}" >&2
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
if [ "$version" != "$tag" ]; then
|
|
49
|
+
echo "version.py ($version) does not match release tag ($tag)" >&2
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
- name: Upload distributions
|
|
54
|
+
uses: actions/upload-artifact@v4
|
|
55
|
+
with:
|
|
56
|
+
name: dist
|
|
57
|
+
path: dist/
|
|
58
|
+
|
|
59
|
+
publish:
|
|
60
|
+
name: Publish to PyPI
|
|
61
|
+
needs: build
|
|
62
|
+
runs-on: ubuntu-latest
|
|
63
|
+
environment:
|
|
64
|
+
name: pypi
|
|
65
|
+
url: https://pypi.org/p/stepfork
|
|
66
|
+
permissions:
|
|
67
|
+
id-token: write
|
|
68
|
+
steps:
|
|
69
|
+
- name: Download distributions
|
|
70
|
+
uses: actions/download-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: dist
|
|
73
|
+
path: dist/
|
|
74
|
+
|
|
75
|
+
- name: Publish to PyPI
|
|
76
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
|
|
7
|
+
# Virtual environments
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
env/
|
|
11
|
+
|
|
12
|
+
# Packaging
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
*.egg-info/
|
|
16
|
+
|
|
17
|
+
# Testing
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.coverage
|
|
20
|
+
.coverage.*
|
|
21
|
+
htmlcov/
|
|
22
|
+
.hypothesis/
|
|
23
|
+
|
|
24
|
+
# Type checking
|
|
25
|
+
.mypy_cache/
|
|
26
|
+
.pyright/
|
|
27
|
+
|
|
28
|
+
# Ruff
|
|
29
|
+
.ruff_cache/
|
|
30
|
+
|
|
31
|
+
# MkDocs build output
|
|
32
|
+
site/
|
|
33
|
+
.cache/
|
|
34
|
+
|
|
35
|
+
# IDEs
|
|
36
|
+
.vscode/
|
|
37
|
+
.idea/
|
|
38
|
+
|
|
39
|
+
# OS
|
|
40
|
+
.DS_Store
|
|
41
|
+
Thumbs.db
|
|
42
|
+
|
|
43
|
+
# Environment / secrets
|
|
44
|
+
.env
|
|
45
|
+
.env.*
|
|
46
|
+
!.env.example
|
|
47
|
+
|
|
48
|
+
# Stepfork local runtime data
|
|
49
|
+
.stepfork/
|
|
50
|
+
|
|
51
|
+
# Temporary trace artifacts
|
|
52
|
+
*.sftrace.tmp
|
|
53
|
+
|
|
54
|
+
# Generated demo artifacts
|
|
55
|
+
examples/booking_agent/.artifacts/
|
|
56
|
+
examples/refund_agent/.artifacts/
|
|
57
|
+
|
|
58
|
+
# Quickstart demo artifacts
|
|
59
|
+
examples/quickstart/.artifacts/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Stepfork are recorded here. The format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/), and this project adheres to
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [0.1.0a2] - 2026-10-09
|
|
8
|
+
|
|
9
|
+
First distribution published to PyPI, using GitHub Actions trusted publishing
|
|
10
|
+
(OpenID Connect) with no stored API token.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- PyPI packaging: install with `pip install --pre stepfork` (pre-release).
|
|
15
|
+
- Minimal quickstart example (`examples/quickstart/`) with an integration test
|
|
16
|
+
that turns a failing run into a pytest regression test.
|
|
17
|
+
- MkDocs documentation site (getting started, concepts, examples, CLI
|
|
18
|
+
reference, integrations, troubleshooting, record/replay/diff/export guides)
|
|
19
|
+
deployed to GitHub Pages.
|
|
20
|
+
- `docs/cli.md`, `docs/integrations.md`,
|
|
21
|
+
`docs/community/early-adopter-guide.md`, and `docs/pypi-publishing.md`.
|
|
22
|
+
- Trusted-publishing workflow (`.github/workflows/publish.yml`) and a docs
|
|
23
|
+
build/deploy workflow.
|
|
24
|
+
- Terminal demo (`scripts/terminal-demo/`) and a workflow diagram asset.
|
|
25
|
+
- `docs/examples.md` and `docs/troubleshooting.md`.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- README rewritten for newcomers: quickstart, installation, CLI, and
|
|
30
|
+
troubleshooting.
|
|
31
|
+
- Publishing runs only when a GitHub Release is published and its tag matches
|
|
32
|
+
`src/stepfork/version.py`; there is no manual trigger and no API token.
|
|
33
|
+
- CLI help text and docstrings no longer reference internal milestones.
|
|
34
|
+
|
|
35
|
+
[0.1.0a2]: https://github.com/utsab345/stepfork/releases/tag/v0.1.0a2
|
|
36
|
+
|
|
37
|
+
## [0.1.0a1] - 2026-10-09
|
|
38
|
+
|
|
39
|
+
Prepared for first public alpha.
|
|
40
|
+
|
|
41
|
+
### Added
|
|
42
|
+
|
|
43
|
+
- Second end-to-end example: `examples/refund_agent/` (buggy vs fixed refund
|
|
44
|
+
eligibility agent) with integration tests in
|
|
45
|
+
`tests/integration/test_refund_failure_to_test.py`.
|
|
46
|
+
- Hypothesis property tests for the behavioral diff engine
|
|
47
|
+
(`first_difference`/`values_equal` agreement, dict key-order independence).
|
|
48
|
+
- CLI error-path tests for `replay` and `export`.
|
|
49
|
+
- Expanded unit coverage for storage, diffing, JSON encoding, runtime replay
|
|
50
|
+
planning, and export runtime error paths.
|
|
51
|
+
- `CHANGELOG.md`, `docs/release-checklist.md`.
|
|
52
|
+
- Top-level `SECURITY.md` documenting the security model and a private
|
|
53
|
+
vulnerability-reporting path.
|
|
54
|
+
- `docs/releases/v0.1.0a1.md` with the public release notes.
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
- README documents installing directly from the public GitHub repository via
|
|
59
|
+
`pip`/`uv` (`git+https://...@v0.1.0a1`); PyPI install is not offered for the
|
|
60
|
+
alpha. The conceptual quickstart is labeled as a sketch and links to the
|
|
61
|
+
runnable demos.
|
|
62
|
+
|
|
63
|
+
- Version is now a single source of truth via hatchling dynamic versioning
|
|
64
|
+
(`[tool.hatch.version] path = "src/stepfork/version.py"`); bumped to
|
|
65
|
+
`0.1.0a1`.
|
|
66
|
+
- `src/stepfork/export/generator.py`: docstrings interpolated into generated
|
|
67
|
+
pytest files are collapsed, escaped, and length-limited, preventing hostile
|
|
68
|
+
trace metadata from breaking out of the generated module docstring.
|
|
69
|
+
- `src/stepfork/cli/inspect.py`: error output is sanitized before display,
|
|
70
|
+
matching diff, export, and replay.
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- Generated pytest tests no longer allow `"""`-containing trace names or
|
|
75
|
+
entrypoints to terminate the generated docstring early (regression test:
|
|
76
|
+
`test_generated_source_escapes_hostile_trace_name_and_entrypoint`).
|
|
77
|
+
- Inspect CLI surfaced unsanitized trace payloads in error messages.
|
|
78
|
+
|
|
79
|
+
### Security
|
|
80
|
+
|
|
81
|
+
- `docs/security.md` documents how to handle untrusted bundles: symlink
|
|
82
|
+
following, integrity not verified by default on replay/export, in-memory
|
|
83
|
+
payload loading, and redaction-at-record-time semantics.
|
|
84
|
+
|
|
85
|
+
[0.1.0a1]: https://github.com/utsab345/stepfork/releases/tag/v0.1.0a1
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Pledge
|
|
4
|
+
|
|
5
|
+
We as members, contributors, and leaders pledge to make participation in our
|
|
6
|
+
community a harassment-free experience for everyone, regardless of age, body
|
|
7
|
+
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
8
|
+
identity and expression, level of experience, education, socio-economic status,
|
|
9
|
+
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
10
|
+
identity and orientation.
|
|
11
|
+
|
|
12
|
+
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
13
|
+
diverse, inclusive, and healthy community.
|
|
14
|
+
|
|
15
|
+
## Our Standards
|
|
16
|
+
|
|
17
|
+
Examples of behavior that contributes to a positive environment for our
|
|
18
|
+
community include:
|
|
19
|
+
|
|
20
|
+
- Demonstrating empathy and kindness toward other people
|
|
21
|
+
- Being respectful of differing opinions, viewpoints, and experiences
|
|
22
|
+
- Giving and gracefully accepting constructive feedback
|
|
23
|
+
- Accepting responsibility and apologizing to those affected by our mistakes,
|
|
24
|
+
and learning from the experience
|
|
25
|
+
- Focusing on what is best not just for us as individuals, but for the overall
|
|
26
|
+
community
|
|
27
|
+
|
|
28
|
+
Examples of unacceptable behavior include:
|
|
29
|
+
|
|
30
|
+
- The use of sexualized language or imagery, and sexual attention or advances
|
|
31
|
+
of any kind
|
|
32
|
+
- Trolling, insulting or derogatory comments, and personal or political attacks
|
|
33
|
+
- Public or private harassment
|
|
34
|
+
- Publishing others' private information, such as a physical or email address,
|
|
35
|
+
without their explicit permission
|
|
36
|
+
- Other conduct which could reasonably be considered inappropriate in a
|
|
37
|
+
professional setting
|
|
38
|
+
|
|
39
|
+
## Enforcement Responsibilities
|
|
40
|
+
|
|
41
|
+
Community leaders are responsible for clarifying and enforcing our standards of
|
|
42
|
+
acceptable behavior and will take appropriate and fair corrective action in
|
|
43
|
+
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
44
|
+
or harmful.
|
|
45
|
+
|
|
46
|
+
Community leaders have the right and responsibility to remove, edit, or reject
|
|
47
|
+
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
48
|
+
not aligned to this Code of Conduct, and will communicate reasons for
|
|
49
|
+
moderation decisions when appropriate.
|
|
50
|
+
|
|
51
|
+
## Scope
|
|
52
|
+
|
|
53
|
+
This Code of Conduct applies within all community spaces, and also applies when
|
|
54
|
+
an individual is officially representing the community in public spaces.
|
|
55
|
+
Examples of representing our community include using an official email address,
|
|
56
|
+
posting via an official social media account, or acting as an appointed
|
|
57
|
+
representative at an online or offline event.
|
|
58
|
+
|
|
59
|
+
## Enforcement
|
|
60
|
+
|
|
61
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
62
|
+
reported to the GitHub repository maintainers. All complaints will be reviewed
|
|
63
|
+
and investigated promptly and fairly.
|
|
64
|
+
|
|
65
|
+
All community leaders are obligated to respect the privacy and security of the
|
|
66
|
+
reporter of any incident.
|
|
67
|
+
|
|
68
|
+
## Enforcement Guidelines
|
|
69
|
+
|
|
70
|
+
Community leaders will follow these Community Impact Guidelines in determining
|
|
71
|
+
the consequences for any action they deem in violation of this Code of Conduct:
|
|
72
|
+
|
|
73
|
+
### 1. Correction
|
|
74
|
+
|
|
75
|
+
Community Impact: Use of inappropriate language or other behavior deemed
|
|
76
|
+
unprofessional or unwelcome in the community.
|
|
77
|
+
|
|
78
|
+
Consequence: A private, written warning from community leaders, providing
|
|
79
|
+
clarity around the nature of the violation and an explanation of why the
|
|
80
|
+
behavior was inappropriate. A public apology may be requested.
|
|
81
|
+
|
|
82
|
+
### 2. Warning
|
|
83
|
+
|
|
84
|
+
Community Impact: A violation through a single incident or series of actions.
|
|
85
|
+
|
|
86
|
+
Consequence: A warning with consequences for continued behavior. No interaction
|
|
87
|
+
with the people involved, including unsolicited interaction with those enforcing
|
|
88
|
+
the Code of Conduct, for a specified period of time. This includes avoiding
|
|
89
|
+
interactions in community spaces as well as external channels like social
|
|
90
|
+
media. Violating these terms may lead to a temporary or permanent ban.
|
|
91
|
+
|
|
92
|
+
### 3. Temporary Ban
|
|
93
|
+
|
|
94
|
+
Community Impact: A serious violation of community standards, including
|
|
95
|
+
sustained inappropriate behavior.
|
|
96
|
+
|
|
97
|
+
Consequence: A temporary ban from any sort of interaction or public
|
|
98
|
+
communication with the community for a specified period of time. No public or
|
|
99
|
+
private interaction with the people involved, including unsolicited interaction
|
|
100
|
+
with those enforcing the Code of Conduct, is allowed during this period.
|
|
101
|
+
Violating these terms may lead to a permanent ban.
|
|
102
|
+
|
|
103
|
+
### 4. Permanent Ban
|
|
104
|
+
|
|
105
|
+
Community Impact: Demonstrating a pattern of violation of community standards,
|
|
106
|
+
including sustained inappropriate behavior, harassment of an individual, or
|
|
107
|
+
aggression toward or disparagement of classes of individuals.
|
|
108
|
+
|
|
109
|
+
Consequence: A permanent ban from any sort of public interaction within the
|
|
110
|
+
community.
|
|
111
|
+
|
|
112
|
+
## Attribution
|
|
113
|
+
|
|
114
|
+
This Code of Conduct is adapted from the Contributor Covenant, version 2.1,
|
|
115
|
+
available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
|
|
116
|
+
|
|
117
|
+
Community Impact Guidelines were inspired by Mozilla's code of conduct
|
|
118
|
+
enforcement ladder.
|