)]}'
{
  "log": [
    {
      "commit": "1c96d1c2f9be68b2947cc7ee2d847bd6303ddc83",
      "tree": "72b0905c4edc6d6a46a88145e2c83d72ef915667",
      "parents": [
        "b2175d20f6a289c786410b96560285dd1a706fa6"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 16:16:21 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 16:16:21 2026 -0400"
      },
      "message": "refactor(api): remove dead schema, fix two persistence defects, drop legacy fields (#682)\n\nRemoves schema no code reads (process_workflow table+proto, resource.status/StatusEnum, orphan agent_deployment_info table, unused BatchQueueRepository, duplicate app_module_mapping entity mapping, dead credentials.CREDENTIAL_OWNER_TYPE column, and the grid-cert-legacy user_dn/generate_cert fields on ProcessModel/UserConfigurationDataModel with proto numbers reserved and Python stubs regenerated). Fixes two defects: parsing_template silently dropped its parser_connections DAG on save, and queue_status.RUNNING_JOBS was a bit(1) truncating the running-job count to 0/1 (now int). Adds UNIQUE constraints on tag(value) and resource_star(user_id, resource_id) with race-safe idempotent find-or-create. Entities and both V1 baselines stay in sync; verified with a clean build and a fresh-DB init of schema + seed."
    },
    {
      "commit": "b2175d20f6a289c786410b96560285dd1a706fa6",
      "tree": "1f84ba755bc390931e23d50e0b23c33a54d9ece0",
      "parents": [
        "f66bdc1253a6b7272d37e6513c56079513a8e212"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 11:45:50 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 11:45:50 2026 -0400"
      },
      "message": "Remove residual dead code: orphaned ServerSettings config + migration CLI (#681)\n\n- Drop the six ServerSettings accessors orphaned when the Helix-era classes were\n  removed (getReSchedulerPolicyClass, getDataAnalyzingEnabledGateways,\n  getDataAnalyzerTimeStep, getDataAnalyzerScanningInterval,\n  getDataAnalyzerNoOfScanningParallelJobs, getMetaschedulerReschedulingThreshold)\n  and their six now-unused config-key constants (data.analyzer.*, the rescheduler\n  policy class, and the metascheduler reschedule threshold). All verified\n  zero-caller; getReSchedulerPolicyClass even defaulted to a since-deleted class.\n- Delete MigrateCredentialEncryption, a standalone main() CLI for the spent\n  one-time CBC-\u003eGCM credential re-encryption (no callers, no build wiring)."
    },
    {
      "commit": "f66bdc1253a6b7272d37e6513c56079513a8e212",
      "tree": "2b88e79a642ecca159e5d63b73085caaffb1b170",
      "parents": [
        "e10475ccee0407ffc03f5c7f3233d99c850fcdb7"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 11:32:15 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 11:32:15 2026 -0400"
      },
      "message": "Remove orphaned method, debug main()s, and stale plugin pins (#680)\n\n- AgentExperimentService.getUserExperimentIDs(): zero callers — orphaned when the\n  FuseService removal deleted its only consumer.\n- Four debug/demo public static void main() methods embedded in live production\n  classes (DefaultComputeResourceSelectionPolicy, LSFOutputParser,\n  TenantManagementKeycloakImpl, NameValidator) — the host classes stay.\n- Two stale pluginManagement pins for abandoned tooling (com.dkanejs\n  docker-compose-maven-plugin, io.fabric8 docker-maven-plugin) that no module\n  activates."
    },
    {
      "commit": "e10475ccee0407ffc03f5c7f3233d99c850fcdb7",
      "tree": "bb4fe83d4853b79bfa48238d0f782c27d16b3dbc",
      "parents": [
        "114720011ba4553cfc0992167627ea616a16404a"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 11:25:55 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 11:25:55 2026 -0400"
      },
      "message": "Remove Helix/gfac-era dead orchestration code (#679)\n\nThirty unreferenced classes under orchestration-service/task plus email-config.yaml,\nall leftover scaffolding from the pre-DB-transactional-executor (Helix/gfac) era —\na closed set that nothing live references (the reactor compiles cleanly without it):\n\n- Email-monitor parsing: EmailParser + PBS/SLURM/UGE/LSF/HTCondor/AiravataCustom\n  parsers + ResourceConfig + email-config.yaml (live monitoring uses squeue polling;\n  ServerSettings.getEmailBasedMonitorAddress, still used by GroovyMapBuilder, is kept).\n- IServer lifecycle + its three impls (DataInterpreterService,\n  ProcessReschedulingService, ComputationalResourceMonitoringService) + DataAnalyzer(Impl).\n  The impls carry no Spring stereotype, so component-scan never instantiated them.\n- Process scanner/scheduler/rescheduler cluster (ProcessScanner(Impl),\n  ProcessScheduler(Impl), ReScheduler, ExponentialBackOffReScheduler).\n- Orphaned leaves: AbstractMonitor, RealtimeJobStatusParser, JobStateValidator,\n  ParsingTaskInput/Inputs/Output/Outputs, AnalyzerConstants, SchedulerConstants,\n  ProcessCompletionMessage."
    },
    {
      "commit": "114720011ba4553cfc0992167627ea616a16404a",
      "tree": "ae46946c1e2e37f38a4ca10028472d08dea33ba7",
      "parents": [
        "280b18c3ad13f8a9842a922cbd8b9dc1f3251b10"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 10:57:41 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 10:57:41 2026 -0400"
      },
      "message": "Tidy airavata-api dependencies (drop unused snakeyaml, relocate groovy/mail) (#678)\n\n- Drop the explicit snakeyaml dependency from airavata-api (0 imports); it stays\n  available transitively via spring-boot, so the resolved tree is unchanged.\n- Relocate two dependencies to the modules that actually use them: groovy-templates\n  -\u003e compute-service (its only importer) and spring-boot-starter-mail -\u003e\n  orchestration-service (its only importer), instead of declaring them in airavata-api.\n\nThe airavata-server fat jar still resolves groovy-templates, spring-boot-starter-mail,\nand snakeyaml (verified via dependency:list); the full reactor compiles."
    },
    {
      "commit": "280b18c3ad13f8a9842a922cbd8b9dc1f3251b10",
      "tree": "d43b6a9670932d13ef877e0fd09fbc80c9f7074c",
      "parents": [
        "ea4424ecc6fb3a7ac94527ab82bd43d474dd0059"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:49:07 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:49:07 2026 -0400"
      },
      "message": "Remove dead dependencyManagement version pins (#677)\n\nTen dependencyManagement entries and the selenium-maven-plugin pluginManagement\nentry pinned artifacts that appear nowhere in the resolved dependency tree, so\nthe pins were inert: dozer-core, the four selenium-* drivers, json-simple,\ncommons-exec, mysql-connector-j (the DB driver is mariadb-java-client),\nkeycloak-authz-client (IAM uses keycloak-admin-client), and slf4j-simple.\ncommons-logging and jcl-over-slf4j are kept — both are live in the tree.\nVerified via dependency:list; reactor resolves and compiles unchanged."
    },
    {
      "commit": "ea4424ecc6fb3a7ac94527ab82bd43d474dd0059",
      "tree": "f472a3d385fe8b2718471479c98e6e8952b689d4",
      "parents": [
        "bd5e06d924e7a5ba024382ce4e641f58f45313d1"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:44:38 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:44:38 2026 -0400"
      },
      "message": "Drop inaccurate \"Return Path\" docstring boilerplate from SDK file ops (#676)\n\nThe line \"Return Path: /{project_name}/{experiment_name}\" was copy-pasted into six\nairavata_experiments file-operation docstrings (upload/list/download/etc.) where it\ndoes not describe the actual return value — only make_experiment_dir returns that\npath, and its first docstring line already says so. Remove the boilerplate."
    },
    {
      "commit": "bd5e06d924e7a5ba024382ce4e641f58f45313d1",
      "tree": "dd2efd2b9aed83f5ddce6727b5998958a4c7ed23",
      "parents": [
        "e0c50804e14121162aba39153fbc10899d7cd708"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:42:47 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:42:47 2026 -0400"
      },
      "message": "Remove unused research config (portal-url / dev-url / dev-user) (#675)\n\nResearchProperties bound airavata.research.portal-url, dev-url, and dev-user from\napplication.properties, but nothing reads getPortalUrl/getDevUrl/getDevUser\n(0 readers). Remove the three fields and their getters/setters, the matching\napplication.properties lines, and the two orphaned research_portal_url /\nresearch_portal_dev_url example vars in the ansible vault template (no .j2\nconsumed them). hub-url, admin-api-key, and limit stay (live)."
    },
    {
      "commit": "e0c50804e14121162aba39153fbc10899d7cd708",
      "tree": "387bed0776e3340063e54d5186d22bef382f33bb",
      "parents": [
        "70ff6c249c72301e43334469078682cb9fc46d38"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:34:19 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:34:19 2026 -0400"
      },
      "message": "Remove dead FuseService subsystem (#674)\n\nThe FUSE gRPC contract was never wired to any client. Remove airavata-fuse.proto\n(the FuseService with 8 stub RPCs), its only impl FuseFSHandler (a @Component\nBindableService that returned hardcoded dummies and is auto-collected into the\nArmeria gRPC service list, so it self-deregisters), the never-invoked\nAiravataFileService and its model types (ExperimentStorageResponse, DirectoryInfo,\nFileInfo), and the three committed SDK fuse stubs. ServiceWiringConfig drops the\nAiravataFileService/AgentExperimentService wiring that existed solely to feed the\ndead read-dir path. No Go agent or SDK/portal client references FuseService."
    },
    {
      "commit": "70ff6c249c72301e43334469078682cb9fc46d38",
      "tree": "5ced60eeb797497f973b8b70029ff453e9c4f63f",
      "parents": [
        "60d7f2df43616b06b2a647955a691888a2c9287f"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:19:58 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:19:58 2026 -0400"
      },
      "message": "Remove dead messaging_events.proto and its orphaned SDK stubs (#673)\n\nmessaging_events.proto (16 Thrift-era event messages: Experiment/Process/Task/Job\nstatus-change and submit/terminate events, plus the generic Message envelope) is\nimported by no other proto and referenced by no hand-written Java/Python — its\nonly consumer, KafkaProxyService, was removed when orchestration moved to the\nDB-transactional executor. Remove it and its three committed SDK stubs. Protos\nare glob-compiled, so the reactor regenerates cleanly without it."
    },
    {
      "commit": "60d7f2df43616b06b2a647955a691888a2c9287f",
      "tree": "5557ae7712b38565698b9770363db31b5f954c15",
      "parents": [
        "d9243eef765ebb4678664cda0a82fe76b195ae16"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:17:40 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:17:40 2026 -0400"
      },
      "message": "Drop placeholder class javadoc and fix corrupted license header (#672)\n\nRemove the boilerplate \"TODO: Class level comments please\" placeholder javadoc\n(the template `@author dimuthu / @since 1.0.0-SNAPSHOT` block) from 10 task/\nand compute/util classes — it adds no information. Also fix the ASF license\nheader in file_handling_client.py, whose first line was mangled by a stray\nfind/replace (\"Licrecursive\u003dNonepache\" -\u003e \"Licensed to the Apache\")."
    },
    {
      "commit": "d9243eef765ebb4678664cda0a82fe76b195ae16",
      "tree": "1ea9d8ea957048615af7b0ef3549597d40acb94d",
      "parents": [
        "20076b36fd6c457277d96b02e062442d97f7af2b"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:13:41 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:13:41 2026 -0400"
      },
      "message": "Remove unused docker-java dependency (#671)\n\ndocker-java (and its three docker-java-* version pins in the root\ndependencyManagement) is declared but never imported anywhere — 0 references.\nIt pulled a large jersey/netty subtree (hence the long exclusion list). Removing\nit slims the dependency tree; the reactor compiles and resolves cleanly without\nit, and docker-java is absent from the resolved tree afterward."
    },
    {
      "commit": "20076b36fd6c457277d96b02e062442d97f7af2b",
      "tree": "fe9b04edbd06e17bf0d61c5b9706f21204fb68c1",
      "parents": [
        "fa9fdd1d5a59ffb8ed4cbe6338bfce7749625525"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 01:01:46 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 01:01:46 2026 -0400"
      },
      "message": "Remove dead workflow_data.proto and its orphaned SDK stubs (#670)\n\nworkflow_data.proto (ComponentStatus, WorkflowStatus, WorkflowModel, EdgeModel,\nPortModel, NodeModel) is imported by no other proto and referenced by no\nhand-written Java/Python/Go — a leftover workflow-engine model contract. Remove\nit and its three committed SDK stubs (workflow_data_pb2.py/.pyi/_grpc.py). Protos\nare glob-compiled, so the reactor regenerates cleanly without it."
    },
    {
      "commit": "fa9fdd1d5a59ffb8ed4cbe6338bfce7749625525",
      "tree": "fda3b8e38cd4d7a5455b4d38926af3b134c5bfb3",
      "parents": [
        "62c980a385065f7c999328ec5ca749188ecfe10d"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:59:04 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:59:04 2026 -0400"
      },
      "message": "Clean dead members from VirtualStreamProducer (#669)\n\nRemove the unused setInputStream/setOutputStream setters (0 callers; the streams\nare only ever set in the constructor and read via the getters), the dead local\n`ConcurrentLinkedQueue q` (the real buffer is the LinkedBlockingQueue `queue`),\nand the now-unused ConcurrentLinkedQueue import. The class stays — it is live\nvia its constructor and getters in DataStagingTask."
    },
    {
      "commit": "62c980a385065f7c999328ec5ca749188ecfe10d",
      "tree": "9e46215fc43e679c68628364fd3db8aa00f23ee4",
      "parents": [
        "dfb11c866d45ee0c8442a633f341b1f7a3ed0564"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:53:01 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:53:01 2026 -0400"
      },
      "message": "Remove dead commented-out orchestrator test stubs (#668)\n\nFour legacy test classes whose entire bodies are commented-out pre-Thrift-removal\ncode: BaseOrchestratorTest (empty class — its body is one big block comment) and\nits three empty subclasses NewOrchestratorTest, OrchestratorTestWithGRAM, and\nOrchestratorTestWithMyProxyAuth. They contain no @Test methods, nothing outside\nthe quartet references them, and test sources compile cleanly without them."
    },
    {
      "commit": "dfb11c866d45ee0c8442a633f341b1f7a3ed0564",
      "tree": "39e5a9b42d0808f63ac2fd3f7490a5714f04da66",
      "parents": [
        "a31da6edb27a090fc8b4f7f09bf509842cb54fba"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:50:24 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:50:24 2026 -0400"
      },
      "message": "Remove dead research-service methods (#667)\n\nThree unused public methods with zero callers across both repos:\n- AgentManagementService.terminateApplication(gatewayId, experimentId)\n- AiravataService.getUserProfile(authzToken, userId, gatewayId) — the 1-arg\n  getUserProfile(userId) is the live overload (used by ResearchResourceService)\n- AgentExperimentService.projectService() accessor — the projectService field\n  stays (read by getProjects); only the unused accessor is removed"
    },
    {
      "commit": "a31da6edb27a090fc8b4f7f09bf509842cb54fba",
      "tree": "295e3f6d214cdb3a70985bfc8d2cb724cb3b47dd",
      "parents": [
        "ce7dd9034ef353a446fe68515ebcbfe7933fef77"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:43:50 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:43:50 2026 -0400"
      },
      "message": "Remove dead ResearchProjectRepository query methods (#666)\n\nSix unused Spring Data declarations with zero callers: existsByOwnerId,\nfindProjectsByRepositoryResource, findProjectsByDatasetResourcesContaining,\nfindAllByOwnerId, findAllByOwnerIdOrderByCreatedAtDesc, and the malformed\nno-op State(StateEnum) (matches no Spring Data query prefix). The active\nstate-scoped variants (...AndState, findByIdAndState, findALlByState) are kept."
    },
    {
      "commit": "ce7dd9034ef353a446fe68515ebcbfe7933fef77",
      "tree": "1377e9ced4bd637b7b1c91e4c95e36b6409007ec",
      "parents": [
        "3d146be771ae42a6ac5d193be72fb602a515993e"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:38:56 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:38:56 2026 -0400"
      },
      "message": "Remove dead credential email-notification subsystem (#665)\n\nA fully self-contained, unreferenced cluster under credential-service/util:\nNotifierBootstrap, EmailNotifier, EmailNotifierConfiguration,\nEmailNotificationMessage, NotificationMessage, CredentialStoreNotifier, and\nEmailNotifierTest. The classes only reference each other and are reachable only\nfrom the dead NotifierBootstrap entry point; nothing wires them. The reactor\n(incl. test sources) compiles cleanly without them."
    },
    {
      "commit": "3d146be771ae42a6ac5d193be72fb602a515993e",
      "tree": "aba3448eeb0c039613d74a03765a08cfa792e5ed",
      "parents": [
        "5d122aab6820e323b5dbafd47097b98989be5f77"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:36:40 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:36:40 2026 -0400"
      },
      "message": "Remove dead iam util classes (#664)\n\nThree unreferenced legacy classes under iam-service/util: SharingModelConverter\n(unused proto-\u003eentity helper) and the Utils + JPAConstants pair (legacy JDBC-URL\nparsing helpers used only by each other). Zero references across both repos\n(the one wildcard import of iam.util.* does not use any of them); the reactor\ncompiles cleanly without them."
    },
    {
      "commit": "5d122aab6820e323b5dbafd47097b98989be5f77",
      "tree": "10de72593b91dfbaf4fdcc193999fe7743990be6",
      "parents": [
        "9a2987c8e0dc10fa143e090f6e18c2311570b43d"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:34:17 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:34:17 2026 -0400"
      },
      "message": "Remove dead orchestration util classes (#663)\n\nEight legacy classes under orchestration-service/util with zero references\nanywhere (verified across both repos including config/reflection-string usages;\nthe reactor compiles cleanly without them): OrchestratorServerConstants,\nProjectModelUtil, WorkflowContext, OrchestratorServerThreadPoolExecutor,\nAiravataJobState, PropertyResolver, ComputeRepositoryFactory, ExecutionType.\nLeftovers from the pre-DB-transactional orchestration engine."
    },
    {
      "commit": "9a2987c8e0dc10fa143e090f6e18c2311570b43d",
      "tree": "e54689e07a069e5e59f7ad01691b8b0943b056ed",
      "parents": [
        "ff893c851e477cc751b5b92a333cf77364d5400b"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 13 00:18:15 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 13 00:18:15 2026 -0400"
      },
      "message": "Fix SDK-launched experiment output listing and clone creation-time (#662)\n\nTwo experiment-data fixes surfaced via the portal:\n\n- \"No files\" for SDK-launched experiment output: the SDK persists an absolute\n  experiment_data_dir (\"/project/experiment\"). The staging write side\n  (DataStagingTask.buildDestinationFilePath) strips the leading \"/\" and anchors\n  the dir under the storage root, but resolve_user_storage_path honored it\n  as-is, so list_dir/dir_exists resolved against the SFTP chroot root (outside\n  the storage root) and listed nothing. Strip the leading \"/\" and anchor under\n  \"~/\", matching the write side and the bare-relative dirs the portal UI sets.\n\n- Clone shows creation time as \"56 years ago\" (epoch 0): the clone re-sends the\n  full experiment via update_experiment with creation_time cleared, but\n  saveExperiment only stamped creation_time on insert, so the update nulled the\n  column. Make creation_time set-once: on update, carry the stored value forward."
    },
    {
      "commit": "ff893c851e477cc751b5b92a333cf77364d5400b",
      "tree": "0aff12599683de33abaf753aa05c098829263094",
      "parents": [
        "8c7aa93878461d0a37449e9f1b2f9a6d7d35eb28"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Fri Jun 12 22:28:18 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 22:28:18 2026 -0400"
      },
      "message": "Externalize DB seeding, prune dead orchestration paths, fix job/experiment status (#661)\n\nDB seeding is moved out of the JVM lifecycle: the schema is seeded from\nexternal SQL (conf/db/seed.sql via MariaDB initdb) and airavata-server starts\nwith Hibernate ddl-auto\u003dvalidate, doing no programmatic DB modification beyond\nFlyway. Removed DBInitConfig/DBInitializer and every *DBInitConfig and\nDev*Initializer, and collapsed the V1+V2 migrations into a single baseline.\n\nRemoved dead infrastructure now that orchestration is DB-transactional: the\nKafka proxy (KafkaProxyService) and the legacy monitors (EmailBasedMonitor,\nRealtimeMonitor, ParsingTriggeringTask) plus their message (de)serializers.\n\nCommitted a fixed devstack SFTP keypair (conf/sftp/id_*) so fresh worktrees no\nlonger crash-loop the sftp container.\n\nFixes surfaced via the portal:\n- MonitoringTask persists job status under the job\u0027s owning (job-submission)\n  task id — JobPK is (jobId, taskId) and addJobStatus no-ops on a miss — and\n  records an ACTIVE transition so the Job Submission stage advances past QUEUED.\n- sacct polling uses --duplicates and picks the most-recently-submitted record,\n  so a reused slurm job id no longer reports a stale CANCELLED/COMPLETED state.\n- ExperimentSummaryEntity is a live @Subselect (no physical table to populate),\n  so the dashboard \"recent experiments\" search returns results.\n- ComputeMapper maps defaultCPUCount -\u003e defaultCpuCount (MapStruct acronym case)."
    },
    {
      "commit": "8c7aa93878461d0a37449e9f1b2f9a6d7d35eb28",
      "tree": "8aa82435ce5f06ce4a1edbae47d3c8532591dbbd",
      "parents": [
        "ff68e7b40468920a49874f9b95c619d29b801db2"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Fri Jun 12 13:43:15 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jun 12 13:43:15 2026 -0400"
      },
      "message": "feat(orchestration): SSH/SFTP×SLURM/AWS resource model on a DB-transactional executor (#660)\n\n* added quickstart and readme\n\n* explicit repeated-field proto mapping, SDK proto enum migration, and experiment persistence fixes\n\n* feat(orchestration): SSH/SFTP×SLURM/AWS resource model on a DB-transactional executor\n\nReplace the Helix/ZooKeeper/Curator/RabbitMQ orchestration stack with a\nDB-transactional ProcessExecutor that walks the PROCESS→TASK DAG using\nSELECT ... FOR UPDATE SKIP LOCKED, with the DB as the single source of truth.\n\n- Transport collapsed to fixed SSH (compute ops) + SFTP (data ops); endpoint read\n  off the compute/storage resource; ssh_port/sftp_port folded onto the resources\n- Provisioning modeled as ResourceType{SLURM,AWS} via ProvisioningAdapter\n- DbTask/DbTaskResult task SPI; remove the messaging/ (RabbitMQ) subsystem, Helix\n  files, and broker/ZooKeeper config + compose services (Kafka retained for the\n  remote-agent path)\n- docker-SLURM cluster added to the devstack; architecture docs (README/CLAUDE) updated"
    },
    {
      "commit": "ff68e7b40468920a49874f9b95c619d29b801db2",
      "tree": "9704992f3b8e0983766cd2ed00dff1c8134cfffb",
      "parents": [
        "87aaeee73325ecd99243bc09a192158e240b8b26"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Wed Jun 10 21:43:17 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Jun 10 21:43:17 2026 -0400"
      },
      "message": "Proto-direct airavata-python-sdk + Keycloak self-service realm config (#659)\n\nRe-architects airavata-python-sdk into a proto-direct gRPC client. The resource helpers (research/compute/storage/iam/sharing/credential) return protobuf messages — or thin WithAccess/WithGroupAccess envelopes and composed pydantic models for cross-service shapes — instead of dict-transformed Thrift output, removing the legacy Thrift mapping layer and its enum-int tables in favor of proto-native types and strict typing, with deduplicated helpers aligned to the gRPC service breakdown and accompanying unit tests. Adds the public entry points the thin portal consumes directly (build_experiment, wrap_groups, list_application_deployments_for_module). Also enables Keycloak-owned account self-service in the dev realm seed (registration / password reset / remember-me) and registers the portal\u0027s local OIDC callback + post-logout URIs."
    },
    {
      "commit": "87aaeee73325ecd99243bc09a192158e240b8b26",
      "tree": "56df9652c5cd7d386c84f834ddfb8826d4a4dfca",
      "parents": [
        "7cadb49f1f4636583de90a93e97c5480c8e2f552"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 12:14:17 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 12:14:17 2026 -0400"
      },
      "message": "style: apply Spotless formatting to D4.3 storage/data-product files (#658)\n\nmvn spotless:apply reformatting for three files added/modified in the D4.3\nstorage work (DevStorageInitializer, DataProductInterface, UserStorageGrpcService)\nthat had minor line-wrapping violations the Spotless check now flags on every PR.\nFormatting-only; no behavior change."
    },
    {
      "commit": "7cadb49f1f4636583de90a93e97c5480c8e2f552",
      "tree": "f4b0d8cb7bf977448b585766deac0543a651b16a",
      "parents": [
        "c1be7bbb7a2fe5d8faf8b7cecabaf624e15d5210"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 12:12:41 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 12:12:41 2026 -0400"
      },
      "message": "feat(python-sdk): add framework-agnostic experiment-orchestration + queue-settings helpers (#657)\n\nRelocate API-side experiment behavior out of the Django portal SDK\n(airavata_django_portal_sdk) into the new gRPC SDK as a framework-agnostic\nairavata_sdk.helpers package. No Django/DRF/request/Thrift dependencies; every\nfunction takes an AiravataClient plus explicit kwargs and routes backend access\nthrough the gRPC facades (client.research / client.storage / client.sharing).\n\n- helpers/experiment_orchestration.py: launch, clone, is_input_file, and the\n  intermediate-output helpers (can_fetch_intermediate_output,\n  get_intermediate_output_process_status, fetch_intermediate_output,\n  get_intermediate_output_data_products). Repointed from\n  request.airavata_client.* + the Django user_storage module onto the gRPC\n  facades and proto snake_case field names. tmp input-file uploads are now moved\n  in place (move_file + update_replica_location) preserving the data-product\n  URI; clone-copy is implemented as download -\u003e upload -\u003e register_data_product\n  since the storage facade has no copy primitive.\n- helpers/queue_settings.py: the queue-settings calculator registry +\n  queue_settings_calculator decorator, relocated verbatim in behavior;\n  calculate_queue_settings now forwards *args/**kwargs so existing callers keep\n  working unchanged.\n\nsetuptools auto-discovers airavata_sdk.helpers via the existing airavata_sdk*\nglob; no version bump."
    },
    {
      "commit": "c1be7bbb7a2fe5d8faf8b7cecabaf624e15d5210",
      "tree": "9aa618159ca13be443ae06cfc4e4c5e9b1904c78",
      "parents": [
        "ac4c7e46c69bf9e20f41337a97179220b143da5d"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 02:59:41 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 02:59:41 2026 -0400"
      },
      "message": "perf(research-service): index DATA_REPLICA_LOCATION.FILE_PATH (#656)\n\nThe per-file data-product-uri resolution added for file listings looks up a data\nproduct by its replica file path (getDataProductByReplicaFilePath). Listing a\ndirectory resolves one such lookup per file, so without an index on FILE_PATH each\nwas a full scan of DATA_REPLICA_LOCATION — N scans for an N-file directory.\n\nAdd an index on FILE_PATH via @Index on DataReplicaLocationEntity (created by\nhbm2ddl on the running schema). Confirmed live: the lookup query\u0027s plan is now an\nindex ref seek (type\u003dref, key\u003dIDX_DATA_REPLICA_FILE_PATH, rows\u003d1) joining to\nDATA_PRODUCT by primary key, instead of a per-file table scan. Listing behavior\nunchanged (data_product_uri still stable/deduped). research-service tests: 53 pass."
    },
    {
      "commit": "ac4c7e46c69bf9e20f41337a97179220b143da5d",
      "tree": "7d02a59cf1876b8285c222baa4f15637f3a5f60d",
      "parents": [
        "2a034e79c83ec683bfe12f7e4886525f44d27615"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 02:42:07 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 02:42:07 2026 -0400"
      },
      "message": "fix(storage-service): move/symlink over SFTP instead of shell commands (#655)\n\nUserStorageService.moveFile and createSymlink ran \"mv\"/\"ln -s\" via\nadaptor.executeCommand, which the SFTP storage adaptor does not support, so\nboth failed with \"Command execution not supported on storage resources\" (the\nsame class of bug just fixed for deleteFile). Add moveFile (SFTP rename) and\ncreateSymlink (SFTP symlink) to the storage adaptor and call them.\n\nValidated live: moving a file relocates it (source gone, destination has the\ncontent); creating a symlink to a directory resolves through the link (listing\nthe link shows the target\u0027s contents). storage + compute unit tests pass."
    },
    {
      "commit": "2a034e79c83ec683bfe12f7e4886525f44d27615",
      "tree": "4fda474fa55be3856fe0efe8545a387a970c394c",
      "parents": [
        "e23618c9fc67bc18b9e18d5b65601ec08187dded"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 02:27:40 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 02:27:40 2026 -0400"
      },
      "message": "fix(storage-service): delete files over SFTP instead of shell rm (#654)\n\nUserStorageService.deleteFile ran \"rm -f \u003cpath\u003e\" via adaptor.executeCommand,\nbut the SFTP storage adaptor does not support command execution, so every file\ndelete failed with \"Command execution not supported on storage resources\".\nAdd a deleteFile to the storage adaptor (SFTP rm) and call it, mirroring how\ndeleteDir already uses deleteDirectory (SFTP rmdir).\n\nValidated live: uploading then deleting a file now succeeds (the file is gone)."
    },
    {
      "commit": "e23618c9fc67bc18b9e18d5b65601ec08187dded",
      "tree": "54bb917e6130794955d9398c282c6fc8adc02cd6",
      "parents": [
        "61112746588fd0319e229f3495aa63bbcf26c26f"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 02:12:19 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 02:12:19 2026 -0400"
      },
      "message": "feat(storage-service): surface per-file data-product URI in listings (#653)\n\nFile listings (list_dir / get_file_metadata / list_experiment_dir) now carry a\nstable data product URI per file, so clients can reference each stored file by\ndata product (downloads, deletes, selection) without a separate registry table.\n\n- DataProductInterface/DataProductRepository: getDataProductByReplicaFilePath\n  (JPQL join on the replica file path + gateway) finds the data product whose\n  gateway-data-store replica is a given path.\n- StorageProvider/StorageProviderImpl: getOrCreateDataProductByPath returns that\n  product\u0027s URI, registering a new FILE data product (single GATEWAY_DATA_STORE\n  replica) if none exists. This replaces the legacy file-path-to-data-product\n  mapping that the portal kept in its own ORM table.\n- UserStorageGrpcService populates FileMetadataResponse.data_product_uri for each\n  file (best-effort: directories and lookup failures yield an empty URI, never a\n  listing failure).\n\nValidated live: an uploaded file\u0027s get_file_metadata/list_dir return a\ndata_product_uri that is stable across calls (found, not re-registered) and\nresolves via the data-product service to the file\u0027s replica. storage-service +\nresearch-service tests pass."
    },
    {
      "commit": "61112746588fd0319e229f3495aa63bbcf26c26f",
      "tree": "2d1b1d98d2b8c2727b05d712140e42a6a99dcffd",
      "parents": [
        "c941eb2a4f7b2a61c3c6c8975038625662c743e0"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 01:57:52 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 01:57:52 2026 -0400"
      },
      "message": "feat(storage-service): expose file modified-time and content-type in metadata\n\nThe gRPC storage listing (list_dir/get_file_metadata) left modified_time and content_type unset even though FileMetadataResponse declares them. Populate both: FileMetadata gains modifiedTime + contentType; SSHJStorageAdaptor sets modifiedTime from SFTP stat mtime and guesses content_type from the filename; toFileMetadataResponse copies them through. created_time is not available over SFTP and stays unset."
    },
    {
      "commit": "c941eb2a4f7b2a61c3c6c8975038625662c743e0",
      "tree": "4d8fe05d4c4fe40ffbe4b7206b024bb3aa5800ec",
      "parents": [
        "f7ed91cf7145485dc7a4c8710112e966b9d0ae95"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 01:23:42 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 01:23:42 2026 -0400"
      },
      "message": "fix(research-service): correct data-product registration and replica round-trip\n\nFour proto-migration regressions in the data-product path: (1) an unset parent_product_uri defaults to \"\" (not null) under proto3, wrongly firing the parent-Collection check so no top-level product could register; (2) dataProductToModel called putAll on the proto builder\u0027s immutable map view (UnsupportedOperationException on every read) and dropped replicaLocations; (3) dataProductToEntity dropped replicaLocations so products persisted with no replica/file path; (4) replica ids were generated only when null, but empty-\"\" ids collided on the same PK so only one replica ever persisted. Hand-written default mappers (matching the existing appDeployment pattern) restore the full upload-\u003eregister-\u003eread round-trip; 53 research-service tests pass."
    },
    {
      "commit": "f7ed91cf7145485dc7a4c8710112e966b9d0ae95",
      "tree": "30673dfaffeccbe30d91e4814058d1fce271176a",
      "parents": [
        "d23df2882c6ea66492e15145be05d99cf0678d9d"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 00:21:29 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 00:21:29 2026 -0400"
      },
      "message": "fix: load storage data-movement interfaces via correct FK column\n\nStorageResourceEntity\u0027s @OneToMany joined on a RESOURCE_ID column the child entity never writes (it writes STORAGE_RESOURCE_ID, part of its composite @Id), so a storage resource never loaded its data-movement interfaces and the SFTP adaptor failed with \u0027No SCP data movement interface\u0027. Joins on STORAGE_RESOURCE_ID (read-only, child-owned). Also includes dev-storage seed/infra fixes (DevStorageInitializer host + self-heal; sftp volume chown)."
    },
    {
      "commit": "d23df2882c6ea66492e15145be05d99cf0678d9d",
      "tree": "b442b7418cfc6de6c278ec633d2f0806c90ac67c",
      "parents": [
        "18faafd8856d83ef8f99e589c9d2e82b0c5a4ce3"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Jun 09 00:21:27 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jun 09 00:21:27 2026 -0400"
      },
      "message": "fix(python-sdk): use product_uri in data-product facade requests\n\nresearch.get_data_product / get_parent_data_product / get_child_data_products built their request messages with a data_product_uri field, but the proto field is product_uri, so every call raised ValueError before reaching the server. Corrects the field name in all three (regression from #614)."
    },
    {
      "commit": "18faafd8856d83ef8f99e589c9d2e82b0c5a4ce3",
      "tree": "1951551560209939633178325a6c2b07fdf3a655",
      "parents": [
        "c5e5199c3ca2ace735abd5f973f0e2ed4777d0fd"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 23:30:33 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 23:30:33 2026 -0400"
      },
      "message": "refactor: nest the iam-service proto packages under api.iam (#648)\n\nRename the three non-iam_admin service protos in iam-service so all of iam-service\u0027s gRPC APIs share the org.apache.airavata.api.iam.* namespace: api.userprofile -\u003e api.iam.userprofile, api.sharing -\u003e api.iam.sharing, api.groupmanager -\u003e api.iam.groupmanager (iam_admin_service already lives at api.iam). A single flat api.iam is infeasible because sharing_service and group_manager_service share 17 message names, so the distinct services are nested as siblings under api.iam.\n\nThis is wire-breaking: the gRPC service paths change (e.g. /org.apache.airavata.api.sharing.SharingService/... -\u003e /org.apache.airavata.api.iam.sharing.SharingService/...). The in-repo Java consumers are updated (the iam Sharing/GroupManager gRPC handlers and the launcher\u0027s UserProfileGrpcService). compute-service\u0027s user_resource_profile_service.proto keeps api.userprofile and is unchanged - it coincidentally shared that Java package with iam\u0027s user_profile_service, so this rename actually un-splits the package across the two modules.\n\nThe Python SDK gRPC stubs for the three services are regenerated with the matching toolchain (protoc 6.31.1 / grpcio 1.80.0) so the diff is purely the rename; the .pyi stubs are unchanged. The full reactor builds green and the iam/compute tests pass. Regenerating the separate-repo portal client is a follow-up."
    },
    {
      "commit": "c5e5199c3ca2ace735abd5f973f0e2ed4777d0fd",
      "tree": "a864effdcc2f7cc4e40f1fc134b9ebdd31028631",
      "parents": [
        "89984b1e1a99994033308877191e2cd4320ce264"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 23:00:26 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 23:00:26 2026 -0400"
      },
      "message": "refactor: flatten the sharing packages into the iam namespace (#647)\n\nNow that the sharing code lives in iam-service, collapse its org.apache.airavata.sharing.{config,event,grpc,model,repository,service,util} Java packages into the matching org.apache.airavata.iam.* packages so the module has a single coherent namespace. This is an internal, server-side-only move: the proto packages (org.apache.airavata.api.sharing / .groupmanager) and the shared org.apache.airavata.sharing.registry.models.proto types are deliberately left untouched, and every external reference to sharing went through those proto/facade types, so no consumer import or gRPC/REST wire contract changes. The redundant SharingServiceConfig is removed because IamServiceConfig already component- and entity-scans org.apache.airavata.iam, which now covers the moved beans and entities. The one name clash — two different AbstractRepository base classes — is resolved by renaming the entity-direct sharing base to AbstractSharingRepository; it has a different type arity and a checked-exception contract than iam\u0027s model-converting AbstractRepository, so the two are kept distinct rather than force-merged. The full reactor builds green and iam-service tests (including the relocated ResourceSharingServiceTest) pass."
    },
    {
      "commit": "89984b1e1a99994033308877191e2cd4320ce264",
      "tree": "e9985889bf78df5eaeebbe7f9b70a813ae71c41a",
      "parents": [
        "200f94a83e04ba819cf05c742ba23f130020ee83"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:40:02 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:40:02 2026 -0400"
      },
      "message": "build(deps): bump github.com/pion/dtls/v3 in /airavata-agent (#646)\n\nBumps [github.com/pion/dtls/v3](https://github.com/pion/dtls) from 3.0.10 to 3.0.11.\n- [Release notes](https://github.com/pion/dtls/releases)\n- [Commits](https://github.com/pion/dtls/compare/v3.0.10...v3.0.11)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/pion/dtls/v3\n  dependency-version: 3.0.11\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "200f94a83e04ba819cf05c742ba23f130020ee83",
      "tree": "ece5ecd45eb43fcf05ce7b6dbedeeb468c7dfe39",
      "parents": [
        "588b40775a12d386986040a031ae509c1fa48f2f"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:39:51 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:39:51 2026 -0400"
      },
      "message": "build(deps): bump github.com/quic-go/quic-go in /airavata-agent (#621)\n\nBumps [github.com/quic-go/quic-go](https://github.com/quic-go/quic-go) from 0.55.0 to 0.59.1.\n- [Release notes](https://github.com/quic-go/quic-go/releases)\n- [Commits](https://github.com/quic-go/quic-go/compare/v0.55.0...v0.59.1)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/quic-go/quic-go\n  dependency-version: 0.59.1\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "588b40775a12d386986040a031ae509c1fa48f2f",
      "tree": "d9b4ba96231c4bd4fb86cb518bcbe6e1a4834835",
      "parents": [
        "4ba2624a6657670c181972e2c7adc6591cc89395"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:36:35 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:36:35 2026 -0400"
      },
      "message": "build(deps): bump github.com/fatedier/frp in /airavata-agent (#616)\n\nBumps [github.com/fatedier/frp](https://github.com/fatedier/frp) from 0.62.1 to 0.68.1.\n- [Release notes](https://github.com/fatedier/frp/releases)\n- [Changelog](https://github.com/fatedier/frp/blob/dev/Release.md)\n- [Commits](https://github.com/fatedier/frp/compare/v0.62.1...v0.68.1)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/fatedier/frp\n  dependency-version: 0.68.1\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "4ba2624a6657670c181972e2c7adc6591cc89395",
      "tree": "6471598d0d2da8841aa602fa56590b56f838f606",
      "parents": [
        "4843e68ae43b626d5eb0ba5b21f8c3897b3a261e"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 22:36:16 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:36:16 2026 -0400"
      },
      "message": "refactor: merge sharing-service into iam-service (#645)\n\nFold the sharing-service module into iam-service so that identity (authentication, user/tenant profiles, gateways) and access control (permissions, groups, resource sharing) live in a single IAM module, eliminating the sharing -\u003e iam internal module dependency. This is a module-level merge only: all sources move under iam-service with their org.apache.airavata.sharing.* Java packages and org.apache.airavata.api.sharing / .groupmanager proto packages preserved, so every consumer import and the gRPC/REST wire contract are unchanged. The sharing-service module is dropped from the reactor, and research-service and airavata-server (both of which already depend on iam-service) have their now-redundant sharing-service dependency removed. The full reactor builds green and the relocated sharing tests pass."
    },
    {
      "commit": "4843e68ae43b626d5eb0ba5b21f8c3897b3a261e",
      "tree": "d03bb1ff881a42cb67923dd665abbb4369825576",
      "parents": [
        "ac72bac528d277c91e162b87d629195ea7362e98"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:33:35 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:33:35 2026 -0400"
      },
      "message": "build(deps): bump github.com/Azure/go-ntlmssp in /airavata-agent (#619)\n\nBumps [github.com/Azure/go-ntlmssp](https://github.com/Azure/go-ntlmssp) from 0.0.0-20221128193559-754e69321358 to 0.1.1.\n- [Release notes](https://github.com/Azure/go-ntlmssp/releases)\n- [Commits](https://github.com/Azure/go-ntlmssp/commits/v0.1.1)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/Azure/go-ntlmssp\n  dependency-version: 0.1.1\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "ac72bac528d277c91e162b87d629195ea7362e98",
      "tree": "5be707d62327e59743c9f6e8bfde66761a9446e6",
      "parents": [
        "c2b8c017b3ac691b465ad9b0bf29b002dda2b391"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:33:19 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:33:19 2026 -0400"
      },
      "message": "build(deps): bump org.bouncycastle:bcprov-jdk18on from 1.81 to 1.84 (#618)\n\nBumps [org.bouncycastle:bcprov-jdk18on](https://github.com/bcgit/bc-java) from 1.81 to 1.84.\n- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)\n- [Commits](https://github.com/bcgit/bc-java/commits)\n\n---\nupdated-dependencies:\n- dependency-name: org.bouncycastle:bcprov-jdk18on\n  dependency-version: \u00271.84\u0027\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "c2b8c017b3ac691b465ad9b0bf29b002dda2b391",
      "tree": "6cb380376ff526738e383ce0872292080a1235c0",
      "parents": [
        "8752c61ec61f710fc058a233359d3f4d2addb6e7"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:33:07 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:33:07 2026 -0400"
      },
      "message": "build(deps): bump org.bouncycastle:bcpkix-jdk18on from 1.81 to 1.84 (#617)\n\nBumps [org.bouncycastle:bcpkix-jdk18on](https://github.com/bcgit/bc-java) from 1.81 to 1.84.\n- [Changelog](https://github.com/bcgit/bc-java/blob/main/docs/releasenotes.html)\n- [Commits](https://github.com/bcgit/bc-java/commits)\n\n---\nupdated-dependencies:\n- dependency-name: org.bouncycastle:bcpkix-jdk18on\n  dependency-version: \u00271.84\u0027\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "8752c61ec61f710fc058a233359d3f4d2addb6e7",
      "tree": "f3ebb4eafa9f113729e2f0dd46e5f21c4139e473",
      "parents": [
        "ee6a15e0a614d1c470718c75017b8447b659ce80"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:32:25 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:32:25 2026 -0400"
      },
      "message": "build(deps): bump org.apache.kafka:kafka-clients from 3.9.1 to 3.9.2 (#615)\n\nBumps org.apache.kafka:kafka-clients from 3.9.1 to 3.9.2.\n\n---\nupdated-dependencies:\n- dependency-name: org.apache.kafka:kafka-clients\n  dependency-version: 3.9.2\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "ee6a15e0a614d1c470718c75017b8447b659ce80",
      "tree": "6753e06dd963cea345018720839b95e58bda502d",
      "parents": [
        "e0bb156566d1c5f2ac8e3b5217a3d37503f11b1e"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Jun 07 22:32:11 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:32:11 2026 -0400"
      },
      "message": "build(deps): bump github.com/go-jose/go-jose/v4 in /airavata-agent (#613)\n\nBumps [github.com/go-jose/go-jose/v4](https://github.com/go-jose/go-jose) from 4.1.3 to 4.1.4.\n- [Release notes](https://github.com/go-jose/go-jose/releases)\n- [Commits](https://github.com/go-jose/go-jose/compare/v4.1.3...v4.1.4)\n\n---\nupdated-dependencies:\n- dependency-name: github.com/go-jose/go-jose/v4\n  dependency-version: 4.1.4\n  dependency-type: indirect\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "e0bb156566d1c5f2ac8e3b5217a3d37503f11b1e",
      "tree": "8a69cd0475a1f4200e908cffa76206e99923bdb6",
      "parents": [
        "0e3cef685d580f3b3f9ef22fc97123d68b248452"
      ],
      "author": {
        "name": "The Apache Software Foundation",
        "email": "root-asf-gitbox-commits@apache.org",
        "time": "Sun Jun 07 21:14:59 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:14:59 2026 -0400"
      },
      "message": "Set up default protection ruleset for default and release branches (#620)"
    },
    {
      "commit": "0e3cef685d580f3b3f9ef22fc97123d68b248452",
      "tree": "4ed683955b26a1609c8258ac3b2f9e81fc715b96",
      "parents": [
        "adb52410968b61f4a9c74486dda495ca13905b6f"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 22:05:08 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 22:05:08 2026 -0400"
      },
      "message": "ci: drop the JavaScript/TypeScript CodeQL analysis (#644)\n\nThe repository contains no JavaScript or TypeScript source, so the javascript-typescript CodeQL job has no code to scan and fails on every PR. Remove it from the language matrix, leaving actions, go, java-kotlin and python."
    },
    {
      "commit": "adb52410968b61f4a9c74486dda495ca13905b6f",
      "tree": "e83e75431cd8a1c69176fb74c44c6d8fee2934fe",
      "parents": [
        "d4e3bf340a65a9579b5e9350ec8b3b8cb785c8dd"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 21:57:46 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 21:57:46 2026 -0400"
      },
      "message": "refactor: move the research Resource catalog from sharing-service into research-service (#643)\n\nResourceEntity (table RESOURCE), TagEntity, ResourceStarEntity, their three repositories and the four research-only enums (ResourceTypeEnum/PrivacyEnum/StateEnum/StatusEnum) physically lived in sharing-service but were referenced only by research-service, which reached into sharing\u0027s internal model/repository packages 28 times. This is a package-only relocation (org.apache.airavata.sharing.{model,repository} -\u003e research.{model,repository}) with no schema change: the RESOURCE/TAG/RESOURCE_STAR tables and their Flyway migrations are untouched, and the broad @EntityScan over org.apache.airavata still discovers them. All consumers and the shared test persistence unit are repointed; research-service\u0027s sharing.model/repository imports drop from 28 to 0. Behavior-preserving; the reactor builds green and research-service\u0027s 53 tests pass."
    },
    {
      "commit": "d4e3bf340a65a9579b5e9350ec8b3b8cb785c8dd",
      "tree": "07a4d4cacef651fe48a36d280ecf69055c1c0f8c",
      "parents": [
        "bfa377caad50d22b3c5a2e4f7239809db08f1b3b"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 21:18:52 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 21:18:52 2026 -0400"
      },
      "message": "refactor: extract shared AuthTokenExtractor for the gRPC and HTTP auth paths (#642)\n\nGrpcAuthInterceptor and HttpAuthDecorator independently stripped the Bearer prefix, parsed the x-claims JSON header (each with its own ObjectMapper), and built the AuthzToken. A new AuthTokenExtractor (stripBearer / parseClaims / buildAuthzToken, with one shared ObjectMapper) provides those three steps; each transport keeps its own concerns: the gRPC UNAUTHENTICATED close, the HTTP UNAUTHORIZED return and per-header claims fallback, and the UserContext lifecycle. Behavior-preserving and the reactor builds green. The only airavata-server test failures are in the unrelated FileControllerTest, which fails identically on master."
    },
    {
      "commit": "bfa377caad50d22b3c5a2e4f7239809db08f1b3b",
      "tree": "9a4c3b953e39f11f8acb689c110bb6daf51981ba",
      "parents": [
        "abb331a9335fa0a4c1abbe3a397638d73433c265"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 21:18:20 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 21:18:20 2026 -0400"
      },
      "message": "fix: read the canonical kafka.broker.url key in KafkaProxyService (#641)\n\nKafkaProxyService injected ${airavata.kafka.broker-url}, a hyphenated key set only by the local Tilt/DinD compose file; real deployments (application.properties, ansible) define kafka.broker.url, so the proxy silently fell back to localhost:9092. Point the @Value at kafka.broker.url and drop the now-redundant -Dairavata.kafka.broker-url override from compose.yml."
    },
    {
      "commit": "abb331a9335fa0a4c1abbe3a397638d73433c265",
      "tree": "5ce96761836a0106c5097053f9f22aa712e02fc6",
      "parents": [
        "60808eccc6db8d371336c171399d8b36ab987f8c"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 20:32:32 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 20:32:32 2026 -0400"
      },
      "message": "refactor: collapse duplicated method families in research-service (#640)\n\nExperimentSummaryRepository.getAccessibleExperimentStatistics repeated six near-identical count-and-list-per-state blocks; they now drive a small table of (state list, count setter, list setter) records through one loop, with the \u0027all\u0027 row carrying a null state list (via Arrays.asList) that the underlying query already treats as \u0027no filter\u0027. ResearchHubService.stopSession and deleteSession, which differed only by a {remove:true} body, now delegate to a single deleteHubSession(sessionId, remove) helper that reuses one RestTemplate instance field instead of constructing one per call. Behavior-preserving; the reactor builds green and research-service\u0027s 53 tests, including ExperimentSummaryRepositoryTest, pass."
    },
    {
      "commit": "60808eccc6db8d371336c171399d8b36ab987f8c",
      "tree": "035f400112a3c8ed3c6c2d304a394c132feca112",
      "parents": [
        "b9baada5431c24cdc6920cf73e45c69f694df616"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 20:17:30 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 20:17:30 2026 -0400"
      },
      "message": "refactor: collapse duplicated method families in storage-service (#639)\n\nIn DataMovementRepository the four protocol getters were identical bar the mapper and the four adders bar the prefix/mapper; they now delegate to two private helpers (getMovement(id, mapper) and addMovement(entity)), with the per-protocol id injection kept in the typed wrappers and the asymmetric update* methods left untouched. In DataStagingTask the structurally identical getInput/getOutputStorageAdaptor methods now delegate to a single direction-parameterized helper, which also fixes the output method\u0027s log line that mislabeled the resource as \u0027input\u0027. Behavior-preserving; the reactor builds green and storage-service tests pass."
    },
    {
      "commit": "b9baada5431c24cdc6920cf73e45c69f694df616",
      "tree": "45877f41c00728eeaf99a69c0f2bc397a0403d4b",
      "parents": [
        "b0243ae2ec87144b2144c60bf86431aaad274898"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 20:06:01 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 20:06:01 2026 -0400"
      },
      "message": "docs: document the SLF4J placeholder logging convention in CLAUDE.md (#638)\n\nAdds a Logging section requiring parameterized {} placeholders over string concatenation in log statements, with the throwable passed as the trailing argument."
    },
    {
      "commit": "b0243ae2ec87144b2144c60bf86431aaad274898",
      "tree": "78a71d91612cb005a36e135c76cbb77d54a21d94",
      "parents": [
        "78ed5b8441fd9a99d8d0dfb39f1943b5a6aca937"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 20:05:27 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 20:05:27 2026 -0400"
      },
      "message": "refactor: collapse duplicated method families in CredentialStoreService (#637)\n\nThe three typed getters (SSH/Certificate/Password), the two SSH-summary-for-gateway methods, and the SSH/PWD delete methods each repeated the same fetch-check-log, collect, and delete-and-log scaffolding; they now delegate to three private helpers (getTypedCredential, collectSshSummaries with a Predicate\u003cSSHCredential\u003e, deleteCredential), whose log statements use SLF4J {} placeholders instead of string concatenation. Public/@Override signatures are preserved; two getter log lines reading \u0027credentialfor\u0027 are normalized to \u0027credential for\u0027 to match the thrown message. Behavior-preserving: the module\u0027s 36 tests, including CredentialStoreServiceTest\u0027s 14, pass unchanged."
    },
    {
      "commit": "78ed5b8441fd9a99d8d0dfb39f1943b5a6aca937",
      "tree": "9355b5c1f0f42ca678986f7178ef55ee8f28581f",
      "parents": [
        "9197d9a92e631a9f037088c25b53f72d561f968b"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 19:32:15 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 19:32:15 2026 -0400"
      },
      "message": "refactor: drop the redundant sharing-service SharingHelper (#636)\n\nResourceSharingService was the only consumer of sharing-service\u0027s util.SharingHelper, a near-duplicate of the shared org.apache.airavata.util.SharingHelper that was also incorrectly annotated @Service despite having a private constructor and only static methods. It now uses the core helper directly, since its arguments are compatible (registryHandler is a RegistryProvider, gatewayGroupsInitializer a GatewayGroupsProvider, and sharingHandler a SharingService which implements the SharingFacade the core method expects), so the duplicate file is removed. Behavior-preserving and the reactor builds green."
    },
    {
      "commit": "9197d9a92e631a9f037088c25b53f72d561f968b",
      "tree": "1d920f0510ae1e21b9962b9c2550fcfbed9d8996",
      "parents": [
        "36cff7403e2a47b7fa22ded3625000fb9241e6b1"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 19:26:17 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 19:26:17 2026 -0400"
      },
      "message": "refactor: dedup iam QueryConstants against the shared db.QueryConstants (#635)\n\nUserProfileRepository now static-imports its two JPQL query strings from the shared org.apache.airavata.db.QueryConstants (their definitions resolve to identical queries), so iam.util.QueryConstants drops the two duplicated user-profile queries plus four gateway queries that were already dead (GatewayRepository uses the core copies) and the five parameter constants only those queries referenced, leaving just the USER_ID/GATEWAY_ID keys it still needs. Behavior-preserving and the reactor builds green."
    },
    {
      "commit": "36cff7403e2a47b7fa22ded3625000fb9241e6b1",
      "tree": "8d84e7d20435cc0203d4da85a18b490d946a7a4d",
      "parents": [
        "20aea9112ab7d7fac3d5c11dee8fcdc437b3b82e"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 19:12:00 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 19:12:00 2026 -0400"
      },
      "message": "refactor: move JsonMapConverter into the shared db package (#634)\n\nThe compute-service and storage-service each carried a byte-identical copy of this JPA JSON-map AttributeConverter; this keeps a single copy in org.apache.airavata.db alongside JsonListConverter and points the two @Convert references (ComputeJobSubmissionEntity, StorageDataMovementEntity) at it. Behavior-preserving and the reactor builds green."
    },
    {
      "commit": "20aea9112ab7d7fac3d5c11dee8fcdc437b3b82e",
      "tree": "a9c1c0fabfc56cfcac5d4d84748aec679449a155",
      "parents": [
        "59c4a0523fd0ce123759368f8d90e4ce49e75904"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 18:45:47 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 18:45:47 2026 -0400"
      },
      "message": "build: consolidate the Testcontainers Ryuk-disable flag into root surefire (#633)\n\nTESTCONTAINERS_RYUK_DISABLED\u003dtrue was repeated in four module surefire blocks (airavata-api, iam, compute, orchestration); this hoists it into the root maven-surefire-plugin configuration so it applies to every module\u0027s tests via inheritance and removes the three RYUK-only blocks plus airavata-api\u0027s copy. Verified with help:effective-pom that the flag still reaches iam/compute/orchestration and now also the other Testcontainers modules, and the reactor builds green."
    },
    {
      "commit": "59c4a0523fd0ce123759368f8d90e4ce49e75904",
      "tree": "5c8fae1f4609cbc5bcb1f2acf94420175bbe0181",
      "parents": [
        "69b5cf15514814a3cdc26375d676eac845f3b111"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 18:35:17 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 18:35:17 2026 -0400"
      },
      "message": "build: centralize dependency versions and drop redundant config (#632)\n\nHoists the Mockito (5.23.0) and MapStruct (now a mapstruct.version property) versions into the root pom so the modules stop repeating them — which also aligns airavata-server\u0027s test Mockito (previously 5.17.0 from the Spring Boot BOM) with the rest — removes the four spring-boot-starter version pins and the misplaced spring-boot-maven-plugin entry from dependencyManagement (all already supplied by the imported spring-boot-dependencies BOM), and bumps the spring-boot-maven-plugin pluginManagement pin to 3.5.12 to match. Behavior-preserving; the reactor builds green and dependency:tree confirms versions are unchanged apart from the intended Mockito alignment."
    },
    {
      "commit": "69b5cf15514814a3cdc26375d676eac845f3b111",
      "tree": "c009082153b9bd64e4cf3de882f10c3a13693b79",
      "parents": [
        "3a052096fadb0a96c5f1303ffc5acf338dca8219"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 17:24:01 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 17:24:01 2026 -0400"
      },
      "message": "Remove airavata-jupyterhub (moved to apache/airavata-portals) (#631)\n\nThe JupyterHub deployment directory has no Maven or build coupling to the middleware and belongs with the gateway-facing portals; it has been moved to apache/airavata-portals, so this removes it here along with its CLAUDE.md section and the stale .dockerignore comment."
    },
    {
      "commit": "3a052096fadb0a96c5f1303ffc5acf338dca8219",
      "tree": "0fc5ab7b98b7365168478dc7349f5bdb584af7b1",
      "parents": [
        "22b59bd5f6cdc966f15779cfb5127955aacecd14"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 17:16:02 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 17:16:02 2026 -0400"
      },
      "message": "style: fix Spotless formatting violations on master (#630)\n\nmvn spotless:check has been failing on master and therefore on every open PR; this applies mvn spotless:apply to the six offending files (SSHJStorageAdaptor, DevStorageInitializer, ExpCatalogDBInitConfig, SharingService, UserStorageGrpcService, StorageMapper) to re-wrap lines, normalize import grouping and drop unused imports. Formatting-only, no behavior change, and the reactor still builds."
    },
    {
      "commit": "22b59bd5f6cdc966f15779cfb5127955aacecd14",
      "tree": "2d010fcdff42deb78a2ee72fd7822d86e601f309",
      "parents": [
        "bb09012c61ffc686a9f7ac851ed33370e82e57c1"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 17:04:59 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 17:04:59 2026 -0400"
      },
      "message": "Remove more dead code from airavata-api (#629)\n\n* chore: remove dead URL/HTML helper methods from StringUtil\n\ngetURLS, createHTMLUrlTaggedString and createHTMLUrlTaggedString2 generate portal-presentation markup, have no callers, and were the only users of the regex imports, so they and the now-unused Matcher/Pattern imports are removed.\n\n* chore: drop unused cross-domain mapper declarations from ExecutionMapper\n\nThe queueStatus and gateway toModel/toEntity methods have no callers (those conversions live in compute\u0027s ComputeMapper and iam\u0027s GatewayEntityMapper), are never used as MapStruct sub-mappers, and only pulled in four cross-module imports, so all are removed.\n\n* chore: remove unused AgentExecution entities, repositories and empty AgentMapper\n\nAgentExecutionEntity/AgentExecutionStatusEntity, their repositories and the empty AgentMapper are never read or written, so they are removed along with their two now-orphaned entries in the shared test persistence unit (which still bootstraps cleanly).\n\n* chore: remove stubbed Utility methods and SSHUtil.main\n\nUtility.encrypt always returned null and loadKeyStore/getPassword were unused (credential encryption is handled by CredentialEncryptionUtil), and SSHUtil.main was a manual test harness, so they and their now-unused imports are removed while the live generateKeyPair/validate/execute paths are kept."
    },
    {
      "commit": "bb09012c61ffc686a9f7ac851ed33370e82e57c1",
      "tree": "087bfec04ba596b007d316fdcea167ab7756b05d",
      "parents": [
        "6a0ca453d0317213b9c1e6d47d6f46b192742faa"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 16:46:56 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 16:46:56 2026 -0400"
      },
      "message": "Remove dead code from airavata-api (#628)\n\n* chore: remove dead instrumentation classes StatCounter/CountWriterTask/LatencyWriterTask\n\nThese three messaging/util classes reference only each other and have no\nexternal callers; StatCounter also spun up two Timer threads writing to\nhardcoded /tmp paths. Remove the whole unused cluster.\n\n* chore: delete unused SwingUtil AWT/Swing helper\n\nA desktop GUI helper has no place in a headless gRPC/REST server and has\nzero references.\n\n* chore: remove unwired MonitoringServer and its ServiceRegistry/ServiceStatus\n\nMonitoringServer stands up a com.sun HttpServer that is never constructed or\nregistered; metrics are served by Spring Actuator. The three classes\nreference only each other. GaugeMonitor/CountMonitor are untouched.\n\n* chore: delete unused LocalEventPublisher\n\nAn unwired Guava EventBus wrapper with no Spring stereotype and no callers;\nthe real publishers are RabbitMQ-backed.\n\n* chore: remove dead SSH-adaptor cluster from compute-service\n\nSshAgentAdaptor, StorageResourceAdaptorImpl, SshAdaptorParams and\nAdaptorParams form a closed, unreachable cluster; the live factory wires\nSSHJ adaptors exclusively. The StorageResourceAdaptor interface,\nStandardOutReader and SSHConnectionService are kept.\n\n* chore: delete unused appcatalog proto-builder helpers from compute-service\n\nAppInterfaceUtil and AppDeploymentUtil build research-service appcatalog\nprotos and have no callers."
    },
    {
      "commit": "6a0ca453d0317213b9c1e6d47d6f46b192742faa",
      "tree": "1158c91037d1ba7300c594568f3f7e5264ee2cd3",
      "parents": [
        "e9db41f83054941a69dc6bcc993fa8b5e860360b"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Jun 07 16:37:05 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Jun 07 16:37:05 2026 -0400"
      },
      "message": "Remove leftover Apache Thrift naming (#627)\n\n* refactor: rename ThriftUtils to SubTaskModelDecoder and move to task package\n\nThe class is a pure protobuf sub-task decoder with no Thrift content; the\nname was a leftover from the pre-gRPC era. Relocate it next to its only\nconsumers in the task package and update both call sites.\n\n* refactor: rename ThriftDataModelConversion to SharingModelConverter\n\nThe class only converts proto UserProfile to a sharing UserEntity; there is\nno Thrift involved. Rename to reflect what it does.\n\n* refactor: rename toThrift* converters to to*Entity in SharingGrpcService\n\nThe six private converters produce JPA *Entity types, not Thrift objects.\nRename them (and drop the Thrift-related comments) for accuracy.\n\n* chore: remove stale Thrift references from comments and parameter names\n\nDe-Thrift leftover javadoc, the AbstractRepository constructor parameter\n(thriftGenericClass -\u003e modelClass), an SSHAccountManager parameter, and four\nexception-class comments. No behavior change.\n\n* chore: remove Thrift references from proto comments\n\nComment-only edits in three protos; wire format and message identity are\nunchanged."
    },
    {
      "commit": "e9db41f83054941a69dc6bcc993fa8b5e860360b",
      "tree": "37927dc8c81be67003ac968ebf3ac055ff80c85f",
      "parents": [
        "6f0bca0796aeb08817ad106ef061dd2df5238e78"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 06 14:11:14 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 06 14:11:14 2026 -0400"
      },
      "message": "chore: reword duplicate-seed WARNs and quiet Kafka config dumps (#626)\n\nReword the idempotent-seed warnings (\"A domain with id\u003d... already exists,\nskipping recreation\") and raise the Kafka client *Config loggers to WARN so\ntheir verbose value dumps stay out of normal INFO logs (recoverable by\nsetting those loggers back to INFO)."
    },
    {
      "commit": "6f0bca0796aeb08817ad106ef061dd2df5238e78",
      "tree": "d66d7fc34e3b28d5781888f60179eace66911c88",
      "parents": [
        "bcd675749df95b3e319beb8d8350744a06b71d66"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 06 12:47:41 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 06 12:47:41 2026 -0400"
      },
      "message": "fix: seed default sharing data idempotently without ERROR noise (#625)\n\nOn every server restart against an existing DB, default-data seeding re-ran\nand SharingService.create{Domain,EntityType,PermissionType} logged the\nexpected duplicate at ERROR with a full stack trace. Make those creates\nidempotent: on an existing entry, log one clean WARN and return the existing\nid instead of throwing/wrapping. The seeder logs \"Ensured\" and surfaces\ngenuine failures at ERROR."
    },
    {
      "commit": "bcd675749df95b3e319beb8d8350744a06b71d66",
      "tree": "245efd5a087f171452222ab3f2ed2a2d2500d25a",
      "parents": [
        "a5829a069dab899dc6a56688f64715575bd9eb45"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 06 02:19:08 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 06 02:19:08 2026 -0400"
      },
      "message": "fix: eliminate server cold-start startup warnings (#624)\n\nAlign the SHARING composite-key column lengths in SharingEntity/SharingPK\nwith the V1 baseline (varchar(152)) so Hibernate ddl-auto stops trying to\nwiden them past InnoDB\u0027s 3072-byte key limit. Register Armeria\u0027s\nBeanPostProcessor as a static @Bean (excluding the library\u0027s non-static\nArmeriaBeanPostProcessorConfiguration) to remove the BPP-eligibility warning.\nThe server now cold-starts with zero WARN/ERROR."
    },
    {
      "commit": "a5829a069dab899dc6a56688f64715575bd9eb45",
      "tree": "40e7ff31415aaace63eb79afcea42087e57c8f15",
      "parents": [
        "9403d8768290659cdbd103de8bd46a376bc14d93"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 06 01:46:27 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 06 01:46:27 2026 -0400"
      },
      "message": "dev: fix DevStorage cold-start init in the containerized server (#623)\n\nMount conf/ into the server so it finds the dev SFTP keypair and the\ncredential-store keystore, and run DevStorageInitializer on\nApplicationReadyEvent so the default gateway exists before its storage\npreference is added."
    },
    {
      "commit": "9403d8768290659cdbd103de8bd46a376bc14d93",
      "tree": "5767d4fcb86c2aaeaa9464a2d9d271baf2be30c5",
      "parents": [
        "0cb57acc8b3fc232c07526ba191735ecf99e05c2"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Jun 06 00:55:50 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Jun 06 00:55:50 2026 -0400"
      },
      "message": "dev: single-container Docker-in-Docker Tilt environment with HTTPS ingress (#622)\n\nRuns the full dev stack (infra + server) inside one host-visible DinD\ncontainer with its own Docker daemon + registry, driven entirely by\n`tilt up`/`tilt down`. Traefik serves *.airavata.localhost over HTTP and\nHTTPS (mkcert). Server connection settings are injected via\nJAVA_TOOL_OPTIONS; /actuator/health is restored (Armeria actuator bridge)\nand InfrastructureHealthIndicator reads broker hosts from config instead\nof hardcoded localhost."
    },
    {
      "commit": "0cb57acc8b3fc232c07526ba191735ecf99e05c2",
      "tree": "37b644cf8aee12996ba75cee59cc312b1dcfe5c0",
      "parents": [
        "82506ff512fa13290df1d5314fae765303a28d17"
      ],
      "author": {
        "name": "yasithdev",
        "email": "yasith.j@icloud.com",
        "time": "Sun Apr 12 00:22:15 2026 -0500"
      },
      "committer": {
        "name": "yasithdev",
        "email": "yasith.j@icloud.com",
        "time": "Sun Apr 12 00:22:15 2026 -0500"
      },
      "message": "add CLAUDE.md\n"
    },
    {
      "commit": "82506ff512fa13290df1d5314fae765303a28d17",
      "tree": "e603941c58bf4e4e75314a45e1c027e3ff128c6f",
      "parents": [
        "f250f6dde8e5f37eb857b5bf3117b556ee2e4b90"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sat Apr 11 23:12:07 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Apr 11 23:12:07 2026 -0500"
      },
      "message": "fix: sharing init, storage mapping, SDK facades, and dev infra (#614)\n\n* feat: airavata server fixes, SDK facades, auto-generated SFTP keys\n\n- Fix sharing EntityRepository null-safe casting\n- Fix ResearchMapper projectId/projectID mapping\n- Update credential store encryption and key generation\n- SDK facade clients updated for gRPC service alignment\n- Tiltfile auto-generates SSH keypair for SFTP container (no static keys in repo)\n- DevStorageInitializer reads keypair from conf/sftp/ instead of generating\n- Keycloak custom theme for dev login\n- Gitignore conf/sftp/id_* generated keys\n\n* fix: use proc check instead of ss for SFTP healthcheck (ss not available in image)\n\n* fix: map DataMovementInterfaceEntity to STORAGE_INTERFACE table instead of DATA_MOVEMENT_INTERFACE"
    },
    {
      "commit": "f250f6dde8e5f37eb857b5bf3117b556ee2e4b90",
      "tree": "4625315f662f78d56a75426e9ecb4ecea82d3cbe",
      "parents": [
        "976c07d494769deb3da3a1d27516f54528029d0e"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Thu Apr 09 21:56:16 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Apr 09 21:56:16 2026 -0500"
      },
      "message": "refactor: gRPC/Armeria migration with full module boundary enforcement (#612)\n\nComplete modernization of Airavata\u0027s service architecture. Server starts\nand serves gRPC + REST on port 9090. All tests pass.\n\nCo-authored-by: Claude Opus 4.6 (1M context) \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "976c07d494769deb3da3a1d27516f54528029d0e",
      "tree": "41ac94401cb44dd096ecc055262a701a8281e98c",
      "parents": [
        "ed2986f79151f06d8ae0a4dc896c63f8a849468c"
      ],
      "author": {
        "name": "yasithdev",
        "email": "yasith.j@icloud.com",
        "time": "Tue Mar 31 02:29:48 2026 -0400"
      },
      "committer": {
        "name": "yasithdev",
        "email": "yasith.j@icloud.com",
        "time": "Tue Mar 31 02:29:48 2026 -0400"
      },
      "message": "chore: add .worktrees/ to gitignore\n"
    },
    {
      "commit": "ed2986f79151f06d8ae0a4dc896c63f8a849468c",
      "tree": "ed4c699b5a6a0c8bf54a97cd87c820e49a83b7a9",
      "parents": [
        "c933b76efe7ae44c1cf9fe2e4de81ede963b84d0"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Tue Mar 31 00:58:26 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 31 00:58:26 2026 -0400"
      },
      "message": "security: upgrade credential encryption from AES/CBC to AES/GCM (#610)\n\n* security: upgrade credential encryption from AES/CBC to AES/GCM\n\nReplace AES/CBC/PKCS5Padding with AES/GCM/NoPadding for credential\nstore encryption. The old code used a static zero IV which is insecure.\nGCM provides authenticated encryption with random IVs prepended to\nthe ciphertext.\n\nExtracted from #556.\n\n* security: add legacy AES/CBC fallback for transparent migration\n\nOn decrypt, try GCM first. If the auth tag fails (AEADBadTagException),\nfall back to the old AES/CBC/PKCS5Padding with static zero IV. This\nallows existing credentials to be read without re-encryption.\n\nCredentials will migrate to GCM format on next update/rotation —\nwrites always use AES/GCM.\n\n* test: add unit tests for GCM/CBC encryption and legacy fallback\n\n- testFallbackDecryptsLegacyCBC: CBC-encrypted data decrypted via fallback\n- testFallbackDecryptsNewGCM: GCM-encrypted data decrypted via fallback\n- testGcmDecryptRejectsLegacyData: GCM decrypt throws on CBC data\n\n* security: remove fallback, add migration script instead\n\nReplace transparent fallback with a one-time migration script\n(MigrateCredentialEncryption) that re-encrypts all CREDENTIALS rows\nfrom legacy AES/CBC to AES/GCM. Run before deploying the GCM-only code.\n\nUsage:\n  java MigrateCredentialEncryption \u003cjdbcUrl\u003e \u003cdbUser\u003e \u003cdbPass\u003e \\\n    \u003ckeystorePath\u003e \u003ckeyAlias\u003e \u003ckeystorePass\u003e\n\nThe script skips rows already in GCM format.\n\n* style: spotless:apply on MigrateCredentialEncryption\n\n* Potential fix for code scanning alert no. 129: Use of a broken or risky cryptographic algorithm\n\nCo-authored-by: Copilot Autofix powered by AI \u003c62310815+github-advanced-security[bot]@users.noreply.github.com\u003e\n\n* fix: make decryptLegacy public for cross-package access from migration script\n\n---------\n\nCo-authored-by: Copilot Autofix powered by AI \u003c62310815+github-advanced-security[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "c933b76efe7ae44c1cf9fe2e4de81ede963b84d0",
      "tree": "dbe80037d1e9dd01f377cfe313c9238e57e84b1e",
      "parents": [
        "4c545fbb6adef8209de9c9a5e9cebbc338ad9fe3"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Mon Mar 30 16:21:25 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 16:21:25 2026 -0400"
      },
      "message": "feat: add root Makefile for common build/serve targets (#611)\n\nExtracted from #556. Provides convenience targets:\n- make build: full Maven build (skip tests)\n- make serve: build + run fat JAR\n- make compile: fast compile only\n- make serve-dev: compile + spring-boot:run (hot reload)\n- make test: run test suite"
    },
    {
      "commit": "4c545fbb6adef8209de9c9a5e9cebbc338ad9fe3",
      "tree": "de1803bb94a4d25a065c9d929b241dea482645f9",
      "parents": [
        "c42a928c3848fdd3648345a4a24fa0eecdadedd4"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Mar 30 15:28:13 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:28:13 2026 -0400"
      },
      "message": "deps: bump grpc-go from 1.64.1 to 1.79.3 in airavata-agent (#605)\n\nIncludes security fix for authorization bypass via malformed :path headers. Also bumps protobuf to 1.36.10 and transitive deps."
    },
    {
      "commit": "c42a928c3848fdd3648345a4a24fa0eecdadedd4",
      "tree": "b0ee2a08711eb530b71ee731a4a65a88cdca714a",
      "parents": [
        "d4110da58f226b24e3fc4d4f61ce9bd8637c5b55"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Mar 30 15:27:14 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:27:14 2026 -0400"
      },
      "message": "deps: bump shiro-core from 2.0.4 to 2.1.0 (#588)\n\nBumps [org.apache.shiro:shiro-core](https://github.com/apache/shiro) from 2.0.4 to 2.1.0.\n- [Release notes](https://github.com/apache/shiro/releases)\n- [Changelog](https://github.com/apache/shiro/blob/main/RELEASE-NOTES)\n- [Commits](https://github.com/apache/shiro/compare/shiro-root-2.0.4...shiro-root-2.1.0)\n\n---\nupdated-dependencies:\n- dependency-name: org.apache.shiro:shiro-core\n  dependency-version: 2.1.0\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "d4110da58f226b24e3fc4d4f61ce9bd8637c5b55",
      "tree": "9fb546c2ad7b93593d75893e16319c94c2014ce5",
      "parents": [
        "2ef5e00a71b0b5747814089a3fa0dcacbff92c0f"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Mon Mar 30 15:27:01 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:27:01 2026 -0400"
      },
      "message": "deps: align all spring-boot artifacts to 3.5.12 (#609)\n\nFollow-up to #604. Aligns spring-boot-starter-web,\nspring-boot-starter-data-jpa, spring-boot-maven-plugin, and\nspring-boot-dependencies BOM to 3.5.12. All tests pass."
    },
    {
      "commit": "2ef5e00a71b0b5747814089a3fa0dcacbff92c0f",
      "tree": "f3cce1e813a98c772c8d4713c54df7a2d46a3ac3",
      "parents": [
        "6eda0b8fc238201ada7884646589a391fa8f56d1"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Mar 30 15:25:10 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:25:10 2026 -0400"
      },
      "message": "deps: bump spring-boot-starter-actuator from 3.5.3 to 3.5.12 (#604)\n\nFollow-up commit will align spring-boot-starter-web and spring-boot-starter-data-jpa to 3.5.12."
    },
    {
      "commit": "6eda0b8fc238201ada7884646589a391fa8f56d1",
      "tree": "626288753ab2112025d3fb543bba3b91fa6f5b1b",
      "parents": [
        "4009f1e04e924515bb2ff661a200f2e047dd01a5"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Mon Mar 30 15:25:04 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:25:04 2026 -0400"
      },
      "message": "deps: align jackson siblings after #590 (#608)\n\njackson-databind 2.19.1 → 2.21.1, jackson-annotations 2.19.1 → 2.19.0 (latest available). All tests pass."
    },
    {
      "commit": "4009f1e04e924515bb2ff661a200f2e047dd01a5",
      "tree": "d22f04414ad171c0c1d3636320f4da8f96c8cb42",
      "parents": [
        "0142fea17a51100ddf9049b4fbd5af3994c7fe02"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Mar 30 15:21:02 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:21:02 2026 -0400"
      },
      "message": "deps: bump jackson-core from 2.19.1 to 2.21.1 (#590)\n\nFollow-up commit will align jackson-databind and jackson-annotations to 2.21.1."
    },
    {
      "commit": "0142fea17a51100ddf9049b4fbd5af3994c7fe02",
      "tree": "3c502adf6f573852b0c616580bb11e0ea8f4d0c9",
      "parents": [
        "49d74eac9d16602b0f1b22ec0edf97ee2c13f5cf"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Mar 30 15:20:19 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:20:19 2026 -0400"
      },
      "message": "deps: bump zookeeper from 3.9.4 to 3.9.5 (#591)\n\nBumps org.apache.zookeeper:zookeeper from 3.9.4 to 3.9.5.\n\n---\nupdated-dependencies:\n- dependency-name: org.apache.zookeeper:zookeeper\n  dependency-version: 3.9.5\n  dependency-type: direct:production\n...\n\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "49d74eac9d16602b0f1b22ec0edf97ee2c13f5cf",
      "tree": "c1467ff44191b721ae957afcdc5e880af44963a3",
      "parents": [
        "47e821e0cfa92d2852837485a98676f62101ee7c"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Mon Mar 30 15:13:26 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:13:26 2026 -0400"
      },
      "message": "deps: align all log4j artifacts to 2.25.3 (#607)\n\nFollow-up to #587 — bump log4j-api, log4j-slf4j2-impl, log4j-1.2-api from 2.24.0 to 2.25.3. All 9 modules build, all tests pass."
    },
    {
      "commit": "47e821e0cfa92d2852837485a98676f62101ee7c",
      "tree": "4b69f17581c565421f9e1684edf30b924b0e470d",
      "parents": [
        "dbb1ec5756e4adbaa86c740f3594ef5a8d2afa74"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Mar 30 15:06:19 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 15:06:19 2026 -0400"
      },
      "message": "deps: bump log4j-core from 2.24.0 to 2.25.3 (#587)\n\nDependabot version bump. Follow-up commit will align log4j-api, log4j-slf4j2-impl, and log4j-1.2-api to 2.25.3."
    },
    {
      "commit": "dbb1ec5756e4adbaa86c740f3594ef5a8d2afa74",
      "tree": "ebd21ef26182bd22e1d33929bd1c200dab1d5247",
      "parents": [
        "f45854ae85ce48803d4164e29e284342d346d484"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Mon Mar 30 14:23:37 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 14:23:37 2026 -0400"
      },
      "message": "reliability: consolidate monitoring, migrate JDBC, fix JPA, harden startup/shutdown (#603)\n\nConsolidate 4 redundant MonitoringServer instances into unified :9097. Bridge Spring datasource into legacy JDBC config (single source of truth). Switch to Spring Boot auto-configured JPA with @EntityScan + PhysicalNamingStrategyStandardImpl. Replace wurstmeister/kafka with apache/kafka:3.9.0 (KRaft). Add compose healthchecks, graceful shutdown, HikariCP resilience, infrastructure health indicator."
    },
    {
      "commit": "f45854ae85ce48803d4164e29e284342d346d484",
      "tree": "58d3b9a4afa1973f9e677f7f2b77dceb539790b6",
      "parents": [
        "b41fbfa93ff224144a7eeae55f051e06d28a7277"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Mon Mar 30 11:41:29 2026 -0400"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Mar 30 11:41:29 2026 -0400"
      },
      "message": "cleanup: lean core — remove dead code, fix cold-start, align docs (#602)\n\nPost-server-collapse cleanup: remove dead dev-tools (PHP SDK, amqpwstunnel, simstream, job-status-rest-server), promote airavata-python-sdk to top level, consolidate load-client as Python, delete airavata-fuse, clean examples, remove @Deprecated code, triage TODOs/FIXMEs, prune Maven deps, fix unified server cold-start (fat JAR, actuator, Hibernate 6.6 compatibility, config consolidation), update all docs/scripts/Dockerfile/Ansible for unified architecture, sync properties.\n\nCo-Authored-By: Claude Opus 4.6 (1M context) \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "b41fbfa93ff224144a7eeae55f051e06d28a7277",
      "tree": "94b1d80ddb65b513bfb72307c92db1350c73b167",
      "parents": [
        "fdffece4ff7c95c7b79becb7f3ef66756fcf448f"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Sun Mar 29 15:34:39 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Mar 29 15:34:39 2026 -0500"
      },
      "message": "refactor: collapse servers, flatten modules, MapStruct, parallel tests (#601)\n\n* refactor: move module libraries under airavata-api as sub-modules\n\n* refactor: collapse server modules into airavata-server sub-modules\n\nMove airavata-rest-server, airavata-grpc-server, and airavata-thrift-server\ninto airavata-server/{rest,grpc,thrift}/ sub-modules with unified package\nnamespace org.apache.airavata.server.{rest,grpc,thrift}.\n\n* refactor: replace RegistryService Thrift clients with direct handler injection\n\nReplace all internal ThriftClientPool\u003cRegistryService.Client\u003e and\nRegistryServiceClientFactory usages in airavata-api with direct calls\nto the RegistryServerHandler @Component via RegistryService.Iface.\n\nThe handler is registered as a global static reference via Utils.setRegistryHandler()\nfrom a @PostConstruct in RegistryServerHandler. All pool/factory patterns\n(getResource/returnResource/returnBrokenResource, ThriftUtils.close) are removed.\n\n* refactor: replace CredentialStore and Profile Thrift clients with direct injection\n\n- Replace CredentialStoreClientFactory usages with direct CredentialStoreServerHandler\n  instantiation in SSHAccountManager, GatewayGroupsInitializer, AgentUtils,\n  IamAdminServicesHandler, TenantProfileServiceHandler, and AiravataDataMigrator\n- Replace ProfileServiceClientFactory usages:\n  - AiravataTask/TaskContext: use UserProfileRepository directly instead of\n    UserProfileService Thrift client (avoids circular dep with airavata-server)\n  - UserProfileServiceHandler: use IamAdminServicesHandler directly\n  - AiravataDataMigrator: use TenantManagementKeycloakImpl directly\n  - AiravataService (research-service): use UserProfileRepository directly\n- Remove unused getCredentialStoreServiceClient from KeyCloakSecurityManager\n- Delete CredentialStoreClientFactory (no remaining references)\n- Keep ProfileServiceClientFactory (still used by example clients)\n\n* refactor: replace remaining Thrift client factories with direct injection\n\nReplace RegistryServiceClientFactory usages in SSHAccountManager,\nAiravataDataMigrator, KeyCloakSecurityManager, GatewayGroupsInitializer,\nOrchestratorServerHandler, and IamAdminServicesHandler with direct\nRegistryServerHandler instantiation. Remove SharingRegistryServiceClientFactory\nand update GroupManagerServiceHandler and SharingServiceDBEventHandler likewise.\n\n* refactor: replace Thrift clients in sub-modules with direct service calls\n\n* refactor: update Tiltfile for restructured module layout\n\n* style: apply spotless formatting\n\n* refactor: consolidate 6 persistence units into single Spring-managed EntityManagerFactory\n\n- Delete 7 JPAUtils classes, 4 catalog-specific abstract repos, 6 JDBCConfig impls\n- Create EntityManagerFactoryHolder (static bridge) + EntityManagerFactoryRegistrar (@Component)\n- 52 concrete repos now extend base AbstractRepository directly\n- Fix ~70 entity classes for Hibernate 6 column mapping strictness\n- Test persistence.xml (test-scope) with single \"airavata\" unit\n- 199 unit tests pass, 0 failures\n\n* fix: resolve Hibernate 6 entity mapping errors for @IdClass entities\n\nReplace @Transient with proper @ManyToOne @JoinColumn(insertable\u003dfalse, updatable\u003dfalse)\non 48 fields across 47 entity files. Fix duplicate column mappings.\nIntegration tests: 50 pass, 18 errors (test data issues), 33 skipped.\n\n* refactor: restore non-Java modules at top level, move proto to src/main/proto\n\nRecover directories lost in 384281df7a when modules/ was removed:\n- modules/agent-framework/airavata-agent → airavata-agent/\n- modules/agent-framework/airavata-fuse → airavata-fuse/\n- modules/research-framework/research-hub → airavata-jupyterhub/\n- modules/research-framework/simexr_mod → dev-tools/simexr_mod/\n\nMove agent-service proto files to src/main/proto/ for consistency\nwith research-service layout, and update pom.xml sourceDirectory.\n\n* build: configure surefire to fail on first error (skipAfterFailureCount\u003d1)\n\n* fix: resolve all integration test failures for Hibernate 6\n\n- Fix JPQL alias case mismatch (dp → DP) in QueryConstants\n- Fix ComputeResourceRepository remove operations using orphanRemoval\n- Fix SharingRegistry cascade (remove CascadeType.PERSIST from UserGroupEntity.groupAdmins)\n- Fix AbstractRepository.get() with FlushMode.MANUAL to prevent cascade-persist\n- Fix AbstractRepository.select() to call initializeEntity on results\n- Replace PersistentMap with HashMap in DataReplicaLocationRepository.initializeEntity\n- Fix DataReplicaLocationRepositoryTest to avoid duplicate key insertion\n\nIntegration tests: 102 run, 0 failures, 0 errors, 33 skipped\nUnit tests: 199 run, 0 failures, 0 errors, 26 skipped\n\n* build: upgrade surefire 3.5.5, JUnit parallel, clean test profiles, merge integration-tests\n\n- Surefire 3.5.5 with forkCount\u003d1C (1 fork per CPU)\n- JUnit 5 parallel execution for unit tests (concurrent classes + methods)\n- @Execution(SAME_THREAD) on non-thread-safe tests (DB, SFTP, ServiceLoader)\n- Clean profile split: mvn test (unit, parallel), mvn test -Pintegration (sequential)\n- @Tag(\"runtime\") for health checks that need full tilt stack\n- Merge integration-tests module into airavata-api test sources\n- Fix SharedMariaDBLauncherSessionListener to detect surefire.groups property\n- Remove build cache extension (Java 25 incompatible)\n\nUnit: 182 pass, 0 fail | Integration: 119 pass, 0 fail\n\n* test: re-enable disabled tests that work with Hibernate 6 and single EMF\n\nEnable SharingServiceIntegrationTest (13 tests) and WorkflowRepositoryTest\n(1 test) which now pass with the consolidated persistence setup. Fix test\nlogic in addAndRemoveGroupAdmin (user must be group member before admin).\nUpdate @Disabled reasons on remaining tests to reflect actual root causes\n(Dozer mapping, FK constraints, test isolation).\n\n* test: re-enable 14 disabled tests, update reasons on remaining 19\n\n- Enable SharingServiceIntegrationTest (13 tests) — single EMF resolved caching issue\n- Enable WorkflowRepositoryTest (1 test) — works with Hibernate 6\n- Fix addAndRemoveGroupAdmin test — user must be added to group before admin\n- Remaining 19 disabled: all Dozer mapping issues (MapStruct migration needed)\n\nUnit: 182 pass, 0 fail, 26 skip | Integration: 119 pass, 0 fail, 19 skip\n\n* perf: eager Dozer init, dynamic SFTP port, remove unnecessary SAME_THREAD\n\n- ObjectMapperSingleton: eager static init (eliminates 2-3s first-test penalty)\n- SFTPDeleteDirTest: use OS-assigned port (no more port conflicts, can run parallel)\n- Fixes race condition in ObjectMapperSingleton (was lazy init without synchronization)\n\nUnit: 52s wall clock, 182 pass | Integration: 2:45, 119 pass\n\n* refactor: replace Dozer with MapStruct for entity-model mapping\n\n5 MapStruct mappers replacing runtime Dozer reflection with compile-time code.\n63 repos updated, 3 AbstractRepository bases cleaned, Dozer dependency removed.\n\nUnit: 179 pass, 0 fail | Integration: 119 pass, 0 fail\n\n* perf: per-test transaction rollback for parallel integration tests\n\nReplace truncate-all-tables cleanup with per-test transaction rollback:\n- EntityManagerFactoryHolder: ThreadLocal test EntityManager support\n- 3 AbstractRepository bases: test mode skips transaction management\n- TestBase: @BeforeEach begins transaction, @AfterEach rolls back\n- 33 test constructors updated (removed Database enum)\n- Integration profile: classes run in parallel (ForkJoinPool)\n\nIntegration tests: 2:23 (was 2:45) — 22s saved from parallelism\nUnit: 179 pass | Integration: 119 pass | 0 failures\n\n* test: re-enable 5 disabled tests after MapStruct migration, fix mapper gaps\n\nRe-enabled tests:\n- ComputeResourceRepositoryTest: listComputeResourcesTest, updateComputeResourceTest,\n  addComputeResourceTest, addUnicoreDataMovementTest\n- ExperimentStatusRepositoryTest: ExperimentStatusRepositoryTest\n\nMapper fixes:\n- BatchQueue: maxRuntime \u003c-\u003e maxRunTime field name mismatch\n- UnicoreDataMovement: unicoreEndpointUrl \u003c-\u003e unicoreEndPointURL mismatch\n- ApplicationDeployment: defaultWallTime \u003c-\u003e defaultWalltime mismatch\n- UserResourceProfile: gatewayId \u003c-\u003e gatewayID mismatch\n- GatewayResourceProfile: gatewayId \u003c-\u003e gatewayID mismatch\n\nJPA fixes:\n- Add insertable\u003dfalse to @JoinColumn on GroupComputeResourcePrefEntity,\n  BatchQueueResourcePolicyEntity, ComputeResourcePolicyEntity to prevent\n  duplicate column mapping with @Id fields\n\nUpdated @Disabled reasons on 14 remaining tests to reflect actual root causes.\n\n* perf: cascading FK deletes, fully parallel integration tests\n\nAdd @OneToMany(cascade\u003dALL, orphanRemoval\u003dtrue) on ResourceJobManagerEntity\nfor JobManagerCommandEntity and ParallelismCommandEntity children, enabling\ncascading deletes. Re-enable deleteResourceJobManagerTest.\n\nSwitch integration test parallelism from same_thread to concurrent for methods,\nincrease dynamic factor to 2, add forkCount\u003d1C. Guard deadlock-prone tests\n(ApplicationInterfaceRepositoryTest, SharingServiceIntegrationTest,\nDatabaseTestCases) with @Execution(SAME_THREAD)."
    },
    {
      "commit": "fdffece4ff7c95c7b79becb7f3ef66756fcf448f",
      "tree": "49a23bf8e086cbeb0d6403bc02b3ec29ba33b653",
      "parents": [
        "3a022a552397f3f92f89f80f9397b47e34708a9a"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Fri Mar 27 23:00:28 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 27 23:00:28 2026 -0500"
      },
      "message": "refactor: unified transport servers — Spring module reorganization (#600)\n\n* feat: add @ConditionalOnServer, AiravataServerProperties, unified UserContext\n\n* refactor: migrate airavata-api from OpenJPA to Hibernate\n\nReplace OpenJPA dependency, bytecode enhancement plugin, and\n@ForeignKey annotations with Hibernate equivalents (@OnDelete).\nDelete persistence.xml — no longer needed with Hibernate runtime\nproxies. EntityManagerFactory usage in JPAUtils noted but left for\nthe Spring Boot wrapping task.\n\n* refactor: convert research-service from standalone Boot app to plain library\n\n* refactor: convert agent-service from standalone Boot app to plain library\n\n- Remove spring-boot-maven-plugin, maven-assembly-plugin, and actuator dependency\n- Add AgentServiceConfig for component scanning, entity scanning, JPA repos\n- Add AgentProperties (@ConfigurationProperties) replacing @Value annotations\n- Replace local UserContext with unified org.apache.airavata.common.security.UserContext\n- Delete AgentServiceApplication, AuthzTokenFilter, application.yml, assembly descriptor\n\n* refactor: convert file-server to plain library, normalize paths to /api/v1/files/*\n\n* feat: create airavata-rest-server, absorb restproxy, centralize auth + OpenAPI\n\n* feat: create airavata-grpc-server with centralized gRPC auth interceptor\n\n* refactor: wrap airavata-thrift-server in Spring Boot with SmartLifecycle\n\nReplace the custom main() bootstrap in AiravataServer.java with\nSpring-managed components:\n\n- AiravataThriftServerConfig: @ConditionalOnServer(\"thrift\") entry point\n- ThriftProcessorConfig: builds TMultiplexedProcessor as a @Bean\n- ThriftServerLifecycle: SmartLifecycle that manages TThreadPoolServer\n- BackgroundServicesConfig: @PostConstruct DB initialization\n\nAll handlers annotated with @Component. OrchestratorServerHandler\ncreated via @Bean factory with graceful fallback on init failure.\nBackground services (Helix, monitoring, etc.) deferred to future task.\n\n* feat: create unified airavata-server launcher with distribution assembly\n\n* refactor: update Tiltfile for unified server startup\n\nReplace 5 separate service definitions (airavata-server, research-service,\nagent-service, file-server, rest-proxy) with a single unified airavata-server\nentry. Update build deps to track new server modules.\n\n* chore: remove stale assembly descriptors from airavata-api\n\nThe unified airavata-server module now produces the distribution tarball,\nso the assembly plugin and descriptor files in airavata-api are no longer needed."
    },
    {
      "commit": "3a022a552397f3f92f89f80f9397b47e34708a9a",
      "tree": "2f8fd2892414fe2ed3d8d9bd7c9d31a5411d75a4",
      "parents": [
        "036898e315d676b5c6d0e04857427913223ee17c"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Fri Mar 27 21:17:49 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 27 21:17:49 2026 -0500"
      },
      "message": "refactor: Phase 3 — execution module, Testcontainers, Java 25 deps\n\nReorganizes remaining classes into execution module, replaces Derby with Testcontainers MariaDB, fixes all tests (301 pass, 0 fail), updates deps for Java 25."
    },
    {
      "commit": "036898e315d676b5c6d0e04857427913223ee17c",
      "tree": "560cb7e18a13af9dbd4c686df5d9e1c6b9201d35",
      "parents": [
        "b8a3c53bd2e185770c9e3e459399357ca1389b5d"
      ],
      "author": {
        "name": "yasithdev",
        "email": "yasith.j@icloud.com",
        "time": "Fri Mar 27 15:00:26 2026 -0500"
      },
      "committer": {
        "name": "yasithdev",
        "email": "yasith.j@icloud.com",
        "time": "Fri Mar 27 15:00:26 2026 -0500"
      },
      "message": "refactor: Phase 2 — reorganize mid-tier modules (credential, storage, compute)\n\nCreates three decoupled domain modules in airavata-api:\n\n- credential/ (47 files) — SSH/password/cert store, account provisioning\n- storage/ (43 files) — Storage resources, data movement, staging tasks\n- compute/ (162 files) — Compute resources, app catalog, job submission tasks\n\nAbsorbs: credential/store/**, accountprovisioning/**, agents/**,\nregistry/core/entities/appcatalog/**, registry/core/repositories/appcatalog/**,\nregistry/core/entities/replicacatalog/**, helix/impl/task/submission/**,\nhelix/impl/task/staging/{DataStaging,Input,Output,Archive}*,\nhelix/adaptor/**, helix/agent/**\n\nAlso updates Tiltfile to use mvn install (needed for spring-boot:run).\n"
    },
    {
      "commit": "b8a3c53bd2e185770c9e3e459399357ca1389b5d",
      "tree": "95cfaffaab3a187acc8b2c4ee23eccc23bc3a554",
      "parents": [
        "f1872d30d5bc34e7e8a7998db200c9f46299b502"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Fri Mar 27 12:15:25 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 27 12:15:25 2026 -0500"
      },
      "message": "refactor: Phase 1 — reorganize leaf modules (common, messaging, security, sharing) (#597)\n\n* refactor: reorganize o.a.a.common into config/, db/, util/, server/ packages\n\nRestructure the common package for better separation of concerns:\n- common/config/: ApplicationSettings, ServerSettings, Constants, WSConstants,\n  ZkConstants, ExecutionMode, RequestContext (from common/utils/ and common/context/)\n- common/db/: DBUtil, JPAUtils, JDBCConfig, DBInitConfig, DBInitializer, DerbyUtil\n  (from common/utils/)\n- common/util/: AiravataUtils, IOUtil, JSONUtil, ThriftUtils, ThriftClientPool,\n  Pair, StringUtil, NameValidator, Version (from common/utils/),\n  AiravataClientFactory (from api/client/)\n- common/server/: IServer, KeyStorePasswordCallback, DefaultKeyStorePasswordCallback\n  (from common/utils/), MonitoringServer, ServiceRegistry, ServiceStatus,\n  CountMonitor, GaugeMonitor (from patform/monitoring/)\n\nDomain-specific classes left in common/utils/ for later phases:\nSecurityUtil, AiravataJobState, DBEventManagerConstants, DBEventService,\nLocalEventPublisher, SwingUtil. WorkflowContext stays in common/context/.\n\n* refactor: reorganize o.a.a.messaging into service/handler/util layers\n\nConsolidate messaging infrastructure from messaging/core/, messaging/client/,\nservice/messaging/, db/event/manager/, and common/utils/ into a layered\nmessaging/ package structure:\n\n- messaging/service/ — core interfaces (Publisher, Subscriber, MessageHandler,\n  MessageContext, MessagingFactory, Type), implementations (RabbitMQPublisher,\n  RabbitMQSubscriber), and event publishers (EventPublisher, LocalEventPublisher)\n- messaging/handler/ — consumers (MessageConsumer, ExperimentConsumer,\n  ProcessConsumer, StatusConsumer), listeners (RabbitMQListener, TestReader),\n  and DB event managers (DBEventManagerRunner, DBEventManagerMessagingFactory,\n  DBEventMessageHandler)\n- messaging/util/ — properties (RabbitMQProperties), constants\n  (MessagingConstants, DBEventConstants, DBEventManagerConstants), stats\n  (StatCounter, LatencyWriterTask, CountWriterTask), and utilities\n  (DBEventPublisherUtils, DbEventManagerZkUtils, DBEventService,\n  DBEventManagerException)\n\nRename db.event.manager.utils.Constants → DBEventConstants to avoid collision.\nDelete empty source directories.\n\n* refactor: reorganize o.a.a.security into repository/service/util/profile layers\n\nMove security-related classes into consolidated package structure:\n- security/repository/: JDBC, LDAP, Session user store implementations\n- security/util/: auth primitives, configuration readers, SecurityUtil\n- security/service/: security managers, identity context, authz cache, interceptors\n- security/profile/: profile service (client, commons, IAM, tenant, user)\n\n* refactor: consolidate sharing into o.a.a.sharing with model/repository/service/handler/util layers\n\nMove sharing registry files from deeply nested sharing/registry/ subtree and\nservice/sharing/ into flat o.a.a.sharing/{model,repository,service,handler,util}.\nRename Constants.java to SharingConstants.java to avoid collision.\nDelete empty sharing/registry/ and service/sharing/ directories.\nUpdate all imports across airavata-api, airavata-thrift-server, and persistence.xml.\n\n* fix: update stale imports in test files after package reorganization\n\nTest files under src/test/java were not updated during the main\nsource reorganization (mvn compile only compiles main sources).\nFixes imports for sharing, security, common, and messaging packages\nin test classes. Moves ResourceSharingServiceTest to new package.\n\n* fix: correct over-broad service.profile → security.profile rewrites\n\nThrift-generated CPI classes (service.profile.*.cpi) and\nthrift-server handlers (service.profile.handlers) should not have\nbeen rewritten to security.profile. Only the non-CPI source files\nin airavata-api/src/main/java were meant to move.\n\nFixes package declarations in thrift-server handlers, CPI imports\nin AiravataDataMigrator, AiravataTask, and example clients."
    },
    {
      "commit": "f1872d30d5bc34e7e8a7998db200c9f46299b502",
      "tree": "005c76de57caac800656d80161539bc94726505c",
      "parents": [
        "b9960950f17848ad7cff60e82bcfa499cd5e7eb2"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Thu Mar 26 17:10:18 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 26 17:10:18 2026 -0500"
      },
      "message": "AIRAVATA-3981: Add integration health check — ServiceRegistry, monitoring endpoints, Tiltfile, test suite (#596)\n\n* feat: add ServiceRegistry and ServiceStatus for background service tracking\n\n* feat: add /health/services and /admin/restart endpoints to MonitoringServer\n\n* refactor: use ServiceRegistry in AiravataServer for background service lifecycle\n\n* feat: add Tiltfile for dev orchestration and integration testing\n\n* feat: add integration-tests Maven module scaffold\n\n* feat: add ThriftServiceHealthTest for all 9 multiplexed services\n\n* feat: add Database, RabbitMQ, and Kafka integration health tests\n\n* feat: add Keycloak and Prometheus integration health tests\n\n* feat: add ServiceHealthEndpoint and BackgroundServiceHealth integration tests\n\n* chore: final cleanup — gitignore docs/superpowers, fix health endpoint format\n\n- Wrap /health/services response in {\"services\": {...}} per spec\n- Update ServiceHealthEndpointTest and BackgroundServiceHealthTest to\n  unwrap the \"services\" key before asserting on service entries\n- Add docs/superpowers/ to .gitignore and remove already-committed files\n  from git tracking (local copies preserved)\n\n* style: apply spotless formatting to MonitoringServer and integration tests\n\n* fix: ServiceRegistry uses IServer.getStatus() for health, add actuator to Spring Boot services\n\n- ServiceRegistry now checks IServer.getStatus() \u003d\u003d STARTED in addition to\n  Thread.isAlive(), fixing false DOWN for services like PostWorkflowManager\n  that spawn sub-threads and let their main thread exit\n- Add spring-boot-starter-actuator to all 4 Spring Boot modules with\n  /actuator/health endpoint exposed\n- Update Tiltfile to use spring-boot:run for Spring Boot services\n- All 8/8 background services + 4/4 Spring Boot services report UP\n\n* docs: update README for thrift-server split, Tiltfile, health monitoring\n\n- Update architecture diagram to show airavata-thrift-server + airavata-api split\n- Replace scripts/start.sh quick start with tilt up\n- Add health monitoring endpoints table (/health/services, /admin/restart)\n- Add integration tests section\n- Update Spring Boot services table with ports and gRPC\n- Replace ide-integration IDE setup with Tilt-based workflow\n- Update workspace CLAUDE.md to include airavata project"
    },
    {
      "commit": "b9960950f17848ad7cff60e82bcfa499cd5e7eb2",
      "tree": "3c775929342d76702c82b8217f2c2960a6a23950",
      "parents": [
        "49ac3ea9ee824179cd5b83214d3170239bd2036f"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Thu Mar 26 15:21:45 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 26 15:21:45 2026 -0500"
      },
      "message": "Extract thrift server into airavata-thrift-server module (#595)\n\n* docs: add airavata-thrift-server extraction design spec\n\n* docs: add airavata-thrift-server extraction implementation plan\n\n* feat: add airavata-thrift-server Maven module scaffold\n\n* refactor: move thrift IDL to airavata-thrift-server/src/main/thrift\n\n* refactor: move AiravataServer and Constants to airavata-thrift-server\n\n* refactor: move AiravataServerHandler and ThriftAdapter to airavata-thrift-server\n\n* refactor: move profile handlers and OrchestratorServerHandler to airavata-thrift-server\n\n* feat: add proto definitions mirroring all thrift IDL data models\n\n33 proto3 files covering all thrift data-models, API commons, security,\nerrors, messaging, and db events. Mechanical 1:1 translation preserving\nfield numbers and structure.\n\n* build: add protobuf-java dependency and protoc compilation to airavata-api\n\n- Add protobuf-java dependency (version managed in root POM at 4.30.1)\n- Add protobuf-maven-plugin with protocVersion 4.30.1 and explicit source dir\n- Fix enum value conflict in compute_resource.proto: rename CLOUD in\n  JobSubmissionProtocol to JSP_CLOUD to avoid C++ scoping collision\n  with CLOUD in ResourceJobManagerType (same package scope)\n- Add .proto suffix to java_package in all 33 proto files to prevent\n  duplicate class errors from identically-named thrift and proto generated\n  classes (e.g. org.apache.airavata.model.workspace.Project)\n\n* build: add MapStruct dependency to airavata-thrift-server\n\n- Add mapstruct and mapstruct-processor 1.6.3 to root dependencyManagement\n- Add mapstruct runtime dependency to airavata-thrift-server\n- Wire mapstruct-processor as annotationProcessorPath on maven-compiler-plugin\n  so MapStruct annotation processing runs at compile time\n\n* fix: rename proto fields to avoid Protobuf 4.x Java codegen name collision\n\nStorageVolumeInfo and StorageDirectoryInfo had int64 fields named\ntotal_size_bytes / used_size_bytes / available_size_bytes alongside string\nfields total_size / used_size / available_size. Protobuf 4.x generates\na raw-bytes accessor getXxxBytes() for each string field, which collides\nwith the generated getLong getter for the _bytes int64 fields.\n\nRenamed int64 fields to use _byte_count suffix instead.\n\n* feat: add representative MapStruct mapper for workspace types\n\nWorkspaceMapper maps bidirectionally between:\n- Thrift: org.apache.airavata.model.workspace.Project\n- Proto:  org.apache.airavata.model.workspace.proto.Project\n\nKey design decisions:\n- @ObjectFactory provides Project.newBuilder() since protobuf builders\n  have no public no-arg constructor for MapStruct to invoke\n- Repeated fields (sharedUsers, sharedGroups) handled via @AfterMapping\n  using builder.addAllXxx() to avoid MapStruct attempting to instantiate\n  the abstract ProtocolStringList type\n- protoToThrift wraps ProtocolStringList into ArrayList naturally\n\n* chore: final cleanup after thrift server extraction\n\nUpdate ide-integration launchers to reflect consolidated server architecture:\n- APIServerStarter: replace removed AiravataAPIServer/OrchestratorServer/ProfileServiceServer\n  references with the consolidated AiravataServer from airavata-thrift-server\n- JobEngineStarter / JobMonitorStarter: fix startServer() calls to use the IServer\n  (Runnable) contract — wrap each service in a named Thread instead\n- ide-integration/pom.xml: add airavata-thrift-server dependency so AiravataServer\n  is resolvable at compile time"
    },
    {
      "commit": "49ac3ea9ee824179cd5b83214d3170239bd2036f",
      "tree": "9539cd5b18f51a0f0f27a9c8b4f1e7a09fdb97e8",
      "parents": [
        "dea11f4ad3e19abc5564db39b05a7b9f63cb3795"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Thu Mar 26 13:19:59 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 26 13:19:59 2026 -0500"
      },
      "message": "feat: extract transport-agnostic service layer from Thrift handlers (#594)\n\n* build: add mockito test dependencies to airavata-api\n\n* feat: add RequestContext for transport-agnostic identity\n\n* feat: add service exception hierarchy\n\n* feat: add EventPublisher wrapping messaging infrastructure\n\n* feat: add ExperimentService with createExperiment and getExperiment\n\nExtracts experiment business logic from AiravataServerHandler into a\nclean service class with explicit dependency injection. Uses isSharingEnabled()\nhelper to safely default to false when the setting is absent.\n\n* feat: add remaining ExperimentService methods\n\n* feat: add ThriftAdapter for DRY exception translation\n\n* refactor: rewire AiravataServerHandler experiment methods to ExperimentService\n\n* feat: add GatewayService and NotificationService\n\nExtract gateway and notification business logic from AiravataServerHandler\ninto GatewayService and NotificationService with full Mockito test coverage.\n\n* refactor: rewire handler gateway and notification methods to service layer\n\nReplace inline gateway and notification method bodies in AiravataServerHandler\nwith ThriftAdapter one-liners delegating to GatewayService and NotificationService.\n\n* feat: add CredentialService\n\nExtract credential business logic from AiravataServerHandler into\nCredentialService, using RequestContext instead of AuthzToken claims\nand direct sharingHandler.userHasAccess() for permission checks.\n\n* refactor: rewire handler credential methods to service layer\n\nReplace all 6 credential method bodies in AiravataServerHandler with\nThriftAdapter one-liners delegating to CredentialService.\n\n* feat: add ProjectService\n\nExtracts createProject, updateProject, deleteProject, getProject,\ngetUserProjects, and searchProjects business logic from AiravataServerHandler\ninto a dedicated ProjectService following the established service layer pattern.\n\n* refactor: rewire handler project methods to service layer\n\nReplace the inline business logic in all 6 project methods\n(createProject, updateProject, deleteProject, getProject,\ngetUserProjects, searchProjects) with ThriftAdapter one-liners\ndelegating to ProjectService.\n\n* feat: add ResourceService for compute, storage, job submission, and data movement\n\nExtracts all resource-related registry delegates into ResourceService covering compute resources, storage resources, job submission interfaces (LOCAL, SSH, SSHFork, Cloud, UNICORE), data movement interfaces (LOCAL, SCP, UNICORE, GridFTP), resource job managers, and batch queues. Includes 16 unit tests covering each sub-domain.\n\n* refactor: rewire handler resource methods to service layer\n\nReplace all compute resource, storage resource, job submission, data movement, resource job manager, and batch queue method bodies in AiravataServerHandler with ThriftAdapter one-liners delegating to ResourceService.\n\n* feat: add ApplicationCatalogService\n\nExtracts application module, deployment, and interface logic from\nAiravataServerHandler into a dedicated service layer class, including\nsharing/permission logic for deployments. Adds 15 unit tests covering\nall three sub-domains.\n\n* feat: add remaining experiment methods to ExperimentService\n\nAdds getExperimentStatistics, getExperimentsInProject, getUserExperiments,\ngetDetailedExperimentTree, updateExperiment, updateExperimentConfiguration,\nupdateResourceScheduleing, validateExperiment, getJobStatuses, getJobDetails.\nRewires corresponding AiravataServerHandler methods to ThriftAdapter one-liners.\n\n* feat: add GatewayResourceProfileService\n\nExtracts all gateway resource profile operations (CRUD, compute/storage\npreferences, SSH account provisioners) from AiravataServerHandler into\nGatewayResourceProfileService. Rewires handler methods to ThriftAdapter\none-liners.\n\n* feat: add UserResourceProfileService\n\nExtracts all user resource profile operations (CRUD, compute/storage\npreferences, queue statuses) from AiravataServerHandler into\nUserResourceProfileService. Rewires handler methods to ThriftAdapter\none-liners.\n\n* refactor: rewire handler experiment and resource profile methods to service layer\n\nRewires all remaining experiment methods (getExperimentStatistics, getExperimentsInProject,\ngetUserExperiments, getDetailedExperimentTree, updateExperiment, updateExperimentConfiguration,\nupdateResourceScheduleing, validateExperiment, getJobStatuses, getJobDetails) and all gateway\nand user resource profile methods in AiravataServerHandler to ThriftAdapter one-liners\ndelegating to the new service classes.\n\n* feat: add DataProductService with ThriftAdapter wiring\n\nExtracts registerDataProduct, getDataProduct, registerReplicaLocation,\ngetParentDataProduct, and getChildDataProducts into DataProductService.\nRewires AiravataServerHandler to delegate via ThriftAdapter.\n\n* feat: add ResourceSharingService with ThriftAdapter wiring\n\nExtracts shareResourceWithUsers, shareResourceWithGroups, revoke* variants,\ngetAllAccessible*/getAllDirectlyAccessible* methods, and userHasAccess into\nResourceSharingService. Rewires AiravataServerHandler to delegate via ThriftAdapter.\n\n* feat: add GroupResourceProfileService with ThriftAdapter wiring\n\nExtracts createGroupResourceProfile (with sharing rollback), updateGroupResourceProfile,\ngetGroupResourceProfile, removeGroupResourceProfile, getGroupResourceList, removeGroupCompute*,\ngetGroupCompute*/getBatchQueue*, and getGatewayGroups into GroupResourceProfileService.\nIncludes credential validation and sharing entity management.\nRewires AiravataServerHandler to delegate via ThriftAdapter.\n\n* feat: add ParserService with ThriftAdapter wiring\n\nExtracts getParser, saveParser, listAllParsers, removeParser, getParsingTemplate,\ngetParsingTemplatesForExperiment, saveParsingTemplate, removeParsingTemplate, and\nlistAllParsingTemplates into ParserService.\nRewires AiravataServerHandler to delegate via ThriftAdapter.\n\n* feat: migrate remaining experiment methods to service layer\n\n- Add isUserExists to GatewayService\n- Add fetchIntermediateOutputs, getIntermediateOutputProcessStatus, and launchExperiment to ExperimentService\n- Add tests for new methods in ExperimentServiceTest and GatewayServiceTest\n\n* refactor: replace handler methods with ThriftAdapter one-liners and delete orphaned helpers\n\n- isUserExists, fetchIntermediateOutputs, getIntermediateOutputProcessStatus, and launchExperiment now delegate to service layer\n- Delete orphaned private helpers: validateString, submitExperiment, submitCancelExperiment, submitExperimentIntermediateOutputsEvent, shareEntityWithAdminGatewayGroups, userHasAccessInternal, getResourceType, createManageSharingPermissionTypeIfMissing, retrieveGatewayGroups\n\n* fix: add proper admin group validation to ResourceSharingService\n\n- Accept RegistryServerHandler in constructor (backwards-compatible overload kept)\n- Implement retrieveGatewayGroups helper using registry\n- validateAdminGroupNotRevoked now checks actual GatewayGroups admin group id\n- Pass registryHandler from AiravataServerHandler constructor\n\n* refactor: extract shared helpers to SharingHelper utility class\n\nConsolidate duplicated isSharingEnabled(), userHasAccess(),\nretrieveGatewayGroups(), shareEntityWithAdminGatewayGroups(), and\ncreateManageSharingPermissionTypeIfMissing() from ExperimentService,\nProjectService, CredentialService, ApplicationCatalogService,\nGatewayService, GroupResourceProfileService, and ResourceSharingService\ninto a single SharingHelper utility class.\n\n* fix: map ServiceNotFoundException to AiravataSystemException in ThriftAdapter\n\nServiceNotFoundException was incorrectly mapped to ExperimentNotFoundException,\nwhich is semantically wrong for non-experiment resources. Map to\nAiravataSystemException with a \"not found\" prefix message instead, since\nthere is no generic Thrift not-found exception type.\n\n* refactor: extract initialization from AiravataServerHandler constructor\n\nMove initSharingRegistry() and postInitDefaultGateway() calls out of the\nconstructor into a new public initialize() method. The constructor now only\nwires dependencies, while initialization side effects are deferred to\ninitialize(), which is called explicitly by AiravataServer after construction.\n\n* refactor: move storage info business logic from handler to ResourceService\n\nMigrated getResourceStorageInfo, getStorageDirectoryInfo, resolveComputeStorageInfoContext,\nand resolveStorageStorageInfoContext from AiravataServerHandler into ResourceService. Handler\nmethods are now pure ThriftAdapter one-liners. ResourceService gains a GroupResourceProfileService\ndependency for the group preference fallback chain.\n\n* feat: add SSHAccountService for SSH account management\n\nExtracted doesUserHaveSSHAccount, isSSHSetupCompleteForUserComputeResourcePreference,\nand setupUserComputeResourcePreferencesForSSH from AiravataServerHandler into a dedicated\nSSHAccountService. Handler methods are now ThriftAdapter one-liners. Includes 6 unit tests\ncovering all methods and error paths.\n\n* refactor: simplify launchExperiment handler to pure one-liner\n\nMoved group resource profile lookup from AiravataServerHandler.launchExperiment into\nExperimentService.launchExperiment, removing the List\u003cGroupResourceProfile\u003e parameter.\nExperimentService gains an optional GroupResourceProfileService set via setter. Handler\nmethod is now a single ThriftAdapter.executeVoid call.\n\n* feat: add integration test infrastructure with Testcontainers MariaDB\n\n- AbstractIntegrationTest base class with @Tag(\"integration\") and MariaDB container\n- SharingServiceIntegrationTest: rewrites monolithic sharing test into 13 ordered tests\n- ExperimentRepositoryIntegrationTest: template for repository integration tests\n- Surefire configured to exclude integration tests by default (run with -Dgroups\u003dintegration)\n\n* style: apply spotless formatting to all service layer code\n\n* docs: update README with service layer architecture, fix Dockerfile ports\n\n- README: document the 14-service architecture and transport-agnostic design\n- Dockerfile: remove obsolete per-service ports (all Thrift on 8930)\n\n* chore: remove working design docs\n\n* style: fix spotless formatting in file-server module"
    },
    {
      "commit": "dea11f4ad3e19abc5564db39b05a7b9f63cb3795",
      "tree": "9a3f0b9c037828e699184b98312594864e9364d4",
      "parents": [
        "7d0d8fb1a9fe3bf453ceb44ce332305b687b4ff0"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Thu Mar 26 04:56:23 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Mar 26 04:56:23 2026 -0500"
      },
      "message": "feat: consolidate Airavata into single JVM with multiplexed Thrift port (#593)\n\nConsolidates Airavata from multiple separate Thrift servers into a single JVM.\n\n- AiravataServer: single entry point with 9 multiplexed Thrift services on port 8930\n- 12 background IServer workers (Helix, workflow managers, monitors) with unified lifecycle\n- AiravataServerHandler: 759 ThriftClientPool RPC calls replaced with in-process handler calls\n- Unified database: all JDBC configs read from airavata.jdbc.* properties\n- IServer interface: simplified to extends Runnable (run/stop/getName/getStatus)\n- AbstractMonitor and WorkflowManager: flattened to composition over inheritance\n- Python SDK: TMultiplexedProtocol on single port for all 7 clients\n- ThriftClientPool: added serviceName for multiplexed connections\n- DatabaseTestCases: migrated from Derby to Testcontainers MariaDB\n- DevOps: ansible, deployment scripts, compose.yml updated; GFac removed\n- Docs: all READMEs rewritten with mermaid diagrams\n\n106 files changed, +2209/-5346"
    },
    {
      "commit": "7d0d8fb1a9fe3bf453ceb44ce332305b687b4ff0",
      "tree": "7c01d29ce5f05200dffdeefe12a347ee789fcc7a",
      "parents": [
        "2b3c211bb43df98cbc18045356d072dcd7e8efe9"
      ],
      "author": {
        "name": "Yasith Jayawardana",
        "email": "yasith@gatech.edu",
        "time": "Wed Mar 25 22:41:48 2026 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Mar 25 22:41:48 2026 -0500"
      },
      "message": "feat(db): unify all databases into single airavata DB with schema migrations (#592)\n\n* feat(db): unify all databases into single airavata DB with schema migrations\n\n- Consolidate 7+ separate databases (app_catalog, experiment_catalog,\n  replica_catalog, workflow_catalog, sharing_catalog, credential_store,\n  profile_service) into a single \u0027airavata\u0027 database\n- Generate V1 baseline schema (146 tables) from JPA entity annotations\n  across all modules: experiment catalog, application catalog, airavata\n  workflow catalog, replica catalog, sharing registry, profile service,\n  research service, and agent service\n- Rename duplicate table names for single-DB coexistence:\n  profile GATEWAY -\u003e TENANT_GATEWAY, research PROJECT -\u003e RESEARCH_PROJECT\n- Remove legacy workflowcatalog tables (dead code, not in any persistence unit)\n- Remove legacy DatabaseCreator and make DBInitializer a no-op\n  (schema creation now handled by migration SQL)\n- Restore persistence.xml (needed by OpenJPA enhancer) and dozer_mapping.xml\n- Standardize all hostnames to airavata.localhost (RFC 6761 .localhost TLD)\n- Simplify compose.yml: single file with all infrastructure services\n  (MariaDB, RabbitMQ, ZooKeeper, Kafka, Keycloak)\n- Remove .devcontainer directory (Dockerfile kept, compose consolidated)\n- Remove portals, proxy, gateway-storage configs\n- DB init uses V1 flyway migration SQL directly via docker-entrypoint-initdb.d\n- Fix validation queries (SELECT 1 instead of SELECT 1 from CONFIGURATION)\n- Fix RabbitMQ credentials to match compose (airavata:airavata)\n\nVerified: all 9 services start and pass schema validation against\nthe V1 baseline with zero errors.\n\n* style: run spotless:apply and update formatter versions\n\n- Update spotless-maven-plugin 2.44.5 -\u003e 3.4.0\n- Update palantir-java-format 2.70.0 -\u003e 2.89.0 (Java 25 compat)\n- Apply formatting fixes"
    },
    {
      "commit": "2b3c211bb43df98cbc18045356d072dcd7e8efe9",
      "tree": "eb1463cd60acd06499f83bdde15c86b653c8b2fc",
      "parents": [
        "2897f02701acda987da1cf5cd1e13835361ad79e"
      ],
      "author": {
        "name": "Dimuthu Wannipurage",
        "email": "dimuthu.upeksha2@gmail.com",
        "time": "Wed Dec 17 11:03:57 2025 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 17 11:03:57 2025 -0500"
      },
      "message": "Experiment cleanup support test cases (#583)\n\n* Adding support to clean up experiment working directory on cluster\n\n* Adding commented delete dir functionality\n\n* escaped the directory path, generated python thrift stubs, and updated the java styles\n\n* Adding test cases to validate the delete directory functionality\n\n* Fixed merge conflict and added missing assertions\n\n* Minor refactoring\n\nCo-authored-by: Copilot \u003c175728472+Copilot@users.noreply.github.com\u003e\n\n---------\n\nCo-authored-by: lahiruj \u003clahirujayathilake@gmail.com\u003e\nCo-authored-by: Copilot \u003c175728472+Copilot@users.noreply.github.com\u003e"
    },
    {
      "commit": "2897f02701acda987da1cf5cd1e13835361ad79e",
      "tree": "f2fee83471076e52dcf2b077ece3090de49023c1",
      "parents": [
        "452fc69d2270406c06319af674890ad43bac9d97"
      ],
      "author": {
        "name": "Lahiru Jayathilake",
        "email": "lahirujayathilake@gmail.com",
        "time": "Tue Dec 09 17:23:32 2025 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 09 16:23:32 2025 -0600"
      },
      "message": "Ansible Scripts to deploy/update the new Airavata Services (#565)\n\n* Initial implementation of ansible scripts to deploy and update airavata services\n\n* Improve Ansible deployment automation and fix service startup issues\n- Add Ubuntu/Debian support across all infrastructure roles (Java, Maven,\n  Zookeeper, Kafka, RabbitMQ, MariaDB, Keycloak, Certbot)\n- Add dynamic keystore generation from Let\u0027s Encrypt certificates\n- Add reverse proxy role for Apache2 configuration\n- Fix Zookeeper AdminServer port conflict\n- Fix Gateway ID NULL error in database initialization\n- Fix Java home detection for keystore generation during updates\n- Update database schema to include cloud execution support migrations\n- Maven build process with proper PATH configuration\n- Add Thrift installation for Ubuntu systems\n- Enhance Keycloak 24.0.0+ configuration with SSL setup\n\n* Fix Ansible roles, Keycloak Quarkus config, template defaults, and remove redundant stops\n\n* Switch RabbitMQ role to use distro packages instead of packagecloud repos\n\n* Fix Keycloak database tasks to authenticate via root socket credentials\n\n* updated the deploy_user\u0027s shell\n\n* start/stop services ansible scripts and conditional archiving logs when stopping airavata services\n\n* Fix Keycloak DB connectivity, rely on env vars, drop optimized mode, and grant localhost access\n\n* dev server encrypted configurations\n\n* include realm import when running keycloak via ansibles\n\n* Parameterize Keycloak realm template for PGA, JupyterLab, and CILogon\n\n* Updated ansible dev server vault configurations\n\n* included dev guides and updated documentation\n\n* Fix service binding and HAProxy backend forwarding\n\n* Support mariadb db server deployment for RH using ansibles\n\n* Ansible scripts for staging environment\n\n* Updated the ansible branch"
    },
    {
      "commit": "452fc69d2270406c06319af674890ad43bac9d97",
      "tree": "212df5affa6f6678b17ea1f8a63aa43890f6d132",
      "parents": [
        "8281d36a5b1e483ed274d274caff61f903083768"
      ],
      "author": {
        "name": "Dimuthu Wannipurage",
        "email": "dimuthu.upeksha2@gmail.com",
        "time": "Sat Nov 29 06:54:58 2025 -0500"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 29 06:54:58 2025 -0500"
      },
      "message": "Adding support to clean up experiment working directory on cluster (#582)\n\n* Adding support to clean up experiment working directory on cluster\n\n* Adding commented delete dir functionality\n\n* escaped the directory path, generated python thrift stubs, and updated the java styles\n\n---------\n\nCo-authored-by: lahiruj \u003clahirujayathilake@gmail.com\u003e"
    },
    {
      "commit": "8281d36a5b1e483ed274d274caff61f903083768",
      "tree": "0db33a467ac7cdcce12543107705d5602da565f8",
      "parents": [
        "e93147ae1d174c12b12f4f4ec59801db6d2f451b"
      ],
      "author": {
        "name": "lahiruj",
        "email": "lahirujayathilake@gmail.com",
        "time": "Thu Nov 27 00:00:14 2025 -0500"
      },
      "committer": {
        "name": "Dimuthu Wannipurage",
        "email": "dimuthu.upeksha2@gmail.com",
        "time": "Thu Nov 27 00:43:38 2025 -0500"
      },
      "message": "Add cleanAfterStaged flag to delete source files after successful staging\n"
    }
  ],
  "next": "e93147ae1d174c12b12f4f4ec59801db6d2f451b"
}
