Skip to content

fix: dedup a promoted instinct in the inject block#105

Merged
ikeikeikeike merged 2 commits into
mainfrom
feat/inject-id-dedup
Jul 14, 2026
Merged

fix: dedup a promoted instinct in the inject block#105
ikeikeikeike merged 2 commits into
mainfrom
feat/inject-id-dedup

Conversation

@ikeikeikeike

Copy link
Copy Markdown
Member

Why

The UserPromptSubmit inject block double-listed an instinct once it was promoted project->global: the project copy and the promoted global twin (same ID) both rendered as separate lines.

What

inject.Build now merges by ID before the confidence floor — a project instinct shadows the same-ID global one, so only the project version is injected (ECC's project-overrides-global precedence). Running the merge before the floor means a below-floor project instinct still suppresses its promoted global twin instead of letting the stale global copy resurface.

Tests

  • TestBuild_ProjectShadowsGlobalOnIDCollision — shared ID deduped, global-only instinct still kept.
  • TestBuild_BelowFloorProjectStillShadowsGlobal — below-floor project shadows its global twin (neither injected).

go test ./internal/inject/ + golangci-lint green.

When a project instinct and a global instinct share the same ID (the
project->global promotion case), Build now emits only the project version
and suppresses the global twin, matching ECC's project-overrides-global
precedence. The merge runs before the confidence floor, so a below-floor
project instinct still shadows its promoted global copy instead of letting
the stale global version resurface.

Tests: TestBuild_ProjectShadowsGlobalOnIDCollision (shared deduped,
global-only kept) and TestBuild_BelowFloorProjectStillShadowsGlobal
(below-floor project still shadows, neither injected).
Comment thread internal/inject/inject.go Outdated
// letting the stale global copy resurface.
projectIDs := make(map[string]bool, len(project))
for _, in := range project {
projectIDs[in.ID] = true

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

projectIDs[in.ID] = true is recorded unconditionally, before the confidence-floor check. Session evaluation (internal/session/evaluate.go) only ever adjusts confidence for the project-scope instinct file; the promoted global twin (internal/cli/instinct_promote.go) is never touched by it. So once a promoted project instinct independently decays below MinConfidence (e.g. after a correction), this line still shadows its still-valid, higher-confidence global twin — the promoted knowledge silently stops appearing in the inject block, with no error or log.

Fix: only record the shadow when the project instinct itself clears the floor (i.e. is actually part of the pool). Pushing that change now.

… twin

Session evaluation (internal/session/evaluate.go) only ever adjusts
confidence for the project-scope instinct file; the promoted global
twin (internal/cli/instinct_promote.go) is never touched by it. The
previous merge recorded a project ID's shadow unconditionally, before
the confidence-floor check, so a promoted project instinct that
independently decays below MinConfidence (e.g. after a correction)
still suppressed its still-valid, higher-confidence global twin --
the promoted knowledge would silently stop appearing in the inject
block, with no error or log.

Only record the shadow when the project instinct itself clears the
floor (i.e. is actually part of the pool). Renamed
TestBuild_BelowFloorProjectStillShadowsGlobal to
TestBuild_BelowFloorProjectDoesNotShadowGlobal to assert the corrected
behavior: the global twin still injects.

Found by code review on PR #105.
@ikeikeikeike
ikeikeikeike merged commit c9ae3c5 into main Jul 14, 2026
11 checks passed
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.

1 participant