Split oversized skill cards along task lines; subset fences; shared filters reference - #136
Merged
Conversation
A fence id can now be group[verb-prefix,...]: a subset fence claiming every verb starting with one of the prefixes, while the bare-group fence renders the unclaimed remainder as the catch-all. gen/check discover fences by scanning the cards for markers instead of deriving one filename per group, so a large command group's reference card can be split along task lines. Topology violations (a verb claimed twice, a prefix claiming nothing, unclaimed verbs with no catch-all, a duplicated fence) fail gen and are reported by check as fence-topology issues.
channel.md (367 lines) carried four rule families beside channel CRUD, and incident.md (508) carried the whole post-mortem surface — every task paid for the whole domain, and the guidance competing for attention is exactly how a hot-flow example gets misread. Split along task lines using subset fences: - channel.md → channel CRUD only; escalation.md (escalate-rule-*); noise.md (silence-rule-*, inhibit-rule-*, unsubscribe-rule-*) - incident.md → triage/investigation; postmortem.md (post-mortem-*) - filters.md: new shared reference for filters/source_filters/ target_filters — OR-of-AND shape, IN/NOTIN semantics incl. the missing-key trap, /regex/ values, construction-from-labels rules, and the per-family key vocabulary. Consumer cards and alert.md's pipeline section point here instead of restating it. - Canonical keys only: guidance now teaches severity/status/ data_source_id; the per-surface aliases (event_severity, alert_severity, incident_severity, alert_status, incident_status, integration_id) always carry the same stored value and are called out as never-use. - SKILL.md router: channel row narrowed; new escalation/noise/postmortem rows; shared-reference note for filters.md.
… guard splice index; single-file two-fence test - filters.md: integration_id is not a legacy alias — the server accepts it and data_source_id interchangeably (the API's response docs in fact deprecate data_source_id), so present the pair as equivalent and keep the never-use list to the severity/status aliases, scoped to rule-evaluation time. - runGen: check the start-marker index before slicing the body with it. - New TestRunGen_TwoFencesInOneFile pins the sequential splice loop for a subset fence and catch-all living in one card.
…corpus load, FindFence - Prefix claims are now hyphen-boundary-bounded (verb == p or p + "-"): an unbounded match could misroute a near-miss verb (rule2-list under rule-) with a clean single-owner partition no topology check would flag. Fence ids normalized to the boundary-safe form (incident[post-mortem]); a trailing-hyphen prefix now claims nothing and dies loudly as a dead-prefix violation. - runGenAll loads the card corpus once and threads it through every group via genGroup (was one full reload per group); genGroup updates the in-memory docs after each write so later groups see current content. runGen's docOrder/byPath bookkeeping dropped — it iterates the docs slice directly. - New skilldoc.FindFence(body, id) centralizes start/end-marker location for both gen and check (the two ad-hoc copies had already drifted in error wording); hasCatchAll bool and a no-op map insert removed; CheckFences reuses groups(d)'s existing order instead of re-sorting.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Splits the two oversized skill cards along task lines and adds the generator support that makes the split possible:
GENERATED:fence id can now begroup[verb-prefix,…]: a subset fence claiming every verb starting with one of the prefixes, while the bare-group fence renders the unclaimed remainder (catch-all).gen/checkdiscover fences by scanning the cards for markers instead of assuming one file per command group. New topology validation: a verb claimed twice, a prefix claiming nothing, unclaimed verbs with no catch-all, and duplicated fences all failgenand surface asfence-topologyissues incheck.escalate-rule-*(dispatch/escalation policy) andsilence-rule-*/inhibit-rule-*/unsubscribe-rule-*(noise reduction) get their own cards.post-mortem-*verbs move out; triage/investigation stays together (those verbs interleave in real flows).reference/filters.md— shared reference forfilters/source_filters/target_filters: OR-of-AND shape,IN/NOTINsemantics including the missing-key trap (NOTINon a key the object doesn't carry matches everything),/regex/values, construction-from-incident-labels rules, and the per-rule-family key vocabulary. The rule cards and alert.md's pipeline section point here instead of restating it.severity/status/data_source_id; the per-surface aliases (event_severity,alert_severity,incident_severity,alert_status,incident_status,integration_id) always carry the same stored value as the canonical key and are called out as never-use. On incident-scoped rulesalert_severityis an alias of the incident's severity, so spelling it invites wrong reads.Why
A reference card is the second level of progressive disclosure: the router sends a task to one card. When one card carries four rule families beside channel CRUD (367 lines) or a whole post-mortem surface beside triage (508 lines), every task pays for the whole domain, and guidance competing for attention within one card is exactly how a hot-flow example gets misread. Card sizes after the split: channel 112, escalation 122, noise 205, postmortem 160, filters 77, incident 420.
Verification
go test ./...green; new fence-topology tests ininternal/skilldoc/fence_test.goand split-across-cardsgentests ininternal/cmd/skilldoc/main_test.go.skilldoc genregenerated every fence from the live CLI tree;skilldoc checkreports cards OK.🤖 Generated with Claude Code