docs: remove fork-only notes from PR branch

This commit is contained in:
ximengkai 2026-08-27 21:15:38 +08:00
parent 183a8792d0
commit a58b4031e7
4 changed files with 0 additions and 281 deletions

View file

@ -39,7 +39,6 @@ Commands and gotchas live under **Repo reference** below and in **[CONTRIBUTING.
## Reference docs
- **[ARCHITECTURE.md](ARCHITECTURE.md)**, **[CONTRIBUTING.md](CONTRIBUTING.md)**, **[GUARDRAILS.md](GUARDRAILS.md)**
- **Fork-specific work:** read **[docs/fork/README.md](docs/fork/README.md)** before changing the Objective-C provider, external index storage, or content-retention behavior. These documents define fork contracts; ForgeMate runner and version orchestration remain outside this repository.
- **Call & inheritance resolution (RFC #909 Ring 3):** See ARCHITECTURE.md § Scope-Resolution Pipeline. All languages resolve calls and inheritance through the scope-resolution pipeline (`Registry.lookup`, `preEmitInheritanceEdges`, `emitHeritageEdges`, `buildMro``MethodDispatchIndex`). **Shared code in `gitnexus/src/core/ingestion/` must not name languages** — plug language behavior in via `LanguageProvider` / `ScopeResolver` hooks. A language plugs in by implementing `ScopeResolver` (`scope-resolution/contract/scope-resolver.ts`) and registering it in `SCOPE_RESOLVERS`. (The legacy call-resolution DAG + `@heritage` capture path were removed in RING4-1 #942.)
- **Cursor:** `.cursor/index.mdc` (always-on); `.cursor/rules/*.mdc` (glob-scoped). Legacy `.cursorrules` deprecated.
- **GitNexus:** standard skills in `.claude/skills/gitnexus-*/`; MCP rules in `gitnexus:start` block below.

View file

@ -1,118 +0,0 @@
# External Storage and Content Retention
Status: implemented
## Goal
Add two opt-in environment variables while preserving the current repository-local behavior by default:
```sh
GITNEXUS_STORAGE_PATH=/absolute/path/to/index-slot
GITNEXUS_CONTENT_RETENTION=full|symbol|none
```
`GITNEXUS_STORAGE_PATH` lets an orchestrator choose the exact directory for one repository index. `GITNEXUS_CONTENT_RETENTION` controls source-derived text written into LadybugDB. Neither option creates a shared graph database or makes GitNexus responsible for an external system's version lifecycle.
## Implemented scope
- The storage resolver is used for index files, metadata, parse caches, locks, branch placement, registry lookup, CLI status, MCP, HTTP, and cleanup operations.
- `full`, `symbol`, and `none` retention are persisted in metadata, select compatible FTS columns, and force a full rebuild when the recorded profile or FTS profile is incompatible.
- MCP and CLI content requests expose retention capability; the HTTP file-preview and grep endpoints return an explicit unavailable response when the profile or missing checkout cannot provide source. The Web UI renders that unavailable state.
- Regression coverage includes storage resolution, metadata compatibility, rebuild behavior, retention profiles, CLI/MCP/API/WebUI behavior, and Objective-C symbol snippets.
The implementation deliberately does not add ForgeMate lifecycle orchestration, external storage services, source-content authorization, project identity, or a shared graph database.
## Storage path contract
### Inputs and default
- A missing `GITNEXUS_STORAGE_PATH` keeps the upstream storage location: `<repo>/.gitnexus/`.
- A non-empty value must be an absolute, NUL-free path whose parent can be created and written. Relative, invalid, or unusable values fail before analysis begins.
- The supplied value is the complete directory for one index, not a common root. The caller owns repository identity and chooses a collision-free slot name.
- When external storage is selected, GitNexus must not create a `.gitnexus/` placeholder, symlink, or metadata duplicate in the source worktree.
### What moves
Every repository-index artifact must resolve through one storage resolver: LadybugDB (`lbug`), index metadata, GitNexus metadata, parse caches, parsed-file caches, lock files, branch placement, runner files, cleanup targets, and any future sibling artifacts. Redirecting only the database is incorrect because later CLI, MCP, server, or cleanup operations would still look in the temporary checkout.
Resolution order is:
```text
1. Explicit GITNEXUS_STORAGE_PATH
2. storagePath recorded in the registered repository entry
3. <repository>/.gitnexus/ compatibility default
```
Registry records may add an optional `storagePath`. On a successful analysis with an explicit path, GitNexus records the resolved absolute path so `status`, `serve`, and MCP can open the index after the source worktree has been removed. Existing registry entries without this field remain valid and use the local default.
### Concurrency and lifecycle
One storage slot permits one writer under the existing lock discipline. Distinct slots may analyze concurrently. GitNexus may know the checkout path used for analysis as diagnostic metadata, but it must not require that path to still exist for graph-only MCP/CLI operations.
An external caller may write to a staging slot and atomically promote it to its own `current` location, retaining a previous slot for rollback. That naming, retention, deletion, source checkout, source revision selection, and authorization are external orchestration concerns, not GitNexus behavior.
## Content retention contract
### Profiles
| Value | File `content` | Symbol/section snippets | Graph and identities | Intended effect |
| -------- | -------------- | ----------------------- | -------------------- | --------------------------------------------------------------- |
| `full` | Retained | Retained | Complete | Current upstream-compatible behavior. |
| `symbol` | Omitted | Retained | Complete | Preserve symbol-level evidence without full eligible file text. |
| `none` | Omitted | Omitted | Complete | Preserve structural graph only. |
Missing or empty `GITNEXUS_CONTENT_RETENTION` means `full`. An explicitly invalid value fails clearly; it must not silently select another profile.
`File.content` is normalized text used for retrieval, not a byte-faithful source archive. It may have normalized whitespace or CJK segmentation and cannot become a source viewer substitute.
### Query behavior
| Capability | `full` | `symbol` | `none` |
| ------------------------------------------------ | --------------------------------------- | ------------------------------------ | ------------------------ |
| Symbol name/selector search | Available | Available | Available |
| `context`, `impact`, `trace`, structural Cypher | Available | Available | Available |
| Arbitrary file-body keyword retrieval | Available | Only if retained in a symbol snippet | Unavailable |
| Content-bearing query/context response | File and symbol content where supported | Symbol snippets only | Clear capability absence |
| Filesystem preview, grep, rename, detect-changes | Requires source worktree | Requires source worktree | Requires source worktree |
The `symbol` and `none` profiles do not change provider parsing, node IDs, line ranges, relationships, or call-graph correctness. They reduce text-retrieval evidence. `symbol` is not equivalent to `full` for natural-language searches that rely on arbitrary comments or method bodies; `none` intentionally removes source text as evidence.
No profile may fabricate an empty source result as though it were a valid source snippet. Commands and MCP tools must expose capability absence or omit content fields deliberately. Tools that require a live worktree remain unavailable after that worktree is deleted regardless of retained profile.
### FTS and stored text
Under `symbol` and `none`, GitNexus must not build file-content FTS indexes. Other FTS indexes may cover only fields allowed by the selected profile. Future FTS allocation improvements, such as skipping unused label indexes, are compatible optimizations but are not required for the first implementation.
`none` removes all source-derived body text, including source comments/descriptions and PDG basic-block text. It retains stable IDs, names, paths, line ranges, node/edge types, relation structure, resolution confidence, and non-text diagnostics.
## Metadata, compatibility, and rebuilds
Persist at least:
```json
{
"contentRetention": "symbol",
"contentRetentionSchemaVersion": 1,
"ftsProfile": "symbol-no-file-content",
"storagePath": "/absolute/path/to/index-slot"
}
```
Incremental reuse must compare source revision/file hashes, GitNexus build and schema, language-provider and grammar versions, retention profile/schema, FTS profile, and include/exclude/max-file-size configuration. A mismatch requires a clean full rebuild into a new database. Clearing `content` values in place is not a valid conversion because prior FTS and database page allocation may remain.
Indexes written before these fields existed are interpreted as `full` for read compatibility. The next successful full rebuild writes the new metadata.
## Web UI and missing source files
The existing Web UI's file preview and grep operations read the repository filesystem. They must not assume that database `File.content` is valid raw code. With an external index and deleted checkout, the UI must report full-file preview and filesystem grep as unavailable, while continuing to show graph data, symbol snippets permitted by the retention profile, file paths, line ranges, source revision, and resolution confidence. A future raw-code browser needs a separate, explicit byte-faithful retention design.
## Regression coverage
- No option: storage, metadata, CLI, MCP, and query results remain compatible with `<repo>/.gitnexus/` and `full` content.
- External storage: all artifacts reside in the selected directory; none appears in the source worktree; a deleted worktree does not prevent graph-only `status` and MCP queries through the registry.
- Storage failures: relative, invalid, unwritable, and conflicting paths fail cleanly without a usable partial index.
- Concurrency: two repositories with distinct external slots do not share locks, caches, metadata, or data.
- Retention: full/symbol/none keep identical structural node and edge counts for a fixture; only allowed text fields and FTS indexes differ.
- Rebuild: changing profile, provider/grammar version, schema, or indexing configuration forces full rebuild and produces a physically new index.
- MCP/CLI: content requests honor each profile and do not return misleading empty source text.
- Web UI: missing checkout, `symbol`, and `none` present explicit unavailable states rather than broken previews.

View file

@ -1,107 +0,0 @@
# Objective-C Provider
Status: implemented
Implementation note (`dev` branch): the first deterministic provider is wired in and covered by
focused unit/integration tests. The parser-loader ABI smoke runs in the published multi-OS test
matrix, and the native prebuild workflow owns Objective-C together with all six vendored grammar
targets. This status describes the implemented MVP; it does not promise full Objective-C
runtime dispatch.
## Goal
Add deterministic, symbol-level Objective-C analysis to GitNexus. The first release must support high-confidence code navigation and direct static dependency analysis for `.m`, `.mm`, and Objective-C `.h` files. It must not imply that Objective-C runtime dispatch is fully resolved.
The provider belongs in the existing language-provider and scope-resolution extension points. Shared ingestion code must remain language-agnostic.
## Compatibility contract
- Existing language detection and parsing must remain unchanged.
- A `.h` file must be classified from its content or surrounding context; it cannot be unconditionally claimed by Objective-C because C and C++ also use that extension.
- If Objective-C grammar loading fails, the error must clearly name the missing provider/grammar and cannot corrupt a previously valid index.
- Provider and grammar versions must be stored in index metadata. A version change that can alter node identity or edges requires a full rebuild.
- No LLM participates in parsing, name resolution, or edge creation. Analysis is Tree-sitter plus deterministic static resolution.
## MVP model
The provider must extract and connect:
- Classes, superclasses, protocols, categories, class extensions, properties, ivars, C functions, imports, declarations, and implementations.
- Instance and class methods, preserving their complete multi-part selector.
- Inheritance, protocol conformance, import, declaration/implementation, host-class/category, and statically resolved call relationships.
Stable identity must include enough ownership to distinguish same-named methods. Recommended forms are:
```text
objc:class:<ClassName>
objc:protocol:<ProtocolName>
objc:category:<HostClass>:<CategoryName>
objc:method:<Owner>:-:<selector>
objc:method:<Owner>:+:<selector>
objc:function:<qualified-or-file-scoped-name>
```
For example, `-loadData:completion:` and `+loadData:completion:` are different symbols. A category method remains linked to both its category and host class; querying the host class must expose distributed implementations.
## Resolution policy
Resolution must be conservative. A missing or dynamic target is evidence of uncertainty, not proof that no target exists.
| Receiver case | Required result |
| --- | --- |
| Explicit class name, `self`, or `super` | Resolve when the owner is statically known. |
| Local, parameter, property, or ivar with known static type | Resolve to matching owner and selector. |
| Protocol-typed receiver | Link the protocol method and identify possible implementations as candidates. |
| `id`, `Class`, macros, reflection, `performSelector:`, `NSInvocation`, runtime injection, or unknown type | Store selector/location with `resolution=unresolved`; do not emit a certain call edge. |
The provider should first collect file-local declarations, imports, and types, then resolve across the repository. It must use structured Tree-sitter captures or AST traversal, not regular expressions over source text. Multi-part selectors, block arguments, nullability annotations, generics, macros, and multiline declarations make a regex-only extractor unsafe.
## Imports and incremental correctness
- Resolve quoted project imports against the current directory, configured include roots, and indexed headers. Model framework imports as external-module evidence without downloading SDK source.
- Merge `@interface`, `@implementation`, categories, and extensions across files.
- A changed header, protocol, class declaration, or category invalidates importing and affected implementation/call-resolution state. Incremental output after such a change must match a full rebuild.
- Index metadata must record provider version, grammar version, include/exclude configuration, and parsing options used for resolution.
## Implementation sequence
1. Add and package a pinned Objective-C Tree-sitter grammar; verify macOS arm64 and the production Linux runner can load it.
2. Add language detection for `.m`, `.mm`, and content-classified `.h` files.
3. Implement AST extraction and stable IDs for declarations and definitions.
4. Implement repository-level merge, imports, inheritance, protocol, and category relationships.
5. Add conservative message-send resolution and explicit unresolved evidence.
6. Integrate invalidation, metadata comparison, MCP/CLI output, and fixtures.
## Fixtures and acceptance
Create a minimal Objective-C fixture containing a class, protocol, category, extension, superclass, properties, ivars, C function, imports, multi-part selector, block parameter, `self`, `super`, protocol receiver, and `id` receiver. Use `symodulebridge` as a real integration fixture after the minimal suite is stable.
The acceptance bar is:
- `query "SYModuleCaller"` yields class/method semantic nodes, not only file nodes.
- `context "SYModuleCaller" --file <path>` yields declaration, implementation, imports, and known references.
- Known statically typed message sends create call edges; dynamic sends are marked unresolved.
- Same selector on multiple classes, a category override, and `+` versus `-` methods remain distinct.
- A `.m`, `.h`, protocol, or category edit produces results equivalent to a clean rebuild.
- Generated documentation, dependency directories, and build output are excluded through explicit indexing configuration.
## Non-goals
The MVP does not promise exact runtime type inference for `id` or `instancetype`, reflection, swizzling, arbitrary category replacement, dynamic selector construction, or complete impact analysis across every runtime dispatch path. Tool results must surface confidence and unresolved evidence rather than presenting guesses as certain graph facts.
## Current implementation coverage on `dev`
Implemented in the branch:
- Vendored `tree-sitter-objc` grammar, registered through the existing Tree-sitter loader.
- `.m` and `.mm` language mapping plus content-based `.h` classification so plain C/C++ headers are not unconditionally claimed.
- LanguageProvider extraction for classes, protocols, categories, extensions, methods, properties, ivars, C functions, imports, unresolved message evidence, stable Objective-C qualified names, and provider/grammar metadata.
- ScopeResolver edges for imports, inheritance, protocol conformance, category host membership, implementation evidence, and conservative static message sends.
- Persisted query/context support for Objective-C class and method nodes, including implementation evidence via `DECLARES`.
- Regression tests for grammar loading, `.h` classification, stable identities, conservative calls, metadata feature mismatch, persisted query/context behavior, and incremental-vs-force parity for Objective-C fixture edits.
Known limits of this MVP:
- The first version does not perform full Objective-C runtime dispatch, swizzling, dynamic selector construction, macro expansion, or `id` flow inference.
- Protocol receiver handling records the protocol method and candidate implementation evidence, but candidate implementations are not emitted as certain call edges.
- Objective-C++ `.mm` files are parsed with the Objective-C grammar path for this MVP; deep C++ semantic extraction inside Objective-C++ bodies remains outside this provider.

View file

@ -1,55 +0,0 @@
# Forge-Specific Extensions
Status: implementation baseline
This directory records behavior that belongs to the `mengkaka/GitNexus` fork. It is intentionally separate from upstream-oriented architecture and user documentation so that a future rebase can distinguish fork contracts from upstream behavior.
## Baseline and status
- Upstream project: <https://github.com/abhigyanpatwari/GitNexus>
- Fork remote: <https://github.com/mengkaka/GitNexus>
- Current fork revision when this directory was introduced: `28187bb3a708`
- Public compatibility rule: without a documented fork option, GitNexus must preserve upstream behavior.
| Capability | Status | Contract |
| -------------------------- | ----------- | -------------------------------------------------------------------------------------- |
| Objective-C Provider | Implemented | [OBJECTIVE_C_PROVIDER.md](OBJECTIVE_C_PROVIDER.md) |
| External index storage | Implemented | [EXTERNAL_STORAGE_AND_CONTENT_RETENTION.md](EXTERNAL_STORAGE_AND_CONTENT_RETENTION.md) |
| Content retention profiles | Implemented | [EXTERNAL_STORAGE_AND_CONTENT_RETENTION.md](EXTERNAL_STORAGE_AND_CONTENT_RETENTION.md) |
`Implemented` means the documented MVP, regression tests, metadata contract, and package/runtime wiring are present on the fork's `dev` branch. It does not expand the provider into full Objective-C runtime dispatch. `Planned` means no CLI, MCP, Web UI, or environment-variable behavior may claim support yet. Each implementation PR must update this table, its related design document, tests, and the public README environment-variable table where applicable.
## Reading order
1. Read this file for scope and compatibility boundaries.
2. Read [OBJECTIVE_C_PROVIDER.md](OBJECTIVE_C_PROVIDER.md) before adding Objective-C parsing or resolution.
3. Read [EXTERNAL_STORAGE_AND_CONTENT_RETENTION.md](EXTERNAL_STORAGE_AND_CONTENT_RETENTION.md) before changing repository storage, metadata, content fields, FTS, CLI, MCP, or Web UI behavior.
4. Read `ARCHITECTURE.md`, `AGENTS.md`, and the affected implementation code before editing.
## Ownership boundary
GitNexus fork responsibilities:
- Parse and model Objective-C with explicit confidence and unresolved cases.
- Persist one repository index at a caller-selected directory while preserving the existing default location.
- Control which source-derived text is stored in that index and expose the resulting capabilities honestly.
ForgeMate responsibilities, intentionally not implemented here:
- Temporary checkout lifecycle, repository identity, index slot naming, and `current` / `previous` retention.
- Source SHA selection, Wiki publication, job status, access control, and cross-repository authorization.
- Combining Wiki and code evidence in its own MCP facade.
The fork must not turn GitNexus into ForgeMate's authoritative version database or a multi-repository shared graph database. A GitNexus index remains a rebuildable per-repository artifact.
## Change rules
- Keep default, no-option behavior byte-for-byte compatible where practical.
- Persist every option that changes index semantics in repository metadata and reject unsafe incremental reuse.
- Treat an index as valid only for its recorded source revision, parser/provider versions, schema, retention profile, and indexing configuration.
- Do not silently substitute filesystem source content for stored content, or vice versa.
- Do not add ForgeMate-specific paths, project IDs, credentials, or runner behavior to GitNexus core.
## Documentation lifecycle
The local `docs/plans/` files are working notes and may remain ignored. Once a design is adopted, this directory is the tracked source of truth for fork contracts. User-facing documentation must not advertise a planned option as available before its code and regression tests land.