atris 3.27.0 → 3.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/README.md +5 -5
- package/atris/features/company-brain-sync/build.md +4 -4
- package/atris/features/company-brain-sync/idea.md +2 -2
- package/atris/features/company-brain-sync/validate.md +19 -19
- package/atris/skills/aeo/SKILL.md +1 -1
- package/atris/skills/autopilot/SKILL.md +2 -2
- package/atris/skills/slides/SKILL.md +2 -2
- package/bin/atris.js +23 -18
- package/commands/aeo.js +1 -1
- package/commands/autopilot.js +1 -1
- package/commands/computer.js +9 -9
- package/commands/feedback.js +1 -1
- package/commands/init.js +2 -2
- package/commands/live.js +3 -3
- package/commands/plugin.js +1 -1
- package/commands/pull.js +4 -4
- package/commands/security-review.js +132 -0
- package/commands/task.js +0 -1
- package/lib/security-scan.js +188 -0
- package/package.json +1 -8
- package/atris/wiki/concepts/agent-activation-contract.md +0 -81
- package/atris/wiki/concepts/workspace-initialization-contract.md +0 -73
- package/atris/wiki/index.md +0 -31
- package/atris/wiki/sources/atris-labs-2026-05-10.txt +0 -14
- package/atris/wiki/sources/atris-labs-goals-2026-05-10.txt +0 -14
- package/atris/wiki/sources/atrisos-generative-ui-product-surface-2026-05-10.txt +0 -10
- package/atris/wiki/sources/jack-dorsey-2026-05-10.txt +0 -12
package/AGENTS.md
CHANGED
|
@@ -110,7 +110,7 @@ member -> mission start --verify -> status --status active -> one bounded step -
|
|
|
110
110
|
- [ ] Only use `atris task accept <id>` when the human has approved the proof
|
|
111
111
|
- [ ] Keep durable learning in Atris-owned policy/skill/wiki/task state; keep `AGENTS.md` as a generated/pointer layer
|
|
112
112
|
- [ ] Treat `atris/TODO.md` as a rendered view; do not manually use it as the source of truth
|
|
113
|
-
- [ ] Use
|
|
113
|
+
- [ ] Use the real business slug from local Atris state; do not hardcode private slugs in generated docs
|
|
114
114
|
|
|
115
115
|
## Anti-patterns
|
|
116
116
|
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Owner has many Computers
|
|
|
10
10
|
Computer = workspace + files + tools + secrets + memory + agents + validation loop
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
A computer can be personal or shared by a business. It can run a job like code, research, CRM, reporting,
|
|
13
|
+
A computer can be personal or shared by a business. It can run a job like code, research, CRM, reporting, event ops, support, or business ops.
|
|
14
14
|
|
|
15
15
|
## For Coding Agents
|
|
16
16
|
|
|
@@ -142,9 +142,9 @@ leaderboard.
|
|
|
142
142
|
If you want a shared owner for a company, lab, collective, community, artist, team, or project, use the business command instead of raw `atris init`.
|
|
143
143
|
|
|
144
144
|
```bash
|
|
145
|
-
atris business init "
|
|
146
|
-
cd ~/arena/atris-business/
|
|
147
|
-
atris business onboard --website https://
|
|
145
|
+
atris business init "Example Co" --owner-email operator@example.com
|
|
146
|
+
cd ~/arena/atris-business/example-co
|
|
147
|
+
atris business onboard --website https://example.com --contact "Example Owner" --note "sample customer workspace"
|
|
148
148
|
atris align --fix
|
|
149
149
|
```
|
|
150
150
|
|
|
@@ -166,7 +166,7 @@ You can also use bare input:
|
|
|
166
166
|
atris business onboard https://example.com "founder-led b2b ops" ./notes.md
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
If you already have a folder full of source material, run it from there with `atris business init "
|
|
169
|
+
If you already have a folder full of source material, run it from there with `atris business init "Example Co" --here`.
|
|
170
170
|
|
|
171
171
|
When the first recap is done, record it into the RL state logs:
|
|
172
172
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Current Patch
|
|
4
4
|
|
|
5
|
-
The immediate
|
|
5
|
+
The immediate Example Co lane now follows the correct company-brain model:
|
|
6
6
|
|
|
7
|
-
- `atris push` keeps the business root as the path root so `
|
|
7
|
+
- `atris push` keeps the business root as the path root so `example-co/atris/MAP.md` maps to cloud `/atris/MAP.md`
|
|
8
8
|
- business `pull` and `push` default to the `atris/` scope
|
|
9
9
|
- root-level duplicates such as `MAP.md`, `TODO.md`, and `security-report.md` are ignored by default
|
|
10
10
|
- manifests record the local workspace root to prevent a manifest from one folder authorizing pushes from another folder
|
|
@@ -114,7 +114,7 @@ Later it should also let the user ask Atris to merge semantically with model ass
|
|
|
114
114
|
|
|
115
115
|
`atris sync --watch` is the current always-on lane:
|
|
116
116
|
|
|
117
|
-
- watch `
|
|
117
|
+
- watch `example-co/atris/`
|
|
118
118
|
- debounce local edits
|
|
119
119
|
- fetch cloud hashes periodically
|
|
120
120
|
- sync clean changes
|
|
@@ -136,5 +136,5 @@ Required before broad customer use:
|
|
|
136
136
|
- retry-policy tests proving watch failures do not kill the alive loop
|
|
137
137
|
- fixture tests proving parent-folder junk is ignored
|
|
138
138
|
- fixture tests proving no cloud deletes without explicit opt-in
|
|
139
|
-
- end-to-end dry-run against a real
|
|
139
|
+
- end-to-end dry-run against a real Example Co-shaped workspace
|
|
140
140
|
- command copy that never recommends `--force` for normal use
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Problem
|
|
4
4
|
|
|
5
|
-
Atris business workspaces are company brains, not plain folders. The canonical knowledge surface is the `atris/` folder inside each business workspace, for example `
|
|
5
|
+
Atris business workspaces are company brains, not plain folders. The canonical knowledge surface is the `atris/` folder inside each business workspace, for example `example-co/atris/`.
|
|
6
6
|
|
|
7
7
|
Raw push/pull is the wrong abstraction for this surface. It makes a shared knowledge base feel like file mirroring, which creates merge anxiety and makes users responsible for sync safety.
|
|
8
8
|
|
|
@@ -19,7 +19,7 @@ Cloud Atris is canonical. Local Atris is a working copy. Sync publishes proposed
|
|
|
19
19
|
|
|
20
20
|
## User Model
|
|
21
21
|
|
|
22
|
-
Jonathan should be able to work inside `
|
|
22
|
+
Jonathan should be able to work inside `example-co/atris/` and run one command:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
atris sync
|
|
@@ -51,47 +51,47 @@ node -c commands/pull.js
|
|
|
51
51
|
node -c commands/push.js
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
Fresh
|
|
54
|
+
Fresh Example Co-shaped workspace dry-run:
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
atris sync
|
|
57
|
+
atris sync example-co --dry-run
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Observed result:
|
|
61
61
|
|
|
62
62
|
```text
|
|
63
|
-
Syncing
|
|
63
|
+
Syncing example-co knowledge wiki...
|
|
64
64
|
scope: atris/
|
|
65
65
|
...
|
|
66
|
-
Pushing to
|
|
66
|
+
Pushing to Example Co...
|
|
67
67
|
Checking cloud freshness... fresh
|
|
68
68
|
Already up to date.
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
Fresh
|
|
71
|
+
Fresh Example Co-shaped workspace real command with no local edits:
|
|
72
72
|
|
|
73
73
|
```bash
|
|
74
|
-
atris sync
|
|
74
|
+
atris sync example-co
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
Observed result:
|
|
78
78
|
|
|
79
79
|
```text
|
|
80
|
-
Pulling
|
|
80
|
+
Pulling Example Co...
|
|
81
81
|
Already up to date.
|
|
82
82
|
122 unchanged.
|
|
83
|
-
Pushing to
|
|
83
|
+
Pushing to Example Co...
|
|
84
84
|
Checking cloud freshness... fresh
|
|
85
85
|
Already up to date.
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
No cloud writes were required in the validation case because the clean workspace had no local changes to publish.
|
|
89
89
|
|
|
90
|
-
Local edit dry-run in
|
|
90
|
+
Local edit dry-run in an Example Co-shaped workspace:
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
93
|
printf '# Sync smoke\n\nLocal-only knowledge update.\n' > atris/wiki/smoke/local-edit.md
|
|
94
|
-
atris sync
|
|
94
|
+
atris sync example-co --dry-run
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
Observed result:
|
|
@@ -101,11 +101,11 @@ Observed result:
|
|
|
101
101
|
1 would be pushed, 122 unchanged. (--dry-run, nothing sent)
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
Local delete dry-run in
|
|
104
|
+
Local delete dry-run in an Example Co-shaped workspace:
|
|
105
105
|
|
|
106
106
|
```bash
|
|
107
107
|
rm -f atris/wiki/index.md
|
|
108
|
-
atris sync
|
|
108
|
+
atris sync example-co --dry-run
|
|
109
109
|
```
|
|
110
110
|
|
|
111
111
|
Observed result:
|
|
@@ -118,7 +118,7 @@ Deletes require an explicit real push with --delete.
|
|
|
118
118
|
Real delete attempt without `--delete`:
|
|
119
119
|
|
|
120
120
|
```bash
|
|
121
|
-
atris sync
|
|
121
|
+
atris sync example-co
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
Observed result:
|
|
@@ -148,10 +148,10 @@ Slug auto-detection:
|
|
|
148
148
|
atris sync --dry-run
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
Observed result from
|
|
151
|
+
Observed result from an Example Co-shaped workspace:
|
|
152
152
|
|
|
153
153
|
```text
|
|
154
|
-
Syncing
|
|
154
|
+
Syncing example-co knowledge wiki...
|
|
155
155
|
scope: atris/
|
|
156
156
|
```
|
|
157
157
|
|
|
@@ -165,7 +165,7 @@ Observed shape:
|
|
|
165
165
|
|
|
166
166
|
```text
|
|
167
167
|
Company brain status
|
|
168
|
-
business:
|
|
168
|
+
business: example-co
|
|
169
169
|
brain: atris/ (...)
|
|
170
170
|
conflicts: none
|
|
171
171
|
watcher: ...
|
|
@@ -218,12 +218,12 @@ atris pull example-co --keep-local --only atris/wiki --timeout 120
|
|
|
218
218
|
atris push example-co --only atris/wiki --dry-run
|
|
219
219
|
```
|
|
220
220
|
|
|
221
|
-
-
|
|
221
|
+
- Example Co post-publish smoke:
|
|
222
222
|
|
|
223
223
|
```bash
|
|
224
|
-
cd ~/arena/atris-business/
|
|
224
|
+
cd ~/arena/atris-business/example-co
|
|
225
225
|
atris wiki verify
|
|
226
|
-
atris push
|
|
226
|
+
atris push example-co --dry-run
|
|
227
227
|
```
|
|
228
228
|
|
|
229
229
|
- Packaged CLI smoke already passed locally for `3.15.12`: tarball install exposes `atris pull --no-manifest` and `atris wiki verify`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: aeo
|
|
3
3
|
description: "AI Engine Optimization — write content engineered to get cited by ChatGPT, Claude, and Gemini. Not SEO. Triggers on: aeo, AI engine, llm citation, get cited, write for ai."
|
|
4
|
-
when_to_use: "Use when the user wants content that ranks in AI answers (not Google SERP). Examples: 'write an AEO page', 'get ExampleCo cited by ChatGPT', 'aeo for our
|
|
4
|
+
when_to_use: "Use when the user wants content that ranks in AI answers (not Google SERP). Examples: 'write an AEO page', 'get ExampleCo cited by ChatGPT', 'aeo for our pricing page', 'make this quotable by LLMs'."
|
|
5
5
|
version: 0.1.0
|
|
6
6
|
allowed-tools: Read, Write, Edit, Glob, Grep, Bash
|
|
7
7
|
tags:
|
|
@@ -20,8 +20,8 @@ Every tick prints this BEFORE scanning for work, so you can see the loop's state
|
|
|
20
20
|
┌──────────────────────────────────────────────────────────────┐
|
|
21
21
|
│ tick · 14:23 │
|
|
22
22
|
│ identity: building atris-business cloud for design partners │
|
|
23
|
-
│ horizon:
|
|
24
|
-
│
|
|
23
|
+
│ horizon: customer-onboarding │
|
|
24
|
+
│ three setup checks are ready to ship │
|
|
25
25
|
│ progress: ████████░░░░ 6/9 endgame steps │
|
|
26
26
|
└──────────────────────────────────────────────────────────────┘
|
|
27
27
|
```
|
|
@@ -121,7 +121,7 @@ curl -s -X POST "https://api.atris.ai/api/integrations/google-slides/presentatio
|
|
|
121
121
|
{
|
|
122
122
|
"insertText": {
|
|
123
123
|
"objectId": "subtitleId",
|
|
124
|
-
"text": "
|
|
124
|
+
"text": "{{company_name}} - Confidential"
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
127
|
]
|
|
@@ -207,7 +207,7 @@ curl -s -X POST "https://api.atris.ai/api/integrations/google-slides/presentatio
|
|
|
207
207
|
{
|
|
208
208
|
"replaceAllText": {
|
|
209
209
|
"containsText": {"text": "{{company_name}}"},
|
|
210
|
-
"replaceText": "
|
|
210
|
+
"replaceText": "Example Co"
|
|
211
211
|
}
|
|
212
212
|
}
|
|
213
213
|
]
|
package/bin/atris.js
CHANGED
|
@@ -345,7 +345,7 @@ function showHelp() {
|
|
|
345
345
|
console.log('Atris Computers:');
|
|
346
346
|
console.log(' Owner = User | Business');
|
|
347
347
|
console.log(' Owners have Computers: workspace + files + tools + secrets + memory + agents + validation');
|
|
348
|
-
console.log(' Types: code, research, CRM, reporting,
|
|
348
|
+
console.log(' Types: code, research, CRM, reporting, events, support, business ops');
|
|
349
349
|
console.log('');
|
|
350
350
|
console.log('Setup:');
|
|
351
351
|
console.log(' setup - Guided first-time setup (login, pick business, pull)');
|
|
@@ -823,7 +823,7 @@ if (command === '2' && ['fast', 'pro'].includes(String(firstCommandArg || '').to
|
|
|
823
823
|
const knownCommands = ['init', 'log', 'now', 'radar', 'ctop', 'status', 'analytics', 'visualize', 'brain', 'brainstorm', 'autopilot', 'run', 'plan', 'do', 'review', 'release',
|
|
824
824
|
'activate', '_activate', 'agent', 'chat', 'fast', 'ax', 'console', 'serve', 'login', 'logout', 'whoami', 'switch', 'use', 'accounts', '_resolve', '_profile-email', '_switch-session', 'shell-init', 'update', 'upgrade', 'version', 'help', 'next', 'atris',
|
|
825
825
|
'clean', 'verify', 'search', 'skill', 'member', 'codex-goal', 'app', 'apps', 'learn', 'lesson', 'plugin', 'experiments', 'receipt', 'proof', 'openclaw', 'pull', 'push', 'live', 'align', 'terminal', 'computer', 'diff', 'business', 'sync', 'youtube',
|
|
826
|
-
'ingest', 'query', 'lint', 'loop', 'pulse', 'task', 'mission', 'probe', 'worktree', 'aeo', 'slop', 'deck', 'site', 'theme', 'card', 'reel', 'improve', 'xp', 'play', 'gm', 'x', 'recap', 'signup', 'clarity', 'moves',
|
|
826
|
+
'ingest', 'query', 'lint', 'loop', 'pulse', 'task', 'mission', 'probe', 'worktree', 'aeo', 'slop', 'security-review', 'secure', 'deck', 'site', 'theme', 'card', 'reel', 'improve', 'xp', 'play', 'gm', 'x', 'recap', 'signup', 'clarity', 'moves',
|
|
827
827
|
'gmail', 'calendar', 'twitter', 'slack', 'imessage', 'integrations', 'setup', 'clean-workspace', 'cw',
|
|
828
828
|
'fork', 'browse', 'publish', 'sleep', 'wake', 'feedback', 'errors', 'wiki', 'code-review', 'cr', 'soul', 'fleet', 'compile', 'spaceship'];
|
|
829
829
|
|
|
@@ -2061,6 +2061,27 @@ if (command === 'init') {
|
|
|
2061
2061
|
Promise.resolve(require('../commands/slop').slopCommand(process.argv.slice(3)))
|
|
2062
2062
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2063
2063
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2064
|
+
} else if (command === 'security-review' || command === 'secure') {
|
|
2065
|
+
// Security review: deterministic secrets/PII/code-risk scan (no LLM). Exit 1 = HIGH finding,
|
|
2066
|
+
// for the autopilot/mission/CI gate + a SOC 2 evidence artifact via --json.
|
|
2067
|
+
Promise.resolve(require('../commands/security-review').securityReviewCommand(process.argv.slice(3)))
|
|
2068
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2069
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2070
|
+
} else if (command === 'signup') {
|
|
2071
|
+
// Signup: one-call seedless agent signup → writes the active profile (install→signup→play seam).
|
|
2072
|
+
Promise.resolve(require('../commands/signup').signupCommand(process.argv.slice(3)))
|
|
2073
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2074
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2075
|
+
} else if (command === 'moves') {
|
|
2076
|
+
// Moves: your 3 next moves — approve one into the loop, kill, or skip.
|
|
2077
|
+
Promise.resolve(require('../commands/moves').movesCommand(process.argv.slice(3)))
|
|
2078
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2079
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2080
|
+
} else if (command === 'clarity') {
|
|
2081
|
+
// Clarity: interview yourself once; agents read how you work so you stop repeating it.
|
|
2082
|
+
Promise.resolve(require('../commands/clarity').clarityCommand(process.argv.slice(3)))
|
|
2083
|
+
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2084
|
+
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2064
2085
|
} else if (command === 'deck') {
|
|
2065
2086
|
// Deck: premium Google Slides from a plain content spec, via the Atris deck engine (anti-slop design system).
|
|
2066
2087
|
Promise.resolve(require('../commands/deck').run(process.argv.slice(3)))
|
|
@@ -2086,22 +2107,6 @@ if (command === 'init') {
|
|
|
2086
2107
|
Promise.resolve(require('../commands/reel').run(process.argv.slice(3)))
|
|
2087
2108
|
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2088
2109
|
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2089
|
-
} else if (command === 'signup') {
|
|
2090
|
-
// Signup: one-call seedless agent signup (POST /auth/agent/signup) → writes the
|
|
2091
|
-
// active profile so `atris play` works next. The install→signup→play seam.
|
|
2092
|
-
Promise.resolve(require('../commands/signup').signupCommand(process.argv.slice(3)))
|
|
2093
|
-
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2094
|
-
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2095
|
-
} else if (command === 'moves') {
|
|
2096
|
-
// Moves: your 3 next moves — approve one into the loop, kill, or skip.
|
|
2097
|
-
Promise.resolve(require('../commands/moves').movesCommand(process.argv.slice(3)))
|
|
2098
|
-
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2099
|
-
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2100
|
-
} else if (command === 'clarity') {
|
|
2101
|
-
// Clarity: interview yourself once; agents read how you work so you stop repeating it.
|
|
2102
|
-
Promise.resolve(require('../commands/clarity').clarityCommand(process.argv.slice(3)))
|
|
2103
|
-
.then((code) => process.exit(typeof code === 'number' ? code : 0))
|
|
2104
|
-
.catch((err) => { console.error(`\n✗ Error: ${err.message || err}`); process.exit(1); });
|
|
2105
2110
|
} else if (command === 'receipt' || command === 'proof' || command === 'openclaw') {
|
|
2106
2111
|
const subcommand = process.argv[3];
|
|
2107
2112
|
const args = process.argv.slice(4);
|
package/commands/aeo.js
CHANGED
|
@@ -173,7 +173,7 @@ function printHelp() {
|
|
|
173
173
|
console.log('');
|
|
174
174
|
console.log('Examples:');
|
|
175
175
|
console.log(' atris aeo log --engine perplexity --limit 5');
|
|
176
|
-
console.log(' atris aeo packet
|
|
176
|
+
console.log(' atris aeo packet <slug>');
|
|
177
177
|
console.log(' atris aeo status');
|
|
178
178
|
console.log(' atris aeo discover https://atris.ai/aeo --canonical-url https://atris.ai/aeo');
|
|
179
179
|
}
|
package/commands/autopilot.js
CHANGED
|
@@ -42,7 +42,7 @@ function looksOwnerGatedTitle(title) {
|
|
|
42
42
|
/\bhuman[- ](?:approval|input|gate|gated)\b/.test(text) ||
|
|
43
43
|
/\bmanual send\b/.test(text) ||
|
|
44
44
|
/\broute confirmation\b/.test(text) ||
|
|
45
|
-
/\bconfirm
|
|
45
|
+
/\bconfirm customer destination\b/.test(text) ||
|
|
46
46
|
/\bconfirm .+ destination before .+ approval\b/.test(text) ||
|
|
47
47
|
/\bapprove and manually send\b/.test(text)
|
|
48
48
|
);
|
package/commands/computer.js
CHANGED
|
@@ -1601,8 +1601,8 @@ async function computerCreate(token, args = [], defaults = {}) {
|
|
|
1601
1601
|
console.log('Create a business computer, activate it, and wake it in one command.');
|
|
1602
1602
|
console.log('');
|
|
1603
1603
|
console.log('Examples:');
|
|
1604
|
-
console.log(' atris computer create "My Business Computer" --business
|
|
1605
|
-
console.log(' atris computer create "
|
|
1604
|
+
console.log(' atris computer create "My Business Computer" --business <business>');
|
|
1605
|
+
console.log(' atris computer create "Support Computer"');
|
|
1606
1606
|
if (!options.name && !options.help) process.exitCode = 1;
|
|
1607
1607
|
return;
|
|
1608
1608
|
}
|
|
@@ -1810,8 +1810,8 @@ async function computerDelete(token, ctx, options = {}, args = []) {
|
|
|
1810
1810
|
console.log('Sleeps the computer first, then deletes the non-default workspace after confirmation.');
|
|
1811
1811
|
console.log('');
|
|
1812
1812
|
console.log('Examples:');
|
|
1813
|
-
console.log(' atris computer delete --business
|
|
1814
|
-
console.log(' atris computer delete --business
|
|
1813
|
+
console.log(' atris computer delete --business <business> --workspace ws_123');
|
|
1814
|
+
console.log(' atris computer delete --business <business> --workspace ws_123 --confirm "delete ws_123"');
|
|
1815
1815
|
return;
|
|
1816
1816
|
}
|
|
1817
1817
|
|
|
@@ -3291,7 +3291,7 @@ async function runComputer() {
|
|
|
3291
3291
|
console.log(' Owner has many Computers');
|
|
3292
3292
|
console.log(' Computer = workspace + files + tools + secrets + memory + agents + validation');
|
|
3293
3293
|
console.log('');
|
|
3294
|
-
console.log('Common types: codeops, research, CRM, reporting,
|
|
3294
|
+
console.log('Common types: codeops, research, CRM, reporting, event ops, support, business ops.');
|
|
3295
3295
|
console.log('A business can be a company, lab, collective, community, artist, team, or project.');
|
|
3296
3296
|
console.log('');
|
|
3297
3297
|
console.log('First use:');
|
|
@@ -3342,10 +3342,10 @@ async function runComputer() {
|
|
|
3342
3342
|
console.log(' atris computer');
|
|
3343
3343
|
console.log(' atris computer card --write');
|
|
3344
3344
|
console.log(' atris business init "My Lab" # first/default computer with Atris + operator');
|
|
3345
|
-
console.log(' atris computer create "
|
|
3346
|
-
console.log(' atris computer --business
|
|
3347
|
-
console.log(' atris computer sleep --business
|
|
3348
|
-
console.log(' atris computer delete --business
|
|
3345
|
+
console.log(' atris computer create "Support Computer" --business <business>');
|
|
3346
|
+
console.log(' atris computer --business <business> --workspace <workspace-id>');
|
|
3347
|
+
console.log(' atris computer sleep --business <business> --workspace <workspace-id>');
|
|
3348
|
+
console.log(' atris computer delete --business <business> --workspace <workspace-id>');
|
|
3349
3349
|
console.log(' atris computer proof');
|
|
3350
3350
|
console.log(' atris computer local');
|
|
3351
3351
|
console.log(' atris computer codex');
|
package/commands/feedback.js
CHANGED
|
@@ -231,7 +231,7 @@ function printHelp(write = console.log) {
|
|
|
231
231
|
write(' atris feedback delete <id> Delete feedback (admin)');
|
|
232
232
|
write('');
|
|
233
233
|
write('IDs may be the first 8 chars of the UUID.');
|
|
234
|
-
write('Business slugs come from ~/.atris/businesses.json
|
|
234
|
+
write('Business slugs come from ~/.atris/businesses.json.');
|
|
235
235
|
write('');
|
|
236
236
|
}
|
|
237
237
|
|
package/commands/init.js
CHANGED
|
@@ -257,7 +257,7 @@ function initAtris() {
|
|
|
257
257
|
}
|
|
258
258
|
// GUARD: Refuse nested init.
|
|
259
259
|
// Bug: running `atris init` inside an existing `atris/` folder creates
|
|
260
|
-
// `atris/atris/` nesting hell.
|
|
260
|
+
// `atris/atris/` nesting hell. A cloud business workspace had this exact problem.
|
|
261
261
|
// Fix: detect three nesting conditions and refuse with a clear error.
|
|
262
262
|
const cwd = process.cwd();
|
|
263
263
|
const cwdBase = path.basename(cwd);
|
|
@@ -705,7 +705,7 @@ member -> mission start --verify -> status --status active -> one bounded step -
|
|
|
705
705
|
- [ ] Only use \`atris task accept <id>\` when the human has approved the proof
|
|
706
706
|
- [ ] Keep durable learning in Atris-owned policy/skill/wiki/task state; keep \`AGENTS.md\` as a generated/pointer layer
|
|
707
707
|
- [ ] Treat \`atris/TODO.md\` as a rendered view; do not manually use it as the source of truth
|
|
708
|
-
- [ ] Use
|
|
708
|
+
- [ ] Use the real business slug from local Atris state; do not hardcode private slugs in generated docs
|
|
709
709
|
|
|
710
710
|
## Anti-patterns
|
|
711
711
|
|
package/commands/live.js
CHANGED
|
@@ -101,10 +101,10 @@ function printLiveHelp() {
|
|
|
101
101
|
console.log('Keeps a business brain fresh: doctor, pull, watch local changes, push after quiet, and periodically pull.');
|
|
102
102
|
console.log('');
|
|
103
103
|
console.log('Examples:');
|
|
104
|
-
console.log(' atris live
|
|
104
|
+
console.log(' atris live <business>');
|
|
105
105
|
console.log(' atris live --once');
|
|
106
|
-
console.log(' atris live
|
|
107
|
-
console.log(' atris live
|
|
106
|
+
console.log(' atris live <business> --dry-run');
|
|
107
|
+
console.log(' atris live <business> --interval=120 --debounce=30');
|
|
108
108
|
console.log('');
|
|
109
109
|
console.log('Options:');
|
|
110
110
|
console.log(' --once Run one freshness cycle and exit');
|
package/commands/plugin.js
CHANGED
|
@@ -46,7 +46,7 @@ function generateManifest(skills, projectDir) {
|
|
|
46
46
|
version: pkg.version || '1.0.0',
|
|
47
47
|
description: `Atris workspace skills for Cowork — ${skills.length} integrations (email, calendar, slack, drive, notion, and more)`,
|
|
48
48
|
author: {
|
|
49
|
-
name: typeof pkg.author === 'string' ? pkg.author : (pkg.author?.name || 'Atris
|
|
49
|
+
name: typeof pkg.author === 'string' ? pkg.author : (pkg.author?.name || 'Atris')
|
|
50
50
|
},
|
|
51
51
|
homepage: pkg.homepage || 'https://github.com/atrislabs/atris',
|
|
52
52
|
keywords: ['atris', 'workspace', 'integrations', 'email', 'calendar', 'slack', 'notion', 'drive']
|
package/commands/pull.js
CHANGED
|
@@ -110,9 +110,9 @@ async function pullAtris() {
|
|
|
110
110
|
console.log(' Local files that conflict with cloud are replaced by the cloud version.');
|
|
111
111
|
console.log('');
|
|
112
112
|
console.log(' atris pull Pull into current business workspace');
|
|
113
|
-
console.log(' atris pull
|
|
114
|
-
console.log(' atris pull
|
|
115
|
-
console.log(' atris pull
|
|
113
|
+
console.log(' atris pull <business> Pull a business into ./<business> or --into <path>');
|
|
114
|
+
console.log(' atris pull <business> --into /tmp/<business>');
|
|
115
|
+
console.log(' atris pull <business> --only atris/wiki/');
|
|
116
116
|
console.log(' atris pull --keep-local Preserve conflicting local edits as .remote files (legacy)');
|
|
117
117
|
console.log(' atris pull --dry-run Preview pull changes without writing local files');
|
|
118
118
|
console.log(' atris pull --no-manifest Pull for inspection without changing this machine\'s sync anchor');
|
|
@@ -249,7 +249,7 @@ async function pullBusiness(slug) {
|
|
|
249
249
|
// correct workspace for THIS business — i.e. it has a `.atris/business.json`
|
|
250
250
|
// whose slug matches `slug`. Any other signal (a stray `atris/` folder, a
|
|
251
251
|
// business.json for a different business, etc.) is NOT enough: pulling
|
|
252
|
-
//
|
|
252
|
+
// one business on top of another business workspace would mix two businesses into
|
|
253
253
|
// one directory and write one manifest over the other (or vice
|
|
254
254
|
// versa), causing the next sync to do strange things.
|
|
255
255
|
//
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
// atris security-review — deterministic secrets / PII / privacy scan (no LLM).
|
|
2
|
+
//
|
|
3
|
+
// "Is this workspace safe to commit, publish, or hand to an autonomous loop?"
|
|
4
|
+
// Answers it with facts: file:line + rule + severity. Exit 1 on a HIGH finding,
|
|
5
|
+
// so it drops into the autopilot/mission/CI verification gate. `--json` emits a
|
|
6
|
+
// SOC 2 evidence artifact. Scans git-tracked files by default (what is exposed
|
|
7
|
+
// is what is committed), or a path you pass.
|
|
8
|
+
//
|
|
9
|
+
// Usage:
|
|
10
|
+
// atris security-review scan tracked files (default)
|
|
11
|
+
// atris security-review src/ scan a path
|
|
12
|
+
// atris security-review --staged scan staged changes (pre-commit gate)
|
|
13
|
+
// atris security-review --json machine output for CI / the loop
|
|
14
|
+
// atris security-review --strict also fail on MEDIUM (PII/paths)
|
|
15
|
+
// atris security-review hook install a pre-commit gate
|
|
16
|
+
//
|
|
17
|
+
// Exit code: 0 = clean, 1 = findings at/over the fail threshold, 2 = bad usage.
|
|
18
|
+
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const path = require('path');
|
|
21
|
+
const { runScan, RULES } = require('../lib/security-scan');
|
|
22
|
+
|
|
23
|
+
const ICON = { high: '✗', medium: '!', low: '·', privacy: '✗', secret: '✗', pii: '!' };
|
|
24
|
+
const SEV_ORDER = { high: 0, medium: 1, low: 2 };
|
|
25
|
+
|
|
26
|
+
function securityReviewCommand(argv = []) {
|
|
27
|
+
const sub = argv[0];
|
|
28
|
+
if (sub === 'help' || argv.includes('-h') || argv.includes('--help')) return printHelp();
|
|
29
|
+
if (sub === 'rules') return printRules();
|
|
30
|
+
if (sub === 'hook' || sub === 'install-hook') return installHook();
|
|
31
|
+
|
|
32
|
+
const json = argv.includes('--json');
|
|
33
|
+
const quiet = argv.includes('--quiet');
|
|
34
|
+
const strict = argv.includes('--strict');
|
|
35
|
+
const staged = argv.includes('--staged');
|
|
36
|
+
const paths = argv.filter((a) => !a.startsWith('-') && a !== 'scan');
|
|
37
|
+
const root = process.cwd();
|
|
38
|
+
|
|
39
|
+
let result;
|
|
40
|
+
try {
|
|
41
|
+
result = runScan({ root, paths, staged });
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.error(`security-review: ${e.message}`);
|
|
44
|
+
return 2;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const { findings, counts, scanned } = result;
|
|
48
|
+
findings.sort((a, b) => (SEV_ORDER[a.sev] - SEV_ORDER[b.sev]) || a.file.localeCompare(b.file) || (a.line - b.line));
|
|
49
|
+
const failThreshold = strict ? ['high', 'medium'] : ['high'];
|
|
50
|
+
const failing = findings.filter((f) => failThreshold.includes(f.sev)).length;
|
|
51
|
+
|
|
52
|
+
if (json) {
|
|
53
|
+
console.log(JSON.stringify({
|
|
54
|
+
ok: failing === 0,
|
|
55
|
+
scanned,
|
|
56
|
+
counts,
|
|
57
|
+
fail_threshold: strict ? 'medium' : 'high',
|
|
58
|
+
findings,
|
|
59
|
+
generated_for: 'soc2-evidence',
|
|
60
|
+
}, null, 2));
|
|
61
|
+
return failing ? 1 : 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!quiet) {
|
|
65
|
+
console.log('\n ◉ atris security review');
|
|
66
|
+
if (!findings.length) {
|
|
67
|
+
console.log(`\n ✓ clean — no secrets, PII, or sensitive files in ${scanned} tracked file${scanned === 1 ? '' : 's'}\n`);
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
console.log('');
|
|
71
|
+
const w = Math.max(...findings.map((f) => `${f.file}${f.line ? ':' + f.line : ''}`.length));
|
|
72
|
+
for (const f of findings) {
|
|
73
|
+
const loc = `${f.file}${f.line ? ':' + f.line : ''}`.padEnd(w);
|
|
74
|
+
console.log(` ${ICON[f.sev] || '·'} ${f.sev.toUpperCase().padEnd(6)} ${loc} ${f.rule.padEnd(22)} ${f.why}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
console.log(`\n ${counts.high || 0} high · ${counts.medium || 0} medium · ${counts.low || 0} low across ${scanned} file${scanned === 1 ? '' : 's'}`);
|
|
78
|
+
if (failing) {
|
|
79
|
+
console.log(` ${failing} finding${failing === 1 ? '' : 's'} at/over the ${strict ? 'MEDIUM' : 'HIGH'} threshold · exit 1`);
|
|
80
|
+
console.log(' fix or suppress (trailing `atris-allow-secret`), then re-run.\n');
|
|
81
|
+
} else {
|
|
82
|
+
console.log(` no findings at the ${strict ? 'MEDIUM' : 'HIGH'} threshold · exit 0\n`);
|
|
83
|
+
}
|
|
84
|
+
return failing ? 1 : 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function printRules() {
|
|
88
|
+
console.log('\n atris security-review — deterministic rules:\n');
|
|
89
|
+
for (const r of RULES) console.log(` ${r.sev.toUpperCase().padEnd(6)} ${r.cat.padEnd(8)} ${r.id.padEnd(22)} ${r.why}`);
|
|
90
|
+
console.log(`\n ${RULES.length} rules + tracked-sensitive-file check. Suppress a line with a trailing \`atris-allow-secret\`.\n`);
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function installHook() {
|
|
95
|
+
const root = process.cwd();
|
|
96
|
+
const hookDir = path.join(root, '.git', 'hooks');
|
|
97
|
+
try {
|
|
98
|
+
fs.mkdirSync(hookDir, { recursive: true });
|
|
99
|
+
const hookPath = path.join(hookDir, 'pre-commit');
|
|
100
|
+
const marker = '# atris security gate';
|
|
101
|
+
let content = '';
|
|
102
|
+
try { content = fs.readFileSync(hookPath, 'utf8'); } catch {}
|
|
103
|
+
if (content.includes(marker)) { console.log(`\n already installed: ${path.relative(root, hookPath)}\n`); return 0; }
|
|
104
|
+
if (!content) content = '#!/bin/sh\n';
|
|
105
|
+
if (!content.endsWith('\n')) content += '\n';
|
|
106
|
+
content += `\n${marker}\nif command -v atris >/dev/null 2>&1; then atris security-review --staged --quiet || exit 1; fi\n`;
|
|
107
|
+
fs.writeFileSync(hookPath, content);
|
|
108
|
+
fs.chmodSync(hookPath, 0o755);
|
|
109
|
+
console.log(`\n ✓ security pre-commit gate installed: ${path.relative(root, hookPath)}\n every commit now runs: atris security-review --staged\n`);
|
|
110
|
+
return 0;
|
|
111
|
+
} catch (e) { console.error(` ${e.message}`); return 2; }
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function printHelp() {
|
|
115
|
+
console.log(`
|
|
116
|
+
atris security-review — deterministic secrets / PII / privacy scan (no LLM)
|
|
117
|
+
|
|
118
|
+
atris security-review scan git-tracked files (default)
|
|
119
|
+
atris security-review <path> scan a file or dir
|
|
120
|
+
atris security-review --staged scan staged changes (pre-commit gate)
|
|
121
|
+
atris security-review --strict also fail on MEDIUM (PII / personal paths)
|
|
122
|
+
atris security-review --json machine output / SOC 2 evidence artifact
|
|
123
|
+
atris security-review rules list the active detectors
|
|
124
|
+
atris security-review hook install a pre-commit gate
|
|
125
|
+
|
|
126
|
+
Scans for hardcoded secrets, API keys, personal data, and tracked sensitive
|
|
127
|
+
files. exit 0 = clean, 1 = found. Wire into the autopilot/mission gate and CI.
|
|
128
|
+
`);
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
module.exports = { securityReviewCommand };
|
package/commands/task.js
CHANGED
|
@@ -616,7 +616,6 @@ function readGoalSources(root = process.cwd()) {
|
|
|
616
616
|
const candidates = [
|
|
617
617
|
path.join(root, 'atris', 'goals.md'),
|
|
618
618
|
path.join(root, 'goals.md'),
|
|
619
|
-
path.join(root, 'atris', 'wiki', 'concepts', 'atris-labs-goals.md'),
|
|
620
619
|
];
|
|
621
620
|
for (const file of candidates) {
|
|
622
621
|
if (!fs.existsSync(file)) continue;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// atris security scan — deterministic secrets / PII / privacy detectors (no LLM).
|
|
4
|
+
//
|
|
5
|
+
// A finding is a fact (file:line + rule + severity), so it drops straight into a
|
|
6
|
+
// loop / mission / CI gate and doubles as a SOC 2 evidence artifact (machine
|
|
7
|
+
// JSON). Precision over recall: a noisy gate gets muted, and a muted gate is dead.
|
|
8
|
+
// Suppress a single line with a trailing `atris-allow-secret` comment.
|
|
9
|
+
//
|
|
10
|
+
// Zero external deps (Node built-ins only) — repo contract.
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const { execFileSync } = require('child_process');
|
|
15
|
+
|
|
16
|
+
const SCAN_EXTS = new Set([
|
|
17
|
+
'.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx', '.json', '.md', '.mdx', '.txt',
|
|
18
|
+
'.yml', '.yaml', '.env', '.sh', '.bash', '.zsh', '.py', '.rb', '.go', '.java',
|
|
19
|
+
'.php', '.toml', '.ini', '.cfg', '.conf', '.html', '.vue', '.svelte', '.patch',
|
|
20
|
+
]);
|
|
21
|
+
const SKIP_DIRS = new Set(['node_modules', '.git', 'dist', 'build', '.next', 'coverage', 'out', 'vendor', '.cache', '__pycache__']);
|
|
22
|
+
|
|
23
|
+
// Lines that opt out, and placeholder noise we never flag.
|
|
24
|
+
const ALLOW_MARKER = /atris-allow-secret|atris-security-ignore/i;
|
|
25
|
+
const PLACEHOLDER = /\b(?:example|placeholder|your[_-]?|my[_-]?key|xxx+|redacted|dummy|sample|changeme|test[_-]?key|fake|dummy|<[a-z_-]+>|process\.env|getenv|os\.environ|import\.meta\.env)\b/i;
|
|
26
|
+
|
|
27
|
+
// High-precision secret patterns. severity high => fails the gate.
|
|
28
|
+
const SECRET_RULES = [
|
|
29
|
+
{ id: 'private-key', sev: 'high', cat: 'secret', re: /-----BEGIN (?:RSA |EC |OPENSSH |PGP |DSA |ENCRYPTED )?PRIVATE KEY-----/, why: 'private key committed in source' },
|
|
30
|
+
{ id: 'aws-access-key-id', sev: 'high', cat: 'secret', re: /\bAKIA[0-9A-Z]{16}\b/, why: 'AWS access key id' },
|
|
31
|
+
{ id: 'github-token', sev: 'high', cat: 'secret', re: /\bgh[pousr]_[A-Za-z0-9]{36,}\b/, why: 'GitHub personal/OAuth token' },
|
|
32
|
+
{ id: 'slack-token', sev: 'high', cat: 'secret', re: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/, why: 'Slack token' },
|
|
33
|
+
{ id: 'slack-webhook', sev: 'high', cat: 'secret', re: /https:\/\/hooks\.slack\.com\/services\/[A-Za-z0-9/_-]{20,}/, why: 'Slack incoming webhook url' },
|
|
34
|
+
{ id: 'openai-key', sev: 'high', cat: 'secret', re: /\bsk-(?:proj-)?[A-Za-z0-9]{20,}\b/, why: 'OpenAI-style API key' },
|
|
35
|
+
{ id: 'anthropic-key', sev: 'high', cat: 'secret', re: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/, why: 'Anthropic API key' },
|
|
36
|
+
{ id: 'google-api-key', sev: 'high', cat: 'secret', re: /\bAIza[0-9A-Za-z_-]{35}\b/, why: 'Google API key' },
|
|
37
|
+
{ id: 'stripe-key', sev: 'high', cat: 'secret', re: /\b[rs]k_live_[A-Za-z0-9]{20,}\b/, why: 'Stripe live key' },
|
|
38
|
+
{ id: 'npm-token', sev: 'high', cat: 'secret', re: /\bnpm_[A-Za-z0-9]{36}\b/, why: 'npm access token' },
|
|
39
|
+
{ id: 'jwt', sev: 'medium', cat: 'secret', re: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{6,}\b/, why: 'JWT (often carries claims/PII)' },
|
|
40
|
+
{ id: 'bearer-token', sev: 'medium', cat: 'secret', re: /\bBearer\s+[A-Za-z0-9._-]{24,}/, why: 'hardcoded Bearer token' },
|
|
41
|
+
{ id: 'assigned-secret', sev: 'high', cat: 'secret', re: /(?:password|passwd|pwd|secret|api[_-]?key|apikey|access[_-]?token|auth[_-]?token|client[_-]?secret|private[_-]?key)\s*[:=]\s*['"][^'"\s]{8,}['"]/i, why: 'hardcoded credential assignment' },
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
// Personal data. Home-path is the recurring leak (a username + local layout).
|
|
45
|
+
const PII_RULES = [
|
|
46
|
+
{ id: 'home-path', sev: 'medium', cat: 'pii', re: /(?:\/Users\/|\/home\/)(?!runner\/|runner\b|root\/|root\b|ubuntu\/|ubuntu\b|user\/|user\b|node\/)[a-z][a-z0-9_.-]+/i, why: 'personal home path leaks a username + local layout (use os.homedir()/relative)' },
|
|
47
|
+
{ id: 'windows-home-path', sev: 'medium', cat: 'pii', re: /[A-Za-z]:\\Users\\(?!Public\b)[^\\\s'"]+/, why: 'personal Windows path leaks a username' },
|
|
48
|
+
{ id: 'email', sev: 'low', cat: 'pii', re: /\b[A-Za-z0-9._%+-]+@(?!example\.|sentry\.io|test\b|localhost|[\w.-]*\.local\b|sub\.)[A-Za-z0-9.-]+\.(?:com|net|org|ai|io|dev|co)\b/, why: 'email address (possible PII)' },
|
|
49
|
+
{ id: 'phone', sev: 'low', cat: 'pii', re: /(?<![\d.\w])(?:\+?1[-.\s])?\(?\d{3}\)?[-.\s]\d{3}[-.\s]\d{4}(?![\d.\w])/, why: 'phone-number-shaped string' },
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
// Code-execution risks. For an AI CLI that runs autonomous loops and shells out,
|
|
53
|
+
// these are the "are we actually safe" checks beyond data exposure. eval/Function
|
|
54
|
+
// are almost never legitimate (HIGH); shelling out with interpolated input is the
|
|
55
|
+
// command-injection class (MEDIUM — common and sometimes safe, so it asks for a
|
|
56
|
+
// human look rather than hard-failing the gate).
|
|
57
|
+
const CODE_RULES = [
|
|
58
|
+
{ id: 'eval-call', sev: 'high', cat: 'code', re: /(?<![.\w])eval\((?!\s*\))/, why: 'eval() executes arbitrary code' },
|
|
59
|
+
{ id: 'new-function', sev: 'high', cat: 'code', re: /\bnew\s+Function\(/, why: 'new Function() executes arbitrary code' },
|
|
60
|
+
{ id: 'shell-exec-interpolation', sev: 'medium', cat: 'code', re: /\b(?:exec|execSync)\s*\(\s*[`'"][^`'"]*(?:\$\{|"\s*\+|'\s*\+)/, why: 'shell exec with interpolated input (command-injection risk; prefer execFile/spawn with an args array)' },
|
|
61
|
+
{ id: 'child-process-shell-true', sev: 'medium', cat: 'code', re: /\bshell\s*:\s*true\b/, why: 'child_process shell:true enables shell interpretation of args' },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
// extra per-line excludes that keep email/path rules from firing on safe noise
|
|
65
|
+
const EMAIL_SAFE = /\b(?:noreply|no-reply|support|hello|info|contact|team|hi|admin|press)@/i;
|
|
66
|
+
|
|
67
|
+
const RULES = [...SECRET_RULES, ...PII_RULES, ...CODE_RULES];
|
|
68
|
+
|
|
69
|
+
// Filenames that should never be committed (checked against the tracked file list).
|
|
70
|
+
const SENSITIVE_FILE_RE = /(?:^|\/)(?:\.env(?:\.[\w.-]+)?|id_rsa|id_dsa|id_ed25519|.*\.pem|.*\.pfx|.*\.p12|.*\.keystore|credentials\.json|\.npmrc|\.pypirc|\.netrc|secrets?\.(?:json|ya?ml|env))$/i;
|
|
71
|
+
const SENSITIVE_FILE_ALLOW = /\.env\.example$|\.env\.sample$|\.env\.template$/i;
|
|
72
|
+
|
|
73
|
+
function scanLine(line, rules = RULES) {
|
|
74
|
+
if (ALLOW_MARKER.test(line)) return [];
|
|
75
|
+
const findings = [];
|
|
76
|
+
const placeholder = PLACEHOLDER.test(line);
|
|
77
|
+
for (const rule of rules) {
|
|
78
|
+
const m = rule.re.exec(line);
|
|
79
|
+
if (!m) continue;
|
|
80
|
+
// Secrets in obvious placeholder/env-read lines are not real leaks.
|
|
81
|
+
if (rule.cat === 'secret' && placeholder) continue;
|
|
82
|
+
if (rule.id === 'email' && EMAIL_SAFE.test(line)) continue;
|
|
83
|
+
findings.push({ rule: rule.id, sev: rule.sev, cat: rule.cat, why: rule.why, snippet: m[0].trim().slice(0, 60) });
|
|
84
|
+
}
|
|
85
|
+
return findings;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function scanText(text, rules = RULES) {
|
|
89
|
+
const out = [];
|
|
90
|
+
const lines = String(text || '').split('\n');
|
|
91
|
+
for (let i = 0; i < lines.length; i++) {
|
|
92
|
+
for (const f of scanLine(lines[i], rules)) out.push({ ...f, line: i + 1 });
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Code-execution rules only make sense in actual code files — `eval(` written in
|
|
98
|
+
// a markdown doc is prose, not a vuln.
|
|
99
|
+
const CODE_EXTS = new Set(['.js', '.mjs', '.cjs', '.ts', '.tsx', '.jsx', '.py', '.rb', '.go', '.java', '.php', '.sh', '.bash', '.zsh']);
|
|
100
|
+
|
|
101
|
+
function rulesForFile(file) {
|
|
102
|
+
return CODE_EXTS.has(path.extname(file)) ? RULES : RULES.filter((r) => r.cat !== 'code');
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function scanFile(file, rules) {
|
|
106
|
+
let text;
|
|
107
|
+
try { text = fs.readFileSync(file, 'utf8'); } catch { return []; }
|
|
108
|
+
return scanText(text, rules || rulesForFile(file)).map((f) => ({ ...f, file }));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Repo-level hygiene: a sensitive file being tracked at all is a finding,
|
|
112
|
+
// independent of its contents.
|
|
113
|
+
function sensitiveFileFindings(relPaths) {
|
|
114
|
+
const out = [];
|
|
115
|
+
for (const p of relPaths) {
|
|
116
|
+
if (SENSITIVE_FILE_RE.test(p) && !SENSITIVE_FILE_ALLOW.test(p)) {
|
|
117
|
+
out.push({ file: p, line: 0, rule: 'tracked-sensitive-file', sev: 'high', cat: 'privacy', why: 'sensitive file is tracked in git (gitignore + remove it)', snippet: path.basename(p) });
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function gitTrackedFiles(root, { staged = false } = {}) {
|
|
124
|
+
try {
|
|
125
|
+
const args = staged ? ['diff', '--cached', '--name-only', '--diff-filter=ACM'] : ['ls-files'];
|
|
126
|
+
const out = execFileSync('git', args, { cwd: root, encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
|
|
127
|
+
return out.split('\n').map((s) => s.trim()).filter(Boolean);
|
|
128
|
+
} catch {
|
|
129
|
+
return null; // not a git repo / git unavailable
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function walk(target, out) {
|
|
134
|
+
let stat;
|
|
135
|
+
try { stat = fs.statSync(target); } catch { return out; }
|
|
136
|
+
if (stat.isFile()) { out.push(target); return out; }
|
|
137
|
+
if (stat.isDirectory()) {
|
|
138
|
+
if (SKIP_DIRS.has(path.basename(target))) return out;
|
|
139
|
+
for (const name of fs.readdirSync(target)) {
|
|
140
|
+
if (name === '.git' || SKIP_DIRS.has(name)) continue;
|
|
141
|
+
walk(path.join(target, name), out);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return out;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function scannable(file) {
|
|
148
|
+
const ext = path.extname(file);
|
|
149
|
+
return SCAN_EXTS.has(ext) || path.basename(file).startsWith('.env');
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Resolve the set of files to scan + the relative-path list for hygiene checks.
|
|
153
|
+
function resolveTargets({ root = process.cwd(), paths = [], staged = false } = {}) {
|
|
154
|
+
if (paths.length) {
|
|
155
|
+
const files = paths.flatMap((p) => walk(path.resolve(root, p), [])).filter(scannable);
|
|
156
|
+
return { files, relPaths: files.map((f) => path.relative(root, f)) };
|
|
157
|
+
}
|
|
158
|
+
const tracked = gitTrackedFiles(root, { staged });
|
|
159
|
+
if (tracked) {
|
|
160
|
+
const files = tracked.filter(scannable).map((p) => path.join(root, p)).filter((f) => fs.existsSync(f));
|
|
161
|
+
return { files, relPaths: tracked };
|
|
162
|
+
}
|
|
163
|
+
const files = walk(root, []).filter(scannable);
|
|
164
|
+
return { files, relPaths: files.map((f) => path.relative(root, f)) };
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Full scan: line-level findings across files + repo hygiene findings.
|
|
168
|
+
// The scanner's own pattern database and its fixtures necessarily contain the
|
|
169
|
+
// very strings it detects — never scan them (a tool that flags itself is noise).
|
|
170
|
+
const SELF_FILES = new Set(['lib/security-scan.js', 'commands/security-review.js', 'test/security-scan.test.js']);
|
|
171
|
+
|
|
172
|
+
function runScan({ root = process.cwd(), paths = [], staged = false } = {}) {
|
|
173
|
+
const { files, relPaths } = resolveTargets({ root, paths, staged });
|
|
174
|
+
const findings = [];
|
|
175
|
+
for (const f of files) {
|
|
176
|
+
if (SELF_FILES.has(path.relative(root, f))) continue;
|
|
177
|
+
for (const finding of scanFile(f)) findings.push({ ...finding, file: path.relative(root, finding.file) });
|
|
178
|
+
}
|
|
179
|
+
findings.push(...sensitiveFileFindings(relPaths.filter((p) => !SELF_FILES.has(p))));
|
|
180
|
+
const counts = { high: 0, medium: 0, low: 0 };
|
|
181
|
+
for (const f of findings) counts[f.sev] = (counts[f.sev] || 0) + 1;
|
|
182
|
+
return { findings, counts, scanned: files.length };
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
module.exports = {
|
|
186
|
+
scanLine, scanText, scanFile, sensitiveFileFindings, gitTrackedFiles,
|
|
187
|
+
resolveTargets, runScan, SECRET_RULES, PII_RULES, RULES,
|
|
188
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atris",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.28.0",
|
|
4
4
|
"main": "bin/atris.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"atris": "bin/atris.js",
|
|
@@ -48,13 +48,6 @@
|
|
|
48
48
|
"atris/features/_templates/",
|
|
49
49
|
"atris/features/company-brain-sync/",
|
|
50
50
|
"templates/",
|
|
51
|
-
"atris/wiki/index.md",
|
|
52
|
-
"atris/wiki/concepts/agent-activation-contract.md",
|
|
53
|
-
"atris/wiki/concepts/workspace-initialization-contract.md",
|
|
54
|
-
"atris/wiki/sources/atris-labs-2026-05-10.txt",
|
|
55
|
-
"atris/wiki/sources/atris-labs-goals-2026-05-10.txt",
|
|
56
|
-
"atris/wiki/sources/atrisos-generative-ui-product-surface-2026-05-10.txt",
|
|
57
|
-
"atris/wiki/sources/jack-dorsey-2026-05-10.txt",
|
|
58
51
|
"atris/policies/",
|
|
59
52
|
"atris/skills/"
|
|
60
53
|
],
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: concept
|
|
3
|
-
slug: agent-activation-contract
|
|
4
|
-
title: Agent Activation Contract
|
|
5
|
-
sources:
|
|
6
|
-
- atris/CLAUDE.md
|
|
7
|
-
- commands/activate.js
|
|
8
|
-
last_compiled: 2026-06-23
|
|
9
|
-
last_verified: 2026-06-23
|
|
10
|
-
confidence: 0.9
|
|
11
|
-
dependencies:
|
|
12
|
-
- atris/wiki/concepts/plan-do-review-loop.md
|
|
13
|
-
- atris/wiki/concepts/wiki-as-memory-substrate.md
|
|
14
|
-
actionability: "Use this before changing agent boot instructions, `atris activate`, MAP-first behavior, first-message requirements, or durable-memory routing."
|
|
15
|
-
created: 2026-05-10
|
|
16
|
-
updated: 2026-06-23
|
|
17
|
-
tags:
|
|
18
|
-
- agent-activation
|
|
19
|
-
- protocol
|
|
20
|
-
- mapfirst
|
|
21
|
-
---
|
|
22
|
-
# Agent Activation Contract
|
|
23
|
-
|
|
24
|
-
`atris/CLAUDE.md` is the editor-facing boot contract for agents entering an Atris-managed project. `commands/activate.js` is the runtime context panel agents use after that boot. Together they define what "activation" means before responding or editing.
|
|
25
|
-
|
|
26
|
-
## Boot Sequence
|
|
27
|
-
|
|
28
|
-
```text
|
|
29
|
-
first message -> atris atris.md
|
|
30
|
-
setup -> PERSONA + activate + wiki STATUS
|
|
31
|
-
navigation -> MAP first, then one grep if needed
|
|
32
|
-
work -> plan -> do -> review
|
|
33
|
-
memory -> wiki or ingest durable knowledge
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
The first response path is explicit: run `atris atris.md`, show the welcome visualization, then answer. After that, agents load `atris/PERSONA.md`, run `atris activate`, and treat `atris/wiki/STATUS.md` as the current memory snapshot when it exists.
|
|
37
|
-
|
|
38
|
-
## Runtime Activation
|
|
39
|
-
|
|
40
|
-
`atris activate` refuses to run without an `atris/` folder and tells the operator to run `atris init` first. In a valid workspace it creates today's journal if missing, detects workspace state, loads current task context, reads `atris/wiki/STATUS.md`, and prints a narrow activation card.
|
|
41
|
-
|
|
42
|
-
The activation card can include:
|
|
43
|
-
|
|
44
|
-
- a handoff block from today's journal when `## Handoff` has structured context,
|
|
45
|
-
- the last three deduped completions from journal history,
|
|
46
|
-
- the current state summary from detected in-progress, backlog, and inbox items,
|
|
47
|
-
- a learning count from `atris/learnings.jsonl`,
|
|
48
|
-
- wiki health from `atris/wiki/STATUS.md`,
|
|
49
|
-
- core file paths for persona, MAP, task view, journal, and wiki status.
|
|
50
|
-
|
|
51
|
-
The command ends by pointing the operator back to `atris plan -> do -> review` or `atris log`. It is a read/load surface with one deliberate local side effect: ensuring the current journal file exists so the session is writable.
|
|
52
|
-
|
|
53
|
-
## MAP-First Rule
|
|
54
|
-
|
|
55
|
-
Before any file search, read `atris/MAP.md` and search the map for the target keyword. If the map has the location, go directly to that file and line. If not, grep once and update `MAP.md` so the next agent does not repeat the same scan.
|
|
56
|
-
|
|
57
|
-
## Core Truth Surfaces
|
|
58
|
-
|
|
59
|
-
- `atris/MAP.md` is navigation.
|
|
60
|
-
- `atris/TODO.md` is the visible work queue; current task ownership lives in `atris task`.
|
|
61
|
-
- `atris/logs/YYYY/YYYY-MM-DD.md` is the operating journal.
|
|
62
|
-
- `atris/wiki/STATUS.md` is the current memory snapshot.
|
|
63
|
-
- `atris/wiki/index.md` is the durable knowledge index.
|
|
64
|
-
- `atris/atris.md` is the full protocol.
|
|
65
|
-
|
|
66
|
-
## Execution Contract
|
|
67
|
-
|
|
68
|
-
Work follows `atris plan -> atris do -> atris review`. Planning requires an ASCII visualization and an approval gate. Execution is step-by-step, with verification as reality changes. Completed tasks should be removed from the active queue; the target state is zero stale tasks.
|
|
69
|
-
|
|
70
|
-
Durable project knowledge belongs in `atris/wiki/` or through the local wiki flow. Ephemeral progress belongs in task state and the daily journal, not in ad hoc context.
|
|
71
|
-
|
|
72
|
-
`atris/CLAUDE.md` now also carries an explicit agent contract: before edits, claim or create one small task with `atris task` and write the goal/files/done/check contract into task dialogue; after edits, move proof-backed work to Review with `atris task ready <id> --proof "..."`. Proof-ready and human accept are separate gates: an agent's native goal can complete once proof is in Review, but only a human-run `atris task accept <id>` marks the task Done and awards AgentXP. Work that should outlive the chat runs through `atris mission` (start with a verifier, bounded step, `mission tick --verify`, then complete or continue).
|
|
73
|
-
|
|
74
|
-
## Limits
|
|
75
|
-
|
|
76
|
-
This page summarizes the activation contract only. Use `atris/atris.md` for the complete protocol, `atris/wiki/concepts/plan-do-review-loop.md` for stage ownership and proof, and `atris/wiki/concepts/wiki-as-memory-substrate.md` for wiki page shape and upkeep behavior. `atris activate` reports state; it does not claim tasks, finish work, or repair broken wiki pages.
|
|
77
|
-
|
|
78
|
-
## Cross-References
|
|
79
|
-
|
|
80
|
-
- [[atris/wiki/concepts/plan-do-review-loop.md]] - stage ownership, proof, and review closure
|
|
81
|
-
- [[atris/wiki/concepts/wiki-as-memory-substrate.md]] - durable memory routing and wiki verification
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: concept
|
|
3
|
-
slug: workspace-initialization-contract
|
|
4
|
-
title: Workspace Initialization Contract
|
|
5
|
-
sources:
|
|
6
|
-
- commands/init.js
|
|
7
|
-
last_compiled: 2026-06-23
|
|
8
|
-
last_verified: 2026-06-23
|
|
9
|
-
confidence: 0.86
|
|
10
|
-
dependencies:
|
|
11
|
-
- atris/wiki/systems/atris-cli.md
|
|
12
|
-
- atris/wiki/concepts/agent-activation-contract.md
|
|
13
|
-
- atris/wiki/concepts/wiki-as-memory-substrate.md
|
|
14
|
-
actionability: "Use this before changing `atris init`, workspace scaffolds, generated agent instructions, project detection, or boot hook behavior."
|
|
15
|
-
created: 2026-05-10
|
|
16
|
-
updated: 2026-06-23
|
|
17
|
-
tags:
|
|
18
|
-
- initialization
|
|
19
|
-
- workspace
|
|
20
|
-
- scaffold
|
|
21
|
-
---
|
|
22
|
-
# Workspace Initialization Contract
|
|
23
|
-
|
|
24
|
-
`commands/init.js` defines the local contract for turning an arbitrary folder into an Atris-managed workspace. It is the repo-level bootstrap path, not the business workspace onboarding path.
|
|
25
|
-
|
|
26
|
-
## Shape
|
|
27
|
-
|
|
28
|
-
```text
|
|
29
|
-
guard workspace -> create atris/ -> scaffold memory + teams + features
|
|
30
|
-
-> detect project -> inject team context
|
|
31
|
-
-> generate agent entry files + hooks
|
|
32
|
-
-> copy atris protocol
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The command handles `atris init [--force]`. Help flags print usage without filesystem side effects. Normal execution refuses to run inside an existing `atris/` directory, inside a parent business workspace, or in a folder with `.atris/business.json` unless `--force` is present.
|
|
36
|
-
|
|
37
|
-
## What Init Creates
|
|
38
|
-
|
|
39
|
-
- Core workspace: `atris/`, `atris/atris.md`, `atris/PERSONA.md`, `atris/GETTING_STARTED.md`, `atris/MAP.md`, `atris/TODO.md`, `atris/now.md`, `atris/lessons.md`, and dated logs.
|
|
40
|
-
- Memory surfaces: wiki scaffold via `ensureWikiScaffold`, feature templates, experiments harness, and `INTUITION.md`.
|
|
41
|
-
- Team surfaces: `atris/team/<member>/MEMBER.md` plus `skills/`, `tools/`, and `context/` folders for default members.
|
|
42
|
-
- Project profile: `.project-profile.json` from package files, framework hints, directory shape, and default test command.
|
|
43
|
-
- Agent entry files: `AGENTS.md`, `.cursorrules`, `.cursor/rules/atris.mdc`, `.claude/commands/atris.md`, `.claude/commands/atris-autopilot.md`, `atris/CLAUDE.md`, `.claude/settings.json`, `.devin/config.local.json`, and root `CLAUDE.md` Atris markers.
|
|
44
|
-
- Skills: package `atris/skills/` copied into the workspace and linked into `.claude/skills/` when possible.
|
|
45
|
-
|
|
46
|
-
## Project Detection
|
|
47
|
-
|
|
48
|
-
`detectProjectContext()` scans package files first, then framework-specific dependencies, then common structure directories. It detects Node, Python, Ruby, Go, Rust, Java, PHP, Elixir, D, iOS, and markdown-only knowledge bases. The resulting test command is a default hint (`npm test`, `pytest`, `go test ./...`, etc.), not a guarantee that validation is sufficient.
|
|
49
|
-
|
|
50
|
-
`injectProjectPatterns()` writes that profile into navigator, executor, and validator specs so the first generated team has a local project shape before any agent starts work.
|
|
51
|
-
|
|
52
|
-
## Generated Agent Contract
|
|
53
|
-
|
|
54
|
-
The generated instruction files all point agents back to the same small operating loop:
|
|
55
|
-
|
|
56
|
-
- run the Atris boot sequence before first response,
|
|
57
|
-
- keep replies short,
|
|
58
|
-
- use ASCII visuals for planning,
|
|
59
|
-
- check `MAP.md` before code search,
|
|
60
|
-
- use `atris task` for ownership and proof,
|
|
61
|
-
- treat `TODO.md` as rendered state, not the task database.
|
|
62
|
-
|
|
63
|
-
Claude-specific setup also adds a `SessionStart` hook that runs `atris atris.md` when `atris/` exists and a `Stop` hook that points to the autopilot stop hook.
|
|
64
|
-
|
|
65
|
-
## Limits
|
|
66
|
-
|
|
67
|
-
`atris init` bootstraps local files. It does not push to cloud, create a shared business owner, or reconcile template updates after custom edits. Use business commands for shared-owner workspaces and `atris update` / sync flows for canonical file refreshes.
|
|
68
|
-
|
|
69
|
-
## Cross-References
|
|
70
|
-
|
|
71
|
-
- [[atris/wiki/concepts/agent-activation-contract.md]] - the boot behavior generated agent files point to
|
|
72
|
-
- [[atris/wiki/concepts/wiki-as-memory-substrate.md]] - the wiki scaffold and memory contract initialized by this command
|
|
73
|
-
- [[atris/wiki/systems/atris-cli.md]] - repo-level command surface that includes `atris init`
|
package/atris/wiki/index.md
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
# Atris Wiki Index
|
|
2
|
-
|
|
3
|
-
## Entities
|
|
4
|
-
|
|
5
|
-
- [[atris/wiki/people/jack-dorsey.md]] — Block / Twitter founder; AI-native company thesis
|
|
6
|
-
- [[atris/wiki/systems/atris-cli.md]] — this project; dev-tool layer of the Atris stack
|
|
7
|
-
- [[atris/wiki/systems/atris-business.md]] — sibling product; shared owners with persistent AI computers
|
|
8
|
-
- [[atris/wiki/systems/atris-labs.md]] — reference business owner in the Atris fleet; default computer dogfood
|
|
9
|
-
|
|
10
|
-
## Concepts
|
|
11
|
-
|
|
12
|
-
- [[atris/wiki/concepts/intent-capability-composition.md]] — the operating loop; roadmap from gaps
|
|
13
|
-
- [[atris/wiki/concepts/wiki-as-memory-substrate.md]] — what `atris/wiki/` is and isn't
|
|
14
|
-
- [[atris/wiki/concepts/plan-do-review-loop.md]] — core Atris workflow and how local memory fits into it
|
|
15
|
-
- [[atris/wiki/concepts/rebased-pack-co-first-loop.md]] — local-only business workspace first loop and proof guardrails
|
|
16
|
-
- [[atris/wiki/concepts/atris-labs-goals.md]] — atris-labs north star, 2026 Q2 targets, standing constraints
|
|
17
|
-
- [[atris/wiki/concepts/horizon-types.md]] — horizon slug prefix convention; type categories and inference rules
|
|
18
|
-
- [[atris/wiki/concepts/verifiable-reward-loop.md]] — reward, scorecards, and why the repo now acts like an RL-style environment
|
|
19
|
-
- [[atris/wiki/concepts/recursive-self-improvement-position.md]] — honest capability assessment: the loop is the RSI skeleton on the leverage axis, intelligence axis fixed by the model
|
|
20
|
-
- [[atris/wiki/concepts/owner-computer-model.md]] — Owner = User | Business; constrained entity modes, typed computers, and groups as the social/access layer
|
|
21
|
-
- [[atris/wiki/concepts/agent-activation-contract.md]] — editor-facing boot contract: first message, MAP-first, setup, and durable-memory routing
|
|
22
|
-
- [[atris/wiki/concepts/workspace-initialization-contract.md]] — `atris init` bootstrap contract: guards, scaffolds, team context, generated agent files, and hooks
|
|
23
|
-
- [[atris/wiki/concepts/glass-interface-principle.md]] — AI tool design doctrine: make reasoning visible and inspectable, not black-boxed
|
|
24
|
-
|
|
25
|
-
## Briefs
|
|
26
|
-
|
|
27
|
-
- [[atris/wiki/briefs/rebased-pack-co-starter-brief.md]] — starter brief for the local-only Rebased Pack Co smoke workspace
|
|
28
|
-
- [[atris/wiki/briefs/atris-cli-overview.md]] — summary of CLI, owner/computer model, workspace layers, and why `atris/wiki/` exists
|
|
29
|
-
- [[atris/wiki/briefs/atris-labs-workspace-protocol.md]] — atris-labs workspace protocol: on-load sequence, layout, surfaces, north star
|
|
30
|
-
- [[atris/wiki/briefs/atrisos-generative-ui-product-surface.md]] — historical AtrisOS generative UI / block surface design note
|
|
31
|
-
- [[atris/wiki/briefs/launch-post.md]] — historical launch drafts for the local-first wiki feature
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
Source receipt for atris/wiki/systems/atris-labs.md
|
|
2
|
-
Compiled: 2026-05-10
|
|
3
|
-
|
|
4
|
-
Local evidence checked:
|
|
5
|
-
- historical Atris Labs customer workspace docs
|
|
6
|
-
- historical Atris Labs context status and pipeline notes
|
|
7
|
-
- historical Atris Labs member profile notes
|
|
8
|
-
- historical Atris Labs app workspace inventory
|
|
9
|
-
- historical Atris Labs cloud workspace binding metadata
|
|
10
|
-
|
|
11
|
-
Notes:
|
|
12
|
-
- The previous wiki source is missing in this workspace.
|
|
13
|
-
- Available status/pipeline files are historical March 2026 artifacts.
|
|
14
|
-
- Treat this page as orientation, not a live company operating report.
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
Source receipt for atris/wiki/concepts/atris-labs-goals.md
|
|
2
|
-
Compiled: 2026-05-10
|
|
3
|
-
|
|
4
|
-
Local evidence checked:
|
|
5
|
-
- atris/wiki/concepts/atris-labs-goals.md before refresh
|
|
6
|
-
- atris/wiki/log.md historical ingest notes for missing goals.md
|
|
7
|
-
- historical Atris Labs context status and pipeline notes
|
|
8
|
-
- historical Atris Labs fundraising metrics notes
|
|
9
|
-
- historical Atris Labs fundraising story notes
|
|
10
|
-
|
|
11
|
-
Notes:
|
|
12
|
-
- The previous goals source is missing in this workspace.
|
|
13
|
-
- The page is retained as historical direction only.
|
|
14
|
-
- Revenue/customer counts require live verification before operational use.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
Source receipt for atris/wiki/briefs/atrisos-generative-ui-product-surface.md
|
|
2
|
-
Compiled: 2026-05-10
|
|
3
|
-
|
|
4
|
-
Local evidence checked:
|
|
5
|
-
- atris/wiki/briefs/atrisos-generative-ui-product-surface.md before metadata repair
|
|
6
|
-
- atris/wiki/systems/atris-cli.md for current CLI/product context
|
|
7
|
-
|
|
8
|
-
Notes:
|
|
9
|
-
- This brief appears to be an in-session product/design synthesis from 2026-04-29.
|
|
10
|
-
- It is retained as a historical design note, not a current design-system contract.
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Source receipt for atris/wiki/people/jack-dorsey.md
|
|
2
|
-
Compiled: 2026-05-10
|
|
3
|
-
|
|
4
|
-
External sources checked:
|
|
5
|
-
- YouTube episode URL: https://www.youtube.com/watch?v=YTVSwOY19Qs
|
|
6
|
-
- Sequoia transcript: https://sequoiacap.com/podcast/jack-dorsey-every-company-can-now-be-a-mini-agi/
|
|
7
|
-
- Block essay: https://block.xyz/inside/from-hierarchy-to-intelligence
|
|
8
|
-
|
|
9
|
-
Notes:
|
|
10
|
-
- The Sequoia page provides the transcript for the episode linked from YouTube.
|
|
11
|
-
- The Block essay is the co-authored primary written thesis by Jack Dorsey and Roelof Botha.
|
|
12
|
-
- No Atris YouTube processing credits were spent for this refresh.
|