Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ Run this after updating the package and before the first retrieval with the new
agent helpers and stages any required rebuild in a separate generation. It never deletes the active
index first: only a validated replacement activates, and interrupted or failed rebuilds remain
resumable. A long-running host can keep its already loaded runtime serving the previous generation,
then restart or cut over after `status=current` and `ready=true`.
then restart or cut over after `status=current` and `ready=true`. Privacy or extractor warnings are
reported separately as `advisory` lines and do not mislabel an operational index as needing repair;
resolve them with `rgr security-audit` without discarding the working index.

### Semantic retrieval and scanned PDFs

Expand Down
2 changes: 2 additions & 0 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ peer-only, and changed paths plus recommended actions. It never includes source
authoritative copy.

`inspectUpgrade(cwd)` reports whether an index is current, missing, incompatible, or needs repair.
Its `ready` field covers upgrade and retrieval continuity; `privacyCompliant` and `advisories`
surface independent local security follow-ups without turning a compatible index into a repair.
`upgradeProject({ cwd })` refreshes managed helpers and safely ingests or rebuilds before returning
the final doctor report. Call it after updating the package and before accepting retrieval on the
new runtime. Rebuild activation never deletes the previous validated generation first. A host that
Expand Down
7 changes: 5 additions & 2 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ rgr upgrade
`upgrade --check` reports `current`, `index-required`, `rebuild-required`, or `repair-required`,
including the version that wrote the active index. Run it after updating the package and before the
first retrieval with the new runtime. Incompatible retrieval is refused with a direct `rgr upgrade`
instruction instead of reading an untrusted layout.
instruction instead of reading an untrusted layout. `ready` describes upgrade and retrieval
continuity. `privacyCompliant` and repeated `advisory` lines report separate security follow-ups;
they do not turn a compatible operational index into `repair-required`.

`upgrade` refreshes managed agent helpers and performs any required ingest or rebuild. Schema,
embedding, chunking, redaction, and index-policy changes use the staged-generation flow: Ragmir
Expand All @@ -109,7 +111,8 @@ duplicate-ID validation activates. Failed or interrupted rebuilds never activate
and can resume. Older configs that omit newer optional fields receive current safe defaults.
`rgr doctor --fix` uses the same repair path. A long-running host can keep its already loaded
runtime on the previous generation, then restart or cut over after the upgrade reports
`status=current` and `ready=true`.
`status=current` and `ready=true`. Address any advisory with `rgr security-audit` or
`rgr security-audit --strict`; deleting and rebuilding a healthy index is not required.

## Resumable ingestion

Expand Down
3 changes: 3 additions & 0 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ activates. If the process is interrupted, rerun the command to resume; do not de
`.ragmir/storage/` first. A long-running host can keep its already loaded runtime serving during the
rebuild, then restart or cut over once the upgrade reports `status=current` and `ready=true`. Use
`rgr doctor --fix` for the same repair flow when setup or agent helpers also need attention.
`privacyCompliant=false` and `advisory=...` can accompany `status=current`: retrieval is compatible,
but a separate local security control still needs review. Run `rgr security-audit` for the exact
follow-up instead of deleting a healthy index.

## Strict audit fails

Expand Down
3 changes: 2 additions & 1 deletion packages/ragmir-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ Top-level `ingest`, `search`, `ask`, and `research` functions remain available f
- `rgr team snapshot` and `rgr team compare` explain configuration and per-file drift without
sharing source text or guessing which copy is authoritative.
- After a package update, `rgr upgrade --check` previews compatibility; `rgr upgrade` safely stages
any required rebuild without deleting the active index first.
any required rebuild without deleting the active index first. Privacy warnings remain visible as
non-blocking advisories and can be handled separately with `rgr security-audit`.

The [CLI reference](https://github.com/jcode-works/jcode-ragmir/blob/main/docs/cli-reference.md),
[API reference](https://github.com/jcode-works/jcode-ragmir/blob/main/docs/api-reference.md), and
Expand Down
8 changes: 8 additions & 0 deletions packages/ragmir-core/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,14 @@ program
`indexedWithRagmirVersion=${inspection.indexedWithRagmirVersion ?? "unavailable"}`,
)
console.log(`ready=${inspection.ready}`)
console.log(`privacyCompliant=${inspection.privacyCompliant}`)
console.log(`safeActivation=${inspection.safeActivation}`)
if (inspection.reason) {
console.log(`reason=${inspection.reason}`)
}
for (const advisory of inspection.advisories) {
console.log(`advisory=${advisory}`)
}
return
}

Expand All @@ -329,6 +333,7 @@ program
console.log(`runtimeRagmirVersion=${result.runtimeRagmirVersion}`)
console.log(`indexedWithRagmirVersion=${result.indexedWithRagmirVersion ?? "unavailable"}`)
console.log(`ready=${result.ready}`)
console.log(`privacyCompliant=${result.privacyCompliant}`)
console.log(`safeActivation=${result.safeActivation}`)
console.log(`action=${result.action}`)
console.log(
Expand All @@ -338,6 +343,9 @@ program
if (result.reason) {
console.log(`reason=${result.reason}`)
}
for (const advisory of result.advisories) {
console.log(`advisory=${advisory}`)
}
if (!result.ready) {
process.exitCode = 1
}
Expand Down
27 changes: 27 additions & 0 deletions packages/ragmir-core/src/upgrade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,33 @@ describe("upgrade continuity", () => {
})
}, 20_000)

it("should report privacy warnings as non-blocking upgrade advisories", async () => {
const root = await upgradeFixture()
const config = await loadConfig(root)
const currentManifest = await readIndexManifest(config)
if (!currentManifest?.health) {
throw new Error("Expected an index health snapshot.")
}
const warning = "A configured local extractor executes with operator authority."
await writeIndexManifest(
{
...currentManifest,
health: { ...currentManifest.health, securityWarnings: [warning] },
},
config,
currentManifest.indexedFiles,
)

await expect(inspectUpgrade(root)).resolves.toMatchObject({
status: "current",
ready: true,
privacyCompliant: false,
advisories: [warning],
reason: null,
})
await expect(search("continuity", { cwd: root })).resolves.toHaveLength(1)
}, 20_000)

it("should stage a rebuild when an old index has no compatible manifest", async () => {
const root = await upgradeFixture()
const config = await loadConfig(root)
Expand Down
8 changes: 6 additions & 2 deletions packages/ragmir-core/src/upgrade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export interface UpgradeInspection {
runtimeRagmirVersion: string
indexedWithRagmirVersion: string | null
ready: boolean
privacyCompliant: boolean
advisories: string[]
reason: string | null
recommendedCommand: "rgr upgrade"
safeActivation: boolean
Expand Down Expand Up @@ -42,7 +44,9 @@ export async function inspectUpgrade(cwd = process.cwd()): Promise<UpgradeInspec
status,
runtimeRagmirVersion: VERSION,
indexedWithRagmirVersion: manifest?.ragmirVersion ?? null,
ready: report.ready,
ready: status === "current",
privacyCompliant: report.readiness.privacyCompliant,
advisories: report.securityWarnings,
reason: upgradeReason(report, status),
recommendedCommand: "rgr upgrade",
safeActivation: true,
Expand Down Expand Up @@ -86,7 +90,7 @@ function upgradeStatus(report: DoctorReport, manifestFound: boolean): UpgradeSta
if (!report.readiness.indexPolicyCurrent) {
return "rebuild-required"
}
if (!report.ready) {
if (!report.readiness.operationalReady) {
return "repair-required"
}
return "current"
Expand Down