How nanostack works internally

Skills are markdown. Artifacts are JSON. Coordination is atomic file operations. No daemon, no service, no database.

Skills are SKILL.md files

Every skill is a directory with one required file: SKILL.md. The directory can also contain references, templates, and scripts that the skill needs at runtime.

think/
├── SKILL.md              # the skill definition
├── references/
│   ├── founder-questions.md
│   ├── startup-questions.md
│   └── builder-questions.md
└── templates/
    └── think-summary.json

The SKILL.md starts with YAML frontmatter that declares metadata and runtime behavior. Everything after the frontmatter is the prompt — plain markdown that the agent reads as instructions.

---
name: think
description: Challenge scope before planning
concurrency: exclusive
depends_on: []
hooks:
  PreToolUse:
    - matcher: Bash
      command: "./guard/bin/check-dangerous.sh"
---

# /think -- Challenge the scope

## Process

1. Read the user prompt and classify: founder, startup, or builder.
2. Run the six diagnostic questions for the selected mode.
3. Write the think summary to .nanostack/think.json.
4. Save the artifact:

```bash
bin/save-artifact.sh think think-summary.json
```

Artifacts are the memory

Every phase produces an artifact — a JSON file that captures what happened. Artifacts are the only way phases communicate with each other. The agent reads previous artifacts to understand context. It writes new artifacts to record decisions.

{
  "phase": "review",
  "timestamp": "2026-03-28T14:22:31Z",
  "project": "nanostack-site",
  "branch": "feat/framework-docs",
  "summary": "4 issues found. 2 critical: missing input validation on config parser, race condition in lock acquisition. 2 minor: inconsistent error messages, unused import.",
  "scope_drift": false,
  "context_checkpoint": {
    "files_reviewed": 12,
    "lines_analyzed": 847,
    "patterns_checked": ["error-handling", "input-validation", "concurrency"]
  },
  "integrity": "sha256:a3f2b8c1d4e5f6..."
}

Every artifact is project-scoped (tied to the git repo), timestamped (ISO 8601), integrity-verified (SHA-256 hash of the content), and secret-scanned before writing to disk. Large artifacts are truncated to stay under the context window limit.

Scripts are the glue

Four shell scripts handle the artifact lifecycle. They live in bin/ and work on any POSIX system.

# Save an artifact after a phase completes
bin/save-artifact.sh review review-findings.json

# Find the most recent artifact for a phase
bin/find-artifact.sh --phase review --project nanostack-site

# Check if scope has drifted from the plan
bin/scope-drift.sh --plan nano-plan.json --current .

# Search past solutions for similar problems
bin/find-solution.sh --type "race-condition" --tag "concurrency"

Where do artifacts live? The store-path.sh script resolves the storage directory using a three-level fallback:

  • $NANOSTACK_STORE environment variable, if set
  • .nanostack/ at the git repository root, if inside a repo
  • ~/.nanostack/ as the global fallback

This means artifacts stay with the project by default but can be redirected to a shared location for teams.

Hooks are enforcement

Hooks are the only mechanism the agent cannot bypass. They are declared in the SKILL.md frontmatter and enforced by the Claude Code runtime — not by the agent's own instructions.

hooks:
  PreToolUse:
    - matcher: Bash
      command: "./guard/bin/check-dangerous.sh"

When the agent tries to run a Bash command, Claude Code intercepts it and runs check-dangerous.shfirst. If the script exits with code 1, the command is blocked. The agent receives the script's stderr as an explanation of why the action was denied.

This is not a suggestion the agent might ignore. It is a hard gate enforced by the runtime. The agent never sees the blocked command execute.

Coordination is filesystem-based

When multiple agents run a sprint in parallel, they coordinate through files on disk. No process stays running between commands. No socket, no port, no IPC.

.nanostack/sprint/
├── sprint.json          # sprint state: phases, status, timestamps
├── lock/
│   ├── review/          # mkdir = atomic claim
│   │   └── owner.json   # { "agent": "claude-code", "pid": 42381 }
│   ├── qa/
│   │   └── owner.json
│   └── security/
│       └── owner.json
└── done/
    ├── review.json      # completed artifact reference
    ├── qa.json
    └── security.json

The coordination primitive is mkdir. On every POSIX system, creating a directory is atomic — if two processes try to create the same directory at the same instant, exactly one succeeds and the other gets EEXIST. This gives lock semantics without any external dependency. No Redis, no flock, no daemon. Just the filesystem doing what it already guarantees.

NextArtifact pipeline