Skip to content
Draft
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
193 changes: 193 additions & 0 deletions .sdd/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
{
"manifest_version": 1,
"repository": {
"name": "kitchenSink",
"purpose": "Cisco Webex Android SDK Kitchen Sink demo app — a sample Android client that exercises every Webex SDK feature (auth, calling, messaging, search, people, webhooks) by sequence.",
"category": "cat1-legacy",
"primary_languages": ["kotlin"]
},
"topology": "Single-repo",
"commands": {
"build": { "command": "./gradlew assembleFullDebug", "source_file": "app/build.gradle", "role": "build" },
"unit-test": { "command": "./gradlew testFullDebugUnitTest", "source_file": "app/build.gradle", "role": "unit-test" },
"instrumented-test": { "command": "./gradlew connectedFullDebugAndroidTest", "source_file": "app/build.gradle", "role": "e2e" },
"clean": { "command": "./gradlew clean", "source_file": "build.gradle", "role": "other" }
},
"toolchain": [
{ "name": "jdk", "version": "17", "origin": "repo-config", "source_file": "buildSrc/src/main/java/com/ciscowebex/androidsdk/build/Versions.kt" },
{ "name": "kotlin", "version": "2.1.20", "origin": "repo-config", "source_file": "buildSrc/src/main/java/com/ciscowebex/androidsdk/build/Versions.kt" },
{ "name": "android-gradle-plugin", "version": "8.7.3", "origin": "repo-config", "source_file": "build.gradle" },
{ "name": "android-compile-sdk", "version": "34", "origin": "repo-config", "source_file": "buildSrc/src/main/java/com/ciscowebex/androidsdk/build/Versions.kt" },
{ "name": "android-ndk", "version": "27.2.12479018", "origin": "repo-config", "source_file": "buildSrc/src/main/java/com/ciscowebex/androidsdk/build/Versions.kt" }
],
"registries": [
{
"name": "cisco-devhub-webexsdk",
"type": "maven",
"host": "devhub.cisco.com",
"settings_file": "build.gradle",
"egress_required": true,
"origin": "repo-config",
"source_file": "build.gradle"
}
],
"artifacts": [
{
"name": "webex-android-sdk (full)",
"type": "maven-dependency",
"coordinates": "com.ciscowebex:webexsdk",
"version": "3.16.3",
"registry": "cisco-devhub-webexsdk",
"source_file": "app/build.gradle"
},
{
"name": "webex-android-sdk (meeting)",
"type": "maven-dependency",
"coordinates": "com.ciscowebex:webexsdk-meeting",
"version": "3.16.3",
"registry": "cisco-devhub-webexsdk",
"source_file": "app/build.gradle"
},
{
"name": "webex-android-sdk (wxc)",
"type": "maven-dependency",
"coordinates": "com.ciscowebex:webexsdk-wxc",
"version": "3.16.3",
"registry": "cisco-devhub-webexsdk",
"source_file": "app/build.gradle"
},
{
"name": "webex-android-sdk (message)",
"type": "maven-dependency",
"coordinates": "com.ciscowebex:webexsdk-message",
"version": "3.16.3",
"registry": "cisco-devhub-webexsdk",
"source_file": "app/build.gradle"
}
],
"tests": {
"unit": { "command_ref": "unit-test", "dir": "app/src/test", "framework": "JUnit 4" },
"e2e": { "command_ref": "instrumented-test", "dir": "app/src/androidTest", "framework": "AndroidX Test / Espresso", "external_deps": ["android device or emulator (API 28+)"] }
},
"quality_gates": {
"code_coverage": {
"origin": "unknown"
}
},
"coverage_status_definitions": {
"specced": ">=80% public surface specced, drift <5% — spec is authoritative",
"partial": "40-80% specced — spec is a hint, cross-check code",
"untracked": "<40% specced — code is the source of truth"
},
"modules": [
{
"path": "app/",
"coverage_status": "Partial",
"coverage_evidence": "First onboarding pass (assess-only). Draft canonical spec generated from real source (KitchenSinkApp.kt, WebexModule.kt, WebexRepository.kt, WebexViewModel.kt, AndroidManifest.xml). Public surface is the Android app entry points (launcher LoginActivity, exported CallRejectService, FCM service) plus the Koin feature modules; behavior largely delegates to the external Webex SDK. Coverage not yet measured; host-deferred coverage review pending.",
"canonical_spec": "app/ai-docs/app-spec.md",
"contracts": {
"provides": [
"Android launcher: com.ciscowebex.androidsdk.kitchensink.auth.LoginActivity (MAIN/LAUNCHER)",
"Exported service: .CallRejectService (call rejection intent handling)",
"Foreground services: .KitchenSinkForegroundService (specialUse), .CallManagementService (phoneCall)",
"FCM push receiver: .firebase.KitchenSinkFCMService (com.google.firebase.MESSAGING_EVENT)",
"FileProvider authority: ${applicationId}.provider"
],
"requires": [
"com.ciscowebex:webexsdk* 3.16.3 (Webex Android SDK — full/meeting/wxc/message flavors)",
"Cisco Webex cloud services + identity provider (OAuth/JWT/AccessToken auth)",
"Firebase (Crashlytics, Analytics, Cloud Messaging) via firebase-bom 26.1.0",
"Koin DI 2.2.3, RxJava2, AndroidX UI libraries"
]
},
"last_assessed": "2026-08-06",
"section_profile": {
"has_ui": true,
"crosses_service_boundaries": true,
"enforces_domain_rules": false,
"is_concurrent_async": true,
"owns_persistence": false,
"returns_caller_errors": true,
"has_design_tradeoff": null,
"stateful_transitions": true,
"exposes_wire_protocol": false,
"ui_multi_screen": true,
"large_data_model": false,
"has_tiers": false,
"module_specific_conventions": true,
"published_package": false,
"embedded_in_host": false,
"holds_client_state": true,
"has_submodules": false,
"resolved_by": "claude-cli (invocation-input; bootstrap questionnaire, assess-only)",
"resolved_at": "2026-08-06T00:00:00Z"
}
}
],
"spec_policy": {
"delta_grammar": {
"added": "## ADDED Requirements",
"modified": "## MODIFIED Requirements",
"removed": "## REMOVED Requirements"
},
"require_what_and_why": true,
"require_provenance": true,
"protected_specs": ["app/ai-docs/app-spec.md"],
"required_sections_by_change_class": {
"core_always": ["Intent (WHAT)", "Rationale (WHY)", "Scope/Out-of-scope", "Acceptance criteria", "Contracts delta"],
"security_or_contract_or_perf_critical": ["Data", "Error Matrix", "Resilience", "Observability", "Operations"]
}
},
"validation": {
"generator_runtime": "claude-cli",
"generator_model": "us.anthropic.claude-opus-4-8",
"generator_runtime_source": "invocation-input",
"minimum_independence": "different-runtime",
"blocking_severities": ["Blocking"],
"generator_run_id": "304fd06d-20af-4883-8029-f5c4fbead6c1"
},
"layout": {
"sdd_root": ".sdd",
"docs_root": "ai-docs",
"agent_entry_path": "AGENTS.md",
"standing_docs_root": "ai-docs",
"spec_index_path": "ai-docs/SPEC_INDEX.md",
"module_docs_strategy": "source-local",
"module_docs_folder_name": "ai-docs",
"template_roots": {
"canonical": ".sdd/templates",
"extensions": [".sdd/templates/extensions"]
},
"repo_skills_root": ".sdd/skills",
"contracts_strategy": "root-index-module-detail"
},
"coverage_ratchet": {
"enabled": true,
"waivers": []
},
"substrate": {
"source": "No org repo-readiness (repo-standards) substrate detected in this repo.",
"consumed": ["README.md", "proguard-rules.pro", "gradle.properties"],
"compliance_tier": "legacy"
},
"section_profiles": {
"repo": {
"owns_datastore": false,
"holds_client_state": true,
"components_interact": true,
"domain_data_across_components": false,
"caches_data": false,
"observability_convention": true,
"deploys_to_infra": false,
"shared_base_libs": false,
"is_monorepo": false,
"multi_platform": false,
"published_package": false,
"embedded_in_host": false,
"cross_repo_deps_material": true,
"security_arch_warranted": true
},
"resolved_by": "claude-cli (invocation-input; bootstrap questionnaire, assess-only)",
"resolved_at": "2026-08-06T00:00:00Z"
}
}
85 changes: 85 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!-- sdd-generated-metadata
doc_kind: agent-entry
generated_from: agents@0.2.2
generated_by: claude-cli
approved_by: pending
updated_at: 2026-08-06T00:00:00Z
validation_status: not-run
-->
# AGENTS.md — kitchenSink (Cisco Webex Android SDK Example)

> You are the agent entry point — read first. Next: router [`SPEC_INDEX.md`](ai-docs/SPEC_INDEX.md) · system [`ARCHITECTURE.md`](ai-docs/ARCHITECTURE.md). Load this + `SPEC_INDEX.md` first; pull module/standing docs on demand.
> Context-efficiency: link to canonical docs — don't duplicate them; keep this file under ~200 lines.

> Cross-tool context file. Auto-loaded by AI coding agents. This is a **draft, assess-only** onboarding
> artifact: code remains the source of truth. Unresolved confirmations are marked `[NEEDS HUMAN INPUT]`.

## Repo Overview
**kitchenSink** is a sample Android application ("Kitchen Sink" demo) that showcases the Cisco Webex
Android SDK by exercising its APIs by sequence, so developers can cut, paste, and adapt the code
(`README.md`). It supports Android 7.0+ and ships four product flavors (`full`, `meeting`, `wxc`,
`message`) selecting which Webex SDK variant is linked (`app/build.gradle`).

**What it is:**
- A reference/demo Android client for the Webex SDK covering auth, calling/meetings, messaging, search, people, and webhooks.
- A single-module Gradle Android app (`settings.gradle` `include ':app'`).
**What it is NOT:**
- ❌ Not the Webex Android SDK itself — it *consumes* `com.ciscowebex:webexsdk*` as an external dependency (`app/build.gradle`).
- ❌ Not a production service or backend — it owns no server, database, or deployable infrastructure.
- ❌ Not a published library — it is an installable APK, not an artifact other apps depend on.

## Tech Stack
- Kotlin 2.1.20, Android (compileSdk 34, minSdk 28), Android Gradle Plugin 8.7.3, JDK 17 (`buildSrc/.../Versions.kt`, `app/build.gradle`).
- Koin 2.2.3 for DI, RxJava2, AndroidX (AppCompat, ConstraintLayout, RecyclerView, ViewPager2, DataBinding), Firebase (Crashlytics/Analytics/Messaging).
- Tests: JUnit 4 unit tests (`app/src/test`), AndroidX Test + Espresso instrumented tests (`app/src/androidTest`).

## Architecture
```
Android UI (Activities/Fragments) -> ViewModels (LiveData) -> WebexRepository -> Webex SDK -> Webex cloud
(per-feature Koin modules loaded on login by LoginType) ^ Firebase FCM push -> services
```
→ Full repo architecture & component responsibilities: **[ARCHITECTURE.md](./ai-docs/ARCHITECTURE.md)**

## Module / Package Structure
```
app/ # the entire demo application (single Gradle module)
src/main/java/.../kitchensink/
KitchenSinkApp.kt # Application; startKoin; loads feature modules by LoginType
WebexModule.kt / WebexRepository.kt / WebexViewModel.kt # SDK access + shared VM
auth/ calling/ messaging/ search/ person/ webhooks/ extras/ firebase/ utils/ # feature areas
src/main/AndroidManifest.xml # activity/service graph, permissions
src/test/ , src/androidTest/ # unit + instrumented tests
```
→ Per-module docs and the spec router: **[ai-docs/SPEC_INDEX.md](./ai-docs/SPEC_INDEX.md)**

## Critical Rules
1. **Code is the source of truth.** Never invent an SDK API, activity, service, or permission — read the real file. This is a Partial-coverage repo (assess-only onboarding); cross-check code.
2. **Ask before coding.** Present a plan / Spec Summary; wait for confirmation.
3. **Never commit secrets.** `CLIENT_ID`, `CLIENT_SECRET`, `REDIRECT_URI`, `WEBHOOK_URL` come from `local.properties`; `SCOPE` from `gradle.properties`. Keep the committed defaults empty (`app/build.gradle`).
4. **One WebexSDK flavor at a time.** Use the flavor-scoped dependency (`fullImplementation`, `meetingImplementation`, `wxcImplementation`, `messageImplementation`) — never link two SDK variants together (`app/build.gradle`).
5. **Register feature behavior through a Koin module.** New feature areas follow the module-per-feature convention and are loaded in `KitchenSinkApp.loadKoinModules` (`KitchenSinkApp.kt`).

## Essential Commands
| Role | Command |
|---|---|
| Install | `./gradlew` (Gradle wrapper resolves the toolchain) |
| Build | `./gradlew assembleFullDebug` |
| Unit test | `./gradlew testFullDebugUnitTest` |
| Lint/format | `[NEEDS HUMAN INPUT]` — no committed lint/format gate found |
→ Full command surface, toolchain, and registries: **[GETTING_STARTED.md](./ai-docs/GETTING_STARTED.md)** · test tiers & coverage gate: **[TEST_INDEX.md](./ai-docs/TEST_INDEX.md)**

## Common Gotchas
1. Empty auth constants: without `CLIENT_ID`/`CLIENT_SECRET`/`REDIRECT_URI` in `local.properties`, login flows cannot complete — the build defaults them to empty strings (`app/build.gradle`).
2. Koin modules are loaded lazily on login and unloaded on logout (`KitchenSinkApp.loadKoinModules`/`unloadKoinModules`); resolving a ViewModel before modules load throws.
3. FedRAMP mode swaps auth configuration (`auth/LoginActivity.kt` `AppConfiguration.containsFedRampRestrictions()`); testing normal OAuth while FedRAMP restrictions are active gives misleading results.
4. Foreground/call services require the special-use and phoneCall foreground-service types on newer Android (`AndroidManifest.xml`); missing runtime permissions silently break calling.

## Pre-Commit Checklist
- [ ] Unit tests pass (`./gradlew testFullDebugUnitTest`)
- [ ] Spec/docs updated in the same change (spec-currency) — `app/ai-docs/app-spec.md`
- [ ] No hardcoded secrets; auth constants stay empty in committed config
- [ ] Only one WebexSDK flavor is linked; new behavior wired via its Koin module

---
**SDD coverage:** this repo's per-module coverage state lives in `.sdd/manifest.json` (mirror in
`ai-docs/SPEC_INDEX.md`). Use that state to decide whether the spec is authoritative or code must be cross-checked.
Loading