Repository navigation
feat(runtime): add decision policy governance types #1921
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
base: master
Are you sure you want to change the base?
Changes from 2 commits
b1d544b
ba7c086
08133ca
62b4117
7da33c6
d4a8603
5098f5d
cd2bc83
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -259,6 +259,7 @@ def __init__( | |
| artifact_resolver: _ArtifactResolver | None = None, | ||
| id_factory: IdFactory | None = None, | ||
| prompt_context: ScopedPrompts | None = None, | ||
| scope_id: str = "unscoped", | ||
| write_gate: MemoryWriteGate | None = None, | ||
| capacity_budget: MemoryCapacityBudget | None = None, | ||
| compaction: MemoryCompactionPolicy | None = None, | ||
|
|
@@ -268,6 +269,7 @@ def __init__( | |
| self._prompt_context = prompt_context | ||
| self._candidate_pipeline = candidate_pipeline | ||
| self._write_gate = write_gate | ||
| self._scope_id = scope_id | ||
| self._embedding_model = embedding_model | ||
| if rerank_candidate_limit < 1: | ||
| raise _InvalidMemoryOperationError("search-limit") | ||
|
|
@@ -1384,6 +1386,10 @@ async def _assess_write( | |
| candidates=tuple(candidate.text for candidate in candidates), | ||
| evidence=projection.entries, | ||
| expected_revision=None if base is None else base.revision, | ||
| scope_id=self._scope_id, | ||
| operation_id=_gate_operation_id(base), | ||
| subject_refs=_gate_subject_refs(candidates), | ||
| evidence_refs=tuple(_gate_evidence_ref(entry) for entry in projection.entries), | ||
| ) | ||
| ) | ||
| except Exception: | ||
|
|
@@ -1839,6 +1845,25 @@ def _candidate_gate_identity(candidate_index: int, identity: str) -> str: | |
| return f"candidate:{candidate_index} {identity}" | ||
|
|
||
|
|
||
| def _gate_operation_id(base: Memory | None) -> str: | ||
| if base is None: | ||
| return "memory-write:new" | ||
| return f"memory-write:{base.artifact_id}@{base.revision + 1}" | ||
|
|
||
|
|
||
| def _gate_subject_refs(candidates: tuple[MemoryEntryInput, ...]) -> tuple[str, ...]: | ||
| return tuple( | ||
| f"candidate:{index}" | ||
| if candidate.entry is None | ||
| else f"entry:{candidate.entry.entry_id}@{candidate.entry.entry_version_id}" | ||
| for index, candidate in enumerate(candidates, start=1) | ||
|
Comment on lines
+1987
to
+1991
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 5098f5d. Applied writes replace candidate placeholders with exact committed entry/version refs and the committed Memory revision operation ID. Held, unchanged, and failed candidates cannot be reconstructed without retaining raw input, so their sidecars explicitly clear subject_refs and set incomplete_subject_count rather than claiming replayability.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [P2] Retain references for the complete assessed candidate batch Applied single-candidate writes now have exact committed refs, but batch coverage is still incomplete on cd2bc83. Through
|
||
| ) | ||
|
|
||
|
|
||
| def _gate_evidence_ref(value: str) -> str: | ||
| return value.partition("\n")[0] | ||
|
|
||
|
|
||
| def _source_gate_content(source: Source, resolver: _SourceResolver | None) -> str | None: | ||
| content = getattr(source, "content", None) | ||
| if isinstance(content, str): | ||
|
|
||
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.
[P2] The example value contradicts the actual default for the privacy boundary
RuntimeConfig.memory_write_gate_privacy_boundarydefaults tono_external_call(runtime/config.py, andtest_memory_write_gate_defaults_to_no_external_callpins it), and the comment above this line correctly says "The default makes no decision-model call". But by this file's own convention the commented line shows the default (..._MODE=shadowtwo lines up matches its actual default), and here it showslocal_only- a value that DOES make a decision-model call on a loopback backend.An operator who uncomments the line to "keep the documented default" actually enables model calls. Suggest changing the example to
# POWERCONTEXT_SERVER_RUNTIME_MEMORY_WRITE_GATE_PRIVACY_BOUNDARY=no_external_call(and optionally a follow-up line showing thelocal_onlyopt-in), or rewording so the example is clearly an opt-in and not the default.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 5098f5d. .env.example now shows no_external_call, matching RuntimeConfig and the surrounding documentation. local_only remains described as the explicit loopback opt-in.
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 5098f5d. .env.example now shows no_external_call, matching RuntimeConfig and the surrounding documentation. local_only remains described as the explicit loopback opt-in.