@namewta/speculo 1.0.5 → 1.0.7
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.
- package/README.md +1 -1
- package/dist/src/kernel.d.ts +23 -2
- package/dist/src/kernel.js +9 -0
- package/dist/src/kernel.js.map +1 -1
- package/dist/src/ops-resources.d.ts +3 -0
- package/dist/src/ops-resources.js +188 -0
- package/dist/src/ops-resources.js.map +1 -0
- package/dist/src/refresh.js +20 -2
- package/dist/src/refresh.js.map +1 -1
- package/dist/src/structured.js +7 -0
- package/dist/src/structured.js.map +1 -1
- package/dist/src/workflows.js +1 -1
- package/dist/src/workflows.js.map +1 -1
- package/package.json +1 -1
- package/template/.speculo/README.md +3 -3
- package/template/.speculo/kernel/README.md +3 -0
- package/template/.speculo/kernel/checkpoint.schema.json +138 -4
- package/template/commands/archive-and-consolidate.md +5 -1
- package/template/commands/status.md +2 -2
- package/template/workflows/ops/D-project-deploy/D-project-deploy.md +34 -0
- package/template/workflows/ops/H-host-manage/H-host-manage.md +30 -0
- package/template/workflows/ops/I-initialize/I-initialize.md +28 -0
- package/template/workflows/ops/INDEX.md +15 -17
- package/template/workflows/ops/README.md +59 -93
- package/template/workflows/ops/_state/status.json +15 -3
- package/template/workflows/ops/common/CAPABILITIES.md +23 -0
- package/template/workflows/ops/common/USAGE.md +112 -0
- package/template/workflows/ops/common/examples/README.md +7 -0
- package/template/workflows/ops/common/examples/binding.example.json +12 -0
- package/template/workflows/ops/common/examples/compose-app.example.json +56 -0
- package/template/workflows/ops/common/examples/credential.example.json +9 -0
- package/template/workflows/ops/common/examples/environment-request.example.json +7 -0
- package/template/workflows/ops/common/examples/register.example.json +44 -0
- package/template/workflows/ops/common/examples/shared-allocation.example.json +37 -0
- package/template/workflows/ops/common/rules/activation-and-memory.md +5 -20
- package/template/workflows/ops/common/rules/persistence-and-secrets.md +27 -0
- package/template/workflows/ops/common/rules/recovery.md +15 -0
- package/template/workflows/ops/common/rules/shared-services.md +13 -0
- package/template/workflows/ops/common/schemas/allocation.schema.json +92 -0
- package/template/workflows/ops/common/schemas/approval.schema.json +41 -21
- package/template/workflows/ops/common/schemas/binding.schema.json +73 -0
- package/template/workflows/ops/common/schemas/deployment.schema.json +244 -0
- package/template/workflows/ops/common/schemas/host.schema.json +88 -0
- package/template/workflows/ops/common/schemas/plan.schema.json +1573 -0
- package/template/workflows/ops/common/schemas/project.schema.json +55 -11
- package/template/workflows/ops/common/schemas/spec.schema.json +1032 -0
- package/template/workflows/ops/common/schemas/status.schema.json +758 -17
- package/template/workflows/ops/common/service-profiles/custom.md +5 -0
- package/template/workflows/ops/common/service-profiles/docker-engine.md +11 -0
- package/template/workflows/ops/common/service-profiles/minio.md +7 -0
- package/template/workflows/ops/common/service-profiles/mysql.md +7 -0
- package/template/workflows/ops/common/service-profiles/redis.md +7 -0
- package/template/workflows/ops/common/templates/CONTROLLER-RECORD.md +13 -0
- package/template/workflows/ops/common/templates/EXECUTION-PLAN.md +15 -0
- package/template/workflows/ops/common/templates/HOST-README.md +11 -0
- package/template/workflows/ops/common/templates/PROJECT-README.md +15 -0
- package/template/workflows/ops/common/tests/test_ops.mjs +752 -0
- package/template/workflows/ops/common/tools/bootstrap.ps1 +18 -0
- package/template/workflows/ops/common/tools/bootstrap.sh +27 -0
- package/template/workflows/ops/common/tools/demo-local.mjs +101 -0
- package/template/workflows/ops/common/tools/ops.mjs +4 -0
- package/template/workflows/ops/common/tools/opslib/agent.mjs +873 -0
- package/template/workflows/ops/common/tools/opslib/cli.mjs +311 -0
- package/template/workflows/ops/common/tools/opslib/core.mjs +393 -0
- package/template/workflows/ops/common/tools/opslib/docs.mjs +252 -0
- package/template/workflows/ops/common/tools/opslib/execution.mjs +378 -0
- package/template/workflows/ops/common/tools/opslib/host_recipes.mjs +109 -0
- package/template/workflows/ops/common/tools/opslib/model.mjs +272 -0
- package/template/workflows/ops/common/tools/opslib/native_windows.mjs +36 -0
- package/template/workflows/ops/common/tools/opslib/planner.mjs +687 -0
- package/template/workflows/ops/common/tools/opslib/services.mjs +76 -0
- package/template/workflows/ops/common/tools/opslib/sources.mjs +56 -0
- package/template/workflows/ops/common/tools/opslib/transport.mjs +127 -0
- package/template/workflows/ops/common/tools/validate-ops.mjs +43 -1012
- package/template/workflows/ops/manifest.json +60 -1
- package/template/workflows/ops/runtime-contract.json +1 -6
- package/template/workflows/ops/A-archive-and-learn/A-archive-and-learn.md +0 -73
- package/template/workflows/ops/A-archive-and-learn/promotion-plan-template.md +0 -41
- package/template/workflows/ops/A-archive-and-learn/retrospective-template.md +0 -53
- package/template/workflows/ops/E-execute-and-stabilize/E-execute-and-stabilize.md +0 -82
- package/template/workflows/ops/E-execute-and-stabilize/attempt-summary-template.md +0 -44
- package/template/workflows/ops/E-execute-and-stabilize/diagnosis-template.md +0 -24
- package/template/workflows/ops/E-execute-and-stabilize/handoff-template.md +0 -32
- package/template/workflows/ops/E-execute-and-stabilize/rollback-template.md +0 -26
- package/template/workflows/ops/E-execute-and-stabilize/verification-state-template.json +0 -30
- package/template/workflows/ops/E-execute-and-stabilize/verification-template.md +0 -55
- package/template/workflows/ops/H-computer-hygiene/H-computer-hygiene.md +0 -105
- package/template/workflows/ops/H-computer-hygiene/examples/README.md +0 -9
- package/template/workflows/ops/H-computer-hygiene/examples/linux/2026-09-14.environment.md +0 -45
- package/template/workflows/ops/H-computer-hygiene/examples/linux/2026-09-14.json +0 -970
- package/template/workflows/ops/H-computer-hygiene/examples/linux/2026-09-14.md +0 -216
- package/template/workflows/ops/H-computer-hygiene/examples/macos/2026-09-14.environment.md +0 -45
- package/template/workflows/ops/H-computer-hygiene/examples/macos/2026-09-14.json +0 -970
- package/template/workflows/ops/H-computer-hygiene/examples/macos/2026-09-14.md +0 -216
- package/template/workflows/ops/H-computer-hygiene/examples/windows/2026-09-14.environment.md +0 -45
- package/template/workflows/ops/H-computer-hygiene/examples/windows/2026-09-14.json +0 -969
- package/template/workflows/ops/H-computer-hygiene/examples/windows/2026-09-14.md +0 -216
- package/template/workflows/ops/H-computer-hygiene/references/00-sources.md +0 -58
- package/template/workflows/ops/H-computer-hygiene/references/01-safety.md +0 -52
- package/template/workflows/ops/H-computer-hygiene/references/10-windows.md +0 -47
- package/template/workflows/ops/H-computer-hygiene/references/11-macos.md +0 -46
- package/template/workflows/ops/H-computer-hygiene/references/12-linux.md +0 -13
- package/template/workflows/ops/H-computer-hygiene/references/20-toolchains.md +0 -83
- package/template/workflows/ops/H-computer-hygiene/references/21-path-migration.md +0 -64
- package/template/workflows/ops/H-computer-hygiene/references/22-repositories.md +0 -35
- package/template/workflows/ops/H-computer-hygiene/references/30-software-removal.md +0 -41
- package/template/workflows/ops/H-computer-hygiene/references/40-report-spec.md +0 -54
- package/template/workflows/ops/H-computer-hygiene/references/50-speculo-integration.md +0 -26
- package/template/workflows/ops/H-computer-hygiene/references/source-register.json +0 -406
- package/template/workflows/ops/H-computer-hygiene/rules/catalog.json +0 -191
- package/template/workflows/ops/H-computer-hygiene/scripts/hygiene.py +0 -1348
- package/template/workflows/ops/H-computer-hygiene/scripts/run.ps1 +0 -7
- package/template/workflows/ops/H-computer-hygiene/scripts/run.sh +0 -5
- package/template/workflows/ops/H-computer-hygiene/templates/config.example.json +0 -13
- package/template/workflows/ops/H-computer-hygiene/templates/maven-settings.fragment.xml +0 -6
- package/template/workflows/ops/H-computer-hygiene/templates/native-evidence.example.json +0 -19
- package/template/workflows/ops/H-computer-hygiene/tests/cli_smoke.py +0 -65
- package/template/workflows/ops/H-computer-hygiene/tests/make_examples.py +0 -114
- package/template/workflows/ops/H-computer-hygiene/tests/test_hygiene.py +0 -486
- package/template/workflows/ops/I-intake-and-assess/I-intake-and-assess.md +0 -73
- package/template/workflows/ops/I-intake-and-assess/change-status-template.json +0 -26
- package/template/workflows/ops/I-intake-and-assess/collector-catalog.md +0 -28
- package/template/workflows/ops/I-intake-and-assess/deployment-dossier-template.md +0 -62
- package/template/workflows/ops/I-intake-and-assess/global-change-status-template.json +0 -26
- package/template/workflows/ops/I-intake-and-assess/project-detection.md +0 -38
- package/template/workflows/ops/I-intake-and-assess/request-template.md +0 -44
- package/template/workflows/ops/I-intake-and-assess/system-report-template.md +0 -34
- package/template/workflows/ops/I-intake-and-assess/target-profile-template.json +0 -24
- package/template/workflows/ops/P-plan-and-approve/P-plan-and-approve.md +0 -72
- package/template/workflows/ops/P-plan-and-approve/plan-review-template.md +0 -78
- package/template/workflows/ops/_state/archive/.gitkeep +0 -1
- package/template/workflows/ops/_state/changes/.gitkeep +0 -1
- package/template/workflows/ops/common/rules/artifact-contract.md +0 -38
- package/template/workflows/ops/common/rules/closure-and-learning.md +0 -27
- package/template/workflows/ops/common/rules/evidence-and-redaction.md +0 -22
- package/template/workflows/ops/common/rules/execution-loop.md +0 -27
- package/template/workflows/ops/common/rules/path-and-scope-contract.md +0 -21
- package/template/workflows/ops/common/rules/plan-and-approval.md +0 -25
- package/template/workflows/ops/common/rules/project-and-change-scope.md +0 -20
- package/template/workflows/ops/common/rules/target-profile-and-release-gates.md +0 -44
- package/template/workflows/ops/common/schemas/attempt.schema.json +0 -42
- package/template/workflows/ops/common/schemas/change-status.schema.json +0 -43
- package/template/workflows/ops/common/schemas/deployment-model.schema.json +0 -26
- package/template/workflows/ops/common/schemas/implementation-plan.schema.json +0 -221
- package/template/workflows/ops/common/schemas/inventory-snapshot.schema.json +0 -31
- package/template/workflows/ops/common/schemas/journal-event.schema.json +0 -22
- package/template/workflows/ops/common/schemas/promotion-approval.schema.json +0 -20
- package/template/workflows/ops/common/schemas/promotion-manifest.schema.json +0 -22
- package/template/workflows/ops/common/schemas/target-profile.schema.json +0 -32
- package/template/workflows/ops/common/schemas/verification-state.schema.json +0 -30
- package/template/workflows/ops/common/tools/close-change.mjs +0 -177
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
# Read-only audit wrapper. Run with a trusted Python 3.10+ interpreter.
|
|
2
|
-
[CmdletBinding()]
|
|
3
|
-
param([Parameter(ValueFromRemainingArguments = $true)][string[]]$AuditArgs)
|
|
4
|
-
$ErrorActionPreference = 'Stop'
|
|
5
|
-
$scriptFile = Join-Path $PSScriptRoot 'hygiene.py'
|
|
6
|
-
& python $scriptFile audit @AuditArgs
|
|
7
|
-
exit $LASTEXITCODE
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema_version": 1,
|
|
3
|
-
"project_roots": [],
|
|
4
|
-
"exclude_roots": [],
|
|
5
|
-
"target_root": null,
|
|
6
|
-
"max_entries_per_tree": 20000,
|
|
7
|
-
"max_entries_total": 200000,
|
|
8
|
-
"seconds_per_tree": 3.0,
|
|
9
|
-
"seconds_total": 90.0,
|
|
10
|
-
"project_depth": 3,
|
|
11
|
-
"min_age_days": 14,
|
|
12
|
-
"large_file_mib": 512
|
|
13
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
<!-- EXAMPLE ONLY: merge localRepository into the existing settings.xml.
|
|
2
|
-
Do not replace the whole file: servers/profiles/mirrors may be essential.
|
|
3
|
-
Replace DEVROOT with a verified absolute path; back up local-only artifacts. -->
|
|
4
|
-
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0">
|
|
5
|
-
<localRepository>DEVROOT/data/maven/repository</localRepository>
|
|
6
|
-
</settings>
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema_version": 1,
|
|
3
|
-
"record_kind": "TEMPLATE_NOT_REAL_EVIDENCE",
|
|
4
|
-
"scan_id": "REPLACE_WITH_REAL_SCAN_ID",
|
|
5
|
-
"collected_at": null,
|
|
6
|
-
"tool": "go",
|
|
7
|
-
"trusted_executable_path": "REPLACE_WITH_VERIFIED_ABSOLUTE_PATH",
|
|
8
|
-
"user_authorized_execution": false,
|
|
9
|
-
"argv": ["env", "GOPATH", "GOBIN", "GOCACHE", "GOMODCACHE", "GOROOT", "GOENV"],
|
|
10
|
-
"executed": false,
|
|
11
|
-
"exit_code": null,
|
|
12
|
-
"version": null,
|
|
13
|
-
"allowed_path_values": {},
|
|
14
|
-
"effective_scope": "unknown until actually queried; CLI/project/IDE may differ",
|
|
15
|
-
"full_stdout_recorded": false,
|
|
16
|
-
"full_environment_recorded": false,
|
|
17
|
-
"source_document_verified_at": null,
|
|
18
|
-
"limitations": ["Example only. Starting even a query can invoke shims, plugins, downloads or telemetry."]
|
|
19
|
-
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Linux-only end-to-end CLI test in a temporary HOME; no real account scan."""
|
|
3
|
-
import hashlib
|
|
4
|
-
import json
|
|
5
|
-
import os
|
|
6
|
-
import platform
|
|
7
|
-
import subprocess
|
|
8
|
-
import sys
|
|
9
|
-
import tempfile
|
|
10
|
-
import time
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def main():
|
|
15
|
-
if platform.system() != "Linux":
|
|
16
|
-
print(json.dumps({"status": "skipped", "reason": "Linux fixture test; native platform acceptance is separate"}))
|
|
17
|
-
return 0
|
|
18
|
-
script = Path(__file__).resolve().parents[1] / "scripts/hygiene.py"
|
|
19
|
-
stages = []
|
|
20
|
-
with tempfile.TemporaryDirectory(prefix="hygiene-cli-fixture-") as tmp:
|
|
21
|
-
root = Path(tmp).resolve()
|
|
22
|
-
home = root / "home"
|
|
23
|
-
cache = home / ".npm/_cacache"
|
|
24
|
-
payload = cache / "content-v2/aa/data"
|
|
25
|
-
payload.parent.mkdir(parents=True)
|
|
26
|
-
payload.write_bytes(b"CLI-FIXTURE-ONLY\n")
|
|
27
|
-
original = hashlib.sha256(payload.read_bytes()).hexdigest()
|
|
28
|
-
old = time.time() - 40 * 86400
|
|
29
|
-
for path in sorted(cache.rglob("*"), key=lambda x: len(x.parts), reverse=True):
|
|
30
|
-
os.utime(path, (old, old))
|
|
31
|
-
os.utime(cache, (old, old))
|
|
32
|
-
(home / "bin").mkdir()
|
|
33
|
-
env = {"HOME": str(home), "PATH": str(home / "bin"), "LANG": "C.UTF-8", "PYTHONDONTWRITEBYTECODE": "1"}
|
|
34
|
-
def call(stage, args, expected=0, raw=False):
|
|
35
|
-
result = subprocess.run([sys.executable, str(script), *args], env=env, cwd=root,
|
|
36
|
-
capture_output=True, text=True, timeout=30, check=False)
|
|
37
|
-
stages.append({"stage": stage, "exit_code": result.returncode, "expected": expected})
|
|
38
|
-
if result.returncode != expected:
|
|
39
|
-
raise RuntimeError(f"{stage} failed: {result.stderr}")
|
|
40
|
-
return result.stdout.strip() if raw else (json.loads(result.stdout) if result.stdout.strip() else None)
|
|
41
|
-
version = call("version", ["--version"], raw=True)
|
|
42
|
-
files = call("audit", ["audit", "--output", str(root / "reports")])
|
|
43
|
-
assert payload.exists() and not (home / ".speculo-hygiene").exists()
|
|
44
|
-
review = call("review", ["review", "--plan", files["plan"]])
|
|
45
|
-
assert len(review["actions"]) == 1
|
|
46
|
-
approval = root / "approval.json"
|
|
47
|
-
result = call("approve", ["approve", "--plan", files["plan"], "--ids", review["actions"][0]["id"],
|
|
48
|
-
"--output", str(approval), "--ack", "I_REVIEWED_EACH_ID"])
|
|
49
|
-
args = ["apply", "--plan", files["plan"], "--approval", str(approval), "--confirm", result["apply_confirmation"]]
|
|
50
|
-
call("missing-tools-closed-refused", args, expected=2)
|
|
51
|
-
assert payload.exists()
|
|
52
|
-
applied = call("apply", [*args, "--tools-closed"])
|
|
53
|
-
assert not payload.exists() and applied["freed_disk_space"] is False
|
|
54
|
-
preview = call("restore-preview", ["restore", "--receipt", applied["receipt"]])
|
|
55
|
-
call("restore", ["restore", "--receipt", applied["receipt"], "--confirm", preview["confirmation"]])
|
|
56
|
-
assert payload.exists() and hashlib.sha256(payload.read_bytes()).hexdigest() == original
|
|
57
|
-
output = {"status": "passed", "fixture_only": True, "temporary_home_only": True,
|
|
58
|
-
"version": version, "stages": stages, "restored_payload_hash_matches": True,
|
|
59
|
-
"default_audit_no_source_mutation": True, "no_permanent_deletion": True}
|
|
60
|
-
print(json.dumps(output, ensure_ascii=False, indent=2))
|
|
61
|
-
return 0
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if __name__ == "__main__":
|
|
65
|
-
raise SystemExit(main())
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Build explicitly synthetic examples without reading the real user's home/apps.
|
|
3
|
-
|
|
4
|
-
Only isolated tempfile content is audited. Native OS inventories are replaced by
|
|
5
|
-
fixture metadata. Never run this as evidence about a real computer.
|
|
6
|
-
"""
|
|
7
|
-
import importlib.util
|
|
8
|
-
import json
|
|
9
|
-
import os
|
|
10
|
-
import tempfile
|
|
11
|
-
import time
|
|
12
|
-
from pathlib import Path
|
|
13
|
-
|
|
14
|
-
WORK = Path(__file__).resolve().parents[1]
|
|
15
|
-
spec = importlib.util.spec_from_file_location("hygiene", WORK / "scripts/hygiene.py")
|
|
16
|
-
h = importlib.util.module_from_spec(spec)
|
|
17
|
-
spec.loader.exec_module(h)
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
class FixtureAuditor(h.Auditor):
|
|
21
|
-
def platform_inventory(self):
|
|
22
|
-
self.coverage.append(dict(area="applications/startup", status="SIMULATED-NOT-NATIVE",
|
|
23
|
-
detail="Synthetic application metadata only; no real registry, Applications, launchd or service reads."))
|
|
24
|
-
example = {"name": "Example Editor", "version": "1.0-fixture", "system_component": False,
|
|
25
|
-
"action": "fixture candidate; not real software and never uninstalled"}
|
|
26
|
-
if self.system == "Windows":
|
|
27
|
-
example["identity"] = "HKCU/Uninstall/FIXTURE-EXAMPLE-ID"
|
|
28
|
-
else:
|
|
29
|
-
example.update(path=str(self.home / "Applications/Example Editor.app"), bundle_id="invalid.example.editor")
|
|
30
|
-
return {"applications": [example], "startup": [], "persistent_environment": [],
|
|
31
|
-
"errors": ["Real OS inventory intentionally disabled for this example."]}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def populate(home, system):
|
|
35
|
-
h.ensure_private_dir(home)
|
|
36
|
-
for folder in ("bin-primary", "bin-old"):
|
|
37
|
-
name = "java.exe" if system == "Windows" else "java"
|
|
38
|
-
binary = home / folder / name
|
|
39
|
-
binary.parent.mkdir(parents=True)
|
|
40
|
-
binary.write_text("FIXTURE: NOT EXECUTABLE CODE")
|
|
41
|
-
binary.chmod(0o755)
|
|
42
|
-
repo = home / ".m2/repository/example/internal/1.0"
|
|
43
|
-
repo.mkdir(parents=True)
|
|
44
|
-
(repo / "internal-1.0.jar").write_bytes(b"LOCAL_ONLY_FIXTURE" * 1024)
|
|
45
|
-
(home / ".m2/settings.xml").write_text(f"<settings><localRepository>{home / '.m2/repository'}</localRepository><servers><server><password>DO_NOT_EXPORT_DEMO_SECRET</password></server></servers></settings>")
|
|
46
|
-
cargo = home / ".cargo"
|
|
47
|
-
cargo.mkdir()
|
|
48
|
-
(cargo / "credentials.toml").write_text('token="DO_NOT_EXPORT_DEMO_SECRET"')
|
|
49
|
-
(cargo / "config.toml").write_text("# protected fixture config")
|
|
50
|
-
for kind, path in h.default_cache_allowlist(home, system).items():
|
|
51
|
-
relative = {"npm-content-cache": "content-v2/aa/data", "pip-cache": "wheels/aa/demo.whl", "go-build-cache": "aa/demo-a"}[kind]
|
|
52
|
-
f = path / relative
|
|
53
|
-
f.parent.mkdir(parents=True)
|
|
54
|
-
f.write_bytes(b"regenerable-fixture-cache\n" * 2048)
|
|
55
|
-
old = time.time() - 45 * 86400
|
|
56
|
-
for child in sorted(path.rglob("*"), key=lambda p: len(p.parts), reverse=True):
|
|
57
|
-
os.utime(child, (old, old))
|
|
58
|
-
os.utime(path, (old, old))
|
|
59
|
-
project = home / "Projects/example-web"
|
|
60
|
-
project.mkdir(parents=True)
|
|
61
|
-
(project / ".git").mkdir()
|
|
62
|
-
(project / "package.json").write_text('{"packageManager":"pnpm@9.0.0"}')
|
|
63
|
-
for name in ("pnpm-lock.yaml", "package-lock.json", ".nvmrc"):
|
|
64
|
-
(project / name).write_text("fixture")
|
|
65
|
-
(project / "node_modules").mkdir()
|
|
66
|
-
(project / "node_modules/local-note.txt").write_text("May be unique data: do not auto-delete")
|
|
67
|
-
(home / ".zshrc").write_text('export JAVA_HOME="$HOME/old-jdk" # DO_NOT_EXPORT_DEMO_SECRET\n')
|
|
68
|
-
(home / ".profile").write_text('export JAVA_HOME="$HOME/new-jdk"\n')
|
|
69
|
-
downloads = home / "Downloads"
|
|
70
|
-
downloads.mkdir()
|
|
71
|
-
(downloads / "old-installer.zip").write_bytes(b"installer fixture")
|
|
72
|
-
unsafe = downloads / "source-clone"
|
|
73
|
-
unsafe.mkdir()
|
|
74
|
-
(unsafe / ".git").write_text("gitdir: ../../Projects/example-web/.git/worktrees/example")
|
|
75
|
-
delimiter = ";" if system == "Windows" else ":"
|
|
76
|
-
return {"PATH": delimiter.join(str(home / n) for n in ("bin-primary", "bin-old", "bin-primary", "missing-bin")),
|
|
77
|
-
"HOME": str(home), "LOCALAPPDATA": str(home / "AppData/Local"),
|
|
78
|
-
"JAVA_HOME": str(home / "old-jdk"), "CARGO_HOME": str(cargo),
|
|
79
|
-
"GOCACHE": str(h.default_cache_allowlist(home, system)["go-build-cache"])}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def main():
|
|
83
|
-
generated = []
|
|
84
|
-
for system, folder in (("Windows", "windows"), ("Darwin", "macos"), ("Linux", "linux")):
|
|
85
|
-
with tempfile.TemporaryDirectory(prefix="hygiene-demo-") as temporary:
|
|
86
|
-
home = Path(temporary).resolve() / "fixture-home"
|
|
87
|
-
env = populate(home, system)
|
|
88
|
-
auditor = FixtureAuditor(home=home, system=system, environ=env,
|
|
89
|
-
options={"project_roots": [str(home / "Projects"), str(home / "Downloads")], "seconds_per_tree": 10},
|
|
90
|
-
label="SYNTHETIC_FIXTURE_NOT_YOUR_COMPUTER", native_platform_reads=False)
|
|
91
|
-
report, plan = auditor.run()
|
|
92
|
-
report["host"].update(release="SIMULATED_OS_METADATA", machine="SIMULATED_ARCHITECTURE",
|
|
93
|
-
elevated=False, fingerprint="FIXTURE_NOT_FOR_APPROVAL",
|
|
94
|
-
disk_total_bytes=512 * 1024**3, disk_free_bytes=120 * 1024**3,
|
|
95
|
-
execution_context_signals={"fixture_only": True})
|
|
96
|
-
report["scope"]["limitations"].append("Disk capacity, architecture and application identity are illustrative fixture values, not real measurements.")
|
|
97
|
-
report["findings"] = [x for x in report["findings"] if x["category"] != "privilege"]
|
|
98
|
-
report["summary"]["findings"] = len(report["findings"])
|
|
99
|
-
output = WORK / "examples" / folder
|
|
100
|
-
output.mkdir(parents=True, exist_ok=True)
|
|
101
|
-
date = report["date"]
|
|
102
|
-
md = h.render_report(report, plan)
|
|
103
|
-
public = h.redact(report, home)
|
|
104
|
-
assert "DO_NOT_EXPORT_DEMO_SECRET" not in md + json.dumps(public)
|
|
105
|
-
(output / f"{date}.md").write_text(md, encoding="utf-8")
|
|
106
|
-
(output / f"{date}.json").write_bytes(h.json_bytes(public))
|
|
107
|
-
target = h.target_root(home, system, env, None)
|
|
108
|
-
(output / f"{date}.environment.md").write_text("**模拟示例,不是已执行迁移。**\n\n" + h.render_environment(report, target), encoding="utf-8")
|
|
109
|
-
generated.append({"system": system, "example": str(output / f"{date}.md"), "findings": len(report["findings"]), "quarantine_candidates": len(plan["actions"])})
|
|
110
|
-
print(json.dumps({"fixture_only": True, "generated": generated}, ensure_ascii=False, indent=2))
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if __name__ == "__main__":
|
|
114
|
-
main()
|