Skip to content

Commit 562f1c4

Browse files
docs(bestpractices): add CHANGELOG + docs/ folder for OpenSSF criteria (RAN-55) (#3)
Closes the last two `Unmet` blockers from the bestpractices.dev/projects/12648 audit (board comment on RAN-55): - `release_notes` Unmet → Met. Add CHANGELOG.md (Keep a Changelog 1.1.0 format) with an [Unreleased] section that catalogues what landed in PR #1: OpenSSF scaffolding, OSV-Scanner CI fix, debounced-search-on-close fix, deep-review fixes, LICENSE attribution, Security adoption notes. Pre-1.0 the commit SHA on `main` is the version identifier; the [Unreleased] block rolls into a versioned heading when the first tag is cut. - `documentation_basics` Unmet ("No appropriate folder found") → Met. Add docs/ folder with: docs/README.md (index), docs/architecture.md (5-phase startup, repo shape, runtime invariants, stack), docs/install.md (requirements, run + flags, tests, update path), docs/troubleshooting.md (preflight bitmap, CLM / AppLocker / EDR blockers, DPAPI store recovery), docs/security.md (threat model, hardened invariants, crypto, distribution integrity). - Update .bestpractices.json: * documentation_basics_status: Met (now backed by docs/ folder; URL added pointing at the tree) * release_notes_status: N/A → Met (URL added pointing at CHANGELOG.md) * release_notes_vulns_status: N/A → Met (URL added pointing at CHANGELOG.md#security) Co-authored-by: Paperclip <noreply@paperclip.ing>
1 parent bce5f30 commit 562f1c4

7 files changed

Lines changed: 379 additions & 5 deletions

File tree

.bestpractices.json

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"license_location_url": "https://github.com/RandomCodeSpace/vigil/blob/main/LICENSE",
2828

2929
"documentation_basics_status": "Met",
30-
"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.",
30+
"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.",
31+
"documentation_basics_url": "https://github.com/RandomCodeSpace/vigil/tree/main/docs",
3132

3233
"documentation_interface_status": "Met",
3334
"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.",
@@ -53,11 +54,13 @@
5354
"version_unique_status": "Met",
5455
"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.",
5556

56-
"release_notes_status": "N/A",
57-
"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.",
57+
"release_notes_status": "Met",
58+
"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.",
59+
"release_notes_url": "https://github.com/RandomCodeSpace/vigil/blob/main/CHANGELOG.md",
5860

59-
"release_notes_vulns_status": "N/A",
60-
"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.",
61+
"release_notes_vulns_status": "Met",
62+
"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.",
63+
"release_notes_vulns_url": "https://github.com/RandomCodeSpace/vigil/blob/main/CHANGELOG.md#security",
6164

6265
"report_process_status": "Met",
6366
"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).",

CHANGELOG.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Changelog
2+
3+
All notable changes to Vigil are documented in this file.
4+
5+
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.
6+
7+
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.
8+
9+
## [Unreleased]
10+
11+
### Added
12+
13+
- **OpenSSF Best Practices + Scorecard scaffolding** ([RAN-55], [RAN-60]).
14+
- `.github/workflows/scorecard.yml` — OpenSSF Scorecard supply-chain analysis (push to `main` + Mondays 06:00 UTC, SHA-pinned actions, SARIF + artifact).
15+
- `.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.
16+
- `.github/dependabot.yml``github-actions` ecosystem only (Vigil ships no language lockfile).
17+
- `.bestpractices.json` — canonical autofill schema, `project_id: 12648`, `level: passing`, per-criterion `*_status` + `*_justification` fields.
18+
- `CLAUDE.md` — architecture + conventions SSoT, OpenSSF observability target, Scorecard policy.
19+
- `SECURITY.md` — private-disclosure policy, scope, hardening references.
20+
- `AGENTS.md` — agent-collaborator entry point.
21+
- `README.md` — OpenSSF Best Practices + Scorecard badges at the top.
22+
- **`docs/` folder** ([RAN-55]) — documentation basics (architecture, run, troubleshooting, security model) for the OpenSSF `documentation_basics` criterion.
23+
- **`CHANGELOG.md`** — this file ([RAN-55]).
24+
25+
### Fixed
26+
27+
- **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.
28+
- **Search debounce on close** — pending search-input debounce is now flushed on window close, so the last text typed is never lost.
29+
- **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).
30+
31+
### Changed
32+
33+
- `LICENSE` — copyright attributed to `Amit Kumar` (matches the project lineage / sibling-repo precedent).
34+
35+
### Security
36+
37+
- 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.
38+
- 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.
39+
40+
[Unreleased]: https://github.com/RandomCodeSpace/vigil/commits/main
41+
[RAN-55]: https://github.com/RandomCodeSpace/vigil/issues
42+
[RAN-60]: https://github.com/RandomCodeSpace/vigil/issues

docs/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Vigil — Documentation
2+
3+
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.
4+
5+
## Contents
6+
7+
- [Architecture](architecture.md) — 5-phase startup, repository shape, file-by-file responsibilities, runtime invariants.
8+
- [Install & run](install.md) — system requirements, supported PowerShell hosts, first-run side effects (`.vigil/` path, auto-start shortcut, tray icon), `-NoUI` and `-IncludeCalendar` flags.
9+
- [Troubleshooting](troubleshooting.md) — common environment blockers (Constrained Language Mode, AppLocker / AMSI / EDR, Outlook COM auth), preflight bitmap decoding, log file location.
10+
- [Security model](security.md) — DPAPI scope, threat model, atomic-write contract, vulnerability disclosure pointer.
11+
12+
## See also
13+
14+
- [`README.md`](../README.md) — user-facing landing page (features, quickstart).
15+
- [`CLAUDE.md`](../CLAUDE.md) — architecture + conventions SSoT for code-touching changes.
16+
- [`AGENTS.md`](../AGENTS.md) — entry point for agent collaborators.
17+
- [`SECURITY.md`](../SECURITY.md) — vulnerability disclosure policy.
18+
- [`CHANGELOG.md`](../CHANGELOG.md) — release notes / `Unreleased` log.
19+
- [`.bestpractices.json`](../.bestpractices.json) — OpenSSF Best Practices self-assessment.

docs/architecture.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Architecture
2+
3+
Vigil is a single-file PowerShell + WPF desktop app. Three scripts compose the project; there is no compile step.
4+
5+
## Repository shape
6+
7+
| File | Purpose |
8+
|---|---|
9+
| [`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`. |
10+
| [`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. |
11+
| [`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. |
12+
| `.vigil/` | Runtime state (DPAPI-wrapped `tasks.json`, logs). Colocated next to the script; fallback `~/.vigil`; legacy migration from the old userprofile path. |
13+
14+
## 5-phase startup (`VIGIL.ps1`)
15+
16+
```
17+
1. preflight → environment checks, emits status bitmap
18+
2. quick-add → optional fast-path popup if invoked with input
19+
3. Outlook → 15-minute COM sync (flagged emails / 24h calendar / open tasks)
20+
runs on a separate runspace; never blocks the dispatcher
21+
4. shortcut → install desktop / startup shortcut on first run
22+
5. UI + tray → chromeless WPF window with Fluent / Mica + system tray icon
23+
```
24+
25+
Search input is debounced; the debounce is flushed on window close so the last text is never lost.
26+
27+
## Runtime invariants
28+
29+
These are enforced by the test harness and reviewed for at PR time:
30+
31+
1. **Single-instance mutex**`Global\VIGIL_TaskTracker` named mutex + P/Invoke window reactivation. Do not introduce a second process model.
32+
2. **DPAPI-wrapped `tasks.json`** — CurrentUser scope, only when BitLocker is off. Per-user OS-managed master key; no key material is exfiltrated.
33+
3. **Atomic writes** — via `[System.IO.File]::Replace` exclusively, never `Move-Item -Force`.
34+
4. **Outlook COM**`Sort()` **before** `Restrict()` for correct flagged counts; reverse-order `ReleaseComObject` + forced GC after each session to prevent RCW leaks.
35+
5. **Log rotation** — 500-line cap.
36+
6. **Cross-platform core** — anything that is not WPF / Outlook COM must run on Linux / macOS pwsh; the test suite enforces this.
37+
7. **`System.Drawing` is lazy-loaded** — Linux pwsh lacks `libgdiplus`; do not import at script top.
38+
8. **Path canonicalisation** — task-store path is canonicalised via `[System.IO.Path]::GetFullPath` and asserted to live under `.vigil/` or `~/.vigil`.
39+
9. **Reduce-motion** — variant strips Storyboards entirely; honour the user's preference.
40+
41+
## Stack
42+
43+
| Layer | Choice |
44+
|---|---|
45+
| Primary language | PowerShell 7.5+ (`pwsh`) — cross-platform core |
46+
| Legacy fallback | Windows PowerShell 5.1 — data layer only; Fluent theme degrades |
47+
| Runtime | .NET 9 |
48+
| UI | WPF / Fluent / Mica (Windows-only) |
49+
| Embedded C# | `Add-Type` inline P/Invoke for window reactivation + tray hotkeys |
50+
| External integration | Outlook COM (15-minute sync) |
51+
| Storage | DPAPI-wrapped `tasks.json` (CurrentUser scope) |
52+
| Tests | Custom asserts, dot-sources VIGIL with `-NoUI` |
53+
| Package manager | None — Vigil ships no `package-lock.json`, `pom.xml`, or `requirements.txt`. Dependencies are framework-bundled (.NET / pwsh built-ins). |
54+
55+
## See also
56+
57+
- [`CLAUDE.md`](../CLAUDE.md) §1–§9 — full conventions and quality gates.
58+
- [`docs/install.md`](install.md) — install + run.
59+
- [`docs/troubleshooting.md`](troubleshooting.md) — common environment issues.

docs/install.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Install & run
2+
3+
Vigil is distributed as PowerShell source. There is no installer, no compiled binary, no auto-updater.
4+
5+
## Requirements
6+
7+
| Component | Required | Notes |
8+
|---|---|---|
9+
| OS | Windows 10 / 11 (full UI) | Cross-platform pwsh on Linux / macOS works for the data layer + tests, no UI |
10+
| PowerShell | 7.5+ (`pwsh`) | Bundles .NET 9 |
11+
| .NET runtime | 9 | Bundled with PowerShell 7.5 |
12+
| Microsoft Outlook | Optional | Required only for the 15-minute Outlook COM sync (flagged emails / calendar / tasks) |
13+
| Disk | < 1 MB | Source-only; `.vigil/` stores at most a few KB of task data |
14+
15+
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)`.
16+
17+
## Get the source
18+
19+
```powershell
20+
git clone https://github.com/RandomCodeSpace/vigil.git
21+
cd vigil
22+
```
23+
24+
To pin to a specific revision:
25+
26+
```powershell
27+
git checkout <commit-sha>
28+
```
29+
30+
`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.
31+
32+
## Run
33+
34+
```powershell
35+
pwsh -ExecutionPolicy Bypass -File .\VIGIL.ps1
36+
```
37+
38+
First launch:
39+
40+
1. Runs `preflight.ps1` to emit the environment bitmap.
41+
2. Creates `.vigil/` next to `VIGIL.ps1` (fallback `~/.vigil` if the script directory is not writable; legacy `%USERPROFILE%\.vigil` is migrated).
42+
3. Installs a Desktop shortcut and registers an auto-start entry.
43+
4. Starts the chromeless WPF window with system-tray integration.
44+
45+
### Flags
46+
47+
| Flag | Behaviour |
48+
|---|---|
49+
| `-NoUI` | Headless mode — no WPF window, no tray icon. Used by the test harness. |
50+
| `-IncludeCalendar` | Include the next 24 hours of Outlook calendar items in the task list. |
51+
52+
Combine flags as needed: `pwsh -File .\VIGIL.ps1 -NoUI -IncludeCalendar`.
53+
54+
## Tests
55+
56+
```powershell
57+
pwsh -NoProfile -File .\Test-Vigil.ps1
58+
```
59+
60+
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).
61+
62+
## Update
63+
64+
```powershell
65+
git pull --ff-only origin main
66+
```
67+
68+
Vigil does not phone home; security fixes land on `main` and `git pull` is the patch channel. See [`SECURITY.md`](../SECURITY.md) §Supported versions.
69+
70+
## Uninstall
71+
72+
```powershell
73+
# Stop the running instance (close from tray) then:
74+
Remove-Item -Recurse .\.vigil # task store + logs
75+
# Remove the Desktop shortcut and auto-start entry by hand if desired.
76+
```
77+
78+
## See also
79+
80+
- [`docs/architecture.md`](architecture.md) — how the app is structured.
81+
- [`docs/troubleshooting.md`](troubleshooting.md) — common environment blockers.
82+
- [`docs/security.md`](security.md) — security model + threat model.

docs/security.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Security model
2+
3+
Vigil is a single-user desktop tool. The threat model assumes the user trusts the code they run as themselves.
4+
5+
## Threat model summary
6+
7+
**In scope:**
8+
9+
- Path traversal in the local task store (`.vigil/`).
10+
- Command / XAML injection via Outlook fields or manual task input rendered by the WPF binding layer.
11+
- DPAPI key handling (CurrentUser scope, BitLocker-off branch).
12+
- Outlook COM RCW lifecycle (resource leak → privilege-escalation surface if a hostile add-in is loaded).
13+
- Auto-start shortcut + tray-icon flows (privilege escalation through writable-shortcut hijack).
14+
- Single-instance mutex hijack (`Global\VIGIL_TaskTracker`).
15+
16+
**Out of scope:**
17+
18+
- Pre-existing local code execution as the same user. Vigil is a single-user desktop tool; you trust the code you run.
19+
- Public-internet attack surface. Vigil does not bind a network socket and does not phone home.
20+
- Third-party services we do not control (Microsoft Outlook, Windows DPAPI, GitHub itself) — please report those upstream.
21+
- Constrained Language Mode / AppLocker / AMSI-EDR interactions where the corporate policy is intentionally blocking script execution. `preflight.ps1` reports those as known blockers.
22+
23+
## Hardened invariants
24+
25+
Per [`CLAUDE.md`](../CLAUDE.md) §7 and enforced by `Test-Vigil.ps1`:
26+
27+
- **Inputs** — every Outlook field that hits the UI is treated as untrusted text; manual task input is escaped before being interpolated into XAML.
28+
- **Path canonicalisation** — task-store path is canonicalised via `[System.IO.Path]::GetFullPath` and asserted to live under `.vigil/` or `~/.vigil`.
29+
- **Atomic writes**`[System.IO.File]::Replace` only; never `Move-Item -Force`.
30+
- **No secrets in code / config / logs** — Gitleaks runs on full git history (.github/workflows/security.yml).
31+
- **CVE policy** — High/Critical = block merge; Medium = fix-or-document with TechLead sign-off; Low = next bump cycle.
32+
33+
## Crypto
34+
35+
Vigil's only crypto dependency is **Windows DPAPI** (Data Protection API). Used to wrap `tasks.json` at CurrentUser scope.
36+
37+
- Algorithm: AES-256 + HMAC-SHA-512 (Windows 10+).
38+
- Key handling: per-user OS-managed master key. Never exfiltrated, never leaves the machine.
39+
- No proprietary crypto is implemented in Vigil. No MD5 / SHA-1 for integrity, no DES / 3DES, no ECB mode, no hardcoded IVs / keys.
40+
- See [`.bestpractices.json`](../.bestpractices.json) `crypto_*` criteria for the full per-criterion rationale.
41+
42+
## Distribution integrity
43+
44+
- Source distributed exclusively over HTTPS via `git clone`.
45+
- Every commit on `main` is ssh-signed (board-owned branch protection toggle); verify via `git verify-commit <sha>`.
46+
- No GitHub Releases / signed tarballs yet — the commit SHA on `main` is the canonical version identifier.
47+
48+
## Reporting a vulnerability
49+
50+
**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.
51+
52+
## OpenSSF supply-chain observability
53+
54+
- [`.github/workflows/scorecard.yml`](../.github/workflows/scorecard.yml) — OpenSSF Scorecard (push to `main` + Mondays 06:00 UTC).
55+
- [`.github/workflows/security.yml`](../.github/workflows/security.yml) — Semgrep, OSV-Scanner, Trivy, Gitleaks, jscpd, Syft SBOM.
56+
- [`.github/dependabot.yml`](../.github/dependabot.yml)`github-actions` ecosystem only.
57+
- [`.bestpractices.json`](../.bestpractices.json) — OpenSSF Best Practices self-assessment, `project_id: 12648`.
58+
59+
## See also
60+
61+
- [`SECURITY.md`](../SECURITY.md) — disclosure policy + scope.
62+
- [`CLAUDE.md`](../CLAUDE.md) §7 — security gates.
63+
- [`docs/architecture.md`](architecture.md) — runtime invariants the security model relies on.

0 commit comments

Comments
 (0)