Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
162 commits
Select commit Hold shift + click to select a range
2310392
Checkpoint governed App runtime and public ingress foundations
Maneek21 Sep 24, 2026
8bce1b4
Add reviewed Runtime App authoring and human execution
Maneek21 Sep 24, 2026
d946506
feat(apps): install reviewed experiences and public Runtime claims
Maneek21 Sep 24, 2026
f74ff68
fix native resource privacy and add strict v2 references
Maneek21 Sep 24, 2026
e1ae2d0
add live-authorized native resource display reads
Maneek21 Sep 24, 2026
e61a2e6
Add bounded candidate resource sync page contracts
Maneek21 Sep 24, 2026
186e2c9
Add experimental sync transport and encrypted owner primitives
Maneek21 Sep 24, 2026
a65452d
Make automation operator state reflect current authority
Maneek21 Sep 24, 2026
241771b
Add dormant reviewed App resource sync schema
Maneek21 Sep 24, 2026
ff53bbb
Fence sync sessions and retain encrypted resource keys at startup
Maneek21 Sep 24, 2026
6494546
Add authoring-only App Protocol v5 resource package contract
Maneek21 Sep 24, 2026
074b581
Verify resource App authoring remains outside host activation
Maneek21 Sep 24, 2026
7a844be
Define bounded private sync consent and credential policy
Maneek21 Sep 24, 2026
788d9c8
Record fresh schema history and reject untracked upgrades
Maneek21 Sep 24, 2026
0cb0ded
Run ledger upgrade proof on explicit four-database profile
Maneek21 Sep 24, 2026
af5b837
Add atomic resource sync page store foundation
Maneek21 Sep 24, 2026
c54e265
Add reviewed Protocol 5 App authority without resource execution
Maneek21 Sep 24, 2026
21a506a
Reconstruct reviewed sync grants and verify merged foundations
Maneek21 Sep 24, 2026
7366c10
Accept fixed resource sync policy in signed receipts
Maneek21 Sep 24, 2026
0d634aa
Add owner-reviewed private sync consent and v2 session authority
Maneek21 Sep 24, 2026
b52c503
Validate private sync management identifiers
Maneek21 Sep 24, 2026
4f3a536
Admit reviewed private sync through atomic host-owned Runs
Maneek21 Sep 24, 2026
158f03f
Add guarded resource sync channel settlement
Maneek21 Sep 24, 2026
ec1ceb3
Limit sync start to one input release
Maneek21 Sep 24, 2026
e3a4fa9
Prove packed resource sync SDK over separate-process HTTP
Maneek21 Sep 24, 2026
7f7fddf
Freeze private sync checkpoint acceptance inventory
Maneek21 Sep 24, 2026
6fc237a
Add authenticated private sync management and safe status
Maneek21 Sep 26, 2026
e39725a
feat: add bounded owner-private synchronized resource reads
Maneek21 Sep 26, 2026
4d50ece
Cover management HTTP body limits and credential redaction
Maneek21 Sep 26, 2026
ac98ee7
feat: schedule bounded private resource sync through host admission
Maneek21 Sep 26, 2026
975674d
fix: fence private read delivery before final consent check
Maneek21 Sep 26, 2026
e353bb5
Fence private sync delivery by current human participant identity
Maneek21 Sep 26, 2026
d03675c
Recheck consent deadlines after management session guards
Maneek21 Sep 26, 2026
be9b4ca
test: prove private sync restore and process loss fencing
Maneek21 Sep 26, 2026
6e41881
test: require private sync boundaries and focused compatibility evidence
Maneek21 Sep 26, 2026
488d015
Fence management participants after final web session waits
Maneek21 Sep 26, 2026
8fa4c71
fix: bound private host requests before authentication
Maneek21 Sep 26, 2026
d6367fc
test(apps): prove reviewed automation renewal and permanent revocation
Maneek21 Sep 26, 2026
1e88c11
test: require reviewed automation renewal acceptance cases
Maneek21 Sep 26, 2026
2b7951a
feat(apps): expose guarded owner-private resource management
Maneek21 Sep 26, 2026
aa647a2
Isolate automation scan item failures across tenant pages
Maneek21 Sep 26, 2026
2fa00a6
test: require automation scanner fault isolation cases
Maneek21 Sep 26, 2026
5d2d188
test: attest the isolated automation capacity mode
Maneek21 Sep 26, 2026
4d304a1
test: close capacity mode provider clients on cleanup
Maneek21 Sep 26, 2026
2c74a3f
feat: expose reviewed private sync setup context
Maneek21 Sep 26, 2026
27c7882
feat(resources): resolve owner-private runtime display safely
Maneek21 Sep 26, 2026
d9800b2
fix: avoid joined row locks during sync setup discovery
Maneek21 Sep 26, 2026
4e3a33f
fix(automations): bound scanner database work and settle cancellation
Maneek21 Sep 26, 2026
105180e
feat: review and activate sync-only Apps over web v2
Maneek21 Sep 26, 2026
652e531
feat(apps): connect private resources through reviewed browser setup
Maneek21 Sep 26, 2026
cf6eee7
fix(api): retain bounded automation scanner continuation
Maneek21 Sep 26, 2026
56ef1a9
test(api): cover automation budget admission boundaries
Maneek21 Sep 26, 2026
9479de4
test(gate-g): inventory setup activation and scheduler evidence
Maneek21 Sep 26, 2026
62d9bee
test(api): verify persisted automation history and DST identities
Maneek21 Sep 26, 2026
d3ecf0e
test(gate-g): require persisted history and DST evidence
Maneek21 Sep 26, 2026
20bda72
test(api): prove automation recovery identities and catalog continuation
Maneek21 Sep 26, 2026
464e4f3
feat: support separate private resource operators
Maneek21 Sep 26, 2026
47f0b19
Add explicit session-bound Experience resource consent behind default…
Maneek21 Sep 26, 2026
0c04c68
Align Experience exposure child primary key with upgrade schema
Maneek21 Sep 26, 2026
97a9115
Record Gate G checkpoint 09 required cases and default-off exposure s…
Maneek21 Sep 26, 2026
c19c1d5
Expose the browser Experience SDK without authoring dependencies
Maneek21 Sep 26, 2026
f72a64f
Govern v5 Experience actions through reviewed Runtime Run admission
Maneek21 Sep 26, 2026
97bf28a
Recheck v5 Experience gates after final session lock
Maneek21 Sep 26, 2026
dc45f1e
test: cover exposure authority races and real port transport
Maneek21 Sep 26, 2026
d51f4fa
Permit separately governed reads in mixed v5 Experiences and freeze f…
Maneek21 Sep 26, 2026
36267c3
fix(workers): refill settled spare slots without dropping late work
Maneek21 Sep 26, 2026
b5400a1
Freeze Gate G checkpoint 10 scheduler acceptance profiles
Maneek21 Sep 26, 2026
fe25ecd
feat: add reviewed same-protocol runtime App upgrades
Maneek21 Sep 26, 2026
ed4f18b
feat(apps): add reviewed public availability and claim deadlines
Maneek21 Sep 26, 2026
af02a47
Freeze checkpoint 11 acceptance profiles and isolated validation
Maneek21 Sep 26, 2026
39a7a4d
fix(web): retire Experience sessions across page lifetimes
Maneek21 Sep 26, 2026
ff36a3a
feat(apps): enforce reviewed durable public reservation budgets
Maneek21 Sep 26, 2026
4693619
Add owner-authorized native App resource destinations
Maneek21 Sep 26, 2026
e2cd80b
Bound App Run maintenance and make reviewed drain policy explicit
Maneek21 Sep 26, 2026
f1a92e6
test(apps): inventory checkpoint 12 acceptance profiles
Maneek21 Sep 26, 2026
13aa13f
Load public availability Run runtime only when cursor keys are used
Maneek21 Sep 26, 2026
ae9d740
Normalize native reference test end of file
Maneek21 Sep 26, 2026
2b8be91
Add reviewed signed public claim ingress with durable bounded nonce r…
Maneek21 Sep 26, 2026
0e4de09
Fence public management by final WebSID and authenticate raw HTTP cla…
Maneek21 Sep 26, 2026
198f3d4
Require explicit reviewed supersede policy for connected App upgrades
Maneek21 Sep 26, 2026
a8833bd
Use exact transaction and human actor types for connected upgrade guards
Maneek21 Sep 26, 2026
f5ad73a
Use guarded connected upgrade review with explicit pending-work consent
Maneek21 Sep 26, 2026
6ec9662
Freeze signed ingress and connected upgrade acceptance cases
Maneek21 Sep 26, 2026
dfac46f
Add paginated owner search over private App projections
Maneek21 Sep 26, 2026
46a879e
Recover private search scope after visibility changes
Maneek21 Sep 26, 2026
636ef6b
Freeze owner search and exposure database boundary acceptance
Maneek21 Sep 26, 2026
2e0cb26
Add explicit versioned Experience private search consent
Maneek21 Sep 26, 2026
0788aec
Clarify identifiers permitted by approved Experience fields
Maneek21 Sep 26, 2026
38ea2cd
Freeze checkpoint 15 Experience search acceptance inventory
Maneek21 Sep 26, 2026
b64e9fa
feat(app-kit): add closed native Calendar protocol 6 authoring
Maneek21 Sep 26, 2026
065239e
Add closed native public canonical scalar mapping
Maneek21 Sep 26, 2026
7b9a486
Add draft native Calendar authority and atomic Run execution
Maneek21 Sep 26, 2026
4ea5560
Fence native approval participant kind after final web session wait
Maneek21 Sep 26, 2026
2fcf3e6
Sample native final deadlines after last authority read
Maneek21 Sep 26, 2026
41db410
Normalize stale native public capture at Run boundary
Maneek21 Sep 26, 2026
2889072
Fence native invocation participants after final web session wait
Maneek21 Sep 26, 2026
50d6d3f
Unify final native authority and isolate atomic public submission
Maneek21 Sep 26, 2026
7d42702
Carry exact guarded web session deadline through native final fence
Maneek21 Sep 26, 2026
b41b65f
Fence native App staging and Experience guard deadlines
Maneek21 Sep 26, 2026
17693ae
Prove native atomic recovery and reviewed same-protocol upgrades
Maneek21 Sep 26, 2026
9a7a43d
Compose reviewed native public claims with governed owner Runs
Maneek21 Sep 26, 2026
ad8843e
fix public native terminal Run budget matching
Maneek21 Sep 26, 2026
2f4fdde
Require current owner exact input review for native Calendar approvals
Maneek21 Sep 26, 2026
aec1cc3
Prove mixed native App public Runtime consumption
Maneek21 Sep 26, 2026
2db4102
Freeze native Calendar integration and protocol 6 exposure acceptance
Maneek21 Sep 26, 2026
1928f97
fix: revalidate file download authority after storage reads
Maneek21 Sep 26, 2026
f5b53bb
test: use exact web authority for file compatibility coverage
Maneek21 Sep 26, 2026
4d9093e
Freeze file download authority and compatibility acceptance
Maneek21 Sep 26, 2026
dc65df6
Add immutable human private resource sharing grant schema
Maneek21 Sep 26, 2026
46e0fa8
Add retained public claim controls and atomic pre-effect withdrawal
Maneek21 Sep 26, 2026
3d44fa8
Add explicit human private resource sharing and recipient search
Maneek21 Sep 26, 2026
8ceb2a8
Freeze Gate G sharing and public control acceptance
Maneek21 Sep 26, 2026
9ad35d0
Fence native File metadata with current parent and session authority
Maneek21 Sep 26, 2026
7ed53aa
Add dormant protocol 7 attachment custody schema
Maneek21 Sep 26, 2026
4e382f7
Add retained public cancellation owner selection schema
Maneek21 Sep 26, 2026
1d35146
Govern retained public cancellation through current owner approval
Maneek21 Sep 26, 2026
a9bfd40
Add independent bounded MCP private grant schema
Maneek21 Sep 26, 2026
7ab71b2
Admit closed protocol 7 grants with bounded custody accounting
Maneek21 Sep 26, 2026
6d96cd8
Verify cancellation integration and guard maintenance child startup
Maneek21 Sep 26, 2026
3a200f3
Add closed protocol7 attachment and channel3 candidate contracts
Maneek21 Sep 26, 2026
600733b
feat(apps): expose owner reviewed public cancellation workflow
Maneek21 Sep 27, 2026
878041c
Add reviewed owner-only protocol7 attachment custody channel
Maneek21 Sep 26, 2026
9e14083
Fence attachment retirement against delayed ciphertext publication
Maneek21 Sep 27, 2026
c94c628
Record custody and cancellation evidence with portable cold fixtures
Maneek21 Sep 27, 2026
6c9aee7
feat(apps): govern exact private MCP context grants
Maneek21 Sep 27, 2026
477784b
Clarify declared native App authority in settings
Maneek21 Sep 27, 2026
55ceda6
Record private MCP acceptance and default-off configuration
Maneek21 Sep 27, 2026
44fab11
test(apps): require live Module and Task compatibility proof
Maneek21 Sep 27, 2026
9e09b43
feat(db): admit separately reviewed protocol7 composition grants
Maneek21 Sep 27, 2026
e914a4d
fix(db): preserve new migration checksums across checkouts
Maneek21 Sep 27, 2026
509a69a
Add default-off sealed private Defty context backend
Maneek21 Sep 27, 2026
37675d2
test(app-kit): keep unsupported schema assertion version independent
Maneek21 Sep 27, 2026
c79b646
feat(apps): compose reviewed Email7 Runtime and scalar custody access
Maneek21 Sep 27, 2026
8cdcb81
Fence private conversation classification and retained viewer metadata
Maneek21 Sep 27, 2026
4be558f
test(apps): require integrated composition and private Defty evidence
Maneek21 Sep 27, 2026
9c7de81
Reject unreviewed Anthropic environment headers in private turns
Maneek21 Sep 27, 2026
5a0960f
Prove retained Email7 scalar context through sealed Defty model turn
Maneek21 Sep 27, 2026
b766d4c
test(apps): require Email Defty convergence and credential boundary e…
Maneek21 Sep 27, 2026
0d659f0
docs(apps): declare default-off attachment UI flag
Maneek21 Sep 27, 2026
cda1ca9
Expose guarded channel3 owner and operator metadata
Maneek21 Sep 27, 2026
3ed078b
test(apps): allow isolated operator compatibility database clones
Maneek21 Sep 27, 2026
6266881
fix(apps): report unavailable attachment keys safely
Maneek21 Sep 27, 2026
adbbd2c
test(apps): require attachment management metadata evidence
Maneek21 Sep 27, 2026
be705fc
Add generic protocol7 resource and attachment controls
Maneek21 Sep 27, 2026
2234ab9
Expose governed attachment download headers to allowed origins
Maneek21 Sep 27, 2026
738e307
fix(apps): preserve latest authorized Experience view
Maneek21 Sep 27, 2026
1ca153e
test(apps): require Experience view ordering evidence
Maneek21 Sep 27, 2026
a439481
Keep owner sync metadata within its reviewed channel version
Maneek21 Sep 27, 2026
24da057
test(apps): require separated owner metadata modes
Maneek21 Sep 27, 2026
1c53f4c
Accept absent optional Experience SDK request fields
Maneek21 Sep 27, 2026
ed688c5
fix(web): size reviewed App approval controls and show input borders
Maneek21 Sep 27, 2026
fe0d9a4
test(apps): require public SDK optional-field compatibility evidence
Maneek21 Sep 27, 2026
3e48040
Add responsive layouts and rich controls for app experiences
Maneek21 Sep 27, 2026
8684267
Refine flat responsive app workspace presentation
Maneek21 Sep 27, 2026
5a8b67b
Complete governed app consent, drafts, reviewed batches and native pr…
Maneek21 Sep 28, 2026
019d862
Merge remote-tracking branch 'origin/master' into codex/apps-demo-pla…
Maneek21 Sep 28, 2026
2c8c80c
test(app-kit): align undeclared action diagnostic expectation
Maneek21 Sep 28, 2026
e09319a
test(apps): use cryptographic fixture session identifiers
Maneek21 Sep 28, 2026
9d300ae
fix(shared): resolve resource source import in production builds
Maneek21 Sep 28, 2026
1415029
fix(apps): keep composer pill actions at touch target size
Maneek21 Sep 28, 2026
9f7ebfd
fix(deploy): pass attachment UI flag into image builds
Maneek21 Sep 28, 2026
7fe25ab
fix(apps): preserve workspace approval for generic employee runs
Maneek21 Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
27 changes: 27 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,33 @@ NEXT_PUBLIC_FEATURE_HUDDLES=false
# beta. Enable the API and bake the public UI flag into the same build.
DEFT_APPS_ENABLED=false
NEXT_PUBLIC_FEATURE_APPS=false
# Private resource sync remains a separate experimental opt-in. The web flag
# must be baked into a source build; it does not grant read or sync authority.
NEXT_PUBLIC_FEATURE_APP_RESOURCE_SYNC=false
DEFT_APP_RESOURCE_SYNC_CHANNEL_ENABLED=false
DEFT_APP_RESOURCE_SYNC_SCHEDULER_ENABLED=false
# Protocol 7 attachment custody also requires owner-reviewed parent and binary consent.
DEFT_APP_ATTACHMENT_BROKER_ENABLED=false
# Build-time UI opt-in for reviewed attachment setup and owner viewing; requires
# the Apps and private resource sync UI flags. This grants no data access.
NEXT_PUBLIC_FEATURE_APP_ATTACHMENT_BROKER=false
# Installed App code needs a separate session-bound review before reading saved
# private fields. Sync consent alone never grants this experimental exposure.
DEFT_APP_EXPERIENCE_RESOURCE_EXPOSURE_ENABLED=false
# Protocol-v5 effects retain separate Runtime binding and per-invocation review.
DEFT_APP_V5_RUNTIME_ACTIONS_ENABLED=false
# Opt-in protocol 6 native Calendar bindings; each invocation requires owner approval.
DEFT_APP_NATIVE_CALENDAR_ENABLED=false
# Explicit human private-resource sharing; recipient rights require owner review.
DEFT_APP_PRIVATE_SHARING_ENABLED=false
NEXT_PUBLIC_FEATURE_APP_PRIVATE_SHARING=false
# Exact personal/employee MCP credential access requires its own owner review.
DEFT_APP_PRIVATE_MCP_ENABLED=false
NEXT_PUBLIC_FEATURE_APP_PRIVATE_MCP=false
# Private Defty context requires a separate owner review of fields and model destination.
# Retained encrypted history needs its original key versions after revocation.
DEFT_APP_PRIVATE_DEFTY_ENABLED=false
NEXT_PUBLIC_FEATURE_APP_PRIVATE_DEFTY=false
DEFT_APP_DEVELOPER_PAIRING_ENABLED=false
# The App Run engine can decrypt and drain accepted work only when this exact
# opt-in and valid purpose-separated keyrings are supplied.
Expand Down
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
scripts/docker-entrypoint.sh text eol=lf
docs/examples/operations/*.sh text eol=lf
**/deft.app.lock.json text eol=lf
# Migration checksums cover physical bytes; pin new files without rewriting history.
packages/db/upgrades/0.3.0-preview.51-app-attachment-composition.sql text eol=lf
packages/db/upgrades/0.3.0-preview.52-private-defty-context.sql text eol=lf
packages/db/upgrades/0.3.0-preview.54-app-experience-consent.sql text eol=lf
# Preserve the exact mixed line-ending bytes already applied in preview databases.
packages/db/upgrades/0.3.0-preview.53-app-private-state.sql -text whitespace=cr-at-eol,-blank-at-eof
packages/db/upgrades/0.3.0-preview.55-app-action-batches.sql -text whitespace=cr-at-eol,-blank-at-eof
packages/db/upgrades/0.3.0-preview.56-app-action-batch-policy-revision.sql text eol=lf
10 changes: 10 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ jobs:
run: pnpm module:verify
- name: Test App Kit authoring contracts
run: pnpm --filter @deft/app-kit test
- name: Test shared authority and resource contracts
run: pnpm --filter @deft/shared test
- name: Verify release publishing contract
run: pnpm test:release-workflow
- name: Verify container process supervision
Expand Down Expand Up @@ -68,6 +70,14 @@ jobs:
'src/app/(app)/notes/note-save-coordinator.test.ts'
'src/app/(app)/notes/protected-note-image.test.ts'
'src/app/(app)/notes/note-load-state.test.ts'
- name: Test installed app session and review contracts
run: >-
pnpm --filter @deft/web exec tsx --test
src/lib/app-experience-*.test.ts
src/lib/app-runtime-setup.test.ts
src/lib/private-state-adoption.test.ts
src/lib/action-batch-review.test.ts
src/lib/app-navigation.test.ts
- name: Type check API
run: pnpm --filter @deft/api typecheck
- name: Type check Web
Expand Down
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,17 @@ ARG NEXT_PUBLIC_API_URL=__DEFT_API_URL__
ARG NEXT_PUBLIC_WS_URL=__DEFT_WS_URL__
ARG NEXT_PUBLIC_FEATURE_HUDDLES=false
ARG NEXT_PUBLIC_FEATURE_APPS=false
ARG NEXT_PUBLIC_FEATURE_APP_RESOURCE_SYNC=false
ARG NEXT_PUBLIC_FEATURE_APP_ATTACHMENT_BROKER=false
ARG NEXT_PUBLIC_DEFT_SELF_HOSTED=false
ARG DEFT_RELEASE_VERSION=0.3.0-preview.14
ENV NEXT_PUBLIC_APP_URL=$NEXT_PUBLIC_APP_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_WS_URL=$NEXT_PUBLIC_WS_URL
ENV NEXT_PUBLIC_FEATURE_HUDDLES=$NEXT_PUBLIC_FEATURE_HUDDLES
ENV NEXT_PUBLIC_FEATURE_APPS=$NEXT_PUBLIC_FEATURE_APPS
ENV NEXT_PUBLIC_FEATURE_APP_RESOURCE_SYNC=$NEXT_PUBLIC_FEATURE_APP_RESOURCE_SYNC
ENV NEXT_PUBLIC_FEATURE_APP_ATTACHMENT_BROKER=$NEXT_PUBLIC_FEATURE_APP_ATTACHMENT_BROKER
ENV NEXT_PUBLIC_DEFT_SELF_HOSTED=$NEXT_PUBLIC_DEFT_SELF_HOSTED
ENV DEFT_RELEASE_VERSION=$DEFT_RELEASE_VERSION

Expand Down
62 changes: 62 additions & 0 deletions apps/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,34 @@ import { skillsRoutes } from './routes/skills.js';
import { taskTemplateRoutes } from './routes/task-templates.js';
import { workIntentRoutes } from './routes/work-intents.js';
import { moduleRoutes } from './routes/modules.js';
import { resourceRoutes } from './routes/resources.js';
import { appRoutes } from './routes/apps.js';
import { appActionRoutes } from './routes/app-actions.js';
import { appRunRoutes } from './routes/app-runs.js';
import { appDeveloperRoutes } from './routes/app-developer.js';
import { appRuntimeChannelRoutes } from './routes/app-runtime-channel.js';
import { appAttachmentSyncChannelRoutes } from './routes/app-attachment-sync-channel.js';
import { appResourceSyncChannelRoutes } from './routes/app-resource-sync-channel.js';
import { appResourceSyncLimits } from './middleware/app-resource-sync-limits.js';
import { appRuntimeManagementRoutes } from './routes/app-runtime-management.js';
import { appResourceSyncManagementRoutes } from './routes/app-resource-sync-management.js';
import { appResourceAccessRoutes } from './routes/app-resource-access.js';
import { appAttachmentOwnerRoutes } from './routes/app-attachments.js';
import { appPrivateMcpRoutes } from './routes/app-private-mcp.js';
import { appPrivateDeftyRoutes } from './routes/app-private-defty.js';
import { appResourcePrivateReadRoutes } from './routes/app-resource-private-read.js';
import { appResourcePrivateReadLimits, appResourceSyncManagementLimits, createAppResourcePrivateReadLimits } from './middleware/app-resource-private-limits.js';
import { appRuntimeReviewRoutes } from './routes/app-runtime-review.js';
import { appRuntimeActionRoutes } from './routes/app-runtime-actions.js';
import { appExperienceRoutes } from './routes/app-experiences.js';
import { createAppActionBatchRoutes } from './routes/app-action-batches.js';
import { createExperienceHumanActionRoutes } from './lib/app-experience-human-action-routes.js';
import { AppExperienceHumanActionService } from './lib/app-experience-human-action-service.js';
import { AppExperienceExposureService } from './lib/app-experience-exposure.js';
import { getAppRunRuntime } from './lib/app-run-runtime.js';
import { createAppPublicRoutes } from './routes/app-public.js';
import { AppPublicClaimService } from './lib/app-public-service.js';
import { appPublicManagementRoutes } from './routes/app-public-management.js';
import { APPS_ENABLED, APP_DEVELOPER_PAIRING_ENABLED } from './lib/env.js';
import { moduleTaskLinkRoutes } from './routes/module-task-links.js';
import { authMiddleware } from './middleware/auth.js';
Expand Down Expand Up @@ -108,6 +132,7 @@ app.use('*', cors({
'Mcp-Name',
],
allowMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
exposeHeaders: ['Content-Disposition', 'X-Content-Type-Options'],
}));

// Task 4 (private-alpha): security headers. Browsers loading API responses
Expand Down Expand Up @@ -184,6 +209,32 @@ if (APP_DEVELOPER_PAIRING_ENABLED) {
app.use('/api/app-developer/*', authLimiter);
app.route('/api/app-developer', appDeveloperRoutes);
}
// Runtime credentials have a separate audience; never accept browser cookies.
if (APPS_ENABLED) {
app.use('/api/app-runtime/channel/*', authLimiter);
app.route('/api/app-runtime/channel', appRuntimeChannelRoutes);
app.use('/api/app-resource-sync/channel/*', appResourceSyncLimits);
app.use('/api/app-resource-sync-channel/v3/*',appResourceSyncLimits);
app.route('/api/app-resource-sync-channel/v3',appAttachmentSyncChannelRoutes);
app.route('/api/app-resource-sync/channel', appResourceSyncChannelRoutes);
// Owner controls and private reads verify a live web SID themselves. Employee
// and Runtime credentials must never reach these human-only surfaces.
app.use('/api/app-resource-sync-management/*', appResourceSyncManagementLimits);
app.route('/api/app-resource-sync-management', appResourceSyncManagementRoutes);
app.use('/api/app-resource-private/*', appResourcePrivateReadLimits);
app.use('/api/private-resources/*',appResourcePrivateReadLimits);
app.route('/api/private-resources',appAttachmentOwnerRoutes);
app.route('/api/app-resource-private', appResourcePrivateReadRoutes);
app.use('/api/app-resource-access/*', createAppResourcePrivateReadLimits());
app.route('/api/app-resource-access', appResourceAccessRoutes);
app.use('/api/app-private-mcp/*', createAppResourcePrivateReadLimits());
app.route('/api/app-private-mcp', appPrivateMcpRoutes);
app.use('/api/apps/private-defty/*', createAppResourcePrivateReadLimits());
app.route('/api/apps/private-defty', appPrivateDeftyRoutes);
}
if (APPS_ENABLED && process.env.DEFT_APP_PUBLIC_INGRESS_ENABLED === 'true') {
app.route('/api/public/apps', createAppPublicRoutes(new AppPublicClaimService({ enabled: true })));
}
app.use('/api/*', authMiddleware);
app.use('/api/*', defaultLimiter);
app.use('/api/agent/*', agentLimiter);
Expand Down Expand Up @@ -245,6 +296,17 @@ app.route('/api/task-templates', taskTemplateRoutes);
app.route('/api/work-intents', workIntentRoutes);
app.route('/api/modules', moduleRoutes);
if (APPS_ENABLED) {
app.route('/api/resources', resourceRoutes);
app.route('/api/apps/public', appPublicManagementRoutes);
app.route('/api/apps/runtime', appRuntimeManagementRoutes);
app.route('/api/app-runtime-review', appRuntimeReviewRoutes);
app.route('/api/app-runtime-actions', appRuntimeActionRoutes);
app.route('/api/app-experiences', appExperienceRoutes);
app.route('/api/app-action-batches', createAppActionBatchRoutes());
app.route('/api/app-experiences', createExperienceHumanActionRoutes(async () => {
const runtime = await getAppRunRuntime();
return new AppExperienceHumanActionService(new AppExperienceExposureService(runtime.keys), runtime);
}));
app.route('/api/apps', appRoutes);
app.route('/api/app-actions', appActionRoutes);
app.route('/api/app-runs', appRunRoutes);
Expand Down
7 changes: 4 additions & 3 deletions apps/api/src/lib/agent-approval-resolver.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { AppRunTransaction } from './app-run-repository.js';
/**
* Phase 6.5 — approval resolver.
*
Expand Down Expand Up @@ -820,7 +821,7 @@ async function dispatchAction(
export async function approveAction(
actionId: string,
approverUserId: string,
options: { internal?: boolean } = {},
options: { internal?: boolean; appRunFinalGuard?: (tx: AppRunTransaction) => Promise<void> } = {},
): Promise<ApprovalResolverResult> {
const result = await withDbAdvisoryLock(
`agent-approval:${actionId}`,
Expand All @@ -835,7 +836,7 @@ export async function approveAction(
async function approveActionLocked(
actionId: string,
approverUserId: string,
options: { internal?: boolean },
options: { internal?: boolean; appRunFinalGuard?: (tx: AppRunTransaction) => Promise<void> },
): Promise<ApprovalResolverResult> {
// Pre-checks read immutable fields so they are safe to run before the
// atomic claim. If any pre-check fails we return without ever flipping
Expand Down Expand Up @@ -884,7 +885,7 @@ async function approveActionLocked(
}

if (row.action === APP_RUN_APPROVAL_ACTION) {
return (await appRunApprovalResolver()).approve(actionId, approverUserId);
return (await appRunApprovalResolver()).approve(actionId, approverUserId, options.appRunFinalGuard);
}

const resumesApprovedModule = isModuleMutation
Expand Down
Loading
Loading