Skip to content

Tier 1 + Tier 2 improvements: docs, CI, tests, output flexibility - #1

Open
JTCneo wants to merge 15 commits into
kvarnelis:mainfrom
JTCneo:main
Open

Tier 1 + Tier 2 improvements: docs, CI, tests, output flexibility#1
JTCneo wants to merge 15 commits into
kvarnelis:mainfrom
JTCneo:main

Conversation

@JTCneo

@JTCneo JTCneo commented Apr 25, 2026

Copy link
Copy Markdown

Tier 1 + Tier 2 improvements: docs, CI, tests, output flexibility, failure handling

Motivation

deep-recon v1.0.0 is a strong skill but ships as a black box for forkers and a
black box for users when things go wrong. The README markets the workflow well
but doesn't help when an agent times out, a Synthesizer write fails, or a fork
produces generic-feeling output (the latter caused by a hardcoded reference to a
personal style guide in agents/synthesizer.md). This PR addresses those gaps
and adds the smallest amount of structure (CI, structural tests, CHANGELOG) the
repo can carry without losing its minimal character.

Changes

Tier 1 — Quick wins (docs, examples, CI hygiene)

  • CHANGELOG.md — Keep-a-Changelog format, retroactive entry for v1.0.0
    derived from release notes, Unreleased section captures everything since the
    v1.0.0 tag.
  • README — new Troubleshooting section (missing-document recovery,
    determinism expectations, partial-round failure, generic-voice fixes,
    metrics-after-compaction, cost guidance), new Documentation section
    pointing to CHANGELOG / TUNING / examples, and a Claude-Code-version-agnostic
    rewrite of the Architecture section (the prior "experimental in 4.6" framing
    is replaced with a forward-compatible explanation). New subsection clarifying
    that agents/*.md are prompt templates, not Claude Code agent definitions.
  • docs/TUNING.md — guidance for forkers on customizing the Synthesizer's
    voice. Surfaces the hardcoded _resources/Kazys Varnelis – Personal Writing Style Guide.md reference at agents/synthesizer.md:16 and gives three
    remediation paths (replace path / remove reference / parameterize).
  • examples/ — two illustrative recon outputs (Explore mode, Focus mode)
    plus a README explicitly marking them as illustrative, not best-of.
  • SKILL.md — added argument-hint frontmatter field (verified against
    current Claude Code 4.7 spec — all other frontmatter fields current and
    correct).
  • CI.github/workflows/lint.yml runs markdownlint-cli2 plus a
    SKILL.md frontmatter check (must have name, description,
    allowed-tools) plus a negative check (agents/*.md must NOT have YAML
    frontmatter, since they are prompt templates).
  • .markdownlint.json — config tuned to match the repo's existing style
    (MD040 disabled because the repo convention is plain ``` blocks).

Tier 2 — Meaningful upgrades

  • CONTRIBUTING.md — PR norms: triage path by change type, prompt-edit
    conventions (atomic / justify / before-after), local testing, style
    expectations matching the repo's existing register. Voice changes are
    routed to forks rather than upstream PRs.

  • Structural validator (tests/check_recon_structure.py,
    tests/run_smoke_tests.sh, tests/README.md) — Python validator (no deps)
    that asserts the output contract: required frontmatter fields, mode-specific
    section names, Territory cardinality (3–5 framings in Explore mode), Process
    Log + Central Question callouts, Obsidian flavoring (or the corresponding
    plain-mode invariants when --plain is set). Self-tests against examples/.
    Caught one real structural regression in focus-example.md (which has been
    fixed) on the first run.

  • --plain flag — Synthesizer produces CommonMark-only output (no
    [[wikilinks]], no > [!callouts]) for non-Obsidian environments (Logseq,
    Foam, plain GitHub markdown). Default Obsidian flavor is unchanged.

  • Per-agent model overrides--explorer-model, --associator-model,
    --critic-model, --synthesizer-model flags. SKILL.md's "Agent Model
    Selection" section is now operational rather than purely descriptive: the
    Task dispatch passes model: and resolution order is documented.
    Cost-conscious guidance: --explorer-model haiku is the safe single
    substitution; never substitute the Synthesizer.

  • --budget <tokens> flag — hard cap on total token spend. Orchestrator
    reads _metrics.md between rounds and aborts gracefully (writing the
    best-available draft) before exceeding the cap. Default behavior (no cap)
    is unchanged.

  • Failure handling in the orchestrator — six failure modes are explicitly
    handled:

    • One agent fails or times out → proceed with N–1 reports, log in Process Log
    • All agents fail in a round → skip to final Synthesizer with prior rounds'
      material
    • Synthesizer's final write fails → retry once, then orchestrator writes
      captured text directly, or writes a stub pointing at per-agent reports
    • _metrics.md write fails → log to stderr, continue
    • Web search empty → Explorer handles in its own prompt; orchestrator does
      not auto-fallback to --vault-only
    • User kills mid-round → do not auto-resume on next invocation

    Principle: substance survives. Agent reports on disk are the ground truth.
    The README's troubleshooting section is updated to match this new behavior.

Migration notes

This PR is fully backwards-compatible. Default behavior is unchanged:

  • No new required flags.
  • No changes to the four agent prompt files except agents/synthesizer.md,
    which gets a new "Plain Mode" subsection that only fires when --plain is
    passed.
  • The output template (templates/brainstorm-output.md) is unmodified.
  • Existing recon/ directories are untouched.
  • Existing _metrics.md files continue to be read and written in the same
    format.

For forkers: see docs/TUNING.md for the Synthesizer voice-tuning
guidance — this is the most important read after merge.

Risks

  • Orchestrator prompt is now ~50% larger (especially Tier 2's failure
    handling at +37 lines). Token-spend per recon goes up slightly. This is
    recovered by the new --budget cap if needed.
  • Untested behaviorally. Structural validator and lint config were verified;
    the skill itself has not been invoked end-to-end against these changes.
    Smoke-test recommended before merge: a default-mode recon, a --plain
    recon, a --budget test, and a model-override test.
  • Per-agent model override depends on the Task tool's model: parameter
    being supported in Claude Code 4.7. Verified against the current skills doc
    during T1.4.
  • The hardcoded _resources/Kazys Varnelis… reference is documented but not
    removed.
    This is intentional. Upstream should preserve the original
    author's voice tuning; forkers retune via docs/TUNING.md.

Rollback

Each commit is atomic and self-contained. To revert any single change:

git revert <sha>

To return the branch fully to upstream main:

git reset --hard origin/main

No external state is touched (no shared infrastructure, no published packages,
no production data).

Verification

End-to-end runs against a live vault would burn $5–$15 of Opus tokens per
pass. Instead, this PR ships a free verification harness that proves the
plumbing without the spend:

  1. Validator-contract tests (tests/test_validator_contract.py) — feeds
    the structural validator 10 stubs (3 valid, 7 intentionally malformed:
    missing section, framings under/over cardinality, missing frontmatter
    field, plain-mode wikilinks, plain-mode callouts, Obsidian-mode without
    wikilinks). Catches regressions that would silently weaken the validator.
    Wired into tests/run_smoke_tests.sh. 10/10 assertions pass.
  2. Static analysis — every smoke-test claim is traced to specific
    SKILL.md and agent-file lines (see table below).
  3. Mock walk — the --budget abort condition is exercised against a
    synthetic _metrics.md: cumulative=73k, projected_next=78k, cap=80k →
    abort fires correctly per SKILL.md:162-175.

Static traces — what wires what

Claim Wired at
Default Explore parse → dispatch → write-to-disk SKILL.md:21,76-86,222; example output passes validator
--plain propagates to Synthesizer; plain-mode rules enforced SKILL.md:41,258-264; agents/synthesizer.md:85-95; validator catches both wikilinks-in-plain and callouts-in-plain
--budget aborts gracefully SKILL.md:49,162-175; mock walk above; Process Log message format at SKILL.md:172
--explorer-model haiku dispatches Haiku SKILL.md:43-47,266-294; resolution order documented; Task call format specified as Task(model: <resolved>, ...)

Pre-merge checklist

  • Markdownlint CI workflow passes. (local: markdownlint-cli2 "**/*.md" → 0 errors across all .md files. See commit 69386d2.)
  • Structural validator self-tests pass. (local: bash tests/run_smoke_tests.sh — both example files OK.)
  • Validator-contract tests pass. (local: python3 tests/test_validator_contract.py — 10/10. New in this PR.)
  • SKILL.md frontmatter has all CI-required fields (name,
    description, allowed-tools).
  • agents/*.md have no YAML frontmatter (CI negative check).
  • Static analysis traces every flag to its handling code path
    (table above).
  • --budget abort condition mock-walked and verified.

Deferred to maintainer review (live-run-only)

These three claims are statically wired but cannot be verified without
running the skill end-to-end against a real vault. They are deferred for
maintainer review:

  • A real Explorer/Associator/Critic/Synthesizer dispatch returns
    per-agent reports on disk that the orchestrator then composes. Static
    trace says yes; runtime is the only proof.
  • Claude Code's Task tool accepts model: <id> as documented in
    SKILL.md:286-294. The skill is built to this contract; a smoke
    recon with --explorer-model haiku is the one-shot way to confirm.
  • Output prose actually matches the Synthesizer's voice rules — beyond
    the validator's structural pass.

Maintainer is welcome to run any subset of these against their own vault.
Suggested cheapest verification: one autonomous, vault-only, Haiku-on-all-
agents recon (~$0.50 in tokens) covers all three deferred items.

Commits (15)

  • Add CHANGELOG.md (T1.3)
  • Add Troubleshooting section, update Architecture for 4.7 (T1.1/T1.7/T1.8)
  • Add docs/TUNING.md for forker voice customization (T1.6)
  • Add examples/ directory with illustrative recon outputs (T1.2)
  • Add argument-hint to SKILL.md frontmatter (T1.4)
  • Add markdownlint CI workflow + config (T1.5)
  • Add CONTRIBUTING.md (T2.6)
  • Add structural validator for recon outputs (T2.4)
  • Add --plain output flag for non-Obsidian forks (T2.3)
  • Add per-agent model override (T2.5)
  • Add token budget guard --budget (T2.2)
  • Add failure handling to orchestrator (T2.1)
  • Update CHANGELOG with Tier 1 + Tier 2 additions
  • Tune markdownlint config to match repo voice; backtick placeholders
  • Add validator contract tests (T2.4 follow-up)

🤖 Generated with Claude Code

Jesus Tolentino Cortez and others added 15 commits April 24, 2026 18:34
Keep-a-Changelog format. Retroactive entry for v1.0.0 plus an
Unreleased section for the post-tag --pdfs commits.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…1.8)

- Troubleshooting section covers missing-recon recovery, determinism
  expectations, partial-round failure, generic-voice fixes, metrics
  after compaction, and cost guidance.
- Architecture section updated: the 4.6-specific agent-teams language
  is replaced with a version-agnostic framing of the subagents-vs-teams
  choice. The subagent + orchestrator pattern remains the right call
  until agent teams reach a deterministic-dispatch form.
- New subsection "A note on the agents/ directory" explains that the
  agent files are prompt templates (no frontmatter), not Claude Code
  agent definitions. This clarifies the design choice for forkers.
- New Documentation section pointing to CHANGELOG, TUNING, and examples.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The Synthesizer reads a hardcoded path in agents/synthesizer.md:16
(_resources/Kazys Varnelis – Personal Writing Style Guide.md) for
voice-matching. Forks of this skill silently degrade unless the
forker handles this. TUNING.md documents the issue and three
remediation paths (replace path, remove reference, parameterize),
plus guidance on writing a personal style guide and verifying it
worked.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two synthetic examples (Explore mode and Focus mode) plus a README
making clear they are illustrative, not real. Real recons vary in
length and quality based on vault context, mode, and Synthesizer
voice tuning. Examples follow the templates/brainstorm-output.md
structure exactly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Verified against current Claude Code 4.7 skill spec — name,
description, allowed-tools, and user-invocable are valid as-is
and no required fields were missing. Added argument-hint as a UX
improvement: surfaces the skill's flag set (--autonomous, --focus,
--vault-only, --pdfs, --output) to the user at invocation time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI runs on push and PR to main:
- markdownlint-cli2-action over **/*.md
- Frontmatter check: SKILL.md must have name, description, and
  allowed-tools fields
- Negative check: agent files must NOT have YAML frontmatter
  (they are prompt templates, not agent definitions — see README
  architecture note)

.markdownlint.json disables MD013 (line length, prose style),
MD040 (fenced-code language hint — repo convention is plain ```),
MD041 (first line must be h1 — example files have YAML frontmatter
first), and tightens MD024 to siblings_only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sets PR norms for the skill repo. Covers: triage path by change
type (bug / feature / voice / architectural / docs), prompt-edit
conventions (atomic changes, justify additions, before/after),
local testing requirements, style expectations matching the
repo's existing register, commit-message format, and issue
content guidance.

Specifically routes voice/personal-style changes to forks
(not upstream PRs) per docs/TUNING.md, and reserves architectural
changes for issue-led RFC discussion.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tests/check_recon_structure.py asserts the output contract:
required frontmatter fields, mode-specific section list,
Territory cardinality (3-5 framings in Explore mode), Process
Log + Central Question callouts, Obsidian flavoring (wikilinks),
or the corresponding plain-mode invariants when --plain is
passed.

tests/run_smoke_tests.sh exercises the validator against the
example files in examples/. Caught one structural regression in
examples/focus-example.md (## Tensions Worth Preserving →
## Tensions), now fixed.

This is structural validation only. It catches prompt-edit
regressions that change the shape of the output. It does not
assess prose quality, voice match, or content fidelity.

tests/README.md documents the validator's scope, how to run it
locally and in CI, and how to add golden snapshots from real
recon runs over time.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SKILL.md:
- New flag in Step 1 (input parsing): --plain
- Updated Formatting section with default vs --plain rules
- Updated argument-hint
- Pass-through to Synthesizer in dispatch

agents/synthesizer.md:
- New "Plain Mode" subsection in "For the Final Round" — documents
  the substitutions for wikilinks, callouts, and the Process Log /
  Central Question structures. Frontmatter and footnotes remain
  unchanged (both are CommonMark-compatible).

README.md:
- New row in Modes table for --plain.

Default behavior (Obsidian-flavored) is unchanged. The validator
in tests/check_recon_structure.py already supports --plain via
its own --plain flag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step 1 of input parsing now accepts --explorer-model,
--associator-model, --critic-model, --synthesizer-model flags.
The Agent Model Selection section is now operational rather than
purely descriptive: defaults are tabulated with rationale, the
Task dispatch syntax shows where model is passed, and resolution
order is documented (per-agent flag → repo config → default).

Cost-conscious guidance: --explorer-model haiku is the safest
single substitution. Maximum-quality guidance: opus across all
four roughly 4-5x cost.

The argument-hint deliberately omits the per-agent model flags
to keep it readable; they're advanced/rare.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Step 1 of input parsing accepts --budget <tokens> (numeric or 1m
shorthand). New "Budget Check" section between rounds reads
_metrics.md, estimates next-round spend from prior round, and
short-circuits to the final Synthesizer path if the next round
would exceed the cap.

Failure semantics: produce the best available draft from
already-collected agent reports, not abort mid-recon. The
budget abort is logged in the Process Log so the user sees what
happened and which round the recon stopped at.

Default behavior (no cap) is unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SKILL.md gets a Failure Handling section covering:
- One agent fails or times out: proceed with N-1 reports, log the
  failure in the Process Log
- All agents fail in a round: skip to final Synthesizer with prior
  rounds' material, or write a stub explaining the failure
- Synthesizer's final write fails: retry once, then orchestrator
  writes captured text directly, or writes a stub pointing at the
  per-agent reports on disk
- _metrics.md write fails: log to stderr, continue
- Web search empty / errors: Explorer handles in its own prompt;
  orchestrator does NOT auto-fallback to --vault-only
- User kills mid-round: agent reports may land async; do not auto-
  resume on next invocation

Principle: substance survives. Agent reports on disk are the
ground truth; the final document is built from them; anything
else is auxiliary and recoverable.

README troubleshooting updated to match the new behavior (the
prior "does not currently handle partial-round failures" caveat
is removed) and the cost-control section now references --budget
and --explorer-model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Captures everything in the deep-recon-improve branch under
[Unreleased]: new flags (--plain, --budget, per-agent --*-model),
argument-hint frontmatter, examples/, docs/TUNING.md,
CONTRIBUTING.md, tests/, lint CI, README Troubleshooting and
Documentation sections, and the orchestrator failure-handling
behavior.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The CI lint workflow added in T1.5 would have failed on first push (87
errors). The default markdownlint rules disagree with the repo's existing
voice in five places — heading/list spacing, blockquote blanks, fenced-code
blanks, table pipe style. Disable those rules so the existing markdown
passes without rewriting it.

Three remaining MD033 violations in SKILL.md were real: angle-bracket
placeholders (<tokens>, <agent>, <N-failures>, <timestamp>, <output_dir>)
inside quoted log-message templates were being parsed as HTML. Backticked
them — they ARE template placeholders, so code formatting is the right
shape.

Verified: markdownlint-cli2 reports 0 errors across all 14 .md files.
Structural validator still green on both example outputs.
The structural validator passes against the example files, but that only
asserts the examples conform to the contract — it does not assert the
contract is real. A future edit that loosens the validator (e.g., relaxing
the cardinality check, dropping the plain-mode invariants) could land
silently because the examples would still pass.

This commit adds tests/test_validator_contract.py, which feeds the
validator 10 stubs (3 valid, 7 intentionally malformed) and asserts the
expected errors fire:

  - missing The Territory section
  - 2 framings (under floor of 3)
  - 6 framings (over ceiling of 5)
  - missing required frontmatter field
  - plain mode containing wikilinks
  - plain mode containing callouts
  - Obsidian mode without any wikilinks
  - plus 3 valid cases (Obsidian Explore, Plain Explore, Obsidian Focus)

Wired into tests/run_smoke_tests.sh so it runs alongside the example self-
tests. Updates tests/README.md and CHANGELOG.md.

Cost: ~$0 to run; ~50ms wall-clock; no third-party dependencies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant