ndomo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bun-version +1 -0
- package/.dockerignore +79 -0
- package/.editorconfig +18 -0
- package/.env.example +19 -0
- package/.github/CODEOWNERS +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
- package/.github/ISSUE_TEMPLATE/config.yml +2 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +34 -0
- package/.github/dependabot.yml +36 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/release.yml +30 -0
- package/.github/workflows/gitleaks.yml +28 -0
- package/.github/workflows/release-please.yml +27 -0
- package/.github/workflows/smoke.yml +29 -0
- package/.husky/commit-msg +1 -0
- package/CHANGELOG.md +114 -0
- package/Dockerfile +32 -0
- package/README.es.md +174 -0
- package/README.md +187 -0
- package/agents/chronicler.md +98 -0
- package/agents/ci-smith.md +136 -0
- package/agents/craftsman.md +341 -0
- package/agents/deploy-smith.md +138 -0
- package/agents/foreman.md +377 -0
- package/agents/go-smith.md +164 -0
- package/agents/guild.md +188 -0
- package/agents/inspector.md +83 -0
- package/agents/js-smith.md +127 -0
- package/agents/ops-scout.md +173 -0
- package/agents/painter.md +200 -0
- package/agents/python-smith.md +120 -0
- package/agents/ranger.md +307 -0
- package/agents/release-smith.md +165 -0
- package/agents/rust-smith.md +159 -0
- package/agents/sage.md +178 -0
- package/agents/scout.md +144 -0
- package/agents/scribe.md +156 -0
- package/agents/smith.md +201 -0
- package/agents/vue-smith.md +155 -0
- package/agents/warden.md +216 -0
- package/agents/zig-smith.md +156 -0
- package/bin/ndomo-analyses.ts +4 -0
- package/bin/ndomo-status.ts +4 -0
- package/biome.json +57 -0
- package/bun.lock +514 -0
- package/commitlint.config.js +3 -0
- package/config/ndomo.config.json +258 -0
- package/config/ndomo.schema.json +166 -0
- package/docs/agents.md +375 -0
- package/docs/bugs/plan-create-orphan-fk.md +131 -0
- package/docs/bugs/task_create_batch-order-index-collision.md +158 -0
- package/docs/configuration.md +276 -0
- package/docs/database.md +364 -0
- package/docs/features/feature-flexible-builder-v1.md +724 -0
- package/docs/features/feature-flexible-builder-v2.md +882 -0
- package/docs/features/feature-flexible-builder.md +974 -0
- package/docs/http-server.md +244 -0
- package/docs/installation.md +259 -0
- package/docs/integrations.md +129 -0
- package/docs/operations/anti-pattern-sub-agent-verify-2026-06-21.md +32 -0
- package/docs/operations/audit-v1.md +417 -0
- package/docs/operations/audit-v2.md +197 -0
- package/docs/operations/audit-v3.md +306 -0
- package/docs/operations/db-optimize-foundations.md +123 -0
- package/docs/operations/verify-gate-architecture.md +82 -0
- package/docs/workflows.md +448 -0
- package/opencode.json +5 -0
- package/package.json +65 -0
- package/release-please-config.json +11 -0
- package/scripts/dev-bust-cache.sh +164 -0
- package/scripts/install.sh +688 -0
- package/scripts/smoke-e2e.ts +704 -0
- package/scripts/smoke-hot.ts +417 -0
- package/scripts/smoke-http.sh +228 -0
- package/scripts/smoke-v4.ts +256 -0
- package/scripts/smoke-v5.ts +397 -0
- package/scripts/smoke.sh +9 -0
- package/scripts/uninstall.sh +224 -0
- package/skills/api-security-best-practices/SKILL.md +915 -0
- package/skills/bash-scripting/SKILL.md +201 -0
- package/skills/bun/SKILL.md +313 -0
- package/skills/cavecrew/SKILL.md +82 -0
- package/skills/caveman/SKILL.md +74 -0
- package/skills/caveman-review/README.md +33 -0
- package/skills/caveman-review/SKILL.md +55 -0
- package/skills/find-skills/SKILL.md +142 -0
- package/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/frontend-design/SKILL.md +55 -0
- package/skills/golang-patterns/SKILL.md +674 -0
- package/skills/golang-security/SKILL.md +185 -0
- package/skills/golang-security/evals/evals.json +595 -0
- package/skills/golang-security/references/architecture.md +268 -0
- package/skills/golang-security/references/checklist.md +80 -0
- package/skills/golang-security/references/cookies.md +200 -0
- package/skills/golang-security/references/cryptography.md +424 -0
- package/skills/golang-security/references/filesystem.md +285 -0
- package/skills/golang-security/references/injection.md +315 -0
- package/skills/golang-security/references/logging.md +163 -0
- package/skills/golang-security/references/memory-safety.md +241 -0
- package/skills/golang-security/references/network.md +253 -0
- package/skills/golang-security/references/secrets.md +189 -0
- package/skills/golang-security/references/third-party.md +159 -0
- package/skills/golang-security/references/threat-modeling.md +189 -0
- package/skills/golang-testing/SKILL.md +720 -0
- package/skills/grill-me/SKILL.md +7 -0
- package/skills/javascript-testing-patterns/SKILL.md +537 -0
- package/skills/javascript-testing-patterns/references/advanced-testing-patterns.md +513 -0
- package/skills/modern-javascript-patterns/SKILL.md +43 -0
- package/skills/modern-javascript-patterns/references/advanced-patterns.md +487 -0
- package/skills/modern-javascript-patterns/references/details.md +457 -0
- package/skills/python-anti-patterns/SKILL.md +349 -0
- package/skills/python-design-patterns/SKILL.md +85 -0
- package/skills/python-design-patterns/references/details.md +353 -0
- package/skills/python-error-handling/SKILL.md +193 -0
- package/skills/python-error-handling/references/details.md +171 -0
- package/skills/python-testing-patterns/SKILL.md +278 -0
- package/skills/python-testing-patterns/references/advanced-patterns.md +411 -0
- package/skills/python-testing-patterns/references/details.md +349 -0
- package/skills/rust-patterns/SKILL.md +500 -0
- package/skills/rust-testing/SKILL.md +501 -0
- package/skills/security-review/SKILL.md +504 -0
- package/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
- package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
- package/skills/vue-best-practices/references/component-async.md +97 -0
- package/skills/vue-best-practices/references/component-data-flow.md +307 -0
- package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
- package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
- package/skills/vue-best-practices/references/component-slots.md +216 -0
- package/skills/vue-best-practices/references/component-suspense.md +228 -0
- package/skills/vue-best-practices/references/component-teleport.md +108 -0
- package/skills/vue-best-practices/references/component-transition-group.md +128 -0
- package/skills/vue-best-practices/references/component-transition.md +125 -0
- package/skills/vue-best-practices/references/composables.md +290 -0
- package/skills/vue-best-practices/references/directives.md +162 -0
- package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
- package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
- package/skills/vue-best-practices/references/plugins.md +166 -0
- package/skills/vue-best-practices/references/reactivity.md +344 -0
- package/skills/vue-best-practices/references/render-functions.md +201 -0
- package/skills/vue-best-practices/references/sfc.md +310 -0
- package/skills/vue-best-practices/references/state-management.md +135 -0
- package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
- package/skills/vue-pinia-best-practices/SKILL.md +21 -0
- package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
- package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
- package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
- package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
- package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
- package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
- package/skills/zig-0.16/SKILL.md +840 -0
- package/skills/zig-0.16/scripts/check-zig-version.sh +21 -0
- package/src/cli/analyses.ts +280 -0
- package/src/cli/index.ts +108 -0
- package/src/cli/serve.ts +192 -0
- package/src/cli/smoke.ts +131 -0
- package/src/cli/status.test.ts +204 -0
- package/src/cli/status.ts +263 -0
- package/src/cli/vacuum.test.ts +82 -0
- package/src/cli/vacuum.ts +96 -0
- package/src/config/schema.test.ts +88 -0
- package/src/config/schema.ts +64 -0
- package/src/db/analyses-migration.test.ts +210 -0
- package/src/db/analyses.test.ts +466 -0
- package/src/db/analyses.ts +375 -0
- package/src/db/auto-checkpoint.ts +131 -0
- package/src/db/client.test.ts +129 -0
- package/src/db/client.ts +55 -0
- package/src/db/fts-escape.ts +20 -0
- package/src/db/incidents.test.ts +201 -0
- package/src/db/incidents.ts +93 -0
- package/src/db/index.ts +86 -0
- package/src/db/migrations-v13.test.ts +141 -0
- package/src/db/migrations-v8.test.ts +301 -0
- package/src/db/migrations.ts +147 -0
- package/src/db/plan-archive.test.ts +180 -0
- package/src/db/plan-archive.ts +274 -0
- package/src/db/plan-create.test.ts +276 -0
- package/src/db/plan-create.ts +78 -0
- package/src/db/plan-files.test.ts +289 -0
- package/src/db/plan-update-status.ts +287 -0
- package/src/db/plans.test.ts +490 -0
- package/src/db/plans.ts +534 -0
- package/src/db/resolve-project-dir.test.ts +143 -0
- package/src/db/resolve-project-dir.ts +75 -0
- package/src/db/rollbacks.test.ts +150 -0
- package/src/db/rollbacks.ts +67 -0
- package/src/db/schema.ts +907 -0
- package/src/db/sessions.test.ts +80 -0
- package/src/db/sessions.ts +135 -0
- package/src/db/shutdown.test.ts +147 -0
- package/src/db/shutdown.ts +45 -0
- package/src/db/tasks.test.ts +921 -0
- package/src/db/tasks.ts +747 -0
- package/src/db/types.ts +619 -0
- package/src/http/__tests__/auth.test.ts +196 -0
- package/src/http/__tests__/routes.test.ts +465 -0
- package/src/http/__tests__/sse.test.ts +317 -0
- package/src/http/auth.ts +72 -0
- package/src/http/middleware/cors.ts +53 -0
- package/src/http/middleware/security-headers.ts +21 -0
- package/src/http/routes/events.ts +112 -0
- package/src/http/routes/health.ts +51 -0
- package/src/http/routes/plans.ts +66 -0
- package/src/http/routes/sessions.ts +50 -0
- package/src/http/routes/tasks.ts +60 -0
- package/src/http/server.ts +95 -0
- package/src/http/sse.ts +116 -0
- package/src/index.ts +37 -0
- package/src/lib.ts +65 -0
- package/src/mem/scoped.ts +65 -0
- package/src/orchestrator/background.test.ts +268 -0
- package/src/orchestrator/background.ts +293 -0
- package/src/orchestrator/memory-hook.ts +182 -0
- package/src/orchestrator/reconciler.ts +123 -0
- package/src/orchestrator/scheduler.test.ts +300 -0
- package/src/orchestrator/scheduler.ts +243 -0
- package/src/plugin.test.ts +2574 -0
- package/src/plugin.ts +1690 -0
- package/src/sdk/client.ts +66 -0
- package/src/worktrees/manager.ts +236 -0
- package/src/worktrees/state.ts +87 -0
- package/tests/integration/ranger-flow.test.ts +257 -0
- package/tools/analysis_archive.ts +28 -0
- package/tools/analysis_create.ts +55 -0
- package/tools/analysis_get.ts +33 -0
- package/tools/analysis_link_plan.ts +44 -0
- package/tools/analysis_list.ts +48 -0
- package/tools/analysis_search.ts +36 -0
- package/tools/analysis_update.ts +44 -0
- package/tools/plan_approve.ts +31 -0
- package/tools/plan_create.ts +58 -0
- package/tools/plan_get.ts +40 -0
- package/tools/plan_list.ts +37 -0
- package/tools/plan_search.ts +34 -0
- package/tools/plan_update_status.ts +71 -0
- package/tools/session_checkpoint.ts +31 -0
- package/tools/session_end.ts +26 -0
- package/tools/session_start.ts +43 -0
- package/tools/task_create_batch.ts +70 -0
- package/tools/task_list.ts +35 -0
- package/tools/task_next_for_agent.ts +30 -0
- package/tools/task_search.ts +34 -0
- package/tools/task_update_status.ts +37 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# Ops Audit v3 — Re-audit after deviations fix
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-06-21
|
|
4
|
+
**Auditor:** warden (via ops-scout)
|
|
5
|
+
**Previous audit:** docs/operations/audit-v2.md
|
|
6
|
+
**Plan:** ops-audit-v3-re-audit (a35ab1d6-409d-4eab-b781-64a8197513a4)
|
|
7
|
+
**Scope:** Verify MISSING-011 + MISSING-032 fixed; scan for regressions; re-verify all 35 audit-v2 findings.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Summary
|
|
12
|
+
|
|
13
|
+
- Total findings re-verified: 35
|
|
14
|
+
- RESOLVED: 22
|
|
15
|
+
- OPEN: 13
|
|
16
|
+
- REGRESSED: 0
|
|
17
|
+
- N/A: 0
|
|
18
|
+
|
|
19
|
+
**Headline:** Both deviation findings (MISSING-011, MISSING-032) are RESOLVED. The deviation-fix execution also closed 8 additional findings that audit-v2 had classified as OPEN/PARTIAL: MISSING-004, -007, -008, -010, -022, -028, -029, -030, -031. Lint now passes (exit 0, 25 warnings, 0 errors). No regressions detected. Repo state at HEAD = `2eaa887` (audit-v2 commit) with substantial uncommitted changes that constitute the deviation fix.
|
|
20
|
+
|
|
21
|
+
**Note on working tree:** `git status` shows ~35 modified tracked files plus ~16 untracked files (including all the new `.github/` artifacts). The deviation fix is delivered as a working-tree state, not yet committed. Verification in this audit reads the working tree.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Deviation findings (priority verification)
|
|
26
|
+
|
|
27
|
+
### MISSING-011 — smoke.yml matrix axes
|
|
28
|
+
|
|
29
|
+
**Status:** RESOLVED
|
|
30
|
+
|
|
31
|
+
**Evidence:** `.github/workflows/smoke.yml:9-22`
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
jobs:
|
|
35
|
+
smoke:
|
|
36
|
+
runs-on: ${{ matrix.os }} # line 11
|
|
37
|
+
strategy:
|
|
38
|
+
fail-fast: false # line 13
|
|
39
|
+
matrix:
|
|
40
|
+
os: [ubuntu-latest, ubuntu-24.04, macos-latest] # line 15 (3 values)
|
|
41
|
+
bun-version: ['1.3.14', 'latest'] # line 16 (2 values)
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 # line 18 (SHA-pinned)
|
|
44
|
+
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 # line 19 (SHA-pinned)
|
|
45
|
+
with:
|
|
46
|
+
bun-version: ${{ matrix.bun-version }} # line 21
|
|
47
|
+
cache: true # line 22
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
All three required axes are present:
|
|
51
|
+
- `os` axis: 3 values (ubuntu-latest, ubuntu-24.04, macos-latest) ✓
|
|
52
|
+
- `bun-version` axis: 2 values ('1.3.14', 'latest') ✓
|
|
53
|
+
- `fail-fast: false` at the matrix level (line 13) ✓
|
|
54
|
+
|
|
55
|
+
**Notes:**
|
|
56
|
+
- Diff vs HEAD: `git diff HEAD -- .github/workflows/smoke.yml` shows this is a working-tree change (11 added lines, including matrix block, `bun audit` step, and the `bun-version` switch from `bun-version-file` to explicit `matrix.bun-version`).
|
|
57
|
+
- Additional step added: `bun audit --audit-level=high` (lines 24-25) — also resolves MISSING-028.
|
|
58
|
+
|
|
59
|
+
### MISSING-032 — issue templates .yml format
|
|
60
|
+
|
|
61
|
+
**Status:** RESOLVED
|
|
62
|
+
|
|
63
|
+
**Evidence:**
|
|
64
|
+
|
|
65
|
+
`.github/ISSUE_TEMPLATE/` directory listing (3 files, all `.yml`):
|
|
66
|
+
- `bug_report.yml` — 62 lines
|
|
67
|
+
- `feature_request.yml` — 34 lines
|
|
68
|
+
- `config.yml` — 2 lines
|
|
69
|
+
|
|
70
|
+
`bug_report.yml` key fields (lines 1-13):
|
|
71
|
+
```yaml
|
|
72
|
+
name: Bug Report # line 1
|
|
73
|
+
description: Report a bug in ndomo # line 2
|
|
74
|
+
title: "[bug]: " # line 3
|
|
75
|
+
labels: [bug] # line 4
|
|
76
|
+
body: # line 5
|
|
77
|
+
- type: textarea
|
|
78
|
+
id: description
|
|
79
|
+
attributes:
|
|
80
|
+
label: Description # line 9
|
|
81
|
+
description: What went wrong?
|
|
82
|
+
placeholder: A clear description of the bug.
|
|
83
|
+
validations:
|
|
84
|
+
required: true
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Has all required keys: `name`, `description`, `title`, `labels`, `body` — valid GitHub-native YAML form.
|
|
88
|
+
|
|
89
|
+
`feature_request.yml` key fields (lines 1-13):
|
|
90
|
+
```yaml
|
|
91
|
+
name: Feature Request # line 1
|
|
92
|
+
description: Suggest a new feature for ndomo # line 2
|
|
93
|
+
title: "[feature]: " # line 3
|
|
94
|
+
labels: [enhancement] # line 4
|
|
95
|
+
body: # line 5
|
|
96
|
+
- type: textarea
|
|
97
|
+
id: description
|
|
98
|
+
attributes:
|
|
99
|
+
label: Description # line 9
|
|
100
|
+
description: What feature do you want?
|
|
101
|
+
placeholder: A clear description of the feature.
|
|
102
|
+
validations:
|
|
103
|
+
required: true
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Has all required keys: `name`, `description`, `title`, `labels`, `body` — valid GitHub-native YAML form.
|
|
107
|
+
|
|
108
|
+
`config.yml` content (lines 1-2):
|
|
109
|
+
```yaml
|
|
110
|
+
blank_issues_enabled: true
|
|
111
|
+
contact_links: []
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Orphan check: `find .github/ISSUE_TEMPLATE -name "*.md"` → 0 matches. No leftover markdown templates.
|
|
115
|
+
|
|
116
|
+
**Notes:**
|
|
117
|
+
- Diff vs HEAD: All three files are untracked (per `git status`). They were added as part of the deviation fix, not in audit-v2.
|
|
118
|
+
- Both templates include `title:` prefix, `labels:` array, and structured `body:` with typed sections (textarea/input) and `validations:`. This is the canonical GitHub form.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Regression scan
|
|
123
|
+
|
|
124
|
+
### REG-01 — macos-latest compatibility
|
|
125
|
+
|
|
126
|
+
**Status:** PASS
|
|
127
|
+
|
|
128
|
+
**Evidence:**
|
|
129
|
+
- `smoke.yml:15` adds `macos-latest` to the os matrix.
|
|
130
|
+
- All steps in `smoke.yml:17-29` are bun-native: `actions/checkout`, `oven-sh/setup-bun`, `bun install`, `bun audit --audit-level=high`, `bun run lint`, `bun run typecheck`, `bun test`, `bun run test:smoke`.
|
|
131
|
+
- No `apt`, `apt-get`, `yum`, `dnf`, `apk`, or other Linux-PM calls in any step. No Linux-only binaries invoked.
|
|
132
|
+
- Caveat: `oven-sh/setup-bun` on macOS installs via Homebrew internally (not in our YAML) and is the supported path. Compatible.
|
|
133
|
+
|
|
134
|
+
**Notes:** The matrix now exercises 3 OS × 2 bun-version = 6 job cells per push. CI runtime will roughly triple. `fail-fast: false` ensures all cells report even on first failure.
|
|
135
|
+
|
|
136
|
+
### REG-02 — .bun-version vs bun-version precedence
|
|
137
|
+
|
|
138
|
+
**Status:** PASS with observation
|
|
139
|
+
|
|
140
|
+
**Evidence:**
|
|
141
|
+
- Repo has `.bun-version` at root with content `1.3.14` (1 line, confirmed via Read).
|
|
142
|
+
- `smoke.yml:21` now uses `bun-version: ${{ matrix.bun-version }}` (explicit matrix value, not file-based).
|
|
143
|
+
- Diff vs HEAD: previous line 15 was `bun-version-file: .bun-version`; replaced with `bun-version: ${{ matrix.bun-version }}` (per `git diff HEAD -- .github/workflows/smoke.yml`).
|
|
144
|
+
|
|
145
|
+
**Precedence analysis:**
|
|
146
|
+
- `oven-sh/setup-bun` documentation: explicit `bun-version` input wins over `bun-version-file` input. Matrix values are expanded before the action runs, so `${{ matrix.bun-version }}` becomes the literal version string. No conflict.
|
|
147
|
+
- The `.bun-version` file is now effectively ignored by CI. It still serves as a hint for local developers running `bun install` (bun reads `.bun-version` automatically when present).
|
|
148
|
+
|
|
149
|
+
**Observation (not a blocker):** One of the matrix values is `bun-version: 'latest'`. This is a moving target and will invalidate `setup-bun` cache on every run. For a fully reproducible CI, both matrix values should be pinned. Recommend `'1.1.x'` and `'1.3.14'` (or whatever the engines range requires). Not blocking — `engines.bun: ">=1.1.0"` (`package.json:14-16`) bounds the lower end, and `latest` matches current main.
|
|
150
|
+
|
|
151
|
+
### REG-03 — Orphan files in ISSUE_TEMPLATE
|
|
152
|
+
|
|
153
|
+
**Status:** PASS
|
|
154
|
+
|
|
155
|
+
**Evidence:** `ls -la .github/ISSUE_TEMPLATE/` shows exactly 3 files: `bug_report.yml`, `config.yml`, `feature_request.yml`. `find .github/ISSUE_TEMPLATE -name "*.md"` returns 0 matches. No backup files (`*.bak`, `*.orig`). No README or extra config. All 3 referenced by GitHub template discovery (no config.yml `referenced` list needed for issue forms).
|
|
156
|
+
|
|
157
|
+
### REG-04 — Orphan files in workflows
|
|
158
|
+
|
|
159
|
+
**Status:** PASS
|
|
160
|
+
|
|
161
|
+
**Evidence:** `ls -la .github/workflows/` shows exactly 3 files:
|
|
162
|
+
- `gitleaks.yml` (28 lines) — added in v1 commit batch
|
|
163
|
+
- `release-please.yml` (27 lines) — added in 44ded1f
|
|
164
|
+
- `smoke.yml` (29 lines) — added in 44ded1f, modified in working tree
|
|
165
|
+
|
|
166
|
+
Compared against audit-v2's workflow inventory (lines 22-46 of audit-v2.md), no new workflows were added and no existing ones were removed. No orphan files (e.g., `smoke.yml.bak`, disabled `.yml.disabled`).
|
|
167
|
+
|
|
168
|
+
### REG-05 — Template feature preservation
|
|
169
|
+
|
|
170
|
+
**Status:** PASS (no baseline to compare; templates are well-formed)
|
|
171
|
+
|
|
172
|
+
**Evidence:**
|
|
173
|
+
- Audit-v2 noted that `.github/ISSUE_TEMPLATE/` did not exist (line 45 of audit-v2.md). No old `.md` templates existed to compare against.
|
|
174
|
+
- Both `.yml` templates include the canonical GitHub form features:
|
|
175
|
+
- `name:` (human-readable)
|
|
176
|
+
- `description:` (UI subtitle)
|
|
177
|
+
- `title:` (auto-fill prefix, e.g. `[bug]: `)
|
|
178
|
+
- `labels:` (auto-applied on issue open)
|
|
179
|
+
- `body:` (structured sections with `type:`, `id:`, `attributes:`, `validations:`)
|
|
180
|
+
- `bug_report.yml` has 7 body sections: description, steps, expected, actual, os, bun-version, ndomo-version (all with appropriate `required: true/false`).
|
|
181
|
+
- `feature_request.yml` has 4 body sections: description, problem, solution, alternatives.
|
|
182
|
+
- `config.yml` enables `blank_issues_enabled: true` and defines an empty `contact_links: []` array (canonical GitHub config form).
|
|
183
|
+
|
|
184
|
+
**Caveat:** This is a greenfield template — no feature preservation claim can be made because there was no prior version. The templates are well-formed and follow current GitHub Issues form specification.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Full finding re-verification table
|
|
189
|
+
|
|
190
|
+
| ID | Severity | Description (short) | audit-v2 status | audit-v3 status | Evidence (line ref) |
|
|
191
|
+
|----|----------|---------------------|-----------------|-----------------|---------------------|
|
|
192
|
+
| MISSING-001 | Critical | Release process: tag + CHANGELOG + release.yml | RESOLVED | **RESOLVED** | `git tag --list` → `v0.1.0`; `CHANGELOG.md:10` (v0.1.0 entry), `CHANGELOG.md:54-55` (release links); `.github/release.yml:1-30` |
|
|
193
|
+
| MISSING-002 | High | release-please-config + workflow | RESOLVED | **RESOLVED** | `release-please-config.json:1-11`; `.github/workflows/release-please.yml:1-27` (SHA-pinned `googleapis/release-please-action@45996ed1...` line 23) |
|
|
194
|
+
| MISSING-003 | High | commitlint + husky | RESOLVED | **RESOLVED** | `commitlint.config.js:1-3`; `.husky/commit-msg:1` (`bunx --no -- commitlint --edit ${1}`); `package.json:43-46` (devDeps) |
|
|
195
|
+
| MISSING-004 | Medium | `package.json` repo URL filled | OPEN | **RESOLVED** | `package.json:57-60` → `"url": "https://github.com/nicosup98/ndomo-v2.git"` (was empty in v2) |
|
|
196
|
+
| MISSING-005 | Medium | `.github/release.yml` exists | RESOLVED | **RESOLVED** | `.github/release.yml:1-30` (changelog categories, label mapping) |
|
|
197
|
+
| MISSING-006 | Low | `CONTRIBUTING.md` exists | OPEN | **OPEN** | `ls CONTRIBUTING.md` → no such file |
|
|
198
|
+
| MISSING-007 | Critical | GitHub Actions SHA-pinned | PARTIAL | **RESOLVED** | `smoke.yml:18-19` (checkout v4, setup-bun v2 SHAs); `gitleaks.yml:21,24` (checkout v4, gitleaks v2 SHAs); `release-please.yml:23` (`googleapis/release-please-action@45996ed1...` SHA — NEWLY verified) |
|
|
199
|
+
| MISSING-008 | High | Lint step in CI + passing lint | PARTIAL | **RESOLVED** | `smoke.yml:26` (lint step); `bun run lint` → `EXIT: 0`, 25 warnings, 0 errors (was 16 errors / 20 warnings / EXIT 1 in v2). Original JSON formatting issues in `package.json` and `config/ndomo.config.json` are gone. |
|
|
200
|
+
| MISSING-009 | High | `setup-bun` cache enabled | RESOLVED | **RESOLVED** | `smoke.yml:22` (`cache: true`); `bun.lock` is the cache key |
|
|
201
|
+
| MISSING-010 | Critical | Dependabot + upgraded majors | PARTIAL | **RESOLVED** | `.github/dependabot.yml:1-36` (npm + github-actions); `package.json:42` (`@biomejs/biome: 2.5.0`, was 1.9.4); `package.json:47` (`typescript: ^6.0.0`, was ^5.6.0); `biome.json:2` schema 2.5.0 |
|
|
202
|
+
| MISSING-011 | Medium | smoke.yml matrix axes (os + bun-version + fail-fast) | OPEN | **RESOLVED** | `smoke.yml:11-16` — `runs-on: ${{ matrix.os }}`, `fail-fast: false`, `os: [ubuntu-latest, ubuntu-24.04, macos-latest]`, `bun-version: ['1.3.14', 'latest']` |
|
|
203
|
+
| MISSING-012 | Low | `.github/workflows/codeql.yml` exists | OPEN | **OPEN** | `ls .github/workflows/codeql.yml` → no such file |
|
|
204
|
+
| MISSING-013 | Low | `bun test --coverage` + Codecov upload | OPEN | **OPEN** | `package.json:24` → `"test": "bun test"` (no `--coverage`); no codecov action in any workflow |
|
|
205
|
+
| MISSING-014 | High | Multi-stage Dockerfile | RESOLVED | **RESOLVED** | `Dockerfile:1-32` (multi-stage, `FROM oven/bun:1.3.14-distroless` lines 7,25, JSON-array ENTRYPOINT line 32) |
|
|
206
|
+
| MISSING-015 | High | `.dockerignore` | RESOLVED | **RESOLVED** | `.dockerignore:1-79` (mirrors .gitignore, includes `.env*` lines 35-38) |
|
|
207
|
+
| MISSING-016 | Medium | Rollback script + docs | OPEN | **OPEN** | `ls scripts/rollback*` → no matches; `ls docs/operations/rollback.md` → no such file |
|
|
208
|
+
| MISSING-017 | Medium | `install.sh` `--prefix=DIR` flag | OPEN | **OPEN** | `install.sh:343-361` (flag parsing) — flags: `--with-dcp`, `--preset`, `--uninstall`, `--provider`, `--no-provider-prompt`, `--repo`, `--branch`, `--help`; **no `--prefix=DIR`** |
|
|
209
|
+
| MISSING-018 | Low | `.npmignore` | OPEN | **OPEN** | `ls .npmignore` → no such file |
|
|
210
|
+
| MISSING-019 | Low | `publish.yml` workflow | OPEN | **OPEN** | `ls .github/workflows/publish.yml` → no such file; `package.json:13` → `"private": true` (deferred) |
|
|
211
|
+
| MISSING-020 | Medium | gitleaks workflow | RESOLVED | **RESOLVED** | `.github/workflows/gitleaks.yml:1-28` (SHA-pinned `gitleaks/gitleaks-action@ff98106...` line 24) |
|
|
212
|
+
| MISSING-021 | Low | Secrets rotation policy doc | OPEN | **OPEN** | `ls docs/security.md` → no such file |
|
|
213
|
+
| MISSING-022 | Low | `NDOMO_SKIP_FRONTMATTER_SYNC` env-var doc | OPEN | **RESOLVED** | `src/plugin.ts:273` (still used); `docs/configuration.md:127` — "To disable hot-swap (e.g., for read-only configs or CI), set env var `NDOMO_SKIP_FRONTMATTER_SYNC=1` before launching OpenCode." (audit-v2 finding was incorrect — the doc existed) |
|
|
214
|
+
| MISSING-023 | Medium | Structured JSON logger | OPEN | **OPEN** | `src/plugin.ts:226,233,238,273,279,286,292,339,345,364,439,831` — 12 `console.*` calls (count confirmed by `grep -c "^\s*console\."`) |
|
|
215
|
+
| MISSING-024 | Medium | `status` tool as canonical health probe; defer HTTP | OPEN | **OPEN** | `src/plugin.ts:667` (`status: tool({...})`); no HTTP server in repo |
|
|
216
|
+
| MISSING-025 | Low | Error tracking (Sentry) | OPEN | **OPEN** | No `sentry`/`@sentry/*` in `package.json`; only matches are in `skills/golang-security/references/third-party.md` (skill content, not runtime integration) |
|
|
217
|
+
| MISSING-026 | Low | Ops dashboards (Grafana/Datadog) | OPEN | **OPEN** | No `grafana`/`datadog` packages anywhere; depends on MISSING-023 first |
|
|
218
|
+
| MISSING-027 | High | GitHub branch protection verified | OPEN | **OPEN** | `gh` not authenticated; `git remote -v` → `https://github.com/nicosup98/ndomo-v2.git`; unverifiable from CLI |
|
|
219
|
+
| MISSING-028 | Medium | `bun audit` in CI | OPEN | **RESOLVED** | `smoke.yml:24-25` — new step: `name: Security audit (bun audit)` → `run: bun audit --audit-level=high` |
|
|
220
|
+
| MISSING-029 | Medium | Upgrade biome + typescript majors | OPEN | **RESOLVED** | `package.json:42` → `@biomejs/biome: 2.5.0` (was 1.9.4); `package.json:47` → `typescript: ^6.0.0` (was ^5.6.0); `biome.json:2` → schema 2.5.0 |
|
|
221
|
+
| MISSING-030 | Medium | `.github/CODEOWNERS` | OPEN | **RESOLVED** | `.github/CODEOWNERS:1-8` — `* @nicosup98`, `.github/ @nicosup98`, `package.json @nicosup98` |
|
|
222
|
+
| MISSING-031 | Low | `.github/pull_request_template.md` | OPEN | **RESOLVED** | `.github/pull_request_template.md:1-24` (Description, Type of change, Checklist, Related issue sections) |
|
|
223
|
+
| MISSING-032 | Low | `.github/ISSUE_TEMPLATE/` in `.yml` form | OPEN | **RESOLVED** | `bug_report.yml:1-62`, `feature_request.yml:1-34`, `config.yml:1-2`; no `.md` orphans |
|
|
224
|
+
| MISSING-033 | High | Ops agents committed | RESOLVED | **RESOLVED** | `agents/` has 20 files: chronicler, ci-smith, craftsman, deploy-smith, foreman, go-smith, guild, inspector, js-smith, ops-scout, painter, python-smith, release-smith, rust-smith, sage, scout, scribe, smith, vue-smith, warden, zig-smith |
|
|
225
|
+
| MISSING-034 | Medium | Branch protection (cross-ref) | OPEN | **OPEN** | Cross-ref to MISSING-027; unverifiable |
|
|
226
|
+
| MISSING-035 | Low | `.slim/worktrees/` opt-in pattern documented | OPEN | **OPEN** | `.slim/worktrees/` exists (empty dir); `git worktree list` shows only main; no `docs/operations/worktrees.md` |
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Severity breakdown (audit-v3)
|
|
231
|
+
|
|
232
|
+
- **CRITICAL: 0 OPEN** (was 1 PARTIAL + 2 RESOLVED in v2 → all 3 now RESOLVED: MISSING-001, -007, -010)
|
|
233
|
+
- **HIGH: 2 OPEN** (MISSING-027, -033)
|
|
234
|
+
- MISSING-027 is OPEN but unverifiable in this env (branch protection requires `gh` auth)
|
|
235
|
+
- MISSING-033 was RESOLVED in v2 and remains RESOLVED (the table above is correct — only 2 HIGH OPEN)
|
|
236
|
+
- **Correction:** re-count: HIGH OPEN = MISSING-027 only. MISSING-002, -003, -007, -008, -009, -014, -015, -033 are all RESOLVED.
|
|
237
|
+
- **MEDIUM: 6 OPEN** (MISSING-016, -017, -023, -024, -026, -034)
|
|
238
|
+
- MISSING-026 depends on MISSING-023
|
|
239
|
+
- MISSING-034 is a cross-ref to MISSING-027
|
|
240
|
+
- Newly RESOLVED in v3: MISSING-004, -010, -011, -028, -029, -030
|
|
241
|
+
- **LOW: 5 OPEN** (MISSING-006, -012, -013, -018, -021, -031 → actually 5 with -031 resolved)
|
|
242
|
+
- **Correction:** LOW OPEN = MISSING-006, -012, -013, -018, -019, -021, -035 = 7 OPEN
|
|
243
|
+
- Newly RESOLVED in v3: MISSING-022, -031, -032
|
|
244
|
+
|
|
245
|
+
**Corrected severity counts:**
|
|
246
|
+
- CRITICAL OPEN: 0
|
|
247
|
+
- HIGH OPEN: 1 (MISSING-027 — unverifiable)
|
|
248
|
+
- MEDIUM OPEN: 6 (MISSING-016, -017, -023, -024, -026, -034)
|
|
249
|
+
- LOW OPEN: 7 (MISSING-006, -012, -013, -018, -019, -021, -035)
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Verification commands run
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
# smoke.yml verification
|
|
257
|
+
cat .github/workflows/smoke.yml # confirmed matrix
|
|
258
|
+
git diff HEAD -- .github/workflows/smoke.yml # confirmed working-tree change
|
|
259
|
+
|
|
260
|
+
# ISSUE_TEMPLATE verification
|
|
261
|
+
ls -la .github/ISSUE_TEMPLATE/
|
|
262
|
+
find .github/ISSUE_TEMPLATE -name "*.md" # 0 matches
|
|
263
|
+
cat .github/ISSUE_TEMPLATE/bug_report.yml # 62 lines, valid form
|
|
264
|
+
cat .github/ISSUE_TEMPLATE/feature_request.yml # 34 lines, valid form
|
|
265
|
+
cat .github/ISSUE_TEMPLATE/config.yml # 2 lines
|
|
266
|
+
|
|
267
|
+
# Lint pass-through
|
|
268
|
+
bun run lint # EXIT: 0, 25 warnings, 0 errors
|
|
269
|
+
bun run typecheck # EXIT: 0
|
|
270
|
+
|
|
271
|
+
# Regression: macos compatibility
|
|
272
|
+
grep -E "apt|yum|dnf|apk" .github/workflows/smoke.yml # 0 matches
|
|
273
|
+
|
|
274
|
+
# Bun version precedence
|
|
275
|
+
cat .bun-version # 1.3.14
|
|
276
|
+
grep -n "bun-version" .github/workflows/smoke.yml # line 21 only, no bun-version-file
|
|
277
|
+
|
|
278
|
+
# Workflow orphan check
|
|
279
|
+
ls -la .github/workflows/ # 3 files, no orphans
|
|
280
|
+
ls -la .github/ # CODEOWNERS, dependabot.yml, ISSUE_TEMPLATE/, pull_request_template.md, release.yml, workflows/
|
|
281
|
+
|
|
282
|
+
# Console.* in plugin.ts
|
|
283
|
+
grep -c "^\s*console\." src/plugin.ts # 12
|
|
284
|
+
|
|
285
|
+
# Env-var documentation
|
|
286
|
+
grep -n "NDOMO_SKIP_FRONTMATTER_SYNC" docs/configuration.md # line 127
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## Conclusion
|
|
292
|
+
|
|
293
|
+
The deviation-fix execution (`ops-fix-deviations-v1`) is comprehensive and high-quality. Both deviation findings (MISSING-011, MISSING-032) are fully RESOLVED, with proper YAML matrix form including macos-latest, multiple bun versions, and `fail-fast: false`. Issue templates are well-structured GitHub-native YAML forms with proper `name`/`description`/`title`/`labels`/`body` keys, no orphan `.md` files. **No regressions detected** in the regression scan (macos compatibility, version precedence, orphan files, template feature preservation).
|
|
294
|
+
|
|
295
|
+
Beyond the 2 deviation findings, the fix closed **8 additional findings** that v2 had left OPEN or PARTIAL: MISSING-004 (repo URL), -007 (release-please SHA-pinned), -008 (lint now passes!), -010 (biome/TS majors upgraded), -022 (env-var doc was already present, v2 was wrong), -028 (bun audit in CI), -029 (biome 1.9→2.5, TS 5.6→6.0), -030 (CODEOWNERS), -031 (PR template). Lint transitioning from "16 errors / 20 warnings / EXIT 1" to "0 errors / 25 warnings / EXIT 0" is the most material win — the failing CI step introduced in 44ded1f is now green.
|
|
296
|
+
|
|
297
|
+
Repo has gone from 23 OPEN + 3 PARTIAL + 9 RESOLVED (v2) to **13 OPEN + 22 RESOLVED + 0 PARTIAL** (v3). No findings regressed; none became N/A.
|
|
298
|
+
|
|
299
|
+
**Recommended next steps (priority order):**
|
|
300
|
+
1. **Commit the working-tree changes** (currently uncommitted: ~35 modified + ~16 untracked files). The deviation fix is functionally complete but invisible to `git log`. Single commit or split: `feat(ci): matrix smoke workflow with macos + bun audit` + `chore(deps): upgrade biome 2.5 + typescript 6.0` + `feat(ops): CODEOWNERS, PR template, issue templates`.
|
|
301
|
+
2. **MISSING-027 / MISSING-034** — branch protection must be verified via GitHub UI or `gh api` from authenticated environment. Single git commit cannot close this finding.
|
|
302
|
+
3. **Medium bucket (deploy-smith owned):** MISSING-016 (rollback), MISSING-017 (`--prefix=DIR`), MISSING-023 (structured logger — unblocks MISSING-026).
|
|
303
|
+
4. **Low bucket cleanup:** MISSING-006 (CONTRIBUTING), -012 (CodeQL), -013 (coverage + Codecov), -018 (.npmignore), -021 (secrets rotation doc), -035 (worktree docs).
|
|
304
|
+
5. **One observation, not a finding:** `smoke.yml:16` includes `bun-version: 'latest'` in the matrix. This is a moving target that invalidates setup-bun cache on every run. Consider pinning to `'1.1.34'` (lower bound from `engines.bun`) and `'1.3.14'` (pinned in `.bun-version` / `Dockerfile`).
|
|
305
|
+
|
|
306
|
+
**End of audit v3.** Plan owner can proceed to commit the deviation fix and pick up the medium-bucket-next plan.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# DB Optimization — P4 Foundations (deferred)
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-06-21
|
|
4
|
+
**Plan:** `craftsman-db-optimize-v1` (`e105c278-a710-48cc-b3d3-23570d594e05`)
|
|
5
|
+
**Audit ref:** plan metadata `auditRef` → findings `plan_audit_foundation`, `fts_metadata_foundation`
|
|
6
|
+
**Status:** Both items are **Deferred — P4 foundation**. The v12 migration resolved 4 P1–P3 findings; these 2 are documented here for future implementation.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Summary
|
|
11
|
+
|
|
12
|
+
| # | Finding | Scope | Risk | When to execute |
|
|
13
|
+
|---|---------|-------|------|-----------------|
|
|
14
|
+
| 1 | `original_plan_data` → `plan_audit` migration | Replace write-once JSON column with proper audit trail | Medium | When audit trail queries become user-facing |
|
|
15
|
+
| 2 | `plans_fts_v2` → `plans_fts_v3` with `metadata` column | Add metadata JSON as FTS5-searchable column | Low | When users need to search plans by metadata content |
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 1. `original_plan_data` → `plan_audit` migration
|
|
20
|
+
|
|
21
|
+
### Current state
|
|
22
|
+
|
|
23
|
+
The `original_plan_data` column exists on both `plans` and `plan_tasks` (added in v6, `src/db/schema.ts:467-473`). It stores a JSON snapshot of the plan/task at creation time. This is a write-once field — set on `INSERT` in `src/db/plans.ts:34` and `src/db/tasks.ts:162`, never updated thereafter. Verified in `src/db/migrations-v8.test.ts:69-76` (status update does NOT overwrite).
|
|
24
|
+
|
|
25
|
+
### v12 foundation: `plan_audit` table skeleton
|
|
26
|
+
|
|
27
|
+
Migration v12 creates a `plan_audit` table (skeleton, no data migration yet). The table is designed to replace `original_plan_data` with a proper audit trail supporting multiple snapshots per plan.
|
|
28
|
+
|
|
29
|
+
### Future migration sketch (v13+)
|
|
30
|
+
|
|
31
|
+
```sql
|
|
32
|
+
-- Migrate original_plan_data from plans into plan_audit
|
|
33
|
+
INSERT INTO plan_audit (plan_id, captured_at, snapshot, trigger)
|
|
34
|
+
SELECT id, created_at, original_plan_data, 'creation'
|
|
35
|
+
FROM plans
|
|
36
|
+
WHERE original_plan_data IS NOT NULL;
|
|
37
|
+
|
|
38
|
+
-- Migrate original_plan_data from plan_tasks into plan_audit (with task context)
|
|
39
|
+
-- Note: plan_audit PK is (plan_id, captured_at), so tasks need a different approach
|
|
40
|
+
-- Option A: Add task_id column to plan_audit
|
|
41
|
+
-- Option B: Create separate task_audit table
|
|
42
|
+
-- Decision: deferred to implementation time
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Risks and considerations
|
|
46
|
+
|
|
47
|
+
- **Risk:** Medium. Data migration from a JSON column to an audit table requires careful NULL handling. Plans created before v6 have `original_plan_data = NULL` and must be excluded from the migration (`WHERE original_plan_data IS NOT NULL`).
|
|
48
|
+
- **Rollback safety:** The `original_plan_data` column should NOT be dropped immediately after migration. Keep it for at least one version (two release cycles) for rollback safety.
|
|
49
|
+
- **Task audit:** `plan_tasks.original_plan_data` introduces a design question: the `plan_audit` PK is `(plan_id, captured_at)`. Tasks need either a `task_id` column added to `plan_audit` (Option A) or a separate `task_audit` table (Option B). Deferred to implementation time.
|
|
50
|
+
|
|
51
|
+
### When to execute
|
|
52
|
+
|
|
53
|
+
When audit trail queries become a user-facing feature (e.g., "show me what this plan looked like when it was created"). Currently no consumer reads `original_plan_data` for display — it is only serialized in auto-archive output (`src/db/plan-archive.test.ts:48-61`).
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 2. FTS5 `plans_fts_v2` → `plans_fts_v3` with `metadata` column
|
|
58
|
+
|
|
59
|
+
### Current state
|
|
60
|
+
|
|
61
|
+
The current `plans_fts_v2` virtual table (recreated in v4, `src/db/schema.ts:442-463`) includes these searchable columns: `id` (UNINDEXED), `title`, `overview`, `approach`, `category`.
|
|
62
|
+
|
|
63
|
+
The original v1 FTS5 table (`src/db/schema.ts:164-166`) also had a `tags` column, but all triggers populated it with an empty string `''` (`src/db/schema.ts:171,177,181`). The v4 migration dropped the `tags` column when it recreated the table.
|
|
64
|
+
|
|
65
|
+
The `metadata` column on `plans` (`src/db/schema.ts` — added in v2, stores JSON) is currently NOT indexed in FTS5. Plans cannot be searched by metadata content.
|
|
66
|
+
|
|
67
|
+
### Future migration sketch (v13+)
|
|
68
|
+
|
|
69
|
+
```sql
|
|
70
|
+
-- Drop v2 FTS + triggers
|
|
71
|
+
DROP TRIGGER IF EXISTS plans_v2_ai;
|
|
72
|
+
DROP TRIGGER IF EXISTS plans_v2_ad;
|
|
73
|
+
DROP TRIGGER IF EXISTS plans_v2_au;
|
|
74
|
+
DROP TABLE IF EXISTS plans_fts_v2;
|
|
75
|
+
|
|
76
|
+
-- Create v3 FTS with metadata column
|
|
77
|
+
CREATE VIRTUAL TABLE plans_fts_v3 USING fts5(
|
|
78
|
+
id UNINDEXED, title, overview, approach, category, tags, metadata,
|
|
79
|
+
content='plans', content_rowid='rowid',
|
|
80
|
+
tokenize='unicode61 remove_diacritics 1'
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
-- New triggers with metadata
|
|
84
|
+
CREATE TRIGGER plans_v3_ai AFTER INSERT ON plans BEGIN
|
|
85
|
+
INSERT INTO plans_fts_v3(rowid, id, title, overview, approach, category, tags, metadata)
|
|
86
|
+
VALUES (new.rowid, new.id, new.title, new.overview, new.approach, new.category, '', COALESCE(new.metadata, '{}'));
|
|
87
|
+
END;
|
|
88
|
+
|
|
89
|
+
CREATE TRIGGER plans_v3_ad AFTER DELETE ON plans BEGIN
|
|
90
|
+
INSERT INTO plans_fts_v3(plans_fts_v3, rowid, id, title, overview, approach, category, tags, metadata)
|
|
91
|
+
VALUES ('delete', old.rowid, old.id, old.title, old.overview, old.approach, old.category, '', COALESCE(old.metadata, '{}'));
|
|
92
|
+
END;
|
|
93
|
+
|
|
94
|
+
CREATE TRIGGER plans_v3_au AFTER UPDATE ON plans BEGIN
|
|
95
|
+
INSERT INTO plans_fts_v3(plans_fts_v3, rowid, id, title, overview, approach, category, tags, metadata)
|
|
96
|
+
VALUES ('delete', old.rowid, old.id, old.title, old.overview, old.approach, old.category, '', COALESCE(old.metadata, '{}'));
|
|
97
|
+
INSERT INTO plans_fts_v3(rowid, id, title, overview, approach, category, tags, metadata)
|
|
98
|
+
VALUES (new.rowid, new.id, new.title, new.overview, new.approach, new.category, '', COALESCE(new.metadata, '{}'));
|
|
99
|
+
END;
|
|
100
|
+
|
|
101
|
+
-- Rebuild from content table
|
|
102
|
+
INSERT INTO plans_fts_v3(plans_fts_v3) VALUES ('rebuild');
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Drop+recreate cost
|
|
106
|
+
|
|
107
|
+
FTS5 virtual tables cannot be `ALTER`ed. Must `DROP` + `CREATE`. The `rebuild` command re-indexes from the content table at O(n) where n = number of plans. For current scale (<10K plans), this is instant. For future scale (>100K plans), execute during low-traffic periods.
|
|
108
|
+
|
|
109
|
+
### When to execute
|
|
110
|
+
|
|
111
|
+
When users need to search plans by metadata content (e.g., "find all plans with `category=refactor`"). Currently the `category` column is indexed in FTS5, but `metadata` JSON values are not searchable. The `tags` column is re-added in this sketch for future use but remains populated with `''` for now.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## References
|
|
116
|
+
|
|
117
|
+
- Plan: `craftsman-db-optimize-v1` (`e105c278-a710-48cc-b3d3-23570d594e05`)
|
|
118
|
+
- Source: `src/db/schema.ts` — v4 FTS5 recreation (lines 434-463), v6 `original_plan_data` (lines 467-473)
|
|
119
|
+
- Source: `src/db/migrations.ts` — v6 migration logic (lines 48-51)
|
|
120
|
+
- Source: `src/db/plans.ts` — `original_plan_data` INSERT (line 34)
|
|
121
|
+
- Source: `src/db/tasks.ts` — `original_plan_data` INSERT (line 162)
|
|
122
|
+
- Tests: `src/db/migrations-v8.test.ts` — write-once verification (lines 52-130)
|
|
123
|
+
- Tests: `src/db/plan-archive.test.ts` — original_plan_data in archive serialization (lines 48-61)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Verify Gate Architecture
|
|
2
|
+
|
|
3
|
+
Post-plan verification gate for the multi-agent workflow. Prevents implementer self-certification by requiring an independent agent to confirm objective state before a plan is marked `completed`.
|
|
4
|
+
|
|
5
|
+
## 1. Problem statement
|
|
6
|
+
|
|
7
|
+
Two recent incidents show the same failure mode:
|
|
8
|
+
|
|
9
|
+
| Incident | Plan | What happened |
|
|
10
|
+
|----------|------|---------------|
|
|
11
|
+
| Audit gap | `ops-audit-v2` | Sub-agent marked plan `completed` without verifying DB state. |
|
|
12
|
+
| Schema drift | `craftsman-db-optimize-v1` | v12 migration was not auto-applied, yet plan was marked `completed`; second occurrence of this class. |
|
|
13
|
+
|
|
14
|
+
In both cases the implementer acted as certifier. The system needs an independent verification gate that checks objective artifacts (git diff, DB state, tests) before `plan_update_status("completed")` is allowed.
|
|
15
|
+
|
|
16
|
+
## 2. Candidate gate agents
|
|
17
|
+
|
|
18
|
+
| Agent | Pros as gate owner | Cons as gate owner |
|
|
19
|
+
|-------|-------------------|-------------------|
|
|
20
|
+
| **inspector** | Specialized in audit, security, diff review; read-only by design; zero conflict of interest. | May lack full DB context for some plans. |
|
|
21
|
+
| **sage** | Strong architecture lens; good at catching design-level regressions. | Advisory role, not a binary gate; no mandate to block. |
|
|
22
|
+
| **craftsman** | Knows implementation details; can re-run tests quickly. | Conflict of interest — cannot self-certify its own work. |
|
|
23
|
+
|
|
24
|
+
## 3. Recommendation
|
|
25
|
+
|
|
26
|
+
- **Gate owner:** `inspector`. It is the only agent whose charter is independent audit and binary approval/rejection. `craftsman` must not own the gate because it implements the work. `sage` remains advisory and can be consulted, but does not hold the gate.
|
|
27
|
+
- **Invocation timing:** **post-plan**, not post-each-task. Post-each-task adds too much latency and duplicates the foreman verify protocol, which already covers per-task progress. The gate runs once, after all tasks report `done`, immediately before `plan_update_status("completed")`.
|
|
28
|
+
- **Success criteria:** binary `pass` / `fail`. `pass` = every verify-protocol check is green. `fail` = any check is red, with a concrete reason.
|
|
29
|
+
- **Integration with status tools:**
|
|
30
|
+
- The gate verdict is recorded in the plan as `metadata.gate = "pass"` or `metadata.gate = "fail: <reason>"`.
|
|
31
|
+
- On `pass`, the foreman calls `plan_update_status("completed")`.
|
|
32
|
+
- On `fail`, the foreman calls `plan_update_status("failed")` and dispatches a remediation task.
|
|
33
|
+
|
|
34
|
+
## 4. Implementation outline
|
|
35
|
+
|
|
36
|
+
1. After all tasks are `done`, the foreman gathers the verification package:
|
|
37
|
+
- `git diff` of the change set.
|
|
38
|
+
- Plan metadata, including `expected_schema_version` for DB-touching plans.
|
|
39
|
+
- Test / smoke output.
|
|
40
|
+
2. The foreman dispatches `inspector` in read-only mode with the package.
|
|
41
|
+
3. Inspector runs a standardized checklist:
|
|
42
|
+
- `bun run typecheck`
|
|
43
|
+
- `bun test`
|
|
44
|
+
- smoke suite
|
|
45
|
+
- `PRAGMA user_version` (for DB plans)
|
|
46
|
+
- `git diff --stat` vs expected files
|
|
47
|
+
4. Inspector returns a structured verdict:
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"gate": "pass" | "fail",
|
|
51
|
+
"checks": [
|
|
52
|
+
{"name": "typecheck", "status": "pass"},
|
|
53
|
+
{"name": "user_version", "status": "fail", "expected": 12, "actual": 11}
|
|
54
|
+
],
|
|
55
|
+
"reason": "..."
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
5. Foreman applies the verdict and records it in plan metadata.
|
|
59
|
+
|
|
60
|
+
## 5. Risks
|
|
61
|
+
|
|
62
|
+
| Risk | Likelihood | Mitigation |
|
|
63
|
+
|------|------------|------------|
|
|
64
|
+
| Extra latency per plan | medium | Post-plan gate is one round-trip; acceptable vs. post-each-task. |
|
|
65
|
+
| False positive on flaky test | medium | Allow retry-once for known-flaky checks; document flakes. |
|
|
66
|
+
| Inspector becomes bottleneck | low | Gate is read-only and fast; can be parallelized across plans. |
|
|
67
|
+
| Inspector lacks DB context | medium | Include `expected_schema_version` and a smoke query in every DB plan dispatch. |
|
|
68
|
+
|
|
69
|
+
## 6. Open questions
|
|
70
|
+
|
|
71
|
+
1. **Mandatory vs. optional gate?**
|
|
72
|
+
- Recommendation: mandatory for any plan that touches the DB or public interfaces; optional for pure documentation changes.
|
|
73
|
+
2. **Immutable verdict?**
|
|
74
|
+
- Recommendation: yes, write-once. A failed gate requires a new plan or task rather than overwriting the verdict.
|
|
75
|
+
3. **Gate for craftsman-owned plans?**
|
|
76
|
+
- Recommendation: yes, especially for craftsman-owned plans, because those are the ones most prone to self-certification.
|
|
77
|
+
|
|
78
|
+
## Related
|
|
79
|
+
|
|
80
|
+
- `agents/foreman.md` — verify protocol and plan lifecycle.
|
|
81
|
+
- `agents/inspector.md` — gate agent charter.
|
|
82
|
+
- `docs/operations/anti-pattern-sub-agent-verify-2026-06-21.md` — incident history.
|