Skip to content

claude/fuze fuzefront registration hymmqk - #63

Draft
github-actions[bot] wants to merge 5 commits into
masterfrom
claude/fuze-fuzefront-registration-hymmqk
Draft

claude/fuze fuzefront registration hymmqk#63
github-actions[bot] wants to merge 5 commits into
masterfrom
claude/fuze-fuzefront-registration-hymmqk

Conversation

@github-actions

Copy link
Copy Markdown
Contributor
  • feat(registration): self-register FuzeKeys with the FuzeFront portal
  • fix(governance): supply the mcp-maintainer agent file + auto-merge permissions
  • chore(governance): reconcile managed files to FuzeSDLC v1 [skip ci]
  • feat(mobile): declare the mobile requirements contract
  • feat(registration): declare standalone surface via modes + routing.host

izzywdev and others added 5 commits July 28, 2026 16:25
- registration/manifest.json — identity + nav { section: platform, order: 10 }.
  `platform` rather than a lifecycle stage: FuzeKeys is a capability the other apps
  consume (providesTo lists 18 repos), not a step in plan -> build -> sell -> serve.

  The MF contract is real and verified against frontend/vite.config.ts +
  frontend/Dockerfile: scope=fuzeKeysApp, module=./FuzeKeysApp, remoteEntry at
  https://keys.prod.fuzefront.com/apps/fuzekeys/remoteEntry.js (base '/apps/fuzekeys/'
  + the keys.prod.fuzefront.com ingress; the Dockerfile comment says outright that
  FuzeFront fetches remoteEntry.js from that path, and nginx.conf serves it).

- registration/policy.json — derived from backend/app/models/: Identity, Account,
  VaultAsset (identity_cards + api_credentials), Site, SignupScript, ApiKey.

  READING A SECRET IS NOT A READ. VaultAsset splits `read` (list/inspect metadata) from
  `reveal` (return the decrypted value), and `reveal` is granted to admin ONLY. That
  lets operator create and rotate credentials without being able to read back an
  existing one — the property that makes an operator role safe to hand out. Folding
  reveal into ordinary `read` would have silently handed every viewer the vault.
  SignupScript:run is likewise split from writes; it drives real account creation
  against third-party sites.

- .fuze/manifest.json — mcp scaffold (enabled:false) + mcp-maintainer in agents, which
  now resolves after FuzeSDLC#66. The note carries the same constraint: a tool that
  returns a decrypted secret must never be classified as a read.

Validated: manifest passes the generated AppManifest schema; every permission resolves
to a resource+action the same document declares; VaultAsset:reveal confirmed to be held
by admin alone.

NOT DONE, deliberately: the init container is not wired. deploy/helm/fuzekeys is a
multi-service chart (backend, frontend, vault, tokenizer, presidio, litellm) and exactly
one deployment must register. frontend is the natural owner since it serves the remote,
but confirming that is devops-engineer's call, flagged not guessed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GaPa3JgrVNtWrGvqQEAEqv
…rmissions

Two red checks with the same root shape: something was DECLARED without the file
that backs it, and neither gate could self-heal.

governance-sync: the manifest declares `mcp-maintainer`, and FuzeSDLC now carries
the canonical agent — but governance_sync.py only COPIES a file that already exists
and has drifted. A wholly absent one is reported `missing` and hard-fails
(governance_sync.py:84), so `--write` was never going to create it. Added
.claude/agents/mcp-maintainer.md from the canonical, plus the mcp-maintain.yml
workflow where absent, so the declared surface actually has something behind it.

auto-merge.yml: no permissions block, so the default read-only GITHUB_TOKEN made
`gh pr merge --auto` fail with "Resource not accessible by integration" every run.
FuzeSDLC#66 fixed the canonical template; this copy was stale. Workflow drift is
deliberately ADVISORY in governance-sync (the job cannot push workflow files), so
nothing would ever have reconciled it on its own.

Verified with governance_sync.py against the canonical: ok=True, missing=[].

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GaPa3JgrVNtWrGvqQEAEqv
No repo in the family declared `mobile` at all, so `mobile-app-engineer` had nothing
to read on merge and no gate could tell "mobile is out of scope" from "nobody wrote
it down".

Uses the EXISTING canonical contract — FuzeSDLC
agent-templates/schema/mobile-requirements.schema.json — which already sanctions a
`mobile` block inside .fuze/manifest.json. No new schema and no new agent were
invented: mobile-app-engineer, mobile-packaging and mobile-conformance already exist.

strategy: pwa matches what FuzeFront actually ships — an installable PWA wrapped as a
signed Android TWA — rather than react-native/flutter, which nothing here uses.
targets omit ios until there is a signing identity for it.

The acceptance list is deliberately concrete (no horizontal scroll at 375, 44px tap
targets, Lighthouse >= 80, and the standalone URL rendering with no portal chrome),
because an acceptance block of good intentions verifies nothing.

Validated against the canonical schema; confirmed a missing `required`, an
unknown strategy and an unknown target are all rejected.

NOTE ON SEQUENCING: this declares mobile INTENT only. The `modes: ["portal",
"standalone"]` + `routing.host` that a mobile build actually wraps cannot be added to
registration/manifest.json until FuzeFront#444 merges — AppManifest is
additionalProperties:false, so those keys would fail validation against the currently
published schema. Registration side follows once that lands.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GaPa3JgrVNtWrGvqQEAEqv
This repo declares a `mobile` block, and a mobile build can only wrap a
URL that stands on its own — an app store has nothing to point at
otherwise. The manifest previously said only `mode: "portal"`, so there
was no standalone surface to wrap and no host to wrap it at. That made
the mobile contract unsatisfiable on its face.

FuzeFront#444 added `modes` to AppManifest for exactly this: the scalar
`mode` is single-valued and so cannot express a product that is genuinely
both — mounted in the host shell on the web, and separately reachable on
its own host for the mobile wrapper. `modes` is the multi-valued form and
wins where both are present.

- `modes: ["portal", "standalone"]` — portal stays the default surface.
  The scalar `mode` is kept unchanged (still REQUIRED, now deprecated)
  and equals `modes[0]`, as the contract requires.
- `routing.host` — the user-facing standalone host, `<slug>.fuzefront.com`.
  Distinct from `*.prod.fuzefront.com`, which is the infra host serving
  the portal `remoteEntry`. Portal integration is untouched.

Validated against packages/onboarding-kit/manifest.schema.json at merged
master (9d2b0af).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GaPa3JgrVNtWrGvqQEAEqv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant