scan-skill 0.3.1__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.
- scan_skill-0.3.1/LICENSE +21 -0
- scan_skill-0.3.1/PKG-INFO +286 -0
- scan_skill-0.3.1/README.md +267 -0
- scan_skill-0.3.1/pyproject.toml +47 -0
- scan_skill-0.3.1/scanbench/README.md +11 -0
- scan_skill-0.3.1/scanbench/__init__.py +1 -0
- scan_skill-0.3.1/scanbench/fixtures/__init__.py +1 -0
- scan_skill-0.3.1/scanbench/fixtures/archive-boundary/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/archive-boundary/expected.json +30 -0
- scan_skill-0.3.1/scanbench/fixtures/archive-boundary/fixture.json +8 -0
- scan_skill-0.3.1/scanbench/fixtures/archive-boundary/project/README.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/archive-boundary/project/bundle.zip +0 -0
- scan_skill-0.3.1/scanbench/fixtures/clean-minimal/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/clean-minimal/expected.json +39 -0
- scan_skill-0.3.1/scanbench/fixtures/clean-minimal/fixture.json +6 -0
- scan_skill-0.3.1/scanbench/fixtures/clean-minimal/project/app.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/false-runtime-claim/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/false-runtime-claim/expected.json +34 -0
- scan_skill-0.3.1/scanbench/fixtures/false-runtime-claim/fixture.json +6 -0
- scan_skill-0.3.1/scanbench/fixtures/false-runtime-claim/project/status.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/false-runtime-claim/project/test_example.py +2 -0
- scan_skill-0.3.1/scanbench/fixtures/generated-and-vendor/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/generated-and-vendor/expected.json +24 -0
- scan_skill-0.3.1/scanbench/fixtures/generated-and-vendor/fixture.json +6 -0
- scan_skill-0.3.1/scanbench/fixtures/generated-and-vendor/project/dist/app.js +1 -0
- scan_skill-0.3.1/scanbench/fixtures/generated-and-vendor/project/src/main.js +1 -0
- scan_skill-0.3.1/scanbench/fixtures/generated-and-vendor/project/vendor/lib.js +1 -0
- scan_skill-0.3.1/scanbench/fixtures/hidden-files/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/hidden-files/expected.json +19 -0
- scan_skill-0.3.1/scanbench/fixtures/hidden-files/fixture.json +6 -0
- scan_skill-0.3.1/scanbench/fixtures/hidden-files/project/.hidden.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/hidden-files/project/visible.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/incomplete-discovery/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/incomplete-discovery/expected.json +29 -0
- scan_skill-0.3.1/scanbench/fixtures/incomplete-discovery/fixture.json +8 -0
- scan_skill-0.3.1/scanbench/fixtures/incomplete-discovery/project/a.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/incomplete-discovery/project/b.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/inventory-basic/expected.json +3 -0
- scan_skill-0.3.1/scanbench/fixtures/malformed-filename/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/malformed-filename/expected.json +24 -0
- scan_skill-0.3.1/scanbench/fixtures/malformed-filename/fixture.json +6 -0
- scan_skill-0.3.1/scanbench/fixtures/malformed-filename/project/-rf.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/malformed-filename/project/space name.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/malformed-filename/project/unicode-/316/273.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/prompt-injection/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/prompt-injection/expected.json +28 -0
- scan_skill-0.3.1/scanbench/fixtures/prompt-injection/fixture.json +8 -0
- scan_skill-0.3.1/scanbench/fixtures/prompt-injection/project/instructions.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/secret-redaction/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/secret-redaction/expected.json +29 -0
- scan_skill-0.3.1/scanbench/fixtures/secret-redaction/fixture.json +9 -0
- scan_skill-0.3.1/scanbench/fixtures/secret-redaction/project/public.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/secret-redaction/project/secrets.env +1 -0
- scan_skill-0.3.1/scanbench/fixtures/symlink-escape/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/symlink-escape/expected.json +31 -0
- scan_skill-0.3.1/scanbench/fixtures/symlink-escape/fixture.json +13 -0
- scan_skill-0.3.1/scanbench/fixtures/symlink-escape/project/inside.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/unreadable-artifact/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/unreadable-artifact/expected.json +30 -0
- scan_skill-0.3.1/scanbench/fixtures/unreadable-artifact/fixture.json +8 -0
- scan_skill-0.3.1/scanbench/fixtures/unreadable-artifact/project/locked.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/unreadable-artifact/project/readable.txt +1 -0
- scan_skill-0.3.1/scanbench/fixtures/unsupported-binary/README.md +5 -0
- scan_skill-0.3.1/scanbench/fixtures/unsupported-binary/expected.json +26 -0
- scan_skill-0.3.1/scanbench/fixtures/unsupported-binary/fixture.json +6 -0
- scan_skill-0.3.1/scanbench/fixtures/unsupported-binary/project/blob.bin +0 -0
- scan_skill-0.3.1/scanbench/fixtures/unsupported-binary/project/note.txt +1 -0
- scan_skill-0.3.1/scanbench/manifest.json +24 -0
- scan_skill-0.3.1/setup.cfg +4 -0
- scan_skill-0.3.1/src/scan_core/__init__.py +101 -0
- scan_skill-0.3.1/src/scan_core/__main__.py +7 -0
- scan_skill-0.3.1/src/scan_core/auxiliary.py +139 -0
- scan_skill-0.3.1/src/scan_core/baseline.py +88 -0
- scan_skill-0.3.1/src/scan_core/builder.py +538 -0
- scan_skill-0.3.1/src/scan_core/cli.py +342 -0
- scan_skill-0.3.1/src/scan_core/compare.py +176 -0
- scan_skill-0.3.1/src/scan_core/config.py +101 -0
- scan_skill-0.3.1/src/scan_core/core.py +293 -0
- scan_skill-0.3.1/src/scan_core/doctor.py +223 -0
- scan_skill-0.3.1/src/scan_core/errors.py +52 -0
- scan_skill-0.3.1/src/scan_core/git_change.py +214 -0
- scan_skill-0.3.1/src/scan_core/git_provenance.py +213 -0
- scan_skill-0.3.1/src/scan_core/ids.py +43 -0
- scan_skill-0.3.1/src/scan_core/inventory.py +305 -0
- scan_skill-0.3.1/src/scan_core/privacy.py +391 -0
- scan_skill-0.3.1/src/scan_core/render.py +368 -0
- scan_skill-0.3.1/src/scan_core/report/__init__.py +1 -0
- scan_skill-0.3.1/src/scan_core/report/shell.html +142 -0
- scan_skill-0.3.1/src/scan_core/reuse.py +214 -0
- scan_skill-0.3.1/src/scan_core/scanbench.py +473 -0
- scan_skill-0.3.1/src/scan_core/schema.py +31 -0
- scan_skill-0.3.1/src/scan_core/schemas/__init__.py +1 -0
- scan_skill-0.3.1/src/scan_core/schemas/scan-state-1.2.schema.json +26 -0
- scan_skill-0.3.1/src/scan_core/schemas/scan-state-1.3.schema.json +29 -0
- scan_skill-0.3.1/src/scan_core/schemas/scan-state-1.4.schema.json +58 -0
- scan_skill-0.3.1/src/scan_core/settings.py +133 -0
- scan_skill-0.3.1/src/scan_core/snapshot.py +48 -0
- scan_skill-0.3.1/src/scan_core/state.py +477 -0
- scan_skill-0.3.1/src/scan_core/validate.py +847 -0
- scan_skill-0.3.1/src/scan_core/version.py +3 -0
- scan_skill-0.3.1/src/scan_skill.egg-info/PKG-INFO +286 -0
- scan_skill-0.3.1/src/scan_skill.egg-info/SOURCES.txt +118 -0
- scan_skill-0.3.1/src/scan_skill.egg-info/dependency_links.txt +1 -0
- scan_skill-0.3.1/src/scan_skill.egg-info/entry_points.txt +2 -0
- scan_skill-0.3.1/src/scan_skill.egg-info/top_level.txt +2 -0
- scan_skill-0.3.1/tests/test_open_issues.py +265 -0
- scan_skill-0.3.1/tests/test_report_ux.py +228 -0
- scan_skill-0.3.1/tests/test_self_review_defects.py +593 -0
- scan_skill-0.3.1/tests/test_slice1.py +88 -0
- scan_skill-0.3.1/tests/test_slice2.py +170 -0
- scan_skill-0.3.1/tests/test_slice3.py +197 -0
- scan_skill-0.3.1/tests/test_slice4.py +234 -0
- scan_skill-0.3.1/tests/test_slice5.py +235 -0
- scan_skill-0.3.1/tests/test_slice6.py +255 -0
- scan_skill-0.3.1/tests/test_v03_slice1.py +266 -0
- scan_skill-0.3.1/tests/test_v03_slice2.py +249 -0
- scan_skill-0.3.1/tests/test_v03_slice3.py +412 -0
- scan_skill-0.3.1/tests/test_v03_slice4.py +244 -0
- scan_skill-0.3.1/tests/test_v03_slice5.py +126 -0
- scan_skill-0.3.1/tests/test_v03_slice6.py +77 -0
scan_skill-0.3.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 legendteddy
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: scan-skill
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Evidence-backed whole-project inspection core and agent skill
|
|
5
|
+
Author: legendteddy
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/legendteddy/scan
|
|
8
|
+
Project-URL: Repository, https://github.com/legendteddy/scan
|
|
9
|
+
Project-URL: Issues, https://github.com/legendteddy/scan/issues
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Requires-Python: >=3.11
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# Scan
|
|
21
|
+
|
|
22
|
+
[](https://github.com/legendteddy/scan/actions/workflows/validate.yml)
|
|
23
|
+
[](LICENSE)
|
|
24
|
+
|
|
25
|
+
**Know what an AI agent actually inspected.**
|
|
26
|
+
|
|
27
|
+
Scan is an **evidence-backed whole-project inspection** project with two layers: an AI-agent skill for deeper evidence-linked review and a local deterministic core for safe inventory, canonical state, privacy enforcement, validation, and self-contained HTML reporting.
|
|
28
|
+
|
|
29
|
+
**Coverage ≠ confidence.** Finding a file, reading it, assessing a check, and verifying runtime behavior are different things. Scan makes those differences visible.
|
|
30
|
+
|
|
31
|
+
## Start here: run Scan locally
|
|
32
|
+
|
|
33
|
+
Install from a source checkout when you want the command and bundled evidence assets from the exact repository state you reviewed:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git clone https://github.com/legendteddy/scan.git
|
|
37
|
+
cd scan
|
|
38
|
+
python -m pip install .
|
|
39
|
+
scan doctor .
|
|
40
|
+
scan . --offline
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Change the project, then run the same scan again:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
scan . --offline
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The second run uses the previous local `.scan/state.json` as its baseline and reports what was added, changed, removed or unchanged, while keeping fresh and reused evidence separate. `scan doctor .` is an offline, non-destructive readiness diagnostic: it checks installed package assets, target access and optional Git support, and uses a temporary local output probe that it removes before returning. It does not install, repair or contact anything.
|
|
50
|
+
|
|
51
|
+
For published builds, package-index availability depends on the release channel. If `scan-skill` is available in your configured Python package index, you can install the packaged CLI with `python -m pip install scan-skill`, `pipx install scan-skill`, or `uv tool install scan-skill`.
|
|
52
|
+
|
|
53
|
+
## What makes Scan different?
|
|
54
|
+
|
|
55
|
+
- **Inventory before verdict:** account for discoverable files, including unreadable, excluded, metadata-only and partially inspected items.
|
|
56
|
+
- **Two kinds of coverage:** track artifact discovery/analysis separately from checks assessed, partial, blocked or not performed.
|
|
57
|
+
- **Receipts for claims:** findings, controls, relationships and architecture map back to evidence IDs and precise source locators.
|
|
58
|
+
- **Static-first boundaries:** target files and embedded instructions are untrusted; no executing unknown target code or silent fixes without authorization.
|
|
59
|
+
- **Honest uncertainty:** static source observations are not presented as runtime proof, a vulnerability clearance or a release certification.
|
|
60
|
+
- **Portable handoff:** HTML reports include inert structured state for revalidation and continuation (current standalone core: schema **1.4**; checked-in synthetic demo: historical schema **1.2**).
|
|
61
|
+
|
|
62
|
+
Scan can guide inspection of source repositories, websites, document collections, archives, binaries and mixed folders. Actual depth depends on access, file types, safety limits and the agent's available tools.
|
|
63
|
+
|
|
64
|
+
For the concrete false-confidence failure mode Scan is designed to prevent, read [Why Scan exists](docs/why-scan.md).
|
|
65
|
+
|
|
66
|
+
## Standalone core
|
|
67
|
+
|
|
68
|
+
The packaged standalone core requires **Python 3.11+**. It can inventory a local project, create canonical Scan 1.4 JSON, compare repeated scans against a prior local state, safely reuse compatible higher-level static evidence, render a self-contained HTML report from that exact state, validate both formats, enforce deterministic privacy/redaction metadata, and produce a no-network egress preview.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
python -m pip install .
|
|
72
|
+
scan doctor .
|
|
73
|
+
scan . --offline
|
|
74
|
+
# Change the project, then scan again. The prior .scan/state.json is used locally as the baseline.
|
|
75
|
+
scan . --offline
|
|
76
|
+
# Optional local-only Git prioritization context; full Scan inventory still runs.
|
|
77
|
+
scan . --offline --changed-since origin/main
|
|
78
|
+
scan validate .scan/state.json
|
|
79
|
+
scan validate .scan/report.html
|
|
80
|
+
scan compare previous-state.json .scan/state.json --json
|
|
81
|
+
scan render .scan/state.json --output .scan/rerendered.html
|
|
82
|
+
scan schema --version 1.4
|
|
83
|
+
scan egress . --privacy controlled-remote --redact strict --json
|
|
84
|
+
scan bench
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The standalone HTML report is static and useful without JavaScript. Its only script block is inert `application/json` state with ID `project-anatomy-state`; visible count markers are validated against that embedded state. `scan egress` is preview-only: it reports selected/omitted files, selected bytes and redaction counts, and performs **no network action**. Use `--sensitive-path "pattern/**"` to keep declared path names out of canonical state and egress selection.
|
|
88
|
+
|
|
89
|
+
### Scan modes
|
|
90
|
+
|
|
91
|
+
Scan exposes explicit coverage promises instead of silently sampling:
|
|
92
|
+
|
|
93
|
+
- `--mode quick` is triage: it inventories the project while suppressing common dependency/build/cache trees and Git internals from ordinary content analysis. A quick scan is always presented as partial and its continuation state points to `deep`.
|
|
94
|
+
- `--mode deep` is the default whole-project first-party mode. It broadly accounts for safely readable project content while treating `.git/**` as repository provenance rather than normal source.
|
|
95
|
+
- `--mode forensic` opts repository internals back in for provenance-heavy or historical investigation. Explicit user exclusions and normal safety/resource boundaries still apply.
|
|
96
|
+
|
|
97
|
+
Git repositories record bounded HEAD/branch/commit and sanitized remote metadata separately. Scan deliberately does not invoke Git status, hooks, filesystem monitors or target-configured helpers merely to determine clean/dirty state; that field is recorded as `not_assessed` unless established by an authorized higher-level analyzer.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
scan . --offline --mode quick
|
|
101
|
+
scan . --offline --mode deep
|
|
102
|
+
scan . --offline --mode forensic
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Project configuration
|
|
106
|
+
|
|
107
|
+
Optional configuration lives at `.scan/config.toml`. Precedence is **CLI arguments > project config > built-in defaults**.
|
|
108
|
+
|
|
109
|
+
```toml
|
|
110
|
+
[scan]
|
|
111
|
+
privacy = "offline"
|
|
112
|
+
redact = "standard"
|
|
113
|
+
mode = "deep"
|
|
114
|
+
max_file_bytes = 5000000
|
|
115
|
+
max_total_bytes = 250000000
|
|
116
|
+
follow_internal_links = false
|
|
117
|
+
|
|
118
|
+
[exclude]
|
|
119
|
+
patterns = ["vendor/**"]
|
|
120
|
+
|
|
121
|
+
[baseline]
|
|
122
|
+
mode = "auto" # auto | none
|
|
123
|
+
reuse = true
|
|
124
|
+
max_state_bytes = 64000000
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Behavior-affecting resolved configuration is included in the canonical configuration digest. An explicit `--baseline PATH` is invocation-only and is never persisted automatically. Use `--baseline none` to disable comparison for a run; `--no-reuse` records that prior evidence must not be reused. Scan configuration does not require secrets.
|
|
128
|
+
|
|
129
|
+
See [explicit semantic continuation](references/semantic-continuation.md) for current producer/check registration and bounded worktree metadata authorization. Baselines never authorize their own semantic producers.
|
|
130
|
+
|
|
131
|
+
### Semantic builder API
|
|
132
|
+
|
|
133
|
+
Semantic agents can extend valid deterministic state without hand-authoring nested JSON. `SemanticStateBuilder` provides typed record helpers for components, evidence, relationships, findings, controls, unknowns, actions and checks; scalar/string-array references are normalized, generated IDs are deterministic, and bad references fail with the record ID and field path. The strict Scan validator still runs on `build()`.
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from scan_core import SemanticStateBuilder
|
|
137
|
+
|
|
138
|
+
builder = SemanticStateBuilder.from_state(core_state)
|
|
139
|
+
evidence_id = builder.add_evidence(
|
|
140
|
+
artifact_id=artifact["id"],
|
|
141
|
+
locator=artifact["locator"],
|
|
142
|
+
kind="static",
|
|
143
|
+
claim="Configuration path was reviewed",
|
|
144
|
+
result="The path is resolved locally",
|
|
145
|
+
method="semantic source review",
|
|
146
|
+
limitations="Runtime behavior was not observed",
|
|
147
|
+
source_digest=artifact["content_identity"],
|
|
148
|
+
producer_kind="local-model",
|
|
149
|
+
producer_name="review-agent",
|
|
150
|
+
producer_version="1",
|
|
151
|
+
)
|
|
152
|
+
builder.add_finding(
|
|
153
|
+
title="Example finding",
|
|
154
|
+
impact="Explain the user-visible consequence",
|
|
155
|
+
severity="medium",
|
|
156
|
+
confidence="high",
|
|
157
|
+
verification_state="static",
|
|
158
|
+
artifact_ids=artifact["id"],
|
|
159
|
+
evidence_ids=evidence_id,
|
|
160
|
+
uncertainty="Runtime behavior remains unverified",
|
|
161
|
+
recommendation="Address the evidenced condition",
|
|
162
|
+
safe_verification="Re-read the affected source and validate the state",
|
|
163
|
+
)
|
|
164
|
+
semantic_state = builder.build()
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`upgrade_semantic_state(core_state)` is a convenience alias for starting the same builder from deterministic state. Raw canonical JSON remains supported for advanced callers.
|
|
168
|
+
|
|
169
|
+
### Evidence freshness and safe reuse
|
|
170
|
+
|
|
171
|
+
Every run rebuilds the current inventory, hashes and provenance evidence fresh. Prior **higher-level static evidence** is considered for reuse only when its artifact/content identity is unchanged, its producer and producer version exactly match an available current producer, its check identity/definition still matches, its evidence class is explicitly reusable, and the current privacy policy can represent it safely. Runtime, observed, deployment/live-state and time-sensitive evidence is never automatically reused in v0.3.
|
|
172
|
+
|
|
173
|
+
New semantic evidence created through `SemanticStateBuilder` is marked fresh. Reused evidence retains its original observation time, depth and limitations and is marked `verified_reuse`; it never upgrades `content_read` to `analyzed`, an unfinished check to assessed, or static evidence to runtime verification. The state and HTML report expose fresh, reused and rejected-reuse counts separately. Current redaction/sensitive-path policy always wins over older baseline content.
|
|
174
|
+
|
|
175
|
+
### ScanBench v1
|
|
176
|
+
|
|
177
|
+
`scan bench` runs 12 mandatory synthetic adversarial fixtures covering hidden files, escaping symlinks, prompt injection, redaction, hostile filenames, unreadable content, archives, unsupported binaries, generated/vendor files, resource boundaries and false runtime claims. Results are reported separately for **inventory completeness, state integrity, evidence correctness, privacy integrity, and safety-boundary compliance**. ScanBench deliberately does **not** calculate a blended quality score.
|
|
178
|
+
|
|
179
|
+
Run one fixture with `scan bench FIXTURE`. The installed wheel carries the same canonical fixture data, so this works outside the source checkout as well.
|
|
180
|
+
|
|
181
|
+

|
|
182
|
+
|
|
183
|
+
[Explore the synthetic fixture](examples/demo-project/README.md) · [Download the example HTML report](examples/demo-report.html) · [Read the report contract](references/report-contract.md)
|
|
184
|
+
|
|
185
|
+
> **Demo disclosure:** The linked report is a hand-reviewed **synthetic worked example** generated from five fictional files. It demonstrates the Scan 1.2 format and validator, **not** a claim that an autonomous agent scanned a real repository. The example did not execute the inspected code.
|
|
186
|
+
|
|
187
|
+
## Historical synthetic proof
|
|
188
|
+
|
|
189
|
+
The historical report validator wrapper requires **Python 3.11+**, like Scan Core: it imports the current package (including `tomllib`). The validator and its tests use the standard library. Historical schema compatibility does not imply compatibility with older Python runtimes.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
git clone https://github.com/legendteddy/scan.git
|
|
193
|
+
cd scan
|
|
194
|
+
python scripts/validate_report.py examples/demo-report.html
|
|
195
|
+
python scripts/build_demo_report.py --check
|
|
196
|
+
python -m unittest discover -s scripts -p "test_*.py" -v
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Expected: the example report passes the structural contract, the generated HTML matches the checked-in version, and the validator tests pass. Open `examples/demo-report.html` **locally in a browser** to explore it. GitHub's source viewer is not an HTML report host.
|
|
200
|
+
|
|
201
|
+
The validator verifies schema, typed references, evidence origins and coverage accounting. A **PASS is not a factual audit, a runtime test or a security guarantee**.
|
|
202
|
+
|
|
203
|
+
## Install as an agent skill
|
|
204
|
+
|
|
205
|
+
Scan also remains an instruction-based agent skill. Copy or clone this repository into the skill directory used by your compatible agent, then ask the agent to inspect a target.
|
|
206
|
+
|
|
207
|
+
For environments that discover user skills in `~/.agents/skills/`:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
mkdir -p ~/.agents/skills
|
|
211
|
+
git clone https://github.com/legendteddy/scan.git ~/.agents/skills/scan
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
On Windows PowerShell:
|
|
215
|
+
|
|
216
|
+
```powershell
|
|
217
|
+
New-Item -ItemType Directory -Force "$HOME\.agents\skills" | Out-Null
|
|
218
|
+
git clone https://github.com/legendteddy/scan.git "$HOME\.agents\skills\scan"
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Skill locations, invocation and tool access vary by agent. Consult your host's skill documentation; copying a folder alone does not guarantee the host will load it.
|
|
222
|
+
|
|
223
|
+
Example requests to a compatible agent:
|
|
224
|
+
|
|
225
|
+
```text
|
|
226
|
+
Scan this entire repository and show what you could not verify.
|
|
227
|
+
Inspect this project and produce an evidence-backed HTML report.
|
|
228
|
+
Use $scan to map this package's architecture, risks and unknowns.
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The governing instructions are in [SKILL.md](SKILL.md). Scan asks for explicit authorization before running untrusted target code or modifying the inspected target.
|
|
232
|
+
|
|
233
|
+
## What the example shows
|
|
234
|
+
|
|
235
|
+
The fictional **Pocket Ledger** CSV totaler has five source files. Its worked report includes a source-linked concern about floating-point amounts, a missing malformed-input test gap, 14 accounted-for check categories, and explicit unanswered questions.
|
|
236
|
+
|
|
237
|
+
The report's static analysis of the five fixture files is complete **within that narrow scope**, but its broader checks are not complete. That distinction is the point of the demonstration.
|
|
238
|
+
|
|
239
|
+
To regenerate the sample after editing the fixture, update the snapshot time and evidence anchors in `scripts/build_demo_report.py`, then run:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
python scripts/build_demo_report.py
|
|
243
|
+
python scripts/validate_report.py examples/demo-report.html
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Optional visual QA and screenshot refresh: `python scripts/capture_preview.py` (requires Playwright and Chromium; not needed for Scan or CI).
|
|
247
|
+
|
|
248
|
+
## Repository map
|
|
249
|
+
|
|
250
|
+
```text
|
|
251
|
+
SKILL.md Agent instructions and safety boundaries
|
|
252
|
+
pyproject.toml Scan Core package metadata and `scan` entry point
|
|
253
|
+
src/scan_core/ v0.3 deterministic core package
|
|
254
|
+
src/scan_core/baseline.py Local-only bounded baseline resolver
|
|
255
|
+
src/scan_core/compare.py Pure deterministic 1.3/1.4 state comparison
|
|
256
|
+
src/scan_core/git_change.py Local-only advisory Git changed-scope integration
|
|
257
|
+
src/scan_core/reuse.py Strict evidence freshness/reuse decision engine
|
|
258
|
+
src/scan_core/render.py Validated canonical-state HTML renderer
|
|
259
|
+
src/scan_core/scanbench.py ScanBench v1 deterministic harness
|
|
260
|
+
src/scan_core/settings.py `.scan/config.toml` loader and precedence defaults
|
|
261
|
+
src/scan_core/schemas/ Bundled structural schemas 1.2, 1.3 and 1.4
|
|
262
|
+
src/scan_core/report/shell.html Packaged self-contained report shell
|
|
263
|
+
scanbench/fixtures/ 12 mandatory adversarial/ground-truth v1 fixtures
|
|
264
|
+
tests/ Packaged core/contract regression tests
|
|
265
|
+
agents/openai.yaml Skill metadata
|
|
266
|
+
assets/report-shell.html Self-contained HTML dashboard template
|
|
267
|
+
assets/report-components.html Report component patterns
|
|
268
|
+
assets/demo-preview.png Screenshot of the synthetic worked report
|
|
269
|
+
assets/social-preview.png Upload-ready GitHub social image (1280 × 640)
|
|
270
|
+
references/ Inspection lenses, coverage and schema contracts
|
|
271
|
+
scripts/validate_report.py Backward-compatible Scan 1.2 validator wrapper
|
|
272
|
+
scripts/test_validate_report.py Frozen 1.2 validator regression tests
|
|
273
|
+
scripts/build_demo_report.py Reproducible synthetic example generator
|
|
274
|
+
examples/demo-project/ Fictional five-file project
|
|
275
|
+
examples/demo-report.html Validated, self-contained Scan 1.2 example
|
|
276
|
+
launch/launch-kit.md Draft launch copy and approval checklist
|
|
277
|
+
docs/v0.2-technical-spec.md Approved standalone Scan Core + CLI contract
|
|
278
|
+
docs/v0.2-compatibility.md Python/schema/config/ScanBench compatibility boundary
|
|
279
|
+
docs/v0.3-technical-spec.md Approved repeat-scan baseline/diff contract
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Contribute and report security issues
|
|
283
|
+
|
|
284
|
+
Contributions that strengthen evidence discipline, safety, inspection depth, portability, accessibility or validator correctness are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md).
|
|
285
|
+
|
|
286
|
+
MIT licensed — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Scan
|
|
2
|
+
|
|
3
|
+
[](https://github.com/legendteddy/scan/actions/workflows/validate.yml)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
|
|
6
|
+
**Know what an AI agent actually inspected.**
|
|
7
|
+
|
|
8
|
+
Scan is an **evidence-backed whole-project inspection** project with two layers: an AI-agent skill for deeper evidence-linked review and a local deterministic core for safe inventory, canonical state, privacy enforcement, validation, and self-contained HTML reporting.
|
|
9
|
+
|
|
10
|
+
**Coverage ≠ confidence.** Finding a file, reading it, assessing a check, and verifying runtime behavior are different things. Scan makes those differences visible.
|
|
11
|
+
|
|
12
|
+
## Start here: run Scan locally
|
|
13
|
+
|
|
14
|
+
Install from a source checkout when you want the command and bundled evidence assets from the exact repository state you reviewed:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
git clone https://github.com/legendteddy/scan.git
|
|
18
|
+
cd scan
|
|
19
|
+
python -m pip install .
|
|
20
|
+
scan doctor .
|
|
21
|
+
scan . --offline
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Change the project, then run the same scan again:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
scan . --offline
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The second run uses the previous local `.scan/state.json` as its baseline and reports what was added, changed, removed or unchanged, while keeping fresh and reused evidence separate. `scan doctor .` is an offline, non-destructive readiness diagnostic: it checks installed package assets, target access and optional Git support, and uses a temporary local output probe that it removes before returning. It does not install, repair or contact anything.
|
|
31
|
+
|
|
32
|
+
For published builds, package-index availability depends on the release channel. If `scan-skill` is available in your configured Python package index, you can install the packaged CLI with `python -m pip install scan-skill`, `pipx install scan-skill`, or `uv tool install scan-skill`.
|
|
33
|
+
|
|
34
|
+
## What makes Scan different?
|
|
35
|
+
|
|
36
|
+
- **Inventory before verdict:** account for discoverable files, including unreadable, excluded, metadata-only and partially inspected items.
|
|
37
|
+
- **Two kinds of coverage:** track artifact discovery/analysis separately from checks assessed, partial, blocked or not performed.
|
|
38
|
+
- **Receipts for claims:** findings, controls, relationships and architecture map back to evidence IDs and precise source locators.
|
|
39
|
+
- **Static-first boundaries:** target files and embedded instructions are untrusted; no executing unknown target code or silent fixes without authorization.
|
|
40
|
+
- **Honest uncertainty:** static source observations are not presented as runtime proof, a vulnerability clearance or a release certification.
|
|
41
|
+
- **Portable handoff:** HTML reports include inert structured state for revalidation and continuation (current standalone core: schema **1.4**; checked-in synthetic demo: historical schema **1.2**).
|
|
42
|
+
|
|
43
|
+
Scan can guide inspection of source repositories, websites, document collections, archives, binaries and mixed folders. Actual depth depends on access, file types, safety limits and the agent's available tools.
|
|
44
|
+
|
|
45
|
+
For the concrete false-confidence failure mode Scan is designed to prevent, read [Why Scan exists](docs/why-scan.md).
|
|
46
|
+
|
|
47
|
+
## Standalone core
|
|
48
|
+
|
|
49
|
+
The packaged standalone core requires **Python 3.11+**. It can inventory a local project, create canonical Scan 1.4 JSON, compare repeated scans against a prior local state, safely reuse compatible higher-level static evidence, render a self-contained HTML report from that exact state, validate both formats, enforce deterministic privacy/redaction metadata, and produce a no-network egress preview.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
python -m pip install .
|
|
53
|
+
scan doctor .
|
|
54
|
+
scan . --offline
|
|
55
|
+
# Change the project, then scan again. The prior .scan/state.json is used locally as the baseline.
|
|
56
|
+
scan . --offline
|
|
57
|
+
# Optional local-only Git prioritization context; full Scan inventory still runs.
|
|
58
|
+
scan . --offline --changed-since origin/main
|
|
59
|
+
scan validate .scan/state.json
|
|
60
|
+
scan validate .scan/report.html
|
|
61
|
+
scan compare previous-state.json .scan/state.json --json
|
|
62
|
+
scan render .scan/state.json --output .scan/rerendered.html
|
|
63
|
+
scan schema --version 1.4
|
|
64
|
+
scan egress . --privacy controlled-remote --redact strict --json
|
|
65
|
+
scan bench
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The standalone HTML report is static and useful without JavaScript. Its only script block is inert `application/json` state with ID `project-anatomy-state`; visible count markers are validated against that embedded state. `scan egress` is preview-only: it reports selected/omitted files, selected bytes and redaction counts, and performs **no network action**. Use `--sensitive-path "pattern/**"` to keep declared path names out of canonical state and egress selection.
|
|
69
|
+
|
|
70
|
+
### Scan modes
|
|
71
|
+
|
|
72
|
+
Scan exposes explicit coverage promises instead of silently sampling:
|
|
73
|
+
|
|
74
|
+
- `--mode quick` is triage: it inventories the project while suppressing common dependency/build/cache trees and Git internals from ordinary content analysis. A quick scan is always presented as partial and its continuation state points to `deep`.
|
|
75
|
+
- `--mode deep` is the default whole-project first-party mode. It broadly accounts for safely readable project content while treating `.git/**` as repository provenance rather than normal source.
|
|
76
|
+
- `--mode forensic` opts repository internals back in for provenance-heavy or historical investigation. Explicit user exclusions and normal safety/resource boundaries still apply.
|
|
77
|
+
|
|
78
|
+
Git repositories record bounded HEAD/branch/commit and sanitized remote metadata separately. Scan deliberately does not invoke Git status, hooks, filesystem monitors or target-configured helpers merely to determine clean/dirty state; that field is recorded as `not_assessed` unless established by an authorized higher-level analyzer.
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
scan . --offline --mode quick
|
|
82
|
+
scan . --offline --mode deep
|
|
83
|
+
scan . --offline --mode forensic
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Project configuration
|
|
87
|
+
|
|
88
|
+
Optional configuration lives at `.scan/config.toml`. Precedence is **CLI arguments > project config > built-in defaults**.
|
|
89
|
+
|
|
90
|
+
```toml
|
|
91
|
+
[scan]
|
|
92
|
+
privacy = "offline"
|
|
93
|
+
redact = "standard"
|
|
94
|
+
mode = "deep"
|
|
95
|
+
max_file_bytes = 5000000
|
|
96
|
+
max_total_bytes = 250000000
|
|
97
|
+
follow_internal_links = false
|
|
98
|
+
|
|
99
|
+
[exclude]
|
|
100
|
+
patterns = ["vendor/**"]
|
|
101
|
+
|
|
102
|
+
[baseline]
|
|
103
|
+
mode = "auto" # auto | none
|
|
104
|
+
reuse = true
|
|
105
|
+
max_state_bytes = 64000000
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Behavior-affecting resolved configuration is included in the canonical configuration digest. An explicit `--baseline PATH` is invocation-only and is never persisted automatically. Use `--baseline none` to disable comparison for a run; `--no-reuse` records that prior evidence must not be reused. Scan configuration does not require secrets.
|
|
109
|
+
|
|
110
|
+
See [explicit semantic continuation](references/semantic-continuation.md) for current producer/check registration and bounded worktree metadata authorization. Baselines never authorize their own semantic producers.
|
|
111
|
+
|
|
112
|
+
### Semantic builder API
|
|
113
|
+
|
|
114
|
+
Semantic agents can extend valid deterministic state without hand-authoring nested JSON. `SemanticStateBuilder` provides typed record helpers for components, evidence, relationships, findings, controls, unknowns, actions and checks; scalar/string-array references are normalized, generated IDs are deterministic, and bad references fail with the record ID and field path. The strict Scan validator still runs on `build()`.
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from scan_core import SemanticStateBuilder
|
|
118
|
+
|
|
119
|
+
builder = SemanticStateBuilder.from_state(core_state)
|
|
120
|
+
evidence_id = builder.add_evidence(
|
|
121
|
+
artifact_id=artifact["id"],
|
|
122
|
+
locator=artifact["locator"],
|
|
123
|
+
kind="static",
|
|
124
|
+
claim="Configuration path was reviewed",
|
|
125
|
+
result="The path is resolved locally",
|
|
126
|
+
method="semantic source review",
|
|
127
|
+
limitations="Runtime behavior was not observed",
|
|
128
|
+
source_digest=artifact["content_identity"],
|
|
129
|
+
producer_kind="local-model",
|
|
130
|
+
producer_name="review-agent",
|
|
131
|
+
producer_version="1",
|
|
132
|
+
)
|
|
133
|
+
builder.add_finding(
|
|
134
|
+
title="Example finding",
|
|
135
|
+
impact="Explain the user-visible consequence",
|
|
136
|
+
severity="medium",
|
|
137
|
+
confidence="high",
|
|
138
|
+
verification_state="static",
|
|
139
|
+
artifact_ids=artifact["id"],
|
|
140
|
+
evidence_ids=evidence_id,
|
|
141
|
+
uncertainty="Runtime behavior remains unverified",
|
|
142
|
+
recommendation="Address the evidenced condition",
|
|
143
|
+
safe_verification="Re-read the affected source and validate the state",
|
|
144
|
+
)
|
|
145
|
+
semantic_state = builder.build()
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`upgrade_semantic_state(core_state)` is a convenience alias for starting the same builder from deterministic state. Raw canonical JSON remains supported for advanced callers.
|
|
149
|
+
|
|
150
|
+
### Evidence freshness and safe reuse
|
|
151
|
+
|
|
152
|
+
Every run rebuilds the current inventory, hashes and provenance evidence fresh. Prior **higher-level static evidence** is considered for reuse only when its artifact/content identity is unchanged, its producer and producer version exactly match an available current producer, its check identity/definition still matches, its evidence class is explicitly reusable, and the current privacy policy can represent it safely. Runtime, observed, deployment/live-state and time-sensitive evidence is never automatically reused in v0.3.
|
|
153
|
+
|
|
154
|
+
New semantic evidence created through `SemanticStateBuilder` is marked fresh. Reused evidence retains its original observation time, depth and limitations and is marked `verified_reuse`; it never upgrades `content_read` to `analyzed`, an unfinished check to assessed, or static evidence to runtime verification. The state and HTML report expose fresh, reused and rejected-reuse counts separately. Current redaction/sensitive-path policy always wins over older baseline content.
|
|
155
|
+
|
|
156
|
+
### ScanBench v1
|
|
157
|
+
|
|
158
|
+
`scan bench` runs 12 mandatory synthetic adversarial fixtures covering hidden files, escaping symlinks, prompt injection, redaction, hostile filenames, unreadable content, archives, unsupported binaries, generated/vendor files, resource boundaries and false runtime claims. Results are reported separately for **inventory completeness, state integrity, evidence correctness, privacy integrity, and safety-boundary compliance**. ScanBench deliberately does **not** calculate a blended quality score.
|
|
159
|
+
|
|
160
|
+
Run one fixture with `scan bench FIXTURE`. The installed wheel carries the same canonical fixture data, so this works outside the source checkout as well.
|
|
161
|
+
|
|
162
|
+

|
|
163
|
+
|
|
164
|
+
[Explore the synthetic fixture](examples/demo-project/README.md) · [Download the example HTML report](examples/demo-report.html) · [Read the report contract](references/report-contract.md)
|
|
165
|
+
|
|
166
|
+
> **Demo disclosure:** The linked report is a hand-reviewed **synthetic worked example** generated from five fictional files. It demonstrates the Scan 1.2 format and validator, **not** a claim that an autonomous agent scanned a real repository. The example did not execute the inspected code.
|
|
167
|
+
|
|
168
|
+
## Historical synthetic proof
|
|
169
|
+
|
|
170
|
+
The historical report validator wrapper requires **Python 3.11+**, like Scan Core: it imports the current package (including `tomllib`). The validator and its tests use the standard library. Historical schema compatibility does not imply compatibility with older Python runtimes.
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
git clone https://github.com/legendteddy/scan.git
|
|
174
|
+
cd scan
|
|
175
|
+
python scripts/validate_report.py examples/demo-report.html
|
|
176
|
+
python scripts/build_demo_report.py --check
|
|
177
|
+
python -m unittest discover -s scripts -p "test_*.py" -v
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Expected: the example report passes the structural contract, the generated HTML matches the checked-in version, and the validator tests pass. Open `examples/demo-report.html` **locally in a browser** to explore it. GitHub's source viewer is not an HTML report host.
|
|
181
|
+
|
|
182
|
+
The validator verifies schema, typed references, evidence origins and coverage accounting. A **PASS is not a factual audit, a runtime test or a security guarantee**.
|
|
183
|
+
|
|
184
|
+
## Install as an agent skill
|
|
185
|
+
|
|
186
|
+
Scan also remains an instruction-based agent skill. Copy or clone this repository into the skill directory used by your compatible agent, then ask the agent to inspect a target.
|
|
187
|
+
|
|
188
|
+
For environments that discover user skills in `~/.agents/skills/`:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
mkdir -p ~/.agents/skills
|
|
192
|
+
git clone https://github.com/legendteddy/scan.git ~/.agents/skills/scan
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
On Windows PowerShell:
|
|
196
|
+
|
|
197
|
+
```powershell
|
|
198
|
+
New-Item -ItemType Directory -Force "$HOME\.agents\skills" | Out-Null
|
|
199
|
+
git clone https://github.com/legendteddy/scan.git "$HOME\.agents\skills\scan"
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Skill locations, invocation and tool access vary by agent. Consult your host's skill documentation; copying a folder alone does not guarantee the host will load it.
|
|
203
|
+
|
|
204
|
+
Example requests to a compatible agent:
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
Scan this entire repository and show what you could not verify.
|
|
208
|
+
Inspect this project and produce an evidence-backed HTML report.
|
|
209
|
+
Use $scan to map this package's architecture, risks and unknowns.
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The governing instructions are in [SKILL.md](SKILL.md). Scan asks for explicit authorization before running untrusted target code or modifying the inspected target.
|
|
213
|
+
|
|
214
|
+
## What the example shows
|
|
215
|
+
|
|
216
|
+
The fictional **Pocket Ledger** CSV totaler has five source files. Its worked report includes a source-linked concern about floating-point amounts, a missing malformed-input test gap, 14 accounted-for check categories, and explicit unanswered questions.
|
|
217
|
+
|
|
218
|
+
The report's static analysis of the five fixture files is complete **within that narrow scope**, but its broader checks are not complete. That distinction is the point of the demonstration.
|
|
219
|
+
|
|
220
|
+
To regenerate the sample after editing the fixture, update the snapshot time and evidence anchors in `scripts/build_demo_report.py`, then run:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
python scripts/build_demo_report.py
|
|
224
|
+
python scripts/validate_report.py examples/demo-report.html
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Optional visual QA and screenshot refresh: `python scripts/capture_preview.py` (requires Playwright and Chromium; not needed for Scan or CI).
|
|
228
|
+
|
|
229
|
+
## Repository map
|
|
230
|
+
|
|
231
|
+
```text
|
|
232
|
+
SKILL.md Agent instructions and safety boundaries
|
|
233
|
+
pyproject.toml Scan Core package metadata and `scan` entry point
|
|
234
|
+
src/scan_core/ v0.3 deterministic core package
|
|
235
|
+
src/scan_core/baseline.py Local-only bounded baseline resolver
|
|
236
|
+
src/scan_core/compare.py Pure deterministic 1.3/1.4 state comparison
|
|
237
|
+
src/scan_core/git_change.py Local-only advisory Git changed-scope integration
|
|
238
|
+
src/scan_core/reuse.py Strict evidence freshness/reuse decision engine
|
|
239
|
+
src/scan_core/render.py Validated canonical-state HTML renderer
|
|
240
|
+
src/scan_core/scanbench.py ScanBench v1 deterministic harness
|
|
241
|
+
src/scan_core/settings.py `.scan/config.toml` loader and precedence defaults
|
|
242
|
+
src/scan_core/schemas/ Bundled structural schemas 1.2, 1.3 and 1.4
|
|
243
|
+
src/scan_core/report/shell.html Packaged self-contained report shell
|
|
244
|
+
scanbench/fixtures/ 12 mandatory adversarial/ground-truth v1 fixtures
|
|
245
|
+
tests/ Packaged core/contract regression tests
|
|
246
|
+
agents/openai.yaml Skill metadata
|
|
247
|
+
assets/report-shell.html Self-contained HTML dashboard template
|
|
248
|
+
assets/report-components.html Report component patterns
|
|
249
|
+
assets/demo-preview.png Screenshot of the synthetic worked report
|
|
250
|
+
assets/social-preview.png Upload-ready GitHub social image (1280 × 640)
|
|
251
|
+
references/ Inspection lenses, coverage and schema contracts
|
|
252
|
+
scripts/validate_report.py Backward-compatible Scan 1.2 validator wrapper
|
|
253
|
+
scripts/test_validate_report.py Frozen 1.2 validator regression tests
|
|
254
|
+
scripts/build_demo_report.py Reproducible synthetic example generator
|
|
255
|
+
examples/demo-project/ Fictional five-file project
|
|
256
|
+
examples/demo-report.html Validated, self-contained Scan 1.2 example
|
|
257
|
+
launch/launch-kit.md Draft launch copy and approval checklist
|
|
258
|
+
docs/v0.2-technical-spec.md Approved standalone Scan Core + CLI contract
|
|
259
|
+
docs/v0.2-compatibility.md Python/schema/config/ScanBench compatibility boundary
|
|
260
|
+
docs/v0.3-technical-spec.md Approved repeat-scan baseline/diff contract
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## Contribute and report security issues
|
|
264
|
+
|
|
265
|
+
Contributions that strengthen evidence discipline, safety, inspection depth, portability, accessibility or validator correctness are welcome. Read [CONTRIBUTING.md](CONTRIBUTING.md) and [SECURITY.md](SECURITY.md).
|
|
266
|
+
|
|
267
|
+
MIT licensed — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=77"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "scan-skill"
|
|
7
|
+
version = "0.3.1"
|
|
8
|
+
description = "Evidence-backed whole-project inspection core and agent skill"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "legendteddy" }]
|
|
14
|
+
dependencies = []
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Development Status :: 3 - Alpha",
|
|
17
|
+
"Programming Language :: Python :: 3",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.urls]
|
|
24
|
+
Homepage = "https://github.com/legendteddy/scan"
|
|
25
|
+
Repository = "https://github.com/legendteddy/scan"
|
|
26
|
+
Issues = "https://github.com/legendteddy/scan/issues"
|
|
27
|
+
|
|
28
|
+
[project.scripts]
|
|
29
|
+
scan = "scan_core.cli:main"
|
|
30
|
+
|
|
31
|
+
[tool.setuptools]
|
|
32
|
+
package-dir = {"" = "src", "scanbench_data" = "scanbench"}
|
|
33
|
+
packages = ["scan_core", "scan_core.report", "scan_core.schemas", "scanbench_data", "scanbench_data.fixtures"]
|
|
34
|
+
|
|
35
|
+
[tool.setuptools.package-data]
|
|
36
|
+
"scan_core.report" = ["*.html"]
|
|
37
|
+
"scan_core.schemas" = ["*.json"]
|
|
38
|
+
"scanbench_data" = [
|
|
39
|
+
"manifest.json",
|
|
40
|
+
"README.md",
|
|
41
|
+
"fixtures/*/fixture.json",
|
|
42
|
+
"fixtures/*/expected.json",
|
|
43
|
+
"fixtures/*/README.md",
|
|
44
|
+
"fixtures/*/project/*",
|
|
45
|
+
"fixtures/*/project/.*",
|
|
46
|
+
"fixtures/*/project/*/*",
|
|
47
|
+
]
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# ScanBench v1
|
|
2
|
+
|
|
3
|
+
ScanBench is Scan's deterministic release gate. It uses synthetic fixtures and objective assertions across five independent dimensions:
|
|
4
|
+
|
|
5
|
+
- inventory completeness
|
|
6
|
+
- state integrity
|
|
7
|
+
- evidence correctness
|
|
8
|
+
- privacy integrity
|
|
9
|
+
- safety-boundary compliance
|
|
10
|
+
|
|
11
|
+
There is no blended overall quality score. Run all fixtures with `scan bench` or one fixture with `scan bench FIXTURE`. Fixture source is untrusted data and is never executed.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Packaged ScanBench v1 fixture data; not an executable target package."""
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Packaged ScanBench fixture data namespace."""
|