@ai-outfitter/outfitter 1.0.3 → 1.1.1

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.
Files changed (59) hide show
  1. package/.outfitter/skills/outfitter/SKILL.md +1 -1
  2. package/README.md +1 -1
  3. package/code/enterprise/cli/privateCatalogGate.cjs +3 -3
  4. package/dist/cli/OutfitterCli.js +2 -0
  5. package/dist/cli/OutfitterCli.js.map +1 -1
  6. package/dist/cli/commands/DumpCommand.js +8 -3
  7. package/dist/cli/commands/DumpCommand.js.map +1 -1
  8. package/dist/cli/commands/ListCommand.js +4 -3
  9. package/dist/cli/commands/ListCommand.js.map +1 -1
  10. package/dist/cli/commands/PiRuntimeLaunch.js +3 -16
  11. package/dist/cli/commands/PiRuntimeLaunch.js.map +1 -1
  12. package/dist/cli/commands/RunAgentCommand.js +1 -0
  13. package/dist/cli/commands/RunAgentCommand.js.map +1 -1
  14. package/dist/cli/commands/SetupCommand.d.ts +1 -1
  15. package/dist/cli/commands/SetupCommand.js +6 -13
  16. package/dist/cli/commands/SetupCommand.js.map +1 -1
  17. package/dist/cli/commands/SyncCommand.d.ts +31 -0
  18. package/dist/cli/commands/SyncCommand.js +162 -0
  19. package/dist/cli/commands/SyncCommand.js.map +1 -0
  20. package/dist/cli/commands/ValidateCommand.js +4 -2
  21. package/dist/cli/commands/ValidateCommand.js.map +1 -1
  22. package/dist/paths/RepositoryAssets.d.ts +4 -0
  23. package/dist/paths/RepositoryAssets.js +26 -0
  24. package/dist/paths/RepositoryAssets.js.map +1 -0
  25. package/dist/resolver/Layer.d.ts +17 -1
  26. package/dist/resolver/Layer.js +23 -15
  27. package/dist/resolver/Layer.js.map +1 -1
  28. package/dist/resolver/ResolverContext.d.ts +2 -0
  29. package/dist/resolver/ResolverContext.js +7 -2
  30. package/dist/resolver/ResolverContext.js.map +1 -1
  31. package/dist/settings/SettingsLoader.d.ts +12 -3
  32. package/dist/settings/SettingsLoader.js +25 -11
  33. package/dist/settings/SettingsLoader.js.map +1 -1
  34. package/dist/setup/DefaultCatalog.d.ts +3 -2
  35. package/dist/setup/DefaultCatalog.js +26 -51
  36. package/dist/setup/DefaultCatalog.js.map +1 -1
  37. package/dist/sources/GitRepository.d.ts +28 -0
  38. package/dist/sources/GitRepository.js +139 -0
  39. package/dist/sources/GitRepository.js.map +1 -0
  40. package/dist/sources/PrivateCatalogGate.d.ts +27 -0
  41. package/dist/sources/PrivateCatalogGate.js +23 -0
  42. package/dist/sources/PrivateCatalogGate.js.map +1 -0
  43. package/dist/sources/SourceCache.d.ts +11 -1
  44. package/dist/sources/SourceCache.js +11 -2
  45. package/dist/sources/SourceCache.js.map +1 -1
  46. package/docs/documentation/README.md +2 -2
  47. package/docs/documentation/catalogs.md +10 -2
  48. package/docs/documentation/cli.md +12 -4
  49. package/docs/documentation/concepts.md +1 -1
  50. package/docs/documentation/conventions.md +10 -0
  51. package/docs/documentation/getting-started.md +1 -1
  52. package/docs/documentation/personas.md +28 -27
  53. package/docs/documentation/profiles.md +1 -1
  54. package/docs/documentation/settings.md +4 -2
  55. package/docs/documentation/skills.md +2 -2
  56. package/docs/documentation/usecases/engineering.md +1 -1
  57. package/docs/documentation/usecases/organization-profile-catalog.md +1 -1
  58. package/docs/documentation/usecases/persona-reviews.md +90 -139
  59. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitRepository.js","sourceRoot":"","sources":["../../src/sources/GitRepository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { RemoteSourceReference } from './SourceCache.js';
2
+ export interface GitHubRepositoryVisibilityClassifier {
3
+ classify(repository: string): 'private' | 'public' | 'unknown';
4
+ }
5
+ export interface PrivateCatalogPrompt {
6
+ readonly interactive: boolean;
7
+ confirm(repository: string): boolean;
8
+ }
9
+ export interface PrivateCatalogSkippedResult {
10
+ readonly uri: string;
11
+ readonly cachePath: string;
12
+ readonly status: 'skipped';
13
+ readonly message: string;
14
+ }
15
+ export interface PrivateCatalogGateResult<T extends RemoteSourceReference> {
16
+ readonly allowedSources: readonly T[];
17
+ readonly skippedResults: readonly PrivateCatalogSkippedResult[];
18
+ readonly messages: readonly string[];
19
+ }
20
+ export interface PrivateCatalogSourceGate {
21
+ filter<T extends RemoteSourceReference>(sources: readonly T[], cacheDirectory?: string): PrivateCatalogGateResult<T>;
22
+ }
23
+ export declare const createEnterprisePrivateCatalogGate: (input: {
24
+ readonly homeDirectory: string;
25
+ readonly classifier?: GitHubRepositoryVisibilityClassifier;
26
+ readonly prompt?: PrivateCatalogPrompt;
27
+ }) => PrivateCatalogSourceGate;
@@ -0,0 +1,23 @@
1
+ // Loads the enterprise-licensed private-catalog policy boundary for CLI source synchronization.
2
+ import { createRequire } from 'node:module';
3
+ import { resolveRepositoryCodeAsset } from '../paths/RepositoryAssets.js';
4
+ import { createRemoteRepositoryCachePath, formatRemoteSourceDisplay } from './SourceCache.js';
5
+ const loadEnterpriseGateModule = () => createRequire(import.meta.url)(resolveRepositoryCodeAsset('enterprise/cli/privateCatalogGate.cjs'));
6
+ export const createEnterprisePrivateCatalogGate = (input) => {
7
+ const enterprise = loadEnterpriseGateModule();
8
+ const { homeDirectory } = input;
9
+ const gate = enterprise.createPrivateCatalogGate({
10
+ homeDirectory,
11
+ classifier: input.classifier ?? enterprise.createGitHubRepositoryVisibilityClassifier(),
12
+ prompt: input.prompt,
13
+ });
14
+ return {
15
+ filter(sources, cacheDirectory) {
16
+ return enterprise.gatePrivateCatalogSources(sources, gate, {
17
+ formatDisplayUri: formatRemoteSourceDisplay,
18
+ resolveCachePath: (source) => createRemoteRepositoryCachePath(homeDirectory, source, cacheDirectory),
19
+ });
20
+ },
21
+ };
22
+ };
23
+ //# sourceMappingURL=PrivateCatalogGate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrivateCatalogGate.js","sourceRoot":"","sources":["../../src/sources/PrivateCatalogGate.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAChG,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE1E,OAAO,EAAE,+BAA+B,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AA6C9F,MAAM,wBAAwB,GAAG,GAAyB,EAAE,CAC1D,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAC5B,0BAA0B,CAAC,uCAAuC,CAAC,CAC5C,CAAC;AAE5B,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,KAIlD,EAA4B,EAAE;IAC7B,MAAM,UAAU,GAAG,wBAAwB,EAAE,CAAC;IAC9C,MAAM,EAAE,aAAa,EAAE,GAAG,KAAK,CAAC;IAChC,MAAM,IAAI,GAAG,UAAU,CAAC,wBAAwB,CAAC;QAC/C,aAAa;QACb,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,UAAU,CAAC,0CAA0C,EAAE;QACvF,MAAM,EAAE,KAAK,CAAC,MAAM;KACrB,CAAC,CAAC;IAEH,OAAO;QACL,MAAM,CACJ,OAAqB,EACrB,cAAuB;YAEvB,OAAO,UAAU,CAAC,yBAAyB,CAAC,OAAO,EAAE,IAAI,EAAE;gBACzD,gBAAgB,EAAE,yBAAyB;gBAC3C,gBAAgB,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,+BAA+B,CAAC,aAAa,EAAE,MAAM,EAAE,cAAc,CAAC;aACrG,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC,CAAC"}
@@ -10,10 +10,20 @@ export type RemoteSourceReference = {
10
10
  readonly ref?: string;
11
11
  readonly path?: string;
12
12
  };
13
+ /** Distinguishes remote (`uri`/`github`) sources from local `path` sources. */
14
+ export declare const isRemoteSource: <T extends {
15
+ readonly uri?: string;
16
+ readonly github?: string;
17
+ }>(source: T) => source is T & RemoteSourceReference;
13
18
  export declare const normalizeGitUri: (uri: string) => string;
14
19
  export declare const normalizeRemoteSourceUri: (source: RemoteSourceReference) => string;
20
+ export declare const formatRemoteSourceDisplay: (source: RemoteSourceReference) => string;
15
21
  export declare const redactSourceUriCredentials: (uri: string) => string;
22
+ /** Redacts credentials from every URI embedded in arbitrary command or stderr text. */
23
+ export declare const redactEmbeddedSourceCredentials: (value: string) => string;
16
24
  export declare const encodeSourceUri: (uri: string) => string;
17
25
  export declare const encodeRemoteSource: (source: RemoteSourceReference) => string;
18
- export declare const createRemoteRepositoryCachePath: (homeDirectory: string, source: RemoteSourceReference) => string;
26
+ /** Resolves the one cache root used by sync, settings, layer discovery, and setup bootstrap. */
27
+ export declare const resolveRemoteRepositoryCacheRoot: (homeDirectory: string, cacheDirectory?: string) => string;
28
+ export declare const createRemoteRepositoryCachePath: (homeDirectory: string, source: RemoteSourceReference, cacheDirectory?: string) => string;
19
29
  export declare const resolveRemoteRepositorySubpath: (repositoryPath: string, subpath?: string) => string;
@@ -1,5 +1,7 @@
1
1
  // Encodes remote `.agents` source cache paths and normalizes remote source references.
2
2
  import { isAbsolute, join, relative, resolve } from 'node:path';
3
+ /** Distinguishes remote (`uri`/`github`) sources from local `path` sources. */
4
+ export const isRemoteSource = (source) => source.uri !== undefined || source.github !== undefined;
3
5
  export const normalizeGitUri = (uri) => (uri.startsWith('git+') ? uri.slice('git+'.length) : uri);
4
6
  export const normalizeRemoteSourceUri = (source) => {
5
7
  if (source.uri !== undefined) {
@@ -7,6 +9,9 @@ export const normalizeRemoteSourceUri = (source) => {
7
9
  }
8
10
  return `git+https://github.com/${source.github}.git`;
9
11
  };
12
+ export const formatRemoteSourceDisplay = (source) => source.github === undefined
13
+ ? redactSourceUriCredentials(source.uri)
14
+ : `github:${source.github}${source.ref === undefined ? '' : `#${source.ref}`}`;
10
15
  export const redactSourceUriCredentials = (uri) => {
11
16
  const prefix = uri.startsWith('git+') ? 'git+' : '';
12
17
  const normalizedUri = normalizeGitUri(uri);
@@ -20,12 +25,16 @@ export const redactSourceUriCredentials = (uri) => {
20
25
  return `${prefix}${parsedUri.toString()}`;
21
26
  }
22
27
  catch {
23
- return uri.replace(/\/\/[^/@\s]+@/u, '//REDACTED@');
28
+ return uri.replace(/\/\/[^/@\s]+@/gu, '//REDACTED@');
24
29
  }
25
30
  };
31
+ /** Redacts credentials from every URI embedded in arbitrary command or stderr text. */
32
+ export const redactEmbeddedSourceCredentials = (value) => value.replace(/((?:git\+)?[A-Za-z][A-Za-z0-9+.-]*:\/\/)[^/@\s]+@/gu, '$1REDACTED@');
26
33
  export const encodeSourceUri = (uri) => Buffer.from(redactSourceUriCredentials(uri), 'utf8').toString('base64url');
27
34
  export const encodeRemoteSource = (source) => encodeSourceUri(`${normalizeRemoteSourceUri(source)}#${source.ref ?? ''}`);
28
- export const createRemoteRepositoryCachePath = (homeDirectory, source) => join(homeDirectory, '.agents', 'cache', 'repos', encodeRemoteSource(source));
35
+ /** Resolves the one cache root used by sync, settings, layer discovery, and setup bootstrap. */
36
+ export const resolveRemoteRepositoryCacheRoot = (homeDirectory, cacheDirectory) => cacheDirectory ?? join(homeDirectory, '.agents', 'cache');
37
+ export const createRemoteRepositoryCachePath = (homeDirectory, source, cacheDirectory) => join(resolveRemoteRepositoryCacheRoot(homeDirectory, cacheDirectory), 'repos', encodeRemoteSource(source));
29
38
  export const resolveRemoteRepositorySubpath = (repositoryPath, subpath = '') => {
30
39
  if (isAbsolute(subpath)) {
31
40
  throw new Error(`Remote repository path '${subpath}' must be relative.`);
@@ -1 +1 @@
1
- {"version":3,"file":"SourceCache.js","sourceRoot":"","sources":["../../src/sources/SourceCache.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOhE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAAU,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAElH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,MAA6B,EAAU,EAAE;IAChF,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,MAAM,CAAC,GAAG,CAAC;IACpB,CAAC;IAED,OAAO,0BAA0B,MAAM,CAAC,MAAM,MAAM,CAAC;AACvD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,GAAW,EAAU,EAAE;IAChE,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACpD,MAAM,aAAa,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAE3C,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC;QAEzC,IAAI,SAAS,CAAC,QAAQ,KAAK,EAAE,IAAI,SAAS,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;YAC3D,OAAO,GAAG,CAAC;QACb,CAAC;QAED,SAAS,CAAC,QAAQ,GAAG,UAAU,CAAC;QAChC,SAAS,CAAC,QAAQ,GAAG,EAAE,CAAC;QACxB,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC,OAAO,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;IACtD,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAAU,EAAE,CACrD,MAAM,CAAC,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAA6B,EAAU,EAAE,CAC1E,eAAe,CAAC,GAAG,wBAAwB,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,aAAqB,EAAE,MAA6B,EAAU,EAAE,CAC9G,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,cAAsB,EAAE,OAAO,GAAG,EAAE,EAAU,EAAE;IAC7F,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,2BAA2B,OAAO,qBAAqB,CAAC,CAAC;IAC3E,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,QAAQ,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;IAE5D,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACxF,MAAM,IAAI,KAAK,CAAC,2BAA2B,OAAO,oCAAoC,CAAC,CAAC;IAC1F,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC,CAAC"}
1
+ {"version":3,"file":"SourceCache.js","sourceRoot":"","sources":["../../src/sources/SourceCache.ts"],"names":[],"mappings":"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"}
@@ -15,7 +15,7 @@ Outfitter lays out conventions for iterating on and sharing agent configuration
15
15
  - [Agents](./agents.md) — the `agents/<id>/agent.md` resource and its loadout — what you run.
16
16
  - [Agent profiles](./profiles.md) — why an agent and its loadout _is_ the profile.
17
17
  - [Skills](./skills.md) — capability packages with progressive disclosure, references, and routing.
18
- - [Personas](./personas.md) — the base-agent-plus-persona-documents review convention.
18
+ - [Personas](./personas.md) — one portable Markdown file per persona; append at launch or paste anywhere.
19
19
  - [Subagents and delegation](./subagents.md) — the four delegation boundaries, from in-session helpers to Kubernetes Jobs.
20
20
  - [Settings](./settings.md) — scopes, schema, and the flat `settings.local.yml` override file.
21
21
  - [Tasks](./tasks.md) — placeholder for a separate upcoming RFC.
@@ -49,7 +49,7 @@ Each use case is a worked story — a problem, the composition that answers it,
49
49
  - [Grafana alert investigations in-cluster](./usecases/grafana-alert-investigator.md) — a webhook turns each firing alert into one bounded investigation Job.
50
50
  - [Self-improving skills](./usecases/self-improving-skills.md) — a weekly loop that proposes skill edits and ships only measured improvements.
51
51
  - [Resident agents: a researcher wiki](./usecases/resident-agents.md) — a long-lived agent that turns an email inbox into a compounding, reviewable knowledge base.
52
- - [Persona reviews](./usecases/persona-reviews.md) — a base review agent plus customer-persona documents for feedback on ideas, docs, and designs.
52
+ - [Persona reviews](./usecases/persona-reviews.md) — author one persona file, run it through the shared reviewer, paste the same file into any web agent.
53
53
  - [Organization catalog](./usecases/organization-profile-catalog.md) — publish shared org resources and defaults through an `owner/.outfitter` control repository.
54
54
  - [Engineering catalog](./usecases/engineering.md) — package engineering agents and skills for repeatable workflows.
55
55
 
@@ -101,11 +101,19 @@ Remote settings are cached locally and merged at lower precedence than your proj
101
101
 
102
102
  `outfitter sync` synchronizes every remote source into the local cache:
103
103
 
104
- 1. Remote settings repositories are cloned or updated first, then reloaded.
104
+ 1. Local settings are validated. Remote settings repositories are cloned or updated first, then
105
+ merged settings are reloaded.
105
106
  2. Remote sources (including any added by remote settings) are cloned or updated.
106
107
  3. Each synced source is validated; sync reports `updated`, `unchanged`, `skipped`, or `failed` per source.
107
108
 
108
- Pinned (`ref:`) sources stay on their pinned ref until you change it; unpinned sources fast-forward on every sync.
109
+ All repositories live under `<cache_directory>/repos/<encoded-uri-and-ref>/` (default
110
+ `~/.agents/cache`). Pinned (`ref:`) sources stay on their selected ref until you change it; unpinned
111
+ sources resolve the remote's current default branch on every sync.
112
+
113
+ Fetch and validation happen in a temporary sibling directory. Outfitter swaps a valid checkout into
114
+ place atomically, so a failed fetch or invalid update preserves the last working cache. A required
115
+ source failure makes sync exit nonzero. `outfitter run` remains offline with respect to source
116
+ synchronization; run sync explicitly when you want network updates.
109
117
 
110
118
  ## Private repositories
111
119
 
@@ -1,7 +1,5 @@
1
1
  # CLI reference
2
2
 
3
- > **Status: RFC [#165](https://github.com/ai-outfitter/outfitter/issues/165) target.** This reference describes the dotagents end-state command surface. The currently released CLI still implements the legacy profile commands; implementation PRs replace them incrementally.
4
-
5
3
  Global options:
6
4
 
7
5
  | Option | Description |
@@ -23,7 +21,7 @@ Any other arguments and unrecognized options are passed through to the launched
23
21
 
24
22
  ```bash
25
23
  outfitter run engineer --harness claude
26
- outfitter run reviewer -- --print "summarize this repo"
24
+ outfitter run persona-reviewer -- --print "summarize this repo"
27
25
  ```
28
26
 
29
27
  ## `outfitter setup [source]`
@@ -41,7 +39,17 @@ fallback.
41
39
 
42
40
  ## `outfitter sync`
43
41
 
44
- Synchronize remote sources and remote settings into the local cache. Reports a per-source status of `updated`, `unchanged`, `skipped`, or `failed`, and validates synced sources.
42
+ Synchronize remote sources and remote settings into the local cache. Sync validates local settings,
43
+ updates `remote_settings`, reloads the merged settings, and then updates the remote `sources` that
44
+ result. Each repository reports `updated`, `unchanged`, `skipped`, or `failed`.
45
+
46
+ Fetched content is validated in a temporary checkout before an atomic cache swap, so a failed fetch
47
+ or invalid update leaves the last valid cache available. Required-source failures and invalid
48
+ settings exit nonzero. Credentials embedded in URIs are redacted from status, errors, cache paths,
49
+ and Git output.
50
+
51
+ Sync is explicit: `outfitter run` never initiates network access. If a configured cache is absent,
52
+ resolution tells you to run `outfitter sync`.
45
53
 
46
54
  ## `outfitter list [kind]`
47
55
 
@@ -49,7 +49,7 @@ The protocol resources Outfitter resolves and composes:
49
49
  Three related terms, none of which is a settings key or a separate file format:
50
50
 
51
51
  - A **[profile](./profiles.md)** is just an agent and its loadout. "The engineer profile" is the `engineer` agent with everything it composes. There is no `profile.yml` and no `profiles:` map — the loadout lives on the agent.
52
- - A **[persona](./personas.md)** is a _convention_, not a resource: a base review agent (a base prompt plus how-to-review instructions) that reads an interchangeable persona description document — for example `docs/user-personas/coyote-road-runner-chaser.md` — as input. Swapping the input document swaps the persona.
52
+ - A **[persona](./personas.md)** is a _convention_, not a resource: one portable, committed Markdown document per persona — for example `docs/personas/platform-lead.md` — appended at launch to a shared review agent, or pasted into any tool as stakeholder context. Swapping the file swaps the persona.
53
53
  - A **[subagent](./subagents.md)** is an agent projected into the harness's native delegation mechanism, selected in another agent's `subagents` loadout. A leader agent delegates to local coding-harness subagents or to issue- and action-backed subagents.
54
54
 
55
55
  The same agent definition can be run directly or selected as a subagent elsewhere; its loadout decides what it composes.
@@ -50,6 +50,16 @@ The same convention builds a role-scoped profile — a `platform` or `marketing`
50
50
  - **Bespoke per org two ways:** as a [subagent](./subagents.md) other agents delegate role work to, or via one org-specific skill (a `brand` or `platform` skill) carrying the values — endpoints, voice, RBAC — that make the shared profile bespoke without duplicating it.
51
51
  - **Role separation is the point.** An engineer or a marketer doesn't want the other's machinery in context; they work in their own lane and delegate across lanes when needed. Cross-cutting work stays _available_ through inheritance and delegation, not by stuffing every profile.
52
52
 
53
+ ## Worked example: persona documents
54
+
55
+ The [persona convention](./personas.md) applies the same rule to a non-technical contribution: contributing a persona means committing one Markdown file — no loadout involved.
56
+
57
+ - **Community layer supplies the machinery** — the shared `persona-reviewer` agent and the `persona-authoring` / `persona-review` skills ship once, in [`community-profiles`](https://github.com/ai-outfitter/community-profiles).
58
+ - **The project layer holds only the files** — a marketer or founder authors `docs/personas/platform-lead.md` (with `persona-authoring` interviewing them, or from the template by hand) and commits it as ordinary project documentation. No agent, no YAML, no `.agents` entry.
59
+ - **Never copy** — a tenth persona is a tenth file, not a tenth reviewer. The same file also pastes unchanged into web agents as stakeholder context, so it is not tied to any one harness.
60
+
61
+ The full story is the [Persona reviews use case](./usecases/persona-reviews.md).
62
+
53
63
  ## Roadmap: a shareable prompt fragment
54
64
 
55
65
  Today the always-on vehicle is a tree's root `agents.md` / `system-prompt.md` — one file per layer. It inherits and overrides _per layer_, but you cannot yet publish one named fragment from a community catalog and override just that fragment by ID. A first-class, slug-composable shared prompt fragment is the missing primitive; until it lands, a single line per layer's shared context still deduplicates by inheritance — just not as a publishable unit. [Hooks](./hooks.md) carry the analogous gap for portable hook definitions.
@@ -39,7 +39,7 @@ Learn how shared sources work in [Catalogs](./catalogs.md), then see [Agents](./
39
39
 
40
40
  ```bash
41
41
  outfitter run engineer
42
- outfitter run reviewer --harness claude
42
+ outfitter run persona-reviewer --harness claude
43
43
  outfitter sync
44
44
  outfitter list agents
45
45
  outfitter validate
@@ -1,41 +1,42 @@
1
1
  # Personas
2
2
 
3
- A persona is not a resource or a settings key — it is a **convention** built from ordinary pieces:
3
+ A persona is not a resource or a settings key — it is a convention built from ordinary pieces:
4
4
 
5
- 1. A **base review agent** — a normal [agent](./agents.md) whose prompt says how to review something (an app, docs, a UX flow): what to look at, what evidence to cite, what output shape to return.
6
- 2. Interchangeable **persona description documents** plain markdown files with attributes in frontmatter and a short bio underneath. They come in two kinds you **mix and match**: a **role** (a reusable job archetype — goals, anxieties, buying triggers shared across a customer segment) and an **individual** (a named person with demographics — birthdate, income, education, hobbies, skills — who inherits one or more roles and adds their own voice). Give each the concreteness a [Lean Canvas](https://leanstack.com/lean-canvas) customer segment gets.
5
+ 1. A **shared review agent** — [`persona-reviewer`](https://github.com/ai-outfitter/community-profiles/blob/main/agents/persona-reviewer/agent.md), a normal [agent](./agents.md) from the community catalog that selects the `persona-review` skill, which owns the review method and report shape. One reviewer serves all personas.
6
+ 2. **One committed Markdown file per persona** a portable, self-contained document. The whole persona lives in that one file; swapping the file swaps the persona, and the review rules stay fixed.
7
7
 
8
- You run the base agent and feed it the persona files to adopt: a role, refined by an individual. Swapping the files swaps the persona; the base agent — the review rules — stays fixed. Nothing new is added to the protocol: it is one agent plus a folder of description files. See [Persona reviews](./usecases/persona-reviews.md) for the full shape.
8
+ ## The format
9
+
10
+ A persona file is plain Markdown with no frontmatter and no schema:
11
+
12
+ - Starts directly with an H1 naming a **generic role archetype**: `# Platform Lead`, `# Founder-operator`. Use a named individual (`# Priya Nair — Platform Lead`) only when a specific person's voice is the point.
13
+ - First-person prose: an unheaded opening paragraph, then the recommended sections `## My work and context`, `## What I need`, `## How I decide`, and `## How I communicate`. Sections may be renamed or combined; connected prose beats bullet stacks.
14
+ - Everything the persona knows — role, goals, constraints, decision signals, voice — is ordinary Markdown.
15
+
16
+ It lives in normal project documentation, deliberately outside `.agents/`:
9
17
 
10
18
  ```text
11
- customer-review/
12
- agents/
13
- reviewer/agent.md # base: how to review, what to return
14
- settings.yml
15
- docs/user-personas/
16
- roles/ # reusable job archetypes
17
- staff-engineer.md
18
- founder-operator.md
19
- individuals/ # named people, each naming one or more roles
20
- marcus-bell.md
21
- dana-okafor.md
19
+ docs/personas/
20
+ platform-lead.md
21
+ founder-operator.md
22
22
  ```
23
23
 
24
- ## Why a convention, not a key
24
+ A persona is project steering context rather than agent configuration, which is why `outfitter dump` does not carry it. The authoring template and completed reference personas ship in the community catalog's [`persona-authoring`](https://github.com/ai-outfitter/community-profiles/tree/main/skills/persona-authoring) skill.
25
25
 
26
- Modeling personas as their own resource — or as a `personas:` list you compose in order — duplicates what an agent already is and grows the surface area of the system. Agents are exactly what that machinery was reaching for. Keeping personas as "base agent + description document" means a team maintains one review agent and a directory of cheap markdown files, instead of a fleet of near-identical agents.
26
+ ## Three ways to consume the same file
27
27
 
28
- ## Running a persona review
28
+ - **Appended at launch**: `outfitter run persona-reviewer -- --append-system-prompt docs/personas/platform-lead.md …` — the direct run is the underlying interface, and the reviewer adopts the file as its identity for that session only. An agent using the [`persona-review`](https://github.com/ai-outfitter/community-profiles/tree/main/skills/persona-review) skill can drive the same run in the background or synchronously and capture its report in a durable file. See [Persona reviews](./usecases/persona-reviews.md) for the runnable form of both.
29
+ - **Pasted into a web agent**: upload or paste the file unchanged into claude.ai project knowledge or a ChatGPT project as stakeholder context. Same artifact, zero conversion.
30
+ - **Ordinary reading context**: any agent doing product planning, research, or writing can read the file to know who the work is for.
29
31
 
30
- Point the base agent at the artifact and name the persona files to adopt — a role refined by an individual:
32
+ ## Why a convention, not a key
31
33
 
32
- ```bash
33
- outfitter run reviewer -- --print \
34
- "Adopt docs/user-personas/roles/founder-operator.md refined by \
35
- docs/user-personas/individuals/dana-okafor.md. Review README.md and \
36
- docs/getting-started.md and return the standard review shape."
37
- ```
34
+ Modeling personas as their own resource — or as a `personas:` list you compose in order — duplicates what an agent already is and grows the surface area of the system. Keeping personas as "shared agent + one document" means a team maintains one review agent and a directory of cheap Markdown files, instead of a fleet of near-identical agents or a runtime chain of fragments.
35
+
36
+ Organization research, interviews, and individual detail are **authoring inputs**, not committed schema: interview from them, keep research notes however you like, but the committed canonical artifact is always one self-contained role file. Do not invent demographics, income, or biography the research does not support, and never generate an Outfitter agent per persona.
37
+
38
+ ## Status
38
39
 
39
- Because the base agent fixes the output shape, feedback from different persona documents stays directly comparable.
40
+ Personas ride entirely on existing CLI behavior (`outfitter run` plus `--append-system-prompt` passthrough), so no `OFTR-*` requirement covers them. The reviewer runs as the selected agent; native Pi subagent projection is not a prerequisite. An `.agents`-native persona form (a protocol resource, or a settings layer pointing at persona documents) is a separate, deferred design; the portable file must never depend on it.
40
41
 
41
- See [Persona reviews](./usecases/persona-reviews.md) for a complete catalog example.
42
+ See [Persona reviews](./usecases/persona-reviews.md) for the worked author → run → paste-anywhere story, and the community catalog's [persona boundary doc](https://github.com/ai-outfitter/community-profiles/blob/main/docs/persona-review.md) for the setup and runtime responsibility split.
@@ -23,7 +23,7 @@ Settings ([settings.md](./settings.md)) is left with just resolution and launch
23
23
 
24
24
  ## Composing from a base
25
25
 
26
- To share behavior across several agents, keep shared operating context in the tree's `system-prompt.md` and `agents.md` — every agent in the tree inherits those — and put shared procedures in [skills](./skills.md) each agent selects. Selecting an agent as a subagent does _not_ share its policy; it only makes that agent available as a delegation target. The [persona](./personas.md) convention builds on the shared-context idea: one base review agent, many interchangeable persona description documents fed as input.
26
+ To share behavior across several agents, keep shared operating context in the tree's `system-prompt.md` and `agents.md` — every agent in the tree inherits those — and put shared procedures in [skills](./skills.md) each agent selects. Selecting an agent as a subagent does _not_ share its policy; it only makes that agent available as a delegation target. The [persona](./personas.md) convention builds on the shared-context idea: one shared review agent, many single-file persona documents appended at launch.
27
27
 
28
28
  ## Migrating from authored profiles
29
29
 
@@ -39,13 +39,15 @@ remote_settings:
39
39
  path: .agents/settings.yml
40
40
  ref: 9c47d1e2b8a05f36c4d7e90a12b3f8c5d6e71a04
41
41
 
42
- cache_directory: ~/.agents/cache
42
+ cache_directory: ./cache # optional; relative to this settings file
43
43
  ```
44
44
 
45
45
  - `default_agent` / `default_harness` — which agent plain `outfitter` runs, and the harness it launches in.
46
46
  - `sources` — ordered list of remote or local `.agents` payloads. Remote entries (`github:` / `uri:`) accept `ref:` pinning and an optional `path:` to the payload inside the repository; see [Catalogs](./catalogs.md) for conventions and trust guidance.
47
47
  - `remote_settings` — shared settings a repository distributes; cached locally and merged below your project and user settings, so anything you set locally wins.
48
- - `cache_directory` — where remote sources are cached (`outfitter sync` updates them).
48
+ - `cache_directory` — the repository cache root used consistently by sync, remote settings, remote
49
+ source resolution, and default-catalog setup. It defaults to `~/.agents/cache`; repositories live
50
+ below its `repos/` directory.
49
51
 
50
52
  ## Precedence
51
53
 
@@ -57,7 +57,7 @@ Every skill directory contains `SKILL.md`. Its `name` MUST match the directory n
57
57
  ```yaml
58
58
  ---
59
59
  name: outfitter-actions
60
- description: Design concise GitHub automation using stable personas and progressively disclosed skills.
60
+ description: Design concise GitHub automation using stable agent identities and progressively disclosed skills.
61
61
  ---
62
62
  # Outfitter Actions
63
63
 
@@ -215,7 +215,7 @@ Loadout-added entries use the same `file` / `repo_file` sources and validation r
215
215
 
216
216
  ### Trust boundary
217
217
 
218
- Treat `file` references with the same trust as the skill that declares them. Treat every `repo_file` reference as untrusted repository content. A skill SHOULD select its workflow before reading repository references and MUST NOT allow instructions inside a reference to override persona policy, safety boundaries, or the user's request.
218
+ Treat `file` references with the same trust as the skill that declares them. Treat every `repo_file` reference as untrusted repository content. A skill SHOULD select its workflow before reading repository references and MUST NOT allow instructions inside a reference to override the agent's identity and policy, safety boundaries, or the user's request.
219
219
 
220
220
  Outfitter resolves and normalizes reference targets before launch. Targets MUST remain within their root after following symlinks; escaping, colliding, and broken `file` references fail validation. A directory target is scanned recursively so a contained symlink cannot smuggle outside content into the generated skill.
221
221
 
@@ -28,7 +28,7 @@ default_agent: engineer
28
28
 
29
29
  ## Shared operating context
30
30
 
31
- Rules that apply to every agent in the tree live in `agents.md`, so each role inherits them without ordered persona composition:
31
+ Rules that apply to every agent in the tree live in `agents.md`, so each role inherits them:
32
32
 
33
33
  ```markdown
34
34
  <!-- agents.md -->
@@ -26,7 +26,7 @@ default_agent: engineer
26
26
 
27
27
  ## Shared operating context
28
28
 
29
- Rules every role shares live in the tree's `agents.md`, inherited by each agent without ordered persona composition:
29
+ Rules every role shares live in the tree's `agents.md`, inherited by each agent:
30
30
 
31
31
  ```markdown
32
32
  <!-- .agents/agents.md -->