version: 1
kind: HwlabNodeLaneConfig
metadata:
  name: hwlab-node-lanes
defaults:
  node: NC01
  lane: v03
requiredNoProxy:
  - hyueapi.com
  - .hyueapi.com
nodes:
  NC01:
    route: NC01
    kubeRoute: NC01:k3s
    sourceWorkspace: /root/hwlab-v03
    gitopsRoot: deploy/gitops/node
    networkProfile: jd01-node-ci-egress
    downloadProfile: jd01-node-default
lanes:
  v03:
    node: NC01
    activeTarget: NC01
    minor: 3
    version: v0.3
    sourceBranch: v0.3
    sourceAuthority:
      mode: gitMirrorSnapshot
      resolver: k8s-git-mirror
      allowHostGit: false
      allowHostWorkspace: false
      allowGithubDirectInPipeline: false
    sourceSnapshot:
      stageRefPrefix: "refs/unidesk/snapshots/hwlab-node-runtime/{branch}"
      missingObjectPolicy: fail-fast
      refreshPolicy: sync-before-snapshot
    workspace: /root/hwlab-v03
    cicdRepo: /root/hwlab-v03-cicd.git
    cicdRepoLock: /tmp/hwlab-v03-cicd-repo.lock
    app: hwlab-node-v03
    pipeline: hwlab-v03-ci-image-publish
    pipelineRunPrefix: hwlab-v03-ci-poll
    serviceAccountName: hwlab-v03-tekton-runner
    controlPlaneFieldManager: unidesk-hwlab-v03-control-plane
    git:
      url: git@github.com:pikasTech/HWLAB.git
      readUrl: http://git-mirror-http.devops-infra.svc.cluster.local/pikasTech/HWLAB.git
      writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local/pikasTech/HWLAB.git
    gitopsBranch: v0.3-gitops
    catalogPath: deploy/artifact-catalog.v03.json
    runtime:
      path: deploy/gitops/node/runtime-v03
      namespace: hwlab-v03
      renderDir: runtime-v03
    tektonDir: tekton-v03
    argoApplicationFile: application-v03.yaml
    registryPrefix: 127.0.0.1:5000/hwlab
    baseImage: 127.0.0.1:5000/hwlab/hwlab-node20-base:20-bookworm-slim
    baseImageSource: node:20-bookworm-slim
    serviceIds:
      - hwlab-cloud-api
      - hwlab-workbench-runtime
      - hwlab-user-billing
      - hwlab-project-management
      - hwlab-cloud-web
      - hwlab-gateway
      - hwlab-edge-proxy
      - hwlab-agent-skills
    observability:
      prometheusOperator: true
    public:
      webUrl: http://74.48.78.17:20666
      apiUrl: http://74.48.78.17:20667
    bootstrapAdmin:
      username: admin
      displayName: HWLAB v0.3 Admin
      passwordSourceRef: hwlab/nc01-v03-bootstrap-admin.env
      passwordSourceKey: HWLAB_BOOTSTRAP_ADMIN_PASSWORD
      passwordHashTransform: hwlab-sha256
      secretName: hwlab-v03-bootstrap-admin
      secretKey: password-hash
      rollout:
        deployment: hwlab-cloud-api
    targets:
      NC01:
        node: NC01
        workspace: /root/hwlab-v03
        sourceWorkspace:
          git:
            remoteName: origin
            remoteUrl: git@github.com:pikasTech/HWLAB.git
            identityTarget: NC01
            identityId: github.com
            proxyEnvPath: /etc/unidesk/proxy.env
            verifyRemote: false
            requireUpToDate: false
          requiredCommands:
            - git
            - node
            - npm
          requiredFiles:
            - AGENTS.md
            - package.json
            - package-lock.json
          install:
            executor: host
            dependencyCommand: npm ci
            browserCommand: npx playwright install chromium
            stateDir: /tmp/hwlab-v03-source-workspace-bootstrap
            timeoutSeconds: 1800
        sourceAuthority:
          extends: templates.hwlabV03.sourceAuthorityGiteaSnapshot
          giteaMirrorRepoKey: hwlab-nc01-v03
        sourceSnapshot:
          extends: templates.hwlabV03.sourceSnapshotGiteaControlled
        cicdRepo: /root/hwlab-v03-cicd.git
        cicdRepoLock: /tmp/hwlab-v03-cicd-repo.lock
        app: hwlab-node-v03
        pipeline: hwlab-nc01-v03-ci-image-publish
        pipelineRunPrefix: hwlab-nc01-v03-ci-poll
        serviceAccountName: hwlab-nc01-v03-tekton-runner
        controlPlaneFieldManager: unidesk-hwlab-nc01-v03-control-plane
        pipelineProvenance:
          configRef: config/hwlab-node-lanes.yaml#lanes.v03.targets.NC01
          renderer: hwlab-runtime-lane
          mode: remote-pipeline-annotation
          maxInlineScriptBytes: 32768
        git:
          url: git@github.com:pikasTech/HWLAB.git
          readUrl: http://gitea-http.devops-infra.svc.cluster.local:3000/mirrors/pikasTech-HWLAB.git
          writeUrl: http://git-mirror-write.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
        argo:
          repoURL: http://git-mirror-http.devops-infra.svc.cluster.local:8080/pikasTech/HWLAB.git
        gitopsBranch: v0.3-gitops
        catalogPath: deploy/artifact-catalog.nc01-v03.json
        runtime:
          path: deploy/gitops/node/nc01/runtime-v03
          namespace: hwlab-v03
          renderDir: runtime-v03
        runtimeStore:
          postgres:
            mode: platform-service
            serviceName: nc01-host-postgres
            poolMax: 16
        buildkit:
          sidecarImage: 127.0.0.1:5000/hwlab/buildkit:rootless
          sourceImage: docker.io/moby/buildkit:rootless
        stepEnv:
          HOME: /tekton/home
          XDG_CONFIG_HOME: /tekton/home/.config
        runtimeImageRewrites:
          - extends: templates.hwlabV03.runtimeImageRewrites.frpc
          - extends: templates.hwlabV03.runtimeImageRewrites.openfga
          - extends: templates.hwlabV03.runtimeImageRewrites.opencode
        runtimeImageBuilds:
          - extends: templates.hwlabV03.runtimeImageBuilds.moonbridge
          - extends: templates.hwlabV03.runtimeImageBuilds.opencodeGit
        webProbe:
          extends: templates.hwlabV03.webProbeWorkbench
          playwrightBrowsersPath: "0"
        public:
          webUrl: https://hwlab.pikapython.com
          apiUrl: https://hwlab.pikapython.com
        observability:
          prometheusOperator: false
          webProbe:
            monitor:
              configRef: config/hwlab-web-probe-monitor/runtime.yaml#monitor
            monitorRoot:
              enabled: true
              sentinelId: nc01-web-probe-sentinel
              publicBaseUrl: https://monitor.pikapython.com
              routePrefix: /
              caddyManagedBlockOwner: hwlab-web-probe-sentinel-active-root
            sentinels:
              - id: nc01-web-probe-sentinel
                enabled: true
                configRef: "config/hwlab-web-probe-sentinel/profiles.yaml#nodes.${NODE}.sentinels.${nodeLower}-web-probe-sentinel.sentinel"
        bootstrapAdmin:
          username: admin
          displayName: HWLAB v0.3 Admin
          usernameSourceRef: /root/.unidesk/.env/hwlab.auth
          usernameSourceLine: 1
          passwordSourceRef: /root/.unidesk/.env/hwlab.auth
          passwordSourceKey: HWLAB_ADMIN_PASSWORD
          passwordSourceLine: 2
          passwordHashTransform: hwlab-sha256
          secretName: hwlab-v03-bootstrap-admin
          secretKey: password-hash
          rollout:
            deployment: hwlab-cloud-api
        codeAgentProvider:
          secretName: hwlab-v03-code-agent-provider
          sourceRef: hwlab/nc01-v03-code-agent-provider.env
          openaiSourceKey: OPENAI_API_KEY
          opencodeSourceKey: OPENCODE_API_KEY
        codeAgentRuntime:
          enabled: true
          adapter: agentrun-v02
          controlPlaneTarget:
            node: NC01
            lane: nc01-v02
          managerUrl: http://agentrun-mgr.agentrun-v02.svc.cluster.local:8080
          apiKeySecretName: hwlab-v03-master-server-admin-api-key
          apiKeySecretKey: api-key
          runnerNamespace: agentrun-v02
          secretNamespace: agentrun-v02
          repoUrlFrom: runtimeGitReadUrl
          providerIdFrom: runtimeNodeId
          defaultProviderProfile: gpt.pika
          codexStdioSupervisor: repo-owned
          kafkaEventBridge:
            enabled: true
            transactionalProjector:
              heartbeatIntervalMs: 2000
            projectionOutboxRelay:
              intervalMs: 250
              batchSize: 100
              leaseMs: 30000
              sendTimeoutMs: 10000
              retryBackoffMs: 1000
            projectionRealtime:
              outboxTailBatchSize: 100
              sseHeartbeatMs: 15000
              sseDrainTimeoutMs: 2500
            healthThresholds:
              consumerLagWarning: 0
              outboxBacklogWarning: 0
              retryCountWarning: 0
              failedInboxWarning: 0
              dlqWarning: 0
            configRef: config/platform-infra/kafka.yaml#clients.hwlab-v03-cloud-api
            bootstrapServers: platform-infra-kafka-kafka-bootstrap.platform-infra.svc.cluster.local:9092
            stdioTopic: codex-stdio.raw.v1
            agentRunEventTopic: agentrun.event.v1
            hwlabEventTopic: hwlab.event.v1
            clientId: hwlab-v03-cloud-api
            transactionalProjectorConsumerGroupId: hwlab-v03-agentrun-event-projector
            hwlabEventConsumerGroupId: hwlab-v03-workbench-live-sse
        publicExposure:
          extends: templates.hwlabV03.publicExposurePk01
          frpc:
            webProxy:
              remotePort: 22082
            apiProxy:
              remotePort: 22083
        externalPostgres:
          extends: templates.hwlabV03.externalPostgresConsumer
          provider: NC01
          configRef: config/platform-db/postgres-nc01.yaml
          serviceName: nc01-host-postgres
          endpointAddress: 10.42.0.1
          runtimeAccess:
            routeName: nc01-host-postgres
            endpointAddress: 10.42.0.1
            port: 5432
          database: hwlab_nc01_v03
          cloudApi:
            sourceRef: hwlab/nc01-v03-cloud-api-db.env
            role: hwlab_nc01_v03_app
          openfga:
            sourceRef: hwlab/nc01-v03-openfga-db.env
            role: hwlab_nc01_v03_app
        variables:
          LANE: v03
          NODE: NC01
networkProfiles:
  node-ci-egress:
    proxy:
      http: http://g14-provider-egress-proxy.unidesk.svc.cluster.local:18789
      https: http://g14-provider-egress-proxy.unidesk.svc.cluster.local:18789
      all: http://g14-provider-egress-proxy.unidesk.svc.cluster.local:18789
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - host.docker.internal
        - .svc
        - .cluster.local
        - ci-git-mirror
        - ci-git-mirror.unidesk-ci
        - ci-git-mirror.unidesk-ci.svc
        - ci-git-mirror.unidesk-ci.svc.cluster.local
        - g14-provider-egress-proxy
        - g14-provider-egress-proxy.unidesk
        - g14-provider-egress-proxy.unidesk.svc
        - g14-provider-egress-proxy.unidesk.svc.cluster.local
        - g14-tcp-egress-gateway
        - g14-tcp-egress-gateway.unidesk
        - g14-tcp-egress-gateway.unidesk.svc
        - g14-tcp-egress-gateway.unidesk.svc.cluster.local
        - code-queue-ci-read
        - code-queue-ci-read.unidesk-ci
        - code-queue-ci-read.unidesk-ci.svc
        - code-queue-ci-read.unidesk-ci.svc.cluster.local
        - backend-core
        - oa-event-flow
        - database
    dockerBuildProxy:
      http: http://127.0.0.1:18789
      https: http://127.0.0.1:18789
      all: http://127.0.0.1:18789
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - host.docker.internal
        - registry.npmmirror.com
        - cdn.npmmirror.com
  node-local-vpn:
    proxy:
      http: http://127.0.0.1:10808
      https: http://127.0.0.1:10808
      all: socks5h://127.0.0.1:10808
      socks5: socks5h://127.0.0.1:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - .svc
        - .cluster.local
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
    dockerBuildProxy:
      http: http://127.0.0.1:10808
      https: http://127.0.0.1:10808
      all: socks5h://127.0.0.1:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - host.docker.internal
        - 127.0.0.1:5000
  d601-node-ci-egress:
    proxy:
      http: http://sub2api-egress-proxy.platform-infra.svc.cluster.local:10808
      https: http://sub2api-egress-proxy.platform-infra.svc.cluster.local:10808
      all: http://sub2api-egress-proxy.platform-infra.svc.cluster.local:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - 127.0.0.1:5000
        - localhost:5000
        - .svc
        - .svc.cluster.local
        - .cluster.local
        - kubernetes
        - kubernetes.default
        - kubernetes.default.svc
        - 10.0.0.0/8
        - 10.42.0.0/16
        - 10.43.0.0/16
        - 172.16.0.0/12
        - 192.168.0.0/16
        - 82.156.23.220
        - 74.48.78.17
        - hyueapi.com
        - .hyueapi.com
    dockerBuildProxy:
      http: http://127.0.0.1:10808
      https: http://127.0.0.1:10808
      all: http://127.0.0.1:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - 127.0.0.1:5000
        - localhost:5000
        - .svc
        - .svc.cluster.local
        - .cluster.local
  d518-node-ci-egress:
    proxy:
      http: http://sub2api-egress-proxy.platform-infra.svc.cluster.local:10808
      https: http://sub2api-egress-proxy.platform-infra.svc.cluster.local:10808
      all: http://sub2api-egress-proxy.platform-infra.svc.cluster.local:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - 127.0.0.1:5000
        - localhost:5000
        - .svc
        - .svc.cluster.local
        - .cluster.local
        - kubernetes
        - kubernetes.default
        - kubernetes.default.svc
        - 10.0.0.0/8
        - 10.42.0.0/16
        - 10.43.0.0/16
        - 172.16.0.0/12
        - 192.168.0.0/16
        - 82.156.23.220
        - 74.48.78.17
    dockerBuildProxy:
      http: http://127.0.0.1:10808
      https: http://127.0.0.1:10808
      all: http://127.0.0.1:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - 127.0.0.1:5000
        - localhost:5000
        - .svc
        - .svc.cluster.local
        - .cluster.local
  jd01-node-ci-egress:
    proxy:
      http: http://127.0.0.1:10808
      https: http://127.0.0.1:10808
      all: http://127.0.0.1:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - 127.0.0.1:5000
        - localhost:5000
        - .svc
        - .svc.cluster.local
        - .cluster.local
        - kubernetes
        - kubernetes.default
        - kubernetes.default.svc
        - 10.0.0.0/8
        - 10.42.0.0/16
        - 10.43.0.0/16
        - 172.16.0.0/12
        - 192.168.0.0/16
        - 82.156.23.220
        - 74.48.78.17
    dockerBuildProxy:
      http: http://127.0.0.1:10808
      https: http://127.0.0.1:10808
      all: http://127.0.0.1:10808
      noProxy:
        - localhost
        - 127.0.0.1
        - "::1"
        - 127.0.0.1:5000
        - localhost:5000
        - .svc
        - .svc.cluster.local
        - .cluster.local
downloadProfiles:
  node-default:
    git:
      proxyMode: inherit
      retries: 3
      timeoutSeconds: 240
    npm:
      registry: https://registry.npmmirror.com/
      retries: 3
      fetchTimeoutSeconds: 120
    pip:
      indexUrl: https://pypi.org/simple
      retries: 3
      timeoutSeconds: 120
    docker:
      registryMirrors:
        []
      pullRetries: 3
    curl:
      retries: 3
      connectTimeoutSeconds: 10
      maxTimeSeconds: 120
  d601-node-default:
    git:
      proxyMode: inherit
      retries: 3
      timeoutSeconds: 60
    npm:
      registry: https://registry.npmmirror.com/
      retries: 3
      fetchTimeoutSeconds: 120
    pip:
      indexUrl: https://pypi.org/simple
      retries: 3
      timeoutSeconds: 120
    docker:
      registryMirrors:
        []
      pullRetries: 3
    curl:
      retries: 3
      connectTimeoutSeconds: 10
      maxTimeSeconds: 120
  d518-node-default:
    git:
      proxyMode: inherit
      retries: 3
      timeoutSeconds: 60
    npm:
      registry: https://registry.npmmirror.com/
      retries: 3
      fetchTimeoutSeconds: 120
    pip:
      indexUrl: https://pypi.org/simple
      retries: 3
      timeoutSeconds: 120
    docker:
      registryMirrors:
        []
      pullRetries: 3
    curl:
      retries: 3
      connectTimeoutSeconds: 10
      maxTimeSeconds: 120
  jd01-node-default:
    git:
      proxyMode: inherit
      retries: 3
      timeoutSeconds: 60
    npm:
      registry: https://registry.npmmirror.com/
      retries: 3
      fetchTimeoutSeconds: 120
    pip:
      indexUrl: https://pypi.org/simple
      retries: 3
      timeoutSeconds: 120
    docker:
      registryMirrors:
        []
      pullRetries: 3
    curl:
      retries: 3
      connectTimeoutSeconds: 10
      maxTimeSeconds: 120
  d601-node-no-mirror-benchmark:
    git:
      proxyMode: inherit
      retries: 3
      timeoutSeconds: 120
    npm:
      registry: https://registry.npmjs.org/
      retries: 3
      fetchTimeoutSeconds: 120
    pip:
      indexUrl: https://pypi.org/simple
      retries: 3
      timeoutSeconds: 120
    docker:
      registryMirrors:
        []
      pullRetries: 3
    curl:
      retries: 3
      connectTimeoutSeconds: 10
      maxTimeSeconds: 120
templates:
  hwlabV03:
    webProbeWorkbench:
      browserProxyMode: auto
      defaultOrigin: internal
      resourcePolicy:
        memoryStartGuard:
          metric: MemAvailable
          source: /proc/meminfo
          swapExcluded: true
          thresholdBytes: 4294967296
          manualComparator: less-than-or-equal
          sentinelComparator: less-than
          snapshotTimeoutSeconds: 30
          launchLockPath: /tmp/unidesk-web-probe-observer-launch.lock
          launchLockTimeoutSeconds: 15
          launchReadyTimeoutSeconds: 10
          launchReadyPollMilliseconds: 200
        observerLifecycle:
          maxRunSeconds: 3600
          maxSamples: 720
          maxScreenshots: 24
          maxPerformanceEntries: 1000
          maxBrowserProcessHistoryEntries: 360
          maxBrowserFreezeSignalHistoryEntries: 120
          maxRealtimeEventEntries: 256
          maxRealtimeEventBodyBytes: 65536
          maxDomEvidenceRows: 1000
          maxProcessScanEntries: 8192
          maxPerformanceCaptureSeconds: 30
          maxResponseBodyBytes: 524288
          maxWebPerformanceBodyBytes: 65536
          maxJsonlQueueEntries: 512
          maxJsonlQueueBytes: 4194304
          maxJsonlLineBytes: 262144
          jsonlFlushTimeoutMs: 5000
          maxResponseBodyInFlight: 2
          maxPassiveListenerTasks: 64
          passiveTaskFlushTimeoutMs: 5000
          closeStepTimeoutMs: 5000
          maxProcessReadConcurrency: 32
          maxRealtimeTotalEntries: 512
          maxRealtimeTotalBodyBytes: 4194304
        browserEvidence:
          screenshotMode: viewport
          maxNetworkRequestEntries: 200
          maxNetworkRequestBytes: 262144
          maxNetworkFailureEntries: 100
          maxNetworkFailureBytes: 131072
      origins:
        internal:
          mode: k8s-service-cluster-ip
          serviceName: hwlab-cloud-web
          namespace: "hwlab-${lane}"
          port: 8080
          scheme: http
          browserProxyMode: direct
        public:
          mode: public
          browserProxyMode: auto
      authLogin:
        maxAttempts: 6
        requestTimeoutMs: 30000
        initialDelayMs: 500
        maxDelayMs: 10000
      realtimeFanoutProfiles:
        pure-kafka-live:
          subscriberCount: 2
          debugStreams:
            - stdio
            - agentrun
            - hwlab
          productEventsPath: /v1/workbench/events
          debugEventsPath: /v1/workbench/debug/kafka-sse/events
          productReadyEvent: workbench.connected
          debugReadyEvent: hwlab.kafka.connected
          businessEvent: hwlab.event.v1
          fromBeginning: false
          barrierTimeoutMs: 45000
          terminalTimeoutMs: 480000
          terminalQuietMs: 2000
          navigationMaxAttempts: 4
          navigationRetryDelayMs: 1000
          reconnectQuietMs: 3000
          expectedProductSse:
            deliverySemantics: kafka-retention-then-live
            liveOnly: false
            replay: true
            replaySupported: true
            lossPossible: false
            refreshHandoff: true
            replayPriorTraceOnReconnect: true
          forbiddenRequestPaths:
            - /v1/workbench/sync
            - /v1/agent/chat/result/
            - /v1/agent/chat/inspect
            - /snapshot
            - /replay
            - /gap-fill
            - /finalizer
          requiredEventTypes:
            agentrun:
              - user_message
              - assistant_message
              - terminal_status
            hwlab:
              - user
              - assistant
              - terminal
          conditionalEventTypePairs:
            tool-call:
              agentrun: tool_call
              hwlab: tool
            command-output:
              agentrun: command_output
              hwlab: status
      workbenchKafkaDebugReplay:
        enabled: true
        topic: hwlab.event.debug.v1
        groupPrefix: hwlab-v03-workbench-isolated-debug
        completionTimeoutMs: 30000
      workbenchTraceReadability:
        enabled: true
        runningCardTimeoutMs: 15000
        disclosureActionTimeoutMs: 15000
        disclosureOpenTimeoutMs: 10000
        runningReadableTimeoutMs: 480000
        terminalTimeoutMs: 480000
        domStableQuietMs: 2000
        domStableTimeoutMs: 6000
        pollIntervalMs: 100
      alertThresholds:
        sameOriginApiSlowMs: 10000
        partialApiSlowMs: 10000
        longLivedStreamOpenSlowMs: 10000
        visibleLoadingSlowMs: 10000
        turnTimingSampleSlackSeconds: 3
        turnElapsedSevereTimeoutSeconds: 120
        domEvaluateTimeoutRedCount: 2
        domEvaluateTimeoutRedWindowMs: 30000
        screenshotTimeoutRedCount: 2
        pageErrorRedCount: 2
        longTaskRedMs: 1000
        longAnimationFrameRedMs: 1000
        eventLoopGapRedMs: 1000
        browserProcessSampleIntervalMs: 1000
        requestRateBucketMs: 10000
        requestRateTotalRedPerMinute: 300
        requestRatePageRedPerMinute: 240
        requestRateApiPathRedPerMinute: 120
        browserTotalRssRedMb: 800
        browserProcessRssRedMb: 600
        browserRssGrowthRedMb: 300
        browserRssGrowthWindowMs: 30000
        playwrightResponsivenessRedMs: 5000
        playwrightResponsivenessTimeoutRedCount: 2
        cdpMetricsTimeoutRedCount: 2
        uncommandedStateChangeCommandWindowMs: 10000
        scrollJumpCommandWindowMs: 8000
        scrollJumpFromY: 250
        scrollJumpToY: 40
        sessionRailFallbackRatio: 0.5
      browserFreezePolicy:
        enabled: true
        blockerWindowMs: 30000
        memory:
          totalRssBlockerMb: 800
          processRssBlockerMb: 500
          growthBlockerMb: 300
        responsiveness:
          latencyBlockerMs: 5000
          eventBlockerCount: 2
        cdp:
          metricsTimeoutBlockerCount: 2
        kill:
          enabled: true
          gracefulSignal: SIGTERM
          forceSignal: SIGKILL
          graceMs: 3000
          pollIntervalMs: 100
          exitCode: 7
      projectManagement:
        enabled: true
        targetPaths:
          - /projects
          - /projects/mdtodo
        readinessSelectors:
          - "[data-testid=\"project-management-root\"]"
          - "[data-testid=\"project-management-mdtodo\"]"
        naturalApiPathPrefixes:
          - /v1/project-management/
          - /v1/workbench/launches
          - /v1/agent/chat
        commandAllowlist:
          - gotoProjectMdtodo
          - openMdtodoSourceConfig
          - closeMdtodoSourceConfig
          - configureMdtodoHwpodSource
          - probeMdtodoSource
          - reindexMdtodoSource
          - selectProjectSource
          - selectMdtodoSource
          - selectMdtodoFile
          - selectMdtodoTask
          - expandMdtodoTask
          - openMdtodoReportPreview
          - toggleMdtodoReportFullscreen
          - editMdtodoTaskInline
          - editMdtodoTaskTitle
          - editMdtodoTaskBody
          - toggleMdtodoTaskStatus
          - addMdtodoRootTask
          - addMdtodoSubTask
          - continueMdtodoTask
          - deleteMdtodoTask
          - launchWorkbenchFromTask
          - launchWorkbenchFromMdtodo
        launchRoute: /v1/workbench/launches
        slowApiBudgetMs: 10000
    runtimeImageRewrites:
      postgres:
        source: postgres:16-alpine
        target: 127.0.0.1:5000/hwlab/postgres:16-alpine
      frpc:
        source: fatedier/frpc:v0.68.1
        target: 127.0.0.1:5000/hwlab/frpc:v0.68.1
      openfga:
        source: openfga/openfga:v1.17.0
        target: 127.0.0.1:5000/hwlab/openfga:v1.17.0
      opencode:
        source: ghcr.io/anomalyco/opencode:1.17.7
        target: 127.0.0.1:5000/hwlab/opencode:1.17.7
    runtimeImageBuilds:
      moonbridge:
        id: moonbridge
        kind: moonbridge
        target: 127.0.0.1:5000/hwlab/moonbridge:1b99888d3dae
        sourceRepo: https://github.com/ZhiYi-R/moon-bridge.git
        sourceRef: 1b99888d3dae889b79ee602cb875c7907f7e76f2
        builderImage: golang:1.25-bookworm
        goProxy: "https://goproxy.cn,direct"
        dockerNetworkMode: host
      opencodeGit:
        id: opencode-git
        kind: opencode-git
        target: 127.0.0.1:5000/hwlab/opencode:1.17.7-git
        sourceImage: ghcr.io/anomalyco/opencode:1.17.7
        dockerNetworkMode: host
    publicExposurePk01:
      mode: pk01-caddy-frp
      publicBaseUrl: https://hwlab.pikapython.com
      hostname: hwlab.pikapython.com
      expectedA: 82.156.23.220
      frpc:
        serverAddr: 82.156.23.220
        serverPort: 22000
        tokenSourceRef: platform-infra/pk01-frp.env
        tokenSourceKey: FRP_TOKEN
        secretName: hwlab-v03-frpc-secrets
        secretKey: frpc.toml
        tokenKey: token
        webProxy:
          name: "hwlab-${nodeLower}-${lane}-cloud-web"
          localIP: "hwlab-cloud-web.hwlab-${lane}.svc.cluster.local"
          localPort: 8080
        apiProxy:
          name: "hwlab-${nodeLower}-${lane}-edge-proxy"
          localIP: "hwlab-edge-proxy.hwlab-${lane}.svc.cluster.local"
          localPort: 6667
      caddy:
        route: PK01
        configPath: /etc/caddy/Caddyfile
        serviceName: caddy
        email: ops@pikapython.com
        tls: auto
        responseHeaderTimeoutSeconds: 600
    externalPostgresConsumer:
      port: 5432
      sslmode: require
      cloudApi:
        secretName: hwlab-cloud-api-v03-db
        secretKey: database-url
        envKey: DATABASE_URL
      openfga:
        secretName: hwlab-v03-openfga
        secretKey: datastore-uri
        envKey: DATASTORE_URI
        authnKey: authn-preshared-key
    sourceAuthorityGiteaSnapshot:
      mode: giteaSnapshot
      resolver: gitea-mirror
      allowHostGit: false
      allowHostWorkspace: false
      allowGithubDirectInPipeline: false
    sourceSnapshotGiteaControlled:
      stageRefPrefix: "refs/unidesk/snapshots/gitea-actions/hwlab-node-runtime/{branch}"
      missingObjectPolicy: fail-fast
      refreshPolicy: gitea-controlled-snapshot
