fdeops 3.11.1 → 3.13.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/README.md +102 -105
- package/adapters/AGENTS.md +4 -1
- package/adapters/GEMINI.md +4 -1
- package/adapters/LOCAL-LLM.md +1 -1
- package/adapters/README.md +2 -2
- package/adapters/copilot-instructions.md +4 -1
- package/adapters/cursor.fde.mdc +4 -2
- package/bin/check.js +30 -3
- package/bin/fde.js +72 -32
- package/bin/install.js +1 -1
- package/mcp/fdeops-ingest/package.json +1 -1
- package/package.json +5 -2
- package/plugin.json +2 -2
- package/skills/fde/SKILL.md +81 -152
- package/skills/fde/archive/sdlc/README.md +7 -0
- package/skills/fde/references/status.md +2 -0
- /package/skills/fde/{references → archive/sdlc}/build.md +0 -0
- /package/skills/fde/{references → archive/sdlc}/debug.md +0 -0
- /package/skills/fde/{references → archive/sdlc}/observability.md +0 -0
- /package/skills/fde/{references → archive/sdlc}/qa-live.md +0 -0
- /package/skills/fde/{references → archive/sdlc}/security-audit.md +0 -0
- /package/skills/fde/{references → archive/sdlc}/test-on-legacy.md +0 -0
package/README.md
CHANGED
|
@@ -1,130 +1,128 @@
|
|
|
1
1
|
# FDEOps
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**The AI coding agent forgets the client. fdeops is the countersigned record — promised, measured, accepted.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/fdeops)
|
|
6
6
|
[](https://github.com/suboss87/fdeops/actions)
|
|
7
|
+
[](https://skills.sh/suboss87/fdeops)
|
|
7
8
|
[](LICENSE)
|
|
8
9
|
[](https://nodejs.org)
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
One `@fde` skill. Four days on an embed:
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
**the brief is wrong · they went quiet · when did we agree · what did they get**
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
+-----------+-----------+---------+----------+---------+
|
|
18
|
-
the fieldbook (.fde/) - one per engagement
|
|
19
|
-
written as a side effect of the work
|
|
20
|
-
```
|
|
15
|
+
The host agent still writes the TypeScript, runs the tests, and makes the commits. This skill is the engagement record. Do not ask `@fde` to review a unit test.
|
|
16
|
+
|
|
17
|
+
Talk in plain language. The AI coding agent runs the plumbing. You confirm anything that enters the record.
|
|
21
18
|
|
|
22
19
|
---
|
|
23
20
|
|
|
24
|
-
##
|
|
21
|
+
## The week
|
|
25
22
|
|
|
26
|
-
|
|
23
|
+
`@fde` plus English. No cheat sheet.
|
|
27
24
|
|
|
28
|
-
|
|
25
|
+
| When | What you say | What you get |
|
|
26
|
+
|------|--------------|--------------|
|
|
27
|
+
| **The brief is wrong** | `@fde this is Acme. Brief says they want a portal.` | Real problem, or a gap. First chat: you name the client; the AI coding agent binds. |
|
|
28
|
+
| **They went quiet** | `@fde the sponsor went quiet` | Trust signal in the record — process gap vs trust problem. |
|
|
29
|
+
| **When did we agree?** | `@fde when did we agree to drop that?` | Dated receipts, or a clear gap. |
|
|
30
|
+
| **What did they get?** | `@fde what did they get this week` | Friday ledger: promised → measured → accepted. |
|
|
31
|
+
| **After a meeting** | `@fde` debrief these notes *(paste or attach)* | Proposed updates. You review, then confirm. |
|
|
32
|
+
| **Optional: pull** | `@fde` connect Granola *(once)* · `@fde` pull today's Acme transcript | You add that source MCP. We **pull** on request — no push, no sync. [mcp/recipes/](mcp/recipes/) |
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
Same folder every time: `~/fde-engagements/<client>/.fde/`.
|
|
35
|
+
|
|
36
|
+
**Words used here, once:** *engagement* - one client's body of work, one folder. *Fieldbook* - that folder (`.fde/`), the record itself. *Brief vs reality* - what they said the problem was, and what it turned out to be. *Terrain* - their systems and org as you actually found them. *Trust signal* - green / amber / red on one relationship. *Receipts* - the dated line proving something was agreed. *Vault* - the Obsidian copy `fde vault` generates to read it all in one window.
|
|
31
37
|
|
|
32
38
|
---
|
|
33
39
|
|
|
34
40
|
## Quickstart
|
|
35
41
|
|
|
36
|
-
**1. Install**
|
|
42
|
+
**1. Install** (30 seconds). Pick one — both copies `@fde` twice.
|
|
43
|
+
|
|
44
|
+
Claude Code (hooks before you type):
|
|
37
45
|
|
|
38
46
|
```text
|
|
39
47
|
/plugin marketplace add suboss87/fdeops
|
|
40
48
|
/plugin install fdeops@fdeops
|
|
41
49
|
```
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
npx skills add suboss87/fdeops --skill fde # Cursor, Codex, skills-compatible hosts
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
That is one skill, not a catalogue - `@fde` routes the whole method. The CLI needs no install either: the skill reaches for `npx fdeops` when `fde` is not on the PATH. (Drop `--skill fde` and you also get `testing-fieldbook`, which is for people contributing to this repo, not for field work.)
|
|
48
|
-
|
|
49
|
-
Claude Code additionally gets session hooks, so context arrives before you type. Everywhere else it is the same fieldbook, loaded when you ask.
|
|
50
|
-
|
|
51
|
-
**2. Bind once** in the client workspace:
|
|
51
|
+
Cursor, Codex, and any host that speaks the skills CLI:
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
|
-
npx fdeops
|
|
55
|
-
npx fdeops resume # where we are
|
|
54
|
+
npx skills add suboss87/fdeops --skill fde
|
|
56
55
|
```
|
|
57
56
|
|
|
58
|
-
**
|
|
57
|
+
**2. One chat.** Name the client. The AI coding agent binds the engagement; you never type the CLI.
|
|
59
58
|
|
|
60
59
|
```text
|
|
61
|
-
@fde
|
|
60
|
+
@fde this is Acme
|
|
62
61
|
```
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
Paste kickoff notes in the same thread. `@fde` routes; you confirm judgment. Workflow: [docs/USAGE.md](docs/USAGE.md).
|
|
64
|
+
|
|
65
|
+
Claude Code auto-loads the fieldbook at session start. Elsewhere, say `@fde`. Tomorrow the file is still there.
|
|
65
66
|
|
|
66
67
|
<details>
|
|
67
|
-
<summary>
|
|
68
|
+
<summary>Terminal bind · other hosts · env</summary>
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
Fallback if the agent cannot bind — creates the engagement under `~/fde-engagements` and points this checkout at it:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npx fdeops resume --init acme # ~/fde-engagements/acme + bind this checkout
|
|
74
|
+
npx fdeops resume # where we are
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- **Adapters** (Cursor rules, Gemini, Copilot): `npx fdeops adapters .` — [adapters/](adapters/README.md)
|
|
78
|
+
- **Local LLMs:** load `skills/fde/SKILL.md` — [guide](adapters/LOCAL-LLM.md)
|
|
71
79
|
- **Air-gapped:** `git clone https://github.com/suboss87/fdeops.git && cd fdeops && node bin/install.js`
|
|
72
80
|
- **No install:** `npx fdeops demo` · `npx fdeops scan` (heuristic recon, not findings)
|
|
73
81
|
- **Requires:** Node.js >= 18
|
|
74
|
-
- **Override:** `FDEOPS_ENGAGEMENT`
|
|
82
|
+
- **Override:** `FDEOPS_ENGAGEMENT` — [docs/install.md](docs/install.md)
|
|
75
83
|
|
|
76
84
|
</details>
|
|
77
85
|
|
|
78
86
|
---
|
|
79
87
|
|
|
80
|
-
##
|
|
88
|
+
## See it
|
|
81
89
|
|
|
82
|
-
|
|
90
|
+
```bash
|
|
91
|
+
npx fdeops demo
|
|
92
|
+
```
|
|
83
93
|
|
|
84
|
-
|
|
85
|
-
|------|--------------|--------------|
|
|
86
|
-
| **Start of week** | `@fde` - or just open Claude Code | Fieldbook on disk either way. **Claude Code** injects trust, phase, next before you type. **Cursor / Codex / others:** say `@fde` or `resume` - nothing auto-loads. |
|
|
87
|
-
| **After a meeting** | `@fde` debrief these notes *(paste or attach)* | Proposed updates. You review, then confirm. |
|
|
88
|
-
| **Optional: pull** | `@fde` connect Granola *(once)* · `@fde` pull today's Acme transcript | You add that source MCP. We **pull** on request - no push, no sync. [mcp/recipes/](mcp/recipes/) |
|
|
89
|
-
| **Before a stakeholder meeting** | `@fde` prep me for tomorrow with the sponsor | Brief from what you already logged. |
|
|
90
|
-
| **Scope dispute** | `@fde` when did we agree to drop that? | Dated answers, or a clear gap. |
|
|
91
|
-
| **End of week** | `@fde` draft the sponsor update from the record | Status grounded in what happened. |
|
|
94
|
+
Real commands on a fake client: messy notes → you confirm → cold reload → prep → receipts → fieldbook page. Nothing of yours is read. Lives in `~/fde-engagements/.demo/`. Remove with `npx fdeops demo --clean`.
|
|
92
95
|
|
|
93
|
-
|
|
96
|
+
One recorded session — kickoff notes, next morning, “when did we agree?” weeks later. CLI output; typing pace is staged. Re-record: [`media/record-session.sh`](media/record-session.sh).
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
<p align="center"><img alt="A real fdeops session: messy kickoff notes routed into dated memory after you confirm, then a cold session that already knows the client, a grounded sponsor-meeting brief, and dated receipts" src="media/session.gif" width="900" /></p>
|
|
96
99
|
|
|
97
|
-
|
|
100
|
+
Two things a chat window cannot do: **nothing is written until you confirm**, and `<private>` lands sealed as `(private - redacted)` — never in `resume`, `prep`, `receipts`, or the dashboard.
|
|
98
101
|
|
|
99
|
-
|
|
100
|
-
- **The AI coding agent** routes to a method, does the work, and drafts the memory.
|
|
101
|
-
- **The CLI** (`bin/fde.js`) does every write, receipt, and status check - git and file reads only, no network, no model tokens. You do not live in the CLI; your agent runs it. [docs/USAGE.md](docs/USAGE.md)
|
|
102
|
-
- **You confirm.** Nothing enters the record unreviewed; `fde debrief --dry-run` shows the routing first.
|
|
102
|
+
---
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
## How it works
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
- **You** describe the situation with `@fde` (or plain language once the skill is loaded). First chat: you name the client; the AI coding agent runs the bind.
|
|
107
|
+
- **Hooks (Claude Code)** load where you left off and snapshot on the way out. Other hosts: same CLI and files; you call `@fde`.
|
|
108
|
+
- **Local CLI** — writes, receipts, status. Zero model tokens. The AI coding agent runs it; you do not live in the CLI. Friday, `fde status` prints promised → measured → accepted. [docs/USAGE.md](docs/USAGE.md)
|
|
109
|
+
- **Pull (optional)** — FDEOps is the sink. Paste is the daily path. A source MCP you add (Granola, Slack, Notion, …) can fetch text; `@fde connect …` walks config. No push, no sync, no tokens in `.fde/`. [mcp/recipes/](mcp/recipes/)
|
|
107
110
|
|
|
108
|
-
|
|
111
|
+
`CLAUDE.md` is how the *code* works. The fieldbook is how the *engagement* works. The record lives at `~/fde-engagements/<client>/.fde/` — not inside any vendor.
|
|
109
112
|
|
|
110
|
-
|
|
111
|
-
|---|---|---|
|
|
112
|
-
| Fieldbook, methods, CLI, dashboard | yes | yes |
|
|
113
|
-
| Context loaded before you type | session hooks | you say `@fde` / `resume` |
|
|
114
|
-
| Snapshot on session end | session hooks | `@fde` capture, or `fde capture` |
|
|
115
|
-
| Pull from Granola / Slack / Notion | you add that source MCP; FDEOps only ingests | same |
|
|
113
|
+
### Switch coding agents anytime
|
|
116
114
|
|
|
117
|
-
|
|
115
|
+
Change hosts, install `@fde` on the new one, bind if needed, keep talking. The client record does not move.
|
|
118
116
|
|
|
119
117
|
<details>
|
|
120
|
-
<summary>
|
|
118
|
+
<summary>Engagement verbs</summary>
|
|
121
119
|
|
|
122
120
|
| Verb | When |
|
|
123
121
|
|------|------|
|
|
124
|
-
| **land** | First days
|
|
125
|
-
| **discover** | The brief is wrong
|
|
122
|
+
| **land** | First days — brief, stakeholders, success |
|
|
123
|
+
| **discover** | The brief is wrong — evidence from the repo |
|
|
126
124
|
| **plan** | Sequence backwards from done, PR-sized |
|
|
127
|
-
|
|
|
125
|
+
| log delivery | After the host agent codes — what shipped, how it rolls back |
|
|
128
126
|
| **ship** | Pre-flight, canary, rollback |
|
|
129
127
|
| **close** | Handoff, retro, receipts that survive you |
|
|
130
128
|
|
|
@@ -136,48 +134,26 @@ Overlays (AI, fintech, healthcare, gov) fire on signal. [docs/skills.md](docs/sk
|
|
|
136
134
|
|
|
137
135
|
## Engagement memory (`.fde/`)
|
|
138
136
|
|
|
139
|
-
One folder per client. Plain markdown
|
|
137
|
+
One folder per client. Plain markdown. Grep it, copy it, defend it.
|
|
140
138
|
|
|
141
139
|
| File | Holds |
|
|
142
140
|
|------|-------|
|
|
143
141
|
| `context.md` | Where you are |
|
|
144
|
-
| `brief.md` / `success.md` | What they asked; what
|
|
142
|
+
| `brief.md` / `success.md` | What they asked; what “done” is and who signs |
|
|
145
143
|
| `reality.md` / `terrain.md` | The real problem; the map |
|
|
146
144
|
| `stakeholders.md` | `[signal:green\|amber\|red]` |
|
|
147
145
|
| `trust-profile.md` | Sacred data, AI policy, approval chain |
|
|
148
146
|
| `decisions.md` / `risks.md` / `delivery.md` | Dated choices; live risks; what shipped and how it rolls back |
|
|
149
147
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## The field methods
|
|
155
|
-
|
|
156
|
-
You never pick one. You describe the situation and `@fde` routes. **37 methods** across six domains, each a method - thinking, artifact, checkpoint - not a tip sheet. [docs/skills.md](docs/skills.md) · [docs/skills-reference.md](docs/skills-reference.md)
|
|
157
|
-
|
|
158
|
-
<details>
|
|
159
|
-
<summary>All 37 methods</summary>
|
|
160
|
-
|
|
161
|
-
| Domain | Methods |
|
|
162
|
-
|--------|---------|
|
|
163
|
-
| **1. Embed & Trust** | [land](skills/fde/references/land.md) · [audit](skills/fde/references/audit.md) · [stakeholder-radar](skills/fde/references/stakeholder-radar.md) · [trust-engineering](skills/fde/references/trust-engineering.md) · [scope-defense](skills/fde/references/scope-defense.md) |
|
|
164
|
-
| **2. Discover & Diagnose** | [discover](skills/fde/references/discover.md) · [assumption-audit](skills/fde/references/assumption-audit.md) · [use-case-scoring](skills/fde/references/use-case-scoring.md) · [sketch](skills/fde/references/sketch.md) |
|
|
165
|
-
| **3. Plan & Align** | [plan](skills/fde/references/plan.md) · [business-case](skills/fde/references/business-case.md) · [options-analysis](skills/fde/references/options-analysis.md) · [initiative-triage](skills/fde/references/initiative-triage.md) |
|
|
166
|
-
| **4. Build & Guard** | [build](skills/fde/references/build.md) · [incremental-build](skills/fde/references/incremental-build.md) · [test-on-legacy](skills/fde/references/test-on-legacy.md) · [blast-radius](skills/fde/references/blast-radius.md) · [debug](skills/fde/references/debug.md) · [rescue](skills/fde/references/rescue.md) · [security-audit](skills/fde/references/security-audit.md) · [observability](skills/fde/references/observability.md) |
|
|
167
|
-
| **5. Ship & Verify** | [ship](skills/fde/references/ship.md) · [review](skills/fde/references/review.md) · [rollback-drill](skills/fde/references/rollback-drill.md) · [qa-live](skills/fde/references/qa-live.md) |
|
|
168
|
-
| **6. Operate & Close** | [status](skills/fde/references/status.md) · [demo-prep](skills/fde/references/demo-prep.md) · [debrief](skills/fde/references/debrief.md) · [exec-narrative](skills/fde/references/exec-narrative.md) · [dashboard](skills/fde/references/dashboard.md) · [multi-customer-ops](skills/fde/references/multi-customer-ops.md) · [close](skills/fde/references/close.md) · [handoff-engineering](skills/fde/references/handoff-engineering.md) · [pattern-extract](skills/fde/references/pattern-extract.md) · [red-team](skills/fde/references/red-team.md) · [ingest](skills/fde/references/ingest.md) · [ingest-connect](skills/fde/references/ingest-connect.md) |
|
|
169
|
-
|
|
170
|
-
Overlays: [ai](skills/fde/references/ai.md) · [artifacts](skills/fde/references/artifacts.md) · [fintech](skills/fde/references/fintech.md) · [healthcare](skills/fde/references/healthcare.md) · [gov](skills/fde/references/gov.md)
|
|
171
|
-
|
|
172
|
-
</details>
|
|
148
|
+
Schema: [docs/schema.md](docs/schema.md).
|
|
173
149
|
|
|
174
150
|
---
|
|
175
151
|
|
|
176
152
|
## Fieldbook UI
|
|
177
153
|
|
|
178
|
-
`@fde` dashboard, or `npx fdeops dashboard` (`--all` for the portfolio)
|
|
154
|
+
Local HTML: trust, phase, next, the record. `@fde` dashboard, or `npx fdeops dashboard` (`--all` for the portfolio).
|
|
179
155
|
|
|
180
|
-
<p align="center"><img width="1336" height="624" alt="
|
|
156
|
+
<p align="center"><img width="1336" height="624" alt="fdeops Fieldbook in the browser" src="https://github.com/user-attachments/assets/5683614c-7730-4a3a-860d-185053a377eb" /></p>
|
|
181
157
|
|
|
182
158
|
---
|
|
183
159
|
|
|
@@ -185,32 +161,35 @@ Overlays: [ai](skills/fde/references/ai.md) · [artifacts](skills/fde/references
|
|
|
185
161
|
|
|
186
162
|
| You are | What this is |
|
|
187
163
|
|---------|----------------|
|
|
188
|
-
| **Forward Deployed Engineer** | The job this was built for
|
|
164
|
+
| **Forward Deployed Engineer** | The job this was built for — first meeting through handoff |
|
|
189
165
|
| **Consultant / contractor on site** | The engagement stops resetting every morning |
|
|
190
166
|
| **Solutions architect** | Politics and architecture in the same record |
|
|
191
|
-
| **Agency, 3
|
|
167
|
+
| **Agency, 3–5 clients** | One `.fde/` each — they stop blurring |
|
|
192
168
|
| **Fractional CTO on client work** | System of record for the embed, and the billable trail |
|
|
193
169
|
|
|
170
|
+
Ordinary TypeScript, unit tests, and git commits stay in the host agent.
|
|
171
|
+
|
|
194
172
|
---
|
|
195
173
|
|
|
196
174
|
## Your data stays yours
|
|
197
175
|
|
|
198
176
|
- **Local only.** `git` + files. No network, no telemetry, no account. Air-gapped is fine.
|
|
199
|
-
- **Plain markdown.** No database
|
|
200
|
-
- **No new data path.** The model sees client code only when you point the AI coding agent at it. `<private>`
|
|
201
|
-
- **
|
|
177
|
+
- **Plain markdown.** No database.
|
|
178
|
+
- **No new data path.** The model sees client code only when you point the AI coding agent at it. `<private>` is redacted from CLI, dashboard, and hooks — do not open raw private blocks with file tools.
|
|
179
|
+
- **Nothing unreviewed.** Draft → you confirm. `fde debrief --dry-run` shows routing first.
|
|
180
|
+
- **Know the sync surface.** `~/fde-engagements` is in `$HOME`. iCloud/Dropbox is an NDA incident waiting. `resume --init` warns. [PRIVACY.md](PRIVACY.md) before the first NDA.
|
|
202
181
|
|
|
203
|
-
[PRIVACY.md](PRIVACY.md)
|
|
182
|
+
[PRIVACY.md](PRIVACY.md) · [SECURITY.md](SECURITY.md)
|
|
204
183
|
|
|
205
184
|
---
|
|
206
185
|
|
|
207
186
|
## Principles
|
|
208
187
|
|
|
209
|
-
- **The artifact is the memory**
|
|
210
|
-
- **Methods, not autonomy**
|
|
211
|
-
- **Brief is a hypothesis**
|
|
212
|
-
- **Evidence on every claim**
|
|
213
|
-
- **One customer, one folder**
|
|
188
|
+
- **The artifact is the memory** — producing the work and recording it are one action
|
|
189
|
+
- **Methods, not autonomy** — the kit says what to check; judgment stays yours
|
|
190
|
+
- **Brief is a hypothesis** — discover before building the wrong thing
|
|
191
|
+
- **Evidence on every claim** — these files get defended in the room
|
|
192
|
+
- **One customer, one folder** — context never bleeds
|
|
214
193
|
|
|
215
194
|
---
|
|
216
195
|
|
|
@@ -224,8 +203,26 @@ Re-run the Quickstart install, or from a clone: `git pull && node bin/install.js
|
|
|
224
203
|
|
|
225
204
|
**[Subash Natarajan](https://www.linkedin.com/in/subashn/)**. [Issues](https://github.com/suboss87/fdeops/issues) · [CONTRIBUTING.md](CONTRIBUTING.md)
|
|
226
205
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
**What we won't build:** SaaS sync; Slack/Notion/Granola connectors or **push** inside the CLI; CRM as core; hardware capture; generic code-craft packs (TDD and review live elsewhere). You may **pull** via *your* MCP. The `fde` CLI stays local-only.
|
|
206
|
+
**What we won't build:** SaaS sync; Slack/Notion/Granola connectors or **push** inside the CLI; CRM as core; hardware capture; generic code-craft packs. You may **pull** via *your* MCP. The `fde` CLI stays local-only.
|
|
230
207
|
|
|
231
208
|
[FDE Methodology](FDE-METHODOLOGY.md) · [SECURITY.md](SECURITY.md) · [PRIVACY.md](PRIVACY.md) · [Repo layout](docs/REPO_LAYOUT.md) · [Skills matrix](docs/skills.md) · MIT
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
<details>
|
|
213
|
+
<summary>31 field methods (you never pick one)</summary>
|
|
214
|
+
|
|
215
|
+
You describe the situation; `@fde` routes. **31 methods**, six domains — each a method (thinking, artifact, checkpoint), not a tip sheet. [docs/skills.md](docs/skills.md) · [docs/skills-reference.md](docs/skills-reference.md)
|
|
216
|
+
|
|
217
|
+
| Domain | Methods |
|
|
218
|
+
|--------|---------|
|
|
219
|
+
| **1. Embed & Trust** | [land](skills/fde/references/land.md) · [audit](skills/fde/references/audit.md) · [stakeholder-radar](skills/fde/references/stakeholder-radar.md) · [trust-engineering](skills/fde/references/trust-engineering.md) · [scope-defense](skills/fde/references/scope-defense.md) |
|
|
220
|
+
| **2. Discover & Diagnose** | [discover](skills/fde/references/discover.md) · [assumption-audit](skills/fde/references/assumption-audit.md) · [use-case-scoring](skills/fde/references/use-case-scoring.md) · [sketch](skills/fde/references/sketch.md) |
|
|
221
|
+
| **3. Plan & Align** | [plan](skills/fde/references/plan.md) · [business-case](skills/fde/references/business-case.md) · [options-analysis](skills/fde/references/options-analysis.md) · [initiative-triage](skills/fde/references/initiative-triage.md) |
|
|
222
|
+
| **4. Build & Guard** | [incremental-build](skills/fde/references/incremental-build.md) · [blast-radius](skills/fde/references/blast-radius.md) · [rescue](skills/fde/references/rescue.md) |
|
|
223
|
+
| **5. Ship & Verify** | [ship](skills/fde/references/ship.md) · [review](skills/fde/references/review.md) · [rollback-drill](skills/fde/references/rollback-drill.md) |
|
|
224
|
+
| **6. Operate & Close** | [status](skills/fde/references/status.md) · [demo-prep](skills/fde/references/demo-prep.md) · [debrief](skills/fde/references/debrief.md) · [exec-narrative](skills/fde/references/exec-narrative.md) · [dashboard](skills/fde/references/dashboard.md) · [multi-customer-ops](skills/fde/references/multi-customer-ops.md) · [close](skills/fde/references/close.md) · [handoff-engineering](skills/fde/references/handoff-engineering.md) · [pattern-extract](skills/fde/references/pattern-extract.md) · [red-team](skills/fde/references/red-team.md) · [ingest](skills/fde/references/ingest.md) · [ingest-connect](skills/fde/references/ingest-connect.md) |
|
|
225
|
+
|
|
226
|
+
Overlays: [ai](skills/fde/references/ai.md) · [artifacts](skills/fde/references/artifacts.md) · [fintech](skills/fde/references/fintech.md) · [healthcare](skills/fde/references/healthcare.md) · [gov](skills/fde/references/gov.md)
|
|
227
|
+
|
|
228
|
+
</details>
|
package/adapters/AGENTS.md
CHANGED
|
@@ -4,10 +4,13 @@ You are the AI coding agent for a **Forward Deployed Engineer (FDE)** - the huma
|
|
|
4
4
|
|
|
5
5
|
## Entry
|
|
6
6
|
|
|
7
|
-
When the FDE types **`@fde
|
|
7
|
+
When the FDE types **`@fde`**, names a client, pastes meeting notes, asks what was agreed, or describes embed work (quiet sponsor, brief feels wrong, Friday update) — load the skill. If `fde resume` says NO ENGAGEMENT: ask the client name once, then **you** run `fde resume --init <slug>`. Never tell them to type it.
|
|
8
|
+
|
|
9
|
+
Do **not** load `@fde` for ordinary code edits, TypeScript, unit tests, refactors, or git commits.
|
|
8
10
|
|
|
9
11
|
- Skill (single source of truth): `~/.claude/skills/fde/SKILL.md`
|
|
10
12
|
- **Never ask the FDE to pick a skill.** Read the situation, route silently, do the work.
|
|
13
|
+
- **Never ask the FDE to type `fde …` commands.** You run the local CLI; they confirm judgment in chat.
|
|
11
14
|
|
|
12
15
|
## Engagement memory
|
|
13
16
|
|
package/adapters/GEMINI.md
CHANGED
|
@@ -4,10 +4,13 @@ Context for Gemini CLI when assisting a **Forward Deployed Engineer (FDE)** - th
|
|
|
4
4
|
|
|
5
5
|
## Entry
|
|
6
6
|
|
|
7
|
-
When the FDE types **`@fde
|
|
7
|
+
When the FDE types **`@fde`**, names a client, pastes meeting notes, asks what was agreed, or describes embed work (quiet sponsor, brief feels wrong, Friday update) — load the skill. If `fde resume` says NO ENGAGEMENT: ask the client name once, then **you** run `fde resume --init <slug>`. Never tell them to type it.
|
|
8
|
+
|
|
9
|
+
Do **not** load `@fde` for ordinary code edits, TypeScript, unit tests, refactors, or git commits.
|
|
8
10
|
|
|
9
11
|
- Skill (single source of truth): `~/.claude/skills/fde/SKILL.md`
|
|
10
12
|
- **Never ask the FDE to pick a skill.** Read the situation, route silently, do the work.
|
|
13
|
+
- **Never ask the FDE to type `fde …` commands.** You run the local CLI; they confirm judgment in chat.
|
|
11
14
|
|
|
12
15
|
## Engagement memory
|
|
13
16
|
|
package/adapters/LOCAL-LLM.md
CHANGED
|
@@ -62,7 +62,7 @@ The model reads SKILL.md, routes to the right skill, and produces artifacts in y
|
|
|
62
62
|
|
|
63
63
|
## Model size recommendations
|
|
64
64
|
|
|
65
|
-
The methodology is detailed (
|
|
65
|
+
The methodology is detailed (31 methods, routing logic, evidence format, memory contract). Larger models handle it better:
|
|
66
66
|
|
|
67
67
|
| Model class | Experience |
|
|
68
68
|
|-------------|-----------|
|
package/adapters/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**One brain, thin adapters.** fdeops has a single source of truth - the `@fde` skill at `skills/fde/SKILL.md` and the `fde` CLI. Each AI coding tool discovers it through a small pointer file in the place that tool already looks. No forked logic, no five copies to maintain - every adapter says the same thing: *route via `@fde`, read/write `.fde/` memory, talk like a peer, never touch what isn't yours.*
|
|
4
4
|
|
|
5
|
-
**Switching tools:** the fieldbook does not live in the agent. It lives at `~/fde-engagements/<client>/.fde/`. Point a new tool at a bound workspace, drop adapters (or install the skill/plugin for that tool), and the same client record opens. Auto session hooks are Claude Code–first; elsewhere load via `@fde` / `fde resume`. See [README §
|
|
5
|
+
**Switching tools:** the fieldbook does not live in the agent. It lives at `~/fde-engagements/<client>/.fde/`. Point a new tool at a bound workspace, drop adapters (or install the skill/plugin for that tool), and the same client record opens. Auto session hooks are Claude Code–first; elsewhere load via `@fde` / `fde resume`. See [README § Switch coding agents](../README.md#switch-coding-agents-anytime).
|
|
6
6
|
|
|
7
7
|
## What goes where
|
|
8
8
|
|
|
@@ -31,4 +31,4 @@ Defaults to the current directory if no path is given. Existing files are never
|
|
|
31
31
|
|
|
32
32
|
## The principle
|
|
33
33
|
|
|
34
|
-
The adapter only tells the tool **where the brain is and how to behave**. All the method - the
|
|
34
|
+
The adapter only tells the tool **where the brain is and how to behave**. All the method - the 31 methods, the overlays, the memory contract - lives once in `skills/fde/SKILL.md`. Update the brain, every platform gets it. That's why fdeops feels native in whatever the FDE already uses, without five things to keep in sync.
|
|
@@ -4,10 +4,13 @@ You are the AI coding agent for a **Forward Deployed Engineer (FDE)** - the huma
|
|
|
4
4
|
|
|
5
5
|
## Entry
|
|
6
6
|
|
|
7
|
-
When the FDE types **`@fde
|
|
7
|
+
When the FDE types **`@fde`**, names a client, pastes meeting notes, asks what was agreed, or describes embed work (quiet sponsor, brief feels wrong, Friday update) — load the skill. If `fde resume` says NO ENGAGEMENT: ask the client name once, then **you** run `fde resume --init <slug>`. Never tell them to type it.
|
|
8
|
+
|
|
9
|
+
Do **not** load `@fde` for ordinary code edits, TypeScript, unit tests, refactors, or git commits.
|
|
8
10
|
|
|
9
11
|
- Skill (single source of truth): `~/.claude/skills/fde/SKILL.md`
|
|
10
12
|
- **Never ask the FDE to pick a skill.** Read the situation, route silently, do the work.
|
|
13
|
+
- **Never ask the FDE to type `fde …` commands.** You run the local CLI; they confirm judgment in chat.
|
|
11
14
|
|
|
12
15
|
## Engagement memory
|
|
13
16
|
|
package/adapters/cursor.fde.mdc
CHANGED
|
@@ -9,9 +9,11 @@ You are the AI coding agent for a **Forward Deployed Engineer (FDE)** - the huma
|
|
|
9
9
|
|
|
10
10
|
## Entry
|
|
11
11
|
|
|
12
|
-
When the FDE types **`@fde
|
|
12
|
+
When the FDE types **`@fde`**, names a client, pastes meeting notes, asks what was agreed, or describes embed work (quiet sponsor, brief feels wrong, Friday update) — load `@fde`. If `fde resume` says NO ENGAGEMENT: ask the client name once, then **you** run `fde resume --init <slug>`. Never tell them to type it.
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Do **not** load `@fde` for ordinary code edits, unit tests, refactors, or git commits.
|
|
15
|
+
|
|
16
|
+
- Skill (single source of truth): `~/.claude/skills/fde/SKILL.md` (or the copy this install placed)
|
|
15
17
|
- **Never ask the FDE to pick a skill.** Read the situation, route silently, do the work.
|
|
16
18
|
- **Never ask the FDE to type `fde …` commands.** You run the local CLI; they confirm judgment in chat.
|
|
17
19
|
|
package/bin/check.js
CHANGED
|
@@ -59,8 +59,8 @@ ok('skills structure')
|
|
|
59
59
|
|
|
60
60
|
// v3: one skill + phase references (progressive disclosure)
|
|
61
61
|
const requiredReferences = [
|
|
62
|
-
'land.md', 'discover.md', 'audit.md', 'plan.md', '
|
|
63
|
-
'
|
|
62
|
+
'land.md', 'discover.md', 'audit.md', 'plan.md', 'review.md',
|
|
63
|
+
'rescue.md', 'ship.md', 'sketch.md', 'close.md', 'dashboard.md',
|
|
64
64
|
'debrief.md', 'status.md', 'demo-prep.md',
|
|
65
65
|
'healthcare.md', 'fintech.md', 'gov.md',
|
|
66
66
|
'ai.md', 'eval-pack.md',
|
|
@@ -80,7 +80,7 @@ ok('phase references')
|
|
|
80
80
|
// every judgment-heavy reference carries a worked example that names the memory
|
|
81
81
|
// file the work lands in. Prose-only guidance drifts into advice nobody can apply.
|
|
82
82
|
const exampleReferences = [
|
|
83
|
-
'land.md', 'discover.md', 'plan.md', '
|
|
83
|
+
'land.md', 'discover.md', 'plan.md', 'ship.md', 'close.md',
|
|
84
84
|
'status.md', 'stakeholder-radar.md', 'options-analysis.md', 'business-case.md',
|
|
85
85
|
'assumption-audit.md', 'scope-defense.md',
|
|
86
86
|
]
|
|
@@ -286,6 +286,33 @@ if (!read('skills/fde/SKILL.md').includes('npx --yes fdeops')) {
|
|
|
286
286
|
fail('skills/fde/SKILL.md must fall back to npx --yes fdeops when the CLI is not installed')
|
|
287
287
|
} else ok('SKILL.md npx CLI fallback')
|
|
288
288
|
|
|
289
|
+
// The frontmatter description is the only text every host reads before deciding
|
|
290
|
+
// to load the skill. If it triggers on "@fde" alone, an FDE who just talks about
|
|
291
|
+
// their client gets no memory - so it must carry natural-intent triggers in the
|
|
292
|
+
// "Use when …" convention, and @fde must be one of several, never the gate.
|
|
293
|
+
{
|
|
294
|
+
const fm = /^---\n([\s\S]*?)\n---/.exec(read('skills/fde/SKILL.md'))
|
|
295
|
+
const desc = fm ? (/^description:[^\S\n]*(.*)$/m.exec(fm[1]) || [])[1] || '' : ''
|
|
296
|
+
const triggers = desc.match(/Use when/g) || []
|
|
297
|
+
if (triggers.length < 4) {
|
|
298
|
+
fail(`SKILL.md description needs several "Use when …" triggers so it fires on intent (found ${triggers.length})`)
|
|
299
|
+
} else if (/Use when the human says @fde or/.test(desc)) {
|
|
300
|
+
fail('SKILL.md description must not gate on @fde - name the client-work intents first')
|
|
301
|
+
} else ok('SKILL.md description triggers on intent')
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Six invented words (fieldbook, terrain, reality, trust signal, receipts,
|
|
305
|
+
// vault) carry the method. They were never defined in one place, so a stranger
|
|
306
|
+
// met them scattered through the docs and guessed.
|
|
307
|
+
{
|
|
308
|
+
const gloss = /Words used here[\s\S]{0,1200}/.exec(readme)
|
|
309
|
+
const missing = ['fieldbook', 'reality', 'terrain', 'trust signal', 'receipts', 'vault']
|
|
310
|
+
.filter(w => !gloss || !new RegExp(w, 'i').test(gloss[0]))
|
|
311
|
+
if (!gloss) fail('README must define its invented words once (a "Words used here" line)')
|
|
312
|
+
else if (missing.length) fail(`README glossary is missing: ${missing.join(', ')}`)
|
|
313
|
+
else ok('README defines its own vocabulary')
|
|
314
|
+
}
|
|
315
|
+
|
|
289
316
|
if (!fs.existsSync(path.join(root, 'docs', 'USAGE.md'))) {
|
|
290
317
|
fail('docs/USAGE.md missing')
|
|
291
318
|
} else ok('docs/USAGE.md')
|
package/bin/fde.js
CHANGED
|
@@ -18,13 +18,13 @@
|
|
|
18
18
|
* fde debrief --smart propose routing from messy notes; --apply commits it
|
|
19
19
|
* fde prep [label] grounded walk-in brief from existing .fde/ only
|
|
20
20
|
* fde doctor deterministic memory lint (stale signals, gaps)
|
|
21
|
-
* fde
|
|
21
|
+
* fde tidy [--apply] propose safe consolidations; apply only with --apply (was: garden)
|
|
22
22
|
* fde ingest … stage → propose → apply pull sink (.inbox/; never auto-writes .fde/)
|
|
23
23
|
* fde owner [set …] who keeps this engagement record
|
|
24
24
|
* fde receipts <term> "what did we agree?" - search memory with dates
|
|
25
25
|
* fde capture session-end snapshot → context.md (hooks use this)
|
|
26
26
|
* fde preserve pre-compaction context snapshot (hook-internal; hooks use this)
|
|
27
|
-
* fde status [--all]
|
|
27
|
+
* fde status [--all] value ledger first, then trust (pass --all for portfolio)
|
|
28
28
|
* fde dashboard [--all] current engagement fieldbook (default) or all (--all)
|
|
29
29
|
* fde vault derived Obsidian vault of the fieldbook (disposable; --redacted)
|
|
30
30
|
*/
|
|
@@ -1223,7 +1223,7 @@ function cmdResume(args) {
|
|
|
1223
1223
|
.filter(d => !d.startsWith('.') && fs.existsSync(path.join(ENGAGEMENTS_ROOT, d, '.fde')))
|
|
1224
1224
|
.join(', ') || '(none yet)'
|
|
1225
1225
|
: '(none yet)'
|
|
1226
|
-
console.log(`NO ENGAGEMENT for this workspace.\nexisting: ${list}\
|
|
1226
|
+
console.log(`NO ENGAGEMENT for this workspace.\nexisting: ${list}\nAsk the human the client name (one question), then run: fde resume --init <client-name>\nDo not tell them to type that command.`)
|
|
1227
1227
|
process.exit(2)
|
|
1228
1228
|
}
|
|
1229
1229
|
// Monday-morning: triage + proactive hygiene (silent when clean), then memory.
|
|
@@ -2295,21 +2295,59 @@ function hasValueBucket(eng) {
|
|
|
2295
2295
|
const PENDING_CELL_RE =
|
|
2296
2296
|
/^(?:pending|tbd|to ?be ?(?:measured|confirmed|determined)|n\s*\/\s*a|na|none|unknown|not measured|\?+|\.{2,}|…|-+|—+|–+)(?:[^\w].*)?$/i
|
|
2297
2297
|
|
|
2298
|
-
function
|
|
2298
|
+
function parseValueLedger(eng) {
|
|
2299
2299
|
const ledger = stripTemplateNoise(sectionBody(readClean(eng, 'delivery.md'), 'Value ledger') || '')
|
|
2300
2300
|
const table = parseMdTable(ledger)
|
|
2301
|
-
if (!table) return {
|
|
2302
|
-
const
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2301
|
+
if (!table) return { rows: [], columnMissing: false }
|
|
2302
|
+
const idx = {
|
|
2303
|
+
slice: colIndex(table.headers, /slice/i),
|
|
2304
|
+
promised: colIndex(table.headers, /promised/i),
|
|
2305
|
+
measured: colIndex(table.headers, /measured/i),
|
|
2306
|
+
accepted: colIndex(table.headers, /accept/i),
|
|
2307
|
+
}
|
|
2308
|
+
const cell = (row, i) => (i === -1 ? '' : String(row[i] || '').trim())
|
|
2309
|
+
const rows = []
|
|
2306
2310
|
for (const row of table.rows) {
|
|
2307
|
-
const
|
|
2308
|
-
|
|
2309
|
-
const
|
|
2310
|
-
|
|
2311
|
+
const slice = cell(row, idx.slice)
|
|
2312
|
+
const promised = cell(row, idx.promised)
|
|
2313
|
+
const measured = cell(row, idx.measured)
|
|
2314
|
+
const accepted = cell(row, idx.accepted)
|
|
2315
|
+
if (!slice && !promised && !measured) continue
|
|
2316
|
+
const measuredPending = !measured || PENDING_CELL_RE.test(measured)
|
|
2317
|
+
const acceptedPending = idx.accepted === -1 || !accepted || PENDING_CELL_RE.test(accepted)
|
|
2318
|
+
let state = 'unmeasured'
|
|
2319
|
+
if (!measuredPending && acceptedPending) state = 'claimed'
|
|
2320
|
+
else if (!measuredPending) state = 'accepted'
|
|
2321
|
+
rows.push({ slice, promised, measured, accepted, state })
|
|
2311
2322
|
}
|
|
2312
|
-
return {
|
|
2323
|
+
return { rows, columnMissing: idx.accepted === -1 }
|
|
2324
|
+
}
|
|
2325
|
+
|
|
2326
|
+
function claimedValueRows(eng) {
|
|
2327
|
+
const { rows, columnMissing } = parseValueLedger(eng)
|
|
2328
|
+
return { claimed: rows.filter(r => r.state === 'claimed').length, columnMissing }
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
function formatValueLedgerLine(r) {
|
|
2332
|
+
const name = r.slice || 'value'
|
|
2333
|
+
let body = r.promised || ''
|
|
2334
|
+
if (r.state !== 'unmeasured' && r.measured) {
|
|
2335
|
+
if (!body) body = r.measured
|
|
2336
|
+
else if (!body.includes(r.measured)) body = `${body} → ${r.measured}`
|
|
2337
|
+
}
|
|
2338
|
+
const head = body ? `${name}: ${body}` : name
|
|
2339
|
+
if (r.state === 'accepted') return `${head} · accepted by ${r.accepted}`
|
|
2340
|
+
if (r.state === 'claimed') return `${head} · claimed, not yet accepted`
|
|
2341
|
+
return `${head} · not yet measured`
|
|
2342
|
+
}
|
|
2343
|
+
|
|
2344
|
+
function valueLedgerStatusLines(eng, opts = {}) {
|
|
2345
|
+
const { rows } = parseValueLedger(eng)
|
|
2346
|
+
if (!rows.length) return [' value: none yet']
|
|
2347
|
+
const cap = opts.compact ? 1 : 8
|
|
2348
|
+
const lines = rows.slice(0, cap).map(r => ` ${formatValueLedgerLine(r)}`)
|
|
2349
|
+
if (rows.length > cap) lines.push(` … ${rows.length - cap} more in delivery.md`)
|
|
2350
|
+
return lines
|
|
2313
2351
|
}
|
|
2314
2352
|
|
|
2315
2353
|
// AI in scope for ship/close hygiene — delivery/decisions/trust evidence only.
|
|
@@ -2488,18 +2526,18 @@ function cmdGarden(args) {
|
|
|
2488
2526
|
// Gardener contract (from Rowboat note_curation): no new facts, no deleted substance,
|
|
2489
2527
|
// reversible via git when healthy, confirm before apply. Mechanical only - no LLM rewrite.
|
|
2490
2528
|
if (gitHealth.ok) {
|
|
2491
|
-
console.log('
|
|
2529
|
+
console.log('TIDY (contract: no new facts · no deleted substance · reversible via memory git)')
|
|
2492
2530
|
} else if (gitHealth.reason === 'broken') {
|
|
2493
|
-
console.log('
|
|
2531
|
+
console.log('TIDY (contract: no new facts · no deleted substance · ⚠ memory git BROKEN — NOT reversible until ledger is repaired)')
|
|
2494
2532
|
} else {
|
|
2495
|
-
console.log('
|
|
2533
|
+
console.log('TIDY (contract: no new facts · no deleted substance · ⚠ memory not git-versioned — NOT reversible)')
|
|
2496
2534
|
}
|
|
2497
2535
|
console.log(resumeTriage(eng))
|
|
2498
2536
|
if (!gitHealth.ok) {
|
|
2499
2537
|
console.log(
|
|
2500
2538
|
gitHealth.reason === 'broken'
|
|
2501
|
-
? '\n⚠ ledger is UNVERSIONED (corrupt .git). Repair before trusting
|
|
2502
|
-
: '\n⚠ no memory git —
|
|
2539
|
+
? '\n⚠ ledger is UNVERSIONED (corrupt .git). Repair before trusting tidy apply: mv .fde/.git .fde/.git.broken && run any fde write to re-init.'
|
|
2540
|
+
: '\n⚠ no memory git — tidy apply cannot create a reversible commit until the ledger exists.'
|
|
2503
2541
|
)
|
|
2504
2542
|
}
|
|
2505
2543
|
const proposals = []
|
|
@@ -2539,18 +2577,18 @@ function cmdGarden(args) {
|
|
|
2539
2577
|
})
|
|
2540
2578
|
}
|
|
2541
2579
|
if (!proposals.length) {
|
|
2542
|
-
console.log('\nNothing to
|
|
2580
|
+
console.log('\nNothing to tidy.')
|
|
2543
2581
|
return
|
|
2544
2582
|
}
|
|
2545
2583
|
console.log(`\n${proposals.length} proposal(s):`)
|
|
2546
2584
|
proposals.forEach((p, i) => console.log(` ${i + 1}. [${p.kind}] ${p.text}`))
|
|
2547
2585
|
if (!apply) {
|
|
2548
|
-
console.log('\nApply mechanical items only: fde
|
|
2586
|
+
console.log('\nApply mechanical items only: fde tidy --apply')
|
|
2549
2587
|
console.log('Manual items stay yours. Every apply commits to memory git when the ledger is healthy.')
|
|
2550
2588
|
return
|
|
2551
2589
|
}
|
|
2552
2590
|
if (!gitHealth.ok && gitHealth.reason === 'broken') {
|
|
2553
|
-
console.error('refusing
|
|
2591
|
+
console.error('refusing tidy --apply while memory git is broken - repair the ledger first')
|
|
2554
2592
|
process.exit(1)
|
|
2555
2593
|
}
|
|
2556
2594
|
ensureMemoryGit(eng)
|
|
@@ -2603,9 +2641,9 @@ function cmdGarden(args) {
|
|
|
2603
2641
|
touched.add('context-archive.md')
|
|
2604
2642
|
console.log(`applied: archived ${p.sessionBlocks.length} old session-end blocks → context-archive.md`)
|
|
2605
2643
|
}
|
|
2606
|
-
const hash = commitMemory(eng, '
|
|
2644
|
+
const hash = commitMemory(eng, 'tidy', { files: [...touched] })
|
|
2607
2645
|
if (!applied) console.log('no mechanical proposals applied (manual items remain)')
|
|
2608
|
-
else console.log(`
|
|
2646
|
+
else console.log(`tidy done${hash ? ` @${hash}` : ''}`)
|
|
2609
2647
|
}
|
|
2610
2648
|
|
|
2611
2649
|
// Keep the first open-risk bullet per fingerprint; move later echoes under ## Retired.
|
|
@@ -2647,7 +2685,7 @@ function applyRiskDedupe(eng, clusters) {
|
|
|
2647
2685
|
const stamp = new Date().toISOString().slice(0, 10)
|
|
2648
2686
|
const block = retiredLines.map(l => {
|
|
2649
2687
|
const body = l.trim().replace(/^-\s*/, '')
|
|
2650
|
-
return `- [${stamp}] (
|
|
2688
|
+
return `- [${stamp}] (tidy dedupe) ${body}`
|
|
2651
2689
|
}).join('\n')
|
|
2652
2690
|
out = appendUnderSection(out, 'Retired', block)
|
|
2653
2691
|
withFileLock(p, () => { atomicWriteFile(p, out.endsWith('\n') ? out : out + '\n') })
|
|
@@ -2669,7 +2707,7 @@ function cmdStatus(args) {
|
|
|
2669
2707
|
if (!fs.existsSync(eng)) continue
|
|
2670
2708
|
const s = computeSignals(eng)
|
|
2671
2709
|
const note = [s.memoryWarn, (s.dirtyFiles && s.dirtyFiles.length) ? `dirty:${s.dirtyFiles.length}` : '', s.reason || s.topRisk].filter(Boolean).join(' · ').slice(0, 70)
|
|
2672
|
-
rows.push({ name: d, phase: s.phase, trust: s.trust, signalAge: s.signalAge, stale: s.stale, updated: s.updated, reason: note, memoryWarn: s.memoryWarn, dirtyFiles: s.dirtyFiles })
|
|
2710
|
+
rows.push({ name: d, phase: s.phase, trust: s.trust, signalAge: s.signalAge, stale: s.stale, updated: s.updated, reason: note, memoryWarn: s.memoryWarn, dirtyFiles: s.dirtyFiles, valueLines: valueLedgerStatusLines(eng, { compact: true }) })
|
|
2673
2711
|
}
|
|
2674
2712
|
} else {
|
|
2675
2713
|
const eng = resolveEngagement()
|
|
@@ -2679,13 +2717,14 @@ function cmdStatus(args) {
|
|
|
2679
2717
|
}
|
|
2680
2718
|
const s = computeSignals(eng)
|
|
2681
2719
|
const note = [s.memoryWarn, (s.dirtyFiles && s.dirtyFiles.length) ? `dirty:${s.dirtyFiles.length}` : '', s.reason || s.topRisk].filter(Boolean).join(' · ').slice(0, 70)
|
|
2682
|
-
rows.push({ name: engagementSlugFromPath(eng), phase: s.phase, trust: s.trust, signalAge: s.signalAge, stale: s.stale, updated: s.updated, reason: note, memoryWarn: s.memoryWarn, dirtyFiles: s.dirtyFiles })
|
|
2720
|
+
rows.push({ name: engagementSlugFromPath(eng), phase: s.phase, trust: s.trust, signalAge: s.signalAge, stale: s.stale, updated: s.updated, reason: note, memoryWarn: s.memoryWarn, dirtyFiles: s.dirtyFiles, valueLines: valueLedgerStatusLines(eng) })
|
|
2683
2721
|
}
|
|
2684
2722
|
if (!rows.length) { console.log('no engagements yet'); return }
|
|
2685
2723
|
const order = { RED: 0, amber: 1, green: 2 }
|
|
2686
2724
|
rows.sort((a, b) => order[a.trust] - order[b.trust])
|
|
2687
|
-
console.log((all ? 'FDE PORTFOLIO' : 'FDE STATUS') + ' -
|
|
2725
|
+
console.log((all ? 'FDE PORTFOLIO' : 'FDE STATUS') + ' - value first, then trust\n')
|
|
2688
2726
|
for (const r of rows) {
|
|
2727
|
+
for (const line of r.valueLines) console.log(line)
|
|
2689
2728
|
// "amber?" = structured signal went stale (>21d) - reconfirm before trusting it
|
|
2690
2729
|
const label = r.trust + (r.stale ? '?' : '')
|
|
2691
2730
|
const sig = r.signalAge != null ? `signal ${r.signalAge}d old${r.stale ? ' (STALE - reconfirm)' : ''} ` : ''
|
|
@@ -3150,14 +3189,13 @@ function printUsage() {
|
|
|
3150
3189
|
fde prep [label] grounded walk-in brief from existing .fde/ only
|
|
3151
3190
|
fde doctor lint engagement memory (stale signals, gaps)
|
|
3152
3191
|
fde redact <term> preview/remove lines containing a buried term (pass --apply to commit)
|
|
3153
|
-
fde
|
|
3192
|
+
fde tidy [--apply] propose safe consolidations (contract: no new facts; git-reversible)
|
|
3154
3193
|
fde owner [set email] who keeps this engagement record
|
|
3155
3194
|
fde receipts <term> "what did we agree?" with dates
|
|
3156
|
-
fde
|
|
3157
|
-
fde preserve pre-compaction context snapshot (hook-internal; hooks use this)
|
|
3158
|
-
fde status [--all] current engagement status (pass --all for full portfolio)
|
|
3195
|
+
fde status [--all] value ledger, then trust (pass --all for full portfolio)
|
|
3159
3196
|
fde dashboard [--all] current engagement fieldbook (pass --all for every client)
|
|
3160
3197
|
fde vault derived Obsidian vault of every engagement (--current for one, --redacted for a shared screen, --out <dir>)
|
|
3198
|
+
hooks call these; you do not: capture (session-end snapshot), preserve (pre-compaction snapshot)
|
|
3161
3199
|
env FDEOPS_ENGAGEMENTS_ROOT override ~/fde-engagements (init/status/dashboard/registry)
|
|
3162
3200
|
writes require a workspace bind (or FDEOPS_ENGAGEMENT) - folder-name match is read-only
|
|
3163
3201
|
.fde/ is git-versioned locally for tamper-evident receipts (no remote, no telemetry)
|
|
@@ -3176,6 +3214,8 @@ switch (cmd) {
|
|
|
3176
3214
|
case 'prep': cmdPrep(args); break
|
|
3177
3215
|
case 'doctor': cmdDoctor(); break
|
|
3178
3216
|
case 'redact': cmdRedact(args); break
|
|
3217
|
+
// `garden` was the name through 3.11.x; it keeps working.
|
|
3218
|
+
case 'tidy':
|
|
3179
3219
|
case 'garden': cmdGarden(args); break
|
|
3180
3220
|
case 'owner': cmdOwner(args); break
|
|
3181
3221
|
case 'receipts': cmdReceipts(args); break
|
package/bin/install.js
CHANGED
|
@@ -355,7 +355,7 @@ function cmdInstall(opts = {}) {
|
|
|
355
355
|
// through to the CLI (fde.js reads process.argv itself, so require() is enough).
|
|
356
356
|
const FDE_SUBCOMMANDS = [
|
|
357
357
|
'demo', 'scan', 'resume', 'triage', 'log', 'debrief', 'ingest', 'prep', 'doctor', 'redact',
|
|
358
|
-
'garden', 'owner', 'receipts', 'capture', 'preserve', 'status', 'dashboard', 'vault', 'help',
|
|
358
|
+
'tidy', 'garden', 'owner', 'receipts', 'capture', 'preserve', 'status', 'dashboard', 'vault', 'help',
|
|
359
359
|
]
|
|
360
360
|
|
|
361
361
|
const INSTALL_SUBCOMMANDS = ['init', 'adapters', 'install']
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fdeops",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "3.13.0",
|
|
4
|
+
"description": "Engagement memory for AI coding agents. Your agent forgets the client every morning - the sponsor, the promise, who signed off. FDEOps keeps that as dated markdown on your laptop: one @fde skill for the four days of an embed, a deterministic local CLI, and hooks that make it automatic. Claude Code plugin and any agent that loads skills.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"fdeops": "bin/install.js",
|
|
7
7
|
"fde": "bin/fde.js"
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
"ai-agent",
|
|
31
31
|
"skills",
|
|
32
32
|
"plugin",
|
|
33
|
+
"engagement-memory",
|
|
34
|
+
"agent-memory",
|
|
35
|
+
"client-context",
|
|
33
36
|
"fde",
|
|
34
37
|
"forward-deployed",
|
|
35
38
|
"forward-deployed-engineer",
|
package/plugin.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "fdeops",
|
|
4
|
-
"version": "3.
|
|
5
|
-
"description": "Engagement
|
|
4
|
+
"version": "3.13.0",
|
|
5
|
+
"description": "Engagement memory for AI coding agents: per-client memory in local .fde/ files, one @fde skill, the four days of an embed. Local-only, no network.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Subash Natarajan",
|
|
8
8
|
"url": "https://github.com/suboss87"
|
package/skills/fde/SKILL.md
CHANGED
|
@@ -1,80 +1,57 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: fde
|
|
3
|
-
description:
|
|
3
|
+
description: Keeps engagement memory for client work - sponsor, promise, what shipped, who accepted it. Use when the human names a client, customer or stakeholder. Use when they debrief a meeting or paste notes from one. Use when they ask what was agreed, or want dates and receipts. Use when they prep a client meeting or readout, when scope or trust shifts, or when they say @fde. Route the phase and run the local fde CLI (or npx --yes fdeops if it is not installed); never ask them to type commands. Not for ordinary code edits, unit tests, refactors or commits.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# @fde
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## Purpose
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
- **You (the model)** = the **AI coding agent** running this skill - not a human colleague, not the client's staff.
|
|
10
|
+
This skill is the **engagement record** for one client — not a land-through-close operating system, and not a coding skill. Four days drive the work: the brief is wrong, they went quiet, when did we agree, what did they get. You read `.fde/`, route, do the judgment, **confirm with the FDE, then write**. The host agent writes the code; you log what they got.
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
Every routed method still produces a concrete artifact in `.fde/`. The artifact is the deliverable AND the memory.
|
|
14
13
|
|
|
15
|
-
##
|
|
14
|
+
## When NOT to use
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|-----|-----------|
|
|
19
|
-
| **FDE (human)** | `@fde` + natural language. Examples: "debrief these notes", "prep me for tomorrow's sponsor meeting", "when did we agree to drop that?", "draft the sponsor update". |
|
|
20
|
-
| **You (agent)** | Run the local `fde` CLI for deterministic memory work. Never tell the FDE to type `fde …` (except if setup is missing - then **you** run `fde resume --init <name>` after one clarifying question). |
|
|
21
|
-
|
|
22
|
-
If you catch yourself saying "run `fde debrief --smart notes.txt`" to the human - **stop**. Run it yourself (or write a temp notes file and run it), then show the human the result in plain language for confirm/reject.
|
|
16
|
+
`@fde` is the client record. Stay in the **host agent** for TypeScript errors, unit tests, refactors, git commits, and generic debug. Do not load `archive/sdlc/`. Agreed slice + code: implement in the host agent, then `fde log delivery`.
|
|
23
17
|
|
|
24
|
-
##
|
|
18
|
+
## Four days (use these first)
|
|
25
19
|
|
|
26
|
-
|
|
20
|
+
Name the day, not the phase. Each moment: one sentence to say, one CLI verb, then stop. Coding, tests, and generic debug stay in the host agent.
|
|
27
21
|
|
|
28
|
-
|
|
22
|
+
| The day | Sentence to say | You run | Then read |
|
|
23
|
+
|---------|-----------------|---------|-----------|
|
|
24
|
+
| **The brief is wrong** | "If this works, who in their company would have to agree that it worked?" | `fde resume` then follow discover | `references/discover.md` |
|
|
25
|
+
| **They went quiet** | "Is this a process gap, or a trust problem?" | `fde log contact "…" --signal amber\|red\|green` | `references/rescue.md` (trust fire) |
|
|
26
|
+
| **When did we agree?** | Don't argue from memory. Search the record. | `fde receipts <term>` | — |
|
|
27
|
+
| **What did they get?** | Read the ledger out loud. A number nobody signed is claimed, not delivered. | `fde status` | `references/status.md` |
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
This is what makes fdeops a second brain instead of a chat window.
|
|
29
|
+
After a meeting, still: `fde debrief --smart` → confirm → `--apply`. Before a walk-in: `fde prep`. Friday: `fde status` (promised → measured → accepted). Notes: dated, sourced, one customer.
|
|
33
30
|
|
|
34
|
-
|
|
35
|
-
2. **Deliverable = memory.** The output of every phase IS a `.fde/` file. You never ask the FDE to "update their notes" - producing the work and writing the memory are one action. The phase reference tells you which file.
|
|
36
|
-
3. **Evidence rule.** Every claim in an artifact carries its source: `(validated with: ops lead, Day 5)`, `(churn: 47 commits/90d)`, `(stated, unverified)`. The FDE defends these files in front of skeptical clients - traceable beats plausible.
|
|
37
|
-
4. **No invented facts - ever.** People, names, quotes, meetings, and numbers exist only if the FDE said them or the repo shows them. Never invent a stakeholder, a conversation, or a source to make the narrative richer - one fabricated name poisons every real citation around it. A missing fact is written as `unknown - ask: <the question>`, nothing else.
|
|
38
|
-
5. **On exit (session digest):** before the session ends — and again before opening a PR — capture the *thinking*, not the chat. Propose this digest in plain language; on FDE confirm, write into existing `.fde/` files (never a transcript dump, never a product-repo history folder):
|
|
39
|
-
|
|
40
|
-
| Digest beat | Lands in |
|
|
41
|
-
|-------------|----------|
|
|
42
|
-
| **TL;DR** (1–2 sentences: what moved) | `context.md` current state / short dated note |
|
|
43
|
-
| **Key decisions & why** (only real ones) | `decisions.md` dated lines — skip if none |
|
|
44
|
-
| **Pivot / aha** (course correction that mattered) | one line in `context.md`, or `decisions.md` if it changed the plan |
|
|
45
|
-
| **Scope + verification** (files/slice + how you checked) | `delivery.md` when code or a PR is in play; else skip |
|
|
46
|
-
| **Gotchas for the next reader** | `context.md` (teammate / Monday-you) |
|
|
47
|
-
| **Next action** | existing `## Next action` — **replace** the bullet; never append a second heading |
|
|
31
|
+
## Audience
|
|
48
32
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
7. **Never delete a code-read section when rewriting an artifact.** `stakeholders.md`'s `## Signal history` holds dated `[signal:...]` tokens that `fde status`/`fde receipts`/the dashboard read verbatim; `risks.md`'s `## Retired` is read the same way. Rewriting either file as an artifact (land, audit, stakeholder-radar) is fine - dropping one of these sections is not. Carry existing entries forward untouched.
|
|
33
|
+
- **FDE** = the **human** who types `@fde` (or plain language) in the chat.
|
|
34
|
+
- **You (the model)** = the **AI coding agent** running this skill - not a human colleague, not the client's staff.
|
|
52
35
|
|
|
53
|
-
|
|
36
|
+
When this skill says "ask the FDE," it means the human. When it says "write to `.fde/`," you (the AI) write the files.
|
|
54
37
|
|
|
55
|
-
|
|
38
|
+
## Human surface vs agent plumbing (non-negotiable)
|
|
56
39
|
|
|
57
|
-
|
|
|
58
|
-
|
|
59
|
-
|
|
|
60
|
-
|
|
|
61
|
-
| Route to a phase because it "feels senior" while the signal is muddy | **Stop.** Playback + one natural question, or name the ambiguity ("discover or rescue — leaning X because…"). |
|
|
62
|
-
| Fill `success.md` / `terrain.md` with plausible defaults when the brief is thin | **Stop.** Run **brief interrogation** in land/discover (one Q + GUESS + confidence) until you can write without guessing, or leave gaps explicit. |
|
|
63
|
-
| Ship / go-live / irreversible change with "probably fine" | **Stop.** Run **intent vs diff** (KEEP/JUSTIFY/SPLIT/DROP) then **pre-blast challenge** in ship (or red-team) — CLAIM → CHALLENGE → VERDICT — and log both. |
|
|
64
|
-
| Grill the FDE with a checklist when they're mid-flow | **Stop.** Playback rule wins. Probe only when a missing fact changes the next move. |
|
|
65
|
-
| Sync chat transcripts / agent brain folders into the product git repo for "team share" | **Stop.** Run **session digest** into `.fde/` (judgment only). Transcripts stay local. |
|
|
40
|
+
| Who | Interface |
|
|
41
|
+
|-----|-----------|
|
|
42
|
+
| **FDE (human)** | `@fde` + natural language. Examples: "debrief these notes", "prep me for tomorrow's sponsor meeting", "when did we agree to drop that?", "draft the sponsor update". |
|
|
43
|
+
| **You (agent)** | Run the local `fde` CLI for deterministic memory work. Never tell the FDE to type `fde …` (except if setup is missing - then **you** run `fde resume --init <name>` after one clarifying question). |
|
|
66
44
|
|
|
67
|
-
|
|
45
|
+
If you catch yourself saying "run `fde debrief --smart notes.txt`" to the human - **stop**. Run it yourself (or write a temp notes file and run it), then show the human the result in plain language for confirm/reject.
|
|
68
46
|
|
|
69
|
-
##
|
|
47
|
+
## Entry (every session)
|
|
70
48
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- Locked-down engagement (no AI on their code)? Use the CLI + the fieldbook only. The memory layer is the FDE's own notes, not customer code.
|
|
49
|
+
1. Run `fde resume` (fallbacks, in order: `node ~/.claude/fdeops/fde.js resume`, then `npx --yes fdeops resume`). Bounded `context.md` only. `fde resume --full` if you genuinely need the whole log.
|
|
50
|
+
2. If **NO ENGAGEMENT**: **do not leave them there.** Ask once: "What should we call this client?" Then **you** run `fde resume --init <slug>`. Never show them the command. After bind, if they pasted notes, go straight to debrief.
|
|
51
|
+
3. Playback 2–3 lines from TRIAGE + bounded `context.md`. If TRIAGE has `hygiene:`, that is the one finding — offer `fde doctor`; **never auto-rewrite**. Else one line, ask where to pick up.
|
|
52
|
+
4. Route (Four days, then the table below). Read **one** `references/*.md`. Confirm with the FDE, then write.
|
|
76
53
|
|
|
77
|
-
**
|
|
54
|
+
**Path.** Workspace registry (written once by `fde resume --init <name>`) is the normal bind: env override → registry → pointer file → workspace-name match (read-only) → `./.fde`. Writes need a bind (or `FDEOPS_ENGAGEMENT`), not folder name alone. Never install fdeops on infrastructure the FDE does not control.
|
|
78
55
|
|
|
79
56
|
**You run the `fde` CLI for deterministic work - never improvise shell, never hand the command to the FDE:**
|
|
80
57
|
|
|
@@ -87,115 +64,83 @@ When NOT to interrogate or challenge: unambiguous one-liners, mechanical ops, FD
|
|
|
87
64
|
| "Connect a new MCP" / "connect Granola/Slack/Notion" / "what can you pull?" | Follow `references/ingest-connect.md`: source MCP only; sink is `fde ingest` here. They save/reload; you cannot silent-install. Paste still works with no MCP. |
|
|
88
65
|
| "Prep me for the meeting with …" / walk-in brief | `fde prep "<short label>"` - present the brief in plain language; do not invent facts missing from `.fde/` |
|
|
89
66
|
| "When did we agree…?" / scope dispute | `fde receipts <term>` - answer with dates; no hit = gap, not proof |
|
|
90
|
-
| "Draft the sponsor update" / how are we doing | `fde status` then follow `references/status.md`
|
|
67
|
+
| "Draft the sponsor update" / how are we doing | `fde status` (value ledger first) then follow `references/status.md` |
|
|
91
68
|
| "Log that they went quiet" / trust signal | `fde log contact "…" --signal amber\|green\|red`. If they already named the color ("log that as amber"), that is the confirm — write it. If they only described the situation, playback the color once, then write. |
|
|
92
69
|
| Want the HTML fieldbook | `fde dashboard` |
|
|
93
|
-
| "Open my clients in Obsidian" / one window over everything / "can I show this to the sponsor?" | `fde vault` (add `--redacted` for a shared screen). Derived and disposable:
|
|
94
|
-
| "Clean up the fieldbook" / hygiene / memory feels messy | `fde doctor` - walk issues in plain language; propose fixes; never auto-rewrite without confirm. Includes structural gaps: empty operating map (plan+), stakeholder name forks (Denise vs Denise Chen), duplicates, ship/close risks. Contradictions need judgment (brief vs reality) - doctor is structural; you handle meaning. |
|
|
70
|
+
| "Open my clients in Obsidian" / one window over everything / "can I show this to the sponsor?" | `fde vault` (add `--redacted` for a shared screen). Derived and disposable: rebuilt from `.fde/` on every run and never read back. Keep logging to the fieldbook, not the vault. |
|
|
71
|
+
| "Clean up the fieldbook" / hygiene / memory feels messy | `fde doctor` - walk issues in plain language; propose fixes; never auto-rewrite without confirm. Includes structural gaps: empty operating map (plan+), stakeholder name forks (Denise vs Denise Chen), duplicates, ship/close risks. Contradictions need judgment (brief vs reality) - doctor is structural; you handle meaning. `fde tidy` proposes safe consolidations (no new facts). |
|
|
95
72
|
| "Scrub this secret / redact that token" (buried line, not just last write) | `fde redact <term>` preview, then `fde redact <term> --apply` after confirm. Undo is last-write only; redact is for buried lines. Remind them to rotate the real credential. |
|
|
96
73
|
|
|
97
74
|
**The debrief verb.** Highest-frequency loop. When the FDE shares notes or says "debrief": **you** run the smart path (write notes to a temp file if needed). `--smart` writes a propose file via deterministic heuristics (existing prefixes + light keywords); authentic rambling notes often land mostly in context until **you** rewrite lines with type prefixes. Show the proposed routing in plain language. Only `--apply` (or pipe prefixed lines) after they confirm. Never ask them to run the CLI. Detail: `references/debrief.md`.
|
|
98
75
|
|
|
99
76
|
CLI genuinely unavailable (no Node, offline, npx blocked) → use the manual fallbacks inside each reference (still you write files; still never ask the FDE to run setup). A skill-only install is not "unavailable": run the verb through `npx --yes fdeops …` so the gates, dating and redaction still hold.
|
|
100
77
|
|
|
101
|
-
**
|
|
78
|
+
**Tokens.** CLI work is free. Hooks inject TRIAGE + bounded `context.md` + a pointer — never this full skill (loads on `@fde`). Pull **one** reference when you route; never dump a whole `.fde/` file — bounded resume, or `fde receipts <term>`.
|
|
102
79
|
|
|
103
|
-
##
|
|
80
|
+
## Anti-invention gates (field anti-slop)
|
|
104
81
|
|
|
105
|
-
|
|
82
|
+
These stop confident fiction. They are not optional soft tips.
|
|
106
83
|
|
|
107
|
-
|
|
84
|
+
| Temptation | Gate |
|
|
85
|
+
|------------|------|
|
|
86
|
+
| Tell the FDE to run `fde debrief` / `fde prep` / `fde receipts` themselves | **Stop.** You run the CLI; they confirm results in plain language. |
|
|
87
|
+
| Invent a stakeholder, meeting, or quote to make the narrative rich | **Stop.** Write `unknown - ask: <question>`. One fake name poisons every real citation. |
|
|
88
|
+
| Route to a phase because it "feels senior" while the signal is muddy | **Stop.** Playback + one natural question, or name the ambiguity ("discover or rescue — leaning X because…"). |
|
|
89
|
+
| Fill `success.md` / `terrain.md` with plausible defaults when the brief is thin | **Stop.** Run **brief interrogation** in land/discover (one Q + GUESS + confidence) until you can write without guessing, or leave gaps explicit. |
|
|
90
|
+
| Ship / go-live / irreversible change with "probably fine" | **Stop.** Run **intent vs diff** (KEEP/JUSTIFY/SPLIT/DROP) then **pre-blast challenge** in ship (or red-team) — CLAIM → CHALLENGE → VERDICT — and log both. |
|
|
91
|
+
| Grill the FDE with a checklist when they're mid-flow | **Stop.** Playback rule wins. Probe only when a missing fact changes the next move. |
|
|
92
|
+
| Sync chat transcripts / agent brain folders into the product git repo for "team share" | **Stop.** Run **session digest** into `.fde/` (judgment only). Transcripts stay local. |
|
|
108
93
|
|
|
109
|
-
|
|
94
|
+
When NOT to interrogate or challenge: unambiguous one-liners, mechanical ops, FDE explicitly asked for speed, answer already in `.fde/`.
|
|
110
95
|
|
|
111
|
-
|
|
96
|
+
## The memory contract (non-negotiable)
|
|
112
97
|
|
|
113
|
-
|
|
98
|
+
This is what makes fdeops a second brain instead of a chat window.
|
|
114
99
|
|
|
115
|
-
1. **
|
|
116
|
-
2.
|
|
117
|
-
3.
|
|
100
|
+
1. **On entry:** resolve the engagement path and read `context.md` via `fde resume` (a bounded view - current state + recent activity). Nothing else until the routed phase needs it; pull other `.fde/` files only when the phase calls for them.
|
|
101
|
+
2. **Deliverable = memory.** The output of every phase IS a `.fde/` file. You never ask the FDE to "update their notes" - producing the work and writing the memory are one action. The phase reference tells you which file.
|
|
102
|
+
3. **Evidence rule.** Every claim in an artifact carries its source: `(validated with: ops lead, Day 5)`, `(churn: 47 commits/90d)`, `(stated, unverified)`. The FDE defends these files in front of skeptical clients - traceable beats plausible.
|
|
103
|
+
4. **No invented facts - ever.** People, names, quotes, meetings, and numbers exist only if the FDE said them or the repo shows them. Never invent a stakeholder, a conversation, or a source to make the narrative richer - one fabricated name poisons every real citation around it. A missing fact is written as `unknown - ask: <the question>`, nothing else.
|
|
104
|
+
5. **On exit (session digest):** before the session ends — and again before opening a PR — capture the *thinking*, not the chat. Propose this digest in plain language; on FDE confirm, write into existing `.fde/` files (never a transcript dump, never a product-repo history folder):
|
|
118
105
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
106
|
+
| Digest beat | Lands in |
|
|
107
|
+
|-------------|----------|
|
|
108
|
+
| **TL;DR** (1–2 sentences: what moved) | `context.md` current state / short dated note |
|
|
109
|
+
| **Key decisions & why** (only real ones) | `decisions.md` dated lines — skip if none |
|
|
110
|
+
| **Pivot / aha** (course correction that mattered) | one line in `context.md`, or `decisions.md` if it changed the plan |
|
|
111
|
+
| **Scope + verification** (files/slice + how you checked) | `delivery.md` when code or a PR is in play; else skip |
|
|
112
|
+
| **Gotchas for the next reader** | `context.md` (teammate / Monday-you) |
|
|
113
|
+
| **Next action** | existing `## Next action` — **replace** the bullet; never append a second heading |
|
|
124
114
|
|
|
125
|
-
|
|
115
|
+
The `session-stop` hook backstops a thin snapshot; **you** write the meaningful digest. Raw agent transcripts stay on the machine — judgment is what ships in the fieldbook.
|
|
116
|
+
6. **One customer, one folder.** Never merge two engagements into one `.fde/`. Confirm which engagement applies when multiple exist.
|
|
117
|
+
7. **Never delete a code-read section when rewriting an artifact.** `stakeholders.md`'s `## Signal history` holds dated `[signal:...]` tokens that `fde status`/`fde receipts`/the dashboard read verbatim; `risks.md`'s `## Retired` is read the same way. Rewriting either file as an artifact (land, audit, stakeholder-radar) is fine - dropping one of these sections is not. Carry existing entries forward untouched.
|
|
126
118
|
|
|
127
|
-
##
|
|
119
|
+
## Data boundary (confirm before touching their code)
|
|
128
120
|
|
|
129
|
-
|
|
121
|
+
- The `fde` CLI is **local only** - `git` + file reads, no AI, no network. Safe in any environment.
|
|
122
|
+
- **You (the AI) only ever see customer code when the FDE points you at it** inside the agent they are already authorized to run. fdeops adds no new data path.
|
|
123
|
+
- **Before reading or generating against customer code, the AI policy must be known.** New engagement, policy unknown → ask it (land phase: "policy on AI-generated code? data that must never touch AI?") *before* loading their code into context. Default to "not permitted" until the FDE confirms.
|
|
124
|
+
- Data tagged `<private>` (sacred data, PHI, cardholder, classified) is **redacted from CLI, dashboard, and hook-injected context**. Do **not** open raw `<private>` blocks with file tools (that bypasses redaction) or paste them into prompts/subagents - work around them, never with them.
|
|
125
|
+
- Locked-down engagement (no AI on their code)? Use the CLI + the fieldbook only. The memory layer is the FDE's own notes, not customer code.
|
|
130
126
|
|
|
131
|
-
|
|
132
|
-
- **Back-and-forth, not a monologue.** React to what they just said before you add your own read. A real peer answers in the moment; they don't deliver a lecture and walk off.
|
|
133
|
-
- **Question-driven - but the question has to earn its place.** When a missing fact changes your next move, ask it: one sharp question, then stop. Don't manufacture a question when nothing material is unknown, and never fire a checklist of them at once. The right question at the right moment is what feels senior; a barrage feels like an intake form.
|
|
134
|
-
- **Point of view.** "I'd stop coding and fix alignment first." Not "you might consider exploring stakeholder dynamics."
|
|
135
|
-
- **Their words.** Use the customer name, role, and details they gave you.
|
|
136
|
-
- **Never:** survey mode, "Certainly", "Happy to help", template lines read aloud, advice built on fiction they didn't tell you.
|
|
127
|
+
## Voice
|
|
137
128
|
|
|
138
|
-
|
|
129
|
+
Direct, their words, no "Certainly." Playback 2–4 lines before you act. One sharp question only when a missing fact changes the next move. After writing memory, one directed next move; skip if they're already in flow.
|
|
139
130
|
|
|
140
|
-
|
|
131
|
+
Ask once on a new engagement: days, weeks, or months of runway? **Sprint** (1–2 days) skip ceremony; **Standard** (1–4 weeks) full sequence; **Programme** (months) plus political mapping and formal handoff. Speed changes depth, not which phases exist.
|
|
141
132
|
|
|
142
|
-
|
|
133
|
+
### Checkpoint — one question before you cross a line
|
|
143
134
|
|
|
144
|
-
| Before you… |
|
|
145
|
-
|
|
146
|
-
| touch their code the first time | "Is there a safe place to break things, or am I in production?"
|
|
135
|
+
| Before you… | Ask |
|
|
136
|
+
|-------------|-----|
|
|
137
|
+
| touch their code the first time | "Is there a safe place to break things, or am I in production?" — plus AI-code policy if unknown |
|
|
147
138
|
| deploy or go live | "Who needs to know this is shipping, and what's the rollback if it turns?" |
|
|
148
139
|
| hand an artifact to a sponsor or exec | "Does this go to them as-is, or do you want to gut-check it first?" |
|
|
149
|
-
| act on a pivot
|
|
140
|
+
| act on a pivot (budget cut, new CTO, reprioritisation) | "Is the old plan dead, or just paused?" |
|
|
150
141
|
| respond to a quiet stakeholder / slipping trust | "Is this a process gap, or a trust problem?" |
|
|
151
142
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
## Two-way co-pilot (not one-way recording)
|
|
155
|
-
|
|
156
|
-
You are not a scribe. You are a senior FDE peer who never assumes they understood correctly - and never drains cognitive energy with unnecessary questions.
|
|
157
|
-
|
|
158
|
-
**The playback rule:** Before acting on any skill, state your understanding in 2-4 lines. Not as a question - as a brief confirmation that invites correction:
|
|
159
|
-
|
|
160
|
-
> "Working with: payment retry after failure. Blast radius is payment-service and notification-service. Terrain is 3 days fresh. No open critical risks on these modules. Generating the spec."
|
|
161
|
-
|
|
162
|
-
The FDE can nod (zero friction) or correct ("billing-service too"). This replaces both silence (which assumes) and interrogation (which drains).
|
|
163
|
-
|
|
164
|
-
**When to probe (elevates the FDE):**
|
|
165
|
-
- A fact is missing that WILL cause rework if wrong → one precise question, then act
|
|
166
|
-
- Two artifacts contradict each other → name it briefly, suggest which one is current
|
|
167
|
-
- Acceptance criteria are untestable → rephrase them specifically and confirm
|
|
168
|
-
|
|
169
|
-
**When to stay quiet (respects the FDE's flow):**
|
|
170
|
-
- The FDE is clearly in motion and knows what they're doing
|
|
171
|
-
- The concern is minor and won't change the next 3 moves
|
|
172
|
-
- You already have the answer in the artifacts - act on it, don't re-confirm
|
|
173
|
-
|
|
174
|
-
**The principle:** Your goal is to elevate, not interrogate. Add clarity where it prevents mistakes. Stay out of the way everywhere else.
|
|
175
|
-
|
|
176
|
-
**Never:** fire multiple questions at once, probe where the answer doesn't change the work, repeat what's already in the artifacts, or slow down a confident FDE to prove you're being thorough. One well-placed observation beats five careful questions.
|
|
177
|
-
|
|
178
|
-
## Forward momentum (after writing memory)
|
|
179
|
-
|
|
180
|
-
After updating `.fde/` artifacts, suggest the ONE next move that accelerates the engagement - but only when the next step isn't already obvious to the FDE.
|
|
181
|
-
|
|
182
|
-
**Do this when:**
|
|
183
|
-
- The FDE just finished a phase and the natural next step saves them thinking time
|
|
184
|
-
- There's a dependency that unblocks faster if acted on now (access request, stakeholder conversation, spec generation)
|
|
185
|
-
- The engagement is at a decision point (plan needs approval, risk needs escalation)
|
|
186
|
-
|
|
187
|
-
**Don't do this when:**
|
|
188
|
-
- The FDE is clearly in flow and already knows what's next
|
|
189
|
-
- You just finished a minor update (logging a risk, updating a signal)
|
|
190
|
-
- The next step is obvious from context (mid-build, next task in sequence)
|
|
191
|
-
|
|
192
|
-
**The format:** One line, directed, based on engagement state. Not a menu.
|
|
193
|
-
|
|
194
|
-
> "Updated. Terrain is mapped - ready to plan the slices, or does Denise need to see this first?"
|
|
195
|
-
|
|
196
|
-
> "Shipped and logged. Task 4 touches the billing module where that open risk sits. Worth addressing that before starting?"
|
|
197
|
-
|
|
198
|
-
> "Brief written. You don't have repo access yet - want me to draft the request or are you handling that?"
|
|
143
|
+
If `context.md` already answers it, don't ask again.
|
|
199
144
|
|
|
200
145
|
## Routing - 6 domains
|
|
201
146
|
|
|
@@ -241,14 +186,9 @@ Safe implementation on someone else's codebase.
|
|
|
241
186
|
|
|
242
187
|
| You hear | Skill | Reference |
|
|
243
188
|
|----------|-------|-----------|
|
|
244
|
-
| Ready to build, implementing, legacy change, ship a feature end to end | build | `references/build.md` |
|
|
245
189
|
| Large feature, need visible progress every 2–3 days | incremental-build | `references/incremental-build.md` |
|
|
246
|
-
| No tests, legacy code, need to make changes safely | test-on-legacy | `references/test-on-legacy.md` |
|
|
247
190
|
| What could go wrong, touching shared infrastructure, need to assess impact | blast-radius | `references/blast-radius.md` |
|
|
248
|
-
| Something's broken, can't reproduce, shouldn't be happening | debug | `references/debug.md` |
|
|
249
191
|
| Production down, urgent - OR stakeholder gone quiet, trust slipping | rescue | `references/rescue.md` |
|
|
250
|
-
| Security check, auth/payments/user data, compliance question | security-audit | `references/security-audit.md` |
|
|
251
|
-
| Need monitoring, can't tell when things break, shipping to prod | observability | `references/observability.md` |
|
|
252
192
|
|
|
253
193
|
### Domain 5 - Ship & Verify
|
|
254
194
|
|
|
@@ -261,7 +201,6 @@ Getting to production without surprises.
|
|
|
261
201
|
| Diff grew / scope creep in the PR / "did we only build what we said" / KEEP JUSTIFY SPLIT DROP | review (+ ship if going live) | `references/review.md` Stage 1 · `references/ship.md` Intent vs diff |
|
|
262
202
|
| Wrap the session / share the thinking / catch teammates up / before I open the PR | (memory contract — session digest) | SKILL.md **On exit** — write TL;DR + decisions/why into `.fde/`; no transcript sync |
|
|
263
203
|
| "We can always revert" - need to actually test the escape route | rollback-drill | `references/rollback-drill.md` |
|
|
264
|
-
| Need to test from user perspective, "works on my machine" | qa-live | `references/qa-live.md` |
|
|
265
204
|
|
|
266
205
|
### Domain 6 - Operate & Close
|
|
267
206
|
|
|
@@ -315,20 +254,10 @@ If the FDE says "how are we doing" / "are we on track": load `reality.md`, `risk
|
|
|
315
254
|
- Any risk overdue for action?
|
|
316
255
|
- Value delivered and logged in `delivery.md`?
|
|
317
256
|
|
|
318
|
-
## Three speeds
|
|
319
|
-
|
|
320
|
-
Ask once on a new engagement, woven in naturally: days, weeks, or months of runway?
|
|
321
|
-
|
|
322
|
-
- **Sprint** (1–2 days): land fast, find the real problem, ship something visible. Skip ceremony.
|
|
323
|
-
- **Standard** (1–4 weeks): full sequence, one stakeholder check-in per phase.
|
|
324
|
-
- **Programme** (months): full sequence plus political mapping, pattern extraction, formal handoff.
|
|
325
|
-
|
|
326
|
-
Speed changes the depth of each phase, not which phases exist.
|
|
327
|
-
|
|
328
257
|
## Operational edge cases
|
|
329
258
|
|
|
330
259
|
- **`.fde/` exists but `context.md` is empty:** treat as new session - ask what's happening.
|
|
331
|
-
- **"Ready to build" but no `terrain.md` or plan in `decisions.md`:** route to discover or plan first. Never start code blind.
|
|
260
|
+
- **"Ready to build" but no `terrain.md` or plan in `decisions.md`:** route to discover or plan first. Never start code blind. Agreed slice + code work: **you implement in the host agent**; log delivery with `fde log delivery`. Do not load archived SDLC sermons (`archive/sdlc/`).
|
|
332
261
|
- **Taking over mid-flight without `audit.md`:** audit before build.
|
|
333
262
|
- **Multiple customers in one message:** confirm which engagement; never cross-contaminate folders.
|
|
334
263
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Archived SDLC methods (not routed)
|
|
2
|
+
|
|
3
|
+
These files used to sit in `references/` and compete with ordinary coding-agent skills (TDD, review, debug). They are **not** in the `@fde` router.
|
|
4
|
+
|
|
5
|
+
Keep them here for history. Do not load them for a TypeScript error, a unit test, or a deploy checklist — that work stays in the host agent.
|
|
6
|
+
|
|
7
|
+
Routed FDE work is in `../references/` and the four days in `SKILL.md`.
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
## Method (you do this work)
|
|
8
8
|
|
|
9
|
+
**First:** run `fde status`. It prints the value ledger before trust — promised → measured → accepted by, or `claimed, not yet accepted`. Those lines are the Situation. Do not invent a number the CLI did not print.
|
|
10
|
+
|
|
9
11
|
**Always draft in SCQA.** One page maximum. No other shape.
|
|
10
12
|
|
|
11
13
|
| Block | What to write | Source |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|