Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ PORT=3000
SLACK_SIGNING_SECRET=
SLACK_BOT_TOKEN=
SLACK_APP_TOKEN=
SLACK_TOKEN_VERIFICATION_ENABLED=true
DATABASE_URL=
USE_SOCKET_MODE=true
ENABLE_LLM_SUMMARIES=false
Expand All @@ -10,3 +11,4 @@ CEREBRAS_API_KEY=
CEREBRAS_MODEL=gpt-oss-120b
CEREBRAS_BASE_URL=https://api.cerebras.ai/v1
CEREBRAS_REASONING_EFFORT=none
PUBLIC_BASE_URL=
90 changes: 0 additions & 90 deletions .github/workflows/azure-app-service.yml

This file was deleted.

74 changes: 74 additions & 0 deletions .github/workflows/render-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
name: Verify and Deploy GoSignal to Render

on:
push:
branches:
- main
pull_request:
workflow_dispatch:

permissions:
contents: read

concurrency:
group: gosignal-${{ github.ref }}
cancel-in-progress: true

env:
NODE_VERSION: 22

jobs:
verify:
runs-on: ubuntu-latest

steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: npm

- name: Install dependencies
run: npm ci

- name: Verify source, tests, and production entrypoint
run: npm run verify

- name: Smoke test the built production artifact
run: npm run smoke

deploy:
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.ref == 'refs/heads/main')
needs: verify
runs-on: ubuntu-latest
environment: production

steps:
- name: Check whether the Render deploy hook is configured
id: render-hook
env:
RENDER_DEPLOY_HOOK_URL: ${{ secrets.RENDER_DEPLOY_HOOK_URL }}
run: |
if [ -n "$RENDER_DEPLOY_HOOK_URL" ]; then
echo "configured=true" >> "$GITHUB_OUTPUT"
else
echo "configured=false" >> "$GITHUB_OUTPUT"
fi

- name: Trigger Render deploy hook for the exact commit
if: steps.render-hook.outputs.configured == 'true'
env:
RENDER_DEPLOY_HOOK_URL: ${{ secrets.RENDER_DEPLOY_HOOK_URL }}
COMMIT_SHA: ${{ github.sha }}
run: |
test -n "$RENDER_DEPLOY_HOOK_URL" || (echo "Missing GitHub repository secret RENDER_DEPLOY_HOOK_URL" && exit 1)
curl --fail --silent --show-error --request POST "${RENDER_DEPLOY_HOOK_URL}?ref=${COMMIT_SHA}"

- name: Explain why Render deploy was skipped
if: steps.render-hook.outputs.configured != 'true'
run: |
echo "Render deploy skipped because the GitHub repository secret RENDER_DEPLOY_HOOK_URL is not set yet."
echo "Set the secret, then rerun this workflow or push a new commit to main."
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22
138 changes: 138 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Architecture

GoSignal is a Slack-native launch readiness agent with a deterministic
decisioning core and an optional LLM phrasing layer.

## High-Level Flow

```mermaid
flowchart TD
A["Slack user"] --> B["Shortcut or app mention"]
B --> C["Bolt app handlers"]
C --> D["Thread retrieval"]
C --> E["Public search retrieval"]
C --> M["Workspace settings modal"]
D --> F["Deterministic readiness engine"]
E --> F
F --> G["Optional Cerebras summary layer"]
F --> H["Launch repository"]
C --> N["Workspace admin service"]
N --> O["Workspace settings store"]
N --> P["Audit ledger"]
G --> I["Thread response blocks"]
H --> J["App Home launches"]
O --> J
P --> J
F --> K["Canvas markdown writer"]
K --> L["Slack canvas"]
```

## Slack Surfaces

- Agent view
- App Home
- Message shortcut
- Thread replies
- Markdown canvas
- App DMs for follow-up questions about an already analyzed launch

## Component Map

| Component | Files | Responsibility |
| --- | --- | --- |
| App bootstrap and routes | `src/app.ts`, `src/index.ts`, `src/http/customRoutes.ts` | Starts the Bolt app, serves health routes, and wires dependencies |
| Slack handlers | `src/handlers/registerHandlers.ts` | Receives app mentions, shortcut invocations, App Home opens, DMs, and block actions |
| Thread and search retrieval | `src/services/slackSources.ts` | Reads launch threads, public search context, and writes canvases |
| Readiness engine | `src/domain/readiness.ts`, `src/domain/textSignals.ts`, `src/domain/constants.ts` | Classifies approvals, blockers, ambiguity, rollback, dependencies, and next action |
| Launch orchestration | `src/services/launchService.ts` | Combines retrieval, readiness evaluation, summary generation, persistence, and canvas writing |
| Workspace admin service | `src/services/workspaceAdminService.ts` | Resolves workspace settings, records audit events, and drives the admin App Home behavior |
| Optional LLM layer | `src/services/llmProvider.ts` | Rewrites grounded results into more natural text, with deterministic fallback |
| Persistence | `src/repositories/memoryLaunchRepository.ts`, `src/repositories/postgresLaunchRepository.ts`, `src/repositories/workspaceAdminRepository.ts`, `src/repositories/schema.sql` | Stores launch records, workspace settings, and audit events |
| UI rendering | `src/ui/blocks.ts`, `src/ui/canvas.ts`, `src/ui/appHome.ts` | Builds thread blocks, canvas markdown, and App Home surfaces |
| Verification | `src/scripts/checkLlm.ts`, `src/scripts/smoke.ts` | Verifies the LLM path and the production artifact |

## Storage Model

The primary persisted object is a `LaunchRecord`, which includes:

- `workspaceId`
- `sourceChannelId`
- `sourceThreadTs`
- launch name and status
- category states
- approvals
- blockers
- evidence excerpts
- final decision snapshot
- canvas linkage

The workspace admin layer also persists:

- `WorkspaceSettingsRecord` for search mode and audit retention
- `AuditEventRecord` for operator-visible actions such as analyze, rerun,
sign-off request, canvas open, and settings updates

Workspace isolation is achieved through repository queries that always scope to
`workspace_id`, plus a unique index on:

- `workspace_id`
- `source_channel_id`
- `source_thread_ts`

## Deterministic And LLM Boundaries

Deterministic logic is the source of truth for:

- overall state
- blocker detection
- missing approvals
- dependency risk
- ambiguity
- next action

Optional LLM usage is limited to:

- natural summary phrasing
- natural DM answers about an existing launch

The LLM does not override a deterministic red, yellow, green, or
`needs_review` state.

## Deployment Topology

Current deployment target:

- Render Web Service
- Node.js 22
- built artifact from `dist/`
- `server.js` as the production entrypoint

Health endpoints:

- `GET /`
- `GET /healthz`

Repository verification path:

- `npm run verify`
- `npm run smoke`

## Current Trust Boundaries

- Launch analysis is public-first in the current MVP.
- Public Slack thread messages form the main evidence base.
- Public search evidence is only used when a user-triggered action provides an
action token.
- Workspace settings can disable live search entirely and force thread-only
analysis.
- The thread board and markdown canvas both surface evidence receipts and live
search diagnostics from the current run.
- LLM output is grounded in structured launch data prepared by the deterministic
layer.

## Known Architectural Gaps Before Final Submission

- There is no dedicated installation store or encrypted token store yet.
- There is no self-service deletion UI or automated retention purge yet.
- Final Marketplace request URLs and five-workspace proof are external to the
repository and still pending.
42 changes: 42 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Contributing

Thanks for contributing to GoSignal.

## Local Workflow

1. Install dependencies with `npm install`.
2. Copy `.env.example` to `.env` and add local Slack credentials.
3. Run `npm run dev` or `npm run dev:watch`.
4. Before pushing changes, run:

```bash
npm run verify
npm run smoke
```

If you are changing the optional LLM path, also run:

```bash
npm run check:llm
```

## Contribution Guidelines

- Keep the deterministic readiness engine authoritative.
- Treat LLM output as optional phrasing, not the source of truth.
- Preserve workspace scoping in repository queries and UI flows.
- Do not commit secrets, tokens, or private screenshots.
- Update docs when the install, deployment, or Marketplace posture changes.

## Pull Request Checklist

- Code builds from the production path.
- Tests pass.
- Smoke test passes.
- New behavior is documented if it changes setup, deployment, or submission
proof.

## Reporting Issues

- General issues: `https://github.com/BitTriad/GoSignal/issues`
- Do not post secrets or live credentials in public issues.
Loading
Loading