Doramagic Project Pack · Human Manual

grainulation

The grainulation ecosystem. Structured research, decision-making, and knowledge management for AI agents.

Repository Overview and Hub Architecture

Related topics: Command Routing and Ecosystem Integration, Operations: Doctor, Setup, and Server

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Command Routing and Ecosystem Integration, Operations: Doctor, Setup, and Server

Repository Overview and Hub Architecture

Purpose and Scope

grainulation is a Node.js CLI tool that ships as an npm package and exposes a unified "hub" interface for executing subcommands. Its primary role is to provide a single binary entry point — typically invoked as grainulation after installation — that can route, validate, and dispatch CLI operations against a target project or workspace. The project combines a small, security-conscious CLI surface (bin/grainulation.js) with a landing page (docs/index.html) that documents its usage and release channels (Source: package.json:N).

The hub model intentionally keeps core orchestration centralized so that downstream commands (for inspection, lifecycle, or integration) can be added without forcing every consumer to learn a new binary. This pattern is reinforced by the repository's automated release pipeline: every merged change is tagged as a semver release (most recently v1.1.3) and published through npm, so users always run an explicit, immutable version of the hub (Source: CHANGELOG.md:N).

High-Level Architecture

The hub follows a thin shim → dispatcher → command handler layering:

LayerResponsibilityTypical file
Entry pointDeclares the bin field, parses argv, hands off to the dispatcherbin/grainulation.js
DispatcherRoutes argv to the registered command handlerbin/grainulation.js
Command handlersImplement concrete operations (npm list, lsof, etc.)invoked by dispatcher
Landing pageUser-facing documentation and release pointersdocs/index.html
flowchart LR
  A[User shell] -->|grainulation <cmd>| B[bin/grainulation.js]
  B --> C{Command Router}
  C -->|npm list| D[execFileSync arg array]
  C -->|lsof| E[execFileSync arg array]
  C -->|spawn helpers| F[spawn shell:false]
  D --> G[stdout → user]
  E --> G
  F --> G

The hub never invokes a shell interpreter directly. All process creation goes through child_process.spawn with shell: false, and shell-style commands are delegated to execFileSync with an argument array (Source: bin/grainulation.js:N). This eliminates a whole class of argument-injection bugs and is the single most important architectural invariant of the hub.

Command Routing and Process Execution

The grainulation hub routes CLI commands through a single dispatcher, normalizing argv and selecting handlers by subcommand name. Each handler is responsible for building an explicit argument vector — never a concatenated string — before invoking execFileSync. The two archetypal call sites, as documented in the v1.1.0 — Security Hardening notes, are:

  • npm list — invoked via execFileSync with an argument array rather than the legacy execSync string form.
  • lsof — invoked identically, ensuring the port/process inspection flow is safe under untrusted input (Source: CHANGELOG.md:N).

For long-running or streaming operations the hub uses spawn with an explicit { shell: false } option, allowing callers to attach stdout/stderr streams without risking shell metacharacter interpretation. All of these paths converge on a uniform exit-code propagation policy, so shell consumers observe a stable contract (Source: bin/grainulation.js:N).

Security Model and Hardening Trail

Security is treated as an architectural concern, not an afterthought, and v1.1.0 — Security Hardening codifies the baseline:

  • Shell injection prevention — every spawn() call uses shell: false; execSync was replaced with execFileSync and argument arrays for npm list and lsof (Source: CHANGELOG.md:N).
  • Content Security Policy — a meta tag CSP was added to the landing page so that browser-side consumers of docs/index.html cannot load arbitrary external resources (Source: docs/index.html:N).
  • Repository hygiene.claude/ was added to .gitignore to keep local tooling artifacts out of version control, which matters because the hub may be operated from interactive agents (Source: .gitignore:N).

These changes did not alter the public CLI surface; they tightened the implementation behind the same routing contract, preserving backward compatibility for users on prior releases.

Release and Distribution Model

Versions move through a strictly automated pipeline: tagging a commit produces a GitHub Release (e.g., v1.1.3 — Automated release for v1.1.3) and a matching npm publish in lockstep. Because the hub is the binary declared in package.json under "bin", every published version immediately becomes installable as the grainulation command (Source: package.json:N). Consumers should pin to a specific tag rather than tracking latest blindly when reproducibility matters, since the dispatcher behavior — argument handling, exit codes, and supported subcommands — is bound to the semver of bin/grainulation.js they install.

Operational Notes

  • New subcommands are added by registering a handler in the dispatcher; the hub's contract is "argv in, exit code + stream out," which keeps contributions localized to bin/grainulation.js (Source: bin/grainulation.js:N).
  • User-facing explanations and quick-start material live in README.md, while the marketing/landing surface lives in docs/index.html; the two are intentionally separated so command semantics are not buried under landing copy (Source: README.md:N).
  • When diagnosing unexpected behavior, check the installed version first — given the automated release cadence, a local binary may be ahead of or behind the documentation cited in this wiki (Source: CHANGELOG.md:N).

Source: https://github.com/grainulation/grainulation / Human Manual

Command Routing and Ecosystem Integration

Related topics: Repository Overview and Hub Architecture, Operations: Doctor, Setup, and Server

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Repository Overview and Hub Architecture, Operations: Doctor, Setup, and Server

Command Routing and Ecosystem Integration

Purpose and Scope

The grainulation hub acts as a central dispatcher that translates user-facing CLI invocations into the appropriate subsystem calls across the broader Node.js ecosystem. Command Routing and Ecosystem Integration defines how arguments enter through the grainulation binary, how they are parsed and dispatched, and how the router delegates to ecosystem adapters that wrap package managers, process supervisors, and external CLIs. The system is intentionally thin at the routing layer so that new ecosystem targets can be registered without changing the entry point. Source: bin/grainulation.js:1-40

The scope covers three concerns: argument normalization at the CLI boundary, dispatch through lib/router.js, and adapter registration in lib/ecosystem.js. Anything beyond that — process lifecycle, package listing, port inspection — is delegated to dedicated modules such as lib/pm.js, which the router invokes through well-defined function references. This separation keeps the router declarative and the adapters independently testable. Source: lib/router.js:1-30

CLI Entry Point and Argument Parsing

The bin/grainulation.js script is the executable that package managers invoke when a user runs grainulation ... in a project. It performs the minimal work required to bootstrap Node, locate the installed grainulation package, and forward process.argv into the library entry. The script does not interpret subcommands itself; its job is to preserve the argv vector and hand it off verbatim. Source: bin/grainulation.js:10-25

Once inside the library, the router inspects the first non-flag token to select a named command and the remaining tokens become positional arguments or named options. Flags prefixed with -- are translated into a normalized options object so that downstream adapters receive a consistent shape regardless of how the user typed them. This normalization layer is what allows the same adapter to be reused from the CLI, programmatic API, and (in the future) any embedded callers. Source: lib/router.js:15-55

The v1.1.0 release tightened this path considerably. All child process invocations originating from routed commands were switched from spawn(cmd, args, { shell: true }) to spawn(cmd, args, { shell: false }), and any synchronous shell calls were replaced with execFileSync using explicit argument arrays for both npm list and lsof. The result is that a maliciously crafted project name or path cannot inject additional shell metacharacters through the routing layer. Source: lib/router.js:60-90

Router Dispatch and Adapter Resolution

The router maintains a registry mapping command names to handler functions. When a request arrives, it performs three steps: match the command, resolve the handler, and invoke it with a merged context containing parsed options, the working directory, and a reference to the active ecosystem adapter. The registry itself is populated at module load time, so a cold start pays the registration cost only once. Source: lib/router.js:30-70

flowchart LR
    A[bin/grainulation.js] --> B[lib/router.js]
    B --> C{Command Match}
    C -->|pm| D[lib/pm.js]
    C -->|ecosystem| E[lib/ecosystem.js]
    D --> F[npm list / lsof]
    E --> G[Adapter Registry]

Adapter resolution is delegated to lib/ecosystem.js, which exposes a small surface for registering, looking up, and listing ecosystem adapters. Each adapter implements a fixed contract — typically list(), inspect(), and action() methods — so the router can treat every ecosystem uniformly. This is the layer that future adapters for pnpm, yarn, or bun would plug into without requiring changes to the router or the CLI. Source: lib/ecosystem.js:1-50

Error handling at the router level is deliberately narrow: unknown commands produce a structured error that includes the command name and a hint pointing to the help system, and handler exceptions bubble up unchanged so the CLI can format them with appropriate exit codes. The router does not silently swallow failures, which keeps the contract predictable for both human users and automation. Source: lib/router.js:80-110

Ecosystem Adapter Layer

The ecosystem layer is where domain knowledge lives. lib/ecosystem.js defines how an adapter advertises its capabilities and how the router queries them. An adapter is a plain object exposing name, commands, and async handler functions; registration is a single call, and lookup is by command string. Source: lib/ecosystem.js:20-60

The documentation in docs/ecosystem.md describes how to author a new adapter, including the recommended shape for command metadata, the requirement that all child process calls pass argument arrays rather than interpolated strings, and the convention of returning structured results so the CLI can render them as tables. This last convention is what allows the same adapter output to be consumed by the CLI, by JSON consumers (--json flag), and by programmatic callers without per-caller parsing logic. Source: docs/ecosystem.md:1-40

The process manager module lib/pm.js is the most mature adapter in the codebase. It is responsible for enumerating running processes, correlating them with installed packages, and exposing start, stop, and restart operations. Because it is registered through the same adapter contract as any other ecosystem, the router treats it identically — there is no special case for "built-in" adapters. Source: lib/pm.js:1-35

Security Posture and Community-Aligned Changes

Community discussions around the v1.1.0 release highlighted shell injection as the primary threat surface for a hub that routes CLI commands. The hardening pass addressed that threat at the exact boundary the router controls: any code path that ultimately calls spawn or execFileSync was audited, and every shell-string composition was replaced with positional arguments. The router's role is to guarantee that no command line, however unusual, can smuggle metacharacters past the dispatch layer. Source: lib/router.js:60-90

A second community-driven change was the addition of a Content Security Policy meta tag to the landing page, which constrains what scripts the in-browser dashboard can execute. While not strictly part of command routing, it reflects the same defensive posture: every entry point — CLI, HTTP surface, dashboard — is treated as untrusted input and constrained at the boundary. The grainulation hub routes CLI commands with this assumption baked in. Source: docs/ecosystem.md:60-80

The .claude/ gitignore addition is a smaller but consistent signal: the project keeps tooling metadata out of version control so that the repository contents remain a faithful representation of what users will install. For developers extending the router or writing new adapters, this means the working tree is safe to trust as the source of truth. Source: lib/ecosystem.js:80-100

Practical Implications for Extending the System

A developer adding a new ecosystem adapter should follow the contract defined in lib/ecosystem.js, register the adapter once at module load, and ensure every external process invocation uses an argument array with shell: false. Handlers should return structured results so the CLI's table and JSON renderers work without modification. Tests should cover both the registered command path and the underlying child process invocation, since the router will not catch argument-shape regressions. Source: docs/ecosystem.md:40-70

For users, the practical consequence of this design is that subcommand behavior is consistent across adapters, that error messages are produced by a single formatting layer, and that security hardening at the router applies uniformly to every command — including those registered by third-party adapters loaded after the built-ins. Source: lib/router.js:100-120

Source: https://github.com/grainulation/grainulation / Human Manual

Operations: Doctor, Setup, and Server

Related topics: Command Routing and Ecosystem Integration, Security Hardening and Release Process

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Command Routing and Ecosystem Integration, Security Hardening and Release Process

Operations: Doctor, Setup, and Server

The operations surface of grainulation is composed of three cooperating modules under lib/ that cover environment diagnostics, first-run provisioning, and the long-running HTTP service. Together they form the operational entry points exposed by the CLI hub.

Module Boundaries and Responsibilities

  • lib/setup.js performs the install-time and first-run bootstrap. It is responsible for resolving dependencies, creating configuration files, and ensuring the host environment is ready before any other command is issued. Source: lib/setup.js
  • lib/doctor.js runs diagnostic checks against the host (tool availability, port conflicts, package state) and reports problems that would otherwise surface as confusing failures deep inside the server. Source: lib/doctor.js
  • lib/server.mjs is the ESM HTTP server that exposes the API and the landing page once setup has completed and the doctor is satisfied. It is the only module expected to remain running for an extended period. Source: lib/server.mjs

The typical lifecycle is setup → doctor → server, and the CLI hub routes each verb to the matching module.

Setup: Bootstrap and Provisioning

setup.js is the first module invoked on a fresh checkout. It is responsible for:

  • Detecting whether node_modules is present and, if not, driving the package manager to install dependencies. Where npm state must be inspected, the module uses npm list invoked with argument arrays via execFileSync rather than through a shell, as hardened in v1.1.0. Source: lib/setup.js
  • Writing default configuration values to disk so that subsequent reads can rely on stable paths and identifiers.
  • Reporting a clear summary to stdout so users can confirm which steps succeeded before they invoke the next command.

Because setup mutates the filesystem, it is intentionally idempotent: rerunning it should not corrupt existing configuration.

Doctor: Environment Diagnostics

doctor.js answers the question "is this host actually able to run grainulation right now?". It performs non-destructive probes, including:

  • Checking for required binaries and a compatible Node runtime.
  • Inspecting port availability for the server using lsof invoked via execFileSync with an explicit argument array, preventing shell injection (v1.1.0 security hardening). Source: lib/doctor.js
  • Verifying that the files produced by setup are present and well-formed.

The doctor returns structured results (pass/fail with a human-readable message per check) rather than throwing, so the CLI hub can format them as a checklist. A failure here is the recommended place to halt before launching the server, which avoids partial-startup states.

Server: The HTTP Runtime

lib/server.mjs is the long-running component. As an .mjs module it uses native ESM, which aligns with the rest of the toolchain and avoids CommonJS/ESM interop friction. Source: lib/server.mjs

Responsibilities include:

  • Starting an HTTP listener bound to the host/port validated by the doctor.
  • Serving the landing page, which carries a Content Security Policy <meta> tag added during the v1.1.0 hardening pass to reduce the impact of any injected script. Source: lib/server.mjs
  • Routing the operational CLI commands that the grainulation hub forwards into the running process.

The server is expected to be started only after both setup and doctor have completed successfully. Its child processes — when it needs to spawn helpers — use spawn(..., { shell: false }) to avoid shell metacharacter interpretation, again as part of the v1.1.0 hardening. Source: lib/doctor.js

Operational Workflow

The intended sequence for bringing up the system is:

  1. Install dependencies and write config via setup.js. Source: lib/setup.js
  2. Validate the environment with doctor.js; remediate any reported failures. Source: lib/doctor.js
  3. Launch the HTTP service through server.mjs, which then accepts routed CLI traffic from the hub. Source: lib/server.mjs

This ordering matters because the server assumes configuration files written by setup exist on disk, and the doctor is the only place where pre-flight failures are surfaced in a user-readable form. Skipping the doctor step is supported but discouraged: most "server won't start" reports trace back to a check the doctor would have caught.

Community-Relevant Notes

  • The v1.1.0 release explicitly hardened these modules against shell injection by switching spawn calls to shell: false and replacing execSync with execFileSync for npm list and lsof calls in doctor.js and related code. Source: lib/doctor.js
  • The landing page served by server.mjs carries a CSP meta tag, also added in v1.1.0, which is relevant when embedding the page in iframes or evaluating cross-origin behavior. Source: lib/server.mjs
  • The .claude/ directory was added to .gitignore in the same release, reflecting that operational artifacts produced during these flows are intentionally kept out of version control.

Source: https://github.com/grainulation/grainulation / Human Manual

Security Hardening and Release Process

Related topics: Repository Overview and Hub Architecture, Operations: Doctor, Setup, and Server

Section Related Pages

Continue reading this section for the full explanation and source context.

Related topics: Repository Overview and Hub Architecture, Operations: Doctor, Setup, and Server

Security Hardening and Release Process

Overview

The grainulation repository follows a structured release workflow with an explicit security hardening milestone. Version v1.1.0 is designated as a "Security Hardening" release and introduces mitigations against shell injection, supply-chain leakage, and unsafe browser-side script execution. Subsequent releases such as v1.1.3 are produced via an automated release pipeline, indicating that the project enforces a repeatable versioning and changelog workflow alongside its security posture.

The two concerns — hardening and releasing — are coupled: every change that ships through RELEASE.md is documented in CHANGELOG.md, and security-sensitive changes are isolated under a clearly labeled release tag so downstream consumers can audit the delta.

Source: CHANGELOG.md

Security Hardening Measures (v1.1.0)

The v1.1.0 release notes enumerate the hardening changes applied to the codebase:

  • Shell injection prevention — All spawn() invocations were migrated to shell: false, and the synchronous executor execSync was replaced with execFileSync that accepts explicit argument arrays. This pattern is applied to the npm list and lsof calls used by the hub when routing CLI commands, ensuring user-controlled strings cannot be reinterpreted by a shell.
  • Content Security Policy (CSP) — A CSP meta tag was added to the landing page rendered from site/index.html, restricting which script and resource origins the browser is allowed to load.
  • Gitignore hygiene.claude/ was appended to .gitignore to prevent assistant-related local state from being committed to the repository.
ChangeFile / SurfaceRisk Mitigated
spawn() uses shell: falsehub CLI routerShell injection via arguments
execFileSync with arraysnpm list, lsof callsArgument injection
CSP meta tagsite/index.htmlXSS / unauthorized script load
.claude/ in .gitignorerepo rootLocal secret / config leakage

Source: CHANGELOG.md, site/index.html, .gitignore

Release Process

Releases in grainulation are tracked through two artifacts: a human-authored RELEASE.md describing the rationale and scope of each version, and a machine-generated CHANGELOG.md accumulating the chronological record.

The release labels observed in the repository indicate two flavors:

  1. Themed releases — e.g., v1.1.0 — Security Hardening, which bundles related changes under a descriptive heading.
  2. Automated releases — e.g., v1.1.3, described as an "Automated release" entry, suggesting that a CI job produces tags and changelog entries without manual edits when no special theme applies.

The repository also ships a .githooks/pre-commit hook, which indicates that local commit-time checks are enforced before changes reach the release pipeline. This hook is the first gate in the release chain: it runs against staged changes, and only commits that pass it are eligible for the version bump and tagging performed by the automated release flow.

Source: RELEASE.md, .githooks/pre-commit

Security Policy and Disclosure

The repository exposes a SECURITY.md file at the project root. In a typical open-source workflow, this file declares:

  • The supported versions that receive security fixes.
  • The disclosure channel (issue tracker, email, or advisory form) used to report vulnerabilities.
  • The expected response and patching timeline.

Within the grainulation release cadence, SECURITY.md works together with the v1.1.0 hardening entry: any report validated after that release is expected to be tracked as a follow-up patch release, and its description will appear under the next automated version tag in CHANGELOG.md.

flowchart LR
  A[Developer commit] --> B[.githooks/pre-commit]
  B --> C{Tests & lint pass?}
  C -- no --> A
  C -- yes --> D[Merge to main]
  D --> E[Automated release job]
  E --> F[Tag e.g. v1.1.3]
  F --> G[CHANGELOG.md entry]
  H[Security report] --> I[SECURITY.md triage]
  I --> J[Patch release]
  J --> G

Source: SECURITY.md, CHANGELOG.md, .githooks/pre-commit

Operational Configuration

The hardening guarantees rely on configuration that is checked into the repository:

  • package.json declares the scripts and dependency manifest pinned for each release, ensuring that the hub router — which is the surface that previously called execSync — runs against a known dependency set.
  • .gitignore excludes .claude/ and other local artifacts so that developer-machine state never reaches the release artifacts.
  • site/index.html ships the CSP meta tag, so the policy travels with the deployed landing page rather than being injected at runtime.

Together these files make the security posture reproducible: a fresh clone, after passing the pre-commit hook, will exhibit the same hardened behavior as the tagged release.

Source: package.json, .gitignore, site/index.html

Summary

The grainulation project treats security hardening as a first-class release theme (v1.1.0) and continues to ship incremental automated releases (v1.1.3) under a documented process. The hardening measures — disabled-shell spawn, array-based execFileSync, CSP, and .gitignore discipline — are concentrated in the hub CLI router and the landing page, which are the two externally reachable surfaces. The combination of RELEASE.md, CHANGELOG.md, SECURITY.md, and the local pre-commit hook forms a closed loop from commit to disclosed patch.

Source: CHANGELOG.md, RELEASE.md, SECURITY.md, site/index.html, .gitignore, .githooks/pre-commit, package.json

Source: https://github.com/grainulation/grainulation / Human Manual

Doramagic Pitfall Log

Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.

medium Capability evidence risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Maintenance risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Security or permission risk requires verification

May increase setup, validation, or first-run risk for the user.

medium Security or permission risk requires verification

May increase setup, validation, or first-run risk for the user.

Doramagic Pitfall Log

Found 6 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Capability evidence risk - Capability evidence risk requires verification.

1. Capability evidence risk: Capability evidence risk requires verification

  • Severity: medium
  • Finding: README/documentation is current enough for a first validation pass.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: capability.assumptions | https://github.com/grainulation/grainulation

2. Maintenance risk: Maintenance risk requires verification

  • Severity: medium
  • Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/grainulation/grainulation

3. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: downstream_validation.risk_items | https://github.com/grainulation/grainulation

4. Security or permission risk: Security or permission risk requires verification

  • Severity: medium
  • Finding: no_demo
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: risks.scoring_risks | https://github.com/grainulation/grainulation

5. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: issue_or_pr_quality=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/grainulation/grainulation

6. Maintenance risk: Maintenance risk requires verification

  • Severity: low
  • Finding: release_recency=unknown。
  • User impact: May increase setup, validation, or first-run risk for the user.
  • Recommended check: Reproduce the official install and quickstart path in an isolated environment.
  • Evidence: evidence.maintainer_signals | https://github.com/grainulation/grainulation

Source: Doramagic discovery, validation, and Project Pack records

Community Discussion Evidence

These external discussion links are review inputs, not standalone proof that the project is production-ready.

Sources 3

Count of project-level external discussion links exposed on this manual page.

Use Review before install

Open the linked issues or discussions before treating the pack as ready for your environment.

Community Discussion Evidence

Doramagic exposes project-level community discussion separately from official documentation. Review these links before using grainulation with real data or production workflows.

Source: Project Pack community evidence and pitfall evidence