Skip to content
Merged
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
40 changes: 39 additions & 1 deletion .fuze/repo-manifest.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,12 @@
"platformAuth": {
"type": "object",
"additionalProperties": false,
"description": "NEW BLOCK \u2014 no repo declares it yet, and that is the point: it gates the platform-auth capability. Consume @fuzefront/auth (published as @izzywdev/fuzefront-auth) rather than a bespoke verifier. A product NEVER calls Permit directly; it knows exactly one thing, the base URL of FuzeFront's Security API.",
"description": "NEW BLOCK. Consume @fuzefront/auth (published as @izzywdev/fuzefront-auth) rather than a bespoke verifier. A product NEVER calls Permit directly; it knows exactly one thing, the base URL of FuzeFront's Security API. gate-platform-auth ENFORCES BY DEFAULT \u2014 this block is how a repo opts OUT, not how it opts in.",
"properties": {
"enforce": {
"type": "boolean",
"description": "Ratchet for gate-platform-auth, and it is OPT-OUT: absent means ENFORCING. Set false only to silence the gate while a repo migrates, and only together with `reason` \u2014 an `enforce: false` with no reason is ignored and the gate enforces anyway, because an undocumented opt-out is indistinguishable from an oversight. The earlier opt-in shape was chosen to avoid redding the fleet on pre-existing violations, but that is how gate-identifier reached zero adoption across 21 repos: a check nobody enabled is indistinguishable from a check that does not exist. What actually prevents a `|| true` is visibility, not coldness \u2014 an `enforce: false` naming a repo and a reason is greppable and countable; `|| true` in a workflow is neither."
},
"mode": {
"enum": [
"federated-jwks",
Expand All @@ -251,6 +255,10 @@
},
"note": {
"type": "string"
},
"reason": {
"type": "string",
"description": "REQUIRED when enforce is false. What blocks adoption and who owns closing it. This is the whole cost of the escape hatch: the opt-out must read as debt someone wrote down, not as a setting someone left alone."
}
}
},
Expand Down Expand Up @@ -667,6 +675,36 @@
}
}
},
"dataTier": {
"type": "array",
"description": "Declarative data-tier provisioning request (the IaC hand-off to FuzeInfra). FuzeInfra's reconciler consumes each entry: it ensures the per-service role exists AND is GRANTED the declared privileges on the declared database, then VERIFIES the role can actually read/write it (fail-loud if a role can auth but not access its DB). Replaces the old ad-hoc '@claude please provision' request (governance/shared-cluster-deploy.md §5). Every store the product's role authenticates to MUST be declared here, with the exact database name the app uses — a role granted on the wrong db name is the classic silent-empty-data bug.",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["store", "database", "role"],
"properties": {
"store": { "enum": ["postgres", "mongo", "redis", "neo4j", "chroma"], "description": "Shared datastore this role needs access in." },
"database": { "type": "string", "description": "The exact database/keyspace name the app reads/writes (e.g. robot_catalog). The role MUST be granted on THIS name; provisioning verifies it." },
"role": { "type": "string", "description": "The per-service role/user (e.g. mendys)." },
"privileges": { "enum": ["readWrite", "read", "admin"], "default": "readWrite", "description": "Privilege level to grant the role on `database`." },
"authSource": { "type": "string", "description": "Mongo authSource db the role authenticates against (e.g. admin), when it differs from `database`." }
}
}
},
"egress": {
"type": "array",
"description": "External hosts the product's pods need outbound HTTPS to. The shared cluster is egress-restricted (HTTP-only behind the Cloudflare tunnel; no default outbound to third-party APIs), so every external dependency MUST be declared here. FuzeInfra's reconciler turns these into namespace egress allow-rules (NetworkPolicy / egress gateway). Declare each third-party API explicitly (e.g. LLM providers).",
"items": {
"type": "object",
"additionalProperties": false,
"required": ["host"],
"properties": {
"host": { "type": "string", "description": "FQDN, e.g. api.openai.com." },
"port": { "type": "integer", "default": 443, "description": "Destination port (default 443)." },
"reason": { "type": "string", "description": "Why the product needs it (e.g. 'AI keyword generation')." }
}
}
},
"dependsOn": {
"type": "array",
"description": "Product-to-product dependencies this repo consumes beyond the spine (e.g. FuzeService dependsOn FuzeContact, FuzeBI).",
Expand Down
Loading