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.
Files changed (171) hide show
  1. stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/bug_report.yml +52 -0
  2. stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/config.yml +11 -0
  3. stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/documentation.yml +32 -0
  4. stepfork-0.1.0a2/.github/ISSUE_TEMPLATE/feature_request.yml +32 -0
  5. stepfork-0.1.0a2/.github/pull_request_template.md +15 -0
  6. stepfork-0.1.0a2/.github/workflows/ci.yml +50 -0
  7. stepfork-0.1.0a2/.github/workflows/docs.yml +83 -0
  8. stepfork-0.1.0a2/.github/workflows/publish.yml +76 -0
  9. stepfork-0.1.0a2/.gitignore +59 -0
  10. stepfork-0.1.0a2/.python-version +1 -0
  11. stepfork-0.1.0a2/CHANGELOG.md +85 -0
  12. stepfork-0.1.0a2/CODE_OF_CONDUCT.md +118 -0
  13. stepfork-0.1.0a2/CONTRIBUTING.md +100 -0
  14. stepfork-0.1.0a2/LICENSE +184 -0
  15. stepfork-0.1.0a2/PKG-INFO +377 -0
  16. stepfork-0.1.0a2/README.md +352 -0
  17. stepfork-0.1.0a2/SECURITY.md +47 -0
  18. stepfork-0.1.0a2/assets/stepfork-logo.png +0 -0
  19. stepfork-0.1.0a2/assets/stepfork-workflow.png +0 -0
  20. stepfork-0.1.0a2/docs/.gitkeep +0 -0
  21. stepfork-0.1.0a2/docs/architecture.md +96 -0
  22. stepfork-0.1.0a2/docs/assets/stepfork-logo.png +0 -0
  23. stepfork-0.1.0a2/docs/cli.md +348 -0
  24. stepfork-0.1.0a2/docs/community/early-adopter-guide.md +144 -0
  25. stepfork-0.1.0a2/docs/concepts.md +104 -0
  26. stepfork-0.1.0a2/docs/development.md +106 -0
  27. stepfork-0.1.0a2/docs/diff.md +46 -0
  28. stepfork-0.1.0a2/docs/examples.md +67 -0
  29. stepfork-0.1.0a2/docs/getting-started.md +132 -0
  30. stepfork-0.1.0a2/docs/index.md +73 -0
  31. stepfork-0.1.0a2/docs/integrations.md +87 -0
  32. stepfork-0.1.0a2/docs/pypi-publishing.md +118 -0
  33. stepfork-0.1.0a2/docs/pytest-export.md +80 -0
  34. stepfork-0.1.0a2/docs/recording.md +104 -0
  35. stepfork-0.1.0a2/docs/release-checklist.md +59 -0
  36. stepfork-0.1.0a2/docs/releases/v0.1.0a1.md +83 -0
  37. stepfork-0.1.0a2/docs/releases/v0.1.0a2.md +100 -0
  38. stepfork-0.1.0a2/docs/replay.md +65 -0
  39. stepfork-0.1.0a2/docs/security.md +87 -0
  40. stepfork-0.1.0a2/docs/trace-format.md +88 -0
  41. stepfork-0.1.0a2/docs/troubleshooting.md +121 -0
  42. stepfork-0.1.0a2/examples/__init__.py +1 -0
  43. stepfork-0.1.0a2/examples/booking_agent/__init__.py +30 -0
  44. stepfork-0.1.0a2/examples/booking_agent/agent.py +111 -0
  45. stepfork-0.1.0a2/examples/booking_agent/demo.py +268 -0
  46. stepfork-0.1.0a2/examples/booking_agent/expected.json +5 -0
  47. stepfork-0.1.0a2/examples/quickstart/README.md +54 -0
  48. stepfork-0.1.0a2/examples/quickstart/__init__.py +24 -0
  49. stepfork-0.1.0a2/examples/quickstart/agent.py +76 -0
  50. stepfork-0.1.0a2/examples/quickstart/demo.py +256 -0
  51. stepfork-0.1.0a2/examples/quickstart/expected.json +1 -0
  52. stepfork-0.1.0a2/examples/refund_agent/__init__.py +30 -0
  53. stepfork-0.1.0a2/examples/refund_agent/agent.py +161 -0
  54. stepfork-0.1.0a2/examples/refund_agent/demo.py +268 -0
  55. stepfork-0.1.0a2/examples/refund_agent/expected.json +7 -0
  56. stepfork-0.1.0a2/mkdocs.yml +49 -0
  57. stepfork-0.1.0a2/pyproject.toml +135 -0
  58. stepfork-0.1.0a2/scripts/terminal-demo/README.md +49 -0
  59. stepfork-0.1.0a2/scripts/terminal-demo/stepfork-demo.gif +0 -0
  60. stepfork-0.1.0a2/scripts/terminal-demo/stepfork-demo.tape +36 -0
  61. stepfork-0.1.0a2/src/stepfork/__init__.py +32 -0
  62. stepfork-0.1.0a2/src/stepfork/__main__.py +6 -0
  63. stepfork-0.1.0a2/src/stepfork/cli/__init__.py +1 -0
  64. stepfork-0.1.0a2/src/stepfork/cli/diff.py +156 -0
  65. stepfork-0.1.0a2/src/stepfork/cli/export.py +210 -0
  66. stepfork-0.1.0a2/src/stepfork/cli/inspect.py +155 -0
  67. stepfork-0.1.0a2/src/stepfork/cli/main.py +54 -0
  68. stepfork-0.1.0a2/src/stepfork/cli/replay.py +221 -0
  69. stepfork-0.1.0a2/src/stepfork/cli/validate.py +160 -0
  70. stepfork-0.1.0a2/src/stepfork/diff/__init__.py +25 -0
  71. stepfork-0.1.0a2/src/stepfork/diff/compare.py +144 -0
  72. stepfork-0.1.0a2/src/stepfork/diff/engine.py +267 -0
  73. stepfork-0.1.0a2/src/stepfork/diff/models.py +63 -0
  74. stepfork-0.1.0a2/src/stepfork/export/__init__.py +20 -0
  75. stepfork-0.1.0a2/src/stepfork/export/entrypoint.py +58 -0
  76. stepfork-0.1.0a2/src/stepfork/export/generator.py +178 -0
  77. stepfork-0.1.0a2/src/stepfork/export/runtime.py +101 -0
  78. stepfork-0.1.0a2/src/stepfork/fork/__init__.py +4 -0
  79. stepfork-0.1.0a2/src/stepfork/inspect/__init__.py +11 -0
  80. stepfork-0.1.0a2/src/stepfork/inspect/inspector.py +143 -0
  81. stepfork-0.1.0a2/src/stepfork/inspect/models.py +42 -0
  82. stepfork-0.1.0a2/src/stepfork/minimize/__init__.py +4 -0
  83. stepfork-0.1.0a2/src/stepfork/py.typed +0 -0
  84. stepfork-0.1.0a2/src/stepfork/recorder/__init__.py +21 -0
  85. stepfork-0.1.0a2/src/stepfork/recorder/llm.py +68 -0
  86. stepfork-0.1.0a2/src/stepfork/recorder/session.py +500 -0
  87. stepfork-0.1.0a2/src/stepfork/recorder/tooling.py +208 -0
  88. stepfork-0.1.0a2/src/stepfork/replay/__init__.py +32 -0
  89. stepfork-0.1.0a2/src/stepfork/replay/exceptions.py +37 -0
  90. stepfork-0.1.0a2/src/stepfork/replay/plan.py +282 -0
  91. stepfork-0.1.0a2/src/stepfork/replay/session.py +338 -0
  92. stepfork-0.1.0a2/src/stepfork/trace/__init__.py +115 -0
  93. stepfork-0.1.0a2/src/stepfork/trace/canonical.py +55 -0
  94. stepfork-0.1.0a2/src/stepfork/trace/hashing.py +75 -0
  95. stepfork-0.1.0a2/src/stepfork/trace/integrity.py +196 -0
  96. stepfork-0.1.0a2/src/stepfork/trace/jsonable.py +97 -0
  97. stepfork-0.1.0a2/src/stepfork/trace/manifest.py +85 -0
  98. stepfork-0.1.0a2/src/stepfork/trace/models.py +271 -0
  99. stepfork-0.1.0a2/src/stepfork/trace/redaction.py +294 -0
  100. stepfork-0.1.0a2/src/stepfork/trace/replay_policy.py +18 -0
  101. stepfork-0.1.0a2/src/stepfork/trace/schema.py +25 -0
  102. stepfork-0.1.0a2/src/stepfork/trace/storage.py +250 -0
  103. stepfork-0.1.0a2/src/stepfork/trace/validation.py +285 -0
  104. stepfork-0.1.0a2/src/stepfork/version.py +5 -0
  105. stepfork-0.1.0a2/tests/golden/.gitkeep +0 -0
  106. stepfork-0.1.0a2/tests/golden/README.md +17 -0
  107. stepfork-0.1.0a2/tests/golden/build_fixtures.py +72 -0
  108. stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/events.jsonl +4 -0
  109. stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/integrity.json +9 -0
  110. stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/manifest.json +21 -0
  111. stepfork-0.1.0a2/tests/golden/diff_baseline.sftrace/redactions.json +4 -0
  112. stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/events.jsonl +4 -0
  113. stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/integrity.json +9 -0
  114. stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/manifest.json +21 -0
  115. stepfork-0.1.0a2/tests/golden/diff_changed.sftrace/redactions.json +4 -0
  116. stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/events.jsonl +4 -0
  117. stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/integrity.json +9 -0
  118. stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/manifest.json +25 -0
  119. stepfork-0.1.0a2/tests/golden/failed_llm_run.sftrace/redactions.json +4 -0
  120. stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/events.jsonl +5 -0
  121. stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/integrity.json +9 -0
  122. stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/manifest.json +25 -0
  123. stepfork-0.1.0a2/tests/golden/failed_tool_run.sftrace/redactions.json +11 -0
  124. stepfork-0.1.0a2/tests/golden/legacy_v01.sftrace/events.jsonl +2 -0
  125. stepfork-0.1.0a2/tests/golden/legacy_v01.sftrace/manifest.json +21 -0
  126. stepfork-0.1.0a2/tests/golden/legacy_v01.sftrace/redactions.json +4 -0
  127. stepfork-0.1.0a2/tests/golden/partial_run.sftrace/events.jsonl +1 -0
  128. stepfork-0.1.0a2/tests/golden/partial_run.sftrace/integrity.json +9 -0
  129. stepfork-0.1.0a2/tests/golden/partial_run.sftrace/manifest.json +21 -0
  130. stepfork-0.1.0a2/tests/golden/partial_run.sftrace/redactions.json +4 -0
  131. stepfork-0.1.0a2/tests/golden/successful_run.sftrace/events.jsonl +6 -0
  132. stepfork-0.1.0a2/tests/golden/successful_run.sftrace/integrity.json +9 -0
  133. stepfork-0.1.0a2/tests/golden/successful_run.sftrace/manifest.json +21 -0
  134. stepfork-0.1.0a2/tests/golden/successful_run.sftrace/redactions.json +4 -0
  135. stepfork-0.1.0a2/tests/integration/.gitkeep +0 -0
  136. stepfork-0.1.0a2/tests/integration/test_docs_assets.py +52 -0
  137. stepfork-0.1.0a2/tests/integration/test_failure_to_test.py +137 -0
  138. stepfork-0.1.0a2/tests/integration/test_golden_fixtures.py +120 -0
  139. stepfork-0.1.0a2/tests/integration/test_quickstart_failure_to_test.py +127 -0
  140. stepfork-0.1.0a2/tests/integration/test_refund_failure_to_test.py +140 -0
  141. stepfork-0.1.0a2/tests/integration/test_secure_trace_roundtrip.py +144 -0
  142. stepfork-0.1.0a2/tests/integration/test_trace_infrastructure_flow.py +124 -0
  143. stepfork-0.1.0a2/tests/integration/test_trace_roundtrip.py +59 -0
  144. stepfork-0.1.0a2/tests/property/.gitkeep +0 -0
  145. stepfork-0.1.0a2/tests/property/test_trace_properties.py +98 -0
  146. stepfork-0.1.0a2/tests/unit/test_canonical.py +61 -0
  147. stepfork-0.1.0a2/tests/unit/test_cli.py +27 -0
  148. stepfork-0.1.0a2/tests/unit/test_cli_diff.py +67 -0
  149. stepfork-0.1.0a2/tests/unit/test_cli_export.py +272 -0
  150. stepfork-0.1.0a2/tests/unit/test_cli_inspect.py +135 -0
  151. stepfork-0.1.0a2/tests/unit/test_cli_replay.py +233 -0
  152. stepfork-0.1.0a2/tests/unit/test_cli_validate.py +133 -0
  153. stepfork-0.1.0a2/tests/unit/test_diff.py +210 -0
  154. stepfork-0.1.0a2/tests/unit/test_export.py +350 -0
  155. stepfork-0.1.0a2/tests/unit/test_hashing.py +84 -0
  156. stepfork-0.1.0a2/tests/unit/test_inspector.py +147 -0
  157. stepfork-0.1.0a2/tests/unit/test_integrity.py +158 -0
  158. stepfork-0.1.0a2/tests/unit/test_invalid_bundles.py +121 -0
  159. stepfork-0.1.0a2/tests/unit/test_jsonable.py +49 -0
  160. stepfork-0.1.0a2/tests/unit/test_llm_request.py +151 -0
  161. stepfork-0.1.0a2/tests/unit/test_manifest.py +118 -0
  162. stepfork-0.1.0a2/tests/unit/test_recording_session.py +243 -0
  163. stepfork-0.1.0a2/tests/unit/test_redaction.py +127 -0
  164. stepfork-0.1.0a2/tests/unit/test_replay_plan.py +117 -0
  165. stepfork-0.1.0a2/tests/unit/test_replay_tool.py +269 -0
  166. stepfork-0.1.0a2/tests/unit/test_schema.py +42 -0
  167. stepfork-0.1.0a2/tests/unit/test_storage.py +333 -0
  168. stepfork-0.1.0a2/tests/unit/test_trace_models.py +310 -0
  169. stepfork-0.1.0a2/tests/unit/test_trace_tool.py +124 -0
  170. stepfork-0.1.0a2/tests/unit/test_validation.py +196 -0
  171. 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.