1
0
Fork 0
Code Issues Pull requests Projects Releases 2 Packages Wiki Activity Actions Pages

Merge adapter lifecycle safeguards

This commit is contained in:
Andraxion 2026-07-29 02:59:24 -04:00
commit 15a913003c
11 changed files with 541 additions and 11 deletions

View file

@ -296,6 +296,34 @@ The incremental path is:
Missing, incompatible, or corrupt cache data is a cache miss. It must never become a partial graph
or replace the last valid index.
### Declare the process-stable adapter implementation boundary
An adapter object is loaded once when its project-bound process starts. Source synchronization can
refresh the graph, but it cannot safely replace already imported adapter code in place.
`AdapterProject` automatically fingerprints a project-local Python package containing the loader
class and a declared descriptor file. Declare a broader or non-Python boundary explicitly when the
adapter uses helpers, configuration, schemas, or templates outside that inferred package:
```python
settings = AdapterProjectSettings(
implementation=AdapterImplementation(
roots=(project_root / "docforge_adapter",),
files=(project_root / ".docforge" / "project.toml",),
suffixes=(".py", ".toml"),
),
)
```
The boundary is confined to the project root and limited to 4,096 files and 64,000,000 bytes.
DocForge fingerprints relative paths and bytes. An added, changed, deleted, missing, or symlinked
implementation file produces `adapter_restart_required` before another MCP operation. Restart the
project-bound server; do not use Python module reloading to mutate a live adapter graph.
The manifest remains a current source snapshot, not a Git-index snapshot. A Git-backed adapter must
omit a deleted source whether its deletion is unstaged or staged. Staging is never a required
DocForge synchronization step.
## Step 9: keep the complete path independent
The full rebuild must not read the incremental extraction cache. Otherwise equivalence compares
@ -344,7 +372,9 @@ An adapter is not complete until these cases pass:
| Shared header/module change | Every reverse dependent reparses |
| Added source | New contribution appears without stale duplicates |
| Renamed source | Old contribution disappears and new identity follows policy |
| Deleted source | Owned nodes, relationships, and Logic disappear |
| Unstaged and staged deleted source | Owned nodes, relationships, and Logic disappear identically |
| Adapter implementation edit/add/delete | `adapter_restart_required` before synchronization |
| Adapter descriptor/configuration edit | `adapter_restart_required` before synchronization |
| Build flags/features change | Affected units invalidate |
| Extractor version change | Old contributions invalidate |
| Corrupt cache | Clean recovery without partial publication |
@ -445,4 +475,3 @@ For every such change:
- [ ] Session composition and family isolation are proven.
- [ ] Viewer, query, context, and Logic retrieval are proven.
- [ ] Performance, graph shape, unsupported facts, and version rules are recorded.

View file

@ -96,10 +96,27 @@ DocForge invalidates a source when:
Deleted sources are omitted from the candidate projection. Their cached dependency declarations
remain available long enough to invalidate surviving dependents.
The manifest describes the current supported filesystem snapshot. It must not retain a missing file
only because Git still tracks it, and it must not require staging before a deletion disappears.
Git-backed adapters must prove that staged and unstaged deletions produce the same current source
set. DocForge then removes the omitted contribution and invalidates its surviving reverse
dependents.
If an adapter cannot precisely describe the affected sources, it should declare broader
dependencies or change its adapter/extractor version. Incorrectly retaining a stale relationship
is never an acceptable optimization.
## Adapter implementation lifecycle
Graph source changes are synchronizable. Changes to the code or configuration implementing the
adapter are not.
`AdapterProject` fingerprints the inferred or explicitly declared implementation boundary when the
project process starts. Every MCP operation validates that boundary before work begins. Changes to
implementation paths or bytes return `adapter_restart_required` with bounded added, changed, and
deleted path evidence. The error is intentionally not auto-repaired through `docforge_sync`; a
fresh process must import and validate the current adapter.
## Build reporting
`build` and `reindex` include an extraction report:

View file

@ -38,6 +38,11 @@ returns the complete fixed binding, active index path, proposal and application
recommended workflow. `docforge_sync` exposes the same idempotent synchronization explicitly.
Neither operation changes canonical sources.
Adapter-backed servers also validate their process-start implementation fingerprint before every
tool. `adapter_restart_required` is stale but not synchronizable. Its remediation is
`restart_project_server`; the current process does not reload project code, update Git staging, or
continue with a newly changed validator.
The normal command binds the generic project loader. An explicit project integration may instead
construct the same read-only surface from a validated `ProjectService` and project-owned context
provider. This form cannot register proposal tools. Project discovery, session selection, family

View file

@ -677,6 +677,16 @@ without a source-analysis rewrite.
## Troubleshooting
### `adapter_restart_required`
The project-local adapter code, its declared descriptor, or another implementation file changed
after the project-bound MCP process started. DocForge rejects every further operation before
synchronization because the live Python objects still represent the prior implementation.
Restart the MCP server or start a fresh client session. Do not stage files merely to change the
adapter's source manifest, and do not attempt in-process module reloading. The error includes
bounded added, changed, and deleted path evidence to identify the changed implementation boundary.
### `stale_index` or `visualization_stale`
Normal MCP operations automatically repair a missing, stale, or invalid disposable index under a