|
1 | | -# Aware — Agent Development Prompt |
| 1 | +# Aware Agent Bootstrap |
2 | 2 |
|
3 | | -## Overview |
| 3 | +Use this file as a pointer, not as the canonical product spec. |
4 | 4 |
|
5 | | -Build a macOS menu bar app that prevents screen dimming/sleep by periodically checking for user presence via the FaceTime camera. No UI beyond a menu bar icon. |
| 5 | +## Canonical Docs |
6 | 6 |
|
7 | | ---- |
| 7 | +- `repo-operating-model.md` defines routing, provenance, and artifact rules. |
| 8 | +- `SPEC.md` holds durable product truth. |
| 9 | +- `STATUS.md` holds current operational reality. |
| 10 | +- `PLANS.md` holds accepted future direction only. |
| 11 | +- `INBOX.md` is the scratch surface for untriaged intake. |
| 12 | +- `records/decisions/` and `records/agent-worklogs/` store durable decisions and execution history. |
8 | 13 |
|
9 | | -## Core Behavior |
| 14 | +## Working Rules |
10 | 15 |
|
11 | | -- Run as a menu bar–only app (`LSUIElement = YES`, no Dock icon). |
12 | | -- Register display sleep prevention using `IOPMAssertionCreateWithName` with assertion type `kIOPMAssertionTypePreventUserIdleDisplaySleep`. |
13 | | -- On a configurable polling interval (default: 30s), capture a single frame from the default `AVCaptureDevice` camera. |
14 | | -- Run the frame through Vision's `VNDetectFaceRectanglesRequest`. If ≥1 face is detected, call `IOPMAssertionDeclareSystemActivity` to reset the idle timer and prevent dimming. If no face is detected, release the assertion and allow normal sleep behavior. |
15 | | -- Camera is only active during the brief capture — not streaming continuously. |
| 16 | +- Do not duplicate product truth here; update the canonical repo docs instead. |
| 17 | +- Use stable IDs when creating artifacts: `IBX-*`, `RSH-*`, `DEC-*`, and `LOG-*`. |
| 18 | +- For normal post-bootstrap commits, include commit trailers: `project: aware`, `agent: <agent-id>`, `role: orchestrator|worker|subagent|operator`, and `artifacts: <artifact-id>[, ...]`. |
| 19 | +- Treat `README.md`, `docs/`, and `release-notes/` as user-facing or release-facing surfaces, not the canonical operating record. |
16 | 20 |
|
17 | | ---- |
| 21 | +## Codebase Orientation |
18 | 22 |
|
19 | | -## Face Detection & Hardware Acceleration |
| 23 | +- `Aware/` contains the Swift and AppKit runtime. |
| 24 | +- `Aware.xcodeproj/` contains project settings and build metadata. |
| 25 | +- `.github/workflows/` contains build, release, and appcast automation. |
| 26 | +- `docs/` and `release-notes/` contain Sparkle setup and release-publishing docs. |
20 | 27 |
|
21 | | -- Use `VNDetectFaceRectanglesRequest` via the Vision framework. This is already ANE/GPU-accelerated on Apple Silicon via Core ML internally — no `VNCoreMLRequest` wrapper needed, and no CPU-bound alternatives. |
22 | | -- Set the request's `revision` to `VNDetectFaceRectanglesRequestRevision3` (most accurate, still hardware-accelerated). |
23 | | -- Pass the captured `CMSampleBuffer` directly to `VNImageRequestHandler` using the `.cvPixelBuffer` path — avoid JPEG/PNG encoding the frame, which wastes CPU cycles. |
24 | | -- Downscale capture resolution: configure `AVCaptureSession` preset to `AVCaptureSessionPreset640x480` or `352x288`. Full-resolution frames are wasteful for binary face-present/absent detection. |
25 | | -- Run `VNImageRequestHandler` on a background `DispatchQueue` with `.userInitiated` QoS — this is what lets the system route work to the ANE/GPU rather than the main thread CPU. |
| 28 | +## Bootstrap Records |
26 | 29 |
|
27 | | ---- |
28 | | - |
29 | | -## Stack |
30 | | - |
31 | | -- **Language**: Swift |
32 | | -- **UI**: AppKit (NSStatusItem, NSMenu) |
33 | | -- **Camera**: AVFoundation |
34 | | -- **Face detection**: Vision |
35 | | -- **Sleep prevention**: IOKit |
36 | | -- **Target**: macOS 13+ |
37 | | -- **Dependencies**: None (no third-party packages) |
38 | | - |
39 | | ---- |
40 | | - |
41 | | -## Menu Bar Items |
42 | | - |
43 | | -| Item | Behavior | |
44 | | -|---|---| |
45 | | -| Enable/Disable toggle | Persisted via `UserDefaults` | |
46 | | -| Polling interval | 15s / 30s / 60s picker, persisted via `UserDefaults` | |
47 | | -| Last detection status | Displays "Face detected", "No face", or "Disabled" | |
48 | | -| Quit | Terminates the app | |
49 | | - |
50 | | ---- |
51 | | - |
52 | | -## Permissions |
53 | | - |
54 | | -- Request `NSCameraUsageDescription` at first enable. |
55 | | -- If camera permission is denied, show an alert and disable the feature gracefully. |
56 | | -- No network access. No data leaves the device. |
57 | | - |
58 | | ---- |
59 | | - |
60 | | -## Project Structure |
61 | | - |
62 | | -Single Xcode project. Separate service classes for distinct responsibilities: |
63 | | - |
64 | | -- `PresenceDetector` — owns `AVCaptureSession` lifecycle and `VNDetectFaceRectanglesRequest` execution |
65 | | -- `SleepAssertion` — wraps `IOPMAssertion` create/release logic |
66 | | -- `MenuBarController` — owns both services, drives the polling loop via `DispatchSourceTimer`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu` (AppKit), presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu`, presents menu via `NSStatusItem` and `NSMenu` |
67 | | - |
68 | | ---- |
69 | | - |
70 | | -## Efficiency Summary |
71 | | - |
72 | | -The key efficiency wins are: |
73 | | -1. Low-resolution capture (`352x288` or `640x480`) |
74 | | -2. Hardware-accelerated inference via Vision/ANE — no sustained CPU load |
75 | | -3. Camera only wakes for a fraction of a second per polling interval, not a continuous stream |
| 30 | +- Decision: `DEC-20260409-001` |
| 31 | +- Worklog: `LOG-20260409-001` |
0 commit comments