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
Continue reading this section for the full explanation and source context.
Related Pages
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:
| Layer | Responsibility | Typical file |
|---|---|---|
| Entry point | Declares the bin field, parses argv, hands off to the dispatcher | bin/grainulation.js |
| Dispatcher | Routes argv to the registered command handler | bin/grainulation.js |
| Command handlers | Implement concrete operations (npm list, lsof, etc.) | invoked by dispatcher |
| Landing page | User-facing documentation and release pointers | docs/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 --> GThe 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 viaexecFileSyncwith an argument array rather than the legacyexecSyncstring 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 usesshell: false;execSyncwas replaced withexecFileSyncand argument arrays fornpm listandlsof(Source: CHANGELOG.md:N). - Content Security Policy — a
metatag CSP was added to the landing page so that browser-side consumers ofdocs/index.htmlcannot load arbitrary external resources (Source: docs/index.html:N). - Repository hygiene —
.claude/was added to.gitignoreto 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 indocs/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
Continue reading this section for the full explanation and source context.
Related Pages
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
Continue reading this section for the full explanation and source context.
Related Pages
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.jsperforms 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.jslib/doctor.jsruns 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.jslib/server.mjsis 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_modulesis present and, if not, driving the package manager to install dependencies. Where npm state must be inspected, the module usesnpm listinvoked with argument arrays viaexecFileSyncrather 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
lsofinvoked viaexecFileSyncwith an explicit argument array, preventing shell injection (v1.1.0 security hardening). Source: lib/doctor.js - Verifying that the files produced by
setupare 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:
- Install dependencies and write config via
setup.js. Source: lib/setup.js - Validate the environment with
doctor.js; remediate any reported failures. Source: lib/doctor.js - 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
spawncalls toshell: falseand replacingexecSyncwithexecFileSyncfornpm listandlsofcalls indoctor.jsand related code. Source: lib/doctor.js - The landing page served by
server.mjscarries 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.gitignorein 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
Continue reading this section for the full explanation and source context.
Related Pages
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 toshell: false, and the synchronous executorexecSyncwas replaced withexecFileSyncthat accepts explicit argument arrays. This pattern is applied to thenpm listandlsofcalls 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.gitignoreto prevent assistant-related local state from being committed to the repository.
| Change | File / Surface | Risk Mitigated |
|---|---|---|
spawn() uses shell: false | hub CLI router | Shell injection via arguments |
execFileSync with arrays | npm list, lsof calls | Argument injection |
| CSP meta tag | site/index.html | XSS / unauthorized script load |
.claude/ in .gitignore | repo root | Local 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:
- Themed releases — e.g.,
v1.1.0 — Security Hardening, which bundles related changes under a descriptive heading. - 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 --> GSource: SECURITY.md, CHANGELOG.md, .githooks/pre-commit
Operational Configuration
The hardening guarantees rely on configuration that is checked into the repository:
package.jsondeclares the scripts and dependency manifest pinned for each release, ensuring that the hub router — which is the surface that previously calledexecSync— runs against a known dependency set..gitignoreexcludes.claude/and other local artifacts so that developer-machine state never reaches the release artifacts.site/index.htmlships 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.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
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.
Count of project-level external discussion links exposed on this manual page.
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.
- v1.1.3 - github / github_release
- v1.1.0 — Security Hardening - github / github_release
- Capability evidence risk requires verification - GitHub / issue
Source: Project Pack community evidence and pitfall evidence