instar 0.28.119 → 0.28.120

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ /**
2
+ * conversationalActionCatalog — discovery + rendering for the conversational
3
+ * action catalog (Layer-3 primitive #10, v0.1).
4
+ *
5
+ * Spec: specs/instar-concepts/conversational-action.md
6
+ *
7
+ * Walks canonical skills under `.instar/skills/<name>/SKILL.md`, generates a
8
+ * stable markdown block listing each one as a conversational action, and
9
+ * idempotently inserts/replaces that block in canonical AGENT.md.
10
+ *
11
+ * v0.1 scope:
12
+ * - Catalog discovery + filtering.
13
+ * - Markdown block generation with delimiter comments.
14
+ * - Idempotent applyCatalogBlock() — insert or replace cleanly.
15
+ *
16
+ * v0.2 deferred:
17
+ * - `user-invocable: true` frontmatter filter (pending Skill v0.2 field surface).
18
+ * - Authed POST execution endpoints.
19
+ * - Per-action JSON Schema / action-shape declarations.
20
+ * - Wiring into FrameworkParitySentinel as a parity rule (catalog-drift detection).
21
+ */
22
+ export interface ConversationalAction {
23
+ /** Canonical skill name (== slug == slash-command suffix) */
24
+ name: string;
25
+ /** Short description used in catalog entry + agent-side intent classification */
26
+ description: string;
27
+ /** Framework-agnostic invocation path. v0.1: always `/${name}` */
28
+ invocation: string;
29
+ }
30
+ declare function parseFrontmatter(raw: string): {
31
+ fm: Record<string, unknown>;
32
+ rest: string;
33
+ };
34
+ /**
35
+ * Walk `.instar/skills/<name>/SKILL.md` under `projectRoot`, return the
36
+ * discovered conversational actions sorted by name.
37
+ *
38
+ * v0.1: enumerates ALL canonical skills (no `user-invocable` filter).
39
+ */
40
+ export declare function discoverActions(projectRoot: string): Promise<ConversationalAction[]>;
41
+ /**
42
+ * Render the catalog markdown block (with start/end delimiter comments).
43
+ *
44
+ * Stable output — given the same actions list, returns the same string.
45
+ * Pure function: no I/O. Caller decides where the block lands (typically a
46
+ * Tier 2 ContextHierarchy segment, a SelfKnowledgeTree probe response, or a
47
+ * Playbook context item — NOT inlined into AGENT.md, per the bloat-aware
48
+ * design constraint documented in the concept spec).
49
+ */
50
+ export declare function renderCatalogBlock(actions: ReadonlyArray<ConversationalAction>): string;
51
+ export declare const _internals: {
52
+ parseFrontmatter: typeof parseFrontmatter;
53
+ BLOCK_START: string;
54
+ BLOCK_END: string;
55
+ };
56
+ export {};
57
+ //# sourceMappingURL=conversationalActionCatalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversationalActionCatalog.d.ts","sourceRoot":"","sources":["../../../src/providers/parity/conversationalActionCatalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAWH,MAAM,WAAW,oBAAoB;IACnC,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;CACpB;AAkBD,iBAAS,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAiBpF;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAoC1F;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,oBAAoB,CAAC,GAAG,MAAM,CAiBvF;AAgBD,eAAO,MAAM,UAAU;;;;CAA+C,CAAC"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * conversationalActionCatalog — discovery + rendering for the conversational
3
+ * action catalog (Layer-3 primitive #10, v0.1).
4
+ *
5
+ * Spec: specs/instar-concepts/conversational-action.md
6
+ *
7
+ * Walks canonical skills under `.instar/skills/<name>/SKILL.md`, generates a
8
+ * stable markdown block listing each one as a conversational action, and
9
+ * idempotently inserts/replaces that block in canonical AGENT.md.
10
+ *
11
+ * v0.1 scope:
12
+ * - Catalog discovery + filtering.
13
+ * - Markdown block generation with delimiter comments.
14
+ * - Idempotent applyCatalogBlock() — insert or replace cleanly.
15
+ *
16
+ * v0.2 deferred:
17
+ * - `user-invocable: true` frontmatter filter (pending Skill v0.2 field surface).
18
+ * - Authed POST execution endpoints.
19
+ * - Per-action JSON Schema / action-shape declarations.
20
+ * - Wiring into FrameworkParitySentinel as a parity rule (catalog-drift detection).
21
+ */
22
+ import { promises as fs } from 'node:fs';
23
+ import path from 'node:path';
24
+ import yaml from 'js-yaml';
25
+ const CANONICAL_SKILLS_ROOT = '.instar/skills';
26
+ const BLOCK_START = '<!-- instar:conversational-actions:start -->';
27
+ const BLOCK_END = '<!-- instar:conversational-actions:end -->';
28
+ const SLUG_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
29
+ class CatalogError extends Error {
30
+ constructor(message) {
31
+ super(message);
32
+ this.name = 'CatalogError';
33
+ }
34
+ }
35
+ async function pathExists(p) {
36
+ try {
37
+ await fs.access(p);
38
+ return true;
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ }
44
+ function parseFrontmatter(raw) {
45
+ if (!raw.startsWith('---\n')) {
46
+ return { fm: {}, rest: raw };
47
+ }
48
+ const close = raw.indexOf('\n---', 4);
49
+ if (close < 0) {
50
+ throw new CatalogError('skill SKILL.md has unterminated YAML frontmatter');
51
+ }
52
+ const fmRaw = raw.slice(4, close);
53
+ let fm;
54
+ try {
55
+ fm = yaml.load(fmRaw, { schema: yaml.FAILSAFE_SCHEMA, json: false });
56
+ }
57
+ catch (err) {
58
+ throw new CatalogError(`skill SKILL.md YAML parse error: ${err.message}`);
59
+ }
60
+ const rest = raw.slice(close + 4).replace(/^\n/, '');
61
+ return { fm: (fm && typeof fm === 'object' ? fm : {}), rest };
62
+ }
63
+ /**
64
+ * Walk `.instar/skills/<name>/SKILL.md` under `projectRoot`, return the
65
+ * discovered conversational actions sorted by name.
66
+ *
67
+ * v0.1: enumerates ALL canonical skills (no `user-invocable` filter).
68
+ */
69
+ export async function discoverActions(projectRoot) {
70
+ const skillsRoot = path.join(projectRoot, CANONICAL_SKILLS_ROOT);
71
+ if (!(await pathExists(skillsRoot)))
72
+ return [];
73
+ const entries = await fs.readdir(skillsRoot, { withFileTypes: true });
74
+ const actions = [];
75
+ for (const entry of entries) {
76
+ if (!entry.isDirectory())
77
+ continue;
78
+ if (!SLUG_RE.test(entry.name))
79
+ continue;
80
+ const skillMdPath = path.join(skillsRoot, entry.name, 'SKILL.md');
81
+ if (!(await pathExists(skillMdPath)))
82
+ continue;
83
+ let raw;
84
+ try {
85
+ raw = await fs.readFile(skillMdPath, 'utf-8');
86
+ }
87
+ catch {
88
+ continue;
89
+ }
90
+ let parsed;
91
+ try {
92
+ parsed = parseFrontmatter(raw);
93
+ }
94
+ catch {
95
+ // Skip broken skills; the Skill parity rule surfaces them separately.
96
+ continue;
97
+ }
98
+ const name = String(parsed.fm.name ?? entry.name);
99
+ const description = typeof parsed.fm.description === 'string'
100
+ ? parsed.fm.description
101
+ : '(no description)';
102
+ actions.push({
103
+ name,
104
+ description,
105
+ invocation: `/${name}`,
106
+ });
107
+ }
108
+ actions.sort((a, b) => a.name.localeCompare(b.name));
109
+ return actions;
110
+ }
111
+ /**
112
+ * Render the catalog markdown block (with start/end delimiter comments).
113
+ *
114
+ * Stable output — given the same actions list, returns the same string.
115
+ * Pure function: no I/O. Caller decides where the block lands (typically a
116
+ * Tier 2 ContextHierarchy segment, a SelfKnowledgeTree probe response, or a
117
+ * Playbook context item — NOT inlined into AGENT.md, per the bloat-aware
118
+ * design constraint documented in the concept spec).
119
+ */
120
+ export function renderCatalogBlock(actions) {
121
+ const lines = [BLOCK_START, '## Conversational Actions', ''];
122
+ if (actions.length === 0) {
123
+ lines.push('_No conversational actions installed yet. Install a skill under `.instar/skills/<name>/` to make it available here._');
124
+ }
125
+ else {
126
+ lines.push('When the user expresses intent that maps to one of these, invoke the slash-command (or guide them conversationally to the equivalent action). You do not need to surface the slash-command name to the user — translate intent into invocation.', '');
127
+ for (const a of actions) {
128
+ lines.push(`- \`${a.invocation}\` — ${a.description}`);
129
+ }
130
+ }
131
+ lines.push('', BLOCK_END);
132
+ return lines.join('\n') + '\n';
133
+ }
134
+ /*
135
+ * NOTE: applyCatalogBlock(...) deliberately NOT exported in v0.1.
136
+ *
137
+ * Writing the catalog block directly into AGENT.md (the always-loaded Tier 0
138
+ * identity file) is the AGENT.md-bloat antipattern Instar built three
139
+ * defenses against (ContextHierarchy, Playbook, SelfKnowledgeTree). The
140
+ * catalog block is returned as a string from renderCatalogBlock(); the
141
+ * caller (a v0.2 ContextHierarchy Tier 2 segment writer, a SelfKnowledgeTree
142
+ * probe handler, or a Playbook context item) decides where it lands.
143
+ *
144
+ * See specs/instar-concepts/conversational-action.md ("Bloat-awareness as a
145
+ * v0.1 design constraint") for the full rationale.
146
+ */
147
+ export const _internals = { parseFrontmatter, BLOCK_START, BLOCK_END };
148
+ //# sourceMappingURL=conversationalActionCatalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversationalActionCatalog.js","sourceRoot":"","sources":["../../../src/providers/parity/conversationalActionCatalog.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "0.28.119",
3
+ "version": "0.28.120",
4
4
  "description": "Persistent autonomy infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-05-19T02:38:16.455Z",
5
- "instarVersion": "0.28.119",
4
+ "generatedAt": "2026-05-19T04:26:32.444Z",
5
+ "instarVersion": "0.28.120",
6
6
  "entryCount": 189,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,44 @@
1
+ # Upgrade Guide — v1.0.6
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ Lands the Conversational-action primitive (Layer-3 required primitive #10) — but **deliberately narrow**: pure-data catalog primitives only, no direct AGENT.md write.
8
+
9
+ Foundational stance, locked 2026-05-18 per Justin: users should never have to know any Instar internals. Conversational is the default; slash-commands are a backstop. When the user says "let's switch to local" the agent recognizes that intent and either invokes /local-model or guides the user there — without surfacing the slash-command name.
10
+
11
+ For the agent to translate intent to action, it needs a catalog of what is invocable. The earlier draft of this PR would have written that catalog directly into AGENT.md (the always-loaded identity file). After a scope-coherence pause + Justin's research request, we caught that this contradicts three Instar systems built specifically to prevent AGENT.md bloat: ContextHierarchy (Tier 0/1/2 segments), Playbook (scored decaying items), Self-Knowledge Tree (on-demand probes). So we removed the AGENT.md-writing API from v0.1.
12
+
13
+ v0.1 ships only the pure-data primitives:
14
+ - discoverActions(projectRoot) walks .instar/skills/ and returns the discovered actions sorted by name
15
+ - renderCatalogBlock(actions) generates a stable markdown block as a string (caller decides where it lands)
16
+
17
+ v0.1 explicitly does NOT ship:
18
+ - A function that writes the catalog into AGENT.md. v0.2 will route the catalog through ContextHierarchy Tier 2 segments (loaded on demand when the agent is interpreting user intent), a Self-Knowledge Tree probe (queried on demand), and a Playbook item (scored + decaying). All three load conditionally, not always.
19
+ - Authed POST execution endpoints. v0.2 with per-action shape declarations + trust integration.
20
+ - The user-invocable: true frontmatter filter. v0.2 once Skill primitive surfaces that field.
21
+
22
+ 14 unit tests cover discovery and rendering, including a structural assertion that the AGENT.md-writing API is absent from the public surface — the bloat-aware design is enforced at the test layer.
23
+
24
+ Spec at specs/instar-concepts/conversational-action.md (converged + approved per hybrid-C pre-auth). ELI16 + convergence report alongside. Side-effects review documents the amendment in full.
25
+
26
+ ## What to Tell Your User
27
+
28
+ - "The first piece of the conversational-action primitive is built — it discovers what is invocable and generates the catalog. The wiring step is held until v0.2 so we can load the catalog only when the agent needs it, instead of inlining it into the always-on identity prompt. That avoids the context-bloat trap we hit three times before."
29
+
30
+ ## Summary of New Capabilities
31
+
32
+ | Capability | How to Use |
33
+ |-----------|-----------|
34
+ | Conversational action catalog (pure-data) | Import discoverActions and renderCatalogBlock from src/providers/parity/conversationalActionCatalog.js. Walks installed skills, generates the catalog block as a string. |
35
+ | Bloat-aware design enforced at test layer | The applyCatalogBlock API is deliberately absent from the public module exports; a structural test asserts this. |
36
+
37
+ ## Deferred (Tracked Follow-ups)
38
+
39
+ - v0.2 wiring through ContextHierarchy Tier 2 segment + SelfKnowledgeTree catalog probe + Playbook context item (all three on-demand loaders).
40
+ - v0.2 FrameworkParitySentinel wiring as a catalog-drift parity rule.
41
+ - v0.2 authed POST /api/conversational/execute endpoints with per-action shape declarations + trust integration.
42
+ - v0.2 user-invocable: true frontmatter filter (pending Skill v0.2 field surface).
43
+ - InstructionFile primitive (separate spec, next) — decides what minimal pointer goes into framework-native instruction files.
44
+ - Intent-classification examples in skill frontmatter.
@@ -0,0 +1,101 @@
1
+ # Side-Effects Review — Conversational-action primitive v0.1 (bloat-aware catalog primitives)
2
+
3
+ **Version / slug:** `feat-conversational-action`
4
+ **Date:** 2026-05-19
5
+ **Author:** Echo (autonomous mode, hybrid C, amended after scope-coherence grounding pause)
6
+
7
+ ## Summary of the change
8
+
9
+ Lands the Conversational-action primitive (Layer-3 required primitive #10) as **bloat-aware pure-data primitives**: `discoverActions` (walks installed canonical skills) + `renderCatalogBlock` (generates the catalog block as a string). 14 unit tests including a structural assertion that `applyCatalogBlock` is deliberately NOT exported.
10
+
11
+ **Amended scope (post-grounding):** the original draft included `applyCatalogBlock(projectRoot, actions)` that wrote directly into `.instar/AGENT.md`. The scope-coherence hook + Justin's explicit research request surfaced that this contradicts three existing Instar systems built specifically to prevent AGENT.md bloat:
12
+
13
+ - `ContextHierarchy` (`src/core/ContextHierarchy.ts`) — Tier 0/1/2 segments, "right context at right moment > all context all the time" (born from the Luna incident 2026-02-25)
14
+ - `Playbook` (`docs/PLAYBOOK-GETTING-STARTED.md`) — scored decaying context items
15
+ - `SelfKnowledgeTree` (`src/knowledge/SelfKnowledgeTree.ts`) — on-demand probe queries instead of memorized lists
16
+ - Plus the `Structure > Willpower` principle codified in CLAUDE.md template
17
+
18
+ `applyCatalogBlock` was removed from v0.1 to prevent baking the wrong placement decision into a primitive's surface. v0.2 wiring goes through the three infrastructures above (Tier 2 segment writer, `catalog` probe, Playbook item) — not direct AGENT.md insert.
19
+
20
+ **Files changed (specs):**
21
+ - specs/instar-concepts/conversational-action.md (new, converged + approved per pre-auth; includes "Bloat-awareness as a v0.1 design constraint" section)
22
+ - specs/instar-concepts/conversational-action.eli16.md (new)
23
+ - docs/specs/reports/conversational-action-concept-convergence.md (new — records the amended scope as iteration 2 finding)
24
+
25
+ **Files changed (source):**
26
+ - src/providers/parity/conversationalActionCatalog.ts (new — discoverActions + renderCatalogBlock only; applyCatalogBlock deliberately NOT exported)
27
+
28
+ **Files changed (tests):**
29
+ - tests/unit/providers/parity/conversationalActionCatalog.test.ts (new — 14 tests; includes structural assertion that applyCatalogBlock is absent from public API)
30
+
31
+ **Files changed (release notes):**
32
+ - upgrades/NEXT.md (new)
33
+ - package.json (version bump)
34
+
35
+ ## Decision-point inventory
36
+
37
+ - **Building-block scope, bloat-aware**: ships `discoverActions` + `renderCatalogBlock` only. No direct AGENT.md write. Caller (v0.2 ContextHierarchy / SelfKnowledgeTree / Playbook wiring) decides where the block lands.
38
+ - **`applyCatalogBlock` removal**: structural prevention of AGENT.md bloat. Spec body documents why; one test enforces the public API surface.
39
+ - **Skill discovery enumerates all canonical skills**: `user-invocable: true` filter deferred to v0.2 (Skill v0.1 doesn't surface that field).
40
+ - **Catalog block format**: HTML-comment delimited (`<!-- instar:conversational-actions:start -->` / `:end -->`), stable + machine-readable, idempotent re-renders.
41
+ - **Discovery skip-on-error**: skills with broken YAML frontmatter or invalid slugs are silently skipped (Skill parity rule surfaces them separately as drift). Avoids double-reporting.
42
+ - **No registry entry**: catalog is consumed via direct import (matches Tool primitive precedent). v0.2 sentinel-wired drift detection is the registry consumer.
43
+ - **No I/O writes**: `discoverActions` reads `.instar/skills/`; `renderCatalogBlock` is pure function. Module never writes anywhere.
44
+
45
+ ## Over-block / under-block analysis
46
+
47
+ **Over-block risk (catalog rendering):** none — block is pure data, never imposed on AGENT.md.
48
+
49
+ **Under-block risk (broken skills skipped):** a skill with malformed frontmatter is silently absent from the catalog. The Skill parity rule already surfaces this as drift on its own pass; v0.2 sentinel wiring will combine signals.
50
+
51
+ **Under-block risk (v0.2 not yet wired):** until v0.2 wires the catalog into ContextHierarchy / SelfKnowledgeTree / Playbook, the catalog data exists but nothing reads it. That's intentional — better to ship correct pure-data primitives now than to ship a half-baked wiring that bakes in the bloat path.
52
+
53
+ ## Level-of-abstraction fit
54
+
55
+ - Catalog primitives are pure data — discovery + rendering. No I/O writes, no LLM calls, no AGENT.md awareness.
56
+ - Boundary clean: catalog OWNS the block format; doesn't OWN where it lands.
57
+ - Pure-function shape: `discoverActions`, `renderCatalogBlock` — composable with any downstream loading vehicle.
58
+
59
+ ## Signal-vs-authority compliance
60
+
61
+ - Catalog is signal (here's what's invocable + when).
62
+ - Authority over loading placement: the v0.2 ContextHierarchy / SelfKnowledgeTree / Playbook integrations + ultimately the agent's runtime intent classifier.
63
+ - v0.2 authed POST endpoints will gate execution via trust — separate authority layer.
64
+
65
+ ## Interaction surface
66
+
67
+ - One new file under `src/providers/parity/`. No HTTP routes, no server.ts wiring, no config additions, no AGENT.md writes.
68
+ - Reads `.instar/skills/<name>/SKILL.md`.
69
+ - No changes to existing rules, registries, scaffold, or migration paths.
70
+ - No new dependencies.
71
+
72
+ ## Rollback cost
73
+
74
+ - Pure-add. Revert removes the module + tests + spec. No data migrations, no AGENT.md state to undo (because no writes).
75
+ - Worst-case bug: `renderCatalogBlock` produces malformed markdown. Mitigated by stability test + delimiter shape test.
76
+
77
+ ## Test coverage
78
+
79
+ - Unit: 14 tests covering discovery (empty/single/multiple/sort/fallback/slug-filter/broken-YAML-skip/files-vs-dirs), rendering (empty placeholder, bullet shape, stability), end-to-end discover → render, **structural assertion that applyCatalogBlock is NOT in the public API** (enforces the bloat-aware design constraint at the test layer).
80
+ - Integration + E2E: not applicable for pure-data primitives. v0.2 wiring PR will add integration + E2E when HTTP/sentinel/segment-writer surfaces land.
81
+
82
+ ## Documentation
83
+
84
+ - Concept spec + ELI16 at `specs/instar-concepts/` (both updated to lead with the bloat-awareness design constraint).
85
+ - Convergence report at `docs/specs/reports/` (iteration 2 records the bloat-aware amendment).
86
+ - NEXT.md with "What to Tell Your User" entries explaining the deliberately-narrow v0.1 scope.
87
+
88
+ ## Deferred (tracked, not silent)
89
+
90
+ - **ContextHierarchy Tier 2 segment writer** that consumes `renderCatalogBlock` output → `.instar/context/conversational-actions.md` with triggers `interpreting-user-intent` / `answering-what-can-you-do` — v0.2.
91
+ - **SelfKnowledgeTree `catalog` probe** that returns matching actions for a query at runtime — v0.2.
92
+ - **Playbook context item** seeded with the catalog discovery pattern + decay configuration — v0.2.
93
+ - **FrameworkParitySentinel wiring** as a catalog-drift parity rule (catalog-out-of-sync detection on scan) — v0.2.
94
+ - **Authed POST /api/conversational/execute endpoints** — v0.2 with per-action shape declarations + trust integration.
95
+ - **`user-invocable: true` filter** — v0.2, pending Skill v0.2 field surface.
96
+ - **InstructionFile primitive** — separate spec, decides what minimal pointer (3 sentences max) goes into framework-native CLAUDE.md / AGENTS.md.
97
+ - **Intent-classification examples in skill frontmatter** — v0.2.
98
+
99
+ ## Why this amendment matters
100
+
101
+ The pre-amendment v0.1 would have shipped `applyCatalogBlock` as the headline API, with a NEXT.md line saying "v0.2 will fix the bloat concern." That's the "Phase 2" anti-pattern Justin explicitly listed in this autonomous session's stop-hook brief: "every task has a concrete done state. No deferrals disguised as planning." Removing `applyCatalogBlock` makes the v0.1 surface honest — the primitive ships what it can ship correctly, and the wiring decision waits for the right loading vehicle to land.