planlens-agent 0.1.0__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.
- planlens_agent-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +17 -0
- planlens_agent-0.1.0/.github/workflows/ci.yml +140 -0
- planlens_agent-0.1.0/.github/workflows/consumer-demo.yml +115 -0
- planlens_agent-0.1.0/.github/workflows/publish.yml +104 -0
- planlens_agent-0.1.0/.gitignore +10 -0
- planlens_agent-0.1.0/AUTHORS.md +21 -0
- planlens_agent-0.1.0/CHANGELOG.md +177 -0
- planlens_agent-0.1.0/CONTRIBUTING.md +57 -0
- planlens_agent-0.1.0/LICENSE +202 -0
- planlens_agent-0.1.0/NOTICE +15 -0
- planlens_agent-0.1.0/PKG-INFO +85 -0
- planlens_agent-0.1.0/PROVENANCE.md +103 -0
- planlens_agent-0.1.0/README.md +196 -0
- planlens_agent-0.1.0/README.pypi.md +64 -0
- planlens_agent-0.1.0/docs/README.md +20 -0
- planlens_agent-0.1.0/docs/acceptance-examples.md +41 -0
- planlens_agent-0.1.0/docs/brand/README.md +26 -0
- planlens_agent-0.1.0/docs/brand/planlens-mark-dark.svg +6 -0
- planlens_agent-0.1.0/docs/brand/planlens-mark-light.svg +6 -0
- planlens_agent-0.1.0/docs/brand/planlens-mark-mono-dark.svg +6 -0
- planlens_agent-0.1.0/docs/brand/planlens-mark-mono-light.svg +6 -0
- planlens_agent-0.1.0/docs/brand/planlens-wordmark-dark.svg +9 -0
- planlens_agent-0.1.0/docs/brand/planlens-wordmark-light.svg +9 -0
- planlens_agent-0.1.0/docs/brand/planlens-wordmark-mono-dark.svg +9 -0
- planlens_agent-0.1.0/docs/brand/planlens-wordmark-mono-light.svg +9 -0
- planlens_agent-0.1.0/docs/ci.md +122 -0
- planlens_agent-0.1.0/docs/developer-rehearsal.md +79 -0
- planlens_agent-0.1.0/docs/evidence.md +49 -0
- planlens_agent-0.1.0/docs/inspector.md +110 -0
- planlens_agent-0.1.0/docs/integration.md +96 -0
- planlens_agent-0.1.0/docs/media/demo-narrow.gif +0 -0
- planlens_agent-0.1.0/docs/media/demo-narrow.png +0 -0
- planlens_agent-0.1.0/docs/media/demo-transcript.txt +58 -0
- planlens_agent-0.1.0/docs/media/demo.gif +0 -0
- planlens_agent-0.1.0/docs/media/demo.png +0 -0
- planlens_agent-0.1.0/docs/media/inspector-finding-light.png +0 -0
- planlens_agent-0.1.0/docs/media/inspector-finding-narrow-light.png +0 -0
- planlens_agent-0.1.0/docs/media/inspector-finding-narrow.png +0 -0
- planlens_agent-0.1.0/docs/media/inspector-finding.png +0 -0
- planlens_agent-0.1.0/docs/media/inspector-light.png +0 -0
- planlens_agent-0.1.0/docs/media/inspector.png +0 -0
- planlens_agent-0.1.0/docs/media/social-preview.png +0 -0
- planlens_agent-0.1.0/docs/naming.md +46 -0
- planlens_agent-0.1.0/docs/quickstart.md +213 -0
- planlens_agent-0.1.0/docs/rules.md +358 -0
- planlens_agent-0.1.0/docs/sarif.md +84 -0
- planlens_agent-0.1.0/docs/semantics.md +280 -0
- planlens_agent-0.1.0/docs/suites.md +215 -0
- planlens_agent-0.1.0/examples/README.md +12 -0
- planlens_agent-0.1.0/examples/guarded_runner.py +49 -0
- planlens_agent-0.1.0/examples/langgraph_gate/README.md +70 -0
- planlens_agent-0.1.0/examples/langgraph_gate/gate.py +195 -0
- planlens_agent-0.1.0/examples/langgraph_gate/requirements.in +8 -0
- planlens_agent-0.1.0/examples/langgraph_gate/requirements.lock +1233 -0
- planlens_agent-0.1.0/examples/langgraph_gate/test_gate.py +313 -0
- planlens_agent-0.1.0/examples/sdk_check.py +34 -0
- planlens_agent-0.1.0/pyproject.toml +83 -0
- planlens_agent-0.1.0/release/NOTES_0.1.0.md +37 -0
- planlens_agent-0.1.0/release/PUBLISHING.md +201 -0
- planlens_agent-0.1.0/scripts/browser_check.py +382 -0
- planlens_agent-0.1.0/scripts/ci_gate.py +304 -0
- planlens_agent-0.1.0/scripts/ci_local.py +282 -0
- planlens_agent-0.1.0/scripts/docs_check.py +312 -0
- planlens_agent-0.1.0/scripts/gen_acceptance_doc.py +66 -0
- planlens_agent-0.1.0/scripts/gen_rule_docs.py +66 -0
- planlens_agent-0.1.0/scripts/journey.py +259 -0
- planlens_agent-0.1.0/scripts/make_demo_media.py +658 -0
- planlens_agent-0.1.0/scripts/make_pilot_package.py +108 -0
- planlens_agent-0.1.0/scripts/make_review_zip.py +125 -0
- planlens_agent-0.1.0/scripts/make_samples.py +162 -0
- planlens_agent-0.1.0/scripts/release_check.py +253 -0
- planlens_agent-0.1.0/src/planlens_agent/__init__.py +56 -0
- planlens_agent-0.1.0/src/planlens_agent/_version.py +1 -0
- planlens_agent-0.1.0/src/planlens_agent/approval.py +75 -0
- planlens_agent-0.1.0/src/planlens_agent/checker.py +408 -0
- planlens_agent-0.1.0/src/planlens_agent/cli.py +479 -0
- planlens_agent-0.1.0/src/planlens_agent/compare.py +497 -0
- planlens_agent-0.1.0/src/planlens_agent/diagnostics.py +426 -0
- planlens_agent-0.1.0/src/planlens_agent/fixtures.py +172 -0
- planlens_agent-0.1.0/src/planlens_agent/inspector/__init__.py +681 -0
- planlens_agent-0.1.0/src/planlens_agent/inspector/inspector.css +272 -0
- planlens_agent-0.1.0/src/planlens_agent/inspector/inspector.js +88 -0
- planlens_agent-0.1.0/src/planlens_agent/loading.py +442 -0
- planlens_agent-0.1.0/src/planlens_agent/plan.py +371 -0
- planlens_agent-0.1.0/src/planlens_agent/policy.py +759 -0
- planlens_agent-0.1.0/src/planlens_agent/py.typed +0 -0
- planlens_agent-0.1.0/src/planlens_agent/report.py +198 -0
- planlens_agent-0.1.0/src/planlens_agent/runner.py +174 -0
- planlens_agent-0.1.0/src/planlens_agent/sarif.py +318 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/catalog.v1.schema.json +71 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/contract.v1.schema.json +127 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/fixtures.v1.schema.json +66 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/plan.v1.schema.json +66 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/report.v1.schema.json +289 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/run-diff.v1.schema.json +365 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/run.v1.schema.json +471 -0
- planlens_agent-0.1.0/src/planlens_agent/schemas/suite.v1.schema.json +76 -0
- planlens_agent-0.1.0/src/planlens_agent/suite.py +691 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/README.md +102 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v1/expedite.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v1/hotfix.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v1/legacy.json +35 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v1/standard-1.json +35 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v1/standard-2.json +35 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v2/expedite.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v2/hotfix.json +35 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v2/legacy.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v2/standard-1.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v2/standard-2.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v3/expedite.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v3/hotfix.json +35 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v3/legacy.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v3/standard-1.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/candidates/v3/standard-2.json +39 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/catalog.toml +36 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/contract.toml +46 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/fixtures.toml +33 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/plans/artifact-mismatch.json +12 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/plans/reversed-review.json +11 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/plans/valid-alternate-order.json +11 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/plans/valid.json +12 -0
- planlens_agent-0.1.0/src/planlens_agent/templates/release_basic/suite.toml +33 -0
- planlens_agent-0.1.0/src/planlens_agent/view_model.py +323 -0
- planlens_agent-0.1.0/tests/acceptance/cases.toml +158 -0
- planlens_agent-0.1.0/tests/acceptance/contracts/catalog-mismatch.toml +46 -0
- planlens_agent-0.1.0/tests/acceptance/contracts/cyclic.toml +53 -0
- planlens_agent-0.1.0/tests/acceptance/contracts/unknown-action.toml +46 -0
- planlens_agent-0.1.0/tests/acceptance/contracts/unsupported-rule.toml +53 -0
- planlens_agent-0.1.0/tests/acceptance/plans/compound.json +11 -0
- planlens_agent-0.1.0/tests/acceptance/plans/duplicate-step-id.json +10 -0
- planlens_agent-0.1.0/tests/acceptance/plans/malformed.json +7 -0
- planlens_agent-0.1.0/tests/acceptance/plans/policy-override.json +12 -0
- planlens_agent-0.1.0/tests/acceptance/plans/reference-before-producer.json +10 -0
- planlens_agent-0.1.0/tests/acceptance/plans/unresolved-reference.json +10 -0
- planlens_agent-0.1.0/tests/acceptance/plans/unsupported-semantics.json +11 -0
- planlens_agent-0.1.0/tests/conftest.py +5 -0
- planlens_agent-0.1.0/tests/data/sarif/NOTICE.md +32 -0
- planlens_agent-0.1.0/tests/data/sarif/sarif-schema-2.1.0.json +3389 -0
- planlens_agent-0.1.0/tests/helpers.py +82 -0
- planlens_agent-0.1.0/tests/test_acceptance.py +119 -0
- planlens_agent-0.1.0/tests/test_ci_files.py +176 -0
- planlens_agent-0.1.0/tests/test_ci_gate.py +755 -0
- planlens_agent-0.1.0/tests/test_cli.py +197 -0
- planlens_agent-0.1.0/tests/test_compare.py +589 -0
- planlens_agent-0.1.0/tests/test_determinism.py +67 -0
- planlens_agent-0.1.0/tests/test_docs.py +616 -0
- planlens_agent-0.1.0/tests/test_inputs.py +707 -0
- planlens_agent-0.1.0/tests/test_inspector.py +757 -0
- planlens_agent-0.1.0/tests/test_integrity.py +219 -0
- planlens_agent-0.1.0/tests/test_output_protection.py +310 -0
- planlens_agent-0.1.0/tests/test_reference_semantics.py +237 -0
- planlens_agent-0.1.0/tests/test_release.py +181 -0
- planlens_agent-0.1.0/tests/test_rule_docs.py +37 -0
- planlens_agent-0.1.0/tests/test_runner.py +248 -0
- planlens_agent-0.1.0/tests/test_sarif.py +470 -0
- planlens_agent-0.1.0/tests/test_schemas.py +131 -0
- planlens_agent-0.1.0/tests/test_semantics.py +139 -0
- planlens_agent-0.1.0/tests/test_suite.py +527 -0
- planlens_agent-0.1.0/uv.lock +276 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug report
|
|
3
|
+
about: A wrong verdict, a crash or instructions that do not work
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
**Version:** output of `planlens-agent --version`
|
|
7
|
+
|
|
8
|
+
**Python and operating system:**
|
|
9
|
+
|
|
10
|
+
**Exact command and exit status:**
|
|
11
|
+
|
|
12
|
+
**Smallest catalog, contract and plan that show the problem:**
|
|
13
|
+
<!-- Remove credentials and anything confidential. -->
|
|
14
|
+
|
|
15
|
+
**What you expected, and which rule should or should not have applied:**
|
|
16
|
+
|
|
17
|
+
**Full output:**
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Runs the same stages as `python scripts/ci_local.py`. No secrets and no model calls.
|
|
2
|
+
name: CI
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
push:
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
lint:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 15
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
20
|
+
with:
|
|
21
|
+
version: "0.12.3"
|
|
22
|
+
enable-cache: false
|
|
23
|
+
- run: uv run --no-project --python 3.14 scripts/ci_local.py lint --python 3.14
|
|
24
|
+
|
|
25
|
+
test:
|
|
26
|
+
strategy:
|
|
27
|
+
fail-fast: false
|
|
28
|
+
matrix:
|
|
29
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
30
|
+
python: ["3.11", "3.12", "3.13", "3.14"]
|
|
31
|
+
runs-on: ${{ matrix.os }}
|
|
32
|
+
timeout-minutes: 20
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
35
|
+
with:
|
|
36
|
+
persist-credentials: false
|
|
37
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
38
|
+
with:
|
|
39
|
+
version: "0.12.3"
|
|
40
|
+
enable-cache: false
|
|
41
|
+
- run: uv run --no-project --python ${{ matrix.python }} scripts/ci_local.py test --python ${{ matrix.python }}
|
|
42
|
+
|
|
43
|
+
package:
|
|
44
|
+
strategy:
|
|
45
|
+
fail-fast: false
|
|
46
|
+
matrix:
|
|
47
|
+
python: ["3.11", "3.14"]
|
|
48
|
+
runs-on: ubuntu-latest
|
|
49
|
+
timeout-minutes: 20
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
52
|
+
with:
|
|
53
|
+
persist-credentials: false
|
|
54
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
55
|
+
with:
|
|
56
|
+
version: "0.12.3"
|
|
57
|
+
enable-cache: false
|
|
58
|
+
- run: uv run --no-project --python ${{ matrix.python }} scripts/ci_local.py package --python ${{ matrix.python }}
|
|
59
|
+
|
|
60
|
+
journey:
|
|
61
|
+
strategy:
|
|
62
|
+
fail-fast: false
|
|
63
|
+
matrix:
|
|
64
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
65
|
+
runs-on: ${{ matrix.os }}
|
|
66
|
+
timeout-minutes: 15
|
|
67
|
+
steps:
|
|
68
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
69
|
+
with:
|
|
70
|
+
persist-credentials: false
|
|
71
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
72
|
+
with:
|
|
73
|
+
version: "0.12.3"
|
|
74
|
+
enable-cache: false
|
|
75
|
+
- run: uv run --no-project --python 3.14 scripts/ci_local.py journey --python 3.14 --log journey.log
|
|
76
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
77
|
+
if: always()
|
|
78
|
+
with:
|
|
79
|
+
name: journey-${{ matrix.os }}
|
|
80
|
+
path: journey.log
|
|
81
|
+
if-no-files-found: warn
|
|
82
|
+
|
|
83
|
+
recipe:
|
|
84
|
+
strategy:
|
|
85
|
+
fail-fast: false
|
|
86
|
+
matrix:
|
|
87
|
+
python: ["3.11", "3.14"]
|
|
88
|
+
runs-on: ubuntu-latest
|
|
89
|
+
timeout-minutes: 15
|
|
90
|
+
steps:
|
|
91
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
92
|
+
with:
|
|
93
|
+
persist-credentials: false
|
|
94
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
95
|
+
with:
|
|
96
|
+
version: "0.12.3"
|
|
97
|
+
enable-cache: false
|
|
98
|
+
- run: uv run --no-project --python ${{ matrix.python }} scripts/ci_local.py recipe --python ${{ matrix.python }} --log recipe-journey.log
|
|
99
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
100
|
+
if: always()
|
|
101
|
+
with:
|
|
102
|
+
name: recipe-journey-${{ matrix.python }}
|
|
103
|
+
path: recipe-journey.log
|
|
104
|
+
if-no-files-found: warn
|
|
105
|
+
|
|
106
|
+
pilot:
|
|
107
|
+
strategy:
|
|
108
|
+
fail-fast: false
|
|
109
|
+
matrix:
|
|
110
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
111
|
+
python: ["3.11", "3.14"]
|
|
112
|
+
runs-on: ${{ matrix.os }}
|
|
113
|
+
timeout-minutes: 15
|
|
114
|
+
steps:
|
|
115
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
116
|
+
with:
|
|
117
|
+
persist-credentials: false
|
|
118
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
119
|
+
with:
|
|
120
|
+
version: "0.12.3"
|
|
121
|
+
enable-cache: false
|
|
122
|
+
- run: uv run --no-project --python ${{ matrix.python }} scripts/ci_local.py pilot --python ${{ matrix.python }}
|
|
123
|
+
|
|
124
|
+
docs:
|
|
125
|
+
strategy:
|
|
126
|
+
fail-fast: false
|
|
127
|
+
matrix:
|
|
128
|
+
os: [ubuntu-latest, macos-latest]
|
|
129
|
+
python: ["3.11", "3.14"]
|
|
130
|
+
runs-on: ${{ matrix.os }}
|
|
131
|
+
timeout-minutes: 15
|
|
132
|
+
steps:
|
|
133
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
134
|
+
with:
|
|
135
|
+
persist-credentials: false
|
|
136
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
137
|
+
with:
|
|
138
|
+
version: "0.12.3"
|
|
139
|
+
enable-cache: false
|
|
140
|
+
- run: uv run --no-project --python ${{ matrix.python }} scripts/ci_local.py docs --python ${{ matrix.python }}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Shows the gate as a consumer would use it. Started by hand only.
|
|
2
|
+
#
|
|
3
|
+
# `reject-demo` and `sarif-demo` FAIL ON PURPOSE: the candidates break the contract, and the
|
|
4
|
+
# gate's failing status is kept. A red run of this workflow is the expected result.
|
|
5
|
+
# Every plan is an authored example. The baselines here are generated inside the job so the
|
|
6
|
+
# demo stands alone; a real baseline is an owner-reviewed file. See docs/ci.md.
|
|
7
|
+
name: Consumer demo
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
pass-demo:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
timeout-minutes: 10
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
21
|
+
with:
|
|
22
|
+
persist-credentials: false
|
|
23
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
24
|
+
with:
|
|
25
|
+
version: "0.12.3"
|
|
26
|
+
enable-cache: false
|
|
27
|
+
- name: Install the built wheel
|
|
28
|
+
run: |
|
|
29
|
+
uv build --wheel --out-dir wheel
|
|
30
|
+
uv venv --python 3.14 demo
|
|
31
|
+
uv pip install --python demo/bin/python --no-deps wheel/*.whl
|
|
32
|
+
demo/bin/planlens-agent init release-basic project
|
|
33
|
+
- name: Gate on passing candidates
|
|
34
|
+
working-directory: project
|
|
35
|
+
run: ../demo/bin/planlens-agent suite run suite.toml --plans-dir candidates/v3 --output candidate.run.json
|
|
36
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
37
|
+
if: always()
|
|
38
|
+
with:
|
|
39
|
+
name: pass-demo-run
|
|
40
|
+
path: project/*.run.json
|
|
41
|
+
if-no-files-found: warn
|
|
42
|
+
|
|
43
|
+
reject-demo:
|
|
44
|
+
runs-on: ubuntu-latest
|
|
45
|
+
timeout-minutes: 10
|
|
46
|
+
steps:
|
|
47
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
48
|
+
with:
|
|
49
|
+
persist-credentials: false
|
|
50
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
51
|
+
with:
|
|
52
|
+
version: "0.12.3"
|
|
53
|
+
enable-cache: false
|
|
54
|
+
- name: Install the built wheel
|
|
55
|
+
run: |
|
|
56
|
+
uv build --wheel --out-dir wheel
|
|
57
|
+
uv venv --python 3.14 demo
|
|
58
|
+
uv pip install --python demo/bin/python --no-deps wheel/*.whl
|
|
59
|
+
demo/bin/planlens-agent init release-basic project
|
|
60
|
+
- name: Create the demonstration baseline
|
|
61
|
+
working-directory: project
|
|
62
|
+
run: ../demo/bin/planlens-agent suite run suite.toml --plans-dir candidates/v3 --output baseline.run.json
|
|
63
|
+
- name: Gate on rejecting candidates (fails on purpose)
|
|
64
|
+
working-directory: project
|
|
65
|
+
run: ../demo/bin/planlens-agent suite run suite.toml --plans-dir candidates/v2 --output candidate.run.json
|
|
66
|
+
- name: Show what changed (also fails, because findings are new)
|
|
67
|
+
if: always()
|
|
68
|
+
working-directory: project
|
|
69
|
+
run: ../demo/bin/planlens-agent suite diff baseline.run.json candidate.run.json --output comparison.json
|
|
70
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
71
|
+
if: always()
|
|
72
|
+
with:
|
|
73
|
+
name: reject-demo-diagnostics
|
|
74
|
+
path: |
|
|
75
|
+
project/*.run.json
|
|
76
|
+
project/comparison.json
|
|
77
|
+
if-no-files-found: warn
|
|
78
|
+
|
|
79
|
+
sarif-demo:
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
timeout-minutes: 10
|
|
82
|
+
permissions:
|
|
83
|
+
actions: read # upload-sarif reads this workflow run; needed on private repositories
|
|
84
|
+
contents: read
|
|
85
|
+
security-events: write
|
|
86
|
+
steps:
|
|
87
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
88
|
+
with:
|
|
89
|
+
persist-credentials: false
|
|
90
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
91
|
+
with:
|
|
92
|
+
version: "0.12.3"
|
|
93
|
+
enable-cache: false
|
|
94
|
+
- name: Install the built wheel
|
|
95
|
+
run: |
|
|
96
|
+
uv build --wheel --out-dir wheel
|
|
97
|
+
uv venv --python 3.14 demo
|
|
98
|
+
uv pip install --python demo/bin/python --no-deps wheel/*.whl
|
|
99
|
+
- name: Check a rejected plan and write SARIF (fails on purpose)
|
|
100
|
+
run: |
|
|
101
|
+
demo/bin/planlens-agent check src/planlens_agent/templates/release_basic/plans/reversed-review.json \
|
|
102
|
+
--contract src/planlens_agent/templates/release_basic/contract.toml \
|
|
103
|
+
--catalog src/planlens_agent/templates/release_basic/catalog.toml \
|
|
104
|
+
--format sarif --output planlens.sarif --source-root .
|
|
105
|
+
- uses: github/codeql-action/upload-sarif@33d7b85da1a04171e211befe2c739303b9a4c066 # v4.39.3
|
|
106
|
+
if: always()
|
|
107
|
+
with:
|
|
108
|
+
sarif_file: planlens.sarif
|
|
109
|
+
category: planlens-agent-demo
|
|
110
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
111
|
+
if: always()
|
|
112
|
+
with:
|
|
113
|
+
name: sarif-demo-log
|
|
114
|
+
path: planlens.sarif
|
|
115
|
+
if-no-files-found: warn
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Publishes one checked wheel and sdist to PyPI through Trusted Publishing.
|
|
2
|
+
# Manual only. Run it from the release tag, after the steps in release/PUBLISHING.md.
|
|
3
|
+
name: Publish to PyPI
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
version:
|
|
9
|
+
description: Version to publish, without the leading v
|
|
10
|
+
required: true
|
|
11
|
+
type: string
|
|
12
|
+
commit:
|
|
13
|
+
description: Full commit SHA that the tag and main must both be
|
|
14
|
+
required: true
|
|
15
|
+
type: string
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
check:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 20
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
actions: read
|
|
27
|
+
steps:
|
|
28
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
persist-credentials: false
|
|
32
|
+
- uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
|
|
33
|
+
with:
|
|
34
|
+
version: "0.12.3"
|
|
35
|
+
enable-cache: false
|
|
36
|
+
- name: Stop unless this is the approved tag, commit and main
|
|
37
|
+
env:
|
|
38
|
+
REF: ${{ github.ref }}
|
|
39
|
+
VERSION: ${{ inputs.version }}
|
|
40
|
+
COMMIT: ${{ inputs.commit }}
|
|
41
|
+
run: |
|
|
42
|
+
test "$REF" = "refs/tags/v$VERSION"
|
|
43
|
+
test "$(git rev-parse HEAD)" = "$COMMIT"
|
|
44
|
+
test "$(git rev-parse refs/remotes/origin/main)" = "$COMMIT"
|
|
45
|
+
- name: Stop unless CI passed for this exact commit
|
|
46
|
+
env:
|
|
47
|
+
COMMIT: ${{ inputs.commit }}
|
|
48
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
49
|
+
run: python3 scripts/ci_gate.py --commit "$COMMIT"
|
|
50
|
+
- name: Build the pair once
|
|
51
|
+
run: uv build --python 3.14 --out-dir release-pair/dist
|
|
52
|
+
- name: Check that pair
|
|
53
|
+
env:
|
|
54
|
+
VERSION: ${{ inputs.version }}
|
|
55
|
+
run: >-
|
|
56
|
+
uv run --no-project --python 3.14 scripts/release_check.py
|
|
57
|
+
--wheel "release-pair/dist/planlens_agent-$VERSION-py3-none-any.whl"
|
|
58
|
+
--sdist "release-pair/dist/planlens_agent-$VERSION.tar.gz"
|
|
59
|
+
--sums release-pair/SHA256SUMS
|
|
60
|
+
--tag "v$VERSION"
|
|
61
|
+
--python "$(uv python find --no-project 3.14)"
|
|
62
|
+
- name: Check the description renders
|
|
63
|
+
run: >-
|
|
64
|
+
uvx --from twine==7.0.0 --with "readme-renderer[md]==46.0"
|
|
65
|
+
twine check --strict release-pair/dist/*
|
|
66
|
+
- name: Record the hashes for the approver
|
|
67
|
+
run: cat release-pair/SHA256SUMS >> "$GITHUB_STEP_SUMMARY"
|
|
68
|
+
- name: Keep the CI gate for the check just before upload
|
|
69
|
+
run: cp scripts/ci_gate.py release-pair/ci_gate.py
|
|
70
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
71
|
+
with:
|
|
72
|
+
name: release-pair
|
|
73
|
+
path: release-pair
|
|
74
|
+
if-no-files-found: error
|
|
75
|
+
|
|
76
|
+
publish:
|
|
77
|
+
needs: check
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
timeout-minutes: 15
|
|
80
|
+
environment:
|
|
81
|
+
name: pypi
|
|
82
|
+
url: https://pypi.org/project/planlens-agent/
|
|
83
|
+
permissions:
|
|
84
|
+
actions: read
|
|
85
|
+
id-token: write
|
|
86
|
+
steps:
|
|
87
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
88
|
+
with:
|
|
89
|
+
name: release-pair
|
|
90
|
+
path: release-pair
|
|
91
|
+
- name: Stop unless these are exactly the checked files
|
|
92
|
+
working-directory: release-pair/dist
|
|
93
|
+
run: |
|
|
94
|
+
files=(*)
|
|
95
|
+
test "${#files[@]}" -eq 2
|
|
96
|
+
sha256sum --check --strict ../SHA256SUMS
|
|
97
|
+
- name: Stop unless CI still passes for this exact commit
|
|
98
|
+
env:
|
|
99
|
+
COMMIT: ${{ inputs.commit }}
|
|
100
|
+
GITHUB_TOKEN: ${{ github.token }}
|
|
101
|
+
run: python3 release-pair/ci_gate.py --commit "$COMMIT"
|
|
102
|
+
- uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
|
|
103
|
+
with:
|
|
104
|
+
packages-dir: release-pair/dist
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Authors
|
|
2
|
+
|
|
3
|
+
PlanLens (distributed as `planlens-agent`) is by, in this order:
|
|
4
|
+
|
|
5
|
+
| Author | Role |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| Nurdaulet Abdrakhman | Project lead and primary maintainer; primary project contact |
|
|
8
|
+
| Daniyal Kozyrev | Co-author and contributor |
|
|
9
|
+
|
|
10
|
+
Nurdaulet Abdrakhman leads the project and is responsible for its maintenance. Contact:
|
|
11
|
+
[LinkedIn](https://www.linkedin.com/in/nurdaulet-abdrakhman-523784375).
|
|
12
|
+
|
|
13
|
+
These names and roles were confirmed by the project owner.
|
|
14
|
+
|
|
15
|
+
Implementation of this product used an AI coding assistant, Claude Code, under the project lead's direction.
|
|
16
|
+
|
|
17
|
+
## Research artifact
|
|
18
|
+
|
|
19
|
+
This product is separate from the PlanLens research artifact. That repository's `AUTHORS.md` lists Nurdaulet
|
|
20
|
+
Abdrakhman (primary and contact author) and Daniyal Kozyrev (coauthor). That is a statement about the
|
|
21
|
+
research artifact, whose own attribution and copyright are recorded there; see `NOTICE` and `PROVENANCE.md`.
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 - first public release
|
|
4
|
+
|
|
5
|
+
Changed
|
|
6
|
+
|
|
7
|
+
- Version 0.1.0, with the package maturity classifier `Development Status :: 3 - Alpha`. The
|
|
8
|
+
public API may evolve during 0.x.
|
|
9
|
+
- Installation is documented as `python -m pip install "planlens-agent==0.1.0"`.
|
|
10
|
+
- The package description comes from `README.pypi.md`, because the GitHub README uses relative
|
|
11
|
+
images and links that would break on PyPI.
|
|
12
|
+
- The README opens with a walkthrough of one authored example, built from real package output and
|
|
13
|
+
a real Inspector capture, and the summary now reads "Catch plan errors before execution".
|
|
14
|
+
- The logo is the approved "Planform" mark, with light, dark and one-colour variants.
|
|
15
|
+
- The selected names are recorded in `docs/naming.md`, with PyPI registration pending.
|
|
16
|
+
|
|
17
|
+
Compatibility
|
|
18
|
+
|
|
19
|
+
- The evaluator digest covers `_version.py`, so runs saved by a `0.1.0.dev0` build are
|
|
20
|
+
`not_comparable` (exit 2) with runs from 0.1.0. Regenerate those baselines and review them.
|
|
21
|
+
Strict comparison and the engine-version check on approvals are unchanged.
|
|
22
|
+
|
|
23
|
+
No checker rule, diagnostic meaning, schema or policy behaviour changed from the last development
|
|
24
|
+
build, and no runtime dependency was added.
|
|
25
|
+
|
|
26
|
+
Added
|
|
27
|
+
|
|
28
|
+
- `scripts/release_check.py` checks a built wheel and sdist as one pair, and `release/` holds the
|
|
29
|
+
release notes and publishing procedure.
|
|
30
|
+
- `.github/workflows/publish.yml`, a manual-only PyPI Trusted Publishing workflow.
|
|
31
|
+
`scripts/ci_gate.py` stops it unless GitHub's Actions API shows CI passed for the exact commit.
|
|
32
|
+
|
|
33
|
+
## 0.1.0.dev0 - unreleased (checkpoint B2)
|
|
34
|
+
|
|
35
|
+
Added
|
|
36
|
+
|
|
37
|
+
- `suite run` and `suite diff`: run developer-supplied candidates through `check()`, save
|
|
38
|
+
an auditable run (`planlens-agent/run/v1`), and compare two runs
|
|
39
|
+
(`planlens-agent/run-diff/v1`). See `docs/suites.md`.
|
|
40
|
+
- Runs record plan content and digests, contract and catalog identity, report and rule
|
|
41
|
+
versions, and an evaluator digest that tells apart builds sharing a version string.
|
|
42
|
+
- `load_suite`, `run_suite`, `load_run`, `compare_runs` in the SDK; schemas for suites, runs
|
|
43
|
+
and comparisons.
|
|
44
|
+
- `candidates/` and `suite.toml` in the `release-basic` template, all authored.
|
|
45
|
+
- `examples/langgraph_gate`: a planner, check, execute-or-reject graph, tested with
|
|
46
|
+
LangGraph 1.2.20. The core still has no runtime dependencies.
|
|
47
|
+
- `.github/workflows/ci.yml` and `consumer-demo.yml`, prepared and not yet run on a hosted
|
|
48
|
+
service; `scripts/ci_local.py` runs the same stages locally; `scripts/journey.py` walks the
|
|
49
|
+
whole journey against an installed command.
|
|
50
|
+
|
|
51
|
+
Fixed
|
|
52
|
+
|
|
53
|
+
- A file name too long for the operating system made `check()` raise, and the CLI report an
|
|
54
|
+
internal error, for plans, contracts and catalogs. It is now an `unreadable` finding, with
|
|
55
|
+
no source location invented. The same fault is fixed in `--source-root`, `init` and
|
|
56
|
+
`regress`.
|
|
57
|
+
|
|
58
|
+
Fixed after independent review of B2 (B2-r2)
|
|
59
|
+
|
|
60
|
+
- LangGraph recipe: a returned state or caller-supplied fields could authorize a later
|
|
61
|
+
invocation whose planner failed, and removing the plan after the check skipped the
|
|
62
|
+
comparison. The graph now accepts only `request`, every invocation starts clean, and
|
|
63
|
+
execution needs a current plan.
|
|
64
|
+
- `load_run`: every declared type is checked before use, so a malformed value is a
|
|
65
|
+
`RunFileError` instead of an uncaught `TypeError`. Booleans and floats are no longer
|
|
66
|
+
accepted as integers, identifiers cannot end in a newline, and findings must agree with the
|
|
67
|
+
run's rule versions.
|
|
68
|
+
- `suite diff`: two runs agreeing on an unsupported `report_schema` are `not_comparable`.
|
|
69
|
+
- `suite diff --output` refuses to replace either input, including through other spellings,
|
|
70
|
+
symlinks and hard links.
|
|
71
|
+
|
|
72
|
+
Fixed after independent review of B2-r2 (B2-r3)
|
|
73
|
+
|
|
74
|
+
- `check`, `inspect` and `suite run --overwrite` could overwrite their own inputs. All of them
|
|
75
|
+
now refuse, with exit 2, an output that is the plan, contract, catalog, suite manifest or a
|
|
76
|
+
candidate in use, including through other spellings, symlinks and hard links.
|
|
77
|
+
|
|
78
|
+
Developer experience
|
|
79
|
+
|
|
80
|
+
- README rebuilt around the journey; quickstart with an owner-defined workflow; evidence page.
|
|
81
|
+
- An authored demo GIF, a static fallback and an inspector screenshot, generated from installed-wheel
|
|
82
|
+
output by `scripts/make_demo_media.py`.
|
|
83
|
+
- `scripts/docs_check.py` and a `docs` CI stage run the copy-and-run blocks exactly as written. Each
|
|
84
|
+
command has its own status, so a failure in the middle of a block is fatal, and the README's
|
|
85
|
+
development command is run from a clean shell.
|
|
86
|
+
|
|
87
|
+
Presentation
|
|
88
|
+
|
|
89
|
+
- PlanLens wordmark, a README built around the first questions a developer asks, a saved diagnosis
|
|
90
|
+
in a collapsed section, a docs index, an examples index and contributor guidance.
|
|
91
|
+
- Terminal media is now a labelled excerpt with a complete transcript beside it.
|
|
92
|
+
|
|
93
|
+
Project details
|
|
94
|
+
|
|
95
|
+
- Owner-confirmed authors, maintainer, copyright holder and contact in `AUTHORS.md`, `NOTICE`, the README
|
|
96
|
+
and package metadata. `CONTRIBUTING.md` is now in the sdist.
|
|
97
|
+
|
|
98
|
+
Fixed on hosted CI
|
|
99
|
+
|
|
100
|
+
- `.gitattributes` keeps LF on every platform and leaves the vendored OASIS schema untouched.
|
|
101
|
+
Windows checkouts had rewritten its line endings.
|
|
102
|
+
- The SARIF demo job has the `actions: read` permission that `upload-sarif` needs on private
|
|
103
|
+
repositories.
|
|
104
|
+
|
|
105
|
+
Unchanged
|
|
106
|
+
|
|
107
|
+
- `check` and `inspect` output: byte-identical to the previous checkpoint's wheel across the
|
|
108
|
+
acceptance cases and bundled plans.
|
|
109
|
+
|
|
110
|
+
## 0.1.0.dev0 - unreleased (checkpoint A)
|
|
111
|
+
|
|
112
|
+
Not published. Distribution, module and command names are provisional
|
|
113
|
+
(see `docs/naming.md`).
|
|
114
|
+
|
|
115
|
+
Added
|
|
116
|
+
|
|
117
|
+
- Owner-supplied action catalog and contract (`.toml` or `.json`), validated
|
|
118
|
+
together before any plan is read: schema, catalog pin, unknown actions,
|
|
119
|
+
prerequisite cycles, inconsistent or unsatisfiable artifact rules, and
|
|
120
|
+
unsupported rule kinds.
|
|
121
|
+
- Ordered sequential plans with unique step ids and `"<step>.<output>"`
|
|
122
|
+
artifact references.
|
|
123
|
+
- Checks: unknown actions, required actions, prerequisites, reference
|
|
124
|
+
resolution and order, input binding and type, planned artifact identity, and
|
|
125
|
+
attempts by a plan to override policy.
|
|
126
|
+
- One diagnostic model for the SDK, CLI and JSON reports
|
|
127
|
+
(`planlens-agent/report/v1`), with stable rule ids and offline explanations.
|
|
128
|
+
- CLI `planlens-agent` with `check` (exit 0 / 1 / 2), `validate-policy`,
|
|
129
|
+
`regress`, `init`, `rules`, `explain`.
|
|
130
|
+
- `ApprovedPlan` snapshots and a `ReferenceRunner` that dispatches only the
|
|
131
|
+
exact approved snapshot.
|
|
132
|
+
- `release-basic` template, regression fixtures, JSON Schemas.
|
|
133
|
+
|
|
134
|
+
Fixed during the checkpoint A source review
|
|
135
|
+
|
|
136
|
+
- An integer longer than 4,300 digits in a JSON or TOML document made `check()`
|
|
137
|
+
raise `ValueError`; through the CLI it was reported as an internal error with
|
|
138
|
+
no report. It is now a `<doc>/limit` finding.
|
|
139
|
+
- Excessive nesting was reported as `malformed` or `schema` depending on which
|
|
140
|
+
depth check fired first. It is now always `<doc>/limit`.
|
|
141
|
+
|
|
142
|
+
Fixed after the second source review
|
|
143
|
+
|
|
144
|
+
- A validated policy exposed mutable dicts, so clearing an action's inputs made a
|
|
145
|
+
rejected plan pass under the same digest. Catalog and contract are now
|
|
146
|
+
read-only private copies bound to their content; `check(policy=...)` and the
|
|
147
|
+
runner refuse a policy that no longer matches (`PolicyIntegrityError`).
|
|
148
|
+
- The runner re-checked the plan, then dispatched from `approval.plan`, which a
|
|
149
|
+
caller could mutate during dispatch. It now dispatches its own validated
|
|
150
|
+
read-only copy, and `ApprovedPlan` always holds a private copy.
|
|
151
|
+
- A JSON escape for an unpaired surrogate (`"\ud800"`) crashed checking of plans,
|
|
152
|
+
contracts and catalogs. It is now a `<doc>/schema` finding with a location.
|
|
153
|
+
- `contract/unsatisfiable-input` (rule version 2) now detects required actions
|
|
154
|
+
whose inputs cannot be bootstrapped, not only types no action outputs.
|
|
155
|
+
- `uv.lock` is included in the sdist.
|
|
156
|
+
|
|
157
|
+
Added in checkpoint B1
|
|
158
|
+
|
|
159
|
+
- `planlens-agent inspect PLAN --output FILE`: a self-contained HTML report of one
|
|
160
|
+
check, built from an explicit view model (`build_view`, `render_html`).
|
|
161
|
+
- `planlens-agent check --format sarif [--source-root DIR]`: SARIF 2.1.0 export
|
|
162
|
+
(`to_sarif`, `to_sarif_json`). `--output` saves what is printed in this mode;
|
|
163
|
+
text and JSON modes are unchanged.
|
|
164
|
+
- `Policy.catalog_origin` and `Policy.contract_origin`, so a syntax error in a policy
|
|
165
|
+
document can be located in its file.
|
|
166
|
+
|
|
167
|
+
Fixed after the B1 source review
|
|
168
|
+
|
|
169
|
+
- More than 702 distinct artifact references in one report made `build_view` raise
|
|
170
|
+
`IndexError`, so `inspect` gave no report. Group labels now continue past ZZ with no
|
|
171
|
+
limit, and a label stands for one reference across all rules.
|
|
172
|
+
- SARIF export resolved relative paths against the working directory at export time.
|
|
173
|
+
Locations are now fixed when each document is read (`CheckResult.plan_source`,
|
|
174
|
+
`Policy.contract_source`, `Policy.catalog_source`).
|
|
175
|
+
- The diagram's relationship limit is now checked before any of it is built.
|
|
176
|
+
- Raw observed and required data moved behind native disclosure controls, with a compact
|
|
177
|
+
summary from the same structured fields left visible.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
PlanLens is in its 0.x series, and its public API may evolve. You need Git and [uv](https://docs.astral.sh/uv/).
|
|
4
|
+
|
|
5
|
+
## Set up and test
|
|
6
|
+
|
|
7
|
+
<!-- run prereq -->
|
|
8
|
+
```sh
|
|
9
|
+
git clone https://github.com/nurdauletabdurahman777-maker/planlens-agent.git
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Run everything below from the root of the clone. No virtual environment has to be active: `uv run` creates
|
|
13
|
+
`.venv` and uses it.
|
|
14
|
+
|
|
15
|
+
<!-- run dev contains=" passed" contains="Success: no issues found" -->
|
|
16
|
+
```sh
|
|
17
|
+
uv run --locked --extra dev pytest tests -q
|
|
18
|
+
uvx ruff@0.17.4 format --check .
|
|
19
|
+
uvx ruff@0.17.4 check .
|
|
20
|
+
uvx mypy@2.4.1 --strict src/planlens_agent
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Every CI stage, as CI runs it:
|
|
24
|
+
|
|
25
|
+
```text
|
|
26
|
+
uv run --no-project --python 3.14 scripts/ci_local.py all --python 3.14
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What to keep true
|
|
30
|
+
|
|
31
|
+
- The core has no runtime dependencies. Development tools stay out of the wheel.
|
|
32
|
+
- The checker is deterministic and makes no model calls.
|
|
33
|
+
- Every command in a `sh` block in the README, Quickstart or this file must work as written. The `docs` CI stage
|
|
34
|
+
runs them. A command that is meant to fail goes last in its block.
|
|
35
|
+
- Label authored examples as authored. Do not report results that were not observed.
|
|
36
|
+
|
|
37
|
+
## Regenerate media
|
|
38
|
+
|
|
39
|
+
On macOS with Google Chrome, from the root of the clone:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
uv run --script scripts/make_demo_media.py
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This rebuilds `docs/media` and `docs/brand` from the real package. Its tools are used only by that script.
|
|
46
|
+
|
|
47
|
+
## Report a bug
|
|
48
|
+
|
|
49
|
+
Open an issue, and include:
|
|
50
|
+
|
|
51
|
+
- the output of `planlens-agent --version`, your Python version and operating system;
|
|
52
|
+
- the exact command and its exit status;
|
|
53
|
+
- the smallest catalog, contract and plan that show the problem;
|
|
54
|
+
- what you expected, and the full output.
|
|
55
|
+
|
|
56
|
+
Remove credentials and anything confidential first. A wrong verdict is the most important kind of bug: include
|
|
57
|
+
the plan, and say which rule should or should not have applied.
|