Skip to content

fix: 3.10.3 — an unhonorable FDEOPS_ENGAGEMENT refuses instead of filing under another client - #44

Merged
suboss87 merged 1 commit into
Mainfrom
devin/1787128570-stability-pass
Aug 20, 2026
Merged

fix: 3.10.3 — an unhonorable FDEOPS_ENGAGEMENT refuses instead of filing under another client#44
suboss87 merged 1 commit into
Mainfrom
devin/1787128570-stability-pass

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

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_ENGAGEMENT fell 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:

if (env) {
  const ok = accept(env)
  if (ok) return ok      // …and on failure: fall through to the registry
}

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 .fde path. FDEOPS_ENGAGEMENT=acme did nothing useful, and FDEOPS_ENGAGEMENT=~/fde-engagements/acme (the folder, not its .fde) succeeded — writing decisions.md beside 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. readRegistry turned junk into bindings. line.lastIndexOf(' ') returns -1 on a line with no space, so l.slice(0, -1) yielded a workspace path missing its last character and slug was the whole line. One hand-edited line made every real binding under it unreachable behind NO ENGAGEMENT. Non-binding lines are now skipped with one warning naming the file; resume --init rewrites the registry without them.

4. doctor called a broken memory file healthy. A .fde/decisions.md that 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 check is red on Main#43 removed the README section holding media/session.gif, which the gate added in #35 requires. Rather than reverting an editorial choice, the gate now accepts the recording in README.md or docs/USAGE.md (still enforcing gif + cast + reproducible recorder), and the recording moved to docs/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.js currently enforces:

  • registry_engagement_dir (17 lines of awk) is copied verbatim into all three hooks and must stay in lockstep with resolveEngagement — unifying it means either a sourced hooks/lib/ file or hooks delegating resolution to the CLI, and the gates mandate today's shape.
  • bin/fde.js is ~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 jscpd found 0 clones in the JS at a 35-token threshold, so there was nothing to unify or delete.

Verified: npm run check green, 97/97 tests (4 new), and from the packed 3.10.3 tarball on a clean HOMEfdeops dmeo exits 1, FDEOPS_ENGAGEMENT=ghost fde resume exits 2 with the refusal, fde demo exits 0.

Link to Devin session: https://app.devin.ai/sessions/f135381c4682413bae73dff38eb6d1a3
Requested by: @suboss87


Open in Devin Review

@suboss87 suboss87 self-assigned this Aug 19, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@suboss87
suboss87 merged commit 62bba4b into Main Aug 20, 2026
1 of 2 checks passed

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog

## 3.10.3 — 2026-08-04

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants