# Project export: Second Shift

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: Second Shift remembers where I left off and helps me choose what to work on next.
- Devpost: https://devpost.com/software/second-shift
- GitHub: https://github.com/minutechreview/second-shift
- Video: https://www.youtube.com/embed/Rm63qmJH_Lc?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Rayan Abdul Cader (39 commits)

## Devpost submission (written by the team)

No Devpost description available.

## README (from the GitHub repository)

# Second Shift

Second Shift is a local-first, notch-native macOS focus companion for people
who work across multiple projects and AI agents. It remembers what changed,
where work stopped, what remains blocked, and the most useful next action for
the time available.

Its core ritual is **Brief → Focus → Debrief**. The notch is the primary
interface; a detachable workspace remains available for longer reading and
configuration.

## The Problem

AI-assisted work is easy to start and hard to resume. Decisions remain in one
agent, unfinished work in another, and deadlines in Calendar or Reminders.
Second Shift turns those scattered traces into one answer: **what deserves my
attention now, and where exactly did I leave off?**

## What You Can Do

- Capture an idea with text, voice, or the global Quick Capture shortcut.
- Click the MacBook notch or companion sprite to reveal the complete daily workflow; moving away collapses it.
- Receive completed-turn context automatically from Codex, Claude Code, and
  Hermes through local hooks and MCP tools.
- See adapter health, last sync, hook state, missing setup, and repair actions
  for Codex, Claude Code, Hermes, Cursor, and OpenCode.
- Read technical agent updates as plain-language titles, short key points,
  why they matter, and one concrete next action.
- Review new captures in Inbox, then move them into a globally searchable
  Knowledge base spanning every stored date and source.
- Ask Codex questions across the local memory library or about one memory.
- Get an evidence-based next action, active blocker, deferred topics, and a
  compact Resume Context instead of another generic summary.
- Run a focused shift from the notch with a timer, a three-step plan, quick
  notes, and a clear debrief.
- See calm, truthful source activity only when work meaningfully changes.
- Search memories, projects, calendar context, voice captures, and normalized
  agent updates from the existing Inbox and Knowledge search field.
- Ask why a recommendation appeared and see concise reasons backed by its
  actual Context Events.
- Find an uninterrupted focus window, move a focus block, reschedule unfinished
  work, or add a follow-up only after explicit confirmation.
- Remember each project's repository, apps, files, links, preferred agent,
  and preferred calendar.
- Optionally enable Gentle Focus Awareness and once-daily commitment
  resurfacing with quiet hours; both are off by default.
- Review prior sessions as calm Shift Replay rows with duration, completed
  steps, captured thoughts, remaining work, and the recommended continuation.
- Load or reset a fictional demo workspace directly from Today or Settings.
- Use the floating companion for low-friction reminders while the panel is
  collapsed.
- Choose Memo, Nimbus, or Luma; every companion includes idle, blink,
  thinking, alert, listening, sleeping, happy, and concerned expressions.

## Demo Flow

1. Click **Load Demo Workspace** on Today.
2. Choose an available-time window and prepare the pre-shift brief.
3. See an old unresolved blocker outrank a newer trivial thought.
4. Start the shift, complete a plan step, and capture a quick note.
5. End the shift and confirm the debrief.
6. Review how completed work disappears while unresolved work stays open.

## Current Intelligence Flow

```text
voice / text / Codex / external agent handoff
                    |
              raw local context
                    |
          Codex event normalization
                    |
          structured ContextEvents
                    |
          project-state reconciliation
                    |
 evidence engine / deduplication / explainability
                    |
 recommendation / resume context / open loops / mascot
```

Raw context, normalized events, and project states are stored locally in SQLite. Only bounded excerpts selected for normalization or reconciliation are sent through the signed-in Codex runtime.

## Plain-Language Context Editor

Agent evidence is never overwritten. Second Shift stores an optional cached
plain-language view beside the original title and body:

- one short header;
- up to two simple key points;
- why the update matters;
- one concrete next action.

New meaningful agent imports enter a local processing queue automatically.
Second Shift processes at most three historical items at launch. The explicit
**Clean Up Inbox** preview can deterministically simplify the remaining useful
items and identify obvious historical noise before anything is archived. Codex
enhancement is capped to a bounded subset, so cleanup does not create an
unlimited background-usage loop. Every simplified detail retains a **View
original agent evidence** disclosure.

## Codex Setup

Second Shift defaults to Codex and reuses the Codex CLI login:

```sh
codex login status
```

If needed, authenticate with:

```sh
codex login
```

This path uses eligible Codex access associated with the signed-in ChatGPT account. It does not require an OpenAI Platform API key. Direct API-key support is reserved as an optional later provider.

Second Shift pins semantic reconciliation and session planning to the ChatGPT-account-compatible `gpt-5.4-mini` with low reasoning to conserve usage. Deterministic lifecycle policy still controls completion and reopening, and this does not change the global model used by the Codex app or CLI.

Gemma remains available in Settings as an offline local chat fallback through an Ollama-compatible endpoint.

## First-Run Setup

On first launch, Second Shift asks each user to:

1. Choose a local display name.
2. Select which local agents to connect: Codex, Claude Code, and/or Hermes.
3. Choose their own AI provider: signed-in Codex, a local Ollama-compatible model, or their own OpenAI API key.
4. Optionally load fictional judge demo data.

OpenAI API keys are stored only in macOS Keychain. They are never written to
SQLite, UserDefaults, logs, exported memories, or this repository. Local model
users supply their own endpoint and installed model. Agent hooks write only to
the user's local `~/Documents/Memory Companion/Agent Inbox/` folder.

The packaged app includes the local bridge installers. Settings can be used to
change AI providers after onboarding.

## Build and Run

```sh
./script/build_and_run.sh --verify
```

The packaged app is created at:

```text
dist/MemoryCompanion.app
```

Its visible macOS name is **Second Shift**.

## Five-Minute Judge Path

1. Build and launch with `./script/build_and_run.sh --verify` on macOS 14 or later.
2. Open Second Shift from the MacBook notch or its floating companion.
3. Select **Load Demo Workspace** on Today. The sample data is fictional and
   does not require an API key or connected agent.
4. Choose a time window, inspect **Why this?**, and select **Prepare My Shift**.
5. Start the shift, complete a step, capture a note, and end the shift to see
   the debrief update the next recommendation.
6. Use **Reset Demo Workspace** in Settings to restore the user's normal local
   workspace or reset the fictional data for another test run.

Optional Codex, agent, Apple Notes, Calendar, Reminders, and Composio features
use the judge's own accounts and permissions. No author credentials are
included or required for the core demo.

## Hackathon Build Without An Apple Developer Account

The release script produces an ad-hoc-signed ZIP and verifies its signature:

```sh
./script/build_and_run.sh --package
```

Output:

```text
dist/SecondShift-macOS.zip
```

Judges may also download the prebuilt prototype from the
[`build-week-2026` GitHub release](https://github.com/minutechreview/second-shift/releases/tag/build-week-2026).

Ad-hoc signing does not require a paid Apple Developer account. It preserves
the bundle's integrity but is not Apple notarization, so Gatekeeper may warn a
judge after downloading it. The recommended submission is the public source
repository plus demo video, with this ZIP as an optional downloadable build.
Exact judg

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 126 recognized source files, 1071 KB.
- Python (language) — detected in the code
- Swift (language) — detected in the code
- Node.js (technology) — claimed on Devpost, not found in the code
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 141)

```
.codex/environments/environment.toml
.gitignore
docs/agent-memory-handoff.md
docs/hackathon/BUILD_LOG.md
docs/hackathon/CODEX_COLLABORATION.md
docs/hackathon/CORE_EXPERIENCE.md
docs/hackathon/CURRENT_ARCHITECTURE.md
docs/hackathon/DEMO_SCRIPT.md
docs/hackathon/IMPLEMENTATION_PLAN.md
docs/hackathon/INSTALL_WITHOUT_NOTARIZATION.md
docs/hackathon/PRODUCT_PIVOT.md
docs/hackathon/PRUNING_PLAN.md
docs/hackathon/SECOND_SHIFT_SCOPE.md
docs/hackathon/SHIFT_RITUAL.md
docs/hackathon/SUBMISSION_BRIEF.md
docs/hackathon/TECHNICAL_DESIGN.md
docs/hackathon/VOICE_AND_WORKSPACE.md
LICENSE
MemoryCompanion.entitlements
Package.swift
pet-runs/keeper/imagegen-jobs.json
pet-runs/keeper/pet_request.json
pet-runs/keeper/prompts/base-pet.md
pet-runs/keeper/prompts/rows/failed.md
pet-runs/keeper/prompts/rows/idle.md
pet-runs/keeper/prompts/rows/jumping.md
pet-runs/keeper/prompts/rows/review.md
pet-runs/keeper/prompts/rows/running-left.md
pet-runs/keeper/prompts/rows/running-right.md
pet-runs/keeper/prompts/rows/running.md
pet-runs/keeper/prompts/rows/waiting.md
pet-runs/keeper/prompts/rows/waving.md
README.md
scratch/transparency_fix.py
script/audit_public_repo.sh
script/build_and_run.sh
Sources/MemoryCompanion/App/AppDelegate.swift
Sources/MemoryCompanion/App/MemoryCompanionApp.swift
Sources/MemoryCompanion/App/MemoryCompanionRuntime.swift
Sources/MemoryCompanion/App/NotchPanelController.swift
Sources/MemoryCompanion/Models/CompanionMood.swift
Sources/MemoryCompanion/Models/CompanionStyle.swift
Sources/MemoryCompanion/Models/ContextEvent.swift
Sources/MemoryCompanion/Models/FocusSession.swift
Sources/MemoryCompanion/Models/ImportedAgentMemory.swift
Sources/MemoryCompanion/Models/LibrarySection.swift
Sources/MemoryCompanion/Models/MemoryItem.swift
Sources/MemoryCompanion/Models/NotchPresentation.swift
Sources/MemoryCompanion/Models/ProjectState.swift
Sources/MemoryCompanion/Models/ShiftLifecycle.swift
Sources/MemoryCompanion/Models/WorkspaceTarget.swift
Sources/MemoryCompanion/Services/ActivityFeed.swift
Sources/MemoryCompanion/Services/AgentAdapter.swift
Sources/MemoryCompanion/Services/AgentContextFilter.swift
Sources/MemoryCompanion/Services/AgentIntegrationService.swift
Sources/MemoryCompanion/Services/AgentMemoryExporter.swift
Sources/MemoryCompanion/Services/AgentMemoryImportService.swift
Sources/MemoryCompanion/Services/AgentMemoryParser.swift
Sources/MemoryCompanion/Services/AgentWorkspaceService.swift
Sources/MemoryCompanion/Services/AppleNotesImportService.swift
Sources/MemoryCompanion/Services/CalendarIntelligence.swift
Sources/MemoryCompanion/Services/CodexAppServerClient.swift
Sources/MemoryCompanion/Services/CodexHandoffService.swift
Sources/MemoryCompanion/Services/CommitmentSelector.swift
Sources/MemoryCompanion/Services/CompletionEvidenceEngine.swift
Sources/MemoryCompanion/Services/ComposioConnector.swift
Sources/MemoryCompanion/Services/ContextBus.swift
Sources/MemoryCompanion/Services/ContextEditorService.swift
Sources/MemoryCompanion/Services/ContextEventDeduplicator.swift
Sources/MemoryCompanion/Services/ContextInspectorService.swift
Sources/MemoryCompanion/Services/DemoWorkspaceSeeder.swift
Sources/MemoryCompanion/Services/EventImportService.swift
Sources/MemoryCompanion/Services/FocusAwarenessService.swift
Sources/MemoryCompanion/Services/FocusInterventionService.swift
Sources/MemoryCompanion/Services/InboxWatcher.swift
Sources/MemoryCompanion/Services/KeychainService.swift
Sources/MemoryCompanion/Services/LocalAIClient.swift
Sources/MemoryCompanion/Services/NativeSpeechService.swift
Sources/MemoryCompanion/Services/ProjectStateReconciler.swift
Sources/MemoryCompanion/Services/QuickCaptureScreenContextService.swift
Sources/MemoryCompanion/Services/ReminderNudgeService.swift
Sources/MemoryCompanion/Services/SecondShiftIntelligence.swift
Sources/MemoryCompanion/Services/SpeechCaptureService.swift
Sources/MemoryCompanion/Services/StalledMonitor.swift
Sources/MemoryCompanion/Services/UniversalSearchService.swift
Sources/MemoryCompanion/Services/VoiceIntentRouter.swift
Sources/MemoryCompanion/Services/WorkspaceTargetStore.swift
Sources/MemoryCompanion/Stores/MemoryStore.swift
Sources/MemoryCompanion/Support/GeminiUIStyle.swift
Sources/MemoryCompanion/Support/NotchInteractionFeedback.swift
Sources/MemoryCompanion/Support/Notifications.swift
Sources/MemoryCompanion/Views/CompanionBubbleView.swift
Sources/MemoryCompanion/Views/ContentView.swift
Sources/MemoryCompanion/Views/FocusInterventionView.swift
Sources/MemoryCompanion/Views/InteractiveCalendarView.swift
Sources/MemoryCompanion/Views/NotchRootView.swift
Sources/MemoryCompanion/Views/OnboardingView.swift
Sources/MemoryCompanion/Views/PixelAgentSprite.swift
Sources/MemoryCompanion/Views/QuickCaptureView.swift
Sources/MemoryCompanion/Views/QuietWorkspaceViews.swift
Sources/MemoryCompanion/Views/SecondShiftCoreView.swift
Sources/MemoryCompanion/Views/SettingsView.swift
Sources/MemoryCompanion/Views/VoiceEntryView.swift
Tests/MemoryCompanionTests/AgentAdapterTests.swift
Tests/MemoryCompanionTests/AgentContextFilterTests.swift
Tests/MemoryCompanionTests/AgentMemoryParserTests.swift
Tests/MemoryCompanionTests/AppleNotesImportServiceTests.swift
Tests/MemoryCompanionTests/CalendarIntelligenceTests.swift
Tests/MemoryCompanionTests/CapturePipelineTests.swift
Tests/MemoryCompanionTests/CodexHandoffTests.swift
Tests/MemoryCompanionTests/CommitmentResurfacingTests.swift
Tests/MemoryCompanionTests/CommitmentSelectorTests.swift
Tests/MemoryCompanionTests/CompanionCursorAwarenessTests.swift
Tests/MemoryCompanionTests/CompletionEvidenceEngineTests.swift
Tests/MemoryCompanionTests/ComposioConnectorTests.swift
Tests/MemoryCompanionTests/ContextBusTests.swift
Tests/MemoryCompanionTests/ContextEditorServiceTests.swift
Tests/MemoryCompanionTests/ContextEventDeduplicatorTests.swift
Tests/MemoryCompanionTests/ContextInspectorServiceTests.swift
Tests/MemoryCompanionTests/DemoWorkspaceSeederTests.swift
[21 more files omitted for size]
```

### Dependencies

No dependency index available.

### Recent commits (newest first)

- Add judge release download path
- Prepare Second Shift Build Week release
- Add plain-language context editor
- Polish Second Shift for final submission
- Balance notch companion and live status
- Animate generated agent activity sprites
- Remove expanded notch panel shadow
- Hide collapsed notch window shadow
- Polish notch hover and display integration
- Rebuild Second Shift around the notch
- Simplify projects and repair memory actions
- Tighten shift planning and lifecycle
- Fix main window reopening in accessory mode
- Add structured Codex handoff
- Add demo data removal
- Add reproducible demo workspace
- Make pre-shift briefs change and time aware
- Harden capture classification and inbox routing
- Make companion gaze follow the cursor
- Add subtle cursor awareness to companion

## Key source files (fetched from GitHub, selected and truncated for size)

### docs/agent-memory-handoff.md

```markdown
# Second Shift Agent Handoff

Send this to other agents when you want them to contribute meaningful project
context to Second Shift.

```text
You are handing project context to my local Second Shift Mac app.

First read my durable personal context at:
~/Documents/Memory Companion/Shared Context/unified-context.md

Please summarize meaningful state changes using this exact Markdown shape. Keep
each entry short, concrete, and useful for answering where I left off.

For each important idea, decision, open loop, task, reminder, source, or stalled
item, write:

## Memory
Title: <short title>
Type: idea | task | decision | reminder | source | question | stalled
Priority: low | normal | high
Project: <project/client/topic, or none>
Tags: <comma-separated tags>
Due: <YYYY-MM-DD, relative timing, or none>
Source: <agent/tool/document/conversation name>
Confidence: low | medium | high

Body:
<2-5 sentences explaining the useful context. Include what happened, why it
matters, and what should be remembered.>

Next action:
<one concrete next step, or none>

Reminder rule:
<when this should resurface, e.g. "if untouched for 7 days", "2 days before due",
"after next client meeting", or none>
```

Rules:

- Do not include secrets, API keys, passwords, private tokens, or payment data.
- Prefer state-changing evidence over raw transcript or casual commentary.
- Use separate entries when work was completed but a blocker remains.
- Treat "maybe", "consider", and exploratory architecture discussions as ideas,
  not decisions.
- Never claim intended work was completed.
- Preserve exact dates when dates matter.
- If something is uncertain, say so in `Confidence` and explain briefly in `Body`.
- If you created files, include absolute paths in `Body` or `Source`.
- If there are no important memories, reply: `No memory-worthy updates.`

If you run locally on my Mac and have filesystem access, do not only return the
handoff in chat. Write it to a uniquely named `.md` file in:

`~/Documents/Memory Companion/Agent Inbox/`

The app watches that folder and imports valid memory blocks automatically.
```

## Automated Agent Bridge

Codex, Hermes, and Claude Code can use the local `second-shift` MCP server instead of writing
the Markdown by hand. It exposes:

- `record_context`: stores a meaningful update in the watched Agent Inbox.
- `get_project_state`: reads the latest reconciled state for a project ID.

The agents also have automatic end-of-turn capture. A free local relevance
filter keeps completed changes, decisions, blockers, errors, deadlines, test
results, and concrete next actions. It drops greetings, acknowledgements,
probes, ordinary short answers, and duplicate events before they reach the
inbox, so skipped turns do not trigger Second Shift's Codex normalization.
Explicit `record_context` calls always remain available when an agent needs to
preserve a precise update.

The hook deliberately ignores work performed inside
`~/Documents/Memory Companion` to prevent Second
[truncated — 104 more characters]
```

### docs/hackathon/INSTALL_WITHOUT_NOTARIZATION.md

```markdown
# Installing Second Shift Without Notarization

Second Shift is an independent Build Week prototype. The downloadable build is
ad-hoc signed and signature-verified, but it is not notarized because the
builder does not have a paid Apple Developer account.

## Recommended Submission

Submit these together:

1. The source repository, including build and test instructions.
2. The demo video showing the real app running on macOS.
3. `SecondShift-macOS.zip` as an optional convenience build.

Judges can always build from source with:

```sh
swift test
./script/build_and_run.sh --verify
```

This requires Xcode Command Line Tools and macOS 14 or later.

## Opening The Downloadable Build

1. Unzip `SecondShift-macOS.zip`.
2. Move **Second Shift.app** to Applications if desired.
3. Control-click the app, choose **Open**, then choose **Open** again in the
   Gatekeeper dialog.

If macOS still quarantines the downloaded prototype, a judge who trusts the
repository and release asset can remove quarantine locally:

```sh
xattr -dr com.apple.quarantine "/Applications/Second Shift.app"
```

Then open the app normally. This does not bypass code-signature verification;
the packaged app remains ad-hoc signed and can be checked with:

```sh
codesign --verify --deep --strict "/Applications/Second Shift.app"
```

## Build The Release ZIP

```sh
./script/build_and_run.sh --package
```

The script builds, ad-hoc signs, verifies, and creates:

```text
dist/SecondShift-macOS.zip
```

Do not claim the app is notarized or distributed through the Mac App Store.

```

### Tools/second-shift-bridge/server.mjs

```
#!/usr/bin/env node
import readline from "node:readline";
import { spawnSync } from "node:child_process";
import os from "node:os";
import path from "node:path";
import { titleFrom, writeHandoff } from "./lib.mjs";

const tools = [
  {
    name: "record_context",
    description: "Save a meaningful decision, completed change, blocker, open loop, or next action to the user's local Second Shift context bus. Call this once near the end of meaningful work; skip greetings and trivial tool chatter.",
    inputSchema: {
      type: "object",
      required: ["content"],
      properties: {
        content: { type: "string", description: "Concise useful context: what changed, why it matters, and what remains." },
        title: { type: "string" },
        project: { type: "string" },
        source: { type: "string", description: "Agent name, normally Codex or Hermes." },
        session_id: { type: "string" },
        next_action: { type: "string" },
        type: { type: "string", enum: ["idea", "task", "decision", "reminder", "source", "question", "stalled"] },
        priority: { type: "string", enum: ["low", "normal", "high"] },
      },
    },
  },
  {
    name: "get_project_state",
    description: "Read Second Shift's latest reconciled local state for a project ID.",
    inputSchema: {
      type: "object",
      required: ["project_id"],
      properties: { project_id: { type: "string" } },
    },
  },
];

function success(id, result) {
  process.stdout.write(`${JSON.stringify({ jsonrpc: "2.0", id, result })}\n`);
}

function failure(id, code, message) {
  process.stdout.write(`${JSON.stringify({ jsonrpc: "2.0", id, error: { code, message } })}\n`);
}

function textResult(text, isError = false) {
  return { content: [{ type: "text", text }], isError };
}

function projectState(projectID) {
  if (!/^[a-zA-Z0-9._ -]{1,120}$/.test(projectID)) {
    return textResult("Invalid project ID.", true);
  }
  const database = process.env.SECOND_SHIFT_DB_PATH || path.join(
    os.homedir(), "Library", "Application Support", "MemoryCompanion", "memory.sqlite"
  );
  const escaped = projectID.replaceAll("'", "''");
  const result = spawnSync("/usr/bin/sqlite3", [database, `SELECT state_json FROM project_states WHERE project_id='${escaped}' LIMIT 1;`], { encoding: "utf8" });
  if (result.error || result.status !== 0) return textResult("Second Shift has no readable local state database yet.", true);
  return textResult(result.stdout.trim() || `No state found for ${projectID}.`);
}

async function handle(message) {
  const { id, method, params = {} } = message;
  if (method === "initialize") {
    success(id, {
      protocolVersion: params.protocolVersion || "2025-03-26",
      capabilities: { tools: { listChanged: false } },
      serverInfo: { name: "second-shift", version: "1.0.0" },
      instructions: "Use record_context once after meaningful work that changes project state, creates a decision, leaves a blocker, or establishes a next action. Do not record greetings, raw logs, secrets, or trivial chatter.",
    });
    return;
  }
  if (method === "notifications/initialized" || method === "notifications/cancelled") return;
  if (method === "ping") return success(id, {});
  if (method === "tools/list") return success(id, { tools });
  if (method === "tools/call") {
    const args = params.arguments || {};
    if (params.name === "record_context") {
      const destination = writeHandoff({
        title: args.title || titleFrom(args.content),
        content: args.content,
        source: args.source || "MCP agent",
        project: args.project || "none",
        sessionID: args.session_id || "none",
        nextAction: args.next_action || "Review this update in Second Shift.",
        type: args.type || "idea",
        priority: args.priority || "normal",
        tags: ["mcp"],
      });
      return success(id, textResult(`Saved locally for Second Shift: ${destination}`));
    }
    if (params.name === "get_project_state") return success(id, projectState(String(args.project_id || "")));
    return success(id, textResult(`Unknown tool: ${params.name}`, true));
  }
  if (id !== undefined) failure(id, -32601, `Method not found: ${method}`);
}

const input = readline.createInterface({ input: process.stdin, crlfDelay: Infinity });
input.on("line", (line) => {
  if (!line.trim()) return;
  try { handle(JSON.parse(line)); } catch (error) { failure(null, -32700, String(error)); }
});


```

### Package.swift

```swift
// swift-tools-version: 6.0

import PackageDescription

let package = Package(
    name: "MemoryCompanion",
    platforms: [
        .macOS(.v14)
    ],
    products: [
        .executable(name: "MemoryCompanion", targets: ["MemoryCompanion"])
    ],
    targets: [
        .executableTarget(
            name: "MemoryCompanion",
            resources: [
                .process("Resources")
            ],
            linkerSettings: [
                .linkedFramework("AppKit"),
                .linkedFramework("EventKit"),
                .linkedFramework("SwiftUI"),
                .linkedFramework("UserNotifications"),
                .linkedFramework("Speech"),
                .linkedFramework("AVFoundation"),
                .linkedFramework("Carbon"),
                .linkedFramework("Security"),
                .linkedFramework("ScreenCaptureKit"),
                .linkedFramework("Vision"),
                .linkedLibrary("sqlite3")
            ]
        ),
        .testTarget(
            name: "MemoryCompanionTests",
            dependencies: ["MemoryCompanion"]
        )
    ]
)

```

### script/audit_public_repo.sh

```shell
#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "$0")/.."

patterns='(sk-[A-Za-z0-9_-]{20,}|AKIA[0-9A-Z]{16}|BEGIN (RSA |EC |OPENSSH )?PRIVATE KEY|api[_-]?key[[:space:]]*[:=][[:space:]]*[^$<{[:space:]]|password[[:space:]]*[:=][[:space:]]*[^$<{[:space:]]|/Users/[^/[:space:]]+)'
if git grep -nEI "$patterns" -- . ':(exclude)script/audit_public_repo.sh'; then
  echo "Potential private data found in tracked files." >&2
  exit 1
fi

for forbidden in '*.sqlite' '*.sqlite3' '*.db' '*.pem' '*.p12' '.env' '.env.*'; do
  if git ls-files "$forbidden" | grep -q .; then
    echo "Forbidden tracked file pattern: $forbidden" >&2
    exit 1
  fi
done

echo "Tracked-file privacy audit passed."

```

### scratch/transparency_fix.py

```python
import os
from pathlib import Path
from PIL import Image

def make_transparent(img_path):
    print(f"Processing {img_path}...")
    if not os.path.exists(img_path):
        print(f"File not found: {img_path}")
        return
        
    img = Image.open(img_path).convert("RGBA")
    data = img.getdata()
    width, height = img.size
    
    # Sample corner pixels to determine checkerboard colors
    color1 = img.getpixel((0, 0))[:3]
    # Sample 16 pixels to the right to catch the second checkerboard square
    color2 = img.getpixel((16, 0))[:3] if width > 16 else color1
    
    print(f"Sampled checkerboard color 1: {color1}")
    print(f"Sampled checkerboard color 2: {color2}")
    
    new_data = []
    
    def matches_bg(pixel):
        r, g, b, a = pixel
        # Euclidean distance squared to color1 and color2
        dist1 = (r - color1[0])**2 + (g - color1[1])**2 + (b - color1[2])**2
        dist2 = (r - color2[0])**2 + (g - color2[1])**2 + (b - color2[2])**2
        # Threshold: if it is very close to either checkerboard color
        return dist1 < 625 or dist2 < 625  # 25 pixel distance threshold squared
        
    for item in data:
        if matches_bg(item):
            new_data.append((0, 0, 0, 0))
        else:
            new_data.append(item)
            
    img.putdata(new_data)
    img.save(img_path, "PNG")
    print(f"Successfully removed background from {img_path}")

resources_dir = Path(__file__).resolve().parents[1] / "Sources/MemoryCompanion/Resources"
for name in ["sparky-base.png", "cat-base.png", "orby-base.png"]:
    path = os.path.join(resources_dir, name)
    make_transparent(path)

```

### script/build_and_run.sh

```shell
#!/usr/bin/env bash
set -euo pipefail

APP_NAME="MemoryCompanion"
APP_DISPLAY_NAME="Second Shift"
APP_IDENTIFIER="local.memory-companion.app"
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
DIST_DIR="$ROOT_DIR/dist"
APP_DIR="$DIST_DIR/$APP_NAME.app"
RELEASE_ZIP="$DIST_DIR/SecondShift-macOS.zip"
STAGING_APP_DIR="${TMPDIR:-/private/tmp}/$APP_NAME-build-$$.app"
RELEASE_STAGE_DIR="${TMPDIR:-/private/tmp}/SecondShift-release-$$"
EXECUTABLE="$ROOT_DIR/.build/debug/$APP_NAME"

trap 'rm -rf "$STAGING_APP_DIR" "$RELEASE_STAGE_DIR"' EXIT

cd "$ROOT_DIR"

if pgrep -x "$APP_NAME" >/dev/null 2>&1; then
  pkill -x "$APP_NAME" || true
fi

swift build

rm -rf "$STAGING_APP_DIR"
mkdir -p "$STAGING_APP_DIR/Contents/MacOS"
cp "$EXECUTABLE" "$STAGING_APP_DIR/Contents/MacOS/$APP_NAME"
mkdir -p "$STAGING_APP_DIR/Contents/Resources"
cp -R "$ROOT_DIR/Tools/second-shift-bridge" "$STAGING_APP_DIR/Contents/Resources/second-shift-bridge"
cp "$ROOT_DIR/Design/Brand/app-icon.png" "$STAGING_APP_DIR/Contents/Resources/SecondShift.png"

cat > "$STAGING_APP_DIR/Contents/Info.plist" <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>CFBundleExecutable</key>
  <string>$APP_NAME</string>
  <key>CFBundleIdentifier</key>
  <string>$APP_IDENTIFIER</string>
  <key>CFBundleName</key>
  <string>$APP_DISPLAY_NAME</string>
  <key>CFBundleDisplayName</key>
  <string>$APP_DISPLAY_NAME</string>
  <key>CFBundleShortVersionString</key>
  <string>0.1.0</string>
  <key>CFBundleVersion</key>
  <string>1</string>
  <key>CFBundlePackageType</key>
  <string>APPL</string>
  <key>CFBundleIconFile</key>
  <string>SecondShift.png</string>
  <key>LSMinimumSystemVersion</key>
  <string>14.0</string>
  <key>LSMultipleInstancesProhibited</key>
  <true/>
  <key>NSCalendarsFullAccessUsageDescription</key>
  <string>Memory Companion can connect calendar events to your local memory timeline.</string>
  <key>NSRemindersFullAccessUsageDescription</key>
  <string>Memory Companion can connect reminders to your local idea follow-ups.</string>
  <key>NSAppleEventsUsageDescription</key>
  <string>Second Shift reads only the Apple Notes folders you select and keeps changed notes in your local context.</string>
  <key>NSSpeechRecognitionUsageDescription</key>
  <string>Memory Companion uses speech recognition to capture your ideas by voice.</string>
  <key>NSMicrophoneUsageDescription</key>
  <string>Memory Companion needs the microphone to transcribe your spoken ideas.</string>
  <key>NSPrefersDisplaySafeAreaCompatibilityMode</key>
  <false/>
  <key>NSPrincipalClass</key>
  <string>NSApplication</string>
</dict>
</plist>
PLIST

xattr -cr "$STAGING_APP_DIR"
xattr -d com.apple.FinderInfo "$STAGING_APP_DIR" 2>/dev/null || true
xattr -d 'com.apple.fileprovider.fpfs#P' "$STAGING_APP_DIR" 2>/dev/null || true
codesign --force --deep --sign - \
  --requirements "=designated => identifier \"$APP_IDENTIFIER\"" \
  --entitlements "$ROOT_DIR/MemoryCompanion.entitlements" \
  "$STAGING_APP_DIR"
codesign --verify --deep --strict "$STAGING_APP_DIR"

rm -f "$RELEASE_ZIP"
mkdir -p "$RELEASE_STAGE_DIR"
cp -R "$STAGING_APP_DIR" "$RELEASE_STAGE_DIR/Second Shift.app"
xattr -cr "$RELEASE_STAGE_DIR/Second Shift.app"
xattr -d com.apple.FinderInfo "$RELEASE_STAGE_DIR/Second Shift.app" 2>/dev/null || true
xattr -d 'com.apple.fileprovider.fpfs#P' "$RELEASE_STAGE_DIR/Second Shift.app" 2>/dev/null || true
codesign --force --deep --sign - \
  --requirements "=designated => identifier \"$APP_IDENTIFIER\"" \
  --entitlements "$ROOT_DIR/MemoryCompanion.entitlements" \
  "$RELEASE_STAGE_DIR/Second Shift.app"
codesign --verify --deep --strict "$RELEASE_STAGE_DIR/Second Shift.app"
(
  cd "$RELEASE_STAGE_DIR"
  COPYFILE_DISABLE=1 /usr/bin/zip -qry "$RELEASE_ZIP" "Second Shift.app"
)

if [[ "${1:-}" == "--package" ]]; then
  echo "$APP_NAME packaged and signature verified: $RELEASE_ZIP"
  exit 0
fi

rm -rf "$APP_DIR"
cp -R "$STAGING_APP_DIR" "$APP_DIR"
xattr -cr "$APP_DIR"
xattr -d com.apple.FinderInfo "$APP_DIR" 2>/dev/null || true
xattr -d 'com.apple.fileprovider.fpfs#P' "$APP_DIR" 2>/dev/null || true
# The app is already signed and strictly verified in staging. Documents may be
# backed by File Provider, which can immediately attach Finder metadata to the
# copied app and make a redundant second signing pass fail despite unchanged
# executable contents.

if [[ "${1:-}" == "--verify" ]]; then
  /usr/bin/open "$APP_DIR"
  sleep 2
  pgrep -x "$APP_NAME" >/dev/null
  echo "$APP_NAME launched"
else
  /usr/bin/open "$APP_DIR"
fi

```

### Tests/MemoryCompanionTests/ComposioConnectorTests.swift

```swift
import Foundation
import Testing
@testable import MemoryCompanion

@Suite struct ComposioConnectorTests {
    @Test func curatedGalleryUsesOnlyProductivityToolkits() {
        #expect(Set(ComposioToolkit.allCases.map(\.rawValue)) == [
            "github", "linear", "notion", "gmail", "slack", "googledrive", "googletasks"
        ])
        #expect(ComposioToolkit.allCases.allSatisfy { !$0.contextPolicy.isEmpty })
    }

    @Test func everyToolkitShipsWithAnOfflineLogo() {
        for toolkit in ComposioToolkit.allCases {
            #expect(toolkit.logoURL != nil)
        }
    }
}

```

### Tests/MemoryCompanionTests/AppleNotesImportServiceTests.swift

```swift
import Foundation
import Testing
@testable import MemoryCompanion

struct AppleNotesImportServiceTests {
    @Test func emptyAppleEventDescriptorDoesNotCrash() {
        let descriptor = NSAppleEventDescriptor(listDescriptor: ())

        #expect(AppleNotesImportService.descriptorLists(descriptor).isEmpty)
    }

    @Test func emptyRowsAreIgnoredWithoutCreatingInvalidRanges() {
        let descriptor = NSAppleEventDescriptor(listDescriptor: ())
        descriptor.insert(NSAppleEventDescriptor(listDescriptor: ()), at: 1)

        #expect(AppleNotesImportService.descriptorLists(descriptor).isEmpty)
    }
}

```

### Tests/MemoryCompanionTests/FocusMetricsTests.swift

```swift
import Foundation
import Testing
@testable import MemoryCompanion

struct FocusMetricsTests {
    @Test func debriefPersistsCalmFocusMetricsWithoutARewardScore() throws {
        let debrief = ShiftDebrief(
            sessionID: UUID(), projectID: "p", focusedMinutes: 24,
            completedSteps: ["Ship fix"], skippedSteps: [], capturedThoughts: ["Follow up"],
            notes: "", stillOpen: nil, nextRecommendedFocus: "Review release",
            plannedMinutes: 30, interruptionCount: 1
        )
        let encoded = try JSONEncoder().encode(debrief)
        let decoded = try JSONDecoder().decode(ShiftDebrief.self, from: encoded)
        #expect(decoded.plannedMinutes == 30)
        #expect(decoded.focusedMinutes == 24)
        #expect(decoded.interruptionCount == 1)
        #expect(decoded.completedSteps.count == 1)
        #expect(decoded.capturedThoughts.count == 1)
    }
}

```

[113 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]