docs: source ADR-0029 claims and sync ADRs and hook docs with behaviour
- cite the VS Code prompt-file deprecation and the verbatim apm quote - add ADR-0029 boundary-clause enforcement and Consequences - mark superseded ADR-0019 passages; record neutral lock advice, source fork and reloadSkills, amend for the hook hardening - move the ADR-0025 amendment out of the Decision list - amend ADR-0022 for create keeping 0.1.0 - fix hooks.md merge and event claims, README guard caveat, gates.md Vale globs, and pin the research registry URL Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KkT7RSDwDbmrM9T34b6sTi
This commit is contained in:
@@ -34,7 +34,9 @@ behind and refreshes it in place.
|
||||
*session* loads, and that is the moment the staleness does damage. It also enables two things a git
|
||||
hook structurally cannot do: `additionalContext` puts the notice into the agent's context rather
|
||||
than terminal scrollback nobody reads, and `reloadSkills: true` makes the host re-scan the skill
|
||||
directories after the hook returns, so a refresh lands in the running session without a restart.
|
||||
directories after the hook returns, so a refresh lands in the running session without a restart
|
||||
(`reloadSkills` is a documented `SessionStart` `hookSpecificOutput` field:
|
||||
code.claude.com/docs/en/hooks, checked 2026-09-29).
|
||||
|
||||
apm's own lifecycle events (`pre-/post-install`, `pre-/post-update`, `pre-/post-uninstall`) were
|
||||
rejected: they fire around apm operations already chosen, so they can announce a refresh but never
|
||||
@@ -51,8 +53,9 @@ Three sub-decisions:
|
||||
drift. A hook shipped in a package is written into that file by apm itself, so it is apm's output
|
||||
and does not drift. `.claude/settings.local.json` also works but is gitignored and machine-local,
|
||||
which fails the requirement that this travel with the repo.
|
||||
- **`startup` matcher only.** `resume`, `clear`, `compact` and `fork` would re-run the check on every
|
||||
compaction, and a compaction is not an event after which the remote can have moved.
|
||||
- **`startup` matcher only.** `resume`, `clear`, `compact` and `fork` — the other documented
|
||||
`SessionStart` matchers (code.claude.com/docs/en/hooks, checked 2026-09-29) — would re-run the check
|
||||
on every compaction, and a compaction is not an event after which the remote can have moved.
|
||||
|
||||
The executable-trust gate is switched on at the same time. Root `apm.yml` gains an `executables:`
|
||||
block allowing kyberforge's hooks and bin.
|
||||
@@ -142,6 +145,22 @@ value to be larger — so changing either side without the other fails the suite
|
||||
> Re-measured: ~24–26 s for the same six-behind refresh, warm, on a LAN remote — well inside the
|
||||
> 380 s above.
|
||||
|
||||
> **Amendment (2026-09-29) — the time limits are harder to escape, and portable.** Four changes to
|
||||
> `check-apm-current.sh` (PR #144):
|
||||
>
|
||||
> - Both limits are now `timeout -k 5`: a child that ignores SIGTERM is SIGKILLed 5 s later. The
|
||||
> worst case is 60 + 5 + 300 + 5 = 370 s, still below the host's 380, and the test now sums each
|
||||
> limit plus its grace.
|
||||
> - `timeout` falls back to `gtimeout` (Homebrew coreutils on macOS). With neither on `PATH` the
|
||||
> hook emits a notice and exits without calling `apm`. Before, the missing binary exited 127, the
|
||||
> `|| exit 0` swallowed it, and the hook silently never ran.
|
||||
> - `GIT_TERMINAL_PROMPT=0` is exported, so a remote that wants credentials fails at once instead of
|
||||
> blocking on an invisible prompt until the timeout fires.
|
||||
> - `apm update` runs under `flock -n` on `apm_modules/.kyberforge-apm-update.lock` when `flock` exists
|
||||
> and `apm_modules/` does. A second session starting at the same moment skips its refresh and says
|
||||
> so, instead of running a second `apm update` over the same tree. Without `flock` (stock macOS) the
|
||||
> refresh runs unserialised, as before.
|
||||
|
||||
**Reading a human-readable CLI for a control decision cost a silent failure, again.** `apm outdated`
|
||||
has no `--json` or other machine-readable flag (confirmed against 0.28.0), so the hook must match
|
||||
its prose. The first attempt matched `outdated dependencies found` — plural only. apm emits
|
||||
@@ -204,9 +223,20 @@ Until then the repo has the mechanism in source and not in effect.
|
||||
> and it does not last. At the next session start the hook finds the restored lock behind `main`
|
||||
> and refreshes again.
|
||||
|
||||
> **Amendment (2026-09-19) — the advice is neutral when the default branch is unknown.** The hook
|
||||
> picks its lock advice by comparing the current branch with `refs/remotes/origin/HEAD`. That ref is
|
||||
> often unset: git writes it on clone, and `git remote add` never does. The fallback used to be
|
||||
> `main`, which told a checkout whose default branch is `master` to discard a real lock update while
|
||||
> it stood on its default branch. Now, when `origin/HEAD` is unset, the notice gives neither the
|
||||
> default-branch nor the feature-branch advice. It says only "commit it or discard it
|
||||
> deliberately", the same text used outside a git checkout or on a detached HEAD. Learning the
|
||||
> remote's default would need the network, so the hook asserts nothing and the reader decides
|
||||
> (`ea119d8`).
|
||||
|
||||
**`.claude/settings.json` stops being `{"hooks": {}}`.** apm merges the hook into it and tracks
|
||||
ownership in a `.claude/apm-hooks.json` sidecar, with the script copied to
|
||||
`.claude/hooks/<pkg>/`. The sidecar and the script directory are gitignored install output; the
|
||||
`.claude/hooks/<pkg>/`. The sidecar and the script directory are gitignored install output
|
||||
(*superseded for the sidecar: it is committed, see correction 2026-09-16 below*); the
|
||||
settings file remains committed, now with apm-generated content in it. ADR-0018's statement that the
|
||||
committed content is exactly `{"hooks": {}}` is superseded on that point only — the rule it was
|
||||
protecting, that nothing repo-authored goes in that file, is unchanged.
|
||||
@@ -223,7 +253,9 @@ protecting, that nothing repo-authored goes in that file, is unchanged.
|
||||
|
||||
**Native consumers are protected by a guard, not by the gate.** A host installing holocron through
|
||||
`claude plugin install` auto-discovers `hooks/hooks.json` and does not consult apm's trust gate at
|
||||
all. The script therefore exits silently when there is no `apm.lock.yaml` in the working directory,
|
||||
all. The script therefore exits silently when there is no `apm.lock.yaml` in the working directory
|
||||
(*superseded: it now checks `${CLAUDE_PROJECT_DIR}/apm.lock.yaml` and has no cwd fallback, see
|
||||
correction 2026-09-28 below*),
|
||||
which is what makes it inert in a repo that does not consume packages through apm. Copilot CLI sees
|
||||
no hook at all, for the reasons already documented in `plugins/kyberforge/docs/hooks.md`.
|
||||
|
||||
|
||||
@@ -191,6 +191,17 @@ comments (`:9-93`) have described all three correctly since it shipped.
|
||||
was wrong for the tree-identical case: the `same_subtree` skip makes a push **pass** that this ADR as
|
||||
written requires to **fail**, which is documented behaviour changing, not an implementation detail.
|
||||
|
||||
## Amendment (2026-09-29): a new skill stays at `0.1.0` until its first improve
|
||||
|
||||
The Decision says `skill-author`'s create/improve bump convention is "unchanged". It has changed
|
||||
since. Before, `skill-author` bumped the **minor** version on create, so a skill left its first
|
||||
session above the `0.1.0` scaffold. Now create keeps the scaffold's `0.1.0` and does not bump it;
|
||||
the first improve is the first bump, a **patch** (`skill-author` `SKILL.md`, `references/create.md`
|
||||
and `references/improve.md`; `965208b`, PR #144). This makes `0.1.0` mean what this ADR says it
|
||||
means, "created and never yet revised", instead of a value no created skill ever kept. The rules
|
||||
above are otherwise unaffected: `metadata.version` is still required, and the push gate still
|
||||
compares whatever value is there.
|
||||
|
||||
## Consequences
|
||||
|
||||
27 SKILL.md files gain `metadata.version: "1.0.0"`, and a 28th — `bin/write-docs` — reaches the same
|
||||
|
||||
@@ -172,31 +172,6 @@ fallback row. It could not route a `SKILL.md` file path, a trigger its own descr
|
||||
Its agent row ("a path under `.apm/agents/`… or an agent markdown file") was both wider than the
|
||||
script and circular.
|
||||
|
||||
> **Amendment (2026-09-28) — three more modes: hook, instruction and prompt.** The "two accepted
|
||||
> shapes" above are now five. The `primitive-author` change (issue #94, PR #144) added three rows to
|
||||
> the Step 0 table, each with its own self-contained flow file and a shared
|
||||
> `scripts/lib-checks-primitive.sh` that `validate.sh` sources for all three:
|
||||
>
|
||||
> - A file named `*.instructions.md` takes the instruction flow (`references/instruction-flow.md`).
|
||||
> - A file named `*.prompt.md` takes the prompt flow (`references/prompt-flow.md`); the prompt rules
|
||||
> themselves are ADR-0029's.
|
||||
> - A `.json` file whose *immediate* parent directory is `hooks/` (`.apm/hooks/`, or a package's
|
||||
> root `hooks/`) takes the hook flow (`references/hook-flow.md`).
|
||||
>
|
||||
> The suffix rows are checked before the `agents/`-parent rule, so a `*.prompt.md` or
|
||||
> `*.instructions.md` under `agents/` is not audited as an agent. The fallback row is unchanged in
|
||||
> kind: anything else stops, runs no validator, exits 2, and names every accepted shape rather than
|
||||
> two. The exit-code table below applies to the new modes as written; its "matches neither shape"
|
||||
> row now means "matches none of the five".
|
||||
>
|
||||
> This is ADR-0020's merge-siblings rule applied forward rather than a new decision. Auditing a hook,
|
||||
> an instruction or a prompt is the same job as auditing a skill or agent — deterministic checks,
|
||||
> a read, a qualitative pass, one shared report — over a different input type, which is exactly the
|
||||
> case the rule says belongs in one skill behind a dispatch table, not in a new sibling audit skill.
|
||||
> The authoring side follows the rule's other half: the author skills stay split because they emit
|
||||
> genuinely different artifacts, so the three primitives got their own `primitive-author` rather
|
||||
> than rows in `skill-author` or `agent-author`.
|
||||
|
||||
**3. One entry point per script, auto-detecting, with the mode-specific half sourced.**
|
||||
|
||||
- `scripts/validate.sh` detects the target type itself, then sources `scripts/lib-boundary-resolver.sh`
|
||||
@@ -303,6 +278,31 @@ both entry points, and that is what most of the table is. Every change below is
|
||||
A single `validate.sh` copied or symlinked out of its `scripts/` directory still does not work,
|
||||
because its libraries are not beside it. It now fails at exit 2 and says so.
|
||||
|
||||
> **Amendment (2026-09-28) — three more modes: hook, instruction and prompt.** The "two accepted
|
||||
> shapes" in point 2 above are now five. The `primitive-author` change (issue #94, PR #144) added
|
||||
> three rows to the Step 0 table, each with its own self-contained flow file and a shared
|
||||
> `scripts/lib-checks-primitive.sh` that `validate.sh` sources for all three:
|
||||
>
|
||||
> - A file named `*.instructions.md` takes the instruction flow (`references/instruction-flow.md`).
|
||||
> - A file named `*.prompt.md` takes the prompt flow (`references/prompt-flow.md`); the prompt rules
|
||||
> themselves are ADR-0029's.
|
||||
> - A `.json` file whose *immediate* parent directory is `hooks/` (`.apm/hooks/`, or a package's
|
||||
> root `hooks/`) takes the hook flow (`references/hook-flow.md`).
|
||||
>
|
||||
> The suffix rows are checked before the `agents/`-parent rule, so a `*.prompt.md` or
|
||||
> `*.instructions.md` under `agents/` is not audited as an agent. The fallback row is unchanged in
|
||||
> kind: anything else stops, runs no validator, exits 2, and names every accepted shape rather than
|
||||
> two. The exit-code table above applies to the new modes as written; its "matches neither shape"
|
||||
> row now means "matches none of the five".
|
||||
>
|
||||
> This is ADR-0020's merge-siblings rule applied forward rather than a new decision. Auditing a hook,
|
||||
> an instruction or a prompt is the same job as auditing a skill or agent — deterministic checks,
|
||||
> a read, a qualitative pass, one shared report — over a different input type, which is exactly the
|
||||
> case the rule says belongs in one skill behind a dispatch table, not in a new sibling audit skill.
|
||||
> The authoring side follows the rule's other half: the author skills stay split because they emit
|
||||
> genuinely different artifacts, so hooks, instructions and prompts got their own
|
||||
> `primitive-author` rather than rows in `skill-author` or `agent-author`.
|
||||
|
||||
## Considered options
|
||||
|
||||
**Keep two skills and rely on the byte-identity contract test alone (rejected).** This is the status
|
||||
|
||||
@@ -8,17 +8,21 @@ parameters. It is the text a user would otherwise type again and again. It carri
|
||||
beyond steering existing skills or agents by name. Once it holds reusable know-how, bundled files,
|
||||
or anything the model should find on its own, it is a **Skill** in the wrong container.
|
||||
|
||||
This is stricter than apm. apm's docs call a prompt "a callable program for an LLM", and 0.28.0
|
||||
scaffolds one as a numbered-steps workflow (`apm_cli/workflow/discovery.py`). On every harness this
|
||||
repo targets, a prompt with a full workflow in it is a worse skill:
|
||||
This is stricter than apm. apm frames a prompt as a program: its docs state that "a prompt is a
|
||||
program for an LLM" (microsoft.github.io/apm/concepts/what-is-apm/, "Secure by default"; the same
|
||||
sentence is in the apm-cli 0.28.0 package README), and 0.28.0 scaffolds one as a numbered-steps
|
||||
workflow (`apm_cli/workflow/discovery.py`). On every harness this repo targets, a prompt with a full
|
||||
workflow in it is a worse skill:
|
||||
|
||||
- **Claude Code.** Custom commands have been merged into skills. "Both create `/deploy` and work
|
||||
the same way", and both are model-invocable by default (code.claude.com/docs/en/skills.md).
|
||||
apm 0.28.0 keeps only `description`, `allowed-tools`, `model`, `argument-hint` and `input` for
|
||||
Claude (`_PRESERVED_COMMAND_KEYS`) and drops `disable-model-invocation`. A deployed prompt is
|
||||
therefore a model-visible skill with fewer frontmatter keys, and it cannot be made user-only.
|
||||
- **Copilot / VS Code.** Prompt files are marked deprecated for Agent Host, and VS Code offers a
|
||||
migration to agent skills.
|
||||
- **Copilot / VS Code.** "Prompt files are deprecated for Agent Host sessions and aren't loaded by
|
||||
Agent Host", and VS Code offers a migration that converts existing prompt files to agent skills
|
||||
(code.visualstudio.com/docs/agent-customization/prompt-files). They still load in the Local agent,
|
||||
which that page says will be removed in a future release.
|
||||
- **Codex.** Codex receives no prompts at all.
|
||||
|
||||
The one job a prompt does better than a skill is a short, parameterised "do this now, using X and Y"
|
||||
@@ -45,10 +49,28 @@ happen, the cost is bounded: the prompt is a thin wrapper that calls the right s
|
||||
- `description` is present and non-empty (FAIL).
|
||||
- It is 250 characters or fewer (SUGGESTION).
|
||||
- It has no "Use when" trigger clause (SUGGESTION).
|
||||
- It has no `Not X -> Y` boundary clause (SUGGESTION).
|
||||
- **`factory-audit`, judgment step.** A body that clearly carries reusable procedure is a FAIL. A
|
||||
borderline body is a SUGGESTION. There is deliberately no line-count or heading heuristic: the
|
||||
call is made by reading the content, because any threshold misfires.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **`factory-audit` gains a prompt mode.** `*.prompt.md` is a Step 0 dispatch row with its own
|
||||
`references/prompt-flow.md`, and `scripts/lib-checks-primitive.sh` carries the three description
|
||||
checks above plus the judgment step (ADR-0025, amendment 2026-09-28). A prompt that was fine under
|
||||
apm's framing — a trigger clause, a boundary clause, a numbered workflow — now draws findings.
|
||||
- **`primitive-author` refuses procedure-bearing prompts.** Its prompt reference opens with the
|
||||
boundary gate, so a "make me a command" request that carries reusable know-how is redirected to
|
||||
`skill-author` before any file is written. That makes skill-vs-prompt a checked boundary rather
|
||||
than an authoring preference.
|
||||
- **Codex gets no prompts from this repo.** apm deploys none to Codex, so anything a prompt steers
|
||||
must also be reachable there through the skill it names. Keeping procedure in the skill is what
|
||||
makes that true; a fat prompt would be content Codex users silently never see.
|
||||
- **Reversing this is cheap in files, not in routing.** No prompt exists in the repo yet, so the rule
|
||||
constrains new work only. Loosening it later means re-deciding the description contract, and every
|
||||
prompt written under it would need a trigger clause added.
|
||||
|
||||
## Considered options
|
||||
|
||||
- **Fat workflow prompts as peers of skills (rejected).** This follows apm's framing. But every
|
||||
|
||||
@@ -787,8 +787,10 @@ Wiring Vale as a deterministic prefilter for `factory-audit`'s Description dimen
|
||||
issue #84) is repo-specific, not part of the generic `lint` plugin, so it does not live in
|
||||
`plugins/lint/` — and per ADR-0014 it no longer lives at the repo root either. It lives **once**,
|
||||
under `plugins/kyberforge/.apm/skills/factory-audit/assets/vale/`, carrying both the `Kyberforge`
|
||||
and `KyberforgeCopilot` styles and a single `.vale.ini` with all three glob sections:
|
||||
`[**/SKILL.md]`, `[**/agents/*.md]`, `[**/*.agent.md]`.
|
||||
and `KyberforgeCopilot` styles and a single `.vale.ini` with five glob sections:
|
||||
`[**/SKILL.md]`, `[**/agents/*.md]`, `[**/*.instructions.md]`, `[**/*.prompt.md]` and
|
||||
`[**/*.agent.md]`. The instructions and prompt sections arrived with `factory-audit`'s primitive
|
||||
modes (ADR-0025, amendment 2026-09-28).
|
||||
|
||||
ADR-0014 split this into two skill-scoped copies because a plugin's cache-install copies only each
|
||||
skill's own files and `skill-audit` could not reach across the skill boundary into `agent-audit`'s
|
||||
@@ -816,7 +818,8 @@ Its `StylesPath` and `BasedOnStyles` checks were **not** diffs. They were per-fi
|
||||
invoked `vale --config` on one representative path per file shape. It was the only assertion
|
||||
anywhere that catches a `.vale.ini` glob typo (`[**/SKILL.md]` → `[**/SKILLS.md]`), the failure mode
|
||||
where every other check stays clean while Vale lints zero files. One config does not make that
|
||||
impossible: a typo in any one of the three sections still 0-file-skips that shape.
|
||||
impossible: a typo in any one section still 0-file-skips that shape. The table has since grown
|
||||
to eight rows: one each for the instructions and prompt sections added later.
|
||||
|
||||
**Case 0** runs before any Vale-dependent case and needs no Vale binary. It asserts that the shipped
|
||||
`.vale.ini` exists and is readable, sets a `StylesPath` that resolves to a directory, and names only
|
||||
@@ -826,8 +829,9 @@ cases back.
|
||||
|
||||
The probes now live in `tests/test-vale-wrap.sh` (cases 28–30), rehomed against the merged config:
|
||||
one representative path per file shape, each asserted to produce a Vale scan of more than zero files
|
||||
*and* a Kyberforge alert (case 28). Case 28 also checks that each probe path is in scope of a
|
||||
published vale hook, and that every `.vale.ini` section has a probe row. Its Part B drops
|
||||
*and* a Kyberforge alert (case 28). Case 28 also checks that every `.vale.ini` section has an
|
||||
isolating probe row. It no longer holds each probe path to a hook's `files:` scope: that half read
|
||||
the retired `.pre-commit-hooks.yaml`, and case 32 owns the local hooks' scope. Its Part B drops
|
||||
`Kyberforge` from each section's `BasedOnStyles` in a copy and requires that section's probes to
|
||||
fail as "style not loaded". Case 29 is a mutation case: it typos each section in a copy of the
|
||||
assets and requires that section's isolating probes to drop to zero. Case 30 asserts that
|
||||
@@ -931,17 +935,17 @@ authors. Without the binary the hooks fail with a bare "command not found" and n
|
||||
**Two hooks, not one combined hook — for a different reason than ADR-0014 gave.** The original
|
||||
reason was mechanical: with a config per skill, a single hook could point at only one copy and would
|
||||
silently 0-file-skip the other file shape (see
|
||||
[A 0-file Vale run is NOT RUN](#a-0-file-vale-run-is-not-run)). One `.vale.ini` carrying all three
|
||||
sections removes that constraint. The split stays anyway because the `files:` regexes still have to
|
||||
[A 0-file Vale run is NOT RUN](#a-0-file-vale-run-is-not-run)). One `.vale.ini` carrying every
|
||||
section removes that constraint. The split stays anyway because the `files:` regexes still have to
|
||||
differ — each hook hands Vale only the file shape it is scoped to. Both hooks name the same
|
||||
plugin-bundled `factory-audit/scripts/vale-wrap.sh` through `repo: local`; there is no second root
|
||||
copy.
|
||||
|
||||
### The `.vale.ini` globs do no scoping
|
||||
|
||||
The `.vale.ini`'s section globs are **path-agnostic** — `[**/SKILL.md]`, `[**/agents/*.md]` and
|
||||
`[**/*.agent.md]` — and constrain filename *shape*, not
|
||||
location: Vale's `*` crosses `/`. A `SKILL.md` outside `plugins/` (a project-scope
|
||||
The `.vale.ini`'s section globs are **path-agnostic** — `[**/SKILL.md]`, `[**/agents/*.md]`,
|
||||
`[**/*.instructions.md]`, `[**/*.prompt.md]` and `[**/*.agent.md]` — and constrain filename *shape*,
|
||||
not location: Vale's `*` crosses `/`. A `SKILL.md` outside `plugins/` (a project-scope
|
||||
`.claude/skills/foo/SKILL.md`, say) still matches `[**/SKILL.md]` and gets linted normally.
|
||||
|
||||
All scoping therefore comes from the pre-commit hooks' own `files:` regexes, which pin this repo's
|
||||
@@ -951,8 +955,16 @@ invocation — in this repo or in any repo that installs it, whatever that repo'
|
||||
Narrowing a `.vale.ini` glob to a `plugins/`-shaped path to "tighten" it breaks the consumer case:
|
||||
`factory-audit` run against a project-scope `.claude/skills/` tree would lint nothing.
|
||||
`check-vale-style-sync`'s probe set was built to catch exactly that; it moved to
|
||||
`tests/test-vale-wrap.sh` with the hook's deletion, and two of the six probes exist specifically to
|
||||
pin this location independence — see [One copy, one config](#one-copy-one-config).
|
||||
`tests/test-vale-wrap.sh` with the hook's deletion. Its table (`PROBE_TABLE28`) now has eight rows,
|
||||
one or more per section, and the two `.claude/`-prefixed rows exist specifically to pin this
|
||||
location independence — see [One copy, one config](#one-copy-one-config).
|
||||
|
||||
**No pre-commit Vale hook covers `*.instructions.md` or `*.prompt.md` yet.** The `.vale.ini`
|
||||
sections exist so that `factory-audit`'s own Vale call lints those files when it is handed one, in
|
||||
any repo. This repo's two prefilter hooks select only `SKILL.md` and `.agent.md` files, and the repo
|
||||
has no instruction or prompt file for a third hook to select. Case 32 requires every Vale hook's
|
||||
`files:` regex to match at least one tracked file, so a hook added now would fail it. Add the hook
|
||||
in the change that lands the first `.apm/instructions/` or `.apm/prompts/` file.
|
||||
|
||||
### The blind spot: `references/` is unlinted, for two independent reasons
|
||||
|
||||
@@ -1051,9 +1063,9 @@ clean.
|
||||
### Pre-push
|
||||
|
||||
`vale` is still a **pre-push** dependency, but no longer through a hook of its own.
|
||||
`check-vale-style-sync` — the hook that ran the six glob probes, and whose
|
||||
`check-vale-style-sync` — the hook that ran the original six glob probes, and whose
|
||||
`CHECK_VALE_STYLE_SYNC_ALLOW_MISSING_VALE=1` opt-out downgraded them audibly rather than skipping the
|
||||
hook — is deleted with the second Vale copy (ADR-0025). The six glob probes survive it inside
|
||||
hook — is deleted with the second Vale copy (ADR-0025). The glob probes survive it inside
|
||||
`test-vale-wrap.sh`, so `run-tests --strict` is now the gate that runs them. That is also what keeps
|
||||
`vale` a pre-push requirement: `test-vale-wrap.sh` exits 77 without the binary once its static cases
|
||||
pass, and a skip fails the push.
|
||||
|
||||
Reference in New Issue
Block a user