Skip to content

fix(memory): pin proposal target_file to the kind's canonical file - #1563

Closed
anikinsasha wants to merge 1 commit into
danielmiessler:mainfrom
anikinsasha:fix/pin-proposal-target-file
Closed

fix(memory): pin proposal target_file to the kind's canonical file#1563
anikinsasha wants to merge 1 commit into
danielmiessler:mainfrom
anikinsasha:fix/pin-proposal-target-file

Conversation

@anikinsasha

Copy link
Copy Markdown

Problem

Memory proposals carry target_file as free text emitted by the reviewer (an LLM). PROPOSAL_KIND_TO_FILES already maps most proposal kinds to exactly one canonical file, so the target is fully determined by the kind — yet enqueueProposal persists the model's path verbatim.

When the model hallucinates that path (wrong casing, a dropped path segment), the bad path is stored and then either silently mis-files the edit or fails to apply with target file missing, reopening the proposal on every review with no resolution.

Fix

Pin target_file to the kind's canonical file at enqueue time via a new pure helper pinProposalTargetFile(kind, suppliedPath) in MemoryTypes.ts:

  • Single-file kinds (style, definition, canonical-content, resume, operational-rule, projects, contacts): the supplied path is ignored and the canonical file is used — the model can't misdirect a deterministic target.
  • Multi-file kind (identity → PRINCIPAL_IDENTITY / DA_IDENTITY): can't be pinned, so the supplied path must be one of the two allowed files; otherwise the proposal is rejected with EINVAL_ITEM rather than stored with an unresolvable path.
  • Unknown kind: supplied path returned unchanged (the caller validates the kind separately) — no behavior change.

enqueueProposal calls the helper and rejects an out-of-set identity path.

Testing

bun MemoryTypes.ts test — added 5 assertions covering the helper (single-file pin ignores a hallucinated path; identity in-set kept; identity out-of-set → null). Full smoke suite passes (57/57).

Notes

Backward-compatible: the reverse-path inference default and the existing apply/allowlist behavior are unchanged; this only stops a hallucinated path from being persisted at the source.

A memory proposal's target_file is emitted as free text by the reviewer (an LLM).
PROPOSAL_KIND_TO_FILES already maps most proposal kinds to exactly one canonical
file, so the target is fully determined by the kind — but enqueueProposal stored
the model's path verbatim. A hallucinated path (wrong casing, a dropped path
segment) therefore got persisted and then silently mis-filed or failed to apply
("target file missing"), reopening the proposal forever.

Pin target_file to the kind's canonical file via a new pinProposalTargetFile
helper: for a single-file kind the supplied path is ignored and the canonical
one is used; for the 2-file identity kind the supplied path must be one of the
allowed files, else the proposal is rejected (EINVAL_ITEM) rather than stored
with an unresolvable path. Adds MemoryTypes smokeTest coverage for the helper.
@danielmiessler

Copy link
Copy Markdown
Owner

Ported into source, thank you. Exactly as designed: single-file kinds pin to the canonical path (a hallucinated reviewer path can no longer mis-file a proposal), identity validates within its two-file set and rejects out-of-set with EINVAL_ITEM. Your five smoke asserts came along; the suite runs 57/57. Context on why this closes without merging: the public repo is generated from the private source tree at release, so PRs are ported rather than merged, with credit at the fix site and in the README. Ships with the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants