Skip to content

fix: warn and back up before replacing custom content in agent files - #575

Open
Som Samantray (SomSamantray) wants to merge 5 commits into
langchain-ai:mainfrom
SomSamantray:fix/preserve-agent-instructions
Open

fix: warn and back up before replacing custom content in agent files#575
Som Samantray (SomSamantray) wants to merge 5 commits into
langchain-ai:mainfrom
SomSamantray:fix/preserve-agent-instructions

Conversation

@SomSamantray

Copy link
Copy Markdown

Summary

openwiki code-mode runs can no longer silently destroy custom content in a repo's AGENTS.md/CLAUDE.md.

Before: any content a user placed inside the managed <!-- OPENWIKI:START -->…<!-- OPENWIKI:END --> block was replaced with the generated snippet on the next init/update/chat run, with no notice (the destructive path behind #573).

After: when the managed block holds content that differs from the generated snippet, the run saves the file to <file>.openwiki.bak (atomic temp-plus-rename), prints a warning naming the file and the backup path, then refreshes. Canonical blocks are left completely untouched — no rewrite, no mtime churn, line endings preserved (CRLF and lone-CR files compare equal to the LF snippet). Malformed markers still abort with both files unchanged, and an aborted run never leaves a backup behind.

Design decisions

  • Warn + backup, then proceed (over abort-with-error and warn-only): aborting would break the scheduled CI update run for affected repos; warn-only leaves no recovery copy. The scheduled-update workflow now commits the backups in its add-paths, so CI users get a durable recovery artifact.
  • Warning channel: new optional onWarning sink on the setup options, defaulting to stderr. The TUI mirrors warnings to the run log and stderr (so they survive a re-render or an error-terminated run); --print/CI keeps piped stdout clean.
  • Existing installs: openwiki code --init now warns when an already-present workflow predates the backup commit paths, since a preserved workflow is never silently modified.
  • Integrity guards: non-UTF-8 agent files are refused (no lossy rewrite or backup); stale backup temp files from a crash are swept at setup; a backup failure aborts before any rewrite and warns for backups that already succeeded.

Session-settled decisions carried from planning: protection posture warn+backup-then-proceed (user-approved, over abort-with-error and warn-only); warning channel onWarning option with stderr default (user-approved, over hardcoded stderr and the shared event stream).

Fixes #573

Testing

  • 917 tests pass (27 in the code-mode suite, including new coverage for: backup+warning on non-canonical blocks, canonical skip-write with mtime checks, CRLF/lone-CR canonical detection, malformed-marker abort leaving no backup, backup overwrite semantics, backup-failure abort, orphan-backup preservation, symlinked files, marker-less append, the warning sink, and the workflow add-paths).
  • Manual smoke: openwiki code --update --print on a fixture repo with a hand-edited block emits the warning on stderr, keeps stdout clean, writes the .bak, and preserves surrounding content; a second run is silent; a malformed-marker sibling aborts with no backup for either file; --init against a pre-existing workflow warns about the missing backup paths without touching the customized file.

Known residuals

  • Snippet-drift: if a future openwiki release changes the snippet text, one refresh per repo will read the old canonical block as "user content" and its unconditional single-slot backup would overwrite a prior genuine backup. Bounded by git history; the snippet has been byte-stable since the first release. Version-stamping the snippet is the proposed follow-up.
  • Pre-existing read-modify-write TOCTOU between read and write is unchanged.
  • The module-local pathExists copies in src/schedules.ts/src/connectors/tools.ts (different error policies) are not yet migrated to the new shared src/fs-errors.ts helper.

Post-Deploy Monitoring & Validation

No additional operational monitoring required. This is a CLI + generated-workflow change; watch scheduled-update PRs of affected repos for the backup files in add-paths diffs, and roll back by reverting this commit.


Compound Engineering

… content

Detect custom content inside the managed OPENWIKI:START/END block of
AGENTS.md and CLAUDE.md. Before refreshing, save the file to
<file>.openwiki.bak atomically (temp-plus-rename) and warn on stderr,
naming the file, the backup path, and any replaced backup. Canonical
blocks are now skipped entirely (no rewrite, no mtime churn), CRLF and
lone-CR files compare equal to the LF snippet, and marker validation
runs for both files before any backup or write so an aborted run never
leaves a backup. The scheduled-update workflow's add-paths now includes
the backups as the durable CI recovery artifact.
The TUI call site appends the warning as a run-log text event and
mirrors it to stderr so it survives a re-render or an error-terminated
run that discards the log. The --print call site pins explicit stderr
wiring so piped stdout stays clean.
README code-mode section now covers the backup file, the restore
procedure, and moving content outside the markers to stop replacement.
Adds a patch changeset for the fix.
…ration

Extract pathExists into fs-errors.ts (the repo's designated home for fs
helpers) and use it for the backup-existence check, dropping the
whole-file read. Collapse the paired backupContent/warning fields into a
single optional backup object, run backup writes in parallel, and hoist
the normalized snippet out of the per-file prepare loop.
- Mirror run-log warnings to stderr via a testable factory (survives a
  throwing log callback)
- Warn when an existing workflow predates the backup commit paths, so
  existing installs learn their CI discards backups
- Emit warnings for already-succeeded backups when a sibling backup
  fails, then abort with context (agent files left unchanged)
- Sweep stale backup temp files left by a crash between write and rename
- Refuse to rewrite or back up non-UTF-8 agent files lossily
- Document pathExists error-policy divergence from pre-existing copies
- Test hardening: fresh-backup suffix discrimination, temp cleanup
  assertion, symlink target refresh, pathExists unit tests
@changeset-bot

changeset-bot Bot commented Aug 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e68cb6f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openwiki Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

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.

openwiki init overwrites existing AGENTS.md and CLAUDE.md without warning

1 participant