atris 3.42.0 → 3.44.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/atris/skills/design/SKILL.md +7 -1
- package/atris/skills/engines/SKILL.md +44 -13
- package/atris/team/customer-lead/MEMBER.md +45 -0
- package/atris/team/customer-lead/SOUL.md +33 -0
- package/atris/team/customer-lead/START_HERE.md +7 -0
- package/atris/team/customer-lead/skills/customer-commitments/SKILL.md +45 -0
- package/atris/team/improver/MEMBER.md +33 -0
- package/bin/atris.js +37 -4
- package/commands/autoland.js +15 -1
- package/commands/caretaker.js +303 -0
- package/commands/clean.js +76 -0
- package/commands/engine-watch.js +212 -0
- package/commands/engine.js +99 -11
- package/commands/founder.js +304 -0
- package/commands/human-missions.js +844 -0
- package/commands/init.js +16 -7
- package/commands/lesson.js +178 -4
- package/commands/mission.js +124 -69
- package/commands/slop.js +34 -3
- package/commands/task.js +51 -4
- package/commands/team.js +329 -13
- package/commands/verify.js +99 -6
- package/commands/worktree.js +119 -4
- package/lib/auto-accept-certified.js +302 -0
- package/lib/cloud-mission.js +59 -2
- package/lib/conductor-artifacts.js +1 -1
- package/lib/dispatch-scout.js +383 -0
- package/lib/engine-ask.js +645 -0
- package/lib/engine-job-lifecycle.js +65 -0
- package/lib/engine-receipt-sweep.js +98 -0
- package/lib/engine-registry.js +2 -2
- package/lib/engine-validate.js +374 -0
- package/lib/fleet.js +459 -106
- package/lib/known-commands.js +2 -2
- package/lib/lesson-ledger.js +84 -0
- package/lib/member-alive.js +2 -2
- package/lib/policy-lessons.js +70 -0
- package/lib/receipt-evidence.js +56 -1
- package/lib/runner-command.js +1 -1
- package/lib/secret-gateway.js +588 -0
- package/lib/team-presence.js +13 -1
- package/lib/voice-gate.js +6 -0
- package/lib/wish-audit.js +5 -205
- package/lib/wish-delegate.js +5 -2
- package/package.json +6 -1
package/lib/wish-audit.js
CHANGED
|
@@ -189,84 +189,6 @@ const VAGUE_SUPERLATIVE_WORDS = new Set([
|
|
|
189
189
|
'perfect',
|
|
190
190
|
'smartest',
|
|
191
191
|
]);
|
|
192
|
-
const GENERIC_INTERPRETATION_VERBS = new Set([
|
|
193
|
-
'add',
|
|
194
|
-
'build',
|
|
195
|
-
'change',
|
|
196
|
-
'create',
|
|
197
|
-
'do',
|
|
198
|
-
'fix',
|
|
199
|
-
'get',
|
|
200
|
-
'improve',
|
|
201
|
-
'make',
|
|
202
|
-
'polish',
|
|
203
|
-
'tweak',
|
|
204
|
-
'update',
|
|
205
|
-
]);
|
|
206
|
-
const AMBIGUITY_INTERPRETATIONS = {
|
|
207
|
-
'vague-superlative': {
|
|
208
|
-
candidates: ['faster to use', 'smarter by default', 'more complete'],
|
|
209
|
-
recommendedIndex: 1,
|
|
210
|
-
ask: 'which should I optimize for',
|
|
211
|
-
},
|
|
212
|
-
'missing-audience': {
|
|
213
|
-
candidates: ['solo operator', 'team member', 'end user'],
|
|
214
|
-
recommendedIndex: 0,
|
|
215
|
-
ask: 'who is this for',
|
|
216
|
-
},
|
|
217
|
-
'missing-first-slice': {
|
|
218
|
-
candidates: ['capture path', 'resurfacing rule', 'closure loop'],
|
|
219
|
-
recommendedIndex: 1,
|
|
220
|
-
ask: 'what should I change first',
|
|
221
|
-
},
|
|
222
|
-
};
|
|
223
|
-
const SUBJECT_KIND_INTERPRETATIONS = {
|
|
224
|
-
list: {
|
|
225
|
-
'vague-superlative': {
|
|
226
|
-
candidates: ['fastest capture', 'smartest resurfacing', 'most closure'],
|
|
227
|
-
recommendedIndex: 1,
|
|
228
|
-
},
|
|
229
|
-
'missing-first-slice': {
|
|
230
|
-
candidates: ['capture path', 'resurfacing rule', 'closure loop'],
|
|
231
|
-
recommendedIndex: 1,
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
page: {
|
|
235
|
-
'vague-superlative': {
|
|
236
|
-
candidates: ['clearer layout', 'faster scanning', 'stronger action'],
|
|
237
|
-
recommendedIndex: 0,
|
|
238
|
-
},
|
|
239
|
-
'missing-first-slice': {
|
|
240
|
-
candidates: ['top section', 'content hierarchy', 'primary action'],
|
|
241
|
-
recommendedIndex: 1,
|
|
242
|
-
},
|
|
243
|
-
},
|
|
244
|
-
loop: {
|
|
245
|
-
'vague-superlative': {
|
|
246
|
-
candidates: ['fewer steps', 'smarter defaults', 'more reliable completion'],
|
|
247
|
-
recommendedIndex: 1,
|
|
248
|
-
},
|
|
249
|
-
'missing-first-slice': {
|
|
250
|
-
candidates: ['entry path', 'decision rule', 'completion check'],
|
|
251
|
-
recommendedIndex: 1,
|
|
252
|
-
},
|
|
253
|
-
},
|
|
254
|
-
generic: {
|
|
255
|
-
'vague-superlative': {
|
|
256
|
-
candidates: ['faster to use', 'smarter by default', 'more complete'],
|
|
257
|
-
recommendedIndex: 1,
|
|
258
|
-
},
|
|
259
|
-
'missing-first-slice': {
|
|
260
|
-
candidates: ['first step', 'default behavior', 'completion path'],
|
|
261
|
-
recommendedIndex: 1,
|
|
262
|
-
},
|
|
263
|
-
},
|
|
264
|
-
};
|
|
265
|
-
const SUBJECT_KIND_WORDS = {
|
|
266
|
-
list: new Set(['backlog', 'board', 'inbox', 'kanban', 'list', 'queue', 'reminder', 'task', 'todo']),
|
|
267
|
-
page: new Set(['card', 'dashboard', 'form', 'homepage', 'landing', 'modal', 'page', 'panel', 'screen', 'site', 'surface', 'ui', 'view', 'website']),
|
|
268
|
-
loop: new Set(['auth', 'automation', 'cadence', 'checkout', 'flow', 'import', 'login', 'loop', 'onboarding', 'pipeline', 'process', 'routine', 'signup', 'sync', 'workflow']),
|
|
269
|
-
};
|
|
270
192
|
// A conjunction followed by a determiner ("an ml researcher and a 2nd grade
|
|
271
193
|
// teacher") joins noun phrases inside one clause, not two separate wishes.
|
|
272
194
|
const PART_JOINER_WORDS = new Set(['and', 'plus', 'also', 'adn', 'nad', 'annd']);
|
|
@@ -770,12 +692,6 @@ function sharesMeaningfulWords(left, right) {
|
|
|
770
692
|
return false;
|
|
771
693
|
}
|
|
772
694
|
|
|
773
|
-
function capitalizeFirst(text) {
|
|
774
|
-
const clean = String(text || '').trim();
|
|
775
|
-
if (!clean) return '';
|
|
776
|
-
return clean.charAt(0).toUpperCase() + clean.slice(1);
|
|
777
|
-
}
|
|
778
|
-
|
|
779
695
|
function singularInterpretationWord(word) {
|
|
780
696
|
const clean = cleanWord(word);
|
|
781
697
|
if (clean.length > 3 && clean.endsWith('s')) return clean.slice(0, -1);
|
|
@@ -799,15 +715,6 @@ function interpretationWords(text, subject) {
|
|
|
799
715
|
return values;
|
|
800
716
|
}
|
|
801
717
|
|
|
802
|
-
function interpretationVerb(text) {
|
|
803
|
-
for (const word of wordList(text)) {
|
|
804
|
-
const clean = cleanWord(word);
|
|
805
|
-
if (!clean || GENERIC_INTERPRETATION_VERBS.has(clean)) continue;
|
|
806
|
-
if (VERBS.has(clean)) return clean;
|
|
807
|
-
}
|
|
808
|
-
return '';
|
|
809
|
-
}
|
|
810
|
-
|
|
811
718
|
function superlativeWord(text) {
|
|
812
719
|
for (const word of wordList(text)) {
|
|
813
720
|
const clean = cleanWord(word);
|
|
@@ -818,114 +725,12 @@ function superlativeWord(text) {
|
|
|
818
725
|
|
|
819
726
|
function interpretationContext(text, subject) {
|
|
820
727
|
const nouns = interpretationWords(text, subject);
|
|
821
|
-
const topic = nouns.slice(0, 2).join(' ');
|
|
822
728
|
return {
|
|
823
|
-
|
|
824
|
-
topicWords: nouns,
|
|
825
|
-
topic,
|
|
826
|
-
topicHead: nouns[0] || '',
|
|
827
|
-
action: interpretationVerb(text),
|
|
729
|
+
topic: nouns.slice(0, 2).join(' '),
|
|
828
730
|
superlative: superlativeWord(text),
|
|
829
731
|
};
|
|
830
732
|
}
|
|
831
733
|
|
|
832
|
-
function subjectKindForInterpretation(ctx) {
|
|
833
|
-
const topicWords = Array.isArray(ctx.topicWords) ? ctx.topicWords : [];
|
|
834
|
-
if (!topicWords.length) return 'generic';
|
|
835
|
-
const words = new Set(topicWords);
|
|
836
|
-
for (const [kind, kindWords] of Object.entries(SUBJECT_KIND_WORDS)) {
|
|
837
|
-
if (Array.from(words).some((word) => kindWords.has(word))) return kind;
|
|
838
|
-
}
|
|
839
|
-
return 'generic';
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
function subjectKindInterpretation(kind, ctx) {
|
|
843
|
-
const subjectKind = subjectKindForInterpretation(ctx);
|
|
844
|
-
return (SUBJECT_KIND_INTERPRETATIONS[subjectKind] && SUBJECT_KIND_INTERPRETATIONS[subjectKind][kind])
|
|
845
|
-
|| (SUBJECT_KIND_INTERPRETATIONS.generic && SUBJECT_KIND_INTERPRETATIONS.generic[kind])
|
|
846
|
-
|| null;
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
function uniqueInterpretations(values) {
|
|
850
|
-
const seen = new Set();
|
|
851
|
-
const unique = [];
|
|
852
|
-
for (const value of values) {
|
|
853
|
-
const clean = String(value || '').trim().replace(/\s+/g, ' ');
|
|
854
|
-
const key = clean.toLowerCase();
|
|
855
|
-
if (!clean || seen.has(key)) continue;
|
|
856
|
-
seen.add(key);
|
|
857
|
-
unique.push(clean);
|
|
858
|
-
}
|
|
859
|
-
return unique;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
function joinInterpretations(values) {
|
|
863
|
-
if (values.length <= 1) return values[0] || '';
|
|
864
|
-
if (values.length === 2) return `${values[0]} or ${values[1]}`;
|
|
865
|
-
return `${values.slice(0, -1).join(', ')}, or ${values[values.length - 1]}`;
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
function interpretationCandidates(kind, ctx) {
|
|
869
|
-
const domain = kind === 'vague-superlative' || kind === 'missing-first-slice'
|
|
870
|
-
? subjectKindInterpretation(kind, ctx)
|
|
871
|
-
: null;
|
|
872
|
-
const table = domain || AMBIGUITY_INTERPRETATIONS[kind];
|
|
873
|
-
const candidates = table ? [...table.candidates] : [];
|
|
874
|
-
if (kind === 'missing-audience' && ctx.topic) candidates[0] = `${ctx.topic} owner`;
|
|
875
|
-
if (kind === 'missing-first-slice' && domain && ctx.topic && subjectKindForInterpretation(ctx) !== 'generic') {
|
|
876
|
-
candidates[0] = `${ctx.topic} ${candidates[0]}`;
|
|
877
|
-
}
|
|
878
|
-
if (kind === 'missing-first-slice' && !domain && ctx.topic) candidates[0] = `${ctx.topic} capture path`;
|
|
879
|
-
if (kind === 'missing-first-slice' && !domain && ctx.action) candidates[0] = `${ctx.action} path`;
|
|
880
|
-
return uniqueInterpretations(candidates).slice(0, 3);
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
function recommendedInterpretationIndex(kind, ctx, candidates) {
|
|
884
|
-
const words = new Set(ctx.words);
|
|
885
|
-
if (kind === 'missing-audience') {
|
|
886
|
-
if (words.has('team') || words.has('member')) return Math.min(1, candidates.length - 1);
|
|
887
|
-
if (words.has('customer') || words.has('visitor') || words.has('client')) return Math.min(2, candidates.length - 1);
|
|
888
|
-
}
|
|
889
|
-
if (kind === 'vague-superlative' || kind === 'missing-first-slice') {
|
|
890
|
-
if (['fast', 'faster', 'fastest', 'speed', 'quick', 'quickly'].some((word) => words.has(word))) return 0;
|
|
891
|
-
if (['done', 'finish', 'finished', 'close', 'closure', 'complete', 'ship'].some((word) => words.has(word))) {
|
|
892
|
-
return Math.min(2, candidates.length - 1);
|
|
893
|
-
}
|
|
894
|
-
if (['todo', 'task', 'tasks', 'list', 'backlog', 'inbox', 'remind', 'reminder', 'surface', 'resurface'].some((word) => words.has(word))) {
|
|
895
|
-
return Math.min(1, candidates.length - 1);
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
const domain = kind === 'vague-superlative' || kind === 'missing-first-slice'
|
|
899
|
-
? subjectKindInterpretation(kind, ctx)
|
|
900
|
-
: null;
|
|
901
|
-
const table = domain || AMBIGUITY_INTERPRETATIONS[kind];
|
|
902
|
-
return Math.min(table ? table.recommendedIndex : 0, candidates.length - 1);
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
function recommendedInterpretationName(candidate) {
|
|
906
|
-
return String(candidate || '').replace(/^(?:fastest|smartest|most)\s+/i, '').trim();
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
function interpretationLabel(kind, ctx) {
|
|
910
|
-
if (kind === 'vague-superlative') {
|
|
911
|
-
if (ctx.superlative && ctx.topic) return `${capitalizeFirst(ctx.superlative)} ${ctx.topic}`;
|
|
912
|
-
return capitalizeFirst(ctx.superlative || ctx.topic || 'this');
|
|
913
|
-
}
|
|
914
|
-
const topic = ctx.topic ? `${ctx.topic} ` : '';
|
|
915
|
-
if (kind === 'missing-audience') return capitalizeFirst(`${topic}audience`);
|
|
916
|
-
if (kind === 'missing-first-slice') return capitalizeFirst(`${topic}first slice`);
|
|
917
|
-
return capitalizeFirst(ctx.topic || 'this');
|
|
918
|
-
}
|
|
919
|
-
|
|
920
|
-
function buildInterpretationQuestion(text, subject, kind) {
|
|
921
|
-
const table = AMBIGUITY_INTERPRETATIONS[kind];
|
|
922
|
-
const ctx = interpretationContext(text, subject);
|
|
923
|
-
const candidates = interpretationCandidates(kind, ctx);
|
|
924
|
-
const recommended = recommendedInterpretationName(candidates[recommendedInterpretationIndex(kind, ctx, candidates)]);
|
|
925
|
-
const label = interpretationLabel(kind, ctx);
|
|
926
|
-
return `${label} could mean ${joinInterpretations(candidates)}. I would bet on ${recommended}, so ${table.ask}?`;
|
|
927
|
-
}
|
|
928
|
-
|
|
929
734
|
function hasSubjectBearingSuperlative(text, subject) {
|
|
930
735
|
const ctx = interpretationContext(text, subject);
|
|
931
736
|
return Boolean(ctx.superlative && ctx.topic);
|
|
@@ -936,15 +741,10 @@ function buildClarityQuestions(text, subject, vague, options = {}) {
|
|
|
936
741
|
? hasSubjectBearingSuperlative(text, subject)
|
|
937
742
|
: !!options.subjectSuperlative;
|
|
938
743
|
if (!vague && !subjectSuperlative) return [];
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
if (!AUDIENCE_WORDS.test(text)) {
|
|
944
|
-
questions.push(buildInterpretationQuestion(text, subject, 'missing-audience'));
|
|
945
|
-
}
|
|
946
|
-
questions.push(buildInterpretationQuestion(text, subject, 'missing-first-slice'));
|
|
947
|
-
return questions;
|
|
744
|
+
const topic = interpretationContext(text, subject).topic;
|
|
745
|
+
return [topic
|
|
746
|
+
? `What should be different about ${topic} when this is done?`
|
|
747
|
+
: 'What should be different when this is done?'];
|
|
948
748
|
}
|
|
949
749
|
|
|
950
750
|
function priorQuestionRowForAuditTextAnyQuestion(text, root) {
|
package/lib/wish-delegate.js
CHANGED
|
@@ -212,7 +212,7 @@ function wishTitle(wish) {
|
|
|
212
212
|
|
|
213
213
|
// One question at a time, always ending with how to answer it.
|
|
214
214
|
function printQuestion(wish, question) {
|
|
215
|
-
console.log(`Got it
|
|
215
|
+
console.log(`Got it: ${quoteText(wish.text || '')}.`);
|
|
216
216
|
console.log(String(question || 'What should be different when this wish comes true?'));
|
|
217
217
|
console.log('Answer with: atris wish answer "your words"');
|
|
218
218
|
}
|
|
@@ -1097,7 +1097,7 @@ function builderWish(wish, audit, root, asJson) {
|
|
|
1097
1097
|
|
|
1098
1098
|
// Plain per-part reply: what started, what lives elsewhere, and one question per unclear part.
|
|
1099
1099
|
function printDecomposed(wish, parts, delegatedParts, waitingParts) {
|
|
1100
|
-
console.log(`Got it
|
|
1100
|
+
console.log(`Got it: ${quoteText(wish.text || '')}. It has ${parts.length} parts.`);
|
|
1101
1101
|
delegatedParts.forEach((part) => {
|
|
1102
1102
|
if (part.attached_to_existing_flight) {
|
|
1103
1103
|
printGranted(part.text, null, {
|
|
@@ -1267,6 +1267,9 @@ function intakeQuestionSubject(question) {
|
|
|
1267
1267
|
const interpretationMarker = ' could mean ';
|
|
1268
1268
|
const interpretationIndex = normalized.indexOf(interpretationMarker);
|
|
1269
1269
|
if (interpretationIndex > 0) return `interpretation:${normalized.slice(0, interpretationIndex)}`;
|
|
1270
|
+
const grounded = normalized.match(/^what should be different about (.+?) when this is done\?$/);
|
|
1271
|
+
if (grounded) return `interpretation:${grounded[1]}`;
|
|
1272
|
+
if (normalized === 'what should be different when this is done?') return 'interpretation:this';
|
|
1270
1273
|
return `question:${normalized}`;
|
|
1271
1274
|
}
|
|
1272
1275
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "atris",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.44.0",
|
|
4
4
|
"description": "you say what you want in plain words. atris builds it, checks it, and shows you proof.",
|
|
5
5
|
"main": "bin/atris.js",
|
|
6
6
|
"bin": {
|
|
@@ -43,6 +43,11 @@
|
|
|
43
43
|
"atris/team/mission-lead/MEMBER.md",
|
|
44
44
|
"atris/team/mission-lead/MISSION.md",
|
|
45
45
|
"atris/team/mission-lead/START_HERE.md",
|
|
46
|
+
"atris/team/improver/MEMBER.md",
|
|
47
|
+
"atris/team/customer-lead/MEMBER.md",
|
|
48
|
+
"atris/team/customer-lead/SOUL.md",
|
|
49
|
+
"atris/team/customer-lead/START_HERE.md",
|
|
50
|
+
"atris/team/customer-lead/skills/customer-commitments/SKILL.md",
|
|
46
51
|
"atris/team/opus-overnight/MEMBER.md",
|
|
47
52
|
"atris/team/opus-overnight/MISSION.md",
|
|
48
53
|
"atris/team/opus-overnight/START_HERE.md",
|