Engineering agent-design 16 min read

HUMAN_INPUT Autofill Design: Classify SSOT vs. Experiential Facts

Two HUMAN_INPUT types: SSOT values filled by machine, experiential facts left for humans. This split scales your pipeline.

Published 2026-05-27 森本拓見

HUMAN_INPUT Markers in 30 Seconds

When an AI writing skill generates article body text, it leaves placeholders like <!-- HUMAN_INPUT: description --> wherever the actual value is unknown — numbers, proper nouns, experiential facts, and so on. These are HUMAN_INPUT markers. Since they are meant to be filled in by a human later, the pre-publish gate (G1) checks for any remaining markers before publication. This article covers the design for classifying which markers can be filled mechanically from SSOT and which can only be written by a human.

Not every HUMAN_INPUT marker left in a writing skill’s output needs to be filled by a human. The 2026-05-19 pipeline retro revealed that HUMAN_INPUT markers fall into at least two distinct types. Once classified, the machine-fillable range can be processed first, leaving only the values that genuinely require human judgment. This article covers the classification criteria, the design of the SSOT mapping table, and the placement of the blog-fill-ssot skill within the pipeline.


Two Types of HUMAN_INPUT — SSOT-Sourced vs. Experiential Facts

SSOT-Sourced Examples: Member Count / Skill Count / Founded Date / Retro Failure Cases

SSOT-sourced HUMAN_INPUT values have confirmed data that exists within the repo.

  • Member count: array length from src/config/members.ts
  • Skill count: output of ls .claude/skills/
  • Agent count: output of ls .claude/agents/
  • Founded date: company.founded in src/config/brand.ts
  • Retro-derived failure cases: list of blog-ops/retros/*.md files

26

In the 2026-05-19 retro, 4 out of 26 HUMAN_INPUT markers were identified as SSOT-sourced and auto-filled. The breakdown was: skill count / agent count / founding information / 2 retro-derived failure cases. All of these were confirmed values retrievable by simply grepping specific files in the repo.

Experiential Fact Examples: Cost Figures / KPI Results / Decision Background / Stage Evaluation

Experiential facts do not exist in any SSOT. They depend solely on the author’s memory and judgment.

  • Cost figures: financial data such as monthly external service expenses
  • KPI results: measured traffic numbers and conversion rates
  • Decision background: the reasoning behind why a particular architecture was chosen
  • Stage evaluation: rationale for MVP / beta / production judgments

Attempting to auto-fill these would constitute fabrication. Filling in values without confirmed sources is equivalent to injecting misinformation into the article body — misinformation that slips through the quality gates.

Classification Logic: If It Exists in SSOT, Fill by Machine

The decision flow is as follows:

  1. Match the HUMAN_INPUT marker’s key (id) against the SSOT mapping table.
  2. If the mapping table has a corresponding source entry → auto-fill as SSOT-sourced.
  3. If not found in the mapping table → leave as HUMAN_INPUT (treat as experiential fact).
  4. If found in the mapping table but the retrieved value is empty or undefined → leave as HUMAN_INPUT (do not fill with ambiguous values).

This decision can be executed deterministically. Rather than pulling “plausible values” through semantic search like RAG, it supplements only verified values through explicit key-to-source mapping.


Designing the SSOT Mapping Table

Explicit KEY → SSOT Location Mapping Is Optimal at Current Scale

The SSOT mapping table has the following structure:

mappings:
  member_count:
    source: src/config/members.ts
    query: "array length of members"
    type: integer
  skill_count:
    source: .claude/skills/
    query: "file count via ls"
    type: integer
  founded_year:
    source: src/config/brand.ts
    query: "company.founded"
    type: string
  retro_failure_examples:
    source: blog-ops/retros/
    query: "list of *.md file titles (latest N)"
    type: list

This mapping table is stored as blog-ops/config/ssot-mapping.yaml. By keeping it as the single canonical file that all skills reference, adding new SSOT sources requires only one update to propagate across all skills.

Four Sources: brand.ts / members.ts / ls .claude/ / retros/

The current SSOT sources are the following four:

  1. src/config/brand.ts: Basic company information (founded date / business domain / positioning)
  2. src/config/members.ts: Member information (name / role / join date)
  3. ls .claude/skills/ / ls .claude/agents/: Actual count of implemented skills and agents
  4. blog-ops/retros/: Accumulated retros (list of failure cases and learnings)

All four sources have explicit schemas that require no natural-language querying. Deterministic mapping retrieves values with greater precision and zero additional cost compared to introducing RAG.

Why Deterministic Mapping Beats RAG: Lower Cost, Higher Precision

RAG (Retrieval-Augmented Generation) is effective when the query is ambiguous. But for a task like “return the array length of members.ts for the key member_count,” semantic search is unnecessary.

Deterministic mapping has the following advantages:

  • Zero mis-fills: No fill unless the key matches exactly, so incorrect values never enter the article.
  • Zero cost: No API calls needed — just file reads.
  • Easy to debug: The mapping table makes it immediately clear where every value came from.
  • Easy to extend: Adding a new SSOT source requires just one line in the mapping table.

Designing the blog-fill-ssot Skill

Pipeline Placement: After Write Completes, Before Review Launches

The blog-fill-ssot skill sits between the “write → review” stages in the pipeline:

write (blog-tech-write / blog-case-write)

fill-ssot (blog-fill-ssot)  ← SSOT-sourced values are machine-filled here

review (blog-review)  ← review runs with experiential HUMAN_INPUT still present

By machine-filling SSOT-sourced values before review launches, reviewers (or human reviewers) no longer need to check whether each marker could have been machine-filled. The review stage can focus entirely on verifying experiential facts and enforcing quality gates.

Three Principles of Autofill: SSOT-Confirmed / Leave HUMAN_INPUT / No Ambiguity

The blog-fill-ssot skill follows exactly three principles:

  1. SSOT-confirmed only: Fill only when the mapping table has a corresponding source and the value can be confirmed.
  2. Leave HUMAN_INPUT: If not found in the mapping table or the value cannot be retrieved, leave {{HUMAN_INPUT: ...}} as-is.
  3. No ambiguity: Never write hedged values like “several people,” “a few times,” or “years ago.” If the value is uncertain, leave it as HUMAN_INPUT.

These three principles are derived directly from “Learning 4” in the retro. They represent the minimal defense for eliminating fabrication risk.

Integration with {{HUMAN_INPUT: id - hint}} Placeholder Format

HUMAN_INPUT markers output by writing skills use the following format:

{{HUMAN_INPUT: member_count - number of Yakumo members (confirm in members.ts)}}

blog-fill-ssot matches the id field (in this case, member_count) against the SSOT mapping table. If the match succeeds, the placeholder is replaced with the actual value. If it fails (indicating an experiential fact), the placeholder is left as-is.


Summary — Defining the Machine-Fillable Range Enables Scale

Explicit Classification Eliminates Mechanical Edits from the Opus Main Thread

Before the 2026-05-19 retro, the main thread (Opus) was manually grepping SSOT and replacing HUMAN_INPUT every time. This approach had three problems:

  1. It violated the principle that “Opus is judgment-only; bulk writing and mechanical edits go through skills.”
  2. As article count grew, main thread costs scaled linearly — no scale.
  3. “Which SSOT to check” depended on main thread context memory, making it unreproducible in a fresh context.

The SSOT mapping table and blog-fill-ssot skill delegate this mechanical work to a skill. The main thread no longer needs to ask “can this be retrieved from SSOT?” on every run.

Next Implementation Steps: Expanding the Mapping Table and Applying Skills at Scale

The current SSOT mapping table covers 4 sources, but as article topics expand, more keys will be needed. The extension process is straightforward:

  1. When a new HUMAN_INPUT key begins appearing repeatedly, add it to the SSOT mapping table.
  2. Specify the corresponding source (file path / command).
  3. From the next blog-fill-ssot run onward, it is automatically included in the fill scope.

A scalable system is not “fully automated.” The design explicitly defines what the machine can fill and delegates only that range to the machine. Experiential facts that require human judgment remain as HUMAN_INPUT until the end, prompting the author to decide. That is the fundamental structure for maintaining quality without fabrication.