refactor(airlock): align physical directory name to workspace flat-si… - #153
refactor(airlock): align physical directory name to workspace flat-si…#153kenwalger wants to merge 1 commit into
Conversation
…bling convention Renames `packages/sovereign-sdk-airlock/` to `packages/sovereign-airlock/` to match the established directory layout of sibling packages (`sovereign-core`, `sovereign-sieve`, `sovereign-ledger`, `sovereign-edge`, `sovereign-sensor`). Distribution name (`sovereign-sdk-airlock`), import namespace (`sovereign_airlock`), and all runtime dependency declarations are unchanged. Changes: - packages/sovereign-sdk-airlock/ → packages/sovereign-airlock/ (directory rename) - Updated file-path header comments in all 7 source modules under src/sovereign_airlock/ - uv.lock: editable path references updated from packages/sovereign-sdk-airlock to packages/sovereign-airlock; re-resolved cleanly (uv lock) - README.md: workspace topography tree entry corrected - CHANGELOG.md: workspace member path reference corrected - ROADMAP.md: Phase 9.6 pyproject.toml path reference corrected Verification: 469 passed, 1 skipped. Zero regressions.
Greptile SummaryThis PR adds the
Confidence Score: 3/5The core boundary orchestration and evidence pipeline are solid, but the PolicyEngine has two functional gaps that would silently misbehave in production. The
Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Caller
participant AirlockBoundary
participant PolicyEngine
participant sieve_with_metrics
participant AirlockTelemetry
participant ReceiptBuilder
participant SovereignLedger
Caller->>AirlockBoundary: process(NormalizedPayload)
AirlockBoundary->>PolicyEngine: evaluate(payload)
PolicyEngine-->>AirlockBoundary: PolicyVerdict
alt "verdict.allowed == False"
AirlockBoundary-->>Caller: raise AirlockPolicyViolation
end
AirlockBoundary->>sieve_with_metrics: sieve_with_metrics(raw_content)
sieve_with_metrics-->>AirlockBoundary: SieveOutput
AirlockBoundary->>AirlockTelemetry: from_sieve_output(sieve_output, raw_content)
AirlockTelemetry-->>AirlockBoundary: AirlockTelemetry
AirlockBoundary->>ReceiptBuilder: build_and_commit(sieved_content, telemetry, warnings, source)
ReceiptBuilder->>SovereignLedger: append_receipt(receipt, sieved_content)
alt ledger write fails
SovereignLedger-->>ReceiptBuilder: Exception (non-fatal, logged)
end
ReceiptBuilder-->>AirlockBoundary: ForensicReceipt
AirlockBoundary-->>Caller: AirlockResult(sieved_content, telemetry, receipt, policy_warnings)
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Caller
participant AirlockBoundary
participant PolicyEngine
participant sieve_with_metrics
participant AirlockTelemetry
participant ReceiptBuilder
participant SovereignLedger
Caller->>AirlockBoundary: process(NormalizedPayload)
AirlockBoundary->>PolicyEngine: evaluate(payload)
PolicyEngine-->>AirlockBoundary: PolicyVerdict
alt "verdict.allowed == False"
AirlockBoundary-->>Caller: raise AirlockPolicyViolation
end
AirlockBoundary->>sieve_with_metrics: sieve_with_metrics(raw_content)
sieve_with_metrics-->>AirlockBoundary: SieveOutput
AirlockBoundary->>AirlockTelemetry: from_sieve_output(sieve_output, raw_content)
AirlockTelemetry-->>AirlockBoundary: AirlockTelemetry
AirlockBoundary->>ReceiptBuilder: build_and_commit(sieved_content, telemetry, warnings, source)
ReceiptBuilder->>SovereignLedger: append_receipt(receipt, sieved_content)
alt ledger write fails
SovereignLedger-->>ReceiptBuilder: Exception (non-fatal, logged)
end
ReceiptBuilder-->>AirlockBoundary: ForensicReceipt
AirlockBoundary-->>Caller: AirlockResult(sieved_content, telemetry, receipt, policy_warnings)
|
| global_cfg: dict[str, Any] = raw.get("global") or {} | ||
| self._max_token_ceiling = int(global_cfg.get("max_token_ceiling", 0)) | ||
| self._prose_tax_warning_threshold = float( | ||
| global_cfg.get("prose_tax_warning_threshold", 0.0) | ||
| ) |
There was a problem hiding this comment.
prose_tax_warning_threshold is loaded but never evaluated
_prose_tax_warning_threshold is parsed and stored from the YAML global block (and documented as a configurable knob in the README and ROADMAP), but it is never consulted anywhere in evaluate(). An operator who sets prose_tax_warning_threshold: 0.35 will never see a warning emitted — the value is silently ignored. The evaluate() method only checks _max_token_ceiling; a matching branch in _evaluate_telemetry (or directly in evaluate() after the sieve pass) is needed to honour this configuration intent.
| content: list[str] | ||
| metadata: dict[str, Any] = field(default_factory=dict) | ||
| tools: list[dict[str, Any]] = field(default_factory=list) | ||
| token_estimate: int = 0 |
There was a problem hiding this comment.
Frozen dataclass with mutable collection fields
frozen=True prevents attribute reassignment, but callers can still mutate payload.metadata["k"] = "v" or payload.tools.append(...) after construction, silently invalidating the token_estimate and any downstream governance decision that was computed against the original content. Consider typing content as tuple, using types.MappingProxyType for metadata, or adding a __post_init__ that converts them to immutable equivalents if deep immutability is a required invariant for the governance surface.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
…bling convention
Renames
packages/sovereign-sdk-airlock/topackages/sovereign-airlock/to match the established directory layout of sibling packages (sovereign-core,sovereign-sieve,sovereign-ledger,sovereign-edge,sovereign-sensor).Distribution name (
sovereign-sdk-airlock), import namespace (sovereign_airlock), and all runtime dependency declarations are unchanged.Changes:
Verification: 469 passed, 1 skipped. Zero regressions.