gabriel / musehub public
musehub_mist_push_validator.py python
85 lines 2.9 KB
Raw
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 9 days ago
1 """Hub-side validation for mist-domain pushes.
2
3 Called by ``wire_push_unpack_mpack`` before any objects are persisted when
4 ``repo.domain_id == "mist"``.
5
6 Validation contract
7 -------------------
8 Hard errors (``errors`` non-empty → push rejected 422):
9 - Null bytes in filename
10 - Path traversal sequences (``..``)
11 - Path separators (``/``, ``\\``)
12 - Control characters (0x01–0x1F, 0x7F)
13 - ANSI escape sequences
14 - Filename exceeds 255 characters
15 - Empty filename
16
17 Warnings (``warnings`` non-empty → push accepted with advisory):
18 - Unrecognised file extension (artifact type cannot be auto-detected)
19 - No file extension at all
20 """
21
22 from dataclasses import dataclass, field
23
24 from muse.plugins.mist.plugin import detect_artifact_type, validate_mist_filename
25 from musehub.types.json_types import StrDict
26
27 # Extensions whose artifact type can be reliably detected.
28 # Anything outside this set gets a warning — the mist is still accepted.
29 _KNOWN_EXTENSIONS = {
30 ".py", ".js", ".ts", ".jsx", ".tsx", ".sol", ".rs", ".go",
31 ".java", ".c", ".cpp", ".h", ".hpp", ".cs", ".rb", ".php",
32 ".swift", ".kt", ".json", ".yaml", ".yml", ".toml", ".md",
33 ".txt", ".html", ".css", ".scss", ".svg", ".xml", ".sh",
34 ".bash", ".zsh", ".fish", ".mid", ".midi", ".abi",
35 }
36
37 @dataclass
38 class MistValidationResult:
39 """Result of validating a mist snapshot manifest.
40
41 ``valid`` is ``True`` when ``errors`` is empty (warnings are non-fatal).
42 """
43 errors: list[str] = field(default_factory=list)
44 warnings: list[str] = field(default_factory=list)
45
46 @property
47 def valid(self) -> bool:
48 return len(self.errors) == 0
49
50 def validate_mist_manifest(manifest: StrDict) -> MistValidationResult:
51 """Validate all filenames in a mist snapshot manifest.
52
53 Args:
54 manifest: Mapping of ``{filename: object_id}`` from a snapshot manifest.
55
56 Returns:
57 ``MistValidationResult`` with accumulated errors and warnings.
58 Callers should reject the push when ``result.valid is False``.
59 """
60 errors: list[str] = []
61 warnings: list[str] = []
62
63 for filename in manifest:
64 # Hard gate — empty filename is always rejected.
65 if not filename:
66 errors.append("Mist filename must not be empty")
67 continue
68
69 # Hard gate — delegate to the canonical security validator.
70 try:
71 validate_mist_filename(filename)
72 except ValueError as exc:
73 errors.append(str(exc))
74 continue
75
76 # Soft gate — warn when the artifact type cannot be detected.
77 import pathlib
78 ext = pathlib.PurePosixPath(filename).suffix.lower()
79 if not ext or ext not in _KNOWN_EXTENSIONS:
80 warnings.append(
81 f"unrecognised file extension for '{filename}' — "
82 "artifact type will be stored as 'unknown'"
83 )
84
85 return MistValidationResult(errors=errors, warnings=warnings)
File History 13 commits
sha256:fc04e4cae9e1774d6a21b65c45daeed0e6787eb581d13aa1b03bfe9384a34226 Merge branch 'fix/two-column-scroll-layout' into dev Human 9 days ago
sha256:408916fc5973ba59c6e4eebaa80ebdcc801c0a63205651e25009d11548f79454 chore: bump version to 0.2.0.dev2 — nightly.2, matching muse Sonnet 4.6 patch 12 days ago
sha256:d035733f21ccff27735fddebfbbe0ed24565a32a22db8de5885402262671ecd2 chore: bump version to 0.2.0rc15 for musehub#113 fix release Sonnet 4.6 patch 15 days ago
sha256:0032d6cfa33bc3c8367436ad768e7dd0e339b4332153160247da8266cb5fa352 Merge branch 'task/version-tags-phase3-server' into dev Human 17 days ago
sha256:4669620efda9ff41c55bdefd1f7bfe1c239d468428744c84ead9957e5a003a53 merge: rescue snapshot-recovery hardening (c00aa21d) into d… Opus 4.8 minor 30 days ago
sha256:a59da49c4611b970fc4b6ae48678ce4943261c213a07ddbd73ce9201df869b4a fix: remove false-positive proposal_comments index drop fro… Sonnet 4.6 patch 34 days ago
sha256:0a240d6dbff234f07d98a28a4a9a68db702f3f9ff9260196f24219bdb1c0b6f3 feat: render markdown mists as HTML with heading anchor links Sonnet 4.6 patch 35 days ago
sha256:24a7d47486ebc4ebd1832830580e177ec6f877b48dced8c000e198cdec4ce9d6 Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 36 days ago
sha256:b9ff931d147e0114a1f17060f415b89ed551c170a91ff226c70437aa5c85f9ee Merge 'task/bump-version-rc12' into 'dev' — proposal: Bump … Human 36 days ago
sha256:d1122d21e73471879b460037b22c0b50fded7c423444a176f248428f75dac39c Merge 'task/fix-issue-pagination-cursor' into 'dev' — propo… Human 36 days ago
sha256:01e18975e73d2b3cd5b6db7929c895bef9aa6e0d4391dc5b2adfc548b41318dd Merge 'feat/adding-debug-logs-to-staging' into 'dev' — prop… Human 36 days ago
sha256:6b1949fc2797ca4c1936a637a4cbfec828ef56cf52398a2e74ca3c4f494e728f fix: use wire_bytes not mpack_bytes_raw in compute_object_b… Sonnet 4.6 patch 48 days ago
sha256:b99f2455dc346966d040133f5203297e6e3ef5803a93728a2c30568d0a0f7583 rename: delta_add → delta_upsert across wire format, models… Sonnet 4.6 patch 50 days ago