docs(6208): the remaining frontend comments drop milestone, step and rule citations
CI & Build / Python lint (push) Successful in 9s
CI & Build / Plugin hooks (push) Successful in 22s
CI & Build / TypeScript typecheck (push) Successful in 1m0s
CI & Build / integration (push) Successful in 1m55s
CI & Build / Python tests (push) Successful in 2m20s
CI & Build / Build & push image (push) Successful in 1m7s
CI & Build / Python lint (push) Successful in 9s
CI & Build / Plugin hooks (push) Successful in 22s
CI & Build / TypeScript typecheck (push) Successful in 1m0s
CI & Build / integration (push) Successful in 1m55s
CI & Build / Python tests (push) Successful in 2m20s
CI & Build / Build & push image (push) Successful in 1m7s
Components, stores, api clients, router, types and shared CSS now state what each piece is and why, without the milestone that introduced it. diff.ts names its consumers instead of the copy history; stores/notes and tasks state their current scope instead of the cleanup that set it; theme.css states the token practice instead of the sweep that established it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { apiGet, apiPost, apiPut } from "@/api/client";
|
||||
|
||||
/**
|
||||
* Scheduled backups (milestone 523) — `/api/admin/backups`. One dated,
|
||||
* Scheduled backups — `/api/admin/backups`. One dated,
|
||||
* uncompressed tar per run, delivered to a folder or an S3 bucket.
|
||||
*/
|
||||
export interface BackupConfig {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Canonical systems — the GLOBAL area vocabulary every project's Systems can
|
||||
* map onto (milestone 307).
|
||||
* map onto.
|
||||
*
|
||||
* The mapping is an ASSOCIATION, never a rename: a project's System keeps the
|
||||
* name the project gave it, and `canonical_id` only records which shared area
|
||||
|
||||
@@ -55,7 +55,7 @@ export function apiErrorMessage(e: unknown, fallback: string): string {
|
||||
/**
|
||||
* How long an ordinary JSON call may wait before it is declared failed.
|
||||
*
|
||||
* Rule 156: a wait with no deadline is a bug. `fetch`'s own default is to wait
|
||||
* A wait with no deadline is a bug. `fetch`'s own default is to wait
|
||||
* as long as the browser will, which is not a deadline — it is the absence of
|
||||
* one, and it renders as a spinner that never resolves. There is no state a
|
||||
* surface can show for "pending forever" that is not a lie.
|
||||
@@ -118,7 +118,7 @@ export interface RequestOpts {
|
||||
* The one place a request is actually made — every verb below goes through
|
||||
* here, so the deadline cannot be forgotten by adding a sixth.
|
||||
*
|
||||
* EXPIRY SURFACES AS AN `ApiError`, which is rule 156's second half: the
|
||||
* EXPIRY SURFACES AS AN `ApiError`, the deadline's second half: the
|
||||
* failure has to arrive in the shape the caller already handles. A bare
|
||||
* `DOMException: TimeoutError` would reach `apiErrorMessage(e, fallback)` as
|
||||
* an object with no `body`, so every catch site in the app would report its
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Family canon (milestone 463): ideas every project on a platform shares, and
|
||||
* Family canon: ideas every project on a platform shares, and
|
||||
* the log of every decision about them.
|
||||
*
|
||||
* The agent promotes by written criteria — no approval step. This door is for
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/** Project inception (milestone 297): what a project was decided to inherit. */
|
||||
/** Project inception: what a project was decided to inherit. */
|
||||
import { apiGet, apiPost } from "@/api/client";
|
||||
import type { ProjectPlatform } from "@/api/platforms";
|
||||
|
||||
export interface InceptionChoices {
|
||||
design_system_id: number | null;
|
||||
seed_systems: boolean;
|
||||
/** Platform slugs (milestone 463). null = not answered; a list is the
|
||||
/** Platform slugs. null = not answered; a list is the
|
||||
* whole answer — members left out of it are recorded as "not this".
|
||||
* Absent on records decided before the question existed. */
|
||||
platforms?: string[] | null;
|
||||
|
||||
@@ -72,7 +72,7 @@ export interface Lesson {
|
||||
tags: string[];
|
||||
note_type: string;
|
||||
/** Where it was LEARNED. Kept as a fact, but not a limit on where it can be
|
||||
* found: a lesson is retrievable from every project (milestone 385 step 3). */
|
||||
* found: a lesson is retrievable from every project. */
|
||||
project_id: number | null;
|
||||
permission?: string;
|
||||
created_at: string | null;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { apiGet, apiPost, apiDelete } from "@/api/client";
|
||||
|
||||
/**
|
||||
* The moments of work rules mount on (milestone 458), and the actions that
|
||||
* The moments of work rules mount on, and the actions that
|
||||
* reach each one on this install — `GET /api/retrieval/moments`, the payload
|
||||
* the `list_moments` MCP tool returns, plus the counts the Settings view shows
|
||||
* beside each moment.
|
||||
@@ -102,9 +102,8 @@ export function unmapAction(change: MappingChange): Promise<void> {
|
||||
|
||||
/**
|
||||
* Proposals about a rule's moments, waiting on a person. A `mount` proposal
|
||||
* (milestone 458 step 7) comes from a pass that read the rule, or from the
|
||||
* rule being opened just after the moment fired. An `unmount` proposal (step
|
||||
* 7b) comes from sessions reporting that the mount arrived where it did not
|
||||
* comes from a pass that read the rule, or from the rule being opened just
|
||||
* after the moment fired. An `unmount` proposal comes from sessions reporting that the mount arrived where it did not
|
||||
* apply. `GET /api/retrieval/moments/proposals`, the payload the
|
||||
* `rule_moment_proposals` MCP tool returns.
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Platforms — what a project is built on or ships as (milestone 463).
|
||||
* Platforms — what a project is built on or ships as.
|
||||
*
|
||||
* The catalog is GLOBAL, like the canonical areas, and admin-written. A
|
||||
* project's answer per platform is `declared` (a person said so), `detected`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { apiGet } from "@/api/client";
|
||||
|
||||
/**
|
||||
* The reply shapes Scribe ships (milestone 500) — `GET /api/retrieval/reply-shapes`.
|
||||
* The reply shapes Scribe ships — `GET /api/retrieval/reply-shapes`.
|
||||
* The same catalog the `list_reply_shapes` MCP tool returns, plus what only
|
||||
* the operator's view needs: the preferences mounted on each shape's moment,
|
||||
* and how often each shape was delivered.
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { RecordUsage } from "@/types/usage";
|
||||
import { apiGet, apiPost, apiPatch, apiDelete } from "@/api/client";
|
||||
import type { LinkState } from "@/api/lessons";
|
||||
|
||||
/** How a rule reaches a session (milestone 307). */
|
||||
/** How a rule reaches a session. */
|
||||
|
||||
/**
|
||||
* A typed edge between two rules. Each kind exists because its absence forced
|
||||
@@ -56,7 +56,7 @@ export type RuleKind = "rule" | "preference";
|
||||
|
||||
/** A new record opened from somewhere that already knows what it is for —
|
||||
* "Adjust this" on a reply shape opens a preference mounted on that shape's
|
||||
* moment (milestone 500 step 5). The editor applies it once, when creating. */
|
||||
* moment. The editor applies it once, when creating. */
|
||||
export interface RulePreset {
|
||||
kind?: RuleKind;
|
||||
moments?: string[];
|
||||
@@ -91,11 +91,11 @@ export interface Rule {
|
||||
updated_at: string | null;
|
||||
/** Present only when the rule has them (the server omits empty keys). */
|
||||
systems?: { id: number; name: string }[];
|
||||
/** The moments this rule arrives at whenever they happen (milestone 458),
|
||||
/** The moments this rule arrives at whenever they happen,
|
||||
* in catalog order. Present only when the rule is mounted. */
|
||||
moments?: string[];
|
||||
relations?: RuleRelation[];
|
||||
/** The lessons that point at this rule (milestone 440) — the concrete
|
||||
/** The lessons that point at this rule — the concrete
|
||||
* situations judged instances of it, plus any suggested and awaiting a
|
||||
* judgment. Readable lessons only; omitted when there are none. */
|
||||
lessons?: { id: number; title: string; state: LinkState; note: string }[];
|
||||
@@ -124,7 +124,7 @@ export interface RuleHeader {
|
||||
*/
|
||||
last_verified?: string;
|
||||
/**
|
||||
* Surfaced-vs-opened counts from `rule_usage_events` (milestone 333).
|
||||
* Surfaced-vs-opened counts from `rule_usage_events`.
|
||||
* Zero-filled by the list route, so a rule predating the table reads as
|
||||
* "never surfaced" rather than as a missing field — which for a while is
|
||||
* every rule on every install.
|
||||
@@ -238,7 +238,7 @@ export async function updateRule(id: number, data: Partial<RuleWrite>): Promise<
|
||||
}
|
||||
|
||||
/** Give a rule a new home: a topic makes it global, a project makes it that
|
||||
* project's. Keeps its id, history, areas and relations (milestone 414). */
|
||||
* project's. Keeps its id, history, areas and relations. */
|
||||
export async function moveRule(
|
||||
id: number, to: { topic_id: number } | { project_id: number },
|
||||
): Promise<Rule> {
|
||||
@@ -295,7 +295,7 @@ export async function getRuleVersion(
|
||||
return apiGet<RuleVersion>(`/api/rules/${ruleId}/versions/${versionId}`);
|
||||
}
|
||||
|
||||
// No restore FOR A RULE, deliberately (milestone 323). Putting an old wording
|
||||
// No restore FOR A RULE, deliberately. Putting an old wording
|
||||
// back goes through updateRule, which snapshots what it replaces — so the
|
||||
// undo stays visible in the history like any other edit.
|
||||
//
|
||||
|
||||
@@ -57,7 +57,7 @@ export interface Snippet {
|
||||
|
||||
/** Kept as a name because every consumer here says "snippet usage" — but it IS
|
||||
* the shared shape, since rules answer the same question off their own table
|
||||
* (milestone 333). The reasoning lives on `RecordUsage`; duplicating the four
|
||||
* The reasoning lives on `RecordUsage`; duplicating the four
|
||||
* fields here is how the two drift. */
|
||||
export type SnippetUsage = RecordUsage;
|
||||
|
||||
@@ -95,7 +95,7 @@ export interface SnippetListItem {
|
||||
* written, which is a shape to adapt rather than code to paste. */
|
||||
language?: string;
|
||||
/** When to reach for it, projected from the `data` mirror. The title is the
|
||||
* name alone since milestone 427, so this is where the situation lives. */
|
||||
* name alone, so this is where the situation lives. */
|
||||
when_to_use?: string;
|
||||
/** Always present from the backend, zero-filled for records with no events. */
|
||||
usage?: SnippetUsage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Moments (milestone 458): the pieces the rule editor's picker and the
|
||||
/* Moments: the pieces the rule editor's picker and the
|
||||
Settings section share, so a moment's name and a chip's remove control look
|
||||
the same wherever a person meets them. Loaded unscoped by both. */
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
milestone (tier, then verification) and were byte-identical; a third would
|
||||
have drifted. The pane's italic serif title is inherited by anything inside
|
||||
it, so the chip resets family and style explicitly. */
|
||||
/* A rule with no trigger cannot be retrieved, and since milestone 394
|
||||
retrieval is the only delivery — so this marks a rule that will never
|
||||
/* A rule with no trigger cannot be retrieved, and retrieval is the only
|
||||
delivery — so this marks a rule that will never
|
||||
reach a session. Warning rather than error: the rule is not broken, it is
|
||||
unreachable, and the fix is one field away. */
|
||||
.rule-chip-inert {
|
||||
|
||||
@@ -208,11 +208,8 @@
|
||||
*/
|
||||
|
||||
/* ==========================================================================
|
||||
The compatibility-alias block that lived here is GONE (#2533). It let ~55
|
||||
components keep their historical --color-* names while theme.css was
|
||||
repointed at the design system; the rename sweep it promised ran on
|
||||
2026-08-08 and every component now references --fs-* directly. Do not
|
||||
reintroduce app-local alias names — the design system's tokens are the
|
||||
Every component references the design system's --fs-* tokens directly.
|
||||
Do not introduce app-local alias names — the design system's tokens are the
|
||||
vocabulary, and check_snippets_against_design_system can only see through
|
||||
names the system actually declares.
|
||||
========================================================================== */
|
||||
|
||||
@@ -11,7 +11,7 @@ import { fmtStamp } from "@/utils/dateFormat";
|
||||
import { useToastStore } from "@/stores/toast";
|
||||
|
||||
/**
|
||||
* Scheduled backups (milestone 523): one dated, uncompressed tar per run,
|
||||
* Scheduled backups: one dated, uncompressed tar per run,
|
||||
* delivered to a folder or an S3 bucket. The page answers "is my data backed
|
||||
* up?" first — the verdict, then anything wrong — and the settings follow.
|
||||
*/
|
||||
@@ -50,7 +50,7 @@ async function load() {
|
||||
}
|
||||
}
|
||||
|
||||
// While a backup runs, follow it. Re-armed from load()'s finally (rule 157),
|
||||
// While a backup runs, follow it. Re-armed from load()'s finally, never after the work,
|
||||
// so one failed read does not stop the page following the run.
|
||||
function schedulePoll() {
|
||||
if (pollTimer) clearTimeout(pollTimer);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* The adoption matrix (milestone 463 step 4): every project × every canon
|
||||
* The adoption matrix: every project × every canon
|
||||
* family idea that reaches it, and the project's answer.
|
||||
*
|
||||
* Nobody approves an answer — the agent assesses each project against the
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* The inception form (milestone 297): "what does this project inherit?"
|
||||
* The inception form: "what does this project inherit?"
|
||||
*
|
||||
* Two homes, one component. mode="create" rides the New-project modal's
|
||||
* second step and only emits the choices (the project does not exist yet);
|
||||
* mode="decide" sits on ProjectView for an undecided project, loads that
|
||||
* project's current defaults, and records the decision itself.
|
||||
*
|
||||
* Platforms (milestone 463) start UNANSWERED (null). Ticking any box makes
|
||||
* Platforms start UNANSWERED (null). Ticking any box makes
|
||||
* the list the whole answer; in decide mode the boxes start from what
|
||||
* detection already found, so recording confirms it.
|
||||
*/
|
||||
|
||||
@@ -8,9 +8,9 @@ import { useToastStore } from "@/stores/toast";
|
||||
|
||||
/**
|
||||
* Proposals about a rule's moments, waiting on a person. A mount proposal
|
||||
* (milestone 458 step 7) comes from a pass that read the rule, or from the
|
||||
* comes from a pass that read the rule, or from the
|
||||
* rule being opened just after the moment fired in several sessions; nothing
|
||||
* is mounted until "Mount" is pressed. An unmount proposal (step 7b) comes
|
||||
* is mounted until "Mount" is pressed. An unmount proposal comes
|
||||
* from sessions reporting that the mount arrived where it did not apply;
|
||||
* nothing is taken off until "Take it off" is pressed. Both are the judgment
|
||||
* `judge_rule_moments` makes in a session, through the same service.
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { MomentAction, MomentUsage } from "@/api/moments";
|
||||
import { fmtDate } from "@/utils/dateFormat";
|
||||
|
||||
/**
|
||||
* The human door onto moments (milestone 458 step 6): every moment in the
|
||||
* The human door onto moments: every moment in the
|
||||
* catalog, the actions that reach it on this install, how many rules ride on
|
||||
* it, and what reaching it has delivered. The session's own door is
|
||||
* `list_moments` / `map_action` / `unmap_action`, and both call the same
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
* deliberately rather than abstracting: the ordering carries urgency, "never"
|
||||
* is categorically different from a date, and a failed check writes nothing.
|
||||
*
|
||||
* Lives in the Knowledge view rather than beside the rules sweep (operator's
|
||||
* call, milestone 317 step 4): notes stay where notes live. The cost, accepted
|
||||
* Lives in the Knowledge view rather than beside the rules sweep: notes stay
|
||||
* where notes live. The cost, accepted
|
||||
* knowingly, is that there is no single screen showing every record anyone has
|
||||
* left unconfirmed — /rules keeps its own.
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* A project's place in the family (milestone 463): which platforms it is.
|
||||
* A project's place in the family: which platforms it is.
|
||||
*
|
||||
* Membership is what makes "does this family idea reach this project?" a
|
||||
* lookup rather than a judgment — an idea is for some platforms, and it
|
||||
|
||||
@@ -7,7 +7,7 @@ import RuleEditorSlideOver from "@/components/rules/RuleEditorSlideOver.vue";
|
||||
|
||||
/**
|
||||
* The reply shapes Scribe ships, and the operator's adjustments to each
|
||||
* (milestone 500 step 5). A shape is product, so its text is read-only here;
|
||||
* A shape is product, so its text is read-only here;
|
||||
* what the operator owns is the preferences mounted on the shape's moment,
|
||||
* which arrive beside it and win where they differ. "Adjust this" opens the
|
||||
* preference editor already mounted there.
|
||||
|
||||
@@ -570,7 +570,7 @@ async function confirmDelete() {
|
||||
.issue-systems { display: flex; gap: 0.25rem; flex-shrink: 0; flex-wrap: wrap; }
|
||||
.issue-sys-chip { font-size: 0.66rem; color: var(--fs-text-secondary); background: var(--fs-surface-raised); border-radius: 999px; padding: 0.05rem 0.4rem; }
|
||||
|
||||
/* ── Shared-area mapping (milestone 307) ──────────────────────────
|
||||
/* ── Shared-area mapping ──────────────────────────────────────────
|
||||
The review is a disclosure, not a banner: it exists only while there is
|
||||
something to decide, and collapses to one line until opened. */
|
||||
.area-review {
|
||||
@@ -700,7 +700,7 @@ async function confirmDelete() {
|
||||
.system-form-actions { display: flex; gap: 0.4rem; }
|
||||
.system-paths-input { font-family: var(--fs-font-mono); font-size: 0.8rem; }
|
||||
|
||||
/* The area's files (milestone 444). Mono because they are paths to be read
|
||||
/* The area's files. Mono because they are paths to be read
|
||||
character for character; small because they qualify the card, not lead it. */
|
||||
.system-paths {
|
||||
list-style: none;
|
||||
@@ -826,7 +826,7 @@ async function confirmDelete() {
|
||||
border: 1px dashed var(--fs-border-color);
|
||||
border-radius: var(--fs-radius-lg);
|
||||
}
|
||||
/* remainders over the shared recipes (components.css, m302) */
|
||||
/* remainders over the shared recipes (components.css) */
|
||||
.empty-title { margin: 0; color: var(--fs-text-primary); }
|
||||
.empty-sub { margin: 0 0 0.5rem; font-size: 0.82rem; max-width: 32ch; }
|
||||
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
/**
|
||||
* "N/M used" on a list row — surfaced vs opened, for any record kind.
|
||||
*
|
||||
* Extracted from SnippetListView when the rule list needed the same chip
|
||||
* (milestone 333 step 5). The counts read identically for both; what differs
|
||||
* Shared by the snippet and rule lists. The counts read identically for both; what differs
|
||||
* is the ADVICE, which is why that is a prop. A snippet surfaced repeatedly
|
||||
* and never opened should probably go; a rule in the same position may simply
|
||||
* have a `when_to_apply` that fires on the wrong thing, and telling an
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* What Scribe has changed about how it works with you.
|
||||
*
|
||||
* THE RISK THIS EXISTS FOR (milestone 399). A preference is the one record
|
||||
* THE RISK THIS EXISTS FOR. A preference is the one record
|
||||
* kind the agent rewrites on its own, mid-work, without asking — which is
|
||||
* what keeps it current and what makes it dangerous. An agent misreads one
|
||||
* session, rewrites a preference, and follows the rewritten version forever
|
||||
|
||||
@@ -11,7 +11,7 @@ import type { ApplicableRules } from "@/api/rulebooks";
|
||||
import RuleHomePicker from "@/components/rules/RuleHomePicker.vue";
|
||||
|
||||
/**
|
||||
* A project's view of its rules (milestone 414). A rule's home is its reach:
|
||||
* A project's view of its rules. A rule's home is its reach:
|
||||
* the project's own rules apply here and nowhere else, and every global rule
|
||||
* (one in a rulebook) applies here too. There is no subscribing this project
|
||||
* to a rulebook and no skipping a global rule for it — a project that departs
|
||||
|
||||
@@ -27,7 +27,7 @@ const whenToApply = ref("");
|
||||
// session may quietly rewrite.
|
||||
const kind = ref<RuleKind>("rule");
|
||||
const systemIds = ref<number[]>([]);
|
||||
// The moments this rule is mounted on (milestone 458). Catalog moments are
|
||||
// The moments this rule is mounted on. Catalog moments are
|
||||
// ticked; a named procedure's moment (`skill.<name>`) is typed, since its
|
||||
// name is the procedure's own and no list here could know it.
|
||||
const ruleMoments = ref<string[]>([]);
|
||||
@@ -46,7 +46,7 @@ const expiresWhen = ref("");
|
||||
|
||||
const relations = computed(() => store.currentRule?.relations ?? []);
|
||||
|
||||
// The lessons that point at this rule (milestone 440): confirmed instances
|
||||
// The lessons that point at this rule: confirmed instances
|
||||
// first, then suggestions waiting on a judgment. A rejected lesson does not
|
||||
// point at the rule, so it is not listed here — it stays readable on the
|
||||
// lesson, where the judgment was made.
|
||||
@@ -509,7 +509,7 @@ legend { padding: 0 0.35rem; font-size: 0.8rem; color: var(--fs-text-tertiary);
|
||||
.area-opt { display: flex; align-items: flex-start; gap: 0.5rem; margin-bottom: 0.4rem; font-size: 0.88rem; }
|
||||
.area-opt input { width: auto; margin-top: 0.2rem; accent-color: var(--fs-accent); }
|
||||
.trigger-missing textarea { border-color: var(--fs-warning); }
|
||||
/* The moment picker (milestone 458): the name is what a session reads in a
|
||||
/* The moment picker: the name is what a session reads in a
|
||||
delivered line, so it is shown as written; the meaning is the gloss. */
|
||||
.moments { margin-bottom: 1rem; }
|
||||
.moments .intro { margin-top: 0; margin-bottom: var(--fs-space-3); }
|
||||
|
||||
@@ -84,7 +84,7 @@ function changedFields(index: number): string[] {
|
||||
/** True when this edit rewrote or removed the rule's check.
|
||||
*
|
||||
* Worth its own marker because editing `verify_with` silently drops
|
||||
* `verified_at` (milestone 312) — the moment a rule re-entered the staleness
|
||||
* `verified_at` — the moment a rule re-entered the staleness
|
||||
* sweep. That happens nowhere a reader can see it, and this row is the only
|
||||
* surface that can say when it happened. */
|
||||
function checkChanged(index: number): boolean {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* Where a rule lives, and moving it (milestone 414).
|
||||
* Where a rule lives, and moving it.
|
||||
*
|
||||
* A rule's home IS its reach: in a rulebook topic it is global and applies to
|
||||
* every project; on a project it applies there alone. Moving keeps the rule's
|
||||
|
||||
@@ -4,8 +4,7 @@ import { useRulebooksStore } from "@/stores/rulebooks";
|
||||
import type { RulebookTopic } from "@/api/rulebooks";
|
||||
|
||||
// A rulebook's rules are global — they apply to every project — so this pane
|
||||
// lists topics and nothing else. It carried a "Subscribers" checklist of
|
||||
// projects until milestone 414 retired subscriptions.
|
||||
// lists topics and nothing else.
|
||||
const props = defineProps<{
|
||||
rulebookId: number;
|
||||
topics: RulebookTopic[];
|
||||
|
||||
@@ -72,8 +72,8 @@ const router = createRouter({
|
||||
{
|
||||
// Lessons have no list view of their own: the Knowledge browse surface
|
||||
// is where every kind is enumerated, and a second list would be a
|
||||
// second vocabulary to keep in step with it (#3128's defect, in
|
||||
// advance). `/knowledge?type=lesson` is the list.
|
||||
// second vocabulary to keep in step with it. `/knowledge?type=lesson` is
|
||||
// the list.
|
||||
path: "/lessons/new",
|
||||
name: "lesson-new",
|
||||
component: () => import("@/views/LessonEditorView.vue"),
|
||||
@@ -129,7 +129,7 @@ const router = createRouter({
|
||||
component: () => import("@/views/RulesView.vue"),
|
||||
},
|
||||
{
|
||||
// Family canon (milestone 463): ideas shared across every project on a
|
||||
// Family canon: ideas shared across every project on a
|
||||
// platform, and the log of every decision about them.
|
||||
path: "/family",
|
||||
name: "family",
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useToastStore } from "@/stores/toast";
|
||||
import { apiErrorMessage } from "@/api/client";
|
||||
|
||||
/**
|
||||
* The global area catalog (milestone 307). Shared by every project, so it is
|
||||
* The global area catalog. Shared by every project, so it is
|
||||
* fetched ONCE per session rather than per project — the whole point of the
|
||||
* table is that it is the same list everywhere.
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useToastStore } from "@/stores/toast";
|
||||
import { apiErrorMessage } from "@/api/client";
|
||||
|
||||
/**
|
||||
* The moment catalog and this install's mappings (milestone 458 step 6).
|
||||
* The moment catalog and this install's mappings.
|
||||
*
|
||||
* Shared by the rule editor's picker and the Settings section, so the two
|
||||
* cannot offer different moments. The catalog is the product's and changes
|
||||
|
||||
@@ -4,10 +4,8 @@ import { apiGet, apiPost, apiPut, apiDelete } from "@/api/client";
|
||||
import { useToastStore } from "@/stores/toast";
|
||||
import type { Note } from "@/types/note";
|
||||
|
||||
// Single-note + mutation surface. The list/filter/sort/pagination surface that
|
||||
// backed the removed /notes list view was dropped in the 2026-06-02 drift-audit
|
||||
// cleanup (no consumers — KnowledgeView and the editors use single-entity and
|
||||
// mutation methods only).
|
||||
// Single-note + mutation surface. There is no list/filter/sort here:
|
||||
// KnowledgeView and the editors use single-entity and mutation methods only.
|
||||
export const useNotesStore = defineStore("notes", () => {
|
||||
const currentNote = ref<Note | null>(null);
|
||||
const loading = ref(false);
|
||||
|
||||
@@ -4,7 +4,7 @@ import * as api from "@/api/platforms";
|
||||
import type { Platform } from "@/api/platforms";
|
||||
|
||||
/**
|
||||
* The global platform catalog (milestone 463). Shared by every project, so
|
||||
* The global platform catalog. Shared by every project, so
|
||||
* it is fetched once per session — as the canonical-area catalog is.
|
||||
*/
|
||||
export const usePlatformsStore = defineStore("platforms", () => {
|
||||
|
||||
@@ -142,7 +142,7 @@ export const useRulebooksStore = defineStore("rulebooks", () => {
|
||||
return rule;
|
||||
}
|
||||
|
||||
/** After a move (milestone 414): take the rule out of whichever topic list
|
||||
/** After a move: take the rule out of whichever topic list
|
||||
* held it, and into its new topic's list if that one is loaded. A rule moved
|
||||
* onto a project belongs to no topic list at all. */
|
||||
function placeMovedRule(rule: Rule) {
|
||||
|
||||
@@ -14,9 +14,8 @@ interface IssueFields {
|
||||
arose_from_id?: number | null;
|
||||
}
|
||||
|
||||
// Single-task + mutation surface. The list/filter/sort/pagination surface that
|
||||
// backed the removed /tasks list view was dropped in the 2026-06-02 drift-audit
|
||||
// cleanup (no consumers — ProjectView's kanban keeps its own local task list).
|
||||
// Single-task + mutation surface. There is no list/filter/sort here:
|
||||
// ProjectView's kanban keeps its own local task list.
|
||||
export const useTasksStore = defineStore("tasks", () => {
|
||||
const currentTask = ref<Task | null>(null);
|
||||
const loading = ref(false);
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface Note {
|
||||
due_date: string | null;
|
||||
started_at: string | null;
|
||||
completed_at: string | null;
|
||||
// Which session is working this task now (milestone 381). Null when no
|
||||
// Which session is working this task now. Null when no
|
||||
// session ever claimed it; `live` false when the claim's lease ran out —
|
||||
// a session that went quiet mid-task, which is worth seeing, not hiding.
|
||||
claim?: TaskClaim | null;
|
||||
@@ -38,7 +38,7 @@ export interface Note {
|
||||
is_task: boolean;
|
||||
note_type: NoteType;
|
||||
task_kind?: TaskKind;
|
||||
// The note's own check (milestone 317). Empty on almost every note — that
|
||||
// The note's own check. Empty on almost every note — that
|
||||
// is the normal case: a note with no `verify_with` is a DECISION, and there
|
||||
// is nothing to go and check. Only a note asserting a fact about something
|
||||
// outside the operator's control carries one. `verified_at` null while
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* One shape for every record kind the retrieval surfaces can choose. Snippets
|
||||
* and notes are counted in `note_usage_events`; rules in `rule_usage_events`,
|
||||
* which is a separate table because a note id and a rule id are different
|
||||
* namespaces resolved through different maps at restore (milestone 333). The
|
||||
* namespaces resolved through different maps at restore. The
|
||||
* TABLES are separate for that reason; the READOUT is the same question, so
|
||||
* the client type is one.
|
||||
*
|
||||
@@ -21,7 +21,7 @@ export interface RecordUsage {
|
||||
last_surfaced_at: string | null;
|
||||
last_pulled_at: string | null;
|
||||
/** The subsets that happened on a project other than the record's own —
|
||||
* the evidence it transferred (milestone 385). Notes and snippets carry
|
||||
* the evidence it transferred. Notes and snippets carry
|
||||
* them; rules are global, so their readout does not. */
|
||||
surfaced_away_count?: number;
|
||||
pulled_away_count?: number;
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
/**
|
||||
* Line diff — one copy, for every surface that shows what changed.
|
||||
*
|
||||
* WHY THIS FILE EXISTS. The same LCS walk was written out three times:
|
||||
* privately in `useAssist.ts`, and again inside `HistoryPanel.vue` and
|
||||
* `VersionHistorySection.vue`. The three were character-identical apart from
|
||||
* quote style — nobody had diverged them on purpose, they were simply copied
|
||||
* because `computeDiff` was never exported. Milestone 323 needed a fourth
|
||||
* consumer (a rule's edit history), and a fourth copy is the cost #3207
|
||||
* records: a fix or an improvement now has to be found in N places by someone
|
||||
* who does not know N.
|
||||
* WHY THIS FILE EXISTS. The one LCS diff walk, shared by `useAssist.ts`,
|
||||
* `HistoryPanel.vue`, `VersionHistorySection.vue` and the rule edit history.
|
||||
* A copy per consumer means a fix has to be found in N places by someone who
|
||||
* does not know N.
|
||||
*/
|
||||
|
||||
export interface DiffLine {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
/**
|
||||
* Family canon (milestone 463): the ideas every project on a platform shares,
|
||||
* Family canon: the ideas every project on a platform shares,
|
||||
* and the log of every decision about them.
|
||||
*
|
||||
* Nobody approves a promotion — the agent decides against the three criteria
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* exists (#3727) — sessions were proposing rules for things that should never
|
||||
* have bound anyone.
|
||||
*
|
||||
* BUT IT CAN POINT AT ONE (milestone 440). A lesson that is an instance of a
|
||||
* BUT IT CAN POINT AT ONE. A lesson that is an instance of a
|
||||
* rule says so, and the page shows which of the three answers it holds: the
|
||||
* rule(s) it was judged an instance of, "no rule fits" with the reason, or
|
||||
* not yet judged. The third is the one worth acting on, so it is stated as
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
*
|
||||
* THREE FIELDS, NOT ONE MARKDOWN BOX. The title and body are composed by the
|
||||
* service from `what`, `when_to_apply` and `insight`; this form never sends a
|
||||
* document. That is the design milestone 385 step 1 settled on, and the
|
||||
* evidence for it is blunt: the snippet corpus carries a trigger on every
|
||||
* record with no guard anywhere, because a service composes the title from a
|
||||
* named parameter. What is at 100% is a named structured field — not a writer
|
||||
* remembering a convention.
|
||||
* document, because a field the service composes from a named parameter is
|
||||
* filled every time, with no guard anywhere — a writer remembering a
|
||||
* convention is not.
|
||||
*
|
||||
* THE TRIGGER IS THE FIELD THAT CANNOT BE MISSED, so it is given the most
|
||||
* room, its own explanation, and a save button that refuses without it. A
|
||||
@@ -17,7 +15,7 @@
|
||||
* surfaces — and there is nothing to notice afterwards, because it looks
|
||||
* exactly like a lesson that works. The form is where that gets caught.
|
||||
*
|
||||
* WHICH RULE IS THIS AN INSTANCE OF (milestone 440) is asked here, while the
|
||||
* WHICH RULE IS THIS AN INSTANCE OF is asked here, while the
|
||||
* writer still has the situation in mind, the same way the create tool asks
|
||||
* it. There are three answers: the rule(s), "no rule fits" with a reason, or
|
||||
* leave it open. None is forced, because a lesson left open is still a
|
||||
@@ -267,7 +265,7 @@ onMounted(() => {
|
||||
// Pre-fill from the link that brought you here, the same convention the
|
||||
// snippet editor uses. Left null it is a lesson with no recorded origin,
|
||||
// which is valid — `project_id` says where a lesson was LEARNED and was
|
||||
// never the limit on where it can be found (step 3).
|
||||
// never the limit on where it can be found.
|
||||
if (!isEdit.value && route.query.projectId) {
|
||||
projectId.value = Number(route.query.projectId);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ const projectId = ref<number | null>(null);
|
||||
const milestoneId = ref<number | null>(null);
|
||||
const noteType = ref<NoteType>("note");
|
||||
|
||||
// The note's own check (milestone 317). Offered only for a plain note: a
|
||||
// The note's own check. Offered only for a plain note: a
|
||||
// task's decay is its status, and a snippet has verify_snippet — the service
|
||||
// refuses both, so the form must not ask for what the save would reject.
|
||||
const verifyWith = ref("");
|
||||
@@ -509,7 +509,7 @@ onUnmounted(() => assist.clearSelection());
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- The note's own check (milestone 317). Shown only for a plain
|
||||
<!-- The note's own check. Shown only for a plain
|
||||
note: the service refuses a check on a task or a snippet, so
|
||||
offering the fields there would be a form whose save fails. -->
|
||||
<template v-if="canCarryCheck">
|
||||
|
||||
@@ -50,7 +50,7 @@ const newTitle = ref("");
|
||||
const newDescription = ref("");
|
||||
const newGoal = ref("");
|
||||
const creating = ref(false);
|
||||
// Step 2 of the modal (milestone 297): what the new project inherits.
|
||||
// Step 2 of the modal: what the new project inherits.
|
||||
const modalStep = ref<1 | 2>(1);
|
||||
const newInception = ref<InceptionChoices>(emptyChoices());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user