fix: 3.10.3 — an unhonorable FDEOPS_ENGAGEMENT refuses instead of filing under another client - #44
Conversation
…ing under another client
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
| @@ -1,5 +1,18 @@ | |||
| # Changelog | |||
|
|
|||
| ## 3.10.3 — 2026-08-04 | |||
There was a problem hiding this comment.
🟡 New changelog release entry is dated earlier than the previous release
The new release entry is dated (## 3.10.3 — 2026-08-04 at CHANGELOG.md:3) with a day that predates the two entries directly beneath it (3.10.2 and 3.10.1, both 2026-08-13), so the changelog reads as if the newest release shipped before the previous one.
Impact: Readers scanning the changelog see the latest version stamped with an out-of-order, earlier date, making the release history look inconsistent and untrustworthy.
Date ordering against surrounding entries
The entry at CHANGELOG.md:3 is dated 2026-08-04, but CHANGELOG.md:16 shows 3.10.2 as 2026-08-13 and 3.10.1 also 2026-08-13. The 2026-08-04 value matches the older 3.10.0 entry, suggesting the date was copied by mistake; the PR itself is dated 2026-08-20.
Prompt for agents
The new changelog heading in CHANGELOG.md line 3 reads '## 3.10.3 — 2026-08-04', which is an earlier date than the 3.10.2 and 3.10.1 entries beneath it (both 2026-08-13). This appears to be a copy error from the 3.10.0 entry. Update the 3.10.3 date to the actual release date (the PR is dated 2026-08-20) so the changelog stays chronologically ordered.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
Output of a stability pass (crash fuzzing + static duplicate/dead-code/coupling analysis) over
bin/,bin/lib/,mcp/,hooks/. Argument and hostile-state fuzzing produced zero crashes in 82 cases — but four correctness defects in engagement resolution, all of which quietly file work under the wrong client or under nothing at all.1.
FDEOPS_ENGAGEMENTfell through when it could not be honored. The env override is documented as taking precedence over the registry; when it pointed nowhere it was silently dropped and resolution continued:So with a workspace bound to
client-b,FDEOPS_ENGAGEMENT=client-a fde log decision "…"appended to client-b, exit 0, no warning — the same cross-client contamination the read-only folder-name path already refuses. Now it refuses, names the value, and prints both paths it tried. Reads refuse too: a stale override printing another client's memory back into the agent is the same defect one step earlier.2. It only accepted the exact
.fdepath.FDEOPS_ENGAGEMENT=acmedid nothing useful, andFDEOPS_ENGAGEMENT=~/fde-engagements/acme(the folder, not its.fde) succeeded — writingdecisions.mdbeside the real memory, outside the git ledger: one client, two records, receipts in neither. Resolution order is now<env>/.fde→<env>→<root>/<slug>/.fde→ refuse.3.
readRegistryturned junk into bindings.line.lastIndexOf(' ')returns-1on a line with no space, sol.slice(0, -1)yielded a workspace path missing its last character andslugwas the whole line. One hand-edited line made every real binding under it unreachable behindNO ENGAGEMENT. Non-binding lines are now skipped with one warning naming the file;resume --initrewrites the registry without them.4.
doctorcalled a broken memory file healthy. A.fde/decisions.mdthat is a directory or a symlink reads as empty and rejects every append (EISDIR, or the symlink write refusal) — doctor printed "OK - no structural issues". It now flags both.Also:
npm run checkis red onMain— #43 removed the README section holdingmedia/session.gif, which the gate added in #35 requires. Rather than reverting an editorial choice, the gate now accepts the recording inREADME.mdordocs/USAGE.md(still enforcing gif + cast + reproducible recorder), and the recording moved todocs/USAGE.md. Say the word if you want it back on the front door instead.The two remaining findings are structural and not in this diff, because both conflict with rules
check.jscurrently enforces:registry_engagement_dir(17 lines of awk) is copied verbatim into all three hooks and must stay in lockstep withresolveEngagement— unifying it means either a sourcedhooks/lib/file or hooks delegating resolution to the CLI, and the gates mandate today's shape.bin/fde.jsis ~2.9k lines carrying dispatch, every verb, the privacy boundary and the doctor rules.Not done, deliberately: no logging/telemetry trackers were injected for "runtime suspects" (routine 3, phase 2) — the repo boundary is no network, no telemetry. Static analysis found 0 unreferenced functions of 193 and
jscpdfound 0 clones in the JS at a 35-token threshold, so there was nothing to unify or delete.Verified:
npm run checkgreen, 97/97 tests (4 new), and from the packed 3.10.3 tarball on a cleanHOME—fdeops dmeoexits 1,FDEOPS_ENGAGEMENT=ghost fde resumeexits 2 with the refusal,fde demoexits 0.Link to Devin session: https://app.devin.ai/sessions/f135381c4682413bae73dff38eb6d1a3
Requested by: @suboss87