Skip to main content

shikumi-devdoc

shikumi-devdoc is a library for growing specifications and design documents together with the implementation.

Developer documentation such as README, Specification, API Reference, and CHANGELOG is written not as standalone Markdown files, but as Python canonical source with meaning and structure.

It is intended for projects that want documentation to remain an authoritative source that is referenced and updated throughout development, rather than something organized only after implementation is complete.

Where it fits

shikumi-devdoc does not provide a particular development process by itself.

Instead, it provides a documentation foundation for development styles that place specifications and design at the center of the work.

For example, it can be combined with approaches such as:

  • Spec-Driven Development (SDD)
    Treat specifications not as temporary material written before implementation, but as an authoritative development source that evolves together with the implementation.

  • Docs as Code
    Manage documentation in the same repository as code, and treat changes, reviews, and history as part of software development.

  • LLM-assisted development
    Maintain the specifications, design, and constraints given to an LLM as development assets with meaning and structure instead of scattered prose.

In SDD in particular, the challenge is not merely writing a specification, but keeping the specification aligned with the implementation over time.

shikumi-devdoc provides a way to keep that authoritative source in Python so that it remains workable for both people and LLMs.

This project is its own sample

shikumi-devdoc uses shikumi-devdoc to manage its own README, Specification, API Reference, CHANGELOG, and other documents.

The canonical sources actually used by this project are under devdocs/canonical_sources/.

The following two examples show documents with very different characteristics.

README: prose-first documentation

Most of a README is ordinary prose.

Its canonical source can preserve that character directly.

from shikumi_devdoc.norms.common import IGNORE, canonical_source
from shikumi_devdoc.norms.document import test_target_field, title


example_source = test_target_field("example source")


@canonical_source(
    "{{project.name}}",
    filename="README.md",
    merge_policy="all",
    unreferenced_fields=IGNORE,
    heading="title",
)
class SECTION_001:
    r"""
    `{{project.name}}` は、仕様や設計文書を
    実装と一緒に育てるためのライブラリです。

    ```python
    {{example_source}}
    ```
    """

    example_source @= r"""
    from shikumi_devdoc.norms.common import canonical_source


    @canonical_source("Example", filename="example.md", merge_policy="local", heading="identity")
    class EXAMPLE:
        class Introduction:
            "Hello from shikumi-devdoc."
    """

    class SECTION_002:
        """このプロジェクト自身の文書も、この仕組みで管理しています。"""

        title @= "このプロジェクト自身がサンプルです"

The document hierarchy is represented by Python class structure, while the body can be written directly as docstrings.

There is no need to decompose prose-oriented documentation into unnecessarily fine-grained data structures.

You can keep a README free-form while giving meaning and structure only to the parts that need them.

Specification: documentation as a collection of items

A Specification has a different shape: the individual specification items matter as much as the prose itself.

This project's own Specification uses the same canonical-source mechanism.

from devdocs.canonical_sources.vocabulary.canonical import TERMS
from shikumi_devdoc.fields.specification import MUST, level
from shikumi_devdoc.norms.common import canonical_source, merge
from shikumi_devdoc.norms.document import title


@canonical_source(
    "Structured fields",
    filename="specification.md",
    order=50,
    merge_policy="local",
    heading="identity",
)
class SPECIFICATION_PART:
    class SPEC_001:
        """canonical root 内の class は {{TERM_006}} として解釈されなければならない。"""

        merge @= TERMS.TERM_006
        title @= "Class-derived document-node identity"
        level @= MUST

README and Specification look and behave quite differently.

One is centered on free-form prose; the other is a collection of semantically meaningful items.

shikumi-devdoc does not force both into one specialized document format. They use the same foundation while choosing a shape appropriate to each document.

README
  └─ free-form prose first
       └─ structure only where needed

Specification
  └─ collection of items first
       └─ meaning attached to each item

Specification and API Reference are not special document grammars.

They are built on the same canonical-source model by combining the meanings required by each document.

Referencing and inserting values

Templates in canonical source can reference separately held values as {{name}} instead of containing only fixed prose.

Those values can come from a field defined on the same node, a local reference brought in from another canonical source, or external context supplied at realization time.

Refer to a value defined on the same node

A field defined on a node with name @= value can be referenced as {{name}} from that node's docstring or other template-bearing content.

The example_source in the README example above uses exactly this mechanism. The code example is kept as independent literal text rather than duplicated directly in the prose, and the template references it where it should appear.

test_target_field can be used to separate code, configuration, commands, expected output, or other text that ordinary tests should reference directly. The sample code in this README is itself separated from the canonical source as a test_target_field; ordinary pytest tests compare it with the corresponding example module and then validate and render that module.

Separating a value with test_target_field does not automatically create or run a test, and it does not imply test coverage. What should be verified and how it should be verified remains part of the project's ordinary test design. test_target_field only makes the text an independent unit in the authoritative source that tests can address directly.

From another canonical source

An object from another canonical source can also be brought into the same node as a local reference.

Vocabulary, for example, uses this mechanism so that shared terminology can be defined once and reused across documents.

merge @= TERMS.TERM_001

Instead of copying terms and definitions directly into prose, documents can retain relationships between authoritative sources.

Vocabulary is one convenient use of this mechanism, but the mechanism itself is not specific to Vocabulary.

From external context

Values can also be supplied from outside the canonical source.

Typical examples include the current version shown in a README or other values determined at generation time.

canonical source
       +
external context
       ↓
     document

These values do not have to be frozen into the canonical source itself; they can be supplied as the context in which the document is generated.

Choose insertion channels with merge policy

Fields defined directly on the same node remain available to templates regardless of merge_policy.

merge_policy constrains two explicit ways of bringing values into template-bearing content:

  • local merge through merge @= ...
  • external context supplied at realization time
policy merge @= ... external context
all allowed allowed
local allowed not used
external not used allowed
forbidden not used not used

This README uses all because it uses both external context and local merge. The Specification uses local because it uses local merge without external context. CHANGELOG uses forbidden because it uses neither. These are choices about the insertion channels used by each canonical source; they do not determine the document type itself.

merge_policy also does not track the provenance of ordinary Python values. Once a value is bound directly on the node with name @= value, it is treated as that node's own field regardless of where the value originated before Python evaluated the assignment.

See the Authoring Guide and Specification for the exact rules of all four policies.

Extensible by design

The meanings and Markdown output provided by shikumi-devdoc are not the only possible uses of the model.

The library is built on Shikumi. See the Shikumi documentation for the underlying mechanisms for semantic annotation, structuring, validation, and realization.

On that foundation, shikumi-devdoc can be extended in two directions.

Express project-specific meaning

You are not limited to the meanings provided by shikumi-devdoc.

Project-specific descriptors can add meaning to the same canonical source.

For example, a development process can represent information such as Requirement, Risk, Decision, Owner, Component, or Review status.

Instead of adapting the project to a fixed document format, you can give documents the meaning that the project itself needs.

Produce formats other than Markdown

shikumi-devdoc provides a Markdown realizer.

When another format is needed, a custom realizer can be implemented using Shikumi's realization model.

Because the meaning held by canonical source is separate from the final output format, the same authoritative source can be used to produce other artifacts as well.

Minimal usage

Install from PyPI:

pip install shikumi-devdoc

A minimal canonical source needs only a root class and a nested class.

from shikumi_devdoc.norms.common import canonical_source


@canonical_source(
    "Example", filename="example.md", merge_policy="local", heading="identity"
)
class EXAMPLE:
    class Introduction:
        """Hello from shikumi-devdoc."""

Pass the module to the CLI:

shikumi-devdoc render document myproject.example -o build/

The generated Markdown is:

# Example

## Introduction

Hello from shikumi-devdoc.

From there, structured information, insertion, cross-document references, and other features can be added as needed.

@= notation and mypy

Shikumi itself does not require @=. shikumi-devdoc intentionally uses the shikumi.standard-style name @= value notation because it keeps canonical source readable as document source.

Checking this style with mypy requires an additional canonical-source-package setting. See STATUS_008 for the rationale, the configuration recipe, and the scope of the suppression.

Documentation

This repository's documentation is itself a working example of shikumi-devdoc.

Comparing canonical source with the generated documents shows how shikumi-devdoc is used in practice.

English documents at the repository root and under docs/ are produced by a separate publication workflow using the Japanese canonical documents as input. That translation and publication process is not itself a feature of shikumi-devdoc.

Version

Current version: 0.3.5

Supported Python: >=3.11

See STATUS.md for the current development stage and compatibility information.

License

shikumi-devdoc is available under the MIT License.

See LICENSE.

Metadata

Release files for shikumi-devdoc 0.3.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for shikumi-devdoc 0.3.5
File Size Uploaded
shikumi_devdoc-0.3.5.tar.gz 215.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for shikumi-devdoc 0.3.5
File Interpreter ABI Platform
shikumi_devdoc-0.3.5-py3-none-any.whl Python 3 none any Details

Total release size: 517.8 kB

Release files / shikumi_devdoc-0.3.5.tar.gz

Download URL shikumi_devdoc-0.3.5.tar.gz
Size 215.3 kB
Tags Source
SHA-256 checksum
How to use checksums
9683bfba68764c174acb37d5c9af1f4a600884cdd0a90bac8920dc737bfdab9a
BLAKE2b-256 checksum
How to use checksums
64860f305e1e967bb59f9e962b27bd2613c13e56ebdbe339aaf34a448bd3f895
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / shikumi_devdoc-0.3.5-py3-none-any.whl

Download URL shikumi_devdoc-0.3.5-py3-none-any.whl
Size 302.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
81370516ec2f5c5c12e1ad353b4c8bf2997c34b6a86777a49facf0e6c89ee5eb
BLAKE2b-256 checksum
How to use checksums
2777450b888fff720b0a847640c48a167d287ee558e8c43195cfed1c91e81d85
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.5 This release

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page