---
title: File tracking and cleanup
description: How inline metadata identifies stale proxies and where preservation guarantees stop.
---


When you rename a backend artifact, its old TypeScript file must disappear or consumers can keep importing a client that no longer has an endpoint. Arc identifies those stale files with inline metadata, rather than a separate JSON index.

## How it works

An illustrative generated metadata line:

```typescript
// @generated by Cratis. Source: MyApp.Commands.CreateOrder. Time: 2024-12-08T12:00:00.0000000Z. Hash: 1E9523083D8C6457F194B1CB045877E19BE204FB42F9F6E5574B77FC79B3ABDA
```

After generating the current artifacts, the executable:

1. Scans `.ts` files recursively below the output path, excluding `index.ts`.
2. Identifies files with valid generated metadata that were not produced in this run.
3. Deletes those orphaned files and attempts to clean their directories.
4. Updates barrel files unless index generation is skipped.

The scan is output-tree-wide, not partitioned by input assembly. **Do not give independent generation runs the same output tree:** one can regard another's proxies as orphans.

For example, renaming `UpdateOrder` to `ModifyOrder` creates `ModifyOrder.ts`, removes the marked `UpdateOrder.ts`, and updates its exports. An unchanged `CreateOrder.ts` retains its timestamp when its existing metadata/hash matches in incremental mode.

## Configuration limits

| Setting | Current behavior |
| --- | --- |
| `CratisProxiesSkipOutputDeletion=true` | Prevents initial recursive output deletion; orphan cleanup still runs |
| `CratisProxiesSkipIndexGeneration=true` | Skips barrel creation/update; does not prevent orphan cleanup from deleting an index |
| `CratisProxiesSkipFileIndexTracking=true` | Forwarded by MSBuild, but ignored by the executable; **does not disable cleanup** |

A manual export can also point at an entire **sibling folder** that has its own `index.ts`/`index.tsx` barrel, or re-export an npm package outright — both are preserved the same way:

```typescript
// A hand-written folder with its own barrel (./List/index.ts)
export * from './List';

// A hand-written re-export of an entire package
export * from '@cratis/components';

export * from './CreateOrder';
export * from './UpdateOrder';
```

The generator only ever removes a relative export once its target genuinely stops resolving — a sibling file that no longer exists, or a sibling folder whose own barrel is gone. It never considers a bare/package specifier for removal, because it has no way to verify one on disk.

:::note
Unlike every other generated file, `index.ts` never carries the `// @generated by Cratis` marker comment. Because it is a merge target you edit directly rather than a file the generator fully owns, marking it "generated" would make it eligible for the orphan-deletion pass described above, and would cause [`@cratis/eslint-plugin-arc`'s `skip-generated-proxies` processor](/arc/backend/csharp/proxy-generation/linting/) to stop linting the hand-written lines it contains. If you'd rather manage `index.ts` entirely yourself, see [output behavior](/arc/backend/csharp/proxy-generation/configuration/output-behavior/), controlled by `CratisProxiesSkipIndexGeneration`.
:::

The executable no longer maintains `.cratis/GeneratedFileIndex.json`, and it does not consume `--project-directory`. Do not create, repair, or configure that retired index as part of a current setup.

See [output behavior](/arc/backend/csharp/proxy-generation/configuration/output-behavior/) for the different MSBuild and direct-executable deletion defaults.

## Barrel preservation is limited

During an index update, the generator recognizes `export * from '…'` lines, adds exports for generated files, and removes recognized exports whose targets are stale. It can retain existing exports to live `.ts`/`.tsx` files; it does not automatically add exports for arbitrary handwritten files.

Nonempty non-matching lines, such as imports and comments, are retained when rewriting, but moved before the managed exports. Blank lines and precise formatting are not preserved. This is not a general TypeScript-aware barrel editor.

A separate orphan-directory cleanup phase can delete `index.ts` without checking whether it is handwritten. Its emptiness test counts other `.ts`/`.tsx` files and subdirectories, not all file types. A directory containing only an index and non-TypeScript assets can lose its index before directory deletion fails because those assets remain. Skipping index generation does not bypass that phase.

For dependable isolation, keep handwritten source, assets, and public barrels **outside** the generated output directory. Do not rely on the skipped-tracking flag as a safety switch.

## Troubleshooting

- **A stale proxy remains:** confirm it has valid first-line generated metadata and lies under the configured output path. Unmarked files are not recognized as orphans.
- **Unexpected deletions:** inspect the build log, output path, full-deletion setting, and whether another assembly shares that tree. Restore handwritten files from version control before rebuilding with isolated output.
- **Unexpected Git diffs:** full deletion recreates inline timestamps; configuration, grouping, or template changes can also change output.
- **A barrel is missing or stale:** inspect index-generation settings and cleanup messages. Review the actual exports rather than assuming all index edits survive.

Commit generated proxies when your frontend workflow consumes them directly, and review generated deletions in code review. Never edit a generated proxy to repair its backend contract; fix the source or generator configuration and rebuild.
