Skip to content
Back to skills

2170 Notification Center D6338995

ASecurity

Trinkets in the system prompt feel "cold/received" to MIRA - like reading a biography, not recalling memories.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added May 31, 2026
ai-agentspython

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 31, 2026

npx -y skills add tools-only/X-Skills --skill 2170-notification-center_d6338995 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2170 Notification Center D6338995?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2170 Notification Center D6338995
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2170-notification-center-d6338995/badge)](https://www.skillsdirectory.com/skills/tools-only-2170-notification-center-d6338995)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# Notification Center Implementation

## Problem
Trinkets in the system prompt feel "cold/received" to MIRA - like reading a biography, not recalling memories.

## Solution
Move dynamic content into a sliding assistant message positioned AFTER the cached conversation but BEFORE the current user message.

## Context Window Structure
```
SYSTEM PROMPT [CACHED]
├── base_prompt
├── domaindoc
├── tool_guidance
└── tool_hints

CONVERSATION HISTORY [PROGRESSIVELY CACHED]
└── ... [cache marker on last assistant msg]

════════════════════════════════════════════════════════════  ← user msg (delimiter)
NOTIFICATION CENTER                                            ← assistant msg
This section moves to the front of your context each turn
to keep important information front-of-mind.
════════════════════════════════════════════════════════════
├── datetime_section
├── conversation_manifest
├── active_reminders
├── context_search_results
└── relevant_memories
════════════════════════════════════════════════════════════

CURRENT USER MESSAGE
```

## Key Design Decisions

### 1. Placement Registry in Base Class
Placement is 100% inside `EventAwareTrinket` - trinkets don't import or declare placement:
```python
# base.py
_NOTIFICATION_CENTER_TRINKETS = frozenset({
    'TimeManager', 'ManifestTrinket',
    'ReminderManager', 'GetContextTrinket', 'ProactiveMemoryTrinket',
})

class EventAwareTrinket:
    @property
    def placement(self) -> TrinketPlacement:
        if self.__class__.__name__ in _NOTIFICATION_CENTER_TRINKETS:
            return TrinketPlacement.NOTIFICATION_CENTER
        return TrinketPlacement.SYSTEM
```

### 2. Single Dict with NamedTuple in Composer
Avoid parallel dicts that can drift:
```python
class SectionData(NamedTuple):
    content: str
    cache_policy: bool
    placement: str

self._sections: Dict[str, SectionData] = {}
```

### 3. Constants Over Magic Strings
```python
PLACEMENT_SYSTEM = "system"
PLACEMENT_NOTIFICATION = "notification"
```

### 4. Delimiter-as-Marker
The user message between conversation and notification center uses the same `═` delimiter, making the role boundary invisible. The delimiter is the opening frame; the notification center content starts with the header. This prevents the model from thinking it spoke the notification center aloud while keeping the infrastructure visually cohesive.

## Files Changed

| File | Change |
|------|--------|
| `working_memory/trinkets/base.py` | `TrinketPlacement` enum + `_NOTIFICATION_CENTER_TRINKETS` registry + `placement` property |
| `working_memory/composer.py` | `SectionData` namedtuple, routing by `section.placement`, `_build_notification_center()` |
| `cns/core/events.py` | `placement` field on `TrinketContentEvent`, `notification_center` field on `SystemPromptComposedEvent` |
| `working_memory/core.py` | Pass `event.placement` to `composer.add_section()` |
| `cns/services/orchestrator.py` | Inject delimiter + notification center after conversation history |
| `cns/integration/factory.py` | Remove `PunchclockTrinket` |
| `working_memory/trinkets/punchclock_trinket.py` | **DELETED** |

## Data Flow
```
EventAwareTrinket.placement (property)
    ↓ .value
TrinketContentEvent.placement ("notification")
    ↓
composer.add_section(placement=...)
    ↓
SectionData.placement
    ↓
compose() routes to notification_parts
    ↓
_build_notification_center() formats with ═══ delimiters
    ↓
SystemPromptComposedEvent.notification_center
    ↓
orchestrator injects after [context refresh]
```

## Cache Behavior (Empirically Verified)
- System prompt: cached
- Conversation history: progressively cached
- Notification center: NOT cached (changes each turn without invalidating conversation cache)
- `[context refresh]` marker: NOT cached

Files in this skill

  • README.md852 B
  • skill.md4.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.