-
Notifications
You must be signed in to change notification settings - Fork 2
Close governance traceability tasks and finish T0-4/T0-5 hardening #188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
719442c
governance: close traceability gate depth tasks and sync evidence
mindfn 288f902
docs: add p0-gate required-check rollout checklist
mindfn b83bdc9
refactor(model): remove wildcard facade export and enforce initialize…
mindfn af2f06b
ci(p0): enforce failure-test ownership mapping and routine checks
mindfn 0095b35
refactor(facade): remove direct _internal imports from public initial…
mindfn a709b7d
Fix facade guard for relative _internal imports
mindfn ed550e8
feat(model): add standalone Anthropic adapter with direct model pass-…
mindfn 06330ef
Revert "feat(model): add standalone Anthropic adapter with direct mod…
mindfn e2a2475
merge(main): resolve #188 conflicts and address review regressions
mindfn df55503
fix(ci): unblock governance-intent-gate and checkpoint defaults facade
mindfn e2f7a8d
fix(checkpoint): preserve session context config in defaults serializ…
mindfn 9ff1dc7
fix(ci): detect directory selector overlap in failure ownership map
mindfn 17d0869
fix(ci): handle detail-claim empty change and intent-gate nounset crash
mindfn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| """Supported default checkpoint implementations and contributors. | ||
|
|
||
| This module keeps legacy checkpoint symbols importable after checkpoint internals | ||
| were consolidated into ``dare_framework.checkpoint.kernel``. | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from dataclasses import asdict | ||
| from typing import Any | ||
| from uuid import uuid4 | ||
|
|
||
| from dare_framework.context.types import Message | ||
|
|
||
| STM = "stm" | ||
| SESSION_STATE = "session_state" | ||
| SESSION_CONTEXT = "session_context" | ||
| WORKSPACE_FILES = "workspace_files" | ||
|
|
||
|
|
||
| class MemoryCheckpointStore: | ||
| """In-memory checkpoint payload store kept for facade compatibility.""" | ||
|
|
||
| def __init__(self) -> None: | ||
| self._store: dict[str, dict[str, Any]] = {} | ||
|
|
||
| def put(self, checkpoint_id: str, payload: dict[str, Any]) -> None: | ||
| self._store[checkpoint_id] = dict(payload) | ||
|
|
||
| def get(self, checkpoint_id: str) -> dict[str, Any] | None: | ||
| if checkpoint_id not in self._store: | ||
| return None | ||
| return dict(self._store[checkpoint_id]) | ||
|
|
||
| def delete(self, checkpoint_id: str) -> bool: | ||
| if checkpoint_id in self._store: | ||
| del self._store[checkpoint_id] | ||
| return True | ||
| return False | ||
|
|
||
|
|
||
| def _scope_keys(scope: Any, method_name: str) -> list[str]: | ||
| method = getattr(scope, method_name, None) | ||
| if callable(method): | ||
| values = method() | ||
| if isinstance(values, (list, tuple, set)): | ||
| return [str(v) for v in values] | ||
| if isinstance(scope, (list, tuple, set)): | ||
| return [str(v) for v in scope] | ||
| return [] | ||
|
|
||
|
|
||
| class DefaultCheckpointSaveRestore: | ||
| """Legacy save/restore coordinator over contributor payload components.""" | ||
|
|
||
| def __init__(self, store: MemoryCheckpointStore, contributors: list[Any]) -> None: | ||
| self._store = store | ||
| self._contributors = { | ||
| str(c.component_key): c | ||
| for c in contributors | ||
| if getattr(c, "component_key", None) is not None | ||
| } | ||
|
|
||
| def save(self, scope: Any, ctx: Any) -> str: | ||
| payload: dict[str, Any] = {} | ||
| for key in _scope_keys(scope, "keys_for_save"): | ||
| contributor = self._contributors.get(key) | ||
| if contributor is None: | ||
| continue | ||
| payload[key] = contributor.serialize(ctx) | ||
| checkpoint_id = uuid4().hex[:16] | ||
| self._store.put(checkpoint_id, payload) | ||
| return checkpoint_id | ||
|
|
||
| def restore(self, checkpoint_id: str, scope: Any, ctx: Any) -> None: | ||
| payload = self._store.get(checkpoint_id) | ||
| if payload is None: | ||
| raise LookupError(f"Checkpoint not found: {checkpoint_id!r}") | ||
| for key in _scope_keys(scope, "keys_for_restore"): | ||
| if key not in payload: | ||
| continue | ||
| contributor = self._contributors.get(key) | ||
| if contributor is None: | ||
| continue | ||
| contributor.deserialize_and_apply(payload[key], ctx) | ||
|
|
||
|
|
||
| class StmContributor: | ||
| """Serialize/restore short-term memory messages.""" | ||
|
|
||
| component_key = STM | ||
|
|
||
| def serialize(self, ctx: Any) -> list[dict[str, Any]]: | ||
| context = getattr(ctx, "context", None) | ||
| if context is None: | ||
| return [] | ||
| messages = context.stm_get() | ||
| return [ | ||
| { | ||
| "role": m.role, | ||
| "content": m.content, | ||
| "name": m.name, | ||
| "metadata": dict(getattr(m, "metadata", {}) or {}), | ||
| } | ||
| for m in messages | ||
| ] | ||
|
|
||
| def deserialize_and_apply(self, payload: list[Any], ctx: Any) -> None: | ||
| context = getattr(ctx, "context", None) | ||
| if context is None: | ||
| return | ||
| context.stm_clear() | ||
| for item in payload or []: | ||
| if not isinstance(item, dict): | ||
| continue | ||
| context.stm_add( | ||
| Message( | ||
| role=item.get("role", "user"), | ||
| content=item.get("content", ""), | ||
| name=item.get("name"), | ||
| metadata=dict(item.get("metadata") or {}), | ||
| ) | ||
| ) | ||
|
|
||
|
|
||
| class SessionStateContributor: | ||
| """Serialize/restore minimal session-state fields.""" | ||
|
|
||
| component_key = SESSION_STATE | ||
|
|
||
| def serialize(self, ctx: Any) -> dict[str, Any] | None: | ||
| state = getattr(ctx, "session_state", None) | ||
| if state is None: | ||
| return None | ||
| try: | ||
| return asdict(state) | ||
| except Exception: | ||
| return { | ||
| "current_milestone_idx": getattr(state, "current_milestone_idx", None), | ||
| "task_id": getattr(state, "task_id", None), | ||
| "run_id": getattr(state, "run_id", None), | ||
| } | ||
|
|
||
| def deserialize_and_apply(self, payload: Any, ctx: Any) -> None: | ||
| state = getattr(ctx, "session_state", None) | ||
| if state is None or not isinstance(payload, dict): | ||
| return | ||
| if "current_milestone_idx" in payload and hasattr(state, "current_milestone_idx"): | ||
| state.current_milestone_idx = payload["current_milestone_idx"] | ||
|
|
||
|
|
||
| class SessionContextContributor: | ||
| """Serialize session context for audit trails (restore intentionally no-op).""" | ||
|
|
||
| component_key = SESSION_CONTEXT | ||
|
|
||
| def serialize(self, ctx: Any) -> dict[str, Any] | None: | ||
| session_context = getattr(ctx, "session_context", None) | ||
| if session_context is None: | ||
| return None | ||
| try: | ||
| serialized = asdict(session_context) | ||
| except Exception: | ||
| return { | ||
| "session_id": getattr(session_context, "session_id", None), | ||
| "task_id": getattr(session_context, "task_id", None), | ||
| } | ||
| config_value = serialized.get("config") | ||
| if config_value is not None and not isinstance(config_value, dict): | ||
| try: | ||
| serialized["config"] = asdict(config_value) | ||
| except Exception: | ||
| serialized["config"] = None | ||
| return serialized | ||
|
|
||
| def deserialize_and_apply(self, payload: Any, ctx: Any) -> None: | ||
| _ = (payload, ctx) | ||
| # SessionContext is construction-time state; legacy restore path keeps this as no-op. | ||
|
|
||
|
|
||
| class WorkspaceGitContributor: | ||
| """Compatibility no-op contributor after workspace-git checkpoint removal.""" | ||
|
|
||
| component_key = WORKSPACE_FILES | ||
|
|
||
| def serialize(self, ctx: Any) -> dict[str, Any]: | ||
| _ = ctx | ||
| return {} | ||
|
|
||
| def deserialize_and_apply(self, payload: Any, ctx: Any) -> None: | ||
| _ = (payload, ctx) | ||
|
|
||
| __all__ = [ | ||
| "MemoryCheckpointStore", | ||
| "DefaultCheckpointSaveRestore", | ||
| "StmContributor", | ||
| "WorkspaceGitContributor", | ||
| "SessionStateContributor", | ||
| "SessionContextContributor", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| """Supported default embedding implementations.""" | ||
|
|
||
| from dare_framework.embedding._internal.openai_embedding import OpenAIEmbeddingAdapter | ||
|
|
||
| __all__ = ["OpenAIEmbeddingAdapter"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| """Supported default event-log implementations.""" | ||
|
|
||
| from dare_framework.event._internal.sqlite_event_log import DefaultEventLog, SQLiteEventLog | ||
|
|
||
| __all__ = ["SQLiteEventLog", "DefaultEventLog"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| """Supported default extension-point implementation.""" | ||
|
|
||
| from dare_framework.hook._internal.hook_extension_point import HookExtensionPoint | ||
|
|
||
| __all__ = ["HookExtensionPoint"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| """Supported default planner/remediator implementations.""" | ||
|
|
||
| from dare_framework.plan._internal.default_planner import DefaultPlanner | ||
| from dare_framework.plan._internal.default_remediator import DefaultRemediator | ||
|
|
||
| __all__ = ["DefaultPlanner", "DefaultRemediator"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| """Supported default transport channel adapters.""" | ||
|
|
||
| from dare_framework.transport._internal import ( | ||
| DefaultAgentChannel, | ||
| DirectClientChannel, | ||
| StdioClientChannel, | ||
| WebSocketClientChannel, | ||
| ) | ||
|
|
||
| __all__ = [ | ||
| "DefaultAgentChannel", | ||
| "DirectClientChannel", | ||
| "StdioClientChannel", | ||
| "WebSocketClientChannel", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Importing
DefaultSecurityBoundaryfromdare_framework.security.implchanges the behavior exposed by the public facade:implaliasesDefaultSecurityBoundarytoPolicySecurityBoundary, which is stricter than the previously exported_internaldefault and can returnAPPROVE_REQUIREDfor non-idempotent tool calls. That means callers relying onfrom dare_framework.security import DefaultSecurityBoundary(including default agent wiring) now get different policy outcomes without opting into a new boundary, so this refactor silently changes runtime behavior rather than only import structure.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in
e2a2475.DefaultSecurityBoundaryis now routed to the legacy permissive implementation again (viadare_framework.security.impl.default_security_boundary) sofrom dare_framework.security import DefaultSecurityBoundarykeeps historical ALLOW behavior instead of inheritingPolicySecurityBoundaryapproval gating.Added regression coverage in
tests/unit/test_security_boundary.py::test_default_security_boundary_remains_permissive_for_high_risk.