b1883befc7
Files changed: - CHANGES.md - VERSION - instructions/claude-code-model-selection.md - instructions/dev/stack-dev/SKILL.md
184 lines
12 KiB
Markdown
184 lines
12 KiB
Markdown
---
|
|
name: stack-dev
|
|
description: Switch a session into tool-development mode - extending tools/wikitool, the compiler, the type schema, or the instruction/skill layer itself, instead of operating on wiki content. Use when the user asks to add a wikitool command, change a type-spec, fix or extend the compiler, or otherwise work on the stack rather than ingest/query/manage/lint the wiki.
|
|
---
|
|
|
|
# Stack Development Mode
|
|
|
|
**Purpose:** Recognize a session that is about the tool stack itself - `tools/wikitool`, the
|
|
type schema, the instruction/skill layer - rather than wiki content, and switch the rules that
|
|
apply accordingly.
|
|
|
|
**Trigger:** The user asks to add or change a `wikitool` command, extend the compiler, change a
|
|
type-spec, or work on `instructions/`/`types/`/`tools/` as code rather than as a place to run
|
|
`wiki-ingest`/`wiki-query`/`wiki-manage`/`wiki-lint`/`wiki-status` against.
|
|
|
|
**This directory is dev-only.** `instructions/dev/` is excluded wholesale by
|
|
`tools/wikitool dist export` - nothing here ever reaches a distributed instance, and there is
|
|
no restore path. If you are in a distributed instance, this skill should not be present at all;
|
|
stack development happens in the origin repo instead (see AGENTS.md's routing line).
|
|
|
|
## What changes in this mode
|
|
|
|
- **Source-binding does not apply to code.** AGENTS.md invariant 3 ("never file an unsourced
|
|
answer into the wiki") governs `kb/` content, not the code you write to extend the stack.
|
|
Ordinary software-engineering judgment applies to `tools/chemenu/*.py`, `types/*`,
|
|
`instructions/*` - it does not need a `raw/` source or a citation.
|
|
- **Test and review conventions from `instructions/dev/` apply instead**, once written down
|
|
there (step 2 below lists what currently exists). Until a given convention has its own
|
|
instruction file, follow the existing test files' own patterns
|
|
(`tools/chemenu/tests/`) rather than inventing a new one silently.
|
|
- **Everything outside this directory still applies.** The tool error contract, the gates, and
|
|
"never hand-edit generated files" (AGENTS.md invariants 1, 5-8) are about how the tool
|
|
behaves at runtime, not about developing it, but they still bind normal session conduct
|
|
(e.g. still use `tools/wikitool publish`, still respect the gates, when the session also
|
|
touches wiki content).
|
|
|
|
## Steps
|
|
|
|
1. **Confirm the mode.** If the task is ambiguous between "extend the tool" and "operate the
|
|
wiki", ask rather than guess - the two have different rules for the same directories.
|
|
2. **Consult `instructions/dev/` for the concrete procedure.** Currently:
|
|
[commonplace-kb.md](../commonplace-kb.md) - vendored knowledge base on agent context
|
|
engineering, memory and deploy-time learning; consult before a design decision in those
|
|
areas.
|
|
[issue-tracking.md](../issue-tracking.md) - open work lives in Gitea issues, one per work
|
|
package, labelled `area/`, `kind/`, `prio/` and `size/`. There is no `TODO.md`. **The body
|
|
of the issue you are working on is this session's plan file:** keep it current as the state
|
|
moves, so an interrupted session leaves a body the next one can resume from, *and* rewrite it
|
|
to its final state before closing. Both halves bind; the second is step 6 below. Read it
|
|
before filing something for later, before editing or closing an issue, or before deciding
|
|
what to pick up next.
|
|
[testing-conventions.md](../testing-conventions.md) - the suite runs against a deliberately
|
|
empty machine; what the autouse fixture already neutralizes, and what a test still has to
|
|
establish itself. Read it before adding or changing a test.
|
|
[version-parts.md](../version-parts.md) - which part a change bumps: the drop-in test, the
|
|
catalogue of breaks that cross the compatibility boundary with `kb/` untouched, and what to
|
|
put in front of the user before a breaking bump. Read it before step 4.
|
|
[corpus-policy.md](../corpus-policy.md) - what "curated enough" means for the shared
|
|
demo/testbed `kb/`, the measurable floors that define it, and what a reactive fix may and may
|
|
not do to corpus content. Read it before judging whether the corpus can exercise a change, or
|
|
before any fix that would touch `kb/` content.
|
|
More instructions are added here incrementally as stack-development needs come up - this
|
|
list grows without needing this skill file to change shape.
|
|
3. **Settle the design before building - and break there for the model switch.** These are two
|
|
different kinds of work, and the split is not stylistic: design, the version part and any
|
|
boundary judgment have **no** mechanical guard, while the code and tests that follow have
|
|
`pytest`, `docs verify`, `instructions verify` and CI behind them.
|
|
|
|
So when the design is settled - the issue body says what will be built, the open questions are
|
|
answered - stop and say so, in one sentence:
|
|
|
|
> Der Plan steht, ab hier ist die Arbeit mechanisch und durch Tests/CI abgedeckt. Wenn du auf
|
|
> Opus bist, ist jetzt der Moment für `/model sonnet` bei Effort `high`.
|
|
|
|
**You cannot make this switch yourself** - the session's model is the user's `/model`, not a
|
|
setting an agent applies. Offer it once and keep working either way; a session that argues
|
|
about its own model has already cost more than the difference. If the design turns out not to
|
|
be settled after all - a boundary crossing surfaces, an assumption breaks - that is a reason to
|
|
offer the switch back up, not to decide it alone.
|
|
|
|
Effort is the cheaper lever than the model, and `high` is the floor for anything touching more
|
|
than one file or a contract. Full table and reasoning:
|
|
[claude-code-model-selection.md](../../claude-code-model-selection.md).
|
|
|
|
4. **Raise the version, if the change ships.** A change under `tools/`, `types/`,
|
|
`instructions/`, `AGENTS.md` or a `CONTRACT.md` reaches every future instance, so it needs a
|
|
version and a changelog entry:
|
|
|
|
```bash
|
|
tools/wikitool version bump --patch --title "<what changed>"
|
|
```
|
|
|
|
Never edit `VERSION` or the entry's heading by hand - `bump` writes both, and `docs verify`
|
|
fails a tree where they disagree. Pick the part by whether the new version is a **drop-in
|
|
replacement** for the old one - not by whether content has to be migrated:
|
|
|
|
| Change | Part |
|
|
|--------|------|
|
|
| Fix, no interface change | `--patch` |
|
|
| New capability, still drop-in in both directions | `--minor` |
|
|
| **Not a drop-in replacement** - any hand-work by the user or a migration script, or a downgrade that no longer works | `--major` |
|
|
|
|
Content migration is one way to land in the last row, not the definition of it: a rename of
|
|
the update path, the artefact, an import name, a flag or an envvar breaks a swap with `kb/`
|
|
entirely untouched. The full test, the catalogue of such breaks, and what to put in front of
|
|
the user first are in [version-parts.md](../version-parts.md) - **read it before choosing
|
|
`--major`.**
|
|
|
|
A `--major` bump therefore needs two things recorded. `--breaking "<what stops working>"`
|
|
is required on every boundary-crossing bump; on top of it, a migration document for the new
|
|
version - written per [migrate-corpus.md](../../migrate-corpus.md) - or
|
|
`--no-migration "<reason>"` when no content actually has to change. `bump` refuses without
|
|
either, and so does `docs verify`: an instance learning that it must migrate, with nothing
|
|
telling it how, is a dead end.
|
|
|
|
Then write the entry's body - `bump` deliberately leaves it empty, the same way `new` leaves
|
|
the prose.
|
|
|
|
Prose-only changes (`README.md`, `INSTALL.md`, `EVALS.md`) and the workflows under `.gitea/`
|
|
do not need a bump - CI's version gate is scoped to what changes behaviour.
|
|
|
|
5. **Verify before publishing.** `tools/wikitool docs verify`, `tools/wikitool instructions
|
|
verify`, and the relevant `pytest` run in `tools/` - the same checks any stack change must
|
|
pass, run explicitly rather than assumed. CI (`.gitea/workflows/ci.yml`) runs these plus a
|
|
full `setup-instance.md` replay against a fresh `dist export`; a push to `main` that moves
|
|
`VERSION` additionally triggers a tagged release. **CI does the tagging** - a session never
|
|
creates a tag, which is what keeps AGENTS.md invariant 5 intact.
|
|
|
|
6. **Close the issue with a body rewrite, not a comment.** The last act of a session that
|
|
finished a work package, and the one most easily skipped: by here the change is published and
|
|
the issue feels done. It is not. The body is the version everyone reads afterwards and nobody
|
|
revisits, so it is the one place the debt comes due at the worst moment.
|
|
|
|
**Break here too, in the other direction.** Everything left in the session - this rewrite,
|
|
whether a `docs/` page's reasoning went stale, the changelog prose - is the unchecked kind of
|
|
work again, the mirror of step 3. If the session dropped to Sonnet there, say so now:
|
|
|
|
> Ab hier greift kein maschineller Check mehr - Issue-Body, `docs/`-Veralterung und
|
|
> Changelog-Prosa prüft nichts. Wenn du zurück auf Opus willst, ist jetzt der Moment.
|
|
|
|
Then **do the work regardless of the answer.** Never block a close on a model switch: the
|
|
change is already published, and a session that stops here leaves exactly the state this step
|
|
exists to prevent. If it ran on the cheaper model, name that in the handover rather than
|
|
leaving it silent.
|
|
|
|
Rewrite it to its final state *first*, then close. The test is what a reader who opens the
|
|
closed issue tomorrow would conclude:
|
|
|
|
- every acceptance criterion ticked, or struck with the reason it was dropped
|
|
- proposals that were decided read as decided; a "to decide" section has become the decision
|
|
and its reasoning
|
|
- nothing left in the present tense about a defect that no longer exists
|
|
- what was verified is named - which checks ran, which CI run - not a commit hash alone
|
|
|
|
Then one short comment naming what changed against the previous state, and nothing else.
|
|
|
|
**A closing report in a comment does not satisfy this**, however thorough: it reads as
|
|
complete to whoever writes it and leaves a body still phrased as open work. Nothing
|
|
mechanical catches it - `wikitool` does not know this tracker exists and must not learn it,
|
|
since it ships to instances that have no board - so this step is the only enforcement there
|
|
is. #44 and #45 both closed exactly this way, the second an hour after the rule was written.
|
|
[issue-tracking.md](../issue-tracking.md) step 7 has the full shape.
|
|
|
|
## Decision points
|
|
|
|
- **Touches both stack code and wiki content in one session?** Apply this skill's rules to the
|
|
code changes and the normal content skills' rules to the content changes - they are not
|
|
mutually exclusive within a session, only per change.
|
|
- **The change turns out not to be a drop-in replacement?** Do not bump across the boundary on
|
|
your own initiative. Every existing instance pays for a breaking change once, by hand, so the
|
|
user decides whether it is worth that: show them what breaks, what an instance has to do about
|
|
it, and the alternatives (avoid the break with a shim, defer and batch it with the next one,
|
|
or split it behind a deprecation window), then recommend one and wait for a go-ahead.
|
|
[version-parts.md](../version-parts.md) step 4 has the full shape. A surfacing boundary crossing
|
|
is also a reason to offer the model switch back up (step 3): the judgment it needs has no
|
|
mechanical guard, and `docs verify` only checks that a crossing documents itself, never that the
|
|
part was chosen correctly.
|
|
|
|
## Scope
|
|
|
|
Not for wiki content work - use `wiki-ingest`/`wiki-query`/`wiki-manage`/`wiki-lint`/
|
|
`wiki-status` for that. Not for setting up a new instance (`instructions/setup-instance.md`) or
|
|
a fresh clone of this repo (`instructions/bootstrap.md`).
|