This commit is contained in:
ZacharyZhang-NY committed 2026-03-18 01:15:58 -04:00
1 parent 7a3db27ffa
commit 1ba3147ed2
96 files changed
+9400 -6269

No files matched your search

+264
View File
@@ -0,0 +1,264 @@
# 2026-03-17 Architecture Freeze
## Supported Platform Target
The product target remains cross-platform:
- macOS
- Windows
- Linux
The current codebase can build on the local host, but release readiness is not equivalent across targets yet.
### Platform-specific constraints to preserve
- macOS
- hidden inset title bar
- signing and notarization required for public release
- `safeStorage` may block on keychain access
- Windows
- App User Model ID is required for correct notifications and taskbar integration
- NSIS is the release target
- code signing required for updater trust
- Linux
- safe storage backend can fall back to weaker semantics when no secret store exists
- Wayland window behavior is more limited than X11
- AppImage is the primary packaged target today
## External Research Decisions
### Electron security
Based on the current Electron security checklist:
- keep `nodeIntegration: false`
- keep `contextIsolation: true`
- keep `sandbox: true`
- keep the custom `app://` protocol instead of `file://`
- validate sender URLs on every IPC entry point
- do not expose raw IPC objects in preload
- define a restrictive CSP in local renderer content
### Utility process
The current choice of `utilityProcess.fork()` is still the right worker primitive.
Reasoning:
- it keeps heavy connector execution off the renderer
- it is more aligned with Electron security guidance than broad use of `ELECTRON_RUN_AS_NODE`
- it is compatible with future fuse hardening around `runAsNode`
### Secret storage
`safeStorage` remains the primary storage contract.
Fallback rules:
- use OS-backed `safeStorage` when real encryption is available
- reject insecure runtime environments by default
- allow AES vault fallback only in explicitly allowed test/insecure modes
### Updater
`electron-updater` remains acceptable, but only if release lanes are made real.
Required implications:
- real publish endpoint
- signed macOS app
- Windows signing
- explicit metadata handling for the generic provider
- download/apply UX in-app, not just “check available”
## Process Boundary Freeze
### Main process
Owns:
- app lifecycle
- BrowserWindow creation
- custom protocol registration
- native menus / tray / dialogs / notifications
- database initialization
- worker process lifecycle
- updater lifecycle
- browser automation windows
- privileged IPC handlers
Must not:
- become the place where all query, mutation, aggregation, and orchestration code accumulates
### Preload
Owns:
- typed, minimal bridge from renderer to approved use-cases
Must not:
- expose raw `ipcRenderer`
- expose generic file-system or shell primitives
- become a mirror of every DB method
### Renderer
Owns:
- operator workflows
- presentation logic
- optimistic local UI state
- command palette / shell navigation
- empty / loading / error / review states
Must not:
- talk in raw CRUD terms when the user is performing operator flows
- own privileged state
- load whole-world snapshots forever as the only data pattern
### Utility process
Owns:
- connector execution
- per-run stream forwarding
- cancellation
- run queue scheduling local to worker
Must not:
- become the persistence layer
- own security policy decisions that belong in main
## State Ownership Model
### Renderer-local state
- selected entities
- open panels / modals
- search queries
- console UI state
- transient filter/sort state
### Persisted domain state
- companies
- connectors
- workspaces
- agents
- goals / projects / tasks
- approvals
- runs
- cost entries
- activity
- secrets
- automation rules
- workflows
- browser actions
### Runtime execution state
- active worker jobs
- agent concurrency map
- workspace lock ownership
- pending wakes
- update progress
- browser action queue
### Derived read models
These should be separated from write repositories:
- overview metrics
- inbox
- standup
- run queue / attention views
- workload and review summaries
## Storage Decision
### Current decision
Keep SQLite + WAL for this tranche.
### Constraints
- single-writer semantics remain acceptable if heavy aggregations are not kept in the same giant repository
- crash recovery must preserve unfinished run semantics
- backup / restore must remain profile-local and reversible
### Required follow-up
- split read models from write repositories
- add offset-based log readers
- keep artifacts and logs on disk, indexed in SQLite
## IPC Contract Strategy
### Contract rules
- every mutating IPC call must stay company-scoped when relevant
- large payloads should use typed request objects, not positional args
- contract names stay explicit and descriptive
- result envelopes stay structured
### Next contract change
The next contract slice will add:
- dedicated run listing / filtering reads
- chunked log reads
- connector selection in onboarding
## Renderer Information Architecture Freeze
Primary desktop sections:
1. Overview
2. Runs
3. Tasks
4. Approvals
5. Messages
6. Agents
7. Workspaces
8. Connectors
9. Costs
10. Activity
11. Settings
Secondary knowledge/operations surfaces can remain, but they should not dominate the shell.
## Milestone Mapping
### Architecture Freeze
- this document accepted
### Interactive Prototype
- shell reordered around operator workflows
- run console and runs list coherent
### Internal Alpha
- onboarding, connector health, task run, approval, message routing, and workspace inspection work together
### Cross-Platform Validation
- menu, tray, notification, and package behavior documented per OS
### Signed Beta
- updater feed real
- signing path documented and testable
### Release Candidate
- all repo quality gates green
### Production Ready
- security audit, release hardening, and operator workflow polish complete
+307
View File
@@ -0,0 +1,307 @@
# 2026-03-17 Audit And Rebuild Plan
## Execution Order
This document is the Phase 1-4 artifact required by `AGENTS.md`.
1. ProjectManager: read the full PRD and define milestone gates.
2. ResearchAnalyst: verify Electron runtime, security, packaging, updater, and OS constraints.
3. TechnicalImplementationResearcher: freeze main/preload/renderer/storage/runtime boundaries.
4. EnterpriseArchitect: validate dependency direction, module seams, IPC contracts, and naming rules.
Implementation work starts only after the decisions below are recorded.
## Scope
The audit covers:
- PRD alignment
- Electron main / preload / renderer boundaries
- IPC contracts, sender validation, and company scoping
- connector runtime execution, orchestration, and background work
- local persistence, backup / restore, workspace locking, and crash recovery
- renderer information architecture, onboarding, and desktop UX
- packaging, updater, release, and verification posture
- adapter package quality and test coverage
## Baseline Evidence
### Repository state
- The working tree is already in a large, incomplete refactor state.
- The repo is no longer a prototype shell; it already contains a local data model, automation engine, workflow engine, browser automation surface, and an Electron shell.
- The implementation breadth is now large enough that coherence, not feature count, is the main problem.
### Verification results on 2026-03-17
- `pnpm typecheck`: pass
- `pnpm test:unit`: pass
- `pnpm test:integration`: pass
- `pnpm test:packages`: pass
- `pnpm test:e2e`: pass
- `pnpm build:verify`: pass
- `pnpm build:dir`: pass, producing `build/release/AgentCompany-0.4.26-arm64-mac.zip`
- `pnpm lint`: fail
### Current build posture
- Main bundle: `out/main/index.js` about `592 kB`
- Preload bundle: `out/preload/index.js` about `151 kB`
- Renderer bundle: `out/renderer/assets/index-*.js` about `1.69 MB`
- Packaging currently succeeds only on the host platform tested locally.
## Research Notes
The following external references were re-checked during this audit:
- Electron security checklist: https://www.electronjs.org/docs/latest/tutorial/security
- BrowserWindow API and platform notices: https://www.electronjs.org/docs/latest/api/browser-window
- Utility process API: https://www.electronjs.org/docs/latest/api/utility-process
- safeStorage API: https://www.electronjs.org/docs/latest/api/safe-storage
- Electron fuses: https://www.electronjs.org/docs/latest/tutorial/fuses
- electron-builder auto-update guide: https://www.electron.build/auto-update
- electron-builder publish guide: https://www.electron.build/publish
These references matter because the PRD explicitly requires secure preload exposure, custom protocol usage, sandboxing, OS-backed secret storage, release signing, and update integrity.
## Current State Summary
The application already has the following real subsystems:
- Electron shell with `contextIsolation`, `nodeIntegration: false`, `sandbox: true`, and a custom `app://` protocol
- local `DatabaseSync` SQLite store with WAL mode
- local API server for agent-driven actions
- utility-process worker for connector execution
- run orchestration, automation rules, workflow pipelines, messages, approvals, documents, meetings, sprints, and browser actions
The main issue is not “missing a single feature”.
The issue is that the system surface is broader than the stability and architecture boundaries that currently support it.
## Findings
### High severity
1. Main-process data access is concentrated in a single synchronous repository that is too large to remain reliable.
- Evidence: `src/main/database.ts` is `3292` lines and owns schema setup, migrations, snapshots, orchestration state, cost accounting, approvals, messaging, workflow persistence, backup/restore, workspace locking, and dashboard aggregation.
- Impact:
- blocks maintainability
- encourages cross-domain coupling
- increases renderer-visible latency because many IPC calls read the same monolith
2. The renderer shell is still a god component and does not match the desktop-native operating model in the PRD.
- Evidence: `src/renderer/App.tsx` is `1520` lines and owns navigation, data loading, company switching, command palette, modal orchestration, run log buffering, and page composition for every domain.
- Impact:
- feature interaction is hard to reason about
- state ownership is blurred
- operator workflows such as run monitoring are buried behind a console drawer instead of having first-class surfaces
3. The verification gate defined by the project itself is currently broken because lint does not run.
- Evidence: `pnpm lint` fails with `ENOENT ... electron.vite.config.<timestamp>.mjs`.
- Impact:
- the release checklist in `AGENTS.md` is not met
- CI or local quality enforcement is unreliable
4. Update and release readiness are not production-grade.
- Evidence:
- `electron-builder.yml` still defaults to a generic placeholder publish URL
- `src/main/updater-service.ts` only checks availability; it does not implement a complete download/apply flow or pre-update backup
- local mac packaging falls back to ad-hoc signing and skips notarization
- Impact:
- no shippable trust chain for public release
- updater behavior is not aligned with PRD requirements
5. Automatic internal coordination is still mostly emergent behavior from prompts and heuristics, not a hardened orchestration contract.
- Evidence:
- `src/main/prompt-builder.ts` contains the majority of “real company behavior” instructions
- `src/main/automation-service.ts` uses rule-triggered wakeups and message dispatch to simulate organization flow
- no dedicated coordination state model exists for “conversation pending response”, “delegation awaiting acceptance”, or “review SLA breached”
- Impact:
- the system can appear intelligent in happy paths while remaining hard to debug in stalled paths
- message flow, approvals, and delegation are not deterministic enough for a production control plane
### Medium severity
1. Snapshot loading is coarse-grained and expensive.
- Evidence:
- `db.listSnapshot()` reads nearly every table every time
- `db.listRendererSnapshot()` still calls `listSnapshot()` first and only then filters by company
- `App.refresh()` reloads the entire current company snapshot on most domain events
- Impact:
- unnecessary main-process work
- unnecessary renderer re-renders
- future scale problems once run/message/activity volume increases
2. Run log access is full-file based, not incremental.
- Evidence:
- `src/main/database.ts#readRunLog` returns the entire log file
- renderer keeps in-memory log buffers in `App.tsx`
- PRD mismatch:
- PRD requires offset-based incremental log reading
- Impact:
- degraded performance on large logs
- poor long-running run observability
3. The preload bridge is typed but too broad for the current architecture maturity.
- Evidence: `src/preload/index.ts` exposes dozens of direct CRUD and orchestration methods.
- Impact:
- large privileged surface area
- difficult contract governance
- weak module boundaries between renderer and domain actions
4. Workflow and automation configuration crosses boundaries as opaque JSON strings.
- Evidence:
- `conditionsJson`, `actionConfigJson`, `stepsJson`, `triggerConfigJson`, `metadataJson`, `attachmentsJson` are passed across IPC and persistence as raw strings
- Impact:
- weak compile-time guarantees
- more runtime parsing failures
- harder migration and refactoring path
5. Onboarding still optimizes for spectacle more than operator clarity.
- Evidence:
- `src/renderer/components/CompanyOnboarding.tsx` strongly promises “autonomous company” behavior
- connector choice and capability differences are not explicit enough
- initial run review is not operator-first
- Impact:
- weak first-use trust
- harder diagnosis when the selected connector is degraded or capability-limited
6. Browser/social automation is fragile and outside the core PRD center of gravity.
- Evidence:
- `src/main/browser-manager.ts` relies on direct DOM selectors, timed delays, and third-party site structure
- Impact:
- brittle surface
- expands support burden
- competes with higher-priority core orchestration work
7. The app supports many domains, but there is no dedicated Runs page.
- Evidence:
- run monitoring exists only through dashboard widgets and the bottom console drawer
- PRD mismatch:
- PRD requires live runs and log console as first-class operating surfaces
### Low severity
1. Renderer design language is coherent but still too web-dashboard-like for a desktop control plane.
- Evidence:
- system font stack in `src/renderer/styles.css`
- single-column content area on many dense surfaces
- heavy modal use for editing
2. Package-level runtime verification is narrow.
- Evidence:
- `test:packages` covers only `adapter-opencode-local` and `adapter-kimi-local`
- `codex`, `claude`, and `gemini` packages do not have equivalent package test commands here
## Detailed Gap List By Domain
### Main / preload / IPC
- Sender validation exists and the custom protocol is correct, which is a good baseline.
- Contracts are typed, but not versioned and not yet narrowed by capability groups.
- `ipc-core-common.ts` and `ipc-domain-common.ts` still use `any`-heavy dependency wiring.
- The privileged bridge still mirrors domain CRUD too directly instead of exposing operator use-cases.
### Data / orchestration
- Workspace lock handling exists, but it is still embedded inside the database class.
- Queued-run recovery exists, but recovery semantics are still best-effort.
- Workflow execution is inline, stateful, and sync-heavy in the main process service layer.
- Aggregation views such as inbox, standup, and metrics are built inside the same DB class.
### Connectors
- Codex / Claude / Gemini / OpenCode have deeper execution paths than Kimi.
- Kimi remains generic CLI mode with explicit capability downgrade.
- Connector health checks use command probes and status translation, but operator feedback is still too shallow.
- Connector discovery and operator selection are still secondary in first-launch UX.
### Renderer
- The UI covers a large domain surface, but the operating hierarchy is inverted:
- overview first
- CRUD pages second
- runs/logs/workspaces hidden as secondary tools
- The app does not yet “scream” workspace, run, and coordination as the primary desktop tasks.
### Testing / release
- Current automated coverage is better than zero, but still not close to the PRD completion criteria.
- E2E currently proves only first-launch onboarding and console toggle.
- No E2E covers:
- task run lifecycle
- approval resolution
- message routing
- workflow execution
- connector health state changes
- backup/restore
- workspace locking / recovery
- Release docs do not yet define signed beta, RC, and production lanes.
## Rebuild Direction
### Tranche A: operator shell and observability
- add first-class Runs navigation and run triage workflow
- move run logs to chunked readers instead of whole-file loads
- make onboarding explicitly choose connector and workspace intent
- fix lint so the repo’s minimum quality gate works again
### Tranche B: boundary extraction
- split `AppDatabase` into read models, command repositories, and orchestration state store
- reduce preload surface to bounded capability groups
- split renderer shell from feature pages and detail inspectors
### Tranche C: release hardening
- define real update lanes and signing rules
- add updater backup/install flow
- document mac notarization, Windows signing, Linux packaging behavior
- flip relevant Electron fuses during packaging
## Milestone Gates
### Architecture Freeze
- audit findings accepted
- platform target confirmed
- process boundaries frozen
- core run / workspace / connector model frozen
### Interactive Prototype
- onboarding, connectors, agents, tasks, runs, console, workspaces all coherent
### Internal Alpha
- connector lifecycle, approvals, message routing, and crash recovery usable end-to-end
### Cross-Platform Validation
- macOS, Windows, Linux behavior documented and smoke-validated
### Signed Beta Build
- signing path defined
- updater feed real
- rollback / backup strategy documented
### Release Candidate
- lint, typecheck, unit, integration, E2E, build, and packaging gates all green
### Production Readiness
- security audit complete
- no placeholder release config remains
- operator workflows are deterministic and observable
## Next Implementation Slice
The next code tranche will target:
1. repair the lint gate
2. add first-class Runs navigation and incremental log loading
3. make onboarding force an explicit connector choice
4. keep build packaging green while making these changes
@@ -0,0 +1,31 @@
# 2026-03-17 Runtime/Security Tranche
This tranche locks the first production-boundary fixes before larger module extraction.
## Scope
- tighten agent run-token authority in the local API server
- stop default connector execution from bypassing runtime permission/sandbox flags
- harden renderer IPC sender validation
- prevent secret bindings from overriding process-critical environment keys
- make browser-action cancellation affect real execution, not only database state
## Why this tranche comes first
These issues sit underneath every feature:
1. A compromised or overpowered run token could mutate company structure, approvals, and browser automation.
2. A globally bypassed connector runtime defeats approval and sandbox posture for all task runs.
3. Loose origin matching weakens the only boundary between renderer and privileged main-process handlers.
4. Fake cancellation creates visible state drift between the UI and external side effects.
5. Unrestricted env injection allows privilege escalation through runtime process configuration.
## Intended outcome
After this tranche:
- agent runs can no longer approve approvals or request arbitrary organization changes without role-based checks
- connector child processes run without implicit dangerous bypass flags
- only exact trusted renderer origins can invoke privileged IPC handlers
- reserved env keys are blocked from connector secret bindings
- cancelling a browser action cancels queued or active execution, not just the row in SQLite
+13
View File
@@ -0,0 +1,13 @@
# Docs Index
Active documents only.
- [2026-03-17-audit-and-rebuild-plan.md](./2026-03-17-audit-and-rebuild-plan.md)
- [2026-03-17-architecture-freeze.md](./2026-03-17-architecture-freeze.md)
- [2026-03-17-runtime-security-tranche.md](./2026-03-17-runtime-security-tranche.md)
Removed:
- duplicate audit snapshots
- duplicate rebuild plans
- stale one-off implementation deltas that no longer matched the working tree