Skip to content

feat(skills): Skills & Health — skill runtime, instruction resolver, doctor v2, support bundle - #71

Closed
AetherAI3 wants to merge 16 commits into
mainfrom
feat/skills-health
Closed

feat(skills): Skills & Health — skill runtime, instruction resolver, doctor v2, support bundle#71
AetherAI3 wants to merge 16 commits into
mainfrom
feat/skills-health

Conversation

@AetherAI3

Copy link
Copy Markdown
Owner

This lane had been sitting unpushed on a local worktree with no branch on origin and no CI ever run against it. Opening it so it gets reviewed and exercised.

Sixteen commits, 100 files, roughly +9157/-343. What is in it:

  • Skills core — the aether.skill/v1 schema, digest, lock, trust, discovery, resolution, lazy loading, and policy.
  • Skills surface — the aether skills CLI family, the /skills REPL command, six built-in skills, and an offline eval engine with skills eval.
  • Instructions and policyInstructionResolver with provenance and conflict reporting; network becomes an explicit gate category. Includes a fix where test-command extraction swallowed the rest of a sentence.
  • Dev session — skill and instruction context on the wire, with an honest refusal on legacy peers.
  • Capability matrix — packaged fallback snapshot plus resolver, pinned to the merged cloud SHA, and an aether capabilities command with /why explanations.
  • Doctor v2 — modular diagnostics, backup-first safe repair, and a redacted self-verifying support bundle.
  • Hardening — Loop F: bounded indexing, no retained bodies, trust-gated automatic selection at scale.
  • Docs — skill authoring, instruction compatibility, capability contract guides, the release record skeleton, and a current-state baseline.

Notes for review: the branch is six commits behind main and will need a rebase, and CI has never run on this code, so expect the first run to be informative rather than green.

🤖 Generated with Claude Code

AetherAI3 and others added 16 commits August 14, 2026 13:58
…urce-of-truth map

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…very, resolution, lazy loading, policy

Strict-JSON manifest validation (closed keys, reserved aether/* namespace,
tool/permission vocabulary checks, safe relative paths), canonical
length-prefixed SHA-256 package digest, committed-safe lock file, local
digest-bound trust store, metadata-only discovery, explicit/automatic
resolution with ambiguity + dependency-cycle refusals, TOCTOU-checked lazy
body loading, intersection-only policy enforcement, and the bounded typed
skill context packet. Stable skill.* refusal codes throughout.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…and conflicts; network becomes an explicit gate category

InstructionResolver: bounded read-only discovery of .aether/instructions.md,
root and nested AGENTS.md, user-level instructions, and CLAUDE.md / GEMINI.md /
copilot / Cursor-rule compatibility imports; nested scoping, explicit
precedence (nearest nested > canonical project > root > user > imports),
test-command conflict detection with the effective winner and reason, honest
unsupported-syntax warnings (a Cursor rule we cannot parse is NOT applied
globally), truncation and binary-file skips with visible reasons, and a typed
instruction context packet carrying per-source digests.

Gate repair: web_search/web_fetch now map to a 'network' gate action instead
of falling through ungated; doctor's tools.gates check and autonomy tests
pin the new mapping. Gate prompts show url/query detail.

Includes skill-core unit tests (schema, digest, trust/lock, discovery,
resolution, lazy-loading proof with TOCTOU refusal, policy, context packet).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…legacy refusal

Additive DevSessionWireRequest fields (capability_contract_version,
skill_context, instruction_context — absent for legacy runs), CloudBrain
DevSessionContext, skill_context_ack / instruction_context_ack frame decoding
and visible acknowledgement rendering, and the skill-session assembly used by
'aether agent': discover, resolve explicit (--skill) plus bounded automatic
candidates, lazy-load, packet build, visible Skills/Rules/Conflict header, and
per-call policy enforcement in the tool gate ahead of the permission gate.
A legacy server with skill context present refuses with
skill.server_unsupported unless --no-skills deliberately opts out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…x built-in skills, offline eval engine

aether skills list/show/explain/create/install/enable/disable/trust/untrust/
lock/check with stable exit codes; trust requires --yes or interactive
confirm and fails closed without a TTY; show/explain never print skill
bodies. /skills mirrors the read-only family through one registry entry and
routes trust to the deliberate CLI action. Built-ins (aether/review-pr,
fix-ci, ship, doctor-project, research-and-implement,
frontend-from-screenshot) ship as strict manifests + SKILL.md copied into
dist/src/skills/builtin by the new deterministic post-build asset step.
skill_eval.ts runs the schema/resolution/policy eval layers offline —
zero model calls, zero UVT — with JUnit output for CI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…skills eval subcommand

Every built-in declares evals/cases.json exercising resolution (automatic
trigger selection) and policy (allowed tools pass, denied tools refuse with
codes) with max_uvt 0 pinned — offline evals are zero-spend by construction.
'aether skills eval [id|--all] [--json] [--junit <path>]' runs them; the
asset copy step now ships evals/ and templates/ alongside references/.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…solver

src/generated/agent_capabilities.ts pins the canonical AETHER-CLOUD contract
(source repo, commit, version, canonical sha256 — digest verified equal to the
Python contract_digest byte-for-byte). resolveCapabilities() prefers the
server manifest, falls back to the snapshot with a visible warning, refuses an
incompatible major contract version, and never mixes vocabularies. Renderer
separates static support from runtime availability.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…t of a sentence

The single greedy regex let 'pytest tests/api. Never cargo test --all here.'
consume everything after pytest, hiding the cargo command and polluting the
extracted value with prose. Runner commands are now token-scanned: args must
look like flags, paths, or scoped targets, and sentence punctuation ends the
command. All 11 instruction tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lity contract guides

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-gated automatic selection at scale

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s, and rollback path

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Pro/Team now lists Claude Opus 5, the GPT-5.6 family, Kimi K3, and Gemini 3.6
Flash first, with the previous generation (Opus 4.8, GPT-5.5, DeepSeek V4 Pro,
Kimi K2.6, Gemma 4 31B) labeled as still selectable rather than presented as
the flagship set. Frontier table unchanged — already current.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…oud SHA

Snapshot now cites AetherAI3/AETHER-CLOUD@97eacd3e (PR #1065, merged and
deployed dark). Contract content and canonical digest unchanged
(8da09423…). Release record updated with the merge evidence.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ostics, backup-first repair, redacted self-verifying bundle

Doctor v2: diagnostics split into cohesive category modules with a check
registry and executor (old ids/behaviors preserved verbatim; diagnostics.ts
is now a re-export shim). New skills/instructions checks, --network (--deep
alias), --category, --failed, --junit, --schema v1|v2 (v1 default for
existing JSON consumers), and --live driving one synthetic dev session end
to end (auth, negotiation, pause/resume acks, sandboxed write-read round
trip, sequence check, teardown, no-residue) with zero model spend.

Safe repair: --fix dry-runs a plan; --fix --yes applies with backup-first
atomic transactions, verify, rollback on failure, and metadata-only receipts
in repair-receipts.jsonl. Only skill-index rebuild, config-dir creation, and
stale-tmp pruning are implemented; destructive classes are documented as
forbidden.

Support bundle: aether support-bundle stages 8 allowlisted metadata-only
entries in a 0700 temp dir, packages with a minimal deterministic ustar
writer, reopens and re-parses the candidate, enforces the entry allowlist,
runs the canonical secret scanner (redaction.ts consolidates session_log's
helpers plus JWT/bearer/hex/userinfo/homedir detectors), verifies per-file
hashes, and only then renames into place — any failure deletes the candidate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… /why explanations, skills eval flags

aether capabilities [--json] [--available] renders static support separately
from runtime availability (packaged snapshot offline, server manifest when
signed in). /why replays the bounded explanation log — skill selections with
reasons and confidence, refusals, permission denials, and instruction
conflicts record entries at the moment they happen. aether agent gains
--skill <id> and --no-skills; skills eval gains --json/--junit passthrough.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AetherAI3 added a commit that referenced this pull request Aug 19, 2026
PR A0.2 of the SC-A0 Skills & Health integration rescue, part 1 of 2.

Recovers PR #71's capability matrix and support bundle onto main:

  src/core/capabilities.ts            capability matrix
  src/generated/agent_capabilities.ts packaged offline fallback snapshot
  src/core/support_bundle.ts          redacted, self-verifying bundle
  src/core/redaction.ts               shared redaction vocabulary
  src/core/tar.ts                     dependency-free tar writer

capabilities, redaction, and tar applied unmodified. support_bundle needed a
two-line port: it called PR #71's doctorReportV2, which this rescue drops in
favour of main's diagnosticReport (see the conflict matrix in
_loopstate/LOOP-01/sc-a0-2026-08-19/AUDIT-ARTIFACT.md, decision C1).

The swap is a strict improvement for the bundle. PR #71's report modelled
configured/reachable/verified as plain booleans, so a fast-mode bundle — which
performs no network I/O — had to serialize verified:false for every remote
axis, indistinguishable from checked-and-failed. main's HealthReport carries
per-axis "not-checked", so an unexercised probe stays visibly unexercised in
the artifact a user sends to support.

Still owed for A0.2 part 2: porting PR #71's skills and instructions checks
(the only two it has that main lacks) from its CheckSpec onto main's
CheckOutcome, and the safe-repair reconciliation.

Gates at this commit:
  npm run typecheck   exit 0
  npm test            1017 pass / 0 fail  (1007 before this commit)
  npm run smoke       3 pass / 3 skip / 1 fail

The smoke failure is `cloud turn` HTTP 401 "Invalid or expired session token".
Verified pre-existing: the identical failure reproduces at 1521199 with this
commit's changes stashed. It is an expired local credential requiring
`aether auth login`, not a code regression, and no file in this commit is on
the cloud-turn path. Recorded as an operator-owned gate, not a pass.

Bundle safety is covered by the ported suites, both passing here: a seeded
canary secret is rejected rather than shipped, and an interrupted generation
leaves no misleading "complete" artifact behind.
AetherAI3 added a commit that referenced this pull request Aug 19, 2026
…ontract

PR A0.2 of the SC-A0 Skills & Health integration rescue, part 2 of 2.

Ports the only two checks PR #71 has that main lacks — skills and instructions
— from PR #71's CheckSpec onto main's DiagnosticCheckSpec/CheckOutcome, and
wires them into fast mode. Six checks land:

  skills.index            store integrity and index errors
  skills.lock             lockfile presence and drift
  skills.trust            project skills untrusted or changed
  skills.evals            declared eval manifests
  instructions.graph      source count and parse warnings
  instructions.conflicts  detected conflicts, by topic

This is a shape translation, not a rewrite. PR #71 modelled a result as a
status plus a detail string with configured/reachable/verified as plain
booleans; each axis here carries its own state and evidence.

The translation is where the contract decision earns its keep. These checks
touch only the filesystem, so `reachable` is n/a — there is no remote to
reach — rather than a pass borrowed from a probe that never ran. Under PR
#71's booleans there was no way to say that: `reachable: false` would have
read as unreachable. `verified` is a genuine yes/no because these checks do
exercise the files they report on during the run.

The axis mapping lives in one helper (`localOutcome`) rather than being
repeated per check, so a future check cannot quietly claim a `verified` it
did not earn.

Extends, rather than relaxes, the frozen check-ID inventory in
test/diagnostics.test.ts. That assertion exists to catch unintended drift;
this drift is intended, so the expected list grows and the deep-equal stays
exact. Adds an assertion that both new categories report `reachable: "na"`,
so a later change cannot silently upgrade them to a pass.

Live proof against the built CLI at this commit — `aether doctor --json`:

  skills.index            cfg=yes reach=na ver=yes  0 skill(s) indexed
  skills.lock             cfg=yes reach=na ver=yes  no project skills, no lock required
  skills.trust            cfg=yes reach=na ver=yes  no project skills awaiting trust review
  skills.evals            cfg=yes reach=na ver=yes  no skills discovered
  instructions.graph      cfg=yes reach=na ver=yes  0 instruction source(s), no parse warnings
  instructions.conflicts  cfg=yes reach=na ver=yes  no instruction conflicts detected

The emitted payload contains no boolean-shaped `verified` field, confirming
PR #71's competing schema-v2 contract is absent rather than merely unused.

"0 skill(s) indexed" is truthful, not a defect: the built-in skill assets are
not packaged until A0.3.

Gates at this commit:
  npm run typecheck   exit 0
  npm test            1017 pass / 0 fail
AetherAI3 added a commit that referenced this pull request Aug 19, 2026
…ged assets

PR A0.3 of the SC-A0 Skills & Health integration rescue.

Makes the work in A0.1 and A0.2 reachable. Until this commit the skill runtime
existed but no user could invoke it.

  aether skills <subcommand>   list, show, check, trust, lock
  aether capabilities          capability contract, with --available
  aether support-bundle        redacted metadata-only diagnostic archive

Built-in skill assets (SKILL.md, skill.json, evals) ship as data, which tsc
does not emit, so `build` now runs scripts/copy-skill-assets.js after compile.
The existing `files: ["dist/src"]` entry already carries them into the tarball;
verified below rather than assumed.

Deliberately NOT taken from PR #71:

  * Its cli_registry entry rewriting `doctor [--deep]` to `[--network] [--fix]`.
    `--deep` stays read-only per decision C2 in the conflict matrix; aliasing it
    to a network-performing mode would silently change what an existing habit
    does. `--network` is a separate, explicitly named mode when it lands.
  * Its main.ts doctor flags (--network, --schema, --category, --failed), which
    belong to the doctor engine this rescue drops. main's doctor parses its own
    argv, so it needs none of them.
  * Its `aether agent --skill` / `--no-skills` flags and dev-session skill
    context. Those touch code.ts, chat.ts, brain_cloud.ts and stream.ts, which
    SC-A1, SC-A4 and SC-A5 own. Deferred rather than raced.

COMMANDS.md gains real sections, not just index entries. The parity test only
asserts the index, but an index pointing at nothing is a doc that lies by
omission. Every subcommand documented was then invoked to confirm it exists:

  skills list   -> 6 built-ins listed
  skills show   -> aether/ship@1.0.0 — Ship
  skills check  -> ok
  skills trust  -> "aether/ship is a builtin skill — already trusted"
  skills lock   -> locked 0 project skills

Live proof at this commit, against the built CLI:

  aether skills list        6 built-in skills, scope and trust shown
  aether capabilities       contract v1, falls back to the packaged snapshot and
                            states that it did so, and why
  aether support-bundle     25600-byte tar written, sha256 reported
  aether doctor --json      skills.index now reports "6 skill(s) indexed"
                            (it read 0 before the assets were packaged)

Gates at this commit:
  npm run typecheck        exit 0
  npm test                 1017 pass / 0 fail
  npm run verify:production exit 0 — ok:true, 518 packed files, 2315934 bytes
  npm pack --dry-run       18 dist/src/skills/builtin/** entries present

The COMMANDS.md parity test failed first on this change, correctly: the CLI
registry had grown and the doc had not. Fixed by documenting the commands, not
by relaxing the assertion.
AetherAI3 added a commit that referenced this pull request Aug 19, 2026
…upport bundle [SC-A0.1 + A0.2a] (#72)

* feat(skills): skill runtime and instruction resolver foundation

PR A0.1 of the SC-A0 Skills & Health integration rescue.

Recovers the skill and instruction subsystems from PR #71 (a868f7d) onto
current main (41a7e26) without importing PR #71's parallel doctor engine.

PR #71 branched at b98ef26 (2026-08-12) and never saw PR #66 (27c100d,
2026-08-14), which landed its own doctor v2 on main. Both declare doctor
schema version 2 with incompatible payloads: main's health.ts models
configured/reachable/verified as Axis objects with a "not-checked" state,
PR #71's contracts.ts models them as plain booleans. A boolean cannot
express "not checked", so in fast mode — which performs no network I/O —
every remote axis would have to report false, which is indistinguishable
from checked-and-failed. main's contract is both newer and safer, so it
stays canonical and PR #71's is dropped rather than merged.

This commit lands only the part of PR #71 that main has no equivalent of,
and which turned out to apply to main unmodified:

  src/core/skills/*        schema, digest, lock, trust, discovery, loader,
                           resolver, policy, bounds, eval, session, settings,
                           context packet, permission vocabulary
  src/core/instructions/*  AGENTS.md discovery and resolution with provenance
  src/core/why_log.ts      capability explanation log

Capabilities, support bundle, and the skills/instructions doctor checks
follow in A0.2; CLI wiring and packaged skill assets follow in A0.3.

The full conflict matrix, including the four textual conflicts and the
decision record for each contested surface, is in
_loopstate/LOOP-01/sc-a0-2026-08-19/AUDIT-ARTIFACT.md.

Gates at this commit, run against this exact tree:
  npm run typecheck   exit 0
  npm test            1006 pass / 0 fail  (baseline on 41a7e26 was 922/0)

* fix(instructions): escape every glob metacharacter, not just the first

CodeQL js/incomplete-sanitization (high) on PR #72, at
src/core/instructions/instruction_resolver.ts:18 — the metacharacter escape
in globToRegExp used a non-global regex.

Not exploitable as written: `char` is `glob[index]`, always a single code
unit, so there is never a second occurrence to miss. But the safety of that
escape rests on an invariant nothing in the function states, and a future
change to a multi-character token would silently widen every glob's match
set. Fixed rather than dismissed, since the fix is free.

Adds a regression test that pins the property rather than the implementation:
a glob containing . + ( ) | { } [ ] $ ^ must match itself literally and must
not match a decoy path, while ** and * keep working.

Mutation-checked: replacing the escape with a bare `pattern += char` fails
the new test with "unescaped . would match axts"; restoring it passes.

Gates at this commit:
  npm run typecheck   exit 0
  npm test            1007 pass / 0 fail

* feat(capabilities): capability matrix and redacted support bundle

PR A0.2 of the SC-A0 Skills & Health integration rescue, part 1 of 2.

Recovers PR #71's capability matrix and support bundle onto main:

  src/core/capabilities.ts            capability matrix
  src/generated/agent_capabilities.ts packaged offline fallback snapshot
  src/core/support_bundle.ts          redacted, self-verifying bundle
  src/core/redaction.ts               shared redaction vocabulary
  src/core/tar.ts                     dependency-free tar writer

capabilities, redaction, and tar applied unmodified. support_bundle needed a
two-line port: it called PR #71's doctorReportV2, which this rescue drops in
favour of main's diagnosticReport (see the conflict matrix in
_loopstate/LOOP-01/sc-a0-2026-08-19/AUDIT-ARTIFACT.md, decision C1).

The swap is a strict improvement for the bundle. PR #71's report modelled
configured/reachable/verified as plain booleans, so a fast-mode bundle — which
performs no network I/O — had to serialize verified:false for every remote
axis, indistinguishable from checked-and-failed. main's HealthReport carries
per-axis "not-checked", so an unexercised probe stays visibly unexercised in
the artifact a user sends to support.

Still owed for A0.2 part 2: porting PR #71's skills and instructions checks
(the only two it has that main lacks) from its CheckSpec onto main's
CheckOutcome, and the safe-repair reconciliation.

Gates at this commit:
  npm run typecheck   exit 0
  npm test            1017 pass / 0 fail  (1007 before this commit)
  npm run smoke       3 pass / 3 skip / 1 fail

The smoke failure is `cloud turn` HTTP 401 "Invalid or expired session token".
Verified pre-existing: the identical failure reproduces at 1521199 with this
commit's changes stashed. It is an expired local credential requiring
`aether auth login`, not a code regression, and no file in this commit is on
the cloud-turn path. Recorded as an operator-owned gate, not a pass.

Bundle safety is covered by the ported suites, both passing here: a seeded
canary secret is rejected rather than shipped, and an interrupted generation
leaves no misleading "complete" artifact behind.

* feat(doctor): skill and instruction health checks on the three-axis contract

PR A0.2 of the SC-A0 Skills & Health integration rescue, part 2 of 2.

Ports the only two checks PR #71 has that main lacks — skills and instructions
— from PR #71's CheckSpec onto main's DiagnosticCheckSpec/CheckOutcome, and
wires them into fast mode. Six checks land:

  skills.index            store integrity and index errors
  skills.lock             lockfile presence and drift
  skills.trust            project skills untrusted or changed
  skills.evals            declared eval manifests
  instructions.graph      source count and parse warnings
  instructions.conflicts  detected conflicts, by topic

This is a shape translation, not a rewrite. PR #71 modelled a result as a
status plus a detail string with configured/reachable/verified as plain
booleans; each axis here carries its own state and evidence.

The translation is where the contract decision earns its keep. These checks
touch only the filesystem, so `reachable` is n/a — there is no remote to
reach — rather than a pass borrowed from a probe that never ran. Under PR
#71's booleans there was no way to say that: `reachable: false` would have
read as unreachable. `verified` is a genuine yes/no because these checks do
exercise the files they report on during the run.

The axis mapping lives in one helper (`localOutcome`) rather than being
repeated per check, so a future check cannot quietly claim a `verified` it
did not earn.

Extends, rather than relaxes, the frozen check-ID inventory in
test/diagnostics.test.ts. That assertion exists to catch unintended drift;
this drift is intended, so the expected list grows and the deep-equal stays
exact. Adds an assertion that both new categories report `reachable: "na"`,
so a later change cannot silently upgrade them to a pass.

Live proof against the built CLI at this commit — `aether doctor --json`:

  skills.index            cfg=yes reach=na ver=yes  0 skill(s) indexed
  skills.lock             cfg=yes reach=na ver=yes  no project skills, no lock required
  skills.trust            cfg=yes reach=na ver=yes  no project skills awaiting trust review
  skills.evals            cfg=yes reach=na ver=yes  no skills discovered
  instructions.graph      cfg=yes reach=na ver=yes  0 instruction source(s), no parse warnings
  instructions.conflicts  cfg=yes reach=na ver=yes  no instruction conflicts detected

The emitted payload contains no boolean-shaped `verified` field, confirming
PR #71's competing schema-v2 contract is absent rather than merely unused.

"0 skill(s) indexed" is truthful, not a defect: the built-in skill assets are
not packaged until A0.3.

Gates at this commit:
  npm run typecheck   exit 0
  npm test            1017 pass / 0 fail

* feat(cli): aether skills, capabilities and support-bundle, with packaged assets

PR A0.3 of the SC-A0 Skills & Health integration rescue.

Makes the work in A0.1 and A0.2 reachable. Until this commit the skill runtime
existed but no user could invoke it.

  aether skills <subcommand>   list, show, check, trust, lock
  aether capabilities          capability contract, with --available
  aether support-bundle        redacted metadata-only diagnostic archive

Built-in skill assets (SKILL.md, skill.json, evals) ship as data, which tsc
does not emit, so `build` now runs scripts/copy-skill-assets.js after compile.
The existing `files: ["dist/src"]` entry already carries them into the tarball;
verified below rather than assumed.

Deliberately NOT taken from PR #71:

  * Its cli_registry entry rewriting `doctor [--deep]` to `[--network] [--fix]`.
    `--deep` stays read-only per decision C2 in the conflict matrix; aliasing it
    to a network-performing mode would silently change what an existing habit
    does. `--network` is a separate, explicitly named mode when it lands.
  * Its main.ts doctor flags (--network, --schema, --category, --failed), which
    belong to the doctor engine this rescue drops. main's doctor parses its own
    argv, so it needs none of them.
  * Its `aether agent --skill` / `--no-skills` flags and dev-session skill
    context. Those touch code.ts, chat.ts, brain_cloud.ts and stream.ts, which
    SC-A1, SC-A4 and SC-A5 own. Deferred rather than raced.

COMMANDS.md gains real sections, not just index entries. The parity test only
asserts the index, but an index pointing at nothing is a doc that lies by
omission. Every subcommand documented was then invoked to confirm it exists:

  skills list   -> 6 built-ins listed
  skills show   -> aether/ship@1.0.0 — Ship
  skills check  -> ok
  skills trust  -> "aether/ship is a builtin skill — already trusted"
  skills lock   -> locked 0 project skills

Live proof at this commit, against the built CLI:

  aether skills list        6 built-in skills, scope and trust shown
  aether capabilities       contract v1, falls back to the packaged snapshot and
                            states that it did so, and why
  aether support-bundle     25600-byte tar written, sha256 reported
  aether doctor --json      skills.index now reports "6 skill(s) indexed"
                            (it read 0 before the assets were packaged)

Gates at this commit:
  npm run typecheck        exit 0
  npm test                 1017 pass / 0 fail
  npm run verify:production exit 0 — ok:true, 518 packed files, 2315934 bytes
  npm pack --dry-run       18 dist/src/skills/builtin/** entries present

The COMMANDS.md parity test failed first on this change, correctly: the CLI
registry had grown and the doc had not. Fixed by documenting the commands, not
by relaxing the assertion.

* chore: drop .aether/skills.lock.json committed by mistake

This file was written into the worktree by running `aether skills lock` while
verifying that the documented subcommand actually exists. It is a byproduct of
that check, not source, and it was swept in by `git add -A` in the previous
commit.

`aether skills lock` is a project-scoped command: the lockfile belongs to
whichever repository a user runs it in, generated on demand. Shipping this
repo's own lockfile would pin an empty project skill set into the package for
no reason.
@AetherAI3

Copy link
Copy Markdown
Owner Author

Superseded by #72, now merged.

The valuable half of this PR is on main: the skill runtime (src/core/skills/*), the instruction resolver, the capability matrix, the redacted support bundle, the aether skills / capabilities / support-bundle commands, and the six packaged built-in skills. It applied to current main with zero source edits — evidence the conflict was confined to one subsystem.

The doctor engine here was deliberately not carried forward. This branch was authored from b98ef26 (08-12) and never saw PR #66 (27c100d, 08-14 14:42), which had already landed its own doctor v2 on main. Both declare schema_version: 2 with incompatible payloads: main models configured/reachable/verified as Axis objects with a not-checked state, this branch as plain booleans. A boolean cannot express not checked — and fast mode performs no network I/O, so every remote axis would serialize false, indistinguishable from checked and failed. main's contract is both newer and the only one that can tell those apart, so it stays canonical.

The two checks this branch had that main lacked — skills and instructions — were ported onto main's three-axis CheckOutcome and are live in #72.

Full reasoning and the per-surface decision record: _loopstate/LOOP-01/sc-a0-2026-08-19/AUDIT-ARTIFACT.md on main.

@AetherAI3 AetherAI3 closed this Aug 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant