voyage/tests/fixtures/synthesis/exploration/convention-scanner.md
Kjell Tore Guttormsen 6b30483304 feat(voyage): S12 — NW3 synthesis-agent built + measured → declined per measurement [skip-docs]
NW3 (CC-26 §6 PoC): delegate trekplan Phase 7 synthesis to a synthesis-agent,
adopt only if Δ main-context ≥30% with no quality loss. Operator chose the
deterministic-proof path (live ≥3-run bake-off was env-blocked: no API key;
installed plugin is a cache copy so a new agent is invisible to `claude -p`).

Decisive structural finding: trekplan Phase 5 runs the swarm FOREGROUND, so its
outputs are already resident in main before Phase 7. Delegating only Phase 7
evicts nothing → Δ_faithful = 0% (BASE-independent). The ≥30% saving needs an
out-of-scope Phase-5 redesign (swarm-writes-to-disk / nested orchestrator).
VERDICT: DECLINED per measurement.

- agents/synthesis-agent.md — dormant, schema-conformant deliverable (NOT wired)
- lib/plan/synthesis-digest-schema.mjs — digest output contract (+ tests)
- scripts/synthesis-measure.mjs — deterministic Δ-accounting core (+ tests)
- tests/fixtures/synthesis/ — 7 exploration outputs + representative digest
- docs/T1-synthesis-poc-results.md — measurement + verdict (reproducible)
- CLAUDE.md — agent table row (doc-consistency: 24 agents)

Tests 670 → 695 (693 pass / 2 skip / 0 fail). `claude plugin validate` clean
(only the pre-existing root-CLAUDE.md warning). commands/trekplan.md untouched.

[skip-docs] rationale: no user-facing feature ships (NW3 declined; agent dormant
and unwired). The substantive doc is docs/T1-synthesis-poc-results.md; the
README/CHANGELOG roll-up for NW1–NW3 is the S13 coordinated release per
docs/W1-narrow-wins-plan.md §S13.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LqBYc8Ltrk7LipyJmGxXiB
2026-06-18 17:58:39 +02:00

42 lines
1.7 KiB
Markdown

# Conventions Report — output of convention-scanner
Task: Add a per-wave concurrency cap to trekexecute headless launches.
## Summary
Mature, consistent conventions. New code should imitate the existing `lib/`
validators almost mechanically.
## Naming
| Element | Convention | Example |
|---------|-----------|---------|
| Files | kebab-case `.mjs` | `lib/profiles/profile-resolver.mjs` |
| Functions | camelCase, verb-first | `validateFindings`, `extractDigestBlock` |
| Error codes | UPPER_SNAKE, domain-prefixed | `FINDING_BAD_LINE`, `DIGEST_NOT_OBJECT` |
| Tests | `<module>.test.mjs` mirroring `lib/` tree | `tests/lib/profile-resolver.test.mjs` |
## Module shape (must follow)
Every `lib/` module is the **3-layer pattern**:
1. exported pure functions (validate/resolve/compute);
2. they return `{valid, errors, warnings, parsed}` via `lib/util/result.mjs`
`issue()`/`fail()`/`ok()`;
3. a CLI shim `if (import.meta.url === \`file://${process.argv[1]}\`)` for Bash.
A `max-parallel-resolver.mjs` must replicate this exactly (pure resolver +
`issue()` errors + CLI shim).
## Error handling
- Never coerce bad input — return a `{valid:false}` Result with a stable code and
a `hint`. Throwing is reserved for genuine programmer error (see
`mainContextTokens` "unknown arm" throw).
- Unknown/extra fields are tolerated (forward-compat), load-bearing fields are
hard errors. Mirror this: clamp/validate the cap, tolerate extra profile keys.
## Imports / tests / commits
- Named ESM imports, relative paths, no path aliases, no barrels.
- Conventional Commits, `type(scope): description`, e.g. `feat(voyage): …`.
- New behavior is TDD'd: failing `node:test` first, then minimal code.