Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions .bestpractices.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
"license_location_url": "https://github.com/RandomCodeSpace/vigil/blob/main/LICENSE",

"documentation_basics_status": "Met",
"documentation_basics_justification": "README.md covers what vigil is, requirements (Windows 10/11, PowerShell 7.5+, .NET 9, optional Outlook), how to run, and how to test. CLAUDE.md §3 documents the repository shape (VIGIL.ps1, preflight.ps1, Test-Vigil.ps1, .vigil/) and §1 the product target. SECURITY.md documents the disclosure policy.",
"documentation_basics_justification": "Dedicated `docs/` folder at repo root collects the structured documentation: docs/README.md (index), docs/architecture.md (5-phase startup, repository shape, runtime invariants, stack), docs/install.md (system requirements, run + flags, tests, update path, uninstall), docs/troubleshooting.md (preflight bitmap decoding, CLM / AppLocker / AMSI / EDR blockers, DPAPI store recovery, single-instance mutex), and docs/security.md (threat model, hardened invariants, crypto, distribution integrity). README.md is the user-facing landing page; CLAUDE.md §3 documents the repository shape; SECURITY.md documents the disclosure policy.",
"documentation_basics_url": "https://github.com/RandomCodeSpace/vigil/tree/main/docs",

"documentation_interface_status": "Met",
"documentation_interface_justification": "README.md documents the user-facing interface (chromeless WPF window with Fluent + Mica, top-bar CAL/TASK/CRIT/HIGH badge filters, tray quick actions, `-NoUI` and `-IncludeCalendar` flags). CLAUDE.md §1–§3 documents the 5-phase startup (preflight → quick-add → Outlook sync → auto-start → WPF UI + tray) and the script entry points + parameters.",
Expand All @@ -53,11 +54,13 @@
"version_unique_status": "Met",
"version_unique_justification": "Each commit on `main` is uniquely identified by its Git SHA (full revision history is the version manifest). Distribution is `git clone` + `pwsh -File .\\VIGIL.ps1`, so users pin to an exact commit SHA. SECURITY.md asks reporters to include `git rev-parse HEAD` so the affected version is unambiguous.",

"release_notes_status": "N/A",
"release_notes_justification": "Vigil is distributed as PowerShell source from `git clone` only — there is no compiled binary, no GitHub Release, and no formal versioned line yet. SECURITY.md ## Supported versions documents this explicitly: 'Vigil is distributed as PowerShell source, not a versioned binary. Security fixes land on `main` and are tagged when material.' Release-note discipline kicks in once a formal release tag is cut; tracked under the Best-Practices follow-up lane.",
"release_notes_status": "Met",
"release_notes_justification": "CHANGELOG.md at repo root tracks all notable changes in Keep-a-Changelog 1.1.0 format. Pre-1.0 distribution is `git clone` of `main` (no compiled binary, no GitHub Release line yet), so the canonical version identifier is the commit SHA on `main` and CHANGELOG ## [Unreleased] catalogues what has landed since the last reference point. Sections covered: Added, Fixed, Changed, Security. Each entry cross-links the Paperclip ticket (RAN-XX). When the first tagged release is cut the [Unreleased] section will be rolled into a versioned heading per the same format.",
"release_notes_url": "https://github.com/RandomCodeSpace/vigil/blob/main/CHANGELOG.md",

"release_notes_vulns_status": "N/A",
"release_notes_vulns_justification": "Same N/A rationale as `release_notes` — vigil has no formal release line yet, so there are no per-release notes in which to enumerate fixed vulnerabilities. SECURITY.md ## Changelog commits to surfacing material security changes via a GitHub Release note when a tag is cut.",
"release_notes_vulns_status": "Met",
"release_notes_vulns_justification": "CHANGELOG.md ## Security section is the dedicated lane for vulnerability-related entries — currently lists adoption of the (B) OSS-CLI security stack as the continuous supply-chain observability surface. Future fixed CVEs will be enumerated in the same section, cross-referencing the GHSA advisory ID where one is published. Pre-1.0 the entry lives under [Unreleased] ## Security; once a tagged line exists each release block carries its own ## Security subsection.",
"release_notes_vulns_url": "https://github.com/RandomCodeSpace/vigil/blob/main/CHANGELOG.md#security",

"report_process_status": "Met",
"report_process_justification": "SECURITY.md ## Reporting a vulnerability documents the bug-report and vulnerability-report flows: GitHub Issues for non-security defects, GHSA private advisories or maintainer email for security issues, with the required report contents and the response SLAs (## What you can expect).",
Expand Down
42 changes: 42 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Changelog

All notable changes to Vigil are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html) once a tagged release line exists.

While Vigil remains pre-1.0 and distributed as PowerShell source from `git clone`, every commit on `main` is the canonical version identifier (`git rev-parse HEAD`). The "Unreleased" section below tracks what has landed on `main` since the last tag.

## [Unreleased]

### Added

- **OpenSSF Best Practices + Scorecard scaffolding** ([RAN-55], [RAN-60]).
- `.github/workflows/scorecard.yml` — OpenSSF Scorecard supply-chain analysis (push to `main` + Mondays 06:00 UTC, SHA-pinned actions, SARIF + artifact).
- `.github/workflows/security.yml` — consolidated OSS-CLI stack (Semgrep, OSV-Scanner via binary install, Trivy filesystem, Gitleaks, jscpd, anchore/sbom-action). PR + push + weekly cron.
- `.github/dependabot.yml` — `github-actions` ecosystem only (Vigil ships no language lockfile).
- `.bestpractices.json` — canonical autofill schema, `project_id: 12648`, `level: passing`, per-criterion `*_status` + `*_justification` fields.
- `CLAUDE.md` — architecture + conventions SSoT, OpenSSF observability target, Scorecard policy.
- `SECURITY.md` — private-disclosure policy, scope, hardening references.
- `AGENTS.md` — agent-collaborator entry point.
- `README.md` — OpenSSF Best Practices + Scorecard badges at the top.
- **`docs/` folder** ([RAN-55]) — documentation basics (architecture, run, troubleshooting, security model) for the OpenSSF `documentation_basics` criterion.
- **`CHANGELOG.md`** — this file ([RAN-55]).

### Fixed

- **OSV-Scanner CI** ([RAN-55]) — replaced the broken `google/osv-scanner-action@v2.3.5` (composite `action.yml` missing the top-level `runs:` block) with a `gh release download` binary install. Mirrors the codeiq fix; coverage activates automatically once a `*.lock` lands in-tree.
- **Search debounce on close** — pending search-input debounce is now flushed on window close, so the last text typed is never lost.
- **Deep-review findings** — fixes across `VIGIL.ps1`, `preflight.ps1`, `Test-Vigil.ps1` (DPAPI key path edge cases, atomic-write contract, Outlook RCW lifecycle, log rotation timing, single-instance mutex hand-off).

### Changed

- `LICENSE` — copyright attributed to `Amit Kumar` (matches the project lineage / sibling-repo precedent).

### Security

- Adopted the (B) OSS-CLI security stack as the project's continuous supply-chain observability surface. High/Critical findings are merge gates per `CLAUDE.md` §7. SARIF results land in the GitHub Security tab where supported and are uploaded as workflow artifacts regardless.
- Branch protection on `main` (signed commits, required PR review, required status checks) and repo-level secret scanning + push protection are board-owned toggles tracked alongside [RAN-55] until enabled.

[Unreleased]: https://github.com/RandomCodeSpace/vigil/commits/main
[RAN-55]: https://github.com/RandomCodeSpace/vigil/issues
[RAN-60]: https://github.com/RandomCodeSpace/vigil/issues
19 changes: 19 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Vigil — Documentation

Documentation index for the Vigil project. The canonical "what / why / how" lives at the repo root in [`README.md`](../README.md); this folder holds the structured docs that the OpenSSF Best Practices `documentation_basics` criterion expects.

## Contents

- [Architecture](architecture.md) — 5-phase startup, repository shape, file-by-file responsibilities, runtime invariants.
- [Install & run](install.md) — system requirements, supported PowerShell hosts, first-run side effects (`.vigil/` path, auto-start shortcut, tray icon), `-NoUI` and `-IncludeCalendar` flags.
- [Troubleshooting](troubleshooting.md) — common environment blockers (Constrained Language Mode, AppLocker / AMSI / EDR, Outlook COM auth), preflight bitmap decoding, log file location.
- [Security model](security.md) — DPAPI scope, threat model, atomic-write contract, vulnerability disclosure pointer.

## See also

- [`README.md`](../README.md) — user-facing landing page (features, quickstart).
- [`CLAUDE.md`](../CLAUDE.md) — architecture + conventions SSoT for code-touching changes.
- [`AGENTS.md`](../AGENTS.md) — entry point for agent collaborators.
- [`SECURITY.md`](../SECURITY.md) — vulnerability disclosure policy.
- [`CHANGELOG.md`](../CHANGELOG.md) — release notes / `Unreleased` log.
- [`.bestpractices.json`](../.bestpractices.json) — OpenSSF Best Practices self-assessment.
59 changes: 59 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Architecture

Vigil is a single-file PowerShell + WPF desktop app. Three scripts compose the project; there is no compile step.

## Repository shape

| File | Purpose |
|---|---|
| [`VIGIL.ps1`](../VIGIL.ps1) | Main app (≈99 KB). 5-phase startup, WPF window, system-tray integration, Outlook COM sync, persistent task store. Parameters: `-NoUI`, `-IncludeCalendar`. |
| [`preflight.ps1`](../preflight.ps1) | 60 environment checks (runtime, corp lockdown CLM / AppLocker / AMSI, Azure AD, hardware). Emits the compact bitmap `VIGIL:v1:<count>:<hex>:P<n>:F<n>:T<tenant>` consumed by the main app. |
| [`Test-Vigil.ps1`](../Test-Vigil.ps1) | Dot-sources `VIGIL.ps1` with `-NoUI`; custom asserts; runs on PowerShell 5.1 and pwsh 6+ across Linux / macOS / Windows. ≈116 cross-platform unit tests for the data layer. |
| `.vigil/` | Runtime state (DPAPI-wrapped `tasks.json`, logs). Colocated next to the script; fallback `~/.vigil`; legacy migration from the old userprofile path. |

## 5-phase startup (`VIGIL.ps1`)

```
1. preflight → environment checks, emits status bitmap
2. quick-add → optional fast-path popup if invoked with input
3. Outlook → 15-minute COM sync (flagged emails / 24h calendar / open tasks)
runs on a separate runspace; never blocks the dispatcher
4. shortcut → install desktop / startup shortcut on first run
5. UI + tray → chromeless WPF window with Fluent / Mica + system tray icon
```

Search input is debounced; the debounce is flushed on window close so the last text is never lost.

## Runtime invariants

These are enforced by the test harness and reviewed for at PR time:

1. **Single-instance mutex** — `Global\VIGIL_TaskTracker` named mutex + P/Invoke window reactivation. Do not introduce a second process model.
2. **DPAPI-wrapped `tasks.json`** — CurrentUser scope, only when BitLocker is off. Per-user OS-managed master key; no key material is exfiltrated.
3. **Atomic writes** — via `[System.IO.File]::Replace` exclusively, never `Move-Item -Force`.
4. **Outlook COM** — `Sort()` **before** `Restrict()` for correct flagged counts; reverse-order `ReleaseComObject` + forced GC after each session to prevent RCW leaks.
5. **Log rotation** — 500-line cap.
6. **Cross-platform core** — anything that is not WPF / Outlook COM must run on Linux / macOS pwsh; the test suite enforces this.
7. **`System.Drawing` is lazy-loaded** — Linux pwsh lacks `libgdiplus`; do not import at script top.
8. **Path canonicalisation** — task-store path is canonicalised via `[System.IO.Path]::GetFullPath` and asserted to live under `.vigil/` or `~/.vigil`.
9. **Reduce-motion** — variant strips Storyboards entirely; honour the user's preference.

## Stack

| Layer | Choice |
|---|---|
| Primary language | PowerShell 7.5+ (`pwsh`) — cross-platform core |
| Legacy fallback | Windows PowerShell 5.1 — data layer only; Fluent theme degrades |
| Runtime | .NET 9 |
| UI | WPF / Fluent / Mica (Windows-only) |
| Embedded C# | `Add-Type` inline P/Invoke for window reactivation + tray hotkeys |
| External integration | Outlook COM (15-minute sync) |
| Storage | DPAPI-wrapped `tasks.json` (CurrentUser scope) |
| Tests | Custom asserts, dot-sources VIGIL with `-NoUI` |
| Package manager | None — Vigil ships no `package-lock.json`, `pom.xml`, or `requirements.txt`. Dependencies are framework-bundled (.NET / pwsh built-ins). |

## See also

- [`CLAUDE.md`](../CLAUDE.md) §1–§9 — full conventions and quality gates.
- [`docs/install.md`](install.md) — install + run.
- [`docs/troubleshooting.md`](troubleshooting.md) — common environment issues.
82 changes: 82 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Install & run

Vigil is distributed as PowerShell source. There is no installer, no compiled binary, no auto-updater.

## Requirements

| Component | Required | Notes |
|---|---|---|
| OS | Windows 10 / 11 (full UI) | Cross-platform pwsh on Linux / macOS works for the data layer + tests, no UI |
| PowerShell | 7.5+ (`pwsh`) | Bundles .NET 9 |
| .NET runtime | 9 | Bundled with PowerShell 7.5 |
| Microsoft Outlook | Optional | Required only for the 15-minute Outlook COM sync (flagged emails / calendar / tasks) |
| Disk | < 1 MB | Source-only; `.vigil/` stores at most a few KB of task data |

PowerShell 5.1 is supported as a legacy fallback for the data layer only — the WPF Fluent theme degrades and parts of the UI are gated behind `if ($PSVersionTable.PSVersion.Major -ge 7)`.

## Get the source

```powershell
git clone https://github.com/RandomCodeSpace/vigil.git
cd vigil
```

To pin to a specific revision:

```powershell
git checkout <commit-sha>
```

`SECURITY.md` asks vulnerability reporters to include `git rev-parse HEAD` so the affected version is unambiguous; the commit SHA is the canonical version identifier until a tagged release line exists.

## Run

```powershell
pwsh -ExecutionPolicy Bypass -File .\VIGIL.ps1
```

First launch:

1. Runs `preflight.ps1` to emit the environment bitmap.
2. Creates `.vigil/` next to `VIGIL.ps1` (fallback `~/.vigil` if the script directory is not writable; legacy `%USERPROFILE%\.vigil` is migrated).
3. Installs a Desktop shortcut and registers an auto-start entry.
4. Starts the chromeless WPF window with system-tray integration.

### Flags

| Flag | Behaviour |
|---|---|
| `-NoUI` | Headless mode — no WPF window, no tray icon. Used by the test harness. |
| `-IncludeCalendar` | Include the next 24 hours of Outlook calendar items in the task list. |

Combine flags as needed: `pwsh -File .\VIGIL.ps1 -NoUI -IncludeCalendar`.

## Tests

```powershell
pwsh -NoProfile -File .\Test-Vigil.ps1
```

Test-Vigil.ps1 dot-sources VIGIL.ps1 with `-NoUI`; runs on PowerShell 5.1 and pwsh 6+ across Linux / macOS / Windows. Approximately 116 unit tests cover the data layer (task model, store path resolution + legacy migration, atomic writes, DPAPI key handling on Windows, Outlook sort-before-restrict invariant, RCW lifecycle hygiene, log rotation).

## Update

```powershell
git pull --ff-only origin main
```

Vigil does not phone home; security fixes land on `main` and `git pull` is the patch channel. See [`SECURITY.md`](../SECURITY.md) §Supported versions.

## Uninstall

```powershell
# Stop the running instance (close from tray) then:
Remove-Item -Recurse .\.vigil # task store + logs
# Remove the Desktop shortcut and auto-start entry by hand if desired.
```

## See also

- [`docs/architecture.md`](architecture.md) — how the app is structured.
- [`docs/troubleshooting.md`](troubleshooting.md) — common environment blockers.
- [`docs/security.md`](security.md) — security model + threat model.
63 changes: 63 additions & 0 deletions docs/security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Security model

Vigil is a single-user desktop tool. The threat model assumes the user trusts the code they run as themselves.

## Threat model summary

**In scope:**

- Path traversal in the local task store (`.vigil/`).
- Command / XAML injection via Outlook fields or manual task input rendered by the WPF binding layer.
- DPAPI key handling (CurrentUser scope, BitLocker-off branch).
- Outlook COM RCW lifecycle (resource leak → privilege-escalation surface if a hostile add-in is loaded).
- Auto-start shortcut + tray-icon flows (privilege escalation through writable-shortcut hijack).
- Single-instance mutex hijack (`Global\VIGIL_TaskTracker`).

**Out of scope:**

- Pre-existing local code execution as the same user. Vigil is a single-user desktop tool; you trust the code you run.
- Public-internet attack surface. Vigil does not bind a network socket and does not phone home.
- Third-party services we do not control (Microsoft Outlook, Windows DPAPI, GitHub itself) — please report those upstream.
- Constrained Language Mode / AppLocker / AMSI-EDR interactions where the corporate policy is intentionally blocking script execution. `preflight.ps1` reports those as known blockers.

## Hardened invariants

Per [`CLAUDE.md`](../CLAUDE.md) §7 and enforced by `Test-Vigil.ps1`:

- **Inputs** — every Outlook field that hits the UI is treated as untrusted text; manual task input is escaped before being interpolated into XAML.
- **Path canonicalisation** — task-store path is canonicalised via `[System.IO.Path]::GetFullPath` and asserted to live under `.vigil/` or `~/.vigil`.
- **Atomic writes** — `[System.IO.File]::Replace` only; never `Move-Item -Force`.
- **No secrets in code / config / logs** — Gitleaks runs on full git history (.github/workflows/security.yml).
- **CVE policy** — High/Critical = block merge; Medium = fix-or-document with TechLead sign-off; Low = next bump cycle.

## Crypto

Vigil's only crypto dependency is **Windows DPAPI** (Data Protection API). Used to wrap `tasks.json` at CurrentUser scope.

- Algorithm: AES-256 + HMAC-SHA-512 (Windows 10+).
- Key handling: per-user OS-managed master key. Never exfiltrated, never leaves the machine.
- No proprietary crypto is implemented in Vigil. No MD5 / SHA-1 for integrity, no DES / 3DES, no ECB mode, no hardcoded IVs / keys.
- See [`.bestpractices.json`](../.bestpractices.json) `crypto_*` criteria for the full per-criterion rationale.

## Distribution integrity

- Source distributed exclusively over HTTPS via `git clone`.
- Every commit on `main` is ssh-signed (board-owned branch protection toggle); verify via `git verify-commit <sha>`.
- No GitHub Releases / signed tarballs yet — the commit SHA on `main` is the canonical version identifier.

## Reporting a vulnerability

**Do not open a public GitHub issue for security problems.** See [`SECURITY.md`](../SECURITY.md) for the private disclosure channels (GitHub Security Advisory + maintainer email) and the response SLAs.

## OpenSSF supply-chain observability

- [`.github/workflows/scorecard.yml`](../.github/workflows/scorecard.yml) — OpenSSF Scorecard (push to `main` + Mondays 06:00 UTC).
- [`.github/workflows/security.yml`](../.github/workflows/security.yml) — Semgrep, OSV-Scanner, Trivy, Gitleaks, jscpd, Syft SBOM.
- [`.github/dependabot.yml`](../.github/dependabot.yml) — `github-actions` ecosystem only.
- [`.bestpractices.json`](../.bestpractices.json) — OpenSSF Best Practices self-assessment, `project_id: 12648`.

## See also

- [`SECURITY.md`](../SECURITY.md) — disclosure policy + scope.
- [`CLAUDE.md`](../CLAUDE.md) §7 — security gates.
- [`docs/architecture.md`](architecture.md) — runtime invariants the security model relies on.
Loading
Loading