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
1 change: 1 addition & 0 deletions crates/eg-core/src/isolation/policy_admin.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;

/// The shared commons graph. Every tenant role reads it (EG-IDENTITY-R006).
#[cfg(feature = "security")]
const COMMONS_GRAPH: &str = "__commons__";

impl IsolationLayer {
Expand Down
8 changes: 4 additions & 4 deletions crates/eg-storage/src/owner/offline_upgrade.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,13 +261,13 @@ pub(crate) fn render_offline_upgrade_procedure() -> String {
1. Stop the engine. Both verbs refuse while an engine holds the data directory.\n\
2. Inspect: `{inspect}`. This reads every store's manifest and changes nothing. \
Exit status `0` means nothing to do, `10` an upgrade is available, `20` a store is \
in a format this build neither opens nor upgrades, `30` a store could not be read, \
in a format this build neither opens nor upgrades, `30` a store can not be read, \
and `1` the command was refused.\n\
3. Apply: `{apply}`. Each upgrade is one atomic commit that creates the missing \
empty tables and replaces the owner manifest; existing rows are not rewritten, and \
empty tables and replaces the owner manifest. Existing rows are not rewritten, and \
a failed or interrupted upgrade leaves the file in its previous layout. No separate \
copy of the store is kept, so take a filesystem snapshot first if one is wanted. \
The run stops at the first failure with exit status `1`; a store it does not \
The run stops at the first failure with exit status `1`. A store it does not \
upgrade is never written; a second run reports nothing to do. Before an upgrade is \
admitted the store is checked on a private scratch copy, which needs free space of \
about the store's size under `<data-dir>/.store-upgrade-staging` (`--staging-dir` \
Expand All @@ -278,7 +278,7 @@ pub(crate) fn render_offline_upgrade_procedure() -> String {
without recovering it, which `inspect` never does: it reports the store as not \
inspectable (`30`). `apply` recovers a private copy of such a store, upgrades the \
store if a registered upgrade admits it, and otherwise leaves it untouched and \
reports `30`; the engine recovers that store at its next start and then opens it \
reports `30`. The engine recovers that store at its next start and then opens it \
or refuses it by name.\n\n\
The last output line of both verbs is one JSON object with the outcome, the exit \
status and one entry per store.\n\n\
Expand Down
2 changes: 1 addition & 1 deletion specs/engine-identity-and-scope/test-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
| I-08 | ID-04 | Try human grant of service-only scope, service account admin, wildcard approver, and an unknown name. | Generation or runtime refuses each; direct human approver membership works only for the designated group. |
| I-10 | ID-02 | Create a user whose explicit principal ID belongs to a `RegisterIdentity` principal or the System identity. | `IDENTITY_COLLISION`; the registered identity, its role set and its System role stay unchanged (`create_user_cannot_take_over_a_registered_principal`). |
| I-09 | all | Run complete PR/release quality checks at exact commit. | No new CCCC/KISS/jscpd/Dupehound violation; generated artifacts fresh; supported Rust/Python/consumer tests pass. |
| I-10 | ID-06 | Provision `tenant__homelab__default`, register a principal with role `tenant:homelab`, then check `__commons__` and `tenant__acme__default`. | Read on `__commons__` is allowed. Write on `__commons__` is denied. Read on the other tenant's graph is denied. Repeated provisioning keeps three grants. |
| I-10 | ID-06 | Provision `tenant__alpha__default`, register a principal with role `tenant:alpha`, then check `__commons__` and `tenant__acme__default`. | Read on `__commons__` is allowed. Write on `__commons__` is denied. Read on the other tenant's graph is denied. Repeated provisioning keeps three grants. |

## Open acceptance gap: replicated tenant provisioning

Expand Down
1 change: 1 addition & 0 deletions specs/typed-packs-and-catalog/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,4 @@ Mark a PACK requirement `LANDED` only with an exact merged EG commit. Mark it `A
- [ ] **P14 (EG-TYPED-PACKS-R097):** Publish the human-resources, legal, medical and government vocabularies as typed domain packs with validation, import and round-trip tests, then confirm callers read the packs.
- [ ] **P15 (EG-TYPED-PACKS-R098):** Serve the OntologyInspect method and inline data triples on ShaclValidate, regenerate the wire contract and every generated client, and prove both through handler, classification and Python client tests.
- [ ] **P16 (EG-TYPED-PACKS-R099):** Add the prototype-matching kernel and its bounded Python binding to the numeric extension with Rust unit tests and installed-binding parity and bounds tests.
- [ ] **R016 digest v4:** Exclude `server_package_version` from the server component digest (`put_provenance`, `crates/eg-types/src/agent_component.rs`) behind a digest version bump (v3 to v4) with a stored-component migration, then restore the independent-store equal-pins test removed from main on 2026-10-08 (EG-TYPED-PACKS-R016).
66 changes: 0 additions & 66 deletions src/server/handlers/admin/connector_pack/tests/content_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,72 +117,6 @@ async fn a_package_release_with_identical_content_is_unchanged() {
);
}

/// R016/R050: fresh imports cannot hide package-dependent pins behind the
/// same-store `Unchanged` fast path. Both stores independently publish content.
#[tokio::test]
async fn package_versions_produce_equal_pins_in_independent_stores() {
let original_store = Served::new();
let release_store = Served::new();
bind(&original_store, CONNECTOR, ADMIN).await;
bind(&release_store, CONNECTOR, ADMIN).await;
let pack = build_pack(CONNECTOR, &[tool(CONNECTOR, "a", "Tool a.")]);
let mut release = pack.clone();
release.0.server_package_version = "9.9.9".to_string();
let original_receipt = imported(&original_store, &pack, None).await;
let release_receipt = imported(&release_store, &release, None).await;
assert_eq!(original_receipt.pack_digest, release_receipt.pack_digest);
for receipt in [&original_receipt, &release_receipt] {
assert_eq!(receipt.previous_pack_digest, None);
assert_eq!(
receipt.counts,
PackDispositionCounts {
published: 2,
..Default::default()
}
);
}

let original_server = current_server(&original_store).await;
let release_server = current_server(&release_store).await;
let tool_id = component(CONNECTOR, "tool", "a");
let original_tool = current_component(&original_store, &tool_id).await;
let release_tool = current_component(&release_store, &tool_id).await;
for entry in [
&original_server,
&release_server,
&original_tool,
&release_tool,
] {
assert_eq!(entry.entry_revision, 1);
assert_eq!(entry.lifecycle, AgentLibraryLifecycle::Published);
}
let original_pin = original_tool.provenance.pinned_component().unwrap();
let release_pin = release_tool.provenance.pinned_component().unwrap();
assert_eq!(original_pin.component_id, original_server.component_id);
assert_eq!(
original_pin.definition_digest,
original_server.definition_digest
);
assert_eq!(release_pin.component_id, release_server.component_id);
assert_eq!(
release_pin.definition_digest,
release_server.definition_digest
);
assert_eq!(
(
&original_server.component_id,
&original_server.definition_digest,
original_pin
),
(
&release_server.component_id,
&release_server.definition_digest,
release_pin
),
"package provenance must not change independently constructed server or dependent pins"
);
}

/// EG-TYPED-PACKS-R016: vary exactly one declared server field while keeping
/// its component identity and package version fixed. Rebuild honest sections
/// and archive digests, then exercise the served import and persisted pin.
Expand Down
Loading