# 👻 Phantom-Shell — The Haunted Terminal
👻 Phantom-Shell — The Haunted Terminal Your terminal remembers what went wrong. Your AI investigates why. What if your terminal could remember its failures, investigate the evidence, and help you understand problems t
👻 Phantom-Shell — The Haunted Terminal
Your terminal remembers what went wrong. Your AI investigates why.
What if your terminal could remember its failures, investigate the evidence, and help you understand problems that would otherwise disappear into a sea of logs?
Phantom-Shell is an open-source, local-first AI terminal investigator designed to turn mysterious command-line failures into structured, evidence-backed investigations. Instead of treating every error as an isolated event, it captures execution history, connects related incidents, investigates problems with local AI, and aims to preserve verified knowledge for future sessions.
The goal is simple: make debugging less like guessing and more like detective work.
What I Built
🕵️ A terminal that investigates its own failures
Developers spend a surprising amount of time reconstructing what happened before a failure. Which command caused it? Was the same issue encountered before? Does the configuration actually support the proposed explanation?
Phantom-Shell explores a different approach: turn terminal activity into a persistent investigation trail.
Here's what the project includes:
- Terminal event capture: Records command execution information, output, exit codes, and working-directory context.
- Persistent local storage: Uses SQLite to preserve events and investigation state.
- Local AI investigation: Integrates with Ollama to investigate incidents using locally hosted language models.
- Evidence validation: Includes components intended to distinguish supported conclusions from assumptions.
- Read-only investigation tools: Allows the investigator to inspect project information through constrained tools.
- Human-controlled actions: Provides an approval workflow for proposed actions rather than giving AI unrestricted control.
- Investigation dashboard: Offers a local web interface for reviewing investigation activity.
- Incident memory: Implements memory management intended to preserve and reuse verified knowledge.
👻 How it fits the theme
The ghost in the machine is the history of a failure that developers can no longer remember.
A build breaks. A test fails. A configuration behaves unexpectedly. The clues are scattered across commands, output, and project files.
Phantom-Shell gives those clues a persistent place to live and uses AI to help investigate them.
Rather than presenting AI as an infallible oracle, the project explores how local models, structured evidence, controlled tools, and persistent memory can work together to make AI-assisted debugging more transparent.
Demo
Dashboard: http://127.0.0.1:8765/ when running locally.
The dashboard is intended for local access; it is not a publicly hosted deployment.
The basic capture workflow has been demonstrated:
phantomshell run --no-model -- bash -lc 'echo "PhantomShell capture works"'
phantomshell report
The first command executes a command through Phantom-Shell, and the second displays the captured event and output.
For the current implementation, interactive shell capture and some end-to-end investigation scenarios are still being verified.
Phantom-Shell in Action 👻
The Phantom-Shell dashboard brings terminal activity into a single investigation timeline. Each captured command is displayed alongside its exit code and output, making successful executions and failures easier to trace.
In this example, the timeline shows a successful build alongside a configuration-related failure caused by a missing src/app.py entry point. Rather than losing the error in terminal scrollback, Phantom-Shell preserves it as part of the project's execution history.
The dashboard runs locally, with the displayed status indicating that inference uses Ollama through a loopback connection rather than external model API calls.
The idea: preserve the evidence, reconstruct the failure, and make debugging more systematic.
Code
GitHub repository: NiranjanRSoorej06/Phantom-Shell
The project is organized into separate components for terminal capture, event persistence, investigation, evidence handling, memory, policy enforcement, and the local dashboard.
The modular structure is intended to make it easier for contributors to improve individual capabilities without having to rebuild the entire application.
How I Built It
Phantom-Shell is implemented in Python, with local persistence, model integration, and a lightweight web dashboard.
Core technologies:
- Python: CLI, event processing, orchestration, and investigation logic.
- Ollama: Local inference through a locally hosted language model.
- SQLite: Persistent storage for terminal events and investigation state.
- FastAPI: Dashboard and API layer.
- Uvicorn: Local web server.
- Pytest: Automated testing.
The architecture
The application separates its responsibilities into several layers:
- Capture: Collect command execution information and output.
- Storage: Persist structured events and investigation data in SQLite.
- Episode management: Associate related events with recurring incidents.
- Investigation: Use available evidence and local AI to analyze an incident.
- Evidence and policy: Apply checks and restrictions to investigation outputs and proposed actions.
- Memory: Manage incident knowledge and its verification status.
- Dashboard: Provide a local interface for reviewing investigation activity and proposed actions.
One important design decision was to separate AI reasoning from action execution. Generating a plausible fix is not the same as proving that it is correct, and proposing an action should not automatically authorize it.
Testing and current status
The existing automated test suite passes 25 tests in 0.82 seconds. Basic one-shot command capture and event reporting have also been demonstrated.
However, passing unit tests is not the same as proving every end-to-end workflow. Interactive shell capture, cross-session memory promotion, network-isolated operation, clean-clone setup, and live-model investigation quality remain areas for further verification.
Why Does Open Innovation Matter?
An AI terminal investigator operates close to a developer's source code, command history, configuration, and debugging workflow. That makes transparency and control especially important.
Open innovation makes it possible to inspect the implementation, experiment with different models, improve the investigation pipeline, and contribute tools without depending on a single proprietary provider.
Using Ollama also allows the application to work with locally hosted models rather than requiring every investigation to be sent to a remote AI API. Actual offline operation still depends on the model and its dependencies being available locally, and is a scenario that needs dedicated verification.
An open-source implementation also makes the safety boundaries inspectable. Developers can review how events are stored, how tools are constrained, how proposed actions are handled, and how evidence is used.
I want Phantom-Shell to be something developers can question, modify, test, and improve — not a black box they have to trust.
My Agent Session
Phantom-Shell itself is the project built for this challenge. Its development involved working through implementation details, testing capture behavior, examining failures, and identifying remaining integration gaps.
<environment_context>
<cwd>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell</cwd>
<shell>bash</shell>
<current_date>2026-10-30</current_date>
<timezone>Asia/Kolkata</timezone>
<filesystem><workspace_roots><root>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell</root></workspace_roots><permission_profile type="managed"><file_system type="restricted"><entry access="read"><special>:root</special></entry><entry access="write"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell</path></entry><entry access="write"><special>:slash_tmp</special></entry><entry access="write"><special>:tmpdir</special></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.git</path></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.agents</path></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.codex</path></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.aws</path></entry></file_system></permission_profile></filesystem>
</environment_context>
implement the plan.md
I’ll read plan.md and the repository guidance first, then implement its steps in the workspace.
The plan is a large staged build, and it explicitly requires acceptance checks and a PROGRESS.md entry after each task. I’m checking the current repo state and environment now so I can start at T0 and follow the plan’s gates in order.
The repo currently contains only plan.md. Python, Git, ripgrep, and Bash meet the stated version checks; the machine reports 9.1 GiB available RAM and no nvidia-smi. Ollama is installed, but its daemon is unavailable in the sandbox, so the required local Gemma probe is the T0 gate. I’m requesting permission to start Ollama and check whether the model is available; implementation beyond T0 depends on that gate.
The existing Ollama daemon is running outside the sandbox, and the Gemma 4 E4B download is progressing (about 93% at the last update). The plan’s local-model gate looks achievable; once the structured-output probe works, I’ll move into the first implementation tasks.
Gemma 4 E4B passed the local schema probe with {"ok": true} in about 20.5 seconds, including initial model load. I’m recording T0 and scaffolding the new Python project; then I’ll build the vertical slice task by task, keeping the implementation and evidence in PROGRESS.md. I’m also applying the repository’s community-wisdom workflow for non-trivial builds.
The T0 project files are in place, but the workspace marks .git read-only, so the plan’s required commit could not be created. I’ll record that limitation and continue with the source changes and acceptance commands; I can’t change Git history from this workspace.
The ingest and marker unit checks pass, and the one-command fallback emits the expected event schema for both false and echo hi. The interactive PTY path is not yet verified: it stalls under the available pseudo-terminal wrapper, and the default database location is outside the writable workspace. I’m recording those limits and continuing with the deterministic episode, investigation, and local dashboard pieces.
The deterministic episode tests pass. I’ve added the loopback dashboard and its token/Origin checks, but its TestClient acceptance check is hanging in this environment, so I’m not treating G1 as passed. Next I’m implementing the model schema contract, quote verifier, and backend-controlled tool policy so the main investigation path exists even while capture and dashboard integration need more work.
The model client is implemented with a strict loopback URL check, JSON schemas, one retry, and run logging. The sandbox blocks its HTTP request even though the earlier escalated curl probe worked, so I’m requesting approval to run the T5 acceptance call against the local Ollama daemon.
{
"cell_id": "59",
"yield_time_ms": 30000,
"max_tokens": 1000
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"1beec5\",\"wall_time_seconds\":1.00106691,\"session_id\":15512,\"original_token_count\":0,\"output\":\"\"}"
}
]
The core investigation path now includes per-session episode grouping, model-generated read-only check proposals, per-action approval endpoints, a deterministic evidence verifier, and watched-file memory. The earlier dashboard test stall came from this environment’s Starlette TestClient; I replaced it with HTTPX’s ASGI transport, and all 16 focused unit/security tests now pass. I’m checking whether the interactive capture path can be exercised with a purpose-built PTY harness.
{
"cell_id": "105",
"yield_time_ms": 30000,
"max_tokens": 1000
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"e7438b\",\"wall_time_seconds\":1.001793075,\"session_id\":16429,\"original_token_count\":0,\"output\":\"\"}"
}
]
{
"cell_id": "109",
"yield_time_ms": 30000,
"max_tokens": 300
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"c9803a\",\"wall_time_seconds\":1.001678649,\"session_id\":48271,\"original_token_count\":0,\"output\":\"\"}"
}
]
The PTY harness confirms that the real wrapped Bash captured echo hi with exit 0 and false with exit 1, hid the OSC markers, propagated Ctrl-C as exit 130, and forwarded a 40×100 terminal resize to stty size. I’m turning that manual check into a repeatable smoke script, then I’ll finish the docs and re-run the full project checks.
The repeatable PTY smoke now passes, including Ctrl-C and resize; the focused suite passes 20 tests, and ruff check is clean. The local Gemma call also produced a valid, tool-specific inspect_project_tree proposal from the actual captured fixture failure. I’m reconciling the claims ledger and platform/license documentation next; the full two-session offline demo remains unverified.
The stricter tool-specific schema now yields a valid inspect_project_tree proposal (depth: 2) for the captured fixture failure; the last logged Plan run took 33.3 seconds and passed schema validation. To verify T8’s actual Conclude path, I’m requesting permission to run that proposed read-only tree check against the fixture and pass its evidence to local Gemma.
{
"cell_id": "145",
"yield_time_ms": 30000,
"max_tokens": 1000
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"8ce5ec\",\"wall_time_seconds\":1.000435465,\"session_id\":78453,\"original_token_count\":0,\"output\":\"\"}"
}
]
{
"cell_id": "151",
"yield_time_ms": 30000,
"max_tokens": 2000
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.2 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"content\":[{\"type\":\"text\",\"text\":\"{\\\"Ok\\\":{\\\"id\\\":82,\\\"title\\\":\\\"Hacktoberfest Open-Source AI Challenge: Week 4\\\",\\\"slug\\\":\\\"hacktoberfest-week4-2026-10-26\\\",\\\"description\\\":\\\"The Hacktoberfest Open-Source AI Challenge: Week 4 runs October 26 to October 31. Build something spooky, or something that honors the past in the spirit of Día de los Muertos, with open-weight models or open-source AI. $2,850 in prizes across 21 winners.\\\\r\\\\n\\\\r\\\\nThis is the final challenge of our Hacktoberfest series. This year's Hacktoberfest is all about building brand-new projects with open-source AI and open-weight models, and the theme is intentionally broad, so interpret it however you'd like!\\\",\\\"details\\\":null,\\\"full_details\\\":\\\"The Hacktoberfest Open-Source AI Challenge: Week 4 runs October 26 to October 31. Build something spooky, or something that honors the past in the spirit of Día de los Muertos, with open-weight models or open-source AI. $2,850 in prizes across 21 winners.\\\\r\\\\n\\\\r\\\\nThis is the final challenge of our Hacktoberfest series. This year's Hacktoberfest is all about building brand-new projects with open-source AI and open-weight models, and the theme is intentionally broad, so interpret it however you'd like!\\\\r\\\\n\\\\r\\\\nOur Theme: Ghost in the Machine\\\\r\\\\n\\\\r\\\\nBuild something spooky, or something that honors the past in the spirit of Día de los Muertos, with open-weight models or open-source AI.\\\\r\\\\n\\\\r\\\\nThis week brings us Halloween on October 31 and Día de los Muertos on November 1 and 2, a stretch of the calendar when the line between past and present feels a little thinner. Whether that brings to mind things that go bump in the night, ofrendas glowing with marigolds and candlelight, or the memories and stories we carry with us, we want to see what it inspires you to build.\\\\r\\\\n\\\\r\\\\nThat can mean running an open-weight model, building on an open-source agent harness or framework, running inference locally, or all three. Whatever you pick, the open pieces should be what makes your project work.\\\\r\\\\n\\\\r\\\\nA few ideas to get you going:\\\\r\\\\n\\\\r\\\\n A haunted terminal that \\\\\\\"possesses\\\\\\\" your shell and whispers back eerie commentary on the commands you run\\\\r\\\\n A digital ofrenda builder that helps you write a remembrance for a loved one and gather their favorite foods, songs, and stories\\\\r\\\\n An offline séance chatbot that channels the spirit of a long-dead programming language\\\\r\\\\n A local oral history tool that records and transcribes family stories so they're never lost\\\\r\\\\n A ghost story generator that weaves your smart home's sensor logs into a creepy tale of what happened while you were asleep\\\\r\\\\n A project that brings an abandoned open-source tool or a forgotten corner of internet history back to life\\\\r\\\\n\\\\r\\\\nIn your post, tell us why open innovation matters for what you built. Does running your own model mean your project works with the lights (and the internet) off? Keep your family's photos and stories private and on your own machine? Make sure what you build isn't locked inside a service that might disappear someday? Tell us where your open-based approach worked better than a closed one.\\\\r\\\\n\\\\r\\\\nPrize Categories\\\\r\\\\n\\\\r\\\\nAlongside our overall winner, we have 20 prize categories for projects that use a specific partner's technology. You don't need to use any of these to win the overall prize. Full descriptions are on the HF26 DEV Challenge Hub (https://dev.to/challenges/hf26).\\\\r\\\\n\\\\r\\\\nFeatured categories: Best Use of Render, Best Use of TabPFN, Best Use of Tinker, Best Use of Arduino, Best Use of DigitalOcean, Best Use of Gemma\\\\r\\\\n\\\\r\\\\nPartner categories: Best Use of Auth0 for AI Agents, Best Use of Backboard, Best Use of Browserbase, Best Use of ElevenLabs, Best Use of Entire, Best Use of GitHub Copilot, Best Use of Mastra, Best Use of MongoDB Atlas, Best Use of Sentry Agent Tracing, Best Use of SerpApi, Best Use of Temporal, Best Use of Tiger Data, Best Use of Ultramarine (Paper Instruments), Best Use of a .tech Domain\\\\r\\\\n\\\\r\\\\nOne project can enter every category it genuinely uses, but you can only win once per challenge. Several partners are giving participants free credits and promo codes at hacktoberfest.com/my.\\\\r\\\\n\\\\r\\\\nJudging Criteria\\\\r\\\\n\\\\r\\\\nThis is DEV, so your write-up matters most. Submissions will be evaluated for:\\\\r\\\\n\\\\r\\\\n Writing Quality (weighted most heavily)\\\\r\\\\n Relevance to the Prompt and Theme\\\\r\\\\n Creativity\\\\r\\\\n Technical Execution\\\\r\\\\n Use of Partner Technology (optional, for prize category entries)\\\\r\\\\n\\\\r\\\\nShow your work: saving your agent session with DevRelay and embedding it in your post is optional, but it helps the judges understand your process.\\\\r\\\\n\\\\r\\\\nPrizes 🏆\\\\r\\\\n\\\\r\\\\nOverall winner (1) will receive:\\\\r\\\\n\\\\r\\\\n $250 USD cash prize\\\\r\\\\n DEV++ Membership\\\\r\\\\n Exclusive DEV Badge\\\\r\\\\n\\\\r\\\\nFeatured category winners (6) will each receive:\\\\r\\\\n\\\\r\\\\n $200 USD cash prize\\\\r\\\\n Exclusive DEV Badge\\\\r\\\\n\\\\r\\\\nPartner category winners (14) will each receive:\\\\r\\\\n\\\\r\\\\n $100 USD cash prize\\\\r\\\\n Exclusive DEV Badge\\\\r\\\\n\\\\r\\\\nAll participants with a valid submission will receive a completion badge on their DEV profile.\\\\r\\\\n\\\\r\\\\nHow To Participate\\\\r\\\\n\\\\r\\\\nPublish a post on DEV using the submission template on the challenge page and be sure to include the required challenge tag: #hf26challenge. Tell us what you built and how you interpreted the theme, show us a demo, and explain why open innovation matters for what you built.\\\\r\\\\n\\\\r\\\\nIf your app requires logging in, please provide testing credentials in your submission and/or instructions on how to best test your application for judges.\\\\r\\\\n\\\\r\\\\nImportant Dates\\\\r\\\\n\\\\r\\\\n October 26: Hacktoberfest Open-Source AI Challenge: Week 4 begins!\\\\r\\\\n October 31: Submissions due at 11:59 PM PDT\\\\r\\\\n Week of November 2: Winners Announced\\\",\\\"type_of\\\":\\\"challenge\\\",\\\"starts_at\\\":\\\"2026-10-26T19:00:00.000Z\\\",\\\"ends_at\\\":\\\"2026-10-31T06:59:00.000Z\\\",\\\"published\\\":true,\\\"cover_image\\\":\\\"https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/events/cover_image/82/e4131c99-f797-42be-95ef-b55e1f04255f.png\\\",\\\"location_url\\\":null}}\"}],\"isError\":false}"
}
]
I found a deadline mismatch while checking the live challenge details: the DEV event feed’s ends_at timestamp falls on Oct 30 at 11:59 PM PDT, while plan.md says Oct 31 at 11:59 PM PDT. I’m verifying the published challenge page before recording any submission deadline in the draft.
{
"cell_id": "174",
"yield_time_ms": 10000,
"max_tokens": 500
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"a31197\",\"wall_time_seconds\":1.001336572,\"session_id\":47763,\"original_token_count\":0,\"output\":\"\"}"
}
]
The T4 gate is now exercised end to end: an interactive PTY session writes events to SQLite, the authenticated dashboard API returns those events, a live server bound on [REDACTED]:18765, the static page returned HTTP 200, and the unauthenticated API returned 401. I’m checking whether this environment permits the plan’s isolated-network test; I’ll record a failure as such rather than claim offline operation.
{
"cell_id": "184",
"yield_time_ms": 10000,
"max_tokens": 800
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"320a8a\",\"wall_time_seconds\":1.000869354,\"session_id\":7797,\"original_token_count\":34,\"output\":\"sudo: a terminal is required to read the password; either use the -S option to read from standard input or configure an askpass helper\\n\"}"
}
]
The offline check is blocked by container privileges: unshare -rn true succeeds, but bringing loopback up fails with “Operation not permitted,” and the full sudo recipe cannot prompt for a password. I’ve recorded that as unverified. The challenge deadline discrepancy is resolved in favor of the official Week 4 page (Oct 31, 11:59 PM PDT); the API feed’s timestamp is one day early. I’m running the project’s local selftest now.
{
"cell_id": "199",
"yield_time_ms": 10000,
"max_tokens": 400
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"4c3af7\",\"wall_time_seconds\":1.00086952,\"session_id\":60109,\"original_token_count\":0,\"output\":\"\"}"
}
]
The project selftest now passes against the pre-pulled local Gemma model. One required plan step remains outside the workspace’s granted permissions: .git is explicitly read-only, so the root project cannot be committed. I’m requesting elevated permission to create a single reviewable build commit; the earlier sandboxed git add failed before staging anything.
{
"cell_id": "202",
"yield_time_ms": 10000,
"max_tokens": 1000
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"69f814\",\"wall_time_seconds\":0.00001102,\"exit_code\":0,\"original_token_count\":635,\"output\":\"warning: adding embedded git repository: demo/fixture_project\\nhint: You've added another git repository inside your current repository.\\nhint: Clones of the outer repository will not contain the contents of\\nhint: the embedded repository and will not know how to obtain it.\\nhint: If you meant to add a submodule, use:\\nhint:\\nhint: \\tgit submodule add <url> demo/fixture_project\\nhint:\\nhint: If you added this path by mistake, you can remove it from the\\nhint: index with:\\nhint:\\nhint: \\tgit rm --cached demo/fixture_project\\nhint:\\nhint: See \\\"git help submodule\\\" for more information.\\nhint: Disable this message with \\\"git config set advice.addEmbeddedRepo false\\\"\\n[main (root-commit) 7f27c8e] T0-T15: implement PhantomShell build plan\\n 41 files changed, 3121 insertions(+)\\n create mode 100644 .gitignore\\n create mode 100644 LICENSE\\n create mode 100644 PROGRESS.md\\n create mode 100644 README.md\\n create mode 160000 demo/fixture_project\\n create mode 100644 demo/script_session1.md\\n create mode 100644 demo/script_session2.md\\n create mode 100644 docs/architecture.md\\n create mode 100644 docs/claims.md\\n create mode 100644 docs/dev-post-draft.md\\n create mode 100644 docs/evaluation.md\\n create mode 100644 docs/threat-model.md\\n create mode 100644 phantomshell/__init__.py\\n create mode 100644 phantomshell/brain.py\\n create mode 100644 phantomshell/capture/__init__.py\\n create mode 100644 phantomshell/capture/hooks.sh\\n create mode 100644 phantomshell/capture/markers.py\\n create mode 100644 phantomshell/capture/pty_session.py\\n create mode 100644 phantomshell/cli.py\\n create mode 100644 phantomshell/episodes.py\\n create mode 100644 phantomshell/ingest.py\\n create mode 100644 phantomshell/investigator.py\\n create mode 100644 phantomshell/memory.py\\n create mode 100644 phantomshell/policy.py\\n create mode 100644 phantomshell/server.py\\n create mode 100644 phantomshell/static/index.html\\n create mode 100644 phantomshell/store.py\\n create mode 100644 phantomshell/tools.py\\n create mode 100644 phantomshell/verify.py\\n create mode 100644 plan.md\\n create mode 100644 pyproject.toml\\n create mode 100644 scripts/test_pty_smoke.py\\n create mode 100644 tests/security/test_brain.py\\n create mode 100644 tests/security/test_dashboard.py\\n create mode 100644 tests/security/test_tools.py\\n create mode 100644 tests/unit/test_capture.py\\n create mode 100644 tests/unit/test_episodes.py\\n create mode 100644 tests/unit/test_ingest.py\\n create mode 100644 tests/unit/test_investigator.py\\n create mode 100644 tests/unit/test_memory.py\\n create mode 100644 tests/unit/test_verifier.py\\n\"}"
}
]
The elevated commit succeeded, but Git treated the fixture’s test-generated .git directory as an embedded repository and committed only a submodule pointer for demo/fixture_project. I need to remove that generated fixture metadata, stage the fixture files normally, and create a correction commit so clones actually contain the demo.
{
"cell_id": "204",
"yield_time_ms": 10000,
"max_tokens": 500
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"2c9825\",\"wall_time_seconds\":0.000008647,\"exit_code\":0,\"original_token_count\":7,\"output\":\"rm 'demo/fixture_project'\\n\"}"
}
]
The root index now stages the fixture’s actual files instead of a gitlink. The correction is the only pending change; I’m creating a follow-up commit so the new root repository is cloneable with the demo project included.
{
"cell_id": "207",
"yield_time_ms": 10000,
"max_tokens": 700
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"b4ba93\",\"wall_time_seconds\":0.00001076,\"exit_code\":0,\"original_token_count\":101,\"output\":\"[main d14eaeb] Fix: track demo fixture files directly\\n 6 files changed, 52 insertions(+), 1 deletion(-)\\n delete mode 160000 demo/fixture_project\\n create mode 100644 demo/fixture_project/README.md\\n create mode 100644 demo/fixture_project/build.py\\n create mode 100644 demo/fixture_project/config.toml\\n create mode 100755 demo/fixture_project/reset.sh\\n create mode 100644 demo/fixture_project/src/main.py\\n\"}"
}
]
The final verification now reports 24 passing unit/security tests, a passing PTY/dashboard smoke, and clean Ruff checks. I’ve updated the progress record and claim draft with those results; I’m committing this last verification update.
{
"cell_id": "216",
"yield_time_ms": 10000,
"max_tokens": 700
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"decfaf\",\"wall_time_seconds\":0.000011434,\"exit_code\":0,\"original_token_count\":28,\"output\":\"[main b820e58] T11-T13: record verified acceptance results\\n 5 files changed, 28 insertions(+), 7 deletions(-)\\n\"}"
}
]
I’ve tightened the Plan prompt after the live Conclude correctly declined to support the cause but still missed the config read. I’m going to run the fixture’s two-session path once more to see whether Gemma now requests enough checks for memory and rename staleness.
{
"cell_id": "221",
"yield_time_ms": 30000,
"max_tokens": 1000
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"0f8d03\",\"wall_time_seconds\":1.001601777,\"session_id\":43660,\"original_token_count\":0,\"output\":\"\"}"
}
]
{
"cell_id": "227",
"yield_time_ms": 30000,
"max_tokens": 300
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"1f0b14\",\"wall_time_seconds\":1.000539524,\"session_id\":88497,\"original_token_count\":0,\"output\":\"\"}"
}
]
{
"cell_id": "231",
"yield_time_ms": 30000,
"max_tokens": 300
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"e7d0c7\",\"wall_time_seconds\":1.000849245,\"session_id\":2915,\"original_token_count\":0,\"output\":\"\"}"
}
]
{
"cell_id": "234",
"yield_time_ms": 30000,
"max_tokens": 500
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"168eda\",\"wall_time_seconds\":1.000545863,\"session_id\":17472,\"original_token_count\":0,\"output\":\"\"}"
}
]
The model now requested three relevant checks, including config.toml, and the backend captured its hash. Its first Conclude still stayed inconclusive despite those results, so I’ve made the Conclude prompt explicitly compare completed checks and cite both the config entry and available tree path when they establish a mismatch. I’m rerunning Conclude on the same evidence to see whether the verifier accepts a supported result.
{
"cell_id": "238",
"yield_time_ms": 30000,
"max_tokens": 300
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"230a8d\",\"wall_time_seconds\":1.001509831,\"session_id\":10450,\"original_token_count\":0,\"output\":\"\"}"
}
]
Gemma’s Conclude still returned “inconclusive” on the fixture evidence, so the live memory-promotion path remains unverified. I’ve adjusted the verifier to suppress any cause-like narrative in that case; I’m checking that change, refreshing the acceptance notes, and rerunning the requested checks.
The broader checks caught two integration issues from the latest change: the conclusion input was reshaped without updating a fake-model test, and the verifier’s inconclusive branch still leaves narrative text intact. I’m fixing both before rerunning the suite.
The code checks now pass: 25 unit/security tests, Ruff, and the PTY/dashboard smoke. The local Ollama selftest also passed after rerunning it with loopback access outside the sandbox. I’m doing the final repository cleanup and recording these results in the progress log.
{
"cell_id": "259",
"yield_time_ms": 1000,
"max_tokens": 2000
}
[
{
"type": "input_text",
"text": "Script completed\nWall time 0.0 seconds\nOutput:\n"
},
{
"type": "input_text",
"text": "{\"chunk_id\":\"654eb5\",\"wall_time_seconds\":0.000010663,\"exit_code\":0,\"original_token_count\":69,\"output\":\"[main 08c5d36] Fix: suppress unsupported inconclusive narratives\\n 8 files changed, 44 insertions(+), 15 deletions(-)\\n08c5d36 Fix: suppress unsupported inconclusive narratives\\nb820e58 T11-T13: record verified acceptance results\\nd14eaeb Fix: track demo fixture files directly\\n\"}"
}
]
Implemented the PhantomShell plan’s core capture, investigation, evidence verification, approval, memory, and dashboard workflows. The work is committed through 08c5d36 (Fix: suppress unsupported inconclusive narratives), and the repository is clean.
Checks: 25 unit/security tests passed; Ruff passed; the PTY/dashboard smoke passed; and the local Ollama selftest passed.
Remaining limits: The live Gemma investigation stayed inconclusive, so the full two-session memory flow remains unverified. Network-isolated execution and a clean-clone setup also remain unverified. The DEV draft is saved locally but is not ready to publish; it still needs the repository URL and demo media.
🌐 Community Wisdom
- Root on Local: Threat-Modeling Local-First AI Coding Agents by @tamizuddin: informed the focus on backend tool permissions and explicit limits around offline claims.
- Building a Privacy-First Local AI Assistant by @tamizuddin: informed the local-inference framing; PhantomShell’s draft avoids claiming full offline operation without an isolated-network run.
- Read Full Discussion on DEV — the fetched articles had no comments.
The Hacktoberfest Week 4 challenge deadline is Oct 31, 2026 at 11:59 PM PDT. The current draft still needs its demo assets before submission.
<environment_context>
<current_date>2026-10-31</current_date>
<timezone>Asia/Kolkata</timezone>
<filesystem><workspace_roots><root>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell</root></workspace_roots><permission_profile type="managed"><file_system type="restricted"><entry access="read"><special>:root</special></entry><entry access="write"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell</path></entry><entry access="write"><special>:slash_tmp</special></entry><entry access="write"><special>:tmpdir</special></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.git</path></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.agents</path></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.codex</path></entry><entry access="read"><path>[PROJECT_PATH]/E8BA8138BA810472/My Folders/Hacktoberfest/Phantom-Shell/.aws</path></entry></file_system></permission_profile></filesystem>
</environment_context>
how to run
I’ll check the project README and CLI entry points so the run instructions match this checkout.
From the repository root, install PhantomShell in a virtual environment and pull the model:
python -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
ollama pull gemma4:e4b
Then use two terminals, with the virtual environment activated in each:
# Terminal 1: start the dashboard
phantomshell serve
# Terminal 2: start an instrumented Bash
phantomshell run
The dashboard prints a local URL with a launch token. In the instrumented Bash, run commands as usual; captured events are saved in SQLite.
To capture just one command instead:
phantomshell run -- python build.py
To capture without model inference, add --no-model before --:
phantomshell run --no-model -- python build.py
For the demo fixture, go to demo/fixture_project, run ./reset.sh, then python build.py. The project’s README has more details.
is entire app implemented ?
The core app is implemented, but the full plan isn’t complete or fully verified.
The terminal capture, SQLite storage, local Ollama calls, read-only investigation tools, evidence checks, approval dashboard, and memory logic are in place. The checks run during implementation passed.
Some planned end-to-end work remains unverified: the live model’s conclusion stayed inconclusive, so memory promotion across two sessions wasn’t demonstrated. Network-isolated operation and clean-clone setup also weren’t verified.
The Spirit of It
There is something unsettling about a failure that appears to come out of nowhere.
You rerun the command. It fails again. You inspect the logs, change a configuration, try another command, and eventually discover that the answer was hiding in something you had already seen.
The machine has been telling you what happened all along. The problem is that the evidence is fragmented, the context disappears, and yesterday's solution becomes tomorrow's mystery.
That is the ghost I wanted to explore.
Phantom-Shell is an attempt to give those forgotten failures a memory — and to make the process of understanding them more systematic.
Not an AI that magically knows every answer, but one that can help gather clues, explain its reasoning, acknowledge uncertainty, and leave the final decision with the developer.
The terminal remembers. Now it is time to investigate.
Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.