跳到正文
DEV Community· suvendu kumar sahoo·· 4 小時前AI 評分46

ContextKeeper:不再遺失開發上下文

Never Lose Your Context Again.

AI 導讀

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:

  1. A command-line interface for developers who prefer scripts, terminals, and structured output.
  2. An interactive local web dashboard for exploring claims, evidence, changes, and recommendations.
  3. 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, and UNKNOWN classification.
  • 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 -.-> Dossier

Architectural 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 --> Types

This 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 stdout

The 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 --> Unknowns

This 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 download

The 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
    end

An 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.
  • execFile with shell: 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 --> CLI

The 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.mmd
  • docs/diagrams/02_component_architecture.mmd
  • docs/diagrams/03_cli_recovery_sequence.mmd
  • docs/diagrams/04_dashboard_request_sequence.mmd
  • docs/diagrams/05_evidence_claim_flow.mmd
  • docs/diagrams/06_local_ai_sequence.mmd
  • docs/diagrams/07_claim_classification_state.mmd
  • docs/diagrams/08_security_trust_boundaries.mmd
  • docs/diagrams/09_packaging_deployment_flow.mmd
  • docs/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