@metasession.co/devaudit-cli 0.1.21 → 0.1.23

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metasession.co/devaudit-cli",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "DevAudit CLI — installs, syncs, and operates the Metasession SDLC across consumer projects.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@clack/prompts": "^0.8.2",
36
- "@metasession.co/devaudit-plugin-sdk": "^0.1.21",
36
+ "@metasession.co/devaudit-plugin-sdk": "^0.1.23",
37
37
  "commander": "^12.1.0",
38
38
  "consola": "^3.2.3",
39
39
  "env-paths": "^3.0.0",
@@ -4,6 +4,8 @@ description: One-time project setup — configure repository, CI pipeline, compl
4
4
 
5
5
  # Project Setup Guide
6
6
 
7
+ > **For the operator only.** This guide is for the first developer setting up the project. If you're joining an **already-onboarded** project, you don't need to run any of this — the synced framework files are already in the repo. See [`SDLC/joining-an-existing-project.md`](./joining-an-existing-project.md) for the second-developer path.
8
+
7
9
  **Document Type:** Setup Guide | **Run Once:** At project start, before any workflow is executed
8
10
 
9
11
  **Parent Documents:** Test Policy, Test Strategy, Test Architecture (all Tier 1, in devaudit/sdlc/files/)
@@ -16,7 +16,7 @@ End-to-end walkthrough for taking a GitHub issue from triage to merged-and-deplo
16
16
  | Your `gh` CLI is authenticated against the project's GitHub repo | `gh auth status` |
17
17
  | Your local checkout is on `develop` (or branched from it) and up-to-date | `git status` |
18
18
 
19
- If `devaudit status` reports gaps, see [`DevAudit-Installer/docs/onboarding.md`](https://github.com/metasession-dev/DevAudit-Installer/blob/main/docs/onboarding.md) to re-sync the framework, then come back here.
19
+ If `devaudit status` reports gaps and you're a developer joining an already-onboarded project, see [`SDLC/joining-an-existing-project.md`](./joining-an-existing-project.md) — your local clone may just need `devaudit auth login` + `devaudit join`. If the project hasn't been onboarded yet (you're the first developer), see [`DevAudit-Installer/docs/onboarding.md`](https://github.com/metasession-dev/DevAudit-Installer/blob/main/docs/onboarding.md) for the operator flow. Either way, come back here once `devaudit status` is green.
20
20
 
21
21
  ## The five stages, at a glance
22
22
 
@@ -0,0 +1,191 @@
1
+ # Joining an existing project
2
+
3
+ You're the second (or nth) developer joining a project that's already been DevAudit-onboarded by the first dev (the project's "operator"). This guide is for you. **Don't run `devaudit install`** — that's the operator's command and it touches the team's shared CI configuration. Use `devaudit join` instead, or just the verify commands below if you already trust the synced framework files.
4
+
5
+ ---
6
+
7
+ ## TL;DR — the five commands
8
+
9
+ ```bash
10
+ npm install -g @metasession.co/devaudit-cli # one-time, all projects
11
+ # Issue a personal PAT at https://devaudit.metasession.co/settings/tokens
12
+ devaudit auth login # paste mctok_…
13
+ gh auth login # if not already
14
+ devaudit doctor # node ≥22, git, gh, jq, curl
15
+ devaudit status . # framework files present?
16
+ devaudit join . # re-sync templates + git hooks (optional)
17
+ ```
18
+
19
+ If `devaudit doctor` and `devaudit status .` are both green, you can skip `devaudit join` — the synced framework files (`SDLC/`, `compliance/`, `scripts/`, `.husky/`, `.github/workflows/`, AI rule files) are already in the repo from the first dev's onboarding commit, and you'll get them on `git clone`. Run `join` after the next `devaudit update` from the operator, or whenever your local templates feel out of date.
20
+
21
+ > **One-liner you'll want to remember:** *`install` creates / rotates / re-applies team configuration; `join` does not.* The CLI auto-detects this scenario as a safety net, but `join` is the explicit second-dev command.
22
+
23
+ ---
24
+
25
+ ## What's already in the repo (and why)
26
+
27
+ When you `git clone`, you've already got everything the framework synced into the project on first install:
28
+
29
+ | Path | What it is | Who owns it |
30
+ |---|---|---|
31
+ | `sdlc-config.json` | Project-wide config (stack, host, slug, runtime, UAT, approval mode, e2e knobs, …) | Team — committed by the operator |
32
+ | `SDLC/*.md` | Stage walkthroughs (0-project-setup, 1-plan-requirement, …) — synced from DevAudit-Installer | Team — refreshed by `devaudit update` |
33
+ | `compliance/RTM.md`, `compliance/risk-register.md`, … | Compliance artefacts | Team — appended by tracked work |
34
+ | `scripts/*.sh` | Helpers (`upload-evidence.sh`, `close-out-release.sh`, `validate-commits.sh`, …) | Team — synced from DevAudit-Installer |
35
+ | `.husky/`, `.github/workflows/*.yml` | Git hooks + CI gates | Team — generated by the operator's onboarding install |
36
+ | `.cursorrules`, `.windsurfrules`, `GEMINI.md`, `INSTRUCTIONS.md`, `CLAUDE.md` | AI rule files | Team — synced |
37
+ | `.claude/skills/` | The `sdlc-implementer` + `e2e-test-engineer` Claude Code skills | Team — synced |
38
+
39
+ Your job is to wire up the **local** half (the bits per-developer):
40
+
41
+ - The CLI globally on your machine.
42
+ - Your personal PAT in `~/.config/devaudit/auth.json` (set by `devaudit auth login`).
43
+ - `gh` CLI authenticated against the project's GitHub repo.
44
+
45
+ That's it. You **do not** create a new portal project, issue new API keys, or write new GitHub repo secrets — those belong to the operator.
46
+
47
+ ---
48
+
49
+ ## Step-by-step
50
+
51
+ ### 1. Install the CLI globally
52
+
53
+ ```bash
54
+ npm install -g @metasession.co/devaudit-cli
55
+ devaudit --version # ≥ 0.1.23 — earlier versions don't have the dev-mode safety net
56
+ ```
57
+
58
+ ### 2. Issue + paste a personal access token
59
+
60
+ Visit `https://devaudit.metasession.co/settings/tokens`, create a token (it starts with `mctok_`), then:
61
+
62
+ ```bash
63
+ devaudit auth login
64
+ # Paste the token when prompted. Stored at ~/.config/devaudit/auth.json (mode 0600).
65
+ ```
66
+
67
+ Verify:
68
+
69
+ ```bash
70
+ devaudit auth status
71
+ # token source: ~/.config/devaudit/auth.json
72
+ # portal: https://devaudit.metasession.co
73
+ # accessible projects: <slug>, <slug>, …
74
+ ```
75
+
76
+ ### 3. Authenticate `gh` against GitHub
77
+
78
+ ```bash
79
+ gh auth status # already authenticated?
80
+ # If not:
81
+ gh auth login # GitHub.com → HTTPS → with web browser
82
+ ```
83
+
84
+ ### 4. Verify your local environment
85
+
86
+ ```bash
87
+ devaudit doctor
88
+ # ✓ node v22.x.x (require ≥22)
89
+ # ✓ git git version 2.x.x
90
+ # ✓ gh gh version 2.x.x
91
+ # ✓ jq jq-1.x
92
+ # ✓ curl curl 8.x.x
93
+ # ✓ releases <N> pending ticket(s); none released on the portal
94
+ ```
95
+
96
+ ### 5. Verify the project is SDLC-ready
97
+
98
+ ```bash
99
+ devaudit status .
100
+ # Project: <slug>
101
+ # Stack: node / python
102
+ # Host: railway
103
+ # …
104
+ # ✓ INSTRUCTIONS.md, CLAUDE.md, .cursorrules, …
105
+ ```
106
+
107
+ If any of the framework files are missing, the operator hasn't completed onboarding yet (or your clone is behind `main` — `git pull`). Ask them to run `devaudit update`.
108
+
109
+ ### 6. (Optional) `devaudit join .` to refresh local-only state
110
+
111
+ ```bash
112
+ devaudit join .
113
+ # Runs auth probe, stack detect, hook bootstrap, template sync.
114
+ # Skips: write sdlc-config, issue API key, set GH secrets, apply branch protection.
115
+ ```
116
+
117
+ The output will tell you which steps it skipped and why (developer mode). If `git status` is clean after the join, your local state matches the team — you're done. If templates drift (occasionally on a new CLI version), commit the drift on a `chore:` branch and open a PR.
118
+
119
+ You can skip this step entirely if the synced templates from `git clone` are already current — `devaudit status .` will tell you.
120
+
121
+ ---
122
+
123
+ ## The token model
124
+
125
+ Two distinct credentials exist; conflating them is what causes the silent-CI-token rotation bug this guide exists to prevent.
126
+
127
+ | Credential | Format | Where it lives | Who it identifies | Used by |
128
+ |---|---|---|---|---|
129
+ | **Personal PAT** | `mctok_…` | `~/.config/devaudit/auth.json` (per developer) | You (the user) | Your local CLI commands |
130
+ | **Project API key** | `dak_…` | Repo secret `DEVAUDIT_API_KEY` | The project | CI's `devaudit push` calls |
131
+ | **Operator's PAT** | `mctok_…` | Repo secret `DEVAUDIT_USER_TOKEN` | The operator (singular) | CI's mutation calls (release register, approval submit) |
132
+
133
+ **Never paste your personal PAT into a repo secret.** Repo `DEVAUDIT_USER_TOKEN` is operator-owned. CI portal mutations are attributed to whoever's PAT is there — if it's yours, your name shows up against every release the team ships, and the moment your PAT expires CI breaks. Rotation belongs to the operator: `devaudit install --force-team-config` on their machine.
134
+
135
+ If `devaudit auth status` shows the wrong user, run `devaudit auth logout && devaudit auth login` and paste the right PAT.
136
+
137
+ ---
138
+
139
+ ## Why not `devaudit install`
140
+
141
+ `install` is the **operator's** command. It does eleven steps including:
142
+ - writing `sdlc-config.json`,
143
+ - creating the portal project (if absent),
144
+ - issuing a new project API key (if absent),
145
+ - writing four repo secrets (including `DEVAUDIT_USER_TOKEN` to whoever ran the command),
146
+ - applying branch protection rules.
147
+
148
+ A second dev running it silently rotates the team's `DEVAUDIT_USER_TOKEN` repo secret to their personal PAT — which (a) breaks CI attribution and (b) ties CI's expiry to your PAT lifetime.
149
+
150
+ **As of 0.1.23 the CLI detects this scenario and routes to developer mode automatically** (skipping the destructive steps), but `devaudit join` is the explicit, intent-correct command. If you ran `install` and want to verify the safety net engaged, look at the report's "11/11 Done" line — `Done (developer mode)` means it did; `Done` (no suffix) means you were in operator mode (either a fresh project, the safety net didn't engage, or `--force-team-config` was passed).
151
+
152
+ ---
153
+
154
+ ## Local-vs-CI parity
155
+
156
+ The synced CI gates expect a specific environment. Here's what you need locally if you're running them against the same project:
157
+
158
+ | Surface | CI | Local (your machine) |
159
+ |---|---|---|
160
+ | Personal identity | `secrets.DEVAUDIT_USER_TOKEN` (operator's) | `~/.config/devaudit/auth.json` (yours) — `devaudit auth login` |
161
+ | Project API key | `secrets.DEVAUDIT_API_KEY` | Usually unset locally — only needed if you're testing `devaudit push` against the live portal; ask the operator if you need to debug it |
162
+ | Portal URL | `vars.DEVAUDIT_BASE_URL` | `~/.config/devaudit/auth.json` (set by `auth login`) or `$DEVAUDIT_BASE_URL` env |
163
+ | GitHub auth | `${{ github.token }}` (auto) | `gh auth login` |
164
+ | Node | matrix-pinned to project's `node_version` | nvm / volta / whatever — `devaudit doctor` checks ≥ 22 |
165
+ | `jq` / `curl` | always present on GH runners | install via package manager — `devaudit doctor` flags absence |
166
+
167
+ For everything else (DB migrations, env files, `npm install`), the consumer's `README.md` is the source of truth.
168
+
169
+ ---
170
+
171
+ ## Troubleshooting
172
+
173
+ | Symptom | Cause | Fix |
174
+ |---|---|---|
175
+ | `devaudit status` reports missing framework files | Local clone is behind `main`, or the operator hasn't run a recent `devaudit update` | `git pull origin develop` first; if still missing, ping the operator |
176
+ | `devaudit auth status` says "token rejected" | PAT expired, was revoked, or you typed it wrong | Issue a fresh PAT at `/settings/tokens` and re-run `devaudit auth login` |
177
+ | `devaudit doctor` flags missing tool | The matching binary isn't on PATH | Install via your package manager (`brew install gh`, `apt install jq`, etc.) |
178
+ | "I ran `devaudit install` and now CI is broken" | The 0.1.23+ safety net should have caught this, but if you're on an older CLI version, `DEVAUDIT_USER_TOKEN` may have been rotated to your PAT | Ask the operator to run `devaudit install --force-team-config` from their machine — that re-writes `DEVAUDIT_USER_TOKEN` from their PAT |
179
+ | `devaudit join` exits 7 saying "sdlc-config.json missing" | The project hasn't been onboarded yet (you're the first dev) | This is the operator's job — run `devaudit install <path>` |
180
+
181
+ ---
182
+
183
+ ## What to do next
184
+
185
+ The framework's per-stage walkthrough is in `SDLC/implementing-an-sdlc-issue.md`. For day-to-day implementation work, run the `sdlc-implementer` skill from your AI assistant (Claude Code, Windsurf, Cursor — it's already synced into `.claude/skills/`):
186
+
187
+ ```text
188
+ > Implement issue #N under the SDLC.
189
+ ```
190
+
191
+ For the operator-side onboarding flow (your reference if you ever become the operator on a new project), see [`docs/onboarding.md`](https://github.com/metasession-dev/DevAudit-Installer/blob/main/docs/onboarding.md) in DevAudit-Installer.
@@ -70,8 +70,18 @@ jobs:
70
70
  esac
71
71
  # Bootstrap probe (#301): project may not exist in DevAudit yet —
72
72
  # the first compliance-evidence.yml run auto-creates it. A 404 here
73
- # means we're on the introducing PR; pass with a notice. 401/403
73
+ # means we're on the introducing PR; pass with a warning. 401/403
74
74
  # means the API key is invalid → fail (not bootstrap).
75
+ #
76
+ # Defense in depth (#74): if /api/ci/projects/<slug> 404s we
77
+ # cross-check against /api/ci/releases/resolve — a known-good
78
+ # read endpoint scoped to the same project. If THAT returns 2xx
79
+ # the project clearly exists, and the projects-endpoint 404 is a
80
+ # portal-side bug. Failing closed beats silently passing the
81
+ # four-eyes gate. The original "GET /api/ci/projects/<slug>"
82
+ # endpoint didn't exist on the portal before metasession-dev/
83
+ # devaudit#NN, so this exact false-positive was the universal
84
+ # state of the gate across every consumer.
75
85
  PROJ_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 10 \
76
86
  -H "Authorization: Bearer ${DEVAUDIT_API_KEY}" \
77
87
  "${BASE%/}/api/ci/projects/${PROJECT_SLUG}" || echo "000")
@@ -80,9 +90,34 @@ jobs:
80
90
  echo "DevAudit project '${PROJECT_SLUG}' confirmed (HTTP ${PROJ_CODE})"
81
91
  ;;
82
92
  404)
83
- echo "::notice::DevAudit project '${PROJECT_SLUG}' does not exist yet (HTTP 404) — bootstrap mode. Gate passes. The project will be auto-created by the first compliance-evidence.yml run; enforcement kicks in on the next PR after that."
84
- echo "BOOTSTRAP_MODE=true" >> "$GITHUB_ENV"
85
- exit 0
93
+ # Cross-check: does the project actually exist? versionPrefix=v
94
+ # matches every release version shape (REQ-XXX, vYYYY.MM.DD,
95
+ # vX.Y.Z) — we don't care about the body, only whether the
96
+ # endpoint authorises the project. Endpoint returns 200 even
97
+ # when no releases match the prefix (just with latest: null).
98
+ CROSS_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 10 \
99
+ -H "Authorization: Bearer ${DEVAUDIT_API_KEY}" \
100
+ "${BASE%/}/api/ci/releases/resolve?projectSlug=${PROJECT_SLUG}&versionPrefix=v" \
101
+ || echo "000")
102
+ case "$CROSS_CODE" in
103
+ 2*)
104
+ echo "::error::Portal /api/ci/projects/${PROJECT_SLUG} returned 404 but releases/resolve confirms the project exists (HTTP ${CROSS_CODE}). This is a portal-side issue (missing or broken endpoint), not a bootstrap. Failing closed to avoid silently bypassing the four-eyes gate. Triage at metasession-dev/devaudit (and/or DevAudit-Installer#75)."
105
+ exit 1
106
+ ;;
107
+ 404)
108
+ echo "::warning::DevAudit project '${PROJECT_SLUG}' does not exist yet (HTTP 404 from both /api/ci/projects and /api/ci/releases/resolve) — bootstrap mode. Gate passes. The project will be auto-created by the first compliance-evidence.yml run; enforcement kicks in on the next PR after that."
109
+ echo "BOOTSTRAP_MODE=true" >> "$GITHUB_ENV"
110
+ exit 0
111
+ ;;
112
+ 401|403)
113
+ echo "::error::DevAudit returned HTTP ${CROSS_CODE} for releases/resolve on project '${PROJECT_SLUG}' (cross-check after the projects endpoint 404'd) — API key is invalid or lacks access. Verify DEVAUDIT_API_KEY belongs to the right project."
114
+ exit 1
115
+ ;;
116
+ *)
117
+ echo "::error::Cross-check endpoint /api/ci/releases/resolve returned unexpected HTTP ${CROSS_CODE} after the projects endpoint 404'd. Investigate before retrying."
118
+ exit 1
119
+ ;;
120
+ esac
86
121
  ;;
87
122
  401|403)
88
123
  echo "::error::DevAudit returned HTTP ${PROJ_CODE} for project '${PROJECT_SLUG}' — API key is invalid or lacks access. Verify DEVAUDIT_API_KEY belongs to the right project."