This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine.
Imagine opening an unfamiliar repository. The README is incomplete, the architecture is unclear, and the commit history contains messages like WIP and fix stuff.
The code survived. Understanding it takes an investigation.
I have spent too much time trying to connect those fragments when exploring neglected projects. For private code, sending everything to a hosted AI service is not always an acceptable shortcut either.
That led me to RepoSéance: a local-first software archaeology workbench built with Flutter for Windows, Gemma 4 E2B, and Ollama.
“Back to life” is the metaphor, not an automatic repair feature. RepoSéance helps a developer investigate what remains; it does not rebuild, modify, or run the project it inspects.
What I built
RepoSéance combines deterministic repository inspection with local model inference. Dart collects and organises the evidence; Gemma interprets selected excerpts.
The application can:
- inspect a bounded selection of tracked repository files;
- generate a structured report about apparent purpose, components, and technical characteristics;
- display recent commit records;
- answer questions using evidence selected from the current snapshot; and
- export a Markdown report, optionally including Q&A.
The references are inspectable. A developer can open the captured excerpt behind a finding instead of accepting a confident explanation on trust.
## The ghost is the context
I interpreted Ghost in the Machine as the technical context left behind in a codebase: source files, manifests, comments, documentation, and commit records.
Those fragments can help explain a project. They cannot reliably reveal a former maintainer’s private intentions.
RepoSéance therefore needs to distinguish an observation from an inference—and admit when the inspected material cannot answer a question.
## Demo
The walkthrough shows the real Windows application inspecting its own
reposeancerepository onmain, opening captured file and commit evidence, trying Q&A, and preparing a Markdown export. It is not a demonstration of reviving an abandoned third-party project. The video is edited for viewing: waiting periods are shortened and disclosed onscreen. The autopsy report in this recording displays 136.6 seconds. The Q&A examples include insufficient-evidence responses; I do not present those as successful factual answers. The fixture test below is a separate evaluation case, not the repository shown in that walkthrough. ## A question it answered—and why I could check it For a controlled test, I usedforgotten_inventory, a synthetic Flutter-like repository created for evaluation. It is not a real abandoned project or an external user trial. I asked: > What dependencies and packages are declared in pubspec.yaml? In that fixture run, the response returnednot_found: falsein approximately 36.1 seconds and made three observed claims, each citingE001: - The project declares
flutteras a dependency. - It declares
flutter_barcode_scannerwith version constraint^2.0.0. - It declares
sqflitewith version constraint^2.3.0. The relevant part of the capturedpubspec.yamlexcerpt was:
dependencies:
flutter:
sdk: flutter
sqflite: ^2.3.0
flutter_barcode_scanner: ^2.0.0
These claims are directly supported by the manifest. They establish declared dependencies, not that every package is installed, imported, or used correctly at runtime.
That is a modest result, but an inspectable one. A deeper claim about persistence would require implementation evidence—not just the presence of sqflite in a manifest.
I also tested the question:
Why SQLite instead of PostgreSQL?
In that separate fixture case, Gemma returnednot_found: true, an empty claims list, and an explanation that the supplied evidence did not document the decision. That refusal came from the model; passing application schema checks is a separate step.
A useful factual answer and a justified refusal are different outcomes. I want the application to handle both without pretending they are interchangeable.
How it works
Local Git repository
|
v
Bounded file scanner + read-only Git inspection
|
v
Captured evidence snapshot
|
+--> Lexical retrieval for Q&A
|
v
Selected evidence + structured prompt
|
v
Local Ollama HTTP API --> Gemma 4 E2B
|
v
Dart response validation + request-level evidence checks
|
v
Report / answer / captured evidence preview
Inspection is not execution. Git is invoked with argument lists and shell execution disabled. RepoSéance does not run the target repository’s builds, tests, or package scripts, and the model does not receive filesystem or shell tools.
The snapshot is partial. The scanner bounds candidate enumeration, selected files, traversal depth, and extracted text. In the recorded run, the selected-file limit was 50 and the depth limit was four; the report disclosed skipped files and omitted candidates.
References belong to the application. File excerpts and commit records receive evidence IDs. Captured file content is fingerprinted with SHA-256, and returned IDs are checked against the evidence supplied for that request. The UI resolves references through those records rather than trusting model-generated paths.
Q&A uses lightweight retrieval. A lexical matcher selects relevant snippets before inference. No vector database is required, but literal matching can miss a concept expressed through different terminology—for example, a question about a “database” when the useful manifest names sqflite.
The hard part was not making the model sound certain
The difficult part was getting a compact local model to produce bounded structured output without inventing references or exhausting the output budget.
I used structured response contracts, bounded output settings, think: false, and application-side validation. But these controls solve different problems:
- Output settings constrain generation; they do not guarantee correctness or determinism.
- Schema checks enforce the expected response shape.
- The request-level allowlist rejects references to evidence not supplied for that question.
- Human inspection is still needed to assess whether an excerpt supports a conclusion.
A valid citation is provenance, not semantic proof. SHA-256 does not make an interpretation true, and rejecting an unknown ID does not eliminate all hallucinations.
Repository text is also untrusted input. Prompt delimiters and instructions help distinguish evidence from commands, but they do not make prompt injection impossible. The model’s lack of execution tools is an important separate boundary.
## How I checked the release
My recorded local release checks were:
| Check | Recorded result |
| --- | --- |
|
flutter analyze| Exit 0; no issues reported | | Test suite | 146 passing tests, with no reported failures or skips | |flutter build windows --release| Exit 0; Windows release runner built | | Live local-model checks | Structured autopsy generation and Q&A through local Ollama | | Invalid-reference probe | UnsuppliedE999rejected in the adversarial check | | Export checks | Automated checks for formatting, path sanitisation, and credential masking | These are my local results, not an independent security audit or a guarantee of correct answers on arbitrary repositories. The three manifest claims above are a small, directly inspectable example—not a general model-accuracy score. ## Why open-weight AI matters here Gemma is not an optional chatbot attached to a conventional report. Its interpretation of the selected evidence is part of the central analysis workflow. Running it through local Ollama matters because: -
Repository excerpts can stay with a local inference runtime. The analysis path uses
127.0.0.1:11434instead of requiring a hosted model API. - There is no hosted per-token inference bill. Hardware, storage, electricity, and setup still have costs.
- The runtime is under the developer’s control. Compatible models and settings can be changed, although alternatives need their own quality and compatibility checks. The trade-off is visible: CPU inference is not instant. The recorded self-analysis took 136.6 seconds; the separate fixture dependency question took about 36.1 seconds. Those are different requests, not a controlled comparison or a universal performance benchmark. The development machine was a Windows 11 laptop with 16 GB RAM, using CPU inference. I have not tested analysis with the internet connection disabled. The application’s loopback-only design should not be presented as a completed offline test or proof about every process on the machine. ## Limits and next steps This is an early Windows release, not a replacement for a maintainer’s investigation.
- Untracked, excluded, oversized, or otherwise uninspected files may change the interpretation.
- Filename-based secret exclusions and export masking are best-effort protections, not comprehensive credential detection.
- Lexical retrieval may omit the most useful evidence.
- A compact model can produce an incorrect inference even with a real citation.
- Commit subjects record what was written in version control; they do not establish the exact change or its motivation without further evidence. My next priorities are better evidence selection, stronger request-isolation regression coverage, and syntax-aware indexing. Historical diff analysis and other desktop platforms are future work, not current release capabilities. ## Code and Windows release
-
Source:
RepoSéance 👻
Summon the ghost in the machine.
A local-first, privacy-respecting AI software archaeology workbench that reconstructs the purpose, architecture, and development history of unfamiliar or abandoned Git repositories — powered by Google's Gemma model running 100% locally on your machine with verifiable, source-grounded evidence citations.Built for DEV Hacktoberfest 2026 Week 4: "Ghost in the Machine".
⚡ Highlights & Key Features
- 🔒 100% Local & Offline: Operates entirely on your machine via direct loopback HTTP (
127.0.0.1:11434) to local Ollama. Zero outbound telemetry, zero cloud API keys, zero cloud egress. - 🛡️ Zero-Execution Sandbox: Inspects repository text and Git metadata deterministically. Never executes arbitrary build scripts, test runners, npm scripts, or hooks found inside untrusted target repositories.
- 📜 Evidence-Grounded Citations: Every claim in the generated autopsy and Q&A references concrete evidence items (e.g.
[E001]). Claims cannot hallucinate uninspected files or confabulate non-existent commits. - 🧠…
- 🔒 100% Local & Offline: Operates entirely on your machine via direct loopback HTTP (
- Windows package: RepoSéance v1.0.0
-
Initial project commit:
be72cfa -
Implementation freeze:
042ccfa -
Published release tag target:
b52e867 -
Application license: MIT
The later release commit adds the README and MIT license; it does not change the application implementation frozen at
042ccfa. Ollama and the local model remain external prerequisites; see the release instructions before running the Windows package. ## Prize category I am entering Best Use of Gemma. Gemma performs the local interpretation behind the report and Q&A, rather than serving as an incidental feature. --- I do not expect an AI model to recover every lost decision. I want it to help a developer examine what remains, show the evidence behind a useful answer, and stop when that evidence runs out. The ghost is not the developer. It is the context they left behind.
Top comments (0)