Diffing each retrofitted SKILL.md against its replacement references/ files found
rules that existed on main and now existed nowhere — relocated in intent, deleted in
fact. A trim that loses a rule is not progressive disclosure, it is data loss with a
smaller word count.
Three had no survivor. The least-privilege guidance for `tools` kept its mechanics
and lost the "restrict to what the agent needs" half, so the remaining text read as
encouragement to omit the field. The improve flow lost its regression check, so
nothing compared the closing audit against the pre-edit state and a PASS quietly
becoming a SUGGESTION went unnoticed — restored on both halves of the author pair,
since agent-author had dropped its equivalent too. And agent bodies lost "would the
agent get this wrong without it?", which mattered more than it looks: ADR-0020
deliberately sets no body word gate for agents, three of the four already sit
between 933 and 1,199 words, and the delegation check only fires on procedure a
skill already owns. That heuristic was the only brake left.
Two more were reachable only from the wrong scope. agent-author tells the reader to
load only the file for the resolved scope, but the mcp__ glob syntax for
disallowedTools and the five tools no subagent ever receives had both landed in
project-user-scope.md. disallowedTools is the ONLY permitted fence at plugin/APM
scope, so the scope that needs the syntax most could not reach it, and a plugin-scope
run could write a body telling the agent to ask the user a question.
Two documents were actively wrong rather than merely thin. agent-audit told auditors
that validate.sh resolves boundary targets for skills only; it runs at both scopes,
so the auditor was hand-resolving what the script had already decided and could
contradict it. And skill-audit routed to its script-troubleshooting reference
whenever validate.sh "fails" — but it exits 1 on ordinary content FAILs, the normal
outcome for the whole #99 population, so 1,302 words loaded on nearly every audit.
A context-budget regression inside the skill that enforces the context budget.
Finally, two illustrations taught the shape the gate ERRORs on, unfenced, while an
adjacent rubric called it a hard ERROR.
LESSONS.md records the reference-chain depth rule flipping from "one level deep" to
"two hops, never three". ADR-0020 is silent on it and the reversal rode entirely on
the diff; the looser rule is what mandatory dispatch requires.
Refs: #99
ADR: 0020
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015W3iwF9ncfRZddGBxsMCYi
The ADR was written against base commit `f9b919d` and then not updated as the
implementation moved, so several of its numbers were measuring one thing and being
read as another — the exact conflation the ADR exists to stop, reproduced inside
it. Corrections, all reproducible now that each figure states its method:
- The preload tax is 23,427 chars / ~5,900 tokens, not 23,612 / ~6,200.
- `MAX_WORDS=2770` is a density proxy for the agentskills.io ~5,000-token ceiling,
not "2× p90". Neither percentile reaches it: 2× the body-only p90 is 2,698 and
2× the whole-file p90 is 3,052. Reading it as a percentile pairs a whole-file
gate against a body-only distribution.
- `apm-workflow` is a 421-word body; 554 is its whole-file count. `skill-author`
and `agent-author` were 2,623 and 2,582 body words — 2,760 and 2,758 whole-file,
which is where "within twelve words of the gate" comes from. Two numbers for one
file is the point, and only one of them is what either gate measures.
- Every `file:line` citation now says it resolves against `f9b919d`, since this
change rewrites most of the cited files.
Three things the ADR asserted that no validator implemented are now filed by tier
in an exhaustive enforcement table — deterministic, prose-pattern, or auditor
judgment — because a rule filed under "Enforcement" that nothing enforces is the
failure mode this ADR is most exposed to. The Gotchas entry count moves to
SUGGESTION to match the script; the paraphrase FAIL is marked as an auditor's,
since semantic equivalence is not pattern-matchable.
Two gaps recorded rather than quietly left:
- The agent body-gate exemption lives in `agent-audit`'s validator and in the
`skill-size-check` hook's `SKILL.md`-only `files:` pattern — *not* in
`scripts/skill-size-check.sh`, which measures whatever path it is handed and
today reports 900-word body FAILs on `git-orchestrate` (933),
`gitea-orchestrate` (1,199) and `apm-orchestrate` (1,080). Agents escape by file
pattern, not because the script knows the difference, so widening that pattern
would silently enforce a gate this ADR declines to set.
- The `skill-audit`/`agent-audit` merge is deferred to #101. This change made the
split deeper, not shallower: the dispatch retrofit took them from 3 and 4
reference files to 7 and 8, and their two same-named `description-quality.md`
files now differ on 100 of ~120 lines after normalising skill/agent. The merge
reopens ADR-0008 and touches every call site in `skill-author`, `agent-author`
and `forge`, so it is its own change. #100 carries the dangling-target fixes.
AGENTS.md and CONTEXT.md take the same corrections plus the two live setup
changes: PyYAML is now a hard requirement rather than an optional accelerator (a
fallback that mis-parses an unfamiliar scalar shape reports a clean pass on a file
it never measured), and `.claude/settings.json`'s `pretty-format-json` exclusion is
documented as load-bearing rather than as a tidy-up candidate.
LESSONS.md's autofix entry is corrected on its own provenance, which it got wrong
in both directions. `git log --date=iso` puts the introducing commit at 18:47 and
the fix at 21:54 — three hours, not "weeks" — and `git branch -a --contains` puts
the introducing commit on this branch only, not on main. It was manufactured
inside the same PR that diagnosed it. The added lesson is that "pre-existing" is a
claim about history and history is queryable: a defect found while working on a
branch feels inherited, and the feeling is not evidence.
Refs: ADR-0020, #99, #100, #101
Two pre-existing failures, both red at HEAD before ADR-0020 work began,
both invisible in an ordinary local run.
RUN_TESTS_STRICT leaked from the environment into test-run-tests.sh's
fixture children. The meta-test is itself a suite the runner discovers,
so under the gate's own invocation the variable propagated outer runner
-> batch_run -> the fixture's copy of run-tests.sh, flipping it strict.
Case 10c (a deliberate control asserting a skip is tolerated WITHOUT
strict) then failed. Six further cases were silently running strict too
and asserting against the wrong stream — case 9 was matching the stderr
strict block rather than the stdout skip list it was written to check.
run_fake now spawns via 'env -u RUN_TESTS_STRICT', so fixture strictness
is a property of the case, never of how the file was launched. No
assertion weakened; run-tests.sh itself is untouched.
pretty-format-json --autofix was re-sorting apm's output on the way into
every commit. .claude/settings.json is apm-owned (ADR-0018/0019) and its
exclude list named fifteen generated manifests but not this file, so
since 2e395a4 it has been committed in a key order apm would never write
— permanent drift on a file with an empty git diff. Content was always
byte-identical; only JSON key order differed. The exclude ships in the
same commit as the corrected file because otherwise the hook re-breaks
it during staging.
apm.lock.yaml: generated_at churn, plus lint's exec_status corrected from
'deployed' to 'gated_pending_approval' — executables.allow grants only
kyberforge#1.5.0, so lint's hooks/bin are genuinely gated.
New coverage: an ambient RUN_TESTS_STRICT must not reach a fixture that
did not ask for it, and under --strict the skip report goes to stderr
only with the stdout list suppressed. Neither was pinned.
Skill name+description pairs are preloaded into every session, costing
~6,200 tokens across 39 skills before any skill is invoked. The authoring
rules mandated that growth: skill-author:104 and description-quality.md:21
both required padding, while skill-author:102 (the deflating rule) had no
FAIL condition behind it.
Gates (blocking, no baseline file):
- description 250 chars SUGGESTION / 400 FAIL, measured on the folded
YAML value
- body-only 600 words SUGGESTION / 900 FAIL, independent of the unchanged
whole-file 2770-word / 500-line spec backstop
- every boundary-clause routing target must resolve to a real skill or
agent; catches skill-improve, neuledge-context and gitea-labels
- agents take the description gates but deliberately no body gate; a test
pins that absence
Vale: DescriptionOpener widened to ^This\b, new CompositionNote rule
banning architecture notes from descriptions. 10 hits, 0 false positives.
Kyberforge's own four skills retrofitted: descriptions 3,364 -> 938 chars
(-72%), bodies 8,306 -> 2,487 words (-70%), all via the apm-workflow
dispatch pattern. Fixes the skill-improve dangling route and the
agent-author misroute to manual review.
Also fixes a pre-existing false positive where any line-initial 'read '
was flagged as interactive input, which had already caused two scripts to
be rewritten around it.
Refs: ADR-0020
AGENTS.md told an offline agent to push with SKIP=apm-marketplace-check and
asserted that hook was "the only one whose failure mode is 'no network'".
Running all 12 pre-push hooks under a network namespace shows two fail, for
one shared cause: apm-pack-check-clean resolves the same remote entry. An
exact pin does not remove the ls-remote, so both hooks are named now.
AGENTS.md also said everything in a plugin root except .apm/ is generated.
Plugin roots carry hand-authored README.md, docs/, bin/, sources.md and
.mcp.json, so an agent would hunt for an .apm/ source that does not exist or
refuse the edit. The rule is positional: immunity belongs to the plugin root,
and anything inside a mirrored directory is still rm -rf'd.
ADR-0017 said apm strips a hooks field. The real loop is (agents, skills,
commands, instructions) -- hooks absent, instructions never mentioned -- and
it can never fire, because synthesize_plugin_json_from_apm_yml only emits the
eight identity fields. The decision stands; the mechanism was overstated. Its
mcpServers amendment is rewritten for the pointer payload and now records the
real reason: inlining bypassed apm's credential sanitizer.
ADR-0015's owner.email and version-pin passages are corrected against the apm
source, and ADR-0016 gains the disallowedTools amendment. agent-audit's
allowlist is data, so it gains disallowedTools too -- the ADR and the
validator that enforces it had come apart.
architecture.md described a root CLAUDE.md that imports two files (it imports
one, plus an RTK block) and pointed at an ADR index that does not exist.
Seven skill READMEs listed tests/ files the mirror strips, promising installed
users files their install lacks; those rows are marked source-only, with the
depth-4 template tests explicitly called out as surviving. And
plugins/kyberforge/hooks/README.md, deleted during the conversion and
preserved nowhere, is restored to a path the mirror does not own -- verified
by running a sync against a scratch copy.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7GvKuJfy2WrdBmUttV4DT
The first is new: four fixes specified by the orchestrating reviewer were wrong,
each in a way that would have shipped a guard catching nothing. A finding arrives
with evidence and gets scrutinised; the fix beside it arrives with the same
authority and gets implemented. Worth naming because the failure is silent — the
guard looks right and the suite stays green.
The second is flagged as a graduation candidate rather than promoted: it overlaps
two 2026-08-09 entries on assertions that pin something adjacent to what they
name. Per the graduation rule, promotion to core/instructions/testing.md is the
human's call, not mine.
Refs: #95
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X7GvKuJfy2WrdBmUttV4DT
The apm conversion (5e23250) moved skills/agents to plugins/<name>/.apm/
and deleted plugin-author/marketplace-author, but a review against issue
#90's Definition of Done found several stale pre-conversion references
left behind by straight git-mv's, plus one real content gap:
- ADR-0014 still documented the old flat vale-prefilter paths in 6
places, despite ADR-0015 claiming it had been updated.
- ADR-0015 also overclaimed: it said ADR-0014 had both a skills/ and an
agents/ path regex updated, but ADR-0014 never had an agents/ path
regex to begin with (its one "agents" mention is a Vale glob-section
identifier, not a filesystem path). Corrected the wording.
- CONTEXT.md's Skill glossary entry, its Vale-prefilter section, and its
plugin-author/marketplace-author forward-pointer all still described
the pre-conversion layout or a "pending issue #90" state that has since
landed.
- LESSONS.md and two skill test READMEs pointed at skill-author/
skill-audit/agent-author paths without the .apm/ segment.
- apm-workflow/references/marketplace.md cited plugin-author/SKILL.md's
Gotchas for the Claude Code reserved plugin-name-prefix list, but that
list was never actually carried into apm-workflow during the
conversion despite ADR-0015 claiming it was. Recovered the list from
git history and inlined it directly rather than leaving a dangling
citation.
- agent-author/references/deployment-modes.md had an example
contradicting its own stated .apm/agents/ convention two lines above.
Refs: #90
The aggregate-assertion failure joins the "a clean result can mean nothing ran"
family as its fifth instance: a total over N subjects is satisfiable by a
proper subset, so it proves nothing about any individual subject. Records the
reverse mutation sweep — neuter each assertion, confirm exactly one case fails
— as standing practice for checks whose failure mode is silence.
The second entry is about accepted residuals: the U+2019 rewrite survived
review because its justification was documented in the same breath as the
workaround, and the covering test asserted the residual's presence rather than
the behaviour it cost. Documentation records a belief; a belief adjacent to a
workaround is the one most worth attacking.
Refs: #85
A config's local mode can prove nothing about the mode that ships:
repo: local collapses the clone prefix, cwd and repo root into one
directory, so a byte-identical entry: string worked locally for a
reason that exists only locally, through three review rounds.
Deleting a token from a shared artifact breaks whatever parses it,
silently: dropping --config killed the loop that gave the bundled
Vale styles release coverage, shrinking a derived path list with no
error and no failing test.
Kept separate from the adjacent "clean linter result" and "one signal,
two consumers" entries, which describe different failure modes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
A review of PR #85's last two commits (1164f3a, 4d018af) found the new
release-gate script fails open in four separate ways, and the new drift
check for the duplicated Vale styles only ever detects drift after a
human already hand-edited both copies out of sync.
check-release-needed.sh:
- The `-e` existence filter dropped a RELEASE_PATHS entry from the diff
pathspec once it was deleted from the tree, so deleting a path exposed
via .pre-commit-hooks.yaml since the last tag passed the gate clean —
exactly the breakage the gate exists to catch. git diff reports
deletions fine without an existence check; the filter is gone.
- `git diff ... 2>/dev/null || true` turned any git failure (a shallow
clone missing the tag's objects, a corrupted ref) into an empty,
falsely-clean diff. The diff result is no longer swallowed: a failure
now hard-fails with the underlying git error visible.
- RELEASE_PATHS was a hand-maintained array duplicating
.pre-commit-hooks.yaml's entry: paths with only a comment holding them
in sync, and was already over-broad (it swept in validate.sh /
validate-provenance.sh, which no hook entry references). It's now
parsed straight from .pre-commit-hooks.yaml's entry: lines at
runtime, so it can't drift from the manifest and only tracks what a
hook actually exposes.
- `git describe --tags --abbrev=0` accepted any tag reachable from HEAD
as the diff baseline, not just release tags. Added
`--match 'v[0-9]*.[0-9]*.[0-9]*'` so an incidental checkpoint tag
can't shift the baseline and mask a real release-relevant change.
check-vale-style-sync.sh still only detects drift between skill-audit's
and agent-audit's duplicated vale-wrap.sh/styles/Kyberforge copies
(both copies must exist independently per the plugin's no-cross-skill-
path packaging rule — a symlink would break at install time). Added
scripts/sync-vale-styles.sh to regenerate skill-audit's copy from
agent-audit's canonical one on demand, and pointed the sync check's
failure message at it, so fixing drift is one command instead of a
hand diff across two files.
Also recorded, rather than silently left unfixed: check-release-needed.sh
only fires on a local `git push` through pre-commit's pre-push hook — a
PR merged via Gitea's merge button, or CI invoking
`pre-commit run --hook-stage pre-push` directly, never sets
PRE_COMMIT_REMOTE_BRANCH and skips the gate entirely. Closing that needs
a server-side CI job this repo doesn't have yet; documented as a known
limitation in ADR-0014 rather than papered over.
Separately, LESSONS.md's "a clean check can mean nothing ran" entry was
marked **Graduated** without ever being promoted per the repo's own
graduation rule (3+ instances → a standing doc, marked
`[graduated → target file]`). Actually promoted it into
core/instructions/testing.md and fixed the marker.
tests/test-check-release-needed.sh gained 4 regression tests, one per
check-release-needed.sh fix above, each verified to fail against the
pre-fix script and pass against the current one.
Verification: bash tests/run-tests.sh (11 scripts + 125 bats, all
passing), pre-commit run --all-files, and
pre-commit run --all-files --hook-stage pre-push all clean.
ADR: 0014
skill-audit/agent-audit's Step 1 resolved vale-wrap.sh/.vale.ini via
`git rev-parse --show-toplevel`, which returns whichever repo the skill
happens to run in. Inside ai-development that works; in any external repo
that installs kyberforge@holocron as a plugin, it resolves to that repo's
own root, which has no .vale.ini — the prefilter silently fell back to
full LLM judgment. ADR-0013 named this as a deliberately deferred gap.
Vale's config/styles/wrapper now ship inside the plugin itself: a
canonical copy in agent-audit/assets/vale/ (Kyberforge + KyberforgeCopilot,
the superset agent-audit needs) and a smaller duplicate in
skill-audit/assets/vale/ (Kyberforge only) — per the no-cross-skill-path
rule already established for plugin cache-installs. Both skills resolve
these relative to their own directory, same as scripts/validate.sh
already does.
A new root .pre-commit-hooks.yaml exposes both copies plus
skill-size-check so any external repo can enforce the same rules via
`repo: <this-repo-url>, rev: <tag>` in its own pre-commit config,
independent of Claude Code entirely — the same mechanism covers CI. This
repo's own pre-commit hook now consumes the identical plugin-bundled
copies via repo: local (not a third root copy, and not a pinned
self-reference, which would lint working-tree edits against the last
tagged release instead of the change being made). Split into
vale-audit-prefilter-skill/-agent hooks after confirming, by diffing the
full corpus against both old and new config before deleting the old
files, that one combined hook pointed at only one copy silently 0-file-
skips the other file type.
scripts/check-vale-style-sync.sh guards the two copies against drift,
wired at pre-push alongside check-manifests.
ADR: 0014
Three rounds of review on the Vale prefilter surfaced patterns worth
keeping rather than just fixing.
The first has now recurred three times in a single PR — a check reporting
success because it had silently not run — so it is flagged as a
graduation candidate per LESSONS.md's own three-instance rule.
- A clean linter result can mean "nothing was checked": the frontmatter
scope silently not matching, warning-level rules never affecting an
exit code, and globs matching zero files all produced green results
that were then cited as evidence of cleanliness.
- One signal, two consumers, no named distinction: Vale severities were
tuned for the audit report while the commit gate silently inherited the
resulting exit code, because CONTEXT.md described both as one mechanism.
- Measure a rule's false-positive rate at the severity you will ship it
at: VagueQualifier was trialled at warning, where a false positive is
free, and shipped at error, where it costs a blocked commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCQ648fLSFXPHGZdQ8gn58
## Why
ROADMAP.md was a static file that duplicated tracking information now
owned by Gitea milestones and issues. Keeping it created a maintenance
burden — references drifted out of sync with the actual state of work,
and agents were directed to read it when the source of truth had moved.
## Implementation Notes
All inbound references replaced with either the relevant Gitea milestone
("Skills & Agents") or removed where the context made them redundant.
Test assertions that verified ROADMAP.md content removed; test output
strings updated to drop the ROADMAP cross-reference instruction.
## Impact
Agents no longer read docs/ROADMAP.md at session start. Gitea milestones
and issues are the canonical source for roadmap and open-question tracking.
---
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Update docs to reflect pre-commit migration and cleanup:
- spec/overview.md: removed phantom test file references
- ROADMAP.md: removed references to non-existent test files
- LESSONS.md: removed reference to setup-hooks.sh bug
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
## Why
Two recurring failure modes surfaced during the agent-author workstream
that are worth capturing before they repeat: biased forks producing
false-PASS audits, and parallel forks producing conflicting fixes on
the same file.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Reorder skill-audit description to lead with 'Use when...' trigger (P3)
- Add concrete example to 'control calibration' body discipline check (P4)
- Add bats test files to README file tables for both skills
- Fix REPO_ROOT and SCRIPT paths in bats files after tests/ subdirectory removed
- Add three lessons: plugin cache isolation, spec-grounded rubrics, test file placement
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- claude plugin validate --strict absent from standard test sweep
- gitleaks source/deployed config silent divergence risk
- shellcheck without -x blocks pre-commit on scripts using source
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv5iNACZxumtF2k6TsK18q
- Add sub-file constraint: content-type split rule (explains vs. directs),
three spec-defined optional directories (scripts/, references/, assets/),
one-level-deep rule, and wiring syntax requirement
- Update output format section to list optional sub-files as a third output
- Add self-check item for sub-file placement and wiring
- Update SKILL-TEMPLATE.md constraints and output format examples to match
- Bump META.md to v1.3
- Add two LESSONS.md entries: research agents presenting synthesis as spec
fact; META-TEMPLATE fix deferred with explicit do-not-apply note
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add model: sonnet to SKILL.md frontmatter (Claude Code extension; correct
location per research — runtime config belongs in frontmatter, not META.md)
- Document model field in SKILL-TEMPLATE.md with factory §9 routing guidance
- Wire grill output explicitly to trigger description step (step 3 now references
agreed name/category/purpose from grill rather than drafting independently)
- Strengthen eval self-check: presence check → coverage check (trigger cases +
at least one output case required)
- Bump META.md to v1.2 (2026-05-26)
- Add three LESSONS.md entries: META-TEMPLATE comment retention, overlap check
scope (deployed dir not just repo), model field placement boundary
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Complete 2026-05-18 workstream for write-skill refactor (issue 0018 phase 1).
Grill output (handoff in docs/issues/0018-factory-write-skill.md):
- 6-section standard replaces 8: Role and When/When not dropped (not in
agentskills.io spec; description carries trigger scope and negatives)
- Frontmatter reduced to 3 fields; provenance moves to META.md
(progressive disclosure — not loaded at every skill scan)
- SKILL-TEMPLATE.md and META-TEMPLATE.md as authoritative copy-fill artifacts
- CATEGORIES.md as self-contained category reference in skill directory
- Copy and fill explicitly split into separate process steps for determinism
New files in .agents/skills/write-skill/:
- SKILL-TEMPLATE.md — 6-section template with XML blocks and inline examples per section
- META-TEMPLATE.md — provenance schema with inline-commented YAML; source vs references explicit
- CATEGORIES.md — self-contained category table (no runtime dependency on factory docs)
- META.md — write-skill's own provenance (v1.1, self-authored)
SKILL.md rewritten: 8-step process, XML blocks (<requirements>, <steps>, <checks>),
3-field frontmatter, copy-then-fill steps explicit.
Supporting docs updated:
- skill-implementation-workflow.md: SKILL-TEMPLATE.md as authoritative template;
source:/references: now reference META.md; when: marked resolved
- factory-integration-decisions.md: frontmatter spec corrected
- ROADMAP.md: authoring standard description updated
- CONTEXT.md: Source field entry corrected; META.md added to glossary
- docs/spec/overview.md: 2026-05-18 refactor entry added
- docs/issues/0018: handoff status updated; acceptance criteria marked complete
LESSONS.md: 3 entries added in grill session (cargo-culted body sections,
provenance fields in frontmatter, copy-fill determinism) + 1 from implementation
(planning meta-commentary does not belong in deployed artifacts).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds write-eval, the first factory meta-skill. Produces eval.yaml test
files for skills following the two-section schema (trigger_tests +
output_tests) with provider-agnostic string assertions and show-plan-
then-merge-on-rerun behaviour. Hand-written bootstrap — subsequent
skills will use write-eval to produce their own evals.
Also tightens skill-implementation-workflow.md step 5b: per-section
options walk-through is now a named gate before writing, separate from
the synthesis grill. LESSONS.md entry added.
HITL behavioral test pending.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
13 manual scenarios run across instructions and governance layers (two
rounds for failures). Fixed four rules that lost to RLHF defaults:
- Exploratory question format: tightened with boundary framing; added
@import CONTEXT.md to repo CLAUDE.md and a standing rule to check
docs/adr/ and ROADMAP resolved entries before answering design questions
(3-round iteration to resolve)
- File-edit intent: added counter-example to stop clarification-seeking
- Push confirmation: reframed as "do not call the tool" not "ask first"
- Secrets rule: extended to cover credential reproduction in response
text and usage examples, with explicit placeholder requirement
Scenario 4 (push confirmation) inconclusive — no remote configured.
Governance scenario 3 (HITL on real infra) untestable — Nginx not installed.
Both share the same root cause: agent delegates to permission system.
Also corrects stale skill list in docs/spec/overview.md (12 actual
deployed skills vs 16 names previously listed).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add LESSONS.md as the long-loop feedback log at repo root. Patterns
observed during development graduate to standing rules when three or
more entries appear.
Introduce docs/spec/ as the living spec layer: overview.md (deployed
state) and architecture.md (directory structure, install pipeline,
provider model, governance layer). Refactor docs/VISION.md to goals
and intent only — architecture content moved to docs/spec/architecture.md.
Update CLAUDE.md and CONTEXT.md to reference the new spec files.
Close issues 0013 and 0014. Update ROADMAP and factory integration
note to reflect completion.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>