pluribus-context 0.3.14 → 0.3.16
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/CHANGELOG.md +14 -0
- package/README.md +1 -1
- package/bin/pluribus.js +3 -1
- package/docs/portability-fidelity-report.md +95 -0
- package/examples/portability-fidelity/pluribus.md +56 -0
- package/package.json +1 -1
- package/schemas/audit-result.schema.json +78 -0
- package/src/commands/audit.js +114 -2
- package/src/utils/version.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@
|
|
|
4
4
|
|
|
5
5
|
All notable changes to Pluribus are documented here.
|
|
6
6
|
|
|
7
|
+
## 0.3.16 — audit fidelity evidence
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add `pluribus audit --fidelity-report` so maintainers can emit target-by-target portability evidence in JSON or human output: represented sections, unsupported sections, activation shape, warnings, and the next step before claiming a rule/skill bundle is universal.
|
|
12
|
+
- Update the portability fidelity report guide to use `audit --json --fidelity-report` as the reproducible evidence artifact for directory reviewers and rule/skill bundle maintainers.
|
|
13
|
+
|
|
14
|
+
## 0.3.15 — portability fidelity report demo
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Add a portability fidelity report guide and example for AI rule/skill bundle maintainers who need evidence-based compatibility claims across `CLAUDE.md`, Cursor, Copilot, and `AGENTS.md` outputs.
|
|
19
|
+
- Link the new report from the README so directory reviewers and skill/rule authors can test portability claims without treating `universal` as a self-attested boolean.
|
|
20
|
+
|
|
7
21
|
## 0.3.14 — coordination contract demo
|
|
8
22
|
|
|
9
23
|
### Added
|
package/README.md
CHANGED
|
@@ -152,7 +152,7 @@ npx --yes pluribus-context@latest sync --dry-run
|
|
|
152
152
|
|
|
153
153
|
If the preview looks right, run `npx --yes pluribus-context@latest sync` to write the tool-specific files.
|
|
154
154
|
|
|
155
|
-
For a fuller walkthrough, see the [Quickstart](docs/quickstart.md). To enforce generated context files in pull requests, use the [CI audit example](docs/ci-audit-example.md); to catch drift before commits leave your machine, use the [Pre-commit Audit Hook](docs/pre-commit-audit.md). If your repo already has `CLAUDE.md`, `.cursorrules`, Copilot instructions, or `AGENTS.md`, run a [Context Drift Audit](docs/context-drift-audit.md) first, try the intentionally drifted [audit example](examples/context-drift-audit/), then follow [Migrate Existing AI Context Files](docs/migrate-existing-context.md). If you switch between Cursor, Claude Code, Copilot, and terminal agents, try the [Cursor ↔ Claude Code context handoff guide](docs/cursor-claude-context-handoff.md) and its [example source file](examples/context-handoff/pluribus.md). If you run multiple AI sessions on the same project, try the [Coordination Contract guide](docs/coordination-contract.md) and its [example source file](examples/coordination-contract/pluribus.md) to keep event-log/scratchpad protocol rules aligned without turning Pluribus into an orchestrator. Before committing shared or generated AI instructions, use the [Context File Review Checklist](docs/context-file-review.md). If you're deciding between Pluribus and a one-way rules converter, see [When to use Pluribus](docs/when-to-use-pluribus.md). If you are debugging "context drift" after compaction or long sessions, start with the [Context Drift Taxonomy](docs/context-drift-taxonomy.md) to separate file drift from runtime precedence drift. If you use MCP memory or knowledge-graph tools, try the [MCP memory handoff demo](docs/memory-mcp-handoff.md) to keep recall/store protocols aligned across AI coding tools without turning Pluribus into a memory server. If you are reviewing Pluribus for a list, newsletter, or tool directory, use the [Community Review Packet](docs/community-review-packet.md) for directory submission fields, a one-line description, safety notes, and a disposable 60-second smoke test. Maintainers can track package/repo discovery with the [Discovery Smoke Checks](docs/discovery-smoke.md).
|
|
155
|
+
For a fuller walkthrough, see the [Quickstart](docs/quickstart.md). To enforce generated context files in pull requests, use the [CI audit example](docs/ci-audit-example.md); to catch drift before commits leave your machine, use the [Pre-commit Audit Hook](docs/pre-commit-audit.md). If your repo already has `CLAUDE.md`, `.cursorrules`, Copilot instructions, or `AGENTS.md`, run a [Context Drift Audit](docs/context-drift-audit.md) first, try the intentionally drifted [audit example](examples/context-drift-audit/), then follow [Migrate Existing AI Context Files](docs/migrate-existing-context.md). If you switch between Cursor, Claude Code, Copilot, and terminal agents, try the [Cursor ↔ Claude Code context handoff guide](docs/cursor-claude-context-handoff.md) and its [example source file](examples/context-handoff/pluribus.md). If you run multiple AI sessions on the same project, try the [Coordination Contract guide](docs/coordination-contract.md) and its [example source file](examples/coordination-contract/pluribus.md) to keep event-log/scratchpad protocol rules aligned without turning Pluribus into an orchestrator. If you publish AI rules, skills, or instruction bundles as "portable", use the [Portability Fidelity Report](docs/portability-fidelity-report.md) and its [example source file](examples/portability-fidelity/pluribus.md) to make compatibility claims evidence-based instead of self-attested. Before committing shared or generated AI instructions, use the [Context File Review Checklist](docs/context-file-review.md). If you're deciding between Pluribus and a one-way rules converter, see [When to use Pluribus](docs/when-to-use-pluribus.md). If you are debugging "context drift" after compaction or long sessions, start with the [Context Drift Taxonomy](docs/context-drift-taxonomy.md) to separate file drift from runtime precedence drift. If you use MCP memory or knowledge-graph tools, try the [MCP memory handoff demo](docs/memory-mcp-handoff.md) to keep recall/store protocols aligned across AI coding tools without turning Pluribus into a memory server. If you are reviewing Pluribus for a list, newsletter, or tool directory, use the [Community Review Packet](docs/community-review-packet.md) for directory submission fields, a one-line description, safety notes, and a disposable 60-second smoke test. Maintainers can track package/repo discovery with the [Discovery Smoke Checks](docs/discovery-smoke.md).
|
|
156
156
|
|
|
157
157
|
### Usage
|
|
158
158
|
|
package/bin/pluribus.js
CHANGED
|
@@ -55,6 +55,7 @@ OPTIONS (audit)
|
|
|
55
55
|
--json Print machine-readable audit results
|
|
56
56
|
--output Write --json results to a file instead of stdout
|
|
57
57
|
--github-annotations Print GitHub Actions annotations for drift/missing outputs
|
|
58
|
+
--fidelity-report Include portability/fidelity evidence for selected targets
|
|
58
59
|
|
|
59
60
|
OPTIONS (watch)
|
|
60
61
|
--source Path to pluribus.md (default: ./pluribus.md)
|
|
@@ -78,6 +79,7 @@ EXAMPLES
|
|
|
78
79
|
pluribus audit --json
|
|
79
80
|
pluribus audit --strict --json --output pluribus-audit.json
|
|
80
81
|
pluribus audit --strict --github-annotations
|
|
82
|
+
pluribus audit --json --fidelity-report
|
|
81
83
|
pluribus watch --tools claude,cursor
|
|
82
84
|
|
|
83
85
|
DOCS
|
|
@@ -88,7 +90,7 @@ const COMMAND_FLAGS = {
|
|
|
88
90
|
init: new Set(['name', 'description', 'tools', 'dry-run']),
|
|
89
91
|
sync: new Set(['dry-run', 'tools', 'source', 'update-imports']),
|
|
90
92
|
validate: new Set(['source', 'update-imports']),
|
|
91
|
-
audit: new Set(['source', 'tools', 'update-imports', 'strict', 'ci', 'json', 'output', 'github-annotations']),
|
|
93
|
+
audit: new Set(['source', 'tools', 'update-imports', 'strict', 'ci', 'json', 'output', 'github-annotations', 'fidelity-report']),
|
|
92
94
|
watch: new Set(['source', 'tools', 'update-imports', 'dry-run', 'once', 'debounce']),
|
|
93
95
|
}
|
|
94
96
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# Portability Fidelity Report
|
|
2
|
+
|
|
3
|
+
Use this when a rule pack, skill bundle, `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, or Copilot instruction file claims to be portable across AI coding tools.
|
|
4
|
+
|
|
5
|
+
The goal is not to prove that every tool behaves identically. The goal is to make portability claims falsifiable: which tools were tested, which capabilities are required, where semantics are lossy, and what evidence a reviewer can inspect.
|
|
6
|
+
|
|
7
|
+
This pattern came from live market signals around AI skills and rule bundles: authors want to mark instructions as "universal", but tool capabilities, file loading rules, write APIs, glob semantics, and security defaults differ enough that a boolean label can hide silent semantic loss.
|
|
8
|
+
|
|
9
|
+
## 60-second disposable check
|
|
10
|
+
|
|
11
|
+
Try the example without touching a real repo:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
git clone https://github.com/caioribeiroclw-pixel/pluribus.git
|
|
15
|
+
cd pluribus/examples/portability-fidelity
|
|
16
|
+
node ../../bin/pluribus.js validate
|
|
17
|
+
node ../../bin/pluribus.js sync --dry-run
|
|
18
|
+
node ../../bin/pluribus.js audit --json --fidelity-report
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For the npm release path, copy `examples/portability-fidelity/pluribus.md` into a temporary directory as `pluribus.md`, then run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx --yes pluribus-context@latest validate
|
|
25
|
+
npx --yes pluribus-context@latest sync --dry-run
|
|
26
|
+
npx --yes pluribus-context@latest audit --json --fidelity-report
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## What a claim should say
|
|
30
|
+
|
|
31
|
+
Avoid this:
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
portable: true
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Prefer claims that include evidence and known loss:
|
|
38
|
+
|
|
39
|
+
```yaml
|
|
40
|
+
portability:
|
|
41
|
+
tier: portable-with-adapters
|
|
42
|
+
testedOn:
|
|
43
|
+
- target: claude-code
|
|
44
|
+
evidence: generated CLAUDE.md smoke-reviewed on 2026-05-18
|
|
45
|
+
- target: cursor
|
|
46
|
+
evidence: generated .cursorrules smoke-reviewed on 2026-05-18
|
|
47
|
+
- target: github-copilot
|
|
48
|
+
evidence: generated .github/copilot-instructions.md smoke-reviewed on 2026-05-18
|
|
49
|
+
requiredCapabilities:
|
|
50
|
+
- read repository instructions before planning
|
|
51
|
+
- preserve generated-file warning
|
|
52
|
+
- respect security constraints before edits
|
|
53
|
+
knownLossyTargets:
|
|
54
|
+
- target: flat-markdown-targets
|
|
55
|
+
loss: cannot represent Cursor-style path/glob activation; keep scoped rules tool-native or annotate the loss
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
In Pluribus, keep that claim inside the source file so every generated output carries the same reviewable contract.
|
|
59
|
+
|
|
60
|
+
## Decision rule
|
|
61
|
+
|
|
62
|
+
A rule/skill/context bundle is portable only when a maintainer can answer four questions from the repo:
|
|
63
|
+
|
|
64
|
+
1. **Capability:** what does the instruction require from the target tool?
|
|
65
|
+
2. **Evidence:** where was that target actually rendered or smoke-tested?
|
|
66
|
+
3. **Loss:** which semantics are degraded, flattened, or unsupported?
|
|
67
|
+
4. **Fallback:** what should a user do when a target lacks the capability?
|
|
68
|
+
|
|
69
|
+
If any answer is missing, use a narrower label such as `project-local`, `target-native`, or `portable-with-loss` instead of `universal`.
|
|
70
|
+
|
|
71
|
+
## How Pluribus helps
|
|
72
|
+
|
|
73
|
+
Pluribus is intentionally narrower than a skill registry or memory layer:
|
|
74
|
+
|
|
75
|
+
- `pluribus.md` keeps the claim in one reviewed source of truth.
|
|
76
|
+
- `sync --dry-run` previews target-specific outputs before writing files.
|
|
77
|
+
- generated files carry a warning header so manual edits are visible.
|
|
78
|
+
- `audit --json --fidelity-report` gives CI/reviewers a machine-readable check for missing/drifted outputs plus target-by-target section loss, activation shape, and portability warnings.
|
|
79
|
+
- remote imports are opt-in, locked, cached, and digest-checked before becoming shared context.
|
|
80
|
+
|
|
81
|
+
That does **not** prove runtime behavior. You still need tool-specific smoke tests for load order, path/glob activation, available tools, MCP servers, and permission semantics.
|
|
82
|
+
|
|
83
|
+
## Suggested workflow for maintainers
|
|
84
|
+
|
|
85
|
+
1. Put the portability claim in the canonical source.
|
|
86
|
+
2. Generate target outputs with `sync --dry-run` and inspect semantic loss.
|
|
87
|
+
3. Keep target-native instructions when a semantic cannot be represented everywhere.
|
|
88
|
+
4. Commit a small audit artifact (`pluribus audit --json --fidelity-report --output reports/pluribus-audit.json`) when you want CI/review evidence.
|
|
89
|
+
5. Update the claim whenever a new target is added, a tool changes capability names, or a permission/security default changes.
|
|
90
|
+
|
|
91
|
+
## Feedback wanted
|
|
92
|
+
|
|
93
|
+
If your rule pack, skill bundle, or instruction manifest needs a different evidence shape, open a focused issue: https://github.com/caioribeiroclw-pixel/pluribus/issues/new
|
|
94
|
+
|
|
95
|
+
Do not paste private instructions, secrets, tokens, customer data, or proprietary source in public feedback.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<!-- pluribus:tools: claude,cursor,copilot,openclaw -->
|
|
2
|
+
|
|
3
|
+
# Identity
|
|
4
|
+
This repository publishes an AI rule or skill bundle that claims portability across Claude Code, Cursor, GitHub Copilot, and AGENTS.md-compatible coding agents.
|
|
5
|
+
|
|
6
|
+
The bundle should be treated as portable only when its required capabilities, tested targets, known lossy targets, and fallback behavior are visible in review.
|
|
7
|
+
|
|
8
|
+
# Stack
|
|
9
|
+
- Source format: Markdown rules/skills maintained in git.
|
|
10
|
+
- Generated targets: `CLAUDE.md`, `.cursorrules`, `.github/copilot-instructions.md`, and `AGENTS.md`.
|
|
11
|
+
- Review command: `npx --yes pluribus-context@latest sync --dry-run`.
|
|
12
|
+
- Drift command: `npx --yes pluribus-context@latest audit --json`.
|
|
13
|
+
|
|
14
|
+
# Conventions
|
|
15
|
+
- Do not use `universal` as a boolean portability claim.
|
|
16
|
+
- Describe portability as claims with evidence: tier, tested targets, required capabilities, project assumptions, known lossy targets, and fallback behavior.
|
|
17
|
+
- Treat `project-local` and `portable-with-loss` as honest labels, not failures.
|
|
18
|
+
- Keep target-native rules when a target has semantics that flat Markdown cannot preserve, such as path/glob activation or manual attachment behavior.
|
|
19
|
+
- When converting between tool formats, never silently drop security constraints, generated-file warnings, required read-before-plan steps, or scoped-rule metadata.
|
|
20
|
+
|
|
21
|
+
## Portability claim
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
portability:
|
|
25
|
+
tier: portable-with-adapters
|
|
26
|
+
testedOn:
|
|
27
|
+
- target: claude-code
|
|
28
|
+
evidence: generated CLAUDE.md smoke-reviewed
|
|
29
|
+
- target: cursor
|
|
30
|
+
evidence: generated .cursorrules smoke-reviewed
|
|
31
|
+
- target: github-copilot
|
|
32
|
+
evidence: generated .github/copilot-instructions.md smoke-reviewed
|
|
33
|
+
- target: agents-md
|
|
34
|
+
evidence: generated AGENTS.md smoke-reviewed
|
|
35
|
+
requiredCapabilities:
|
|
36
|
+
- load repository instructions before planning
|
|
37
|
+
- preserve generated-file warning
|
|
38
|
+
- expose security constraints before edits
|
|
39
|
+
knownLossyTargets:
|
|
40
|
+
- target: flat-markdown-targets
|
|
41
|
+
loss: cannot express Cursor-style path/glob activation without annotation
|
|
42
|
+
fallback:
|
|
43
|
+
- if a target cannot represent scoped activation, keep that scoped rule in the target-native file and document the loss
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
# Goals
|
|
47
|
+
1. Make portability claims falsifiable before users copy a rule pack into production.
|
|
48
|
+
2. Give maintainers a reviewable report of which targets were generated and where semantics may be lossy.
|
|
49
|
+
3. Help directory/list reviewers distinguish real multi-tool support from self-attested compatibility.
|
|
50
|
+
4. Keep one canonical source for shared claims while preserving target-native files for semantics that do not round-trip.
|
|
51
|
+
|
|
52
|
+
# Constraints
|
|
53
|
+
- Do not expose tokens, private instructions, customer data, internal paths, or proprietary source when reporting portability evidence.
|
|
54
|
+
- Do not claim that generated Markdown proves runtime load order, model behavior, permission mapping, MCP availability, or path/glob precedence.
|
|
55
|
+
- Do not flatten tool-specific security or activation semantics into a generic target without a visible fidelity warning.
|
|
56
|
+
- Do not replace human review of rule/skill substance with a passing sync or audit check.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pluribus-context",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.16",
|
|
4
4
|
"description": "AI context/rules sync for CLAUDE.md, Claude Code, Cursor rules, Copilot instructions, OpenClaw, Windsurf, Continue, and Zed.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://github.com/caioribeiroclw-pixel/pluribus#readme",
|
|
@@ -68,6 +68,10 @@
|
|
|
68
68
|
"type": "string",
|
|
69
69
|
"format": "uri",
|
|
70
70
|
"description": "Issue template URL for reporting audit false positives, noisy output, or confusing next steps."
|
|
71
|
+
},
|
|
72
|
+
"fidelityReport": {
|
|
73
|
+
"$ref": "#/$defs/fidelityReport",
|
|
74
|
+
"description": "Optional portability/fidelity evidence emitted by `pluribus audit --fidelity-report`."
|
|
71
75
|
}
|
|
72
76
|
},
|
|
73
77
|
"allOf": [
|
|
@@ -92,6 +96,80 @@
|
|
|
92
96
|
],
|
|
93
97
|
"additionalProperties": false,
|
|
94
98
|
"$defs": {
|
|
99
|
+
"fidelityReport": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"required": ["claim", "sourceSections", "targets", "summary", "warnings", "nextStep"],
|
|
102
|
+
"properties": {
|
|
103
|
+
"claim": { "type": "string" },
|
|
104
|
+
"sourceSections": {
|
|
105
|
+
"type": "array",
|
|
106
|
+
"items": { "type": "string" }
|
|
107
|
+
},
|
|
108
|
+
"targets": {
|
|
109
|
+
"type": "array",
|
|
110
|
+
"items": { "$ref": "#/$defs/fidelityTarget" }
|
|
111
|
+
},
|
|
112
|
+
"summary": {
|
|
113
|
+
"type": "object",
|
|
114
|
+
"required": ["targetCount", "targetsWithUnsupportedSections", "warningCount"],
|
|
115
|
+
"properties": {
|
|
116
|
+
"targetCount": { "type": "integer", "minimum": 0 },
|
|
117
|
+
"targetsWithUnsupportedSections": { "type": "integer", "minimum": 0 },
|
|
118
|
+
"warningCount": { "type": "integer", "minimum": 0 }
|
|
119
|
+
},
|
|
120
|
+
"additionalProperties": false
|
|
121
|
+
},
|
|
122
|
+
"warnings": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"items": { "$ref": "#/$defs/fidelityWarning" }
|
|
125
|
+
},
|
|
126
|
+
"nextStep": { "type": "string" }
|
|
127
|
+
},
|
|
128
|
+
"additionalProperties": false
|
|
129
|
+
},
|
|
130
|
+
"fidelityTarget": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"required": ["toolId", "files", "activation", "representedSections", "unsupportedSections"],
|
|
133
|
+
"properties": {
|
|
134
|
+
"toolId": { "type": "string" },
|
|
135
|
+
"files": {
|
|
136
|
+
"type": "array",
|
|
137
|
+
"items": { "type": "string" }
|
|
138
|
+
},
|
|
139
|
+
"activation": { "$ref": "#/$defs/fidelityActivation" },
|
|
140
|
+
"representedSections": {
|
|
141
|
+
"type": "array",
|
|
142
|
+
"items": { "type": "string" }
|
|
143
|
+
},
|
|
144
|
+
"unsupportedSections": {
|
|
145
|
+
"type": "array",
|
|
146
|
+
"items": { "type": "string" }
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
"additionalProperties": false
|
|
150
|
+
},
|
|
151
|
+
"fidelityActivation": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"required": ["kind", "evidence"],
|
|
154
|
+
"properties": {
|
|
155
|
+
"kind": { "type": "string" },
|
|
156
|
+
"evidence": {
|
|
157
|
+
"type": "array",
|
|
158
|
+
"items": { "type": "string" }
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
"additionalProperties": false
|
|
162
|
+
},
|
|
163
|
+
"fidelityWarning": {
|
|
164
|
+
"type": "object",
|
|
165
|
+
"required": ["code", "target", "message"],
|
|
166
|
+
"properties": {
|
|
167
|
+
"code": { "type": "string" },
|
|
168
|
+
"target": { "type": "string" },
|
|
169
|
+
"message": { "type": "string" }
|
|
170
|
+
},
|
|
171
|
+
"additionalProperties": false
|
|
172
|
+
},
|
|
95
173
|
"result": {
|
|
96
174
|
"type": "object",
|
|
97
175
|
"required": ["toolId", "status", "file"],
|
package/src/commands/audit.js
CHANGED
|
@@ -38,6 +38,7 @@ export async function runAudit(args) {
|
|
|
38
38
|
const strict = Boolean(args.strict || ci)
|
|
39
39
|
const json = Boolean(args.json)
|
|
40
40
|
const githubAnnotations = Boolean(args['github-annotations'] || ci)
|
|
41
|
+
const fidelityReportEnabled = Boolean(args['fidelity-report'])
|
|
41
42
|
const hasJsonOutput = Object.prototype.hasOwnProperty.call(args, 'output')
|
|
42
43
|
const jsonOutput = typeof args.output === 'string' && args.output.trim() ? args.output : null
|
|
43
44
|
const cwd = process.cwd()
|
|
@@ -225,12 +226,18 @@ export async function runAudit(args) {
|
|
|
225
226
|
}, {})
|
|
226
227
|
|
|
227
228
|
const hasProblem = (summary.drift || 0) + (summary.missing || 0) + (summary.error || 0) > 0
|
|
229
|
+
const fidelityReport = fidelityReportEnabled ? buildFidelityReport({ cwd, sections, tools, loadSkill }) : null
|
|
230
|
+
|
|
231
|
+
if (!json && fidelityReport) {
|
|
232
|
+
printFidelityReport(fidelityReport)
|
|
233
|
+
}
|
|
234
|
+
|
|
228
235
|
if (githubAnnotations) {
|
|
229
236
|
writeGitHubAnnotations(results, { strict })
|
|
230
237
|
}
|
|
231
238
|
|
|
232
239
|
if (json) {
|
|
233
|
-
|
|
240
|
+
const payload = {
|
|
234
241
|
ok: !hasProblem,
|
|
235
242
|
source: displaySource,
|
|
236
243
|
sourceFound: true,
|
|
@@ -246,7 +253,13 @@ export async function runAudit(args) {
|
|
|
246
253
|
? 'Run pluribus sync --dry-run to preview fixes, then pluribus sync to update generated files.'
|
|
247
254
|
: 'Generated context files are in sync.',
|
|
248
255
|
feedback: AUDIT_FEEDBACK_URL,
|
|
249
|
-
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (fidelityReport) {
|
|
259
|
+
payload.fidelityReport = fidelityReport
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
writeJson(payload, jsonOutput)
|
|
250
263
|
} else {
|
|
251
264
|
console.log('')
|
|
252
265
|
console.log(`Summary: ${summary.current || 0} current, ${summary.drift || 0} drifted, ${summary.missing || 0} missing, ${summary.error || 0} error(s).`)
|
|
@@ -264,6 +277,105 @@ export async function runAudit(args) {
|
|
|
264
277
|
}
|
|
265
278
|
}
|
|
266
279
|
|
|
280
|
+
function buildFidelityReport({ cwd, sections, tools, loadSkill }) {
|
|
281
|
+
const presentSections = Object.entries(sections)
|
|
282
|
+
.filter(([, value]) => String(value || '').trim())
|
|
283
|
+
.map(([name]) => name)
|
|
284
|
+
.sort((a, b) => a.localeCompare(b))
|
|
285
|
+
|
|
286
|
+
const lowerPresentSections = new Set(presentSections.map((name) => name.toLowerCase()))
|
|
287
|
+
const targets = tools.map((toolId) => {
|
|
288
|
+
const skill = loadSkill(cwd, toolId)
|
|
289
|
+
const representedSections = new Set([...(skill?.required || []), ...(skill?.optional || [])].map((name) => name.toLowerCase()))
|
|
290
|
+
const unsupportedSections = presentSections.filter((name) => !representedSections.has(name.toLowerCase()))
|
|
291
|
+
|
|
292
|
+
return {
|
|
293
|
+
toolId,
|
|
294
|
+
files: skill?.outputFiles || [],
|
|
295
|
+
activation: inferActivation(toolId, skill?.outputFiles || []),
|
|
296
|
+
representedSections: presentSections.filter((name) => representedSections.has(name.toLowerCase())),
|
|
297
|
+
unsupportedSections,
|
|
298
|
+
}
|
|
299
|
+
})
|
|
300
|
+
|
|
301
|
+
const warnings = []
|
|
302
|
+
for (const target of targets) {
|
|
303
|
+
if (target.unsupportedSections.length > 0) {
|
|
304
|
+
warnings.push({
|
|
305
|
+
code: 'section-not-rendered-by-target',
|
|
306
|
+
target: target.toolId,
|
|
307
|
+
message: `${target.toolId} template does not render section(s): ${target.unsupportedSections.join(', ')}`,
|
|
308
|
+
})
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (targets.some((target) => target.activation.kind === 'flat-project-wide')) {
|
|
313
|
+
warnings.push({
|
|
314
|
+
code: 'project-wide-activation-only',
|
|
315
|
+
target: '*',
|
|
316
|
+
message: 'Generated outputs are project-wide/always-on; Pluribus does not currently model path-scoped activation, manual attach, or progressive disclosure semantics.',
|
|
317
|
+
})
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const advancedSections = ['workflow', 'context', 'examples', 'anti-patterns'].filter((name) => lowerPresentSections.has(name))
|
|
321
|
+
if (advancedSections.length > 0 && warnings.some((warning) => warning.code === 'section-not-rendered-by-target')) {
|
|
322
|
+
warnings.push({
|
|
323
|
+
code: 'portability-claim-needs-evidence',
|
|
324
|
+
target: '*',
|
|
325
|
+
message: `Do not claim universal portability without evidence: advanced section(s) ${advancedSections.join(', ')} are not represented equally by every selected target.`,
|
|
326
|
+
})
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return {
|
|
330
|
+
claim: 'project-wide instruction portability evidence for selected targets',
|
|
331
|
+
sourceSections: presentSections,
|
|
332
|
+
targets,
|
|
333
|
+
summary: {
|
|
334
|
+
targetCount: targets.length,
|
|
335
|
+
targetsWithUnsupportedSections: targets.filter((target) => target.unsupportedSections.length > 0).length,
|
|
336
|
+
warningCount: warnings.length,
|
|
337
|
+
},
|
|
338
|
+
warnings,
|
|
339
|
+
nextStep: warnings.length > 0
|
|
340
|
+
? 'Review unsupportedSections/warnings before calling this context universal; narrow the tools list, change the source, or document known lossy targets.'
|
|
341
|
+
: 'Selected targets render the current non-empty source sections with no known Pluribus template loss; still smoke-test behavior in each agent.',
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
function inferActivation(toolId, outputFiles) {
|
|
346
|
+
if (toolId === 'windsurf' || toolId === 'continue') {
|
|
347
|
+
return {
|
|
348
|
+
kind: 'project-wide-rule',
|
|
349
|
+
evidence: outputFiles,
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return {
|
|
354
|
+
kind: 'flat-project-wide',
|
|
355
|
+
evidence: outputFiles,
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function printFidelityReport(report) {
|
|
360
|
+
console.log('')
|
|
361
|
+
console.log('Fidelity report:')
|
|
362
|
+
console.log(` Claim: ${report.claim}`)
|
|
363
|
+
console.log(` Targets: ${report.targets.map((target) => target.toolId).join(', ')}`)
|
|
364
|
+
|
|
365
|
+
for (const target of report.targets) {
|
|
366
|
+
const unsupported = target.unsupportedSections.length > 0
|
|
367
|
+
? `; unsupported sections: ${target.unsupportedSections.join(', ')}`
|
|
368
|
+
: '; no known section loss'
|
|
369
|
+
console.log(` • ${target.toolId}: ${target.activation.kind}${unsupported}`)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
for (const warning of report.warnings) {
|
|
373
|
+
console.log(` ⚠️ ${warning.code}: ${warning.message}`)
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
console.log(` Next: ${report.nextStep}`)
|
|
377
|
+
}
|
|
378
|
+
|
|
267
379
|
function getTools(rawContent, toolsArg) {
|
|
268
380
|
if (toolsArg) {
|
|
269
381
|
return splitTools(toolsArg)
|
package/src/utils/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.3.
|
|
1
|
+
export const VERSION = '0.3.16'
|