snipara-companion 3.2.25 → 3.2.27
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 +22 -0
- package/README.md +12 -7
- package/dist/index.js +54 -9
- package/docs/FULL_REFERENCE.md +11 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,28 @@
|
|
|
2
2
|
|
|
3
3
|
Release notes for `snipara-companion`, newest first.
|
|
4
4
|
|
|
5
|
+
## New In 3.2.27
|
|
6
|
+
|
|
7
|
+
- Scopes `context-control drift` dirty Git detection to the ProjectContext
|
|
8
|
+
manifest, declared manifest sources, local Decision Requests, and
|
|
9
|
+
`.snipara/context-control/` artifacts. Dirty files outside that scope remain
|
|
10
|
+
visible but no longer force permanent `DRIFT_DETECTED` in shared checkouts.
|
|
11
|
+
- Clarifies the Context as Code V0 boundary: manifests are local declarative
|
|
12
|
+
metadata and do not refresh hosted context, reconcile manifest-vs-hosted
|
|
13
|
+
state, or mutate hosted memory. Hosted refresh/apply remains V1 work.
|
|
14
|
+
- Adds executable documentation smoke tests that run the README and full
|
|
15
|
+
reference `context-control` examples against the built local CLI, closing the
|
|
16
|
+
loop that previously allowed narrative examples to drift from command reality.
|
|
17
|
+
|
|
18
|
+
## New In 3.2.26
|
|
19
|
+
|
|
20
|
+
- Fixes the published `context-control plan` examples so they use the real CLI
|
|
21
|
+
contract: `--summary` plus `--output`, without the nonexistent `--operation`
|
|
22
|
+
or `--content` flags or an out-of-scope target.
|
|
23
|
+
- Adds a package-doc regression test that executes the documented command shape
|
|
24
|
+
and rejects the unsupported flags if they return to the README or full
|
|
25
|
+
reference.
|
|
26
|
+
|
|
5
27
|
## New In 3.2.25
|
|
6
28
|
|
|
7
29
|
- Adds `snipara-companion context-control plan` and `apply` for local,
|
package/README.md
CHANGED
|
@@ -99,13 +99,11 @@ These commands are useful without hosted Snipara:
|
|
|
99
99
|
`context-control` is the local trust layer for Project Intelligence state. It
|
|
100
100
|
borrows Terraform's useful product grammar without copying Terraform: preview a
|
|
101
101
|
bounded context mutation, inspect drift, then apply only the exact reviewed
|
|
102
|
-
plan.
|
|
102
|
+
plan. V0 is intentionally local-only: it creates trust artifacts for review, not
|
|
103
|
+
hosted context mutations.
|
|
103
104
|
|
|
104
105
|
```bash
|
|
105
106
|
npx -y snipara-companion context-control plan \
|
|
106
|
-
--operation write_file \
|
|
107
|
-
--target demo.json \
|
|
108
|
-
--content '{"ok":true}' \
|
|
109
107
|
--summary "record reviewed context state" \
|
|
110
108
|
--output .snipara/context-control/plans/demo.json
|
|
111
109
|
|
|
@@ -126,13 +124,15 @@ locally:
|
|
|
126
124
|
"path": "docs/architecture.md",
|
|
127
125
|
"authority": "canonical",
|
|
128
126
|
"tier": "HOT",
|
|
129
|
-
"
|
|
127
|
+
"required": true,
|
|
128
|
+
"description": "Architecture context that agents should treat as canonical."
|
|
130
129
|
}
|
|
131
130
|
],
|
|
132
131
|
"policies": [
|
|
133
132
|
{
|
|
134
133
|
"id": "review-context-changes",
|
|
135
|
-
"
|
|
134
|
+
"scope": "memory.canonical",
|
|
135
|
+
"requirement": "Human review required before changing canonical context.",
|
|
136
136
|
"reviewRequired": true
|
|
137
137
|
}
|
|
138
138
|
]
|
|
@@ -145,7 +145,12 @@ npx -y snipara-companion context-control plan --manifest snipara.project-context
|
|
|
145
145
|
```
|
|
146
146
|
|
|
147
147
|
The manifest is declarative metadata only. Validation and local reconciliation
|
|
148
|
-
do not upload documents, approve memory,
|
|
148
|
+
do not upload documents, approve memory, refresh hosted context, or mutate
|
|
149
|
+
hosted Snipara state. `context-control drift` scopes dirty Git signals to the
|
|
150
|
+
manifest, manifest sources, local Decision Requests, and `.snipara/context-control/`
|
|
151
|
+
artifacts so unrelated checkout noise does not become permanent drift. A future
|
|
152
|
+
V1 hosted refresh/apply surface should compare manifest state against hosted
|
|
153
|
+
context before allowing real hosted mutations.
|
|
149
154
|
|
|
150
155
|
### Local Worker Registry
|
|
151
156
|
|
package/dist/index.js
CHANGED
|
@@ -33089,6 +33089,35 @@ function parseDirtyFile2(line) {
|
|
|
33089
33089
|
const renameParts = withoutStatus.split(" -> ");
|
|
33090
33090
|
return renameParts[renameParts.length - 1]?.replace(/^"|"$/g, "");
|
|
33091
33091
|
}
|
|
33092
|
+
function resolveGitDriftScopePaths(cwd) {
|
|
33093
|
+
const scopePaths = [
|
|
33094
|
+
PROJECT_CONTEXT_MANIFEST_DEFAULT_PATH,
|
|
33095
|
+
CONTEXT_CONTROL_RELATIVE_DIR,
|
|
33096
|
+
path30.join(".snipara", "decisions")
|
|
33097
|
+
];
|
|
33098
|
+
const manifestPath = resolveManifestPath(cwd);
|
|
33099
|
+
if (!fs30.existsSync(manifestPath)) {
|
|
33100
|
+
return normalizeScopePaths(scopePaths, cwd);
|
|
33101
|
+
}
|
|
33102
|
+
const manifestRead = readJsonFileSafe(manifestPath);
|
|
33103
|
+
if (!manifestRead.value) {
|
|
33104
|
+
return normalizeScopePaths(scopePaths, cwd);
|
|
33105
|
+
}
|
|
33106
|
+
const validation = validateProjectContextManifest({ manifest: manifestRead.value });
|
|
33107
|
+
const manifestSourcePaths = validation.manifest?.sources.map((source2) => source2.path) ?? [];
|
|
33108
|
+
return normalizeScopePaths([...scopePaths, ...manifestSourcePaths], cwd);
|
|
33109
|
+
}
|
|
33110
|
+
function normalizeScopePaths(scopePaths, cwd) {
|
|
33111
|
+
return uniqueStrings20(
|
|
33112
|
+
scopePaths.map((scopePath) => normalizeProjectRelativePath(scopePath, cwd).replace(/\/+$/g, ""))
|
|
33113
|
+
);
|
|
33114
|
+
}
|
|
33115
|
+
function isPathInsideScope(filePath, scopePaths) {
|
|
33116
|
+
const normalized = filePath.replace(/\\/g, "/").replace(/\/+$/g, "");
|
|
33117
|
+
return scopePaths.some(
|
|
33118
|
+
(scopePath) => normalized === scopePath || normalized.startsWith(`${scopePath}/`)
|
|
33119
|
+
);
|
|
33120
|
+
}
|
|
33092
33121
|
function slugify2(value) {
|
|
33093
33122
|
const slug2 = value.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 64);
|
|
33094
33123
|
return slug2 || "context-control-state";
|
|
@@ -33380,25 +33409,39 @@ function readJsonFileSafe(filePath) {
|
|
|
33380
33409
|
}
|
|
33381
33410
|
function collectGitDriftSignals(cwd) {
|
|
33382
33411
|
const revision = resolveGitBaseRevision(cwd);
|
|
33412
|
+
const scopePaths = resolveGitDriftScopePaths(cwd);
|
|
33413
|
+
const relevantDirtyFiles = revision.dirtyFiles.filter(
|
|
33414
|
+
(file) => isPathInsideScope(file, scopePaths)
|
|
33415
|
+
);
|
|
33383
33416
|
const upstream = runGit3(["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"], cwd);
|
|
33384
33417
|
const upstreamCounts = upstream ? runGit3(["rev-list", "--left-right", "--count", `${upstream}...HEAD`], cwd) : void 0;
|
|
33385
33418
|
const [behind = 0, ahead = 0] = upstreamCounts ? upstreamCounts.split(/\s+/g).map((part) => Number.parseInt(part, 10) || 0) : [];
|
|
33386
|
-
const dirtySignal = revision.dirty ? {
|
|
33387
|
-
id: "git-working-tree-dirty",
|
|
33419
|
+
const dirtySignal = revision.dirty ? relevantDirtyFiles.length > 0 ? {
|
|
33420
|
+
id: "git-working-tree-dirty-relevant",
|
|
33388
33421
|
surface: "git",
|
|
33389
33422
|
state: "DRIFT_DETECTED",
|
|
33390
|
-
summary: "Working tree has
|
|
33391
|
-
expected: "
|
|
33392
|
-
observed:
|
|
33393
|
-
refs:
|
|
33423
|
+
summary: "Working tree has uncommitted changes in context-control or ProjectContext scope.",
|
|
33424
|
+
expected: "Manifest, manifest sources, Decision Requests, and context-control artifacts are clean.",
|
|
33425
|
+
observed: relevantDirtyFiles.join(", "),
|
|
33426
|
+
refs: relevantDirtyFiles,
|
|
33394
33427
|
severity: "watch",
|
|
33395
|
-
reasonCodes: ["
|
|
33428
|
+
reasonCodes: ["git_working_tree_dirty_relevant"]
|
|
33429
|
+
} : {
|
|
33430
|
+
id: "git-working-tree-dirty-out-of-scope",
|
|
33431
|
+
surface: "git",
|
|
33432
|
+
state: "IN_SYNC",
|
|
33433
|
+
summary: "Working tree has uncommitted changes, but none are in context-control or ProjectContext scope.",
|
|
33434
|
+
expected: `Only scoped dirty paths affect context-control drift: ${scopePaths.join(", ")}.`,
|
|
33435
|
+
observed: `${revision.dirtyFiles.length} out-of-scope dirty file(s)`,
|
|
33436
|
+
refs: revision.dirtyFiles,
|
|
33437
|
+
severity: "info",
|
|
33438
|
+
reasonCodes: ["git_working_tree_dirty_out_of_scope"]
|
|
33396
33439
|
} : {
|
|
33397
33440
|
id: "git-working-tree-clean",
|
|
33398
33441
|
surface: "git",
|
|
33399
33442
|
state: "IN_SYNC",
|
|
33400
|
-
summary: "Working tree
|
|
33401
|
-
refs:
|
|
33443
|
+
summary: "Working tree has no uncommitted changes.",
|
|
33444
|
+
refs: scopePaths,
|
|
33402
33445
|
severity: "info",
|
|
33403
33446
|
reasonCodes: ["git_working_tree_clean"]
|
|
33404
33447
|
};
|
|
@@ -33645,6 +33688,8 @@ function buildLocalProjectDriftReport(options = {}) {
|
|
|
33645
33688
|
],
|
|
33646
33689
|
caveats: [
|
|
33647
33690
|
"Project Drift V0 is a read-only local report.",
|
|
33691
|
+
"Git dirty-file drift is scoped to the ProjectContext manifest, manifest sources, Decision Requests, and .snipara/context-control artifacts; use git status for full working-tree release readiness.",
|
|
33692
|
+
"Project Drift V0 validates manifest health locally but does not refresh hosted context state; hosted manifest-vs-context reconciliation is V1 work.",
|
|
33648
33693
|
"UNKNOWN is never treated as IN_SYNC; verify missing or unreadable evidence before applying changes."
|
|
33649
33694
|
]
|
|
33650
33695
|
});
|
package/docs/FULL_REFERENCE.md
CHANGED
|
@@ -232,7 +232,7 @@ snipara-companion workflow sync-policy-ledger
|
|
|
232
232
|
snipara-companion workflow producer-report
|
|
233
233
|
snipara-companion workflow producer-review --latest --outcome useful --reviewer alice
|
|
234
234
|
snipara-companion workflow run --adaptive-routing-dry-run --route-local-workers "document a scoped change"
|
|
235
|
-
snipara-companion context-control plan --
|
|
235
|
+
snipara-companion context-control plan --summary "record reviewed context state" --output .snipara/context-control/plans/demo.json
|
|
236
236
|
snipara-companion context-control apply --plan .snipara/context-control/plans/demo.json
|
|
237
237
|
snipara-companion context-control drift
|
|
238
238
|
snipara-companion context-control validate --manifest snipara.project-context.json
|
|
@@ -339,13 +339,18 @@ snipara-companion workflow resume --include-session-context
|
|
|
339
339
|
Git bases by default, writes only under `.snipara/context-control/`, and emits
|
|
340
340
|
an apply receipt linked to the plan hash.
|
|
341
341
|
- `context-control drift` is a read-only Project Drift V0 report. It checks Git
|
|
342
|
-
|
|
343
|
-
Requests, saved plans and receipts, and ProjectContext manifest
|
|
344
|
-
|
|
342
|
+
upstream state, scoped Git dirty files, managed workflow state, pending
|
|
343
|
+
Decision Requests, saved plans and receipts, and ProjectContext manifest
|
|
344
|
+
health. Dirty Git files only become drift when they touch the ProjectContext
|
|
345
|
+
manifest, manifest sources, local Decision Requests, or
|
|
346
|
+
`.snipara/context-control/`; unrelated checkout noise remains visible without
|
|
347
|
+
classifying the project as `DRIFT_DETECTED`. `UNKNOWN` is never treated as
|
|
348
|
+
`IN_SYNC`.
|
|
345
349
|
- `context-control validate --manifest snipara.project-context.json` validates
|
|
346
350
|
Context as Code V0. The manifest is JSON metadata declaring context sources,
|
|
347
|
-
tiers, authority,
|
|
348
|
-
|
|
351
|
+
tiers, authority, freshness, and review policies. It does not upload content,
|
|
352
|
+
refresh hosted context, reconcile manifest-vs-hosted state, or mutate hosted
|
|
353
|
+
Snipara state; hosted refresh/apply belongs to the future V1 surface.
|
|
349
354
|
- `lead-plan` turns local workflow state, Team Sync, file scope, context refs,
|
|
350
355
|
proof gates, and acceptance criteria into an advisory Engineering Lead Plan.
|
|
351
356
|
It emits worker recommendations and handoff contracts, keeps
|