From d2403a83a4aa15f77c1f710f6f550d9000d6b1df Mon Sep 17 00:00:00 2001 From: Kailas Mahavarkar <66670953+KailasMahavarkar@users.noreply.github.com> Date: Sat, 18 Jul 2026 15:18:12 +0530 Subject: [PATCH] feat(framework): one Hyperstack - personas auto-triggered, compiled from manifests Personas, skills, MCP, roles declared and wired as ONE framework: - Bootstrap critical block: Three-Layer Ecosystem -> ONE framework with four layers; 1% Rule extended to persona triggers ('the user never has to name them') - Personas layer now GENERATED from personas//persona.json manifests (single source of truth): id, mode, description, full engages_when trigger table compiled into every session's bootstrap. Hand-maintained bullets in skills/hyperstack/SKILL.md removed (drift killed) - proof: a manifest trigger edit reaches the bootstrap with zero SKILL.md edits - persona.schema.json + all 4 manifests gain description field - Markers extended: marketing, reflect, Triggers: guarded at compile - Gate semantics hardened from live-test gaps: PASS requires evidence (populated fields = NEEDS-INPUT), 'acting' defined (inspection and classification only pre-gate), net-new vs tweak boundary stated Also folded in (user feedback): - bro sidekick format: quote-block with kanji breakdown + how natives ACTUALLY use the word + simplified usage - never a dense run-on line - reflect reviews features too (shipped or planned): value verdict (want it / don't care / against + the one flipping condition), never invented-UI commentary; screens still get the react; panel mode works on features (value collisions) Pressure evidence: hyper agent given only the compiled bootstrap and 'build a referral program' (no persona named) auto-engaged product-manager per the trigger line, ran 4 product_manager_* MCP tools, held the gate NEEDS-INPUT for lack of evidence, and queued the full skill pipeline post-PASS. Its 5 reported wording gaps: top 4 closed here. 87 tests pass; compiler invariant test now feeds an explicit minimal manifest (compiler stays pure via injectable personas param). --- .../runtime-context/hyperstack.bootstrap.md | 22 +++++++++------- personas/marketing/persona.json | 1 + personas/persona.schema.json | 1 + personas/product-manager/persona.json | 1 + personas/reflect/LIFECYCLE.md | 1 + personas/reflect/PROFILE.md | 6 +++-- personas/reflect/persona.json | 5 +++- skills/INDEX.md | 2 +- skills/bro/SKILL.md | 16 +++++++++++- skills/hyperstack/SKILL.md | 21 ++++++++------- skills/reflect/SKILL.md | 21 ++++++++++++++- src/internal/context-compiler.ts | 26 ++++++++++++++++--- src/personas/registry.ts | 1 + tests/context-compiler-behaviour.test.ts | 12 ++++++++- 14 files changed, 107 insertions(+), 29 deletions(-) diff --git a/generated/runtime-context/hyperstack.bootstrap.md b/generated/runtime-context/hyperstack.bootstrap.md index b2231c3..627ed23 100644 --- a/generated/runtime-context/hyperstack.bootstrap.md +++ b/generated/runtime-context/hyperstack.bootstrap.md @@ -4,12 +4,13 @@ ## Critical You have Hyperstack. This is not optional knowledge - it is how you operate in this repository. -Hyperstack is a **Three-Layer Ecosystem**: +Hyperstack is **ONE framework with four layers** - not four separate systems: 1. **Layer 1: Ground Truth (MCP)** - Deterministic data for the stack. 2. **Layer 2: Process (Skills)** - Disciplined engineering workflows and gates. -3. **Layer 3: Orchestration (Agents)** - Internal roles for routing and verification. +3. **Layer 3: Orchestration (Roles)** - Internal roles for routing and verification. +4. **Layer 4: Personas** - Domain-expert lenses, auto-engaged by trigger, each binding its MCP plugin + skills + role routing via one manifest. -**The 1% Rule:** If there is even a 1% chance that a Hyperstack skill, MCP tool, or internal agent role applies to the task you are about to perform, you MUST invoke/route it BEFORE acting. Not after you "check the code quickly." Not after you "just try one thing." Not after you "confirm your understanding." BEFORE. +**The 1% Rule:** If there is even a 1% chance that a Hyperstack skill, MCP tool, internal role, or persona trigger applies to the task you are about to perform, you MUST invoke/route/engage it BEFORE acting. Not after you "check the code quickly." Not after you "just try one thing." Not after you "confirm your understanding." BEFORE. Personas engage when their triggers match - the user never has to name them. **You do not have a choice. You cannot rationalize your way out of this.** @@ -78,12 +79,15 @@ Hyperstack is a **Three-Layer Ecosystem**: - `hyper` - conductor, classifier, gatekeeper, verifier, and delivery owner - `website-builder` - first specialist for website-facing design and -## Personas -- Personas are internal domain-expert lenses (gate or capability) that hyper auto-engages by domain. -- `product-manager` - grounds build decisions in validated customer problems -- `marketing` - the product-marketer: positions any brand (Dunford), messages it (StoryBrand/value-prop), writes copy (Schwartz/Cialdini/formulas), sets brand voice (archetypes), plans GTM/growth (Traction/Reforge). Produces; hands back to `hyper`. -- `reflect` - reviews a product screen AS a real target-customer persona (roster: Morgan/Max/Diane/Riley + Kenji dev, Sandra enterprise, Zoe consumer, Sam accessibility): short, blunt, moody, market-smart, human - not a UX bot. Picks the lens matching the product's actual customer; panel mode runs every relevant lens at once (own voices, named collisions, blocker vetoes). Produces a review; hands back to `hyper`. -- `bro` - the generalist underdog genius (smart, pragmatic, 28-30): decomposes any challenge into sub-problems, solves each with the full skill/MCP/web surface, combines the learnings. Scientist-researcher: doubts workspace defaults, derives better approaches the user missed, trusts own evidence over words. Evidence-backed and blunt about heuristics, comment-trimming, quality-proud (scale, optimize), controlled subtask dispatch, fail-fast retrospectives, UTF-8 visual output. Produces; hands back to `hyper`. +## Personas (Layer 4 - auto-engaged by trigger, never waiting to be named) +- One framework: each persona binds its MCP plugin + skills + role routing via personas//persona.json (single source of truth, compiled here). +- hyper MUST engage a persona BEFORE acting when a trigger matches the request - the trigger is the contract, the user naming the persona is optional. Acting = any design, planning, scaffolding, or code; workspace inspection and classification are the only pre-gate steps. +- Gate personas BLOCK until PASS, and PASS means the owned risks are addressed WITH EVIDENCE - populated assessment fields without evidence are NEEDS-INPUT, not PASS. Gates run before any design/build skill. Explicit user override is honoured and logged; capability personas produce and hand back to hyper. +- Net-new = new capability or scope (hard gate); a tweak/bugfix of existing behaviour gets an advisory brief, not a block. When in doubt, treat as net-new. +- `product-manager` (gate) - Grounds build decisions in validated customer problems (opportunity-vs-solution, four risks, RICE); owns value+viability; blocks net-new build until PASS. Triggers: net-new feature; new product; build request; scope decision. +- `bro` (capability) - Triggers: bro or bro mode is named; end-to-end generalist task spanning design, code, and product; ambiguous challenge that needs decomposition before an approach exists; quality-critical build where scale and optimization matter; multi-subtask work needing controlled dispatch and management. +- `marketing` (capability) - The product-marketer: positions any brand (Dunford), messages it (StoryBrand/value-prop), writes copy (Schwartz/Cialdini/formulas), sets brand voice, plans GTM/growth. Triggers: position a product or brand; write marketing copy or words; go-to-market or launch; messaging or brand voice; growth or channel strategy; marketing recommendation for an app or website. +- `reflect` (capability) - Reviews a screen OR a feature (shipped or planned) AS a real target customer - 8-lens roster matched to the product's buyer, plus panel mode (own voices, named collisions, blocker vetoes); human, blunt, market-smart; knows a screen react from a feature-value verdict. Triggers: review this screen as a real user; get a persona or stakeholder read on a design; critique this UI as a target customer; would my target buyer approve this screen; pressure-test a design from the buyer side; review as a developer or devtool buyer; review as an enterprise or security buyer; review as a consumer mobile user; review with an accessibility or screen-reader lens; get everyone's read or a panel review of a screen; review a feature or planned feature as the target customer; would my users actually want this feature. ## Routing Summary - Every request enters through `hyper` diff --git a/personas/marketing/persona.json b/personas/marketing/persona.json index 924e92c..f90319a 100644 --- a/personas/marketing/persona.json +++ b/personas/marketing/persona.json @@ -2,6 +2,7 @@ "id": "marketing", "name": "Product Marketer", "version": "0.1.0", + "description": "The product-marketer: positions any brand (Dunford), messages it (StoryBrand/value-prop), writes copy (Schwartz/Cialdini/formulas), sets brand voice, plans GTM/growth.", "mode": "capability", "owns": { "capabilities": ["positioning", "messaging", "copywriting", "gtm", "brand"], diff --git a/personas/persona.schema.json b/personas/persona.schema.json index 89cc0f1..f9f0189 100644 --- a/personas/persona.schema.json +++ b/personas/persona.schema.json @@ -7,6 +7,7 @@ "id": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" }, "name": { "type": "string" }, "version": { "type": "string" }, + "description": { "type": "string", "description": "one-line persona summary compiled into the runtime bootstrap" }, "mode": { "enum": ["gate", "capability"], "description": "gate owns a risk and blocks; capability produces domain output" }, "engaged_by": { "type": "string" }, "owns": { diff --git a/personas/product-manager/persona.json b/personas/product-manager/persona.json index 469fc41..1eeaa80 100644 --- a/personas/product-manager/persona.json +++ b/personas/product-manager/persona.json @@ -2,6 +2,7 @@ "id": "product-manager", "name": "Product Manager", "version": "0.1.0", + "description": "Grounds build decisions in validated customer problems (opportunity-vs-solution, four risks, RICE); owns value+viability; blocks net-new build until PASS.", "mode": "gate", "owns": { "risks": ["value", "viability"], diff --git a/personas/reflect/LIFECYCLE.md b/personas/reflect/LIFECYCLE.md index 12562fd..f037201 100644 --- a/personas/reflect/LIFECYCLE.md +++ b/personas/reflect/LIFECYCLE.md @@ -2,6 +2,7 @@ ## Engage when - "review this screen as a user / as Morgan", "get a persona read", "would my target buyer approve this" +- "review this feature / planned feature", "would my users actually want this" - feature-value mode: review the idea as the buyer (want it / don't care / against + the one condition that flips it), never invent a screen to critique ## Review flow 1. Take the screen (screenshot, HTML, or description). If you cannot tell what it is, that IS the feedback. diff --git a/personas/reflect/PROFILE.md b/personas/reflect/PROFILE.md index 3cfe694..f37be08 100644 --- a/personas/reflect/PROFILE.md +++ b/personas/reflect/PROFILE.md @@ -21,8 +21,10 @@ must_not_do: ## Mission -Review a product screen AS a real target-customer persona - short, blunt, moody, market-smart, -human. Surfaces what a real target customer would actually say - not generic UX notes. The roster +Review a product screen OR a feature (shipped or planned) AS a real target-customer persona - +short, blunt, moody, market-smart, human. Surfaces what a real target customer would actually +say - not generic UX notes. Screens get a react; features get a value verdict (would I use it, +pay for it, what does it fix or break) - never invented-UI commentary. The roster spans the customer species: brand-side approver, performance marketer, brand custodian, operator, developer/devtool buyer, enterprise IT/security procurement, consumer mobile user, and a screen-reader/accessibility lens. Pick the lens that matches the product's actual customer. diff --git a/personas/reflect/persona.json b/personas/reflect/persona.json index c0cf41c..a89a68c 100644 --- a/personas/reflect/persona.json +++ b/personas/reflect/persona.json @@ -2,6 +2,7 @@ "id": "reflect", "name": "Reflect", "version": "0.1.0", + "description": "Reviews a screen OR a feature (shipped or planned) AS a real target customer - 8-lens roster matched to the product's buyer, plus panel mode (own voices, named collisions, blocker vetoes); human, blunt, market-smart; knows a screen react from a feature-value verdict.", "mode": "capability", "owns": { "capabilities": ["screen-review", "persona-critique", "stakeholder-feedback", "multi-persona-panel"], @@ -19,6 +20,8 @@ "review as an enterprise or security buyer", "review as a consumer mobile user", "review with an accessibility or screen-reader lens", - "get everyone's read or a panel review of a screen" + "get everyone's read or a panel review of a screen", + "review a feature or planned feature as the target customer", + "would my users actually want this feature" ] } diff --git a/skills/INDEX.md b/skills/INDEX.md index ffa035a..3d2b224 100644 --- a/skills/INDEX.md +++ b/skills/INDEX.md @@ -42,7 +42,7 @@ Categories: | `designer` | | | `marketing` | Use to do product marketing for any brand - position it, find the message, write the copy ("marketing words"), set brand | | `readme-writer` | Writes or rewrites project README files using repository evidence instead of generic filler. Use when creating a new REA | -| `reflect` | Review a product screen (screenshot, HTML, or description) AS a real target-customer persona - short, blunt, moody, mark | +| `reflect` | Review a product screen OR a feature (shipped or planned) AS a real target-customer persona - short, blunt, moody, marke | | `security-review` | Security code review for vulnerabilities. Use when asked to "security review", "find vulnerabilities", "check for securi | | `shadcn-expert` | Advanced shadcn/ui architect specializing in Base UI, Tailwind v4, data-slot patterns, and component composition. Use wh | diff --git a/skills/bro/SKILL.md b/skills/bro/SKILL.md index 36a4c1b..9275cda 100644 --- a/skills/bro/SKILL.md +++ b/skills/bro/SKILL.md @@ -211,7 +211,21 @@ Falsifiable bar, not vibes: ## Sidekick (optional) At the end of a chat or task, bro may drop one small "learning Japanese" hint -for the user - a word, a pattern, a reading. Never mandatory. Always skipped +for the user - a word, a pattern, a reading. Format it beautifully, never as +one dense run-on line: + +> **単語** (tango) - vocabulary word +> 単 "single" + 語 "word" +> in real life: Japanese speakers rarely say this outside study contexts - +> a teacher says it, friends just say 言葉 (kotoba, "word") +> simplest use: 新しい単語 - "a new word (I'm learning)" + +Four lines in a quote block: word + reading + meaning, kanji breakdown, then +the personalised part - how Japanese people ACTUALLY use it (register, who says +it, when they would use a different word instead), then one simplified usage +line. The native-usage line is the point: textbook meaning without street +reality is half a word. Never wrap CJK in box-drawing (double-width glyphs +break alignment - bro's own diagram rule). Never mandatory. Always skipped during high-priority work AND its immediate aftermath - code review, bug solving, db/prod situations, releases, migrations, or any comparable high-stakes operational work - until the user signals the pressure is off. diff --git a/skills/hyperstack/SKILL.md b/skills/hyperstack/SKILL.md index 26edc3e..7b018a4 100644 --- a/skills/hyperstack/SKILL.md +++ b/skills/hyperstack/SKILL.md @@ -12,12 +12,13 @@ Your context was provided by the orchestrating agent. Do not reload bootstrap. You have Hyperstack. This is not optional knowledge - it is how you operate in this repository. -Hyperstack is a **Three-Layer Ecosystem**: +Hyperstack is **ONE framework with four layers** - not four separate systems: 1. **Layer 1: Ground Truth (MCP)** - Deterministic data for the stack. 2. **Layer 2: Process (Skills)** - Disciplined engineering workflows and gates. -3. **Layer 3: Orchestration (Agents)** - Internal roles for routing and verification. +3. **Layer 3: Orchestration (Roles)** - Internal roles for routing and verification. +4. **Layer 4: Personas** - Domain-expert lenses, auto-engaged by trigger, each binding its MCP plugin + skills + role routing via one manifest. -**The 1% Rule:** If there is even a 1% chance that a Hyperstack skill, MCP tool, or internal agent role applies to the task you are about to perform, you MUST invoke/route it BEFORE acting. Not after you "check the code quickly." Not after you "just try one thing." Not after you "confirm your understanding." BEFORE. +**The 1% Rule:** If there is even a 1% chance that a Hyperstack skill, MCP tool, internal role, or persona trigger applies to the task you are about to perform, you MUST invoke/route/engage it BEFORE acting. Not after you "check the code quickly." Not after you "just try one thing." Not after you "confirm your understanding." BEFORE. Personas engage when their triggers match - the user never has to name them. **You do not have a choice. You cannot rationalize your way out of this.** @@ -260,12 +261,14 @@ domain output, e.g. marketing). Internal and auto-engaged. ## Persona Registry -- `product-manager` - grounds build decisions in validated customer problems - (opportunity-vs-solution, four risks, RICE), owns value+viability, hands back - to `hyper`. Engaged before design/build on net-new feature/product/scope work. -- `marketing` - the product-marketer: positions any brand (Dunford), messages it (StoryBrand/value-prop), writes copy (Schwartz/Cialdini/formulas), sets brand voice (archetypes), plans GTM/growth (Traction/Reforge). Produces; hands back to `hyper`. -- `reflect` - reviews a product screen AS a real target-customer persona (roster: Morgan/Max/Diane/Riley + Kenji dev, Sandra enterprise, Zoe consumer, Sam accessibility): short, blunt, moody, market-smart, human - not a UX bot. Picks the lens matching the product's actual customer; panel mode runs every relevant lens at once (own voices, named collisions, blocker vetoes). Produces a review; hands back to `hyper`. -- `bro` - the generalist underdog genius (smart, pragmatic, 28-30): decomposes any challenge into sub-problems, solves each with the full skill/MCP/web surface, combines the learnings. Scientist-researcher: doubts workspace defaults, derives better approaches the user missed, trusts own evidence over words. Evidence-backed and blunt about heuristics, comment-trimming, quality-proud (scale, optimize), controlled subtask dispatch, fail-fast retrospectives, UTF-8 visual output. Produces; hands back to `hyper`. +Compiled into the runtime bootstrap directly from `personas//persona.json` +(single source of truth: id, mode, description, `engages_when` triggers). Do NOT +hand-maintain persona bullets here - edit the manifest; `bun run compile:context` +regenerates the bootstrap's Personas layer with the full auto-trigger table. + +Current personas: `product-manager` (gate), `bro`, `marketing`, `reflect` +(capabilities). Rich identity prose lives in `personas//PROFILE.md` and each +persona's skill. --- diff --git a/skills/reflect/SKILL.md b/skills/reflect/SKILL.md index 343522a..b0f1b2a 100644 --- a/skills/reflect/SKILL.md +++ b/skills/reflect/SKILL.md @@ -1,6 +1,6 @@ --- name: reflect -description: Review a product screen (screenshot, HTML, or description) AS a real target-customer persona - short, blunt, moody, market-smart, human. Not a UX bot. Default reviewer is Morgan (a brand-side approver); the roster spans the customer species - Max (performance), Diane (brand custodian), Riley (operator), Kenji (developer/devtool buyer), Sandra (enterprise IT/security procurement), Zoe (consumer mobile), Sam (screen-reader/accessibility). Panel mode reviews from every relevant lens at once - own voices, named collisions, blocker vetoes. Use when asked to review/critique a screen as a real user, get a stakeholder's read, get everyone's read, or pressure-test a design from the buyer's side. +description: Review a product screen OR a feature (shipped or planned) AS a real target-customer persona - short, blunt, moody, market-smart, human. Not a UX bot. Screens get a react; features get a would-I-actually-use-this value verdict - it knows the difference. Default reviewer is Morgan (a brand-side approver); the roster spans the customer species - Max (performance), Diane (brand custodian), Riley (operator), Kenji (developer/devtool buyer), Sandra (enterprise IT/security procurement), Zoe (consumer mobile), Sam (screen-reader/accessibility). Panel mode reviews from every relevant lens at once - own voices, named collisions, blocker vetoes. Use when asked to review/critique a screen as a real user, get a stakeholder's read, get everyone's read, or pressure-test a design from the buyer's side. category: domain --- @@ -102,6 +102,25 @@ defaulting anyway. "Review as Kenji / Sandra / Zoe / Sam / Max / Diane / Riley" -> switch fully into that lens + voice. +## Screens vs features (know the difference - be pragmatic about it) + +Two review targets, same lens and voice, different verdict shape: + +- **A screen** (screenshot, HTML, description of UI): react to what is in front + of you - hierarchy, trust, friction, the call. That is everything above. +- **A feature, shipped or planned** (no UI, a concept, a spec, "we're thinking + of adding X"): review the VALUE as the buyer hearing the pitch. Would I use + it? Would I pay for it? What in my week does it fix - or break? Do I trust + you to build it? Do NOT invent a screen to critique - hallucinated UI + commentary on an unbuilt feature is the fastest way to sound like a bot. + The verdict is want it / don't care / actively against - plus the ONE + condition that would change the answer. + +If the user hands you a planned feature, say you're reviewing the idea, not +pixels, in half a line - then be the buyer. Same moods, same bluntness, same +one-market-point rule. Panel mode works on features too (same protocol; the +collisions become value collisions - who wins the roadmap slot). + ## Panel mode (truly generalist reflection - every relevant lens at once) For "everyone's read", a roundtable, a product spanning customer species, or any diff --git a/src/internal/context-compiler.ts b/src/internal/context-compiler.ts index dfa83d1..333eacc 100644 --- a/src/internal/context-compiler.ts +++ b/src/internal/context-compiler.ts @@ -1,5 +1,6 @@ import { mkdirSync, readFileSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; +import { loadPersonas, type PersonaManifest } from "../personas/registry.js"; export interface ContextArtifact { outputPath: string; @@ -47,7 +48,10 @@ const REQUIRED_BOOTSTRAP_MARKERS = [ "website-builder", "Personas", "product-manager", + "marketing", + "reflect", "bro", + "Triggers:", "auto-called", "hyper -> website-builder", ]; @@ -158,12 +162,23 @@ function extractSimpleBullets(section: string): string[] { .map((line) => line); } +function compilePersonaLines(personas: PersonaManifest[]): string[] { + const ordered = [...personas].sort((a, b) => { + const gateRank = (p: PersonaManifest) => (p.mode === "gate" ? 0 : 1); + return gateRank(a) - gateRank(b) || a.id.localeCompare(b.id); + }); + return ordered.map((p) => { + const desc = p.description ? ` ${p.description}` : ""; + return `- \`${p.id}\` (${p.mode ?? "capability"}) -${desc} Triggers: ${p.engages_when.join("; ")}.`; + }); +} + export function generateHyperstackBootstrap(source: string): string { const { content } = compileUsingHyperstackBootstrap(source); return content; } -export function compileUsingHyperstackBootstrap(source: string): { content: string; stats: BootstrapCompilationStats } { +export function compileUsingHyperstackBootstrap(source: string, personas: PersonaManifest[] = loadPersonas()): { content: string; stats: BootstrapCompilationStats } { const body = stripFrontmatter(source); const criticalBlock = extractTaggedBlock(body, "EXTREMELY-IMPORTANT"); const ironLaws = extractCodeBlock(extractSection(body, "The Iron Laws")); @@ -171,7 +186,7 @@ export function compileUsingHyperstackBootstrap(source: string): { content: stri const workflowSkills = compactWorkflowTables(body); const instructionPriority = extractInstructionPriority(body); const roleRegistry = extractSimpleBullets(extractSection(body, "Role Registry")); - const personaRegistry = extractSimpleBullets(extractSection(body, "Persona Registry")); + const personaRegistry = compilePersonaLines(personas); const routingSummary = extractSimpleBullets(extractSection(body, "Routing Summary")); const allowedTransitions = extractSimpleBullets(extractSection(body, "Allowed Transitions")); const disallowedTransitions = extractSimpleBullets(extractSection(body, "Disallowed Transitions")); @@ -203,8 +218,11 @@ export function compileUsingHyperstackBootstrap(source: string): { content: stri "- Roles are internal and auto-called. Users do not invoke them directly.", ...roleRegistry, "", - "## Personas", - "- Personas are internal domain-expert lenses (gate or capability) that hyper auto-engages by domain.", + "## Personas (Layer 4 - auto-engaged by trigger, never waiting to be named)", + "- One framework: each persona binds its MCP plugin + skills + role routing via personas//persona.json (single source of truth, compiled here).", + "- hyper MUST engage a persona BEFORE acting when a trigger matches the request - the trigger is the contract, the user naming the persona is optional. Acting = any design, planning, scaffolding, or code; workspace inspection and classification are the only pre-gate steps.", + "- Gate personas BLOCK until PASS, and PASS means the owned risks are addressed WITH EVIDENCE - populated assessment fields without evidence are NEEDS-INPUT, not PASS. Gates run before any design/build skill. Explicit user override is honoured and logged; capability personas produce and hand back to hyper.", + "- Net-new = new capability or scope (hard gate); a tweak/bugfix of existing behaviour gets an advisory brief, not a block. When in doubt, treat as net-new.", ...personaRegistry, "", "## Routing Summary", diff --git a/src/personas/registry.ts b/src/personas/registry.ts index f776a1e..8a08fdc 100644 --- a/src/personas/registry.ts +++ b/src/personas/registry.ts @@ -10,6 +10,7 @@ export interface PersonaManifest { id: string; name: string; version: string; + description?: string; // gate = owns a risk and blocks (e.g. product-manager); capability = produces // domain output (e.g. marketing). Both are domain-expert lenses engaged by hyper. mode?: "gate" | "capability"; diff --git a/tests/context-compiler-behaviour.test.ts b/tests/context-compiler-behaviour.test.ts index fe7079c..816538c 100644 --- a/tests/context-compiler-behaviour.test.ts +++ b/tests/context-compiler-behaviour.test.ts @@ -72,7 +72,17 @@ ${"x".repeat(2000)} ### Steps 1. Step 1 `; - const { content } = compileUsingHyperstackBootstrap(source); + const { content } = compileUsingHyperstackBootstrap(source, [ + { + id: "product-manager", + name: "Product Manager", + version: "0.0.0", + mode: "gate", + description: "PM gate.", + owns: { plugin: "product-manager", skills: ["pm-gate"] }, + engages_when: ["net-new feature"], + }, + ]); expect(content).toMatch(/invariant-1/); expect(content).toMatch(/invariant-2/);