ContextKeeper:不再遺失開發上下文
Never Lose Your Context Again.
ContextKeeper 2.0 是一款以本機為先的專案復原工具,透過程式碼庫證據重建中斷的編碼工作階段。復原引擎會將判斷分類為事實、推論或未知,並可選用本機託管的 Ollama 模型輔助解讀;AI 不負責判定程式碼庫事實。
🚀 Hacktoberfest 2026 — Week 4: Building ContextKeeper | Evidence-Driven AI, Local-First Recovery & Engineering Beyond the Demo
This Hacktoberfest, I've been building *ContextKeeper *, a local-first developer productivity tool designed to help developers reconstruct interrupted coding sessions from repository evidence.
The central problem is simple, but technically interesting:
What happens when your IDE crashes, your terminal closes, your AI coding-agent session disappears, or you return to a project after losing the context of what you were working on?
You might have uncommitted changes, untracked files, partially implemented functions, stale test logs, incomplete documentation, and no reliable record of the original task.
Git can show committed history and working-tree changes. Documentation can explain intended architecture. Test logs can describe earlier execution results. A local language model can interpret code and suggest possibilities.
But none of those sources, individually, necessarily tells you exactly what happened during an interrupted session.
I wanted to approach this problem from a different engineering perspective:
Instead of asking an AI to guess what happened, reconstruct the observable state first, preserve evidence, distinguish facts from assumptions, and make uncertainty explicit.
That idea became ContextKeeper.
🧠 1. The Problem ContextKeeper Is Trying to Solve
Modern development involves multiple tools, branches, terminals, coding agents, partial implementations, and context switches.
When a session is interrupted, a developer may need to reconstruct:
- Which branch and commit they were working on.
- Whether the working tree contains staged, unstaged, untracked, renamed, deleted, or conflicted files.
- Which parts of the implementation appear to have changed recently.
- Which source files, configuration files, and documents are relevant.
- Whether a test log represents the current code or an earlier version.
- Which conclusions are directly supported by repository artifacts.
- Which likely explanations are only inferences.
- Which parts of the original objective cannot be determined without clarification.
Traditional recovery based only on commit history misses uncommitted work. Persistent AI memory can retain useful context, but it may not reflect the actual current filesystem state. Automatically executing the project's tests or scripts may also be inappropriate when inspecting an unfamiliar or sensitive repository.
ContextKeeper is designed to address this gap with a deterministic, passive recovery pipeline and optional local AI interpretation.
The guiding principle is:
Reconstruct what the evidence supports. Explain what can reasonably be inferred. Preserve what remains unknown.
🎯 2. What Is ContextKeeper 2.0?
ContextKeeper is a local-first project recovery application with three main ways to interact with its capabilities:
- A command-line interface for developers who prefer scripts, terminals, and structured output.
- An interactive local web dashboard for exploring claims, evidence, changes, and recommendations.
- An optional AI-assisted interpretation mode that uses a locally hosted Ollama model.
The recovery engine is designed to operate independently of AI. Local AI can provide a qualitative narrative, but it is not the authority for determining repository facts.
Core capabilities
Repository inspection
- Git working-tree status.
- Staged and unstaged diffs.
- Untracked files, deletions, renames, and conflicts.
- Recent commit history.
- Selected source files, package manifests, and project documentation.
- Explicitly supplied historical test logs.
Evidence and provenance
- Structured evidence records.
- Relative file paths and line locators.
- SHA-256 content digests.
- Stable, content-derived evidence identifiers.
- Evidence freshness and redaction metadata.
- Cross-references between claims and evidence records.
Deterministic recovery
-
FACT,INFERENCE, andUNKNOWNclassification. - Defensive validation of evidence identifiers.
- Explicit limitations and knowledge gaps.
- State-dependent, conservative recovery recommendations.
Developer experience
- Markdown recovery dossiers.
- Machine-readable JSON output.
- Interactive dashboard.
- Claim filters and search.
- Evidence inspector.
- Git diff viewer.
- Prioritized next steps.
- Markdown and JSON export.
- Optional light and dark themes.
Optional local AI
- Ollama integration.
- Loopback-only endpoint policy.
- Bounded, redacted evidence input.
- Structured model responses.
- Evidence-reference validation.
- Deterministic fallback when inference is unavailable, malformed, or too slow.
The intention is to make session recovery useful without requiring a cloud AI account or mandatory remote processing.
🏗️ 3. Technology Stack and Engineering Choices
ContextKeeper uses a deliberately lightweight stack.
| Area | Technology | Responsibility |
|---|---|---|
| Language | TypeScript | Typed application logic and domain contracts |
| Runtime | Node.js | Application execution and native APIs |
| Module system | ECMAScript modules | Modular source code and compiled distribution |
| Filesystem | node:fs/promises |
Bounded read-only repository inspection |
| Git execution | node:child_process.execFile |
Controlled subprocess calls without shell interpolation |
| HTTP server | node:http |
Local dashboard and API |
| Cryptography | node:crypto |
SHA-256 content digest generation |
| CLI parsing | node:util.parseArgs |
Command and option parsing |
| Local AI | Ollama HTTP API | Optional locally hosted inference |
| Tests | Node.js native test runner | Unit, integration, security, and evaluation tests |
| Type checking | TypeScript compiler | Static type validation |
| Distribution | npm executable package | CLI packaging and installation |
One architectural decision was to avoid production runtime dependencies wherever practical.
The reported implementation declares zero production dependencies and primarily uses Node.js standard-library APIs. TypeScript and Node.js type declarations are development dependencies.
This reduces dependency overhead and simplifies distribution, although it does not eliminate every security risk: the application still needs careful input validation, safe subprocess handling, robust HTTP controls, and dependency/build verification.
The dashboard also uses a self-contained HTML/CSS/JavaScript interface rather than depending on a remote UI service or CDN.
📐 4. Architecture Diagram 1 — System Context
This diagram shows how the developer, CLI, dashboard, security controls, inspection subsystems, recovery engine, evidence records, and optional local AI fit together.
flowchart TB
subgraph Users["Users and Interfaces"]
Dev["Developer using CLI"]
BrowserDev["Developer using Browser"]
end
subgraph Entrypoints["Entrypoints and Presentation"]
CLI["CLI Entry Point<br/>bin/contextkeeper.js → src/cli.ts"]
WebUI["Local Dashboard<br/>127.0.0.1:3333"]
DashServer["Dashboard Server<br/>dashboardServer.ts"]
DashHTML["Dashboard Client<br/>dashboardHtml.ts"]
Formatters["Markdown and JSON Formatters"]
end
subgraph Security["Security and Boundaries"]
PathGuard["Path and Symlink Guard"]
Redactor["Secret Redactor"]
GitRunner["Restricted Git Runner"]
end
subgraph Inspection["Passive Inspection"]
Inspector["Inspection Orchestrator"]
GitInspector["Git Inspector"]
FileInspector["Filesystem Inspector"]
Digest["SHA-256 and Evidence IDs"]
end
subgraph Recovery["Deterministic Recovery"]
Engine["Recovery Engine"]
Claims["Claim Generator"]
Dossier[("Recovery Dossier")]
end
subgraph LocalAI["Optional Local AI"]
Provider["Ollama Provider"]
Ollama["Local Ollama Daemon"]
end
Repo["Selected Repository<br/>Working Tree and Git Data"]
Dev --> CLI
BrowserDev --> WebUI
WebUI <--> DashServer
DashServer --> DashHTML
CLI --> Inspector
DashServer --> Inspector
CLI --> PathGuard
DashServer --> PathGuard
Inspector --> GitInspector
Inspector --> FileInspector
GitInspector --> GitRunner
GitRunner --> Repo
FileInspector --> Repo
FileInspector --> PathGuard
GitInspector --> Redactor
FileInspector --> Redactor
Redactor --> Digest
Inspector --> Engine
Engine --> Claims
Claims --> Dossier
Engine --> Dossier
Dossier --> Formatters
Formatters --> CLI
Dossier --> DashServer
Engine -.-> Provider
Provider <--> Ollama
Provider -.-> DossierArchitectural takeaway: both user interfaces rely on the same recovery foundation. The dashboard is not intended to become a separate source of truth, and optional AI does not replace deterministic evidence collection.
🔍 5. The Evidence Pipeline
The core of ContextKeeper is not the dashboard or the model. It is the process of turning repository artifacts into traceable evidence.
The pipeline starts by validating the target repository path. The Git and filesystem inspection subsystems then gather bounded observations. Sensitive content is redacted, content is normalized, and evidence identifiers are generated.
The recovery engine consumes those records and constructs a dossier.
A typical evidence record may contain:
- An evidence ID, such as
ev_git_status_.... - A source type, such as Git status, commit history, diff hunk, project document, or source file.
- A relative path or other locator.
- A content digest.
- A capture timestamp and freshness classification.
- Redaction status.
- Bounded content or an excerpt.
- Metadata about skipped files or inspection limitations.
SHA-256 helps identify the captured content. It does not prove that the content is semantically correct or that a claim derived from it is true.
Architecture Diagram 2 — Component Architecture
flowchart TD
Bin["bin/contextkeeper.js"]
subgraph Entry["Application Entrypoints"]
CLI["src/cli.ts"]
Index["src/index.ts"]
end
subgraph Presentation["Presentation"]
Server["src/server/dashboardServer.ts"]
HTML["src/server/dashboardHtml.ts"]
Markdown["markdownFormatter.ts"]
Text["textFormatter.ts"]
end
subgraph Recovery["Core Recovery"]
Engine["recoveryEngine.ts"]
Generator["claimsGenerator.ts"]
Types["src/types.ts"]
end
subgraph Inspection["Inspection"]
Inspector["src/inspector.ts"]
Git["gitInspector.ts"]
FS["fileInspector.ts"]
Runner["gitRunner.ts"]
end
subgraph Security["Security and Integrity"]
Guard["pathGuard.ts"]
Redactor["redactor.ts"]
Digest["evidence/digest.ts"]
end
AI["src/ai/localAiProvider.ts"]
Bin --> CLI
Index --> Types
Index --> Inspector
Index --> Engine
Index --> Server
CLI --> Inspector
CLI --> Engine
CLI --> Markdown
CLI --> Text
CLI --> Server
CLI --> AI
Server --> HTML
Server --> Guard
Server --> Inspector
Server --> Engine
Server --> Markdown
Server --> AI
Inspector --> Guard
Inspector --> Git
Inspector --> FS
Git --> Runner
Git --> Redactor
Git --> Digest
FS --> Guard
FS --> Redactor
FS --> Digest
Engine --> Generator
Generator --> Digest
Generator --> Types
Markdown --> Types
Text --> Types
AI --> TypesThis diagram represents the documented module boundaries. The actual implementation still has some tightly coupled responsibilities, particularly in the CLI, dashboard server, and embedded dashboard asset.
🔄 6. Architecture Diagram 3 — Deterministic CLI Recovery
The CLI workflow illustrates how ContextKeeper reconstructs project state without asking an AI model to establish the facts.
sequenceDiagram
autonumber
actor Developer
participant Bin as bin/contextkeeper.js
participant CLI as src/cli.ts
participant Guard as pathGuard.ts
participant Inspector as inspector.ts
participant Git as gitInspector.ts
participant Runner as gitRunner.ts
participant FS as fileInspector.ts
participant Redactor as redactor.ts
participant Digest as digest.ts
participant Engine as recoveryEngine.ts
participant Claims as claimsGenerator.ts
participant Formatter as markdownFormatter.ts
Developer->>Bin: contextkeeper recover . --report markdown
Bin->>CLI: runCli(argv)
CLI->>CLI: Parse and validate options
CLI->>Guard: validateTargetRoot(".")
Guard-->>CLI: Canonical repository root
CLI->>Inspector: inspectRepository(root, options)
Inspector->>Git: inspectGitRepository(root)
Git->>Runner: Read-only Git status and diffs
Runner-->>Git: Bounded Git output
Git->>Redactor: Redact sensitive content
Git->>Digest: Generate evidence digest and ID
Git-->>Inspector: Git evidence records
Inspector->>FS: inspectFilesystem(root, options)
FS->>Guard: Validate contained file paths
FS->>Redactor: Redact selected file content
FS->>Digest: Generate evidence identifiers
FS-->>Inspector: File evidence and warnings
Inspector-->>CLI: InspectionResult
CLI->>Engine: reconstructProjectState(result)
Engine->>Claims: generateClaims(result)
Claims->>Claims: Classify and validate claims
Claims-->>Engine: Recovery claims
Engine->>Engine: Generate safe recommendations
Engine-->>CLI: Recovery dossier
CLI->>Formatter: Format Markdown
Formatter-->>CLI: Recovery report
CLI-->>Developer: Write report to stdoutThe key design property is the separation between collecting observable state and interpreting it. The CLI should not need to run the inspected project's tests, execute its scripts, or modify its repository to construct the recovery report.
🧾 7. The Claim Model: FACT, INFERENCE, UNKNOWN
One of ContextKeeper's central architectural decisions is to make the epistemic status of a statement explicit.
FACT
A directly supported observation.
Examples:
- The repository is on a particular branch.
- A specific file exists.
- A Git status query reports uncommitted changes.
- A captured diff contains particular lines.
- A source file contains a particular exported declaration.
A FACT must cite one or more valid evidence records. A valid identifier is necessary, but identifier existence alone is not sufficient to prove semantic support.
INFERENCE
A reasoned interpretation based on evidence.
Examples:
- Active edits may indicate that work was in progress when a session ended.
- A TODO marker may indicate an unfinished implementation concern.
- Related untracked files may be part of the same development task.
An inference must explain its rationale and limitations. It should never be presented as direct observation.
UNKNOWN
A meaningful limitation of the available evidence.
Examples:
- The original user objective cannot be reconstructed reliably from code alone.
- A test log does not establish the current working tree's test status if code changed after the log was generated.
- A source declaration does not prove successful execution.
- Conflicting documents do not always reveal which intended behavior is correct.
Preserving UNKNOWN is not a failure to reason. It prevents a recovery tool from sending the developer in the wrong direction with unjustified certainty.
Architecture Diagram 4 — Evidence-to-Claim Flow
flowchart LR
subgraph Raw["Repository Artifacts"]
Status["Git Status"]
Diff["Git Diffs"]
Log["Commit History"]
Docs["Documentation"]
Code["Source Files"]
TestLog["Approved Historical Test Log"]
end
subgraph Sanitize["Sanitization and Normalization"]
Redact["Secret Redaction"]
Hash["Normalize Lines and Hash Content"]
ID["Generate Evidence IDs"]
end
Evidence[("Evidence Records")]
subgraph Synthesis["Claim Generation"]
Fact["FACT Rules"]
Infer["INFERENCE Rules"]
Unknown["UNKNOWN Rules"]
Verify["Citation Verification"]
end
subgraph Ledger["Auditable Claim Ledger"]
Facts["Evidence-backed facts"]
Inferences["Explicitly labeled inferences"]
Unknowns["Documented knowledge gaps"]
end
Status --> Redact
Diff --> Redact
Log --> Redact
Docs --> Redact
Code --> Redact
TestLog --> Redact
Redact --> Hash --> ID --> Evidence
Evidence --> Fact
Evidence --> Infer
Evidence --> Unknown
Fact --> Verify
Infer --> Verify
Unknown --> Verify
Verify --> Facts
Verify --> Inferences
Verify --> UnknownsThis workflow aims to make each recovery conclusion inspectable rather than relying on a single free-form generated summary.
Architecture Diagram 5 — Claim Classification and Validation
stateDiagram-v2
[*] --> CandidateObservation
state CandidateObservation {
[*] --> CheckEvidence
CheckEvidence --> HasEvidence: Evidence exists
CheckEvidence --> NoEvidence: Evidence missing
}
HasEvidence --> EvaluateCertainty
state EvaluateCertainty {
DirectObservation: Direct observation
Deduction: Deductive reasoning
Conflict: Stale or conflicting evidence
}
DirectObservation --> FactCandidate
Deduction --> InferenceCandidate
Conflict --> UnknownCandidate
NoEvidence --> UnknownCandidate
state FactCandidate {
[*] --> CitationAudit
CitationAudit --> CitationsValid: IDs resolve
CitationAudit --> CitationsInvalid: IDs missing
}
CitationsValid --> FACT
CitationsInvalid --> UNKNOWN
InferenceCandidate --> INFERENCE
UnknownCandidate --> UNKNOWN
FACT --> [*]
INFERENCE --> [*]
UNKNOWN --> [*]The classification model is designed to be conservative. Its remaining challenge is semantic validation: ensuring that the wording of a claim is actually justified by the content it cites.
🌐 8. The Interactive Dashboard
The CLI is useful for automation, terminal workflows, and piping results into other tools. The dashboard makes the same information easier to explore.
The local dashboard includes:
Recovery overview
- Repository path, branch, commit, and working-tree state.
- Claim counts by classification.
- Evidence counts and inspection statistics.
- Warnings and skipped-file reasons.
- Recovery recommendations.
Claim ledger
- Search by claim text or ID.
- Filter by FACT, INFERENCE, and UNKNOWN.
- Sort and inspect claim details.
- View rationale, limitations, and evidence references.
- Navigate from a claim to its supporting evidence.
Evidence inspector
- Evidence ID and source type.
- File or Git locator.
- SHA-256 digest.
- Freshness and redaction status.
- Bounded content inspection.
Changes viewer
- Staged and unstaged diffs.
- Untracked files.
- Readable, line-oriented change inspection.
Report preview and export
- Markdown recovery report.
- Structured JSON dossier.
- Downloadable outputs.
Visual experience
- Light and dark themes.
- Accessible status labels and visible focus states.
- A responsive, self-contained interface without external fonts or CDNs.
The design goal is to make a recovery report something a developer can investigate, rather than a wall of text they have to trust blindly.
Architecture Diagram 6 — Dashboard Request Sequence
sequenceDiagram
autonumber
actor User as Developer
participant Browser as Dashboard Browser
participant Server as dashboardServer.ts
participant Guard as pathGuard.ts
participant Inspector as inspector.ts
participant Engine as recoveryEngine.ts
participant AI as localAiProvider.ts
participant Formatter as markdownFormatter.ts
User->>Browser: Open local dashboard
Browser->>Server: GET /
Server->>Server: Validate loopback client and Host
Server-->>Browser: Self-contained dashboard HTML
User->>Browser: Select repository and inspect
Browser->>Server: POST /api/inspect
Server->>Server: Validate request and Origin
Server->>Guard: Validate target root
Guard-->>Server: Canonical root
Server->>Inspector: inspectRepository(root)
Inspector-->>Server: InspectionResult
Server->>Engine: reconstructProjectState(result)
Engine-->>Server: RecoveryDossier
opt AI interpretation requested
Server->>AI: Interpret bounded redacted evidence
AI-->>Server: Validated interpretation or fallback
end
Server-->>Browser: RecoveryDossier JSON
Browser->>Browser: Render claims and evidence
User->>Browser: Export Markdown report
Browser->>Server: GET /api/export/markdown
Server->>Formatter: Format validated dossier
Formatter-->>Server: Markdown
Server-->>Browser: Report downloadThe dashboard is intended to run on the local loopback interface at http://127.0.0.1:3333. Its request boundaries and the recovery engine should be tested independently of the appearance of the interface.
🤖 9. Optional Local AI — Interpretation Without Giving Up Provenance
ContextKeeper also supports optional AI-assisted interpretation using a locally hosted Ollama model.
The architectural intention is not to replace deterministic recovery with an unrestricted autonomous agent.
Instead, the model receives bounded, redacted evidence and can help produce a qualitative explanation of what may be happening in the project.
The local AI subsystem is designed around several controls:
- Only local loopback inference endpoints are accepted.
- Repository content is treated as untrusted input.
- Prompt construction explicitly isolates repository content.
- Responses are expected to conform to a structured schema.
- Model-generated evidence identifiers are checked against the real evidence set.
- Invalid responses, unavailable models, and timeouts trigger deterministic fallback.
- AI is optional and is not required for the core CLI or dashboard.
Ollama has been exercised with a local gemma3:4b model in the reported validation. However, local inference latency can vary; a larger recovery prompt has previously exceeded the configured 25-second timeout. The fallback behavior is therefore important, and broader latency testing remains useful.
Architecture Diagram 7 — Local AI Sequence
sequenceDiagram
autonumber
participant Caller as CLI or Dashboard
participant AI as localAiProvider.ts
participant Ollama as Local Ollama
participant Dossier as Recovery Dossier
Caller->>AI: generateLocalAiInterpretation(dossier)
AI->>AI: Validate loopback endpoint
alt Non-local endpoint
AI-->>Caller: Reject and fall back
else Local endpoint accepted
AI->>Ollama: GET /api/tags
alt Daemon unavailable
AI-->>Caller: UNAVAILABLE / FALLBACK
else Model available
Ollama-->>AI: Installed model list
AI->>AI: Build bounded redacted prompt
Note over AI: Repository text is untrusted<br/>Evidence IDs are supplied explicitly
AI->>Ollama: POST /api/generate
alt Timeout or HTTP failure
AI-->>Caller: Deterministic fallback
else Response received
Ollama-->>AI: Structured response
AI->>AI: Parse and validate schema
AI->>AI: Validate cited evidence IDs
alt Invalid response or citations
AI-->>Caller: Fallback with warning
else Valid response
AI-->>Dossier: Attach AI interpretation
AI-->>Caller: SUCCESS
end
end
end
endAn important distinction: a local model producing plausible prose is not the same as a model proving a fact. The model's role is interpretation; verified evidence remains the foundation for factual statements.
🔐 10. Security Architecture: Treat Repositories as Untrusted Input
ContextKeeper may inspect repositories cloned from unfamiliar locations or containing sensitive company code. That makes its security boundaries an essential part of the architecture.
The project implements several layers of defense.
Filesystem safety
- Canonical path validation.
- Symlink containment checks.
- File type and path exclusion policies.
- Bounded file count, individual file size, cumulative bytes, directory depth, and inspection time.
- Graceful handling of inaccessible or unsupported files.
Git subprocess safety
- Explicitly allowlisted read-only Git subcommands.
-
execFilewithshell: false. - Sanitized Git-related environment variables.
- Defensive Git configuration overrides.
- Timeouts and bounded output buffers.
- Rejection of dangerous arguments outside the supported interface.
Secret handling
- Pattern-based masking of common credential formats.
- High-entropy token screening.
- Redaction before evidence is stored or rendered.
- Regression tests using synthetic credentials.
Dashboard security
- Loopback-only binding.
- Client and Host header validation.
- Origin validation for state-changing requests.
- Request-body size limits.
- Content Security Policy and anti-framing headers.
- Restricted target paths.
AI security
- Local-only endpoint checks.
- Redacted, bounded prompt payloads.
- Untrusted repository-content isolation.
- Structured response validation.
- Evidence-ID verification.
- Deterministic fallback.
These are defense-in-depth controls, not a claim that every conceivable attack or secret format can be detected. ContextKeeper still requires continuing security review, especially as new data sources and dashboard features are introduced.
Architecture Diagram 8 — Security Trust Boundaries
flowchart TD
subgraph Untrusted["Untrusted Inputs"]
Args["CLI Arguments and Paths"]
Requests["Dashboard HTTP Requests"]
Files["Repository Files and Symlinks"]
GitConfig["Hostile Git Configuration"]
ModelOutput["Untrusted Model Output"]
end
subgraph HTTPBoundary["HTTP Boundary"]
Loopback["Loopback IP Check"]
Host["Host Header Validation"]
Origin["Origin / CSRF Validation"]
Body["Request Size Limit"]
end
subgraph PathBoundary["Filesystem Boundary"]
Root["Canonical Root Validation"]
Symlinks["Symlink Containment"]
Exclusions["Path and File Exclusions"]
Limits["File and Time Budgets"]
end
subgraph ProcessBoundary["Subprocess Boundary"]
Allowlist["Git Command Allowlist"]
Environment["Environment Sanitization"]
Config["Git Configuration Overrides"]
Exec["execFile, shell:false, Timeout"]
end
subgraph DataBoundary["Evidence Boundary"]
Redact["Secret Redaction"]
Digest["SHA-256 Content Identity"]
Provenance["Evidence Citation Validation"]
end
subgraph AIBoundary["AI and Output Boundary"]
LocalOnly["Local Endpoint Enforcement"]
PromptIsolation["Untrusted Content Isolation"]
Schema["Structured Response Validation"]
end
Outputs["Recovery Dossier and Reports"]
Requests --> Loopback --> Host --> Origin --> Body --> Root
Args --> Root
Files --> Symlinks
Root --> Symlinks --> Exclusions --> Limits
GitConfig --> Environment --> Allowlist --> Config --> Exec
Limits --> Redact
Exec --> Redact
Redact --> Digest --> Provenance
ModelOutput --> Schema
Provenance --> LocalOnly --> PromptIsolation --> Schema
Provenance --> Outputs
Schema --> Outputs📦 11. Packaging and Distribution
ContextKeeper is designed to be distributed as a lightweight npm executable.
The development workflow uses TypeScript for strict checking and compiles the source into ECMAScript modules for distribution.
The package build and packaging checks are intended to include:
- The executable wrapper.
- Compiled JavaScript output.
- README and license.
- Required runtime files.
- No test fixtures or internal development reports in the distributable package.
The CLI supports recovery-report generation and starting the local dashboard. The project documentation also covers typechecking, testing, building, installation, and troubleshooting.
Architecture Diagram 9 — Build and Deployment
flowchart TD
Source["TypeScript Source"]
Tests["Automated Tests"]
Config["tsconfig.json"]
Typecheck["npm run typecheck"]
Test["npm test"]
Build["npm run build"]
Dist["Compiled dist/src/*.js"]
Prepack["npm prepack"]
Allowlist["Package File Allowlist"]
Tarball["npm Package Tarball"]
Install["Install Package"]
Binary["contextkeeper Executable"]
Runtime["Resolve Compiled CLI"]
CLI["Run CLI or Dashboard"]
Source --> Typecheck
Tests --> Test
Config --> Typecheck
Source --> Build
Build --> Dist
Typecheck --> Build
Test --> Build
Dist --> Prepack
Prepack --> Allowlist
Allowlist --> Tarball
Tarball --> Install
Install --> Binary
Binary --> Runtime
Runtime --> CLIThe reported package dry-run included 21 files and retained zero runtime production dependencies. The CLI package was also reported as successfully installed and exercised in an isolated sandbox.
One issue identified during the architecture audit was the need to ensure the package's public JavaScript import entry point matches the files actually included in the tarball. Programmatic library consumption should be verified separately from executable CLI use.
🧪 12. Testing and Evaluation
I wanted the project to go beyond a successful build and a few happy-path demos.
The reported validation suite covers several distinct categories:
Unit tests
- SHA-256 digest stability.
- Line-ending normalization.
- Evidence ID generation.
- Secret-redaction behavior.
- Filesystem path validation.
- Git command argument restrictions.
Integration tests
- Git porcelain status parsing.
- Repository inspection lifecycle.
- Non-Git directory handling.
- Recovery claims and recommendations.
- Dashboard HTTP lifecycle.
Security tests
- Hostile Git configurations.
- Dangerous environment variable handling.
- Command and option injection attempts.
- Symlink escapes.
- Secret redaction.
- Invalid dashboard Host and Origin requests.
- Non-destructive inspection.
Synthetic evaluation
- Untracked feature files.
- Exported source declarations.
- Staged and unstaged changes.
- Stale documentation.
- Historical test logs.
- Unknown project intent.
- Secret-bearing content.
- Resource-limit enforcement.
- Malformed input.
- Non-Git repositories.
Dogfooding
- Self-inspection of the ContextKeeper repository.
- Synthetic interrupted-session profiles.
- Citation resolution and uncertainty handling.
- Repository immutability.
- Repeat-run determinism.
Optional local AI tests
- Loopback endpoint enforcement.
- Non-local endpoint rejection.
- Unavailable-daemon handling.
- Local model response and citation validation where the runtime is available.
Reported validation results
At the time of the supplied project reports:
- 60/60 automated tests passed.
- TypeScript typechecking completed with zero reported errors.
- The production build succeeded.
- The 12-scenario synthetic corpus passed.
- The dogfooding suite reported 9/9 passing scenarios.
- The combined evaluation reported 48/48 eligible files inspected, 202/202 citation references resolving, 24/24 required UNKNOWN classifications preserved, zero seeded-secret exposures, and 59/59 evaluated recommendations matching expected repository state.
- Package generation and an isolated CLI installation were reported successful.
These are measured results for the project's implemented test corpus. They should not be interpreted as proof of universal recovery accuracy, complete secret detection, or perfect semantic correctness across arbitrary repositories.
Architecture Diagram 10 — Testing and Validation Pipeline
flowchart TB
Start["npm test"]
subgraph Unit["Unit Tests"]
Digest["Digest Tests"]
Redactor["Redactor Tests"]
PathGuard["Path Guard Tests"]
GitRunner["Git Runner Tests"]
end
subgraph Integration["Integration Tests"]
GitStatus["Git Status Tests"]
Inspection["Inspection Lifecycle"]
Recovery["Recovery Engine Tests"]
Dashboard["Dashboard HTTP Tests"]
end
subgraph Security["Security Audits"]
HostileGit["Hostile Git Config Tests"]
Arguments["Argument and Environment Tests"]
Immutability["Non-Destructive Invariants"]
end
subgraph Evaluation["Recovery Evaluation"]
GroundTruth["12 Ground-Truth Archetypes"]
Dogfooding["9 Dogfooding Scenarios"]
end
subgraph AI["Local AI Tests"]
Locality["Loopback Enforcement"]
Fallback["Unavailable and Timeout Fallback"]
Citations["Model Citation Validation"]
end
Typecheck["npm run typecheck"]
Build["npm run build"]
Release["Review Results and Package"]
Start --> Unit
Start --> Integration
Start --> Security
Start --> Evaluation
Start --> AI
Unit --> Typecheck
Integration --> Typecheck
Security --> Typecheck
Evaluation --> Typecheck
AI --> Typecheck
Typecheck --> Build --> Release🧩 13. SOLID Principles and Architecture Review
A senior-level project should discuss its weaknesses as openly as its strengths.
The architecture audit found the following.
Single Responsibility Principle — Partial
The CLI handles several responsibilities, including argument parsing, command routing, recovery execution, and dashboard startup.
The dashboard server also combines transport security, routing, recovery orchestration, and export formatting. The dashboard HTML module embeds a large amount of CSS, HTML, and JavaScript in one source file.
Potential improvement: split command handlers, route handlers, and frontend assets into focused modules.
Open/Closed Principle — Partial
The claim generator contains sequential claim-generation rules. Adding another class of evidence or claim may require modifying the central generator.
The local AI provider is also closely coupled to the Ollama API.
Potential improvement: introduce a small claim-rule registry and a local AI provider interface only when extension needs justify the additional abstraction.
Liskov Substitution Principle — Not Applicable
The application is primarily functional and data-oriented. It relies on TypeScript interfaces and data structures rather than a class hierarchy.
Introducing inheritance purely to satisfy a SOLID checklist would add little value.
Interface Segregation Principle — Pass
The audit reports that the domain interfaces, including inspection options, content locators, and recommendations, have focused responsibilities.
Dependency Inversion Principle — Partial
Some high-level components import concrete filesystem operations and Git-running functions directly.
Potential improvement: use injected interfaces in the parts that would benefit from easier isolated testing or alternate implementations.
The wider engineering review also considered DRY, KISS, YAGNI, type safety, error handling, immutability, determinism, separation of concerns, testability, and maintainability.
The goal is not to maximize abstractions. It is to keep the architecture understandable, testable, and safe as the project grows.
🧱 14. Architectural Decisions and Trade-Offs
Several decisions shape the product.
1. Zero runtime dependencies
Using Node.js native APIs keeps the package lightweight. The trade-off is that routing, argument handling, and server behavior must be implemented and tested carefully.
2. Read-only repository inspection
ContextKeeper does not automatically stash, commit, clean, or modify the target repository. It also avoids executing arbitrary target-project test scripts during recovery.
This protects unfinished work but means current runtime correctness cannot be inferred from the repository alone.
3. Deterministic recovery first
The recovery pipeline remains useful without a model. AI is an optional layer rather than a required dependency.
4. Evidence-linked claims
The system requires claims to cite evidence records. This improves traceability, but semantic support still needs careful evaluation: the existence of a citation is not equivalent to proof that the claim is correct.
5. Local-only dashboard and AI
The dashboard uses loopback access controls, and the AI provider is designed for local Ollama inference. This limits the deployment model but supports a privacy-oriented experience for developers working with sensitive source code.
6. Bounded inspection
File-count, byte-size, depth, and time limits control resource usage. The trade-off is incomplete evidence when a repository exceeds those limits. Skipped files must remain visible through warnings rather than disappearing silently.
These decisions are documented in the project's architecture decision records and threat model.
⚠️ 15. What ContextKeeper Cannot Guarantee
Being explicit about limitations is part of building reliable developer tools.
ContextKeeper cannot reliably reconstruct the original task from arbitrary code changes alone. A developer may need to clarify the intended outcome.
A valid SHA-256 digest establishes content identity, not semantic truth. A source declaration does not establish runtime correctness. A historical test log does not establish that subsequently changed code passes.
Secret detection relies on patterns and heuristics, so unusual, custom, or low-entropy secrets may evade detection.
Concurrent external processes may also change a repository while it is being inspected. Read-only content operations can update operating-system access timestamps, depending on filesystem behavior.
Local model inference may time out or return invalid output; deterministic fallback remains essential.
Finally, the evaluation results are bounded by the repositories and scenarios tested so far. More diverse real-world sessions and independent evaluations are needed to establish how useful the tool is across different projects and workflows.
🗺️ 16. Development Roadmap
The next stages are about improving reliability and usability rather than adding features without evidence.
Priority 1 — Real-world recovery quality
Evaluate actual interrupted coding sessions and record missed changes, weak recommendations, ambiguous claims, and cases where UNKNOWN should be preserved.
Priority 2 — Package and public API correctness
Keep the installed CLI reliable and ensure that any advertised programmatic library interface resolves to actual packaged JavaScript and type declarations.
Priority 3 — Architecture modularity
Split the largest modules into clearer units when doing so demonstrably improves testability and maintainability.
Priority 4 — Local AI latency and resilience
Measure inference time on real hardware, minimize redundant prompt content, and improve bounded payload construction without removing provenance controls.
Priority 5 — Developer onboarding and community contribution
Maintain useful diagrams, installation instructions, architectural decision records, contributor documentation, reproducible tests, and accessible issue reports.
💻 17. Quick Start
For developers who want to explore the project, the documented commands include:
# Run in the ContextKeeper repository
npm install
# Typecheck
npm run typecheck
# Run the automated tests
npm test
# Build the distribution
npm run build
# Generate a Markdown recovery dossier
node bin/contextkeeper.js recover . --report markdown
# Generate JSON
node bin/contextkeeper.js recover . --report json
# Start the local dashboard
node bin/contextkeeper.js ui .
# Optional: request local AI interpretation
node bin/contextkeeper.js recover . --report markdown --ai --ai-model gemma3:4b
# Inspect package contents without publishing
npm pack --dry-run
The AI command requires a working local Ollama service and the selected model to be installed. Without it, deterministic recovery remains the fallback.
📚 18. Open-Source Documentation and Architecture Artifacts
The project includes a set of engineering documents designed to make the implementation inspectable and easier to contribute to:
-
docs/PROJECT_DEEP_DIVE.md— system architecture and workflow walkthroughs. -
docs/ARCHITECTURE_DECISION_RECORDS.md— architectural choices and trade-offs. -
docs/SOLID_AND_CODE_QUALITY_AUDIT.md— design-principle assessment and remediation proposals. -
docs/DEVELOPER_GUIDE.md— development setup, CLI, dashboard, testing, packaging, and troubleshooting. -
docs/FINAL_MVP_COMPLETION_REPORT.md— recorded acceptance and validation results. docs/diagrams/01_system_context.mmddocs/diagrams/02_component_architecture.mmddocs/diagrams/03_cli_recovery_sequence.mmddocs/diagrams/04_dashboard_request_sequence.mmddocs/diagrams/05_evidence_claim_flow.mmddocs/diagrams/06_local_ai_sequence.mmddocs/diagrams/07_claim_classification_state.mmddocs/diagrams/08_security_trust_boundaries.mmddocs/diagrams/09_packaging_deployment_flow.mmddocs/diagrams/10_testing_validation_pipeline.mmd
These diagrams illustrate the system context, component architecture, CLI recovery, dashboard request flow, evidence-to-claim pipeline, local AI lifecycle, claim classification, security boundaries, packaging, and testing.
The diagrams are authored as Mermaid source files. Their syntax should be validated with an actual renderer before describing them as independently render-tested.
🌱 19. What I Learned Building ContextKeeper
This project has reinforced several lessons for me as a developer working at the intersection of AI, developer tools, and open source.
First, deterministic systems still matter in AI products. Collecting reliable physical facts about a repository is often more valuable than generating an elaborate explanation without provenance.
Second, security needs to shape the architecture. Path validation, subprocess restrictions, redaction, bounded processing, and read-only behavior are core design decisions—not features that should be added only after the interface is complete.
Third, uncertainty deserves an explicit representation. Keeping UNKNOWN as a first-class outcome makes it possible to recover project state without pretending to understand a developer's intentions.
Fourth, passing tests are necessary but not sufficient. Packaging, failure handling, actual model behavior, interface usability, semantic claim support, and real-world validation all matter.
Finally, good architecture includes trade-offs. Zero runtime dependencies, embedded dashboard assets, a deterministic-first engine, and a locally hosted AI provider each offer benefits while introducing limitations that should be documented and revisited as the product matures.
🚀 20. The Vision
My goal with ContextKeeper is to make interrupted development less painful by helping developers recover their working context from observable evidence.
I want to keep improving the experience while preserving its core engineering principles:
- Local-first operation.
- Read-only inspection.
- Bounded resource usage.
- Redacted evidence.
- Traceable conclusions.
- Explicit uncertainty.
- Optional, locally hosted AI.
- Reproducible validation.
- Clear architectural documentation.
ContextKeeper is not meant to pretend it knows everything about a project. It is meant to help developers establish what can be known, understand what is likely, and recognize what still requires their judgment.
The principle behind the project is simple:
Don't let AI invent your project's history. Reconstruct the evidence, preserve uncertainty, and help the developer take the next step.
I'm continuing to improve ContextKeeper and welcome constructive feedback, architectural review, security feedback, testing ideas, and contributions from the developer and open-source community.
🔗 GitHub: [https://github.com/suvendukungfu/contextkeeper-ai]
Hacktoberfest #hf26challenge #devchallenges #OpenSource
來源:DEV Community · dev.to