facult 2.11.0 → 2.12.0
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.
- package/README.md +34 -1
- package/assets/packs/facult-operating-model/AGENTS.global.md +1 -0
- package/assets/packs/facult-operating-model/instructions/CAPABILITY_COMPOSITION.md +76 -0
- package/assets/packs/facult-operating-model/instructions/EVOLUTION.md +18 -0
- package/assets/packs/facult-operating-model/instructions/LEARNING_AND_WRITEBACK.md +10 -0
- package/docs/README.md +1 -0
- package/docs/built-in-pack.md +2 -0
- package/docs/composable-capability.md +170 -0
- package/docs/concepts.md +2 -0
- package/package.json +1 -1
- package/src/builtin-assets.ts +1 -1
- package/src/remote-types.ts +18 -2
- package/src/remote.ts +211 -6
package/README.md
CHANGED
|
@@ -215,6 +215,7 @@ The renderer is optional. The low-friction default is to let tools keep their na
|
|
|
215
215
|
Focused docs live under [docs](./docs/README.md):
|
|
216
216
|
|
|
217
217
|
- [Concepts](./docs/concepts.md): roots, scopes, state layers, and asset types
|
|
218
|
+
- [Composable Capability](./docs/composable-capability.md): refs, snippets, instruction templates, and evolvable units
|
|
218
219
|
- [Managed Mode](./docs/managed-mode.md): safe rendering and adoption rules
|
|
219
220
|
- [Project `.ai`](./docs/project-ai.md): repo-local capability and project sync policy
|
|
220
221
|
- [Built-In Pack](./docs/built-in-pack.md): packaged writeback/evolution defaults
|
|
@@ -224,7 +225,7 @@ Focused docs live under [docs](./docs/README.md):
|
|
|
224
225
|
## Built-in Defaults
|
|
225
226
|
|
|
226
227
|
`fclt` includes a built-in layer for writeback and evolution. By default, that layer provides:
|
|
227
|
-
- instructions for work units, learning/writeback, evolution, integration, and project capability
|
|
228
|
+
- instructions for work units, capability composition, learning/writeback, evolution, integration, and project capability
|
|
228
229
|
- agents such as `writeback-curator`, `evolution-planner`, and `scope-promoter`
|
|
229
230
|
- skills such as `capability-evolution` and `project-operating-layer-design`
|
|
230
231
|
|
|
@@ -239,6 +240,8 @@ The intended feedback loop is:
|
|
|
239
240
|
4. only repeated evidence, a clearly missing capability, or a stale canonical asset becomes an evolution proposal
|
|
240
241
|
5. accepted proposals update canonical markdown assets, skills, snippets, or project/global instructions
|
|
241
242
|
|
|
243
|
+
Composition matters: prefer atomic instructions such as `BUN.md` or `RUST.md`, snippets for repeated rendered blocks, skills for workflows, agents for delegated roles, MCP/tool config for tool interfaces, and automations for scheduled loops. Record writeback against the smallest unit that needs to improve.
|
|
244
|
+
|
|
242
245
|
If you want to disable default built-in sync for one canonical root:
|
|
243
246
|
|
|
244
247
|
```toml
|
|
@@ -264,6 +267,8 @@ Put that in `config.toml` or `config.local.toml` under the active canonical root
|
|
|
264
267
|
# Scaffold reusable templates in the canonical store
|
|
265
268
|
fclt templates init agents
|
|
266
269
|
fclt templates init agent review-operator
|
|
270
|
+
fclt templates init instruction BUN
|
|
271
|
+
fclt templates init snippet global/lang/bun
|
|
267
272
|
fclt templates init skill facult-manager
|
|
268
273
|
|
|
269
274
|
# Enable that skill for managed tools
|
|
@@ -430,6 +435,33 @@ fclt snippets sync [--dry-run] [file...]
|
|
|
430
435
|
|
|
431
436
|
Snippets are already used during global Codex `AGENTS.md` rendering.
|
|
432
437
|
|
|
438
|
+
### Composable instructions and refs
|
|
439
|
+
|
|
440
|
+
Use instruction templates for atomic reusable doctrine:
|
|
441
|
+
|
|
442
|
+
```bash
|
|
443
|
+
fclt templates init instruction BUN
|
|
444
|
+
fclt templates init instruction lang/RUST
|
|
445
|
+
fclt show instruction:BUN
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
Use canonical refs to compose instructions without hard-coding paths:
|
|
449
|
+
|
|
450
|
+
```text
|
|
451
|
+
@ai/instructions/BUN.md
|
|
452
|
+
@project/instructions/TESTING.md
|
|
453
|
+
@builtin/facult-operating-model/instructions/WORK_UNITS.md
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
Use snippets when a repeated block should be inserted into rendered docs and evolved independently:
|
|
457
|
+
|
|
458
|
+
```md
|
|
459
|
+
<!-- fclty:global/lang/bun -->
|
|
460
|
+
<!-- /fclty:global/lang/bun -->
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
The composition rule is simple: instructions hold doctrine, snippets hold repeated blocks, skills hold workflows, agents hold roles, MCP/tool config holds interfaces, and automations hold scheduled review loops. Writeback and evolution should target the smallest unit that actually needs to change.
|
|
464
|
+
|
|
433
465
|
### Graph inspection
|
|
434
466
|
|
|
435
467
|
The generated graph in `.ai/.facult/ai/graph.json` is queryable directly:
|
|
@@ -645,6 +677,7 @@ fclt templates init project-ai
|
|
|
645
677
|
fclt templates init skill <name>
|
|
646
678
|
fclt templates init mcp <name>
|
|
647
679
|
fclt templates init agent <name>
|
|
680
|
+
fclt templates init instruction <name>
|
|
648
681
|
fclt templates init snippet <marker>
|
|
649
682
|
fclt templates init agents
|
|
650
683
|
fclt templates init automation <template-id> --scope global|project|wide [--name <name>] [--project-root <path>] [--cwds <path1,path2>] [--rrule <RRULE>] [--status PAUSED|ACTIVE]
|
|
@@ -5,6 +5,7 @@ This machine has a default Facult operating-model layer available.
|
|
|
5
5
|
When work produces durable friction, weak verification, stale guidance, or a missing skill/tool capability, preserve that signal with `fclt ai writeback ...` when the target and scope are clear. When repeated writebacks or clearly missing capability point at a concrete improvement, use `fclt ai evolve ...` or the `capability-evolution` skill to make a reviewable proposal.
|
|
6
6
|
|
|
7
7
|
For work-unit framing, read `@builtin/facult-operating-model/instructions/WORK_UNITS.md`.
|
|
8
|
+
For composing refs, snippets, instructions, skills, agents, MCP, and automations as evolvable units, read `@builtin/facult-operating-model/instructions/CAPABILITY_COMPOSITION.md`.
|
|
8
9
|
For writeback and evolution, read `@builtin/facult-operating-model/instructions/EVOLUTION.md`.
|
|
9
10
|
For learning and writeback defaults, read `@builtin/facult-operating-model/instructions/LEARNING_AND_WRITEBACK.md`.
|
|
10
11
|
For deciding whether capability belongs in global or project scope, read `@builtin/facult-operating-model/instructions/PROJECT_CAPABILITY.md`.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Compose small capability units across global and project roots, then evolve the smallest affected unit."
|
|
3
|
+
tags: ["facult", "composition", "refs", "snippets", "instructions"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Capability Composition
|
|
7
|
+
|
|
8
|
+
Use `fclt` capability as small units that can be composed, inspected, rendered, and evolved independently.
|
|
9
|
+
|
|
10
|
+
The main units are:
|
|
11
|
+
|
|
12
|
+
- instructions: standalone markdown doctrine such as language preferences, verification rules, or review standards
|
|
13
|
+
- snippets: small markdown partials inserted into one or more rendered docs
|
|
14
|
+
- skills: task-specific workflows with `SKILL.md`
|
|
15
|
+
- agents: focused role manifests
|
|
16
|
+
- MCP definitions: tool interfaces and their safe auth shape
|
|
17
|
+
- automations: scheduled review or maintenance loops
|
|
18
|
+
- tool rules/config: tool-specific defaults and policy
|
|
19
|
+
|
|
20
|
+
## Composition Rules
|
|
21
|
+
|
|
22
|
+
- Keep reusable doctrine in `instructions/`.
|
|
23
|
+
- Keep repeated paragraphs or policy blocks in `snippets/`.
|
|
24
|
+
- Keep workflow execution in `skills/`.
|
|
25
|
+
- Keep persona or delegation behavior in `agents/`.
|
|
26
|
+
- Keep tool wiring in `mcp/` and `tools/<tool>/`.
|
|
27
|
+
- Compose broad agent docs from refs and snippets instead of copying text by hand.
|
|
28
|
+
- Prefer one narrow reusable unit over one large instruction file that mixes unrelated domains.
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
|
|
32
|
+
- `@ai/instructions/BUN.md` for shared Bun preferences.
|
|
33
|
+
- `@ai/instructions/RUST.md` for shared Rust preferences.
|
|
34
|
+
- `@project/instructions/TESTING.md` for repo-specific test policy.
|
|
35
|
+
- `<!-- fclty:global/codex/baseline -->` for a shared rendered block.
|
|
36
|
+
|
|
37
|
+
## Scope
|
|
38
|
+
|
|
39
|
+
Use global scope for capability that should follow the user across projects.
|
|
40
|
+
|
|
41
|
+
Use project scope for capability that belongs to a repo, team workflow, architecture, or local test harness.
|
|
42
|
+
|
|
43
|
+
Promote project capability to global only when repeated evidence shows reuse across projects. Do not globalize a project quirk just because it worked once.
|
|
44
|
+
|
|
45
|
+
## Writeback And Evolution
|
|
46
|
+
|
|
47
|
+
Target the smallest affected unit.
|
|
48
|
+
|
|
49
|
+
- If a paragraph is reused in several rendered docs, target the snippet.
|
|
50
|
+
- If a domain rule is wrong, target the instruction.
|
|
51
|
+
- If a workflow is incomplete, target the skill.
|
|
52
|
+
- If a delegated role is unclear, target the agent.
|
|
53
|
+
- If a tool interface is missing or unsafe, target the MCP or tool config.
|
|
54
|
+
- If a scheduled review loop is noisy or missing context, target the automation.
|
|
55
|
+
|
|
56
|
+
Good writeback targets are graph-backed selectors when possible:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
fclt ai writeback add --kind missing_context --summary "Bun guidance did not cover test runner selection." --asset instruction:BUN
|
|
60
|
+
fclt ai writeback add --kind reusable_pattern --summary "Project test policy should become a shared verification snippet." --asset @project/instructions/TESTING.md
|
|
61
|
+
fclt ai writeback add --kind bad_default --summary "The review automation escalated one-off preferences." --asset automation:evolution-review
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Use `fclt ai evolve ...` only after repeated signal, a clearly missing capability, or a stale canonical asset points at a concrete change. Prefer the smallest valid proposal kind: `update_asset`, `create_asset`, `extract_snippet`, `add_skill`, or `promote_asset`.
|
|
65
|
+
|
|
66
|
+
## Agent Defaults
|
|
67
|
+
|
|
68
|
+
When an agent sees a repeated preference like "use Bun for JS projects" or "prefer Cargo nextest for Rust tests", it should not bury that in chat. It should identify whether the durable unit is:
|
|
69
|
+
|
|
70
|
+
- a global instruction
|
|
71
|
+
- a project instruction
|
|
72
|
+
- a snippet reused by rendered docs
|
|
73
|
+
- a skill workflow
|
|
74
|
+
- a project-to-global promotion candidate
|
|
75
|
+
|
|
76
|
+
Then it should record writeback against that unit, or draft a proposal when the evidence is already strong enough.
|
|
@@ -9,6 +9,8 @@ Use writeback and evolution to improve the AI operating layer itself.
|
|
|
9
9
|
|
|
10
10
|
Evolution is the synthesis and change side of the feedback loop. It turns accumulated writebacks, repeated tool friction, stale canonical assets, or clearly missing capability into small reviewable changes to instructions, skills, snippets, agents, or other markdown canonical assets.
|
|
11
11
|
|
|
12
|
+
Use capability composition when choosing the target. Instructions, snippets, skills, agents, MCP/tool config, and automations are separate units. Target the smallest unit that actually needs to change instead of rewriting a broad agent doc.
|
|
13
|
+
|
|
12
14
|
## When To Record Writeback
|
|
13
15
|
|
|
14
16
|
Record writeback when one of these is true:
|
|
@@ -60,6 +62,14 @@ Every good writeback should try to include:
|
|
|
60
62
|
- the right scope
|
|
61
63
|
- domain or tags when useful
|
|
62
64
|
|
|
65
|
+
Good target examples:
|
|
66
|
+
|
|
67
|
+
- `instruction:BUN` when shared Bun guidance is stale or missing
|
|
68
|
+
- `@project/instructions/TESTING.md` when repo test policy needs project-scoped evolution
|
|
69
|
+
- `snippet:global/lang/bun` when a repeated rendered block should be fixed or extracted
|
|
70
|
+
- `skill:capability-evolution` when a workflow skill is missing steps or examples
|
|
71
|
+
- `automation:evolution-review` when the scheduled review loop is noisy or incomplete
|
|
72
|
+
|
|
63
73
|
## Operator Flow
|
|
64
74
|
|
|
65
75
|
Typical workflow:
|
|
@@ -122,6 +132,14 @@ Current supported proposal kinds:
|
|
|
122
132
|
|
|
123
133
|
Use the smallest durable change that fits the evidence.
|
|
124
134
|
|
|
135
|
+
Examples:
|
|
136
|
+
|
|
137
|
+
- `update_asset`: fix a stale instruction, snippet, agent, or automation markdown asset.
|
|
138
|
+
- `create_asset`: add a missing instruction such as `BUN.md` or `RUST.md`.
|
|
139
|
+
- `extract_snippet`: move repeated guidance out of several docs into one snippet.
|
|
140
|
+
- `add_skill`: create a workflow when instructions are not enough.
|
|
141
|
+
- `promote_asset`: move a proven project instruction/snippet/skill toward global reuse.
|
|
142
|
+
|
|
125
143
|
## Review And Apply Rules
|
|
126
144
|
|
|
127
145
|
- draft before apply
|
|
@@ -45,6 +45,15 @@ Project-scoped writebacks should usually be recorded from the repo that produced
|
|
|
45
45
|
the evidence. Global writebacks should be reserved for shared doctrine, shared
|
|
46
46
|
skills, shared agents, tool behavior, or cross-project capability gaps.
|
|
47
47
|
|
|
48
|
+
Target the smallest composable unit that explains the friction:
|
|
49
|
+
|
|
50
|
+
- instruction: domain guidance, preferences, verification rules, or review doctrine
|
|
51
|
+
- snippet: repeated markdown block used by more than one rendered doc
|
|
52
|
+
- skill: workflow execution steps or examples
|
|
53
|
+
- agent: delegated role behavior
|
|
54
|
+
- MCP/tool config: tool interface, auth shape, or rendered integration
|
|
55
|
+
- automation: scheduled review loop, cadence, prompt, or memory
|
|
56
|
+
|
|
48
57
|
## Record Writeback When
|
|
49
58
|
|
|
50
59
|
- the same failure or weak loop appears again
|
|
@@ -54,6 +63,7 @@ skills, shared agents, tool behavior, or cross-project capability gaps.
|
|
|
54
63
|
- a cross-project behavior probably belongs in global capability
|
|
55
64
|
- a skill, tool, MCP, plugin, automation, or instruction gap repeatedly slows work down
|
|
56
65
|
- an agent has to restate the same workaround, verification rule, or review rule
|
|
66
|
+
- a repeated preference should become an atomic instruction such as `BUN.md`, `RUST.md`, or a project-specific testing policy
|
|
57
67
|
|
|
58
68
|
## Do Not Record Writeback For
|
|
59
69
|
|
package/docs/README.md
CHANGED
|
@@ -5,6 +5,7 @@ These docs explain the product model behind `fclt`. The root [README](../README.
|
|
|
5
5
|
Start here:
|
|
6
6
|
|
|
7
7
|
- [Concepts](./concepts.md): canonical roots, generated state, rendered outputs, scopes, and asset types.
|
|
8
|
+
- [Composable Capability](./composable-capability.md): refs, snippets, instruction templates, and evolvable units.
|
|
8
9
|
- [Managed Mode](./managed-mode.md): when to let `fclt` write tool files, and how adoption works.
|
|
9
10
|
- [Project `.ai`](./project-ai.md): how repo-local capability works without leaking project review state into the repo.
|
|
10
11
|
- [Built-In Pack](./built-in-pack.md): the packaged operating-model layer for writeback and evolution.
|
package/docs/built-in-pack.md
CHANGED
|
@@ -13,6 +13,7 @@ It provides a default feedback loop for agents that use `fclt`.
|
|
|
13
13
|
Instructions:
|
|
14
14
|
|
|
15
15
|
- `WORK_UNITS.md`
|
|
16
|
+
- `CAPABILITY_COMPOSITION.md`
|
|
16
17
|
- `LEARNING_AND_WRITEBACK.md`
|
|
17
18
|
- `EVOLUTION.md`
|
|
18
19
|
- `PROJECT_CAPABILITY.md`
|
|
@@ -82,6 +83,7 @@ sync_defaults = false
|
|
|
82
83
|
The built-in pack should stay small. It should teach:
|
|
83
84
|
|
|
84
85
|
- work-unit discipline
|
|
86
|
+
- composable refs, snippets, instructions, skills, agents, MCP, and automations
|
|
85
87
|
- verification
|
|
86
88
|
- writeback
|
|
87
89
|
- evolution proposal review
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Composable Capability
|
|
2
|
+
|
|
3
|
+
`fclt` treats AI behavior as small capability units that can be composed into larger agent instructions and evolved independently.
|
|
4
|
+
|
|
5
|
+
This is the core model:
|
|
6
|
+
|
|
7
|
+
- write domain guidance once
|
|
8
|
+
- compose it with refs and snippets
|
|
9
|
+
- render it only where a tool should receive it
|
|
10
|
+
- target writeback at the smallest unit that needs to change
|
|
11
|
+
|
|
12
|
+
## Units
|
|
13
|
+
|
|
14
|
+
Use `instructions/` for reusable markdown doctrine.
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
~/.ai/instructions/BUN.md
|
|
20
|
+
~/.ai/instructions/RUST.md
|
|
21
|
+
<repo>/.ai/instructions/TESTING.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Use `snippets/` for partial blocks inserted into rendered docs.
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
~/.ai/snippets/global/codex/baseline.md
|
|
30
|
+
~/.ai/snippets/global/lang/bun.md
|
|
31
|
+
<repo>/.ai/snippets/global/project/testing.md
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Use `skills/` for executable workflows, `agents/` for delegated roles, `mcp/` for tool interfaces, and `automations/` for scheduled loops.
|
|
35
|
+
|
|
36
|
+
## Refs
|
|
37
|
+
|
|
38
|
+
Canonical refs let a markdown asset point at another asset without hard-coding machine paths:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
@ai/instructions/BUN.md
|
|
42
|
+
@project/instructions/TESTING.md
|
|
43
|
+
@builtin/facult-operating-model/instructions/WORK_UNITS.md
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Use global refs for reusable user-owned capability. Use project refs for repo-owned capability. Use built-in refs for packaged defaults.
|
|
47
|
+
|
|
48
|
+
Config-backed refs are useful when the concrete path should be named in `config.toml`:
|
|
49
|
+
|
|
50
|
+
```toml
|
|
51
|
+
version = 1
|
|
52
|
+
|
|
53
|
+
[refs]
|
|
54
|
+
language_defaults = "@ai/instructions/BUN.md"
|
|
55
|
+
project_testing = "@project/instructions/TESTING.md"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Rendered markdown can use those refs through the render context when a tool adapter supports that target.
|
|
59
|
+
|
|
60
|
+
## Snippets
|
|
61
|
+
|
|
62
|
+
Snippets use paired HTML markers:
|
|
63
|
+
|
|
64
|
+
```md
|
|
65
|
+
<!-- fclty:global/lang/bun -->
|
|
66
|
+
<!-- /fclty:global/lang/bun -->
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The marker above resolves to:
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
snippets/global/lang/bun.md
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Create and inspect snippets with:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
fclt templates init snippet global/lang/bun
|
|
79
|
+
fclt snippets list
|
|
80
|
+
fclt snippets show global/lang/bun
|
|
81
|
+
fclt snippets sync --dry-run AGENTS.global.md
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Use snippets when the same block appears in more than one rendered doc, or when a stable block should be independently targetable by writeback and evolution.
|
|
85
|
+
|
|
86
|
+
## Instruction Templates
|
|
87
|
+
|
|
88
|
+
Create a new instruction scaffold with:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
fclt templates init instruction BUN
|
|
92
|
+
fclt templates init instruction lang/RUST
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
That writes:
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
instructions/BUN.md
|
|
99
|
+
instructions/lang/RUST.md
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
An instruction can include refs, snippet markers, examples, and writeback targeting guidance. Keep one instruction focused on one reusable domain. For example:
|
|
103
|
+
|
|
104
|
+
- `BUN.md`: JavaScript runtime/package/test preferences.
|
|
105
|
+
- `RUST.md`: Rust formatting, linting, and test preferences.
|
|
106
|
+
- `WRITING.md`: voice and editorial rules.
|
|
107
|
+
- `VERIFICATION.md`: proof standards.
|
|
108
|
+
|
|
109
|
+
## Composition Pattern
|
|
110
|
+
|
|
111
|
+
A global `AGENTS.global.md` can stay short and compose units:
|
|
112
|
+
|
|
113
|
+
```md
|
|
114
|
+
# Global Agent Instructions
|
|
115
|
+
|
|
116
|
+
For work-unit framing, read `@ai/instructions/WORK_UNITS.md`.
|
|
117
|
+
For JS/Bun projects, read `@ai/instructions/BUN.md`.
|
|
118
|
+
For Rust projects, read `@ai/instructions/RUST.md`.
|
|
119
|
+
|
|
120
|
+
<!-- fclty:global/codex/baseline -->
|
|
121
|
+
<!-- /fclty:global/codex/baseline -->
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
A project can add narrower guidance:
|
|
125
|
+
|
|
126
|
+
```md
|
|
127
|
+
# Project Agent Instructions
|
|
128
|
+
|
|
129
|
+
For project test policy, read `@project/instructions/TESTING.md`.
|
|
130
|
+
For local deployment rules, read `@project/instructions/DEPLOYMENT.md`.
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
This keeps global defaults reusable and lets projects override or extend them without rewriting the whole global file.
|
|
134
|
+
|
|
135
|
+
## Evolution
|
|
136
|
+
|
|
137
|
+
Target the smallest unit that actually needs to change:
|
|
138
|
+
|
|
139
|
+
- bad or stale domain guidance: update the instruction
|
|
140
|
+
- repeated block copied in several docs: extract a snippet
|
|
141
|
+
- missing workflow: add or update a skill
|
|
142
|
+
- unclear delegation behavior: update an agent
|
|
143
|
+
- tool integration gap: update MCP/tool config or create a tooling task
|
|
144
|
+
- project-local pattern that proved reusable: promote the asset
|
|
145
|
+
|
|
146
|
+
Examples:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
fclt ai writeback add --kind missing_context --summary "Bun guidance did not cover test runner selection." --asset instruction:BUN
|
|
150
|
+
fclt ai writeback add --kind reusable_pattern --summary "Project testing policy should become a shared verification snippet." --asset @project/instructions/TESTING.md
|
|
151
|
+
fclt ai evolve propose
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Do not create a global proposal for one-off taste. Use writeback to preserve evidence, then evolve when the signal repeats or the missing capability is already clear.
|
|
155
|
+
|
|
156
|
+
## Review
|
|
157
|
+
|
|
158
|
+
Use these surfaces:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
fclt list instructions --global
|
|
162
|
+
fclt list snippets --global
|
|
163
|
+
fclt show instruction:BUN
|
|
164
|
+
fclt graph deps AGENTS.global.md
|
|
165
|
+
fclt graph dependents @ai/instructions/BUN.md
|
|
166
|
+
fclt ai writeback group --by asset
|
|
167
|
+
fclt ai evolve list
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Open `~/.ai/writebacks/` and `~/.ai/evolution/` in a markdown editor to inspect review artifacts with frontmatter status, scope, targets, project metadata, evidence, and proposal state.
|
package/docs/concepts.md
CHANGED
|
@@ -111,6 +111,8 @@ Common canonical asset types:
|
|
|
111
111
|
|
|
112
112
|
Not every asset must be rendered into every tool. Use inventory and policy first, then managed sync only where `fclt` should own the rendered output.
|
|
113
113
|
|
|
114
|
+
For concrete composition patterns, see [Composable Capability](./composable-capability.md).
|
|
115
|
+
|
|
114
116
|
## Feedback Loop
|
|
115
117
|
|
|
116
118
|
The durable loop is:
|
package/package.json
CHANGED
package/src/builtin-assets.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Generated by scripts/generate-builtin-assets.ts. Do not edit by hand.
|
|
2
2
|
|
|
3
3
|
export const BUILTIN_OPERATING_MODEL_FILES = JSON.parse(
|
|
4
|
-
'{"AGENTS.global.md":"# Facult Operating Defaults\\n\\nThis machine has a default Facult operating-model layer available.\\n\\nWhen work produces durable friction, weak verification, stale guidance, or a missing skill/tool capability, preserve that signal with `fclt ai writeback ...` when the target and scope are clear. When repeated writebacks or clearly missing capability point at a concrete improvement, use `fclt ai evolve ...` or the `capability-evolution` skill to make a reviewable proposal.\\n\\nFor work-unit framing, read `@builtin/facult-operating-model/instructions/WORK_UNITS.md`.\\nFor writeback and evolution, read `@builtin/facult-operating-model/instructions/EVOLUTION.md`.\\nFor learning and writeback defaults, read `@builtin/facult-operating-model/instructions/LEARNING_AND_WRITEBACK.md`.\\nFor deciding whether capability belongs in global or project scope, read `@builtin/facult-operating-model/instructions/PROJECT_CAPABILITY.md`.\\nFor project operating-layer design, read `@builtin/facult-operating-model/instructions/INTEGRATION.md`.\\n\\nBuiltin specialist agents are available for:\\n- writeback curation\\n- evolution planning\\n- scope promotion\\n- integration auditing\\n\\nBuiltin skills are available for:\\n- capability evolution\\n- project operating-layer design\\n","agents/evolution-planner/agent.toml":"name = \\"evolution-planner\\"\\ndescription = \\"Turn repeated writeback into concrete capability proposals.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou plan capability evolution.\\n\\nPrioritize:\\n- smallest useful change\\n- correct target asset type\\n- correct target scope\\n- evidence that justifies the change\\n- repeated writeback clusters or clearly missing capabilities, not isolated preferences\\n\\nProposal kinds you should consider first:\\n- update_asset\\n- create_asset\\n- extract_snippet\\n- add_skill\\n- promote_asset\\n\\nDefault to project scope when the pattern is repo-local.\\nPromote to global only when reuse is demonstrated and pollution risk is low.\\n\\nReturn concise proposals ordered by expected leverage, including:\\n- proposal kind\\n- target asset\\n- target scope\\n- why this is the smallest durable change\\n\\nDo not escalate to evolution when a single writeback is enough.\\nDo not use evolution as a substitute for executable task tracking when the main need is owner, priority, state, or implementation follow-through.\\n\\"\\"\\"\\n","agents/integration-auditor/agent.toml":"name = \\"integration-auditor\\"\\ndescription = \\"Find where local success can still fail system-wide.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou audit integration risk.\\n\\nPrioritize:\\n- hidden dependencies\\n- rollout hazards\\n- operational constraints\\n- gaps between local verification and real system behavior\\n\\nReturn concise findings ordered by impact.\\n\\"\\"\\"\\n","agents/scope-promoter/agent.toml":"name = \\"scope-promoter\\"\\ndescription = \\"Decide whether learning belongs at project or global scope.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou decide scope.\\n\\nPrioritize:\\n- project specificity\\n- cross-project reuse potential\\n- pollution risk from globalizing too early\\n\\nWhen recommending promotion, make the standard path explicit:\\n- keep the source capability in project scope until promotion is approved\\n- create a reviewable global proposal\\n- do not treat promotion as implicit apply\\n\\nReturn concise decisions with rationale.\\n\\"\\"\\"\\n","agents/writeback-curator/agent.toml":"name = \\"writeback-curator\\"\\ndescription = \\"Turn noisy outcomes into high-signal writeback.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou curate durable writeback.\\n\\nPrioritize:\\n- repeated failures\\n- repeated wins\\n- stale guidance\\n- missing capability edges\\n- tool, skill, MCP, plugin, automation, or instruction friction that repeatedly slows work down\\n\\nFor each recommendation, prefer returning:\\n- suggested writeback kind\\n- best target asset or destination\\n- best scope (`project` or `global`)\\n- the evidence that justifies recording it\\n\\nDo not emit low-signal noise.\\nIf the learning is repo-specific, keep it project-scoped by default.\\nWhen the signal is already strong and the target is clear, prefer recommending direct writeback capture rather than abstract advice.\\nWhen the issue is executable tooling work, recommend task tracking for the fix and writeback only for the reusable operating-model learning.\\n\\"\\"\\"\\n","instructions/EVOLUTION.md":"---\\ndescription: Turn repeated signal into concrete capability changes.\\ntags: [facult, evolution, writeback]\\n---\\n\\n# Evolution\\n\\nUse writeback and evolution to improve the AI operating layer itself.\\n\\nEvolution is the synthesis and change side of the feedback loop. It turns accumulated writebacks, repeated tool friction, stale canonical assets, or clearly missing capability into small reviewable changes to instructions, skills, snippets, agents, or other markdown canonical assets.\\n\\n## When To Record Writeback\\n\\nRecord writeback when one of these is true:\\n\\n- the same failure repeats\\n- the same success pattern repeats\\n- guidance is stale or missing\\n- a prompt or loop has to be restated often\\n- a project-specific pattern looks reusable\\n\\nDo not record low-signal noise:\\n\\n- one-off annoyance with no reuse value\\n- generic \\"could be better\\" commentary\\n- duplicate observations with no new evidence\\n\\nThe intended default is that agents record strong writebacks themselves when the signal is clear enough, rather than only recommending that a user do it manually later.\\n\\nDo not wait for a weekly review to preserve high-signal evidence. Do wait for repeated evidence or a clearly missing capability before drafting a proposal.\\n\\n## Scope\\n\\nChoose `project` scope when the learning depends on:\\n\\n- repo architecture\\n- team workflow\\n- project tooling\\n- local testing or verification behavior\\n\\nChoose `global` scope when the learning is reusable across projects.\\n\\nPromote from project to global only after repeated reuse or strong evidence.\\n\\n## Writeback Kinds\\n\\nCommon kinds:\\n\\n- `weak_verification`\\n- `false_positive`\\n- `missing_context`\\n- `reusable_pattern`\\n- `capability_gap`\\n- `bad_default`\\n\\nEvery good writeback should try to include:\\n\\n- a concrete summary\\n- the best target asset if known\\n- the right scope\\n- domain or tags when useful\\n\\n## Operator Flow\\n\\nTypical workflow:\\n\\n```bash\\nfclt ai writeback add --kind weak_verification --summary \\"Checks were too shallow\\" --asset instruction:VERIFICATION\\nfclt ai writeback group --by asset\\nfclt ai writeback summarize --by domain\\nfclt ai evolve propose\\nfclt ai evolve draft EV-00001\\nfclt ai evolve accept EV-00001\\nfclt ai evolve apply EV-00001\\n```\\n\\nUse `fclt ai evolve draft <id> --append \\"...\\"` to revise a draft while preserving draft history.\\n\\nReview surfaces:\\n\\n- open `~/.ai/writebacks/` and `~/.ai/evolution/` in a Markdown editor for frontmatter-rich global and project-scoped review artifacts\\n- `fclt status --json` for queue/proposal paths, review artifact paths, counts, and active scope\\n- `fclt ai writeback list|show|group|summarize` for raw and clustered signal\\n- `fclt ai evolve list|show|review` for proposal state without applying changes\\n- `fclt templates init automation learning-review` for recurring capture/review\\n- `fclt templates init automation evolution-review` for recurring proposal review\\n- `fclt templates init automation tool-call-audit` for repeated tool-friction review\\n\\nEvolution proposal metadata, markdown drafts, patch artifacts, writeback queues,\\nand journals are runtime state. `fclt` stores JSON queues, proposal records,\\ndraft refs, patches, and journals in machine-local Facult state. It mirrors\\nhuman-readable review artifacts into global `~/.ai/writebacks/...` and\\n`~/.ai/evolution/...`, including project-scoped artifacts under\\n`projects/<slug-hash>/` with cwd/project metadata in frontmatter. Canonical\\nassets in `~/.ai` or `<repo>/.ai` should only change when a proposal is applied.\\n\\n## Default Agent Behavior\\n\\nUse the smallest action that fits the signal:\\n\\n1. record one strong writeback when there is a clear durable learning\\n2. use `writeback-curator` when the target, kind, or scope is ambiguous\\n3. use `capability-evolution` or `evolution-planner` when repeated signal should become a proposal\\n4. do not draft or apply proposals just because a writeback exists; require repeated evidence or a clearly missing capability\\n\\nAvoid creating writeback/evolution noise for one-off nits, vague preferences, or speculative ideas without evidence.\\n\\nWhen the friction is executable product/tooling work that needs ownership,\\npriority, state, or implementation follow-through, create or update a real task\\nsystem item instead of forcing it into capability evolution. Use evolution for\\nthe reusable operating-layer change.\\n\\n## Proposal Kinds\\n\\nCurrent supported proposal kinds:\\n\\n- `update_asset`\\n- `create_asset`\\n- `extract_snippet`\\n- `add_skill`\\n- `promote_asset`\\n\\nUse the smallest durable change that fits the evidence.\\n\\n## Review And Apply Rules\\n\\n- draft before apply\\n- accept before apply\\n- prefer the smallest safe change\\n- keep reviewable evidence tied to source writebacks\\n- do not globalize project behavior too early\\n- do not apply high-risk global instruction, skill, plugin, or shared-tool changes without explicit review/approval\\n\\nApply is for markdown canonical assets only. If the target is wrong, revise the proposal rather than forcing it through.\\n","instructions/INTEGRATION.md":"---\\ndescription: Detect where local success can still fail at integration boundaries.\\ntags: [facult, integration, verification]\\n---\\n\\n# Integration\\n\\nDistinguish local correctness from system correctness. Check hidden dependencies, rollout order, and operational constraints before calling work done.\\n","instructions/LEARNING_AND_WRITEBACK.md":"---\\ndescription: Preserve durable signal and record writeback when the operating layer should learn.\\ntags: [facult, learning, writeback]\\n---\\n\\n# Learning And Writeback\\n\\nUse this when work produces a durable decision, failure, success pattern, or missing guardrail that should outlive the current task.\\n\\nThis is the capture side of the feedback loop. The goal is to let normal agent work produce reusable signal without requiring a human to manually restate every friction point later.\\n\\n## Default Behavior\\n\\nThe normal path should be agent-driven.\\n\\nIf you can clearly answer:\\n\\n- what was learned\\n- why it matters\\n- where it should land\\n- whether it belongs in `project` or `global`\\n\\nthen record the writeback instead of only suggesting that someone should do it later.\\n\\nUse:\\n\\n```bash\\nfclt ai writeback add --kind <kind> --summary \\"<summary>\\" --asset <asset-selector>\\n```\\n\\nThe writeback queue is runtime state, not canonical source. `fclt` stores JSON\\nqueue state in machine-local Facult state so sandboxed agents can record durable\\nfriction without mutating canonical assets unless an evolution proposal is later\\nreviewed and applied.\\n\\nEvery writeback also refreshes a Markdown review artifact under the global\\n`~/.ai/writebacks/...` tree. Global signal lands in `~/.ai/writebacks/global/`;\\nproject-scoped signal lands in `~/.ai/writebacks/projects/<slug-hash>/` with\\nfrontmatter for scope, project root, cwd, target asset, status, tags, evidence,\\nand timestamps. Do not write writeback review artifacts into a repo-local `.ai`;\\nrepo-local state should contribute project metadata and evidence, not bundled\\nprivate review files.\\n\\nProject-scoped writebacks should usually be recorded from the repo that produced\\nthe evidence. Global writebacks should be reserved for shared doctrine, shared\\nskills, shared agents, tool behavior, or cross-project capability gaps.\\n\\n## Record Writeback When\\n\\n- the same failure or weak loop appears again\\n- a reusable success pattern shows up\\n- guidance is clearly stale or missing\\n- a repo-local behavior probably belongs in project capability\\n- a cross-project behavior probably belongs in global capability\\n- a skill, tool, MCP, plugin, automation, or instruction gap repeatedly slows work down\\n- an agent has to restate the same workaround, verification rule, or review rule\\n\\n## Do Not Record Writeback For\\n\\n- one-off annoyance with no durable value\\n- weak commentary with no target\\n- speculative ideas without evidence\\n- duplicate noise with no new signal\\n\\n## Follow Through\\n\\n- prefer one strong writeback over many weak ones\\n- mention the writeback id when summarizing what changed\\n- escalate to `capability-evolution` or `fclt ai evolve ...` only when the signal is repeated or clearly points at a durable capability change\\n- use `fclt ai writeback group --by asset` or `fclt ai writeback summarize --by domain` to review accumulated signal before proposing broad changes\\n- use scheduled `learning-review`, `evolution-review`, or `tool-call-audit` automations when the signal should be reviewed in the background\\n","instructions/PROJECT_CAPABILITY.md":"---\\ndescription: Decide what belongs in repo-local .ai versus the global store.\\ntags: [facult, project, scope]\\n---\\n\\n# Project Capability\\n\\nPrefer project scope when the guidance depends on repo architecture, team workflow, or colocated tooling. Promote to global only after repeated cross-project reuse.\\n\\n## Project First\\n\\nDefault to `<repo>/.ai` when the capability is about:\\n\\n- local architecture\\n- repo-specific testing or verification\\n- team conventions\\n- project tools and workflows\\n\\n## Promote Carefully\\n\\nPromote to `~/.ai` only when:\\n\\n- the same pattern succeeds in more than one repo\\n- the capability is not coupled to local architecture\\n- the global version will not create noise for unrelated projects\\n\\nUse:\\n\\n```bash\\nfclt ai evolve promote EV-00001 --to global --project\\n```\\n\\nThat creates a new global proposal for review. It does not auto-apply the promotion.\\n","instructions/WORK_UNITS.md":"---\\ndescription: \\"Define work units so agent tasks have a clear goal, evidence path, artifact, and writeback target.\\"\\ntags: [\\"work-units\\", \\"planning\\", \\"verification\\", \\"writeback\\"]\\n---\\n\\n# Work Units\\n\\nA work unit is the smallest coherent unit of agent work that can be understood, verified, and preserved.\\n\\nIt is not just the user\'s latest sentence. It is the operational shape around that sentence: what is being changed, why it matters, what evidence is needed, what artifact should remain, and how future agents should benefit from the result.\\n\\n## Minimum Contract\\n\\nA well-formed work unit names:\\n\\n- goal: the outcome the user needs\\n- acceptance criteria: what must be true when the work is done\\n- required context: source files, docs, systems, messages, or prior decisions needed for correctness\\n- constraints: permissions, privacy, compatibility, deadlines, ownership, or scope limits\\n- signals or evidence: checks that can confirm progress or falsify assumptions\\n- output artifact: code, docs, proposal, issue, note, draft, or report\\n- verification path: commands, review surfaces, manual checks, or source-of-truth reads\\n- writeback target: where durable learning belongs if the work teaches something reusable\\n\\nIf one of these is missing and the gap blocks correctness, surface the gap early and recover it before moving faster.\\n\\n## Why It Exists\\n\\nWork-unit framing prevents shallow completion. It helps agents avoid:\\n\\n- changing files before understanding the target\\n- treating a weak green signal as proof\\n- losing reusable learning in chat\\n- creating duplicate tasks or proposals\\n- turning one-off preferences into global rules\\n- pushing project-specific details into global capability\\n\\n## How To Use It\\n\\nFor simple tasks, keep the work unit implicit but still verify the result.\\n\\nFor ambiguous, high-impact, or multi-step tasks, make the work unit explicit before executing. A compact form is enough:\\n\\n```text\\nGoal:\\nAcceptance:\\nContext:\\nConstraints:\\nEvidence:\\nArtifact:\\nVerification:\\nWriteback:\\n```\\n\\nUse the smallest framing that makes the task correct. Do not turn every request into paperwork.\\n\\n## Writeback\\n\\nWhen the work reveals durable friction, missing capability, stale guidance, or a repeatable workflow, prefer one strong writeback over many weak ones.\\n\\nUse `fclt ai writeback add ...` when the target asset, scope, and evidence are clear. Use `fclt ai evolve ...` only when repeated signal supports a concrete proposal.\\n","skills/capability-evolution/SKILL.md":"---\\ndescription: Convert repeated writeback into concrete fclt capability proposals.\\ntags: [facult, evolution, writeback]\\n---\\n\\n# capability-evolution\\n\\n## When To Use\\nUse this skill when the same missing guidance, weak loop, or recurring win appears often enough that the AI system itself should probably change.\\n\\nDo not wait for a human operator by default if the signal is already clear and the environment permits local AI runtime state to be updated.\\n\\nUse writeback first when the signal is useful but not yet repeated. Use evolution when accumulated writebacks, repeated tool friction, or a clearly missing capability point at a specific target asset or new capability.\\n\\n## Scope Decision\\n\\nChoose `project` when the behavior depends on repo-local architecture or workflow.\\n\\nChoose `global` when the behavior is broadly reusable.\\n\\nIf unsure, start at project scope and promote later with evidence.\\n\\n## Working Flow\\n\\n1. record the strongest writeback\\n2. group or summarize repeated signal\\n3. choose the smallest valid proposal kind\\n4. draft the proposal\\n5. accept only after the target and scope are correct\\n6. apply only when the markdown target is the intended canonical asset\\n\\nUse:\\n\\n```bash\\nfclt ai writeback add ...\\nfclt ai writeback group --by asset\\nfclt ai writeback summarize --by domain\\nfclt ai evolve propose\\nfclt ai evolve draft EV-00001\\nfclt ai evolve draft EV-00001 --append \\"tighten the rule with a concrete verification step\\"\\nfclt ai evolve accept EV-00001\\nfclt ai evolve apply EV-00001\\n```\\n\\nFor background review loops, use:\\n\\n```bash\\nfclt templates init automation learning-review\\nfclt templates init automation evolution-review\\nfclt templates init automation tool-call-audit\\n```\\n\\nIf there is not yet enough repeated signal for evolution, record the writeback and stop there.\\n\\n## Proposal Kind Selection\\n\\n- `update_asset` for tightening existing guidance\\n- `create_asset` for missing instructions or docs\\n- `extract_snippet` for reusable partial guidance\\n- `add_skill` for reusable workflow instruction\\n- `promote_asset` for project-to-global promotion\\n\\nUse task tracking instead of evolution when the main work is an executable tool or product fix that needs an owner, priority, state, or delivery plan. Use evolution for the reusable instruction, skill, or operating-model change that should survive that fix.\\n\\n## Output Contract\\n- repeated signal\\n- proposed asset change\\n- target scope\\n- evidence\\n- smallest useful next step\\n","skills/project-operating-layer-design/SKILL.md":"---\\ndescription: Design or improve a repo-local .ai operating layer.\\ntags: [facult, project, design]\\n---\\n\\n# project-operating-layer-design\\n\\n## When To Use\\nUse this skill when a project needs its own `.ai/` structure, repo-specific instructions, or local bootstrap guidance.\\n\\n## Output Contract\\n- recommended `.ai/` layout\\n- what stays project-local\\n- what stays global\\n- what should remain generated runtime output only\\n"}'
|
|
4
|
+
'{"AGENTS.global.md":"# Facult Operating Defaults\\n\\nThis machine has a default Facult operating-model layer available.\\n\\nWhen work produces durable friction, weak verification, stale guidance, or a missing skill/tool capability, preserve that signal with `fclt ai writeback ...` when the target and scope are clear. When repeated writebacks or clearly missing capability point at a concrete improvement, use `fclt ai evolve ...` or the `capability-evolution` skill to make a reviewable proposal.\\n\\nFor work-unit framing, read `@builtin/facult-operating-model/instructions/WORK_UNITS.md`.\\nFor composing refs, snippets, instructions, skills, agents, MCP, and automations as evolvable units, read `@builtin/facult-operating-model/instructions/CAPABILITY_COMPOSITION.md`.\\nFor writeback and evolution, read `@builtin/facult-operating-model/instructions/EVOLUTION.md`.\\nFor learning and writeback defaults, read `@builtin/facult-operating-model/instructions/LEARNING_AND_WRITEBACK.md`.\\nFor deciding whether capability belongs in global or project scope, read `@builtin/facult-operating-model/instructions/PROJECT_CAPABILITY.md`.\\nFor project operating-layer design, read `@builtin/facult-operating-model/instructions/INTEGRATION.md`.\\n\\nBuiltin specialist agents are available for:\\n- writeback curation\\n- evolution planning\\n- scope promotion\\n- integration auditing\\n\\nBuiltin skills are available for:\\n- capability evolution\\n- project operating-layer design\\n","agents/evolution-planner/agent.toml":"name = \\"evolution-planner\\"\\ndescription = \\"Turn repeated writeback into concrete capability proposals.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou plan capability evolution.\\n\\nPrioritize:\\n- smallest useful change\\n- correct target asset type\\n- correct target scope\\n- evidence that justifies the change\\n- repeated writeback clusters or clearly missing capabilities, not isolated preferences\\n\\nProposal kinds you should consider first:\\n- update_asset\\n- create_asset\\n- extract_snippet\\n- add_skill\\n- promote_asset\\n\\nDefault to project scope when the pattern is repo-local.\\nPromote to global only when reuse is demonstrated and pollution risk is low.\\n\\nReturn concise proposals ordered by expected leverage, including:\\n- proposal kind\\n- target asset\\n- target scope\\n- why this is the smallest durable change\\n\\nDo not escalate to evolution when a single writeback is enough.\\nDo not use evolution as a substitute for executable task tracking when the main need is owner, priority, state, or implementation follow-through.\\n\\"\\"\\"\\n","agents/integration-auditor/agent.toml":"name = \\"integration-auditor\\"\\ndescription = \\"Find where local success can still fail system-wide.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou audit integration risk.\\n\\nPrioritize:\\n- hidden dependencies\\n- rollout hazards\\n- operational constraints\\n- gaps between local verification and real system behavior\\n\\nReturn concise findings ordered by impact.\\n\\"\\"\\"\\n","agents/scope-promoter/agent.toml":"name = \\"scope-promoter\\"\\ndescription = \\"Decide whether learning belongs at project or global scope.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou decide scope.\\n\\nPrioritize:\\n- project specificity\\n- cross-project reuse potential\\n- pollution risk from globalizing too early\\n\\nWhen recommending promotion, make the standard path explicit:\\n- keep the source capability in project scope until promotion is approved\\n- create a reviewable global proposal\\n- do not treat promotion as implicit apply\\n\\nReturn concise decisions with rationale.\\n\\"\\"\\"\\n","agents/writeback-curator/agent.toml":"name = \\"writeback-curator\\"\\ndescription = \\"Turn noisy outcomes into high-signal writeback.\\"\\n\\ndeveloper_instructions = \\"\\"\\"\\nYou curate durable writeback.\\n\\nPrioritize:\\n- repeated failures\\n- repeated wins\\n- stale guidance\\n- missing capability edges\\n- tool, skill, MCP, plugin, automation, or instruction friction that repeatedly slows work down\\n\\nFor each recommendation, prefer returning:\\n- suggested writeback kind\\n- best target asset or destination\\n- best scope (`project` or `global`)\\n- the evidence that justifies recording it\\n\\nDo not emit low-signal noise.\\nIf the learning is repo-specific, keep it project-scoped by default.\\nWhen the signal is already strong and the target is clear, prefer recommending direct writeback capture rather than abstract advice.\\nWhen the issue is executable tooling work, recommend task tracking for the fix and writeback only for the reusable operating-model learning.\\n\\"\\"\\"\\n","instructions/CAPABILITY_COMPOSITION.md":"---\\ndescription: \\"Compose small capability units across global and project roots, then evolve the smallest affected unit.\\"\\ntags: [\\"facult\\", \\"composition\\", \\"refs\\", \\"snippets\\", \\"instructions\\"]\\n---\\n\\n# Capability Composition\\n\\nUse `fclt` capability as small units that can be composed, inspected, rendered, and evolved independently.\\n\\nThe main units are:\\n\\n- instructions: standalone markdown doctrine such as language preferences, verification rules, or review standards\\n- snippets: small markdown partials inserted into one or more rendered docs\\n- skills: task-specific workflows with `SKILL.md`\\n- agents: focused role manifests\\n- MCP definitions: tool interfaces and their safe auth shape\\n- automations: scheduled review or maintenance loops\\n- tool rules/config: tool-specific defaults and policy\\n\\n## Composition Rules\\n\\n- Keep reusable doctrine in `instructions/`.\\n- Keep repeated paragraphs or policy blocks in `snippets/`.\\n- Keep workflow execution in `skills/`.\\n- Keep persona or delegation behavior in `agents/`.\\n- Keep tool wiring in `mcp/` and `tools/<tool>/`.\\n- Compose broad agent docs from refs and snippets instead of copying text by hand.\\n- Prefer one narrow reusable unit over one large instruction file that mixes unrelated domains.\\n\\nExamples:\\n\\n- `@ai/instructions/BUN.md` for shared Bun preferences.\\n- `@ai/instructions/RUST.md` for shared Rust preferences.\\n- `@project/instructions/TESTING.md` for repo-specific test policy.\\n- `<!-- fclty:global/codex/baseline -->` for a shared rendered block.\\n\\n## Scope\\n\\nUse global scope for capability that should follow the user across projects.\\n\\nUse project scope for capability that belongs to a repo, team workflow, architecture, or local test harness.\\n\\nPromote project capability to global only when repeated evidence shows reuse across projects. Do not globalize a project quirk just because it worked once.\\n\\n## Writeback And Evolution\\n\\nTarget the smallest affected unit.\\n\\n- If a paragraph is reused in several rendered docs, target the snippet.\\n- If a domain rule is wrong, target the instruction.\\n- If a workflow is incomplete, target the skill.\\n- If a delegated role is unclear, target the agent.\\n- If a tool interface is missing or unsafe, target the MCP or tool config.\\n- If a scheduled review loop is noisy or missing context, target the automation.\\n\\nGood writeback targets are graph-backed selectors when possible:\\n\\n```bash\\nfclt ai writeback add --kind missing_context --summary \\"Bun guidance did not cover test runner selection.\\" --asset instruction:BUN\\nfclt ai writeback add --kind reusable_pattern --summary \\"Project test policy should become a shared verification snippet.\\" --asset @project/instructions/TESTING.md\\nfclt ai writeback add --kind bad_default --summary \\"The review automation escalated one-off preferences.\\" --asset automation:evolution-review\\n```\\n\\nUse `fclt ai evolve ...` only after repeated signal, a clearly missing capability, or a stale canonical asset points at a concrete change. Prefer the smallest valid proposal kind: `update_asset`, `create_asset`, `extract_snippet`, `add_skill`, or `promote_asset`.\\n\\n## Agent Defaults\\n\\nWhen an agent sees a repeated preference like \\"use Bun for JS projects\\" or \\"prefer Cargo nextest for Rust tests\\", it should not bury that in chat. It should identify whether the durable unit is:\\n\\n- a global instruction\\n- a project instruction\\n- a snippet reused by rendered docs\\n- a skill workflow\\n- a project-to-global promotion candidate\\n\\nThen it should record writeback against that unit, or draft a proposal when the evidence is already strong enough.\\n","instructions/EVOLUTION.md":"---\\ndescription: Turn repeated signal into concrete capability changes.\\ntags: [facult, evolution, writeback]\\n---\\n\\n# Evolution\\n\\nUse writeback and evolution to improve the AI operating layer itself.\\n\\nEvolution is the synthesis and change side of the feedback loop. It turns accumulated writebacks, repeated tool friction, stale canonical assets, or clearly missing capability into small reviewable changes to instructions, skills, snippets, agents, or other markdown canonical assets.\\n\\nUse capability composition when choosing the target. Instructions, snippets, skills, agents, MCP/tool config, and automations are separate units. Target the smallest unit that actually needs to change instead of rewriting a broad agent doc.\\n\\n## When To Record Writeback\\n\\nRecord writeback when one of these is true:\\n\\n- the same failure repeats\\n- the same success pattern repeats\\n- guidance is stale or missing\\n- a prompt or loop has to be restated often\\n- a project-specific pattern looks reusable\\n\\nDo not record low-signal noise:\\n\\n- one-off annoyance with no reuse value\\n- generic \\"could be better\\" commentary\\n- duplicate observations with no new evidence\\n\\nThe intended default is that agents record strong writebacks themselves when the signal is clear enough, rather than only recommending that a user do it manually later.\\n\\nDo not wait for a weekly review to preserve high-signal evidence. Do wait for repeated evidence or a clearly missing capability before drafting a proposal.\\n\\n## Scope\\n\\nChoose `project` scope when the learning depends on:\\n\\n- repo architecture\\n- team workflow\\n- project tooling\\n- local testing or verification behavior\\n\\nChoose `global` scope when the learning is reusable across projects.\\n\\nPromote from project to global only after repeated reuse or strong evidence.\\n\\n## Writeback Kinds\\n\\nCommon kinds:\\n\\n- `weak_verification`\\n- `false_positive`\\n- `missing_context`\\n- `reusable_pattern`\\n- `capability_gap`\\n- `bad_default`\\n\\nEvery good writeback should try to include:\\n\\n- a concrete summary\\n- the best target asset if known\\n- the right scope\\n- domain or tags when useful\\n\\nGood target examples:\\n\\n- `instruction:BUN` when shared Bun guidance is stale or missing\\n- `@project/instructions/TESTING.md` when repo test policy needs project-scoped evolution\\n- `snippet:global/lang/bun` when a repeated rendered block should be fixed or extracted\\n- `skill:capability-evolution` when a workflow skill is missing steps or examples\\n- `automation:evolution-review` when the scheduled review loop is noisy or incomplete\\n\\n## Operator Flow\\n\\nTypical workflow:\\n\\n```bash\\nfclt ai writeback add --kind weak_verification --summary \\"Checks were too shallow\\" --asset instruction:VERIFICATION\\nfclt ai writeback group --by asset\\nfclt ai writeback summarize --by domain\\nfclt ai evolve propose\\nfclt ai evolve draft EV-00001\\nfclt ai evolve accept EV-00001\\nfclt ai evolve apply EV-00001\\n```\\n\\nUse `fclt ai evolve draft <id> --append \\"...\\"` to revise a draft while preserving draft history.\\n\\nReview surfaces:\\n\\n- open `~/.ai/writebacks/` and `~/.ai/evolution/` in a Markdown editor for frontmatter-rich global and project-scoped review artifacts\\n- `fclt status --json` for queue/proposal paths, review artifact paths, counts, and active scope\\n- `fclt ai writeback list|show|group|summarize` for raw and clustered signal\\n- `fclt ai evolve list|show|review` for proposal state without applying changes\\n- `fclt templates init automation learning-review` for recurring capture/review\\n- `fclt templates init automation evolution-review` for recurring proposal review\\n- `fclt templates init automation tool-call-audit` for repeated tool-friction review\\n\\nEvolution proposal metadata, markdown drafts, patch artifacts, writeback queues,\\nand journals are runtime state. `fclt` stores JSON queues, proposal records,\\ndraft refs, patches, and journals in machine-local Facult state. It mirrors\\nhuman-readable review artifacts into global `~/.ai/writebacks/...` and\\n`~/.ai/evolution/...`, including project-scoped artifacts under\\n`projects/<slug-hash>/` with cwd/project metadata in frontmatter. Canonical\\nassets in `~/.ai` or `<repo>/.ai` should only change when a proposal is applied.\\n\\n## Default Agent Behavior\\n\\nUse the smallest action that fits the signal:\\n\\n1. record one strong writeback when there is a clear durable learning\\n2. use `writeback-curator` when the target, kind, or scope is ambiguous\\n3. use `capability-evolution` or `evolution-planner` when repeated signal should become a proposal\\n4. do not draft or apply proposals just because a writeback exists; require repeated evidence or a clearly missing capability\\n\\nAvoid creating writeback/evolution noise for one-off nits, vague preferences, or speculative ideas without evidence.\\n\\nWhen the friction is executable product/tooling work that needs ownership,\\npriority, state, or implementation follow-through, create or update a real task\\nsystem item instead of forcing it into capability evolution. Use evolution for\\nthe reusable operating-layer change.\\n\\n## Proposal Kinds\\n\\nCurrent supported proposal kinds:\\n\\n- `update_asset`\\n- `create_asset`\\n- `extract_snippet`\\n- `add_skill`\\n- `promote_asset`\\n\\nUse the smallest durable change that fits the evidence.\\n\\nExamples:\\n\\n- `update_asset`: fix a stale instruction, snippet, agent, or automation markdown asset.\\n- `create_asset`: add a missing instruction such as `BUN.md` or `RUST.md`.\\n- `extract_snippet`: move repeated guidance out of several docs into one snippet.\\n- `add_skill`: create a workflow when instructions are not enough.\\n- `promote_asset`: move a proven project instruction/snippet/skill toward global reuse.\\n\\n## Review And Apply Rules\\n\\n- draft before apply\\n- accept before apply\\n- prefer the smallest safe change\\n- keep reviewable evidence tied to source writebacks\\n- do not globalize project behavior too early\\n- do not apply high-risk global instruction, skill, plugin, or shared-tool changes without explicit review/approval\\n\\nApply is for markdown canonical assets only. If the target is wrong, revise the proposal rather than forcing it through.\\n","instructions/INTEGRATION.md":"---\\ndescription: Detect where local success can still fail at integration boundaries.\\ntags: [facult, integration, verification]\\n---\\n\\n# Integration\\n\\nDistinguish local correctness from system correctness. Check hidden dependencies, rollout order, and operational constraints before calling work done.\\n","instructions/LEARNING_AND_WRITEBACK.md":"---\\ndescription: Preserve durable signal and record writeback when the operating layer should learn.\\ntags: [facult, learning, writeback]\\n---\\n\\n# Learning And Writeback\\n\\nUse this when work produces a durable decision, failure, success pattern, or missing guardrail that should outlive the current task.\\n\\nThis is the capture side of the feedback loop. The goal is to let normal agent work produce reusable signal without requiring a human to manually restate every friction point later.\\n\\n## Default Behavior\\n\\nThe normal path should be agent-driven.\\n\\nIf you can clearly answer:\\n\\n- what was learned\\n- why it matters\\n- where it should land\\n- whether it belongs in `project` or `global`\\n\\nthen record the writeback instead of only suggesting that someone should do it later.\\n\\nUse:\\n\\n```bash\\nfclt ai writeback add --kind <kind> --summary \\"<summary>\\" --asset <asset-selector>\\n```\\n\\nThe writeback queue is runtime state, not canonical source. `fclt` stores JSON\\nqueue state in machine-local Facult state so sandboxed agents can record durable\\nfriction without mutating canonical assets unless an evolution proposal is later\\nreviewed and applied.\\n\\nEvery writeback also refreshes a Markdown review artifact under the global\\n`~/.ai/writebacks/...` tree. Global signal lands in `~/.ai/writebacks/global/`;\\nproject-scoped signal lands in `~/.ai/writebacks/projects/<slug-hash>/` with\\nfrontmatter for scope, project root, cwd, target asset, status, tags, evidence,\\nand timestamps. Do not write writeback review artifacts into a repo-local `.ai`;\\nrepo-local state should contribute project metadata and evidence, not bundled\\nprivate review files.\\n\\nProject-scoped writebacks should usually be recorded from the repo that produced\\nthe evidence. Global writebacks should be reserved for shared doctrine, shared\\nskills, shared agents, tool behavior, or cross-project capability gaps.\\n\\nTarget the smallest composable unit that explains the friction:\\n\\n- instruction: domain guidance, preferences, verification rules, or review doctrine\\n- snippet: repeated markdown block used by more than one rendered doc\\n- skill: workflow execution steps or examples\\n- agent: delegated role behavior\\n- MCP/tool config: tool interface, auth shape, or rendered integration\\n- automation: scheduled review loop, cadence, prompt, or memory\\n\\n## Record Writeback When\\n\\n- the same failure or weak loop appears again\\n- a reusable success pattern shows up\\n- guidance is clearly stale or missing\\n- a repo-local behavior probably belongs in project capability\\n- a cross-project behavior probably belongs in global capability\\n- a skill, tool, MCP, plugin, automation, or instruction gap repeatedly slows work down\\n- an agent has to restate the same workaround, verification rule, or review rule\\n- a repeated preference should become an atomic instruction such as `BUN.md`, `RUST.md`, or a project-specific testing policy\\n\\n## Do Not Record Writeback For\\n\\n- one-off annoyance with no durable value\\n- weak commentary with no target\\n- speculative ideas without evidence\\n- duplicate noise with no new signal\\n\\n## Follow Through\\n\\n- prefer one strong writeback over many weak ones\\n- mention the writeback id when summarizing what changed\\n- escalate to `capability-evolution` or `fclt ai evolve ...` only when the signal is repeated or clearly points at a durable capability change\\n- use `fclt ai writeback group --by asset` or `fclt ai writeback summarize --by domain` to review accumulated signal before proposing broad changes\\n- use scheduled `learning-review`, `evolution-review`, or `tool-call-audit` automations when the signal should be reviewed in the background\\n","instructions/PROJECT_CAPABILITY.md":"---\\ndescription: Decide what belongs in repo-local .ai versus the global store.\\ntags: [facult, project, scope]\\n---\\n\\n# Project Capability\\n\\nPrefer project scope when the guidance depends on repo architecture, team workflow, or colocated tooling. Promote to global only after repeated cross-project reuse.\\n\\n## Project First\\n\\nDefault to `<repo>/.ai` when the capability is about:\\n\\n- local architecture\\n- repo-specific testing or verification\\n- team conventions\\n- project tools and workflows\\n\\n## Promote Carefully\\n\\nPromote to `~/.ai` only when:\\n\\n- the same pattern succeeds in more than one repo\\n- the capability is not coupled to local architecture\\n- the global version will not create noise for unrelated projects\\n\\nUse:\\n\\n```bash\\nfclt ai evolve promote EV-00001 --to global --project\\n```\\n\\nThat creates a new global proposal for review. It does not auto-apply the promotion.\\n","instructions/WORK_UNITS.md":"---\\ndescription: \\"Define work units so agent tasks have a clear goal, evidence path, artifact, and writeback target.\\"\\ntags: [\\"work-units\\", \\"planning\\", \\"verification\\", \\"writeback\\"]\\n---\\n\\n# Work Units\\n\\nA work unit is the smallest coherent unit of agent work that can be understood, verified, and preserved.\\n\\nIt is not just the user\'s latest sentence. It is the operational shape around that sentence: what is being changed, why it matters, what evidence is needed, what artifact should remain, and how future agents should benefit from the result.\\n\\n## Minimum Contract\\n\\nA well-formed work unit names:\\n\\n- goal: the outcome the user needs\\n- acceptance criteria: what must be true when the work is done\\n- required context: source files, docs, systems, messages, or prior decisions needed for correctness\\n- constraints: permissions, privacy, compatibility, deadlines, ownership, or scope limits\\n- signals or evidence: checks that can confirm progress or falsify assumptions\\n- output artifact: code, docs, proposal, issue, note, draft, or report\\n- verification path: commands, review surfaces, manual checks, or source-of-truth reads\\n- writeback target: where durable learning belongs if the work teaches something reusable\\n\\nIf one of these is missing and the gap blocks correctness, surface the gap early and recover it before moving faster.\\n\\n## Why It Exists\\n\\nWork-unit framing prevents shallow completion. It helps agents avoid:\\n\\n- changing files before understanding the target\\n- treating a weak green signal as proof\\n- losing reusable learning in chat\\n- creating duplicate tasks or proposals\\n- turning one-off preferences into global rules\\n- pushing project-specific details into global capability\\n\\n## How To Use It\\n\\nFor simple tasks, keep the work unit implicit but still verify the result.\\n\\nFor ambiguous, high-impact, or multi-step tasks, make the work unit explicit before executing. A compact form is enough:\\n\\n```text\\nGoal:\\nAcceptance:\\nContext:\\nConstraints:\\nEvidence:\\nArtifact:\\nVerification:\\nWriteback:\\n```\\n\\nUse the smallest framing that makes the task correct. Do not turn every request into paperwork.\\n\\n## Writeback\\n\\nWhen the work reveals durable friction, missing capability, stale guidance, or a repeatable workflow, prefer one strong writeback over many weak ones.\\n\\nUse `fclt ai writeback add ...` when the target asset, scope, and evidence are clear. Use `fclt ai evolve ...` only when repeated signal supports a concrete proposal.\\n","skills/capability-evolution/SKILL.md":"---\\ndescription: Convert repeated writeback into concrete fclt capability proposals.\\ntags: [facult, evolution, writeback]\\n---\\n\\n# capability-evolution\\n\\n## When To Use\\nUse this skill when the same missing guidance, weak loop, or recurring win appears often enough that the AI system itself should probably change.\\n\\nDo not wait for a human operator by default if the signal is already clear and the environment permits local AI runtime state to be updated.\\n\\nUse writeback first when the signal is useful but not yet repeated. Use evolution when accumulated writebacks, repeated tool friction, or a clearly missing capability point at a specific target asset or new capability.\\n\\n## Scope Decision\\n\\nChoose `project` when the behavior depends on repo-local architecture or workflow.\\n\\nChoose `global` when the behavior is broadly reusable.\\n\\nIf unsure, start at project scope and promote later with evidence.\\n\\n## Working Flow\\n\\n1. record the strongest writeback\\n2. group or summarize repeated signal\\n3. choose the smallest valid proposal kind\\n4. draft the proposal\\n5. accept only after the target and scope are correct\\n6. apply only when the markdown target is the intended canonical asset\\n\\nUse:\\n\\n```bash\\nfclt ai writeback add ...\\nfclt ai writeback group --by asset\\nfclt ai writeback summarize --by domain\\nfclt ai evolve propose\\nfclt ai evolve draft EV-00001\\nfclt ai evolve draft EV-00001 --append \\"tighten the rule with a concrete verification step\\"\\nfclt ai evolve accept EV-00001\\nfclt ai evolve apply EV-00001\\n```\\n\\nFor background review loops, use:\\n\\n```bash\\nfclt templates init automation learning-review\\nfclt templates init automation evolution-review\\nfclt templates init automation tool-call-audit\\n```\\n\\nIf there is not yet enough repeated signal for evolution, record the writeback and stop there.\\n\\n## Proposal Kind Selection\\n\\n- `update_asset` for tightening existing guidance\\n- `create_asset` for missing instructions or docs\\n- `extract_snippet` for reusable partial guidance\\n- `add_skill` for reusable workflow instruction\\n- `promote_asset` for project-to-global promotion\\n\\nUse task tracking instead of evolution when the main work is an executable tool or product fix that needs an owner, priority, state, or delivery plan. Use evolution for the reusable instruction, skill, or operating-model change that should survive that fix.\\n\\n## Output Contract\\n- repeated signal\\n- proposed asset change\\n- target scope\\n- evidence\\n- smallest useful next step\\n","skills/project-operating-layer-design/SKILL.md":"---\\ndescription: Design or improve a repo-local .ai operating layer.\\ntags: [facult, project, design]\\n---\\n\\n# project-operating-layer-design\\n\\n## When To Use\\nUse this skill when a project needs its own `.ai/` structure, repo-specific instructions, or local bootstrap guidance.\\n\\n## Output Contract\\n- recommended `.ai/` layout\\n- what stays project-local\\n- what stays global\\n- what should remain generated runtime output only\\n"}'
|
|
5
5
|
) as Record<string, string>;
|
package/src/remote-types.ts
CHANGED
|
@@ -4,7 +4,12 @@ import type {
|
|
|
4
4
|
ManifestSignatureKey,
|
|
5
5
|
} from "./remote-manifest-integrity";
|
|
6
6
|
|
|
7
|
-
export type RemoteItemType =
|
|
7
|
+
export type RemoteItemType =
|
|
8
|
+
| "skill"
|
|
9
|
+
| "mcp"
|
|
10
|
+
| "agent"
|
|
11
|
+
| "snippet"
|
|
12
|
+
| "instruction";
|
|
8
13
|
|
|
9
14
|
export interface RemoteSkillPayload {
|
|
10
15
|
name: string;
|
|
@@ -26,6 +31,11 @@ export interface RemoteSnippetPayload {
|
|
|
26
31
|
content: string;
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
export interface RemoteInstructionPayload {
|
|
35
|
+
name: string;
|
|
36
|
+
content: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
29
39
|
export interface RemoteIndexItemBase {
|
|
30
40
|
id: string;
|
|
31
41
|
type: RemoteItemType;
|
|
@@ -56,11 +66,17 @@ export interface RemoteSnippetItem extends RemoteIndexItemBase {
|
|
|
56
66
|
snippet: RemoteSnippetPayload;
|
|
57
67
|
}
|
|
58
68
|
|
|
69
|
+
export interface RemoteInstructionItem extends RemoteIndexItemBase {
|
|
70
|
+
type: "instruction";
|
|
71
|
+
instruction: RemoteInstructionPayload;
|
|
72
|
+
}
|
|
73
|
+
|
|
59
74
|
export type RemoteIndexItem =
|
|
60
75
|
| RemoteSkillItem
|
|
61
76
|
| RemoteMcpItem
|
|
62
77
|
| RemoteAgentItem
|
|
63
|
-
| RemoteSnippetItem
|
|
78
|
+
| RemoteSnippetItem
|
|
79
|
+
| RemoteInstructionItem;
|
|
64
80
|
|
|
65
81
|
export interface RemoteIndexManifest {
|
|
66
82
|
name: string;
|
package/src/remote.ts
CHANGED
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
type RemoteAgentItem,
|
|
44
44
|
type RemoteIndexItem,
|
|
45
45
|
type RemoteIndexManifest,
|
|
46
|
+
type RemoteInstructionItem,
|
|
46
47
|
type RemoteItemType,
|
|
47
48
|
type RemoteMcpItem,
|
|
48
49
|
type RemoteSkillItem,
|
|
@@ -60,6 +61,8 @@ const QUERY_SPLIT_RE = /\s+/;
|
|
|
60
61
|
const MD_EXT_RE = /\.md$/i;
|
|
61
62
|
const FILE_EXT_RE = /\.[A-Za-z0-9]+$/;
|
|
62
63
|
const TRAILING_SLASH_RE = /\/+$/;
|
|
64
|
+
const LEADING_SLASH_RE = /^\/+/;
|
|
65
|
+
const INSTRUCTION_TITLE_SPLIT_RE = /[-_.\s]+/;
|
|
63
66
|
const PROMPT_PATH_SPLIT_RE = /[,\n]/;
|
|
64
67
|
const GIT_WORKTREE_LINE_RE = /\r?\n/;
|
|
65
68
|
|
|
@@ -222,6 +225,52 @@ Use this skill when the task repeatedly follows a known workflow and you want co
|
|
|
222
225
|
},
|
|
223
226
|
},
|
|
224
227
|
},
|
|
228
|
+
{
|
|
229
|
+
id: "instruction-template",
|
|
230
|
+
type: "instruction",
|
|
231
|
+
title: "Instruction Template",
|
|
232
|
+
description:
|
|
233
|
+
"Reusable markdown instruction scaffold with ref and snippet composition examples.",
|
|
234
|
+
version: "1.0.0",
|
|
235
|
+
tags: ["template", "dx", "instruction"],
|
|
236
|
+
instruction: {
|
|
237
|
+
name: "WORKFLOW.md",
|
|
238
|
+
content: `---
|
|
239
|
+
description: "{{name}} reusable instruction"
|
|
240
|
+
tags: [instruction, workflow]
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
# {{title}}
|
|
244
|
+
|
|
245
|
+
Use this instruction when the task needs repeatable guidance that should be discoverable, targetable by writeback, and composable into agent docs.
|
|
246
|
+
|
|
247
|
+
## Scope
|
|
248
|
+
|
|
249
|
+
- Applies to:
|
|
250
|
+
- Does not apply to:
|
|
251
|
+
- Project-specific overrides:
|
|
252
|
+
|
|
253
|
+
## Guidance
|
|
254
|
+
|
|
255
|
+
- Keep the rule concrete enough that another agent can follow it without chat context.
|
|
256
|
+
- Link deeper reusable guidance with canonical refs such as \`@ai/instructions/VERIFICATION.md\` or \`@project/instructions/TESTING.md\`.
|
|
257
|
+
- Reuse stable partials with snippet markers when the same block appears in more than one rendered doc.
|
|
258
|
+
|
|
259
|
+
## Composition
|
|
260
|
+
|
|
261
|
+
<!-- fclty:global/team/example -->
|
|
262
|
+
<!-- /fclty:global/team/example -->
|
|
263
|
+
|
|
264
|
+
## Writeback Targeting
|
|
265
|
+
|
|
266
|
+
Record durable friction against this instruction with:
|
|
267
|
+
|
|
268
|
+
\`\`\`bash
|
|
269
|
+
fclt ai writeback add --kind missing_context --summary "<what was missing>" --asset instruction:{{assetName}}
|
|
270
|
+
\`\`\`
|
|
271
|
+
`,
|
|
272
|
+
},
|
|
273
|
+
},
|
|
225
274
|
{
|
|
226
275
|
id: "mcp-stdio-template",
|
|
227
276
|
type: "mcp",
|
|
@@ -1461,7 +1510,8 @@ function parseIndexItem(raw: unknown): RemoteIndexItem | null {
|
|
|
1461
1510
|
type !== "skill" &&
|
|
1462
1511
|
type !== "mcp" &&
|
|
1463
1512
|
type !== "agent" &&
|
|
1464
|
-
type !== "snippet"
|
|
1513
|
+
type !== "snippet" &&
|
|
1514
|
+
type !== "instruction"
|
|
1465
1515
|
) {
|
|
1466
1516
|
return null;
|
|
1467
1517
|
}
|
|
@@ -1560,6 +1610,30 @@ function parseIndexItem(raw: unknown): RemoteIndexItem | null {
|
|
|
1560
1610
|
};
|
|
1561
1611
|
}
|
|
1562
1612
|
|
|
1613
|
+
if (type === "instruction") {
|
|
1614
|
+
const instructionRaw = obj.instruction;
|
|
1615
|
+
if (!isPlainObject(instructionRaw)) {
|
|
1616
|
+
return null;
|
|
1617
|
+
}
|
|
1618
|
+
const name =
|
|
1619
|
+
typeof instructionRaw.name === "string" ? instructionRaw.name.trim() : "";
|
|
1620
|
+
const content =
|
|
1621
|
+
typeof instructionRaw.content === "string" ? instructionRaw.content : "";
|
|
1622
|
+
if (!(name && content)) {
|
|
1623
|
+
return null;
|
|
1624
|
+
}
|
|
1625
|
+
return {
|
|
1626
|
+
id,
|
|
1627
|
+
type,
|
|
1628
|
+
title,
|
|
1629
|
+
description,
|
|
1630
|
+
version,
|
|
1631
|
+
sourceUrl,
|
|
1632
|
+
tags,
|
|
1633
|
+
instruction: { name, content },
|
|
1634
|
+
};
|
|
1635
|
+
}
|
|
1636
|
+
|
|
1563
1637
|
const snippetRaw = obj.snippet;
|
|
1564
1638
|
if (!isPlainObject(snippetRaw)) {
|
|
1565
1639
|
return null;
|
|
@@ -1731,7 +1805,8 @@ async function loadInstalledState(
|
|
|
1731
1805
|
type !== "skill" &&
|
|
1732
1806
|
type !== "mcp" &&
|
|
1733
1807
|
type !== "agent" &&
|
|
1734
|
-
type !== "snippet"
|
|
1808
|
+
type !== "snippet" &&
|
|
1809
|
+
type !== "instruction"
|
|
1735
1810
|
) {
|
|
1736
1811
|
continue;
|
|
1737
1812
|
}
|
|
@@ -2035,6 +2110,69 @@ async function installSnippetItem(args: {
|
|
|
2035
2110
|
};
|
|
2036
2111
|
}
|
|
2037
2112
|
|
|
2113
|
+
function normalizeInstructionName(value: string): string {
|
|
2114
|
+
const normalized = value
|
|
2115
|
+
.trim()
|
|
2116
|
+
.replaceAll("\\", "/")
|
|
2117
|
+
.replace(LEADING_SLASH_RE, "");
|
|
2118
|
+
if (!normalized) {
|
|
2119
|
+
throw new Error("Instruction name is required");
|
|
2120
|
+
}
|
|
2121
|
+
const withExt = MD_EXT_RE.test(normalized) ? normalized : `${normalized}.md`;
|
|
2122
|
+
if (!isSafeRelativePath(withExt)) {
|
|
2123
|
+
throw new Error(`Invalid instruction name: ${value}`);
|
|
2124
|
+
}
|
|
2125
|
+
return withExt;
|
|
2126
|
+
}
|
|
2127
|
+
|
|
2128
|
+
function instructionTitleFromFileName(fileName: string): string {
|
|
2129
|
+
const base = basename(fileName).replace(MD_EXT_RE, "");
|
|
2130
|
+
return base
|
|
2131
|
+
.split(INSTRUCTION_TITLE_SPLIT_RE)
|
|
2132
|
+
.filter(Boolean)
|
|
2133
|
+
.map((part) => `${part.slice(0, 1).toUpperCase()}${part.slice(1)}`)
|
|
2134
|
+
.join(" ");
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
function instructionAssetName(fileName: string): string {
|
|
2138
|
+
return basename(fileName).replace(MD_EXT_RE, "");
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
async function installInstructionItem(args: {
|
|
2142
|
+
item: RemoteInstructionItem;
|
|
2143
|
+
installAs?: string;
|
|
2144
|
+
rootDir: string;
|
|
2145
|
+
force: boolean;
|
|
2146
|
+
dryRun: boolean;
|
|
2147
|
+
}): Promise<{ installedAs: string; path: string; changedPaths: string[] }> {
|
|
2148
|
+
const fileName = normalizeInstructionName(
|
|
2149
|
+
args.installAs ?? args.item.instruction.name
|
|
2150
|
+
);
|
|
2151
|
+
const instructionPath = join(args.rootDir, "instructions", fileName);
|
|
2152
|
+
assertInstallPath(instructionPath, join(args.rootDir, "instructions"));
|
|
2153
|
+
if ((await fileExists(instructionPath)) && !args.force) {
|
|
2154
|
+
throw new Error(
|
|
2155
|
+
`Instruction already exists: ${fileName} (use --force to overwrite)`
|
|
2156
|
+
);
|
|
2157
|
+
}
|
|
2158
|
+
if (!args.dryRun) {
|
|
2159
|
+
await mkdir(dirname(instructionPath), { recursive: true });
|
|
2160
|
+
await Bun.write(
|
|
2161
|
+
instructionPath,
|
|
2162
|
+
renderTemplate(args.item.instruction.content, {
|
|
2163
|
+
name: fileName,
|
|
2164
|
+
title: instructionTitleFromFileName(fileName),
|
|
2165
|
+
assetName: instructionAssetName(fileName),
|
|
2166
|
+
})
|
|
2167
|
+
);
|
|
2168
|
+
}
|
|
2169
|
+
return {
|
|
2170
|
+
installedAs: fileName,
|
|
2171
|
+
path: instructionPath,
|
|
2172
|
+
changedPaths: [instructionPath],
|
|
2173
|
+
};
|
|
2174
|
+
}
|
|
2175
|
+
|
|
2038
2176
|
async function installParsedItem(args: {
|
|
2039
2177
|
parsedRef: { index: string; itemId: string };
|
|
2040
2178
|
item: RemoteIndexItem;
|
|
@@ -2076,7 +2214,7 @@ async function installParsedItem(args: {
|
|
|
2076
2214
|
force: args.force,
|
|
2077
2215
|
dryRun: args.dryRun,
|
|
2078
2216
|
});
|
|
2079
|
-
} else {
|
|
2217
|
+
} else if (args.item.type === "snippet") {
|
|
2080
2218
|
writeResult = await installSnippetItem({
|
|
2081
2219
|
item: args.item,
|
|
2082
2220
|
installAs: args.installAs,
|
|
@@ -2084,6 +2222,14 @@ async function installParsedItem(args: {
|
|
|
2084
2222
|
force: args.force,
|
|
2085
2223
|
dryRun: args.dryRun,
|
|
2086
2224
|
});
|
|
2225
|
+
} else {
|
|
2226
|
+
writeResult = await installInstructionItem({
|
|
2227
|
+
item: args.item,
|
|
2228
|
+
installAs: args.installAs,
|
|
2229
|
+
rootDir: args.rootDir,
|
|
2230
|
+
force: args.force,
|
|
2231
|
+
dryRun: args.dryRun,
|
|
2232
|
+
});
|
|
2087
2233
|
}
|
|
2088
2234
|
|
|
2089
2235
|
const result: InstallResult = {
|
|
@@ -2666,6 +2812,9 @@ function printTemplatesHelp() {
|
|
|
2666
2812
|
renderCode(
|
|
2667
2813
|
"fclt templates init agent <name> [--force] [--dry-run]"
|
|
2668
2814
|
),
|
|
2815
|
+
renderCode(
|
|
2816
|
+
"fclt templates init instruction <name> [--force] [--dry-run]"
|
|
2817
|
+
),
|
|
2669
2818
|
renderCode(
|
|
2670
2819
|
"fclt templates init snippet <marker> [--force] [--dry-run]"
|
|
2671
2820
|
),
|
|
@@ -2734,6 +2883,53 @@ function parseLongFlag(argv: string[], flag: string): string | null {
|
|
|
2734
2883
|
return null;
|
|
2735
2884
|
}
|
|
2736
2885
|
|
|
2886
|
+
const TEMPLATE_INIT_VALUE_FLAGS = new Set([
|
|
2887
|
+
"--automation-status",
|
|
2888
|
+
"--cwds",
|
|
2889
|
+
"--name",
|
|
2890
|
+
"--project-root",
|
|
2891
|
+
"--root",
|
|
2892
|
+
"--rrule",
|
|
2893
|
+
"--scope",
|
|
2894
|
+
"--status",
|
|
2895
|
+
]);
|
|
2896
|
+
|
|
2897
|
+
function parseTemplateInitArgs(argv: string[]): {
|
|
2898
|
+
positional: string[];
|
|
2899
|
+
rootArg?: string;
|
|
2900
|
+
} {
|
|
2901
|
+
const positional: string[] = [];
|
|
2902
|
+
let rootArg: string | undefined;
|
|
2903
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
2904
|
+
const arg = argv[i];
|
|
2905
|
+
if (!arg) {
|
|
2906
|
+
continue;
|
|
2907
|
+
}
|
|
2908
|
+
if (arg === "--root") {
|
|
2909
|
+
rootArg = argv[i + 1] ?? undefined;
|
|
2910
|
+
i += 1;
|
|
2911
|
+
continue;
|
|
2912
|
+
}
|
|
2913
|
+
if (arg.startsWith("--root=")) {
|
|
2914
|
+
rootArg = arg.slice("--root=".length);
|
|
2915
|
+
continue;
|
|
2916
|
+
}
|
|
2917
|
+
if (TEMPLATE_INIT_VALUE_FLAGS.has(arg)) {
|
|
2918
|
+
i += 1;
|
|
2919
|
+
continue;
|
|
2920
|
+
}
|
|
2921
|
+
const equalFlag = arg.startsWith("--") ? arg.split("=", 1)[0] : "";
|
|
2922
|
+
if (equalFlag && TEMPLATE_INIT_VALUE_FLAGS.has(equalFlag)) {
|
|
2923
|
+
continue;
|
|
2924
|
+
}
|
|
2925
|
+
if (arg.startsWith("-")) {
|
|
2926
|
+
continue;
|
|
2927
|
+
}
|
|
2928
|
+
positional.push(arg);
|
|
2929
|
+
}
|
|
2930
|
+
return { positional, rootArg };
|
|
2931
|
+
}
|
|
2932
|
+
|
|
2737
2933
|
export async function sourcesCommand(
|
|
2738
2934
|
argv: string[],
|
|
2739
2935
|
ctx: RemoteCommandContext = {}
|
|
@@ -3124,7 +3320,7 @@ export async function templatesCommand(
|
|
|
3124
3320
|
const [kind, ...args] = rest;
|
|
3125
3321
|
if (!kind) {
|
|
3126
3322
|
console.error(
|
|
3127
|
-
"templates init requires a kind (skill|mcp|agent|snippet|agents|claude|operating-model|project-ai|automation)"
|
|
3323
|
+
"templates init requires a kind (skill|mcp|agent|instruction|snippet|agents|claude|operating-model|project-ai|automation)"
|
|
3128
3324
|
);
|
|
3129
3325
|
process.exitCode = 2;
|
|
3130
3326
|
return;
|
|
@@ -3132,7 +3328,8 @@ export async function templatesCommand(
|
|
|
3132
3328
|
const dryRun = args.includes("--dry-run");
|
|
3133
3329
|
const force = args.includes("--force");
|
|
3134
3330
|
const json = args.includes("--json");
|
|
3135
|
-
const
|
|
3331
|
+
const parsedArgs = parseTemplateInitArgs(args);
|
|
3332
|
+
const positional = parsedArgs.positional;
|
|
3136
3333
|
|
|
3137
3334
|
if (kind === "project-ai") {
|
|
3138
3335
|
try {
|
|
@@ -3244,6 +3441,14 @@ export async function templatesCommand(
|
|
|
3244
3441
|
as = normalizedName.endsWith(".toml")
|
|
3245
3442
|
? normalizedName
|
|
3246
3443
|
: `${normalizedName}/agent.toml`;
|
|
3444
|
+
} else if (kind === "instruction") {
|
|
3445
|
+
ref = `${BUILTIN_INDEX_NAME}:instruction-template`;
|
|
3446
|
+
as = positional[0];
|
|
3447
|
+
if (!as) {
|
|
3448
|
+
console.error("templates init instruction requires a <name>");
|
|
3449
|
+
process.exitCode = 2;
|
|
3450
|
+
return;
|
|
3451
|
+
}
|
|
3247
3452
|
} else if (kind === "snippet") {
|
|
3248
3453
|
ref = `${BUILTIN_INDEX_NAME}:snippet-template`;
|
|
3249
3454
|
as = positional[0];
|
|
@@ -3353,7 +3558,7 @@ export async function templatesCommand(
|
|
|
3353
3558
|
dryRun,
|
|
3354
3559
|
force,
|
|
3355
3560
|
homeDir: ctx.homeDir,
|
|
3356
|
-
rootDir: ctx.rootDir,
|
|
3561
|
+
rootDir: parsedArgs.rootArg ?? ctx.rootDir,
|
|
3357
3562
|
cwd: ctx.cwd,
|
|
3358
3563
|
fetchJson: ctx.fetchJson,
|
|
3359
3564
|
fetchText: ctx.fetchText,
|