@tekyzinc/gsd-t 5.0.13 → 5.1.10
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/CHANGELOG.md +26 -0
- package/README.md +1 -1
- package/bin/gsd-t-doc-marker.cjs +65 -0
- package/bin/gsd-t-env-registry-check.cjs +318 -0
- package/bin/gsd-t-env-registry.cjs +1046 -0
- package/bin/gsd-t-logging-scaffolder.cjs +6 -18
- package/bin/gsd-t-verify-gate.cjs +2 -0
- package/bin/gsd-t.js +10 -0
- package/commands/gsd-t-architect.md +16 -0
- package/commands/gsd-t-init.md +6 -0
- package/commands/gsd-t-populate.md +5 -0
- package/package.json +1 -1
- package/scripts/gsd-t-architect-oversight-guard.js +12 -2
- package/templates/CLAUDE-global.md +49 -0
- package/templates/infrastructure.md +40 -0
- package/templates/workflows/gsd-t-phase.workflow.js +13 -0
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
const fs = require("fs");
|
|
22
22
|
const path = require("path");
|
|
23
23
|
const crypto = require("crypto");
|
|
24
|
+
// M102 — the marker-block idempotent doc-writer was extracted here into the ONE
|
|
25
|
+
// shared module both this scaffolder and bin/gsd-t-env-registry.cjs call.
|
|
26
|
+
const { upsertMarkedDocBlock } = require("./gsd-t-doc-marker.cjs");
|
|
24
27
|
|
|
25
28
|
const VALID_BACKENDS = ["db-table", "local-sqlite", "local-jsonl"];
|
|
26
29
|
|
|
@@ -182,24 +185,9 @@ function writeChoiceToProjectDocs(projectDir, envelope) {
|
|
|
182
185
|
const targetPath = candidates.find((p) => fs.existsSync(p)) || candidates[0];
|
|
183
186
|
|
|
184
187
|
const block = docBlock(envelope);
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
} else {
|
|
189
|
-
const dir = path.dirname(targetPath);
|
|
190
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (content.includes(DOC_MARKER_START) && content.includes(DOC_MARKER_END)) {
|
|
194
|
-
const startIdx = content.indexOf(DOC_MARKER_START);
|
|
195
|
-
const endIdx = content.indexOf(DOC_MARKER_END) + DOC_MARKER_END.length;
|
|
196
|
-
content = content.slice(0, startIdx) + block + content.slice(endIdx);
|
|
197
|
-
} else {
|
|
198
|
-
content = content.replace(/\s*$/, "") + "\n\n" + block + "\n";
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
fs.writeFileSync(targetPath, content, "utf8");
|
|
202
|
-
return targetPath;
|
|
188
|
+
// M102 — delegate to the ONE shared marker-block writer (byte-identical logic
|
|
189
|
+
// to the former inline replace/append; extracted so env-registry reuses it).
|
|
190
|
+
return upsertMarkedDocBlock(targetPath, DOC_MARKER_START, DOC_MARKER_END, block);
|
|
203
191
|
}
|
|
204
192
|
|
|
205
193
|
// ─── Seam envelope builder ──────────────────────────────────────────────────
|
|
@@ -307,6 +307,8 @@ function _detectDefaultTrack2(projectDir, notes) {
|
|
|
307
307
|
|
|
308
308
|
plan.push({ id: 'logging-envelope', cmd: 'node', args: [path.join(__dirname, 'gsd-t-logging-envelope-check.cjs'), '--project', projectDir], timeoutMs: 30000 }); // M100 D3: structural trace+audit envelope gate, FAIL-CLOSED
|
|
309
309
|
|
|
310
|
+
plan.push({ id: 'env-registry', cmd: 'node', args: [path.join(__dirname, 'gsd-t-env-registry-check.cjs'), '--project', projectDir], timeoutMs: 30000 }); // M102 D3: no-secret-in-registry + rule-without-table gate, FAIL-CLOSED
|
|
311
|
+
|
|
310
312
|
// secrets — gitleaks (PATH detection deferred to runtime)
|
|
311
313
|
if (_hasOnPath('gitleaks')) {
|
|
312
314
|
plan.push({
|
package/bin/gsd-t.js
CHANGED
|
@@ -2999,6 +2999,16 @@ const PROJECT_BIN_TOOLS = [
|
|
|
2999
2999
|
// ship to every project or the consumers can't classify. Same propagation class as
|
|
3000
3000
|
// gsd-t-graph-store-resolver.cjs above. [[project_global_bin_propagation_gap]]
|
|
3001
3001
|
"gsd-t-graph-availability.cjs",
|
|
3002
|
+
// M102 — Environment Registry. The shared marker-block doc-writer + the
|
|
3003
|
+
// registry helper (record/lookup/detect/add-permission/ensure-gitignore).
|
|
3004
|
+
// Sandboxed workflows (init/populate + provisioning execute/quick tasks) call
|
|
3005
|
+
// the registry via project-local Bash, and the registry `require`s the shared
|
|
3006
|
+
// writer at load — BOTH must ship or the registry throws / the writer is a
|
|
3007
|
+
// second copy. Same propagation class as the graph tools above.
|
|
3008
|
+
// [[project_global_bin_propagation_gap]]
|
|
3009
|
+
// Plus the verify-gate lint (gsd-t-verify-gate.cjs invokes it via __dirname,
|
|
3010
|
+
// so it must sit alongside the gate in the project's bin/).
|
|
3011
|
+
"gsd-t-doc-marker.cjs", "gsd-t-env-registry.cjs", "gsd-t-env-registry-check.cjs",
|
|
3002
3012
|
];
|
|
3003
3013
|
|
|
3004
3014
|
// Files that older versions of this installer copied into project bin/ but
|
|
@@ -79,6 +79,18 @@ The subagent works through the six stages IN ORDER. Each can kill or reshape the
|
|
|
79
79
|
the simpler fix actually works** — if the plan says "handled elsewhere / picked up later,"
|
|
80
80
|
VERIFY that's true; do not assert self-healing you haven't checked. (This is the trap that
|
|
81
81
|
hides inside a simplification.)
|
|
82
|
+
6b. **NO-FALLBACK-EVER** — Does the design add ANY fallback (anything that CONTINUES after a
|
|
83
|
+
failure: catch-and-continue, `|| default`, silent degrade, try-X-else-Y where Y masks X
|
|
84
|
+
failing)? If yes, do NOT design it in — surface it as an OPEN QUESTION for the user, UNLESS
|
|
85
|
+
you can cite a confirmed reproducible case only a fallback catches. The straight-line process
|
|
86
|
+
that produces the result is the goal; where it can fail, prefer a **HALT** (stop + demand
|
|
87
|
+
fix), which is NOT a fallback. (See CLAUDE.md § No-Fallback-Ever Doctrine.)
|
|
88
|
+
7. **SIMPLY-STATED** (clarity gate — the review is NOT done until this passes) — state every
|
|
89
|
+
finding and the verdict SIMPLY: precise and complete, but every word load-bearing, the logic
|
|
90
|
+
in a straight line, ZERO jargon standing in for a clear idea, no nested clauses hiding a
|
|
91
|
+
tangle. If a finding cannot be stated simply, the thinking on it is not finished — RE-THINK
|
|
92
|
+
the muddled part, do not re-word it. "Too sophisticated to simplify" is a BANNED escape hatch
|
|
93
|
+
(simplify the expression, never the idea). (See CLAUDE.md § Simply Stated Doctrine.)
|
|
82
94
|
|
|
83
95
|
A stage the subagent cannot answer with evidence is a HALT — surface it as an open question for
|
|
84
96
|
the user, do not paper over it with a guess.
|
|
@@ -94,6 +106,10 @@ a summary table, near-zero preamble. For each CURRENT block, say **why it does w
|
|
|
94
106
|
successive fixes). Unless `--chat-only`, write it to `.gsd-t/pseudocode/PseudoCode-<Target>.md`.
|
|
95
107
|
|
|
96
108
|
**B — Session summary** (always printed, even under `--build`):
|
|
109
|
+
- **Simply Stated** (REQUIRED FIRST LINE — the clarity gate) — the verdict + the single most
|
|
110
|
+
important finding in ONE clean, jargon-free, straight-line statement a smart non-specialist
|
|
111
|
+
acts on without re-reading. If you cannot write this line cleanly, the review is NOT done —
|
|
112
|
+
re-think, don't re-word. Everything below is the depth for whoever wants it.
|
|
97
113
|
- **Core objective** (one line)
|
|
98
114
|
- **Is this a "complicated over time" issue?** (yes/no + the accretion history if yes)
|
|
99
115
|
- **What's reusable** (process or a stored output already available)
|
package/commands/gsd-t-init.md
CHANGED
|
@@ -296,6 +296,12 @@ docs/
|
|
|
296
296
|
|
|
297
297
|
These are the living documents that persist across milestones and keep institutional knowledge alive. The `infrastructure.md` is especially important — it captures the exact commands for provisioning cloud resources, setting up databases, managing secrets, and deploying, so this knowledge doesn't get lost between sessions.
|
|
298
298
|
|
|
299
|
+
The `infrastructure.md` template ships with a marker-delimited `## Environments` table (`<!-- gsd-t-env-registry:start -->` / `:end`) — the committed, **secret-free** connection registry (M102). It is created empty by init and populated by the two triggers:
|
|
300
|
+
- **Greenfield (record-at-create):** whenever this project later BUILDS/PROVISIONS/CONFIGURES an environment (a local test DB, a remote server, credentials, or hands the user setup instructions), record the map row in the SAME pass:
|
|
301
|
+
`node bin/gsd-t-env-registry.cjs record '{"projectDir":".","scope":"local","kind":"postgres","host":"localhost","port":"5432","name":"appdb","authMethod":"password","secretVault":"local (.env)","secretEnvVarName":"DATABASE_URL","fetchCommand":"read $DATABASE_URL from .env","connectCommand":"psql \"$DATABASE_URL\""}'`
|
|
302
|
+
Records only the MAP + vault pointer + env-var NAME + fetch/connect commands — **never a secret VALUE** (a literal password/token in a command is REJECTED). `scope=prod` defaults `read-only=YES`.
|
|
303
|
+
- Also run `node bin/gsd-t-env-registry.cjs ensure-gitignore .` so `.env` is gitignored (auto-add + report; secret-leak precheck).
|
|
304
|
+
|
|
299
305
|
## Step 8: Ensure README.md Exists
|
|
300
306
|
|
|
301
307
|
If no `README.md` exists, create one with:
|
|
@@ -29,6 +29,11 @@ Scan this codebase and populate the GSD-T documentation. Analyze the actual code
|
|
|
29
29
|
- List Credentials and Secrets from .env.example (local) and any secret manager configs
|
|
30
30
|
- Document Deployment from CI/CD configs, Dockerfiles, cloud configs
|
|
31
31
|
- Document Logging and Monitoring from any logging setup or dashboard configs
|
|
32
|
+
- **Back-fill the `## Environments` registry (M102 — brownfield capture).** For an existing project whose non-local environments are undocumented, back-fill the map-only Environments table WITHOUT ever reading or writing a secret VALUE:
|
|
33
|
+
1. `node bin/gsd-t-env-registry.cjs detect .` → proposes the vault + fetch command from `.env.example` var NAMES, connection-string SHAPES, and `vercel.json`/`.vercel` (Vercel) · `cloudbuild.yaml`/`.gcloudignore` (Google Secret Manager) · neon dep (Neon) · plain `.env` (local). Map only — never a value.
|
|
34
|
+
2. Confirm/fill gaps with the human, then `node bin/gsd-t-env-registry.cjs record '<json>'` per environment (upsert by `(scope, kind)` — a re-provision replaces the stale row).
|
|
35
|
+
3. `node bin/gsd-t-env-registry.cjs ensure-gitignore .` — auto-add `.env` to `.gitignore` if missing + report.
|
|
36
|
+
- **No-Fallback-Ever:** a genuinely undocumented environment reached for the first time HALTs → detect → ask → record → `add-permission` → proceed. NEVER guess a connection string, NEVER grep transcripts to rediscover.
|
|
32
37
|
|
|
33
38
|
## Graph Structural Slice — who-imports + cluster (M94-D10)
|
|
34
39
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekyzinc/gsd-t",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.10",
|
|
4
4
|
"description": "GSD-T: Contract-Driven Development for Claude Code — 54 slash commands with headless-by-default workflow spawning, unattended supervisor relay with event stream, graph-powered code analysis, real-time agent dashboard, task telemetry, doc-ripple enforcement, backlog management, impact analysis, test sync, milestone archival, and PRD generation",
|
|
5
5
|
"author": "Tekyz, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,13 +33,23 @@
|
|
|
33
33
|
const fs = require("fs");
|
|
34
34
|
const path = require("path");
|
|
35
35
|
|
|
36
|
-
//
|
|
36
|
+
// A pointer, not the doctrine. Keeps context cost ~nil. Carries TWO reminders:
|
|
37
|
+
// the Six-Stage Pass (design-first) and the No-Fallback-Ever rule (never branch
|
|
38
|
+
// around a failure without asking) — both fire at the write-code moment.
|
|
37
39
|
const REMINDER =
|
|
38
40
|
"[GSD-T ARCHITECT] About to write/edit code — run the Architect's Oversight " +
|
|
39
41
|
"Six-Stage Pass FIRST (Objective → Conflict → Reuse[query the graph] → " +
|
|
40
42
|
"Simplicity → Reuse-forecast → Risk), each answered with evidence not conviction. " +
|
|
41
43
|
"Is this the simplest design, and does something reusable already exist? " +
|
|
42
|
-
"
|
|
44
|
+
"NO-FALLBACK-EVER: if this adds anything that CONTINUES AFTER A FAILURE " +
|
|
45
|
+
"(catch-and-continue, || default, silent degrade, try-X-else-Y) — STOP and ask the " +
|
|
46
|
+
"user first, unless you can cite a confirmed reproducible case only a fallback catches. " +
|
|
47
|
+
"A HALT (stop + demand fix) is NOT a fallback and is the preferred move. " +
|
|
48
|
+
"SIMPLY-STATED: before presenting an architecture/plan/finding, state it SIMPLY — every " +
|
|
49
|
+
"word load-bearing, logic in a straight line, no jargon or nested clauses. If you can't " +
|
|
50
|
+
"state it cleanly the thinking isn't done (muddle in the words = muddle in the design) — " +
|
|
51
|
+
"RE-THINK, don't re-word. 'Too sophisticated to simplify' is a banned escape hatch. " +
|
|
52
|
+
"See ~/.claude/CLAUDE.md § Architect's Oversight + No-Fallback-Ever + Simply Stated Doctrines.";
|
|
43
53
|
|
|
44
54
|
// File extensions that are PROSE/config, not code — skip the reminder for these.
|
|
45
55
|
// (The doctrine's own artifacts are markdown; reminding while authoring them is noise.)
|
|
@@ -99,6 +99,26 @@ NEED TO UNDERSTAND SOMETHING?
|
|
|
99
99
|
└── Not documented? → Research, then DOCUMENT IT
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
### Environment Access — read-first, HALT-and-document (M102)
|
|
103
|
+
|
|
104
|
+
**EXTENDS No-Re-Research; obeys No-Fallback-Ever.** Before reaching ANY non-local environment (staging/prod DB, remote server, hosted API, SSH host), the connection MAP is read from the committed `## Environments` table in `docs/infrastructure.md` — NEVER re-discovered.
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
NEED TO REACH A NON-LOCAL ENVIRONMENT?
|
|
108
|
+
├── lookupEnvironment(scope, kind) FIRST → bin/gsd-t-env-registry.cjs lookup
|
|
109
|
+
├── Row exists → use its connect command; the secret is pulled at runtime via
|
|
110
|
+
│ the recorded env-var NAME from its vault (never a value in the doc).
|
|
111
|
+
│ scope=prod + read-only=YES + a WRITE op → HALT, confirm with human.
|
|
112
|
+
└── Row MISSING → HALT the connect. Do NOT guess a connection string. Do NOT grep
|
|
113
|
+
transcripts to rediscover. The brownfield path:
|
|
114
|
+
detectEnvConfig → ask human to confirm/fill → recordEnvironment
|
|
115
|
+
→ addPermissionEntry → THEN proceed. First need = last rediscovery.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- The registry stores only the MAP + which vault holds the secret + the env-var NAME + the fetch/connect commands — **never a secret VALUE**.
|
|
119
|
+
- **Zero fallback.** A missing row resolves by DOCUMENTING (detect → ask → record → proceed), never by a guessed connstring or a transcript re-grep. That HALT-then-document is NOT a fallback.
|
|
120
|
+
- Greenfield: when GSD-T builds/provisions an env, it records the row in the SAME pass (`recordEnvironment`) — so staleness self-heals (a re-provision upserts by `(scope, kind)` and replaces the stale row).
|
|
121
|
+
|
|
102
122
|
|
|
103
123
|
# Versioning
|
|
104
124
|
|
|
@@ -456,6 +476,35 @@ See memory pointer: `feedback_auto_research_external_gaps`.
|
|
|
456
476
|
|
|
457
477
|
**§Enforcement (three layers — same shape as Unproven-Assumption):** (1) this doctrine = the *definition* (reference, always available); (2) a **PreToolUse hook on Write/Edit** = the *trigger* — injects a one-line reminder pointing here at the build moment, so it can't be missed under load; (3) the **plan/milestone workflow gate** = the *execution* — the Six-Stage Pass runs as blocking `agent()` steps with graph/doc evidence, and pseudocode-completeness is a verify check. Injecting the doctrine ≠ executing it; the workflow does the doing.
|
|
458
478
|
|
|
479
|
+
### No-Fallback-Ever Doctrine (governed, enforced — the strongest sibling of No-Silent-Degradation)
|
|
480
|
+
|
|
481
|
+
**Pretend every project is a vampire and the word "fallback" is garlic.** A fallback — **anything that continues after a failure** (a `catch` that keeps going, `|| default`, a silent degrade, a secondary path, a "try X else Y" where Y masks X failing) — is **BANNED unless the user explicitly approves it first, OR you can cite a confirmed, reproducible case where the straight-line path provably fails and ONLY a fallback catches it.** No trivial exception. This is a Destructive-Action-Guard-class STOP: before writing any such branch, **halt and ask the user.**
|
|
482
|
+
|
|
483
|
+
**Why:** the reflex to add a fallback "just in case" is what hides real failures — a fallback that guards an *unproven* case doesn't add safety, it adds a place for a real failure to hide (e.g. a graph query that silently falls back to grep when the graph is actually broken). The desired discipline is the **straight-line process that produces the result**; if the straight line can fail, the answer is **HALT and surface it**, not branch around it.
|
|
484
|
+
|
|
485
|
+
**The one thing that is NOT a fallback (and is REQUIRED where a straight line can fail):** a **HALT** — refusing to continue and demanding a fix (return `blocked-needs-human`, exit non-zero, loud message). A halt is the *opposite* of a fallback: it stops the hiding instead of enabling it. When you're tempted to write a fallback, the correct move is almost always a halt.
|
|
486
|
+
|
|
487
|
+
**Test before writing any "continue after failure" branch:**
|
|
488
|
+
1. Is this a fallback (continues past a failure) or a halt (stops)? Halt → allowed. Fallback → continue to 2.
|
|
489
|
+
2. Can I name a **confirmed, reproducible** failing case where ONLY this fallback catches it? If NO → **STOP and ask the user.** If YES → cite it in a comment + the commit, then proceed.
|
|
490
|
+
3. Never judge "trivial" yourself — the trivial-fallback judgment is exactly the one that has been failing. Ask.
|
|
491
|
+
|
|
492
|
+
**Applies to the release process too:** a publish/propagate step must **verify the change actually landed** (installed version advanced; a sample project received the new file) and **HALT if it didn't** — never trust an install/copy that *reports* success. A package manager silently keeping the old version is itself a banned silent fallback.
|
|
493
|
+
|
|
494
|
+
**§Enforcement (three layers):** (1) this doctrine = the definition; (2) the **Architect's Oversight Write/Edit trigger is extended** to challenge every fallback at the build moment ("is this a fallback? name the proven case or ask"); (3) mechanical guards where they already exist — the graph consumers' `try→catch→grep` fallback is caught by `bin/gsd-t-graph-anti-grep-lint.cjs` (reused, not duplicated); a general static "detect every fallback" lint is deliberately NOT built (it can't judge *proven-necessary* — that is the human/architect ask, which is layer 2).
|
|
495
|
+
|
|
496
|
+
### Simply Stated Doctrine (governed, enforced — clarity as a defect gate, not a writing-style reminder)
|
|
497
|
+
|
|
498
|
+
**Before GSD-T presents an architecture, plan, finding, review, or milestone definition, it must first state it *simply* — precise and complete, every word earning its place, the logic in a straight line, with no jargon standing in for a clear idea and no nested clauses hiding a tangle. If it cannot be stated simply, the thinking is NOT finished: the muddle in the words IS a muddle in the design. It goes back to be RE-THOUGHT, not re-worded.** The simply-stated version leads the deliverable; the technical depth sits below it for whoever wants it.
|
|
499
|
+
|
|
500
|
+
**This is a DIFFERENT mechanism from the Reader Contract / jargon lint.** Those treat verbosity as an OUTPUT-polish problem — trim the prose after the thinking is done — and repeatedly fail because a reminder loses to "but this case needs the detail" under load. Simply Stated treats verbosity as what it is: **a symptom of unclear thinking, and the same unclear thinking ships the bugs.** If you cannot express it cleanly, you do not yet understand it — and not-understanding is where defects come from. The inability to state it simply is a DEFECT SIGNAL, gated like the No-Fallback HALT, not a soft nudge.
|
|
501
|
+
|
|
502
|
+
**"Simply" is NOT "dumbed down."** The content stays as sophisticated as the problem demands — sophisticated IN its simplicity and conciseness (simplify the *expression*, never the *idea*). The test is NOT "could a novice understand the topic." The test is: **is every word load-bearing, and is the logic a straight line?** "This topic is too sophisticated to state simply" is the banned escape hatch.
|
|
503
|
+
|
|
504
|
+
**The HALT (the teeth):** a deliverable whose simply-stated lead cannot be written cleanly is NOT done — stop, surface it, re-think the muddled part. Do not ship the verbose version with an apology; the verbose version is evidence the design has a gap.
|
|
505
|
+
|
|
506
|
+
**§Enforcement (three layers):** (1) this doctrine = the definition; (2) the **Architect's Oversight Write/Edit trigger** carries a Simply-Stated line; (3) the **plan/milestone Six-Stage Pass + `/gsd-t-architect` gain a Simply-Stated gate** — the pass does not complete until its finding/plan has a clean simply-stated lead, and the validation protocols flag a deliverable that lacks one. The simply-stated lead is a REQUIRED ARTIFACT (like the pseudocode file), not advice.
|
|
507
|
+
|
|
459
508
|
### Phase Flow
|
|
460
509
|
- Upon completing a phase, automatically proceed to the next phase
|
|
461
510
|
- ONLY run Discussion phase if truly required (clear path → skip to Plan)
|
|
@@ -68,6 +68,46 @@ cp .env.example .env
|
|
|
68
68
|
{command}
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
+
<!-- gsd-t-env-registry:start -->
|
|
72
|
+
## Environments
|
|
73
|
+
|
|
74
|
+
> **Map, not secrets.** This table records only WHERE an environment lives and
|
|
75
|
+
> HOW to reach it — host/port/name/auth-method/which-vault-holds-the-secret/the
|
|
76
|
+
> env-var NAME/the fetch + connect commands. It NEVER stores a secret VALUE.
|
|
77
|
+
> The value lives in the vault (`.env` / Vercel / Neon / Google Secret Manager)
|
|
78
|
+
> and is pulled at runtime via the env-var NAME. A missing row → HALT and
|
|
79
|
+
> document (detect → ask → record → proceed); never guess a connection string,
|
|
80
|
+
> never grep transcripts to rediscover.
|
|
81
|
+
|
|
82
|
+
| id | scope | kind | host | port | db/name | auth method | secret vault | secret env-var NAME | fetch command | connect command | access gotchas | read-only default | recorded |
|
|
83
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
84
|
+
<!-- gsd-t-env-registry:end -->
|
|
85
|
+
|
|
86
|
+
<!--
|
|
87
|
+
Column notes:
|
|
88
|
+
scope = local | staging | prod
|
|
89
|
+
kind = postgres | mysql | redis | http-api | ssh-host | ...
|
|
90
|
+
secret vault = local (.env) | Vercel | Neon | Google Secret Manager | ...
|
|
91
|
+
secret env-var NAME = e.g. DATABASE_URL_PROD — the NAME only, NEVER the value
|
|
92
|
+
host = POSITIVE shape: localhost | IPv4 | dotted DNS hostname |
|
|
93
|
+
short lowercase service name (letters+hyphen, no digits, e.g. db, postgres)
|
|
94
|
+
db/name = short lowercase snake identifier (<=16, e.g. binvoice_prod, analytics)
|
|
95
|
+
auth method = ENUMERATED — password | iam | oauth | oauth2 | service-account |
|
|
96
|
+
ssh-key | api-key | none | scram-sha-256 | md5 | trust | token | key | ...
|
|
97
|
+
fetch command = how to pull the secret from its vault (e.g. `vercel env pull`)
|
|
98
|
+
POSITIVE allowlist: a token is accepted ONLY if it IS a $VAR/${VAR} ref,
|
|
99
|
+
a flag, a hostname/IP, a .env dotfile, or a curated CLI/db word.
|
|
100
|
+
Any OTHER bare literal is REJECTED (move it to an env var, reference as $VAR).
|
|
101
|
+
connect command = references the env-var by name: `psql "$DATABASE_URL_PROD"` (same allowlist)
|
|
102
|
+
access gotchas = ENUMERATED — vpn | ip-allowlist | ssh-tunnel | bastion | none,
|
|
103
|
+
optionally `via <hostname>` (e.g. `ssh-tunnel via bastion.example.com`).
|
|
104
|
+
Free prose is FORBIDDEN (nowhere for a secret to hide).
|
|
105
|
+
read-only default = YES for scope=prod unless a human explicitly recorded write-ok
|
|
106
|
+
There is deliberately NO secret-value column — a row is structurally incapable
|
|
107
|
+
of holding a secret. Populated by `gsd-t-env-registry` (record-at-create +
|
|
108
|
+
capture-on-first-need).
|
|
109
|
+
-->
|
|
110
|
+
|
|
71
111
|
## Credentials & Secrets
|
|
72
112
|
|
|
73
113
|
### Local (.env)
|
|
@@ -928,6 +928,19 @@ const _architectPassLine = _ARCHITECT_PHASES.has(phaseName)
|
|
|
928
928
|
` if stability forbids touching it → build new BUT register a "reuse-candidate" graph link`,
|
|
929
929
|
` to the twin (never a silent rogue duplicate).`,
|
|
930
930
|
` 6. RISK — any security or stability/scalability risk? Am I sure?`,
|
|
931
|
+
` 6b. NO-FALLBACK-EVER — does this plan add ANY fallback (anything that CONTINUES after a`,
|
|
932
|
+
` failure: catch-and-continue, || default, silent degrade, try-X-else-Y where Y masks X`,
|
|
933
|
+
` failing)? If yes: STOP and surface it as an OPEN QUESTION for the user — do NOT design`,
|
|
934
|
+
` it in — UNLESS you can cite a confirmed reproducible case only a fallback catches. The`,
|
|
935
|
+
` straight-line process that produces the result is the goal; where it can fail, prefer a`,
|
|
936
|
+
` HALT (stop + demand fix), which is NOT a fallback. Fallbacks are rare and ask-first.`,
|
|
937
|
+
` 7. SIMPLY-STATED (clarity gate — the plan is NOT done until this passes) — write the ${phaseName}`,
|
|
938
|
+
` as a SIMPLY-STATED lead FIRST: precise and complete, but every word load-bearing, the logic`,
|
|
939
|
+
` in a straight line, ZERO jargon standing in for a clear idea, no nested clauses hiding a`,
|
|
940
|
+
` tangle. If you CANNOT state it simply, the thinking is not finished — the muddle in the`,
|
|
941
|
+
` words is a muddle in the design; RE-THINK the muddled part, do not re-word it. "Too`,
|
|
942
|
+
` sophisticated to simplify" is a BANNED escape hatch (simplify the expression, never the`,
|
|
943
|
+
` idea). This simply-stated lead heads the deliverable; the depth sits below it.`,
|
|
931
944
|
`A stage you cannot answer with evidence HALTS the plan (needs-human) — do not proceed on a hunch.`,
|
|
932
945
|
].join("\n")
|
|
933
946
|
: "";
|